aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@src.gnome.org>2008-09-30 11:25:23 +0800
committerMatthew Barnes <mbarnes@src.gnome.org>2008-09-30 11:25:23 +0800
commitc261a99bc4765ccb99206ed6105a323698b514c7 (patch)
treee31aad86711d0be181ac703713a79586c914c7f5
parent098ea8aad8d3249d9faca5df5b4fe67b94ba660f (diff)
downloadgsoc2013-evolution-c261a99bc4765ccb99206ed6105a323698b514c7.tar.gz
gsoc2013-evolution-c261a99bc4765ccb99206ed6105a323698b514c7.tar.zst
gsoc2013-evolution-c261a99bc4765ccb99206ed6105a323698b514c7.zip
Memos are mostly working now. Tasks to follow.
svn path=/branches/kill-bonobo/; revision=36495
-rw-r--r--addressbook/gui/component/e-book-shell-view-actions.c77
-rw-r--r--addressbook/gui/component/e-book-shell-view-private.h6
-rw-r--r--calendar/modules/e-cal-shell-view-private.c6
-rw-r--r--calendar/modules/e-cal-shell-view-private.h2
-rw-r--r--calendar/modules/e-memo-shell-content.c1
-rw-r--r--calendar/modules/e-memo-shell-sidebar.c95
-rw-r--r--calendar/modules/e-memo-shell-view-actions.c131
-rw-r--r--calendar/modules/e-memo-shell-view-actions.h10
-rw-r--r--calendar/modules/e-memo-shell-view-private.c129
-rw-r--r--calendar/modules/e-memo-shell-view-private.h16
-rw-r--r--calendar/modules/e-task-shell-view-private.c12
-rw-r--r--calendar/modules/e-task-shell-view-private.h2
-rw-r--r--e-util/e-util.c26
-rw-r--r--e-util/e-util.h2
-rw-r--r--shell/e-shell-content.c13
-rw-r--r--shell/e-shell-content.h3
-rw-r--r--shell/e-shell-window-actions.c10
-rw-r--r--widgets/misc/e-action-combo-box.c52
-rw-r--r--widgets/misc/e-action-combo-box.h3
19 files changed, 533 insertions, 63 deletions
diff --git a/addressbook/gui/component/e-book-shell-view-actions.c b/addressbook/gui/component/e-book-shell-view-actions.c
index f0acab8138..211487ca01 100644
--- a/addressbook/gui/component/e-book-shell-view-actions.c
+++ b/addressbook/gui/component/e-book-shell-view-actions.c
@@ -518,7 +518,7 @@ action_search_execute_cb (GtkAction *action,
/* Filter by category. */
value = e_shell_content_get_filter_value (shell_content);
- if (value >= 0) {
+ if (value >= CONTACT_FILTER_ANY_CATEGORY) {
GList *categories;
const gchar *category_name;
gchar *temp;
@@ -551,6 +551,15 @@ action_search_execute_cb (GtkAction *action,
e_book_shell_content_set_preview_contact (book_shell_content, NULL);
}
+static void
+action_search_filter_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ EBookShellView *book_shell_view)
+{
+ g_debug ("Contacts filter changed");
+ action_search_execute_cb (GTK_ACTION (current), book_shell_view);
+}
+
static GtkActionEntry contact_entries[] = {
{ "address-book-copy",
@@ -751,6 +760,16 @@ static GtkToggleActionEntry contact_toggle_entries[] = {
TRUE }
};
+static GtkRadioActionEntry contact_filter_entries[] = {
+
+ { "contact-filter-any-category",
+ NULL,
+ N_("Any Category"),
+ NULL,
+ NULL,
+ CONTACT_FILTER_ANY_CATEGORY }
+};
+
static GtkRadioActionEntry contact_search_entries[] = {
{ "contact-search-any-field-contains",
@@ -934,6 +953,10 @@ e_book_shell_view_actions_update (EBookShellView *book_shell_view)
action = ACTION (CONTACT_SEND_MESSAGE);
sensitive = (n_selected > 0);
gtk_action_set_sensitive (action, sensitive);
+ label = ngettext (
+ "_Send Message to Contact",
+ "_Send Message to Contacts", n_selected);
+ g_object_set (action, "label", label, NULL);
/* TODO Add some context sensitivity to SEND_MESSAGE:
* Send Message to Contact (n_selected == 1)
@@ -958,53 +981,55 @@ e_book_shell_view_update_search_filter (EBookShellView *book_shell_view)
EShellContent *shell_content;
EShellView *shell_view;
GtkActionGroup *action_group;
- GtkRadioAction *action;
+ GtkRadioAction *radio_action;
GList *list, *iter;
- GSList *group = NULL;
+ GSList *group;
gint ii;
shell_view = E_SHELL_VIEW (book_shell_view);
shell_content = e_shell_view_get_shell_content (shell_view);
action_group = book_shell_view->priv->filter_actions;
- /* XXX Annoying that GTK+ doesn't provide a function for this.
- * http://bugzilla.gnome.org/show_bug.cgi?id=550485 */
- list = gtk_action_group_list_actions (action_group);
- for (iter = list; iter != NULL; iter = iter->next)
- gtk_action_group_remove_action (action_group, iter->data);
- g_list_free (list);
+ e_action_group_remove_all_actions (action_group);
- action = gtk_radio_action_new (
- "category-any", _("Any Category"), NULL, NULL, -1);
+ /* Add the standard filter actions. */
+ gtk_action_group_add_radio_actions (
+ action_group, contact_filter_entries,
+ G_N_ELEMENTS (contact_filter_entries),
+ CONTACT_FILTER_ANY_CATEGORY,
+ G_CALLBACK (action_search_filter_cb),
+ book_shell_view);
- /* Activating the action executes a new search. */
- g_signal_connect (
- action, "activate",
- G_CALLBACK (action_search_execute_cb), book_shell_view);
+ /* Retrieve the radio group from an action we just added. */
+ list = gtk_action_group_list_actions (action_group);
+ radio_action = GTK_RADIO_ACTION (list->data);
+ group = gtk_radio_action_get_group (radio_action);
+ g_list_free (list);
- gtk_radio_action_set_group (action, group);
- group = gtk_radio_action_get_group (action);
+ /* Build the category actions. */
list = e_categories_get_list ();
for (iter = list, ii = 0; iter != NULL; iter = iter->next, ii++) {
const gchar *category_name = iter->data;
+ GtkAction *action;
gchar *action_name;
- action_name = g_strdup_printf ("category-%d", ii);
- action = gtk_radio_action_new (
+ action_name = g_strdup_printf (
+ "contact-filter-category-%d", ii);
+ radio_action = gtk_radio_action_new (
action_name, category_name, NULL, NULL, ii);
g_free (action_name);
- /* Activating the action executes a new search. */
- g_signal_connect (
- action, "activate", G_CALLBACK (
- action_search_execute_cb), book_shell_view);
+ gtk_radio_action_set_group (radio_action, group);
+ group = gtk_radio_action_get_group (radio_action);
- gtk_radio_action_set_group (action, group);
- group = gtk_radio_action_get_group (action);
+ /* The action group takes ownership of the action. */
+ action = GTK_ACTION (radio_action);
+ gtk_action_group_add_action (action_group, action);
+ g_object_unref (radio_action);
}
g_list_free (list);
/* Use any action in the group; doesn't matter which. */
- e_shell_content_set_filter_action (shell_content, action);
+ e_shell_content_set_filter_action (shell_content, radio_action);
}
diff --git a/addressbook/gui/component/e-book-shell-view-private.h b/addressbook/gui/component/e-book-shell-view-private.h
index 00a9249c2d..63ce28cc10 100644
--- a/addressbook/gui/component/e-book-shell-view-private.h
+++ b/addressbook/gui/component/e-book-shell-view-private.h
@@ -71,6 +71,12 @@ struct _EditorUidClosure {
EBookShellView *view;
};
+/* List these in the order to be displayed.
+ * Positive values are reserved for categories. */
+enum {
+ CONTACT_FILTER_ANY_CATEGORY
+};
+
/* List these in the order to be displayed. */
enum {
CONTACT_SEARCH_NAME_CONTAINS,
diff --git a/calendar/modules/e-cal-shell-view-private.c b/calendar/modules/e-cal-shell-view-private.c
index 97aada4a89..75d0e0e8db 100644
--- a/calendar/modules/e-cal-shell-view-private.c
+++ b/calendar/modules/e-cal-shell-view-private.c
@@ -133,11 +133,11 @@ e_cal_shell_view_private_constructed (ECalShellView *cal_shell_view)
g_signal_connect_swapped (
calendar, "dates-shown-changed",
- G_CALLBACK (e_cal_shell_view_sidebar_update),
+ G_CALLBACK (e_cal_shell_view_update_sidebar),
cal_shell_view);
e_shell_view_update_actions (shell_view);
- e_cal_shell_view_sidebar_update (cal_shell_view);
+ e_cal_shell_view_update_sidebar (cal_shell_view);
}
void
@@ -196,7 +196,7 @@ e_cal_shell_view_set_status_message (ECalShellView *cal_shell_view,
}
void
-e_cal_shell_view_sidebar_update (ECalShellView *cal_shell_view)
+e_cal_shell_view_update_sidebar (ECalShellView *cal_shell_view)
{
EShellView *shell_view;
EShellSidebar *shell_sidebar;
diff --git a/calendar/modules/e-cal-shell-view-private.h b/calendar/modules/e-cal-shell-view-private.h
index 645b514bf4..6960187508 100644
--- a/calendar/modules/e-cal-shell-view-private.h
+++ b/calendar/modules/e-cal-shell-view-private.h
@@ -93,7 +93,7 @@ void e_cal_shell_view_actions_init
void e_cal_shell_view_set_status_message
(ECalShellView *cal_shell_view,
const gchar *status_message);
-void e_cal_shell_view_sidebar_update
+void e_cal_shell_view_update_sidebar
(ECalShellView *cal_shell_view);
G_END_DECLS
diff --git a/calendar/modules/e-memo-shell-content.c b/calendar/modules/e-memo-shell-content.c
index 52055f5146..95a86ad5a9 100644
--- a/calendar/modules/e-memo-shell-content.c
+++ b/calendar/modules/e-memo-shell-content.c
@@ -336,6 +336,7 @@ memo_shell_content_constructed (GObject *object)
gtk_scrolled_window_set_shadow_type (
GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
gtk_paned_add2 (GTK_PANED (container), widget);
+ gtk_widget_show (widget);
container = widget;
diff --git a/calendar/modules/e-memo-shell-sidebar.c b/calendar/modules/e-memo-shell-sidebar.c
index 21948b87ed..5fed456f53 100644
--- a/calendar/modules/e-memo-shell-sidebar.c
+++ b/calendar/modules/e-memo-shell-sidebar.c
@@ -88,7 +88,28 @@ memo_shell_sidebar_emit_status_message (EMemoShellSidebar *memo_shell_sidebar,
static void
memo_shell_sidebar_update_timezone (EMemoShellSidebar *memo_shell_sidebar)
{
- /* FIXME */
+ GHashTable *client_table;
+ icaltimezone *zone;
+ GList *keys;
+
+ zone = calendar_config_get_icaltimezone ();
+ client_table = memo_shell_sidebar->priv->client_table;
+ keys = g_hash_table_get_values (client_table);
+
+ while (keys != NULL) {
+ ECal *client = keys->data;
+
+ if (e_cal_get_load_state (client) == E_CAL_LOAD_LOADED)
+ e_cal_set_default_timezone (client, zone, NULL);
+
+ keys = g_list_delete_link (keys, keys);
+ }
+
+ /* XXX Need to call e_memo_preview_set_default_timezone() here
+ * but the sidebar is not really supposed to access content
+ * stuff. I guess we could emit an "update-timezone" signal
+ * here, but that feels wrong. Maybe this whole thing should
+ * be in EMemoShellView instead. */
}
static void
@@ -171,6 +192,8 @@ memo_shell_sidebar_client_opened_cb (EMemoShellSidebar *memo_shell_sidebar,
shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
shell_window = e_shell_view_get_shell_window (shell_view);
+ g_debug ("%s (status = %d)", G_STRFUNC, status);
+
switch (status) {
case E_CALENDAR_STATUS_OK:
g_signal_handlers_disconnect_matched (
@@ -203,10 +226,60 @@ memo_shell_sidebar_client_opened_cb (EMemoShellSidebar *memo_shell_sidebar,
}
static void
+memo_shell_sidebar_row_changed_cb (EMemoShellSidebar *memo_shell_sidebar,
+ GtkTreePath *tree_path,
+ GtkTreeIter *tree_iter,
+ GtkTreeModel *tree_model)
+{
+ ESourceSelector *selector;
+ ESource *source;
+
+ /* XXX ESourceSelector's underlying tree store has only one
+ * column: ESource objects. While we're not supposed to
+ * know this, listening for "row-changed" signals from
+ * the model is easier to deal with than the selector's
+ * "selection-changed" signal, which doesn't tell you
+ * _which_ row changed. */
+
+ selector = e_memo_shell_sidebar_get_selector (memo_shell_sidebar);
+ gtk_tree_model_get (tree_model, tree_iter, 0, &source, -1);
+
+ /* XXX This signal gets emitted a lot while the model is being
+ * rebuilt, during which time we won't get a valid ESource.
+ * ESourceSelector should probably block this signal while
+ * rebuilding the model, but we'll be forgiving and not
+ * emit a warning. */
+ if (!E_IS_SOURCE (source))
+ return;
+
+ if (e_source_selector_source_is_selected (selector, source))
+ e_memo_shell_sidebar_add_source (memo_shell_sidebar, source);
+ else
+ e_memo_shell_sidebar_remove_source (memo_shell_sidebar, source);
+}
+
+static void
memo_shell_sidebar_selection_changed_cb (EMemoShellSidebar *memo_shell_sidebar,
ESourceSelector *selector)
{
- /* FIXME */
+ GSList *list, *iter;
+
+ /* This signal is emitted less frequently than "row-changed",
+ * especially when the model is being rebuilt. So we'll take
+ * it easy on poor GConf. */
+
+ list = e_source_selector_get_selection (selector);
+
+ for (iter = list; iter != NULL; iter = iter->next) {
+ ESource *source = iter->data;
+
+ iter->data = (gpointer) e_source_peek_uid (source);
+ g_object_unref (source);
+ }
+
+ calendar_config_set_memos_selected (list);
+
+ g_slist_free (list);
}
static void
@@ -216,6 +289,9 @@ memo_shell_sidebar_primary_selection_changed_cb (EMemoShellSidebar *memo_shell_s
ESource *source;
const gchar *uid;
+ /* XXX ESourceSelector needs a "primary-selection-uid" property
+ * so we can just bind the property with GConfBridge. */
+
source = e_source_selector_peek_primary_selection (selector);
if (source == NULL)
return;
@@ -283,6 +359,7 @@ memo_shell_sidebar_constructed (GObject *object)
ESourceList *source_list;
ESource *source;
GtkContainer *container;
+ GtkTreeModel *model;
GtkWidget *widget;
GSList *list, *iter;
gchar *uid;
@@ -316,6 +393,13 @@ memo_shell_sidebar_constructed (GObject *object)
priv->selector = g_object_ref (widget);
gtk_widget_show (widget);
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
+
+ g_signal_connect_swapped (
+ model, "row-changed",
+ G_CALLBACK (memo_shell_sidebar_row_changed_cb),
+ object);
+
g_signal_connect_swapped (
widget, "selection-changed",
G_CALLBACK (memo_shell_sidebar_selection_changed_cb),
@@ -352,8 +436,7 @@ memo_shell_sidebar_constructed (GObject *object)
if (source == NULL)
continue;
- e_source_selector_select_source (
- E_SOURCE_SELECTOR (priv->selector), source);
+ e_source_selector_select_source (selector, source);
}
g_slist_free (list);
}
@@ -532,6 +615,8 @@ e_memo_shell_sidebar_add_source (EMemoShellSidebar *memo_shell_sidebar,
uid = e_source_peek_uid (source);
client = g_hash_table_lookup (client_table, uid);
+ g_debug ("%s (%s): %s", G_STRFUNC, e_source_peek_relative_uri (source), client != NULL ? "Already added" : "Added");
+
if (client != NULL)
return;
@@ -582,6 +667,8 @@ e_memo_shell_sidebar_remove_source (EMemoShellSidebar *memo_shell_sidebar,
uid = e_source_peek_uid (source);
client = g_hash_table_lookup (client_table, uid);
+ g_debug ("%s (%s): %s", G_STRFUNC, e_source_peek_relative_uri (source), client == NULL ? "Already removed" : "Removed");
+
if (client == NULL)
return;
diff --git a/calendar/modules/e-memo-shell-view-actions.c b/calendar/modules/e-memo-shell-view-actions.c
index 6b6bac4fab..7c63447cc2 100644
--- a/calendar/modules/e-memo-shell-view-actions.c
+++ b/calendar/modules/e-memo-shell-view-actions.c
@@ -21,6 +21,23 @@
#include "e-memo-shell-view-private.h"
static void
+action_gal_save_custom_view_cb (GtkAction *action,
+ EMemoShellView *memo_shell_view)
+{
+ EMemoShellContent *memo_shell_content;
+ EShellView *shell_view;
+ GalViewInstance *view_instance;
+
+ shell_view = E_SHELL_VIEW (memo_shell_view);
+ if (!e_shell_view_is_active (shell_view))
+ return;
+
+ memo_shell_content = memo_shell_view->priv->memo_shell_content;
+ view_instance = e_memo_shell_content_get_view_instance (memo_shell_content);
+ gal_view_instance_save_as (view_instance);
+}
+
+static void
action_memo_clipboard_copy_cb (GtkAction *action,
EMemoShellView *memo_shell_view)
{
@@ -122,7 +139,7 @@ action_memo_list_copy_cb (GtkAction *action,
memo_shell_sidebar = memo_shell_view->priv->memo_shell_sidebar;
selector = e_memo_shell_sidebar_get_selector (memo_shell_sidebar);
source = e_source_selector_peek_primary_selection (selector);
- g_return_if_fail (source == NULL);
+ g_return_if_fail (E_IS_SOURCE (source));
copy_source_dialog (
GTK_WINDOW (shell_window),
@@ -158,7 +175,7 @@ action_memo_list_delete_cb (GtkAction *action,
memo_shell_sidebar = memo_shell_view->priv->memo_shell_sidebar;
selector = e_memo_shell_sidebar_get_selector (memo_shell_sidebar);
source = e_source_selector_peek_primary_selection (selector);
- g_return_if_fail (source == NULL);
+ g_return_if_fail (E_IS_SOURCE (source));
/* Ask for confirmation. */
response = e_error_run (
@@ -260,7 +277,7 @@ action_memo_list_properties_cb (GtkAction *action,
memo_shell_sidebar = memo_shell_view->priv->memo_shell_sidebar;
selector = e_memo_shell_sidebar_get_selector (memo_shell_sidebar);
source = e_source_selector_peek_primary_selection (selector);
- g_return_if_fail (source != NULL);
+ g_return_if_fail (E_IS_SOURCE (source));
calendar_setup_edit_memo_list (GTK_WINDOW (shell_window), source);
}
@@ -405,6 +422,27 @@ action_memo_save_as_cb (GtkAction *action,
g_free (string);
}
+static void
+action_search_execute_cb (GtkAction *action,
+ EMemoShellView *memo_shell_view)
+{
+ EShellView *shell_view;
+
+ shell_view = E_SHELL_VIEW (memo_shell_view);
+ if (!e_shell_view_is_active (shell_view))
+ return;
+
+ e_memo_shell_view_execute_search (memo_shell_view);
+}
+
+static void
+action_search_filter_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ EMemoShellView *memo_shell_view)
+{
+ e_memo_shell_view_execute_search (memo_shell_view);
+}
+
static GtkActionEntry memo_entries[] = {
{ "memo-clipboard-copy",
@@ -531,6 +569,23 @@ static GtkToggleActionEntry memo_toggle_entries[] = {
TRUE }
};
+static GtkRadioActionEntry memo_filter_entries[] = {
+
+ { "memo-filter-any-category",
+ NULL,
+ N_("Any Category"),
+ NULL,
+ NULL,
+ MEMO_FILTER_ANY_CATEGORY },
+
+ { "memo-filter-unmatched",
+ NULL,
+ N_("Unmatched"),
+ NULL,
+ NULL,
+ MEMO_FILTER_UNMATCHED }
+};
+
static GtkRadioActionEntry memo_search_entries[] = {
{ "memo-search-any-field-contains",
@@ -600,4 +655,74 @@ e_memo_shell_view_actions_init (EMemoShellView *memo_shell_view)
action = ACTION (MEMO_DELETE);
g_object_set (action, "short-label", _("Delete"), NULL);
+
+ g_signal_connect (
+ ACTION (GAL_SAVE_CUSTOM_VIEW), "activate",
+ G_CALLBACK (action_gal_save_custom_view_cb), memo_shell_view);
+
+ g_signal_connect (
+ ACTION (SEARCH_EXECUTE), "activate",
+ G_CALLBACK (action_search_execute_cb), memo_shell_view);
+}
+
+void
+e_memo_shell_view_update_search_filter (EMemoShellView *memo_shell_view)
+{
+ EShellContent *shell_content;
+ EShellView *shell_view;
+ GtkActionGroup *action_group;
+ GtkRadioAction *radio_action;
+ GList *list, *iter;
+ GSList *group;
+ gint ii;
+
+ shell_view = E_SHELL_VIEW (memo_shell_view);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ action_group = memo_shell_view->priv->filter_actions;
+
+ e_action_group_remove_all_actions (action_group);
+
+ /* Add the standard filter actions. */
+ gtk_action_group_add_radio_actions (
+ action_group, memo_filter_entries,
+ G_N_ELEMENTS (memo_filter_entries),
+ MEMO_FILTER_ANY_CATEGORY,
+ G_CALLBACK (action_search_filter_cb),
+ memo_shell_view);
+
+ /* Retrieve the radio group from an action we just added. */
+ list = gtk_action_group_list_actions (action_group);
+ radio_action = GTK_RADIO_ACTION (list->data);
+ group = gtk_radio_action_get_group (radio_action);
+ g_list_free (list);
+
+ /* Build the category actions. */
+
+ list = e_categories_get_list ();
+ for (iter = list, ii = 0; iter != NULL; iter = iter->next, ii++) {
+ const gchar *category_name = iter->data;
+ GtkAction *action;
+ gchar *action_name;
+
+ action_name = g_strdup_printf (
+ "memo-filter-category-%d", ii);
+ radio_action = gtk_radio_action_new (
+ action_name, category_name, NULL, NULL, ii);
+ g_free (action_name);
+
+ gtk_radio_action_set_group (radio_action, group);
+ group = gtk_radio_action_get_group (radio_action);
+
+ /* The action group takes ownership of the action. */
+ action = GTK_ACTION (radio_action);
+ gtk_action_group_add_action (action_group, action);
+ g_object_unref (radio_action);
+ }
+ g_list_free (list);
+
+ /* Use any action in the group; doesn't matter which. */
+ e_shell_content_set_filter_action (shell_content, radio_action);
+
+ e_shell_content_add_filter_separator_after (
+ shell_content, MEMO_FILTER_UNMATCHED);
}
diff --git a/calendar/modules/e-memo-shell-view-actions.h b/calendar/modules/e-memo-shell-view-actions.h
index 4ac71c2083..abaf9a9c2a 100644
--- a/calendar/modules/e-memo-shell-view-actions.h
+++ b/calendar/modules/e-memo-shell-view-actions.h
@@ -32,6 +32,10 @@
E_SHELL_WINDOW_ACTION ((window), "memo-clipboard-paste")
#define E_SHELL_WINDOW_ACTION_MEMO_DELETE(window) \
E_SHELL_WINDOW_ACTION ((window), "memo-delete")
+#define E_SHELL_WINDOW_ACTION_MEMO_FILTER_ANY_CATEGORY(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-filter-any-category")
+#define E_SHELL_WINDOW_ACTION_MEMO_FILTER_UNMATCHED(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-filter-unmatched")
#define E_SHELL_WINDOW_ACTION_MEMO_OPEN(window) \
E_SHELL_WINDOW_ACTION ((window), "memo-open")
#define E_SHELL_WINDOW_ACTION_MEMO_PREVIEW(window) \
@@ -40,6 +44,12 @@
E_SHELL_WINDOW_ACTION ((window), "memo-print")
#define E_SHELL_WINDOW_ACTION_MEMO_PRINT_PREVIEW(window) \
E_SHELL_WINDOW_ACTION ((window), "memo-print-preview")
+#define E_SHELL_WINDOW_ACTION_MEMO_SEARCH_ANY_FIELD_CONTAINS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-search-any-field-contains")
+#define E_SHELL_WINDOW_ACTION_MEMO_SEARCH_DESCRIPTION_CONTAINS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-search-description-contains")
+#define E_SHELL_WINDOW_ACTION_MEMO_SEARCH_SUMMARY_CONTAINS(window) \
+ E_SHELL_WINDOW_ACTION ((window), "memo-search-summary-contains")
/* Action Groups */
#define E_SHELL_WINDOW_ACTION_GROUP_MEMOS(window) \
diff --git a/calendar/modules/e-memo-shell-view-private.c b/calendar/modules/e-memo-shell-view-private.c
index 8d8a8e110d..0a95c998ec 100644
--- a/calendar/modules/e-memo-shell-view-private.c
+++ b/calendar/modules/e-memo-shell-view-private.c
@@ -49,6 +49,8 @@ memo_shell_view_table_user_created_cb (EMemoShellView *memo_shell_view,
memo_shell_sidebar = memo_shell_view->priv->memo_shell_sidebar;
e_memo_shell_sidebar_add_source (memo_shell_sidebar, source);
+
+ e_cal_model_add_client (model, client);
}
static void
@@ -158,6 +160,7 @@ e_memo_shell_view_private_init (EMemoShellView *memo_shell_view,
priv->source_list = g_object_ref (source_list);
priv->memo_actions = gtk_action_group_new ("memos");
+ priv->filter_actions = gtk_action_group_new ("memos-filter");
if (!gal_view_collection_loaded (shell_view_class->view_collection))
memo_shell_view_load_view_collection (shell_view_class);
@@ -173,15 +176,17 @@ e_memo_shell_view_private_constructed (EMemoShellView *memo_shell_view)
EMemoShellViewPrivate *priv = memo_shell_view->priv;
EMemoShellContent *memo_shell_content;
EMemoShellSidebar *memo_shell_sidebar;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
EShellContent *shell_content;
EShellSidebar *shell_sidebar;
- EShellView *shell_view;
EMemoTable *memo_table;
ECalModel *model;
ETable *table;
ESourceSelector *selector;
shell_view = E_SHELL_VIEW (memo_shell_view);
+ shell_window = e_shell_view_get_shell_window (shell_view);
shell_content = e_shell_view_get_shell_content (shell_view);
shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
@@ -224,22 +229,22 @@ e_memo_shell_view_private_constructed (EMemoShellView *memo_shell_view)
g_signal_connect_swapped (
model, "model-changed",
- G_CALLBACK (e_memo_shell_view_sidebar_update),
+ G_CALLBACK (e_memo_shell_view_update_sidebar),
memo_shell_view);
g_signal_connect_swapped (
model, "model-rows-deleted",
- G_CALLBACK (e_memo_shell_view_sidebar_update),
+ G_CALLBACK (e_memo_shell_view_update_sidebar),
memo_shell_view);
g_signal_connect_swapped (
model, "model-rows-inserted",
- G_CALLBACK (e_memo_shell_view_sidebar_update),
+ G_CALLBACK (e_memo_shell_view_update_sidebar),
memo_shell_view);
g_signal_connect_swapped (
table, "selection-change",
- G_CALLBACK (e_memo_shell_view_sidebar_update),
+ G_CALLBACK (e_memo_shell_view_update_sidebar),
memo_shell_view);
g_signal_connect_swapped (
@@ -262,8 +267,15 @@ e_memo_shell_view_private_constructed (EMemoShellView *memo_shell_view)
G_CALLBACK (e_shell_view_update_actions),
memo_shell_view);
+ e_categories_register_change_listener (
+ G_CALLBACK (e_memo_shell_view_update_search_filter),
+ memo_shell_view);
+
e_memo_shell_view_actions_init (memo_shell_view);
- e_memo_shell_view_sidebar_update (memo_shell_view);
+ e_memo_shell_view_update_sidebar (memo_shell_view);
+ e_memo_shell_view_update_search_filter (memo_shell_view);
+
+ e_memo_shell_view_execute_search (memo_shell_view);
}
void
@@ -274,6 +286,7 @@ e_memo_shell_view_private_dispose (EMemoShellView *memo_shell_view)
DISPOSE (priv->source_list);
DISPOSE (priv->memo_actions);
+ DISPOSE (priv->filter_actions);
DISPOSE (priv->memo_shell_content);
DISPOSE (priv->memo_shell_sidebar);
@@ -293,6 +306,105 @@ e_memo_shell_view_private_finalize (EMemoShellView *memo_shell_view)
}
void
+e_memo_shell_view_execute_search (EMemoShellView *memo_shell_view)
+{
+ EMemoShellContent *memo_shell_content;
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EShellContent *shell_content;
+ GtkAction *action;
+ GString *string;
+ EMemoPreview *memo_preview;
+ EMemoTable *memo_table;
+ ECalModel *model;
+ FilterRule *rule;
+ const gchar *format;
+ const gchar *text;
+ gchar *query;
+ gint value;
+
+ shell_view = E_SHELL_VIEW (memo_shell_view);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ text = e_shell_content_get_search_text (shell_content);
+
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ action = ACTION (MEMO_SEARCH_ANY_FIELD_CONTAINS);
+ value = gtk_radio_action_get_current_value (
+ GTK_RADIO_ACTION (action));
+
+ if (text == NULL || *text == '\0') {
+ text = "";
+ value = MEMO_SEARCH_SUMMARY_CONTAINS;
+ }
+
+ switch (value) {
+ default:
+ text = "";
+ /* fall through */
+
+ case MEMO_SEARCH_SUMMARY_CONTAINS:
+ format = "(contains? \"summary\" %s)";
+ break;
+
+ case MEMO_SEARCH_DESCRIPTION_CONTAINS:
+ format = "(contains? \"description\" %s)";
+ break;
+
+ case MEMO_SEARCH_ANY_FIELD_CONTAINS:
+ format = "(contains? \"any\" %s)";
+ break;
+ }
+
+ /* Build the query. */
+ string = g_string_new ("");
+ e_sexp_encode_string (string, text);
+ query = g_strdup_printf (format, string->str);
+ g_string_free (string, TRUE);
+
+ /* Filter by category. */
+ value = e_shell_content_get_filter_value (shell_content);
+ if (value == MEMO_FILTER_UNMATCHED) {
+ gchar *temp;
+
+ temp = g_strdup_printf (
+ "(and (has-categories? #f) %s", query);
+ g_free (query);
+ query = temp;
+ } else if (value != MEMO_FILTER_ANY_CATEGORY) {
+ GList *categories;
+ const gchar *category_name;
+ gchar *temp;
+
+ categories = e_categories_get_list ();
+ category_name = g_list_nth_data (categories, value);
+ g_list_free (categories);
+
+ temp = g_strdup_printf (
+ "(and (has-categories? \"%s\") %s)",
+ category_name, query);
+ g_free (query);
+ query = temp;
+ }
+
+ /* XXX This is wrong. We need to programmatically construct a
+ * FilterRule, tell it to build code, and pass the resulting
+ * expression string to ECalModel. */
+ rule = filter_rule_new ();
+ e_shell_content_set_search_rule (shell_content, rule);
+ g_object_unref (rule);
+
+ /* Submit the query. */
+ memo_shell_content = memo_shell_view->priv->memo_shell_content;
+ memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
+ model = e_memo_table_get_model (memo_table);
+ e_cal_model_set_search_query (model, query);
+ g_free (query);
+
+ memo_preview = e_memo_shell_content_get_memo_preview (memo_shell_content);
+ e_memo_preview_clear (memo_preview);
+}
+
+void
e_memo_shell_view_open_memo (EMemoShellView *memo_shell_view,
ECalModelComponent *comp_data)
{
@@ -356,11 +468,14 @@ e_memo_shell_view_set_status_message (EMemoShellView *memo_shell_view,
} else
e_activity_set_primary_text (activity, status_message);
+ if (status_message != NULL && *status_message != '\0')
+ g_debug ("Memos: %s", status_message);
+
memo_shell_view->priv->activity = activity;
}
void
-e_memo_shell_view_sidebar_update (EMemoShellView *memo_shell_view)
+e_memo_shell_view_update_sidebar (EMemoShellView *memo_shell_view)
{
EMemoShellContent *memo_shell_content;
EShellView *shell_view;
diff --git a/calendar/modules/e-memo-shell-view-private.h b/calendar/modules/e-memo-shell-view-private.h
index fd30a14898..b3e6404f26 100644
--- a/calendar/modules/e-memo-shell-view-private.h
+++ b/calendar/modules/e-memo-shell-view-private.h
@@ -25,6 +25,8 @@
#include <string.h>
#include <glib/gi18n.h>
+#include <libedataserver/e-categories.h>
+#include <libedataserver/e-sexp.h>
#include "e-util/e-dialog-utils.h"
#include "e-util/e-error.h"
@@ -63,6 +65,13 @@
G_BEGIN_DECLS
+/* List these in the order to be displayed.
+ * Positive values are reserved for categories. */
+enum {
+ MEMO_FILTER_ANY_CATEGORY = -2,
+ MEMO_FILTER_UNMATCHED = -1
+};
+
/* List these in the order to be displayed. */
enum {
MEMO_SEARCH_SUMMARY_CONTAINS,
@@ -79,6 +88,7 @@ struct _EMemoShellViewPrivate {
/*** UI Management ***/
GtkActionGroup *memo_actions;
+ GtkActionGroup *filter_actions;
/*** Other Stuff ***/
@@ -103,13 +113,17 @@ void e_memo_shell_view_private_finalize
void e_memo_shell_view_actions_init
(EMemoShellView *memo_shell_view);
+void e_memo_shell_view_execute_search
+ (EMemoShellView *memo_shell_view);
void e_memo_shell_view_open_memo
(EMemoShellView *memo_shell_view,
ECalModelComponent *comp_data);
void e_memo_shell_view_set_status_message
(EMemoShellView *memo_shell_view,
const gchar *status_message);
-void e_memo_shell_view_sidebar_update
+void e_memo_shell_view_update_sidebar
+ (EMemoShellView *memo_shell_view);
+void e_memo_shell_view_update_search_filter
(EMemoShellView *memo_shell_view);
G_END_DECLS
diff --git a/calendar/modules/e-task-shell-view-private.c b/calendar/modules/e-task-shell-view-private.c
index 8e573f538d..0b81de1186 100644
--- a/calendar/modules/e-task-shell-view-private.c
+++ b/calendar/modules/e-task-shell-view-private.c
@@ -321,26 +321,26 @@ e_task_shell_view_private_constructed (ETaskShellView *task_shell_view)
g_signal_connect_swapped (
model, "model-changed",
- G_CALLBACK (e_task_shell_view_sidebar_update),
+ G_CALLBACK (e_task_shell_view_update_sidebar),
task_shell_view);
g_signal_connect_swapped (
model, "model-rows-deleted",
- G_CALLBACK (e_task_shell_view_sidebar_update),
+ G_CALLBACK (e_task_shell_view_update_sidebar),
task_shell_view);
g_signal_connect_swapped (
model, "model-rows-inserted",
- G_CALLBACK (e_task_shell_view_sidebar_update),
+ G_CALLBACK (e_task_shell_view_update_sidebar),
task_shell_view);
g_signal_connect_swapped (
table, "selection-change",
- G_CALLBACK (e_task_shell_view_sidebar_update),
+ G_CALLBACK (e_task_shell_view_update_sidebar),
task_shell_view);
e_task_shell_view_actions_init (task_shell_view);
- e_task_shell_view_sidebar_update (task_shell_view);
+ e_task_shell_view_update_sidebar (task_shell_view);
}
void
@@ -451,7 +451,7 @@ e_task_shell_view_set_status_message (ETaskShellView *task_shell_view,
}
void
-e_task_shell_view_sidebar_update (ETaskShellView *task_shell_view)
+e_task_shell_view_update_sidebar (ETaskShellView *task_shell_view)
{
ETaskShellContent *task_shell_content;
EShellView *shell_view;
diff --git a/calendar/modules/e-task-shell-view-private.h b/calendar/modules/e-task-shell-view-private.h
index bad511ca20..2627545e3d 100644
--- a/calendar/modules/e-task-shell-view-private.h
+++ b/calendar/modules/e-task-shell-view-private.h
@@ -107,7 +107,7 @@ void e_task_shell_view_open_task
void e_task_shell_view_set_status_message
(ETaskShellView *task_shell_view,
const gchar *status_message);
-void e_task_shell_view_sidebar_update
+void e_task_shell_view_update_sidebar
(ETaskShellView *task_shell_view);
G_END_DECLS
diff --git a/e-util/e-util.c b/e-util/e-util.c
index 0055407068..0c737d08a3 100644
--- a/e-util/e-util.c
+++ b/e-util/e-util.c
@@ -140,6 +140,32 @@ e_load_ui_definition (GtkUIManager *ui_manager,
}
/**
+ * e_action_group_remove_all_actions:
+ * @action_group: a #GtkActionGroup
+ *
+ * Removes all actions from the action group.
+ **/
+void
+e_action_group_remove_all_actions (GtkActionGroup *action_group)
+{
+ GList *list, *iter;
+
+ /* XXX I've proposed this function for inclusion in GTK+.
+ * GtkActionGroup stores actions in an internal hash
+ * table and can do this more efficiently by calling
+ * g_hash_table_remove_all().
+ *
+ * http://bugzilla.gnome.org/show_bug.cgi?id=550485 */
+
+ g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
+
+ list = gtk_action_group_list_actions (action_group);
+ for (iter = list; iter != NULL; iter = iter->next)
+ gtk_action_group_remove_action (action_group, iter->data);
+ g_list_free (list);
+}
+
+/**
* e_str_without_underscores:
* @s: the string to strip underscores from.
*
diff --git a/e-util/e-util.h b/e-util/e-util.h
index a6aaa19a99..63cdafe058 100644
--- a/e-util/e-util.h
+++ b/e-util/e-util.h
@@ -46,6 +46,8 @@ void e_display_help (GtkWindow *parent,
const gchar *link_id);
guint e_load_ui_definition (GtkUIManager *ui_manager,
const gchar *basename);
+void e_action_group_remove_all_actions
+ (GtkActionGroup *action_group);
char * e_str_without_underscores (const char *s);
gint e_str_compare (gconstpointer x,
diff --git a/shell/e-shell-content.c b/shell/e-shell-content.c
index efa3b663f0..f3685793b7 100644
--- a/shell/e-shell-content.c
+++ b/shell/e-shell-content.c
@@ -1013,6 +1013,19 @@ e_shell_content_set_filter_visible (EShellContent *shell_content,
}
}
+void
+e_shell_content_add_filter_separator_after (EShellContent *shell_content,
+ gint action_value)
+{
+ EActionComboBox *combo_box;
+
+ g_return_if_fail (E_IS_SHELL_CONTENT (shell_content));
+
+ combo_box = E_ACTION_COMBO_BOX (shell_content->priv->filter_combo_box);
+
+ e_action_combo_box_add_separator_after (combo_box, action_value);
+}
+
RuleContext *
e_shell_content_get_search_context (EShellContent *shell_content)
{
diff --git a/shell/e-shell-content.h b/shell/e-shell-content.h
index defeb0a403..ae9d0446ab 100644
--- a/shell/e-shell-content.h
+++ b/shell/e-shell-content.h
@@ -82,6 +82,9 @@ gboolean e_shell_content_get_filter_visible
void e_shell_content_set_filter_visible
(EShellContent *shell_content,
gboolean filter_visible);
+void e_shell_content_add_filter_separator_after
+ (EShellContent *shell_content,
+ gint action_value);
RuleContext * e_shell_content_get_search_context
(EShellContent *shell_content);
FilterRule * e_shell_content_get_search_rule (EShellContent *shell_content);
diff --git a/shell/e-shell-window-actions.c b/shell/e-shell-window-actions.c
index 28920a7eb7..ab403c31dc 100644
--- a/shell/e-shell-window-actions.c
+++ b/shell/e-shell-window-actions.c
@@ -1727,7 +1727,6 @@ e_shell_window_create_switcher_actions (EShellWindow *shell_window)
gtk_action_group_add_action_with_accel (
action_group, GTK_ACTION (action), accelerator);
- g_debug ("Adding action '%s'", action_name);
e_shell_switcher_add_action (switcher, GTK_ACTION (action));
gtk_ui_manager_add_ui (
@@ -1767,7 +1766,6 @@ e_shell_window_update_view_menu (EShellWindow *shell_window)
GalViewCollection *view_collection;
GtkRadioAction *radio_action;
GtkAction *action;
- GList *list, *iter;
GSList *radio_group;
gboolean visible;
const gchar *path;
@@ -1789,13 +1787,7 @@ e_shell_window_update_view_menu (EShellWindow *shell_window)
/* Unmerge the previous menu. */
gtk_ui_manager_remove_ui (ui_manager, merge_id);
-
- /* XXX Annoying that GTK+ doesn't provide a function for this.
- * http://bugzilla.gnome.org/show_bug.cgi?id=550485 */
- list = gtk_action_group_list_actions (action_group);
- for (iter = list; iter != NULL; iter = iter->next)
- gtk_action_group_remove_action (action_group, iter->data);
- g_list_free (list);
+ e_action_group_remove_all_actions (action_group);
/* We have a view ID, so forge ahead. */
count = gal_view_collection_get_count (view_collection);
diff --git a/widgets/misc/e-action-combo-box.c b/widgets/misc/e-action-combo-box.c
index 5e32268431..e826fb2a54 100644
--- a/widgets/misc/e-action-combo-box.c
+++ b/widgets/misc/e-action-combo-box.c
@@ -98,6 +98,10 @@ action_combo_box_render_pixbuf (GtkCellLayout *layout,
gtk_tree_model_get (model, iter, COLUMN_ACTION, &action, -1);
+ /* A NULL action means the row is a separator. */
+ if (action == NULL)
+ return;
+
g_object_get (
G_OBJECT (action),
"icon-name", &icon_name,
@@ -134,6 +138,10 @@ action_combo_box_render_text (GtkCellLayout *layout,
gtk_tree_model_get (model, iter, COLUMN_ACTION, &action, -1);
+ /* A NULL action means the row is a separator. */
+ if (action == NULL)
+ return;
+
g_object_get (
G_OBJECT (action),
"label", &label,
@@ -157,6 +165,22 @@ action_combo_box_render_text (GtkCellLayout *layout,
g_free (label);
}
+static gboolean
+action_combo_box_is_row_separator (GtkTreeModel *model,
+ GtkTreeIter *iter)
+{
+ GtkAction *action;
+ gboolean separator;
+
+ /* NULL actions are rendered as separators. */
+ gtk_tree_model_get (model, iter, COLUMN_ACTION, &action, -1);
+ separator = (action == NULL);
+ if (action != NULL)
+ g_object_unref (action);
+
+ return separator;
+}
+
static void
action_combo_box_update_model (EActionComboBox *combo_box)
{
@@ -170,8 +194,11 @@ action_combo_box_update_model (EActionComboBox *combo_box)
return;
}
+ /* We store values in the sort column as floats so that we can
+ * insert separators in between consecutive integer values and
+ * still maintain the proper ordering. */
list_store = gtk_list_store_new (
- 2, GTK_TYPE_RADIO_ACTION, G_TYPE_INT);
+ 2, GTK_TYPE_RADIO_ACTION, G_TYPE_FLOAT);
list = gtk_radio_action_get_group (combo_box->priv->action);
@@ -186,7 +213,7 @@ action_combo_box_update_model (EActionComboBox *combo_box)
g_object_get (G_OBJECT (action), "value", &value, NULL);
gtk_list_store_set (
list_store, &iter, COLUMN_ACTION,
- list->data, COLUMN_SORT, value, -1);
+ list->data, COLUMN_SORT, (gfloat) value, -1);
path = gtk_tree_model_get_path (
GTK_TREE_MODEL (list_store), &iter);
@@ -349,6 +376,10 @@ action_combo_box_init (EActionComboBox *combo_box)
(GtkCellLayoutDataFunc) action_combo_box_render_text,
combo_box, NULL);
+ gtk_combo_box_set_row_separator_func (
+ GTK_COMBO_BOX (combo_box), (GtkTreeViewRowSeparatorFunc)
+ action_combo_box_is_row_separator, NULL, NULL);
+
combo_box->priv->index = g_hash_table_new_full (
g_direct_hash, g_direct_equal,
(GDestroyNotify) NULL,
@@ -477,3 +508,20 @@ e_action_combo_box_set_current_value (EActionComboBox *combo_box,
gtk_radio_action_set_current_value (
combo_box->priv->action, current_value);
}
+
+void
+e_action_combo_box_add_separator_after (EActionComboBox *combo_box,
+ gint action_value)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ g_return_if_fail (E_ACTION_IS_COMBO_BOX (combo_box));
+
+ /* NULL actions are rendered as separators. */
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box));
+ gtk_list_store_append (GTK_LIST_STORE (model), &iter);
+ gtk_list_store_set (
+ GTK_LIST_STORE (model), &iter, COLUMN_ACTION,
+ NULL, COLUMN_SORT, (gfloat) action_value + 0.5, -1);
+}
diff --git a/widgets/misc/e-action-combo-box.h b/widgets/misc/e-action-combo-box.h
index 452c3fa265..7327c4723b 100644
--- a/widgets/misc/e-action-combo-box.h
+++ b/widgets/misc/e-action-combo-box.h
@@ -73,6 +73,9 @@ gint e_action_combo_box_get_current_value
void e_action_combo_box_set_current_value
(EActionComboBox *combo_box,
gint current_value);
+void e_action_combo_box_add_separator_after
+ (EActionComboBox *combo_box,
+ gint action_value);
G_END_DECLS