diff options
-rw-r--r-- | calendar/ChangeLog | 53 | ||||
-rw-r--r-- | calendar/calendar.error.xml | 5 | ||||
-rw-r--r-- | calendar/gui/calendar-component.c | 97 | ||||
-rw-r--r-- | calendar/gui/dialogs/comp-editor-page.h | 1 | ||||
-rw-r--r-- | calendar/gui/dialogs/comp-editor.h | 1 | ||||
-rw-r--r-- | calendar/gui/dialogs/memo-editor.c | 14 | ||||
-rw-r--r-- | calendar/gui/dialogs/memo-editor.h | 2 | ||||
-rw-r--r-- | calendar/gui/dialogs/memo-page.c | 450 | ||||
-rw-r--r-- | calendar/gui/dialogs/memo-page.glade | 235 | ||||
-rw-r--r-- | calendar/gui/dialogs/memo-page.h | 2 | ||||
-rw-r--r-- | calendar/gui/e-cal-component-memo-preview.c | 57 | ||||
-rw-r--r-- | calendar/gui/e-cal-model.c | 5 | ||||
-rw-r--r-- | calendar/gui/e-memo-table-config.c | 11 | ||||
-rw-r--r-- | calendar/gui/e-memo-table.c | 91 | ||||
-rw-r--r-- | calendar/gui/e-memo-table.etspec | 8 | ||||
-rw-r--r-- | calendar/gui/e-memo-table.h | 3 | ||||
-rw-r--r-- | calendar/gui/gnome-cal.c | 270 | ||||
-rw-r--r-- | calendar/gui/gnome-cal.h | 3 | ||||
-rw-r--r-- | calendar/gui/memos-component.c | 42 |
19 files changed, 1278 insertions, 72 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog index af348dac7a..525de944c1 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,56 @@ +2006-07-22 Chenthill Palanisamy <pchenthill@novell.com> + + * calendar.error.xml: + * gui/calendar-component.c: (update_task_memo_selection), + (update_primary_task_memo_selection), + (config_tasks_selection_changed_cb), + (config_primary_tasks_selection_changed_cb), + (config_memos_selection_changed_cb), + (config_primary_memos_selection_changed_cb), + (create_component_view), (destroy_component_view), + (calendar_component_init): + * gui/dialogs/comp-editor-page.h: + * gui/dialogs/comp-editor.h: + * gui/dialogs/memo-editor.c: (memo_editor_construct), + (memo_editor_edit_comp), (memo_editor_new): + * gui/dialogs/memo-editor.h: + * gui/dialogs/memo-page.c: (memo_page_init), (memo_page_finalize), + (memo_page_focus_main_widget), (clear_widgets), + (sensitize_widgets), (memo_page_fill_widgets), + (fill_comp_with_recipients), (get_current_account), + (memo_page_fill_component), (get_widgets), (to_button_clicked_cb), + (response_cb), (init_widgets), (get_to_entry), + (memo_page_construct), (memo_page_new), + (memo_page_create_date_edit): + * gui/dialogs/memo-page.glade: + * gui/dialogs/memo-page.h: + * gui/e-cal-component-memo-preview.c: (timet_to_str_with_zone), + (write_html): + * gui/e-cal-model.c: (ecm_value_at): + * gui/e-memo-table-config.c: (e_memo_table_config_set_table): + * gui/e-memo-table.c: (date_compare_cb), (e_memo_table_init), + (open_memo), (e_memo_table_get_current_time): + * gui/e-memo-table.etspec: + * gui/e-memo-table.h: + * gui/gnome-cal.c: (gnome_calendar_class_init), + (get_focus_location), (memo_canvas_focus_change_cb), + (memo_selection_change_cb), (update_memo_view), (setup_config), + (view_progress_cb), (view_done_cb), (setup_widgets), + (gnome_calendar_init), (gnome_calendar_destroy), + (gnome_calendar_set_pane_positions), (client_cal_opened_cb), + (default_client_cal_opened_cb), (open_ecal), (backend_died_cb), + (gnome_calendar_remove_source_by_uid), + (gnome_calendar_vpane_realized), (gnome_calendar_vpane_resized), + (gnome_calendar_cut_clipboard), (gnome_calendar_copy_clipboard), + (gnome_calendar_paste_clipboard), + (gnome_calendar_notify_dates_shown_changed), + (gnome_calendar_delete_selection), + (gnome_calendar_get_memopad_menu): + * gui/gnome-cal.h: + * gui/memos-component.c: (create_new_memo), (create_local_item_cb), + (impl__get_userCreatableItems), (impl_requestCreateItem): Added support + shared memos, Gw notes. + 2006-07-21 Andre Klapper <a9016009@gmx.de> * calendar.error.xml: improve calendar read-only error message. diff --git a/calendar/calendar.error.xml b/calendar/calendar.error.xml index a6e69a7dc7..1d6cc8efc0 100644 --- a/calendar/calendar.error.xml +++ b/calendar/calendar.error.xml @@ -171,6 +171,11 @@ <_secondary>Your calendars will not be available until Evolution is restarted.</_secondary> </error> + <error id="memos-crashed" type="error"> + <_primary>The Evolution memo has quit unexpectedly.</_primary> + <_secondary>Your memos will not be available until Evolution is restarted.</_secondary> + </error> + <error id="editor-error" type="error"> <_primary>Editor could not be loaded.</_primary> <_secondary>{0}.</_secondary> diff --git a/calendar/gui/calendar-component.c b/calendar/gui/calendar-component.c index 2cc987e31d..c125b0a241 100644 --- a/calendar/gui/calendar-component.c +++ b/calendar/gui/calendar-component.c @@ -86,9 +86,11 @@ typedef struct { ESourceList *source_list; ESourceList *task_source_list; + ESourceList *memo_source_list; GSList *source_selection; GSList *task_source_selection; + GSList *memo_source_selection; GnomeCalendar *calendar; @@ -117,6 +119,7 @@ struct _CalendarComponentPrivate { ESourceList *source_list; ESourceList *task_source_list; + ESourceList *memo_source_list; GList *views; @@ -406,39 +409,52 @@ update_selection (CalendarComponentView *component_view) } static void -update_task_selection (CalendarComponentView *component_view) +update_task_memo_selection (CalendarComponentView *component_view, ECalSourceType type) { - GSList *uids_selected, *l; - - /* Get the selection in gconf */ - uids_selected = calendar_config_get_tasks_selected (); + GSList *uids_selected, *l, *source_selection; + ESourceList *source_list = NULL; + + if (type == E_CAL_SOURCE_TYPE_TODO) { + /* Get the selection in gconf */ + uids_selected = calendar_config_get_tasks_selected (); + source_list = component_view->task_source_list; + source_selection = component_view->task_source_selection; + + } else { + uids_selected = calendar_config_get_memos_selected (); + source_list = component_view->memo_source_list; + source_selection = component_view->memo_source_selection; + } /* Remove any that aren't there any more */ - for (l = component_view->task_source_selection; l; l = l->next) { + for (l = source_selection; l; l = l->next) { char *uid = l->data; ESource *source; - source = e_source_list_peek_source_by_uid (component_view->task_source_list, uid); + source = e_source_list_peek_source_by_uid (component_view->source_list, uid); if (!source) - gnome_calendar_remove_source_by_uid (component_view->calendar, E_CAL_SOURCE_TYPE_TODO, uid); + gnome_calendar_remove_source_by_uid (component_view->calendar, type, uid); else if (!is_in_uids (uids_selected, source)) - gnome_calendar_remove_source (component_view->calendar, E_CAL_SOURCE_TYPE_TODO, source); + gnome_calendar_remove_source (component_view->calendar, type, source); g_free (uid); } - g_slist_free (component_view->task_source_selection); + g_slist_free (source_selection); /* Make sure the whole selection is there */ for (l = uids_selected; l; l = l->next) { char *uid = l->data; ESource *source; - source = e_source_list_peek_source_by_uid (component_view->task_source_list, uid); - if (source && !gnome_calendar_add_source (component_view->calendar, E_CAL_SOURCE_TYPE_TODO, source)) + source = e_source_list_peek_source_by_uid (source_list, uid); + if (source && !gnome_calendar_add_source (component_view->calendar, type, source)) /* FIXME do something */; } - component_view->task_source_selection = uids_selected; + if (type == E_CAL_SOURCE_TYPE_TODO) + component_view->task_source_selection = uids_selected; + else + component_view->memo_source_selection = uids_selected; } static void @@ -464,20 +480,28 @@ update_primary_selection (CalendarComponentView *component_view) } static void -update_primary_task_selection (CalendarComponentView *component_view) +update_primary_task_memo_selection (CalendarComponentView *component_view, ECalSourceType type) { ESource *source = NULL; char *uid; + ESourceList *source_list = NULL; + + if (type == E_CAL_SOURCE_TYPE_TODO) { + uid = calendar_config_get_primary_tasks (); + source_list = component_view->task_source_list; + } else { + uid = calendar_config_get_primary_memos (); + source_list = component_view->memo_source_list; + } - uid = calendar_config_get_primary_tasks (); if (uid) { - source = e_source_list_peek_source_by_uid (component_view->task_source_list, uid); + source = e_source_list_peek_source_by_uid (source_list, uid); g_free (uid); } if (source) - gnome_calendar_set_default_source (component_view->calendar, E_CAL_SOURCE_TYPE_TODO, source); + gnome_calendar_set_default_source (component_view->calendar, type, source); } /* Callbacks. */ @@ -748,14 +772,27 @@ config_primary_selection_changed_cb (GConfClient *client, guint id, GConfEntry * static void config_tasks_selection_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) { - update_task_selection (data); + update_task_memo_selection (data, E_CAL_SOURCE_TYPE_TODO); } static void config_primary_tasks_selection_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) { - update_primary_task_selection (data); + update_primary_task_memo_selection (data, E_CAL_SOURCE_TYPE_TODO); +} + +static void +config_memos_selection_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) +{ + update_task_memo_selection (data, E_CAL_SOURCE_TYPE_JOURNAL); +} + + +static void +config_primary_memos_selection_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) +{ + update_primary_task_memo_selection (data, E_CAL_SOURCE_TYPE_JOURNAL); } /* Evolution::Component CORBA methods. */ @@ -1285,6 +1322,7 @@ create_component_view (CalendarComponent *calendar_component) /* Add the source lists */ component_view->source_list = g_object_ref (priv->source_list); component_view->task_source_list = g_object_ref (priv->task_source_list); + component_view->memo_source_list = g_object_ref (priv->memo_source_list); component_view->vpane_pos = calendar_config_get_tag_vpane_pos (); /* Create sidebar selector */ @@ -1377,18 +1415,28 @@ create_component_view (CalendarComponent *calendar_component) /* Load the selection from the last run */ update_selection (component_view); update_primary_selection (component_view); - update_task_selection (component_view); - update_primary_task_selection (component_view); + update_task_memo_selection (component_view, E_CAL_SOURCE_TYPE_TODO); + update_primary_task_memo_selection (component_view, E_CAL_SOURCE_TYPE_TODO); + update_task_memo_selection (component_view, E_CAL_SOURCE_TYPE_JOURNAL); + update_primary_task_memo_selection (component_view, E_CAL_SOURCE_TYPE_JOURNAL); - /* If the tasks selection changes elsewhere, update it for the mini + /* If the tasks/memos selection changes elsewhere, update it for the mini mini tasks view sidebar */ not = calendar_config_add_notification_tasks_selected (config_tasks_selection_changed_cb, component_view); component_view->notifications = g_list_prepend (component_view->notifications, GUINT_TO_POINTER (not)); + not = calendar_config_add_notification_memos_selected (config_memos_selection_changed_cb, + component_view); + component_view->notifications = g_list_prepend (component_view->notifications, GUINT_TO_POINTER (not)); + not = calendar_config_add_notification_primary_tasks (config_primary_tasks_selection_changed_cb, component_view); component_view->notifications = g_list_prepend (component_view->notifications, GUINT_TO_POINTER (not)); + + not = calendar_config_add_notification_primary_memos (config_primary_memos_selection_changed_cb, + component_view); + component_view->notifications = g_list_prepend (component_view->notifications, GUINT_TO_POINTER (not)); return component_view; } @@ -1403,6 +1451,9 @@ destroy_component_view (CalendarComponentView *component_view) if (component_view->task_source_list) g_object_unref (component_view->task_source_list); + + if (component_view->memo_source_list) + g_object_unref (component_view->memo_source_list); if (component_view->source_selection) e_source_selector_free_selection (component_view->source_selection); @@ -1648,6 +1699,8 @@ calendar_component_init (CalendarComponent *component) if (!e_cal_get_sources (&priv->task_source_list, E_CAL_SOURCE_TYPE_TODO, NULL)) ; + if (!e_cal_get_sources (&priv->memo_source_list, E_CAL_SOURCE_TYPE_JOURNAL, NULL)) + ; } diff --git a/calendar/gui/dialogs/comp-editor-page.h b/calendar/gui/dialogs/comp-editor-page.h index a5ddb03e89..b7a10222cd 100644 --- a/calendar/gui/dialogs/comp-editor-page.h +++ b/calendar/gui/dialogs/comp-editor-page.h @@ -49,6 +49,7 @@ typedef enum { COMP_EDITOR_PAGE_DELEGATE = 1<<2, COMP_EDITOR_PAGE_USER_ORG = 1<<3, COMP_EDITOR_PAGE_IS_ASSIGNED = 1<<4, + COMP_EDITOR_PAGE_IS_SHARED = 1<<5 } CompEditorPageFlags; typedef struct { diff --git a/calendar/gui/dialogs/comp-editor.h b/calendar/gui/dialogs/comp-editor.h index 1c11e1540c..fdf811aedc 100644 --- a/calendar/gui/dialogs/comp-editor.h +++ b/calendar/gui/dialogs/comp-editor.h @@ -65,6 +65,7 @@ typedef enum { COMP_EDITOR_DELEGATE = 1<<2, COMP_EDITOR_USER_ORG = 1<<3, COMP_EDITOR_IS_ASSIGNED = 1<<4, + COMP_EDITOR_IS_SHARED = 1 << 5 } CompEditorFlags; GtkType comp_editor_get_type (void); diff --git a/calendar/gui/dialogs/memo-editor.c b/calendar/gui/dialogs/memo-editor.c index 27babe97fe..2c6356988d 100644 --- a/calendar/gui/dialogs/memo-editor.c +++ b/calendar/gui/dialogs/memo-editor.c @@ -208,10 +208,11 @@ memo_editor_construct (MemoEditor *me, ECal *client) MemoEditorPrivate *priv; CompEditor *editor = COMP_EDITOR (me); gboolean read_only = FALSE; + guint32 flags = comp_editor_get_flags (editor); priv = me->priv; - priv->memo_page = memo_page_new (editor->uic); + priv->memo_page = memo_page_new (editor->uic, flags); g_object_ref (priv->memo_page); gtk_object_sink (GTK_OBJECT (priv->memo_page)); comp_editor_append_page (COMP_EDITOR (me), @@ -225,6 +226,8 @@ memo_editor_construct (MemoEditor *me, ECal *client) bonobo_ui_component_set_prop (editor->uic, "/Toolbar/ecal3", "hidden", "1", NULL); comp_editor_set_e_cal (COMP_EDITOR (me), client); + + init_widgets (me); @@ -241,6 +244,12 @@ memo_editor_set_e_cal (CompEditor *editor, ECal *client) static void memo_editor_edit_comp (CompEditor *editor, ECalComponent *comp) { + CompEditorFlags flags = comp_editor_get_flags (editor); + ECal *client = comp_editor_get_e_cal (editor); + + if (flags & COMP_EDITOR_IS_SHARED) + comp_editor_set_needs_send (editor, itip_organizer_is_user (comp, client)); + if (COMP_EDITOR_CLASS (memo_editor_parent_class)->edit_comp) COMP_EDITOR_CLASS (memo_editor_parent_class)->edit_comp (editor, comp); } @@ -289,11 +298,12 @@ memo_editor_finalize (GObject *object) * editor could not be created. **/ MemoEditor * -memo_editor_new (ECal *client) +memo_editor_new (ECal *client, CompEditorFlags flags) { MemoEditor *me; me = g_object_new (TYPE_MEMO_EDITOR, NULL); + comp_editor_set_flags (COMP_EDITOR (me), flags); return memo_editor_construct (me, client); } diff --git a/calendar/gui/dialogs/memo-editor.h b/calendar/gui/dialogs/memo-editor.h index 79c86e9d4e..b5a76a0b88 100644 --- a/calendar/gui/dialogs/memo-editor.h +++ b/calendar/gui/dialogs/memo-editor.h @@ -53,7 +53,7 @@ struct _MemoEditorClass { GtkType memo_editor_get_type (void); MemoEditor *memo_editor_construct (MemoEditor *te, ECal *client); -MemoEditor *memo_editor_new (ECal *client); +MemoEditor *memo_editor_new (ECal *client, CompEditorFlags flags); #endif /* __MEMO_EDITOR_H__ */ diff --git a/calendar/gui/dialogs/memo-page.c b/calendar/gui/dialogs/memo-page.c index 4fa478238f..42850b60b3 100644 --- a/calendar/gui/dialogs/memo-page.c +++ b/calendar/gui/dialogs/memo-page.c @@ -36,10 +36,14 @@ #include <libgnome/gnome-i18n.h> #include <glade/glade.h> #include <libedataserverui/e-source-option-menu.h> +#include <libedataserverui/e-name-selector.h> +#include <libedataserverui/e-name-selector-entry.h> +#include <libedataserverui/e-name-selector-list.h> #include <widgets/misc/e-dateedit.h> #include "common/authentication.h" #include "e-util/e-dialog-widgets.h" +#include <e-util/e-dialog-utils.h> #include "e-util/e-categories-config.h" #include "e-util/e-util-private.h" #include "../calendar-config.h" @@ -59,16 +63,39 @@ struct _MemoPagePrivate { GtkWidget *memo_content; + EAccountList *accounts; + /* Bonobo Controller for the menu/toolbar */ BonoboUIComponent *uic; ECalComponentClassification classification; + /* Organizer */ + GtkWidget *org_label; + GtkWidget *org_combo; + + /* To field */ + GtkWidget *to_button; + GtkWidget *to_hbox; + GtkWidget *to_entry; + + /* Summary */ + GtkWidget *summary_label; + GtkWidget *summary_entry; + + /* Start date */ + GtkWidget *start_label; + GtkWidget *start_date; + GtkWidget *categories_btn; GtkWidget *categories; GtkWidget *source_selector; + char *default_address; + + ENameSelector *name_selector; + gboolean updating; }; @@ -137,7 +164,6 @@ memo_page_init (MemoPage *mpage) priv->categories = NULL; priv->updating = FALSE; - } /* Destroy handler for the memo page */ @@ -161,6 +187,11 @@ memo_page_finalize (GObject *object) priv->xml = NULL; } + if (priv->default_address) { + g_free (priv->default_address); + priv->default_address = NULL; + } + g_free (priv); mpage->priv = NULL; @@ -215,7 +246,7 @@ memo_page_focus_main_widget (CompEditorPage *page) mpage = MEMO_PAGE (page); priv = mpage->priv; - gtk_widget_grab_focus (priv->memo_content); + gtk_widget_grab_focus (priv->summary_entry); } /* Fills the widgets with default values */ @@ -226,6 +257,9 @@ clear_widgets (MemoPage *mpage) priv = mpage->priv; + /* Summary */ + e_dialog_editable_set (priv->summary_entry, NULL); + /* memo content */ gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->memo_content)), "", 0); @@ -235,6 +269,9 @@ clear_widgets (MemoPage *mpage) /* Categories */ e_dialog_editable_set (priv->categories, NULL); + + if (priv->default_address) + gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (priv->org_combo)->entry), priv->default_address); } void @@ -254,7 +291,7 @@ sensitize_widgets (MemoPage *mpage) if (!e_cal_is_read_only (COMP_EDITOR_PAGE (mpage)->client, &read_only, NULL)) read_only = TRUE; - if (COMP_EDITOR_PAGE (mpage)->flags & COMP_EDITOR_IS_ASSIGNED) + if (COMP_EDITOR_PAGE (mpage)->flags & COMP_EDITOR_IS_SHARED) sens = COMP_EDITOR_PAGE (mpage)->flags & COMP_EDITOR_PAGE_USER_ORG; sensitize = (!read_only && sens); @@ -264,9 +301,20 @@ sensitize_widgets (MemoPage *mpage) if (!e_cal_is_read_only (COMP_EDITOR_PAGE (mpage)->client, &read_only, NULL)) read_only = TRUE; - gtk_widget_set_sensitive (priv->memo_content, !read_only); + gtk_text_view_set_editable (GTK_TEXT_VIEW (priv->memo_content), sensitize); + gtk_widget_set_sensitive (priv->start_date, sensitize); gtk_widget_set_sensitive (priv->categories_btn, !read_only); gtk_entry_set_editable (GTK_ENTRY (priv->categories), !read_only); + gtk_entry_set_editable (GTK_ENTRY (priv->summary_entry), sensitize); + + if (COMP_EDITOR_PAGE (mpage)->flags & COMP_EDITOR_IS_SHARED) { + gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (priv->org_combo)->entry), sensitize); + + if (priv->to_entry) { + gtk_entry_set_editable (GTK_ENTRY (priv->to_entry), !read_only); + gtk_widget_grab_focus (priv->to_entry); + } + } bonobo_ui_component_set_prop (priv->uic, "/commands/ActionClassPublic", "sensitive", sensitize ? "1" : "0" , NULL); @@ -274,7 +322,7 @@ sensitize_widgets (MemoPage *mpage) , NULL); bonobo_ui_component_set_prop (priv->uic, "/commands/ActionClassConfidential", "sensitive", sensitize ? "1" : "0", NULL); - bonobo_ui_component_set_prop (priv->uic, "/commands/ViewCategories", "sensitive", sensitize ? "1" : "0" + bonobo_ui_component_set_prop (priv->uic, "/commands/InsertAttachments", "sensitive", sensitize ? "1" : "0" , NULL); } @@ -285,6 +333,8 @@ memo_page_fill_widgets (CompEditorPage *page, ECalComponent *comp) MemoPage *mpage; MemoPagePrivate *priv; ECalComponentClassification cl; + ECalComponentText text; + ECalComponentDateTime d; GSList *l; const char *categories; ESource *source; @@ -297,6 +347,10 @@ memo_page_fill_widgets (CompEditorPage *page, ECalComponent *comp) /* Clean the screen */ clear_widgets (mpage); + /* Summary */ + e_cal_component_get_summary (comp, &text); + e_dialog_editable_set (priv->summary_entry, text.value); + e_cal_component_get_description_list (comp, &l); if (l && l->data) { ECalComponentText *dtext; @@ -310,6 +364,16 @@ memo_page_fill_widgets (CompEditorPage *page, ECalComponent *comp) } e_cal_component_free_text_list (l); + /* Start Date. */ + e_cal_component_get_dtstart (comp, &d); + if (d.value) { + struct icaltimetype *start_tt = d.value; + e_date_edit_set_date (E_DATE_EDIT (priv->start_date), + start_tt->year, start_tt->month, + start_tt->day); + } else if (!(page->flags & COMP_EDITOR_PAGE_NEW_ITEM)) + e_date_edit_set_time (E_DATE_EDIT (priv->start_date), -1); + /* Classification. */ e_cal_component_get_classification (comp, &cl); @@ -340,6 +404,31 @@ memo_page_fill_widgets (CompEditorPage *page, ECalComponent *comp) e_cal_component_get_categories (comp, &categories); e_dialog_editable_set (priv->categories, categories); + if (e_cal_component_has_organizer (comp)) { + ECalComponentOrganizer organizer; + + e_cal_component_get_organizer (comp, &organizer); + if (organizer.value != NULL) { + const gchar *strip = itip_strip_mailto (organizer.value); + gchar *string; + GList *list = NULL; + + if ( organizer.cn != NULL) + string = g_strdup_printf ("%s <%s>", organizer.cn, strip); + else + string = g_strdup (strip); + + if (itip_organizer_is_user (comp, page->client)) { + } else { + list = g_list_append (list, string); + gtk_combo_set_popdown_strings (GTK_COMBO (priv->org_combo), list); + gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (priv->org_combo)->entry), FALSE); + } + g_free (string); + g_list_free (list); + } + } + /* Source */ source = e_cal_get_source (page->client); e_source_option_menu_select (E_SOURCE_OPTION_MENU (priv->source_selector), source); @@ -351,12 +440,162 @@ memo_page_fill_widgets (CompEditorPage *page, ECalComponent *comp) return TRUE; } +static gboolean +fill_comp_with_recipients (ENameSelector *name_selector, ECalComponent *comp) +{ + EDestinationStore *destination_store; + GString *str = NULL; + GList *l, *destinations; + ENameSelectorModel *name_selector_model = e_name_selector_peek_model (name_selector); + icalcomponent *icalcomp; + icalproperty *icalprop; + + e_name_selector_model_peek_section (name_selector_model, "To", + NULL, &destination_store); + + destinations = e_destination_store_list_destinations (destination_store); + for (l = destinations; l; l = g_list_next (l)) { + EDestination *destination = l->data, *des = NULL; + const GList *list_dests = NULL, *l; + GList card_dest; + + if (e_destination_is_evolution_list (destination)) { + list_dests = e_destination_list_get_dests (destination); + } else { + EContact *contact = e_destination_get_contact (destination); + /* check if the contact is contact list which is not expanded yet */ + /* we expand it by getting the list again from the server forming the query */ + if (contact && e_contact_get (contact , E_CONTACT_IS_LIST)) { + EBook *book = NULL; + ENameSelectorDialog *dialog; + EContactStore *c_store; + GList *books, *l; + char *uri = e_contact_get (contact, E_CONTACT_BOOK_URI); + + dialog = e_name_selector_peek_dialog (name_selector); + c_store = dialog->name_selector_model->contact_store; + books = e_contact_store_get_books (c_store); + + for (l = books; l; l = l->next) { + EBook *b = l->data; + if (g_str_equal (uri, e_book_get_uri (b))) { + book = b; + break; + } + } + + if (book) { + GList *contacts; + EContact *n_con = NULL; + char *qu; + EBookQuery *query; + + qu = g_strdup_printf ("(is \"full_name\" \"%s\")", + (char *) e_contact_get (contact, E_CONTACT_FULL_NAME)); + query = e_book_query_from_string (qu); + + if (!e_book_get_contacts (book, query, &contacts, NULL)) { + g_warning ("Could not get contact from the book \n"); + return; + } else { + des = e_destination_new (); + n_con = contacts->data; + + e_destination_set_contact (des, n_con, 0); + list_dests = e_destination_list_get_dests (des); + + g_list_foreach (contacts, (GFunc) g_object_unref, NULL); + g_list_free (contacts); + } + + e_book_query_unref (query); + g_free (qu); + } + } else { + card_dest.next = NULL; + card_dest.prev = NULL; + card_dest.data = destination; + list_dests = &card_dest; + } + } + + for (l = list_dests; l; l = l->next) { + EDestination *dest = l->data; + const char *name, *attendee = NULL; + + name = e_destination_get_name (dest); + + /* If we couldn't get the attendee prior, get the email address as the default */ + if (attendee == NULL || *attendee == '\0') { + attendee = e_destination_get_email (dest); + } + + if (attendee == NULL || *attendee == '\0') + continue; + + if (!str) { + str = g_string_new (""); + g_string_prepend (str, attendee); + continue; + } + g_string_prepend (str, ";"); + g_string_prepend (str, attendee); + } + } + + g_list_free (destinations); + + if (str && *str->str) { + icalcomp = e_cal_component_get_icalcomponent (comp); + icalprop = icalproperty_new_x (str->str); + icalproperty_set_x_name (icalprop, "X-EVOLUTION-RECIPIENTS"); + icalcomponent_add_property (icalcomp, icalprop); + + g_string_free (str, FALSE); + return TRUE; + } else + return FALSE; +} + +static EAccount * +get_current_account (MemoPage *page) +{ + MemoPagePrivate *priv; + EIterator *it; + const char *str; + + priv = page->priv; + + str = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (priv->org_combo)->entry)); + if (!str) + return NULL; + + for (it = e_list_get_iterator((EList *)priv->accounts); e_iterator_is_valid(it); e_iterator_next(it)) { + EAccount *a = (EAccount *)e_iterator_get(it); + char *full = g_strdup_printf("%s <%s>", a->id->name, a->id->address); + + if (!strcmp (full, str)) { + g_free (full); + g_object_unref (it); + + return a; + } + + g_free (full); + } + g_object_unref (it); + + return NULL; +} + /* fill_component handler for the memo page */ static gboolean memo_page_fill_component (CompEditorPage *page, ECalComponent *comp) { MemoPage *mpage; MemoPagePrivate *priv; + ECalComponentDateTime start_date; + struct icaltimetype start_tt; char *cat, *str; int i; GtkTextBuffer *text_buffer; @@ -366,6 +605,24 @@ memo_page_fill_component (CompEditorPage *page, ECalComponent *comp) priv = mpage->priv; text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->memo_content)); + /* Summary */ + str = e_dialog_editable_get (priv->summary_entry); + if (!str || strlen (str) == 0) + e_cal_component_set_summary (comp, NULL); + else { + ECalComponentText text; + + text.value = str; + text.altrep = NULL; + + e_cal_component_set_summary (comp, &text); + } + + if (str) { + g_free (str); + str = NULL; + } + /* Memo Content */ gtk_text_buffer_get_start_iter (text_buffer, &text_iter_start); @@ -374,7 +631,6 @@ memo_page_fill_component (CompEditorPage *page, ECalComponent *comp) if (!str || strlen (str) == 0){ e_cal_component_set_description_list (comp, NULL); - e_cal_component_set_summary(comp, NULL); } else { int idxToUse = -1, nstr = strlen(str); @@ -410,7 +666,6 @@ memo_page_fill_component (CompEditorPage *page, ECalComponent *comp) l.data = &text; l.next = NULL; - e_cal_component_set_summary(comp, &sumText); e_cal_component_set_description_list (comp, &l); g_free(txt); @@ -419,6 +674,22 @@ memo_page_fill_component (CompEditorPage *page, ECalComponent *comp) if (str) g_free (str); + /* Dates */ + start_tt = icaltime_null_time (); + start_tt.is_date = 1; + start_date.value = &start_tt; + start_date.tzid = NULL; + + if (!e_date_edit_date_is_valid (E_DATE_EDIT (priv->start_date))) { + comp_editor_page_display_validation_error (page, _("Start date is wrong"), priv->start_date); + return FALSE; + } + e_date_edit_get_date (E_DATE_EDIT (priv->start_date), + &start_tt.year, + &start_tt.month, + &start_tt.day); + e_cal_component_set_dtstart (comp, &start_date); + /* Classification. */ e_cal_component_set_classification (comp, priv->classification); @@ -433,6 +704,37 @@ memo_page_fill_component (CompEditorPage *page, ECalComponent *comp) if (str) g_free (str); + if ((page->flags & COMP_EDITOR_PAGE_IS_SHARED) && fill_comp_with_recipients (priv->name_selector, comp)) { + ECalComponentOrganizer organizer = {NULL, NULL, NULL, NULL}; + + EAccount *a; + gchar *addr = NULL; + + /* Find the identity for the organizer or sentby field */ + a = get_current_account (mpage); + + /* Sanity Check */ + if (a == NULL) { + e_notice (page, GTK_MESSAGE_ERROR, + _("The organizer selected no longer has an account.")); + return FALSE; + } + + if (a->id->address == NULL || strlen (a->id->address) == 0) { + e_notice (page, GTK_MESSAGE_ERROR, + _("An organizer is required.")); + return FALSE; + } + + addr = g_strdup_printf ("MAILTO:%s", a->id->address); + + organizer.value = addr; + organizer.cn = a->id->name; + e_cal_component_set_organizer (comp, &organizer); + + g_free (addr); + } + return TRUE; } @@ -479,6 +781,18 @@ get_widgets (MemoPage *mpage) gtk_widget_ref (priv->main); gtk_container_remove (GTK_CONTAINER (priv->main->parent), priv->main); + priv->org_label = GW ("org-label"); + priv->org_combo = GW ("org-combo"); + + priv->to_button = GW ("to-button"); + priv->to_hbox = GW ("to-hbox"); + + priv->summary_label = GW ("sum-label"); + priv->summary_entry = GW ("sum-entry"); + + priv->start_label = GW ("start-label"); + priv->start_date = GW ("start-date"); + priv->memo_content = GW ("memo_content"); priv->categories_btn = GW ("categories-button"); @@ -490,7 +804,8 @@ get_widgets (MemoPage *mpage) return (priv->memo_content && priv->categories_btn - && priv->categories); + && priv->categories + && priv->start_date); } /* Callback used when the categories button is clicked; we must bring up the @@ -584,6 +899,22 @@ widget_focus_out_cb (GtkWidget *widget, GdkEventFocus *event, gpointer data) return FALSE; } +static void +to_button_clicked_cb (GtkButton *button, gpointer data) +{ + MemoPage *page = data; + MemoPagePrivate *priv = page->priv; + ENameSelectorDialog *name_selector_dialog; + + name_selector_dialog = e_name_selector_peek_dialog (priv->name_selector); + gtk_widget_show (GTK_WIDGET (name_selector_dialog)); +} + +static void +response_cb (ENameSelectorDialog *name_selector_dialog, gint response, gpointer user_data) +{ + gtk_widget_hide (GTK_WIDGET (name_selector_dialog)); +} /* Hooks the widget signals */ static gboolean @@ -621,12 +952,38 @@ init_widgets (MemoPage *mpage) g_signal_connect((priv->categories), "changed", G_CALLBACK (field_changed_cb), mpage); + + g_signal_connect((priv->summary_entry), "changed", + G_CALLBACK (field_changed_cb), mpage); + if (priv->name_selector) { + ENameSelectorDialog *name_selector_dialog; + + name_selector_dialog = e_name_selector_peek_dialog (priv->name_selector); + + g_signal_connect (name_selector_dialog, "response", + G_CALLBACK (response_cb), mpage); + g_signal_connect ((priv->to_button), "clicked", G_CALLBACK (to_button_clicked_cb), mpage); + } + memo_page_set_show_categories (mpage, calendar_config_get_show_categories()); return TRUE; } +static GtkWidget * +get_to_entry (ENameSelector *name_selector) +{ + ENameSelectorModel *name_selector_model; + ENameSelectorEntry *name_selector_entry; + + name_selector_model = e_name_selector_peek_model (name_selector); + e_name_selector_model_add_section (name_selector_model, "To", _("To"), NULL); + name_selector_entry = (ENameSelectorEntry *)e_name_selector_peek_section_list (name_selector, "To"); + + return GTK_WIDGET (name_selector_entry); +} + /** * memo_page_construct: @@ -641,7 +998,13 @@ MemoPage * memo_page_construct (MemoPage *mpage) { MemoPagePrivate *priv; + char *backend_address = NULL; + EIterator *it; char *gladefile; + GList *address_strings = NULL, *l; + EAccount *def_account; + EAccount *a; + CompEditorPageFlags flags = COMP_EDITOR_PAGE (mpage)->flags; priv = mpage->priv; @@ -663,6 +1026,59 @@ memo_page_construct (MemoPage *mpage) return NULL; } + if (flags & COMP_EDITOR_PAGE_IS_SHARED) { + priv->accounts = itip_addresses_get (); + def_account = itip_addresses_get_default(); + for (it = e_list_get_iterator((EList *)priv->accounts); + e_iterator_is_valid(it); + e_iterator_next(it)) { + a = (EAccount *)e_iterator_get(it); + char *full; + + full = g_strdup_printf("%s <%s>", a->id->name, a->id->address); + + address_strings = g_list_append(address_strings, full); + + /* Note that the address specified by the backend gets + * precedence over the default mail address. + */ + if (backend_address && !strcmp (backend_address, a->id->address)) { + if (priv->default_address) + g_free (priv->default_address); + + priv->default_address = g_strdup (full); + } else if (a == def_account && !priv->default_address) { + priv->default_address = g_strdup (full); + } + } + + if (backend_address) + g_free (backend_address); + + g_object_unref(it); + + if (address_strings) + gtk_combo_set_popdown_strings (GTK_COMBO (priv->org_combo), address_strings); + else + g_warning ("No potential organizers!"); + + for (l = address_strings; l != NULL; l = l->next) + g_free (l->data); + g_list_free (address_strings); + + gtk_widget_show (priv->org_label); + gtk_widget_show (priv->org_combo); + + if (flags & COMP_EDITOR_PAGE_NEW_ITEM) { + priv->name_selector = e_name_selector_new (); + priv->to_entry = get_to_entry (priv->name_selector); + gtk_container_add ((GtkContainer *)priv->to_hbox, priv->to_entry); + gtk_widget_show (priv->to_hbox); + gtk_widget_show (priv->to_entry); + gtk_widget_show (priv->to_button); + } + } + if (!init_widgets (mpage)) { g_message ("memo_page_construct(): " "Could not initialize the widgets!"); @@ -681,12 +1097,14 @@ memo_page_construct (MemoPage *mpage) * not be created. **/ MemoPage * -memo_page_new (BonoboUIComponent *uic) +memo_page_new (BonoboUIComponent *uic, CompEditorPageFlags flags) { MemoPage *mpage; mpage = gtk_type_new (TYPE_MEMO_PAGE); mpage->priv->uic = uic; + COMP_EDITOR_PAGE (mpage)->flags = flags; + if (!memo_page_construct (mpage)) { g_object_unref (mpage); return NULL; @@ -695,6 +1113,20 @@ memo_page_new (BonoboUIComponent *uic) return mpage; } +GtkWidget *memo_page_create_date_edit (void); + +GtkWidget * +memo_page_create_date_edit (void) +{ + GtkWidget *dedit; + + dedit = comp_editor_new_date_edit (TRUE, FALSE, TRUE); + e_date_edit_set_allow_no_date_set (E_DATE_EDIT (dedit), TRUE); + gtk_widget_show (dedit); + + return dedit; +} + GtkWidget *memo_page_create_source_option_menu (void); GtkWidget * diff --git a/calendar/gui/dialogs/memo-page.glade b/calendar/gui/dialogs/memo-page.glade index b230052fba..5de9142675 100644 --- a/calendar/gui/dialogs/memo-page.glade +++ b/calendar/gui/dialogs/memo-page.glade @@ -33,7 +33,7 @@ <child> <widget class="GtkTable" id="table3"> <property name="visible">True</property> - <property name="n_rows">3</property> + <property name="n_rows">7</property> <property name="n_columns">2</property> <property name="homogeneous">False</property> <property name="row_spacing">0</property> @@ -72,8 +72,8 @@ <packing> <property name="left_attach">1</property> <property name="right_attach">2</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> + <property name="top_attach">6</property> + <property name="bottom_attach">7</property> <property name="x_padding">6</property> <property name="y_padding">3</property> <property name="x_options">expand|shrink|fill</property> @@ -93,8 +93,8 @@ <packing> <property name="left_attach">0</property> <property name="right_attach">1</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> + <property name="top_attach">5</property> + <property name="bottom_attach">6</property> <property name="x_padding">6</property> <property name="y_padding">3</property> <property name="x_options">fill</property> @@ -123,8 +123,8 @@ <packing> <property name="left_attach">0</property> <property name="right_attach">1</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> + <property name="top_attach">6</property> + <property name="bottom_attach">7</property> <property name="x_padding">6</property> <property name="y_padding">3</property> <property name="x_options">fill</property> @@ -156,8 +156,8 @@ <packing> <property name="left_attach">1</property> <property name="right_attach">2</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> <property name="x_padding">6</property> <property name="y_padding">3</property> <property name="x_options">fill</property> @@ -180,8 +180,8 @@ <packing> <property name="left_attach">1</property> <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> + <property name="top_attach">5</property> + <property name="bottom_attach">6</property> <property name="x_padding">6</property> <property name="y_padding">3</property> <property name="y_options"></property> @@ -210,11 +210,224 @@ <packing> <property name="left_attach">0</property> <property name="right_attach">1</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_padding">6</property> + <property name="y_padding">3</property> + <property name="x_options">fill</property> + <property name="y_options">fill</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="org-label"> + <property name="label" translatable="yes">Or_ganizer:</property> + <property name="use_underline">True</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="mnemonic_widget">combo-entry1</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> <property name="top_attach">0</property> <property name="bottom_attach">1</property> <property name="x_padding">6</property> <property name="y_padding">3</property> <property name="x_options">fill</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkButton" id="to-button"> + <property name="can_focus">True</property> + <property name="label" translatable="yes">T_o:</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + </widget> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_padding">6</property> + <property name="y_padding">3</property> + <property name="x_options">fill</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="start-label"> + <property name="visible">True</property> + <property name="label" translatable="yes">Sta_rt date:</property> + <property name="use_underline">True</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">4</property> + <property name="bottom_attach">5</property> + <property name="x_padding">6</property> + <property name="y_padding">3</property> + <property name="x_options">fill</property> + <property name="y_options">shrink</property> + </packing> + </child> + + <child> + <widget class="Custom" id="start-date"> + <property name="visible">True</property> + <property name="creation_function">memo_page_create_date_edit</property> + <property name="int1">0</property> + <property name="int2">0</property> + <property name="last_modification_time">Mon, 17 Jul 2006 21:24:48 GMT</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">4</property> + <property name="bottom_attach">5</property> + <property name="x_padding">6</property> + <property name="y_padding">3</property> + <property name="x_options">fill</property> + <property name="y_options">fill</property> + </packing> + </child> + + <child> + <widget class="GtkEntry" id="sum-entry"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="visibility">True</property> + <property name="max_length">0</property> + <property name="text" translatable="yes"></property> + <property name="has_frame">True</property> + <property name="invisible_char">●</property> + <property name="activates_default">False</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="x_padding">6</property> + <property name="y_padding">3</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="sum-label"> + <property name="visible">True</property> + <property name="label" translatable="yes">Su_mmary</property> + <property name="use_underline">True</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="mnemonic_widget">sum-entry</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="x_padding">6</property> + <property name="y_padding">3</property> + <property name="x_options">fill</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkCombo" id="org-combo"> + <property name="value_in_list">False</property> + <property name="allow_empty">True</property> + <property name="case_sensitive">False</property> + <property name="enable_arrow_keys">True</property> + <property name="enable_arrows_always">False</property> + + <child internal-child="entry"> + <widget class="GtkEntry" id="combo-entry1"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="visibility">True</property> + <property name="max_length">0</property> + <property name="text" translatable="yes"></property> + <property name="has_frame">True</property> + <property name="invisible_char">●</property> + <property name="activates_default">False</property> + </widget> + </child> + + <child internal-child="list"> + <widget class="GtkList" id="combo-list1"> + <property name="visible">True</property> + <property name="selection_mode">GTK_SELECTION_BROWSE</property> + </widget> + </child> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">0</property> + <property name="bottom_attach">1</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="to-hbox"> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <placeholder/> + </child> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_padding">6</property> + <property name="y_padding">3</property> + <property name="x_options">fill</property> <property name="y_options">fill</property> </packing> </child> diff --git a/calendar/gui/dialogs/memo-page.h b/calendar/gui/dialogs/memo-page.h index 45928d96e0..132db6ed22 100644 --- a/calendar/gui/dialogs/memo-page.h +++ b/calendar/gui/dialogs/memo-page.h @@ -52,7 +52,7 @@ typedef struct { GtkType memo_page_get_type (void); MemoPage *memo_page_construct (MemoPage *epage); -MemoPage *memo_page_new (BonoboUIComponent *uic); +MemoPage *memo_page_new (BonoboUIComponent *uic, CompEditorPageFlags flags); G_END_DECLS diff --git a/calendar/gui/e-cal-component-memo-preview.c b/calendar/gui/e-cal-component-memo-preview.c index 7cb23740ce..1dd9dee782 100644 --- a/calendar/gui/e-cal-component-memo-preview.c +++ b/calendar/gui/e-cal-component-memo-preview.c @@ -100,18 +100,59 @@ url_requested_cb (GtkHTML *html, const char *url, GtkHTMLStream *stream, gpointe } } +/* Converts a time_t to a string, relative to the specified timezone */ +static char * +timet_to_str_with_zone (ECalComponentDateTime *dt, ECal *ecal, icaltimezone *default_zone) +{ + struct icaltimetype itt; + icaltimezone *zone; + struct tm tm; + char buf[256]; + + if (dt->tzid) { + /* If we can't find the zone, we'll guess its "local" */ + if (!e_cal_get_timezone (ecal, dt->tzid, &zone, NULL)) + zone = NULL; + } else if (dt->value->is_utc) { + zone = icaltimezone_get_utc_timezone (); + } else { + zone = NULL; + } + + + itt = *dt->value; + if (zone) + icaltimezone_convert_time (&itt, zone, default_zone); + tm = icaltimetype_to_tm (&itt); + + e_time_format_date_and_time (&tm, calendar_config_get_24_hour_format (), + FALSE, FALSE, buf, sizeof (buf)); + + return g_locale_to_utf8 (buf, -1, NULL, NULL, NULL); +} + static void write_html (GtkHTMLStream *stream, ECal *ecal, ECalComponent *comp, icaltimezone *default_zone) { ECalComponentText text; + ECalComponentDateTime dt; gchar *str; GSList *l; gboolean one_added = FALSE; g_return_if_fail (E_IS_CAL_COMPONENT (comp)); - gtk_html_stream_printf (stream, - "<HTML><BODY>"); + /* write document header */ + e_cal_component_get_summary (comp, &text); + + if (text.value) + gtk_html_stream_printf (stream, + "<HTML><BODY><H1>%s</H1>", + text.value); + else + gtk_html_stream_printf (stream, + "<HTML><BODY><H1><I>%s</I></H1>", + _("Untitled")); /* write icons for the categories */ e_cal_component_get_categories_list (comp, &l); @@ -155,6 +196,16 @@ write_html (GtkHTMLStream *stream, ECal *ecal, ECalComponent *comp, icaltimezone gtk_html_stream_printf (stream, "<TABLE BORDER=\"0\" WIDTH=\"80%%\">" "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\" WIDTH=\"15%%\"></TD></TR>"); + /* write start date */ + e_cal_component_get_dtstart (comp, &dt); + if (dt.value != NULL) { + str = timet_to_str_with_zone (&dt, ecal, default_zone); + gtk_html_stream_printf (stream, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\"><B>%s</B></TD><TD>%s</TD></TR>", + _("Start Date:"), str); + + e_cal_component_free_datetime (&dt); + g_free (str); + } /* write description and URL */ gtk_html_stream_printf (stream, "<TR><TD COLSPAN=\"2\"><HR></TD></TR>"); @@ -163,7 +214,7 @@ write_html (GtkHTMLStream *stream, ECal *ecal, ECalComponent *comp, icaltimezone if (l) { GSList *node; - gtk_html_stream_printf (stream, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\"><B>%s</B></TD>", _("Memo:")); + gtk_html_stream_printf (stream, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\"><B>%s</B></TD>", _("Description:")); gtk_html_stream_printf (stream, "<TD>"); diff --git a/calendar/gui/e-cal-model.c b/calendar/gui/e-cal-model.c index 2de983ab10..2658124192 100644 --- a/calendar/gui/e-cal-model.c +++ b/calendar/gui/e-cal-model.c @@ -468,6 +468,11 @@ ecm_value_at (ETableModel *etm, int col, int row) comp = e_cal_component_new (); icalcomp = icalcomponent_new_clone (comp_data->icalcomp); if (e_cal_component_set_icalcomponent (comp, icalcomp)) { + if (e_cal_component_get_vtype (comp) == E_CAL_COMPONENT_JOURNAL) { + g_object_unref (comp); + return GINT_TO_POINTER (retval); + } + if (e_cal_component_has_recurrences (comp)) retval = 1; else if (itip_organizer_is_user (comp, comp_data->client)) diff --git a/calendar/gui/e-memo-table-config.c b/calendar/gui/e-memo-table-config.c index 064ef0810f..f72c863c72 100644 --- a/calendar/gui/e-memo-table-config.c +++ b/calendar/gui/e-memo-table-config.c @@ -22,10 +22,13 @@ */ #include "calendar-config.h" +#include "e-cell-date-edit-config.h" #include "e-memo-table-config.h" struct _EMemoTableConfigPrivate { EMemoTable *table; + + ECellDateEditConfig *cell_config; GList *notifications; }; @@ -208,6 +211,11 @@ e_memo_table_config_set_table (EMemoTableConfig *table_config, EMemoTable *table priv->table = NULL; } + if (priv->cell_config) { + g_object_unref (priv->cell_config); + priv->cell_config = NULL; + } + for (l = priv->notifications; l; l = l->next) calendar_config_remove_notification (GPOINTER_TO_UINT (l->data)); @@ -231,4 +239,7 @@ e_memo_table_config_set_table (EMemoTableConfig *table_config, EMemoTable *table not = calendar_config_add_notification_24_hour_format (twentyfour_hour_changed_cb, table_config); priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); + + /* Date cell */ + priv->cell_config = e_cell_date_edit_config_new (table->dates_cell); } diff --git a/calendar/gui/e-memo-table.c b/calendar/gui/e-memo-table.c index 84ac373017..212d12187f 100644 --- a/calendar/gui/e-memo-table.c +++ b/calendar/gui/e-memo-table.c @@ -88,6 +88,7 @@ static gint e_memo_table_on_key_press (ETable *table, gint col, GdkEventKey *event, EMemoTable *memo_table); +static struct tm e_memo_table_get_current_time (ECellDateEdit *ecde, gpointer data); static ECalModelComponent *get_selected_comp (EMemoTable *memo_table); static void open_memo (EMemoTable *memo_table, ECalModelComponent *comp_data); @@ -136,6 +137,34 @@ e_memo_table_class_init (EMemoTableClass *klass) clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE); } +static gint +date_compare_cb (gconstpointer a, gconstpointer b) +{ + ECellDateEditValue *dv1 = (ECellDateEditValue *) a; + ECellDateEditValue *dv2 = (ECellDateEditValue *) b; + struct icaltimetype tt; + + /* First check if either is NULL. NULL dates sort last. */ + if (!dv1 || !dv2) { + if (dv1 == dv2) + return 0; + else if (dv1) + return -1; + else + return 1; + } + + /* Copy the 2nd value and convert it to the same timezone as the + first. */ + tt = dv2->tt; + + icaltimezone_convert_time (&tt, dv2->zone, dv1->zone); + + /* Now we can compare them. */ + + return icaltime_compare (dv1->tt, tt); +} + /* Comparison function for the task-sort column. Sorts by due date and then by * priority. * @@ -204,7 +233,7 @@ e_memo_table_init (EMemoTable *memo_table) { GtkWidget *table; ETable *e_table; - ECell *cell; + ECell *cell, *popup_cell; ETableExtras *extras; gint i; AtkObject *a11y; @@ -229,8 +258,28 @@ e_memo_table_init (EMemoTable *memo_table) e_table_extras_add_cell (extras, "calstring", cell); + /* + * Date fields. + */ + cell = e_cell_date_edit_text_new (NULL, GTK_JUSTIFY_LEFT); + g_object_set (G_OBJECT (cell), + "bg_color_column", E_CAL_MODEL_FIELD_COLOR, + NULL); + + popup_cell = e_cell_date_edit_new (); + e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell); + g_object_unref (cell); + e_table_extras_add_cell (extras, "dateedit", popup_cell); + memo_table->dates_cell = E_CELL_DATE_EDIT (popup_cell); + e_cell_date_edit_set_get_time_callback (E_CELL_DATE_EDIT (popup_cell), + e_memo_table_get_current_time, + memo_table, NULL); + /* Sorting */ + e_table_extras_add_compare (extras, "date-compare", + date_compare_cb); + /* Create pixmaps */ if (!icon_pixbufs[0]) @@ -681,11 +730,19 @@ open_memo (EMemoTable *memo_table, ECalModelComponent *comp_data) medit = e_comp_editor_registry_find (comp_editor_registry, uid); if (medit == NULL) { ECalComponent *comp; - - medit = COMP_EDITOR (memo_editor_new (comp_data->client)); + CompEditorFlags flags = 0; comp = e_cal_component_new (); e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp)); + + if (e_cal_component_has_organizer (comp)) + flags |= COMP_EDITOR_IS_SHARED; + + if (itip_organizer_is_user (comp, comp_data->client)) + flags |= COMP_EDITOR_USER_ORG; + + medit = COMP_EDITOR (memo_editor_new (comp_data->client, flags)); + comp_editor_edit_comp (medit, comp); e_comp_editor_registry_add (comp_editor_registry, medit, FALSE); @@ -979,6 +1036,34 @@ e_memo_table_save_state (EMemoTable *memo_table, filename); } +/* Returns the current time, for the ECellDateEdit items. + FIXME: Should probably use the timezone of the item rather than the + current timezone, though that may be difficult to get from here. */ +static struct tm +e_memo_table_get_current_time (ECellDateEdit *ecde, gpointer data) +{ + icaltimezone *zone; + struct tm tmp_tm = { 0 }; + struct icaltimetype tt; + + /* Get the current timezone. */ + zone = calendar_config_get_icaltimezone (); + + tt = icaltime_from_timet_with_zone (time (NULL), FALSE, zone); + + /* Now copy it to the struct tm and return it. */ + tmp_tm.tm_year = tt.year - 1900; + tmp_tm.tm_mon = tt.month - 1; + tmp_tm.tm_mday = tt.day; + tmp_tm.tm_hour = tt.hour; + tmp_tm.tm_min = tt.minute; + tmp_tm.tm_sec = tt.second; + tmp_tm.tm_isdst = -1; + + return tmp_tm; +} + + #ifdef TRANSLATORS_ONLY static char *test[] = { diff --git a/calendar/gui/e-memo-table.etspec b/calendar/gui/e-memo-table.etspec index ce2f194399..6474b69d96 100644 --- a/calendar/gui/e-memo-table.etspec +++ b/calendar/gui/e-memo-table.etspec @@ -1,13 +1,13 @@ <ETableSpecification click-to-add="true" _click-to-add-message="Click to add a memo" draw-grid="true"> - <ETableColumn model_col="4" _title="Summary" expansion="3.0" minimum_width="10" resizable="true" cell="calstring" compare="stringcase" priority="0"/> - <ETableColumn model_col="19" _title="Memo sort" cell="task-sort" compare="memo-sort" priority="-4"/> + <ETableColumn model_col="8" _title="Summary" expansion="3.0" minimum_width="10" resizable="true" cell="calstring" compare="stringcase" priority="0"/> <ETableColumn model_col="7" pixbuf="icon" _title="Type" expansion="1.0" minimum_width="16" resizable="false" cell="icon" compare="integer" priority="-4"/> <ETableColumn model_col="0" _title="Categories" cell="calstring" compare="string" expansion="1.0" minimum_width="10" resizable="true" priority="-2"/> + <ETableColumn model_col="5" _title="Start Date" expansion="2.0" minimum_width="10" resizable="true" cell="dateedit" compare="date-compare" priority="-2"/> + <ETableColumn model_col="19" _title="Memo sort" cell="task-sort" compare="memo-sort" priority="-4"/> <ETableState> - <column source="4"/> + <column source="1"/> <column source="0"/> - <column source="2"/> <grouping></grouping> </ETableState> </ETableSpecification> diff --git a/calendar/gui/e-memo-table.h b/calendar/gui/e-memo-table.h index da01405ac0..58e242c35d 100644 --- a/calendar/gui/e-memo-table.h +++ b/calendar/gui/e-memo-table.h @@ -56,6 +56,9 @@ struct _EMemoTable { GtkWidget *etable; + /* The ECell used to view & edit dates. */ + ECellDateEdit *dates_cell; + /* Fields used for cut/copy/paste */ icalcomponent *tmp_vcal; diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c index 0e0b92c22a..9c6a219fb6 100644 --- a/calendar/gui/gnome-cal.c +++ b/calendar/gui/gnome-cal.c @@ -68,9 +68,11 @@ #include "e-cal-list-view-config.h" #include "e-mini-calendar-config.h" #include "e-calendar-table-config.h" +#include "e-memo-table-config.h" #include "evolution-calendar.h" #include "gnome-cal.h" #include "calendar-component.h" +#include "memos-component.h" #include "cal-search-bar.h" #include "calendar-commands.h" #include "calendar-config.h" @@ -114,12 +116,16 @@ struct _GnomeCalendarPrivate { GtkWidget *hpane; GtkWidget *notebook; + GtkWidget *vpane; ECalendar *date_navigator; EMiniCalendarConfig *date_navigator_config; GtkWidget *todo; ECalendarTableConfig *todo_config; + GtkWidget *memo; + EMemoTableConfig *memo_config; + GtkWidget *day_view; GtkWidget *work_week_view; GtkWidget *week_view; @@ -132,11 +138,13 @@ struct _GnomeCalendarPrivate { /* plugin menu managers */ ECalMenu *calendar_menu; ECalMenu *taskpad_menu; + ECalMenu *memopad_menu; /* Calendar query for the date navigator */ GList *dn_queries; /* list of CalQueries */ char *sexp; char *todo_sexp; + char *memo_sexp; guint update_timeout; guint update_marcus_bains_line_timeout; @@ -155,6 +163,8 @@ struct _GnomeCalendarPrivate { will work OK after theme changes. */ gint hpane_pos; gint hpane_pos_month_view; + gint vpane_pos; + gint vpane_pos_month_view; /* The signal handler id for our GtkCalendar "day_selected" handler. */ guint day_selected_id; @@ -183,8 +193,10 @@ enum { DATES_SHOWN_CHANGED, CALENDAR_SELECTION_CHANGED, TASKPAD_SELECTION_CHANGED, + MEMOPAD_SELECTION_CHANGED, CALENDAR_FOCUS_CHANGE, TASKPAD_FOCUS_CHANGE, + MEMOPAD_FOCUS_CHANGE, GOTO_DATE, SOURCE_ADDED, SOURCE_REMOVED, @@ -196,6 +208,7 @@ enum { typedef enum { FOCUS_CALENDAR, FOCUS_TASKPAD, + FOCUS_MEMOPAD, FOCUS_OTHER } FocusLocation; @@ -217,6 +230,8 @@ static void gnome_calendar_update_date_navigator (GnomeCalendar *gcal); static void gnome_calendar_hpane_realized (GtkWidget *w, GnomeCalendar *gcal); static void gnome_calendar_date_navigator_scrolled (GtkWidget *widget, GdkEventScroll *event, gpointer user_data); static gboolean gnome_calendar_hpane_resized (GtkWidget *w, GdkEventButton *e, GnomeCalendar *gcal); +static void gnome_calendar_vpane_realized (GtkWidget *w, GnomeCalendar *gcal); +static gboolean gnome_calendar_vpane_resized (GtkWidget *w, GdkEventButton *e, GnomeCalendar *gcal); static void gnome_calendar_on_date_navigator_date_range_changed (ECalendarItem *calitem, GnomeCalendar *gcal); @@ -227,6 +242,7 @@ static void gnome_calendar_notify_dates_shown_changed (GnomeCalendar *gcal); static void update_query (GnomeCalendar *gcal); static void update_todo_view (GnomeCalendar *gcal); +static void update_memo_view (GnomeCalendar *gcal); G_DEFINE_TYPE (GnomeCalendar, gnome_calendar, GTK_TYPE_VBOX) @@ -264,6 +280,15 @@ gnome_calendar_class_init (GnomeCalendarClass *class) gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); + gnome_calendar_signals[MEMOPAD_SELECTION_CHANGED] = + gtk_signal_new ("memopad_selection_changed", + GTK_RUN_LAST, + G_TYPE_FROM_CLASS (object_class), + GTK_SIGNAL_OFFSET (GnomeCalendarClass, memopad_selection_changed), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + + gnome_calendar_signals[CALENDAR_FOCUS_CHANGE] = gtk_signal_new ("calendar_focus_change", GTK_RUN_FIRST, @@ -282,6 +307,15 @@ gnome_calendar_class_init (GnomeCalendarClass *class) GTK_TYPE_NONE, 1, GTK_TYPE_BOOL); + gnome_calendar_signals[MEMOPAD_FOCUS_CHANGE] = + gtk_signal_new ("memopad_focus_change", + GTK_RUN_FIRST, + G_TYPE_FROM_CLASS (object_class), + GTK_SIGNAL_OFFSET (GnomeCalendarClass, memopad_focus_change), + gtk_marshal_NONE__BOOL, + GTK_TYPE_NONE, 1, + GTK_TYPE_BOOL); + gnome_calendar_signals[SOURCE_ADDED] = g_signal_new ("source_added", G_TYPE_FROM_CLASS (object_class), @@ -331,8 +365,10 @@ gnome_calendar_class_init (GnomeCalendarClass *class) class->dates_shown_changed = NULL; class->calendar_selection_changed = NULL; class->taskpad_selection_changed = NULL; + class->memopad_selection_changed = NULL; class->calendar_focus_change = NULL; class->taskpad_focus_change = NULL; + class->memopad_focus_change = NULL; class->source_added = NULL; class->source_removed = NULL; class->goto_date = gnome_calendar_goto_date; @@ -647,14 +683,17 @@ static FocusLocation get_focus_location (GnomeCalendar *gcal) { GnomeCalendarPrivate *priv; - ETable *etable; + ETable *etable, *m_etable; priv = gcal->priv; etable = e_calendar_table_get_table (E_CALENDAR_TABLE (priv->todo)); + m_etable = e_memo_table_get_table (E_MEMO_TABLE (priv->memo)); if (GTK_WIDGET_HAS_FOCUS (etable->table_canvas)) return FOCUS_TASKPAD; + else if (GTK_WIDGET_HAS_FOCUS (m_etable->table_canvas)) + return FOCUS_MEMOPAD; else { GtkWidget *widget; EDayView *dv; @@ -959,6 +998,19 @@ table_canvas_focus_change_cb (GtkWidget *widget, GdkEventFocus *event, gpointer } static gint +memo_canvas_focus_change_cb (GtkWidget *widget, GdkEventFocus *event, gpointer data) +{ + GnomeCalendar *gcal; + + gcal = GNOME_CALENDAR (data); + + gtk_signal_emit (GTK_OBJECT (gcal), gnome_calendar_signals [MEMOPAD_FOCUS_CHANGE], + event->in ? TRUE : FALSE); + + return FALSE; +} + +static gint calendar_focus_change_cb (GtkWidget *widget, GdkEventFocus *event, gpointer data) { GnomeCalendar *gcal; @@ -1026,6 +1078,16 @@ table_selection_change_cb (ETable *etable, gpointer data) } static void +memo_selection_change_cb (ETable *etable, gpointer data) +{ + GnomeCalendar *gcal; + + gcal = GNOME_CALENDAR (data); + + gtk_signal_emit (GTK_OBJECT (gcal), gnome_calendar_signals[MEMOPAD_SELECTION_CHANGED]); +} + +static void set_week_start (GnomeCalendar *calendar) { GnomeCalendarPrivate *priv; @@ -1137,6 +1199,41 @@ update_todo_view (GnomeCalendar *gcal) } static void +update_memo_view (GnomeCalendar *gcal) +{ + GnomeCalendarPrivate *priv; + ECalModel *model, *view_model; + time_t start, end; + char *iso_start, *iso_end; + + priv = gcal->priv; + + /* Set the query on the memo pad*/ + if (priv->memo_sexp) { + g_free (priv->memo_sexp); + } + + model = e_memo_table_get_model (E_MEMO_TABLE (priv->memo)); + view_model = e_calendar_view_get_model(priv->views[priv->current_view_type]); + e_cal_model_get_time_range (view_model, &start, &end); + + if (start != -1 && end != -1) { + iso_start = isodate_from_time_t (start); + iso_end = isodate_from_time_t (end); + + priv->memo_sexp = g_strdup_printf ("(and (occur-in-time-range? (make-time \"%s\")" + " (make-time \"%s\"))" + " %s)", + iso_start, iso_end, + priv->sexp ? priv->sexp : ""); + e_cal_model_set_search_query (model, priv->memo_sexp); + + g_free (iso_start); + g_free (iso_end); + } +} + +static void process_completed_tasks (GnomeCalendar *gcal, gboolean config_changed) { GnomeCalendarPrivate *priv; @@ -1221,7 +1318,9 @@ setup_config (GnomeCalendar *calendar) /* Pane positions */ priv->hpane_pos = calendar_config_get_hpane_pos (); + priv->vpane_pos = calendar_config_get_vpane_pos (); priv->hpane_pos_month_view = calendar_config_get_month_hpane_pos (); + priv->vpane_pos_month_view = calendar_config_get_month_vpane_pos (); } static void @@ -1307,6 +1406,8 @@ view_progress_cb (ECalModel *model, const char *message, int percent, ECalSource e_calendar_view_set_status_message (E_CALENDAR_VIEW (gcal->priv->week_view), message, percent); } else if (type == E_CAL_SOURCE_TYPE_TODO) { e_calendar_table_set_status_message (E_CALENDAR_TABLE (gcal->priv->todo), message, percent); + } else if (type == E_CAL_SOURCE_TYPE_JOURNAL) { + e_memo_table_set_status_message (E_MEMO_TABLE (gcal->priv->memo), message); } } @@ -1317,6 +1418,8 @@ view_done_cb (ECalModel *model, ECalendarStatus status, ECalSourceType type, Gno e_calendar_view_set_status_message (E_CALENDAR_VIEW (gcal->priv->week_view), NULL, -1); } else if (type == E_CAL_SOURCE_TYPE_TODO) { e_calendar_table_set_status_message (E_CALENDAR_TABLE (gcal->priv->todo), NULL, -1); + } else if (type == E_CAL_SOURCE_TYPE_JOURNAL) { + e_memo_table_set_status_message (E_MEMO_TABLE (gcal->priv->memo), NULL); } } @@ -1331,11 +1434,13 @@ static void setup_widgets (GnomeCalendar *gcal) { GnomeCalendarPrivate *priv; - GtkWidget *w; + GtkWidget *w, *sep; gchar *filename; ETable *etable; GtkAdjustment *adjustment; ECalModel *w_model; + GtkWidget *vbox; + GtkWidget *label; int i; priv = gcal->priv; @@ -1384,12 +1489,34 @@ setup_widgets (GnomeCalendar *gcal) G_CALLBACK (gnome_calendar_on_date_navigator_date_range_changed), gcal); g_signal_connect (w, "scroll-event", G_CALLBACK (gnome_calendar_date_navigator_scrolled), gcal); + + /* The VPaned widget, to contain the ToDo list & Memo list */ + priv->vpane = gtk_vpaned_new (); + g_signal_connect_after (priv->vpane, "realize", + G_CALLBACK(gnome_calendar_vpane_realized), gcal); + g_signal_connect (priv->vpane, "button_release_event", + G_CALLBACK (gnome_calendar_vpane_resized), gcal); + gtk_widget_show (priv->vpane); + gtk_paned_pack2 (GTK_PANED (priv->hpane), priv->vpane, TRUE, TRUE); /* The ToDo list. */ + vbox = gtk_vbox_new (FALSE, 0); + sep = gtk_hseparator_new (); + gtk_box_pack_start ((GtkBox *)vbox, sep, FALSE, TRUE, 0); + + label = gtk_label_new (NULL); + gtk_label_set_markup ((GtkLabel *)label, "<b> Tasks </b>"); + gtk_box_pack_start ((GtkBox *)vbox, label, FALSE, TRUE, 0); + priv->todo = e_calendar_table_new (); priv->todo_config = e_calendar_table_config_new (E_CALENDAR_TABLE (priv->todo)); - gtk_paned_pack2 (GTK_PANED (priv->hpane), priv->todo, TRUE, TRUE); + gtk_paned_pack1 (GTK_PANED (priv->vpane), vbox, FALSE, TRUE); + gtk_box_pack_end ((GtkBox *)vbox, priv->todo, TRUE, TRUE, 0); + gtk_widget_show (priv->todo); + gtk_widget_show (label); + gtk_widget_show (vbox); + gtk_widget_show (sep); filename = g_build_filename (calendar_component_peek_config_directory (calendar_component_peek ()), "TaskPad", NULL); @@ -1501,6 +1628,42 @@ setup_widgets (GnomeCalendar *gcal) gtk_widget_show (GTK_WIDGET (priv->views[i])); } + /* Memo view */ + vbox = gtk_vbox_new (FALSE, 0); + label = gtk_label_new (NULL); + gtk_label_set_markup ((GtkLabel *)label, "<b> Memos </b>"); + gtk_box_pack_start ((GtkBox *)vbox, label, FALSE, TRUE, 0); + priv->memo = e_memo_table_new (); + priv->memo_config = e_memo_table_config_new (E_MEMO_TABLE (priv->memo)); + gtk_paned_pack2 (GTK_PANED (priv->vpane), vbox, TRUE, TRUE); + gtk_box_pack_end ((GtkBox *)vbox, priv->memo, TRUE, TRUE, 0); + + gtk_widget_show (priv->memo); + gtk_widget_show (label); + gtk_widget_show (vbox); + + filename = g_build_filename (memos_component_peek_config_directory (memos_component_peek ()), + "MemoPad", NULL); + e_memo_table_load_state (E_MEMO_TABLE (priv->memo), filename); + + update_memo_view (gcal); + g_free (filename); + + etable = e_memo_table_get_table (E_MEMO_TABLE (priv->memo)); + g_signal_connect (etable->table_canvas, "focus_in_event", + G_CALLBACK (memo_canvas_focus_change_cb), gcal); + g_signal_connect (etable->table_canvas, "focus_out_event", + G_CALLBACK (memo_canvas_focus_change_cb), gcal); + + g_signal_connect (etable, "selection_change", + G_CALLBACK (memo_selection_change_cb), gcal); + + g_signal_connect (e_memo_table_get_model ((EMemoTable *)priv->memo), "cal_view_progress", + G_CALLBACK (view_progress_cb), gcal); + g_signal_connect (e_memo_table_get_model ((EMemoTable *)priv->memo), "cal_view_done", + G_CALLBACK (view_done_cb), gcal); + + /* make sure we set the initial time ranges for the views */ update_view_times (gcal, time (NULL)); gnome_calendar_update_date_navigator (gcal); @@ -1530,10 +1693,12 @@ gnome_calendar_init (GnomeCalendar *gcal) priv->calendar_menu = e_cal_menu_new("org.gnome.evolution.calendar.view"); priv->taskpad_menu = e_cal_menu_new("org.gnome.evolution.calendar.taskpad"); + priv->memopad_menu = e_cal_menu_new ("org.gnome.evolution.calendar.memopad"); priv->dn_queries = NULL; priv->sexp = g_strdup ("#t"); /* Match all */ priv->todo_sexp = g_strdup ("#t"); + priv->memo_sexp = g_strdup ("#t"); priv->view_instance = NULL; priv->view_menus = NULL; @@ -1598,6 +1763,7 @@ gnome_calendar_destroy (GtkObject *object) } g_object_unref (priv->date_navigator_config); g_object_unref (priv->todo_config); + g_object_unref (priv->memo_config); for (l = priv->notifications; l; l = l->next) calendar_config_remove_notification (GPOINTER_TO_UINT (l->data)); @@ -1609,6 +1775,12 @@ gnome_calendar_destroy (GtkObject *object) "TaskPad", NULL); e_calendar_table_save_state (E_CALENDAR_TABLE (priv->todo), filename); g_free (filename); + + /* Save the MemoPad layout. */ + filename = g_build_filename (memos_component_peek_config_directory (memos_component_peek ()), + "MemoPad", NULL); + e_memo_table_save_state (E_MEMO_TABLE (priv->memo), filename); + g_free (filename); if (priv->dn_queries) { for (l = priv->dn_queries; l != NULL; l = l->next) { @@ -1631,6 +1803,11 @@ gnome_calendar_destroy (GtkObject *object) priv->todo_sexp = NULL; } + if (priv->memo_sexp) { + g_free (priv->memo_sexp); + priv->memo_sexp = NULL; + } + if (priv->update_timeout) { g_source_remove (priv->update_timeout); priv->update_timeout = 0; @@ -1661,6 +1838,11 @@ gnome_calendar_destroy (GtkObject *object) priv->taskpad_menu = NULL; } + if (priv->memopad_menu) { + g_object_unref (priv->memopad_menu); + priv->memopad_menu = NULL; + } + g_free (priv); gcal->priv = NULL; } @@ -2321,8 +2503,10 @@ gnome_calendar_set_pane_positions (GnomeCalendar *gcal) if (priv->current_view_type == GNOME_CAL_MONTH_VIEW && !priv->range_selected) { gtk_paned_set_position (GTK_PANED (priv->hpane), priv->hpane_pos_month_view); + gtk_paned_set_position (GTK_PANED (priv->vpane), priv->vpane_pos_month_view); } else { gtk_paned_set_position (GTK_PANED (priv->hpane), priv->hpane_pos); + gtk_paned_set_position (GTK_PANED (priv->vpane), priv->vpane_pos); } } @@ -2349,6 +2533,8 @@ client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal) case E_CAL_SOURCE_TYPE_TODO: e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo), NULL, -1); break; + case E_CAL_SOURCE_TYPE_JOURNAL: + e_memo_table_set_status_message (E_MEMO_TABLE (priv->memo), NULL); default: break; } @@ -2412,7 +2598,13 @@ client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal) e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo), NULL, -1); break; - + case E_CAL_SOURCE_TYPE_JOURNAL: + msg = g_strdup_printf (_("Loading memos at %s"), e_cal_get_uri (ecal)); + e_memo_table_set_status_message (E_MEMO_TABLE (priv->memo), msg); + g_free (msg); + e_cal_model_add_client (e_memo_table_get_model (E_MEMO_TABLE (priv->memo)), ecal); + e_memo_table_set_status_message (E_MEMO_TABLE (priv->memo), NULL); + break; default: g_assert_not_reached (); return; @@ -2441,6 +2633,9 @@ default_client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar case E_CAL_SOURCE_TYPE_TODO: e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo), NULL, -1); break; + case E_CAL_SOURCE_TYPE_JOURNAL: + e_memo_table_set_status_message (E_MEMO_TABLE (priv->memo), NULL); + break; default: break; } @@ -2488,7 +2683,9 @@ default_client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar case E_CAL_SOURCE_TYPE_TODO: e_cal_model_set_default_client (e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo)), ecal); break; - + case E_CAL_SOURCE_TYPE_JOURNAL: + e_cal_model_set_default_client (e_memo_table_get_model (E_MEMO_TABLE (priv->memo)), ecal); + break; default: break; } @@ -2516,6 +2713,9 @@ open_ecal (GnomeCalendar *gcal, ECal *cal, gboolean only_if_exists, open_func of case E_CAL_SOURCE_TYPE_TODO : e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo), msg, -1); break; + case E_CAL_SOURCE_TYPE_JOURNAL: + e_memo_table_set_status_message (E_MEMO_TABLE (priv->memo), msg); + break; default: g_assert_not_reached (); break; @@ -2584,7 +2784,14 @@ backend_died_cb (ECal *ecal, gpointer data) gtk_signal_emit (GTK_OBJECT (gcal), gnome_calendar_signals[SOURCE_REMOVED], source_type, source); break; + + case E_CAL_SOURCE_TYPE_JOURNAL: + id = "calendar:memos-crashed"; + + e_memo_table_set_status_message (E_MEMO_TABLE (priv->memo), NULL); + gtk_signal_emit (GTK_OBJECT (gcal), gnome_calendar_signals[SOURCE_REMOVED], source_type, source); + break; default: g_assert_not_reached (); return; @@ -2827,6 +3034,11 @@ gnome_calendar_remove_source_by_uid (GnomeCalendar *gcal, ECalSourceType source_ model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo)); e_cal_model_remove_client (model, client); break; + + case E_CAL_SOURCE_TYPE_JOURNAL: + model = e_memo_table_get_model (E_MEMO_TABLE (priv->memo)); + e_cal_model_remove_client (model, client); + break; default: g_assert_not_reached (); @@ -3180,6 +3392,37 @@ gnome_calendar_hpane_resized (GtkWidget *w, GdkEventButton *e, GnomeCalendar *gc return FALSE; } +static void +gnome_calendar_vpane_realized (GtkWidget *w, GnomeCalendar *gcal) +{ + GnomeCalendarPrivate *priv; + + priv = gcal->priv; + + if (priv->current_view_type == GNOME_CAL_MONTH_VIEW && !priv->range_selected) { + gtk_paned_set_position (GTK_PANED (priv->vpane), priv->vpane_pos_month_view); + } else { + gtk_paned_set_position (GTK_PANED (priv->vpane), priv->vpane_pos); + } +} + +static gboolean +gnome_calendar_vpane_resized (GtkWidget *w, GdkEventButton *e, GnomeCalendar *gcal) +{ + GnomeCalendarPrivate *priv; + + priv = gcal->priv; + + if (priv->current_view_type == GNOME_CAL_MONTH_VIEW && !priv->range_selected) { + priv->vpane_pos_month_view = gtk_paned_get_position (GTK_PANED (priv->vpane)); + calendar_config_set_month_vpane_pos (priv->vpane_pos_month_view); + } else { + priv->vpane_pos = gtk_paned_get_position (GTK_PANED (priv->vpane)); + calendar_config_set_vpane_pos (priv->vpane_pos); + } + + return FALSE; +} void gnome_calendar_cut_clipboard (GnomeCalendar *gcal) @@ -3195,6 +3438,8 @@ gnome_calendar_cut_clipboard (GnomeCalendar *gcal) e_calendar_view_cut_clipboard (E_CALENDAR_VIEW (gnome_calendar_get_current_view_widget (gcal))); } else if (location == FOCUS_TASKPAD) e_calendar_table_cut_clipboard (E_CALENDAR_TABLE (priv->todo)); + else if (location == FOCUS_MEMOPAD) + e_calendar_table_copy_clipboard (E_MEMO_TABLE (priv->memo)); } void @@ -3211,6 +3456,8 @@ gnome_calendar_copy_clipboard (GnomeCalendar *gcal) e_calendar_view_copy_clipboard (E_CALENDAR_VIEW (gnome_calendar_get_current_view_widget (gcal))); } else if (location == FOCUS_TASKPAD) e_calendar_table_copy_clipboard (E_CALENDAR_TABLE (priv->todo)); + else if (location == FOCUS_MEMOPAD) + e_calendar_table_copy_clipboard (E_MEMO_TABLE (priv->memo)); } void @@ -3227,6 +3474,8 @@ gnome_calendar_paste_clipboard (GnomeCalendar *gcal) e_calendar_view_paste_clipboard (E_CALENDAR_VIEW (gnome_calendar_get_current_view_widget (gcal))); } else if (location == FOCUS_TASKPAD) e_calendar_table_paste_clipboard (E_CALENDAR_TABLE (priv->todo)); + else if (location == FOCUS_MEMOPAD) + e_memo_table_paste_clipboard (E_MEMO_TABLE (priv->memo)); } @@ -3267,6 +3516,7 @@ gnome_calendar_notify_dates_shown_changed (GnomeCalendar *gcal) gtk_signal_emit (GTK_OBJECT (gcal), gnome_calendar_signals[DATES_SHOWN_CHANGED]); } + update_memo_view (gcal); } @@ -3332,6 +3582,8 @@ gnome_calendar_delete_selection (GnomeCalendar *gcal) e_calendar_view_delete_selected_events (E_CALENDAR_VIEW (view)); } else if (location == FOCUS_TASKPAD) e_calendar_table_delete_selected (E_CALENDAR_TABLE (priv->todo)); + else if (location == FOCUS_MEMOPAD) + e_memo_table_delete_selected (E_MEMO_TABLE (priv->memo)); } void @@ -3492,6 +3744,14 @@ ECalMenu *gnome_calendar_get_calendar_menu (GnomeCalendar *gcal) return gcal->priv->calendar_menu; } +ECalMenu *gnome_calendar_get_memopad_menu (GnomeCalendar *gcal) +{ + g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL); + + return gcal->priv->memopad_menu; +} + + void gnome_calendar_edit_appointment (GnomeCalendar *gcal, const char* src_uid, diff --git a/calendar/gui/gnome-cal.h b/calendar/gui/gnome-cal.h index f0b12507e1..de17acbf9e 100644 --- a/calendar/gui/gnome-cal.h +++ b/calendar/gui/gnome-cal.h @@ -86,9 +86,11 @@ struct _GnomeCalendarClass { void (* calendar_selection_changed) (GnomeCalendar *gcal); void (* taskpad_selection_changed) (GnomeCalendar *gcal); + void (* memopad_selection_changed) (GnomeCalendar *gcal); void (* calendar_focus_change) (GnomeCalendar *gcal, gboolean in); void (* taskpad_focus_change) (GnomeCalendar *gcal, gboolean in); + void (* memopad_focus_change) (GnomeCalendar *gcal, gboolean in); void (* change_view) (GnomeCalendar *gcal, GnomeCalendarViewType view_type); @@ -139,6 +141,7 @@ GtkWidget *gnome_calendar_get_view_notebook_widget (GnomeCalendar *gcal); struct _ECalMenu *gnome_calendar_get_taskpad_menu (GnomeCalendar *gcal); struct _ECalMenu *gnome_calendar_get_calendar_menu (GnomeCalendar *gcal); +struct _ECalMenu *gnome_calendar_get_memopad_menu (GnomeCalendar *gcal); void gnome_calendar_setup_view_menus (GnomeCalendar *gcal, BonoboUIComponent *uic); void gnome_calendar_discard_view_menus (GnomeCalendar *gcal); diff --git a/calendar/gui/memos-component.c b/calendar/gui/memos-component.c index 90bd9509b0..5eb8cc5c97 100644 --- a/calendar/gui/memos-component.c +++ b/calendar/gui/memos-component.c @@ -56,6 +56,7 @@ #include "calendar-component.h" #define CREATE_MEMO_ID "memo" +#define CREATE_SHARED_MEMO_ID "shared-memo" #define CREATE_MEMO_LIST_ID "memo-list" enum DndTargetType { @@ -905,12 +906,19 @@ create_new_memo (MemosComponent *memo_component, gboolean is_assigned, MemosComp ECal *ecal; ECalComponent *comp; MemoEditor *editor; + CompEditorFlags flags = 0; ecal = setup_create_ecal (memo_component, component_view); if (!ecal) return FALSE; - editor = memo_editor_new (ecal); + flags |= COMP_EDITOR_NEW_ITEM; + if (is_assigned) { + flags |= COMP_EDITOR_IS_SHARED; + flags |= COMP_EDITOR_USER_ORG; + } + + editor = memo_editor_new (ecal, flags); comp = cal_comp_memo_new_with_defaults (ecal); comp_editor_edit_comp (COMP_EDITOR (editor), comp); @@ -942,8 +950,9 @@ create_local_item_cb (EUserCreatableItemsHandler *handler, const char *item_type if (strcmp (item_type_name, CREATE_MEMO_ID) == 0) { create_new_memo (memos_component, FALSE, component_view); - } - else if (strcmp (item_type_name, CREATE_MEMO_LIST_ID) == 0) { + } else if (strcmp (item_type_name, CREATE_SHARED_MEMO_ID) == 0) { + create_new_memo (memos_component, TRUE, component_view); + } else if (strcmp (item_type_name, CREATE_MEMO_LIST_ID) == 0) { calendar_setup_new_memo_list (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (component_view->memos)))); } } @@ -1145,7 +1154,7 @@ impl__get_userCreatableItems (PortableServer_Servant servant, { GNOME_Evolution_CreatableItemTypeList *list = GNOME_Evolution_CreatableItemTypeList__alloc (); - list->_length = 2; + list->_length = 3; list->_maximum = list->_length; list->_buffer = GNOME_Evolution_CreatableItemTypeList_allocbuf (list->_length); @@ -1159,13 +1168,21 @@ impl__get_userCreatableItems (PortableServer_Servant servant, list->_buffer[0].iconName = "stock_insert-note"; list->_buffer[0].type = GNOME_Evolution_CREATABLE_OBJECT; - list->_buffer[1].id = CREATE_MEMO_LIST_ID; - list->_buffer[1].description = _("New memo list"); - list->_buffer[1].menuDescription = _("Memo li_st"); - list->_buffer[1].tooltip = _("Create a new memo list"); - list->_buffer[1].menuShortcut = '\0'; - list->_buffer[1].iconName = "stock_notes"; - list->_buffer[1].type = GNOME_Evolution_CREATABLE_FOLDER; + list->_buffer[1].id = CREATE_SHARED_MEMO_ID; + list->_buffer[1].description = _("New shared memo"); + list->_buffer[1].menuDescription = _("_Shared memo"); + list->_buffer[1].tooltip = _("Create a shared new memo"); + list->_buffer[1].menuShortcut = 's'; + list->_buffer[1].iconName = "stock_insert-note"; + list->_buffer[1].type = GNOME_Evolution_CREATABLE_OBJECT; + + list->_buffer[2].id = CREATE_MEMO_LIST_ID; + list->_buffer[2].description = _("New memo list"); + list->_buffer[2].menuDescription = _("Memo li_st"); + list->_buffer[2].tooltip = _("Create a new memo list"); + list->_buffer[2].menuShortcut = '\0'; + list->_buffer[2].iconName = "stock_notes"; + list->_buffer[2].type = GNOME_Evolution_CREATABLE_FOLDER; return list; } @@ -1184,6 +1201,9 @@ impl_requestCreateItem (PortableServer_Servant servant, else if (strcmp (item_type_name, CREATE_MEMO_LIST_ID) == 0) { /* FIXME Should we use the last opened window? */ calendar_setup_new_memo_list (NULL); + } else if (strcmp (item_type_name, CREATE_SHARED_MEMO_ID) == 0) { + if (!create_new_memo (memos_component, TRUE, NULL)) + bonobo_exception_set (ev, ex_GNOME_Evolution_Component_Failed); } else { bonobo_exception_set (ev, ex_GNOME_Evolution_Component_UnknownType); |