diff options
Diffstat (limited to 'widgets/misc/e-search-bar.c')
-rw-r--r-- | widgets/misc/e-search-bar.c | 1806 |
1 files changed, 841 insertions, 965 deletions
diff --git a/widgets/misc/e-search-bar.c b/widgets/misc/e-search-bar.c index 2bbbc91a00..9abc60442a 100644 --- a/widgets/misc/e-search-bar.c +++ b/widgets/misc/e-search-bar.c @@ -22,78 +22,72 @@ * */ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gdk/gdkkeysyms.h> +#include "e-search-bar.h" -#include <misc/e-unicode.h> -#include <misc/e-gui-utils.h> +#include "config.h" +#include <stdlib.h> +#include <string.h> #include <glib/gi18n.h> +#include <gdk/gdkkeysyms.h> +#include <e-util/e-util.h> +#include <e-util/e-unicode.h> -#include <bonobo/bonobo-ui-util.h> +#include <e-action-combo-box.h> +#include <e-gui-utils.h> +#include <e-icon-entry.h> -#include <stdlib.h> -#include <string.h> +#define E_SEARCH_BAR_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_SEARCH_BAR, ESearchBarPrivate)) -#include "e-icon-entry.h" -#include "e-search-bar.h" -#include "e-util/e-util.h" +struct _ESearchBarPrivate { + RuleContext *context; + FilterRule *current_query; - -enum { - QUERY_CHANGED, - MENU_ACTIVATED, - SEARCH_ACTIVATED, - SEARCH_CLEARED, - LAST_SIGNAL -}; + GtkWidget *filter_label; + GtkWidget *filter_combo_box; + GtkWidget *search_label; + GtkWidget *search_entry; + GtkWidget *scope_label; + GtkWidget *scope_combo_box; -static gint esb_signals [LAST_SIGNAL] = { 0, }; + GtkRadioAction *search_action; + GtkWidget *search_popup_menu; -static GtkHBoxClass *parent_class = NULL; + GtkActionGroup *action_group; +}; -/* The arguments we take */ enum { PROP_0, - PROP_ITEM_ID, - PROP_SUBITEM_ID, - PROP_TEXT + PROP_CONTEXT, + PROP_FILTER_ACTION, + PROP_FILTER_VALUE, + PROP_FILTER_VISIBLE, + PROP_SEARCH_ACTION, + PROP_SEARCH_TEXT, + PROP_SEARCH_VALUE, + PROP_SEARCH_VISIBLE, + PROP_SCOPE_ACTION, + PROP_SCOPE_VALUE, + PROP_SCOPE_VISIBLE }; - -/* Forward decls. */ - -static int find_id (GtkWidget *menu, int idin, const char *type, GtkWidget **widget); - -static void emit_search_activated (ESearchBar *esb); -static void emit_query_changed (ESearchBar *esb); - - -/* Utility functions. */ +static gpointer parent_class; static void -set_find_now_sensitive (ESearchBar *search_bar, - gboolean sensitive) +action_search_clear_cb (GtkAction *action, + ESearchBar *search_bar) { - if (search_bar->ui_component != NULL) - bonobo_ui_component_set_prop (search_bar->ui_component, - "/commands/ESearchBar:FindNow", - "sensitive", sensitive ? "1" : "0", NULL); + e_search_bar_set_search_text (search_bar, ""); + gtk_action_set_sensitive (action, FALSE); } static void -update_clear_menuitem_sensitive (ESearchBar *search_bar) +action_search_find_cb (GtkAction *action, + ESearchBar *search_bar) { - if (search_bar->ui_component != NULL) { - gboolean sensitive = GTK_WIDGET_SENSITIVE (search_bar->clear_button) || search_bar->viewitem_id != 0; - - bonobo_ui_component_set_prop (search_bar->ui_component, - "/commands/ESearchBar:Clear", - "sensitive", sensitive ? "1" : "0", NULL); - } + gtk_action_set_sensitive (action, FALSE); } static void @@ -162,14 +156,12 @@ emit_query_changed (ESearchBar *esb) } static void -emit_search_activated(ESearchBar *esb) +search_bar_rule_changed (FilterRule *rule, + GtkDialog *dialog) { - if (esb->pending_activate) { - g_source_remove (esb->pending_activate); - esb->pending_activate = 0; - } + gboolean sensitive; - g_signal_emit (esb, esb_signals [SEARCH_ACTIVATED], 0); + sensitive = (rule != NULL && rule->parts != NULL); if (!esb->lite) { set_find_now_sensitive (esb, FALSE); @@ -178,152 +170,60 @@ emit_search_activated(ESearchBar *esb) } static void -emit_menu_activated (ESearchBar *esb, int item) +search_bar_update_search_popup (ESearchBar *search_bar) { - g_signal_emit (esb, - esb_signals [MENU_ACTIVATED], 0, - item); -} + GtkAction *action; + GtkMenuShell *menu_shell; + GSList *list, *iter; - -/* Callbacks -- Standard verbs. */ + action = gtk_action_group_get_action ( + search_bar->priv->action_group, "search-type"); -static void -search_now_verb_cb (BonoboUIComponent *ui_component, - void *data, - const char *verb_name) -{ - ESearchBar *esb; - GtkStyle *style = gtk_widget_get_default_style (); - char *text; - - esb = E_SEARCH_BAR (data); - text = e_search_bar_get_text (esb); - - 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])); - 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); - gtk_widget_set_sensitive (esb->clear_button, FALSE); + if (search_bar->priv->search_popup_menu != NULL) { + g_object_unref (search_bar->priv->search_popup_menu); + search_bar->priv->search_popup_menu = NULL; } - g_free (text); - emit_search_activated (esb); -} - -static void -clear_verb_cb (BonoboUIComponent *ui_component, - void *data, - const char *verb_name) -{ - ESearchBar *esb; - esb = E_SEARCH_BAR (data); - - 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); - gtk_widget_set_sensitive (esb->clear_button, FALSE); - - clear_search (esb); - gtk_entry_set_text (GTK_ENTRY (esb->entry), ""); - gtk_widget_grab_focus (esb->entry); -} - -static void -setup_standard_verbs (ESearchBar *search_bar) -{ - bonobo_ui_component_add_verb (search_bar->ui_component, "ESearchBar:Clear", - clear_verb_cb, search_bar); - bonobo_ui_component_add_verb (search_bar->ui_component, "ESearchBar:FindNow", - search_now_verb_cb, search_bar); - - bonobo_ui_component_set (search_bar->ui_component, "/", - ("<commands>" - " <cmd name=\"ESearchBar:Clear\"/>" - " <cmd name=\"ESearchBar:FindNow\"/>" - "</commands>"), - NULL); - - /* Make sure the entries are created with the correct sensitivity. */ - set_find_now_sensitive (search_bar, FALSE); - update_clear_menuitem_sensitive (search_bar); -} - -/* Callbacks -- The verbs for all the definable items. */ - -static void -search_verb_cb (BonoboUIComponent *ui_component, - void *data, - const char *verb_name) -{ - ESearchBar *esb; - const char *p; - int id; - - esb = E_SEARCH_BAR (data); - - p = strrchr (verb_name, ':'); - g_return_if_fail (p != NULL); - - id = atoi (p + 1); - - emit_menu_activated (esb, id); -} - -/* Get the selected menu item's label */ -static const gchar * -get_selected_item_label (GtkWidget *menu) -{ - GtkWidget *label, *item; - const gchar *text = NULL; - - item = gtk_menu_get_active ((GtkMenu *)menu); - label = gtk_bin_get_child ((GtkBin *)item); - - if (GTK_IS_LABEL (label)) - text = gtk_label_get_text ((GtkLabel *)label); - - return text; -} + if (search_bar->priv->search_action == NULL) { + gtk_action_set_sensitive (action, FALSE); + return; + } -static gboolean -entry_focus_in_cb (GtkWidget *widget, - GdkEventFocus *event, - ESearchBar *esb) -{ - GtkStyle *entry_style, *default_style; + search_bar->priv->search_popup_menu = gtk_menu_new (); + menu_shell = GTK_MENU_SHELL (search_bar->priv->search_popup_menu); + list = gtk_radio_action_get_group (search_bar->priv->search_action); - entry_style = gtk_widget_get_style (esb->entry); - default_style = gtk_widget_get_default_style (); + for (iter = list; iter != NULL; iter = iter->next) { + GtkAction *action = iter->data; + GtkWidget *widget; - if (gdk_color_equal (&(entry_style->text[GTK_STATE_NORMAL]), &(default_style->text[GTK_STATE_INSENSITIVE]))) { - gtk_entry_set_text (GTK_ENTRY (esb->entry), ""); - gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, NULL); + widget = gtk_action_create_menu_item (action); + gtk_menu_shell_append (menu_shell, widget); + gtk_widget_show (widget); } - return FALSE; + gtk_action_set_sensitive (action, TRUE); } static gboolean -paint_search_text (GtkWidget *widget, ESearchBar *esb) +paint_search_text (GtkWidget *widget, + ESearchBar *search_bar) { +#if 0 GtkStyle *style = gtk_widget_get_default_style (); - const gchar *text = NULL; - GtkWidget *menu_widget = esb->option_menu; + const gchar *text; + GtkWidget *menu_widget = search_bar->option_menu; text = gtk_entry_get_text (GTK_ENTRY (widget)); if (text && *text) return FALSE; - if (!GTK_WIDGET_SENSITIVE (esb->option_button)) { - menu_widget = esb->scopeoption_menu; - text = g_object_get_data (G_OBJECT(gtk_menu_get_active ( GTK_MENU (esb->scopeoption_menu))),"string"); - } else if (!GTK_IS_RADIO_MENU_ITEM (gtk_menu_get_active ( GTK_MENU (esb->option_menu)))) + style = gtk_widget_get_default_style (); + + if (!GTK_WIDGET_SENSITIVE (search_bar->option_button)) { + menu_widget = search_bar->scopeoption_menu; + text = g_object_get_data (G_OBJECT(gtk_menu_get_active ( GTK_MENU (search_bar->scopeoption_menu))),"string"); + } else if (!GTK_IS_RADIO_MENU_ITEM (gtk_menu_get_active ( GTK_MENU (search_bar->option_menu)))) return FALSE; else /* no query in search entry .. so set the current option */ text = get_selected_item_label (menu_widget); @@ -332,19 +232,22 @@ paint_search_text (GtkWidget *widget, ESearchBar *esb) if (text && *text) { gchar *t; - if (!GTK_WIDGET_HAS_FOCUS(esb->entry)) { - gtk_entry_set_text (GTK_ENTRY (esb->entry), text); - gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, &(style->text[GTK_STATE_INSENSITIVE])); + if (!GTK_WIDGET_HAS_FOCUS(search_bar->entry)) { + gtk_entry_set_text (GTK_ENTRY (search_bar->entry), text); + gtk_widget_modify_text (search_bar->entry, GTK_STATE_NORMAL, &(style->text[GTK_STATE_INSENSITIVE])); } t = g_strdup_printf ("%s: %s\n%s", _("Search"), text, _("Click here to change the search type")); - gtk_widget_set_tooltip_text (esb->option_button, t); + gtk_widget_set_tooltip_text (search_bar->option_button, t); g_free (t); - gtk_widget_set_sensitive (esb->clear_button, FALSE); + gtk_widget_set_sensitive (search_bar->clear_button, FALSE); } return FALSE; +#endif + + return FALSE; } void @@ -382,293 +285,319 @@ entry_activated_cb (GtkWidget *widget, gtk_widget_set_sensitive (esb->clear_button, FALSE); } - emit_search_activated (esb); + icon_entry = E_ICON_ENTRY (search_bar->priv->search_entry); + entry = e_icon_entry_get_entry (icon_entry); + paint_search_text (entry, search_bar); } static void -entry_changed_cb (GtkWidget *widget, - ESearchBar *esb) +search_bar_entry_activated_cb (ESearchBar *search_bar, + GtkWidget *entry) { - const char *text = gtk_entry_get_text (GTK_ENTRY (esb->entry)); - GtkStyle *entry_style, *default_style; + GtkStyle *style; + GtkAction *action; + GtkActionGroup *action_group; + gboolean sensitive; + const gchar *text; - entry_style = gtk_widget_get_style (esb->entry); - default_style = gtk_widget_get_default_style (); + style = gtk_widget_get_default_style (); + text = gtk_entry_get_text (GTK_ENTRY (entry)); + action_group = e_search_bar_get_action_group (search_bar); if (text && *text) { - if (gdk_color_equal (&(entry_style->text[GTK_STATE_NORMAL]), &(default_style->text[GTK_STATE_INSENSITIVE]))) - gtk_widget_set_sensitive (esb->clear_button, FALSE); - else - gtk_widget_set_sensitive (esb->clear_button, TRUE); + gtk_widget_modify_base ( + entry, GTK_STATE_NORMAL, + &(style->base[GTK_STATE_SELECTED])); + gtk_widget_modify_text ( + entry, GTK_STATE_NORMAL, + &(style->text[GTK_STATE_SELECTED])); + gtk_widget_modify_base ( + search_bar->priv->search_entry, + GTK_STATE_NORMAL, + &(style->base[GTK_STATE_SELECTED])); + gtk_widget_modify_base ( + search_bar->priv->filter_combo_box, + GTK_STATE_NORMAL, + &(style->base[GTK_STATE_SELECTED])); + sensitive = TRUE; } else { - /* selected color means some search text is active */ - gtk_widget_set_sensitive (esb->clear_button, gdk_color_equal (&(entry_style->base[GTK_STATE_NORMAL]), &(default_style->base[GTK_STATE_SELECTED]))); + gtk_widget_modify_base ( + entry, GTK_STATE_NORMAL, NULL); + gtk_widget_modify_text ( + entry, GTK_STATE_NORMAL, NULL); + gtk_widget_modify_base ( + search_bar->priv->search_entry, + GTK_STATE_NORMAL, NULL); + sensitive = FALSE; } -} - -static void -viewitem_activated_cb(GtkWidget *widget, ESearchBar *esb) -{ - gint viewid; - GtkStyle *entry_style, *default_style; - widget = gtk_menu_get_active (GTK_MENU (esb->viewoption_menu)); + action = gtk_action_group_get_action ( + action_group, E_SEARCH_BAR_ACTION_CLEAR); + gtk_action_set_sensitive (action, sensitive); - viewid = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "EsbItemId")); - esb->viewitem_id = viewid; - - entry_style = gtk_widget_get_style (esb->entry); - default_style = gtk_widget_get_default_style (); - - /* If the text is grayed, Its not the query string */ - if (gdk_color_equal (&(entry_style->text[GTK_STATE_NORMAL]), &(default_style->text[GTK_STATE_INSENSITIVE]))) { - gtk_entry_set_text (GTK_ENTRY (esb->entry), ""); - gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, NULL); - } - - esb->block_search = TRUE; - emit_search_activated (esb); - esb->block_search = FALSE; + action = gtk_action_group_get_action ( + action_group, E_SEARCH_BAR_ACTION_FIND); + gtk_action_activate (action); } static void -scopeitem_activated_cb(GtkWidget *widget, ESearchBar *esb) -{ - gint scopeid; - GtkStyle *entry_style, *default_style; - - widget = gtk_menu_get_active (GTK_MENU (esb->scopeoption_menu)); - - scopeid = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "EsbItemId")); - esb->scopeitem_id = scopeid; - - entry_style = gtk_widget_get_style (esb->entry); - default_style = gtk_widget_get_default_style (); - - /* If the text is grayed, Its not the query string */ - if (gdk_color_equal (&(entry_style->text[GTK_STATE_NORMAL]), &(default_style->text[GTK_STATE_INSENSITIVE]))) { - gtk_widget_grab_focus (esb->entry); - gtk_entry_set_text (GTK_ENTRY (esb->entry), ""); - gtk_widget_modify_text (esb->entry, GTK_STATE_NORMAL, NULL); +search_bar_entry_changed_cb (ESearchBar *search_bar, + GtkWidget *entry) +{ + GtkActionGroup *action_group; + GtkAction *action; + GtkStyle *style1; + GtkStyle *style2; + GdkColor *color1; + GdkColor *color2; + gboolean sensitive; + const gchar *text; + + style1 = gtk_widget_get_style (entry); + style2 = gtk_widget_get_default_style (); + + text = gtk_entry_get_text (GTK_ENTRY (entry)); + + if (text != NULL && *text != '\0') { + color1 = &style1->text[GTK_STATE_NORMAL]; + color2 = &style2->text[GTK_STATE_INSENSITIVE]; + sensitive = !gdk_color_equal (color1, color2); + } else { + color1 = &style1->text[GTK_STATE_NORMAL]; + color2 = &style2->text[GTK_STATE_SELECTED]; + sensitive = gdk_color_equal (color1, color2); } - esb->block_search = TRUE; - emit_search_activated (esb); - esb->block_search = FALSE; + action_group = search_bar->priv->action_group; + action = gtk_action_group_get_action ( + action_group, E_SEARCH_BAR_ACTION_CLEAR); + gtk_action_set_sensitive (action, sensitive); } -static void -option_activated_cb (GtkWidget *widget, - ESearchBar *esb) +static gboolean +search_bar_entry_focus_in_cb (ESearchBar *search_bar, + GdkEventFocus *event, + GtkWidget *entry) { - int id; - const char *text; + GtkStyle *style1; + GtkStyle *style2; + GdkColor *color1; + GdkColor *color2; - id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "EsbItemId")); + style1 = gtk_widget_get_style (entry); + style2 = gtk_widget_get_default_style (); - e_search_bar_set_item_id (esb, id); + color1 = &style1->text[GTK_STATE_NORMAL]; + color2 = &style2->text[GTK_STATE_INSENSITIVE]; - if (GTK_IS_RADIO_MENU_ITEM (gtk_menu_get_active ( GTK_MENU (esb->option_menu)))) { - gchar *t; - text = get_selected_item_label (esb->option_menu); - if (text && *text) - t = g_strdup_printf ("%s: %s\n%s", _("Search"), text, _("Click here to change the search type")); - else - t = g_strdup_printf ("%s: %s", _("Search"), _("Click here to change the search type")); - - gtk_widget_set_tooltip_text (esb->option_button, t); - g_free (t); + if (gdk_color_equal (color1, color2)) { + gtk_entry_set_text (GTK_ENTRY (entry), ""); + gtk_widget_modify_text (entry, GTK_STATE_NORMAL, NULL); } - if (!esb->block_search) { - emit_query_changed (esb); - } - if (!esb->block_search && id > 0) { - emit_search_activated (esb); - } -} - -static void -option_button_clicked_cb (GtkWidget *widget, GdkEventButton *event, - ESearchBar *esb) -{ - gtk_menu_popup (GTK_MENU (esb->option_menu), NULL, NULL, NULL, NULL,1,gtk_get_current_event_time()); - - gtk_widget_grab_focus (esb->entry); -} - -static void -clear_button_clicked_cb (GtkWidget *widget, GdkEventButton *event, - ESearchBar *esb) -{ - 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); - gtk_widget_set_sensitive (esb->clear_button, FALSE); - - clear_search (esb); - gtk_entry_set_text (GTK_ENTRY (esb->entry), ""); - gtk_widget_grab_focus (esb->entry); + return FALSE; } static gboolean -entry_key_press_cb (GtkWidget *widget, - GdkEventKey *key_event, - ESearchBar *esb) +search_bar_entry_focus_out_cb (ESearchBar *search_bar, + GdkEventFocus *event, + GtkWidget *entry) { - if (((key_event->state & gtk_accelerator_get_default_mod_mask ()) == - GDK_MOD1_MASK) && (key_event->keyval == GDK_Down)) { - option_button_clicked_cb (NULL, NULL, esb); - return TRUE; - } - - return FALSE; + return paint_search_text (entry, search_bar); } -#if 0 -static void -scopeoption_changed_cb (GtkWidget *option_menu, ESearchBar *search_bar) +static gboolean +search_bar_entry_key_press_cb (ESearchBar *search_bar, + GdkEventKey *key_event, + GtkWidget *entry) { - char *text = NULL; - - text = e_search_bar_get_text (search_bar); - if (!(text && *text)) - gtk_widget_grab_focus (search_bar->entry); - - if(!search_bar->block_search) - emit_query_changed (search_bar); + guint state; - g_free (text); -} +#if 0 /* FIXME */ + state = key_event->state & gtk_accelerator_get_default_mod_mask (); + if (state == GDK_MOD1_MASK && key_event->keyval == GDK_Down) { + search_bar_option_clicked_cb (search_bar, NULL, NULL); + return TRUE; + } #endif - -/* Widgetry creation. */ - -#if 0 -/* This function exists to fix the irreparable GtkOptionMenu stupidity. In - fact, this lame-ass widget adds a 1-pixel-wide empty border around the - button for no reason. So we have add a 1-pixel-wide border around the the - buttons we have in the search bar to make things look right. This is done - through an event box. */ -static GtkWidget * -put_in_spacer_widget (GtkWidget *widget) -{ - GtkWidget *holder; - - holder = gtk_event_box_new (); - gtk_container_set_border_width (GTK_CONTAINER (holder), 1); - gtk_container_add (GTK_CONTAINER (holder), widget); - return holder; + return FALSE; } -#endif static void -append_xml_menu_item (GString *xml, - const char *name, - const char *label, - const char *stock, - const char *verb, - const char *accelerator) -{ - char *encoded_label; - - encoded_label = bonobo_ui_util_encode_str (label); - g_string_append_printf (xml, "<menuitem name=\"%s\" verb=\"%s\" label=\"%s\"", - name, verb, encoded_label); - g_free (encoded_label); - - if (accelerator != NULL) - g_string_append_printf (xml, " accel=\"%s\"", accelerator); - if (stock != NULL) - g_string_append_printf (xml, " pixtype=\"stock\" pixname=\"%s\"", stock); +search_bar_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_CONTEXT: + e_search_bar_set_context ( + E_SEARCH_BAR (object), + g_value_get_object (value)); + return; + + case PROP_FILTER_ACTION: + e_search_bar_set_filter_action ( + E_SEARCH_BAR (object), + g_value_get_object (value)); + return; + + case PROP_FILTER_VALUE: + e_search_bar_set_filter_value ( + E_SEARCH_BAR (object), + g_value_get_int (value)); + return; + + case PROP_FILTER_VISIBLE: + e_search_bar_set_filter_visible ( + E_SEARCH_BAR (object), + g_value_get_boolean (value)); + return; + + case PROP_SEARCH_ACTION: + e_search_bar_set_search_action ( + E_SEARCH_BAR (object), + g_value_get_object (value)); + return; + + case PROP_SEARCH_TEXT: + e_search_bar_set_search_text ( + E_SEARCH_BAR (object), + g_value_get_string (value)); + return; + + case PROP_SEARCH_VALUE: + e_search_bar_set_search_value ( + E_SEARCH_BAR (object), + g_value_get_int (value)); + return; + + case PROP_SEARCH_VISIBLE: + e_search_bar_set_search_visible ( + E_SEARCH_BAR (object), + g_value_get_boolean (value)); + return; + + case PROP_SCOPE_ACTION: + e_search_bar_set_scope_action ( + E_SEARCH_BAR (object), + g_value_get_object (value)); + return; + + case PROP_SCOPE_VALUE: + e_search_bar_set_scope_value ( + E_SEARCH_BAR (object), + g_value_get_int (value)); + return; + + case PROP_SCOPE_VISIBLE: + e_search_bar_set_scope_visible ( + E_SEARCH_BAR (object), + g_value_get_boolean (value)); + return; + } - g_string_append (xml, "/>"); + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } static void -remove_bonobo_menus (ESearchBar *esb) -{ - if (bonobo_ui_component_get_container (esb->ui_component) == CORBA_OBJECT_NIL) - return; +search_bar_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_CONTEXT: + g_value_set_object ( + value, e_search_bar_get_context ( + E_SEARCH_BAR (object))); + return; + + case PROP_FILTER_ACTION: + g_value_set_object ( + value, e_search_bar_get_filter_action ( + E_SEARCH_BAR (object))); + return; + + case PROP_FILTER_VALUE: + g_value_set_int ( + value, e_search_bar_get_filter_value ( + E_SEARCH_BAR (object))); + return; + + case PROP_FILTER_VISIBLE: + g_value_set_boolean ( + value, e_search_bar_get_filter_visible ( + E_SEARCH_BAR (object))); + return; + + case PROP_SEARCH_ACTION: + g_value_set_object ( + value, e_search_bar_get_search_action ( + E_SEARCH_BAR (object))); + return; + + case PROP_SEARCH_TEXT: + g_value_set_string ( + value, e_search_bar_get_search_text ( + E_SEARCH_BAR (object))); + return; + + case PROP_SEARCH_VALUE: + g_value_set_int ( + value, e_search_bar_get_search_value ( + E_SEARCH_BAR (object))); + return; + + case PROP_SEARCH_VISIBLE: + g_value_set_boolean ( + value, e_search_bar_get_search_visible ( + E_SEARCH_BAR (object))); + return; + + case PROP_SCOPE_ACTION: + g_value_set_object ( + value, e_search_bar_get_scope_action ( + E_SEARCH_BAR (object))); + return; + + case PROP_SCOPE_VALUE: + g_value_set_int ( + value, e_search_bar_get_scope_value ( + E_SEARCH_BAR (object))); + return; + + case PROP_SCOPE_VISIBLE: + g_value_set_boolean ( + value, e_search_bar_get_scope_visible ( + E_SEARCH_BAR (object))); + return; + } - bonobo_ui_component_rm (esb->ui_component, "/menu/SearchPlaceholder", NULL); + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } static void -setup_bonobo_menus (ESearchBar *esb) +search_bar_dispose (GObject *object) { - GString *xml; - GSList *p; - char *verb_name; - char *encoded_title; + ESearchBarPrivate *priv; - xml = g_string_new (""); + priv = E_SEARCH_BAR_GET_PRIVATE (object); - encoded_title = bonobo_ui_util_encode_str (_("_Search")); - g_string_append_printf (xml, "<submenu name=\"Search\" label=\"%s\">", encoded_title); - g_free (encoded_title); - - g_string_append (xml, "<placeholder name=\"SearchBar\">"); - - append_xml_menu_item (xml, "FindNow", _("_Find Now"), "gtk-find", "ESearchBar:FindNow", NULL); - append_xml_menu_item (xml, "Clear", _("_Clear"), "gtk-clear", "ESearchBar:Clear", "*Control**Shift*q"); - - for (p = esb->menu_items; p != NULL; p = p->next) { - const ESearchBarItem *item; - - item = (const ESearchBarItem *) p->data; - - verb_name = verb_name_from_id (item->id); - bonobo_ui_component_add_verb (esb->ui_component, verb_name, search_verb_cb, esb); - - if (item->text == NULL) - g_string_append (xml, "<separator/>"); - else - append_xml_menu_item (xml, verb_name, item->text, NULL, verb_name, NULL); - - g_free (verb_name); + if (priv->context != NULL) { + g_object_unref (priv->context); + priv->context = NULL; } - g_string_append (xml, "</placeholder>"); - g_string_append (xml, "</submenu>"); - - remove_bonobo_menus (esb); - bonobo_ui_component_set (esb->ui_component, "/menu/SearchPlaceholder", xml->str, NULL); - - g_string_free (xml, TRUE); - - if (esb->clear_button) { - g_signal_connect (esb->clear_button, "state-changed", G_CALLBACK (clear_button_state_changed), esb); + if (priv->filter_label != NULL) { + g_object_unref (priv->filter_label); + priv->filter_label = NULL; } -} - -static void -update_bonobo_menus (ESearchBar *esb) -{ - setup_bonobo_menus (esb); -} - -static void -set_menu (ESearchBar *esb, - ESearchBarItem *items) -{ - int i; - - free_menu_items (esb); - if (items == NULL) - return; - - for (i = 0; items[i].id != -1; i++) { - ESearchBarItem *new_item; - - new_item = g_new (ESearchBarItem, 1); - new_item->text = items[i].text ? g_strdup (_(items[i].text)) : NULL; - new_item->id = items[i].id; - new_item->type = items[i].type; - - esb->menu_items = g_slist_append (esb->menu_items, new_item); + if (priv->filter_combo_box != NULL) { + g_object_unref (priv->filter_combo_box); + priv->filter_combo_box = NULL; } if (!esb->lite && esb->ui_component != NULL) @@ -734,95 +663,277 @@ set_option (ESearchBar *esb, ESearchBarItem *items) gtk_widget_set_sensitive (item, FALSE); } - gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + if (priv->search_entry != NULL) { + g_object_unref (priv->search_entry); + priv->search_entry = NULL; + } - g_object_set_data (G_OBJECT (item), "EsbItemId", GINT_TO_POINTER(items[i].id)); + if (priv->scope_label != NULL) { + g_object_unref (priv->scope_label); + priv->scope_label = NULL; + } - g_signal_connect (item, "activate", - G_CALLBACK (option_activated_cb), - esb); + if (priv->scope_combo_box != NULL) { + g_object_unref (priv->scope_combo_box); + priv->scope_combo_box = NULL; } - gtk_widget_show_all (menu); - g_object_set_data (G_OBJECT(esb->option_menu), "group", group); - entry_focus_out_cb (esb->entry, NULL, esb); -} + if (priv->search_action != NULL) { + g_object_unref (priv->search_action); + priv->search_action = NULL; + } -static int -find_id (GtkWidget *menu, int idin, const char *type, GtkWidget **widget) -{ - GList *l = GTK_MENU_SHELL (menu)->children; - int row = -1, i = 0, id; - - if (widget) - *widget = NULL; - while (l) { - id = GPOINTER_TO_INT (g_object_get_data (l->data, type)); - if (id == idin) { - row = i; - if (widget) - *widget = l->data; - break; - } - i++; - l = l->next; + if (priv->action_group != NULL) { + g_object_unref (priv->action_group); + priv->action_group = NULL; } - return row; -} - -/* GtkObject methods. */ + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} static void -impl_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +search_bar_class_init (ESearchBarClass *class) { - ESearchBar *esb = E_SEARCH_BAR (object); - - switch (prop_id) { - case PROP_ITEM_ID: - g_value_set_int (value, e_search_bar_get_item_id (esb)); - break; - - case PROP_TEXT: - g_value_take_string (value, e_search_bar_get_text (esb)); - break; + GObjectClass *object_class; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (ESearchBarPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = search_bar_set_property; + object_class->get_property = search_bar_get_property; + object_class->dispose = search_bar_dispose; + + g_object_class_install_property ( + object_class, + PROP_CONTEXT, + g_param_spec_object ( + "context", + NULL, + NULL, + RULE_TYPE_CONTEXT, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_FILTER_ACTION, + g_param_spec_object ( + "filter-action", + NULL, + NULL, + GTK_TYPE_RADIO_ACTION, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_FILTER_VALUE, + g_param_spec_int ( + "filter-value", + NULL, + NULL, + G_MININT, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_FILTER_VISIBLE, + g_param_spec_boolean ( + "filter-visible", + NULL, + NULL, + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_SEARCH_ACTION, + g_param_spec_object ( + "search-action", + NULL, + NULL, + GTK_TYPE_RADIO_ACTION, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_SEARCH_TEXT, + g_param_spec_string ( + "search-text", + NULL, + NULL, + NULL, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_SEARCH_VALUE, + g_param_spec_int ( + "search-value", + NULL, + NULL, + G_MININT, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_SEARCH_VISIBLE, + g_param_spec_boolean ( + "search-visible", + NULL, + NULL, + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_SCOPE_ACTION, + g_param_spec_object ( + "scope-action", + NULL, + NULL, + GTK_TYPE_RADIO_ACTION, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_SCOPE_VALUE, + g_param_spec_int ( + "scope-value", + NULL, + NULL, + G_MININT, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_SCOPE_VISIBLE, + g_param_spec_boolean ( + "scope-visible", + NULL, + NULL, + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); } static void -impl_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +search_bar_init (ESearchBar *search_bar) { - ESearchBar *esb = E_SEARCH_BAR(object); + EIconEntry *icon_entry; + GtkActionGroup *action_group; + GtkAction *action; + GtkLabel *label; + GtkWidget *mnemonic; + GtkWidget *widget; - switch (prop_id) { - case PROP_ITEM_ID: - e_search_bar_set_item_id (esb, g_value_get_int (value)); - break; + search_bar->priv = E_SEARCH_BAR_GET_PRIVATE (search_bar); - case PROP_TEXT: - e_search_bar_set_text (esb, g_value_get_string (value)); - break; + gtk_box_set_spacing (GTK_BOX (search_bar), 3); + gtk_box_set_homogeneous (GTK_BOX (search_bar), FALSE); - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + /*** Filter Widgets ***/ + + /* 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... */ + widget = gtk_label_new_with_mnemonic (_("Sho_w: ")); + gtk_box_pack_start (GTK_BOX (search_bar), widget, FALSE, FALSE, 0); + search_bar->priv->filter_label = g_object_ref (widget); + gtk_widget_show (widget); + + label = GTK_LABEL (widget); + + widget = e_action_combo_box_new (); + gtk_label_set_mnemonic_widget (label, widget); + gtk_box_pack_start (GTK_BOX (search_bar), widget, FALSE, TRUE, 0); + search_bar->priv->filter_combo_box = g_object_ref (widget); + gtk_widget_show (widget); + + /*** Scope Widgets ***/ + + widget = e_action_combo_box_new (); + gtk_box_pack_end (GTK_BOX (search_bar), widget, FALSE, FALSE, 0); + search_bar->priv->scope_combo_box = g_object_ref (widget); + gtk_widget_show (widget); + + mnemonic = widget; + + /* Translators: The " in " label is part of the Quick Search Bar, + * example: Search: [_________________] in [ Current Folder ] */ + widget = gtk_label_new_with_mnemonic (_(" i_n ")); + gtk_label_set_mnemonic_widget (GTK_LABEL (widget), mnemonic); + gtk_box_pack_end (GTK_BOX (search_bar), widget, FALSE, FALSE, 0); + search_bar->priv->scope_label = g_object_ref (widget); + gtk_widget_show (widget); + + /*** Search Widgets ***/ + + widget = e_icon_entry_new (); + gtk_box_pack_end (GTK_BOX (search_bar), widget, FALSE, FALSE, 0); + search_bar->priv->search_entry = g_object_ref (widget); + gtk_widget_show (widget); + + icon_entry = E_ICON_ENTRY (widget); + + /* Translators: The "Search: " label is followed by the Quick Search + * Text input field where one enters the term to search for. */ + widget = gtk_label_new_with_mnemonic (_("Sear_ch: ")); + gtk_box_pack_end (GTK_BOX (search_bar), widget, FALSE, FALSE, 0); + search_bar->priv->search_label = g_object_ref (widget); + gtk_widget_show (widget); + + label = GTK_LABEL (widget); + + widget = e_icon_entry_get_entry (icon_entry); + gtk_label_set_mnemonic_widget (label, widget); + g_signal_connect_swapped ( + widget, "activate", + G_CALLBACK (search_bar_entry_activated_cb), search_bar); + g_signal_connect_swapped ( + widget, "changed", + G_CALLBACK (search_bar_entry_changed_cb), search_bar); + g_signal_connect_swapped ( + widget, "focus-in-event", + G_CALLBACK (search_bar_entry_focus_in_cb), search_bar); + g_signal_connect_swapped ( + widget, "focus-out-event", + G_CALLBACK (search_bar_entry_focus_out_cb), search_bar); + g_signal_connect_swapped ( + widget, "key-press-event", + G_CALLBACK (search_bar_entry_key_press_cb), search_bar); + + action_group = gtk_action_group_new ("search"); + gtk_action_group_set_translation_domain ( + action_group, GETTEXT_PACKAGE); + gtk_action_group_add_actions ( + action_group, search_entries, + G_N_ELEMENTS (search_entries), search_bar); + search_bar->priv->action_group = action_group; + + action = gtk_action_group_get_action ( + action_group, E_SEARCH_BAR_ACTION_TYPE); + e_icon_entry_add_action_start (icon_entry, action); + gtk_action_set_sensitive (action, FALSE); + + action = gtk_action_group_get_action ( + action_group, E_SEARCH_BAR_ACTION_CLEAR); + e_icon_entry_add_action_end (icon_entry, action); + gtk_action_set_sensitive (action, FALSE); } -static void -impl_dispose (GObject *object) +GType +e_search_bar_get_type (void) { - ESearchBar *esb = E_SEARCH_BAR (object); - - g_return_if_fail (object != NULL); - g_return_if_fail (E_IS_SEARCH_BAR (object)); - - /* These three we do need to unref, because we explicitly hold - references to them. */ + static GType type = 0; if (!esb->lite && esb->ui_component != NULL) { bonobo_object_unref (BONOBO_OBJECT (esb->ui_component)); @@ -837,139 +948,44 @@ impl_dispose (GObject *object) esb->suboption = NULL; } - if (esb->pending_activate) { - g_source_remove (esb->pending_activate); - esb->pending_activate = 0; + type = g_type_register_static ( + GTK_TYPE_HBOX, "ESearchBar", &type_info, 0); } - free_menu_items (esb); - - if (G_OBJECT_CLASS (parent_class)->dispose) - G_OBJECT_CLASS (parent_class)->dispose (object); + return type; } - -static void -class_init (ESearchBarClass *klass) +GtkWidget * +e_search_bar_new (void) { - GObjectClass *object_class; - - object_class = G_OBJECT_CLASS (klass); - - parent_class = g_type_class_ref (gtk_hbox_get_type ()); - - object_class->set_property = impl_set_property; - object_class->get_property = impl_get_property; - object_class->dispose = impl_dispose; - - klass->set_menu = set_menu; - klass->set_option = set_option; - - g_object_class_install_property (object_class, PROP_ITEM_ID, - g_param_spec_int ("item_id", - _("Item ID"), - /*_( */"XXX blurb" /*)*/, - 0, 0, 0, - G_PARAM_READWRITE | G_PARAM_LAX_VALIDATION)); - - g_object_class_install_property (object_class, PROP_TEXT, - g_param_spec_string ("text", - _("Text"), - /*_( */"XXX blurb" /*)*/, - NULL, - G_PARAM_READWRITE)); - - esb_signals [QUERY_CHANGED] = - g_signal_new ("query_changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ESearchBarClass, query_changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - esb_signals [MENU_ACTIVATED] = - g_signal_new ("menu_activated", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ESearchBarClass, menu_activated), - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, G_TYPE_INT); - - esb_signals [SEARCH_ACTIVATED] = - g_signal_new ("search_activated", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ESearchBarClass, search_activated), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - esb_signals [SEARCH_CLEARED] = - g_signal_new ("search_cleared", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ESearchBarClass, search_cleared), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); + return g_object_new (E_TYPE_SEARCH_BAR, NULL); } -static void -init (ESearchBar *esb) +GtkActionGroup * +e_search_bar_get_action_group (ESearchBar *search_bar) { - esb->ui_component = NULL; - esb->menu_items = NULL; - - esb->option = NULL; - esb->entry = NULL; - esb->suboption = NULL; - - esb->option_menu = NULL; - esb->suboption_menu = NULL; - esb->option_button = NULL; - esb->clear_button = NULL; - esb->entry_box = NULL; - - esb->scopeoption_menu = NULL; - esb->scopeoption = NULL; - esb->scopeoption_box = NULL; - - esb->pending_activate = 0; + g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), NULL); - esb->item_id = 0; - esb->scopeitem_id = 0; - esb->last_search_option = 0; - esb->block_search = FALSE; + return search_bar->priv->action_group; } - -/* Object construction. */ - -static gint -idle_activate_hack (gpointer ptr) +RuleContext * +e_search_bar_get_context (ESearchBar *search_bar) { - ESearchBar *esb = E_SEARCH_BAR (ptr); - esb->pending_activate = 0; - emit_search_activated (esb); - return FALSE; + g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), NULL); + + return search_bar->priv->context; } void -e_search_bar_construct (ESearchBar *search_bar, - ESearchBarItem *menu_items, - ESearchBarItem *option_items) +e_search_bar_set_context (ESearchBar *search_bar, + RuleContext *context) { - GtkWidget *label, *hbox, *bighbox; - - g_return_if_fail (search_bar != NULL); g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - g_return_if_fail (option_items != NULL); + g_return_if_fail (IS_RULE_CONTEXT (context)); - gtk_box_set_spacing (GTK_BOX (search_bar), 3); - - gtk_box_set_homogeneous (GTK_BOX (search_bar), FALSE); + if (search_bar->priv->context != NULL) + g_object_unref (search_bar->priv->context); bighbox = gtk_hbox_new (FALSE, 0); search_bar->entry_box = gtk_hbox_new (0, FALSE); @@ -1082,201 +1098,131 @@ e_search_bar_construct (ESearchBar *search_bar, search_bar->pending_activate = g_idle_add (idle_activate_hack, search_bar); } -void -e_search_bar_set_menu (ESearchBar *search_bar, ESearchBarItem *menu_items) +GtkRadioAction * +e_search_bar_get_filter_action (ESearchBar *search_bar) { - g_return_if_fail (search_bar != NULL); - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); + EActionComboBox *combo_box; - ((ESearchBarClass *) GTK_OBJECT_GET_CLASS (search_bar))->set_menu (search_bar, menu_items); -} + g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), NULL); -void -e_search_bar_add_menu (ESearchBar *search_bar, ESearchBarItem *menu_item) -{ - g_return_if_fail (search_bar != NULL); - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); + combo_box = E_ACTION_COMBO_BOX (search_bar->priv->filter_combo_box); - set_menu (search_bar, menu_item); + return e_action_combo_box_get_action (combo_box); } void -e_search_bar_set_option (ESearchBar *search_bar, ESearchBarItem *option_items) +e_search_bar_set_filter_action (ESearchBar *search_bar, + GtkRadioAction *action) { - g_return_if_fail (search_bar != NULL); + EActionComboBox *combo_box; + g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - g_return_if_fail (option_items != NULL); - ((ESearchBarClass *) GTK_OBJECT_GET_CLASS (search_bar))->set_option (search_bar, option_items); + combo_box = E_ACTION_COMBO_BOX (search_bar->priv->filter_combo_box); + + e_action_combo_box_set_action (combo_box, action); + g_object_notify (G_OBJECT (search_bar), "filter-action"); } -void -e_search_bar_set_viewoption_menufunc (ESearchBar *search_bar, ESearchBarMenuFunc *menu_gen_func, void *data) +gint +e_search_bar_get_filter_value (ESearchBar *search_bar) { - g_signal_connect (search_bar->viewoption, "button_press_event", G_CALLBACK (menu_gen_func), data); + EActionComboBox *combo_box; + + g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), 0); + + combo_box = E_ACTION_COMBO_BOX (search_bar->priv->filter_combo_box); + + return e_action_combo_box_get_current_value (combo_box); } -/** - * e_search_bar_set_viewoption_menu: - * @search_bar: A search bar. - * @option_id: Identifier of the main option menu item under which the subitems - * are to be set. - * @subitems: Array of subitem information. - * - * Sets the items for the secondary option menu of a search bar. - **/ void -e_search_bar_set_viewoption_menu (ESearchBar *search_bar, GtkWidget *menu) +e_search_bar_set_filter_value (ESearchBar *search_bar, + gint value) { + EActionComboBox *combo_box; - if (search_bar->viewoption_menu != NULL) - gtk_option_menu_remove_menu (GTK_OPTION_MENU (search_bar->viewoption)); + g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - search_bar->viewoption_menu = menu; - gtk_option_menu_set_menu (GTK_OPTION_MENU (search_bar->viewoption), search_bar->viewoption_menu); + combo_box = E_ACTION_COMBO_BOX (search_bar->priv->filter_combo_box); - g_signal_connect (search_bar->viewoption_menu, - "selection-done", - G_CALLBACK (viewitem_activated_cb), - search_bar); + e_action_combo_box_set_current_value (combo_box, value); + g_object_notify (G_OBJECT (search_bar), "filter-value"); } -GtkWidget * -e_search_bar_get_selected_viewitem (ESearchBar *search_bar) +gboolean +e_search_bar_get_filter_visible (ESearchBar *search_bar) { - GtkWidget *widget = NULL; + g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), FALSE); - widget = gtk_menu_get_active (GTK_MENU (search_bar->viewoption_menu)); - - return widget; + return GTK_WIDGET_VISIBLE (search_bar->priv->filter_combo_box); } -/** - * e_search_bar_set_viewoption: - * @search_bar: A search bar. - * @option_id: Identifier of the main option menu item under which the subitems - * are to be set. - * @subitems: Array of subitem information. - * - * Sets the items for the secondary option menu of a search bar. - **/ void -e_search_bar_set_viewoption (ESearchBar *search_bar, int option_id, ESearchBarItem *subitems) +e_search_bar_set_filter_visible (ESearchBar *search_bar, + gboolean visible) { - GtkWidget *menu; - GtkWidget *menu_item; - gint i; - - /* Create the menu if it is not there. right scenario ????*/ + g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - if (search_bar->viewoption_menu == NULL) { - search_bar->viewoption_menu = menu = gtk_menu_new (); + if (visible) { + gtk_widget_show (search_bar->priv->filter_label); + gtk_widget_show (search_bar->priv->filter_combo_box); } else { - gtk_option_menu_remove_menu (GTK_OPTION_MENU (search_bar->viewoption)); - search_bar->viewoption_menu = menu = gtk_menu_new (); + gtk_widget_hide (search_bar->priv->filter_label); + gtk_widget_hide (search_bar->priv->filter_combo_box); } - /* Create the items */ - - for (i = 0; subitems[i].id != -1; ++i) { - if (subitems[i].text) { - char *str = NULL; - str = e_str_without_underscores (subitems[i].text); - menu_item = gtk_menu_item_new_with_label (str); - g_free (str); - } else { - menu_item = gtk_menu_item_new (); - gtk_widget_set_sensitive (menu_item, FALSE); - } - - g_object_set_data (G_OBJECT (menu_item), "EsbItemId", - GINT_TO_POINTER (subitems[i].id)); - - g_signal_connect (menu_item, - "activate", - G_CALLBACK (viewitem_activated_cb), - search_bar); + g_object_notify (G_OBJECT (search_bar), "filter-visible"); +} - gtk_widget_show (menu_item); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); - } - gtk_option_menu_set_menu (GTK_OPTION_MENU (search_bar->viewoption), menu); +GtkRadioAction * +e_search_bar_get_search_action (ESearchBar *search_bar) +{ + g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), NULL); + return search_bar->priv->search_action; } -/** - * e_search_bar_set_scopeoption: - * @search_bar: A search bar. - * are to be set. - * @scopeitems: Array of scope information. - * - * Sets the items for the search scope option menu of a search bar. - **/ void -e_search_bar_set_scopeoption (ESearchBar *search_bar, ESearchBarItem *scopeitems) +e_search_bar_set_search_action (ESearchBar *search_bar, + GtkRadioAction *action) { - GtkWidget *menu; - GtkWidget *menu_item; - gint i; + g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - gtk_widget_show (search_bar->scopeoption_box); - if (search_bar->scopeoption_menu != NULL) { - gtk_option_menu_remove_menu (GTK_OPTION_MENU (search_bar->scopeoption)); + if (action != NULL) { + g_return_if_fail (GTK_IS_RADIO_ACTION (action)); + g_object_ref (action); } - search_bar->scopeoption_menu = menu = gtk_menu_new (); - - /* Generate items */ - for (i = 0; scopeitems[i].id != -1; ++i) { - if (scopeitems[i].text) { - char *str; - str = e_str_without_underscores (_(scopeitems[i].text)); - menu_item = gtk_menu_item_new_with_label (str); - g_object_set_data_full (G_OBJECT (menu_item), "string",str, g_free); - } else { - menu_item = gtk_menu_item_new (); - gtk_widget_set_sensitive (menu_item, FALSE); - } - - g_object_set_data (G_OBJECT (menu_item), "EsbItemId", - GINT_TO_POINTER (scopeitems[i].id)); + search_bar->priv->search_action = action; + search_bar_update_search_popup (search_bar); - g_signal_connect (menu_item, - "activate", - G_CALLBACK (scopeitem_activated_cb), - search_bar); - - gtk_widget_show (menu_item); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); - } - gtk_option_menu_set_menu (GTK_OPTION_MENU (search_bar->scopeoption), menu); + g_object_notify (G_OBJECT (search_bar), "search-action"); } -/** - * e_search_bar_set_scopeoption_menu: - * @search_bar: A search bar. - * @menu: the scope option menu - * - * Sets the items for the secondary option menu of a search bar. - **/ -void -e_search_bar_set_scopeoption_menu (ESearchBar *search_bar, GtkMenu *menu) +const gchar * +e_search_bar_get_search_text (ESearchBar *search_bar) { + EIconEntry *icon_entry; + GtkWidget *entry; + GtkStyle *style1; + GtkStyle *style2; + GdkColor *color1; + GdkColor *color2; - if (search_bar->scopeoption_menu != NULL) - gtk_option_menu_remove_menu (GTK_OPTION_MENU (search_bar->scopeoption)); + g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), NULL); - search_bar->scopeoption_menu = GTK_WIDGET (menu); - gtk_option_menu_set_menu (GTK_OPTION_MENU (search_bar->scopeoption), search_bar->scopeoption_menu); + icon_entry = E_ICON_ENTRY (search_bar->priv->search_entry); + entry = e_icon_entry_get_entry (icon_entry); - g_signal_connect (search_bar->scopeoption_menu, - "selection-done", - G_CALLBACK (scopeitem_activated_cb), - search_bar); -} + style1 = gtk_widget_get_style (entry); + style2 = gtk_widget_get_default_style (); + + color1 = &style1->text[GTK_STATE_NORMAL]; + color2 = &style2->text[GTK_STATE_INSENSITIVE]; GtkWidget * -e_search_bar_new (ESearchBarItem *menu_items, +e_search_bar_lite_new (ESearchBarItem *menu_items, ESearchBarItem *option_items) { GtkWidget *widget; @@ -1284,6 +1230,7 @@ e_search_bar_new (ESearchBarItem *menu_items, 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; e_search_bar_construct (E_SEARCH_BAR (widget), menu_items, option_items); @@ -1329,10 +1276,14 @@ e_search_bar_set_ui_component (ESearchBar *search_bar, } void -e_search_bar_set_menu_sensitive (ESearchBar *search_bar, int id, gboolean state) +e_search_bar_set_search_text (ESearchBar *search_bar, + const gchar *text) { - char *verb_name; - char *path; + EIconEntry *icon_entry; + GtkWidget *entry; + + if (search_bar->lite) + return; if (search_bar->lite) return; @@ -1341,68 +1292,40 @@ e_search_bar_set_menu_sensitive (ESearchBar *search_bar, int id, gboolean state) path = g_strconcat ("/commands/", verb_name, NULL); g_free (verb_name); - bonobo_ui_component_set_prop (search_bar->ui_component, path, - "sensitive", state ? "1" : "0", - NULL); + icon_entry = E_ICON_ENTRY (search_bar->priv->search_entry); + entry = e_icon_entry_get_entry (icon_entry); - g_free (path); + text = (text != NULL) ? text : ""; + gtk_entry_set_text (GTK_ENTRY (entry), text); + g_object_notify (G_OBJECT (search_bar), "search-text"); } -GType -e_search_bar_get_type (void) +gint +e_search_bar_get_search_value (ESearchBar *search_bar) { - static GType type = 0; + g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), 0); - if (!type) { - static const GTypeInfo info = { - sizeof (ESearchBarClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (ESearchBar), - 0, /* n_preallocs */ - (GInstanceInitFunc) init, - }; - - type = g_type_register_static (gtk_hbox_get_type (), "ESearchBar", &info, 0); - } - - return type; + /* FIXME */ + return 0; } void -e_search_bar_set_viewitem_id (ESearchBar *search_bar, int id) +e_search_bar_set_search_value (ESearchBar *search_bar, + gint value) { - int row; - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); if (!search_bar->viewoption_menu) return; - row = find_id (search_bar->viewoption_menu, id, "EsbItemId", NULL); - if (row == -1) - return; - search_bar->viewitem_id = id; - gtk_option_menu_set_history (GTK_OPTION_MENU (search_bar->viewoption), row); + /* FIXME */ - emit_query_changed (search_bar); + g_object_notify (G_OBJECT (search_bar), "search-value"); } -/** - * e_search_bar_set_item_id: - * @search_bar: A search bar. - * @id: Identifier of the item to set. - * - * Sets the active item in the options menu of a search bar. - **/ -void -e_search_bar_set_item_id (ESearchBar *search_bar, int id) +gboolean +e_search_bar_get_search_visible (ESearchBar *search_bar) { - int row; - - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); + g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), FALSE); if (!search_bar->option_menu) return; @@ -1423,217 +1346,170 @@ e_search_bar_set_item_id (ESearchBar *search_bar, int id) } void -e_search_bar_set_item_menu (ESearchBar *search_bar, int id) +e_search_bar_set_search_visible (ESearchBar *search_bar, + gboolean visible) { - int row; - GtkWidget *item; g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - row = find_id (search_bar->option_menu, id, "EsbItemId", &item); - if (row == -1) - return; + if (visible) { + gtk_widget_show (search_bar->priv->search_label); + gtk_widget_show (search_bar->priv->search_entry); + } else { + gtk_widget_hide (search_bar->priv->search_label); + gtk_widget_hide (search_bar->priv->search_entry); + } - gtk_menu_set_active ((GtkMenu *)search_bar->option_menu, row); - if (id>=0) - gtk_check_menu_item_set_active ((GtkCheckMenuItem *)item, TRUE); + g_object_notify (G_OBJECT (search_bar), "search-visible"); } -/** - * e_search_bar_set_search_scope: - * @search_bar: A search bar. - * @id: Identifier of the item to set. - * - * Sets the active item in the options menu of a search bar. - **/ -void -e_search_bar_set_search_scope (ESearchBar *search_bar, int id) +GtkRadioAction * +e_search_bar_get_scope_action (ESearchBar *search_bar) { - int row; + EActionComboBox *combo_box; - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - - row = find_id (search_bar->scopeoption_menu, id, "EsbItemId", NULL); - if (row == -1) - return; + g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), NULL); - search_bar->scopeitem_id = id; - gtk_option_menu_set_history (GTK_OPTION_MENU (search_bar->scopeoption), row); + combo_box = E_ACTION_COMBO_BOX (search_bar->priv->scope_combo_box); - if (!search_bar->block_search) - emit_query_changed (search_bar); + return e_action_combo_box_get_action (combo_box); } - -/** - * e_search_bar_get_item_id: - * @search_bar: A search bar. - * - * Queries the currently selected item in the options menu of a search bar. - * - * Return value: Identifier of the selected item in the options menu. - **/ -int -e_search_bar_get_item_id (ESearchBar *search_bar) +void +e_search_bar_set_scope_action (ESearchBar *search_bar, + GtkRadioAction *action) { - GtkWidget *menu_item; - gint item_id; + EActionComboBox *combo_box; - g_return_val_if_fail (search_bar != NULL, -1); - g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), -1); + g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); + g_return_if_fail (GTK_IS_RADIO_ACTION (action)); - menu_item = gtk_menu_get_active (GTK_MENU (search_bar->option_menu)); - item_id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menu_item), "EsbItemId")); - search_bar->item_id = item_id; + combo_box = E_ACTION_COMBO_BOX (search_bar->priv->scope_combo_box); - return search_bar->item_id; + e_action_combo_box_set_action (combo_box, action); + g_object_notify (G_OBJECT (search_bar), "scope-action"); } -/** - * e_search_bar_get_search_scope: - * @search_bar: A search bar. - * - * Queries the currently selected search type in the options menu of a search bar. - * - * Return value: Identifier of the selected item in the options menu. - **/ -int -e_search_bar_get_search_scope (ESearchBar *search_bar) +gint +e_search_bar_get_scope_value (ESearchBar *search_bar) { - GtkWidget *menu_item; - gint scopeitem_id; + EActionComboBox *combo_box; - g_return_val_if_fail (search_bar != NULL, -1); - g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), -1); + g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), 0); - menu_item = gtk_menu_get_active (GTK_MENU (search_bar->scopeoption_menu)); - scopeitem_id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menu_item), "EsbItemId")); + combo_box = E_ACTION_COMBO_BOX (search_bar->priv->scope_combo_box); - search_bar->scopeitem_id = scopeitem_id; - - return search_bar->scopeitem_id; + return e_action_combo_box_get_current_value (combo_box); } -/** - * e_search_bar_get_viewitem_id: - * @search_bar: A search bar. - * - * Queries the currently selected item in the viewoptions menu of a search bar. - * - * Return value: Identifier of the selected item in the viewoptions menu. - * If the search bar currently contains an entry rather than a a viewoption menu, - * a value less than zero is returned. - **/ -int -e_search_bar_get_viewitem_id (ESearchBar *search_bar) +void +e_search_bar_set_scope_value (ESearchBar *search_bar, + gint value) { - GtkWidget *menu_item; - gint viewitem_id; + EActionComboBox *combo_box; - g_return_val_if_fail (search_bar != NULL, -1); - g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), -1); + g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - if (!search_bar->viewoption_menu) - return -1; + combo_box = E_ACTION_COMBO_BOX (search_bar->priv->scope_combo_box); - menu_item = gtk_menu_get_active (GTK_MENU (search_bar->viewoption_menu)); - viewitem_id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (menu_item), "EsbItemId")); + e_action_combo_box_set_current_value (combo_box, value); + g_object_notify (G_OBJECT (search_bar), "scope-value"); +} - search_bar->viewitem_id = viewitem_id; +gboolean +e_search_bar_get_scope_visible (ESearchBar *search_bar) +{ + g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), FALSE); - return search_bar->viewitem_id; + return GTK_WIDGET_VISIBLE (search_bar->priv->scope_combo_box); } -/** - * e_search_bar_set_ids: - * @search_bar: A search bar. - * @item_id: Identifier of the item to set. - * @subitem_id: Identifier of the subitem to set. - * - * Sets the item and subitem ids for a search bar. This is intended to switch - * to an item that has subitems. - **/ void -e_search_bar_set_ids (ESearchBar *search_bar, int item_id, int subitem_id) +e_search_bar_set_scope_visible (ESearchBar *search_bar, + gboolean visible) { - int item_row; - GtkWidget *item_widget; - - g_return_if_fail (search_bar != NULL); g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - item_row = find_id (search_bar->option_menu, item_id, "EsbChoiceId", &item_widget); - if (item_row == -1 || !item_widget) - return; - - search_bar->item_id = item_id; - gtk_option_menu_set_history (GTK_OPTION_MENU (search_bar->option), item_row); + if (visible) { + gtk_widget_show (search_bar->priv->scope_label); + gtk_widget_show (search_bar->priv->scope_combo_box); + } else { + gtk_widget_hide (search_bar->priv->scope_label); + gtk_widget_hide (search_bar->priv->scope_combo_box); + } + g_object_notify (G_OBJECT (search_bar), "scope-visible"); } -/** - * e_search_bar_set_text: - * @search_bar: A search bar. - * @text: Text to set in the search bar's entry line. - * - * Sets the text string inside the entry line of a search bar. - **/ -void -e_search_bar_set_text (ESearchBar *search_bar, const char *text) +static void +search_bar_rule_changed_cb (FilterRule *rule, + GtkDialog *dialog) { - g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); - gtk_entry_set_text (GTK_ENTRY (search_bar->entry), text); + /* FIXME Think this does something with sensitivity. */ } -/** - * 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(). If a suboption menu is active instead - * of an entry, NULL is returned. - **/ -char * -e_search_bar_get_text (ESearchBar *search_bar) +void +e_search_bar_save_search_dialog (ESearchBar *search_bar, + const gchar *filename) { - GtkStyle *entry_style, *default_style; - - g_return_val_if_fail (search_bar != NULL, NULL); - g_return_val_if_fail (E_IS_SEARCH_BAR (search_bar), NULL); - - entry_style = gtk_widget_get_style (search_bar->entry); - default_style = gtk_widget_get_default_style (); - - if (gdk_color_equal (&(entry_style->text[GTK_STATE_NORMAL]), &(default_style->text[GTK_STATE_INSENSITIVE]))) - return g_strdup (""); - - return g_strdup (gtk_entry_get_text (GTK_ENTRY (search_bar->entry))); -} + RuleContext *context; + FilterRule *rule; + GtkWidget *dialog; + GtkWidget *parent; + GtkWidget *widget; + const gchar *search_text; + gchar *rule_name; -void e_search_bar_scope_enable (ESearchBar *esb, int did, gboolean state) -{ - GtkWidget *widget=NULL; - GList *l ; - int id; - gpointer *pointer; - - g_return_if_fail (esb != NULL); - g_return_if_fail (E_IS_SEARCH_BAR (esb)); - - l = GTK_MENU_SHELL (esb->scopeoption_menu)->children; - while (l) { - pointer = g_object_get_data (l->data, "EsbItemId"); - if (pointer) { - id = GPOINTER_TO_INT (pointer); - if (id == did) { - widget = l->data; - break; - } + g_return_if_fail (E_IS_SEARCH_BAR (search_bar)); + g_return_if_fail (filename != NULL); + + g_return_if_fail (search_bar->priv->current_query != NULL); + + rule = filter_rule_clone (search_bar->priv->current_query); + search_text = e_search_bar_get_search_text (search_bar); + if (search_text == NULL || *search_text == '\0') + search_text = "''"; + + rule_name = g_strdup_printf ("%s %s", rule->name, search_text); + filter_rule_set_name (rule, rule_name); + g_free (rule_name); + + parent = gtk_widget_get_toplevel (GTK_WIDGET (search_bar)); + + dialog = gtk_dialog_new_with_buttons ( + _("Save Search"), GTK_WINDOW (parent), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OK, GTK_RESPONSE_OK, + NULL); + + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); + gtk_window_set_default_size (GTK_WINDOW (dialog), 500, 300); + gtk_container_set_border_width ( + GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 0); + gtk_container_set_border_width ( + GTK_CONTAINER (GTK_DIALOG (dialog)->action_area), 12); + + context = search_bar->priv->context; + widget = filter_rule_get_widget (rule, context); + filter_rule_set_source (rule, FILTER_SOURCE_INCOMING); + gtk_container_set_border_width (GTK_CONTAINER (widget), 12); + gtk_box_pack_start ( + GTK_BOX (GTK_DIALOG (dialog)->vbox), + widget, TRUE, TRUE, 0); + + g_signal_connect ( + rule, "changed", + G_CALLBACK (search_bar_rule_changed_cb), + dialog); + + search_bar_rule_changed_cb (rule, GTK_DIALOG (dialog)); + + if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) { + if (filter_rule_validate (rule)) { + rule_context_add_rule (context, rule); + rule_context_save (context, filename); } - l = l->next; } - if (widget) - gtk_widget_set_sensitive (widget, state); + gtk_widget_destroy (dialog); } |