aboutsummaryrefslogtreecommitdiffstats
path: root/widgets/misc/e-search-bar.c
diff options
context:
space:
mode:
authorSrinivasa Ragavan <sragavan@novell.com>2009-05-22 19:37:09 +0800
committerMatthew Barnes <mbarnes@redhat.com>2009-05-24 22:02:55 +0800
commit2ea8d8f1930bdc7f30e8556d6abeca33eb263af6 (patch)
treecdea10ab7c7228c3cd35484146719b3f600ce1b7 /widgets/misc/e-search-bar.c
parentc3205a427adcc910f0614cb83249622816440c56 (diff)
downloadgsoc2013-evolution-2ea8d8f1930bdc7f30e8556d6abeca33eb263af6.tar
gsoc2013-evolution-2ea8d8f1930bdc7f30e8556d6abeca33eb263af6.tar.gz
gsoc2013-evolution-2ea8d8f1930bdc7f30e8556d6abeca33eb263af6.tar.bz2
gsoc2013-evolution-2ea8d8f1930bdc7f30e8556d6abeca33eb263af6.tar.lz
gsoc2013-evolution-2ea8d8f1930bdc7f30e8556d6abeca33eb263af6.tar.xz
gsoc2013-evolution-2ea8d8f1930bdc7f30e8556d6abeca33eb263af6.tar.zst
gsoc2013-evolution-2ea8d8f1930bdc7f30e8556d6abeca33eb263af6.zip
Filter/Search bar changes for Anjal.
Diffstat (limited to 'widgets/misc/e-search-bar.c')
-rw-r--r--widgets/misc/e-search-bar.c395
1 files changed, 337 insertions, 58 deletions
diff --git a/widgets/misc/e-search-bar.c b/widgets/misc/e-search-bar.c
index a588b73b0c..2d1fd5eb5e 100644
--- a/widgets/misc/e-search-bar.c
+++ b/widgets/misc/e-search-bar.c
@@ -91,37 +91,69 @@ action_search_find_cb (GtkAction *action,
}
static void
-action_search_type_cb (GtkAction *action,
- ESearchBar *search_bar)
+clear_button_state_changed (GtkWidget *clear_button, GtkStateType state, ESearchBar *search_bar)
{
- gtk_menu_popup (
- GTK_MENU (search_bar->priv->search_popup_menu),
- NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time ());
+ g_return_if_fail (clear_button != NULL && search_bar != NULL);
+
+ if (!search_bar->lite)
+ update_clear_menuitem_sensitive (search_bar);
}
-static GtkActionEntry search_entries[] = {
-
- { "search-clear",
- GTK_STOCK_CLEAR,
- NULL,
- "<Shift><Control>q",
- N_("Clear the most recent search"),
- G_CALLBACK (action_search_clear_cb) },
-
- { "search-find",
- GTK_STOCK_FIND,
- N_("_Find Now"),
- NULL,
- N_("Execute the search"),
- G_CALLBACK (action_search_find_cb) },
-
- { "search-type",
- GTK_STOCK_FIND,
- NULL,
- NULL,
- NULL,
- G_CALLBACK (action_search_type_cb) }
-};
+static char *
+verb_name_from_id (int id)
+{
+ return g_strdup_printf ("ESearchBar:Activate:%d", id);
+}
+
+/* This implements the "clear" action, i.e. clears the text and then emits
+ * ::search_activated. */
+
+static void
+clear_search (ESearchBar *esb)
+{
+ e_search_bar_set_text (esb, "");
+ esb->block_search = TRUE;
+ if (esb->item_id < 0)
+ e_search_bar_set_item_id (esb, esb->last_search_option);
+ e_search_bar_set_viewitem_id (esb, 0);
+ esb->block_search = FALSE;
+ emit_search_activated (esb);
+}
+
+static void
+free_menu_items (ESearchBar *esb)
+{
+ GSList *p;
+
+ if (esb->menu_items == NULL)
+ return;
+
+ for (p = esb->menu_items; p != NULL; p = p->next) {
+ ESearchBarItem *item;
+
+ item = (ESearchBarItem *) p->data;
+
+ /* (No submitems for the menu_items, so no need to free that
+ member.) */
+
+ g_free (item->text);
+ g_free (item);
+ }
+
+ g_slist_free (esb->menu_items);
+ esb->menu_items = NULL;
+}
+
+
+/* Signals. */
+
+static void
+emit_query_changed (ESearchBar *esb)
+{
+ g_signal_emit (esb, esb_signals [QUERY_CHANGED], 0);
+ if (!esb->lite)
+ update_clear_menuitem_sensitive (esb);
+}
static void
search_bar_rule_changed (FilterRule *rule,
@@ -131,10 +163,10 @@ search_bar_rule_changed (FilterRule *rule,
sensitive = (rule != NULL && rule->parts != NULL);
- gtk_dialog_set_response_sensitive (
- dialog, GTK_RESPONSE_OK, sensitive);
- gtk_dialog_set_response_sensitive (
- dialog, GTK_RESPONSE_APPLY, sensitive);
+ if (!esb->lite) {
+ set_find_now_sensitive (esb, FALSE);
+ update_clear_menuitem_sensitive (esb);
+ }
}
static void
@@ -221,8 +253,37 @@ paint_search_text (GtkWidget *widget,
void
e_search_bar_paint (ESearchBar *search_bar)
{
- EIconEntry *icon_entry;
- GtkWidget *entry;
+ paint_search_text (search_bar->entry, search_bar);
+}
+
+static gboolean
+entry_focus_out_cb (GtkWidget *widget,
+ GdkEventFocus *event,
+ ESearchBar *esb)
+{
+ return paint_search_text (widget, esb);
+}
+
+static void
+entry_activated_cb (GtkWidget *widget,
+ ESearchBar *esb)
+{
+ const char *text = gtk_entry_get_text (GTK_ENTRY (esb->entry));
+ GtkStyle *style = gtk_widget_get_default_style ();
+
+ if (text && *text) {
+ gtk_widget_modify_base (esb->entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED]));
+ gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, &(style->text[GTK_STATE_SELECTED]));
+ gtk_widget_modify_base (esb->icon_entry, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED]));
+ if (!esb->lite)
+ gtk_widget_modify_base (esb->viewoption, GTK_STATE_NORMAL, &(style->base[GTK_STATE_SELECTED]));
+ } else {
+ gtk_widget_modify_base (esb->entry, GTK_STATE_NORMAL, NULL);
+ gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, NULL);
+ gtk_widget_modify_base (esb->icon_entry, GTK_STATE_NORMAL, NULL);
+ if (!esb->lite)
+ gtk_widget_set_sensitive (esb->clear_button, FALSE);
+ }
icon_entry = E_ICON_ENTRY (search_bar->priv->search_entry);
entry = e_icon_entry_get_entry (icon_entry);
@@ -539,10 +600,68 @@ search_bar_dispose (GObject *object)
priv->filter_combo_box = NULL;
}
- if (priv->search_label != NULL) {
- g_object_unref (priv->search_label);
- priv->search_label = NULL;
- }
+ if (!esb->lite && esb->ui_component != NULL)
+ update_bonobo_menus (esb);
+}
+
+/* /\* Callback used when an option item is destroyed. We have to destroy its */
+/* * suboption items. */
+/* *\/ */
+/* static void */
+/* option_item_destroy_cb (GtkObject *object, gpointer data) */
+/* { */
+/* /\* ESearchBarSubitem *subitems; *\/ */
+
+/* /\* subitems = data; *\/ */
+
+/* /\* g_assert (subitems != NULL); *\/ */
+/* /\* free_subitems (subitems); *\/ */
+/* /\* g_object_set_data (G_OBJECT (object), "EsbChoiceSubitems", NULL); *\/ */
+/* } */
+
+static void
+set_option (ESearchBar *esb, ESearchBarItem *items)
+{
+ GtkWidget *menu;
+ GSList *group = NULL;
+ int i;
+
+ if (esb->option_menu)
+ gtk_widget_destroy (esb->option_menu);
+
+ esb->option_menu = menu = gtk_menu_new ();
+ for (i = 0; items[i].id != -1; i++) {
+ GtkWidget *item;
+
+ /* Create a new group */
+ if (items[i].id == 0)
+ group = NULL;
+
+ if (items[i].text) {
+ char *str;
+ str = e_str_without_underscores (_(items[i].text));
+ switch (items[i].type) {
+ case ESB_ITEMTYPE_NORMAL:
+ item = gtk_menu_item_new_with_label (str);
+ break;
+ case ESB_ITEMTYPE_CHECK:
+ item = gtk_check_menu_item_new_with_label (str);
+ break;
+ case ESB_ITEMTYPE_RADIO:
+ item = gtk_radio_menu_item_new_with_label (group, str);
+ group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM (item));
+ break;
+ default:
+ /* Fixme : this should be a normal item */
+ item = gtk_radio_menu_item_new_with_label (group, str);
+ group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM (item));
+ break;
+ }
+ g_free (str);
+ } else {
+ item = gtk_menu_item_new ();
+ gtk_widget_set_sensitive (item, FALSE);
+ }
if (priv->search_entry != NULL) {
g_object_unref (priv->search_entry);
@@ -816,19 +935,18 @@ e_search_bar_get_type (void)
{
static GType type = 0;
- if (G_UNLIKELY (type == 0)) {
- static const GTypeInfo type_info = {
- sizeof (ESearchBarClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) search_bar_class_init,
- (GClassFinalizeFunc) NULL,
- NULL, /* class_data */
- sizeof (ESearchBar),
- 0, /* n_preallocs */
- (GInstanceInitFunc) search_bar_init,
- NULL /* value_table */
- };
+ if (!esb->lite && esb->ui_component != NULL) {
+ bonobo_object_unref (BONOBO_OBJECT (esb->ui_component));
+ esb->ui_component = NULL;
+ }
+/* if (esb->entry) { */
+/* g_object_unref (esb->entry); */
+/* esb->entry = NULL; */
+/* } */
+ if (esb->suboption) {
+ g_object_unref (esb->suboption);
+ esb->suboption = NULL;
+ }
type = g_type_register_static (
GTK_TYPE_HBOX, "ESearchBar", &type_info, 0);
@@ -869,8 +987,115 @@ e_search_bar_set_context (ESearchBar *search_bar,
if (search_bar->priv->context != NULL)
g_object_unref (search_bar->priv->context);
- search_bar->priv->context = g_object_ref (context);
- g_object_notify (G_OBJECT (search_bar), "context");
+ bighbox = gtk_hbox_new (FALSE, 0);
+ search_bar->entry_box = gtk_hbox_new (0, FALSE);
+ search_bar->icon_entry = e_icon_entry_new ();
+ search_bar->entry = e_icon_entry_get_entry (E_ICON_ENTRY (search_bar->icon_entry));
+
+ g_signal_connect (search_bar->entry, "changed",
+ G_CALLBACK (entry_changed_cb), search_bar);
+ g_signal_connect (search_bar->entry, "activate",
+ G_CALLBACK (entry_activated_cb), search_bar);
+ g_signal_connect (search_bar->entry, "focus-in-event",
+ G_CALLBACK (entry_focus_in_cb), search_bar);
+ g_signal_connect (search_bar->entry, "focus-out-event",
+ G_CALLBACK (entry_focus_out_cb), search_bar);
+ g_signal_connect (search_bar->entry, "key-press-event",
+ G_CALLBACK (entry_key_press_cb), search_bar);
+
+ search_bar->clear_button = e_icon_entry_create_button ("gtk-clear");
+ g_signal_connect (G_OBJECT (search_bar->clear_button), "button-press-event", G_CALLBACK(clear_button_clicked_cb), search_bar);
+ e_icon_entry_pack_widget (E_ICON_ENTRY (search_bar->icon_entry), search_bar->clear_button, FALSE);
+
+ search_bar->option_button = e_icon_entry_create_button ("gtk-find");
+ g_signal_connect (G_OBJECT (search_bar->option_button), "button-press-event", G_CALLBACK(option_button_clicked_cb), search_bar);
+ e_icon_entry_pack_widget (E_ICON_ENTRY (search_bar->icon_entry), search_bar->option_button, TRUE);
+
+ if (!search_bar->lite)
+ gtk_box_pack_start (GTK_BOX(search_bar->entry_box), search_bar->icon_entry, FALSE, FALSE, 0);
+ else
+ gtk_box_pack_start (GTK_BOX(search_bar->entry_box), search_bar->icon_entry, TRUE, TRUE, 0);
+
+
+ gtk_widget_show_all (search_bar->entry_box);
+ gtk_widget_set_sensitive (search_bar->clear_button, FALSE);
+
+ if (!search_bar->lite) {
+ /* Current View filter */
+ search_bar->viewoption_box = gtk_hbox_new (0, FALSE);
+
+ /* To Translators: The "Show: " label is followed by the Quick Search Dropdown Menu where you can choose
+ to display "All Messages", "Unread Messages", "Message with 'Important' Label" and so on... */
+ label = gtk_label_new_with_mnemonic (_("Sho_w: "));
+ gtk_widget_show (label);
+ gtk_box_pack_start (GTK_BOX(search_bar->viewoption_box), label, FALSE, FALSE, 0);
+
+ search_bar->viewoption = gtk_option_menu_new ();
+ gtk_label_set_mnemonic_widget ((GtkLabel *)label, search_bar->viewoption);
+ gtk_box_pack_start (GTK_BOX(search_bar->viewoption_box), search_bar->viewoption, FALSE, TRUE, 0);
+ gtk_widget_show_all (search_bar->viewoption_box);
+ gtk_box_pack_start (GTK_BOX(search_bar), search_bar->viewoption_box, FALSE, FALSE, 0);
+
+ hbox = gtk_hbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX(search_bar), hbox, FALSE, FALSE, 0);
+ }
+
+ /* Search entry */
+ hbox = gtk_hbox_new (FALSE, 0);
+ /* To Translators: The "Show: " label is followed by the Quick Search Text input field where one enters
+ the term to search for */
+ if (!search_bar->lite) {
+ label = gtk_label_new_with_mnemonic (_("Sear_ch: "));
+ gtk_widget_show (label);
+ gtk_box_pack_start (GTK_BOX(hbox), label, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX(hbox), search_bar->entry_box, FALSE, FALSE, 0);
+ gtk_label_set_mnemonic_widget ((GtkLabel *)label, search_bar->entry);
+ } else {
+ gtk_box_pack_start (GTK_BOX(hbox), search_bar->entry_box, TRUE, TRUE, 0);
+ }
+ gtk_widget_show (search_bar->entry_box);
+
+ if (!search_bar->lite) {
+ /* Search Scope Widgets */
+ search_bar->scopeoption_box = gtk_hbox_new (0, FALSE);
+ gtk_box_set_spacing (GTK_BOX (search_bar->scopeoption_box), 3);
+ /* To Translators: The " in " label is part of the Quick Search Bar, example:
+ Search: | <user's_search_term> | in | Current Folder/All Accounts/Current Account */
+ label = gtk_label_new_with_mnemonic (_(" i_n "));
+ gtk_widget_show (label);
+ gtk_box_pack_start (GTK_BOX(search_bar->scopeoption_box), label, FALSE, FALSE, 0);
+
+ search_bar->scopeoption = gtk_option_menu_new ();
+ /* g_signal_connect (GTK_OPTION_MENU (search_bar->scopeoption), "changed", scopeoption_changed_cb, search_bar); */
+ gtk_box_pack_start (GTK_BOX(search_bar->scopeoption_box), search_bar->scopeoption, FALSE, FALSE, 0);
+ gtk_widget_show_all (search_bar->scopeoption_box);
+ gtk_widget_hide (hbox);
+ gtk_label_set_mnemonic_widget ((GtkLabel *)label, search_bar->scopeoption);
+
+ gtk_box_pack_end (GTK_BOX(hbox), search_bar->scopeoption_box, FALSE, FALSE, 0);
+ gtk_widget_hide (search_bar->scopeoption_box);
+
+ }
+ if (!search_bar->lite)
+ gtk_box_pack_end (GTK_BOX(search_bar), hbox, FALSE, FALSE, 0);
+ else
+ gtk_box_pack_end (GTK_BOX(search_bar), hbox, TRUE, TRUE, 0);
+
+ gtk_widget_show (hbox);
+
+ /* Set the menu */
+ e_search_bar_set_menu (search_bar, menu_items);
+ e_search_bar_set_option (search_bar, option_items);
+
+ /*
+ * 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 activated 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->lite)
+ search_bar->pending_activate = g_idle_add (idle_activate_hack, search_bar);
}
GtkRadioAction *
@@ -996,10 +1221,42 @@ e_search_bar_get_search_text (ESearchBar *search_bar)
color1 = &style1->text[GTK_STATE_NORMAL];
color2 = &style2->text[GTK_STATE_INSENSITIVE];
- if (gdk_color_equal (color1, color2))
- return "";
+GtkWidget *
+e_search_bar_lite_new (ESearchBarItem *menu_items,
+ ESearchBarItem *option_items)
+{
+ GtkWidget *widget;
+
+ g_return_val_if_fail (option_items != NULL, NULL);
+
+ widget = g_object_new (e_search_bar_get_type (), NULL);
+ E_SEARCH_BAR(widget)->lite = TRUE;
- return gtk_entry_get_text (GTK_ENTRY (entry));
+ e_search_bar_construct (E_SEARCH_BAR (widget), menu_items, option_items);
+
+ return widget;
+}
+
+void
+e_search_bar_set_ui_component (ESearchBar *search_bar,
+ BonoboUIComponent *ui_component)
+{
+ g_return_if_fail (E_IS_SEARCH_BAR (search_bar));
+
+ if (search_bar->lite)
+ return;
+
+ if (search_bar->ui_component != NULL) {
+ remove_bonobo_menus (search_bar);
+ bonobo_object_unref (BONOBO_OBJECT (search_bar->ui_component));
+ }
+
+ search_bar->ui_component = ui_component;
+ if (ui_component != NULL) {
+ bonobo_object_ref (BONOBO_OBJECT (ui_component));
+ setup_standard_verbs (search_bar);
+ setup_bonobo_menus (search_bar);
+ }
}
void
@@ -1009,7 +1266,12 @@ e_search_bar_set_search_text (ESearchBar *search_bar,
EIconEntry *icon_entry;
GtkWidget *entry;
- g_return_if_fail (E_IS_SEARCH_BAR (search_bar));
+ if (search_bar->lite)
+ return;
+
+ verb_name = verb_name_from_id (id);
+ path = g_strconcat ("/commands/", verb_name, NULL);
+ g_free (verb_name);
icon_entry = E_ICON_ENTRY (search_bar->priv->search_entry);
entry = e_icon_entry_get_entry (icon_entry);
@@ -1033,6 +1295,8 @@ e_search_bar_set_search_value (ESearchBar *search_bar,
gint value)
{
g_return_if_fail (E_IS_SEARCH_BAR (search_bar));
+ if (!search_bar->viewoption_menu)
+ return;
/* FIXME */
@@ -1044,7 +1308,22 @@ e_search_bar_get_search_visible (ESearchBar *search_bar)
{
g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), FALSE);
- return GTK_WIDGET_VISIBLE (search_bar->priv->search_entry);
+ if (!search_bar->option_menu)
+ return;
+ row = find_id (search_bar->option_menu, id, "EsbItemId", NULL);
+ if (row == -1)
+ return;
+
+ if (id>=0)
+ search_bar->last_search_option = id;
+ search_bar->item_id = id;
+ gtk_menu_set_active ((GtkMenu *)search_bar->option_menu, row);
+
+ if (!search_bar->block_search)
+ emit_query_changed (search_bar);
+
+ if (!search_bar->lite)
+ update_clear_menuitem_sensitive (search_bar);
}
void