From 77bdea2d5e7dd878202616d0caf49d01e15ef85c Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 29 Nov 2021 17:35:21 +0100 Subject: Add GtkMultiFileChooserButton --- src/gtkmultifilechooserbutton.c | 148 ++++++++++++++++++++++++++++++++++++++++ src/gtkmultifilechooserbutton.h | 75 ++++++++++++++++++++ 2 files changed, 223 insertions(+) create mode 100644 src/gtkmultifilechooserbutton.c create mode 100644 src/gtkmultifilechooserbutton.h (limited to 'src') 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 + * + * 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 . + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include + +#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 + * + * 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 . + * + */ + +#ifndef GTKMULTIFILECHOOSERBUTTON_H +#define GTKMULTIFILECHOOSERBUTTON_H + +#include +#include + +#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 */ -- cgit v1.2.3