From 2c71859895d091f51dea23f9ed9552a0962b7ba4 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 4 Oct 2008 04:46:50 +0000 Subject: Tweak some aspects of the Contacts module to be more consistent with Tasks and Memos. Take a crack at handling command-line URIs. It's far too long-winded though. Will need to revisit and tighten up the code. svn path=/branches/kill-bonobo/; revision=36554 --- calendar/modules/e-memo-shell-module.c | 134 ++++++++++++++++++++++++- calendar/modules/e-memo-shell-view-actions.c | 4 +- calendar/modules/e-memo-shell-view-private.c | 48 +++++---- calendar/modules/e-task-shell-module.c | 140 ++++++++++++++++++++++++++- calendar/modules/e-task-shell-view-actions.c | 15 ++- calendar/modules/e-task-shell-view-private.c | 93 +++++++++++++++++- calendar/modules/e-task-shell-view-private.h | 1 + 7 files changed, 405 insertions(+), 30 deletions(-) (limited to 'calendar/modules') diff --git a/calendar/modules/e-memo-shell-module.c b/calendar/modules/e-memo-shell-module.c index 0590479bdb..c63f0fd958 100644 --- a/calendar/modules/e-memo-shell-module.c +++ b/calendar/modules/e-memo-shell-module.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -307,8 +308,137 @@ static gboolean memo_module_handle_uri (EShellModule *shell_module, const gchar *uri) { - /* FIXME */ - return FALSE; + CompEditor *editor; + CompEditorFlags flags = 0; + ECal *client; + ECalComponent *comp; + ESource *source; + ESourceList *source_list; + ECalSourceType source_type; + EUri *euri; + icalcomponent *icalcomp; + const gchar *cp; + gchar *source_uid = NULL; + gchar *comp_uid = NULL; + gchar *comp_rid = NULL; + gboolean handled = FALSE; + GError *error = NULL; + + source_type = E_CAL_SOURCE_TYPE_JOURNAL; + + if (strncmp (uri, "memo:", 5) != 0) + return FALSE; + + euri = e_uri_new (uri); + cp = euri->query; + if (cp == NULL) + goto exit; + + while (*cp != '\0') { + gchar *header; + gchar *content; + gsize header_len; + gsize content_len; + + header_len = strcspn (cp, "=&"); + + /* If it's malformed, give up. */ + if (cp[header_len] != '=') + break; + + header = (gchar *) cp; + header[header_len] = '\0'; + cp += header_len + 1; + + content_len = strcspn (cp, "&"); + + content = g_strndup (cp, content_len); + if (g_ascii_strcasecmp (header, "source-uid") == 0) + source_uid = g_strdup (content); + else if (g_ascii_strcasecmp (header, "comp-uid") == 0) + comp_uid = g_strdup (content); + else if (g_ascii_strcasecmp (header, "comp-rid") == 0) + comp_rid = g_strdup (content); + g_free (content); + + cp += content_len; + if (*cp == '&') { + cp++; + if (strcmp (cp, "amp;") == 0) + cp += 4; + } + } + + if (source_uid == NULL || comp_uid == NULL) + goto exit; + + /* URI is valid, so consider it handled. Whether + * we successfully open it is another matter... */ + handled = TRUE; + + if (!e_cal_get_sources (&source_list, source_type, NULL)) { + g_printerr ("Could not get memo sources from GConf!\n"); + goto exit; + } + + source = e_source_list_peek_source_by_uid (source_list, source_uid); + if (source == NULL) { + g_printerr ("No source for UID `%s'\n", source_uid); + g_object_unref (source_list); + goto exit; + } + + client = auth_new_cal_from_source (source, source_type); + if (client == NULL || !e_cal_open (client, TRUE, &error)) { + g_printerr ("%s\n", error->message); + g_object_unref (source_list); + g_error_free (error); + goto exit; + } + + /* XXX Copied from e_memo_shell_view_open_memo(). + * Clearly a new utility function is needed. */ + + editor = comp_editor_find_instance (comp_uid); + + if (editor != NULL) + goto present; + + if (!e_cal_get_object (client, comp_uid, comp_rid, &icalcomp, &error)) { + g_printerr ("%s\n", error->message); + g_object_unref (source_list); + g_error_free (error); + goto exit; + } + + comp = e_cal_component_new (); + e_cal_component_set_icalcomponent (comp, icalcomp); + + if (e_cal_component_has_organizer (comp)) + flags |= COMP_EDITOR_IS_SHARED; + + if (itip_organizer_is_user (comp, client)) + flags |= COMP_EDITOR_USER_ORG; + + editor = memo_editor_new (client, flags); + comp_editor_edit_comp (editor, comp); + + g_object_unref (comp); + +present: + gtk_window_present (GTK_WINDOW (editor)); + + g_object_unref (source_list); + g_object_unref (client); + +exit: + g_free (source_uid); + g_free (comp_uid); + g_free (comp_rid); + + e_uri_free (euri); + + return handled; } static void diff --git a/calendar/modules/e-memo-shell-view-actions.c b/calendar/modules/e-memo-shell-view-actions.c index 00b27de0b3..cbbaceaf9c 100644 --- a/calendar/modules/e-memo-shell-view-actions.c +++ b/calendar/modules/e-memo-shell-view-actions.c @@ -785,6 +785,6 @@ e_memo_shell_view_update_search_filter (EMemoShellView *memo_shell_view) /* 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); + ii = MEMO_FILTER_UNMATCHED; + e_shell_content_add_filter_separator_after (shell_content, ii); } diff --git a/calendar/modules/e-memo-shell-view-private.c b/calendar/modules/e-memo-shell-view-private.c index e8ff33570e..4c2312a9d2 100644 --- a/calendar/modules/e-memo-shell-view-private.c +++ b/calendar/modules/e-memo-shell-view-private.c @@ -322,6 +322,7 @@ e_memo_shell_view_execute_search (EMemoShellView *memo_shell_view) const gchar *format; const gchar *text; gchar *query; + gchar *temp; gint value; shell_view = E_SHELL_VIEW (memo_shell_view); @@ -364,27 +365,32 @@ e_memo_shell_view_execute_search (EMemoShellView *memo_shell_view) /* Apply selected filter. */ 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 >= 0) { - 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; + switch (value) { + case MEMO_FILTER_ANY_CATEGORY: + break; + + case MEMO_FILTER_UNMATCHED: + temp = g_strdup_printf ( + "(and (has-categories? #f) %s", query); + g_free (query); + query = temp; + break; + + default: + { + GList *categories; + const gchar *category_name; + + 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 diff --git a/calendar/modules/e-task-shell-module.c b/calendar/modules/e-task-shell-module.c index 010ba1f924..eba720ac6b 100644 --- a/calendar/modules/e-task-shell-module.c +++ b/calendar/modules/e-task-shell-module.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -307,8 +308,143 @@ static gboolean task_module_handle_uri (EShellModule *shell_module, const gchar *uri) { - /* FIXME */ - return FALSE; + CompEditor *editor; + CompEditorFlags flags = 0; + ECal *client; + ECalComponent *comp; + ESource *source; + ESourceList *source_list; + ECalSourceType source_type; + EUri *euri; + icalcomponent *icalcomp; + icalproperty *icalprop; + const gchar *cp; + gchar *source_uid = NULL; + gchar *comp_uid = NULL; + gchar *comp_rid = NULL; + gboolean handled = FALSE; + GError *error = NULL; + + source_type = E_CAL_SOURCE_TYPE_TODO; + + if (strncmp (uri, "task:", 5) != 0) + return FALSE; + + euri = e_uri_new (uri); + cp = euri->query; + if (cp == NULL) + goto exit; + + while (*cp != '\0') { + gchar *header; + gchar *content; + gsize header_len; + gsize content_len; + + header_len = strcspn (cp, "=&"); + + /* If it's malformed, give up. */ + if (cp[header_len] != '=') + break; + + header = (gchar *) cp; + header[header_len] = '\0'; + cp += header_len + 1; + + content_len = strcspn (cp, "&"); + + content = g_strndup (cp, content_len); + if (g_ascii_strcasecmp (header, "source-uid") == 0) + source_uid = g_strdup (content); + else if (g_ascii_strcasecmp (header, "comp-uid") == 0) + comp_uid = g_strdup (content); + else if (g_ascii_strcasecmp (header, "comp-rid") == 0) + comp_rid = g_strdup (content); + g_free (content); + + cp += content_len; + if (*cp == '&') { + cp++; + if (strcmp (cp, "amp;") == 0) + cp += 4; + } + } + + if (source_uid != NULL || comp_uid != NULL) + goto exit; + + /* URI is valid, so consider it handled. Whether + * we successfully open it is another matter... */ + handled = TRUE; + + if (!e_cal_get_sources (&source_list, source_type, NULL)) { + g_printerr ("Could not get task sources from GConf!\n"); + goto exit; + } + + source = e_source_list_peek_source_by_uid (source_list, source_uid); + if (source == NULL) { + g_printerr ("No source for UID `%s'\n", source_uid); + g_object_unref (source_list); + goto exit; + } + + client = auth_new_cal_from_source (source, source_type); + if (client == NULL || !e_cal_open (client, TRUE, &error)) { + g_printerr ("%s\n", error->message); + g_object_unref (source_list); + g_error_free (error); + goto exit; + } + + /* XXX Copied from e_task_shell_view_open_task(). + * Clearly a new utility function is needed. */ + + editor = comp_editor_find_instance (comp_uid); + + if (editor != NULL) + goto present; + + if (!e_cal_get_object (client, comp_uid, comp_rid, &icalcomp, &error)) { + g_printerr ("%s\n", error->message); + g_object_unref (source_list); + g_error_free (error); + goto exit; + } + + comp = e_cal_component_new (); + e_cal_component_set_icalcomponent (comp, icalcomp); + + icalprop = icalcomponent_get_first_property ( + icalcomp, ICAL_ATTENDEE_PROPERTY); + if (icalprop != NULL) + flags |= COMP_EDITOR_IS_ASSIGNED; + + if (itip_organizer_is_user (comp, client)) + flags |= COMP_EDITOR_USER_ORG; + + if (!e_cal_component_has_attendees (comp)) + flags |= COMP_EDITOR_USER_ORG; + + editor = task_editor_new (client, flags); + comp_editor_edit_comp (editor, comp); + + g_object_unref (comp); + +present: + gtk_window_present (GTK_WINDOW (editor)); + + g_object_unref (source_list); + g_object_unref (client); + +exit: + g_free (source_uid); + g_free (comp_uid); + g_free (comp_rid); + + e_uri_free (euri); + + return handled; } static void diff --git a/calendar/modules/e-task-shell-view-actions.c b/calendar/modules/e-task-shell-view-actions.c index 00911677fa..fe7331b4be 100644 --- a/calendar/modules/e-task-shell-view-actions.c +++ b/calendar/modules/e-task-shell-view-actions.c @@ -785,7 +785,14 @@ static GtkRadioActionEntry task_filter_entries[] = { N_("Tasks with Attachments"), NULL, NULL, /* XXX Add a tooltip! */ - TASK_FILTER_TASKS_WITH_ATTACHMENTS } + TASK_FILTER_TASKS_WITH_ATTACHMENTS }, + + { "task-filter-unmatched", + NULL, + N_("Unmatched"), + NULL, + NULL, /* XXX Add a tooltip! */ + TASK_FILTER_UNMATCHED } }; static GtkRadioActionEntry task_search_entries[] = { @@ -924,4 +931,10 @@ e_task_shell_view_update_search_filter (ETaskShellView *task_shell_view) /* Use any action in the group; doesn't matter which. */ e_shell_content_set_filter_action (shell_content, radio_action); + + ii = TASK_FILTER_UNMATCHED; + e_shell_content_add_filter_separator_after (shell_content, ii); + + ii = TASK_FILTER_TASKS_WITH_ATTACHMENTS; + e_shell_content_add_filter_separator_after (shell_content, ii); } diff --git a/calendar/modules/e-task-shell-view-private.c b/calendar/modules/e-task-shell-view-private.c index 825b039420..bd48cf3f23 100644 --- a/calendar/modules/e-task-shell-view-private.c +++ b/calendar/modules/e-task-shell-view-private.c @@ -321,7 +321,11 @@ e_task_shell_view_execute_search (ETaskShellView *task_shell_view) FilterRule *rule; const gchar *format; const gchar *text; + time_t start_range; + time_t end_range; + gchar *start, *end; gchar *query; + gchar *temp; gint value; shell_view = E_SHELL_VIEW (task_shell_view); @@ -364,7 +368,92 @@ e_task_shell_view_execute_search (ETaskShellView *task_shell_view) /* Apply selected filter. */ value = e_shell_content_get_filter_value (shell_content); - /* FIXME */ + switch (value) { + case TASK_FILTER_ANY_CATEGORY: + break; + + case TASK_FILTER_UNMATCHED: + temp = g_strdup_printf ( + "(and (has-categories? #f) %s)", query); + g_free (query); + query = temp; + break; + + case TASK_FILTER_NEXT_7_DAYS_TASKS: + start_range = time (NULL); + end_range = time_add_day (start_range, 7); + start = isodate_from_time_t (start_range); + end = isodate_from_time_t (end_range); + + temp = g_strdup_printf ( + "(and %s (due-in-time-range? " + "(make-time \"%s\") (make-time \"%s\")))", + query, start, end); + g_free (query); + query = temp; + break; + + case TASK_FILTER_ACTIVE_TASKS: + start_range = time (NULL); + end_range = time_add_day (start_range, 365); + start = isodate_from_time_t (start_range); + end = isodate_from_time_t (end_range); + + temp = g_strdup_printf ( + "(and %s (due-in-time-range? " + "(make-time \"%s\") (make-time \"%s\")) " + "(not (is-completed?)))", + query, start, end); + g_free (query); + query = temp; + break; + + case TASK_FILTER_OVERDUE_TASKS: + start_range = 0; + end_range = time (NULL); + start = isodate_from_time_t (start_range); + end = isodate_from_time_t (end_range); + + temp = g_strdup_printf ( + "(and %s (due-in-time-range? " + "(make-time \"%s\") (make-time \"%s\")) " + "(not (is-completed?)))", + query, start, end); + g_free (query); + query = temp; + break; + + case TASK_FILTER_COMPLETED_TASKS: + temp = g_strdup_printf ( + "(and (is-completed?) %s)", query); + g_free (query); + query = temp; + break; + + case TASK_FILTER_TASKS_WITH_ATTACHMENTS: + temp = g_strdup_printf ( + "(and (has-attachments?) %s)", query); + g_free (query); + query = temp; + break; + + default: + { + GList *categories; + const gchar *category_name; + + 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; + break; + } + } /* XXX This is wrong. We need to programmatically construct a * FilterRule, tell it to build code, and pass the resulting @@ -402,7 +491,7 @@ e_task_shell_view_open_task (ETaskShellView *task_shell_view, uid = icalcomponent_get_uid (comp_data->icalcomp); editor = comp_editor_find_instance (uid); - if (editor == NULL) + if (editor != NULL) goto exit; comp = e_cal_component_new (); diff --git a/calendar/modules/e-task-shell-view-private.h b/calendar/modules/e-task-shell-view-private.h index e5de26d721..4d059419cd 100644 --- a/calendar/modules/e-task-shell-view-private.h +++ b/calendar/modules/e-task-shell-view-private.h @@ -26,6 +26,7 @@ #include #include +#include #include #include -- cgit v1.2.3