diff options
Diffstat (limited to 'widgets')
-rw-r--r-- | widgets/misc/ChangeLog | 13 | ||||
-rw-r--r-- | widgets/misc/Makefile.am | 8 | ||||
-rw-r--r-- | widgets/misc/gal-combo-box.c | 826 | ||||
-rw-r--r-- | widgets/misc/gal-combo-box.h | 91 | ||||
-rw-r--r-- | widgets/misc/gal-combo-text.c | 427 | ||||
-rw-r--r-- | widgets/misc/gal-combo-text.h | 76 | ||||
-rw-r--r-- | widgets/table/ChangeLog | 6 | ||||
-rw-r--r-- | widgets/table/e-table-config.c | 166 | ||||
-rw-r--r-- | widgets/table/e-table-config.h | 3 |
9 files changed, 162 insertions, 1454 deletions
diff --git a/widgets/misc/ChangeLog b/widgets/misc/ChangeLog index 86ad4d50cd..fc6c7bf6ee 100644 --- a/widgets/misc/ChangeLog +++ b/widgets/misc/ChangeLog @@ -1,3 +1,16 @@ +2007-05-25 Matthew Barnes <mbarnes@redhat.com> + + ** Fixes part of bug #441010 + + * gal-combo-box.c: + * gal-combo-box.h: + * gal-combo-text.c: + * gal-combo-text.h: + Bye bye old widgets, go back to Motif! + + * Makefile.am: + Remove the aforementioned files. + 2007-05-21 Wang Xin <jedy.wang@sun.com> * e-dateedit.c: Fixes #439049. diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index 8b77392e9d..c811f81034 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -77,9 +77,7 @@ widgetsinclude_HEADERS = \ e-selection-model-simple.h \ e-selection-model.h \ e-unicode.h \ - e-colors.h \ - gal-combo-box.h \ - gal-combo-text.h + e-colors.h libemiscwidgets_la_SOURCES = \ $(widgetsinclude_HEADERS) \ @@ -125,9 +123,7 @@ libemiscwidgets_la_SOURCES = \ e-selection-model-simple.c \ e-selection-model.c \ e-unicode.c \ - e-colors.c \ - gal-combo-box.c \ - gal-combo-text.c + e-colors.c libemiscwidgets_la_LDFLAGS = $(NO_UNDEFINED) diff --git a/widgets/misc/gal-combo-box.c b/widgets/misc/gal-combo-box.c deleted file mode 100644 index ba010bc2d2..0000000000 --- a/widgets/misc/gal-combo-box.c +++ /dev/null @@ -1,826 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * gtk-combo-box.c - a customizable combobox - * Copyright 2000, 2001, Ximian, Inc. - * - * Authors: - * Miguel de Icaza (miguel@gnu.org) - * Adrian E Feiguin (feiguin@ifir.edu.ar) - * Paolo Molnaro (lupus@debian.org). - * Jon K Hellan (hellan@acm.org) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. - * - * 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#include <config.h> - -#include <gdk/gdkkeysyms.h> -#include <gtk/gtk.h> - -#include "e-util/e-util-marshal.h" -#include "e-util/e-util.h" - -#include "gal-combo-box.h" - -#define PARENT_TYPE GTK_TYPE_HBOX -static GObjectClass *gal_combo_box_parent_class; - -static int gtk_combo_toggle_pressed (GtkToggleButton *tbutton, - GalComboBox *combo_box); -static void gtk_combo_popup_tear_off (GalComboBox *combo, - gboolean set_position); -static void gtk_combo_set_tearoff_state (GalComboBox *combo, - gboolean torn_off); -static void gtk_combo_popup_reparent (GtkWidget *popup, GtkWidget *new_parent, - gboolean unrealize); -static gboolean cb_popup_delete (GtkWidget *w, GdkEventAny *event, - GalComboBox *combo); -static void gtk_combo_tearoff_bg_copy (GalComboBox *combo); - -enum { - POP_DOWN_WIDGET, - POP_DOWN_DONE, - PRE_POP_DOWN, - POST_POP_HIDE, - LAST_SIGNAL -}; - -static guint gal_combo_box_signals [LAST_SIGNAL] = { 0, }; - -struct _GalComboBoxPrivate { - GtkWidget *pop_down_widget; - GtkWidget *display_widget; - - /* - * Internal widgets used to implement the ComboBox - */ - GtkWidget *frame; - GtkWidget *arrow_button; - - GtkWidget *toplevel; /* Popup's toplevel when not torn off */ - GtkWidget *tearoff_window; /* Popup's toplevel when torn off */ - guint torn_off; - - GtkWidget *tearable; /* The tearoff "button" */ - GtkWidget *popup; /* Popup */ - - /* - * Closure for invoking the callbacks above - */ - void *closure; -}; - -static void -gal_combo_box_finalize (GObject *object) -{ - GalComboBox *combo_box = GAL_COMBO_BOX (object); - - g_free (combo_box->priv); - - gal_combo_box_parent_class->finalize (object); -} - -static void -gal_combo_box_destroy (GtkObject *object) -{ - GtkObjectClass *klass = (GtkObjectClass *)gal_combo_box_parent_class; - GalComboBox *combo_box = GAL_COMBO_BOX (object); - - if (combo_box->priv->toplevel) { - gtk_object_destroy (GTK_OBJECT (combo_box->priv->toplevel)); - combo_box->priv->toplevel = NULL; - } - - if (combo_box->priv->tearoff_window) { - gtk_object_destroy (GTK_OBJECT (combo_box->priv->tearoff_window)); - combo_box->priv->tearoff_window = NULL; - } - - if (klass->destroy) - klass->destroy (object); -} - -static gboolean -gal_combo_box_mnemonic_activate (GtkWidget *w, gboolean group_cycling) -{ - GalComboBox *combo_box = GAL_COMBO_BOX (w); - gtk_toggle_button_set_active ( - GTK_TOGGLE_BUTTON (combo_box->priv->arrow_button), TRUE); - return TRUE; -} - -static void -gal_combo_box_class_init (GObjectClass *object_class) -{ - GtkWidgetClass *widget_class = (GtkWidgetClass *)object_class; - gal_combo_box_parent_class = g_type_class_peek_parent (object_class); - - object_class->finalize = gal_combo_box_finalize; - widget_class->mnemonic_activate = gal_combo_box_mnemonic_activate; - ((GtkObjectClass *)object_class)->destroy = gal_combo_box_destroy; - - gal_combo_box_signals [POP_DOWN_WIDGET] = g_signal_new ( - "pop_down_widget", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GalComboBoxClass, pop_down_widget), - NULL, NULL, - e_util_marshal_POINTER__NONE, - G_TYPE_POINTER, 0, G_TYPE_NONE); - - gal_combo_box_signals [POP_DOWN_DONE] = g_signal_new ( - "pop_down_done", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GalComboBoxClass, pop_down_done), - NULL, NULL, - e_util_marshal_BOOLEAN__OBJECT, - G_TYPE_BOOLEAN, 1, G_TYPE_OBJECT); - - gal_combo_box_signals [PRE_POP_DOWN] = g_signal_new ( - "pre_pop_down", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GalComboBoxClass, pre_pop_down), - NULL, NULL, - e_util_marshal_NONE__NONE, - G_TYPE_NONE, 0); - - gal_combo_box_signals [POST_POP_HIDE] = g_signal_new ( - "post_pop_hide", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GalComboBoxClass, post_pop_hide), - NULL, NULL, - e_util_marshal_NONE__NONE, - G_TYPE_NONE, 0); -} - -static void -deactivate_arrow (GalComboBox *combo_box) -{ - GtkToggleButton *arrow; - - arrow = GTK_TOGGLE_BUTTON (combo_box->priv->arrow_button); - g_signal_handlers_block_matched (arrow, - G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, - 0, 0, NULL, - gtk_combo_toggle_pressed, combo_box); - - gtk_toggle_button_set_active (arrow, FALSE); - - g_signal_handlers_unblock_matched (arrow, - G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, - 0, 0, NULL, - gtk_combo_toggle_pressed, combo_box); -} - -/** - * gal_combo_box_popup_hide_unconditional - * @combo_box: Combo box - * - * Hide popup, whether or not it is torn off. - */ -static void -gal_combo_box_popup_hide_unconditional (GalComboBox *combo_box) -{ - gboolean popup_info_destroyed = FALSE; - - g_return_if_fail (combo_box != NULL); - g_return_if_fail (GAL_IS_COMBO_BOX (combo_box)); - - gtk_widget_hide (combo_box->priv->toplevel); - gtk_widget_hide (combo_box->priv->popup); - if (combo_box->priv->torn_off) { - GTK_TEAROFF_MENU_ITEM (combo_box->priv->tearable)->torn_off - = FALSE; - gtk_combo_set_tearoff_state (combo_box, FALSE); - } - - gtk_grab_remove (combo_box->priv->toplevel); - gdk_pointer_ungrab (GDK_CURRENT_TIME); - - g_object_ref (combo_box->priv->pop_down_widget); - g_signal_emit (combo_box, - gal_combo_box_signals [POP_DOWN_DONE], 0, - combo_box->priv->pop_down_widget, &popup_info_destroyed); - - if (popup_info_destroyed){ - gtk_container_remove ( - GTK_CONTAINER (combo_box->priv->frame), - combo_box->priv->pop_down_widget); - combo_box->priv->pop_down_widget = NULL; - } - g_object_unref (combo_box->priv->pop_down_widget); - deactivate_arrow (combo_box); - - g_signal_emit (combo_box, gal_combo_box_signals [POST_POP_HIDE], 0); -} - -/** - * gal_combo_box_popup_hide: - * @combo_box: Combo box - * - * Hide popup, but not when it is torn off. - * This is the external interface - for subclasses and apps which expect a - * regular combo which doesn't do tearoffs. - */ -void -gal_combo_box_popup_hide (GalComboBox *combo_box) -{ - if (!combo_box->priv->torn_off) - gal_combo_box_popup_hide_unconditional (combo_box); - else if (GTK_WIDGET_VISIBLE (combo_box->priv->toplevel)) { - /* Both popup and tearoff window present. Get rid of just - the popup shell. */ - gtk_combo_popup_tear_off (combo_box, FALSE); - deactivate_arrow (combo_box); - } -} - -/* - * Find best location for displaying - */ -void -gal_combo_box_get_pos (GalComboBox *combo_box, int *x, int *y) -{ - GtkWidget *wcombo = GTK_WIDGET (combo_box); - int ph, pw; - - gdk_window_get_origin (wcombo->window, x, y); - *y += wcombo->allocation.height + wcombo->allocation.y; - *x += wcombo->allocation.x; - - ph = combo_box->priv->popup->allocation.height; - pw = combo_box->priv->popup->allocation.width; - - if ((*y + ph) > gdk_screen_height ()) - *y = gdk_screen_height () - ph; - - if ((*x + pw) > gdk_screen_width ()) - *x = gdk_screen_width () - pw; -} - -static void -gal_combo_box_popup_display (GalComboBox *combo_box) -{ - int x, y; - - g_return_if_fail (combo_box != NULL); - g_return_if_fail (GAL_IS_COMBO_BOX (combo_box)); - - /* - * If we have no widget to display on the popdown, - * create it - */ - if (!combo_box->priv->pop_down_widget){ - GtkWidget *pw = NULL; - - g_signal_emit (combo_box, - gal_combo_box_signals [POP_DOWN_WIDGET], 0, &pw); - g_assert (pw != NULL); - combo_box->priv->pop_down_widget = pw; - gtk_container_add (GTK_CONTAINER (combo_box->priv->frame), pw); - } - - g_signal_emit (combo_box, gal_combo_box_signals [PRE_POP_DOWN], 0); - - if (combo_box->priv->torn_off) { - /* To give the illusion that tearoff still displays the - * popup, we copy the image in the popup window to the - * background. Thus, it won't be blank after reparenting */ - gtk_combo_tearoff_bg_copy (combo_box); - - /* We force an unrealize here so that we don't trigger - * redrawing/ clearing code - we just want to reveal our - * backing pixmap. - */ - gtk_combo_popup_reparent (combo_box->priv->popup, - combo_box->priv->toplevel, TRUE); - } - - gal_combo_box_get_pos (combo_box, &x, &y); - - gtk_widget_set_uposition (combo_box->priv->toplevel, x, y); - gtk_widget_realize (combo_box->priv->popup); - gtk_widget_show (combo_box->priv->popup); - gtk_widget_realize (combo_box->priv->toplevel); - gtk_widget_show (combo_box->priv->toplevel); - - gtk_grab_add (combo_box->priv->toplevel); - gdk_pointer_grab (combo_box->priv->toplevel->window, TRUE, - GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK | - GDK_POINTER_MOTION_MASK, - NULL, NULL, GDK_CURRENT_TIME); -} - -static int -gtk_combo_toggle_pressed (GtkToggleButton *tbutton, GalComboBox *combo_box) -{ - if (tbutton->active) - gal_combo_box_popup_display (combo_box); - else - gal_combo_box_popup_hide_unconditional (combo_box); - - return TRUE; -} - -static gint -gal_combo_box_button_press (GtkWidget *widget, GdkEventButton *event, GalComboBox *combo_box) -{ - GtkWidget *child; - - child = gtk_get_event_widget ((GdkEvent *) event); - if (child != widget){ - while (child){ - if (child == widget) - return FALSE; - child = child->parent; - } - } - - gal_combo_box_popup_hide (combo_box); - return TRUE; -} - -/** - * gal_combo_box_key_press - * @widget: Widget - * @event: Event - * @combo_box: Combo box - * - * Key press handler which dismisses popup on escape. - * Popup is dismissed whether or not popup is torn off. - */ -static gint -gal_combo_box_key_press (GtkWidget *widget, GdkEventKey *event, - GalComboBox *combo_box) -{ - if (event->keyval == GDK_Escape) { - gal_combo_box_popup_hide_unconditional (combo_box); - return TRUE; - } else - return FALSE; -} - -static void -cb_state_change (GtkWidget *widget, GtkStateType old_state, GalComboBox *combo_box) -{ - GtkStateType const new_state = GTK_WIDGET_STATE(widget); - gtk_widget_set_state (combo_box->priv->display_widget, new_state); -} - -static void -gal_combo_box_init (GalComboBox *combo_box) -{ - GtkWidget *arrow; - GdkCursor *cursor; - - combo_box->priv = g_new0 (GalComboBoxPrivate, 1); - - /* - * Create the arrow - */ - combo_box->priv->arrow_button = gtk_toggle_button_new (); - gtk_button_set_relief (GTK_BUTTON (combo_box->priv->arrow_button), GTK_RELIEF_NONE); - GTK_WIDGET_UNSET_FLAGS (combo_box->priv->arrow_button, GTK_CAN_FOCUS); - - arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE); - gtk_container_add (GTK_CONTAINER (combo_box->priv->arrow_button), arrow); - gtk_box_pack_end (GTK_BOX (combo_box), combo_box->priv->arrow_button, FALSE, FALSE, 0); - g_signal_connect (combo_box->priv->arrow_button, "toggled", - G_CALLBACK (gtk_combo_toggle_pressed), combo_box); - gtk_widget_show_all (combo_box->priv->arrow_button); - - /* - * prelight the display widget when mousing over the arrow. - */ - g_signal_connect (combo_box->priv->arrow_button, "state-changed", - G_CALLBACK (cb_state_change), combo_box); - - /* - * The pop-down container - */ - - combo_box->priv->toplevel = gtk_window_new (GTK_WINDOW_POPUP); - g_object_ref_sink (combo_box->priv->toplevel); - gtk_window_set_policy (GTK_WINDOW (combo_box->priv->toplevel), - FALSE, TRUE, FALSE); - - combo_box->priv->popup = gtk_event_box_new (); - gtk_container_add (GTK_CONTAINER (combo_box->priv->toplevel), - combo_box->priv->popup); - gtk_widget_show (combo_box->priv->popup); - - gtk_widget_realize (combo_box->priv->popup); - cursor = gdk_cursor_new (GDK_TOP_LEFT_ARROW); - gdk_window_set_cursor (combo_box->priv->popup->window, cursor); - gdk_cursor_unref (cursor); - - combo_box->priv->torn_off = FALSE; - combo_box->priv->tearoff_window = NULL; - - combo_box->priv->frame = gtk_frame_new (NULL); - gtk_container_add (GTK_CONTAINER (combo_box->priv->popup), - combo_box->priv->frame); - gtk_frame_set_shadow_type (GTK_FRAME (combo_box->priv->frame), GTK_SHADOW_OUT); - - g_signal_connect (combo_box->priv->toplevel, "button_press_event", - G_CALLBACK (gal_combo_box_button_press), combo_box); - g_signal_connect (combo_box->priv->toplevel, "key_press_event", - G_CALLBACK (gal_combo_box_key_press), combo_box); -} - -E_MAKE_TYPE (gal_combo_box, - "MyGalComboBox", - GalComboBox, - gal_combo_box_class_init, - gal_combo_box_init, - PARENT_TYPE) - -/** - * gal_combo_box_set_display: - * @combo_box: the Combo Box to modify - * @display_widget: The widget to be displayed - - * Sets the displayed widget for the @combo_box to be @display_widget - */ -void -gal_combo_box_set_display (GalComboBox *combo_box, GtkWidget *display_widget) -{ - g_return_if_fail (combo_box != NULL); - g_return_if_fail (GAL_IS_COMBO_BOX (combo_box)); - g_return_if_fail (display_widget != NULL); - g_return_if_fail (GTK_IS_WIDGET (display_widget)); - - if (combo_box->priv->display_widget && - combo_box->priv->display_widget != display_widget) - gtk_container_remove (GTK_CONTAINER (combo_box), - combo_box->priv->display_widget); - - combo_box->priv->display_widget = display_widget; - - gtk_box_pack_start (GTK_BOX (combo_box), display_widget, TRUE, TRUE, 0); -} - -static gboolean -cb_tearable_enter_leave (GtkWidget *w, GdkEventCrossing *event, gpointer data) -{ - gboolean const flag = GPOINTER_TO_INT(data); - gtk_widget_set_state (w, flag ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL); - return FALSE; -} - -/** - * gtk_combo_popup_tear_off - * @combo: Combo box - * @set_position: Set to position of popup shell if true - * - * Tear off the popup - * - * FIXME: - * Gtk popup menus are toplevel windows, not dialogs. I think this is wrong, - * and make the popups dialogs. But may be there should be a way to make - * them toplevel. We can do this after creating: - * GTK_WINDOW (tearoff)->type = GTK_WINDOW_TOPLEVEL; - */ -static void -gtk_combo_popup_tear_off (GalComboBox *combo, gboolean set_position) -{ - int x, y; - - if (!combo->priv->tearoff_window) { - GtkWidget *tearoff; - gchar *title; - - /* FIXME: made this a toplevel, not a dialog ! */ - tearoff = gtk_window_new (GTK_WINDOW_TOPLEVEL); - g_object_ref_sink (tearoff); - combo->priv->tearoff_window = tearoff; - gtk_widget_set_app_paintable (tearoff, TRUE); - g_signal_connect (tearoff, "key_press_event", - G_CALLBACK (gal_combo_box_key_press), - combo); - gtk_widget_realize (tearoff); - title = g_object_get_data (G_OBJECT (combo), - "gtk-combo-title"); - if (title) - gdk_window_set_title (tearoff->window, title); - gtk_window_set_policy (GTK_WINDOW (tearoff), - FALSE, TRUE, FALSE); - gtk_window_set_transient_for - (GTK_WINDOW (tearoff), - GTK_WINDOW (gtk_widget_get_toplevel - GTK_WIDGET (combo))); - } - - if (GTK_WIDGET_VISIBLE (combo->priv->popup)) { - gtk_widget_hide (combo->priv->toplevel); - - gtk_grab_remove (combo->priv->toplevel); - gdk_pointer_ungrab (GDK_CURRENT_TIME); - } - - gtk_combo_popup_reparent (combo->priv->popup, - combo->priv->tearoff_window, FALSE); - - /* It may have got confused about size */ - gtk_widget_queue_resize (GTK_WIDGET (combo->priv->popup)); - - if (set_position) { - gal_combo_box_get_pos (combo, &x, &y); - gtk_widget_set_uposition (combo->priv->tearoff_window, x, y); - } - gtk_widget_show (GTK_WIDGET (combo->priv->popup)); - gtk_widget_show (combo->priv->tearoff_window); - -} - -/** - * gtk_combo_set_tearoff_state - * @combo_box: Combo box - * @torn_off: TRUE: Tear off. FALSE: Pop down and reattach - * - * Set the tearoff state of the popup - * - * Compare with gtk_menu_set_tearoff_state in gtk/gtkmenu.c - */ -static void -gtk_combo_set_tearoff_state (GalComboBox *combo, - gboolean torn_off) -{ - g_return_if_fail (combo != NULL); - g_return_if_fail (GAL_IS_COMBO_BOX (combo)); - - if (combo->priv->torn_off != torn_off) { - combo->priv->torn_off = torn_off; - - if (combo->priv->torn_off) { - gtk_combo_popup_tear_off (combo, TRUE); - deactivate_arrow (combo); - } else { - gtk_widget_hide (combo->priv->tearoff_window); - gtk_combo_popup_reparent (combo->priv->popup, - combo->priv->toplevel, - FALSE); - } - } -} - -/** - * gtk_combo_tearoff_bg_copy - * @combo_box: Combo box - * - * Copy popup window image to the tearoff window. - */ -static void -gtk_combo_tearoff_bg_copy (GalComboBox *combo) -{ - GdkPixmap *pixmap; - GdkGC *gc; - GdkGCValues gc_values; - - GtkWidget *widget = combo->priv->popup; - - if (combo->priv->torn_off) { - gc_values.subwindow_mode = GDK_INCLUDE_INFERIORS; - gc = gdk_gc_new_with_values (widget->window, - &gc_values, GDK_GC_SUBWINDOW); - - pixmap = gdk_pixmap_new (widget->window, - widget->allocation.width, - widget->allocation.height, - -1); - - gdk_draw_drawable (GDK_DRAWABLE (pixmap), gc, - widget->window, - 0, 0, 0, 0, -1, -1); - g_object_unref (gc); - - gtk_widget_set_size_request (combo->priv->tearoff_window, - widget->allocation.width, - widget->allocation.height); - - gdk_window_set_back_pixmap - (combo->priv->tearoff_window->window, pixmap, FALSE); - g_object_unref (pixmap); - } -} - -/** - * gtk_combo_popup_reparent - * @popup: Popup - * @new_parent: New parent - * @unrealize: Unrealize popup if TRUE. - * - * Reparent the popup, taking care of the refcounting - * - * Compare with gtk_menu_reparent in gtk/gtkmenu.c - */ -static void -gtk_combo_popup_reparent (GtkWidget *popup, - GtkWidget *new_parent, - gboolean unrealize) -{ - GObject *object = G_OBJECT (popup); - gboolean was_floating = g_object_is_floating (object); - - g_object_ref_sink (object); - - if (unrealize) { - g_object_ref (object); - gtk_container_remove (GTK_CONTAINER (popup->parent), popup); - gtk_container_add (GTK_CONTAINER (new_parent), popup); - g_object_unref (object); - } - else - gtk_widget_reparent (GTK_WIDGET (popup), new_parent); - gtk_widget_set_size_request (new_parent, -1, -1); - - if (was_floating) - g_object_force_floating (object); - else - g_object_unref (object); -} - -/** - * cb_tearable_button_release - * @w: Widget - * @event: Event - * @combo: Combo box - * - * Toggle tearoff state. - */ -static gboolean -cb_tearable_button_release (GtkWidget *w, GdkEventButton *event, - GalComboBox *combo) -{ - GtkTearoffMenuItem *tearable; - - g_return_val_if_fail (w != NULL, FALSE); - g_return_val_if_fail (GTK_IS_TEAROFF_MENU_ITEM (w), FALSE); - - tearable = GTK_TEAROFF_MENU_ITEM (w); - tearable->torn_off = !tearable->torn_off; - - if (!combo->priv->torn_off) { - gboolean need_connect; - - need_connect = (!combo->priv->tearoff_window); - gtk_combo_set_tearoff_state (combo, TRUE); - if (need_connect) - g_signal_connect (combo->priv->tearoff_window, - "delete_event", - G_CALLBACK (cb_popup_delete), - combo); - } else - gal_combo_box_popup_hide_unconditional (combo); - - return TRUE; -} - -static gboolean -cb_popup_delete (GtkWidget *w, GdkEventAny *event, GalComboBox *combo) -{ - gal_combo_box_popup_hide_unconditional (combo); - return TRUE; -} - -void -gal_combo_box_construct (GalComboBox *combo_box, GtkWidget *display_widget, GtkWidget *pop_down_widget) -{ - GtkWidget *tearable; - GtkWidget *vbox; - - g_return_if_fail (combo_box != NULL); - g_return_if_fail (GAL_IS_COMBO_BOX (combo_box)); - g_return_if_fail (display_widget != NULL); - g_return_if_fail (GTK_IS_WIDGET (display_widget)); - - GTK_BOX (combo_box)->spacing = 0; - GTK_BOX (combo_box)->homogeneous = FALSE; - - combo_box->priv->pop_down_widget = pop_down_widget; - combo_box->priv->display_widget = NULL; - - vbox = gtk_vbox_new (FALSE, 5); - tearable = gtk_tearoff_menu_item_new (); - g_signal_connect (tearable, "enter-notify-event", - G_CALLBACK (cb_tearable_enter_leave), - GINT_TO_POINTER (TRUE)); - g_signal_connect (tearable, "leave-notify-event", - G_CALLBACK (cb_tearable_enter_leave), - GINT_TO_POINTER (FALSE)); - g_signal_connect (tearable, "button-release-event", - G_CALLBACK (cb_tearable_button_release), - (gpointer) combo_box); - gtk_box_pack_start (GTK_BOX (vbox), tearable, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), pop_down_widget, TRUE, TRUE, 0); - combo_box->priv->tearable = tearable; - - /* - * Finish setup - */ - gal_combo_box_set_display (combo_box, display_widget); - - gtk_container_add (GTK_CONTAINER (combo_box->priv->frame), vbox); - gtk_widget_show_all (combo_box->priv->frame); -} - -GtkWidget * -gal_combo_box_new (GtkWidget *display_widget, GtkWidget *optional_popdown) -{ - GalComboBox *combo_box; - - g_return_val_if_fail (display_widget != NULL, NULL); - g_return_val_if_fail (GTK_IS_WIDGET (display_widget), NULL); - - combo_box = g_object_new (GAL_COMBO_BOX_TYPE, NULL); - gal_combo_box_construct (combo_box, display_widget, optional_popdown); - return GTK_WIDGET (combo_box); -} - -void -gal_combo_box_set_arrow_relief (GalComboBox *cc, GtkReliefStyle relief) -{ - g_return_if_fail (cc != NULL); - g_return_if_fail (GAL_IS_COMBO_BOX (cc)); - - gtk_button_set_relief (GTK_BUTTON (cc->priv->arrow_button), relief); -} - -/** - * gal_combo_box_set_title - * @combo: Combo box - * @title: Title - * - * Set a title to display over the tearoff window. - * - * FIXME: - * - * This should really change the title even when the popup is already torn off. - * I guess the tearoff window could attach a listener to title change or - * something. But I don't think we need the functionality, so I didn't bother - * to investigate. - */ -void -gal_combo_box_set_title (GalComboBox *combo, - const gchar *title) -{ - g_return_if_fail (combo != NULL); - g_return_if_fail (GAL_IS_COMBO_BOX (combo)); - - g_object_set_data_full (G_OBJECT (combo), "gtk-combo-title", - g_strdup (title), (GDestroyNotify) g_free); -} - -/** - * gal_combo_box_set_arrow_sensitive - * @combo: Combo box - * @sensitive: Sensitivity value - * - * Toggle the sensitivity of the arrow button - */ - -void -gal_combo_box_set_arrow_sensitive (GalComboBox *combo, - gboolean sensitive) -{ - g_return_if_fail (combo != NULL); - - gtk_widget_set_sensitive (combo->priv->arrow_button, sensitive); -} - -/** - * gal_combo_box_set_tearable: - * @combo: Combo box - * @tearable: whether to allow the @combo to be tearable - * - * controls whether the combo box's pop up widget can be torn off. - */ -void -gal_combo_box_set_tearable (GalComboBox *combo, gboolean tearable) -{ - g_return_if_fail (combo != NULL); - g_return_if_fail (GAL_IS_COMBO_BOX (combo)); - - if (tearable){ - gtk_widget_show (combo->priv->tearable); - } else { - gtk_combo_set_tearoff_state (combo, FALSE); - gtk_widget_hide (combo->priv->tearable); - } -} diff --git a/widgets/misc/gal-combo-box.h b/widgets/misc/gal-combo-box.h deleted file mode 100644 index 0a05c52d84..0000000000 --- a/widgets/misc/gal-combo-box.h +++ /dev/null @@ -1,91 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * gtk-combo-box.h - a customizable combobox - * Copyright 2000, 2001, Ximian, Inc. - * - * Authors: - * Miguel de Icaza <miguel@ximian.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. - * - * 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#ifndef _GAL_COMBO_BOX_H_ -#define _GAL_COMBO_BOX_H_ - -#include <gtk/gtkhbox.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#define GAL_COMBO_BOX_TYPE (gal_combo_box_get_type()) -#define GAL_COMBO_BOX(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, gal_combo_box_get_type (), GalComboBox) -#define GAL_COMBO_BOX_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, gal_combo_box_get_type (), GalComboBoxClass) -#define GAL_IS_COMBO_BOX(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, gal_combo_box_get_type ()) - -typedef struct _GalComboBox GalComboBox; -typedef struct _GalComboBoxPrivate GalComboBoxPrivate; -typedef struct _GalComboBoxClass GalComboBoxClass; - -struct _GalComboBox { - GtkHBox hbox; - GalComboBoxPrivate *priv; -}; - -struct _GalComboBoxClass { - GtkHBoxClass parent_class; - - GtkWidget *(*pop_down_widget) (GalComboBox *cbox); - - /* - * invoked when the popup has been hidden, if the signal - * returns TRUE, it means it should be killed from the - */ - gboolean *(*pop_down_done) (GalComboBox *cbox, GtkWidget *); - - /* - * Notification signals. - */ - void (*pre_pop_down) (GalComboBox *cbox); - void (*post_pop_hide) (GalComboBox *cbox); -}; - -GtkType gal_combo_box_get_type (void); -void gal_combo_box_construct (GalComboBox *combo_box, - GtkWidget *display_widget, - GtkWidget *optional_pop_down_widget); -void gal_combo_box_get_pos (GalComboBox *combo_box, int *x, int *y); - -GtkWidget *gal_combo_box_new (GtkWidget *display_widget, - GtkWidget *optional_pop_down_widget); -void gal_combo_box_popup_hide (GalComboBox *combo_box); - -void gal_combo_box_set_display (GalComboBox *combo_box, - GtkWidget *display_widget); - -void gal_combo_box_set_title (GalComboBox *combo, - const gchar *title); - -void gal_combo_box_set_tearable (GalComboBox *combo, - gboolean tearable); -void gal_combo_box_set_arrow_sensitive (GalComboBox *combo, - gboolean sensitive); -void gal_combo_box_set_arrow_relief (GalComboBox *cc, - GtkReliefStyle relief); -#ifdef __cplusplus -}; -#endif /* __cplusplus */ - -#endif /* _GAL_COMBO_BOX_H_ */ diff --git a/widgets/misc/gal-combo-text.c b/widgets/misc/gal-combo-text.c deleted file mode 100644 index fe75a7a353..0000000000 --- a/widgets/misc/gal-combo-text.c +++ /dev/null @@ -1,427 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * gtk-combo-text.c - A combo box for selecting from a list. - * Copyright 2000, 2001, Ximian, Inc. - * - * Authors: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. - * - * 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#include <config.h> - -#include <ctype.h> -#include <string.h> - -#include <gtk/gtk.h> - -#include "e-util/e-util.h" - -#include "gal-combo-text.h" - -#define PARENT_TYPE GAL_COMBO_BOX_TYPE -static GtkObjectClass *gal_combo_text_parent_class; - -static gboolean cb_pop_down (GtkWidget *w, GtkWidget *pop_down, - gpointer dummy); - -static void list_unselect_cb (GtkWidget *list, GtkWidget *child, - gpointer data); - -static void update_list_selection (GalComboText *ct, const gchar *text); - -static void -gal_combo_text_destroy (GtkObject *object) -{ - GalComboText *ct = GAL_COMBO_TEXT (object); - - if (ct->elements != NULL) { - g_hash_table_destroy (ct->elements); - ct->elements = NULL; - } - if (ct->list != NULL) { - g_signal_handlers_disconnect_matched (ct, - G_SIGNAL_MATCH_FUNC, - 0, 0, NULL, - cb_pop_down, NULL); - - g_signal_handlers_disconnect_matched (ct->list, - G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, - 0, 0, NULL, - list_unselect_cb, ct); - ct->list = NULL; - } - - (*gal_combo_text_parent_class->destroy) (object); -} - -static void -gal_combo_text_class_init (GtkObjectClass *object_class) -{ - object_class->destroy = &gal_combo_text_destroy; - gal_combo_text_parent_class = g_type_class_ref (PARENT_TYPE); -} - -static void -gal_combo_text_init (GalComboText *object) -{ -} - -E_MAKE_TYPE (gal_combo_text, - "GalComboText", - GalComboText, - gal_combo_text_class_init, - gal_combo_text_init, - PARENT_TYPE) - -static gint -strcase_equal (gconstpointer v, gconstpointer v2) -{ - return g_ascii_strcasecmp ((const gchar*) v, (const gchar*)v2) == 0; -} - -static guint -strcase_hash (gconstpointer v) -{ - const unsigned char *s = (const unsigned char *)v; - const unsigned char *p; - guint h = 0, g; - - for(p = s; *p != '\0'; p += 1) { - h = ( h << 4 ) + g_ascii_tolower (*p); - if ( ( g = h & 0xf0000000 ) ) { - h = h ^ (g >> 24); - h = h ^ g; - } - } - - return h; -} - -/** - * gal_combo_text_set_case_sensitive - * @combo_text: ComboText widget - * @val: make case sensitive if TRUE - * - * Specifies whether the text entered into the GtkEntry field and the text - * in the list items is case sensitive. Because the values are stored in a - * hash, it is not legal to change case sensitivity when the list contains - * elements. - * - * Returns: The function returns -1 if request could not be honored. On - * success, it returns 0. - */ -gint -gal_combo_text_set_case_sensitive (GalComboText *combo, gboolean val) -{ - if (combo->elements - && g_hash_table_size (combo->elements) > 0 - && val != combo->case_sensitive) - return -1; - else { - combo->case_sensitive = val; - if (val != combo->case_sensitive) { - GHashFunc hashfunc; - GCompareFunc comparefunc; - - g_hash_table_destroy (combo->elements); - if (combo->case_sensitive) { - hashfunc = g_str_hash; - comparefunc = g_str_equal; - } else { - hashfunc = strcase_hash; - comparefunc = strcase_equal; - } - combo->elements = g_hash_table_new (hashfunc, - comparefunc); - } - return 0; - } -} - -static void -entry_activate_cb (GtkWidget *entry, gpointer data) -{ - GalComboText *combo = GAL_COMBO_TEXT (data); - - update_list_selection (combo, - gtk_entry_get_text (GTK_ENTRY (combo->entry))); -} - - -static void -list_select_cb (GtkWidget *list, GtkWidget *child, gpointer data) -{ - GalComboText *combo = GAL_COMBO_TEXT (data); - GtkEntry *entry = GTK_ENTRY (combo->entry); - gchar *value = (gchar*) g_object_get_data (G_OBJECT (child), "value"); - - g_return_if_fail (entry && value); - - if (combo->cached_entry == child) - combo->cached_entry = NULL; - - gtk_entry_set_text (entry, value); - gtk_signal_handler_block_by_func (GTK_OBJECT (entry), - GTK_SIGNAL_FUNC (entry_activate_cb), - (gpointer) combo); - g_signal_emit_by_name (entry, "activate"); - gtk_signal_handler_unblock_by_func (GTK_OBJECT (entry), - GTK_SIGNAL_FUNC (entry_activate_cb), - (gpointer) combo); - - gal_combo_box_popup_hide (GAL_COMBO_BOX (data)); -} - -static void -list_unselect_cb (GtkWidget *list, GtkWidget *child, gpointer data) -{ - if (GTK_WIDGET_VISIBLE (list)) /* Undo interactive unselect */ - gtk_list_select_child (GTK_LIST (list), child); -} - -static void -cb_toggle (GtkWidget *child, gpointer data) -{ - GalComboText *ct = GAL_COMBO_TEXT (data); - - gtk_list_select_child (GTK_LIST (ct->list), child); -} - -void -gal_combo_text_select_item (GalComboText *ct, int elem) -{ - gtk_list_select_item (GTK_LIST(ct->list), elem); -} - -static void -update_list_selection (GalComboText *ct, const gchar *text) -{ - gpointer candidate; - GtkWidget *child; - - gtk_signal_handler_block_by_func (GTK_OBJECT (ct->list), - GTK_SIGNAL_FUNC (list_select_cb), - (gpointer) ct); - gtk_signal_handler_block_by_func (GTK_OBJECT (ct->list), - GTK_SIGNAL_FUNC (list_unselect_cb), - (gpointer) ct); - - gtk_list_unselect_all (GTK_LIST (ct->list)); - candidate = g_hash_table_lookup (ct->elements, (gconstpointer) text); - if (candidate && GTK_IS_WIDGET (candidate)) { - child = GTK_WIDGET (candidate); - gtk_list_select_child (GTK_LIST (ct->list), child); - gtk_widget_grab_focus (child); - } - gtk_signal_handler_unblock_by_func (GTK_OBJECT (ct->list), - GTK_SIGNAL_FUNC (list_select_cb), - (gpointer) ct); - gtk_signal_handler_unblock_by_func (GTK_OBJECT (ct->list), - GTK_SIGNAL_FUNC (list_unselect_cb), - (gpointer) ct); -} - -void -gal_combo_text_set_text (GalComboText *ct, const gchar *text) -{ - gtk_entry_set_text (GTK_ENTRY (ct->entry), text); - update_list_selection (ct, text); -} - -/* - * We can't just cache the old widget state on entry: If the pointer is - * dragged, we receive two enter-notify-events, and the original cached - * value would be overwritten with the GTK_STATE_ACTIVE we just set. - * - * However, we know that the gtklist only uses GTK_STATE_SELECTED and - * GTK_STATE_NORMAL. We're OK if we only cache those two. - */ -static gboolean -cb_enter (GtkWidget *w, GdkEventCrossing *event, - gpointer user) -{ - GalComboText *ct = user; - GtkStateType state = GTK_WIDGET_STATE (w); - - if (state == GTK_STATE_NORMAL || state == GTK_STATE_SELECTED) { - ct->cached_entry = w; - ct->cache_mouse_state = state; - } - if (state != GTK_STATE_SELECTED) - gtk_widget_set_state (w, GTK_STATE_ACTIVE); - - return TRUE; -} -static gboolean -cb_exit (GtkWidget *w, GdkEventCrossing *event, - gpointer user) -{ - GalComboText *ct = user; - - if (ct->cached_entry == w) - gtk_widget_set_state (w, ct->cache_mouse_state); - - return TRUE; -} - -static gboolean -cb_pop_down (GtkWidget *w, GtkWidget *pop_down, gpointer dummy) -{ - GalComboText *ct = GAL_COMBO_TEXT (w); - - if (ct->cached_entry) - gtk_widget_set_state (ct->cached_entry, ct->cache_mouse_state); - ct->cached_entry = NULL; - - return FALSE; -} - -typedef struct { - GalComboText *ct; - gchar *value; -} WeakRefClosure; - -static void -cb_remove_from_hash (gpointer data, GObject *where_object_was) -{ - WeakRefClosure *closure = data; - - if (closure->ct->elements) - g_hash_table_remove (closure->ct->elements, closure->value); - - g_free (closure->value); - g_free (closure); -} - -void -gal_combo_text_add_item (GalComboText *ct, - const gchar *item, - const gchar *value) -{ - WeakRefClosure *weak_ref_closure; - GtkWidget *listitem; - gchar *value_copy; - - g_return_if_fail (item); - - if (!value) - value = item; - - value_copy = g_strdup (value); - - listitem = gtk_list_item_new_with_label (item); - gtk_widget_show (listitem); - - g_object_set_data_full (G_OBJECT (listitem), "value", - value_copy, g_free); - g_signal_connect (listitem, "enter-notify-event", - G_CALLBACK (cb_enter), - (gpointer) ct); - g_signal_connect (listitem, "leave-notify-event", - G_CALLBACK (cb_exit), - (gpointer) ct); - g_signal_connect (listitem, "toggle", - G_CALLBACK (cb_toggle), - (gpointer) ct); - - gtk_container_add (GTK_CONTAINER (ct->list), - listitem); - - g_hash_table_insert (ct->elements, (gpointer)value_copy, - (gpointer) listitem); - - weak_ref_closure = g_new (WeakRefClosure, 1); - weak_ref_closure->ct = ct; - weak_ref_closure->value = g_strdup (value_copy); - - g_object_weak_ref (G_OBJECT (listitem), - cb_remove_from_hash, - weak_ref_closure); -} - -static void -cb_list_mapped (GtkWidget *widget, gpointer user_data) -{ - GtkList *list = GTK_LIST (widget); - - if (g_list_length (list->selection) > 0) - gtk_widget_grab_focus (GTK_WIDGET ((list->selection->data))); -} - -void -gal_combo_text_construct (GalComboText *ct, gboolean const is_scrolled) -{ - GtkWidget *entry, *list, *scroll, *display_widget; - - ct->case_sensitive = FALSE; - ct->elements = g_hash_table_new (&strcase_hash, - &strcase_equal); - - /* Probably irrelevant, but lets be careful */ - ct->cache_mouse_state = GTK_STATE_NORMAL; - ct->cached_entry = NULL; - - entry = ct->entry = gtk_entry_new (); - list = ct->list = gtk_list_new (); - if (is_scrolled) { - display_widget = scroll = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(scroll), - GTK_POLICY_NEVER, - GTK_POLICY_AUTOMATIC); - - gtk_scrolled_window_add_with_viewport ( - GTK_SCROLLED_WINDOW(scroll), list); - gtk_container_set_focus_hadjustment ( - GTK_CONTAINER (list), - gtk_scrolled_window_get_hadjustment ( - GTK_SCROLLED_WINDOW (scroll))); - gtk_container_set_focus_vadjustment ( - GTK_CONTAINER (list), - gtk_scrolled_window_get_vadjustment ( - GTK_SCROLLED_WINDOW (scroll))); - gtk_widget_set_size_request (scroll, 0, 200); /* MAGIC NUMBER */ - } else - display_widget = list; - - g_signal_connect (entry, "activate", - G_CALLBACK (entry_activate_cb), - ct); - g_signal_connect (list, "select-child", - G_CALLBACK (list_select_cb), - ct); - g_signal_connect (list, "unselect-child", - G_CALLBACK (list_unselect_cb), - ct); - g_signal_connect (list, "map", - G_CALLBACK (cb_list_mapped), NULL); - - gtk_widget_show (display_widget); - gtk_widget_show (entry); - gal_combo_box_construct (GAL_COMBO_BOX (ct), entry, display_widget); - g_signal_connect (ct, "pop_down_done", - G_CALLBACK (cb_pop_down), NULL); -} - -GtkWidget* -gal_combo_text_new (gboolean const is_scrolled) -{ - GalComboText *ct; - - ct = g_object_new (GAL_COMBO_TEXT_TYPE, NULL); - gal_combo_text_construct (ct, is_scrolled); - return GTK_WIDGET (ct); -} - diff --git a/widgets/misc/gal-combo-text.h b/widgets/misc/gal-combo-text.h deleted file mode 100644 index 82580b6f6e..0000000000 --- a/widgets/misc/gal-combo-text.h +++ /dev/null @@ -1,76 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * gal-combo-text.h - A combo box for selecting from a list. - * Copyright 2000, 2001, Ximian, Inc. - * - * Authors: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License, version 2, as published by the Free Software Foundation. - * - * 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - */ - -#ifndef _GAL_COMBO_TEXT_H -#define _GAL_COMBO_TEXT_H - -#include <misc/gal-combo-box.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#define GAL_COMBO_TEXT_TYPE (gal_combo_text_get_type ()) -#define GAL_COMBO_TEXT(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, gal_combo_text_get_type (), GalComboText) -#define GAL_COMBO_TEXT_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, gal_combo_text_get_type (), GalComboTextClass) -#define GAL_IS_COMBO_TEXT(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, gal_combo_text_get_type ()) - -typedef struct _GalComboText GalComboText; -/* typedef struct _GalComboTextPrivate GalComboTextPrivate;*/ -typedef struct _GalComboTextClass GalComboTextClass; - -struct _GalComboText { - GalComboBox parent; - - GtkWidget *entry; - GtkWidget *list; - GtkWidget *scrolled_window; - GtkStateType cache_mouse_state; - GtkWidget *cached_entry; - gboolean case_sensitive; - GHashTable*elements; -}; - -struct _GalComboTextClass { - GalComboBoxClass parent_class; -}; - - -GtkType gal_combo_text_get_type (void); -GtkWidget *gal_combo_text_new (gboolean const is_scrolled); -void gal_combo_text_construct (GalComboText *ct, gboolean const is_scrolled); - -gint gal_combo_text_set_case_sensitive (GalComboText *combo_text, - gboolean val); -void gal_combo_text_select_item (GalComboText *combo_text, - int elem); -void gal_combo_text_set_text (GalComboText *combo_text, - const gchar *text); -void gal_combo_text_add_item (GalComboText *combo_text, - const gchar *item, - const gchar *value); - -#ifdef __cplusplus -}; -#endif /* __cplusplus */ - -#endif diff --git a/widgets/table/ChangeLog b/widgets/table/ChangeLog index 26a08a0676..53b477ac83 100644 --- a/widgets/table/ChangeLog +++ b/widgets/table/ChangeLog @@ -1,3 +1,9 @@ +2007-05-25 Matthew Barnes <mbarnes@redhat.com> + + * e-table-config.c: + * e-table-config.h: + Replace GalComboText with a GtkComboBox/GtkListStore (#441010). + 2007-05-17 Srinivasa Ragavan <sragavan@novell.com> ** Add more support for GMail like sorting. diff --git a/widgets/table/e-table-config.c b/widgets/table/e-table-config.c index 7af4a8fb00..289007ba21 100644 --- a/widgets/table/e-table-config.c +++ b/widgets/table/e-table-config.c @@ -57,6 +57,11 @@ enum { PROP_STATE, }; +enum { + COLUMN_ITEM, + COLUMN_VALUE +}; + static guint e_table_config_signals [LAST_SIGNAL] = { 0, }; static void @@ -154,6 +159,81 @@ config_class_init (GObjectClass *object_class) glade_init (); } +static void +configure_combo_box_add (GtkComboBox *combo_box, const gchar *item, + const gchar *value) +{ + GtkTreeRowReference *reference; + GtkTreeModel *model; + GtkTreePath *path; + GHashTable *index; + GtkTreeIter iter; + + model = gtk_combo_box_get_model (combo_box); + gtk_list_store_append (GTK_LIST_STORE (model), &iter); + + gtk_list_store_set ( + GTK_LIST_STORE (model), &iter, + COLUMN_ITEM, item, COLUMN_VALUE, value, -1); + + index = g_object_get_data (G_OBJECT (combo_box), "index"); + g_assert (index != NULL); + + /* Add an entry to the tree model index. */ + path = gtk_tree_model_get_path (model, &iter); + reference = gtk_tree_row_reference_new (model, path); + g_assert (reference != NULL); + g_hash_table_insert (index, g_strdup (value), reference); + gtk_tree_path_free (path); +} + +static gchar * +configure_combo_box_get_active (GtkComboBox *combo_box) +{ + GtkTreeIter iter; + gchar *value = NULL; + + if (gtk_combo_box_get_active_iter (combo_box, &iter)) + gtk_tree_model_get ( + gtk_combo_box_get_model (combo_box), &iter, + COLUMN_VALUE, &value, -1); + + if (value != NULL && *value == '\0') { + g_free (value); + value = NULL; + } + + return value; +} + +static void +configure_combo_box_set_active (GtkComboBox *combo_box, const gchar *value) +{ + GtkTreeRowReference *reference; + GHashTable *index; + + index = g_object_get_data (G_OBJECT (combo_box), "index"); + g_assert (index != NULL); + + reference = g_hash_table_lookup (index, value); + if (reference != NULL) { + GtkTreeModel *model; + GtkTreePath *path; + GtkTreeIter iter; + + model = gtk_tree_row_reference_get_model (reference); + path = gtk_tree_row_reference_get_path (reference); + + if (path == NULL) + return; + + if (gtk_tree_model_get_iter (model, &iter, path)) + gtk_combo_box_set_active_iter (combo_box, &iter); + + gtk_tree_path_free (path); + } +} + static ETableColumnSpecification * find_column_in_spec (ETableSpecification *spec, int model_col) { @@ -215,7 +295,7 @@ update_sort_and_group_config_dialog (ETableConfig *config, gboolean is_sort) widgets [i].radio_ascending, widgets [i].toggled_id); g_signal_handler_block ( - widgets [i].combo->entry, + widgets [i].combo, widgets [i].changed_id); if (i < count){ @@ -242,7 +322,7 @@ update_sort_and_group_config_dialog (ETableConfig *config, gboolean is_sort) continue; } - text = dgettext (config->domain, column->title); + text = column->title; /* * Update radio buttons @@ -267,13 +347,14 @@ update_sort_and_group_config_dialog (ETableConfig *config, gboolean is_sort) } /* Set the text */ - gal_combo_text_set_text (widgets [i].combo, text); + configure_combo_box_set_active ( + GTK_COMBO_BOX (widgets[i].combo), text); g_signal_handler_unblock ( widgets [i].radio_ascending, widgets [i].toggled_id); g_signal_handler_unblock ( - widgets [i].combo->entry, + widgets [i].combo, widgets [i].changed_id); } } @@ -631,7 +712,30 @@ GtkWidget *e_table_proxy_gtk_combo_text_new (void); GtkWidget * e_table_proxy_gtk_combo_text_new (void) { - return gal_combo_text_new (TRUE); + GtkCellRenderer *renderer; + GtkListStore *store; + GtkWidget *combo_box; + GHashTable *index; + + store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING); + combo_box = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store)); + + renderer = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start ( + GTK_CELL_LAYOUT (combo_box), renderer, FALSE); + gtk_cell_layout_add_attribute ( + GTK_CELL_LAYOUT (combo_box), renderer, "text", COLUMN_ITEM); + + /* Embed a reverse-lookup index into the widget. */ + index = g_hash_table_new_full ( + g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) gtk_tree_row_reference_free); + g_object_set_data_full ( + G_OBJECT (combo_box), "index", index, + (GDestroyNotify) g_hash_table_destroy); + + return combo_box; } #if 0 @@ -669,22 +773,24 @@ get_source_model_col_index (ETableConfig *config, gint idx) } static void -sort_entry_changed (GtkEntry *entry, ETableConfigSortWidgets *sort) +sort_combo_changed (GtkComboBox *combo_box, ETableConfigSortWidgets *sort) { ETableConfig *config = sort->e_table_config; ETableSortInfo *sort_info = config->temp_state->sort_info; ETableConfigSortWidgets *base = &config->sort[0]; int idx = sort - base; - - const char *s = gtk_entry_get_text (entry); + gchar *s; + + s = configure_combo_box_get_active (combo_box); - if (s && s [0] && g_hash_table_lookup (sort->combo->elements, s)){ + if (s != NULL) { ETableSortColumn c; int col; col = find_model_column_by_name (config->source_spec, s); if (col == -1){ g_warning ("sort: This should not happen (%s)", s); + g_free (s); return; } @@ -698,6 +804,8 @@ sort_entry_changed (GtkEntry *entry, ETableConfigSortWidgets *sort) e_table_sort_info_sorting_truncate (sort_info, idx); update_sort_and_group_config_dialog (config, TRUE); } + + g_free (s); } static void @@ -724,10 +832,10 @@ configure_sort_dialog (ETableConfig *config, GladeXML *gui) char buffer [80]; snprintf (buffer, sizeof (buffer), "sort-combo-%d", i + 1); - config->sort [i].combo = GAL_COMBO_TEXT ( - glade_xml_get_widget (gui, buffer)); + config->sort [i].combo = glade_xml_get_widget (gui, buffer); gtk_widget_show (GTK_WIDGET (config->sort [i].combo)); - gal_combo_text_add_item (config->sort [i].combo, "", ""); + configure_combo_box_add ( + GTK_COMBO_BOX (config->sort[i].combo), "", ""); snprintf (buffer, sizeof (buffer), "frame-sort-%d", i + 1); config->sort [i].frames = @@ -752,8 +860,9 @@ configure_sort_dialog (ETableConfig *config, GladeXML *gui) char *label = l->data; for (i = 0; i < 4; i++){ - gal_combo_text_add_item (config->sort [i].combo, - dgettext (config->domain, label), label); + configure_combo_box_add ( + GTK_COMBO_BOX (config->sort[i].combo), + dgettext (config->domain, label), label); } } @@ -762,8 +871,8 @@ configure_sort_dialog (ETableConfig *config, GladeXML *gui) */ for (i = 0; i < 4; i++){ config->sort [i].changed_id = g_signal_connect ( - config->sort [i].combo->entry, - "changed", G_CALLBACK (sort_entry_changed), + config->sort [i].combo, + "changed", G_CALLBACK (sort_combo_changed), &config->sort [i]); config->sort [i].toggled_id = g_signal_connect ( @@ -774,21 +883,24 @@ configure_sort_dialog (ETableConfig *config, GladeXML *gui) } static void -group_entry_changed (GtkEntry *entry, ETableConfigSortWidgets *group) +group_combo_changed (GtkComboBox *combo_box, ETableConfigSortWidgets *group) { ETableConfig *config = group->e_table_config; ETableSortInfo *sort_info = config->temp_state->sort_info; ETableConfigSortWidgets *base = &config->group[0]; int idx = group - base; - const char *s = gtk_entry_get_text (entry); + gchar *s; - if (s && s [0] && g_hash_table_lookup (group->combo->elements, s)){ + s = configure_combo_box_get_active (combo_box); + + if (s != NULL) { ETableSortColumn c; int col; col = find_model_column_by_name (config->source_spec, s); if (col == -1){ g_warning ("grouping: this should not happen, %s", s); + g_free (s); return; } @@ -802,6 +914,8 @@ group_entry_changed (GtkEntry *entry, ETableConfigSortWidgets *group) e_table_sort_info_grouping_truncate (sort_info, idx); update_sort_and_group_config_dialog (config, FALSE); } + + g_free (s); } static void @@ -828,11 +942,11 @@ configure_group_dialog (ETableConfig *config, GladeXML *gui) char buffer [80]; snprintf (buffer, sizeof (buffer), "group-combo-%d", i + 1); - config->group [i].combo = GAL_COMBO_TEXT ( - glade_xml_get_widget (gui, buffer)); + config->group [i].combo = glade_xml_get_widget (gui, buffer); gtk_widget_show (GTK_WIDGET (config->group [i].combo)); - gal_combo_text_add_item (config->group [i].combo, "", ""); + configure_combo_box_add ( + GTK_COMBO_BOX (config->group[i].combo), "", ""); snprintf (buffer, sizeof (buffer), "frame-group-%d", i + 1); config->group [i].frames = @@ -864,8 +978,8 @@ configure_group_dialog (ETableConfig *config, GladeXML *gui) char *label = l->data; for (i = 0; i < 4; i++){ - gal_combo_text_add_item ( - config->group [i].combo, + configure_combo_box_add ( + GTK_COMBO_BOX (config->group[i].combo), dgettext (config->domain, label), label); } } @@ -875,8 +989,8 @@ configure_group_dialog (ETableConfig *config, GladeXML *gui) */ for (i = 0; i < 4; i++){ config->group [i].changed_id = g_signal_connect ( - config->group [i].combo->entry, - "changed", G_CALLBACK (group_entry_changed), + config->group [i].combo, + "changed", G_CALLBACK (group_combo_changed), &config->group [i]); config->group [i].toggled_id = g_signal_connect ( diff --git a/widgets/table/e-table-config.h b/widgets/table/e-table-config.h index 73fdcf4e01..d1ba54447e 100644 --- a/widgets/table/e-table-config.h +++ b/widgets/table/e-table-config.h @@ -27,7 +27,6 @@ #include <table/e-table-sort-info.h> #include <table/e-table-specification.h> -#include <misc/gal-combo-text.h> #include <table/e-table-without.h> #include <table/e-table-subset-variable.h> #include <table/e-table.h> @@ -43,7 +42,7 @@ G_BEGIN_DECLS #define E_TABLE_CONFIG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), E_TABLE_CONFIG_TYPE, ETableConfigClass)) typedef struct { - GalComboText *combo; + GtkWidget *combo; GtkWidget *frames; GtkWidget *radio_ascending; GtkWidget *radio_descending; |