713 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			713 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | /* LIBPIKA - The PIKA Library
 | ||
|  |  * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball | ||
|  |  * | ||
|  |  * pikaquerybox.c | ||
|  |  * Copyright (C) 1999-2000 Michael Natterer <mitch@gimp.org> | ||
|  |  * | ||
|  |  * This library is free software: you can redistribute it and/or | ||
|  |  * modify it under the terms of the GNU Lesser General Public | ||
|  |  * License as published by the Free Software Foundation; either | ||
|  |  * version 3 of the License, or (at your option) any later version. | ||
|  |  * | ||
|  |  * This library 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 | ||
|  |  * Lesser General Public License for more details. | ||
|  |  * | ||
|  |  * You should have received a copy of the GNU Lesser General Public | ||
|  |  * License along with this library.  If not, see | ||
|  |  * <https://www.gnu.org/licenses/>.
 | ||
|  |  */ | ||
|  | 
 | ||
|  | #include "config.h"
 | ||
|  | 
 | ||
|  | #include <gegl.h>
 | ||
|  | #include <gtk/gtk.h>
 | ||
|  | 
 | ||
|  | #include "libpikabase/pikabase.h"
 | ||
|  | 
 | ||
|  | #include "pikawidgets.h"
 | ||
|  | 
 | ||
|  | #include "libpika/libpika-intl.h"
 | ||
|  | 
 | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * SECTION: pikaquerybox | ||
|  |  * @title: PikaQueryBox | ||
|  |  * @short_description: Some simple dialogs to enter a single int, | ||
|  |  *                     double, string or boolean value. | ||
|  |  * @see_also: #PikaSizeEntry, #PikaUnitMenu | ||
|  |  * | ||
|  |  * These functions provide simple dialogs for entering a single | ||
|  |  * string, integer, double, boolean or pixel size value. | ||
|  |  * | ||
|  |  * They return a pointer to a #GtkDialog which has to be shown with | ||
|  |  * gtk_widget_show() by the caller. | ||
|  |  * | ||
|  |  * The dialogs contain an entry widget for the kind of value they ask | ||
|  |  * for and "OK" and "Cancel" buttons. On "Cancel", all query boxes | ||
|  |  * except the boolean one silently destroy themselves. On "OK" the | ||
|  |  * user defined callback function is called and returns the entered | ||
|  |  * value. | ||
|  |  **/ | ||
|  | 
 | ||
|  | 
 | ||
|  | /*
 | ||
|  |  *  String, integer, double and size query boxes | ||
|  |  */ | ||
|  | 
 | ||
|  | typedef struct _QueryBox QueryBox; | ||
|  | 
 | ||
|  | struct _QueryBox | ||
|  | { | ||
|  |   GtkWidget      *qbox; | ||
|  |   GtkWidget      *vbox; | ||
|  |   GtkWidget      *entry; | ||
|  |   GObject        *object; | ||
|  |   gulong          response_handler; | ||
|  |   GCallback       callback; | ||
|  |   gpointer        callback_data; | ||
|  |   GDestroyNotify  callback_data_destroy; | ||
|  | }; | ||
|  | 
 | ||
|  | 
 | ||
|  | static QueryBox * create_query_box             (const gchar   *title, | ||
|  |                                                 GtkWidget     *parent, | ||
|  |                                                 PikaHelpFunc   help_func, | ||
|  |                                                 const gchar   *help_id, | ||
|  |                                                 GCallback      response_callback, | ||
|  |                                                 const gchar   *icon_name, | ||
|  |                                                 const gchar   *message, | ||
|  |                                                 const gchar   *ok_button, | ||
|  |                                                 const gchar   *cancel_button, | ||
|  |                                                 GObject       *object, | ||
|  |                                                 const gchar   *signal, | ||
|  |                                                 GCallback      callback, | ||
|  |                                                 gpointer       callback_data, | ||
|  |                                                 GDestroyNotify callback_data_destroy); | ||
|  | 
 | ||
|  | static void       query_box_disconnect         (QueryBox      *query_box); | ||
|  | static void       query_box_destroy            (QueryBox      *query_box); | ||
|  | 
 | ||
|  | static void       string_query_box_response    (GtkWidget     *widget, | ||
|  |                                                 gint           response_id, | ||
|  |                                                 QueryBox      *query_box); | ||
|  | static void       int_query_box_response       (GtkWidget     *widget, | ||
|  |                                                 gint           response_id, | ||
|  |                                                 QueryBox      *query_box); | ||
|  | static void       double_query_box_response    (GtkWidget     *widget, | ||
|  |                                                 gint           response_id, | ||
|  |                                                 QueryBox      *query_box); | ||
|  | static void       size_query_box_response      (GtkWidget     *widget, | ||
|  |                                                 gint           response_id, | ||
|  |                                                 QueryBox      *query_box); | ||
|  | static void       boolean_query_box_response   (GtkWidget     *widget, | ||
|  |                                                 gint           response_id, | ||
|  |                                                 QueryBox      *query_box); | ||
|  | 
 | ||
|  | static void       query_box_cancel_callback    (QueryBox      *query_box); | ||
|  | 
 | ||
|  | 
 | ||
|  | /*
 | ||
|  |  *  create a generic query box without any entry widget | ||
|  |  */ | ||
|  | static QueryBox * | ||
|  | create_query_box (const gchar   *title, | ||
|  |                   GtkWidget     *parent, | ||
|  |                   PikaHelpFunc   help_func, | ||
|  |                   const gchar   *help_id, | ||
|  |                   GCallback      response_callback, | ||
|  |                   const gchar   *icon_name, | ||
|  |                   const gchar   *message, | ||
|  |                   const gchar   *ok_button, | ||
|  |                   const gchar   *cancel_button, | ||
|  |                   GObject       *object, | ||
|  |                   const gchar   *signal, | ||
|  |                   GCallback      callback, | ||
|  |                   gpointer       callback_data, | ||
|  |                   GDestroyNotify callback_data_destroy) | ||
|  | { | ||
|  |   QueryBox  *query_box; | ||
|  |   GtkWidget *hbox = NULL; | ||
|  |   GtkWidget *label; | ||
|  | 
 | ||
|  |   /*  make sure the object / signal passed are valid
 | ||
|  |    */ | ||
|  |   g_return_val_if_fail (parent == NULL || GTK_IS_WIDGET (parent), NULL); | ||
|  |   g_return_val_if_fail (object == NULL || G_IS_OBJECT (object), NULL); | ||
|  |   g_return_val_if_fail (object == NULL || signal != NULL, NULL); | ||
|  | 
 | ||
|  |   query_box = g_slice_new0 (QueryBox); | ||
|  | 
 | ||
|  |   query_box->qbox = pika_dialog_new (title, "pika-query-box", | ||
|  |                                      parent, 0, | ||
|  |                                      help_func, help_id, | ||
|  | 
 | ||
|  |                                      cancel_button, GTK_RESPONSE_CANCEL, | ||
|  |                                      ok_button,     GTK_RESPONSE_OK, | ||
|  | 
 | ||
|  |                                      NULL); | ||
|  | 
 | ||
|  |   pika_dialog_set_alternative_button_order (GTK_DIALOG (query_box->qbox), | ||
|  |                                            GTK_RESPONSE_OK, | ||
|  |                                            GTK_RESPONSE_CANCEL, | ||
|  |                                            -1); | ||
|  | 
 | ||
|  |   query_box->response_handler = | ||
|  |     g_signal_connect (query_box->qbox, "response", | ||
|  |                       G_CALLBACK (response_callback), | ||
|  |                       query_box); | ||
|  | 
 | ||
|  |   g_signal_connect (query_box->qbox, "destroy", | ||
|  |                     G_CALLBACK (gtk_widget_destroyed), | ||
|  |                     &query_box->qbox); | ||
|  | 
 | ||
|  |   /*  if we are associated with an object, connect to the provided signal
 | ||
|  |    */ | ||
|  |   if (object) | ||
|  |     { | ||
|  |       GClosure *closure; | ||
|  | 
 | ||
|  |       closure = g_cclosure_new_swap (G_CALLBACK (query_box_cancel_callback), | ||
|  |                                      query_box, NULL); | ||
|  |       g_object_watch_closure (G_OBJECT (query_box->qbox), closure); | ||
|  | 
 | ||
|  |       g_signal_connect_closure (object, signal, closure, FALSE); | ||
|  |     } | ||
|  | 
 | ||
|  |   if (icon_name) | ||
|  |     { | ||
|  |       GtkWidget *content_area; | ||
|  |       GtkWidget *image; | ||
|  | 
 | ||
|  |       content_area = gtk_dialog_get_content_area (GTK_DIALOG (query_box->qbox)); | ||
|  | 
 | ||
|  |       hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); | ||
|  |       gtk_container_set_border_width (GTK_CONTAINER (hbox), 12); | ||
|  |       gtk_box_pack_start (GTK_BOX (content_area), hbox, TRUE, TRUE, 0); | ||
|  |       gtk_widget_show (hbox); | ||
|  | 
 | ||
|  |       image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_DIALOG); | ||
|  |       gtk_widget_set_valign (image, GTK_ALIGN_START); | ||
|  |       gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0); | ||
|  |       gtk_widget_show (image); | ||
|  |     } | ||
|  | 
 | ||
|  |   query_box->vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); | ||
|  | 
 | ||
|  |   g_object_set_data (G_OBJECT (query_box->qbox), "pika-query-box-vbox", | ||
|  |                      query_box->vbox); | ||
|  | 
 | ||
|  |   if (hbox) | ||
|  |     { | ||
|  |       gtk_box_pack_start (GTK_BOX (hbox), query_box->vbox, FALSE, FALSE, 0); | ||
|  |     } | ||
|  |   else | ||
|  |     { | ||
|  |       GtkWidget *content_area; | ||
|  | 
 | ||
|  |       content_area = gtk_dialog_get_content_area (GTK_DIALOG (query_box->qbox)); | ||
|  | 
 | ||
|  |       gtk_container_set_border_width (GTK_CONTAINER (query_box->vbox), 12); | ||
|  |       gtk_box_pack_start (GTK_BOX (content_area), query_box->vbox, | ||
|  |                           TRUE, TRUE, 0); | ||
|  |     } | ||
|  | 
 | ||
|  |   gtk_widget_show (query_box->vbox); | ||
|  | 
 | ||
|  |   if (message) | ||
|  |     { | ||
|  |       label = gtk_label_new (message); | ||
|  |       gtk_label_set_xalign (GTK_LABEL (label), 0.0); | ||
|  |       gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); | ||
|  |       gtk_box_pack_start (GTK_BOX (query_box->vbox), label, FALSE, FALSE, 0); | ||
|  |       gtk_widget_show (label); | ||
|  |     } | ||
|  | 
 | ||
|  |   query_box->entry                 = NULL; | ||
|  |   query_box->object                = object; | ||
|  |   query_box->callback              = callback; | ||
|  |   query_box->callback_data         = callback_data; | ||
|  |   query_box->callback_data_destroy = callback_data_destroy; | ||
|  | 
 | ||
|  |   return query_box; | ||
|  | } | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * pika_query_string_box: | ||
|  |  * @title:        The query box dialog's title. | ||
|  |  * @parent:       The dialog's parent widget. | ||
|  |  * @help_func:    (scope async): The help function to show this dialog's help page. | ||
|  |  * @help_id:      A string identifying this dialog's help page. | ||
|  |  * @message:      A string which will be shown above the dialog's entry widget. | ||
|  |  * @initial:      The initial value. | ||
|  |  * @object:       The object this query box is associated with. | ||
|  |  * @signal:       The object's signal which will cause the query box to be closed. | ||
|  |  * @callback:     The function which will be called when the user selects "OK". | ||
|  |  * @data:         The callback's user data. | ||
|  |  * @data_destroy: Destroy function for @data. | ||
|  |  * | ||
|  |  * Creates a new #GtkDialog that queries the user for a string value. | ||
|  |  * | ||
|  |  * Returns: (transfer full): A pointer to the new #GtkDialog. | ||
|  |  **/ | ||
|  | GtkWidget * | ||
|  | pika_query_string_box (const gchar             *title, | ||
|  |                        GtkWidget               *parent, | ||
|  |                        PikaHelpFunc             help_func, | ||
|  |                        const gchar             *help_id, | ||
|  |                        const gchar             *message, | ||
|  |                        const gchar             *initial, | ||
|  |                        GObject                 *object, | ||
|  |                        const gchar             *signal, | ||
|  |                        PikaQueryStringCallback  callback, | ||
|  |                        gpointer                 data, | ||
|  |                        GDestroyNotify           data_destroy) | ||
|  | { | ||
|  |   QueryBox  *query_box; | ||
|  |   GtkWidget *entry; | ||
|  | 
 | ||
|  |   query_box = create_query_box (title, parent, help_func, help_id, | ||
|  |                                 G_CALLBACK (string_query_box_response), | ||
|  |                                 "dialog-question", | ||
|  |                                 message, | ||
|  |                                 _("_OK"), _("_Cancel"), | ||
|  |                                 object, signal, | ||
|  |                                 G_CALLBACK (callback), | ||
|  |                                 data, data_destroy); | ||
|  | 
 | ||
|  |   if (! query_box) | ||
|  |     return NULL; | ||
|  | 
 | ||
|  |   entry = gtk_entry_new (); | ||
|  |   gtk_entry_set_text (GTK_ENTRY (entry), initial ? initial : ""); | ||
|  |   gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE); | ||
|  |   gtk_box_pack_start (GTK_BOX (query_box->vbox), entry, FALSE, FALSE, 0); | ||
|  |   gtk_widget_grab_focus (entry); | ||
|  |   gtk_widget_show (entry); | ||
|  | 
 | ||
|  |   query_box->entry = entry; | ||
|  | 
 | ||
|  |   return query_box->qbox; | ||
|  | } | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * pika_query_int_box: | ||
|  |  * @title:        The query box dialog's title. | ||
|  |  * @parent:       The dialog's parent widget. | ||
|  |  * @help_func:    (scope async): The help function to show this dialog's help page. | ||
|  |  * @help_id:      A string identifying this dialog's help page. | ||
|  |  * @message:      A string which will be shown above the dialog's entry widget. | ||
|  |  * @initial:      The initial value. | ||
|  |  * @lower:        The lower boundary of the range of possible values. | ||
|  |  * @upper:        The upper boundray of the range of possible values. | ||
|  |  * @object:       The object this query box is associated with. | ||
|  |  * @signal:       The object's signal which will cause the query box to be closed. | ||
|  |  * @callback:     The function which will be called when the user selects "OK". | ||
|  |  * @data:         The callback's user data. | ||
|  |  * @data_destroy: Destroy function for @data. | ||
|  |  * | ||
|  |  * Creates a new #GtkDialog that queries the user for an integer value. | ||
|  |  * | ||
|  |  * Returns: (transfer full): A pointer to the new #GtkDialog. | ||
|  |  **/ | ||
|  | GtkWidget * | ||
|  | pika_query_int_box (const gchar          *title, | ||
|  |                     GtkWidget            *parent, | ||
|  |                     PikaHelpFunc          help_func, | ||
|  |                     const gchar          *help_id, | ||
|  |                     const gchar          *message, | ||
|  |                     gint                  initial, | ||
|  |                     gint                  lower, | ||
|  |                     gint                  upper, | ||
|  |                     GObject              *object, | ||
|  |                     const gchar          *signal, | ||
|  |                     PikaQueryIntCallback  callback, | ||
|  |                     gpointer              data, | ||
|  |                     GDestroyNotify        data_destroy) | ||
|  | { | ||
|  |   QueryBox      *query_box; | ||
|  |   GtkWidget     *spinbutton; | ||
|  |   GtkAdjustment *adjustment; | ||
|  | 
 | ||
|  |   query_box = create_query_box (title, parent, help_func, help_id, | ||
|  |                                 G_CALLBACK (int_query_box_response), | ||
|  |                                 "dialog-question", | ||
|  |                                 message, | ||
|  |                                 _("_OK"), _("_Cancel"), | ||
|  |                                 object, signal, | ||
|  |                                 G_CALLBACK (callback), | ||
|  |                                 data, data_destroy); | ||
|  | 
 | ||
|  |   if (! query_box) | ||
|  |     return NULL; | ||
|  | 
 | ||
|  |   adjustment = gtk_adjustment_new (initial, lower, upper, 1, 10, 0); | ||
|  |   spinbutton = pika_spin_button_new (adjustment, 1.0, 0); | ||
|  |   gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE); | ||
|  |   gtk_entry_set_activates_default (GTK_ENTRY (spinbutton), TRUE); | ||
|  |   gtk_box_pack_start (GTK_BOX (query_box->vbox), spinbutton, FALSE, FALSE, 0); | ||
|  |   gtk_widget_grab_focus (spinbutton); | ||
|  |   gtk_widget_show (spinbutton); | ||
|  | 
 | ||
|  |   query_box->entry = spinbutton; | ||
|  | 
 | ||
|  |   return query_box->qbox; | ||
|  | } | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * pika_query_double_box: | ||
|  |  * @title:       The query box dialog's title. | ||
|  |  * @parent:      The dialog's parent widget. | ||
|  |  * @help_func:   (scope async): The help function to show this dialog's help page. | ||
|  |  * @help_id:     A string identifying this dialog's help page. | ||
|  |  * @message:     A string which will be shown above the dialog's entry widget. | ||
|  |  * @initial:     The initial value. | ||
|  |  * @lower:       The lower boundary of the range of possible values. | ||
|  |  * @upper:       The upper boundray of the range of possible values. | ||
|  |  * @digits:      The number of decimal digits the #GtkSpinButton will provide. | ||
|  |  * @object:      The object this query box is associated with. | ||
|  |  * @signal:      The object's signal which will cause the query box to be closed. | ||
|  |  * @callback:    The function which will be called when the user selects "OK". | ||
|  |  * @data:        The callback's user data. | ||
|  |  * @data_destroy: Destroy function for @data. | ||
|  |  * | ||
|  |  * Creates a new #GtkDialog that queries the user for a double value. | ||
|  |  * | ||
|  |  * Returns: (transfer full): A pointer to the new #GtkDialog. | ||
|  |  **/ | ||
|  | GtkWidget * | ||
|  | pika_query_double_box (const gchar             *title, | ||
|  |                        GtkWidget               *parent, | ||
|  |                        PikaHelpFunc             help_func, | ||
|  |                        const gchar             *help_id, | ||
|  |                        const gchar             *message, | ||
|  |                        gdouble                  initial, | ||
|  |                        gdouble                  lower, | ||
|  |                        gdouble                  upper, | ||
|  |                        gint                     digits, | ||
|  |                        GObject                 *object, | ||
|  |                        const gchar             *signal, | ||
|  |                        PikaQueryDoubleCallback  callback, | ||
|  |                        gpointer                 data, | ||
|  |                        GDestroyNotify           data_destroy) | ||
|  | { | ||
|  |   QueryBox      *query_box; | ||
|  |   GtkWidget     *spinbutton; | ||
|  |   GtkAdjustment *adjustment; | ||
|  | 
 | ||
|  |   query_box = create_query_box (title, parent, help_func, help_id, | ||
|  |                                 G_CALLBACK (double_query_box_response), | ||
|  |                                 "dialog-question", | ||
|  |                                 message, | ||
|  |                                 _("_OK"), _("_Cancel"), | ||
|  |                                 object, signal, | ||
|  |                                 G_CALLBACK (callback), | ||
|  |                                 data, data_destroy); | ||
|  | 
 | ||
|  |   if (! query_box) | ||
|  |     return NULL; | ||
|  | 
 | ||
|  |   adjustment = gtk_adjustment_new (initial, lower, upper, 1, 10, 0); | ||
|  |   spinbutton = pika_spin_button_new (adjustment, 1.0, 0); | ||
|  |   gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE); | ||
|  |   gtk_entry_set_activates_default (GTK_ENTRY (spinbutton), TRUE); | ||
|  |   gtk_box_pack_start (GTK_BOX (query_box->vbox), spinbutton, FALSE, FALSE, 0); | ||
|  |   gtk_widget_grab_focus (spinbutton); | ||
|  |   gtk_widget_show (spinbutton); | ||
|  | 
 | ||
|  |   query_box->entry = spinbutton; | ||
|  | 
 | ||
|  |   return query_box->qbox; | ||
|  | } | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * pika_query_size_box: | ||
|  |  * @title:        The query box dialog's title. | ||
|  |  * @parent:       The dialog's parent widget. | ||
|  |  * @help_func:    (scope async): The help function to show this dialog's help page. | ||
|  |  * @help_id:      A string identifying this dialog's help page. | ||
|  |  * @message:      A string which will be shown above the dialog's entry widget. | ||
|  |  * @initial:      The initial value. | ||
|  |  * @lower:        The lower boundary of the range of possible values. | ||
|  |  * @upper:        The upper boundray of the range of possible values. | ||
|  |  * @digits:       The number of decimal digits the #PikaSizeEntry provide in | ||
|  |  *                "pixel" mode. | ||
|  |  * @unit:         The unit initially shown by the #PikaUnitMenu. | ||
|  |  * @resolution:   The resolution (in dpi) which will be used for pixel/unit | ||
|  |  *                calculations. | ||
|  |  * @dot_for_dot:  %TRUE if the #PikaUnitMenu's initial unit should be "pixels". | ||
|  |  * @object:       The object this query box is associated with. | ||
|  |  * @signal:       The object's signal which will cause the query box | ||
|  |  *                to be closed. | ||
|  |  * @callback:     The function which will be called when the user selects "OK". | ||
|  |  * @data:         The callback's user data. | ||
|  |  * @data_destroy: Destroy function for @data. | ||
|  |  * | ||
|  |  * Creates a new #GtkDialog that queries the user for a size using a | ||
|  |  * #PikaSizeEntry. | ||
|  |  * | ||
|  |  * Returns: (transfer full): A pointer to the new #GtkDialog. | ||
|  |  **/ | ||
|  | GtkWidget * | ||
|  | pika_query_size_box (const gchar           *title, | ||
|  |                      GtkWidget             *parent, | ||
|  |                      PikaHelpFunc           help_func, | ||
|  |                      const gchar           *help_id, | ||
|  |                      const gchar           *message, | ||
|  |                      gdouble                initial, | ||
|  |                      gdouble                lower, | ||
|  |                      gdouble                upper, | ||
|  |                      gint                   digits, | ||
|  |                      PikaUnit               unit, | ||
|  |                      gdouble                resolution, | ||
|  |                      gboolean               dot_for_dot, | ||
|  |                      GObject               *object, | ||
|  |                      const gchar           *signal, | ||
|  |                      PikaQuerySizeCallback  callback, | ||
|  |                      gpointer               data, | ||
|  |                      GDestroyNotify         data_destroy) | ||
|  | { | ||
|  |   QueryBox  *query_box; | ||
|  |   GtkWidget *sizeentry; | ||
|  |   GtkWidget *spinbutton; | ||
|  | 
 | ||
|  |   query_box = create_query_box (title, parent, help_func, help_id, | ||
|  |                                 G_CALLBACK (size_query_box_response), | ||
|  |                                 "dialog-question", | ||
|  |                                 message, | ||
|  |                                 _("_OK"), _("_Cancel"), | ||
|  |                                 object, signal, | ||
|  |                                 G_CALLBACK (callback), | ||
|  |                                 data, data_destroy); | ||
|  | 
 | ||
|  |   if (! query_box) | ||
|  |     return NULL; | ||
|  | 
 | ||
|  |   sizeentry = pika_size_entry_new (1, unit, "%p", TRUE, FALSE, FALSE, 12, | ||
|  |                                    PIKA_SIZE_ENTRY_UPDATE_SIZE); | ||
|  |   if (dot_for_dot) | ||
|  |     pika_size_entry_set_unit (PIKA_SIZE_ENTRY (sizeentry), PIKA_UNIT_PIXEL); | ||
|  |   pika_size_entry_set_resolution (PIKA_SIZE_ENTRY (sizeentry), 0, | ||
|  |                                   resolution, FALSE); | ||
|  |   pika_size_entry_set_refval_digits (PIKA_SIZE_ENTRY (sizeentry), 0, digits); | ||
|  |   pika_size_entry_set_refval_boundaries (PIKA_SIZE_ENTRY (sizeentry), 0, | ||
|  |                                          lower, upper); | ||
|  |   pika_size_entry_set_refval (PIKA_SIZE_ENTRY (sizeentry), 0, initial); | ||
|  | 
 | ||
|  |   spinbutton = pika_size_entry_get_help_widget (PIKA_SIZE_ENTRY (sizeentry), 0); | ||
|  |   gtk_entry_set_activates_default (GTK_ENTRY (spinbutton), TRUE); | ||
|  | 
 | ||
|  |   gtk_box_pack_start (GTK_BOX (query_box->vbox), sizeentry, FALSE, FALSE, 0); | ||
|  |   pika_size_entry_grab_focus (PIKA_SIZE_ENTRY (sizeentry)); | ||
|  |   gtk_widget_show (sizeentry); | ||
|  | 
 | ||
|  |   query_box->entry = sizeentry; | ||
|  | 
 | ||
|  |   return query_box->qbox; | ||
|  | } | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * pika_query_boolean_box: | ||
|  |  * @title:        The query box dialog's title. | ||
|  |  * @parent:       The dialog's parent widget. | ||
|  |  * @help_func:    (scope async): The help function to show this dialog's help page. | ||
|  |  * @help_id:      A string identifying this dialog's help page. | ||
|  |  * @icon_name:    An icon name to specify an icon to appear on the left | ||
|  |  *                on the dialog's message. | ||
|  |  * @message:      A string which will be shown in the query box. | ||
|  |  * @true_button:  The string to be shown in the dialog's left button. | ||
|  |  * @false_button: The string to be shown in the dialog's right button. | ||
|  |  * @object:       The object this query box is associated with. | ||
|  |  * @signal:       The object's signal which will cause the query box | ||
|  |  *                to be closed. | ||
|  |  * @callback:     The function which will be called when the user clicks one | ||
|  |  *                of the buttons. | ||
|  |  * @data:         The callback's user data. | ||
|  |  * @data_destroy: Destroy function for @data. | ||
|  |  * | ||
|  |  * Creates a new #GtkDialog that asks the user to do a boolean decision. | ||
|  |  * | ||
|  |  * Returns: (transfer full): A pointer to the new #GtkDialog. | ||
|  |  **/ | ||
|  | GtkWidget * | ||
|  | pika_query_boolean_box (const gchar              *title, | ||
|  |                         GtkWidget                *parent, | ||
|  |                         PikaHelpFunc              help_func, | ||
|  |                         const gchar              *help_id, | ||
|  |                         const gchar              *icon_name, | ||
|  |                         const gchar              *message, | ||
|  |                         const gchar              *true_button, | ||
|  |                         const gchar              *false_button, | ||
|  |                         GObject                  *object, | ||
|  |                         const gchar              *signal, | ||
|  |                         PikaQueryBooleanCallback  callback, | ||
|  |                         gpointer                  data, | ||
|  |                         GDestroyNotify            data_destroy) | ||
|  | { | ||
|  |   QueryBox  *query_box; | ||
|  | 
 | ||
|  |   query_box = create_query_box (title, parent, help_func, help_id, | ||
|  |                                 G_CALLBACK (boolean_query_box_response), | ||
|  |                                 icon_name, | ||
|  |                                 message, | ||
|  |                                 true_button, false_button, | ||
|  |                                 object, signal, | ||
|  |                                 G_CALLBACK (callback), | ||
|  |                                 data, data_destroy); | ||
|  | 
 | ||
|  |   if (! query_box) | ||
|  |     return NULL; | ||
|  | 
 | ||
|  |   return query_box->qbox; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | /*
 | ||
|  |  *  private functions | ||
|  |  */ | ||
|  | 
 | ||
|  | static void | ||
|  | query_box_disconnect (QueryBox *query_box) | ||
|  | { | ||
|  |   gtk_widget_set_sensitive (query_box->qbox, FALSE); | ||
|  | 
 | ||
|  |   /*  disconnect the response callback to avoid that it may be run twice  */ | ||
|  |   if (query_box->response_handler) | ||
|  |     { | ||
|  |       g_signal_handler_disconnect (query_box->qbox, | ||
|  |                                    query_box->response_handler); | ||
|  | 
 | ||
|  |       query_box->response_handler = 0; | ||
|  |     } | ||
|  | 
 | ||
|  |   /*  disconnect, if we are connected to some signal  */ | ||
|  |   if (query_box->object) | ||
|  |     g_signal_handlers_disconnect_by_func (query_box->object, | ||
|  |                                           query_box_cancel_callback, | ||
|  |                                           query_box); | ||
|  | } | ||
|  | 
 | ||
|  | static void | ||
|  | query_box_destroy (QueryBox *query_box) | ||
|  | { | ||
|  |   /*  Destroy the box  */ | ||
|  |   if (query_box->qbox) | ||
|  |     gtk_widget_destroy (query_box->qbox); | ||
|  | 
 | ||
|  |   if (query_box->callback_data_destroy) | ||
|  |     query_box->callback_data_destroy (query_box->callback_data); | ||
|  | 
 | ||
|  |   g_slice_free (QueryBox, query_box); | ||
|  | } | ||
|  | 
 | ||
|  | static void | ||
|  | string_query_box_response (GtkWidget *widget, | ||
|  |                            gint       response_id, | ||
|  |                            QueryBox  *query_box) | ||
|  | { | ||
|  |   const gchar *string; | ||
|  | 
 | ||
|  |   query_box_disconnect (query_box); | ||
|  | 
 | ||
|  |   /*  Get the entry data  */ | ||
|  |   string = gtk_entry_get_text (GTK_ENTRY (query_box->entry)); | ||
|  | 
 | ||
|  |   /*  Call the user defined callback  */ | ||
|  |   if (response_id == GTK_RESPONSE_OK) | ||
|  |     (* (PikaQueryStringCallback) query_box->callback) (query_box->qbox, | ||
|  |                                                        string, | ||
|  |                                                        query_box->callback_data); | ||
|  | 
 | ||
|  |   query_box_destroy (query_box); | ||
|  | } | ||
|  | 
 | ||
|  | static void | ||
|  | int_query_box_response (GtkWidget *widget, | ||
|  |                         gint       response_id, | ||
|  |                         QueryBox  *query_box) | ||
|  | { | ||
|  |   gint value; | ||
|  | 
 | ||
|  |   query_box_disconnect (query_box); | ||
|  | 
 | ||
|  |   /*  Get the spinbutton data  */ | ||
|  |   value = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (query_box->entry)); | ||
|  | 
 | ||
|  |   /*  Call the user defined callback  */ | ||
|  |   if (response_id == GTK_RESPONSE_OK) | ||
|  |     (* (PikaQueryIntCallback) query_box->callback) (query_box->qbox, | ||
|  |                                                     value, | ||
|  |                                                     query_box->callback_data); | ||
|  | 
 | ||
|  |   query_box_destroy (query_box); | ||
|  | } | ||
|  | 
 | ||
|  | static void | ||
|  | double_query_box_response (GtkWidget *widget, | ||
|  |                            gint       response_id, | ||
|  |                            QueryBox  *query_box) | ||
|  | { | ||
|  |   gdouble value; | ||
|  | 
 | ||
|  |   query_box_disconnect (query_box); | ||
|  | 
 | ||
|  |   /*  Get the spinbutton data  */ | ||
|  |   value = gtk_spin_button_get_value (GTK_SPIN_BUTTON (query_box->entry)); | ||
|  | 
 | ||
|  |   /*  Call the user defined callback  */ | ||
|  |   if (response_id == GTK_RESPONSE_OK) | ||
|  |     (* (PikaQueryDoubleCallback) query_box->callback) (query_box->qbox, | ||
|  |                                                        value, | ||
|  |                                                        query_box->callback_data); | ||
|  | 
 | ||
|  |   query_box_destroy (query_box); | ||
|  | } | ||
|  | 
 | ||
|  | static void | ||
|  | size_query_box_response (GtkWidget *widget, | ||
|  |                          gint       response_id, | ||
|  |                          QueryBox  *query_box) | ||
|  | { | ||
|  |   gdouble  size; | ||
|  |   PikaUnit unit; | ||
|  | 
 | ||
|  |   query_box_disconnect (query_box); | ||
|  | 
 | ||
|  |   /*  Get the sizeentry data  */ | ||
|  |   size = pika_size_entry_get_refval (PIKA_SIZE_ENTRY (query_box->entry), 0); | ||
|  |   unit = pika_size_entry_get_unit (PIKA_SIZE_ENTRY (query_box->entry)); | ||
|  | 
 | ||
|  |   /*  Call the user defined callback  */ | ||
|  |   if (response_id == GTK_RESPONSE_OK) | ||
|  |     (* (PikaQuerySizeCallback) query_box->callback) (query_box->qbox, | ||
|  |                                                      size, | ||
|  |                                                      unit, | ||
|  |                                                      query_box->callback_data); | ||
|  | 
 | ||
|  |   query_box_destroy (query_box); | ||
|  | } | ||
|  | 
 | ||
|  | static void | ||
|  | boolean_query_box_response (GtkWidget *widget, | ||
|  |                             gint       response_id, | ||
|  |                             QueryBox  *query_box) | ||
|  | { | ||
|  |   query_box_disconnect (query_box); | ||
|  | 
 | ||
|  |   /*  Call the user defined callback  */ | ||
|  |   (* (PikaQueryBooleanCallback) query_box->callback) (query_box->qbox, | ||
|  |                                                       (response_id == | ||
|  |                                                        GTK_RESPONSE_OK), | ||
|  |                                                       query_box->callback_data); | ||
|  | 
 | ||
|  |   query_box_destroy (query_box); | ||
|  | } | ||
|  | 
 | ||
|  | static void | ||
|  | query_box_cancel_callback (QueryBox *query_box) | ||
|  | { | ||
|  |   query_box_disconnect (query_box); | ||
|  |   query_box_destroy (query_box); | ||
|  | } |