diff options
-rw-r--r-- | addressbook/ChangeLog | 6 | ||||
-rw-r--r-- | addressbook/gui/component/addressbook.c | 14 | ||||
-rw-r--r-- | calendar/ChangeLog | 5 | ||||
-rw-r--r-- | calendar/gui/cal-search-bar.c | 12 | ||||
-rw-r--r-- | composer/ChangeLog | 5 | ||||
-rw-r--r-- | composer/e-msg-composer-hdrs.c | 5 | ||||
-rw-r--r-- | filter/libfilter-i18n.h | 36 | ||||
-rw-r--r-- | mail/ChangeLog | 4 | ||||
-rw-r--r-- | mail/folder-browser.c | 4 | ||||
-rw-r--r-- | widgets/misc/ChangeLog | 14 | ||||
-rw-r--r-- | widgets/misc/e-filter-bar.c | 6 | ||||
-rw-r--r-- | widgets/misc/e-filter-bar.h | 8 | ||||
-rw-r--r-- | widgets/misc/e-search-bar.c | 265 | ||||
-rw-r--r-- | widgets/misc/e-search-bar.h | 18 |
14 files changed, 333 insertions, 69 deletions
diff --git a/addressbook/ChangeLog b/addressbook/ChangeLog index 58fe5ea77e..7f1ba40654 100644 --- a/addressbook/ChangeLog +++ b/addressbook/ChangeLog @@ -1,3 +1,8 @@ +2001-08-10 Jon Trowbridge <trow@ximian.com> + + * gui/component/addressbook.c: Set the ESearchBarItem + subitems explicitly to NULL. + 2001-08-10 Anna Marie Dirks <anna@ximian.com> * gui/component/select-names/select-names.glade: did a little packing-magic to get the two tables at bottom of this dialog @@ -6,7 +11,6 @@ *gui/component/select-names/e-select-names.c: changed the title of this dialog to "Select Contacts from Addressbook". - 2001-08-09 Anna Marie Dirks <anna@ximian.com> * gui/component/select-names/select-names.glade: redesigned this dialog to fix bug #6815. diff --git a/addressbook/gui/component/addressbook.c b/addressbook/gui/component/addressbook.c index b629bdcf2e..c04a3218a1 100644 --- a/addressbook/gui/component/addressbook.c +++ b/addressbook/gui/component/addressbook.c @@ -612,7 +612,7 @@ set_prop (BonoboPropertyBag *bag, static ESearchBarItem addressbook_search_menu_items[] = { E_FILTERBAR_RESET, - { NULL, -1 }, + { NULL, -1, NULL }, }; static void @@ -634,12 +634,12 @@ enum { }; static ESearchBarItem addressbook_search_option_items[] = { - { N_("Any field contains"), ESB_ANY }, - { N_("Name contains"), ESB_FULL_NAME }, - { N_("Email contains"), ESB_EMAIL }, - { N_("Category contains"), ESB_CATEGORY }, - { N_("Advanced..."), ESB_ADVANCED }, - { NULL, -1 } + { N_("Any field contains"), ESB_ANY, NULL }, + { N_("Name contains"), ESB_FULL_NAME, NULL }, + { N_("Email contains"), ESB_EMAIL, NULL }, + { N_("Category contains"), ESB_CATEGORY, NULL }, + { N_("Advanced..."), ESB_ADVANCED, NULL }, + { NULL, -1, NULL } }; static void diff --git a/calendar/ChangeLog b/calendar/ChangeLog index f443f2c029..fccc526224 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,8 @@ +2001-08-10 Jon Trowbridge <trow@ximian.com> + + * gui/cal-search-bar.c: Where we have ESearchBarItems, set their + subitems to NULL. + 2001-08-09 Damon Chaplin <damon@ximian.com> * pcs/cal-backend.c (cal_backend_get_object_component): added new diff --git a/calendar/gui/cal-search-bar.c b/calendar/gui/cal-search-bar.c index 5ffbfcdb82..f02528a8eb 100644 --- a/calendar/gui/cal-search-bar.c +++ b/calendar/gui/cal-search-bar.c @@ -39,7 +39,7 @@ /* Menu items for the ESearchBar */ static ESearchBarItem search_menu_items[] = { E_FILTERBAR_RESET, - { NULL, -1 } + { NULL, -1, NULL } }; /* IDs and option items for the ESearchBar */ @@ -51,11 +51,11 @@ enum { }; static ESearchBarItem search_option_items[] = { - { N_("Any field contains"), SEARCH_ANY_FIELD_CONTAINS }, - { N_("Summary contains"), SEARCH_SUMMARY_CONTAINS }, - { N_("Description contains"), SEARCH_DESCRIPTION_CONTAINS }, - { N_("Comment contains"), SEARCH_COMMENT_CONTAINS }, - { NULL, -1 } + { N_("Any field contains"), SEARCH_ANY_FIELD_CONTAINS, NULL }, + { N_("Summary contains"), SEARCH_SUMMARY_CONTAINS, NULL }, + { N_("Description contains"), SEARCH_DESCRIPTION_CONTAINS, NULL }, + { N_("Comment contains"), SEARCH_COMMENT_CONTAINS, NULL }, + { NULL, -1, NULL } }; /* Private part of the CalSearchBar structure */ diff --git a/composer/ChangeLog b/composer/ChangeLog index 850f605303..5286653640 100644 --- a/composer/ChangeLog +++ b/composer/ChangeLog @@ -1,3 +1,8 @@ +2001-08-10 Jon Trowbridge <trow@ximian.com> + + * e-msg-composer-hdrs.c (set_recipients): Removed comment about + the need to resolve nicknames properly, because we now do that. + 2001-08-09 Radek Doulik <rodo@ximian.com> * e-msg-composer.c (set_focus_to_editor): new helper function, diff --git a/composer/e-msg-composer-hdrs.c b/composer/e-msg-composer-hdrs.c index 916d8014c0..fcc99e0806 100644 --- a/composer/e-msg-composer-hdrs.c +++ b/composer/e-msg-composer-hdrs.c @@ -644,6 +644,8 @@ set_recipients (CamelMimeMessage *msg, GtkWidget *entry_widget, const gchar *typ if (destv) { dest_str = e_destination_get_address_textv (destv); + + g_message ("dest_str=[%s]", dest_str); /* dest_str has been utf8 encoded 2x by this point...not good */ @@ -651,9 +653,6 @@ set_recipients (CamelMimeMessage *msg, GtkWidget *entry_widget, const gchar *typ addr = camel_internet_address_new (); camel_address_unformat (CAMEL_ADDRESS (addr), dest_str); - /* TODO: In here, we could cross-reference the names with an alias book - or address book, it should be sufficient for unformat to do the parsing too */ - camel_mime_message_set_recipients (msg, type, addr); camel_object_unref (CAMEL_OBJECT (addr)); diff --git a/filter/libfilter-i18n.h b/filter/libfilter-i18n.h index d3cc5cbb36..175eac2dc6 100644 --- a/filter/libfilter-i18n.h +++ b/filter/libfilter-i18n.h @@ -1,39 +1,23 @@ /* Automatically generated. Do not edit. */ -char *s = N_("after"); char *s = N_("Assign Color"); char *s = N_("Assign Score"); char *s = N_("Attachments"); -char *s = N_("before"); -char *s = N_("contains"); char *s = N_("Copy to Folder"); char *s = N_("Date received"); char *s = N_("Date sent"); char *s = N_("Delete"); char *s = N_("Deleted"); -char *s = N_("does not contain"); -char *s = N_("does not end with"); -char *s = N_("does not exist"); -char *s = N_("does not sound like"); -char *s = N_("does not start with"); char *s = N_("Do Not Exist"); char *s = N_("Draft"); -char *s = N_("ends with"); char *s = N_("Exist"); -char *s = N_("exists"); char *s = N_("Expression"); char *s = N_("Important"); -char *s = N_("is"); -char *s = N_("is greater than"); -char *s = N_("is less than"); -char *s = N_("is not"); char *s = N_("Mailing list"); char *s = N_("Message Body"); char *s = N_("Message Header"); char *s = N_("Message was received"); char *s = N_("Message was sent"); char *s = N_("Move to Folder"); -char *s = N_("on or after"); -char *s = N_("on or before"); char *s = N_("Read"); char *s = N_("Recipients"); char *s = N_("Regex Match"); @@ -42,12 +26,28 @@ char *s = N_("Score"); char *s = N_("Sender"); char *s = N_("Set Status"); char *s = N_("Size (kB)"); -char *s = N_("sounds like"); char *s = N_("Source Account"); char *s = N_("Specific header"); -char *s = N_("starts with"); char *s = N_("Status"); char *s = N_("Stop Processing"); char *s = N_("Subject"); +char *s = N_("after"); +char *s = N_("before"); +char *s = N_("contains"); +char *s = N_("does not contain"); +char *s = N_("does not end with"); +char *s = N_("does not exist"); +char *s = N_("does not sound like"); +char *s = N_("does not start with"); +char *s = N_("ends with"); +char *s = N_("exists"); +char *s = N_("is greater than"); +char *s = N_("is less than"); +char *s = N_("is not"); +char *s = N_("is"); +char *s = N_("on or after"); +char *s = N_("on or before"); +char *s = N_("sounds like"); +char *s = N_("starts with"); char *s = N_("was after"); char *s = N_("was before"); diff --git a/mail/ChangeLog b/mail/ChangeLog index 96f4b98a7b..0ee860f98a 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,7 @@ +2001-08-10 Jon Trowbridge <trow@ximian.com> + + * folder-browser.c: Set our ESearchBarItems subitems to NULL. + 2001-08-10 Jeffrey Stedfast <fejj@ximian.com> * mail-callbacks.c (transfer_msg): Prepend the uri with evolution: diff --git a/mail/folder-browser.c b/mail/folder-browser.c index df1539c72c..217f9aff2f 100644 --- a/mail/folder-browser.c +++ b/mail/folder-browser.c @@ -897,9 +897,9 @@ enum { static ESearchBarItem folder_browser_search_menu_items[] = { E_FILTERBAR_RESET, E_FILTERBAR_SAVE, - { N_("Create vFolder from Search"), ESB_SAVE }, + { N_("Create vFolder from Search"), ESB_SAVE, NULL }, E_FILTERBAR_EDIT, - { NULL, -1 } + { NULL, -1, NULL } }; static void diff --git a/widgets/misc/ChangeLog b/widgets/misc/ChangeLog index a4a4c01e45..12b2d6dd29 100644 --- a/widgets/misc/ChangeLog +++ b/widgets/misc/ChangeLog @@ -1,3 +1,17 @@ +2001-08-10 Jon Trowbridge <trow@ximian.com> + + * e-filter-bar.h: Set the subitems to NULL in the pre-defined + ESearchBarItems. + + * e-filter-bar.c (rule_editor_clicked): Set the ESearchBarItem's + subitems to NULL. + (build_items): Set the ESearchBarItem's subitems to NULL. + (e_filter_bar_new): Set the ESearchBarItem's subitems to NULL. + + * e-search-bar.c: Added support for subitems, so that a search + option can key off of another option menu rather than just an + entry. + 2001-08-10 Jeffrey Stedfast <fejj@ximian.com> * e-search-bar.c (impl_destroy): Don't forget to unref stuff here diff --git a/widgets/misc/e-filter-bar.c b/widgets/misc/e-filter-bar.c index 42ec5279e0..80fcc0b3f7 100644 --- a/widgets/misc/e-filter-bar.c +++ b/widgets/misc/e-filter-bar.c @@ -97,6 +97,7 @@ rule_editor_clicked (GtkWidget *dialog, int button, void *data) item.text = rule->name; item.id = efb->menu_base + efb->menu_rules->len; + item.subitems = NULL; g_ptr_array_add (efb->menu_rules, rule); @@ -303,6 +304,7 @@ build_items (ESearchBar *esb, ESearchBarItem *items, int type, int *start, GPtrA /* and add ours */ item.id = 0; item.text = NULL; + item.subitems = NULL; g_array_append_vals (menu, &item, 1); source = FILTER_SOURCE_INCOMING; } else { @@ -312,6 +314,7 @@ build_items (ESearchBar *esb, ESearchBarItem *items, int type, int *start, GPtrA while ((rule = rule_context_next_rule (efb->context, rule, source))) { item.id = id++; item.text = rule->name; + item.subitems = NULL; g_array_append_vals (menu, &item, 1); g_ptr_array_add (rules, rule); } @@ -324,6 +327,7 @@ build_items (ESearchBar *esb, ESearchBarItem *items, int type, int *start, GPtrA item.id = -1; item.text = NULL; + item.subitems = NULL; g_array_append_vals (menu, &item, 1); return menu; @@ -455,7 +459,7 @@ e_filter_bar_new (RuleContext *context, const char *systemrules, const char *use EFilterBarConfigRule config, void *data) { EFilterBar *bar; - ESearchBarItem item = { NULL, -1 }; + ESearchBarItem item = { NULL, -1, NULL }; bar = gtk_type_new (e_filter_bar_get_type ()); diff --git a/widgets/misc/e-filter-bar.h b/widgets/misc/e-filter-bar.h index bd91362c3c..87cecf2488 100644 --- a/widgets/misc/e-filter-bar.h +++ b/widgets/misc/e-filter-bar.h @@ -91,10 +91,10 @@ enum { E_FILTERBAR_LAST_ID = -6, }; -#define E_FILTERBAR_SAVE { N_("Add to Saved Searches"), E_FILTERBAR_SAVE_ID } -#define E_FILTERBAR_RESET { N_("Clear"), E_FILTERBAR_RESET_ID } -#define E_FILTERBAR_EDIT { N_("Edit..."), E_FILTERBAR_EDIT_ID } -#define E_FILTERBAR_ADVANCED { N_("Advanced..."), E_FILTERBAR_ADVANCED_ID } +#define E_FILTERBAR_SAVE { N_("Add to Saved Searches"), E_FILTERBAR_SAVE_ID, NULL } +#define E_FILTERBAR_RESET { N_("Clear"), E_FILTERBAR_RESET_ID, NULL } +#define E_FILTERBAR_EDIT { N_("Edit..."), E_FILTERBAR_EDIT_ID, NULL } +#define E_FILTERBAR_ADVANCED { N_("Advanced..."), E_FILTERBAR_ADVANCED_ID, NULL } #ifdef JUST_FOR_TRANSLATORS const char * strings[] = { diff --git a/widgets/misc/e-search-bar.c b/widgets/misc/e-search-bar.c index 19fc41aa71..9461bbecb4 100644 --- a/widgets/misc/e-search-bar.c +++ b/widgets/misc/e-search-bar.c @@ -5,8 +5,10 @@ * Copyright (C) 2000, 2001 Ximian, Inc. * * Authors: - * Chris Lahey <clahey@ximian.com> + * Chris Lahey <clahey@ximian.com> * Ettore Perazzoli <ettore@ximian.com> + * Jon Trowbridge <trow@ximian.com> + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -30,6 +32,7 @@ #include <gtk/gtkeventbox.h> #include <gtk/gtkmenuitem.h> #include <gtk/gtkoptionmenu.h> +#include <gtk/gtkmain.h> #include <gal/widgets/e-unicode.h> #include <gal/widgets/e-gui-utils.h> @@ -56,6 +59,7 @@ static GtkHBoxClass *parent_class = NULL; enum { ARG_0, ARG_OPTION_CHOICE, + ARG_SUBOPTION_CHOICE, ARG_TEXT, }; @@ -65,6 +69,11 @@ enum { static void emit_query_changed (ESearchBar *esb) { + if (esb->pending_change) { + gtk_idle_remove (esb->pending_change); + esb->pending_change = 0; + } + gtk_signal_emit (GTK_OBJECT (esb), esb_signals [QUERY_CHANGED]); } @@ -91,19 +100,110 @@ menubar_activated_cb (GtkWidget *widget, ESearchBar *esb) } static void -option_activated_cb (GtkWidget *widget, ESearchBar *esb) +entry_activated_cb (GtkWidget *widget, + ESearchBar *esb) { - int id; + emit_query_changed (esb); +} - id = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), "EsbChoiceId")); +static void +subitem_activated_cb (GtkWidget *widget, ESearchBar *esb) +{ + gint id, subid; + + id = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), "EsbItemId")); + subid = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), "EsbSubitemId")); esb->option_choice = id; + esb->suboption_choice = subid; emit_query_changed (esb); } static void -entry_activated_cb (GtkWidget *widget, ESearchBar *esb) +activate_by_subitems (ESearchBar *esb, gint item_id, ESearchBarSubitem *subitems) { + if (subitems == NULL) { + /* This item uses the entry. */ + + if (esb->entry == NULL) { + esb->entry = gtk_entry_new(); + gtk_object_ref (GTK_OBJECT (esb->entry)); + gtk_signal_connect (GTK_OBJECT (esb->entry), "activate", + GTK_SIGNAL_FUNC (entry_activated_cb), esb); + gtk_widget_show(esb->entry); + + esb->suboption_choice = 0; + } + + if (esb->suboption_choice >= 0) { + + if (esb->suboption != NULL) { + gtk_container_remove (GTK_CONTAINER (esb->entry_box), esb->suboption); + } + + gtk_container_add (GTK_CONTAINER (esb->entry_box), esb->entry); + } + + gtk_entry_set_text (GTK_ENTRY (esb->entry), ""); + + esb->suboption_choice = -1; + + } else { + + GtkWidget *menu; + GtkWidget *menu_item; + gint i; + + if (esb->suboption == NULL) { + esb->suboption = gtk_option_menu_new (); + gtk_object_ref (GTK_OBJECT (esb->suboption)); + gtk_widget_show (esb->suboption); + } + + esb->suboption_menu = menu = gtk_menu_new (); + for (i = 0; subitems[i].id != -1; ++i) { + menu_item = gtk_menu_item_new_with_label (_(subitems[i].text)); + + gtk_object_set_data (GTK_OBJECT (menu_item), "EsbItemId", GINT_TO_POINTER (item_id)); + gtk_object_set_data (GTK_OBJECT (menu_item), "EsbSubitemId", GINT_TO_POINTER (subitems[i].id)); + + gtk_signal_connect (GTK_OBJECT (menu_item), + "activate", + GTK_SIGNAL_FUNC (subitem_activated_cb), + esb); + + gtk_widget_show (menu_item); + gtk_menu_append (GTK_MENU (menu), menu_item); + } + + gtk_option_menu_remove_menu (GTK_OPTION_MENU (esb->suboption)); + gtk_option_menu_set_menu (GTK_OPTION_MENU (esb->suboption), menu); + + if (esb->entry != NULL) { + gtk_container_remove (GTK_CONTAINER (esb->entry_box), esb->entry); + } + + gtk_container_add (GTK_CONTAINER (esb->entry_box), esb->suboption); + + esb->suboption_choice = 0; + } + + if (esb->activate_button) { + gtk_widget_set_sensitive (esb->activate_button, subitems == NULL); + } +} + +static void +option_activated_cb (GtkWidget *widget, + ESearchBar *esb) +{ + int id; + + id = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), "EsbChoiceId")); + + activate_by_subitems (esb, id, gtk_object_get_data (GTK_OBJECT (widget), "EsbChoiceSubitems")); + + esb->option_choice = id; emit_query_changed (esb); } @@ -133,6 +233,42 @@ put_in_spacer_widget (GtkWidget *widget) return holder; } +static ESearchBarSubitem * +copy_subitems (ESearchBarSubitem *subitems) +{ + gint i, N; + ESearchBarSubitem *copy; + + if (subitems == NULL) + return NULL; + + for (N=0; subitems[N].id != -1; ++N); + copy = g_new (ESearchBarSubitem, N+1); + + for (i=0; i<N; ++i) { + copy[i].text = g_strdup (subitems[i].text); + copy[i].id = subitems[i].id; + } + + copy[N].text = NULL; + copy[N].id = -1; + + return copy; +} + +static void +free_subitems (ESearchBarSubitem *subitems) +{ + gint i; + + if (subitems != NULL) { + for (i=0; subitems[i].id != -1; ++i) { + g_free (subitems[i].text); + } + g_free (subitems); + } +} + static void add_dropdown (ESearchBar *esb, ESearchBarItem *items) { @@ -211,6 +347,7 @@ set_option (ESearchBar *esb, ESearchBarItem *items) esb->option_menu = menu = gtk_menu_new (); for (i = 0; items[i].id != -1; i++) { GtkWidget *item; + ESearchBarSubitem *subitems = NULL; if (items[i].text) { char *str; @@ -228,10 +365,22 @@ set_option (ESearchBar *esb, ESearchBarItem *items) gtk_object_set_data (GTK_OBJECT (item), "EsbChoiceId", GINT_TO_POINTER(items[i].id)); + if (items[i].subitems != NULL) { + subitems = copy_subitems (items[i].subitems); + esb->subitem_garbage = g_list_prepend (esb->subitem_garbage, subitems); + } + + gtk_object_set_data (GTK_OBJECT (item), "EsbChoiceSubitems", subitems); + + if (i == 0) { + activate_by_subitems (esb, items[i].id, subitems); + } + gtk_signal_connect (GTK_OBJECT (item), "activate", GTK_SIGNAL_FUNC (option_activated_cb), esb); } + gtk_widget_show_all (menu); gtk_option_menu_set_menu (GTK_OPTION_MENU (esb->option), menu); @@ -250,16 +399,6 @@ set_option (ESearchBar *esb, ESearchBarItem *items) } static void -add_entry (ESearchBar *esb) -{ - esb->entry = gtk_entry_new (); - gtk_signal_connect (GTK_OBJECT (esb->entry), "activate", - GTK_SIGNAL_FUNC (entry_activated_cb), esb); - gtk_widget_show (esb->entry); - gtk_box_pack_start (GTK_BOX (esb), esb->entry, TRUE, TRUE, 0); -} - -static void add_activate_button (ESearchBar *esb) { GtkWidget *label; @@ -319,6 +458,10 @@ impl_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) GTK_VALUE_ENUM (*arg) = e_search_bar_get_option_choice (esb); break; + case ARG_SUBOPTION_CHOICE: + GTK_VALUE_ENUM (*arg) = e_search_bar_get_suboption_choice (esb); + break; + case ARG_TEXT: GTK_VALUE_STRING (*arg) = e_search_bar_get_text (esb); break; @@ -344,6 +487,15 @@ impl_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) gtk_option_menu_set_history (GTK_OPTION_MENU (esb->option), row); emit_query_changed (esb); break; + + case ARG_SUBOPTION_CHOICE: + esb->suboption_choice = GTK_VALUE_ENUM (*arg); + row = find_id (esb->suboption_menu, esb->suboption_choice, "EsbSubitemId", NULL); + if (row == -1) + row = 0; + gtk_option_menu_set_history (GTK_OPTION_MENU (esb->suboption), row); + emit_query_changed (esb); + break; case ARG_TEXT: e_utf8_gtk_editable_set_text (GTK_EDITABLE (esb->entry), GTK_VALUE_STRING (*arg)); @@ -362,15 +514,30 @@ impl_destroy (GtkObject *object) g_return_if_fail (object != NULL); g_return_if_fail (E_IS_SEARCH_BAR (object)); - + + /* Should we really be unrefing all of these widgets? */ gtk_object_unref (GTK_OBJECT (esb->dropdown)); gtk_object_unref (GTK_OBJECT (esb->option)); - gtk_object_unref (GTK_OBJECT (esb->entry)); + + /* These two we do need to unref, because we explicitly hold + references to them. */ + if (esb->entry) + gtk_object_unref (GTK_OBJECT (esb->entry)); + if (esb->suboption) + gtk_object_unref (GTK_OBJECT (esb->suboption)); gtk_object_unref (GTK_OBJECT (esb->dropdown_holder)); gtk_object_unref (GTK_OBJECT (esb->option_menu)); gtk_object_unref (GTK_OBJECT (esb->dropdown_menu)); - + + g_list_foreach (esb->subitem_garbage, (GFunc) free_subitems, NULL); + g_list_free (esb->subitem_garbage); + + if (esb->pending_change) { + gtk_idle_remove (esb->pending_change); + esb->pending_change = 0; + } + if (GTK_OBJECT_CLASS (parent_class)->destroy) GTK_OBJECT_CLASS (parent_class)->destroy (object); } @@ -394,6 +561,8 @@ class_init (ESearchBarClass *klass) gtk_object_add_arg_type ("ESearchBar::option_choice", GTK_TYPE_ENUM, GTK_ARG_READWRITE, ARG_OPTION_CHOICE); + gtk_object_add_arg_type ("ESearchBar::suboption_choice", GTK_TYPE_ENUM, + GTK_ARG_READWRITE, ARG_SUBOPTION_CHOICE); gtk_object_add_arg_type ("ESearchBar::text", GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_TEXT); @@ -424,11 +593,21 @@ init (ESearchBar *esb) esb->entry = NULL; esb->option_choice = 0; + esb->suboption_choice = 0; } /* Object construction. */ +static gint +idle_change_hack (gpointer ptr) +{ + ESearchBar *esb = E_SEARCH_BAR (ptr); + esb->pending_change = 0; + emit_query_changed (esb); + return FALSE; +} + void e_search_bar_construct (ESearchBar *search_bar, ESearchBarItem *menu_items, @@ -440,14 +619,30 @@ e_search_bar_construct (ESearchBar *search_bar, g_return_if_fail (option_items != NULL); gtk_box_set_spacing (GTK_BOX (search_bar), 1); - + e_search_bar_set_menu (search_bar, menu_items); - + + search_bar->entry_box = gtk_hbox_new (0, FALSE); + e_search_bar_set_option (search_bar, option_items); - - add_entry (search_bar); - + + gtk_widget_show (search_bar->entry_box); + gtk_box_pack_start (GTK_BOX(search_bar), search_bar->entry_box, TRUE, TRUE, 0); + add_activate_button (search_bar); + + /* + * If the default choice for the option menu has subitems, then we need to + * activate the search immediately. However, the developer won't have + * connected to the changed signal until after the object is constructed, + * so we can't emit here. Thus we launch a one-shot idle function that will + * emit the changed signal, so that the proper callback will get invoked. + */ + if (search_bar->suboption_choice >= 0) { + gtk_widget_set_sensitive (search_bar->activate_button, FALSE); + + search_bar->pending_change = gtk_idle_add (idle_change_hack, search_bar); + } } void @@ -548,13 +743,33 @@ e_search_bar_get_option_choice (ESearchBar *search_bar) } /** + * e_search_bar_get_suboption_choice: + * @search_bar: A search bar. + * + * Queries the currently selected item in the suboptions menu of a search bar. + * + * Return value: Identifier of the selected item in the suboptions menu. + * If the search bar currently contains an entry rather than a a suboption menu, + * a value less than zero is returned. + **/ +int +e_search_bar_get_suboption_choice (ESearchBar *search_bar) +{ + g_return_val_if_fail (search_bar != NULL, -1); + g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), -1); + + return search_bar->suboption_choice; +} + +/** * e_search_bar_get_text: * @search_bar: A search bar. * * Queries the text of the entry line in a search bar. * * Return value: The text string that is in the entry line of the search bar. - * This must be freed using g_free(). + * This must be freed using g_free(). If a suboption menu is active instead + * of an entry, NULL is returned. **/ char * e_search_bar_get_text (ESearchBar *search_bar) @@ -562,5 +777,5 @@ e_search_bar_get_text (ESearchBar *search_bar) g_return_val_if_fail (search_bar != NULL, NULL); g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), NULL); - return e_utf8_gtk_editable_get_text (GTK_EDITABLE (search_bar->entry)); + return search_bar->suboption_choice < 0 ? e_utf8_gtk_editable_get_text (GTK_EDITABLE (search_bar->entry)) : NULL; } diff --git a/widgets/misc/e-search-bar.h b/widgets/misc/e-search-bar.h index 3ca381f92e..10c4eef8db 100644 --- a/widgets/misc/e-search-bar.h +++ b/widgets/misc/e-search-bar.h @@ -47,6 +47,12 @@ extern "C" { typedef struct { char *text; int id; +} ESearchBarSubitem; + +typedef struct { + char *text; + int id; + ESearchBarSubitem *subitems; } ESearchBarItem; typedef struct _ESearchBar ESearchBar; @@ -60,14 +66,21 @@ struct _ESearchBar GtkWidget *dropdown; GtkWidget *option; GtkWidget *entry; + GtkWidget *suboption; /* an option menu for the choices associated with some options */ + /* PRIVATE */ GtkWidget *dropdown_holder; /* holds the dropdown */ GtkWidget *option_menu; + GtkWidget *suboption_menu; GtkWidget *dropdown_menu; GtkWidget *activate_button; + GtkWidget *entry_box; + GList *subitem_garbage; + guint pending_change; int option_choice; + int suboption_choice; /* < 0 if the entry widget is active */ }; struct _ESearchBarClass @@ -95,8 +108,9 @@ GtkWidget *e_search_bar_new (ESearchBarItem *menu_items, void e_search_bar_set_menu_sensitive(ESearchBar *search_bar, int id, gboolean state); -int e_search_bar_get_option_choice (ESearchBar *search_bar); -char *e_search_bar_get_text (ESearchBar *search_bar); +int e_search_bar_get_option_choice (ESearchBar *search_bar); +int e_search_bar_get_suboption_choice (ESearchBar *search_bar); +char *e_search_bar_get_text (ESearchBar *search_bar); #ifdef __cplusplus } |