aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--addressbook/ChangeLog6
-rw-r--r--addressbook/gui/component/addressbook.c14
-rw-r--r--calendar/ChangeLog5
-rw-r--r--calendar/gui/cal-search-bar.c12
-rw-r--r--composer/ChangeLog5
-rw-r--r--composer/e-msg-composer-hdrs.c5
-rw-r--r--filter/libfilter-i18n.h36
-rw-r--r--mail/ChangeLog4
-rw-r--r--mail/folder-browser.c4
-rw-r--r--widgets/misc/ChangeLog14
-rw-r--r--widgets/misc/e-filter-bar.c6
-rw-r--r--widgets/misc/e-filter-bar.h8
-rw-r--r--widgets/misc/e-search-bar.c265
-rw-r--r--widgets/misc/e-search-bar.h18
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
}