aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@physics.org>2021-11-29 17:35:21 +0100
committerThomas White <taw@physics.org>2021-11-29 17:35:21 +0100
commit77bdea2d5e7dd878202616d0caf49d01e15ef85c (patch)
treee5da1d4af6f76fd04b6db81df305bcc3b3ead4a8
parentcc8b4303f422643e9ed4327db4680cf87bcedd0a (diff)
Add GtkMultiFileChooserButton
-rw-r--r--CMakeLists.txt3
-rw-r--r--meson.build1
-rw-r--r--src/gtkmultifilechooserbutton.c148
-rw-r--r--src/gtkmultifilechooserbutton.h75
4 files changed, 226 insertions, 1 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1f69bed2..df68ad18 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -388,7 +388,8 @@ if (GTK_FOUND)
src/gui_peaksearch.c src/gui_index.c src/gui_merge.c src/gui_backend_local.c
src/gui_project.c src/crystfelindexingopts.c src/crystfelmergeopts.c
src/crystfelsymmetryselector.c src/gtk-util-routines.c src/gui_fom.c
- src/gui_export.c src/gui_ambi.c src/gui_import.c)
+ src/gui_export.c src/gui_ambi.c src/gui_import.c
+ src/gtkmultifilechooserbutton.c)
if (HAVE_SLURM)
set(CRYSTFEL_GUI_SOURCES ${CRYSTFEL_GUI_SOURCES} src/gui_backend_slurm.c)
diff --git a/meson.build b/meson.build
index 45fca0ec..7a5b6ed3 100644
--- a/meson.build
+++ b/meson.build
@@ -216,6 +216,7 @@ if gtkdep.found()
'src/gui_ambi.c',
'src/gui_backend_local.c',
'src/gui_project.c',
+ 'src/gtkmultifilechooserbutton.c',
versionc]
if slurmdep.found()
diff --git a/src/gtkmultifilechooserbutton.c b/src/gtkmultifilechooserbutton.c
new file mode 100644
index 00000000..98eb7170
--- /dev/null
+++ b/src/gtkmultifilechooserbutton.c
@@ -0,0 +1,148 @@
+/*
+ * gtkmultifilechooserbutton.c
+ *
+ * A GTK widget to select multiple files
+ *
+ * Copyright © 2021 Deutsches Elektronen-Synchrotron DESY,
+ * a research centre of the Helmholtz Association.
+ *
+ * Authors:
+ * 2021 Thomas White <taw@physics.org>
+ *
+ * This file is part of CrystFEL.
+ *
+ * CrystFEL is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * CrystFEL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with CrystFEL. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <gtk/gtk.h>
+#include <glib-object.h>
+
+#include "gtkmultifilechooserbutton.h"
+
+
+G_DEFINE_TYPE(GtkMultiFileChooserButton,
+ gtk_multi_file_chooser_button,
+ GTK_TYPE_BUTTON)
+
+
+static void gtk_multi_file_chooser_button_finalize(GObject *obj)
+{
+ GtkMultiFileChooserButton *mfc = GTK_MULTI_FILE_CHOOSER_BUTTON(obj);
+ free(mfc->text);
+ G_OBJECT_CLASS(gtk_multi_file_chooser_button_parent_class)->finalize(obj);
+}
+
+
+static void gtk_multi_file_chooser_button_class_init(GtkMultiFileChooserButtonClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS(klass);
+ object_class->finalize = gtk_multi_file_chooser_button_finalize;
+}
+
+
+static void gtk_multi_file_chooser_button_init(GtkMultiFileChooserButton *mfc)
+{
+ mfc->chooser = NULL;
+ mfc->filenames = NULL;
+}
+
+
+static void chooser_destroy_sig(GtkWidget *widget, GtkMultiFileChooserButton *mfc)
+{
+ mfc->chooser = NULL;
+}
+
+
+static void delstring(gpointer data, gpointer user_data)
+{
+ g_free(data);
+}
+
+
+static void chooser_response_sig(GtkWidget *dialog, gint resp,
+ GtkMultiFileChooserButton *mfc)
+{
+ if ( resp == GTK_RESPONSE_ACCEPT ) {
+
+ int n;
+ char tmp[64];
+
+ if ( mfc->filenames != NULL ) {
+ g_slist_foreach(mfc->filenames, delstring, NULL);
+ g_slist_free(mfc->filenames);
+ }
+
+ mfc->filenames = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));
+
+ n = g_slist_length(mfc->filenames);
+ snprintf(tmp, 63, "%i files selected", n);
+ gtk_button_set_label(GTK_BUTTON(mfc), tmp);
+
+ }
+
+ gtk_widget_destroy(dialog);
+}
+
+
+static void click_sig(GtkMultiFileChooserButton *mfc, gpointer data)
+{
+ GtkWidget *parent;
+
+ if ( mfc->chooser != NULL ) return;
+
+ parent = gtk_widget_get_toplevel(GTK_WIDGET(mfc));
+ if ( !GTK_IS_WINDOW(parent) ) {
+ parent = NULL;
+ }
+ mfc->chooser = gtk_file_chooser_dialog_new(mfc->text,
+ GTK_WINDOW(parent),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ "Select", GTK_RESPONSE_ACCEPT,
+ NULL);
+ gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(mfc->chooser), TRUE);
+ g_signal_connect(mfc->chooser, "destroy",
+ G_CALLBACK(chooser_destroy_sig), mfc);
+ g_signal_connect(G_OBJECT(mfc->chooser), "response",
+ G_CALLBACK(chooser_response_sig), mfc);
+ gtk_widget_show(mfc->chooser);
+}
+
+
+GtkWidget *gtk_multi_file_chooser_button_new(const char *text)
+{
+ GtkMultiFileChooserButton *mfc;
+
+ mfc = g_object_new(GTK_TYPE_MULTI_FILE_CHOOSER_BUTTON, NULL);
+ mfc->text = strdup(text);
+ gtk_button_set_label(GTK_BUTTON(mfc), mfc->text);
+ g_signal_connect(mfc, "clicked", G_CALLBACK(click_sig), NULL);
+
+ return GTK_WIDGET(mfc);
+}
+
+
+GSList *gtk_multi_file_chooser_button_get_filenames(GtkMultiFileChooserButton *mfc)
+{
+ return mfc->filenames;
+}
diff --git a/src/gtkmultifilechooserbutton.h b/src/gtkmultifilechooserbutton.h
new file mode 100644
index 00000000..9b2e4e7b
--- /dev/null
+++ b/src/gtkmultifilechooserbutton.h
@@ -0,0 +1,75 @@
+/*
+ * gtkmultifilechooserbutton.h
+ *
+ * A GTK widget to select multiple files
+ *
+ * Copyright © 2021 Deutsches Elektronen-Synchrotron DESY,
+ * a research centre of the Helmholtz Association.
+ *
+ * Authors:
+ * 2021 Thomas White <taw@physics.org>
+ *
+ * This file is part of CrystFEL.
+ *
+ * CrystFEL is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * CrystFEL is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with CrystFEL. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef GTKMULTIFILECHOOSERBUTTON_H
+#define GTKMULTIFILECHOOSERBUTTON_H
+
+#include <gtk/gtk.h>
+#include <glib-object.h>
+
+#define GTK_TYPE_MULTI_FILE_CHOOSER_BUTTON (gtk_multi_file_chooser_button_get_type())
+
+#define GTK_MULTI_FILE_CHOOSER_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
+ GTK_TYPE_MULTI_FILE_CHOOSER_BUTTON, GtkMultiFileChooserButton))
+
+#define GTK_IS_MULTI_FILE_CHOOSER_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), \
+ GTK_TYPE_MULTI_FILE_CHOOSER_BUTTON))
+
+#define GTK_MULTI_FILE_CHOOSER_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((obj), \
+ GTK_TYPE_MULTI_FILE_CHOOSER_BUTTON, GtkMultiFileChooser))
+
+#define GTK_IS_MULTI_FILE_CHOOSER_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((obj), \
+ GTK_TYPE_MULTI_FILE_CHOOSER_BUTTON))
+
+#define GTK_MULTI_FILE_CHOOSER_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), \
+ GTK_TYPE_MULTI_FILE_CHOOSER_BUTTON, GtkMultiFileChooser))
+
+struct _gtkmultifilechooserbutton
+{
+ GtkButton parent_instance;
+
+ /*< private >*/
+ GtkWidget *chooser;
+ char *text;
+ GSList *filenames;
+};
+
+struct _gtkmultifilechooserbuttonclass
+{
+ GtkButtonClass parent_class;
+ int dummy;
+};
+
+typedef struct _gtkmultifilechooserbutton GtkMultiFileChooserButton;
+typedef struct _gtkmultifilechooserbuttonclass GtkMultiFileChooserButtonClass;
+
+extern GType gtk_multi_file_chooser_button_get_type(void);
+extern GtkWidget *gtk_multi_file_chooser_button_new(const char *label);
+extern GSList *gtk_multi_file_chooser_button_get_filenames(GtkMultiFileChooserButton *mfc);
+
+#endif /* GTKMULTIFILECHOOSERBUTTON_H */