home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / libgimp / gimpquerybox.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-11-19  |  18.9 KB  |  645 lines

  1. /* LIBGIMP - The GIMP Library
  2.  * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
  3.  *
  4.  * gimpquerybox.c
  5.  * Copyright (C) 1999-2000 Michael Natterer <mitch@gimp.org> 
  6.  *
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2 of the License, or (at your option) any later version.
  11.  * 
  12.  * This library is distributed in the hope that it will be useful, 
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with this library; if not, write to the
  19.  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  20.  * Boston, MA 02111-1307, USA.
  21.  */
  22.  
  23. #include "config.h"
  24.  
  25. #include <gtk/gtk.h>
  26.  
  27. #include "gimpdialog.h"
  28. #include "gimppixmap.h"
  29. #include "gimpquerybox.h"
  30. #include "gimpsizeentry.h"
  31. #include "gimpwidgets.h"
  32.  
  33. #include "libgimp-intl.h"
  34.  
  35. #include "pixmaps/eek.xpm"
  36.  
  37.  
  38. /*
  39.  *  String, integer, double and size query boxes
  40.  */
  41.  
  42. typedef struct _QueryBox QueryBox;
  43.  
  44. struct _QueryBox
  45. {
  46.   GtkWidget     *qbox;
  47.   GtkWidget     *vbox;
  48.   GtkWidget     *entry;
  49.   GtkObject     *object;
  50.   GtkSignalFunc  callback;
  51.   gpointer       data;
  52. };
  53.  
  54.  
  55. static QueryBox * create_query_box             (const gchar   *title,
  56.                         GimpHelpFunc   help_func,
  57.                         const gchar   *help_data,
  58.                         GtkSignalFunc  ok_callback,
  59.                         GtkSignalFunc  cancel_callback,
  60.                         const gchar   *message,
  61.                         const gchar   *ok_button,
  62.                         const gchar   *cancel_button,
  63.                         GtkObject     *object,
  64.                         const gchar   *signal,
  65.                         GtkSignalFunc  callback,
  66.                         gpointer       data);
  67.  
  68. static QueryBox * query_box_disconnect             (gpointer       data);
  69.  
  70. static void       string_query_box_ok_callback     (GtkWidget     *widget,
  71.                             gpointer       data);
  72. static void       int_query_box_ok_callback        (GtkWidget     *widget,
  73.                             gpointer       data);
  74. static void       double_query_box_ok_callback     (GtkWidget     *widget,
  75.                             gpointer       data);
  76. static void       size_query_box_ok_callback       (GtkWidget     *widget,
  77.                             gpointer       data);
  78.  
  79. static void       boolean_query_box_true_callback  (GtkWidget     *widget,
  80.                             gpointer       data);
  81. static void       boolean_query_box_false_callback (GtkWidget     *widget,
  82.                             gpointer       data);
  83.  
  84. static void       query_box_cancel_callback        (GtkWidget     *widget,
  85.                             gpointer       data);
  86.  
  87.  
  88. /*
  89.  *  create a generic query box without any entry widget
  90.  */
  91. static QueryBox *
  92. create_query_box (const gchar   *title,
  93.           GimpHelpFunc   help_func,
  94.           const gchar   *help_data,
  95.           GtkSignalFunc  ok_callback,
  96.           GtkSignalFunc  cancel_callback,
  97.           const gchar   *message,
  98.           const gchar   *ok_button,
  99.           const gchar   *cancel_button,
  100.           GtkObject     *object,
  101.           const gchar   *signal,
  102.           GtkSignalFunc  callback,
  103.           gpointer       data)
  104. {
  105.   QueryBox  *query_box;
  106.   GtkWidget *qbox;
  107.   GtkWidget *vbox = NULL;
  108.   GtkWidget *label;
  109.  
  110.   /*  make sure the object / signal passed are valid
  111.    */
  112.   g_return_val_if_fail (object == NULL || GTK_IS_OBJECT (object), NULL);
  113.   g_return_val_if_fail (object == NULL || signal != NULL, NULL);
  114.  
  115.   query_box = g_new (QueryBox, 1);
  116.  
  117.   qbox = gimp_dialog_new (title, "query_box",
  118.               help_func, help_data,
  119.               GTK_WIN_POS_MOUSE,
  120.               FALSE, TRUE, FALSE,
  121.  
  122.               ok_button, ok_callback,
  123.               query_box, NULL, NULL, TRUE, FALSE,
  124.               cancel_button, cancel_callback,
  125.               query_box, NULL, NULL, FALSE, TRUE,
  126.  
  127.               NULL);
  128.  
  129.   gtk_signal_connect (GTK_OBJECT (qbox), "destroy",
  130.               GTK_SIGNAL_FUNC (gtk_widget_destroyed),
  131.               &query_box->qbox);
  132.  
  133.   /*  if we are associated with an object, connect to the provided signal
  134.    */
  135.   if (object)
  136.     {
  137.       gtk_signal_connect (GTK_OBJECT (object), "destroy",
  138.               GTK_SIGNAL_FUNC (gtk_widget_destroyed),
  139.               &query_box->object);
  140.  
  141.       gtk_signal_connect (GTK_OBJECT (object), signal,
  142.               GTK_SIGNAL_FUNC (query_box_cancel_callback),
  143.               query_box);
  144.     }
  145.   else
  146.     {
  147.       object = NULL;
  148.     }
  149.  
  150.   if (message)
  151.     {
  152.       vbox = gtk_vbox_new (FALSE, 2);
  153.       gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
  154.       gtk_container_add (GTK_CONTAINER (GTK_DIALOG (qbox)->vbox), vbox);
  155.       gtk_widget_show (vbox);
  156.  
  157.       label = gtk_label_new (message);
  158.       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
  159.       gtk_widget_show (label);
  160.     }
  161.  
  162.   query_box->qbox     = qbox;
  163.   query_box->vbox     = vbox;
  164.   query_box->entry    = NULL;
  165.   query_box->object   = object;
  166.   query_box->callback = callback;
  167.   query_box->data     = data;
  168.  
  169.   return query_box;
  170. }
  171.  
  172. /**
  173.  * gimp_query_string_box:
  174.  * @title: The query box dialog's title.
  175.  * @help_func: The help function to show this dialog's help page.
  176.  * @help_data: A string pointing to this dialog's html help page.
  177.  * @message: A string which will be shown above the dialog's entry widget.
  178.  * @initial: The initial value.
  179.  * @object: The object this query box is associated with.
  180.  * @signal: The object's signal which will cause the query box to be closed.
  181.  * @callback: The function which will be called when the user selects "OK".
  182.  * @data: The callback's user data.
  183.  *
  184.  * Returns: A pointer to the new #GtkDialog.
  185.  **/
  186. GtkWidget *
  187. gimp_query_string_box (const gchar             *title,
  188.                GimpHelpFunc             help_func,
  189.                const gchar             *help_data,
  190.                const gchar             *message,
  191.                const gchar             *initial,
  192.                GtkObject               *object,
  193.                const gchar             *signal,
  194.                GimpQueryStringCallback  callback,
  195.                gpointer                 data)
  196. {
  197.   QueryBox  *query_box;
  198.   GtkWidget *entry;
  199.  
  200.   query_box = create_query_box (title, help_func, help_data,
  201.                 string_query_box_ok_callback,
  202.                 query_box_cancel_callback,
  203.                 message,
  204.                 _("OK"), _("Cancel"),
  205.                 object, signal,
  206.                 callback, data);
  207.  
  208.   if (! query_box)
  209.     return NULL;
  210.  
  211.   entry = gtk_entry_new ();
  212.   gtk_box_pack_start (GTK_BOX (query_box->vbox), entry, FALSE, FALSE, 0);
  213.   if (initial)
  214.     gtk_entry_set_text (GTK_ENTRY (entry), initial);
  215.   gtk_widget_grab_focus (entry);
  216.   gtk_widget_show (entry);
  217.  
  218.   query_box->entry = entry;
  219.  
  220.   return query_box->qbox;
  221. }
  222.  
  223. /**
  224.  * gimp_query_int_box:
  225.  * @title: The query box dialog's title.
  226.  * @help_func: The help function to show this dialog's help page.
  227.  * @help_data: A string pointing to this dialog's html help page.
  228.  * @message: A string which will be shown above the dialog's entry widget.
  229.  * @initial: The initial value.
  230.  * @lower: The lower boundary of the range of possible values.
  231.  * @upper: The upper boundray of the range of possible values.
  232.  * @object: The object this query box is associated with.
  233.  * @signal: The object's signal which will cause the query box to be closed.
  234.  * @callback: The function which will be called when the user selects "OK".
  235.  * @data: The callback's user data.
  236.  *
  237.  * Returns: A pointer to the new #GtkDialog.
  238.  **/
  239. GtkWidget *
  240. gimp_query_int_box (const gchar          *title,
  241.             GimpHelpFunc          help_func,
  242.             const gchar          *help_data,
  243.             const gchar          *message,
  244.             gint                  initial,
  245.             gint                  lower,
  246.             gint                  upper,
  247.             GtkObject            *object,
  248.             const gchar          *signal,
  249.             GimpQueryIntCallback  callback,
  250.             gpointer              data)
  251. {
  252.   QueryBox  *query_box;
  253.   GtkWidget *spinbutton;
  254.   GtkObject *adjustment;
  255.  
  256.   query_box = create_query_box (title, help_func, help_data,
  257.                 int_query_box_ok_callback,
  258.                 query_box_cancel_callback,
  259.                 message,
  260.                 _("OK"), _("Cancel"),
  261.                 object, signal,
  262.                 callback, data);
  263.  
  264.   if (! query_box)
  265.     return NULL;
  266.  
  267.   spinbutton = gimp_spin_button_new (&adjustment,
  268.                      initial, lower, upper, 1, 10, 0,
  269.                      1, 0);
  270.   gtk_box_pack_start (GTK_BOX (query_box->vbox), spinbutton, FALSE, FALSE, 0);
  271.   gtk_widget_grab_focus (spinbutton);
  272.   gtk_widget_show (spinbutton);
  273.  
  274.   query_box->entry = spinbutton;
  275.  
  276.   return query_box->qbox;
  277. }
  278.  
  279. /**
  280.  * gimp_query_double_box:
  281.  * @title: The query box dialog's title.
  282.  * @help_func: The help function to show this dialog's help page.
  283.  * @help_data: A string pointing to this dialog's html help page.
  284.  * @message: A string which will be shown above the dialog's entry widget.
  285.  * @initial: The initial value.
  286.  * @lower: The lower boundary of the range of possible values.
  287.  * @upper: The upper boundray of the range of possible values.
  288.  * @digits: The number of decimal digits the #GtkSpinButton will provide.
  289.  * @object: The object this query box is associated with.
  290.  * @signal: The object's signal which will cause the query box to be closed.
  291.  * @callback: The function which will be called when the user selects "OK".
  292.  * @data: The callback's user data.
  293.  *
  294.  * Returns: A pointer to the new #GtkDialog.
  295.  **/
  296. GtkWidget *
  297. gimp_query_double_box (const gchar             *title,
  298.                GimpHelpFunc             help_func,
  299.                const gchar             *help_data,
  300.                const gchar             *message,
  301.                gdouble                  initial,
  302.                gdouble                  lower,
  303.                gdouble                  upper,
  304.                gint                     digits,
  305.                GtkObject               *object,
  306.                const gchar             *signal,
  307.                GimpQueryDoubleCallback  callback,
  308.                gpointer                 data)
  309. {
  310.   QueryBox  *query_box;
  311.   GtkWidget *spinbutton;
  312.   GtkObject *adjustment;
  313.  
  314.   query_box = create_query_box (title, help_func, help_data,
  315.                 double_query_box_ok_callback,
  316.                 query_box_cancel_callback,
  317.                 message,
  318.                 _("OK"), _("Cancel"),
  319.                 object, signal,
  320.                 callback, data);
  321.  
  322.   if (! query_box)
  323.     return NULL;
  324.  
  325.   spinbutton = gimp_spin_button_new (&adjustment,
  326.                      initial, lower, upper, 1, 10, 0,
  327.                      1, digits);
  328.   gtk_box_pack_start (GTK_BOX (query_box->vbox), spinbutton, FALSE, FALSE, 0);
  329.   gtk_widget_grab_focus (spinbutton);
  330.   gtk_widget_show (spinbutton);
  331.  
  332.   query_box->entry = spinbutton;
  333.  
  334.   return query_box->qbox;
  335. }
  336.  
  337. /**
  338.  * gimp_query_size_box:
  339.  * @title: The query box dialog's title.
  340.  * @help_func: The help function to show this dialog's help page.
  341.  * @help_data: A string pointing to this dialog's html help page.
  342.  * @message: A string which will be shown above the dialog's entry widget.
  343.  * @initial: The initial value.
  344.  * @lower: The lower boundary of the range of possible values.
  345.  * @upper: The upper boundray of the range of possible values.
  346.  * @digits: The number of decimal digits the #GimpSizeEntry provide in
  347.  *          "pixel" mode.
  348.  * @unit: The unit initially shown by the #GimpUnitMenu.
  349.  * @resolution: The resolution (in dpi) which will be used for pixel/unit
  350.  *              calculations.
  351.  * @dot_for_dot: #TRUE if the #GimpUnitMenu's initial unit should be "pixels".
  352.  * @object: The object this query box is associated with.
  353.  * @signal: The object's signal which will cause the query box to be closed.
  354.  * @callback: The function which will be called when the user selects "OK".
  355.  * @data: The callback's user data.
  356.  *
  357.  * Returns: A pointer to the new #GtkDialog.
  358.  **/
  359. GtkWidget *
  360. gimp_query_size_box (const gchar           *title,
  361.              GimpHelpFunc           help_func,
  362.              const gchar           *help_data,
  363.              const gchar           *message,
  364.              gdouble                initial,
  365.              gdouble                lower,
  366.              gdouble                upper,
  367.              gint                   digits,
  368.              GimpUnit               unit,
  369.              gdouble                resolution,
  370.              gboolean               dot_for_dot,
  371.              GtkObject             *object,
  372.              const gchar           *signal,
  373.              GimpQuerySizeCallback  callback,
  374.              gpointer               data)
  375. {
  376.   QueryBox  *query_box;
  377.   GtkWidget *sizeentry;
  378.  
  379.   query_box = create_query_box (title, help_func, help_data,
  380.                 size_query_box_ok_callback,
  381.                 query_box_cancel_callback,
  382.                 message,
  383.                 _("OK"), _("Cancel"),
  384.                 object, signal,
  385.                 callback, data);
  386.  
  387.   if (! query_box)
  388.     return NULL;
  389.  
  390.   sizeentry = gimp_size_entry_new (1, unit, "%p", TRUE, FALSE, FALSE, 100,
  391.                    GIMP_SIZE_ENTRY_UPDATE_SIZE);
  392.   if (dot_for_dot)
  393.     gimp_size_entry_set_unit (GIMP_SIZE_ENTRY (sizeentry), GIMP_UNIT_PIXEL);
  394.   gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (sizeentry), 0,
  395.                   resolution, FALSE);
  396.   gimp_size_entry_set_refval_digits (GIMP_SIZE_ENTRY (sizeentry), 0, digits);
  397.   gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (sizeentry), 0,
  398.                      lower, upper);
  399.   gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (sizeentry), 0, initial);
  400.  
  401.   gtk_box_pack_start (GTK_BOX (query_box->vbox), sizeentry, FALSE, FALSE, 0);
  402.   gimp_size_entry_grab_focus (GIMP_SIZE_ENTRY (sizeentry));
  403.   gtk_widget_show (sizeentry);
  404.  
  405.   query_box->entry = sizeentry;
  406.  
  407.   return query_box->qbox;
  408. }
  409.  
  410. /**
  411.  * gimp_query_boolean_box:
  412.  * @title: The query box dialog's title.
  413.  * @help_func: The help function to show this dialog's help page.
  414.  * @help_data: A string pointing to this dialog's html help page.
  415.  * @eek: #TRUE if you want the "Eek" wilber to appear left of the dialog's
  416.  *       message.
  417.  * @message: A string which will be shown in the query box.
  418.  * @true_button: The string to be shown in the dialog's left button.
  419.  * @false_button: The string to be shown in the dialog's right button.
  420.  * @object: The object this query box is associated with.
  421.  * @signal: The object's signal which will cause the query box to be closed.
  422.  * @callback: The function which will be called when the user clicks one
  423.  *            of the buttons.
  424.  * @data: The callback's user data.
  425.  *
  426.  * Returns: A pointer to the new #GtkDialog.
  427.  **/
  428. GtkWidget *
  429. gimp_query_boolean_box (const gchar              *title,
  430.             GimpHelpFunc              help_func,
  431.             const gchar              *help_data,
  432.             gboolean                  eek,
  433.             const gchar              *message,
  434.             const gchar              *true_button,
  435.             const gchar              *false_button,
  436.             GtkObject                *object,
  437.             const gchar              *signal,
  438.             GimpQueryBooleanCallback  callback,
  439.             gpointer                  data)
  440. {
  441.   QueryBox  *query_box;
  442.   GtkWidget *hbox;
  443.   GtkWidget *pixmap;
  444.   GtkWidget *label;
  445.  
  446.   query_box = create_query_box (title, help_func, help_data,
  447.                 boolean_query_box_true_callback,
  448.                 boolean_query_box_false_callback,
  449.                 eek ? NULL : message,
  450.                 true_button, false_button,
  451.                 object, signal,
  452.                 callback, data);
  453.  
  454.   if (! query_box)
  455.     return NULL;
  456.  
  457.   if (! eek)
  458.     return query_box->qbox;
  459.  
  460.   hbox = gtk_hbox_new (FALSE, 10);
  461.   gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
  462.   gtk_container_add (GTK_CONTAINER (GTK_DIALOG (query_box->qbox)->vbox), hbox);
  463.   gtk_widget_show (hbox);
  464.  
  465.   pixmap = gimp_pixmap_new (eek_xpm);
  466.   gtk_box_pack_start (GTK_BOX (hbox), pixmap, FALSE, FALSE, 0);
  467.   gtk_widget_show (pixmap);
  468.  
  469.   label = gtk_label_new (message);
  470.   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
  471.   gtk_widget_show (label);
  472.  
  473.   return query_box->qbox;
  474. }
  475.  
  476.  
  477. /*
  478.  *  private functions
  479.  */
  480.  
  481. static QueryBox *
  482. query_box_disconnect (gpointer  data)
  483. {
  484.   QueryBox *query_box;
  485.  
  486.   query_box = (QueryBox *) data;
  487.  
  488.   gtk_widget_set_sensitive (query_box->qbox, FALSE);
  489.  
  490.   /*  disconnect, if we are connected to some signal  */
  491.   if (query_box->object)
  492.     gtk_signal_disconnect_by_data (query_box->object, query_box);
  493.  
  494.   return query_box;
  495. }
  496.  
  497. static void
  498. string_query_box_ok_callback (GtkWidget *widget,
  499.                   gpointer   data)
  500. {
  501.   QueryBox *query_box;
  502.   gchar    *string;
  503.  
  504.   query_box = query_box_disconnect (data);
  505.  
  506.   /*  Get the entry data  */
  507.   string = g_strdup (gtk_entry_get_text (GTK_ENTRY (query_box->entry)));
  508.  
  509.   /*  Call the user defined callback  */
  510.   (* query_box->callback) (query_box->qbox, string,
  511.                query_box->data);
  512.  
  513.   /*  Destroy the box  */
  514.   if (query_box->qbox)
  515.     gtk_widget_destroy (query_box->qbox);
  516.  
  517.   g_free (query_box);
  518. }
  519.  
  520. static void
  521. int_query_box_ok_callback (GtkWidget *widget,
  522.                gpointer   data)
  523. {
  524.   QueryBox *query_box;
  525.   gint      value;
  526.  
  527.   query_box = query_box_disconnect (data);
  528.  
  529.   /*  Get the spinbutton data  */
  530.   value =
  531.     gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (query_box->entry));
  532.  
  533.   /*  Call the user defined callback  */
  534.   (* query_box->callback) (query_box->qbox, value,
  535.                query_box->data);
  536.  
  537.   /*  Destroy the box  */
  538.   if (query_box->qbox)
  539.     gtk_widget_destroy (query_box->qbox);
  540.  
  541.   g_free (query_box);
  542. }
  543.  
  544. static void
  545. double_query_box_ok_callback (GtkWidget *widget,
  546.                   gpointer   data)
  547. {
  548.   QueryBox *query_box;
  549.   gdouble   value;
  550.  
  551.   query_box = query_box_disconnect (data);
  552.  
  553.   /*  Get the spinbutton data  */
  554.   value =
  555.     gtk_spin_button_get_value_as_float (GTK_SPIN_BUTTON (query_box->entry));
  556.  
  557.   /*  Call the user defined callback  */
  558.   (* query_box->callback) (query_box->qbox, value,
  559.                query_box->data);
  560.  
  561.   /*  Destroy the box  */
  562.   if (query_box->qbox)
  563.     gtk_widget_destroy (query_box->qbox);
  564.  
  565.   g_free (query_box);
  566. }
  567.  
  568. static void
  569. size_query_box_ok_callback (GtkWidget *widget,
  570.                 gpointer   data)
  571. {
  572.   QueryBox *query_box;
  573.   gdouble   size;
  574.   GimpUnit  unit;
  575.  
  576.   query_box = query_box_disconnect (data);
  577.  
  578.   /*  Get the sizeentry data  */
  579.   size = gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (query_box->entry), 0);
  580.   unit = gimp_size_entry_get_unit (GIMP_SIZE_ENTRY (query_box->entry));
  581.  
  582.   /*  Call the user defined callback  */
  583.   (* query_box->callback) (query_box->qbox, size, unit,
  584.                query_box->data);
  585.  
  586.   /*  Destroy the box  */
  587.   if (query_box->qbox)
  588.     gtk_widget_destroy (query_box->qbox);
  589.  
  590.   g_free (query_box);
  591. }
  592.  
  593. static void
  594. boolean_query_box_true_callback (GtkWidget *widget,
  595.                  gpointer   data)
  596. {
  597.   QueryBox *query_box;
  598.  
  599.   query_box = query_box_disconnect (data);
  600.  
  601.   /*  Call the user defined callback  */
  602.   (* query_box->callback) (query_box->qbox, TRUE,
  603.                query_box->data);
  604.  
  605.   /*  Destroy the box  */
  606.   if (query_box->qbox)
  607.     gtk_widget_destroy (query_box->qbox);
  608.  
  609.   g_free (query_box);
  610. }
  611.  
  612. static void
  613. boolean_query_box_false_callback (GtkWidget *widget,
  614.                   gpointer   data)
  615. {
  616.   QueryBox *query_box;
  617.  
  618.   query_box = query_box_disconnect (data);
  619.  
  620.   /*  Call the user defined callback  */
  621.   (* query_box->callback) (query_box->qbox, FALSE,
  622.                query_box->data);
  623.  
  624.   /*  Destroy the box  */
  625.   if (query_box->qbox)
  626.     gtk_widget_destroy (query_box->qbox);
  627.  
  628.   g_free (query_box);
  629. }
  630.  
  631. static void
  632. query_box_cancel_callback (GtkWidget *widget,
  633.                gpointer   data)
  634. {
  635.   QueryBox *query_box;
  636.  
  637.   query_box = query_box_disconnect (data);
  638.  
  639.   /*  Destroy the box  */
  640.   if (query_box->qbox)
  641.     gtk_widget_destroy (query_box->qbox);
  642.  
  643.   g_free (query_box);
  644. }
  645.