diff options
Diffstat (limited to 'calendar')
126 files changed, 19564 insertions, 10967 deletions
diff --git a/calendar/Makefile.am b/calendar/Makefile.am index 87057a4d3a..20f45f68f9 100644 --- a/calendar/Makefile.am +++ b/calendar/Makefile.am @@ -4,7 +4,7 @@ else CONDUIT_DIR = endif -SUBDIRS = idl common importers gui $(CONDUIT_DIR) +SUBDIRS = idl common importers gui $(CONDUIT_DIR) modules error_DATA = calendar.error errordir = $(privdatadir)/errors diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am index 509aff1596..a2b4be2b8f 100644 --- a/calendar/gui/Makefile.am +++ b/calendar/gui/Makefile.am @@ -1,31 +1,5 @@ -if OS_WIN32 -WIN32_BOOTSTRAP_LIBS = $(top_builddir)/win32/libevolution-mail.la -endif - -## CORBA stuff - -IDLS = \ - $(top_srcdir)/calendar/idl/evolution-calendar.idl - -CALENDAR_IDL_GENERATED_H = \ - evolution-calendar.h -CALENDAR_IDL_GENERATED_C = \ - evolution-calendar-common.c \ - evolution-calendar-skels.c \ - evolution-calendar-stubs.c -CALENDAR_IDL_GENERATED = $(CALENDAR_IDL_GENERATED_C) $(CALENDAR_IDL_GENERATED_H) - -$(CALENDAR_IDL_GENERATED_H): $(IDLS) - $(ORBIT_IDL) -I $(srcdir) $(IDL_INCLUDES) \ - $(top_srcdir)/calendar/idl/evolution-calendar.idl -$(CALENDAR_IDL_GENERATED_C): $(CALENDAR_IDL_GENERATED_H) - -IDL_GENERATED = $(CALENDAR_IDL_GENERATED) - SUBDIRS = alarm-notify dialogs -component_LTLIBRARIES = libevolution-calendar.la - ecalendarincludedir = $(privincludedir)/calendar/gui ecalendarinclude_HEADERS = \ @@ -67,35 +41,34 @@ etspec_DATA = \ e-cal-list-view.etspec \ e-memo-table.etspec -libevolution_calendar_la_SOURCES = \ - $(IDL_GENERATED) \ +privsolib_LTLIBRARIES = libcal-gui.la + +# Removed from SOURCES +# cal-search-bar.c +# cal-search-bar.h +# gnome-cal.c +# gnome-cal.h + +libcal_gui_la_SOURCES = \ e-attachment-handler-calendar.c \ e-attachment-handler-calendar.h \ - cal-search-bar.c \ - cal-search-bar.h \ + e-calendar-view.c \ + e-calendar-view.h \ + e-calendar-table.c \ + e-calendar-table.h \ calendar-config.c \ calendar-config.h \ calendar-config-keys.h \ - calendar-commands.c \ - calendar-commands.h \ - calendar-component.c \ - calendar-component.h \ calendar-view.c \ calendar-view.h \ calendar-view-factory.c \ calendar-view-factory.h \ - comp-editor-factory.c \ - comp-editor-factory.h \ comp-util.c \ comp-util.h \ - control-factory.c \ - control-factory.h \ e-alarm-list.c \ e-alarm-list.h \ e-cal-component-preview.c \ e-cal-component-preview.h \ - e-cal-component-memo-preview.c \ - e-cal-component-memo-preview.h \ e-cal-config.c \ e-cal-config.h \ e-cal-event.c \ @@ -111,18 +84,16 @@ libevolution_calendar_la_SOURCES = \ e-cal-model.h \ e-cal-popup.h \ e-cal-popup.c \ - e-calendar-view.c \ - e-calendar-view.h \ e-cal-list-view.c \ e-cal-list-view.h \ e-cal-list-view-config.c \ e-cal-list-view-config.h \ e-cal-model-memos.c \ e-cal-model-memos.h \ - e-calendar-table.c \ - e-calendar-table.h \ e-calendar-table-config.c \ e-calendar-table-config.h \ + e-calendar-selector.c \ + e-calendar-selector.h \ e-cell-date-edit-config.c \ e-cell-date-edit-config.h \ e-cell-date-edit-text.h \ @@ -160,18 +131,20 @@ libevolution_calendar_la_SOURCES = \ e-meeting-types.h \ e-meeting-utils.c \ e-meeting-utils.h \ + e-memo-list-selector.c \ + e-memo-list-selector.h \ e-memo-table.c \ e-memo-table.h \ e-memo-table-config.c \ e-memo-table-config.h \ - e-memos.c \ - e-memos.h \ e-mini-calendar-config.c \ e-mini-calendar-config.h \ e-select-names-editable.c \ e-select-names-editable.h \ e-select-names-renderer.c \ e-select-names-renderer.h \ + e-task-list-selector.c \ + e-task-list-selector.h \ e-week-view-config.c \ e-week-view-config.h \ e-week-view-event-item.c \ @@ -184,60 +157,44 @@ libevolution_calendar_la_SOURCES = \ e-week-view-titles-item.h \ e-week-view.c \ e-week-view.h \ - e-tasks.c \ - e-tasks.h \ e-timezone-entry.c \ e-timezone-entry.h \ - gnome-cal.c \ - gnome-cal.h \ goto.c \ goto.h \ - itip-bonobo-control.c \ - itip-bonobo-control.h \ itip-utils.c \ itip-utils.h \ - main.c \ - memos-component.c \ - memos-component.h \ - memos-control.c \ - memos-control.h \ - migration.c \ - migration.h \ misc.c \ misc.h \ print.c \ print.h \ tag-calendar.c \ tag-calendar.h \ - tasks-component.c \ - tasks-component.h \ - tasks-control.c \ - tasks-control.h \ weekday-picker.c \ weekday-picker.h -libevolution_calendar_la_LIBADD = \ +# Removed +# $(top_builddir)/a11y/calendar/libevolution-calendar-a11y.la + +libcal_gui_la_LIBADD = \ $(WIN32_BOOTSTRAP_LIBS) \ + $(top_builddir)/composer/libcomposer.la \ + $(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.la \ + $(top_builddir)/addressbook/gui/contact-list-editor/libecontactlisteditor.la \ $(top_builddir)/widgets/menus/libmenus.la \ $(top_builddir)/shell/libeshell.la \ $(top_builddir)/calendar/common/libevolution-calendarprivate.la \ $(top_builddir)/calendar/gui/dialogs/libcal-dialogs.la \ $(top_builddir)/calendar/importers/libevolution-calendar-importers.la \ $(top_builddir)/widgets/e-timezone-dialog/libetimezonedialog.la \ - $(top_builddir)/widgets/misc/libefilterbar.la \ $(top_builddir)/widgets/misc/libemiscwidgets.la \ $(top_builddir)/filter/libfilter.la \ $(top_builddir)/e-util/libeutil.la \ - $(top_builddir)/a11y/calendar/libevolution-calendar-a11y.la \ $(LIBSOUP_LIBS) \ $(CAMEL_LIBS) \ $(EVOLUTION_CALENDAR_LIBS) -libevolution_calendar_la_LDFLAGS = -avoid-version -module $(NO_UNDEFINED) +libcal_gui_la_LDFLAGS = -avoid-version -module $(NO_UNDEFINED) -server_in_files = GNOME_Evolution_Calendar.server.in.in -server_DATA = $(server_in_files:.server.in.in=.server) -@EVO_SERVER_RULE@ @INTLTOOL_SERVER_RULE@ # GConf schemas @@ -252,10 +209,8 @@ EXTRA_DIST = \ $(glade_DATA) \ $(schema_in_files) \ $(etspec_DATA) \ - $(server_in_files) \ $(search_files) -BUILT_SOURCES = $(IDL_GENERATED) $(server_DATA) CLEANFILES = $(BUILT_SOURCES) DISTCLEANFILES = $(schema_DATA) diff --git a/calendar/gui/alarm-notify/alarm-queue.c b/calendar/gui/alarm-notify/alarm-queue.c index 859b775607..17c743126a 100644 --- a/calendar/gui/alarm-notify/alarm-queue.c +++ b/calendar/gui/alarm-notify/alarm-queue.c @@ -905,6 +905,7 @@ create_snooze (CompQueuedAlarms *cqa, gpointer alarm_id, int snooze_mins) static void edit_component (ECal *client, ECalComponent *comp) { +#if 0 /* KILL-BONOBO */ const char *uid; const char *uri; ECalSourceType source_type; @@ -948,6 +949,7 @@ edit_component (ECal *client, ECalComponent *comp) /* Get rid of the factory */ bonobo_object_release_unref (factory, NULL); +#endif } typedef struct { diff --git a/calendar/gui/apps_evolution_calendar.schemas.in b/calendar/gui/apps_evolution_calendar.schemas.in index 48c5100ad8..6e5e057c14 100644 --- a/calendar/gui/apps_evolution_calendar.schemas.in +++ b/calendar/gui/apps_evolution_calendar.schemas.in @@ -268,11 +268,11 @@ </locale> </schema> <schema> - <key>/schemas/apps/evolution/calendar/display/tag_vpane_position</key> - <applyto>/apps/evolution/calendar/display/tag_vpane_position</applyto> + <key>/schemas/apps/evolution/calendar/display/date_navigator_pane_position</key> + <applyto>/apps/evolution/calendar/display/date_navigator_pane_position</applyto> <owner>evolution-calendar</owner> - <type>float</type> - <default>0.5</default> + <type>int</type> + <default>150</default> <locale name="C"> <short>Month view vertical pane position </short> <long>Position of the vertical pane, between the calendar lists and the date navigator calendar.</long> @@ -293,13 +293,25 @@ </schema> <schema> + <key>/schemas/apps/evolution/calendar/display/memo_vpane_position</key> + <applyto>/apps/evolution/calendar/display/memo_vpane_position</applyto> + <owner>evolution-calendar</owner> + <type>int</type> + <default>400</default> + <locale name="C"> + <short>Memos vertical pane position</short> + <long>Position of the vertical pane, between the memo list and the memo preview pane, in pixels.</long> + </locale> + </schema> + + <schema> <key>/schemas/apps/evolution/calendar/display/task_vpane_position</key> <applyto>/apps/evolution/calendar/display/task_vpane_position</applyto> <owner>evolution-calendar</owner> <type>int</type> <default>400</default> <locale name="C"> - <short>Tasks vertical pane position </short> + <short>Tasks vertical pane position</short> <long>Position of the vertical pane, between the task list and the task preview pane, in pixels.</long> </locale> </schema> diff --git a/calendar/gui/cal-search-bar.c b/calendar/gui/cal-search-bar.c index 9ea91f8350..b8fe5a45fd 100644 --- a/calendar/gui/cal-search-bar.c +++ b/calendar/gui/cal-search-bar.c @@ -72,12 +72,12 @@ enum { /* Comments are disabled because they are kind of useless right now, see bug 33247 */ static ESearchBarItem search_option_items[] = { - { N_("Summary contains"), SEARCH_SUMMARY_CONTAINS, ESB_ITEMTYPE_RADIO }, - { N_("Description contains"), SEARCH_DESCRIPTION_CONTAINS, ESB_ITEMTYPE_RADIO }, - { N_("Category is"), SEARCH_CATEGORY_IS, ESB_ITEMTYPE_RADIO }, - { N_("Comment contains"), SEARCH_COMMENT_CONTAINS, ESB_ITEMTYPE_RADIO }, - { N_("Location contains"), SEARCH_LOCATION_CONTAINS, ESB_ITEMTYPE_RADIO }, - { N_("Any field contains"), SEARCH_ANY_FIELD_CONTAINS, ESB_ITEMTYPE_RADIO }, + { N_("Summary contains"), SEARCH_SUMMARY_CONTAINS }, + { N_("Description contains"), SEARCH_DESCRIPTION_CONTAINS }, + { N_("Category is"), SEARCH_CATEGORY_IS }, + { N_("Comment contains"), SEARCH_COMMENT_CONTAINS }, + { N_("Location contains"), SEARCH_LOCATION_CONTAINS }, + { N_("Any field contains"), SEARCH_ANY_FIELD_CONTAINS }, }; /* IDs for the categories suboptions */ diff --git a/calendar/gui/calendar-commands.c b/calendar/gui/calendar-commands.c index fd2bdbef88..e4b72d2299 100644 --- a/calendar/gui/calendar-commands.c +++ b/calendar/gui/calendar-commands.c @@ -66,53 +66,6 @@ typedef struct { guint taskpad_focused : 1; } FocusData; -static void -file_open_event_cb (BonoboUIComponent *uic, gpointer data, const char *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - e_calendar_view_open_event (E_CALENDAR_VIEW (gnome_calendar_get_current_view_widget (gcal))); -} - - -/* Prints the calendar at its current view and time range */ -void -calendar_command_print (GnomeCalendar *gcal, GtkPrintOperationAction action) -{ - if (gnome_calendar_get_view (gcal) == GNOME_CAL_LIST_VIEW) { - ECalListView *list_view; - ETable *table; - - list_view = E_CAL_LIST_VIEW (gnome_calendar_get_current_view_widget (gcal)); - table = e_table_scrolled_get_table (list_view->table_scrolled); - print_table (table, _("Print"), _("Calendar"), action); - } else { - time_t start; - - gnome_calendar_get_current_time_range (gcal, &start, NULL); - print_calendar (gcal, action, start); - } -} - -/* File/Print callback */ -static void -file_print_cb (BonoboUIComponent *uic, gpointer data, const char *path) -{ - GnomeCalendar *gcal = GNOME_CALENDAR (data); - - calendar_command_print (gcal, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG); -} - -static void -file_print_preview_cb (BonoboUIComponent *uic, gpointer data, const char *path) -{ - GnomeCalendar *gcal = GNOME_CALENDAR (data); - - calendar_command_print (gcal, GTK_PRINT_OPERATION_ACTION_PREVIEW); -} - /* Sets a clock cursor for the specified calendar window */ static void set_clock_cursor (GnomeCalendar *gcal) @@ -134,58 +87,6 @@ set_normal_cursor (GnomeCalendar *gcal) } static void -previous_clicked (BonoboUIComponent *uic, gpointer data, const char *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - set_clock_cursor (gcal); - gnome_calendar_previous (gcal); - set_normal_cursor (gcal); -} - -static void -next_clicked (BonoboUIComponent *uic, gpointer data, const char *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - set_clock_cursor (gcal); - gnome_calendar_next (gcal); - set_normal_cursor (gcal); -} - -void -calendar_goto_today (GnomeCalendar *gcal) -{ - set_clock_cursor (gcal); - gnome_calendar_goto_today (gcal); - set_normal_cursor (gcal); -} - -static void -today_clicked (BonoboUIComponent *uic, gpointer data, const char *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - calendar_goto_today (gcal); -} - -static void -goto_clicked (BonoboUIComponent *uic, gpointer data, const char *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - goto_dialog (gcal); -} - -static void show_day_view_clicked (BonoboUIComponent *uic, gpointer data, const char *path) { GnomeCalendar *gcal; @@ -238,65 +139,6 @@ show_list_view_clicked (BonoboUIComponent *uic, gpointer data, const char *path) static void -cut_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - set_clock_cursor (gcal); - gnome_calendar_cut_clipboard (gcal); - set_normal_cursor (gcal); -} - -static void -copy_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - set_clock_cursor (gcal); - gnome_calendar_copy_clipboard (gcal); - set_normal_cursor (gcal); -} - -static void -paste_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - set_clock_cursor (gcal); - gnome_calendar_paste_clipboard (gcal); - set_normal_cursor (gcal); -} - -static void -delete_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - set_clock_cursor (gcal); - gnome_calendar_delete_selection (gcal); - set_normal_cursor (gcal); -} - -static void -delete_occurrence_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - set_clock_cursor (gcal); - gnome_calendar_delete_selected_occurrence (gcal); - set_normal_cursor (gcal); -} - -static void purge_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path) { GnomeCalendar *gcal; @@ -368,69 +210,6 @@ sensitize_items(BonoboUIComponent *uic, struct _sensitize_item *items, guint32 m } } -static struct _sensitize_item calendar_sensitize_table[] = { - { "EventOpen", E_CAL_MENU_SELECT_ONE }, - { "Cut", E_CAL_MENU_SELECT_EDITABLE }, - { "Copy", E_CAL_MENU_SELECT_ANY }, - { "Paste", E_CAL_MENU_SELECT_EDITABLE }, - { "Delete", E_CAL_MENU_SELECT_EDITABLE|E_CAL_MENU_SELECT_NONRECURRING }, - { "DeleteOccurrence", E_CAL_MENU_SELECT_EDITABLE|E_CAL_MENU_SELECT_RECURRING }, - { "DeleteAllOccurrences", E_CAL_MENU_SELECT_EDITABLE|E_CAL_MENU_SELECT_RECURRING }, - { NULL } -}; - -/* Sensitizes the UI Component menu/toolbar calendar commands based on the - * number of selected events. (This will always be 0 or 1 currently.) If enable - * is FALSE, all will be disabled. Otherwise, the currently-selected number of - * events will be used. - */ -void -calendar_control_sensitize_calendar_commands (BonoboControl *control, GnomeCalendar *gcal, gboolean enable) -{ - BonoboUIComponent *uic; - GtkWidget *view; - ECalMenu *menu; - ECalModel *model; - GPtrArray *events; - GList *selected, *l; - ECalMenuTargetSelect *t; - - uic = bonobo_control_get_ui_component (control); - g_return_if_fail (uic != NULL); - - if (bonobo_ui_component_get_container (uic) == CORBA_OBJECT_NIL) - return; - - view = gnome_calendar_get_current_view_widget (gcal); - - menu = gnome_calendar_get_calendar_menu (gcal); - model = e_calendar_view_get_model((ECalendarView *)view); - events = g_ptr_array_new(); - selected = e_calendar_view_get_selected_events((ECalendarView *)view); - for (l=selected;l;l=g_list_next(l)) { - ECalendarViewEvent *event = l->data; - if (event && event->comp_data) - g_ptr_array_add (events, e_cal_model_copy_component_data(event->comp_data)); - } - g_list_free(selected); - - t = e_cal_menu_target_new_select(menu, model, events); - if (!enable) - t->target.mask = ~0; - - sensitize_items(uic, calendar_sensitize_table, t->target.mask); -#if 0 - /* retrieve read-onlyness of the default client */ - e_cal = e_cal_model_get_default_client (gnome_calendar_get_calendar_model (gcal)); - if (e_cal) - e_cal_is_read_only (e_cal, &default_read_only, NULL); - else - default_read_only = TRUE; -#endif - - e_menu_update_target((EMenu *)menu, (EMenuTarget *)t); -} - static struct _sensitize_item taskpad_sensitize_table[] = { { "Cut", E_CAL_MENU_SELECT_EDITABLE }, { "Copy", E_CAL_MENU_SELECT_ANY }, @@ -558,21 +337,6 @@ help_debug (BonoboUIComponent *uid, void *data, const char *path) } static BonoboUIVerb verbs [] = { - BONOBO_UI_VERB ("EventOpen", file_open_event_cb), - BONOBO_UI_VERB ("CalendarPrint", file_print_cb), - BONOBO_UI_VERB ("CalendarPrintPreview", file_print_preview_cb), - - BONOBO_UI_VERB ("Cut", cut_cmd), - BONOBO_UI_VERB ("Copy", copy_cmd), - BONOBO_UI_VERB ("Paste", paste_cmd), - BONOBO_UI_VERB ("Delete", delete_cmd), - BONOBO_UI_VERB ("DeleteOccurrence", delete_occurrence_cmd), - BONOBO_UI_VERB ("DeleteAllOccurrences", delete_cmd), - - BONOBO_UI_VERB ("CalendarPrev", previous_clicked), - BONOBO_UI_VERB ("CalendarToday", today_clicked), - BONOBO_UI_VERB ("CalendarNext", next_clicked), - BONOBO_UI_VERB ("CalendarGoto", goto_clicked), BONOBO_UI_VERB ("ShowDayView", show_day_view_clicked), BONOBO_UI_VERB ("ShowWorkWeekView", show_work_week_view_clicked), @@ -585,35 +349,6 @@ static BonoboUIVerb verbs [] = { BONOBO_UI_VERB_END }; -static EPixmap pixmaps [] = { - E_PIXMAP ("/commands/CalendarPrev", "go-previous", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/CalendarPrint", "document-print", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/DeleteAllOccurrences", "edit-delete", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/DeleteOccurrence", "edit-delete", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/CalendarGoto", "go-jump", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/CalendarNext", "go-next", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/CalendarPrintPreview", "document-print-preview", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/Copy", "edit-copy", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/Cut", "edit-cut", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/Delete", "edit-delete", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/Paste", "edit-paste", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/CalendarToday", "go-today", E_ICON_SIZE_MENU), - - E_PIXMAP ("/Toolbar/Print", "document-print", E_ICON_SIZE_LARGE_TOOLBAR), - E_PIXMAP ("/Toolbar/Delete", "edit-delete", E_ICON_SIZE_LARGE_TOOLBAR), - E_PIXMAP ("/Toolbar/Prev", "go-previous", E_ICON_SIZE_LARGE_TOOLBAR), - E_PIXMAP ("/Toolbar/Next", "go-next", E_ICON_SIZE_LARGE_TOOLBAR), - E_PIXMAP ("/Toolbar/Goto", "go-jump", E_ICON_SIZE_LARGE_TOOLBAR), - E_PIXMAP ("/Toolbar/DayView", "view-calendar-day", E_ICON_SIZE_LARGE_TOOLBAR), - E_PIXMAP ("/Toolbar/WorkWeekView", "view-calendar-workweek", E_ICON_SIZE_LARGE_TOOLBAR), - E_PIXMAP ("/Toolbar/WeekView", "view-calendar-week", E_ICON_SIZE_LARGE_TOOLBAR), - E_PIXMAP ("/Toolbar/MonthView", "view-calendar-month", E_ICON_SIZE_LARGE_TOOLBAR), - E_PIXMAP ("/Toolbar/ListView", "view-calendar-list", E_ICON_SIZE_LARGE_TOOLBAR), - E_PIXMAP ("/Toolbar/Today", "go-today", E_ICON_SIZE_LARGE_TOOLBAR), - - E_PIXMAP_END -}; - void calendar_control_activate (BonoboControl *control, GnomeCalendar *gcal) @@ -645,8 +380,6 @@ calendar_control_activate (BonoboControl *control, NULL); g_free (xmlfile); - e_pixmaps_update (uic, pixmaps); - gnome_calendar_setup_view_menus (gcal, uic); g_signal_connect (gcal, "calendar_focus_change", diff --git a/calendar/gui/calendar-component.c b/calendar/gui/calendar-component.c index 4d30929272..2aaaaf2e6e 100644 --- a/calendar/gui/calendar-component.c +++ b/calendar/gui/calendar-component.c @@ -65,26 +65,9 @@ #define CREATE_MEETING_ID "meeting" #define CREATE_ALLDAY_EVENT_ID "allday-event" #define CREATE_CALENDAR_ID "calendar" -#define WEB_BASE_URI "webcal://" -#define CONTACTS_BASE_URI "contacts://" -#define WEATHER_BASE_URI "weather://" -#define PERSONAL_RELATIVE_URI "system" #define CALENDAR_ERROR_LEVEL_KEY "/apps/evolution/calendar/display/error_level" #define CALENDAR_ERROR_TIME_OUT_KEY "/apps/evolution/calendar/display/error_timeout" -enum DndTargetType { - DND_TARGET_TYPE_CALENDAR_LIST, -}; -#define CALENDAR_TYPE "text/calendar" -#define XCALENDAR_TYPE "text/x-calendar" -static GtkTargetEntry drag_types[] = { - { CALENDAR_TYPE, 0, DND_TARGET_TYPE_CALENDAR_LIST }, - { XCALENDAR_TYPE, 0, DND_TARGET_TYPE_CALENDAR_LIST } -}; -static gint num_drag_types = sizeof(drag_types) / sizeof(drag_types[0]); -#define CALENDAR_COMPONENT_DEFAULT(cc) if (cc == NULL) cc = calendar_component_peek() -#define PARENT_TYPE bonobo_object_get_type () - static BonoboObjectClass *parent_class = NULL; typedef struct @@ -99,27 +82,17 @@ typedef struct GnomeCalendar *calendar; - EInfoLabel *info_label; GtkWidget *source_selector; BonoboControl *view_control; - BonoboControl *sidebar_control; - BonoboControl *statusbar_control; GList *notifications; - EUserCreatableItemsHandler *creatable_items_handler; - - EActivityHandler *activity_handler; - float vpane_pos; } CalendarComponentView; struct _CalendarComponentPrivate { - char *base_directory; - char *config_directory; - GConfClient *gconf_client; int gconf_notify_id; ESourceList *source_list; @@ -136,9 +109,6 @@ struct _CalendarComponentPrivate { GList *notifications; }; -/* FIXME This should be gnome cal likely */ -extern ECompEditorRegistry *comp_editor_registry; - static void calcomp_vpane_realized (GtkWidget *vpane, CalendarComponentView *view) { @@ -156,158 +126,6 @@ calcomp_vpane_resized (GtkWidget *vpane, GdkEventButton *e, CalendarComponentVie return FALSE; } -static void -ensure_sources (CalendarComponent *component) -{ - ESourceList *source_list; - ESourceGroup *on_this_computer; - ESourceGroup *contacts; - ESource *personal_source; - ESource *birthdays_source; - char *base_uri, *base_uri_proto, base_uri_proto_seventh; - const gchar *base_dir; - gchar *create_source; - - personal_source = NULL; - birthdays_source = NULL; - - if (!e_cal_get_sources (&source_list, E_CAL_SOURCE_TYPE_EVENT, NULL)) { - g_warning ("Could not get calendar source list from GConf!"); - return; - } - - base_dir = calendar_component_peek_base_directory (component); - base_uri = g_build_filename (base_dir, "local", NULL); - - base_uri_proto = g_filename_to_uri (base_uri, NULL, NULL); - if (strlen (base_uri_proto) > 7) { - /* compare only file:// part. If user home dir name changes we do not want to create - one more group */ - base_uri_proto_seventh = base_uri_proto[7]; - base_uri_proto[7] = 0; - } else { - base_uri_proto_seventh = -1; - } - - on_this_computer = e_source_list_ensure_group (source_list, _("On This Computer"), base_uri_proto, TRUE); - contacts = e_source_list_ensure_group (source_list, _("Contacts"), CONTACTS_BASE_URI, TRUE); - e_source_list_ensure_group (source_list, _("On The Web"), WEB_BASE_URI, FALSE); - e_source_list_ensure_group (source_list, _("Weather"), WEATHER_BASE_URI, FALSE); - - if (base_uri_proto_seventh != -1) { - base_uri_proto[7] = base_uri_proto_seventh; - } - - if (on_this_computer) { - /* make sure "Personal" shows up as a source under - this group */ - GSList *sources = e_source_group_peek_sources (on_this_computer); - GSList *s; - for (s = sources; s; s = s->next) { - ESource *source = E_SOURCE (s->data); - const gchar *relative_uri; - - relative_uri = e_source_peek_relative_uri (source); - if (relative_uri == NULL) - continue; - if (!strcmp (PERSONAL_RELATIVE_URI, relative_uri)) { - personal_source = source; - break; - } - } - /* Make sure we have the correct base uri. This can change when user's - homedir name changes */ - if (strcmp (base_uri_proto, e_source_group_peek_base_uri (on_this_computer))) { - e_source_group_set_base_uri (on_this_computer, base_uri_proto); - - /* *sigh* . We shouldn't need this sync call here as set_base_uri - call results in synching to gconf, but that happens in idle loop - and too late to prevent user seeing "Can not Open ... because of invalid uri" error.*/ - e_source_list_sync (source_list,NULL); - } - } - - if (personal_source) { - /* ensure the source name is in current locale, not read from configuration */ - e_source_set_name (personal_source, _("Personal")); - } else { - char *primary_calendar = calendar_config_get_primary_calendar(); - GSList *calendars_selected; - - /* Create the default Person addressbook */ - personal_source = e_source_new (_("Personal"), PERSONAL_RELATIVE_URI); - e_source_group_add_source (on_this_computer, personal_source, -1); - g_object_unref (personal_source); - - calendars_selected = calendar_config_get_calendars_selected (); - if (!primary_calendar && !calendars_selected) { - GSList selected; - - calendar_config_set_primary_calendar (e_source_peek_uid (personal_source)); - - selected.data = (gpointer)e_source_peek_uid (personal_source); - selected.next = NULL; - calendar_config_set_calendars_selected (&selected); - } - - if (calendars_selected) { - g_slist_foreach (calendars_selected, (GFunc) g_free, NULL); - g_slist_free (calendars_selected); - } - - g_free (primary_calendar); - e_source_set_color_spec (personal_source, "#BECEDD"); - } - - if (contacts) { - GSList *sources = e_source_group_peek_sources (contacts); - if (sources) { - birthdays_source = E_SOURCE (sources->data); /* There is only one source under Contacts Group*/ - - if (sources->next) { - /* Ensure we have only one contacts source - we was able to create more than one before */ - GSList *l = NULL, *p; - - for (p = sources->next; p; p = p->next) - l = g_slist_prepend (l, p->data); - - for (p = l; p; p = p->next) - e_source_group_remove_source (contacts, p->data); - - g_slist_free (l); - } - } - } - - create_source = e_source_group_get_property (contacts, "create_source"); - if (!create_source) - e_source_group_set_property (contacts, "create_source", "no"); - g_free (create_source); - - if (birthdays_source) { - /* ensure the source name is in current locale, not read from configuration */ - e_source_set_name (birthdays_source, _("Birthdays & Anniversaries")); - } else { - birthdays_source = e_source_new (_("Birthdays & Anniversaries"), "/"); - e_source_group_add_source (contacts, birthdays_source, -1); - g_object_unref (birthdays_source); - } - - if (!e_source_get_property (birthdays_source, "delete")) - e_source_set_property(birthdays_source, "delete", "no"); - - if (e_source_peek_color_spec (birthdays_source) == NULL) - e_source_set_color_spec (birthdays_source, "#DDBECE"); - - component->priv->source_list = source_list; - - g_object_unref (on_this_computer); - g_object_unref (contacts); - g_free (base_uri_proto); - g_free (base_uri); -} - - /* Utility functions. */ static gboolean @@ -341,88 +159,6 @@ is_in_uids (GSList *uids, ESource *source) } static void -update_uris_for_selection (CalendarComponentView *component_view) -{ - GSList *selection, *l, *uids_selected = NULL; - - selection = e_source_selector_get_selection (E_SOURCE_SELECTOR (component_view->source_selector)); - - for (l = component_view->source_selection; l; l = l->next) { - ESource *old_selected_source = l->data; - - if (!is_in_selection (selection, old_selected_source)) - gnome_calendar_remove_source (component_view->calendar, E_CAL_SOURCE_TYPE_EVENT, old_selected_source); - } - - for (l = selection; l; l = l->next) { - ESource *selected_source = l->data; - - if (gnome_calendar_add_source (component_view->calendar, E_CAL_SOURCE_TYPE_EVENT, selected_source)) - uids_selected = g_slist_append (uids_selected, (char *) e_source_peek_uid (selected_source)); - } - - e_source_selector_free_selection (component_view->source_selection); - component_view->source_selection = selection; - - /* Save the selection for next time we start up */ - calendar_config_set_calendars_selected (uids_selected); - g_slist_free (uids_selected); -} - -static void -update_uri_for_primary_selection (CalendarComponentView *component_view) -{ - ESource *source; - - source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector)); - if (!source) - return; - - /* Set the default */ - gnome_calendar_set_default_source (component_view->calendar, E_CAL_SOURCE_TYPE_EVENT, source); - - /* Make sure we are embedded first */ - calendar_control_sensitize_calendar_commands (component_view->view_control, component_view->calendar, TRUE); - - /* Save the selection for next time we start up */ - calendar_config_set_primary_calendar (e_source_peek_uid (source)); -} - -static void -update_selection (CalendarComponentView *component_view) -{ - GSList *selection, *uids_selected, *l; - - /* Get the selection in gconf */ - uids_selected = calendar_config_get_calendars_selected (); - - /* Remove any that aren't there any more */ - selection = e_source_selector_get_selection (E_SOURCE_SELECTOR (component_view->source_selector)); - - for (l = selection; l; l = l->next) { - ESource *source = l->data; - - if (!is_in_uids (uids_selected, source)) - e_source_selector_unselect_source (E_SOURCE_SELECTOR (component_view->source_selector), source); - } - - e_source_selector_free_selection (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->source_list, uid); - if (source) - e_source_selector_select_source (E_SOURCE_SELECTOR (component_view->source_selector), source); - - g_free (uid); - } - g_slist_free (uids_selected); -} - -static void update_task_memo_selection (CalendarComponentView *component_view, ECalSourceType type) { GSList *uids_selected, *l, *source_selection; @@ -471,28 +207,6 @@ update_task_memo_selection (CalendarComponentView *component_view, ECalSourceTyp } static void -update_primary_selection (CalendarComponentView *component_view) -{ - ESource *source = NULL; - char *uid; - - uid = calendar_config_get_primary_calendar (); - if (uid) { - source = e_source_list_peek_source_by_uid (component_view->source_list, uid); - g_free (uid); - } - - if (source) { - e_source_selector_set_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector), source); - } else { - /* Try to create a default if there isn't one */ - source = e_source_list_peek_source_any (component_view->source_list); - if (source) - e_source_selector_set_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector), source); - } -} - -static void update_primary_task_memo_selection (CalendarComponentView *component_view, ECalSourceType type) { ESource *source = NULL; @@ -517,314 +231,6 @@ update_primary_task_memo_selection (CalendarComponentView *component_view, ECalS gnome_calendar_set_default_source (component_view->calendar, type, source); } -/* Callbacks. */ -static void -copy_calendar_cb (EPopup *ep, EPopupItem *pitem, void *data) -{ - CalendarComponentView *component_view = data; - ESource *selected_source; - - selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector)); - if (!selected_source) - return; - - copy_source_dialog (GTK_WINDOW (gtk_widget_get_toplevel (ep->target->widget)), selected_source, E_CAL_SOURCE_TYPE_EVENT); -} - -static void -delete_calendar_cb (EPopup *ep, EPopupItem *pitem, void *data) -{ - CalendarComponentView *component_view = data; - ESource *selected_source; - ECal *cal; - char *uri; - - selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector)); - if (!selected_source) - return; - - if (e_error_run((GtkWindow *)gtk_widget_get_toplevel(ep->target->widget), - "calendar:prompt-delete-calendar", e_source_peek_name(selected_source), NULL) != GTK_RESPONSE_YES) - return; - - /* first, ask the backend to remove the calendar */ - uri = e_source_get_uri (selected_source); - cal = e_cal_model_get_client_for_uri (gnome_calendar_get_calendar_model (component_view->calendar), uri); - if (!cal) - cal = e_cal_new_from_uri (uri, E_CAL_SOURCE_TYPE_EVENT); - g_free (uri); - if (cal) { - if (e_cal_remove (cal, NULL)) { - if (e_source_selector_source_is_selected (E_SOURCE_SELECTOR (component_view->source_selector), - selected_source)) { - gnome_calendar_remove_source (component_view->calendar, E_CAL_SOURCE_TYPE_EVENT, selected_source); - e_source_selector_unselect_source (E_SOURCE_SELECTOR (component_view->source_selector), - selected_source); - } - - e_source_group_remove_source (e_source_peek_group (selected_source), selected_source); - e_source_list_sync (component_view->source_list, NULL); - } - } -} - -static void -new_calendar_cb (EPopup *ep, EPopupItem *pitem, void *data) -{ - calendar_setup_edit_calendar (GTK_WINDOW (gtk_widget_get_toplevel(ep->target->widget)), NULL, pitem->user_data); -} - -static void -rename_calendar_cb (EPopup *ep, EPopupItem *pitem, void *data) -{ - CalendarComponentView *component_view = data; - ESourceSelector *selector; - - selector = E_SOURCE_SELECTOR (component_view->source_selector); - e_source_selector_edit_primary_selection (selector); -} - -static void -edit_calendar_cb (EPopup *ep, EPopupItem *pitem, void *data) -{ - CalendarComponentView *component_view = data; - ESource *selected_source; - - selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector)); - if (!selected_source) - return; - - calendar_setup_edit_calendar (GTK_WINDOW (gtk_widget_get_toplevel(ep->target->widget)), selected_source, NULL); -} - -static void -set_offline_availability (EPopup *ep, EPopupItem *pitem, void *data, const char *value) -{ - CalendarComponentView *component_view = data; - ESource *selected_source; - - selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector)); - if (!selected_source) - return; - - e_source_set_property (selected_source, "offline_sync", value); -} - -static void -mark_no_offline_cb (EPopup *ep, EPopupItem *pitem, void *data) -{ - set_offline_availability (ep, pitem, data, "0"); -} - -static void -mark_offline_cb (EPopup *ep, EPopupItem *pitem, void *data) -{ - set_offline_availability (ep, pitem, data, "1"); -} - -static EPopupItem ecc_source_popups[] = { - { E_POPUP_ITEM, "10.new", N_("_New Calendar"), new_calendar_cb, NULL, "x-office-calendar", 0, 0 }, - { E_POPUP_ITEM, "15.copy", N_("_Copy..."), copy_calendar_cb, NULL, "edit-copy", 0, E_CAL_POPUP_SOURCE_PRIMARY }, - { E_POPUP_ITEM, "18.rename", N_("_Rename..."), rename_calendar_cb, NULL, NULL, 0, E_CAL_POPUP_SOURCE_PRIMARY }, - - { E_POPUP_BAR, "20.bar" }, - { E_POPUP_ITEM, "20.delete", N_("_Delete"), delete_calendar_cb, NULL, "edit-delete", 0,E_CAL_POPUP_SOURCE_USER|E_CAL_POPUP_SOURCE_PRIMARY|E_CAL_POPUP_SOURCE_DELETE }, - { E_POPUP_ITEM, "30.mark_calendar_offline", N_("_Make available for offline use"), mark_offline_cb, NULL, "stock_disconnect", E_CAL_POPUP_SOURCE_OFFLINE, E_CAL_POPUP_SOURCE_USER|E_CAL_POPUP_SOURCE_PRIMARY|E_CAL_POPUP_SOURCE_OFFLINE }, - { E_POPUP_ITEM, "40.mark_calendar_no_offline", N_("_Do not make available for offline use"), mark_no_offline_cb, NULL, "stock_connect", E_CAL_POPUP_SOURCE_NO_OFFLINE, E_CAL_POPUP_SOURCE_USER|E_CAL_POPUP_SOURCE_PRIMARY|E_CAL_POPUP_SOURCE_NO_OFFLINE }, - - { E_POPUP_BAR, "99.bar" }, - { E_POPUP_ITEM, "99.properties", N_("_Properties"), edit_calendar_cb, NULL, "document-properties", 0, E_CAL_POPUP_SOURCE_PRIMARY }, -}; - -static void -ecc_source_popup_free(EPopup *ep, GSList *list, void *data) -{ - g_slist_free(list); -} - -static gboolean -popup_event_cb(ESourceSelector *selector, ESource *insource, GdkEventButton *event, CalendarComponentView *component_view) -{ - ECalPopup *ep; - ECalPopupTargetSource *t; - GSList *menus = NULL; - int i; - GtkMenu *menu; - - /** @HookPoint-ECalPopup: Calendar Source Selector Context Menu - * @Id: org.gnome.evolution.calendar.source.popup - * @Class: org.gnome.evolution.calendar.popup:1.0 - * @Target: ECalPopupTargetSource - * - * The context menu on the source selector in the calendar window. - */ - ep = e_cal_popup_new("org.gnome.evolution.calendar.source.popup"); - t = e_cal_popup_target_new_source(ep, selector); - t->target.widget = (GtkWidget *)component_view->calendar; - - for (i=0;i<sizeof(ecc_source_popups)/sizeof(ecc_source_popups[0]);i++) - menus = g_slist_prepend(menus, &ecc_source_popups[i]); - - e_popup_add_items((EPopup *)ep, menus, NULL, ecc_source_popup_free, component_view); - - menu = e_popup_create_menu_once((EPopup *)ep, (EPopupTarget *)t, 0); - gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event?event->button:0, event?event->time:gtk_get_current_event_time()); - - return TRUE; -} - -static void -source_selection_changed_cb (ESourceSelector *selector, CalendarComponentView *component_view) -{ - update_uris_for_selection (component_view); -} - -static void -primary_source_selection_changed_cb (ESourceSelector *selector, CalendarComponentView *component_view) -{ - update_uri_for_primary_selection (component_view); -} - -static void -source_changed_cb (ESource *source, GnomeCalendar *calendar) -{ - if (calendar) { - GtkWidget *widget = gnome_calendar_get_current_view_widget (calendar); - - if (widget) - gtk_widget_queue_draw (widget); - } -} - -static void -source_added_cb (GnomeCalendar *calendar, ECalSourceType source_type, ESource *source, CalendarComponentView *component_view) -{ - switch (source_type) { - case E_CAL_SOURCE_TYPE_EVENT: - e_source_selector_select_source (E_SOURCE_SELECTOR (component_view->source_selector), source); - g_signal_connect (source, "changed", G_CALLBACK (source_changed_cb), calendar); - break; - default: - break; - } -} - -static void -source_removed_cb (GnomeCalendar *calendar, ECalSourceType source_type, ESource *source, CalendarComponentView *component_view) -{ - switch (source_type) { - case E_CAL_SOURCE_TYPE_EVENT: - g_signal_handlers_disconnect_by_func (source, G_CALLBACK (source_changed_cb), calendar); - e_source_selector_unselect_source (E_SOURCE_SELECTOR (component_view->source_selector), source); - break; - default: - break; - } -} - -static void -set_info (CalendarComponentView *component_view) -{ - icaltimezone *zone; - struct icaltimetype start_tt, end_tt; - time_t start_time, end_time; - struct tm start_tm, end_tm; - char buffer[512], end_buffer[256]; - GnomeCalendarViewType view; - - gnome_calendar_get_visible_time_range (component_view->calendar, &start_time, &end_time); - zone = gnome_calendar_get_timezone (component_view->calendar); - - start_tt = icaltime_from_timet_with_zone (start_time, FALSE, zone); - start_tm.tm_year = start_tt.year - 1900; - start_tm.tm_mon = start_tt.month - 1; - start_tm.tm_mday = start_tt.day; - start_tm.tm_hour = start_tt.hour; - start_tm.tm_min = start_tt.minute; - start_tm.tm_sec = start_tt.second; - start_tm.tm_isdst = -1; - start_tm.tm_wday = time_day_of_week (start_tt.day, start_tt.month - 1, - start_tt.year); - - /* Take one off end_time so we don't get an extra day. */ - end_tt = icaltime_from_timet_with_zone (end_time - 1, FALSE, zone); - end_tm.tm_year = end_tt.year - 1900; - end_tm.tm_mon = end_tt.month - 1; - end_tm.tm_mday = end_tt.day; - end_tm.tm_hour = end_tt.hour; - end_tm.tm_min = end_tt.minute; - end_tm.tm_sec = end_tt.second; - end_tm.tm_isdst = -1; - end_tm.tm_wday = time_day_of_week (end_tt.day, end_tt.month - 1, - end_tt.year); - - view = gnome_calendar_get_view (component_view->calendar); - - switch (view) { - case GNOME_CAL_DAY_VIEW: - case GNOME_CAL_WORK_WEEK_VIEW: - case GNOME_CAL_WEEK_VIEW: - if (start_tm.tm_year == end_tm.tm_year - && start_tm.tm_mon == end_tm.tm_mon - && start_tm.tm_mday == end_tm.tm_mday) { - e_utf8_strftime (buffer, sizeof (buffer), - _("%A %d %b %Y"), &start_tm); - } else if (start_tm.tm_year == end_tm.tm_year) { - e_utf8_strftime (buffer, sizeof (buffer), - _("%a %d %b"), &start_tm); - e_utf8_strftime (end_buffer, sizeof (end_buffer), - _("%a %d %b %Y"), &end_tm); - strcat (buffer, " - "); - strcat (buffer, end_buffer); - } else { - e_utf8_strftime (buffer, sizeof (buffer), - _("%a %d %b %Y"), &start_tm); - e_utf8_strftime (end_buffer, sizeof (end_buffer), - _("%a %d %b %Y"), &end_tm); - strcat (buffer, " - "); - strcat (buffer, end_buffer); - } - break; - case GNOME_CAL_MONTH_VIEW: - case GNOME_CAL_LIST_VIEW: - if (start_tm.tm_year == end_tm.tm_year) { - if (start_tm.tm_mon == end_tm.tm_mon) { - e_utf8_strftime (buffer, sizeof (buffer), - "%d", &start_tm); - e_utf8_strftime (end_buffer, sizeof (end_buffer), - _("%d %b %Y"), &end_tm); - strcat (buffer, " - "); - strcat (buffer, end_buffer); - } else { - e_utf8_strftime (buffer, sizeof (buffer), - _("%d %b"), &start_tm); - e_utf8_strftime (end_buffer, sizeof (end_buffer), - _("%d %b %Y"), &end_tm); - strcat (buffer, " - "); - strcat (buffer, end_buffer); - } - } else { - e_utf8_strftime (buffer, sizeof (buffer), - _("%d %b %Y"), &start_tm); - e_utf8_strftime (end_buffer, sizeof (end_buffer), - _("%d %b %Y"), &end_tm); - strcat (buffer, " - "); - strcat (buffer, end_buffer); - } - break; - default: - g_return_if_reached (); - } - - e_info_label_set_info (component_view->info_label, _("Calendars"), buffer); -} - -static void -calendar_dates_changed_cb (GnomeCalendar *calendar, CalendarComponentView *component_view) -{ - set_info (component_view); -} - static void config_primary_selection_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) { @@ -947,85 +353,6 @@ impl_handleURI (PortableServer_Servant servant, const char *uri, CORBA_Environme } static void -impl_upgradeFromVersion (PortableServer_Servant servant, - CORBA_short major, - CORBA_short minor, - CORBA_short revision, - CORBA_Environment *ev) -{ - GError *err = NULL; - CalendarComponent *calendar_component = CALENDAR_COMPONENT (bonobo_object_from_servant (servant)); - - if (!migrate_calendars (calendar_component, major, minor, revision, &err)) { - GNOME_Evolution_Component_UpgradeFailed *failedex; - - failedex = GNOME_Evolution_Component_UpgradeFailed__alloc(); - failedex->what = CORBA_string_dup(_("Failed upgrading calendars.")); - failedex->why = CORBA_string_dup(err->message); - CORBA_exception_set(ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Component_UpgradeFailed, failedex); - } - - if (err) - g_error_free(err); -} - -static gboolean -selector_tree_data_dropped (ESourceSelector *selector, - GtkSelectionData *data, - ESource *destination, - GdkDragAction action, - guint info, - CalendarComponent *component) -{ - gboolean success = FALSE; - ECal *client; - - client = auth_new_cal_from_source (destination, E_CAL_SOURCE_TYPE_EVENT); - - if (!client || !e_cal_open (client, TRUE, NULL)) { - if (client) - g_object_unref (client); - - return FALSE; - } - - if (data->data) { - icalcomponent *icalcomp = NULL; - char *comp_str; /* do not free this! */ - - /* data->data is "source_uid\ncomponent_string" */ - comp_str = strchr ((char *)data->data, '\n'); - if (comp_str) { - comp_str [0] = 0; - comp_str++; - - icalcomp = icalparser_parse_string (comp_str); - - if (icalcomp) { - success = cal_comp_process_source_list_drop (client, icalcomp, action, (char *)data->data, component->priv->source_list); - icalcomponent_free (icalcomp); - } - } - } - - return success; -} - -static void -control_activate_cb (BonoboControl *control, gboolean activate, gpointer data) -{ - CalendarComponentView *component_view = data; - - if (activate) { - BonoboUIComponent *uic; - uic = bonobo_control_get_ui_component (component_view->view_control); - - e_user_creatable_items_handler_activate (component_view->creatable_items_handler, uic); - } -} - - -static void config_create_ecal_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) { CalendarComponent *calendar_component = data; @@ -1123,79 +450,13 @@ setup_create_ecal (CalendarComponent *calendar_component, CalendarComponentView return priv->create_ecal; } -static gboolean -create_new_event (CalendarComponent *calendar_component, CalendarComponentView *component_view, gboolean is_allday, gboolean is_meeting) -{ - ECal *ecal; - ECalendarView *view; - - ecal = setup_create_ecal (calendar_component, component_view); - if (!ecal) - return FALSE; - - if (component_view && (view = E_CALENDAR_VIEW (gnome_calendar_get_current_view_widget (component_view->calendar)))) { - e_calendar_view_new_appointment_full (view, is_allday, is_meeting, TRUE); - } else { - ECalComponent *comp; - CompEditor *editor; - CompEditorFlags flags; - - flags = COMP_EDITOR_USER_ORG | COMP_EDITOR_NEW_ITEM; - if (is_meeting) - flags |= COMP_EDITOR_MEETING; - comp = cal_comp_event_new_with_current_time (ecal, is_allday); - editor = event_editor_new (ecal, flags); - e_cal_component_commit_sequence (comp); - - comp_editor_edit_comp (editor, comp); - if (is_meeting) - event_editor_show_meeting (EVENT_EDITOR (editor)); - gtk_window_present (GTK_WINDOW (editor)); - - e_comp_editor_registry_add (comp_editor_registry, editor, TRUE); - } - - return TRUE; -} - -static void -create_local_item_cb (EUserCreatableItemsHandler *handler, const char *item_type_name, void *data) -{ - CalendarComponent *calendar_component = data; - CalendarComponentPrivate *priv; - CalendarComponentView *component_view = NULL; - GList *l; - - priv = calendar_component->priv; - - for (l = priv->views; l; l = l->next) { - component_view = l->data; - - if (component_view->creatable_items_handler == handler) - break; - - component_view = NULL; - } - - if (strcmp (item_type_name, CREATE_EVENT_ID) == 0) - create_new_event (calendar_component, component_view, FALSE, FALSE); - else if (strcmp (item_type_name, CREATE_ALLDAY_EVENT_ID) == 0) - create_new_event (calendar_component, component_view, TRUE, FALSE); - else if (strcmp (item_type_name, CREATE_MEETING_ID) == 0) - create_new_event (calendar_component, component_view, FALSE, TRUE); - else if (strcmp (item_type_name, CREATE_CALENDAR_ID) == 0) - calendar_setup_new_calendar (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (component_view->calendar)))); -} - static CalendarComponentView * create_component_view (CalendarComponent *calendar_component) { CalendarComponentPrivate *priv; CalendarComponentView *component_view; - GtkWidget *selector_scrolled_window, *vbox, *vpane; - GtkWidget *statusbar_widget; + GtkWidget **vpane; guint not; - AtkObject *a11y; priv = calendar_component->priv; @@ -1212,14 +473,8 @@ create_component_view (CalendarComponent *calendar_component) 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 */ component_view->source_selector = e_source_selector_new (calendar_component->priv->source_list); - e_source_selector_set_select_new ((ESourceSelector *)component_view->source_selector, TRUE); - a11y = gtk_widget_get_accessible (GTK_WIDGET (component_view->source_selector)); - atk_object_set_name (a11y, _("Calendar Source Selector")); - g_signal_connect ( component_view->source_selector, "data-dropped", G_CALLBACK (selector_tree_data_dropped), calendar_component); @@ -1289,18 +544,11 @@ create_component_view (CalendarComponent *calendar_component) g_signal_connect (component_view->source_selector, "popup_event", G_CALLBACK (popup_event_cb), component_view); +>>>>>>> 23df769955ea54f756a579c19964df87ae6fd5c8:calendar/gui/calendar-component.c /* Set up the "new" item handler */ - component_view->creatable_items_handler = e_user_creatable_items_handler_new ("calendar", create_local_item_cb, calendar_component); g_signal_connect (component_view->view_control, "activate", G_CALLBACK (control_activate_cb), component_view); - /* We use this to update the component information */ - set_info (component_view); - g_signal_connect (component_view->calendar, "dates_shown_changed", - G_CALLBACK (calendar_dates_changed_cb), component_view); - /* Load the selection from the last run */ - update_selection (component_view); - update_primary_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); @@ -1348,12 +596,6 @@ destroy_component_view (CalendarComponentView *component_view) calendar_config_remove_notification (GPOINTER_TO_UINT (l->data)); g_list_free (component_view->notifications); - if (component_view->creatable_items_handler) - g_object_unref (component_view->creatable_items_handler); - - if (component_view->activity_handler) - g_object_unref (component_view->activity_handler); - if (component_view->task_source_selection) { g_slist_foreach (component_view->task_source_selection, (GFunc) g_free, NULL); g_slist_free (component_view->task_source_selection); @@ -1388,109 +630,6 @@ view_destroyed_cb (gpointer data, GObject *where_the_object_was) } } -static GNOME_Evolution_ComponentView -impl_createView (PortableServer_Servant servant, - GNOME_Evolution_ShellView parent, - CORBA_boolean select_item, - CORBA_Environment *ev) -{ - CalendarComponent *calendar_component = CALENDAR_COMPONENT (bonobo_object_from_servant (servant)); - CalendarComponentPrivate *priv; - CalendarComponentView *component_view; - EComponentView *ecv; - - priv = calendar_component->priv; - - /* Create the calendar component view */ - component_view = create_component_view (calendar_component); - if (!component_view) { - /* FIXME Should we describe the problem in a control? */ - bonobo_exception_set (ev, ex_GNOME_Evolution_Component_Failed); - - return CORBA_OBJECT_NIL; - } - - g_object_weak_ref (G_OBJECT (component_view->view_control), view_destroyed_cb, calendar_component); - priv->views = g_list_append (priv->views, component_view); - - /* TODO: Make CalendarComponentView just subclass EComponentView */ - ecv = e_component_view_new_controls (parent, "calendar", component_view->sidebar_control, - component_view->view_control, component_view->statusbar_control); - - return BONOBO_OBJREF(ecv); -} - - -static GNOME_Evolution_CreatableItemTypeList * -impl__get_userCreatableItems (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - GNOME_Evolution_CreatableItemTypeList *list = GNOME_Evolution_CreatableItemTypeList__alloc (); - - list->_length = 4; - list->_maximum = list->_length; - list->_buffer = GNOME_Evolution_CreatableItemTypeList_allocbuf (list->_length); - - CORBA_sequence_set_release (list, FALSE); - - list->_buffer[0].id = CREATE_EVENT_ID; - list->_buffer[0].description = _("New appointment"); - list->_buffer[0].menuDescription = (char *) C_("New", "_Appointment"); - list->_buffer[0].tooltip = _("Create a new appointment"); - list->_buffer[0].menuShortcut = 'a'; - list->_buffer[0].iconName = "appointment-new"; - list->_buffer[0].type = GNOME_Evolution_CREATABLE_OBJECT; - - list->_buffer[1].id = CREATE_MEETING_ID; - list->_buffer[1].description = _("New meeting"); - list->_buffer[1].menuDescription = (char *) C_("New", "M_eeting"); - list->_buffer[1].tooltip = _("Create a new meeting request"); - list->_buffer[1].menuShortcut = 'e'; - list->_buffer[1].iconName = "stock_new-meeting"; - list->_buffer[1].type = GNOME_Evolution_CREATABLE_OBJECT; - - list->_buffer[2].id = CREATE_ALLDAY_EVENT_ID; - list->_buffer[2].description = _("New all day appointment"); - list->_buffer[2].menuDescription = (char *) C_("New", "All Day A_ppointment"); - list->_buffer[2].tooltip = _("Create a new all-day appointment"); - list->_buffer[2].menuShortcut = '\0'; - list->_buffer[2].iconName = "stock_new-24h-appointment"; - list->_buffer[2].type = GNOME_Evolution_CREATABLE_OBJECT; - - list->_buffer[3].id = CREATE_CALENDAR_ID; - list->_buffer[3].description = _("New calendar"); - list->_buffer[3].menuDescription = (char *) C_("New", "Cale_ndar"); - list->_buffer[3].tooltip = _("Create a new calendar"); - list->_buffer[3].menuShortcut = '\0'; - list->_buffer[3].iconName = "x-office-calendar"; - list->_buffer[3].type = GNOME_Evolution_CREATABLE_FOLDER; - - return list; -} - -static void -impl_requestCreateItem (PortableServer_Servant servant, - const CORBA_char *item_type_name, - CORBA_Environment *ev) -{ - CalendarComponent *calendar_component = CALENDAR_COMPONENT (bonobo_object_from_servant (servant)); - gboolean result = FALSE; - - if (strcmp (item_type_name, CREATE_EVENT_ID) == 0) - result = create_new_event (calendar_component, NULL, FALSE, FALSE); - else if (strcmp (item_type_name, CREATE_ALLDAY_EVENT_ID) == 0) - result = create_new_event (calendar_component, NULL, TRUE, FALSE); - else if (strcmp (item_type_name, CREATE_MEETING_ID) == 0) - result = create_new_event (calendar_component, NULL, FALSE, TRUE); - else if (strcmp (item_type_name, CREATE_CALENDAR_ID) == 0) - /* FIXME Should we use the last opened window? */ - calendar_setup_new_calendar (NULL); - else - bonobo_exception_set (ev, ex_GNOME_Evolution_Component_UnknownType); - - if (!result) - bonobo_exception_set (ev, ex_GNOME_Evolution_Component_Failed); -} /* GObject methods. */ @@ -1506,9 +645,9 @@ impl_dispose (GObject *object) priv->source_list = NULL; } - if (priv->gconf_client != NULL) { - g_object_unref (priv->gconf_client); - priv->gconf_client = NULL; + if (priv->activity_handler != NULL) { + g_object_unref (priv->activity_handler); + priv->activity_handler = NULL; } if (priv->activity_handler != NULL) { @@ -1538,27 +677,6 @@ impl_dispose (GObject *object) } static void -impl_finalize (GObject *object) -{ - CalendarComponentPrivate *priv = CALENDAR_COMPONENT (object)->priv; - GList *l; - - for (l = priv->views; l; l = l->next) { - CalendarComponentView *component_view = l->data; - - destroy_component_view (component_view); - } - g_list_free (priv->views); - - g_free (priv->base_directory); - g_free (priv->config_directory); - g_object_unref (priv->logger); - g_free (priv); - - (* G_OBJECT_CLASS (parent_class)->finalize) (object); -} - -static void calendar_component_class_init (CalendarComponentClass *class) { POA_GNOME_Evolution_Component__epv *epv = &class->epv; @@ -1569,17 +687,9 @@ calendar_component_class_init (CalendarComponentClass *class) parent_class = g_type_class_peek_parent (class); - epv->upgradeFromVersion = impl_upgradeFromVersion; - epv->createView = impl_createView; - epv->_get_userCreatableItems = impl__get_userCreatableItems; - epv->requestCreateItem = impl_requestCreateItem; epv->handleURI = impl_handleURI; object_class->dispose = impl_dispose; - object_class->finalize = impl_finalize; - - /* Register attachment handler types. */ - e_attachment_handler_calendar_get_type (); } static void @@ -1588,15 +698,6 @@ calendar_component_init (CalendarComponent *component) CalendarComponentPrivate *priv; guint not; - priv = g_new0 (CalendarComponentPrivate, 1); - - priv->base_directory = g_build_filename (e_get_user_data_dir (), "calendar", NULL); - priv->config_directory = g_build_filename (priv->base_directory, "config", NULL); - - /* EPFIXME: Should use a custom one instead? Also we should add - * calendar_component_peek_gconf_client(). */ - priv->gconf_client = gconf_client_get_default (); - not = calendar_config_add_notification_primary_calendar (config_primary_selection_changed_cb, component); priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); @@ -1607,70 +708,9 @@ calendar_component_init (CalendarComponent *component) e_activity_handler_set_error_flush_time (priv->activity_handler,eni_config_get_error_timeout (CALENDAR_ERROR_TIME_OUT_KEY)*1000); component->priv = priv; - ensure_sources (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)) ; } - - -/* Public API. */ - -CalendarComponent * -calendar_component_peek (void) -{ - static CalendarComponent *component = NULL; - - if (component == NULL) { - component = g_object_new (calendar_component_get_type (), NULL); - - if (g_mkdir_with_parents (calendar_component_peek_config_directory (component), 0777) != 0) { - g_warning (G_STRLOC ": Cannot create directory %s: %s", - calendar_component_peek_config_directory (component), - g_strerror (errno)); - g_object_unref (component); - component = NULL; - } - } - - return component; -} - -const char * -calendar_component_peek_base_directory (CalendarComponent *component) -{ - return component->priv->base_directory; -} - -const char * -calendar_component_peek_config_directory (CalendarComponent *component) -{ - return component->priv->config_directory; -} - -ESourceList * -calendar_component_peek_source_list (CalendarComponent *component) -{ - return component->priv->source_list; -} - -EActivityHandler * -calendar_component_peek_activity_handler (CalendarComponent *component) -{ - CALENDAR_COMPONENT_DEFAULT(component); - - return component->priv->activity_handler; -} - -void -calendar_component_show_logger (gpointer top) -{ - CalendarComponent *cc = calendar_component_peek (); - ELogger *logger = cc->priv->logger; - - eni_show_logger(logger, top, CALENDAR_ERROR_TIME_OUT_KEY, CALENDAR_ERROR_LEVEL_KEY); -} - -BONOBO_TYPE_FUNC_FULL (CalendarComponent, GNOME_Evolution_Component, PARENT_TYPE, calendar_component) diff --git a/calendar/gui/calendar-component.h b/calendar/gui/calendar-component.h index ec3183726d..5fbba8758e 100644 --- a/calendar/gui/calendar-component.h +++ b/calendar/gui/calendar-component.h @@ -56,12 +56,4 @@ struct _CalendarComponentClass { GType calendar_component_get_type (void); -CalendarComponent *calendar_component_peek (void); - -const char *calendar_component_peek_base_directory (CalendarComponent *component); -const char *calendar_component_peek_config_directory (CalendarComponent *component); -ESourceList *calendar_component_peek_source_list (CalendarComponent *component); -EActivityHandler *calendar_component_peek_activity_handler (CalendarComponent *component); -void calendar_component_show_logger (gpointer); - #endif /* _CALENDAR_COMPONENT_H_ */ diff --git a/calendar/gui/calendar-config-keys.h b/calendar/gui/calendar-config-keys.h index 6277f46d31..4e7ec7c254 100644 --- a/calendar/gui/calendar-config-keys.h +++ b/calendar/gui/calendar-config-keys.h @@ -28,18 +28,10 @@ G_BEGIN_DECLS #define CALENDAR_CONFIG_PREFIX "/apps/evolution/calendar" /* Display settings */ -#define CALENDAR_CONFIG_USE_SYSTEM_TIMEZONE CALENDAR_CONFIG_PREFIX "/display/use_system_timezone" #define CALENDAR_CONFIG_TIMEZONE CALENDAR_CONFIG_PREFIX "/display/timezone" #define CALENDAR_CONFIG_SELECTED_CALENDARS CALENDAR_CONFIG_PREFIX "/display/selected_calendars" -#define CALENDAR_CONFIG_PRIMARY_CALENDAR CALENDAR_CONFIG_PREFIX "/display/primary_calendar" #define CALENDAR_CONFIG_24HOUR CALENDAR_CONFIG_PREFIX "/display/use_24hour_format" #define CALENDAR_CONFIG_SHOW_ATTENDEE CALENDAR_CONFIG_PREFIX "/display/show_attendee" -#define CALENDAR_CONFIG_SHOW_ROLE CALENDAR_CONFIG_PREFIX "/display/show_role" -#define CALENDAR_CONFIG_SHOW_STATUS CALENDAR_CONFIG_PREFIX "/display/show_status" -#define CALENDAR_CONFIG_SHOW_TYPE CALENDAR_CONFIG_PREFIX "/display/show_type" -#define CALENDAR_CONFIG_SHOW_RSVP CALENDAR_CONFIG_PREFIX "/display/show_rsvp" -#define CALENDAR_CONFIG_SHOW_TIMEZONE CALENDAR_CONFIG_PREFIX "/display/show_timezone" -#define CALENDAR_CONFIG_SHOW_CATEGORIES CALENDAR_CONFIG_PREFIX "/display/show_categories" #define CALENDAR_CONFIG_WEEK_START CALENDAR_CONFIG_PREFIX "/display/week_start_day" #define CALENDAR_CONFIG_DAY_START_HOUR CALENDAR_CONFIG_PREFIX "/display/day_start_hour" #define CALENDAR_CONFIG_DAY_START_MINUTE CALENDAR_CONFIG_PREFIX "/display/day_start_minute" diff --git a/calendar/gui/calendar-config.c b/calendar/gui/calendar-config.c index 8af8230efd..11c3c8f33d 100644 --- a/calendar/gui/calendar-config.c +++ b/calendar/gui/calendar-config.c @@ -29,12 +29,13 @@ #include <config.h> #endif -#include <string.h> #include <time.h> -#include <libedataserver/e-data-server-util.h> +#include <string.h> #include <e-util/e-util.h> -#include <widgets/e-timezone-dialog/e-timezone-dialog.h> #include <libecal/e-cal-time-util.h> +#include <libedataserver/e-data-server-util.h> +#include <widgets/e-timezone-dialog/e-timezone-dialog.h> +#include <shell/e-shell.h> #include "calendar-config-keys.h" #include "calendar-config.h" @@ -150,73 +151,23 @@ calendar_config_add_notification_calendars_selected (GConfClientNotifyFunc func, return id; } -/* The primary calendar */ -char * -calendar_config_get_primary_calendar (void) -{ - calendar_config_init (); - - return gconf_client_get_string (config, CALENDAR_CONFIG_PRIMARY_CALENDAR, NULL); -} - -void -calendar_config_set_primary_calendar (const char *primary_uid) -{ - calendar_config_init (); - - gconf_client_set_string (config, CALENDAR_CONFIG_PRIMARY_CALENDAR, primary_uid, NULL); -} - - -guint -calendar_config_add_notification_primary_calendar (GConfClientNotifyFunc func, gpointer data) -{ - guint id; - - calendar_config_init (); - - id = gconf_client_notify_add (config, CALENDAR_CONFIG_PRIMARY_CALENDAR, func, data, NULL, NULL); - - return id; -} - -gboolean -calendar_config_get_use_system_timezone (void) -{ - calendar_config_init (); - - return gconf_client_get_bool (config, CALENDAR_CONFIG_USE_SYSTEM_TIMEZONE, NULL); -} - -void -calendar_config_set_use_system_timezone (gboolean use) -{ - calendar_config_init (); - - if (calendar_config_get_use_system_timezone () != use) { - gconf_client_set_bool (config, CALENDAR_CONFIG_USE_SYSTEM_TIMEZONE, use, NULL); - gconf_client_notify (config, CALENDAR_CONFIG_TIMEZONE); - - /* FIXME: notify CALENDAR_CONFIG_TIMEZONE change on system timezone change - itself too, when using system timezone. How to receive such change? */ - } -} - -guint -calendar_config_add_notification_use_system_timezone (GConfClientNotifyFunc func, gpointer data) -{ - calendar_config_init (); - - return gconf_client_notify_add (config, CALENDAR_CONFIG_USE_SYSTEM_TIMEZONE, func, data, NULL, NULL); -} - /* The current timezone, e.g. "Europe/London". It may be NULL, in which case you should assume UTC (though Evolution will show the timezone-setting dialog the next time a calendar or task folder is selected). */ gchar * calendar_config_get_timezone (void) { - if (calendar_config_get_use_system_timezone ()) + EShell *shell; + EShellSettings *shell_settings; + gboolean use_system_timezone; + + shell = e_shell_get_default (); + shell_settings = e_shell_get_shell_settings (shell); + + use_system_timezone = e_shell_settings_get_boolean ( + shell_settings, "cal-use-system-timezone"); + + if (use_system_timezone) return e_cal_util_get_system_timezone_location (); return calendar_config_get_timezone_stored (); @@ -309,107 +260,6 @@ calendar_config_add_notification_24_hour_format (GConfClientNotifyFunc func, gpo return id; } -/* Show RSVP*/ -gboolean -calendar_config_get_show_rsvp (void) -{ - calendar_config_init (); - - return gconf_client_get_bool (config, CALENDAR_CONFIG_SHOW_RSVP, NULL); -} - -void -calendar_config_set_show_rsvp (gboolean state) -{ - calendar_config_init (); - - gconf_client_set_bool (config, CALENDAR_CONFIG_SHOW_RSVP, state, NULL); -} - -/* Show Role*/ -gboolean -calendar_config_get_show_role (void) -{ - calendar_config_init (); - - return gconf_client_get_bool (config, CALENDAR_CONFIG_SHOW_ROLE, NULL); -} - -void -calendar_config_set_show_role (gboolean state) -{ - calendar_config_init (); - - gconf_client_set_bool (config, CALENDAR_CONFIG_SHOW_ROLE, state, NULL); -} - -/* Show Type*/ -gboolean -calendar_config_get_show_type (void) -{ - calendar_config_init (); - - return gconf_client_get_bool (config, CALENDAR_CONFIG_SHOW_TYPE, NULL); -} - -void -calendar_config_set_show_type (gboolean state) -{ - calendar_config_init (); - - gconf_client_set_bool (config, CALENDAR_CONFIG_SHOW_TYPE, state, NULL); -} - -/* Show status */ -gboolean -calendar_config_get_show_status (void) -{ - calendar_config_init (); - - return gconf_client_get_bool (config, CALENDAR_CONFIG_SHOW_STATUS, NULL); -} - -void -calendar_config_set_show_status (gboolean state) -{ - calendar_config_init (); - - gconf_client_set_bool (config, CALENDAR_CONFIG_SHOW_STATUS, state, NULL); -} - -/* Show timezone */ -gboolean -calendar_config_get_show_timezone (void) -{ - calendar_config_init (); - - return gconf_client_get_bool (config, CALENDAR_CONFIG_SHOW_TIMEZONE, NULL); -} - -void -calendar_config_set_show_timezone (gboolean status) -{ - calendar_config_init (); - - gconf_client_set_bool (config, CALENDAR_CONFIG_SHOW_TIMEZONE, status, NULL); -} - -gboolean -calendar_config_get_show_categories (void) -{ - calendar_config_init (); - - return gconf_client_get_bool (config, CALENDAR_CONFIG_SHOW_CATEGORIES, NULL); -} -void -calendar_config_set_show_categories (gboolean status) -{ - calendar_config_init (); - - gconf_client_set_bool (config, CALENDAR_CONFIG_SHOW_CATEGORIES, status, NULL); -} - - /* The start day of the week (0 = Sun to 6 = Mon). */ gint calendar_config_get_week_start_day (void) diff --git a/calendar/gui/calendar-config.h b/calendar/gui/calendar-config.h index c28077c1ec..09a9a7d53b 100644 --- a/calendar/gui/calendar-config.h +++ b/calendar/gui/calendar-config.h @@ -68,16 +68,6 @@ GSList *calendar_config_get_calendars_selected (void); void calendar_config_set_calendars_selected (GSList *selected); guint calendar_config_add_notification_calendars_selected (GConfClientNotifyFunc func, gpointer data); -/* The primary calendar */ -char *calendar_config_get_primary_calendar (void); -void calendar_config_set_primary_calendar (const char *primary_uid); -guint calendar_config_add_notification_primary_calendar (GConfClientNotifyFunc func, gpointer data); - -/* Use system timezone; if TRUE, then influences also the current timezone functions. */ -gboolean calendar_config_get_use_system_timezone (void); -void calendar_config_set_use_system_timezone (gboolean use); -guint calendar_config_add_notification_use_system_timezone (GConfClientNotifyFunc func, gpointer data); - /* The current timezone, e.g. "Europe/London". */ gchar* calendar_config_get_timezone (void); gchar* calendar_config_get_timezone_stored (void); @@ -117,25 +107,6 @@ gboolean calendar_config_get_24_hour_format (void); void calendar_config_set_24_hour_format (gboolean use_24_hour); guint calendar_config_add_notification_24_hour_format (GConfClientNotifyFunc func, gpointer data); -gboolean calendar_config_get_show_status (void); -void calendar_config_set_show_status (gboolean status); - -gboolean calendar_config_get_show_type (void); -void calendar_config_set_show_type (gboolean status); - -gboolean calendar_config_get_show_rsvp (void); -void calendar_config_set_show_rsvp (gboolean status); - -gboolean calendar_config_get_show_timezone (void); -void calendar_config_set_show_timezone (gboolean status); - -gboolean calendar_config_get_show_categories (void); -void calendar_config_set_show_categories (gboolean status); - -gboolean calendar_config_get_show_role (void); -void calendar_config_set_show_role (gboolean state); - - /* The time divisions in the Day/Work-Week view in minutes (5/10/15/30/60). */ gint calendar_config_get_time_divisions (void); void calendar_config_set_time_divisions (gint divisions); diff --git a/calendar/gui/calendar-view-factory.c b/calendar/gui/calendar-view-factory.c index ce76578563..b3f88dd43f 100644 --- a/calendar/gui/calendar-view-factory.c +++ b/calendar/gui/calendar-view-factory.c @@ -181,7 +181,7 @@ calendar_view_factory_new_view (GalViewFactory *factory, const char *name) * * Return value: The same value as @cal_view_factory. **/ -CalendarViewFactory * +GalViewFactory * calendar_view_factory_construct (CalendarViewFactory *cal_view_factory, GnomeCalendarViewType view_type) { @@ -194,7 +194,7 @@ calendar_view_factory_construct (CalendarViewFactory *cal_view_factory, priv->view_type = view_type; - return cal_view_factory; + return GAL_VIEW_FACTORY (cal_view_factory); } /** @@ -205,7 +205,7 @@ calendar_view_factory_construct (CalendarViewFactory *cal_view_factory, * * Return value: A newly-created calendar view factory. **/ -CalendarViewFactory * +GalViewFactory * calendar_view_factory_new (GnomeCalendarViewType view_type) { CalendarViewFactory *cal_view_factory; diff --git a/calendar/gui/calendar-view-factory.h b/calendar/gui/calendar-view-factory.h index 779e59809c..2f5b6f86de 100644 --- a/calendar/gui/calendar-view-factory.h +++ b/calendar/gui/calendar-view-factory.h @@ -57,10 +57,10 @@ typedef struct { GType calendar_view_factory_get_type (void); -CalendarViewFactory *calendar_view_factory_construct (CalendarViewFactory *cal_view_factory, +GalViewFactory *calendar_view_factory_construct (CalendarViewFactory *cal_view_factory, GnomeCalendarViewType view_type); -CalendarViewFactory *calendar_view_factory_new (GnomeCalendarViewType view_type); +GalViewFactory *calendar_view_factory_new (GnomeCalendarViewType view_type); diff --git a/calendar/gui/comp-editor-factory.c b/calendar/gui/comp-editor-factory.c deleted file mode 100644 index 908293a151..0000000000 --- a/calendar/gui/comp-editor-factory.c +++ /dev/null @@ -1,644 +0,0 @@ -/* - * Evolution calendar - Component editor factory object - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Federico Mena-Quintero <federico@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtk.h> -#include <glib/gi18n.h> -#include <bonobo/bonobo-exception.h> -#include <evolution-calendar.h> -#include <libedataserver/e-url.h> -#include <libecal/e-cal.h> -#include "calendar-config.h" -#include "e-comp-editor-registry.h" -#include "comp-editor-factory.h" -#include "comp-util.h" -#include "common/authentication.h" -#include "dialogs/event-editor.h" -#include "dialogs/task-editor.h" - -extern ECompEditorRegistry *comp_editor_registry; - - - -/* A pending request */ - -typedef enum { - REQUEST_EXISTING, - REQUEST_NEW -} RequestType; - -typedef struct { - RequestType type; - - union { - struct { - char *uid; - } existing; - - struct { - GNOME_Evolution_Calendar_CompEditorFactory_CompEditorMode type; - } new; - } u; -} Request; - -/* A client we have open */ -typedef struct { - /* Our parent CompEditorFactory */ - CompEditorFactory *factory; - - /* Uri of the calendar, used as key in the clients hash table */ - char *uri; - - /* Client of the calendar */ - ECal *client; - - /* Count editors using this client */ - int editor_count; - - /* Pending requests; they are pending if the client is still being opened */ - GSList *pending; - - /* Whether this is open or still waiting */ - guint open : 1; -} OpenClient; - -/* Private part of the CompEditorFactory structure */ -struct CompEditorFactoryPrivate { - /* Hash table of URI->OpenClient */ - GHashTable *uri_client_hash; -}; - - - -static void comp_editor_factory_class_init (CompEditorFactoryClass *class); -static void comp_editor_factory_init (CompEditorFactory *factory); -static void comp_editor_factory_finalize (GObject *object); - -static void impl_editExisting (PortableServer_Servant servant, - const CORBA_char *str_uri, - const CORBA_char *uid, - const GNOME_Evolution_Calendar_CompEditorFactory_CompEditorMode corba_type, - CORBA_Environment *ev); -static void impl_editNew (PortableServer_Servant servant, - const CORBA_char *str_uri, - const GNOME_Evolution_Calendar_CalObjType type, - CORBA_Environment *ev); - -static BonoboObjectClass *parent_class = NULL; - - - -BONOBO_TYPE_FUNC_FULL (CompEditorFactory, - GNOME_Evolution_Calendar_CompEditorFactory, - BONOBO_OBJECT_TYPE, - comp_editor_factory) - -/* Class initialization function for the component editor factory */ -static void -comp_editor_factory_class_init (CompEditorFactoryClass *class) -{ - GObjectClass *object_class; - - object_class = (GObjectClass *) class; - - parent_class = g_type_class_peek_parent (class); - - class->epv.editExisting = impl_editExisting; - class->epv.editNew = impl_editNew; - - object_class->finalize = comp_editor_factory_finalize; -} - -/* Frees a Request structure */ -static void -free_request (Request *r) -{ - if (r->type == REQUEST_EXISTING) - g_free (r->u.existing.uid); - - g_free (r); -} - -/* Frees an OpenClient structure */ -static void -free_client (OpenClient *oc) -{ - GSList *l; - - g_free (oc->uri); - oc->uri = NULL; - - g_object_unref (oc->client); - oc->client = NULL; - - for (l = oc->pending; l; l = l->next) { - Request *r; - - r = l->data; - free_request (r); - } - g_slist_free (oc->pending); - oc->pending = NULL; - - g_free (oc); -} - -/* Object initialization function for the component editor factory */ -static void -comp_editor_factory_init (CompEditorFactory *factory) -{ - CompEditorFactoryPrivate *priv; - - priv = g_new (CompEditorFactoryPrivate, 1); - factory->priv = priv; - - priv->uri_client_hash = g_hash_table_new_full ( - g_str_hash, g_str_equal, - (GDestroyNotify) NULL, - (GDestroyNotify) free_client); -} - -/* Destroy handler for the component editor factory */ -static void -comp_editor_factory_finalize (GObject *object) -{ - CompEditorFactory *factory; - CompEditorFactoryPrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_COMP_EDITOR_FACTORY (object)); - - factory = COMP_EDITOR_FACTORY (object); - priv = factory->priv; - - g_hash_table_destroy (priv->uri_client_hash); - priv->uri_client_hash = NULL; - - g_free (priv); - factory->priv = NULL; - - if (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (object); -} - - - -/* Callback used when a component editor gets destroyed */ -static void -editor_destroy_cb (GtkObject *object, gpointer data) -{ - OpenClient *oc; - CompEditorFactory *factory; - CompEditorFactoryPrivate *priv; - - oc = data; - factory = oc->factory; - priv = factory->priv; - - oc->editor_count--; - - /* See if we need to free the client */ - g_return_if_fail (oc->pending == NULL); - - if (oc->editor_count != 0) - return; - - g_hash_table_remove (priv->uri_client_hash, oc->uri); -} - -/* Starts editing an existing component on a client that is already open */ -static void -edit_existing (OpenClient *oc, const char *uid) -{ - ECalComponent *comp; - icalcomponent *icalcomp; - CompEditor *editor; - ECalComponentVType vtype; - CompEditorFlags flags = { 0, }; - - g_return_if_fail (oc->open); - - /* Get the object */ - if (!e_cal_get_object (oc->client, uid, NULL, &icalcomp, NULL)) { - /* FIXME Better error handling */ - g_warning (G_STRLOC ": Syntax error while getting component `%s'", uid); - - return; - } - - comp = e_cal_component_new (); - if (!e_cal_component_set_icalcomponent (comp, icalcomp)) { - g_object_unref (comp); - icalcomponent_free (icalcomp); - return; - } - - /* Create the appropriate type of editor */ - - vtype = e_cal_component_get_vtype (comp); - if (itip_organizer_is_user (comp, oc->client)) - flags |= COMP_EDITOR_USER_ORG; - - - switch (vtype) { - case E_CAL_COMPONENT_EVENT: - if (e_cal_component_has_attendees (comp)) - flags |= COMP_EDITOR_MEETING; - - editor = event_editor_new (oc->client, flags); - break; - - case E_CAL_COMPONENT_TODO: - editor = COMP_EDITOR (task_editor_new (oc->client, flags)); - break; - - default: - g_message ("edit_exiting(): Unsupported object type %d", (int) vtype); - g_object_unref (comp); - return; - } - - /* Set the object on the editor */ - comp_editor_edit_comp (editor, comp); - gtk_window_present (GTK_WINDOW (editor)); - g_object_unref (comp); - - oc->editor_count++; - g_signal_connect (editor, "destroy", G_CALLBACK (editor_destroy_cb), oc); - - e_comp_editor_registry_add (comp_editor_registry, editor, TRUE); -} - -static ECalComponent * -get_default_task (ECal *client) -{ - ECalComponent *comp; - - comp = cal_comp_task_new_with_defaults (client); - - return comp; -} - -/* Edits a new object in the context of a client */ -static void -edit_new (OpenClient *oc, const GNOME_Evolution_Calendar_CompEditorFactory_CompEditorMode type) -{ - ECalComponent *comp; - CompEditor *editor; - - switch (type) { - case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_EVENT: - editor = event_editor_new (oc->client, FALSE); - comp = cal_comp_event_new_with_current_time (oc->client, FALSE); - break; - case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_MEETING: - editor = event_editor_new (oc->client, TRUE); - comp = cal_comp_event_new_with_current_time (oc->client, FALSE); - break; - case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_ALLDAY_EVENT: - editor = event_editor_new (oc->client, FALSE); - comp = cal_comp_event_new_with_current_time (oc->client, TRUE); - break; - case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_TODO: - editor = COMP_EDITOR (task_editor_new (oc->client, FALSE)); - comp = get_default_task (oc->client); - break; - default: - g_return_if_reached (); - return; - } - - comp_editor_edit_comp (editor, comp); - if (type == GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_MEETING) - event_editor_show_meeting (EVENT_EDITOR (editor)); - gtk_window_present (GTK_WINDOW (editor)); - - oc->editor_count++; - g_signal_connect (editor, "destroy", G_CALLBACK (editor_destroy_cb), oc); - - e_comp_editor_registry_add (comp_editor_registry, editor, TRUE); -} - -/* Resolves all the pending requests for a client */ -static void -resolve_pending_requests (OpenClient *oc) -{ - GSList *l; - icaltimezone *zone; - - if (!oc->pending) - return; - - /* Set the default timezone in the backend. */ - zone = calendar_config_get_icaltimezone (); - - /* FIXME Error handling? */ - e_cal_set_default_timezone (oc->client, zone, NULL); - - for (l = oc->pending; l; l = l->next) { - Request *request; - - request = l->data; - - switch (request->type) { - case REQUEST_EXISTING: - edit_existing (oc, request->u.existing.uid); - break; - - case REQUEST_NEW: - edit_new (oc, request->u.new.type); - break; - } - - free_request (request); - } - - g_slist_free (oc->pending); - oc->pending = NULL; -} - -/* Callback used when a client is finished opening. We resolve all the pending - * requests. - */ -static void -cal_opened_cb (ECal *client, ECalendarStatus status, gpointer data) -{ - OpenClient *oc; - CompEditorFactory *factory; - CompEditorFactoryPrivate *priv; - GtkWidget *dialog = NULL; - - oc = data; - factory = oc->factory; - priv = factory->priv; - - switch (status) { - case E_CALENDAR_STATUS_OK: - oc->open = TRUE; - resolve_pending_requests (oc); - return; - - case E_CALENDAR_STATUS_OTHER_ERROR: - case E_CALENDAR_STATUS_NO_SUCH_CALENDAR: - dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, - GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, - "%s", _("Error while opening the calendar")); - break; - - case E_CALENDAR_STATUS_PROTOCOL_NOT_SUPPORTED: - dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, - GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, - "%s", _("Method not supported when opening the calendar")); - break; - - case E_CALENDAR_STATUS_PERMISSION_DENIED : - dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, - GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, - "%s", _("Permission denied to open the calendar")); - break; - - case E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED: - dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, - GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, - "%s", _("Authentication Required")); - break; - - case E_CALENDAR_STATUS_AUTHENTICATION_FAILED : - dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, - GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, - "%s", _("Authentication Failed")); - break; - - default: - dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, - GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, - "%s", _("Unknown error")); - return; - } - - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - - g_hash_table_remove (priv->uri_client_hash, oc->uri); -} - -/* Creates a new OpenClient structure and queues the component editing/creation - * process until the client is open. Returns NULL if it could not issue the - * open request. - */ -static OpenClient * -open_client (CompEditorFactory *factory, ECalSourceType source_type, const char *uristr) -{ - CompEditorFactoryPrivate *priv; - ECal *client; - OpenClient *oc; - GError *error = NULL; - - priv = factory->priv; - - client = auth_new_cal_from_uri (uristr, source_type); - if (!client) - return NULL; - - oc = g_new (OpenClient, 1); - oc->factory = factory; - - oc->uri = g_strdup (uristr); - - oc->client = client; - oc->editor_count = 0; - oc->pending = NULL; - oc->open = FALSE; - - g_signal_connect (oc->client, "cal_opened", G_CALLBACK (cal_opened_cb), oc); - - g_hash_table_insert (priv->uri_client_hash, oc->uri, oc); - - if (!e_cal_open (oc->client, FALSE, &error)) { - g_warning (G_STRLOC ": %s", error->message); - g_free (oc->uri); - g_object_unref (oc->client); - g_free (oc); - g_error_free (error); - - return NULL; - } - - return oc; -} - -/* Looks up an open client or queues it for being opened. Returns the client or - * NULL on failure; in the latter case it sets the ev exception. - */ -static OpenClient * -lookup_open_client (CompEditorFactory *factory, ECalSourceType source_type, const char *str_uri, CORBA_Environment *ev) -{ - CompEditorFactoryPrivate *priv; - OpenClient *oc; - EUri *uri; - - priv = factory->priv; - - /* Look up the client */ - - uri = e_uri_new (str_uri); - if (!uri) { - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_CompEditorFactory_InvalidURI); - return NULL; - } - e_uri_free (uri); - - oc = g_hash_table_lookup (priv->uri_client_hash, str_uri); - if (!oc) { - oc = open_client (factory, source_type, str_uri); - if (!oc) { - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_CompEditorFactory_BackendContactError); - return NULL; - } - } - - return oc; -} - -/* Queues a request for editing an existing object */ -static void -queue_edit_existing (OpenClient *oc, const char *uid) -{ - Request *request; - - g_return_if_fail (!oc->open); - - request = g_new (Request, 1); - request->type = REQUEST_EXISTING; - request->u.existing.uid = g_strdup (uid); - - oc->pending = g_slist_append (oc->pending, request); -} - -/* ::editExisting() method implementation */ -static void -impl_editExisting (PortableServer_Servant servant, - const CORBA_char *str_uri, - const CORBA_char *uid, - const GNOME_Evolution_Calendar_CompEditorFactory_CompEditorMode corba_type, - CORBA_Environment *ev) -{ - CompEditorFactory *factory; - OpenClient *oc; - CompEditor *editor; - ECalSourceType source_type; - - factory = COMP_EDITOR_FACTORY (bonobo_object_from_servant (servant)); - - switch (corba_type) { - case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_TODO: - source_type = E_CAL_SOURCE_TYPE_TODO; - break; - default: - source_type = E_CAL_SOURCE_TYPE_EVENT; - } - - oc = lookup_open_client (factory, source_type, str_uri, ev); - if (!oc) - return; - - if (!oc->open) { - queue_edit_existing (oc, uid); - return; - } - - /* Look up the component */ - editor = e_comp_editor_registry_find (comp_editor_registry, uid); - if (editor == NULL) { - edit_existing (oc, uid); - } else { - gtk_window_present (GTK_WINDOW (editor)); - } -} - -/* Queues a request for creating a new object */ -static void -queue_edit_new (OpenClient *oc, const GNOME_Evolution_Calendar_CompEditorFactory_CompEditorMode type) -{ - Request *request; - - g_return_if_fail (!oc->open); - - request = g_new (Request, 1); - request->type = REQUEST_NEW; - request->u.new.type = type; - - oc->pending = g_slist_append (oc->pending, request); -} - -/* ::editNew() method implementation */ -static void -impl_editNew (PortableServer_Servant servant, - const CORBA_char *str_uri, - const GNOME_Evolution_Calendar_CompEditorFactory_CompEditorMode corba_type, - CORBA_Environment *ev) -{ - CompEditorFactory *factory; - OpenClient *oc; - ECalSourceType source_type; - - factory = COMP_EDITOR_FACTORY (bonobo_object_from_servant (servant)); - - switch (corba_type) { - case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_TODO: - source_type = E_CAL_SOURCE_TYPE_TODO; - break; - default: - source_type = E_CAL_SOURCE_TYPE_EVENT; - } - - oc = lookup_open_client (factory, source_type, str_uri, ev); - if (!oc) - return; - - if (!oc->open) - queue_edit_new (oc, corba_type); - else - edit_new (oc, corba_type); -} - - - -/** - * comp_editor_factory_new: - * - * Creates a new calendar component editor factory. - * - * Return value: A newly-created component editor factory. - **/ -CompEditorFactory * -comp_editor_factory_new (void) -{ - return g_object_new (TYPE_COMP_EDITOR_FACTORY, NULL); -} - - diff --git a/calendar/gui/comp-editor-factory.h b/calendar/gui/comp-editor-factory.h deleted file mode 100644 index fdab8a0a46..0000000000 --- a/calendar/gui/comp-editor-factory.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Evolution calendar - Component editor factory object - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Federico Mena-Quintero <federico@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef COMP_EDITOR_FACTORY_H -#define COMP_EDITOR_FACTORY_H - -#include <bonobo/bonobo-object.h> -#include "evolution-calendar.h" - - - -#define TYPE_COMP_EDITOR_FACTORY (comp_editor_factory_get_type ()) -#define COMP_EDITOR_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_COMP_EDITOR_FACTORY, \ - CompEditorFactory)) -#define COMP_EDITOR_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \ - TYPE_COMP_EDITOR_FACTORY, CompEditorFactoryClass)) -#define IS_COMP_EDITOR_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_COMP_EDITOR_FACTORY)) -#define IS_COMP_EDITOR_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_COMP_EDITOR_FACTORY)) - -typedef struct CompEditorFactoryPrivate CompEditorFactoryPrivate; - -typedef struct { - BonoboObject object; - - /* Private data */ - CompEditorFactoryPrivate *priv; -} CompEditorFactory; - -typedef struct { - BonoboObjectClass parent_class; - - POA_GNOME_Evolution_Calendar_CompEditorFactory__epv epv; -} CompEditorFactoryClass; - -GType comp_editor_factory_get_type (void); - -CompEditorFactory *comp_editor_factory_new (void); - - - -#endif diff --git a/calendar/gui/control-factory.c b/calendar/gui/control-factory.c deleted file mode 100644 index 2fcb3e2688..0000000000 --- a/calendar/gui/control-factory.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Ettore Perazzoli <ettore@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#include <config.h> -#include <string.h> -#include <gtk/gtk.h> -#include <glade/glade.h> -#include <bonobo/bonobo-control.h> -#include <bonobo/bonobo-generic-factory.h> -#include <bonobo/bonobo-persist-file.h> -#include <bonobo/bonobo-context.h> -#include <glade/glade.h> - -#include <libecal/e-cal-time-util.h> -#include <gui/gnome-cal.h> -#include <gui/calendar-commands.h> -#include <gui/calendar-config.h> - -#include "control-factory.h" - -/* Are these supposed to be global or static? */ -CORBA_Environment ev; -CORBA_ORB orb; - -static void -control_activate_cb (BonoboControl *control, gboolean activate, gpointer data) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - if (activate) - calendar_control_activate (control, gcal); - else - calendar_control_deactivate (control, gcal); -} - -BonoboControl * -control_factory_new_control (void) -{ - BonoboControl *control; - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (gnome_calendar_new ()); - if (!gcal) - return NULL; - - gtk_widget_show (GTK_WIDGET (gcal)); - - control = bonobo_control_new (GTK_WIDGET (gcal)); - if (!control) { - g_message ("control_factory_fn(): could not create the control!"); - return NULL; - } - g_object_set_data (G_OBJECT (gcal), "control", control); - - g_signal_connect (control, "activate", G_CALLBACK (control_activate_cb), gcal); - - return control; -} diff --git a/calendar/gui/dialogs/cal-prefs-dialog.c b/calendar/gui/dialogs/cal-prefs-dialog.c index 0e1f0f05d1..cdef86eb5a 100644 --- a/calendar/gui/dialogs/cal-prefs-dialog.c +++ b/calendar/gui/dialogs/cal-prefs-dialog.c @@ -31,6 +31,7 @@ #include "../calendar-config.h" #include "cal-prefs-dialog.h" #include <widgets/misc/e-dateedit.h> +#include <e-util/e-binding.h> #include <e-util/e-dialog-widgets.h> #include <e-util/e-util-private.h> #include <glib/gi18n.h> @@ -486,7 +487,9 @@ template_url_changed (GtkEntry *entry, CalendarPrefsDialog *prefs) } static void -update_system_tz_widgets (CalendarPrefsDialog *prefs) +update_system_tz_widgets (EShellSettings *shell_settings, + GParamSpec *pspec, + CalendarPrefsDialog *prefs) { icaltimezone *zone; @@ -498,15 +501,6 @@ update_system_tz_widgets (CalendarPrefsDialog *prefs) } else { gtk_label_set_text (GTK_LABEL (prefs->system_tz_label), "(UTC)"); } - - gtk_widget_set_sensitive (prefs->timezone, !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (prefs->use_system_tz_check))); -} - -static void -use_system_tz_changed (GtkWidget *check, CalendarPrefsDialog *prefs) -{ - calendar_config_set_use_system_timezone (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check))); - update_system_tz_widgets (prefs); } static void @@ -517,7 +511,6 @@ setup_changes (CalendarPrefsDialog *prefs) for (i = 0; i < 7; i ++) g_signal_connect (G_OBJECT (prefs->working_days[i]), "toggled", G_CALLBACK (working_days_changed), prefs); - g_signal_connect (G_OBJECT (prefs->use_system_tz_check), "toggled", G_CALLBACK (use_system_tz_changed), prefs); g_signal_connect (G_OBJECT (prefs->timezone), "changed", G_CALLBACK (timezone_changed), prefs); g_signal_connect (G_OBJECT (prefs->day_second_zone), "clicked", G_CALLBACK (day_second_zone_clicked), prefs); @@ -652,11 +645,6 @@ show_config (CalendarPrefsDialog *prefs) CalUnits units; int interval; - /* Use system timezone */ - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (prefs->use_system_tz_check), calendar_config_get_use_system_timezone ()); - gtk_widget_set_sensitive (prefs->system_tz_label, FALSE); - update_system_tz_widgets (prefs); - /* Timezone. */ location = calendar_config_get_timezone_stored (); zone = icaltimezone_get_builtin_timezone (location); @@ -666,6 +654,9 @@ show_config (CalendarPrefsDialog *prefs) /* Day's second zone */ update_day_second_zone_caption (prefs); + /* Day's second zone */ + update_day_second_zone_caption (prefs); + /* Working Days. */ working_days = calendar_config_get_working_days (); mask = 1 << 0; @@ -759,13 +750,16 @@ eccp_free (EConfig *ec, GSList *items, void *data) } static void -calendar_prefs_dialog_construct (CalendarPrefsDialog *prefs) +calendar_prefs_dialog_construct (CalendarPrefsDialog *prefs, + EShell *shell) { GladeXML *gui; ECalConfig *ec; ECalConfigTargetPrefs *target; + EShellSettings *shell_settings; int i; GtkWidget *toplevel; + GtkWidget *widget; GSList *l; const char *working_day_names[] = { "sun_button", @@ -778,6 +772,8 @@ calendar_prefs_dialog_construct (CalendarPrefsDialog *prefs) }; char *gladefile; + shell_settings = e_shell_get_shell_settings (shell); + gladefile = g_build_filename (EVOLUTION_GLADEDIR, "cal-prefs-dialog.glade", NULL); @@ -801,8 +797,20 @@ calendar_prefs_dialog_construct (CalendarPrefsDialog *prefs) l = g_slist_prepend (l, &eccp_items[i]); e_config_add_items ((EConfig *) ec, l, NULL, NULL, eccp_free, prefs); + widget = glade_xml_get_widget (gui, "use-system-tz-check"); + e_mutual_binding_new ( + G_OBJECT (shell_settings), "cal-use-system-timezone", + G_OBJECT (widget), "active"); + g_signal_connect ( + G_OBJECT (shell_settings), "notify::cal-use-system-timezone", + G_CALLBACK (update_system_tz_widgets), prefs); + + widget = glade_xml_get_widget (gui, "timezone"); + e_mutual_binding_new_with_negation ( + G_OBJECT (shell_settings), "cal-use-system-timezone", + G_OBJECT (widget), "sensitive"); + /* General tab */ - prefs->use_system_tz_check = glade_xml_get_widget (gui, "use-system-tz-check"); prefs->system_tz_label = glade_xml_get_widget (gui, "system-tz-label"); prefs->timezone = glade_xml_get_widget (gui, "timezone"); prefs->day_second_zone = glade_xml_get_widget (gui, "day_second_zone"); @@ -873,14 +881,18 @@ calendar_prefs_dialog_get_type (void) } GtkWidget * -calendar_prefs_dialog_new (void) +calendar_prefs_dialog_new (EShell *shell) { CalendarPrefsDialog *dialog; - dialog = (CalendarPrefsDialog *) g_object_new (calendar_prefs_dialog_get_type (), NULL); - calendar_prefs_dialog_construct (dialog); + g_return_val_if_fail (E_IS_SHELL (shell), NULL); + + dialog = g_object_new (CALENDAR_TYPE_PREFS_DIALOG, NULL); + + /* FIXME Kill this function. */ + calendar_prefs_dialog_construct (dialog, shell); - return (GtkWidget *) dialog; + return GTK_WIDGET (dialog); } /* called by libglade to create our custom EDateEdit widgets. */ diff --git a/calendar/gui/dialogs/cal-prefs-dialog.h b/calendar/gui/dialogs/cal-prefs-dialog.h index 30b62440e5..ba1bf607ea 100644 --- a/calendar/gui/dialogs/cal-prefs-dialog.h +++ b/calendar/gui/dialogs/cal-prefs-dialog.h @@ -21,14 +21,33 @@ * */ -#ifndef _CAL_PREFS_DIALOG_H_ -#define _CAL_PREFS_DIALOG_H_ +#ifndef CAL_PREFS_DIALOG_H +#define CAL_PREFS_DIALOG_H #include <gtk/gtk.h> #include <glade/glade.h> #include <gconf/gconf-client.h> #include <libedataserverui/e-source-selector.h> -#include "evolution-config-control.h" +#include <shell/e-shell.h> + +/* Standard GObject macros */ +#define CALENDAR_TYPE_PREFS_DIALOG \ + (calendar_prefs_dialog_get_type ()) +#define CALENDAR_PREFS_DIALOG(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), CALENDAR_TYPE_PREFS_DIALOG, CalendarPrefsDialog)) +#define CALENDAR_PREFS_DIALOG_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), CALENDAR_TYPE_PREFS_DIALOG, CalendarPrefsDialogClass)) +#define CALENDAR_IS_PREFS_DIALOG(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), CALENDAR_TYPE_PREFS_DIALOG)) +#define CALENDAR_IS_PREFS_DIALOG_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), CALENDAR_TYPE_PREFS_DIALOG)) +#define CALENDAR_PREFS_DIALOG_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), CALENDAR_TYPE_PREFS_DIALOG, CalendarPrefsDialogClass)) G_BEGIN_DECLS @@ -43,7 +62,6 @@ struct _CalendarPrefsDialog { GConfClient *gconf; /* General tab */ - GtkWidget *use_system_tz_check; GtkWidget *system_tz_label; GtkWidget *timezone; GtkWidget *day_second_zone; @@ -95,9 +113,9 @@ struct _CalendarPrefsDialogClass { GtkVBoxClass parent; }; -GType calendar_prefs_dialog_get_type (void); -GtkWidget *calendar_prefs_dialog_new (void); +GType calendar_prefs_dialog_get_type (void); +GtkWidget * calendar_prefs_dialog_new (EShell *shell); G_END_DECLS -#endif /* _CAL_PREFS_DIALOG_H_ */ +#endif /* CAL_PREFS_DIALOG_H */ diff --git a/calendar/gui/dialogs/comp-editor.c b/calendar/gui/dialogs/comp-editor.c index 4af998eb26..440cf35388 100644 --- a/calendar/gui/dialogs/comp-editor.c +++ b/calendar/gui/dialogs/comp-editor.c @@ -39,7 +39,7 @@ #include <e-util/e-dialog-utils.h> #include <e-util/e-util-private.h> #include <e-util/gconf-bridge.h> -#include <evolution-shell-component-utils.h> +#include <shell/e-shell.h> #include <camel/camel-url.h> #include <camel/camel-exception.h> @@ -76,6 +76,9 @@ /* Private part of the CompEditor structure */ struct _CompEditorPrivate { + + gpointer shell; /* weak pointer */ + /* Client to use */ ECal *client; @@ -125,6 +128,7 @@ enum { PROP_CHANGED, PROP_CLIENT, PROP_FLAGS, + PROP_SHELL, PROP_SUMMARY }; @@ -133,7 +137,10 @@ static const gchar *ui = " <menubar action='main-menu'>" " <menu action='file-menu'>" " <menuitem action='save'/>" +" <separator/>" +" <menuitem action='print-preview'/>" " <menuitem action='print'/>" +" <separator/>" " <menuitem action='close'/>" " </menu>" " <menu action='edit-menu'>" @@ -170,8 +177,8 @@ static void close_dialog (CompEditor *editor); static void page_dates_changed_cb (CompEditor *editor, CompEditorPageDates *dates, CompEditorPage *page); -static void obj_modified_cb (ECal *client, GList *objs, gpointer data); -static void obj_removed_cb (ECal *client, GList *uids, gpointer data); +static void obj_modified_cb (ECal *client, GList *objs, CompEditor *editor); +static void obj_removed_cb (ECal *client, GList *uids, CompEditor *editor); G_DEFINE_TYPE (CompEditor, comp_editor, GTK_TYPE_WINDOW) @@ -180,7 +187,15 @@ enum { LAST_SIGNAL }; -static guint comp_editor_signals[LAST_SIGNAL] = { 0 }; +static guint signals[LAST_SIGNAL]; +static GList *active_editors; + +static void +comp_editor_weak_notify_cb (gpointer unused, + GObject *where_the_object_was) +{ + active_editors = g_list_remove (active_editors, where_the_object_was); +} static void attachment_store_changed_cb (CompEditor *editor) @@ -699,17 +714,22 @@ action_print_cb (GtkAction *action, CompEditor *editor) { CompEditorPrivate *priv = editor->priv; + GtkPrintOperationAction print_action; ECalComponent *comp; GList *l; - icalcomponent *icalcomp = e_cal_component_get_icalcomponent (priv->comp); + icalcomponent *component; + icalcomponent *clone; comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp)); + component = e_cal_component_get_icalcomponent (priv->comp); + clone = icalcomponent_new_clone (component); + e_cal_component_set_icalcomponent (comp, clone); for (l = priv->pages; l != NULL; l = l->next) comp_editor_page_fill_component (l->data, comp); - print_comp (comp, priv->client, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG); + print_action = GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG; + print_comp (comp, priv->client, print_action); g_object_unref (comp); } @@ -719,15 +739,22 @@ action_print_preview_cb (GtkAction *action, CompEditor *editor) { CompEditorPrivate *priv = editor->priv; + GtkPrintOperationAction print_action; ECalComponent *comp; GList *l; - icalcomponent *icalcomp = e_cal_component_get_icalcomponent (priv->comp); + icalcomponent *component; + icalcomponent *clone; comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp)); + component = e_cal_component_get_icalcomponent (priv->comp); + clone = icalcomponent_new_clone (component); + e_cal_component_set_icalcomponent (comp, clone); + for (l = priv->pages; l != NULL; l = l->next) comp_editor_page_fill_component (l->data, comp); - print_comp (comp, priv->client, TRUE); + + print_action = GTK_PRINT_OPERATION_ACTION_PREVIEW; + print_comp (comp, priv->client, print_action); g_object_unref (comp); } @@ -795,12 +822,10 @@ action_save_cb (GtkAction *action, if (e_cal_component_has_recurrences (priv->comp)) { if (!recur_component_dialog (priv->client, priv->comp, &priv->mod, GTK_WINDOW (editor), delegated)) return; - } else if (e_cal_component_is_instance (priv->comp)) priv->mod = CALOBJ_MOD_THIS; comp = comp_editor_get_current_comp (editor, &correct); - e_cal_component_get_summary (comp, &text); g_object_unref (comp); @@ -1182,6 +1207,17 @@ comp_editor_setup_recent_menu (CompEditor *editor) } static void +comp_editor_set_shell (CompEditor *editor, + EShell *shell) +{ + g_return_if_fail (editor->priv->shell == NULL); + + editor->priv->shell = shell; + + g_object_add_weak_pointer (G_OBJECT (shell), &editor->priv->shell); +} + +static void comp_editor_set_property (GObject *object, guint property_id, const GValue *value, @@ -1206,6 +1242,12 @@ comp_editor_set_property (GObject *object, g_value_get_int (value)); return; + case PROP_SHELL: + comp_editor_set_shell ( + COMP_EDITOR (object), + g_value_get_object (value)); + return; + case PROP_SUMMARY: comp_editor_set_summary ( COMP_EDITOR (object), @@ -1241,6 +1283,12 @@ comp_editor_get_property (GObject *object, COMP_EDITOR (object))); return; + case PROP_SHELL: + g_value_set_object ( + value, comp_editor_get_shell ( + COMP_EDITOR (object))); + return; + case PROP_SUMMARY: g_value_set_string ( value, comp_editor_get_summary ( @@ -1316,42 +1364,39 @@ static void comp_editor_map (GtkWidget *widget) { CompEditor *editor = COMP_EDITOR (widget); - GConfBridge *bridge = gconf_bridge_get (); + GConfBridge *bridge; GtkAction *action; + const gchar *key; + + bridge = gconf_bridge_get (); /* Give subclasses a chance to construct their pages before * we fiddle with their widgets. That's why we don't do this * until after object construction. */ + key = "/apps/evolution/calendar/display/show_categories"; action = comp_editor_get_action (editor, "view-categories"); - gconf_bridge_bind_property ( - bridge, CALENDAR_CONFIG_SHOW_CATEGORIES, - G_OBJECT (action), "active"); + gconf_bridge_bind_property (bridge, key, G_OBJECT (action), "active"); + key = "/apps/evolution/calendar/display/show_role"; action = comp_editor_get_action (editor, "view-role"); - gconf_bridge_bind_property ( - bridge, CALENDAR_CONFIG_SHOW_ROLE, - G_OBJECT (action), "active"); + gconf_bridge_bind_property (bridge, key, G_OBJECT (action), "active"); + key = "/apps/evolution/calendar/display/show_rsvp"; action = comp_editor_get_action (editor, "view-rsvp"); - gconf_bridge_bind_property ( - bridge, CALENDAR_CONFIG_SHOW_RSVP, - G_OBJECT (action), "active"); + gconf_bridge_bind_property (bridge, key, G_OBJECT (action), "active"); + key = "/apps/evolution/calendar/display/show_status"; action = comp_editor_get_action (editor, "view-status"); - gconf_bridge_bind_property ( - bridge, CALENDAR_CONFIG_SHOW_STATUS, - G_OBJECT (action), "active"); + gconf_bridge_bind_property (bridge, key, G_OBJECT (action), "active"); + key = "/apps/evolution/calendar/display/show_timezone"; action = comp_editor_get_action (editor, "view-time-zone"); - gconf_bridge_bind_property ( - bridge, CALENDAR_CONFIG_SHOW_TIMEZONE, - G_OBJECT (action), "active"); + gconf_bridge_bind_property (bridge, key, G_OBJECT (action), "active"); + key = "/apps/evolution/calendar/display/show_type"; action = comp_editor_get_action (editor, "view-type"); - gconf_bridge_bind_property ( - bridge, CALENDAR_CONFIG_SHOW_TYPE, - G_OBJECT (action), "active"); + gconf_bridge_bind_property (bridge, key, G_OBJECT (action), "active"); /* Chain up to parent's map() method. */ GTK_WIDGET_CLASS (comp_editor_parent_class)->map (widget); @@ -1498,6 +1543,17 @@ comp_editor_class_init (CompEditorClass *class) g_object_class_install_property ( object_class, + PROP_SHELL, + g_param_spec_object ( + "shell", + NULL, + NULL, + E_TYPE_SHELL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property ( + object_class, PROP_SUMMARY, g_param_spec_string ( "summary", @@ -1506,7 +1562,7 @@ comp_editor_class_init (CompEditorClass *class) NULL, G_PARAM_READWRITE)); - comp_editor_signals[OBJECT_CREATED] = + signals[OBJECT_CREATED] = g_signal_new ("object_created", G_TYPE_FROM_CLASS (class), G_SIGNAL_RUN_LAST, @@ -1529,11 +1585,18 @@ comp_editor_init (CompEditor *editor) GtkAction *action; GtkWidget *container; GtkWidget *widget; + EShell *shell; gint n_targets; GError *error = NULL; editor->priv = priv = COMP_EDITOR_GET_PRIVATE (editor); + g_object_weak_ref ( + G_OBJECT (editor), (GWeakNotify) + comp_editor_weak_notify_cb, NULL); + + active_editors = g_list_prepend (active_editors, editor); + priv->pages = NULL; priv->changed = FALSE; priv->needs_send = FALSE; @@ -1667,6 +1730,10 @@ comp_editor_init (CompEditor *editor) g_signal_connect_swapped ( store, "row-inserted", G_CALLBACK (attachment_store_changed_cb), editor); + + /* FIXME Shell should be passed in. */ + shell = e_shell_get_default (); + e_shell_watch_window (shell, GTK_WINDOW (editor)); } static gboolean @@ -1749,7 +1816,18 @@ close_dialog (CompEditor *editor) gtk_widget_destroy (GTK_WIDGET (editor)); } - +gint +comp_editor_compare (CompEditor *editor_a, + CompEditor *editor_b) +{ + const gchar *uid_a = NULL; + const gchar *uid_b = NULL; + + e_cal_component_get_uid (editor_a->priv->comp, &uid_a); + e_cal_component_get_uid (editor_b->priv->comp, &uid_b); + + return g_strcmp0 (uid_a, uid_b); +} void comp_editor_set_existing_org (CompEditor *editor, gboolean existing_org) @@ -1835,6 +1913,14 @@ comp_editor_get_classification (CompEditor *editor) return gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action)); } +EShell * +comp_editor_get_shell (CompEditor *editor) +{ + g_return_val_if_fail (IS_COMP_EDITOR (editor), NULL); + + return editor->priv->shell; +} + void comp_editor_set_summary (CompEditor *editor, const gchar *summary) @@ -1939,11 +2025,10 @@ comp_editor_set_flags (CompEditor *editor, g_object_notify (G_OBJECT (editor), "flags"); } - CompEditorFlags comp_editor_get_flags (CompEditor *editor) { - g_return_val_if_fail (IS_COMP_EDITOR (editor), FALSE); + g_return_val_if_fail (IS_COMP_EDITOR (editor), 0); return editor->priv->flags; } @@ -2001,6 +2086,20 @@ comp_editor_get_managed_widget (CompEditor *editor, return widget; } +CompEditor * +comp_editor_find_instance (const gchar *uid) +{ + GList *link; + + g_return_val_if_fail (uid != NULL, NULL); + + link = g_list_find_custom ( + active_editors, uid, + (GCompareFunc) comp_editor_compare); + + return (link != NULL) ? link->data : NULL; +} + /** * comp_editor_set_needs_send: * @editor: A component editor @@ -2276,8 +2375,14 @@ fill_widgets (CompEditor *editor) EAttachmentStore *store; EAttachmentView *view; CompEditorPrivate *priv; - GList *l; GtkAction *action; + GList *iter; + + view = E_ATTACHMENT_VIEW (editor->priv->attachment_view); + store = e_attachment_view_get_store (view); + + view = E_ATTACHMENT_VIEW (editor->priv->attachment_view); + store = e_attachment_view_get_store (view); view = E_ATTACHMENT_VIEW (editor->priv->attachment_view); store = e_attachment_view_get_store (view); @@ -2300,12 +2405,14 @@ fill_widgets (CompEditor *editor) } action = comp_editor_get_action (editor, "classify-public"); - g_signal_handlers_block_by_func (action, G_CALLBACK (action_classification_cb), editor); + g_signal_handlers_block_by_func ( + action, G_CALLBACK (action_classification_cb), editor); - for (l = priv->pages; l != NULL; l = l->next) - comp_editor_page_fill_widgets (l->data, priv->comp); + for (iter = priv->pages; iter != NULL; iter = iter->next) + comp_editor_page_fill_widgets (iter->data, priv->comp); - g_signal_handlers_unblock_by_func (action, G_CALLBACK (action_classification_cb), editor); + g_signal_handlers_unblock_by_func ( + action, G_CALLBACK (action_classification_cb), editor); } static void @@ -2711,9 +2818,10 @@ page_dates_changed_cb (CompEditor *editor, } static void -obj_modified_cb (ECal *client, GList *objects, gpointer data) +obj_modified_cb (ECal *client, + GList *objects, + CompEditor *editor) { - CompEditor *editor = COMP_EDITOR (data); CompEditorPrivate *priv; ECalComponent *comp = NULL; @@ -2746,12 +2854,11 @@ obj_modified_cb (ECal *client, GList *objects, gpointer data) } static void -obj_removed_cb (ECal *client, GList *uids, gpointer data) +obj_removed_cb (ECal *client, + GList *uids, + CompEditor *editor) { - CompEditor *editor = COMP_EDITOR (data); - CompEditorPrivate *priv; - - priv = editor->priv; + CompEditorPrivate *priv = editor->priv; if (changed_component_dialog ((GtkWindow *) editor, priv->comp, TRUE, priv->changed)) close_dialog (editor); diff --git a/calendar/gui/dialogs/comp-editor.h b/calendar/gui/dialogs/comp-editor.h index ab277febf7..a6231d55b5 100644 --- a/calendar/gui/dialogs/comp-editor.h +++ b/calendar/gui/dialogs/comp-editor.h @@ -29,6 +29,7 @@ #include <libecal/e-cal.h> #include "../itip-utils.h" #include "comp-editor-page.h" +#include <shell/e-shell.h> /* Standard GObject macros */ #define TYPE_COMP_EDITOR \ @@ -87,6 +88,8 @@ typedef enum { } CompEditorFlags; GType comp_editor_get_type (void); +gint comp_editor_compare (CompEditor *editor_a, + CompEditor *editor_b); void comp_editor_set_changed (CompEditor *editor, gboolean changed); gboolean comp_editor_get_changed (CompEditor *editor); @@ -106,6 +109,7 @@ void comp_editor_set_classification (CompEditor *editor, ECalComponentClassification classification); ECalComponentClassification comp_editor_get_classification (CompEditor *editor); +EShell * comp_editor_get_shell (CompEditor *editor); void comp_editor_set_summary (CompEditor *editor, const gchar *summary); const gchar * comp_editor_get_summary (CompEditor *editor); @@ -150,6 +154,7 @@ GtkActionGroup * const gchar *group_name); GtkWidget * comp_editor_get_managed_widget (CompEditor *editor, const gchar *widget_path); +CompEditor * comp_editor_find_instance (const gchar *uid); G_END_DECLS diff --git a/calendar/gui/dialogs/event-editor.c b/calendar/gui/dialogs/event-editor.c index 7755894f6c..830bbeb0ad 100644 --- a/calendar/gui/dialogs/event-editor.c +++ b/calendar/gui/dialogs/event-editor.c @@ -36,7 +36,6 @@ #include <misc/e-dateedit.h> #include <e-util/e-plugin-ui.h> #include <e-util/e-util-private.h> -#include <evolution-shell-component-utils.h> #include "event-page.h" #include "recurrence-page.h" @@ -466,6 +465,7 @@ event_editor_init (EventEditor *ee) GtkUIManager *ui_manager; GtkActionGroup *action_group; GtkAction *action; + const gchar *id; GError *error = NULL; ee->priv = EVENT_EDITOR_GET_PRIVATE (ee); @@ -488,7 +488,10 @@ event_editor_init (EventEditor *ee) ui_manager = comp_editor_get_ui_manager (editor); gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error); - e_plugin_ui_register_manager ("event-editor", ui_manager, ee); + + id = "org.gnome.evolution.event-editor"; + e_plugin_ui_register_manager (ui_manager, id, ee); + e_plugin_ui_enable_manager (ui_manager, id); if (error != NULL) { g_critical ("%s: %s", G_STRFUNC, error->message); @@ -662,13 +665,16 @@ event_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method, gboo * editor could not be created. **/ CompEditor * -event_editor_new (ECal *client, CompEditorFlags flags) +event_editor_new (ECal *client, + EShell *shell, + CompEditorFlags flags) { g_return_val_if_fail (E_IS_CAL (client), NULL); + g_return_val_if_fail (E_IS_SHELL (client), NULL); return g_object_new ( TYPE_EVENT_EDITOR, - "flags", flags, "client", client, NULL); + "client", client, "flags", flags, "shell", shell, NULL); } void diff --git a/calendar/gui/dialogs/event-editor.h b/calendar/gui/dialogs/event-editor.h index c050b92dfb..c2dde76673 100644 --- a/calendar/gui/dialogs/event-editor.h +++ b/calendar/gui/dialogs/event-editor.h @@ -66,6 +66,7 @@ struct _EventEditorClass { GType event_editor_get_type (void); CompEditor * event_editor_new (ECal *client, + EShell *shell, CompEditorFlags flags); void event_editor_show_meeting (EventEditor *ee); diff --git a/calendar/gui/dialogs/event-page.c b/calendar/gui/dialogs/event-page.c index dfc33fbbc4..c7b6050d3e 100644 --- a/calendar/gui/dialogs/event-page.c +++ b/calendar/gui/dialogs/event-page.c @@ -381,9 +381,11 @@ update_time (EventPage *epage, ECalComponentDateTime *start_date, ECalComponentD EventPagePrivate *priv = epage->priv; CompEditor *editor; ECal *client; + GtkAction *action; struct icaltimetype *start_tt, *end_tt, implied_tt; icaltimezone *start_zone = NULL, *def_zone = NULL; gboolean all_day_event, homezone=TRUE; + gboolean show_timezone; editor = comp_editor_page_get_editor (COMP_EDITOR_PAGE (epage)); client = comp_editor_get_client (editor); @@ -455,7 +457,9 @@ update_time (EventPage *epage, ECalComponentDateTime *start_date, ECalComponentD if (!def_zone || !start_zone || strcmp (icaltimezone_get_tzid(def_zone), icaltimezone_get_tzid (start_zone))) homezone = FALSE; - event_page_set_show_timezone (epage, (calendar_config_get_show_timezone()|| !homezone) & !all_day_event); + action = comp_editor_get_action (editor, "view-time-zone"); + show_timezone = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); + event_page_set_show_timezone (epage, (show_timezone || !homezone) & !all_day_event); /*unblock the endtimezone widget*/ g_signal_handlers_unblock_matched (priv->end_timezone, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, epage); @@ -1815,15 +1819,10 @@ remove_clicked_cb (GtkButton *btn, EventPage *epage) } static void -invite_cb (GtkWidget *widget, gpointer data) +invite_cb (GtkWidget *widget, + EventPage *page) { - EventPage *page; - EventPagePrivate *priv; - - page = EVENT_PAGE (data); - priv = page->priv; - - e_meeting_list_view_invite_others_dialog (priv->list_view); + e_meeting_list_view_invite_others_dialog (page->priv->list_view); } static void @@ -2013,6 +2012,7 @@ event_page_set_all_day_event (EventPage *epage, gboolean all_day) CompEditor *editor; GtkAction *action; gboolean date_set; + gboolean active; editor = comp_editor_page_get_editor (COMP_EDITOR_PAGE (epage)); @@ -2091,7 +2091,10 @@ event_page_set_all_day_event (EventPage *epage, gboolean all_day) TRUE); } - event_page_set_show_timezone (epage, calendar_config_get_show_timezone() & !all_day); + action = comp_editor_get_action (editor, "view-time-zone"); + active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); + event_page_set_show_timezone (epage, active & !all_day); + g_signal_handlers_block_matched (priv->start_time, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, epage); g_signal_handlers_block_matched (priv->end_time, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, epage); @@ -2173,10 +2176,12 @@ event_page_set_info_string (EventPage *epage, const gchar *icon, const gchar *ms static gboolean get_widgets (EventPage *epage) { + CompEditor *editor; CompEditorPage *page = COMP_EDITOR_PAGE (epage); GtkEntryCompletion *completion; EventPagePrivate *priv; GSList *accel_groups; + GtkAction *action; GtkWidget *toplevel; GtkWidget *sw; @@ -2184,6 +2189,8 @@ get_widgets (EventPage *epage) #define GW(name) glade_xml_get_widget (priv->xml, name) + editor = comp_editor_page_get_editor (page); + priv->main = GW ("event-page"); if (!priv->main) return FALSE; @@ -2205,7 +2212,8 @@ get_widgets (EventPage *epage) gtk_widget_show (priv->status_icons); - if (!calendar_config_get_show_timezone()) { + action = comp_editor_get_action (editor, "view-time-zone"); + if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) { gtk_widget_hide (priv->timezone_label); gtk_widget_hide (priv->start_timezone); } else { @@ -2483,14 +2491,10 @@ times_updated (EventPage *epage, gboolean adjust_end_time) * start date < end date and we set the "all day event" button as appropriate. */ static void -start_date_changed_cb (GtkWidget *dedit, gpointer data) +start_date_changed_cb (GtkWidget *dedit, + EventPage *epage) { - EventPage *epage; - - epage = EVENT_PAGE (data); - hour_minute_changed (epage); - times_updated (epage, TRUE); } @@ -2498,12 +2502,9 @@ start_date_changed_cb (GtkWidget *dedit, gpointer data) * start date < end date and we set the "all day event" button as appropriate. */ static void -end_date_changed_cb (GtkWidget *dedit, gpointer data) +end_date_changed_cb (GtkWidget *dedit, + EventPage *epage) { - EventPage *epage; - - epage = EVENT_PAGE (data); - times_updated (epage, FALSE); } @@ -2512,15 +2513,12 @@ end_date_changed_cb (GtkWidget *dedit, gpointer data) * labels on the other notebook pages. */ static void -start_timezone_changed_cb (GtkWidget *widget, gpointer data) +start_timezone_changed_cb (GtkWidget *widget, + EventPage *epage) { - EventPage *epage; - EventPagePrivate *priv; + EventPagePrivate *priv = epage->priv; icaltimezone *zone; - epage = EVENT_PAGE (data); - priv = epage->priv; - if (priv->sync_timezones) { zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->start_timezone)); comp_editor_page_set_updating (COMP_EDITOR_PAGE (epage), TRUE); @@ -2537,17 +2535,13 @@ start_timezone_changed_cb (GtkWidget *widget, gpointer data) * category list dialog. */ static void -categories_clicked_cb (GtkWidget *button, gpointer data) +categories_clicked_cb (GtkWidget *button, + EventPage *epage) { - EventPage *epage; - EventPagePrivate *priv; - GtkWidget *entry; + GtkEntry *entry; - epage = EVENT_PAGE (data); - priv = epage->priv; - - entry = priv->categories; - e_categories_config_open_dialog_for_entry (GTK_ENTRY (entry)); + entry = GTK_ENTRY (epage->priv->categories); + e_categories_config_open_dialog_for_entry (entry); } void @@ -2666,13 +2660,10 @@ set_subscriber_info_string (EventPage *epage, const char *backend_address) } static void -alarm_changed_cb (GtkWidget *widget, gpointer data) +alarm_changed_cb (GtkWidget *widget, + EventPage *epage) { - EventPage *epage; - EventPagePrivate *priv; - - epage = EVENT_PAGE (data); - priv = epage->priv; + EventPagePrivate *priv = epage->priv; if (e_dialog_combo_box_get (priv->alarm_time_combo, priv->alarm_map) != ALARM_NONE) { ECalComponentAlarm *ca; @@ -2814,7 +2805,9 @@ init_widgets (EventPage *epage) GtkTextBuffer *text_buffer; icaltimezone *zone; char *combo_label = NULL; + GtkAction *action; GtkTreeSelection *selection; + gboolean active; ECal *client; editor = comp_editor_page_get_editor (COMP_EDITOR_PAGE (epage)); @@ -2871,11 +2864,28 @@ init_widgets (EventPage *epage) g_signal_connect((priv->start_timezone), "changed", G_CALLBACK (start_timezone_changed_cb), epage); - e_meeting_list_view_column_set_visible (priv->list_view, E_MEETING_STORE_ATTENDEE_COL, TRUE); - e_meeting_list_view_column_set_visible (priv->list_view, E_MEETING_STORE_ROLE_COL, calendar_config_get_show_role ()); - e_meeting_list_view_column_set_visible (priv->list_view, E_MEETING_STORE_RSVP_COL, calendar_config_get_show_rsvp ()); - e_meeting_list_view_column_set_visible (priv->list_view, E_MEETING_STORE_STATUS_COL, calendar_config_get_show_status ()); - e_meeting_list_view_column_set_visible (priv->list_view, E_MEETING_STORE_TYPE_COL, calendar_config_get_show_type ()); + e_meeting_list_view_column_set_visible ( + priv->list_view, E_MEETING_STORE_ATTENDEE_COL, TRUE); + + action = comp_editor_get_action (editor, "view-role"); + active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); + e_meeting_list_view_column_set_visible ( + priv->list_view, E_MEETING_STORE_ROLE_COL, active); + + action = comp_editor_get_action (editor, "view-rsvp"); + active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); + e_meeting_list_view_column_set_visible ( + priv->list_view, E_MEETING_STORE_RSVP_COL, active); + + action = comp_editor_get_action (editor, "view-status"); + active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); + e_meeting_list_view_column_set_visible ( + priv->list_view, E_MEETING_STORE_STATUS_COL, active); + + action = comp_editor_get_action (editor, "view-type"); + active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); + e_meeting_list_view_column_set_visible ( + priv->list_view, E_MEETING_STORE_TYPE_COL, active); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->list_view)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE); @@ -2911,7 +2921,8 @@ init_widgets (EventPage *epage) gtk_widget_show (GTK_WIDGET (priv->list_view)); /* categories */ - if (!calendar_config_get_show_categories()) { + action = comp_editor_get_action (editor, "view-categories"); + if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) { gtk_widget_hide (priv->categories_btn); gtk_widget_hide (priv->categories); } else { @@ -3005,7 +3016,9 @@ init_widgets (EventPage *epage) e_timezone_entry_set_default_timezone (E_TIMEZONE_ENTRY (priv->start_timezone), zone); e_timezone_entry_set_default_timezone (E_TIMEZONE_ENTRY (priv->end_timezone), zone); - event_page_set_show_timezone (epage, calendar_config_get_show_timezone()); + action = comp_editor_get_action (editor, "view-time-zone"); + active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); + event_page_set_show_timezone (epage, active); return TRUE; } diff --git a/calendar/gui/dialogs/memo-editor.c b/calendar/gui/dialogs/memo-editor.c index b90bd6fb3c..8de23430c9 100644 --- a/calendar/gui/dialogs/memo-editor.c +++ b/calendar/gui/dialogs/memo-editor.c @@ -34,7 +34,6 @@ #include <e-util/e-plugin-ui.h> #include <e-util/e-util-private.h> -#include <evolution-shell-component-utils.h> #include "memo-page.h" #include "cancel-comp.h" @@ -135,6 +134,7 @@ memo_editor_init (MemoEditor *me) { CompEditor *editor = COMP_EDITOR (me); GtkUIManager *ui_manager; + const gchar *id; GError *error = NULL; me->priv = MEMO_EDITOR_GET_PRIVATE (me); @@ -142,7 +142,10 @@ memo_editor_init (MemoEditor *me) ui_manager = comp_editor_get_ui_manager (editor); gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error); - e_plugin_ui_register_manager ("memo-editor", ui_manager, me); + + id = "org.gnome.evolution.memo-editor"; + e_plugin_ui_register_manager (ui_manager, id, me); + e_plugin_ui_enable_manager (ui_manager, id); if (error != NULL) { g_critical ("%s: %s", G_STRFUNC, error->message); @@ -160,11 +163,14 @@ memo_editor_init (MemoEditor *me) * editor could not be created. **/ CompEditor * -memo_editor_new (ECal *client, CompEditorFlags flags) +memo_editor_new (ECal *client, + EShell *shell, + CompEditorFlags flags) { g_return_val_if_fail (E_IS_CAL (client), NULL); + g_return_val_if_fail (E_IS_SHELL (shell), NULL); return g_object_new ( TYPE_MEMO_EDITOR, - "flags", flags, "client", client, NULL); + "client", client, "flags", flags, "shell", shell, NULL); } diff --git a/calendar/gui/dialogs/memo-editor.h b/calendar/gui/dialogs/memo-editor.h index b45edd18ce..34db230121 100644 --- a/calendar/gui/dialogs/memo-editor.h +++ b/calendar/gui/dialogs/memo-editor.h @@ -68,6 +68,7 @@ struct _MemoEditorClass { GType memo_editor_get_type (void); CompEditor * memo_editor_new (ECal *client, + EShell *shell, CompEditorFlags flags); G_END_DECLS diff --git a/calendar/gui/dialogs/memo-page.c b/calendar/gui/dialogs/memo-page.c index 4f8c37c0a3..a15c1b1f88 100644 --- a/calendar/gui/dialogs/memo-page.c +++ b/calendar/gui/dialogs/memo-page.c @@ -929,9 +929,14 @@ to_button_clicked_cb (GtkButton *button, static gboolean init_widgets (MemoPage *mpage) { + CompEditor *editor; MemoPagePrivate *priv = mpage->priv; GtkTextBuffer *buffer; GtkTextView *view; + GtkAction *action; + gboolean active; + + editor = comp_editor_page_get_editor (COMP_EDITOR_PAGE (mpage)); /* Generic informative messages */ gtk_widget_hide (priv->info_hbox); @@ -996,8 +1001,9 @@ init_widgets (MemoPage *mpage) G_CALLBACK (comp_editor_page_changed), mpage); } - memo_page_set_show_categories ( - mpage, calendar_config_get_show_categories()); + action = comp_editor_get_action (editor, "view-categories"); + active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); + memo_page_set_show_categories (mpage, active); return TRUE; } diff --git a/calendar/gui/dialogs/memo-page.glade b/calendar/gui/dialogs/memo-page.glade index b1ff10f3f4..8728c9366e 100644 --- a/calendar/gui/dialogs/memo-page.glade +++ b/calendar/gui/dialogs/memo-page.glade @@ -159,6 +159,7 @@ <widget class="GtkLabel" id="label18"> <property name="visible">True</property> <property name="label" translatable="yes">_Description:</property> + <property name="mnemonic_widget">memo_content</property> <property name="use_underline">True</property> <property name="use_markup">False</property> <property name="justify">GTK_JUSTIFY_CENTER</property> diff --git a/calendar/gui/dialogs/task-details-page.c b/calendar/gui/dialogs/task-details-page.c index 959c275443..82fb75564a 100644 --- a/calendar/gui/dialogs/task-details-page.c +++ b/calendar/gui/dialogs/task-details-page.c @@ -517,16 +517,15 @@ complete_date_changed (TaskDetailsPage *tdpage, time_t ctime, gboolean complete) } static void -date_changed_cb (EDateEdit *dedit, gpointer data) +date_changed_cb (EDateEdit *dedit, + TaskDetailsPage *tdpage) { - TaskDetailsPage *tdpage; - TaskDetailsPagePrivate *priv; + TaskDetailsPagePrivate *priv = tdpage->priv; CompEditorPageDates dates = {NULL, NULL, NULL, NULL}; struct icaltimetype completed_tt = icaltime_null_time (); icalproperty_status status; gboolean date_set; - tdpage = TASK_DETAILS_PAGE (data); priv = tdpage->priv; if (comp_editor_page_get_updating (COMP_EDITOR_PAGE (tdpage))) diff --git a/calendar/gui/dialogs/task-details-page.glade b/calendar/gui/dialogs/task-details-page.glade index 44fc3b2fbb..aac90876ed 100644 --- a/calendar/gui/dialogs/task-details-page.glade +++ b/calendar/gui/dialogs/task-details-page.glade @@ -4,7 +4,7 @@ <glade-interface> <widget class="GtkWindow" id="task-details-toplevel"> - <property name="title">window1</property> + <property name="title" translatable="no">window1</property> <property name="type">GTK_WINDOW_TOPLEVEL</property> <property name="window_position">GTK_WIN_POS_NONE</property> <property name="modal">False</property> @@ -15,8 +15,6 @@ <property name="skip_pager_hint">False</property> <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property> <property name="gravity">GDK_GRAVITY_NORTH_WEST</property> - <property name="focus_on_map">True</property> - <property name="urgency_hint">False</property> <child> <widget class="GtkVBox" id="task-details-page"> @@ -38,10 +36,6 @@ <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="padding">0</property> @@ -69,10 +63,6 @@ <property name="yalign">0.5</property> <property name="xpad">12</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="padding">0</property> @@ -103,10 +93,7 @@ <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> + <property name="mnemonic_widget">status</property> </widget> <packing> <property name="left_attach">0</property> @@ -132,10 +119,6 @@ <property name="xpad">0</property> <property name="ypad">0</property> <property name="mnemonic_widget">percent-complete</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> @@ -160,10 +143,7 @@ <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> + <property name="mnemonic_widget">priority</property> </widget> <packing> <property name="left_attach">0</property> @@ -188,10 +168,6 @@ <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> @@ -204,85 +180,153 @@ </child> <child> - <widget class="GtkSpinButton" id="percent-complete"> + <widget class="GtkOptionMenu" id="priority"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="climb_rate">1</property> - <property name="digits">0</property> - <property name="numeric">True</property> - <property name="update_policy">GTK_UPDATE_ALWAYS</property> - <property name="snap_to_ticks">False</property> - <property name="wrap">False</property> - <property name="adjustment">0 0 100 1 10 0</property> + <property name="history">0</property> + + <child internal-child="menu"> + <widget class="GtkMenu" id="convertwidget7"> + <property name="visible">True</property> + + <child> + <widget class="GtkMenuItem" id="convertwidget8"> + <property name="visible">True</property> + <property name="label" translatable="yes">High</property> + <property name="use_underline">True</property> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="convertwidget9"> + <property name="visible">True</property> + <property name="label" translatable="yes">Normal</property> + <property name="use_underline">True</property> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="convertwidget10"> + <property name="visible">True</property> + <property name="label" translatable="yes">Low</property> + <property name="use_underline">True</property> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="convertwidget11"> + <property name="visible">True</property> + <property name="label" translatable="yes">Undefined</property> + <property name="use_underline">True</property> + </widget> + </child> + </widget> + </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="top_attach">2</property> + <property name="bottom_attach">3</property> <property name="x_options">fill</property> <property name="y_options"></property> </packing> </child> <child> - <widget class="Custom" id="completed-date"> + <widget class="GtkOptionMenu" id="status"> <property name="visible">True</property> - <property name="creation_function">task_details_page_create_date_edit</property> - <property name="int1">0</property> - <property name="int2">0</property> - <property name="last_modification_time">Fri, 01 Jun 2001 18:58:51 GMT</property> - <accessibility> - <atkrelation target="date_completed_label" type="labelled-by"/> - </accessibility> + <property name="can_focus">True</property> + <property name="history">0</property> + + <child internal-child="menu"> + <widget class="GtkMenu" id="convertwidget1"> + <property name="visible">True</property> + + <child> + <widget class="GtkMenuItem" id="convertwidget2"> + <property name="visible">True</property> + <property name="label" translatable="yes">Not Started</property> + <property name="use_underline">True</property> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="convertwidget3"> + <property name="visible">True</property> + <property name="label" translatable="yes">In Progress</property> + <property name="use_underline">True</property> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="convertwidget5"> + <property name="visible">True</property> + <property name="label" translatable="yes">Completed</property> + <property name="use_underline">True</property> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="convertwidget6"> + <property name="visible">True</property> + <property name="label" translatable="yes">Canceled</property> + <property name="use_underline">True</property> + </widget> + </child> + </widget> + </child> </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="top_attach">0</property> + <property name="bottom_attach">1</property> <property name="x_options">fill</property> <property name="y_options"></property> </packing> </child> <child> - <widget class="GtkComboBox" id="priority-combobox"> + <widget class="GtkSpinButton" id="percent-complete"> <property name="visible">True</property> - <property name="items" translatable="yes">High -Normal -Low -Undefined</property> - <property name="add_tearoffs">False</property> - <property name="focus_on_click">True</property> + <property name="can_focus">True</property> + <property name="climb_rate">1</property> + <property name="digits">0</property> + <property name="numeric">True</property> + <property name="update_policy">GTK_UPDATE_ALWAYS</property> + <property name="snap_to_ticks">False</property> + <property name="wrap">False</property> + <property name="adjustment">0 0 100 1 10 0</property> </widget> <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">1</property> + <property name="bottom_attach">2</property> <property name="x_options">fill</property> - <property name="y_options">fill</property> + <property name="y_options"></property> </packing> </child> <child> - <widget class="GtkComboBox" id="status-combobox"> + <widget class="Custom" id="completed-date"> <property name="visible">True</property> - <property name="items" translatable="yes">Not Started -In Progress -Completed -Canceled</property> - <property name="add_tearoffs">False</property> - <property name="focus_on_click">True</property> + <property name="creation_function">task_details_page_create_date_edit</property> + <property name="int1">0</property> + <property name="int2">0</property> + <property name="last_modification_time">Fri, 01 Jun 2001 18:58:51 GMT</property> + <accessibility> + <atkrelation target="date_completed_label" type="labelled-by"/> + </accessibility> </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="top_attach">3</property> + <property name="bottom_attach">4</property> <property name="x_options">fill</property> - <property name="y_options">fill</property> + <property name="y_options"></property> </packing> </child> </widget> @@ -313,10 +357,6 @@ Canceled</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="padding">0</property> @@ -344,10 +384,6 @@ Canceled</property> <property name="yalign">0.5</property> <property name="xpad">12</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="padding">0</property> @@ -379,10 +415,6 @@ Canceled</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> diff --git a/calendar/gui/dialogs/task-editor.c b/calendar/gui/dialogs/task-editor.c index eef1d64468..9ee3f02a17 100644 --- a/calendar/gui/dialogs/task-editor.c +++ b/calendar/gui/dialogs/task-editor.c @@ -35,7 +35,6 @@ #include <e-util/e-plugin-ui.h> #include <e-util/e-util-private.h> -#include <evolution-shell-component-utils.h> #include "task-page.h" #include "task-details-page.h" @@ -304,6 +303,7 @@ task_editor_init (TaskEditor *te) CompEditor *editor = COMP_EDITOR (te); GtkUIManager *ui_manager; GtkActionGroup *action_group; + const gchar *id; GError *error = NULL; te->priv = TASK_EDITOR_GET_PRIVATE (te); @@ -346,7 +346,10 @@ task_editor_init (TaskEditor *te) ui_manager = comp_editor_get_ui_manager (editor); gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error); - e_plugin_ui_register_manager ("task-editor", ui_manager, te); + + id = "org.gnome.evolution.task-editor"; + e_plugin_ui_register_manager (ui_manager, id, te); + e_plugin_ui_enable_manager (ui_manager, id); if (error != NULL) { g_critical ("%s: %s", G_STRFUNC, error->message); @@ -489,13 +492,16 @@ task_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method, gbool * editor could not be created. **/ CompEditor * -task_editor_new (ECal *client, CompEditorFlags flags) +task_editor_new (ECal *client, + EShell *shell, + CompEditorFlags flags) { g_return_val_if_fail (E_IS_CAL (client), NULL); + g_return_val_if_fail (E_IS_SHELL (shell), NULL); return g_object_new ( TYPE_TASK_EDITOR, - "flags", flags, "client", client, NULL); + "client", client, "flags", flags, "shell", shell, NULL); } void diff --git a/calendar/gui/dialogs/task-editor.h b/calendar/gui/dialogs/task-editor.h index 9376b4149a..64180ec1fb 100644 --- a/calendar/gui/dialogs/task-editor.h +++ b/calendar/gui/dialogs/task-editor.h @@ -66,6 +66,7 @@ struct _TaskEditorClass { GType task_editor_get_type (void); CompEditor * task_editor_new (ECal *client, + EShell *shell, CompEditorFlags flags); void task_editor_show_assignment (TaskEditor *te); diff --git a/calendar/gui/dialogs/task-page.c b/calendar/gui/dialogs/task-page.c index c3a8e34ba0..d020d5cd4f 100644 --- a/calendar/gui/dialogs/task-page.c +++ b/calendar/gui/dialogs/task-page.c @@ -451,12 +451,14 @@ task_page_fill_widgets (CompEditorPage *page, ECalComponent *comp) ECalComponentClassification cl; CompEditor *editor; CompEditorFlags flags; + GtkAction *action; ECal *client; GSList *l; icalcomponent *icalcomp; const char *categories, *uid; icaltimezone *zone, *default_zone; gchar *backend_addr = NULL; + gboolean active; tpage = TASK_PAGE (page); priv = tpage->priv; @@ -538,7 +540,10 @@ task_page_fill_widgets (CompEditorPage *page, ECalComponent *comp) e_timezone_entry_set_timezone (E_TIMEZONE_ENTRY (priv->timezone), zone ? zone : default_zone); - task_page_set_show_timezone (tpage, calendar_config_get_show_timezone()); + + action = comp_editor_get_action (editor, "view-time-zone"); + active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); + task_page_set_show_timezone (tpage, active); if (!(flags & COMP_EDITOR_NEW_ITEM) && !zone) { GtkAction *action; @@ -1125,15 +1130,10 @@ remove_clicked_cb (GtkButton *btn, TaskPage *page) } static void -invite_cb (GtkWidget *widget, gpointer data) +invite_cb (GtkWidget *widget, + TaskPage *page) { - TaskPage *page; - TaskPagePrivate *priv; - - page = TASK_PAGE (data); - priv = page->priv; - - e_meeting_list_view_invite_others_dialog (priv->list_view); + e_meeting_list_view_invite_others_dialog (page->priv->list_view); } static void @@ -1494,17 +1494,16 @@ summary_changed_cb (GtkEditable *editable, * other pages in the task editor, so they can update any labels. */ static void -date_changed_cb (EDateEdit *dedit, gpointer data) +date_changed_cb (EDateEdit *dedit, + TaskPage *tpage) { - TaskPage *tpage; - TaskPagePrivate *priv; + TaskPagePrivate *priv = tpage->priv; CompEditorPageDates dates; gboolean date_set, time_set; ECalComponentDateTime start_dt, due_dt; struct icaltimetype start_tt = icaltime_null_time(); struct icaltimetype due_tt = icaltime_null_time(); - tpage = TASK_PAGE (data); priv = tpage->priv; if (comp_editor_page_get_updating (COMP_EDITOR_PAGE (tpage))) @@ -1563,33 +1562,24 @@ date_changed_cb (EDateEdit *dedit, gpointer data) } static void -timezone_changed_cb (EDateEdit *dedit, gpointer data) +timezone_changed_cb (EDateEdit *dedit, + TaskPage *tpage) { - TaskPage *tpage; - TaskPagePrivate *priv; - - tpage = TASK_PAGE (data); - priv = tpage->priv; - - date_changed_cb ((EDateEdit *) priv->start_date, tpage); - date_changed_cb ((EDateEdit *) priv->due_date, tpage); + date_changed_cb ((EDateEdit *) tpage->priv->start_date, tpage); + date_changed_cb ((EDateEdit *) tpage->priv->due_date, tpage); } /* Callback used when the categories button is clicked; we must bring up the * category list dialog. */ static void -categories_clicked_cb (GtkWidget *button, gpointer data) +categories_clicked_cb (GtkWidget *button, + TaskPage *tpage) { - TaskPage *tpage; - TaskPagePrivate *priv; - GtkWidget *entry; + GtkEntry *entry; - tpage = TASK_PAGE (data); - priv = tpage->priv; - - entry = priv->categories; - e_categories_config_open_dialog_for_entry (GTK_ENTRY (entry)); + entry = GTK_ENTRY (tpage->priv->categories); + e_categories_config_open_dialog_for_entry (entry); } static gboolean @@ -1844,12 +1834,17 @@ task_page_sendoptions_clicked_cb (TaskPage *tpage) static gboolean init_widgets (TaskPage *tpage) { + CompEditor *editor; TaskPagePrivate *priv; + GtkAction *action; GtkTextBuffer *text_buffer; icaltimezone *zone; + gboolean active; priv = tpage->priv; + editor = comp_editor_page_get_editor (COMP_EDITOR_PAGE (tpage)); + /* Make sure the EDateEdit widgets use our timezones to get the current time. */ e_date_edit_set_get_time_callback (E_DATE_EDIT (priv->start_date), @@ -1945,15 +1940,36 @@ init_widgets (TaskPage *tpage) zone = calendar_config_get_icaltimezone (); e_timezone_entry_set_default_timezone (E_TIMEZONE_ENTRY (priv->timezone), zone); - task_page_set_show_timezone (tpage, calendar_config_get_show_timezone()); + action = comp_editor_get_action (editor, "view-time-zone"); + active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); + task_page_set_show_timezone (tpage, active); + + e_meeting_list_view_column_set_visible ( + priv->list_view, E_MEETING_STORE_ATTENDEE_COL, TRUE); + + action = comp_editor_get_action (editor, "view-role"); + active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); + e_meeting_list_view_column_set_visible ( + priv->list_view, E_MEETING_STORE_ROLE_COL, active); + + action = comp_editor_get_action (editor, "view-rsvp"); + active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); + e_meeting_list_view_column_set_visible ( + priv->list_view, E_MEETING_STORE_RSVP_COL, active); + + action = comp_editor_get_action (editor, "view-status"); + active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); + e_meeting_list_view_column_set_visible ( + priv->list_view, E_MEETING_STORE_STATUS_COL, active); - e_meeting_list_view_column_set_visible (priv->list_view, E_MEETING_STORE_ATTENDEE_COL, TRUE); - e_meeting_list_view_column_set_visible (priv->list_view, E_MEETING_STORE_ROLE_COL, calendar_config_get_show_role ()); - e_meeting_list_view_column_set_visible (priv->list_view, E_MEETING_STORE_RSVP_COL, calendar_config_get_show_rsvp ()); - e_meeting_list_view_column_set_visible (priv->list_view, E_MEETING_STORE_STATUS_COL, calendar_config_get_show_status ()); - e_meeting_list_view_column_set_visible (priv->list_view, E_MEETING_STORE_TYPE_COL, calendar_config_get_show_type ()); + action = comp_editor_get_action (editor, "view-type"); + active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); + e_meeting_list_view_column_set_visible ( + priv->list_view, E_MEETING_STORE_TYPE_COL, active); - task_page_set_show_categories (tpage, calendar_config_get_show_categories()); + action = comp_editor_get_action (editor, "view-categories"); + active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); + task_page_set_show_categories (tpage, active); return TRUE; } diff --git a/calendar/gui/e-cal-component-memo-preview.c b/calendar/gui/e-cal-component-memo-preview.c deleted file mode 100644 index f564538a59..0000000000 --- a/calendar/gui/e-cal-component-memo-preview.c +++ /dev/null @@ -1,368 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Federico Mena Quintero <federico@ximian.com> - * Damon Chaplin <damon@ximian.com> - * Rodrigo Moya <rodrigo@ximian.com> - * Nathan Owens <pianocomp81@yahoo.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <gtk/gtk.h> -#include <glib/gi18n.h> -#include <libecal/e-cal-time-util.h> -#include <libedataserver/e-categories.h> -#include <gtkhtml/gtkhtml.h> -#include <gtkhtml/gtkhtml-stream.h> -#include <libedataserver/e-time-utils.h> -#include <e-util/e-util.h> -#include <e-util/e-categories-config.h> -#include "calendar-config.h" -#include "e-cal-component-memo-preview.h" -#include "e-cal-component-preview.h" -#include <camel/camel-mime-filter-tohtml.h> - -struct _ECalComponentMemoPreviewPrivate { - GtkWidget *html; - - icaltimezone *zone; -}; - -G_DEFINE_TYPE (ECalComponentMemoPreview, e_cal_component_memo_preview, GTK_TYPE_TABLE) - - -static void -on_link_clicked (GtkHTML *html, const char *url, gpointer data) -{ - /* FIXME Pass a parent window. */ - e_show_uri (NULL, url); -} - -static void -on_url_cb (GtkHTML *html, const char *url, gpointer data) -{ -#if 0 - char *msg; - ECalComponentMemoPreview *preview = data; - - if (url && *url) { - msg = g_strdup_printf (_("Click to open %s"), url); - e_calendar_table_set_status_message (e_tasks_get_calendar_table (tasks), msg); - g_free (msg); - } else - e_calendar_table_set_status_message (e_tasks_get_calendar_table (tasks), NULL); -#endif -} - -/* 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)); - - /* 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); - if (l) { - GSList *node; - GString *string = g_string_new (NULL); - - - gtk_html_stream_printf(stream, "<H3>%s: ", _("Categories")); - - for (node = l; node != NULL; node = node->next) { - const char *icon_file; - - icon_file = e_categories_get_icon_file_for ((const char *) node->data); - if (icon_file && g_file_test(icon_file, G_FILE_TEST_EXISTS)) { - gchar *icon_file_uri = g_filename_to_uri (icon_file, NULL, NULL); - gtk_html_stream_printf (stream, "<IMG ALT=\"%s\" SRC=\"%s\">", - (const char *) node->data, icon_file_uri); - g_free (icon_file_uri); - one_added = TRUE; - } - else{ - if(one_added == FALSE){ - g_string_append_printf (string, "%s", (const char *) node->data); - one_added = TRUE; - } - else{ - g_string_append_printf (string, ", %s", (const char *) node->data); - } - } - } - - if (string->len > 0) - gtk_html_stream_printf(stream, "%s", string->str); - - g_string_free (string, TRUE); - - gtk_html_stream_printf(stream, "</H3>"); - - e_cal_component_free_categories_list (l); - } - - /* Start table */ - 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); - - g_free (str); - } - e_cal_component_free_datetime (&dt); - - /* write description and URL */ - gtk_html_stream_printf (stream, "<TR><TD COLSPAN=\"2\"><HR></TD></TR>"); - - e_cal_component_get_description_list (comp, &l); - if (l) { - GSList *node; - - gtk_html_stream_printf (stream, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\"><B>%s</B></TD>", _("Description:")); - - gtk_html_stream_printf (stream, "<TD><TT>"); - - for (node = l; node != NULL; node = node->next) { - char *html; - - text = * (ECalComponentText *) node->data; - html = camel_text_to_html (text.value ? text.value : "", CAMEL_MIME_FILTER_TOHTML_CONVERT_NL | CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES | CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS | CAMEL_MIME_FILTER_TOHTML_CONVERT_ADDRESSES, 0); - - if (html) - gtk_html_stream_printf (stream, "%s", html); - - g_free (html); - } - - gtk_html_stream_printf (stream, "</TT></TD></TR>"); - - e_cal_component_free_text_list (l); - } - - /* URL */ - e_cal_component_get_url (comp, (const char **) &str); - if (str) { - gtk_html_stream_printf (stream, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\"><B>%s</B></TD>", _("Web Page:")); - gtk_html_stream_printf (stream, "<TD><A HREF=\"%s\">%s</A></TD></TR>", str, str); - } - - gtk_html_stream_printf (stream, "</TABLE>"); - - /* close document */ - gtk_html_stream_printf (stream, "</BODY></HTML>"); -} - -static void -e_cal_component_memo_preview_init (ECalComponentMemoPreview *preview) -{ - ECalComponentMemoPreviewPrivate *priv; - GtkWidget *scroll; - - priv = g_new0 (ECalComponentMemoPreviewPrivate, 1); - preview->priv = priv; - - priv->html = gtk_html_new (); - gtk_html_set_default_content_type (GTK_HTML (priv->html), "charset=utf-8"); - gtk_html_load_empty (GTK_HTML (priv->html)); - - g_signal_connect (G_OBJECT (priv->html), "url_requested", - G_CALLBACK (e_cal_comp_preview_url_requested_cb), NULL); - g_signal_connect (G_OBJECT (priv->html), "link_clicked", - G_CALLBACK (on_link_clicked), preview); - g_signal_connect (G_OBJECT (priv->html), "on_url", - G_CALLBACK (on_url_cb), preview); - - scroll = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN); - - gtk_container_add (GTK_CONTAINER (scroll), priv->html); - gtk_container_add (GTK_CONTAINER (preview), scroll); - gtk_widget_show_all (scroll); - - priv->zone = icaltimezone_get_utc_timezone (); -} - -static void -e_cal_component_memo_preview_destroy (GtkObject *object) -{ - ECalComponentMemoPreview *preview; - ECalComponentMemoPreviewPrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (E_IS_CAL_COMPONENT_MEMO_PREVIEW (object)); - - preview = E_CAL_COMPONENT_MEMO_PREVIEW (object); - priv = preview->priv; - - if (priv) { - - g_free (priv); - preview->priv = NULL; - } - - if (GTK_OBJECT_CLASS (e_cal_component_memo_preview_parent_class)->destroy) - (* GTK_OBJECT_CLASS (e_cal_component_memo_preview_parent_class)->destroy) (object); -} - -static void -e_cal_component_memo_preview_class_init (ECalComponentMemoPreviewClass *klass) -{ - GtkObjectClass *object_class; - - object_class = (GtkObjectClass *) klass; - - object_class->destroy = e_cal_component_memo_preview_destroy; -} - -GtkWidget * -e_cal_component_memo_preview_new (void) -{ - ECalComponentMemoPreview *preview; - - preview = g_object_new (e_cal_component_memo_preview_get_type (), NULL); - - return GTK_WIDGET (preview); -} - -icaltimezone * -e_cal_component_memo_preview_get_default_timezone (ECalComponentMemoPreview *preview) -{ - ECalComponentMemoPreviewPrivate *priv; - - g_return_val_if_fail (preview != NULL, NULL); - g_return_val_if_fail (E_IS_CAL_COMPONENT_MEMO_PREVIEW (preview), NULL); - - priv = preview->priv; - - return priv->zone; -} - -void -e_cal_component_memo_preview_set_default_timezone (ECalComponentMemoPreview *preview, icaltimezone *zone) -{ - ECalComponentMemoPreviewPrivate *priv; - - g_return_if_fail (preview != NULL); - g_return_if_fail (E_IS_CAL_COMPONENT_MEMO_PREVIEW (preview)); - g_return_if_fail (zone != NULL); - - priv = preview->priv; - - priv->zone = zone; -} - -void -e_cal_component_memo_preview_display (ECalComponentMemoPreview *preview, ECal *ecal, ECalComponent *comp) -{ - ECalComponentMemoPreviewPrivate *priv; - GtkHTMLStream *stream; - - g_return_if_fail (preview != NULL); - g_return_if_fail (E_IS_CAL_COMPONENT_MEMO_PREVIEW (preview)); - g_return_if_fail (comp != NULL); - g_return_if_fail (E_IS_CAL_COMPONENT (comp)); - - priv = preview->priv; - - stream = gtk_html_begin (GTK_HTML (priv->html)); - write_html (stream, ecal, comp, priv->zone); - gtk_html_stream_close (stream, GTK_HTML_STREAM_OK); -} - -void -e_cal_component_memo_preview_clear (ECalComponentMemoPreview *preview) -{ - ECalComponentMemoPreviewPrivate *priv; - - g_return_if_fail (preview != NULL); - g_return_if_fail (E_IS_CAL_COMPONENT_MEMO_PREVIEW (preview)); - - priv = preview->priv; - - gtk_html_load_empty (GTK_HTML (priv->html)); -} - -GtkWidget * -e_cal_component_memo_preview_get_html (ECalComponentMemoPreview *preview) -{ - g_return_val_if_fail (preview != NULL, NULL); - g_return_val_if_fail (E_IS_CAL_COMPONENT_MEMO_PREVIEW (preview), NULL); - - return preview->priv->html; -} diff --git a/calendar/gui/e-cal-component-memo-preview.h b/calendar/gui/e-cal-component-memo-preview.h deleted file mode 100644 index 7d77a0aa32..0000000000 --- a/calendar/gui/e-cal-component-memo-preview.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Federico Mena Quintero <federico@ximian.com> - * Damon Chaplin <damon@ximian.com> - * Nathan Owens <pianocomp81@yahoo.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_CAL_COMPONENT_MEMO_PREVIEW_H_ -#define _E_CAL_COMPONENT_MEMO_PREVIEW_H_ - -#include <gtk/gtk.h> -#include <libecal/e-cal.h> - -#define E_TYPE_CAL_COMPONENT_MEMO_PREVIEW (e_cal_component_memo_preview_get_type ()) -#define E_CAL_COMPONENT_MEMO_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CAL_COMPONENT_MEMO_PREVIEW, ECalComponentMemoPreview)) -#define E_CAL_COMPONENT_MEMO_PREVIEW_CLASS(klass) (G_TYPE_CHECK_INSTANCE_CAST_CLASS ((klass), E_TYPE_CAL_COMPONENT_MEMO_PREVIEW, \ - ECalComponentMemoPreviewClass)) -#define E_IS_CAL_COMPONENT_MEMO_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CAL_COMPONENT_MEMO_PREVIEW)) -#define E_IS_CAL_COMPONENT_MEMO_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CAL_COMPONENT_MEMO_PREVIEW)) - -typedef struct _ECalComponentMemoPreview ECalComponentMemoPreview; -typedef struct _ECalComponentMemoPreviewClass ECalComponentMemoPreviewClass; -typedef struct _ECalComponentMemoPreviewPrivate ECalComponentMemoPreviewPrivate; - -struct _ECalComponentMemoPreview { - GtkTable table; - - /* Private data */ - ECalComponentMemoPreviewPrivate *priv; -}; - -struct _ECalComponentMemoPreviewClass { - GtkTableClass parent_class; - - /* Notification signals */ - void (* selection_changed) (ECalComponentMemoPreview *preview, int n_selected); -}; - - -GType e_cal_component_memo_preview_get_type (void); -GtkWidget *e_cal_component_memo_preview_new (void); - -icaltimezone *e_cal_component_memo_preview_get_default_timezone (ECalComponentMemoPreview *preview); -void e_cal_component_memo_preview_set_default_timezone (ECalComponentMemoPreview *preview, icaltimezone *zone); - -void e_cal_component_memo_preview_display (ECalComponentMemoPreview *preview, ECal *ecal, ECalComponent *comp); -void e_cal_component_memo_preview_clear (ECalComponentMemoPreview *preview); -GtkWidget *e_cal_component_memo_preview_get_html (ECalComponentMemoPreview *preview); - -#endif /* _E_CAL_COMPONENT_MEMO_PREVIEW_H_ */ diff --git a/calendar/gui/e-cal-component-preview.c b/calendar/gui/e-cal-component-preview.c index 0c759a1591..01c01be6f9 100644 --- a/calendar/gui/e-cal-component-preview.c +++ b/calendar/gui/e-cal-component-preview.c @@ -8,11 +8,19 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. +<<<<<<< HEAD:calendar/gui/e-cal-component-preview.c * * You should have received a copy of the GNU Lesser General Public * License along with the program; if not, see <http://www.gnu.org/licenses/> * * +======= + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * +>>>>>>> 23df769955ea54f756a579c19964df87ae6fd5c8:calendar/gui/e-cal-component-preview.c * Authors: * Federico Mena Quintero <federico@ximian.com> * Damon Chaplin <damon@ximian.com> @@ -22,42 +30,41 @@ * */ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif +#include "e-cal-component-preview.h" #include <string.h> -#include <gio/gio.h> #include <gtk/gtk.h> #include <glib/gi18n.h> -#include <libedataserver/e-categories.h> #include <libecal/e-cal-time-util.h> -#include <gtkhtml/gtkhtml.h> +#include <libedataserver/e-categories.h> #include <gtkhtml/gtkhtml-stream.h> #include <libedataserver/e-time-utils.h> #include <e-util/e-util.h> #include <e-util/e-categories-config.h> #include "calendar-config.h" -#include "e-cal-component-preview.h" #include <camel/camel-mime-filter-tohtml.h> -struct _ECalComponentPreviewPrivate { - GtkWidget *html; +#define E_CAL_COMPONENT_PREVIEW_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_CAL_COMPONENT_PREVIEW, ECalComponentPreviewPrivate)) +struct _ECalComponentPreviewPrivate { icaltimezone *zone; }; -G_DEFINE_TYPE (ECalComponentPreview, e_cal_component_preview, GTK_TYPE_TABLE) +static gpointer parent_class; static void -on_link_clicked (GtkHTML *html, const char *url, gpointer data) +cal_component_preview_link_clicked (GtkHTML *html, + const gchar *uri) { /* FIXME Pass a parent window. */ - e_show_uri (NULL, url); + e_show_uri (NULL, uri); } static void -on_url_cb (GtkHTML *html, const char *url, gpointer data) +cal_component_preview_on_url (GtkHTML *html, + const gchar *url) { #if 0 char *msg; @@ -72,51 +79,11 @@ on_url_cb (GtkHTML *html, const char *url, gpointer data) #endif } -/* Callback used when the user selects a URL in the HTML widget */ -void -e_cal_comp_preview_url_requested_cb (GtkHTML *html, const char *url, GtkHTMLStream *html_stream, gpointer data) -{ - int len = strlen ("file:///"); - - if (!strncmp ("file:///", url, len)) { - GFile *file; - const char *path = url + len - 1; - - g_return_if_fail (html_stream != NULL); - g_return_if_fail (path != NULL); - - file = g_file_new_for_path (path); - if (file) { - char buffer[4096]; - GInputStream *stream; - - /* ignore errors here */ - stream = G_INPUT_STREAM (g_file_read (file, NULL, NULL)); - - if (stream) { - gssize bread; - - do { - /* ignore errors here as well */ - bread = g_input_stream_read (stream, buffer, sizeof (buffer), NULL, NULL); - if (bread > 0) - gtk_html_stream_write (html_stream, buffer, bread); - } while (bread > 0); - - g_input_stream_close (stream, NULL, NULL); - g_object_unref (stream); - - gtk_html_stream_close (html_stream, GTK_HTML_STREAM_OK); - } - - g_object_unref (file); - } - } -} - /* 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) +timet_to_str_with_zone (ECalComponentDateTime *dt, + ECal *ecal, + icaltimezone *default_zone) { struct icaltimetype itt; icaltimezone *zone; @@ -146,12 +113,18 @@ timet_to_str_with_zone (ECalComponentDateTime *dt, ECal *ecal, icaltimezone *def } static void -write_html (GtkHTMLStream *stream, ECal *ecal, ECalComponent *comp, icaltimezone *default_zone) +cal_component_preview_write_html (GtkHTMLStream *stream, + ECal *ecal, + ECalComponent *comp, + icaltimezone *default_zone) { ECalComponentText text; ECalComponentDateTime dt; gchar *str; - GSList *l; + GString *string; + GSList *list, *iter; + icalcomponent *icalcomp; + icalproperty *icalprop; icalproperty_status status; const char *location; int *priority_value; @@ -170,28 +143,34 @@ write_html (GtkHTMLStream *stream, ECal *ecal, ECalComponent *comp, icaltimezone "<HTML><BODY><H1><I>%s</I></H1>", _("Untitled")); - /* write icons for the categories */ - e_cal_component_get_categories_list (comp, &l); - if (l) { - GSList *node; - - for (node = l; node != NULL; node = node->next) { - const char *icon_file; - - icon_file = e_categories_get_icon_file_for ((const char *) node->data); - if (icon_file) { - gchar *icon_file_uri = g_filename_to_uri (icon_file, NULL, NULL); - gtk_html_stream_printf (stream, "<IMG ALT=\"%s\" SRC=\"%s\">", - (const char *) node->data, icon_file_uri); - g_free (icon_file_uri); - } + string = g_string_new (NULL); + e_cal_component_get_categories_list (comp, &list); + if (list != NULL) + gtk_html_stream_printf (stream, "<H3>%s ", _("Categories:")); + for (iter = list; iter != NULL; iter = iter->next) { + const gchar *category = iter->data; + const gchar *icon_file; + + icon_file = e_categories_get_icon_file_for (category); + if (icon_file && g_file_test (icon_file, G_FILE_TEST_EXISTS)) { + gchar *uri; + + uri = g_filename_to_uri (icon_file, NULL, NULL); + gtk_html_stream_printf ( + stream, "<IMG ALT=\"%s\" SRC=\"%s\">", + category, uri); + g_free (uri); + } else { + if (iter != list) + g_string_append_len (string, ", ", 2); + g_string_append (string, category); } - - e_cal_component_free_categories_list (l); - - gtk_html_stream_printf (stream, "<BR><BR><BR>"); } + if (string->len > 0) + gtk_html_stream_printf (stream, "%s</H3>", string->str); + e_cal_component_free_categories_list (list); + g_string_free (string, TRUE); /* Start table */ gtk_html_stream_printf (stream, "<TABLE BORDER=\"0\" WIDTH=\"80%%\">" @@ -237,26 +216,31 @@ write_html (GtkHTMLStream *stream, ECal *ecal, ECalComponent *comp, icaltimezone e_cal_component_free_datetime (&dt); /* write status */ - gtk_html_stream_printf (stream, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\"><B>%s</B></TD>", _("Status:")); - e_cal_component_get_status (comp, &status); - switch (status) { - case ICAL_STATUS_INPROCESS : - str = g_strdup (_("In Progress")); - break; - case ICAL_STATUS_COMPLETED : - str = g_strdup (_("Completed")); - break; - case ICAL_STATUS_CANCELLED : - str = g_strdup (_("Canceled")); - break; - case ICAL_STATUS_NONE : - default : - str = g_strdup (_("Not Started")); - break; - } + icalcomp = e_cal_component_get_icalcomponent (comp); + icalprop = icalcomponent_get_first_property ( + icalcomp, ICAL_STATUS_PROPERTY); + if (icalprop != NULL) { + gtk_html_stream_printf (stream, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\"><B>%s</B></TD>", _("Status:")); + e_cal_component_get_status (comp, &status); + switch (status) { + case ICAL_STATUS_INPROCESS : + str = g_strdup (_("In Progress")); + break; + case ICAL_STATUS_COMPLETED : + str = g_strdup (_("Completed")); + break; + case ICAL_STATUS_CANCELLED : + str = g_strdup (_("Canceled")); + break; + case ICAL_STATUS_NONE : + default : + str = g_strdup (_("Not Started")); + break; + } - gtk_html_stream_printf (stream, "<TD>%s</TD></TR>", str); - g_free (str); + gtk_html_stream_printf (stream, "<TD>%s</TD></TR>", str); + g_free (str); + } /* write priority */ e_cal_component_get_priority (comp, &priority_value); @@ -280,15 +264,15 @@ write_html (GtkHTMLStream *stream, ECal *ecal, ECalComponent *comp, icaltimezone /* write description and URL */ gtk_html_stream_printf (stream, "<TR><TD COLSPAN=\"2\"><HR></TD></TR>"); - e_cal_component_get_description_list (comp, &l); - if (l) { + e_cal_component_get_description_list (comp, &list); + if (list) { GSList *node; gtk_html_stream_printf (stream, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\"><B>%s</B></TD>", _("Description:")); gtk_html_stream_printf (stream, "<TD><TT>"); - for (node = l; node != NULL; node = node->next) { + for (node = list; node != NULL; node = node->next) { char *html; text = * (ECalComponentText *) node->data; @@ -302,7 +286,7 @@ write_html (GtkHTMLStream *stream, ECal *ecal, ECalComponent *comp, icaltimezone gtk_html_stream_printf (stream, "</TT></TD></TR>"); - e_cal_component_free_text_list (l); + e_cal_component_free_text_list (list); } /* URL */ @@ -319,143 +303,120 @@ write_html (GtkHTMLStream *stream, ECal *ecal, ECalComponent *comp, icaltimezone } static void -e_cal_component_preview_init (ECalComponentPreview *preview) +cal_component_preview_finalize (GObject *object) { ECalComponentPreviewPrivate *priv; - GtkWidget *scroll; - priv = g_new0 (ECalComponentPreviewPrivate, 1); - preview->priv = priv; + priv = E_CAL_COMPONENT_PREVIEW_GET_PRIVATE (object); - priv->html = gtk_html_new (); - gtk_html_set_default_content_type (GTK_HTML (priv->html), "charset=utf-8"); - gtk_html_load_empty (GTK_HTML (priv->html)); + /* XXX Nothing to do? */ - g_signal_connect (G_OBJECT (priv->html), "url_requested", - G_CALLBACK (e_cal_comp_preview_url_requested_cb), NULL); - g_signal_connect (G_OBJECT (priv->html), "link_clicked", - G_CALLBACK (on_link_clicked), preview); - g_signal_connect (G_OBJECT (priv->html), "on_url", - G_CALLBACK (on_url_cb), preview); + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} - scroll = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN); +static void +cal_component_preview_class_init (ECalComponentPreviewClass *class) +{ + GObjectClass *object_class; + GtkHTMLClass *gtkhtml_class; - gtk_container_add (GTK_CONTAINER (scroll), priv->html); - gtk_container_add (GTK_CONTAINER (preview), scroll); - gtk_widget_show_all (scroll); + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (ECalComponentPreviewPrivate)); - priv->zone = icaltimezone_get_utc_timezone (); + object_class = G_OBJECT_CLASS (class); + object_class->finalize = cal_component_preview_finalize; + + gtkhtml_class = GTK_HTML_CLASS (class); + gtkhtml_class->link_clicked = cal_component_preview_link_clicked; + gtkhtml_class->on_url = cal_component_preview_on_url; } static void -e_cal_component_preview_destroy (GtkObject *object) +cal_component_preview_init (ECalComponentPreview *preview) { - ECalComponentPreview *preview; ECalComponentPreviewPrivate *priv; + GtkHTML *html; - g_return_if_fail (object != NULL); - g_return_if_fail (E_IS_CAL_COMPONENT_PREVIEW (object)); - - preview = E_CAL_COMPONENT_PREVIEW (object); - priv = preview->priv; + preview->priv = E_CAL_COMPONENT_PREVIEW_GET_PRIVATE (preview); - if (priv) { + html = GTK_HTML (preview); + gtk_html_set_default_content_type (html, "charset=utf-8"); + gtk_html_load_empty (html); - g_free (priv); - preview->priv = NULL; - } - - if (GTK_OBJECT_CLASS (e_cal_component_preview_parent_class)->destroy) - (* GTK_OBJECT_CLASS (e_cal_component_preview_parent_class)->destroy) (object); + priv->zone = icaltimezone_get_utc_timezone (); } -static void -e_cal_component_preview_class_init (ECalComponentPreviewClass *klass) +GType +e_cal_component_preview_get_type (void) { - GtkObjectClass *object_class; - - object_class = (GtkObjectClass *) klass; + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (ECalComponentPreviewClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) cal_component_preview_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (ECalComponentPreview), + 0, /* n_preallocs */ + (GInstanceInitFunc) cal_component_preview_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + GTK_TYPE_HTML, "ECalComponentPreview", &type_info, 0); + } - object_class->destroy = e_cal_component_preview_destroy; + return type; } GtkWidget * e_cal_component_preview_new (void) { - ECalComponentPreview *preview; - - preview = g_object_new (e_cal_component_preview_get_type (), NULL); - - return GTK_WIDGET (preview); + return g_object_new (E_TYPE_CAL_COMPONENT_PREVIEW, NULL); } icaltimezone * e_cal_component_preview_get_default_timezone (ECalComponentPreview *preview) { - ECalComponentPreviewPrivate *priv; - - g_return_val_if_fail (preview != NULL, NULL); g_return_val_if_fail (E_IS_CAL_COMPONENT_PREVIEW (preview), NULL); - priv = preview->priv; - - return priv->zone; + return preview->priv->zone; } void -e_cal_component_preview_set_default_timezone (ECalComponentPreview *preview, icaltimezone *zone) +e_cal_component_preview_set_default_timezone (ECalComponentPreview *preview, + icaltimezone *zone) { - ECalComponentPreviewPrivate *priv; - - g_return_if_fail (preview != NULL); g_return_if_fail (E_IS_CAL_COMPONENT_PREVIEW (preview)); g_return_if_fail (zone != NULL); - priv = preview->priv; - - priv->zone = zone; + preview->priv->zone = zone; } void -e_cal_component_preview_display (ECalComponentPreview *preview, ECal *ecal, ECalComponent *comp) +e_cal_component_preview_display (ECalComponentPreview *preview, + ECal *ecal, + ECalComponent *comp) { - ECalComponentPreviewPrivate *priv; GtkHTMLStream *stream; - g_return_if_fail (preview != NULL); g_return_if_fail (E_IS_CAL_COMPONENT_PREVIEW (preview)); - g_return_if_fail (comp != NULL); g_return_if_fail (E_IS_CAL_COMPONENT (comp)); - priv = preview->priv; - - stream = gtk_html_begin (GTK_HTML (priv->html)); - write_html (stream, ecal, comp, priv->zone); + stream = gtk_html_begin (GTK_HTML (preview)); + cal_component_preview_write_html ( + stream, ecal, comp, preview->priv->zone); gtk_html_stream_close (stream, GTK_HTML_STREAM_OK); } void e_cal_component_preview_clear (ECalComponentPreview *preview) { - ECalComponentPreviewPrivate *priv; - - g_return_if_fail (preview != NULL); g_return_if_fail (E_IS_CAL_COMPONENT_PREVIEW (preview)); - priv = preview->priv; - - gtk_html_load_empty (GTK_HTML (priv->html)); -} - -GtkWidget * -e_cal_component_preview_get_html (ECalComponentPreview *preview) -{ - g_return_val_if_fail (preview != NULL, NULL); - g_return_val_if_fail (E_IS_CAL_COMPONENT_PREVIEW (preview), NULL); - - return preview->priv->html; + gtk_html_load_empty (GTK_HTML (preview)); } diff --git a/calendar/gui/e-cal-component-preview.h b/calendar/gui/e-cal-component-preview.h index 73e8126a36..dd04019e44 100644 --- a/calendar/gui/e-cal-component-preview.h +++ b/calendar/gui/e-cal-component-preview.h @@ -1,5 +1,4 @@ /* - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either @@ -22,52 +21,63 @@ * */ -#ifndef _E_CAL_COMPONENT_PREVIEW_H_ -#define _E_CAL_COMPONENT_PREVIEW_H_ +#ifndef E_CAL_COMPONENT_PREVIEW_H +#define E_CAL_COMPONENT_PREVIEW_H #include <gtk/gtk.h> #include <libecal/e-cal.h> #include <gtkhtml/gtkhtml.h> -#include <gtkhtml/gtkhtml-stream.h> -#define E_TYPE_CAL_COMPONENT_PREVIEW (e_cal_component_preview_get_type ()) -#define E_CAL_COMPONENT_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CAL_COMPONENT_PREVIEW, ECalComponentPreview)) -#define E_CAL_COMPONENT_PREVIEW_CLASS(klass) (G_TYPE_CHECK_INSTANCE_CAST_CLASS ((klass), E_TYPE_CAL_COMPONENT_PREVIEW, \ - ECalComponentPreviewClass)) -#define E_IS_CAL_COMPONENT_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CAL_COMPONENT_PREVIEW)) -#define E_IS_CAL_COMPONENT_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CAL_COMPONENT_PREVIEW)) +/* Standard GObject macros */ +#define E_TYPE_CAL_COMPONENT_PREVIEW \ + (e_cal_component_preview_get_type ()) +#define E_CAL_COMPONENT_PREVIEW(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_CAL_COMPONENT_PREVIEW, ECalComponentPreview)) +#define E_CAL_COMPONENT_PREVIEW_CLASS(cls) \ + (G_TYPE_CHECK_INSTANCE_CAST_CLASS \ + ((cls), E_TYPE_CAL_COMPONENT_PREVIEW, ECalComponentPreviewClass)) +#define E_IS_CAL_COMPONENT_PREVIEW(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_CAL_COMPONENT_PREVIEW)) +#define E_IS_CAL_COMPONENT_PREVIEW_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_CAL_COMPONENT_PREVIEW)) +#define E_CAL_COMPONENT_PREVIEW_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_CAL_COMPONENT_PREVIEW, ECalComponentPreviewClass)) + +G_BEGIN_DECLS typedef struct _ECalComponentPreview ECalComponentPreview; typedef struct _ECalComponentPreviewClass ECalComponentPreviewClass; typedef struct _ECalComponentPreviewPrivate ECalComponentPreviewPrivate; struct _ECalComponentPreview { - GtkTable table; - - /* Private data */ + GtkHTML parent; ECalComponentPreviewPrivate *priv; }; struct _ECalComponentPreviewClass { - GtkTableClass parent_class; + GtkHTMLClass parent_class; /* Notification signals */ void (* selection_changed) (ECalComponentPreview *preview, int n_selected); }; -GType e_cal_component_preview_get_type (void); -GtkWidget *e_cal_component_preview_new (void); - -icaltimezone *e_cal_component_preview_get_default_timezone (ECalComponentPreview *preview); -void e_cal_component_preview_set_default_timezone (ECalComponentPreview *preview, icaltimezone *zone); - -void e_cal_component_preview_display (ECalComponentPreview *preview, ECal *ecal, ECalComponent *comp); -void e_cal_component_preview_clear (ECalComponentPreview *preview); - -/* Callback used when GtkHTML widget requests URL */ -void e_cal_comp_preview_url_requested_cb (GtkHTML *html, const char *url, GtkHTMLStream *html_stream, gpointer data); +GType e_cal_component_preview_get_type(void); +GtkWidget * e_cal_component_preview_new (void); +icaltimezone * e_cal_component_preview_get_default_timezone + (ECalComponentPreview *preview); +void e_cal_component_preview_set_default_timezone + (ECalComponentPreview *preview, + icaltimezone *zone); +void e_cal_component_preview_display (ECalComponentPreview *preview, + ECal *ecal, + ECalComponent *comp); +void e_cal_component_preview_clear (ECalComponentPreview *preview); -GtkWidget *e_cal_component_preview_get_html (ECalComponentPreview *preview); +G_END_DECLS -#endif /* _E_CAL_COMPONENT_PREVIEW_H_ */ +#endif /* E_CAL_COMPONENT_PREVIEW_H */ diff --git a/calendar/gui/e-cal-event.c b/calendar/gui/e-cal-event.c index 6e295ab9a8..ecd1ea5b7e 100644 --- a/calendar/gui/e-cal-event.c +++ b/calendar/gui/e-cal-event.c @@ -43,10 +43,10 @@ static void ece_target_free (EEvent *ev, EEventTarget *t) { switch (t->type) { - case E_CAL_EVENT_TARGET_COMPONENT: { - ECalEventTargetComponent *s = (ECalEventTargetComponent *) t; - if (s->component) - g_object_unref (s->component); + case E_CAL_EVENT_TARGET_MODULE: { + ECalEventTargetModule *s = (ECalEventTargetModule *) t; + if (s->shell_module) + g_object_unref (s->shell_module); break; } } @@ -92,12 +92,12 @@ e_cal_event_peek (void) return e_cal_event; } -ECalEventTargetComponent * -e_cal_event_target_new_component (ECalEvent *ece, struct _CalendarComponent *component, guint32 flags) +ECalEventTargetModule * +e_cal_event_target_new_module (ECalEvent *ece, EShellModule *shell_module, guint32 flags) { - ECalEventTargetComponent *t = e_event_target_new (&ece->event, E_CAL_EVENT_TARGET_COMPONENT, sizeof (*t)); + ECalEventTargetModule *t = e_event_target_new (&ece->event, E_CAL_EVENT_TARGET_MODULE, sizeof (*t)); - t->component = g_object_ref (component); + t->shell_module = g_object_ref (shell_module); t->target.mask = ~flags; return t; @@ -107,13 +107,13 @@ e_cal_event_target_new_component (ECalEvent *ece, struct _CalendarComponent *com static void *eceh_parent_class; -static const EEventHookTargetMask eceh_component_masks[] = { - { "migration", E_CAL_EVENT_COMPONENT_MIGRATION }, +static const EEventHookTargetMask eceh_module_masks[] = { + { "migration", E_CAL_EVENT_MODULE_MIGRATION }, { NULL }, }; static const EEventHookTargetMap eceh_targets[] = { - { "component", E_CAL_EVENT_TARGET_COMPONENT, eceh_component_masks }, + { "module", E_CAL_EVENT_TARGET_MODULE, eceh_module_masks }, { NULL }, }; diff --git a/calendar/gui/e-cal-event.h b/calendar/gui/e-cal-event.h index 4fbaa394ec..6aade251aa 100644 --- a/calendar/gui/e-cal-event.h +++ b/calendar/gui/e-cal-event.h @@ -27,6 +27,7 @@ #include <glib-object.h> #include "e-util/e-event.h" +#include "shell/e-shell-module.h" #ifdef __cplusplus extern "C" { @@ -37,20 +38,19 @@ typedef struct _ECalEvent ECalEvent; typedef struct _ECalEventClass ECalEventClass; enum _e_cal_event_target_t { - E_CAL_EVENT_TARGET_COMPONENT, + E_CAL_EVENT_TARGET_MODULE, }; -/* Flags that describe TARGET_COMPONENT */ +/* Flags that describe TARGET_MODULE */ enum { - E_CAL_EVENT_COMPONENT_MIGRATION = 1 << 0, + E_CAL_EVENT_MODULE_MIGRATION = 1 << 0, }; -typedef struct _ECalEventTargetComponent ECalEventTargetComponent; +typedef struct _ECalEventTargetModule ECalEventTargetModule; -struct _ECalEventTargetComponent { +struct _ECalEventTargetModule { EEventTarget target; - - struct _CalendarComponent *component; + EShellModule *shell_module; }; struct _ECalEvent { @@ -65,7 +65,7 @@ struct _ECalEventClass { GType e_cal_event_get_type (void); ECalEvent* e_cal_event_peek (void); -ECalEventTargetComponent* e_cal_event_target_new_component (ECalEvent *ece, struct _CalendarComponent *component, guint32 flags); +ECalEventTargetModule* e_cal_event_target_new_module (ECalEvent *ece, EShellModule *shell_module, guint32 flags); /* ********************************************************************** */ diff --git a/calendar/gui/e-cal-list-view.c b/calendar/gui/e-cal-list-view.c index 0702d3a297..6c71d1c8c7 100644 --- a/calendar/gui/e-cal-list-view.c +++ b/calendar/gui/e-cal-list-view.c @@ -56,7 +56,6 @@ #include "dialogs/recur-comp.h" #include "comp-util.h" #include "itip-utils.h" -#include "calendar-commands.h" #include "calendar-config.h" #include "goto.h" #include "misc.h" @@ -358,10 +357,12 @@ e_cal_list_view_destroy (GtkObject *object) static void e_cal_list_view_show_popup_menu (ECalListView *cal_list_view, gint row, GdkEvent *gdk_event) { +#if 0 /* KILL-BONOBO */ GtkMenu *menu; menu = e_calendar_view_create_popup_menu (E_CALENDAR_VIEW (cal_list_view)); gtk_menu_popup(menu, NULL, NULL, NULL, NULL, gdk_event?gdk_event->button.button:0, gdk_event?gdk_event->button.time:gtk_get_current_event_time()); +#endif } static gboolean diff --git a/calendar/gui/e-cal-model-memos.c b/calendar/gui/e-cal-model-memos.c index ffb1c8a488..07df7c7460 100644 --- a/calendar/gui/e-cal-model-memos.c +++ b/calendar/gui/e-cal-model-memos.c @@ -261,7 +261,7 @@ ecmm_fill_component_from_model (ECalModel *model, ECalModelComponent *comp_data, /** * e_cal_model_memos_new */ -ECalModelMemos * +ECalModel * e_cal_model_memos_new (void) { return g_object_new (E_TYPE_CAL_MODEL_MEMOS, NULL); diff --git a/calendar/gui/e-cal-model-memos.h b/calendar/gui/e-cal-model-memos.h index 5417c9c09b..d02e51c9f7 100644 --- a/calendar/gui/e-cal-model-memos.h +++ b/calendar/gui/e-cal-model-memos.h @@ -55,8 +55,8 @@ typedef struct { ECalModelClass parent_class; } ECalModelMemosClass; -GType e_cal_model_memos_get_type (void); -ECalModelMemos *e_cal_model_memos_new (void); +GType e_cal_model_memos_get_type (void); +ECalModel * e_cal_model_memos_new (void); G_END_DECLS diff --git a/calendar/gui/e-cal-model-tasks.c b/calendar/gui/e-cal-model-tasks.c index 095cfabc4b..e4d7304c25 100644 --- a/calendar/gui/e-cal-model-tasks.c +++ b/calendar/gui/e-cal-model-tasks.c @@ -1108,7 +1108,7 @@ ecmt_fill_component_from_model (ECalModel *model, ECalModelComponent *comp_data, /** * e_cal_model_tasks_new */ -ECalModelTasks * +ECalModel * e_cal_model_tasks_new (void) { return g_object_new (E_TYPE_CAL_MODEL_TASKS, NULL); diff --git a/calendar/gui/e-cal-model-tasks.h b/calendar/gui/e-cal-model-tasks.h index 40d651e583..c71b737724 100644 --- a/calendar/gui/e-cal-model-tasks.h +++ b/calendar/gui/e-cal-model-tasks.h @@ -64,7 +64,7 @@ typedef struct { } ECalModelTasksClass; GType e_cal_model_tasks_get_type (void); -ECalModelTasks *e_cal_model_tasks_new (void); +ECalModel * e_cal_model_tasks_new (void); void e_cal_model_tasks_mark_comp_complete (ECalModelTasks *model, ECalModelComponent *comp_data); void e_cal_model_tasks_mark_comp_incomplete (ECalModelTasks *model, ECalModelComponent *comp_data); diff --git a/calendar/gui/e-cal-model.c b/calendar/gui/e-cal-model.c index 20306b7128..c437b44dd7 100644 --- a/calendar/gui/e-cal-model.c +++ b/calendar/gui/e-cal-model.c @@ -35,8 +35,8 @@ #include "e-cal-model.h" #include "itip-utils.h" #include "misc.h" -#include "e-util/e-util.h" #include "calendar-config.h" +#include "e-util/e-util.h" typedef struct { ECal *client; diff --git a/calendar/gui/e-calendar-selector.c b/calendar/gui/e-calendar-selector.c new file mode 100644 index 0000000000..54858e56f9 --- /dev/null +++ b/calendar/gui/e-calendar-selector.c @@ -0,0 +1,226 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-calendar-selector.c + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "e-calendar-selector.h" + +#include <libecal/e-cal.h> +#include "common/authentication.h" + +#define E_CALENDAR_SELECTOR_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_CALENDAR_SELECTOR, ECalendarSelectorPrivate)) + +struct _ECalendarSelectorPrivate { + gint dummy_value; +}; + +enum { + DND_TARGET_TYPE_CALENDAR_LIST +}; + +static GtkTargetEntry drag_types[] = { + { "text/calendar", 0, DND_TARGET_TYPE_CALENDAR_LIST }, + { "text/x-calendar", 0, DND_TARGET_TYPE_CALENDAR_LIST } +}; + +static gpointer parent_class; + +static gboolean +calendar_selector_update_single_object (ECal *client, + icalcomponent *icalcomp) +{ + gchar *uid; + icalcomponent *tmp_icalcomp; + + uid = (gchar *) icalcomponent_get_uid (icalcomp); + + if (e_cal_get_object (client, uid, NULL, &tmp_icalcomp, NULL)) + return e_cal_modify_object ( + client, icalcomp, CALOBJ_MOD_ALL, NULL); + + return e_cal_create_object (client, icalcomp, &uid, NULL); +} + +static gboolean +calendar_selector_update_objects (ECal *client, + icalcomponent *icalcomp) +{ + icalcomponent *subcomp; + icalcomponent_kind kind; + + kind = icalcomponent_isa (icalcomp); + if (kind == ICAL_VTODO_COMPONENT || kind == ICAL_VEVENT_COMPONENT) + return calendar_selector_update_single_object ( + client, icalcomp); + else if (kind != ICAL_VCALENDAR_COMPONENT) + return FALSE; + + subcomp = icalcomponent_get_first_component ( + icalcomp, ICAL_ANY_COMPONENT); + while (subcomp != NULL) { + gboolean success; + + kind = icalcomponent_isa (subcomp); + if (kind == ICAL_VTIMEZONE_COMPONENT) { + icaltimezone *zone; + + zone = icaltimezone_new (); + icaltimezone_set_component (zone, subcomp); + + success = e_cal_add_timezone (client, zone, NULL); + icaltimezone_free (zone, 1); + if (!success) + return FALSE; + } else if (kind == ICAL_VTODO_COMPONENT || + kind == ICAL_VEVENT_COMPONENT) { + success = calendar_selector_update_single_object ( + client, subcomp); + if (!success) + return FALSE; + } + + subcomp = icalcomponent_get_next_component ( + icalcomp, ICAL_ANY_COMPONENT); + } + + return TRUE; +} + +static gboolean +calendar_selector_data_dropped (ESourceSelector *selector, + GtkSelectionData *selection_data, + ESource *destination, + GdkDragAction action, + guint info) +{ + GtkTreeView *tree_view; + GtkTreeModel *model; + GtkTreePath *path = NULL; + ECal *client; + icalcomponent *icalcomp; + const gchar *string; + gboolean remove_from_source; + gboolean success = FALSE; + gpointer object = NULL; + + tree_view = GTK_TREE_VIEW (selector); + model = gtk_tree_view_get_model (tree_view); + + string = (const gchar *) selection_data->data; + remove_from_source = (action == GDK_ACTION_MOVE); + + icalcomp = icalparser_parse_string (string); + + if (icalcomp == NULL) + goto exit; + + /* FIXME Deal with GDK_ACTION_ASK. */ + if (action == GDK_ACTION_COPY) { + gchar *uid; + + uid = e_cal_component_gen_uid (); + icalcomponent_set_uid (icalcomp, uid); + } + + client = auth_new_cal_from_source ( + destination, E_CAL_SOURCE_TYPE_EVENT); + + if (client != NULL) { + if (e_cal_open (client, TRUE, NULL)) { + success = TRUE; + calendar_selector_update_objects (client, icalcomp); + } + + g_object_unref (client); + } + + icalcomponent_free (icalcomp); + + success = TRUE; + +exit: + if (path != NULL) + gtk_tree_path_free (path); + + if (object != NULL) + g_object_unref (object); + + return TRUE; +} + +static void +calendar_selector_class_init (ECalendarSelectorClass *class) +{ + ESourceSelectorClass *source_selector_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (ECalendarSelectorPrivate)); + + source_selector_class = E_SOURCE_SELECTOR_CLASS (class); + source_selector_class->data_dropped = calendar_selector_data_dropped; +} + +static void +calendar_selector_init (ECalendarSelector *selector) +{ + selector->priv = E_CALENDAR_SELECTOR_GET_PRIVATE (selector); + + gtk_drag_dest_set ( + GTK_WIDGET (selector), GTK_DEST_DEFAULT_ALL, + drag_types, G_N_ELEMENTS (drag_types), + GDK_ACTION_COPY | GDK_ACTION_MOVE); +} + +GType +e_calendar_selector_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + const GTypeInfo type_info = { + sizeof (ECalendarSelectorClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) calendar_selector_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (ECalendarSelector), + 0, /* n_preallocs */ + (GInstanceInitFunc) calendar_selector_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + E_TYPE_SOURCE_SELECTOR, "ECalendarSelector", + &type_info, 0); + } + + return type; +} + +GtkWidget * +e_calendar_selector_new (ESourceList *source_list) +{ + g_return_val_if_fail (E_IS_SOURCE_LIST (source_list), NULL); + + return g_object_new ( + E_TYPE_CALENDAR_SELECTOR, + "source-list", source_list, NULL); +} diff --git a/calendar/gui/e-calendar-selector.h b/calendar/gui/e-calendar-selector.h new file mode 100644 index 0000000000..65d9a2fc81 --- /dev/null +++ b/calendar/gui/e-calendar-selector.h @@ -0,0 +1,66 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-calendar-selector.h + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef E_CALENDAR_SELECTOR_H +#define E_CALENDAR_SELECTOR_H + +#include <libedataserver/e-source-list.h> +#include <libedataserverui/e-source-selector.h> + +/* Standard GObject macros */ +#define E_TYPE_CALENDAR_SELECTOR \ + (e_calendar_selector_get_type ()) +#define E_CALENDAR_SELECTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_CALENDAR_SELECTOR, ECalendarSelector)) +#define E_CALENDAR_SELECTOR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_CALENDAR_SELECTOR, ECalendarSelectorClass)) +#define E_IS_CALENDAR_SELECTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_CALENDAR_SELECTOR)) +#define E_IS_CALENDAR_SELECTOR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_CALENDAR_SELECTOR)) +#define E_CALENDAR_SELECTOR_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_CALENDAR_SELECTOR, ECalendarSelectorClass)) + +G_BEGIN_DECLS + +typedef struct _ECalendarSelector ECalendarSelector; +typedef struct _ECalendarSelectorClass ECalendarSelectorClass; +typedef struct _ECalendarSelectorPrivate ECalendarSelectorPrivate; + +struct _ECalendarSelector { + ESourceSelector parent; + ECalendarSelectorPrivate *priv; +}; + +struct _ECalendarSelectorClass { + ESourceSelectorClass parent_class; +}; + +GType e_calendar_selector_get_type (void); +GtkWidget * e_calendar_selector_new (ESourceList *source_list); + +G_END_DECLS + +#endif /* E_CALENDAR_SELECTOR_H */ diff --git a/calendar/gui/e-calendar-table-config.c b/calendar/gui/e-calendar-table-config.c index f8a7af9c14..6e43886dbd 100644 --- a/calendar/gui/e-calendar-table-config.c +++ b/calendar/gui/e-calendar-table-config.c @@ -24,221 +24,245 @@ #include "e-cell-date-edit-config.h" #include "e-calendar-table-config.h" +#define E_CALENDAR_TABLE_CONFIG_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_CALENDAR_TABLE_CONFIG, ECalendarTableConfigPrivate)) + struct _ECalendarTableConfigPrivate { ECalendarTable *table; - ECellDateEditConfig *cell_config; - GList *notifications; }; -/* Property IDs */ -enum props { +enum { PROP_0, PROP_TABLE }; -G_DEFINE_TYPE (ECalendarTableConfig, e_calendar_table_config, G_TYPE_OBJECT) +static gpointer parent_class; static void -e_calendar_table_config_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +calendar_table_config_set_timezone (ECalendarTable *table) { - ECalendarTableConfig *table_config; - - table_config = E_CALENDAR_TABLE_CONFIG (object); + ECalModel *model; + icaltimezone *zone; - switch (property_id) { - case PROP_TABLE: - e_calendar_table_config_set_table (table_config, g_value_get_object (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } + zone = calendar_config_get_icaltimezone (); + model = e_calendar_table_get_model (table); + if (model != NULL) + e_cal_model_set_timezone (model, zone); } static void -e_calendar_table_config_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +calendar_table_config_timezone_changed_cb (GConfClient *client, + guint id, + GConfEntry *entry, + gpointer data) { - ECalendarTableConfig *table_config; - - table_config = E_CALENDAR_TABLE_CONFIG (object); + ECalendarTableConfig *table_config = data; - switch (property_id) { - case PROP_TABLE: - g_value_set_object (value, e_calendar_table_config_get_table (table_config)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } + calendar_table_config_set_timezone (table_config->priv->table); } static void -e_calendar_table_config_dispose (GObject *object) +calendar_table_config_set_twentyfour_hour (ECalendarTable *table) { - ECalendarTableConfig *table_config = E_CALENDAR_TABLE_CONFIG (object); + ECalModel *model; + gboolean use_24_hour; - e_calendar_table_config_set_table (table_config, NULL); + use_24_hour = calendar_config_get_24_hour_format (); - if (G_OBJECT_CLASS (e_calendar_table_config_parent_class)->dispose) - G_OBJECT_CLASS (e_calendar_table_config_parent_class)->dispose (object); + model = e_calendar_table_get_model (table); + if (model != NULL) + e_cal_model_set_use_24_hour_format (model, use_24_hour); } static void -e_calendar_table_config_finalize (GObject *object) +calendar_table_config_twentyfour_hour_changed_cb (GConfClient *client, + guint id, + GConfEntry *entry, + gpointer data) { - ECalendarTableConfig *table_config = E_CALENDAR_TABLE_CONFIG (object); - ECalendarTableConfigPrivate *priv; - - priv = table_config->priv; - - g_free (priv); + ECalendarTableConfig *table_config = data; - if (G_OBJECT_CLASS (e_calendar_table_config_parent_class)->finalize) - G_OBJECT_CLASS (e_calendar_table_config_parent_class)->finalize (object); + calendar_table_config_set_twentyfour_hour (table_config->priv->table); } static void -e_calendar_table_config_class_init (ECalendarTableConfigClass *klass) +calendar_table_config_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GParamSpec *spec; - - /* Method override */ - gobject_class->set_property = e_calendar_table_config_set_property; - gobject_class->get_property = e_calendar_table_config_get_property; - gobject_class->dispose = e_calendar_table_config_dispose; - gobject_class->finalize = e_calendar_table_config_finalize; - - spec = g_param_spec_object ("table", NULL, NULL, e_calendar_table_get_type (), - G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT); - g_object_class_install_property (gobject_class, PROP_TABLE, spec); + switch (property_id) { + case PROP_TABLE: + e_calendar_table_config_set_table ( + E_CALENDAR_TABLE_CONFIG (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } static void -e_calendar_table_config_init (ECalendarTableConfig *table_config) +calendar_table_config_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) { - table_config->priv = g_new0 (ECalendarTableConfigPrivate, 1); + switch (property_id) { + case PROP_TABLE: + g_value_set_object ( + value, e_calendar_table_config_get_table ( + E_CALENDAR_TABLE_CONFIG (object))); + return; + } + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } -ECalendarTableConfig * -e_calendar_table_config_new (ECalendarTable *table) +static void +calendar_table_config_dispose (GObject *object) { - ECalendarTableConfig *table_config; + ECalendarTableConfig *table_config = E_CALENDAR_TABLE_CONFIG (object); - table_config = g_object_new (e_calendar_table_config_get_type (), "table", table, NULL); + e_calendar_table_config_set_table (table_config, NULL); - return table_config; + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); } -ECalendarTable * -e_calendar_table_config_get_table (ECalendarTableConfig *table_config) +static void +calendar_table_config_class_init (ECalendarTableConfigClass *class) { - ECalendarTableConfigPrivate *priv; - - g_return_val_if_fail (table_config != NULL, NULL); - g_return_val_if_fail (E_IS_CALENDAR_TABLE_CONFIG (table_config), NULL); - - priv = table_config->priv; - - return priv->table; + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (ECalendarTableConfigPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = calendar_table_config_set_property; + object_class->get_property = calendar_table_config_get_property; + object_class->dispose = calendar_table_config_dispose; + + g_object_class_install_property ( + object_class, + PROP_TABLE, + g_param_spec_object ( + "table", + NULL, + NULL, + E_TYPE_CALENDAR_TABLE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); } static void -set_timezone (ECalendarTable *table) +calendar_table_config_init (ECalendarTableConfig *table_config) { - ECalModel *model; - icaltimezone *zone; - - zone = calendar_config_get_icaltimezone (); - model = e_calendar_table_get_model (table); - if (model) - e_cal_model_set_timezone (model, zone); + table_config->priv = + E_CALENDAR_TABLE_CONFIG_GET_PRIVATE (table_config); } -static void -timezone_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) +GType +e_calendar_table_config_get_type (void) { - ECalendarTableConfig *table_config = data; - ECalendarTableConfigPrivate *priv; - - priv = table_config->priv; + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (ECalendarTableConfigClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) calendar_table_config_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (ECalendarTableConfig), + 0, /* n_preallocs */ + (GInstanceInitFunc) calendar_table_config_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + G_TYPE_OBJECT, "ECalendarTableConfig", &type_info, 0); + } - set_timezone (priv->table); + return type; } -static void -set_twentyfour_hour (ECalendarTable *table) +ECalendarTableConfig * +e_calendar_table_config_new (ECalendarTable *table) { - ECalModel *model; - gboolean use_24_hour; + g_return_val_if_fail (E_IS_CALENDAR_TABLE (table), NULL); - use_24_hour = calendar_config_get_24_hour_format (); - - model = e_calendar_table_get_model (table); - if (model) - e_cal_model_set_use_24_hour_format (model, use_24_hour); + return g_object_new ( + E_TYPE_CALENDAR_TABLE_CONFIG, + "table", table, NULL); } -static void -twentyfour_hour_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) +ECalendarTable * +e_calendar_table_config_get_table (ECalendarTableConfig *table_config) { - ECalendarTableConfig *table_config = data; - ECalendarTableConfigPrivate *priv; - - priv = table_config->priv; + g_return_val_if_fail (E_IS_CALENDAR_TABLE_CONFIG (table_config), NULL); - set_twentyfour_hour (priv->table); + return table_config->priv->table; } void -e_calendar_table_config_set_table (ECalendarTableConfig *table_config, ECalendarTable *table) +e_calendar_table_config_set_table (ECalendarTableConfig *table_config, + ECalendarTable *table) { ECalendarTableConfigPrivate *priv; - guint not; - GList *l; + guint notification; + GList *list, *iter; - g_return_if_fail (table_config != NULL); g_return_if_fail (E_IS_CALENDAR_TABLE_CONFIG (table_config)); priv = table_config->priv; - if (priv->table) { - g_object_unref (priv->table); - priv->table = NULL; + if (table_config->priv->table) { + g_object_unref (table_config->priv->table); + table_config->priv->table = NULL; } - if (priv->cell_config) { - g_object_unref (priv->cell_config); - priv->cell_config = NULL; + if (table_config->priv->cell_config) { + g_object_unref (table_config->priv->cell_config); + table_config->priv->cell_config = NULL; } - for (l = priv->notifications; l; l = l->next) - calendar_config_remove_notification (GPOINTER_TO_UINT (l->data)); - - g_list_free (priv->notifications); - priv->notifications = NULL; + list = table_config->priv->notifications; + for (iter = list; iter != NULL; iter = iter->next) { + notification = GPOINTER_TO_UINT (iter->data); + calendar_config_remove_notification (notification); + } + g_list_free (list); + table_config->priv->notifications = NULL; - /* If the new view is NULL, return right now */ - if (!table) + if (table == NULL) return; - priv->table = g_object_ref (table); + table_config->priv->table = g_object_ref (table); /* Time zone */ - set_timezone (table); + calendar_table_config_set_timezone (table); - not = calendar_config_add_notification_timezone (timezone_changed_cb, table_config); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); + notification = calendar_config_add_notification_timezone ( + calendar_table_config_timezone_changed_cb, table_config); + table_config->priv->notifications = g_list_prepend ( + table_config->priv->notifications, + GUINT_TO_POINTER (notification)); /* 24 Hour format */ - set_twentyfour_hour (table); + calendar_table_config_set_twentyfour_hour (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)); + notification = calendar_config_add_notification_24_hour_format ( + calendar_table_config_twentyfour_hour_changed_cb, table_config); + table_config->priv->notifications = g_list_prepend ( + table_config->priv->notifications, + GUINT_TO_POINTER (notification)); /* Date cell */ - priv->cell_config = e_cell_date_edit_config_new (table->dates_cell); + table_config->priv->cell_config = + e_cell_date_edit_config_new (table->dates_cell); } diff --git a/calendar/gui/e-calendar-table-config.h b/calendar/gui/e-calendar-table-config.h index 12cbc3e326..8f2284ab40 100644 --- a/calendar/gui/e-calendar-table-config.h +++ b/calendar/gui/e-calendar-table-config.h @@ -21,24 +21,38 @@ * */ -#ifndef _E_CALENDAR_TABLE_CONFIG_H_ -#define _E_CALENDAR_TABLE_CONFIG_H_ +#ifndef E_CALENDAR_TABLE_CONFIG_H +#define E_CALENDAR_TABLE_CONFIG_H #include "e-calendar-table.h" -G_BEGIN_DECLS +/* Standard GObject macros */ +#define E_TYPE_CALENDAR_TABLE_CONFIG \ + (e_calendar_table_config_get_type ()) +#define E_CALENDAR_TABLE_CONFIG(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_CALENDAR_TABLE_CONFIG, ECalendarTableConfig)) +#define E_CALENDAR_TABLE_CONFIG_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_CALENDAR_TABLE_CONFIG, ECalendarTableConfigClass)) +#define E_IS_CALENDAR_TABLE_CONFIG(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_CALENDAR_TABLE_CONFIG)) +#define E_IS_CALENDAR_TABLE_CONFIG_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_CALENDAR_TABLE_CONFIG)) +#define E_CALENDAR_TABLE_CONFIG_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_CALENDAR_TABLE_CONFIG, ECalendarTableConfigClass)) -#define E_CALENDAR_TABLE_CONFIG(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, e_calendar_table_config_get_type (), ECalendarTableConfig) -#define E_CALENDAR_TABLE_CONFIG_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, e_calendar_table_config_get_type (), ECalendarTableConfigClass) -#define E_IS_CALENDAR_TABLE_CONFIG(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, e_calendar_table_config_get_type ()) +G_BEGIN_DECLS -typedef struct _ECalendarTableConfig ECalendarTableConfig; -typedef struct _ECalendarTableConfigClass ECalendarTableConfigClass; +typedef struct _ECalendarTableConfig ECalendarTableConfig; +typedef struct _ECalendarTableConfigClass ECalendarTableConfigClass; typedef struct _ECalendarTableConfigPrivate ECalendarTableConfigPrivate; struct _ECalendarTableConfig { GObject parent; - ECalendarTableConfigPrivate *priv; }; @@ -46,11 +60,15 @@ struct _ECalendarTableConfigClass { GObjectClass parent_class; }; -GType e_calendar_table_config_get_type (void); -ECalendarTableConfig *e_calendar_table_config_new (ECalendarTable *table); -ECalendarTable *e_calendar_table_config_get_table (ECalendarTableConfig *view_config); -void e_calendar_table_config_set_table (ECalendarTableConfig *view_config, ECalendarTable *table); +GType e_calendar_table_config_get_type(void); +ECalendarTableConfig * + e_calendar_table_config_new (ECalendarTable *table); +ECalendarTable *e_calendar_table_config_get_table + (ECalendarTableConfig *table_config); +void e_calendar_table_config_set_table + (ECalendarTableConfig *table_config, + ECalendarTable *table); G_END_DECLS -#endif +#endif /* E_CALENDAR_TABLE_CONFIG_H */ diff --git a/calendar/gui/e-calendar-table.c b/calendar/gui/e-calendar-table.c index ddf96d00f2..a4320273ac 100644 --- a/calendar/gui/e-calendar-table.c +++ b/calendar/gui/e-calendar-table.c @@ -32,7 +32,6 @@ #include <sys/stat.h> #include <unistd.h> -#include <glib.h> #include <glib/gi18n.h> #include <glib/gstdio.h> #include <gtk/gtk.h> @@ -44,12 +43,11 @@ #include <table/e-cell-combo.h> #include <e-util/e-dialog-utils.h> #include <e-util/e-util-private.h> -#include <misc/e-cell-date-edit.h> -#include <misc/e-cell-percent.h> +#include <widgets/misc/e-cell-date-edit.h> +#include <widgets/misc/e-cell-percent.h> #include <libecal/e-cal-time-util.h> #include <libedataserver/e-time-utils.h> -#include "calendar-component.h" #include "calendar-config.h" #include "dialogs/delete-comp.h" #include "dialogs/delete-error.h" @@ -58,67 +56,50 @@ #include "e-calendar-table.h" #include "e-calendar-view.h" #include "e-cell-date-edit-text.h" -#include "e-comp-editor-registry.h" #include "print.h" #include <e-util/e-icon-factory.h> #include "e-cal-popup.h" -#include "e-tasks.h" #include "misc.h" -enum TargetType{ - TARGET_TYPE_VCALENDAR -}; +#define E_CALENDAR_TABLE_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_CALENDAR_TABLE, ECalendarTablePrivate)) -static GtkTargetEntry target_types[] = { - { "text/x-calendar", 0, TARGET_TYPE_VCALENDAR }, - { "text/calendar", 0, TARGET_TYPE_VCALENDAR } +struct _ECalendarTablePrivate { + gpointer shell_view; /* weak pointer */ + ECalModel *model; }; -static guint n_target_types = G_N_ELEMENTS (target_types); +enum { + PROP_0, + PROP_MODEL, + PROP_SHELL_VIEW +}; -extern ECompEditorRegistry *comp_editor_registry; - -static void e_calendar_table_class_init (ECalendarTableClass *class); -static void e_calendar_table_init (ECalendarTable *cal_table); -static void e_calendar_table_destroy (GtkObject *object); - -static void e_calendar_table_on_double_click (ETable *table, - gint row, - gint col, - GdkEvent *event, - ECalendarTable *cal_table); -static gint e_calendar_table_show_popup_menu (ETable *table, - GdkEvent *gdk_event, - ECalendarTable *cal_table); - -static gint e_calendar_table_on_right_click (ETable *table, - gint row, - gint col, - GdkEvent *event, - ECalendarTable *cal_table); -static gboolean e_calendar_table_on_popup_menu (GtkWidget *widget, - gpointer data); - -static gint e_calendar_table_on_key_press (ETable *table, - gint row, - gint col, - GdkEventKey *event, - ECalendarTable *cal_table); - -static struct tm e_calendar_table_get_current_time (ECellDateEdit *ecde, - gpointer data); -static void mark_as_complete_cb (EPopup *ep, EPopupItem *pitem, void *data); - -static void hide_completed_rows (ECalModel *model, GList *clients_list, char *hide_sexp, GPtrArray *comp_objects); -static void show_completed_rows (ECalModel *model, GList *clients_list, char *show_sexp, GPtrArray *comp_objects); - -/* Signal IDs */ enum { + OPEN_COMPONENT, + POPUP_EVENT, + STATUS_MESSAGE, USER_CREATED, LAST_SIGNAL }; -static guint signals[LAST_SIGNAL] = { 0 }; +enum { + TARGET_TYPE_VCALENDAR +}; + +static GtkTargetEntry target_types[] = { + { "text/calendar", 0, TARGET_TYPE_VCALENDAR }, + { "text/x-calendar", 0, TARGET_TYPE_VCALENDAR } +}; + +static guint n_target_types = G_N_ELEMENTS (target_types); + +static struct tm e_calendar_table_get_current_time (ECellDateEdit *ecde, gpointer data); + +static gpointer parent_class; +static guint signals[LAST_SIGNAL]; +static GdkAtom clipboard_atom; /* The icons to represent the task. */ #define E_CALENDAR_MODEL_NUM_ICONS 4 @@ -127,36 +108,45 @@ static const char* icon_names[E_CALENDAR_MODEL_NUM_ICONS] = { }; static GdkPixbuf* icon_pixbufs[E_CALENDAR_MODEL_NUM_ICONS] = { NULL }; -static GdkAtom clipboard_atom = GDK_NONE; +static void +calendar_table_emit_open_component (ECalendarTable *cal_table, + ECalModelComponent *comp_data) +{ + guint signal_id = signals[OPEN_COMPONENT]; -G_DEFINE_TYPE (ECalendarTable, e_calendar_table, GTK_TYPE_TABLE) + g_signal_emit (cal_table, signal_id, 0, comp_data); +} static void -e_calendar_table_class_init (ECalendarTableClass *class) +calendar_table_emit_popup_event (ECalendarTable *cal_table, + GdkEvent *event) { - GtkObjectClass *object_class; + guint signal_id = signals[POPUP_EVENT]; - object_class = (GtkObjectClass *) class; + g_signal_emit (cal_table, signal_id, 0, event); +} + +static void +calendar_table_emit_status_message (ECalendarTable *cal_table, + const gchar *message, + gdouble percent) +{ + guint signal_id = signals[STATUS_MESSAGE]; - /* Method override */ - object_class->destroy = e_calendar_table_destroy; + g_signal_emit (cal_table, signal_id, 0, message, percent); +} - signals[USER_CREATED] = - g_signal_new ("user_created", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ECalendarTableClass, user_created), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); +static void +calendar_table_emit_user_created (ECalendarTable *cal_table) +{ + guint signal_id = signals[USER_CREATED]; - /* clipboard atom */ - if (!clipboard_atom) - clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE); + g_signal_emit (cal_table, signal_id, 0); } static gint -date_compare_cb (gconstpointer a, gconstpointer b) +calendar_table_date_compare_cb (gconstpointer a, + gconstpointer b) { ECellDateEditValue *dv1 = (ECellDateEditValue *) a; ECellDateEditValue *dv2 = (ECellDateEditValue *) b; @@ -184,24 +174,18 @@ date_compare_cb (gconstpointer a, gconstpointer b) } static gint -percent_compare_cb (gconstpointer a, gconstpointer b) +calendar_table_percent_compare_cb (gconstpointer a, + gconstpointer b) { int percent1 = GPOINTER_TO_INT (a); int percent2 = GPOINTER_TO_INT (b); - int retval; - - if (percent1 > percent2) - retval = 1; - else if (percent1 < percent2) - retval = -1; - else - retval = 0; - return retval; + return (percent1 < percent2) ? -1 : (percent1 > percent2); } static gint -priority_compare_cb (gconstpointer a, gconstpointer b) +calendar_table_priority_compare_cb (gconstpointer a, + gconstpointer b) { int priority1, priority2; @@ -215,71 +199,85 @@ priority_compare_cb (gconstpointer a, gconstpointer b) priority2 = 10; /* We'll just use the ordering of the priority values. */ - if (priority1 < priority2) - return -1; - else if (priority1 > priority2) - return 1; - else - return 0; + return (priority1 < priority2) ? -1 : (priority1 > priority2); } static gint -status_from_string (const char *str) -{ - int status = -2; - - if (!str || !str[0]) - status = -1; - else if (!g_utf8_collate (str, _("Not Started"))) - status = 0; - else if (!g_utf8_collate (str, _("In Progress"))) - status = 1; - else if (!g_utf8_collate (str, _("Completed"))) - status = 2; - else if (!g_utf8_collate (str, _("Canceled"))) - status = 3; - - return status; +calendar_table_status_compare_cb (gconstpointer a, + gconstpointer b) +{ + const gchar *string_a = a; + const gchar *string_b = b; + gint status_a = -2; + gint status_b = -2; + + if (string_a == NULL || *string_a == '\0') + status_a = -1; + else if (!g_utf8_collate (string_a, _("Not Started"))) + status_a = 0; + else if (!g_utf8_collate (string_a, _("In Progress"))) + status_a = 1; + else if (!g_utf8_collate (string_a, _("Completed"))) + status_a = 2; + else if (!g_utf8_collate (string_a, _("Canceled"))) + status_a = 3; + + if (string_b == NULL || *string_b == '\0') + status_b = -1; + else if (!g_utf8_collate (string_b, _("Not Started"))) + status_b = 0; + else if (!g_utf8_collate (string_b, _("In Progress"))) + status_b = 1; + else if (!g_utf8_collate (string_b, _("Completed"))) + status_b = 2; + else if (!g_utf8_collate (string_b, _("Canceled"))) + status_b = 3; + + return (status_a < status_b) ? -1 : (status_a > status_b); } -static gint -status_compare_cb (gconstpointer a, gconstpointer b) +static void +calendar_table_double_click_cb (ECalendarTable *cal_table, + gint row, + gint col, + GdkEvent *event) { - int sa = status_from_string ((const char *)a); - int sb = status_from_string ((const char *)b); - - if (sa < sb) - return -1; - else if (sa > sb) - return 1; + ECalModel *model; + ECalModelComponent *comp_data; - return 0; + model = e_calendar_table_get_model (cal_table); + comp_data = e_cal_model_get_component_at (model, row); + calendar_table_emit_open_component (cal_table, comp_data); } static void -row_appended_cb (ECalModel *model, ECalendarTable *cal_table) +calendar_table_model_cal_view_progress_cb (ECalendarTable *cal_table, + const gchar *message, + gint progress, + ECalSourceType type) { - g_signal_emit (cal_table, signals[USER_CREATED], 0); + gdouble percent = (gdouble) progress; + + calendar_table_emit_status_message (cal_table, message, percent); } static void -get_time_as_text (struct icaltimetype *tt, icaltimezone *f_zone, icaltimezone *t_zone, char *buff, int buff_len) +calendar_table_model_cal_view_done_cb (ECalendarTable *cal_table, + ECalendarStatus status, + ECalSourceType type) { - struct tm tmp_tm; - - buff [0] = 0; - - tmp_tm = icaltimetype_to_tm_with_zone (tt, f_zone, t_zone); - e_time_format_date_and_time (&tmp_tm, - calendar_config_get_24_hour_format (), - FALSE, FALSE, - buff, buff_len); + calendar_table_emit_status_message (cal_table, NULL, -1.0); } -gboolean -ec_query_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, GtkWidget *etable_wgt, ECalModel *model) +static gboolean +calendar_table_query_tooltip_cb (ECalendarTable *cal_table, + gint x, + gint y, + gboolean keyboard_mode, + GtkTooltip *tooltip) { - ECalModelComponent *comp; + ECalModel *model; + ECalModelComponent *comp_data; int row = -1, col = -1; GtkWidget *box, *l, *w; GtkStyle *style = gtk_widget_get_default_style (); @@ -291,44 +289,44 @@ ec_query_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, Gtk ECalComponent *new_comp; ECalComponentOrganizer organizer; ECalComponentDateTime dtstart, dtdue; + icalcomponent *clone; icaltimezone *zone, *default_zone; GSList *desc, *p; int len; ETable *etable; ESelectionModel *esm; + struct tm tmp_tm; if (keyboard_mode) return FALSE; - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (tooltip != NULL, FALSE); - g_return_val_if_fail (E_IS_TABLE (etable_wgt), FALSE); - g_return_val_if_fail (E_IS_CAL_MODEL (model), FALSE); - - etable = E_TABLE (etable_wgt); - + etable = e_calendar_table_get_table (cal_table); e_table_get_mouse_over_cell (etable, &row, &col); if (row == -1 || !etable) return FALSE; - /* respect sorting option, the 'e_table_get_mouse_over_cell' returns sorted row, not the model one */ + /* Respect sorting option; the 'e_table_get_mouse_over_cell' + * returns sorted row, not the model one. */ esm = e_table_get_selection_model (etable); if (esm && esm->sorter && e_sorter_needs_sorting (esm->sorter)) row = e_sorter_sorted_to_model (esm->sorter, row); - comp = e_cal_model_get_component_at (model, row); - if (!comp || !comp->icalcomp) + model = e_calendar_table_get_model (cal_table); + comp_data = e_cal_model_get_component_at (model, row); + if (!comp_data || !comp_data->icalcomp) return FALSE; new_comp = e_cal_component_new (); - if (!e_cal_component_set_icalcomponent (new_comp, icalcomponent_new_clone (comp->icalcomp))) { + clone = icalcomponent_new_clone (comp_data->icalcomp); + if (!e_cal_component_set_icalcomponent (new_comp, clone)) { g_object_unref (new_comp); return FALSE; } box = gtk_vbox_new (FALSE, 0); - str = e_calendar_view_get_icalcomponent_summary (comp->client, comp->icalcomp, &free_text); + str = e_calendar_view_get_icalcomponent_summary ( + comp_data->client, comp_data->icalcomp, &free_text); if (!(str && *str)) { if (free_text) g_free ((char *)str); @@ -368,7 +366,7 @@ ec_query_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, Gtk if (ptr) { ptr++; - /* To Translators: It will display "Organiser: NameOfTheUser <email@ofuser.com>" */ + /* To Translators: It will display "Organizer: NameOfTheUser <email@ofuser.com>" */ tmp = g_strdup_printf (_("Organizer: %s <%s>"), organizer.cn, ptr); } else { /* With SunOne accounts, there may be no ':' in organiser.value */ @@ -385,12 +383,13 @@ ec_query_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, Gtk e_cal_component_get_dtstart (new_comp, &dtstart); e_cal_component_get_due (new_comp, &dtdue); - default_zone = e_cal_model_get_timezone (model); + default_zone = e_cal_model_get_timezone (model); if (dtstart.tzid) { zone = icalcomponent_get_timezone (e_cal_component_get_icalcomponent (new_comp), dtstart.tzid); if (!zone) - e_cal_get_timezone (comp->client, dtstart.tzid, &zone, NULL); + e_cal_get_timezone ( + comp_data->client, dtstart.tzid, &zone, NULL); if (!zone) zone = default_zone; } else { @@ -400,7 +399,13 @@ ec_query_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, Gtk tmp2 = g_string_new (""); if (dtstart.value) { - get_time_as_text (dtstart.value, zone, default_zone, buff, 1000); + buff[0] = 0; + + tmp_tm = icaltimetype_to_tm_with_zone ( + dtstart.value, zone, default_zone); + e_time_format_date_and_time ( + &tmp_tm, calendar_config_get_24_hour_format (), + FALSE, FALSE, buff, 1000); if (buff [0]) { g_string_append (tmp2, _("Start: ")); @@ -409,7 +414,13 @@ ec_query_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, Gtk } if (dtdue.value) { - get_time_as_text (dtdue.value, zone, default_zone, buff, 1000); + buff[0] = 0; + + tmp_tm = icaltimetype_to_tm_with_zone ( + dtdue.value, zone, default_zone); + e_time_format_date_and_time ( + &tmp_tm, calendar_config_get_24_hour_format (), + FALSE, FALSE, buff, 1000); if (buff [0]) { if (tmp2->len) @@ -431,7 +442,8 @@ ec_query_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, Gtk e_cal_component_free_datetime (&dtstart); e_cal_component_free_datetime (&dtdue); - tmp = e_calendar_view_get_attendees_status_info (new_comp, comp->client); + tmp = e_calendar_view_get_attendees_status_info ( + new_comp, comp_data->client); if (tmp) { l = gtk_label_new (tmp); gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5); @@ -476,46 +488,149 @@ ec_query_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, Gtk } static gboolean -query_tooltip_cb (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, gpointer user_data) +calendar_table_popup_menu_cb (ECalendarTable *cal_table) { - ECalendarTable *cal_table; + calendar_table_emit_popup_event (cal_table, NULL); + + return TRUE; +} + +static gint +calendar_table_right_click_cb (ECalendarTable *cal_table, + gint row, + gint col, + GdkEvent *event) +{ + calendar_table_emit_popup_event (cal_table, event); + + return TRUE; +} + +static void +calendar_table_set_model (ECalendarTable *cal_table, + ECalModel *model) +{ + g_return_if_fail (cal_table->priv->model == NULL); + + cal_table->priv->model = g_object_ref (model); + + g_signal_connect_swapped ( + model, "row_appended", + G_CALLBACK (calendar_table_emit_user_created), cal_table); + + g_signal_connect_swapped ( + model, "cal-view-progress", + G_CALLBACK (calendar_table_model_cal_view_progress_cb), + cal_table); + + g_signal_connect_swapped ( + model, "cal-view-done", + G_CALLBACK (calendar_table_model_cal_view_done_cb), + cal_table); +} + +static void +calendar_table_set_shell_view (ECalendarTable *cal_table, + EShellView *shell_view) +{ + g_return_if_fail (cal_table->priv->shell_view == NULL); + + cal_table->priv->shell_view = shell_view; + + g_object_add_weak_pointer ( + G_OBJECT (shell_view), + &cal_table->priv->shell_view); +} + +static void +calendar_table_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_MODEL: + calendar_table_set_model ( + E_CALENDAR_TABLE (object), + g_value_get_object (value)); + return; + + case PROP_SHELL_VIEW: + calendar_table_set_shell_view ( + E_CALENDAR_TABLE (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +calendar_table_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_MODEL: + g_value_set_object ( + value, e_calendar_table_get_model ( + E_CALENDAR_TABLE (object))); + return; + + case PROP_SHELL_VIEW: + g_value_set_object ( + value, e_calendar_table_get_shell_view ( + E_CALENDAR_TABLE (object))); + return; + } - g_return_val_if_fail (E_IS_CALENDAR_TABLE (user_data), FALSE); + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +calendar_table_dispose (GObject *object) +{ + ECalendarTablePrivate *priv; - cal_table = E_CALENDAR_TABLE (user_data); + priv = E_CALENDAR_TABLE_GET_PRIVATE (object); - return ec_query_tooltip (widget, x, y, keyboard_mode, tooltip, GTK_WIDGET (e_calendar_table_get_table (cal_table)), cal_table->model); + if (priv->model != NULL) { + g_object_unref (priv->model); + priv->model = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); } static void -e_calendar_table_init (ECalendarTable *cal_table) +calendar_table_constructed (GObject *object) { - GtkWidget *table; - ETable *e_table; + ECalendarTable *cal_table; + GtkWidget *widget; + ECalModel *model; + ETable *table; ECell *cell, *popup_cell; ETableExtras *extras; gint i; GdkPixbuf *pixbuf; GList *strings; AtkObject *a11y; - char *etspecfile; - - /* Create the model */ - - cal_table->model = (ECalModel *) e_cal_model_tasks_new (); - g_signal_connect (cal_table->model, "row_appended", G_CALLBACK (row_appended_cb), cal_table); + gchar *etspecfile; - cal_table->user_created_cal = NULL; + cal_table = E_CALENDAR_TABLE (object); + model = e_calendar_table_get_model (cal_table); /* Create the header columns */ - extras = e_table_extras_new(); + extras = e_table_extras_new (); /* * Normal string fields. */ cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT); - g_object_set (G_OBJECT (cell), + g_object_set (cell, "strikeout_column", E_CAL_MODEL_TASKS_FIELD_STRIKEOUT, "bold_column", E_CAL_MODEL_TASKS_FIELD_OVERDUE, "bg_color_column", E_CAL_MODEL_FIELD_COLOR, @@ -528,7 +643,7 @@ e_calendar_table_init (ECalendarTable *cal_table) * Date fields. */ cell = e_cell_date_edit_text_new (NULL, GTK_JUSTIFY_LEFT); - g_object_set (G_OBJECT (cell), + g_object_set (cell, "strikeout_column", E_CAL_MODEL_TASKS_FIELD_STRIKEOUT, "bold_column", E_CAL_MODEL_TASKS_FIELD_OVERDUE, "bg_color_column", E_CAL_MODEL_FIELD_COLOR, @@ -537,13 +652,13 @@ e_calendar_table_init (ECalendarTable *cal_table) 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); cal_table->dates_cell = E_CELL_DATE_EDIT (popup_cell); - e_cell_date_edit_set_get_time_callback (E_CELL_DATE_EDIT (popup_cell), - e_calendar_table_get_current_time, - cal_table, NULL); - + e_cell_date_edit_set_get_time_callback ( + E_CELL_DATE_EDIT (popup_cell), + e_calendar_table_get_current_time, cal_table, NULL); /* * Combo fields. @@ -551,7 +666,7 @@ e_calendar_table_init (ECalendarTable *cal_table) /* Classification field. */ cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT); - g_object_set (G_OBJECT (cell), + g_object_set (cell, "strikeout_column", E_CAL_MODEL_TASKS_FIELD_STRIKEOUT, "bold_column", E_CAL_MODEL_TASKS_FIELD_OVERDUE, "bg_color_column", E_CAL_MODEL_FIELD_COLOR, @@ -668,13 +783,13 @@ e_calendar_table_init (ECalendarTable *cal_table) e_table_extras_add_cell (extras, "calstatus", popup_cell); e_table_extras_add_compare (extras, "date-compare", - date_compare_cb); + calendar_table_date_compare_cb); e_table_extras_add_compare (extras, "percent-compare", - percent_compare_cb); + calendar_table_percent_compare_cb); e_table_extras_add_compare (extras, "priority-compare", - priority_compare_cb); + calendar_table_priority_compare_cb); e_table_extras_add_compare (extras, "status-compare", - status_compare_cb); + calendar_table_status_compare_cb); /* Create pixmaps */ @@ -693,55 +808,175 @@ e_calendar_table_init (ECalendarTable *cal_table) /* Create the table */ - etspecfile = g_build_filename (EVOLUTION_ETSPECDIR, - "e-calendar-table.etspec", - NULL); - table = e_table_scrolled_new_from_spec_file (E_TABLE_MODEL (cal_table->model), - extras, - etspecfile, - NULL); + etspecfile = g_build_filename ( + EVOLUTION_ETSPECDIR, "e-calendar-table.etspec", NULL); + widget = e_table_scrolled_new_from_spec_file ( + E_TABLE_MODEL (model), extras, etspecfile, NULL); + gtk_table_attach ( + GTK_TABLE (cal_table), widget, 0, 1, 0, 1, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + cal_table->etable = widget; + gtk_widget_show (widget); g_free (etspecfile); - /* FIXME: this causes a message from GLib about 'extras' having only a floating - reference */ - /* g_object_unref (extras); */ + table = e_table_scrolled_get_table (E_TABLE_SCROLLED (widget)); + g_signal_connect_swapped ( + table, "double-click", + G_CALLBACK (calendar_table_double_click_cb), cal_table); + g_signal_connect_swapped ( + table, "query-tooltip", + G_CALLBACK (calendar_table_query_tooltip_cb), cal_table); + g_signal_connect_swapped ( + table, "popup-menu", + G_CALLBACK (calendar_table_popup_menu_cb), cal_table); + g_signal_connect_swapped ( + table, "right-click", + G_CALLBACK (calendar_table_right_click_cb), cal_table); + gtk_widget_set_has_tooltip (GTK_WIDGET (table), TRUE); + + a11y = gtk_widget_get_accessible (GTK_WIDGET (table)); + if (a11y) + atk_object_set_name (a11y, _("Tasks")); +} - cal_table->etable = table; - gtk_table_attach (GTK_TABLE (cal_table), table, 0, 1, 0, 1, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - gtk_widget_show (table); +static void +calendar_table_class_init (ECalendarTableClass *class) +{ + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (ECalendarTablePrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = calendar_table_set_property; + object_class->get_property = calendar_table_get_property; + object_class->dispose = calendar_table_dispose; + object_class->constructed = calendar_table_constructed; + + g_object_class_install_property ( + object_class, + PROP_MODEL, + g_param_spec_object ( + "model", + _("Model"), + NULL, + E_TYPE_CAL_MODEL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property ( + object_class, + PROP_SHELL_VIEW, + g_param_spec_object ( + "shell-view", + _("Shell View"), + NULL, + E_TYPE_SHELL_VIEW, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + + signals[OPEN_COMPONENT] = g_signal_new ( + "open-component", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (ECalendarTableClass, open_component), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + E_TYPE_CAL_MODEL_COMPONENT); + + signals[POPUP_EVENT] = g_signal_new ( + "popup-event", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (ECalendarTableClass, popup_event), + NULL, NULL, + g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, 1, + GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); + + signals[STATUS_MESSAGE] = g_signal_new ( + "status-message", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (ECalendarTableClass, status_message), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, + G_TYPE_STRING); + + signals[USER_CREATED] = g_signal_new ( + "user-created", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (ECalendarTableClass, user_created), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE); +} +static void +calendar_table_init (ECalendarTable *cal_table) +{ + cal_table->priv = E_CALENDAR_TABLE_GET_PRIVATE (cal_table); +} - e_table = e_table_scrolled_get_table (E_TABLE_SCROLLED (table)); - g_signal_connect (e_table, "double_click", G_CALLBACK (e_calendar_table_on_double_click), cal_table); - g_signal_connect (e_table, "right_click", G_CALLBACK (e_calendar_table_on_right_click), cal_table); - g_signal_connect (e_table, "key_press", G_CALLBACK (e_calendar_table_on_key_press), cal_table); - g_signal_connect (e_table, "popup_menu", G_CALLBACK (e_calendar_table_on_popup_menu), cal_table); - g_signal_connect (e_table, "query-tooltip", G_CALLBACK (query_tooltip_cb), cal_table); - gtk_widget_set_has_tooltip (GTK_WIDGET (e_table), TRUE); +GType +e_calendar_table_get_type (void) +{ + static GType type = 0; - a11y = gtk_widget_get_accessible ((GtkWidget *)e_table); - if (a11y) - atk_object_set_name (a11y, _("Tasks")); -} + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (ECalendarTableClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) calendar_table_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (ECalendarTable), + 0, /* n_preallocs */ + (GInstanceInitFunc) calendar_table_init, + NULL /* value_table */ + }; + type = g_type_register_static ( + GTK_TYPE_TABLE, "ECalendarTable", &type_info, 0); + } + + return type; +} /** * e_calendar_table_new: - * @Returns: a new #ECalendarTable. + * @shell_view: an #EShellView + * @model: an #ECalModel for the table + * + * Returns a new #ECalendarTable. * - * Creates a new #ECalendarTable. + * Returns: a new #ECalendarTable **/ GtkWidget * -e_calendar_table_new (void) +e_calendar_table_new (EShellView *shell_view, + ECalModel *model) { - GtkWidget *cal_table; - - cal_table = GTK_WIDGET (g_object_new (e_calendar_table_get_type (), NULL)); + g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); + g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL); - return cal_table; + return g_object_new ( + E_TYPE_CALENDAR_TABLE, + "model", model, "shell-view", shell_view, NULL); } +EShellView * +e_calendar_table_get_shell_view (ECalendarTable *cal_table) +{ + g_return_val_if_fail (E_IS_CALENDAR_TABLE (cal_table), NULL); + + return cal_table->priv->shell_view; +} /** * e_calendar_table_get_model: @@ -754,28 +989,12 @@ e_calendar_table_new (void) ECalModel * e_calendar_table_get_model (ECalendarTable *cal_table) { - g_return_val_if_fail (cal_table != NULL, NULL); g_return_val_if_fail (E_IS_CALENDAR_TABLE (cal_table), NULL); - return cal_table->model; + return cal_table->priv->model; } -static void -e_calendar_table_destroy (GtkObject *object) -{ - ECalendarTable *cal_table; - - cal_table = E_CALENDAR_TABLE (object); - - if (cal_table->model) { - g_object_unref (cal_table->model); - cal_table->model = NULL; - } - - GTK_OBJECT_CLASS (e_calendar_table_parent_class)->destroy (object); -} - /** * e_calendar_table_get_table: * @cal_table: A calendar table. @@ -788,37 +1007,13 @@ e_calendar_table_destroy (GtkObject *object) ETable * e_calendar_table_get_table (ECalendarTable *cal_table) { - g_return_val_if_fail (cal_table != NULL, NULL); - g_return_val_if_fail (E_IS_CALENDAR_TABLE (cal_table), NULL); - - return e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable)); -} - -void -e_calendar_table_open_selected (ECalendarTable *cal_table) -{ - ECalModelComponent *comp_data; - icalproperty *prop; + ETableScrolled *table_scrolled; - comp_data = e_calendar_table_get_selected_comp (cal_table); - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_ATTENDEE_PROPERTY); - if (comp_data != NULL) - e_calendar_table_open_task (cal_table, comp_data->client, comp_data->icalcomp, prop ? TRUE : FALSE); -} + g_return_val_if_fail (E_IS_CALENDAR_TABLE (cal_table), NULL); -/** - * e_calendar_table_complete_selected: - * @cal_table: A calendar table - * - * Marks the selected items as completed - **/ -void -e_calendar_table_complete_selected (ECalendarTable *cal_table) -{ - g_return_if_fail (cal_table != NULL); - g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table)); + table_scrolled = E_TABLE_SCROLLED (cal_table->etable); - mark_as_complete_cb (NULL, NULL, cal_table); + return e_table_scrolled_get_table (table_scrolled); } /* Used from e_table_selected_row_foreach(); puts the selected row number in an @@ -833,16 +1028,19 @@ get_selected_row_cb (int model_row, gpointer data) *row = model_row; } -/* Returns the component that is selected in the table; only works if there is +/* + * Returns the component that is selected in the table; only works if there is * one and only one selected row. */ -ECalModelComponent * -e_calendar_table_get_selected_comp (ECalendarTable *cal_table) +static ECalModelComponent * +get_selected_comp (ECalendarTable *cal_table) { + ECalModel *model; ETable *etable; int row; - etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable)); + model = e_calendar_table_get_model (cal_table); + etable = e_calendar_table_get_table (cal_table); if (e_table_selected_count (etable) != 1) return NULL; @@ -852,7 +1050,7 @@ e_calendar_table_get_selected_comp (ECalendarTable *cal_table) &row); g_return_val_if_fail (row != -1, NULL); - return e_cal_model_get_component_at (cal_table->model, row); + return e_cal_model_get_component_at (model, row); } struct get_selected_uids_closure { @@ -864,40 +1062,27 @@ struct get_selected_uids_closure { static void add_uid_cb (int model_row, gpointer data) { - struct get_selected_uids_closure *closure; + struct get_selected_uids_closure *closure = data; ECalModelComponent *comp_data; + ECalModel *model; - closure = data; - - comp_data = e_cal_model_get_component_at (closure->cal_table->model, model_row); + model = e_calendar_table_get_model (closure->cal_table); + comp_data = e_cal_model_get_component_at (model, model_row); closure->objects = g_slist_prepend (closure->objects, comp_data); } -static GSList * -get_selected_objects (ECalendarTable *cal_table) -{ - struct get_selected_uids_closure closure; - ETable *etable; - - closure.cal_table = cal_table; - closure.objects = NULL; - - etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable)); - e_table_selected_row_foreach (etable, add_uid_cb, &closure); - - return closure.objects; -} - /* Deletes all of the selected components in the table */ static void delete_selected_components (ECalendarTable *cal_table) { GSList *objs, *l; + const gchar *status_message; - objs = get_selected_objects (cal_table); + objs = e_calendar_table_get_selected (cal_table); - e_calendar_table_set_status_message (cal_table, _("Deleting selected objects"), -1); + status_message = _("Deleting selected objects"); + calendar_table_emit_status_message (cal_table, status_message, -1.0); for (l = objs; l; l = l->next) { ECalModelComponent *comp_data = (ECalModelComponent *) l->data; @@ -909,7 +1094,7 @@ delete_selected_components (ECalendarTable *cal_table) g_clear_error (&error); } - e_calendar_table_set_status_message (cal_table, NULL, -1); + calendar_table_emit_status_message (cal_table, NULL, -1.0); g_slist_free (objs); } @@ -973,14 +1158,14 @@ e_calendar_table_delete_selected (ECalendarTable *cal_table) g_return_if_fail (cal_table != NULL); g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table)); - etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable)); + etable = e_calendar_table_get_table (cal_table); n_selected = e_table_selected_count (etable); if (n_selected <= 0) return; if (n_selected == 1) - comp_data = e_calendar_table_get_selected_comp (cal_table); + comp_data = get_selected_comp (cal_table); else comp_data = NULL; @@ -1045,7 +1230,16 @@ e_calendar_table_delete_selected (ECalendarTable *cal_table) GSList * e_calendar_table_get_selected (ECalendarTable *cal_table) { - return get_selected_objects(cal_table); + struct get_selected_uids_closure closure; + ETable *etable; + + closure.cal_table = cal_table; + closure.objects = NULL; + + etable = e_calendar_table_get_table (cal_table); + e_table_selected_row_foreach (etable, add_uid_cb, &closure); + + return closure.objects; } /** @@ -1089,6 +1283,7 @@ copy_row_cb (int model_row, gpointer data) { ECalendarTable *cal_table; ECalModelComponent *comp_data; + ECalModel *model; gchar *comp_str; icalcomponent *child; @@ -1096,7 +1291,8 @@ copy_row_cb (int model_row, gpointer data) g_return_if_fail (cal_table->tmp_vcal != NULL); - comp_data = e_cal_model_get_component_at (cal_table->model, model_row); + model = e_calendar_table_get_model (cal_table); + comp_data = e_cal_model_get_component_at (model, model_row); if (!comp_data) return; @@ -1132,14 +1328,13 @@ e_calendar_table_copy_clipboard (ECalendarTable *cal_table) /* create temporary VCALENDAR object */ cal_table->tmp_vcal = e_cal_util_new_top_level (); - etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable)); + etable = e_calendar_table_get_table (cal_table); e_table_selected_row_foreach (etable, copy_row_cb, cal_table); comp_str = icalcomponent_as_ical_string_r (cal_table->tmp_vcal); clipboard = gtk_widget_get_clipboard (GTK_WIDGET (cal_table), clipboard_atom); if (!gtk_clipboard_set_with_data(clipboard, target_types, n_target_types, clipboard_get_calendar_cb, NULL, comp_str)) { - /* no-op */ } else { gtk_clipboard_set_can_store (clipboard, target_types + 1, n_target_types - 1); @@ -1157,8 +1352,10 @@ clipboard_get_calendar_data (ECalendarTable *cal_table, const gchar *text) icalcomponent *icalcomp; char *uid; ECalComponent *comp; + ECalModel *model; ECal *client; icalcomponent_kind kind; + const gchar *status_message; g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table)); @@ -1178,9 +1375,11 @@ clipboard_get_calendar_data (ECalendarTable *cal_table, const gchar *text) return; } - client = e_cal_model_get_default_client (cal_table->model); + model = e_calendar_table_get_model (cal_table); + client = e_cal_model_get_default_client (model); - e_calendar_table_set_status_message (cal_table, _("Updating objects"), -1); + status_message = _("Updating objects"); + calendar_table_emit_status_message (cal_table, status_message, -1.0); if (kind == ICAL_VCALENDAR_COMPONENT) { icalcomponent_kind child_kind; @@ -1225,7 +1424,7 @@ clipboard_get_calendar_data (ECalendarTable *cal_table, const gchar *text) g_object_unref (comp); } - e_calendar_table_set_status_message (cal_table, NULL, -1); + calendar_table_emit_status_message (cal_table, NULL, -1.0); } static void @@ -1234,7 +1433,7 @@ clipboard_paste_received_cb (GtkClipboard *clipboard, gpointer data) { ECalendarTable *cal_table = E_CALENDAR_TABLE (data); - ETable *e_table = e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable)); + ETable *e_table = e_calendar_table_get_table (cal_table); GnomeCanvas *canvas = e_table->table_canvas; GnomeCanvasItem *item = GNOME_CANVAS (canvas)->focused_item; @@ -1269,446 +1468,15 @@ void e_calendar_table_paste_clipboard (ECalendarTable *cal_table) { GtkClipboard *clipboard; - g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table)); - - clipboard = gtk_widget_get_clipboard (GTK_WIDGET (cal_table), clipboard_atom); - g_object_ref (cal_table); - - gtk_clipboard_request_contents (clipboard, - gdk_atom_intern (target_types[0].target, FALSE), - clipboard_paste_received_cb, cal_table); -} - -/* Opens a task in the task editor */ -void -e_calendar_table_open_task (ECalendarTable *cal_table, ECal *client, icalcomponent *icalcomp, gboolean assign) -{ - CompEditor *tedit; - const char *uid; - guint32 flags = 0; - - uid = icalcomponent_get_uid (icalcomp); - - tedit = e_comp_editor_registry_find (comp_editor_registry, uid); - if (tedit == NULL) { - ECalComponent *comp; - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp)); - - if (assign) { - flags |= COMP_EDITOR_IS_ASSIGNED; - if (itip_organizer_is_user (comp, client) || - !e_cal_component_has_attendees (comp)) - flags |= COMP_EDITOR_USER_ORG; - } - - tedit = task_editor_new (client, flags); - comp_editor_edit_comp (tedit, comp); - g_object_unref (comp); - - if (flags & COMP_EDITOR_IS_ASSIGNED) - task_editor_show_assignment (TASK_EDITOR (tedit)); - - e_comp_editor_registry_add (comp_editor_registry, tedit, FALSE); - } - gtk_window_present (GTK_WINDOW (tedit)); -} - -/* Opens the task in the specified row */ -static void -open_task_by_row (ECalendarTable *cal_table, int row) -{ - ECalModelComponent *comp_data; - icalproperty *prop; - - comp_data = e_cal_model_get_component_at (cal_table->model, row); - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_ATTENDEE_PROPERTY); - e_calendar_table_open_task (cal_table, comp_data->client, comp_data->icalcomp, prop ? TRUE : FALSE); -} - -static void -e_calendar_table_on_double_click (ETable *table, - gint row, - gint col, - GdkEvent *event, - ECalendarTable *cal_table) -{ - open_task_by_row (cal_table, row); -} - -/* popup menu callbacks */ - -static void -e_calendar_table_on_open_task (EPopup *ep, EPopupItem *pitem, void *data) -{ - ECalendarTable *cal_table = data; - ECalModelComponent *comp_data; - icalproperty *prop; - - comp_data = e_calendar_table_get_selected_comp (cal_table); - - if (!comp_data) - return; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_ATTENDEE_PROPERTY); - e_calendar_table_open_task (cal_table, comp_data->client, comp_data->icalcomp, prop ? TRUE : FALSE); -} - -static void -e_calendar_table_on_save_as (EPopup *ep, EPopupItem *pitem, void *data) -{ - ECalendarTable *cal_table = data; - ECalModelComponent *comp_data; - char *filename; - char *ical_string; - - comp_data = e_calendar_table_get_selected_comp (cal_table); - if (comp_data == NULL) - return; - - filename = e_file_dialog_save (_("Save as..."), NULL); - if (filename == NULL) - return; - - ical_string = e_cal_get_component_as_string (comp_data->client, comp_data->icalcomp); - if (ical_string == NULL) { - g_warning ("Couldn't convert item to a string"); - return; - } - - e_write_file_uri (filename, ical_string); - - g_free (ical_string); -} - -static void -e_calendar_table_on_print_task (EPopup *ep, EPopupItem *pitem, void *data) -{ - ECalendarTable *cal_table = data; - ECalModelComponent *comp_data; - ECalComponent *comp; - - comp_data = e_calendar_table_get_selected_comp (cal_table); - if (comp_data == NULL) - return; - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp)); - print_comp (comp, comp_data->client, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG); - - g_object_unref (comp); -} - -static void -e_calendar_table_on_cut (EPopup *ep, EPopupItem *pitem, void *data) -{ - ECalendarTable *cal_table = data; - - e_calendar_table_cut_clipboard (cal_table); -} - -static void -e_calendar_table_on_copy (EPopup *ep, EPopupItem *pitem, void *data) -{ - ECalendarTable *cal_table = data; - - e_calendar_table_copy_clipboard (cal_table); -} - -static void -e_calendar_table_on_paste (EPopup *ep, EPopupItem *pitem, void *data) -{ - ECalendarTable *cal_table = data; - - e_calendar_table_paste_clipboard (cal_table); -} - -static void -e_calendar_table_on_assign (EPopup *ep, EPopupItem *pitem, void *data) -{ - ECalendarTable *cal_table = data; - ECalModelComponent *comp_data; - - comp_data = e_calendar_table_get_selected_comp (cal_table); - if (comp_data) - e_calendar_table_open_task (cal_table, comp_data->client, comp_data->icalcomp, TRUE); -} - -static void -e_calendar_table_on_forward (EPopup *ep, EPopupItem *pitem, void *data) -{ - ECalendarTable *cal_table = data; - ECalModelComponent *comp_data; - - comp_data = e_calendar_table_get_selected_comp (cal_table); - if (comp_data) { - ECalComponent *comp; - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp)); - itip_send_comp (E_CAL_COMPONENT_METHOD_PUBLISH, comp, comp_data->client, NULL, NULL, NULL, TRUE); - - g_object_unref (comp); - } -} - -struct AffectedComponents { - ECalendarTable *cal_table; - GSList *components; /* contains pointers to ECalModelComponent */ -}; - -/** - * get_selected_components_cb - * Helper function to fill list of selected components in ECalendarTable. - * This function is called from e_table_selected_row_foreach. - **/ -static void -get_selected_components_cb (int model_row, gpointer data) -{ - struct AffectedComponents *ac = (struct AffectedComponents *) data; - - if (!ac || !ac->cal_table) - return; - - ac->components = g_slist_prepend (ac->components, e_cal_model_get_component_at (E_CAL_MODEL (ac->cal_table->model), model_row)); -} - -/** - * do_for_selected_components - * Calls function func for all selected components in cal_table. - * - * @param cal_table Table with selected components of our interest - * @param func Function to be called on each selected component from cal_table. - * The first parameter of this function is a pointer to ECalModelComponent and - * the second parameter of this function is pointer to cal_table - **/ -static void -do_for_selected_components (ECalendarTable *cal_table, GFunc func) -{ - ETable *etable; - struct AffectedComponents ac; - - g_return_if_fail (cal_table != NULL); - - ac.cal_table = cal_table; - ac.components = NULL; - - etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable)); - e_table_selected_row_foreach (etable, get_selected_components_cb, &ac); - - g_slist_foreach (ac.components, func, cal_table); - g_slist_free (ac.components); -} - -/** - * mark_comp_complete_cb - * Function used in call to @ref do_for_selected_components to mark each component as complete - **/ -static void -mark_comp_complete_cb (gpointer data, gpointer user_data) -{ - ECalendarTable *cal_table; - ECalModelComponent *comp_data; - - comp_data = (ECalModelComponent *) data; - cal_table = E_CALENDAR_TABLE (user_data); - - e_cal_model_tasks_mark_comp_complete (E_CAL_MODEL_TASKS (cal_table->model), comp_data); -} - -/** - * mark_comp_incomplete_cb - * Function used in call to @ref do_for_selected_components to mark each component as incomplete - **/ -static void -mark_comp_incomplete_cb (gpointer data, gpointer user_data) -{ - ECalendarTable *cal_table; - ECalModelComponent *comp_data; - - comp_data = (ECalModelComponent *) data; - cal_table = E_CALENDAR_TABLE (user_data); - - e_cal_model_tasks_mark_comp_incomplete (E_CAL_MODEL_TASKS (cal_table->model), comp_data); -} - -/* Callback used for the "mark tasks as incomplete" menu item */ -static void -mark_as_incomplete_cb (EPopup *ep, EPopupItem *pitem, void *data) -{ - do_for_selected_components (data, mark_comp_incomplete_cb); -} - -/* Callback used for the "mark tasks as complete" menu item */ -static void -mark_as_complete_cb (EPopup *ep, EPopupItem *pitem, void *data) -{ - do_for_selected_components (data, mark_comp_complete_cb); -} - -/* Opens the URL of the task */ -static void -open_url_cb (EPopup *ep, EPopupItem *pitem, void *data) -{ - ECalendarTable *cal_table = data; - ECalModelComponent *comp_data; - icalproperty *prop; - - comp_data = e_calendar_table_get_selected_comp (cal_table); - if (!comp_data) - return; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_URL_PROPERTY); - if (!prop) - return; - - /* FIXME Pass a parent window. */ - e_show_uri (NULL, icalproperty_get_url (prop)); -} - -/* Opens a new task editor */ -static void -on_new_task (EPopup *ep, EPopupItem *pitem, void *data) -{ - ECalendarTable *cal_table = data; - ETasks *tasks = g_object_get_data (G_OBJECT (cal_table), "tasks"); - - if (!tasks) - return; - - e_tasks_new_task (tasks); - -} - -/* Callback for the "delete tasks" menu item */ -static void -delete_cb (EPopup *ep, EPopupItem *pitem, void *data) -{ - ECalendarTable *cal_table = data; - - e_calendar_table_delete_selected (cal_table); -} - -static EPopupItem tasks_popup_items [] = { - { E_POPUP_ITEM, "00.newtask", N_("New _Task"), on_new_task, NULL, "stock_task", 0, 0}, - { E_POPUP_BAR, "01.bar" }, - - { E_POPUP_ITEM, "03.open", N_("_Open"), e_calendar_table_on_open_task, NULL, GTK_STOCK_OPEN, E_CAL_POPUP_SELECT_ONE }, - { E_POPUP_ITEM, "05.openweb", N_("Open _Web Page"), open_url_cb, NULL, NULL, E_CAL_POPUP_SELECT_ONE, E_CAL_POPUP_SELECT_HASURL }, - { E_POPUP_ITEM, "10.saveas", N_("_Save As..."), e_calendar_table_on_save_as, NULL, GTK_STOCK_SAVE_AS, E_CAL_POPUP_SELECT_ONE }, - { E_POPUP_ITEM, "20.print", N_("P_rint..."), e_calendar_table_on_print_task, NULL, GTK_STOCK_PRINT, E_CAL_POPUP_SELECT_ONE }, - - { E_POPUP_BAR, "30.bar" }, - - { E_POPUP_ITEM, "40.cut", N_("C_ut"), e_calendar_table_on_cut, NULL, GTK_STOCK_CUT, 0, E_CAL_POPUP_SELECT_EDITABLE }, - { E_POPUP_ITEM, "50.copy", N_("_Copy"), e_calendar_table_on_copy, NULL, GTK_STOCK_COPY, 0, 0 }, - { E_POPUP_ITEM, "60.paste", N_("_Paste"), e_calendar_table_on_paste, NULL, GTK_STOCK_PASTE, 0, E_CAL_POPUP_SELECT_EDITABLE }, - - { E_POPUP_BAR, "70.bar" }, - - { E_POPUP_ITEM, "80.assign", N_("_Assign Task"), e_calendar_table_on_assign, NULL, NULL, E_CAL_POPUP_SELECT_ONE, E_CAL_POPUP_SELECT_EDITABLE|E_CAL_POPUP_SELECT_ASSIGNABLE }, - { E_POPUP_ITEM, "90.forward", N_("_Forward as iCalendar"), e_calendar_table_on_forward, NULL, "mail-forward", E_CAL_POPUP_SELECT_ONE }, - { E_POPUP_ITEM, "a0.markonecomplete", N_("_Mark as Complete"), mark_as_complete_cb, NULL, NULL, E_CAL_POPUP_SELECT_ONE, E_CAL_POPUP_SELECT_EDITABLE | E_CAL_POPUP_SELECT_NOTCOMPLETE}, - { E_POPUP_ITEM, "b0.markmanycomplete", N_("_Mark Selected Tasks as Complete"), mark_as_complete_cb, NULL, NULL, E_CAL_POPUP_SELECT_MANY, E_CAL_POPUP_SELECT_EDITABLE | E_CAL_POPUP_SELECT_NOTCOMPLETE }, - { E_POPUP_ITEM, "c0.markoneincomplete", N_("_Mark as Incomplete"), mark_as_incomplete_cb, NULL, NULL, E_CAL_POPUP_SELECT_ONE, E_CAL_POPUP_SELECT_EDITABLE|E_CAL_POPUP_SELECT_COMPLETE}, - { E_POPUP_ITEM, "d0.markmanyincomplete", N_("_Mark Selected Tasks as Incomplete"), mark_as_incomplete_cb, NULL, NULL, E_CAL_POPUP_SELECT_MANY, E_CAL_POPUP_SELECT_EDITABLE | E_CAL_POPUP_SELECT_COMPLETE }, - - { E_POPUP_BAR, "e0.bar" }, - - { E_POPUP_ITEM, "f0.delete", N_("_Delete"), delete_cb, NULL, GTK_STOCK_DELETE, E_CAL_POPUP_SELECT_ONE, E_CAL_POPUP_SELECT_EDITABLE }, - { E_POPUP_ITEM, "g0.deletemany", N_("_Delete Selected Tasks"), delete_cb, NULL, GTK_STOCK_DELETE, E_CAL_POPUP_SELECT_MANY, E_CAL_POPUP_SELECT_EDITABLE }, -}; - -static void -ect_popup_free(EPopup *ep, GSList *items, void *data) -{ - g_slist_free(items); -} - -static gint -e_calendar_table_show_popup_menu (ETable *table, - GdkEvent *gdk_event, - ECalendarTable *cal_table) -{ - GtkMenu *menu; - GSList *selection, *l, *menus = NULL; - GPtrArray *events; - ECalPopup *ep; - ECalPopupTargetSelect *t; - int i; - - selection = get_selected_objects (cal_table); - if (!selection) - return TRUE; - - /** @HookPoint-ECalPopup: Tasks Table Context Menu - * @Id: org.gnome.evolution.tasks.table.popup - * @Class: org.gnome.evolution.calendar.popup:1.0 - * @Target: ECalPopupTargetSelect - * - * The context menu on the tasks table. - */ - ep = e_cal_popup_new("org.gnome.evolution.tasks.table.popup"); - - events = g_ptr_array_new(); - for (l=selection;l;l=g_slist_next(l)) - g_ptr_array_add(events, e_cal_model_copy_component_data((ECalModelComponent *)l->data)); - g_slist_free(selection); - - t = e_cal_popup_target_new_select(ep, cal_table->model, events); - t->target.widget = (GtkWidget *)cal_table; - - for (i=0;i<sizeof(tasks_popup_items)/sizeof(tasks_popup_items[0]);i++) - menus = g_slist_prepend(menus, &tasks_popup_items[i]); - e_popup_add_items((EPopup *)ep, menus, NULL, ect_popup_free, cal_table); - - menu = e_popup_create_menu_once((EPopup *)ep, (EPopupTarget *)t, 0); - - gtk_menu_popup(menu, NULL, NULL, NULL, NULL, gdk_event?gdk_event->button.button:0, - gdk_event?gdk_event->button.time:gtk_get_current_event_time()); - - return TRUE; -} - -static gint -e_calendar_table_on_right_click (ETable *table, - gint row, - gint col, - GdkEvent *event, - ECalendarTable *cal_table) -{ - return e_calendar_table_show_popup_menu (table, event, cal_table); -} + g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table)); -static gboolean -e_calendar_table_on_popup_menu (GtkWidget *widget, gpointer data) -{ - ETable *table = E_TABLE(widget); - g_return_val_if_fail(table, FALSE); + clipboard = gtk_widget_get_clipboard ( + GTK_WIDGET (cal_table), clipboard_atom); - return e_calendar_table_show_popup_menu (table, NULL, - E_CALENDAR_TABLE(data)); -} - -static gint -e_calendar_table_on_key_press (ETable *table, - gint row, - gint col, - GdkEventKey *event, - ECalendarTable *cal_table) -{ - if (event->keyval == GDK_Delete) { - delete_cb (NULL, NULL, cal_table); - return TRUE; - } else if ((event->keyval == GDK_o) - &&(event->state & GDK_CONTROL_MASK)) { - open_task_by_row (cal_table, row); - return TRUE; - } - - return FALSE; + gtk_clipboard_request_contents ( + clipboard, gdk_atom_intern (target_types[0].target, FALSE), + clipboard_paste_received_cb, g_object_ref (cal_table)); } static void @@ -1799,29 +1567,31 @@ show_completed_rows (ECalModel *model, GList *clients_list, char *show_sexp, GPt /* Loads the state of the table (headers shown etc.) from the given file. */ void -e_calendar_table_load_state (ECalendarTable *cal_table, - gchar *filename) +e_calendar_table_load_state (ECalendarTable *cal_table, + const gchar *filename) { - struct stat st; + ETable *table; g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table)); + g_return_if_fail (filename != NULL); - if (g_stat (filename, &st) == 0 && st.st_size > 0 - && S_ISREG (st.st_mode)) { - e_table_load_state (e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable)), filename); - } + table = e_calendar_table_get_table (cal_table); + e_table_load_state (table, filename); } /* Saves the state of the table (headers shown etc.) to the given file. */ void -e_calendar_table_save_state (ECalendarTable *cal_table, - gchar *filename) +e_calendar_table_save_state (ECalendarTable *cal_table, + const gchar *filename) { + ETable *table; + g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table)); + g_return_if_fail (filename != NULL); - e_table_save_state (e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable)), - filename); + table = e_calendar_table_get_table (cal_table); + e_table_save_state (table, filename); } /* Returns the current time, for the ECellDateEdit items. @@ -1851,57 +1621,6 @@ e_calendar_table_get_current_time (ECellDateEdit *ecde, gpointer data) return tmp_tm; } - -#ifdef TRANSLATORS_ONLY - -static char *test[] = { - N_("Click to add a task") -}; - -#endif - -void -e_calendar_table_set_activity_handler (ECalendarTable *cal_table, EActivityHandler *activity_handler) -{ - g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table)); - - cal_table->activity_handler = activity_handler; -} - -void -e_calendar_table_set_status_message (ECalendarTable *cal_table, const gchar *message, int percent) -{ - g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table)); - - if (!cal_table->activity_handler) - return; - - if (!message || !*message) { - if (cal_table->activity_id != 0) { - e_activity_handler_operation_finished (cal_table->activity_handler, cal_table->activity_id); - cal_table->activity_id = 0; - } - } else if (cal_table->activity_id == 0) { - char *client_id = g_strdup_printf ("%p", cal_table); - - cal_table->activity_id = e_activity_handler_operation_started ( - cal_table->activity_handler, client_id, message, TRUE); - - g_free (client_id); - } else { - - double progress; - - if (percent < 0) - progress = -1.0; - else { - progress = ((double) percent / 100); - } - - e_activity_handler_operation_progressing (cal_table->activity_handler, cal_table->activity_id, message, progress); - } -} - /** * e_calendar_table_hide_completed_tasks: * @table: A calendar table model. diff --git a/calendar/gui/e-calendar-table.h b/calendar/gui/e-calendar-table.h index e9906ad59b..a3dba94841 100644 --- a/calendar/gui/e-calendar-table.h +++ b/calendar/gui/e-calendar-table.h @@ -23,34 +23,43 @@ #ifndef _E_CALENDAR_TABLE_H_ #define _E_CALENDAR_TABLE_H_ -#include <gtk/gtk.h> -#include <table/e-table-scrolled.h> -#include <misc/e-cell-date-edit.h> -#include "e-activity-handler.h" +#include <shell/e-shell-view.h> +#include <widgets/table/e-table-scrolled.h> +#include <widgets/misc/e-cell-date-edit.h> #include "e-cal-model.h" -G_BEGIN_DECLS - /* * ECalendarTable - displays the iCalendar objects in a table (an ETable). * Used for calendar events and tasks. */ +/* Standard GObject macros */ +#define E_TYPE_CALENDAR_TABLE \ + (e_calendar_table_get_type ()) +#define E_CALENDAR_TABLE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_CALENDAR_TABLE, ECalendarTable)) +#define E_CALENDAR_TABLE_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_CALENDAR_TABLE, ECalendarTableClass)) +#define E_IS_CALENDAR_TABLE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_CALENDAR_TABLE)) +#define E_IS_CALENDAR_TABLE_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_CALENDAR_TABLE)) +#define E_CALENDAR_TABLE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_CALENDAR_TABLE, ECalendarTableClass)) -#define E_CALENDAR_TABLE(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, e_calendar_table_get_type (), ECalendarTable) -#define E_CALENDAR_TABLE_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, e_calendar_table_get_type (), ECalendarTableClass) -#define E_IS_CALENDAR_TABLE(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, e_calendar_table_get_type ()) - - -typedef struct _ECalendarTable ECalendarTable; -typedef struct _ECalendarTableClass ECalendarTableClass; +G_BEGIN_DECLS +typedef struct _ECalendarTable ECalendarTable; +typedef struct _ECalendarTableClass ECalendarTableClass; +typedef struct _ECalendarTablePrivate ECalendarTablePrivate; struct _ECalendarTable { - GtkTable table; - - /* The model that we use */ - ECalModel *model; + GtkTable parent; GtkWidget *etable; @@ -60,61 +69,55 @@ struct _ECalendarTable { /* Fields used for cut/copy/paste */ icalcomponent *tmp_vcal; - /* Activity ID for the EActivityHandler (i.e. the status bar). */ - EActivityHandler *activity_handler; - guint activity_id; - - /* We should know which calendar has been used to create object, so store it here - before emitting "user_created" signal and make it NULL just after the emit. */ - ECal *user_created_cal; + ECalendarTablePrivate *priv; }; struct _ECalendarTableClass { GtkTableClass parent_class; - /* Notification signals */ - void (* user_created) (ECalendarTable *cal_table); + /* Signals */ + void (*open_component) (ECalendarTable *cal_table, + ECalModelComponent *comp_data); + void (*popup_event) (ECalendarTable *cal_table, + GdkEvent *event); + void (*status_message) (ECalendarTable *cal_table, + const gchar *message, + gdouble percent); + void (*user_created) (ECalendarTable *cal_table); }; - -GType e_calendar_table_get_type (void); -GtkWidget* e_calendar_table_new (void); - -ECalModel *e_calendar_table_get_model (ECalendarTable *cal_table); - -ETable *e_calendar_table_get_table (ECalendarTable *cal_table); - -void e_calendar_table_open_selected (ECalendarTable *cal_table); -void e_calendar_table_complete_selected (ECalendarTable *cal_table); -void e_calendar_table_delete_selected (ECalendarTable *cal_table); - -GSList *e_calendar_table_get_selected (ECalendarTable *cal_table); +GType e_calendar_table_get_type (void); +GtkWidget * e_calendar_table_new (EShellView *shell_view, + ECalModel *model); +ECalModel * e_calendar_table_get_model (ECalendarTable *cal_table); +ETable * e_calendar_table_get_table (ECalendarTable *cal_table); +EShellView * e_calendar_table_get_shell_view (ECalendarTable *cal_table); +void e_calendar_table_delete_selected(ECalendarTable *cal_table); +GSList * e_calendar_table_get_selected (ECalendarTable *cal_table); /* Clipboard related functions */ -void e_calendar_table_cut_clipboard (ECalendarTable *cal_table); -void e_calendar_table_copy_clipboard (ECalendarTable *cal_table); -void e_calendar_table_paste_clipboard (ECalendarTable *cal_table); +void e_calendar_table_cut_clipboard (ECalendarTable *cal_table); +void e_calendar_table_copy_clipboard (ECalendarTable *cal_table); +void e_calendar_table_paste_clipboard(ECalendarTable *cal_table); /* These load and save the state of the table (headers shown etc.) to/from the given file. */ -void e_calendar_table_load_state (ECalendarTable *cal_table, - gchar *filename); -void e_calendar_table_save_state (ECalendarTable *cal_table, - gchar *filename); - -void e_calendar_table_set_activity_handler (ECalendarTable *cal_table, - EActivityHandler *activity_handler); -void e_calendar_table_set_status_message (ECalendarTable *cal_table, - const gchar *message, - int percent); -void e_calendar_table_open_task (ECalendarTable *cal_table, - ECal *client, - icalcomponent *icalcomp, - gboolean assign); -ECalModelComponent * e_calendar_table_get_selected_comp (ECalendarTable *cal_table); -void e_calendar_table_hide_completed_tasks (ECalendarTable *table, GList *clients_list, gboolean config_changed); - -void e_calendar_table_process_completed_tasks (ECalendarTable *table, GList *clients_list, gboolean config_changed); +void e_calendar_table_load_state (ECalendarTable *cal_table, + const gchar *filename); +void e_calendar_table_save_state (ECalendarTable *cal_table, + const gchar *filename); + +ECalModelComponent * + e_calendar_table_get_selected_comp + (ECalendarTable *cal_table); +void e_calendar_table_hide_completed_tasks + (ECalendarTable *table, + GList *clients_list, + gboolean config_changed); +void e_calendar_table_process_completed_tasks + (ECalendarTable *table, + GList *clients_list, + gboolean config_changed); gboolean ec_query_tooltip (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, GtkWidget *etable_wgt, ECalModel *model); diff --git a/calendar/gui/e-calendar-view.c b/calendar/gui/e-calendar-view.c index 6c8e1f83ab..2294c0b0ed 100644 --- a/calendar/gui/e-calendar-view.c +++ b/calendar/gui/e-calendar-view.c @@ -37,15 +37,14 @@ #include <e-util/e-icon-factory.h> #include <libecal/e-cal-time-util.h> #include <libecal/e-cal-component.h> +#include <shell/e-shell.h> #include "common/authentication.h" #include "calendar-commands.h" -#include "calendar-component.h" #include "calendar-config.h" #include "comp-util.h" #include "e-cal-model-calendar.h" #include "e-calendar-view.h" -#include "e-comp-editor-registry.h" #include "itip-utils.h" #include "dialogs/delete-comp.h" #include "dialogs/delete-error.h" @@ -67,10 +66,6 @@ struct _ECalendarViewPrivate { /* The calendar model we are monitoring */ ECalModel *model; - /* Current activity (for the EActivityHandler, i.e. the status bar). */ - EActivityHandler *activity_handler; - guint activity_id; - /* The default category */ char *default_category; }; @@ -80,7 +75,6 @@ static void e_calendar_view_set_property (GObject *object, guint property_id, co static void e_calendar_view_destroy (GtkObject *object); static void open_event_with_flags (ECalendarView *cal_view, ECal *client, icalcomponent *icalcomp, guint32 flags); -extern ECompEditorRegistry *comp_editor_registry; /* Property IDs */ enum props { @@ -255,8 +249,10 @@ e_calendar_view_class_init (ECalendarViewClass *klass) GDK_CONTROL_MASK, "open_event", 0); +#if 0 /* KILL-BONOBO */ /* init the accessibility support for e_day_view */ e_cal_view_a11y_init (); +#endif } @@ -264,6 +260,7 @@ void e_calendar_view_add_event (ECalendarView *cal_view, ECal *client, time_t dtstart, icaltimezone *default_zone, icalcomponent *icalcomp, gboolean in_top_canvas) { +#if 0 /* KILL-BONOBO */ ECalComponent *comp; struct icaltimetype itime, old_dtstart, old_dtend; time_t tt_start, tt_end, new_dtstart = 0; @@ -381,6 +378,7 @@ e_calendar_view_add_event (ECalendarView *cal_view, ECal *client, time_t dtstart } g_object_unref (comp); +#endif } static void @@ -537,55 +535,6 @@ e_calendar_view_set_use_24_hour_format (ECalendarView *cal_view, gboolean use_24 e_cal_model_set_use_24_hour_format (cal_view->priv->model, use_24_hour); } -void -e_calendar_view_set_activity_handler (ECalendarView *cal_view, EActivityHandler *activity_handler) -{ - ECalendarViewPrivate *priv; - - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - priv = cal_view->priv; - - priv->activity_handler = activity_handler; -} - -void -e_calendar_view_set_status_message (ECalendarView *cal_view, const gchar *message, int percent) -{ - ECalendarViewPrivate *priv; - - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - priv = cal_view->priv; - - if (!priv->activity_handler) - return; - - if (!message || !*message) { - if (priv->activity_id != 0) { - e_activity_handler_operation_finished (priv->activity_handler, priv->activity_id); - priv->activity_id = 0; - } - } else if (priv->activity_id == 0) { - char *client_id = g_strdup_printf ("%p", cal_view); - - priv->activity_id = e_activity_handler_operation_started ( - priv->activity_handler, client_id, message, TRUE); - - g_free (client_id); - } else { - double progress; - - if (percent < 0) - progress = -1.0; - else { - progress = ((double) percent / 100); - } - - e_activity_handler_operation_progressing (priv->activity_handler, priv->activity_id, message, progress); - } -} - GList * e_calendar_view_get_selected_events (ECalendarView *cal_view) { @@ -656,7 +605,9 @@ e_calendar_view_cut_clipboard (ECalendarView *cal_view) if (!selected) return; +#if 0 /* KILL-BONOBO */ e_calendar_view_set_status_message (cal_view, _("Deleting selected objects"), -1); +#endif e_calendar_view_copy_clipboard (cal_view); for (l = selected; l != NULL; l = l->next) { @@ -701,7 +652,9 @@ e_calendar_view_cut_clipboard (ECalendarView *cal_view) g_object_unref (comp); } +#if 0 /* KILL-BONOBO */ e_calendar_view_set_status_message (cal_view, NULL, -1); +#endif g_list_free (selected); } @@ -870,7 +823,9 @@ clipboard_get_calendar_data (ECalendarView *cal_view, const gchar *text) if (kind != ICAL_VCALENDAR_COMPONENT && kind != ICAL_VEVENT_COMPONENT) return; +#if 0 /* KILL-BONOBO */ e_calendar_view_set_status_message (cal_view, _("Updating objects"), -1); +#endif e_calendar_view_get_selected_time_range (cal_view, &selected_time_start, &selected_time_end); if ((selected_time_end - selected_time_start) == 60 * 60 * 24) @@ -918,7 +873,9 @@ clipboard_get_calendar_data (ECalendarView *cal_view, const gchar *text) e_calendar_view_add_event (cal_view, client, selected_time_start, default_zone, icalcomp, in_top_canvas); } +#if 0 /* KILL-BONOBO */ e_calendar_view_set_status_message (cal_view, NULL, -1); +#endif } static void @@ -1270,11 +1227,13 @@ on_new_meeting (EPopup *ep, EPopupItem *pitem, void *data) static void on_new_task (EPopup *ep, EPopupItem *pitem, void *data) { +#if 0 /* KILL-BONOBO */ ECalendarView *cal_view = data; time_t dtstart, dtend; e_calendar_view_get_selected_time_range (cal_view, &dtstart, &dtend); gnome_calendar_new_task (cal_view->priv->calendar, &dtstart, &dtend); +#endif } static void @@ -1288,9 +1247,11 @@ on_goto_date (EPopup *ep, EPopupItem *pitem, void *data) static void on_goto_today (EPopup *ep, EPopupItem *pitem, void *data) { +#if 0 /* KILL-BONOBO */ ECalendarView *cal_view = data; - calendar_goto_today (cal_view->priv->calendar); + gnome_calendar_goto_today (cal_view->priv->calendar); +#endif } static void @@ -1315,9 +1276,11 @@ on_edit_appointment (EPopup *ep, EPopupItem *pitem, void *data) static void on_print (EPopup *ep, EPopupItem *pitem, void *data) { +#if 0 /* KILL-BONOBO */ ECalendarView *cal_view = data; calendar_command_print (cal_view->priv->calendar, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG); +#endif } static void @@ -1477,16 +1440,20 @@ transfer_selected_items (ECalendarView *cal_view, gboolean remove_item) return; } +#if 0 /* KILL-BONOBO */ /* process all selected events */ if (remove_item) e_calendar_view_set_status_message (cal_view, _("Moving items"), -1); else e_calendar_view_set_status_message (cal_view, _("Copying items"), -1); +#endif for (l = selected; l != NULL; l = l->next) transfer_item_to ((ECalendarViewEvent *) l->data, dest_client, remove_item); +#if 0 /* KILL-BONOBO */ e_calendar_view_set_status_message (cal_view, NULL, -1); +#endif /* free memory */ g_object_unref (destination_source); @@ -1838,69 +1805,6 @@ static EPopupItem ecv_child_items [] = { { E_POPUP_ITEM, "54.delete", N_("Delete _All Occurrences"), on_delete_appointment, NULL, GTK_STOCK_DELETE, E_CAL_POPUP_SELECT_RECURRING, E_CAL_POPUP_SELECT_NOTEDITING | E_CAL_POPUP_SELECT_EDITABLE }, }; -static void -ecv_popup_free (EPopup *ep, GSList *list, void *data) -{ - g_slist_free(list); -} - -GtkMenu * -e_calendar_view_create_popup_menu (ECalendarView *cal_view) -{ - ECalPopup *ep; - GSList *menus = NULL; - GList *selected, *l; - int i; - ECalPopupTargetSelect *t; - ECalModel *model; - GPtrArray *events; - - g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), NULL); - - /* We could do this using a factory on the ECalPopup class, - * that way we would get called implicitly whenever a popup - * menu was created rather than everyone having to call us. - * We could also have a different menu id for each view */ - - /** @HookPoint-ECalPopup: Calendar Main View Context Menu - * @Id: org.gnome.evolution.calendar.view.popup - * @Class: org.gnome.evolution.calendar.popup:1.0 - * @Target: ECalPopupTargetSelect - * - * The context menu on the main calendar view. This menu - * applies to all view types. - */ - ep = e_cal_popup_new("org.gnome.evolution.calendar.view.popup"); - - model = e_calendar_view_get_model(cal_view); - events = g_ptr_array_new(); - selected = e_calendar_view_get_selected_events(cal_view); - for (l=selected;l;l=g_list_next(l)) { - ECalendarViewEvent *event = l->data; - - if (event) - g_ptr_array_add(events, e_cal_model_copy_component_data(event->comp_data)); - } - g_list_free(selected); - - t = e_cal_popup_target_new_select(ep, model, events); - t->target.widget = (GtkWidget *)cal_view; - - if (t->events->len == 0) { - for (i=0;i<sizeof(ecv_main_items)/sizeof(ecv_main_items[0]);i++) - menus = g_slist_prepend(menus, &ecv_main_items[i]); - - gnome_calendar_view_popup_factory(cal_view->priv->calendar, (EPopup *)ep, "60.view"); - } else { - for (i=0;i<sizeof(ecv_child_items)/sizeof(ecv_child_items[0]);i++) - menus = g_slist_prepend(menus, &ecv_child_items[i]); - } - - e_popup_add_items((EPopup *)ep, menus, NULL, ecv_popup_free, cal_view); - - return e_popup_create_menu_once((EPopup *)ep, (EPopupTarget *)t, 0); -} - void e_calendar_view_open_event (ECalendarView *cal_view) { @@ -2099,7 +2003,9 @@ e_calendar_view_new_appointment (ECalendarView *cal_view) static void object_created_cb (CompEditor *ce, ECalendarView *cal_view) { +#if 0 /* KILL-BONOBO */ gnome_calendar_emit_user_created_signal (cal_view, e_calendar_view_get_calendar (cal_view), comp_editor_get_client (ce)); +#endif } static void @@ -2108,13 +2014,16 @@ open_event_with_flags (ECalendarView *cal_view, ECal *client, icalcomponent *ica CompEditor *ce; const char *uid; ECalComponent *comp; + EShell *shell; + /* FIXME ECalendarView should own an EShell pointer. */ + shell = e_shell_get_default (); uid = icalcomponent_get_uid (icalcomp); - ce = e_comp_editor_registry_find (comp_editor_registry, uid); + ce = comp_editor_find_instance (uid); if (!ce) { - ce = event_editor_new (client, flags); + ce = event_editor_new (client, shell, flags); g_signal_connect (ce, "object_created", G_CALLBACK (object_created_cb), cal_view); @@ -2124,8 +2033,6 @@ open_event_with_flags (ECalendarView *cal_view, ECal *client, icalcomponent *ica if (flags & COMP_EDITOR_MEETING) event_editor_show_meeting (EVENT_EDITOR (ce)); - e_comp_editor_registry_add (comp_editor_registry, ce, FALSE); - g_object_unref (comp); } @@ -2661,29 +2568,8 @@ draw_curved_rectangle (cairo_t *cr, double x0, double y0, static void error_response(GtkWidget *widget, gint response, void *data) { - gtk_widget_destroy (widget); -} - -void -e_calendar_utils_show_error_silent (GtkWidget *widget) -{ - EActivityHandler *handler = calendar_component_peek_activity_handler (calendar_component_peek ()); - - if(!g_object_get_data ((GObject *) widget, "response-handled")) { - g_signal_connect(widget, "response", G_CALLBACK(error_response), NULL); - } - - e_activity_handler_make_error (handler, "calendar", E_LOG_ERROR, widget); -} - -void -e_calendar_utils_show_info_silent (GtkWidget *widget) -{ - EActivityHandler *handler = calendar_component_peek_activity_handler (calendar_component_peek ()); - - if(!g_object_get_data ((GObject *) widget, "response-handled")) { - g_signal_connect(widget, "response", G_CALLBACK(error_response), NULL); - } - - e_activity_handler_make_error (handler, "calendar", E_LOG_WARNINGS, widget); + if (response == GTK_RESPONSE_DELETE_EVENT) + gtk_widget_destroy(widget); + else if (response == GTK_RESPONSE_OK) + gtk_widget_destroy(widget); } diff --git a/calendar/gui/e-calendar-view.h b/calendar/gui/e-calendar-view.h index 1f18e67241..e5d8478b8e 100644 --- a/calendar/gui/e-calendar-view.h +++ b/calendar/gui/e-calendar-view.h @@ -27,7 +27,6 @@ #include <gtk/gtk.h> #include "e-cal-model.h" #include "gnome-cal.h" -#include "e-activity-handler.h" G_BEGIN_DECLS @@ -129,7 +128,6 @@ void e_calendar_view_set_default_category (ECalendarView *cal_view, co gboolean e_calendar_view_get_use_24_hour_format (ECalendarView *view); void e_calendar_view_set_use_24_hour_format (ECalendarView *view, gboolean use_24_hour); -void e_calendar_view_set_activity_handler (ECalendarView *cal_view, EActivityHandler *activity_handler); void e_calendar_view_set_status_message (ECalendarView *cal_view, const gchar *message, int percent); GList *e_calendar_view_get_selected_events (ECalendarView *cal_view); diff --git a/calendar/gui/e-day-view-main-item.c b/calendar/gui/e-day-view-main-item.c index 03d630c0f2..f96e6cc5ed 100644 --- a/calendar/gui/e-day-view-main-item.c +++ b/calendar/gui/e-day-view-main-item.c @@ -111,7 +111,9 @@ e_day_view_main_item_class_init (EDayViewMainItemClass *class) G_PARAM_WRITABLE)); /* init the accessibility support for e_day_view */ +#if 0 /* KILL-BONOBO */ e_day_view_main_item_a11y_init (); +#endif } diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c index 96bc63d592..9f48cdecb1 100644 --- a/calendar/gui/e-day-view.c +++ b/calendar/gui/e-day-view.c @@ -51,7 +51,6 @@ #include "print.h" #include "comp-util.h" #include "itip-utils.h" -#include "calendar-commands.h" #include "calendar-config.h" #include "goto.h" #include "e-cal-model-calendar.h" @@ -466,8 +465,10 @@ e_day_view_class_init (EDayViewClass *class) view_class->get_visible_time_range = e_day_view_get_visible_time_range; view_class->paste_text = e_day_view_paste_text; +#if 0 /* KILL-BONOBO */ /* init the accessibility support for e_day_view */ e_day_view_a11y_init (); +#endif } static void @@ -3397,9 +3398,11 @@ e_day_view_show_popup_menu (EDayView *day_view, day_view->popup_event_day = day; day_view->popup_event_num = event_num; +#if 0 /* KILL-BONOBO */ popup = e_calendar_view_create_popup_menu (E_CALENDAR_VIEW (day_view)); g_object_weak_ref (G_OBJECT (popup), popup_destroyed_cb, day_view); gtk_menu_popup (popup, NULL, NULL, NULL, NULL, gdk_event?gdk_event->button.button:0, gdk_event?gdk_event->button.time:gtk_get_current_event_time()); +#endif } static gboolean @@ -5608,6 +5611,7 @@ e_day_view_cursor_key_down (EDayView *day_view, GdkEventKey *event) static void e_day_view_cursor_key_left (EDayView *day_view, GdkEventKey *event) { +#if 0 /* KILL-BONOBO */ if (day_view->selection_start_day == 0) { gnome_calendar_previous (e_calendar_view_get_calendar (E_CALENDAR_VIEW (day_view))); } else { @@ -5621,12 +5625,14 @@ e_day_view_cursor_key_left (EDayView *day_view, GdkEventKey *event) gtk_widget_queue_draw (day_view->main_canvas); } g_signal_emit_by_name (day_view, "selected_time_changed"); +#endif } static void e_day_view_cursor_key_right (EDayView *day_view, GdkEventKey *event) { +#if 0 /* KILL-BONOBO */ if (day_view->selection_end_day == day_view->days_shown - 1) { gnome_calendar_next (e_calendar_view_get_calendar (E_CALENDAR_VIEW (day_view))); } else { @@ -5640,6 +5646,7 @@ e_day_view_cursor_key_right (EDayView *day_view, GdkEventKey *event) gtk_widget_queue_draw (day_view->main_canvas); } g_signal_emit_by_name (day_view, "selected_time_changed"); +#endif } @@ -6374,8 +6381,10 @@ e_day_view_on_editing_stopped (EDayView *day_view, if (!on_server) { if (!e_cal_create_object (client, icalcomp, NULL, NULL)) g_message (G_STRLOC ": Could not create the object!"); +#if 0 /* KILL-BONOBO */ else gnome_calendar_emit_user_created_signal (day_view, e_calendar_view_get_calendar (E_CALENDAR_VIEW (day_view)), client); +#endif /* we remove the object since we either got the update from the server or failed */ e_day_view_remove_event_cb (day_view, day, event_num, NULL); diff --git a/calendar/gui/e-itip-control.c b/calendar/gui/e-itip-control.c index c5a483ea8e..4ecacd2bfe 100644 --- a/calendar/gui/e-itip-control.c +++ b/calendar/gui/e-itip-control.c @@ -31,8 +31,6 @@ #include <unistd.h> #include <glib/gi18n.h> #include <glib/gstdio.h> -#include <bonobo/bonobo-object.h> -#include <bonobo/bonobo-exception.h> #include <gtkhtml/gtkhtml.h> #include <gtkhtml/gtkhtml-embedded.h> #include <gtkhtml/gtkhtml-stream.h> @@ -52,6 +50,7 @@ #include "itip-utils.h" #include "e-itip-control.h" #include "common/authentication.h" +#include <shell/e-shell.h> struct _EItipControlPrivate { GtkWidget *html; @@ -243,12 +242,18 @@ source_changed_cb (ESourceComboBox *escb, EItipControl *itip) static void find_cal_opened_cb (ECal *ecal, ECalendarStatus status, gpointer data) { + EShell *shell; + EShellSettings *shell_settings; EItipControlFindData *fd = data; EItipControlPrivate *priv; ESource *source; ECalSourceType source_type; icalcomponent *icalcomp; + /* FIXME Pass this in. */ + shell = e_shell_get_default (); + shell_settings = e_shell_get_shell_settings (shell); + source_type = e_cal_get_source_type (ecal); source = e_cal_get_source (ecal); @@ -275,20 +280,24 @@ find_cal_opened_cb (ECal *ecal, ECalendarStatus status, gpointer data) if (fd->count == 0) { if (fd->show_selector && !priv->current_ecal && priv->vbox.widget) { GtkWidget *escb; + const gchar *property_name; char *uid; switch (priv->type) { case E_CAL_SOURCE_TYPE_EVENT: - uid = calendar_config_get_primary_calendar (); + property_name = "cal-primary-calendar"; break; case E_CAL_SOURCE_TYPE_TODO: - uid = calendar_config_get_primary_tasks (); + property_name = "cal-primary-tasks"; break; default: uid = NULL; g_return_if_reached (); } + uid = e_shell_settings_get_string ( + shell_settings, property_name); + if (uid) { source = e_source_list_peek_source_by_uid (priv->source_lists[priv->type], uid); g_free (uid); diff --git a/calendar/gui/e-meeting-time-sel.c b/calendar/gui/e-meeting-time-sel.c index 4bf44eb6e1..625d24d600 100644 --- a/calendar/gui/e-meeting-time-sel.c +++ b/calendar/gui/e-meeting-time-sel.c @@ -35,14 +35,13 @@ #include <glib/gi18n.h> #include <libgnomecanvas/gnome-canvas-widget.h> -#include <misc/e-canvas.h> -#include <misc/e-canvas-utils.h> +#include "misc/e-canvas.h" +#include "misc/e-canvas-utils.h" -#include <misc/e-dateedit.h> -#include <e-util/e-cursor.h> -#include <e-util/e-util.h> +#include "misc/e-dateedit.h" +#include "e-util/e-cursor.h" +#include "e-util/e-util.h" -#include "calendar-component.h" #include "calendar-config.h" #include "e-meeting-utils.h" #include "e-meeting-list-view.h" diff --git a/calendar/gui/e-memo-list-selector.c b/calendar/gui/e-memo-list-selector.c new file mode 100644 index 0000000000..9d3408944b --- /dev/null +++ b/calendar/gui/e-memo-list-selector.c @@ -0,0 +1,287 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-memo-list-selector.c + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "e-memo-list-selector.h" + +#include <string.h> +#include <libecal/e-cal.h> +#include "calendar/common/authentication.h" +#include "calendar/gui/comp-util.h" + +#define E_MEMO_LIST_SELECTOR_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_MEMO_LIST_SELECTOR, EMemoListSelectorPrivate)) + +struct _EMemoListSelectorPrivate { + gint dummy_value; +}; + +enum { + DND_TARGET_TYPE_CALENDAR_LIST +}; + +static GtkTargetEntry drag_types[] = { + { "text/calendar", 0, DND_TARGET_TYPE_CALENDAR_LIST }, + { "text/x-calendar", 0, DND_TARGET_TYPE_CALENDAR_LIST } +}; + +static gpointer parent_class; + +static gboolean +memo_list_selector_update_single_object (ECal *client, + icalcomponent *icalcomp) +{ + gchar *uid; + icalcomponent *tmp_icalcomp; + + uid = (gchar *) icalcomponent_get_uid (icalcomp); + + if (e_cal_get_object (client, uid, NULL, &tmp_icalcomp, NULL)) + return e_cal_modify_object ( + client, icalcomp, CALOBJ_MOD_ALL, NULL); + + return e_cal_create_object (client, icalcomp, &uid, NULL); +} + +static gboolean +memo_list_selector_update_objects (ECal *client, + icalcomponent *icalcomp) +{ + icalcomponent *subcomp; + icalcomponent_kind kind; + + kind = icalcomponent_isa (icalcomp); + if (kind == ICAL_VJOURNAL_COMPONENT) + return memo_list_selector_update_single_object ( + client, icalcomp); + else if (kind != ICAL_VCALENDAR_COMPONENT) + return FALSE; + + subcomp = icalcomponent_get_first_component ( + icalcomp, ICAL_ANY_COMPONENT); + while (subcomp != NULL) { + gboolean success; + + kind = icalcomponent_isa (subcomp); + if (kind == ICAL_VTIMEZONE_COMPONENT) { + icaltimezone *zone; + + zone = icaltimezone_new (); + icaltimezone_set_component (zone, subcomp); + + success = e_cal_add_timezone (client, zone, NULL); + icaltimezone_free (zone, 1); + if (!success) + return FALSE; + } else if (kind == ICAL_VJOURNAL_COMPONENT) { + success = memo_list_selector_update_single_object ( + client, subcomp); + if (!success) + return FALSE; + } + + subcomp = icalcomponent_get_next_component ( + icalcomp, ICAL_ANY_COMPONENT); + } + + return TRUE; +} + +static gboolean +memo_list_selector_process_data (ESourceSelector *selector, + ECal *client, + const gchar *source_uid, + icalcomponent *icalcomp, + GdkDragAction action) +{ + ESourceList *source_list; + ESource *source; + icalcomponent *tmp_icalcomp = NULL; + const gchar *uid; + gchar *old_uid = NULL; + gboolean success = FALSE; + gboolean read_only = TRUE; + GError *error = NULL; + + /* FIXME Deal with GDK_ACTION_ASK. */ + if (action == GDK_ACTION_COPY) { + old_uid = g_strdup (icalcomponent_get_uid (icalcomp)); + uid = e_cal_component_gen_uid (); + icalcomponent_set_uid (icalcomp, uid); + } + + uid = icalcomponent_get_uid (icalcomp); + if (old_uid == NULL) + old_uid = g_strdup (uid); + + if (e_cal_get_object (client, uid, NULL, &tmp_icalcomp, &error)) { + icalcomponent_free (tmp_icalcomp); + success = TRUE; + goto exit; + } + + if (error != NULL && error->code != E_CALENDAR_STATUS_OBJECT_NOT_FOUND) { + g_message ( + "Failed to search the object in destination " + "task list: %s", error->message); + g_error_free (error); + goto exit; + } + + success = memo_list_selector_update_objects (client, icalcomp); + + if (!success || action != GDK_ACTION_MOVE) + goto exit; + + source_list = e_source_selector_get_source_list (selector); + source = e_source_list_peek_source_by_uid (source_list, source_uid); + + if (!E_IS_SOURCE (source) || e_source_get_readonly (source)) + goto exit; + + client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_JOURNAL); + if (client == NULL) { + g_message ("Cannot create source client to remove old memo"); + goto exit; + } + + e_cal_is_read_only (client, &read_only, NULL); + if (!read_only && e_cal_open (client, TRUE, NULL)) + e_cal_remove_object (client, old_uid, NULL); + else if (!read_only) + g_message ("Cannot open source client to remove old memo"); + + g_object_unref (client); + +exit: + g_free (old_uid); + + return success; +} + +static gboolean +memo_list_selector_data_dropped (ESourceSelector *selector, + GtkSelectionData *selection_data, + ESource *destination, + GdkDragAction action, + guint info) +{ + ECal *client; + GSList *list, *iter; + gboolean success = FALSE; + + client = auth_new_cal_from_source ( + destination, E_CAL_SOURCE_TYPE_JOURNAL); + + if (client == NULL || !e_cal_open (client, TRUE, NULL)) + goto exit; + + list = cal_comp_selection_get_string_list (selection_data); + + for (iter = list; iter != NULL; iter = iter->next) { + gchar *source_uid = iter->data; + icalcomponent *icalcomp; + gchar *component_string; + + /* Each string is "source_uid\ncomponent_string". */ + component_string = strchr (source_uid, '\n'); + if (component_string == NULL) + continue; + + *component_string++ = '\0'; + icalcomp = icalparser_parse_string (component_string); + if (icalcomp == NULL) + continue; + + success = memo_list_selector_process_data ( + selector, client, source_uid, icalcomp, action); + + icalcomponent_free (icalcomp); + } + + g_slist_foreach (list, (GFunc) g_free, NULL); + g_slist_free (list); + +exit: + if (client != NULL) + g_object_unref (client); + + return success; +} + +static void +memo_list_selector_class_init (EMemoListSelectorClass *class) +{ + ESourceSelectorClass *source_selector_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EMemoListSelectorPrivate)); + + source_selector_class = E_SOURCE_SELECTOR_CLASS (class); + source_selector_class->data_dropped = memo_list_selector_data_dropped; +} + +static void +memo_list_selector_init (EMemoListSelector *selector) +{ + selector->priv = E_MEMO_LIST_SELECTOR_GET_PRIVATE (selector); + + gtk_drag_dest_set ( + GTK_WIDGET (selector), GTK_DEST_DEFAULT_ALL, + drag_types, G_N_ELEMENTS (drag_types), + GDK_ACTION_COPY | GDK_ACTION_MOVE); +} + +GType +e_memo_list_selector_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + const GTypeInfo type_info = { + sizeof (EMemoListSelectorClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) memo_list_selector_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EMemoListSelector), + 0, /* n_preallocs */ + (GInstanceInitFunc) memo_list_selector_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + E_TYPE_SOURCE_SELECTOR, "EMemoListSelector", + &type_info, 0); + } + + return type; +} + +GtkWidget * +e_memo_list_selector_new (ESourceList *source_list) +{ + g_return_val_if_fail (E_IS_SOURCE_LIST (source_list), NULL); + + return g_object_new ( + E_TYPE_MEMO_LIST_SELECTOR, + "source-list", source_list, NULL); +} diff --git a/calendar/gui/e-memo-list-selector.h b/calendar/gui/e-memo-list-selector.h new file mode 100644 index 0000000000..c10cff2a2e --- /dev/null +++ b/calendar/gui/e-memo-list-selector.h @@ -0,0 +1,71 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-memo-list-selector.h + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/* XXX This widget is nearly identical to ETaskListSelector. If + * ECalendarSelector ever learns how to move selections from + * one source to another, perhaps these ESourceSelector sub- + * classes could someday be combined. */ + +#ifndef E_MEMO_LIST_SELECTOR_H +#define E_MEMO_LIST_SELECTOR_H + +#include <libedataserver/e-source-list.h> +#include <libedataserverui/e-source-selector.h> + +/* Standard GObject macros */ +#define E_TYPE_MEMO_LIST_SELECTOR \ + (e_memo_list_selector_get_type ()) +#define E_MEMO_LIST_SELECTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_MEMO_LIST_SELECTOR, EMemoListSelector)) +#define E_MEMO_LIST_SELECTOR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_MEMO_LIST_SELECTOR, EMemoListSelectorClass)) +#define E_IS_MEMO_LIST_SELECTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_MEMO_LIST_SELECTOR)) +#define E_IS_MEMO_LIST_SELECTOR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_MEMO_LIST_SELECTOR)) +#define E_MEMO_LIST_SELECTOR_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_MEMO_LIST_SELECTOR, EMemoListSelectorClass)) + +G_BEGIN_DECLS + +typedef struct _EMemoListSelector EMemoListSelector; +typedef struct _EMemoListSelectorClass EMemoListSelectorClass; +typedef struct _EMemoListSelectorPrivate EMemoListSelectorPrivate; + +struct _EMemoListSelector { + ESourceSelector parent; + EMemoListSelectorPrivate *priv; +}; + +struct _EMemoListSelectorClass { + ESourceSelectorClass parent_class; +}; + +GType e_memo_list_selector_get_type (void); +GtkWidget * e_memo_list_selector_new (ESourceList *source_list); + +G_END_DECLS + +#endif /* E_MEMO_LIST_SELECTOR_H */ diff --git a/calendar/gui/e-memo-table.c b/calendar/gui/e-memo-table.c index 260103ada0..891bec6d32 100644 --- a/calendar/gui/e-memo-table.c +++ b/calendar/gui/e-memo-table.c @@ -24,7 +24,7 @@ /* * EMemoTable - displays the ECalComponent objects in a table (an ETable). - * Used for memos. + * Used for calendar events and tasks. */ #ifdef HAVE_CONFIG_H @@ -35,15 +35,17 @@ #include <unistd.h> #include <glib/gi18n.h> #include <glib/gstdio.h> -#include <gdk/gdkkeysyms.h> #include <widgets/misc/e-gui-utils.h> #include <table/e-cell-checkbox.h> #include <table/e-cell-toggle.h> #include <table/e-cell-text.h> #include <table/e-cell-combo.h> #include <e-util/e-dialog-utils.h> +#include <e-util/e-util-private.h> #include <widgets/misc/e-cell-date-edit.h> #include <widgets/misc/e-cell-percent.h> +#include <libecal/e-cal-time-util.h> +#include <libedataserver/e-time-utils.h> #include "calendar-config.h" #include "dialogs/delete-comp.h" @@ -51,66 +53,52 @@ #include "dialogs/memo-editor.h" #include "e-cal-model-memos.h" #include "e-memo-table.h" +#include "e-calendar-view.h" #include "e-cell-date-edit-text.h" -#include "e-comp-editor-registry.h" #include "print.h" #include <e-util/e-icon-factory.h> -#include <e-util/e-util-private.h> #include "e-cal-popup.h" -#include "e-calendar-table.h" +#include "misc.h" + +#define E_MEMO_TABLE_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_MEMO_TABLE, EMemoTablePrivate)) + +struct _EMemoTablePrivate { + gpointer shell_view; /* weak pointer */ + ECalModel *model; +}; + +enum { + PROP_0, + PROP_MODEL, + PROP_SHELL_VIEW +}; -enum TargetType{ +enum { + OPEN_COMPONENT, + POPUP_EVENT, + STATUS_MESSAGE, + USER_CREATED, + LAST_SIGNAL +}; + +enum { TARGET_TYPE_VCALENDAR }; static GtkTargetEntry target_types[] = { - { "text/x-calendar", 0, TARGET_TYPE_VCALENDAR }, - { "text/calendar", 0, TARGET_TYPE_VCALENDAR } + { "text/calendar", 0, TARGET_TYPE_VCALENDAR }, + { "text/x-calendar", 0, TARGET_TYPE_VCALENDAR } }; static guint n_target_types = G_N_ELEMENTS (target_types); - -extern ECompEditorRegistry *comp_editor_registry; - -static void e_memo_table_class_init (EMemoTableClass *klass); -static void e_memo_table_init (EMemoTable *memo_table); -static void e_memo_table_destroy (GtkObject *object); - -static void e_memo_table_on_double_click (ETable *table, - gint row, - gint col, - GdkEvent *event, - EMemoTable *memo_table); -static gint e_memo_table_show_popup_menu (ETable *table, - GdkEvent *gdk_event, - EMemoTable *memo_table); - -static gint e_memo_table_on_right_click (ETable *table, - gint row, - gint col, - GdkEvent *event, - EMemoTable *memo_table); -static gboolean e_memo_table_on_popup_menu (GtkWidget *widget, - gpointer data); - -static gint e_memo_table_on_key_press (ETable *table, - gint row, - 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); - -/* Signal IDs */ -enum { - USER_CREATED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; +static gpointer parent_class; +static guint signals[LAST_SIGNAL]; +static GdkAtom clipboard_atom; /* The icons to represent the task. */ #define E_MEMO_MODEL_NUM_ICONS 2 @@ -119,37 +107,45 @@ static const char* icon_names[E_MEMO_MODEL_NUM_ICONS] = { }; static GdkPixbuf* icon_pixbufs[E_MEMO_MODEL_NUM_ICONS] = { NULL }; -static GdkAtom clipboard_atom = GDK_NONE; - -G_DEFINE_TYPE (EMemoTable, e_memo_table, GTK_TYPE_TABLE) +static void +memo_table_emit_open_component (EMemoTable *memo_table, + ECalModelComponent *comp_data) +{ + guint signal_id = signals[OPEN_COMPONENT]; + g_signal_emit (memo_table, signal_id, 0, comp_data); +} static void -e_memo_table_class_init (EMemoTableClass *klass) +memo_table_emit_popup_event (EMemoTable *memo_table, + GdkEvent *event) { - GtkObjectClass *object_class; + guint signal_id = signals[POPUP_EVENT]; - object_class = (GtkObjectClass *) klass; + g_signal_emit (memo_table, signal_id, 0, event); +} - /* Method override */ - object_class->destroy = e_memo_table_destroy; +static void +memo_table_emit_status_message (EMemoTable *memo_table, + const gchar *message, + gdouble percent) +{ + guint signal_id = signals[STATUS_MESSAGE]; - signals[USER_CREATED] = - g_signal_new ("user_created", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EMemoTableClass, user_created), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); + g_signal_emit (memo_table, signal_id, 0, message, percent); +} + +static void +memo_table_emit_user_created (EMemoTable *memo_table) +{ + guint signal_id = signals[USER_CREATED]; - /* clipboard atom */ - if (!clipboard_atom) - clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE); + g_signal_emit (memo_table, signal_id, 0); } static gint -date_compare_cb (gconstpointer a, gconstpointer b) +memo_table_date_compare_cb (gconstpointer a, + gconstpointer b) { ECellDateEditValue *dv1 = (ECellDateEditValue *) a; ECellDateEditValue *dv2 = (ECellDateEditValue *) b; @@ -177,76 +173,408 @@ date_compare_cb (gconstpointer a, gconstpointer b) } static void -row_appended_cb (ECalModel *model, EMemoTable *memo_table) +memo_table_double_click_cb (EMemoTable *memo_table, + gint row, + gint col, + GdkEvent *event) +{ + ECalModel *model; + ECalModelComponent *comp_data; + + model = e_memo_table_get_model (memo_table); + comp_data = e_cal_model_get_component_at (model, row); + memo_table_emit_open_component (memo_table, comp_data); +} + +static void +memo_table_model_cal_view_progress_cb (EMemoTable *memo_table, + const gchar *message, + gint progress, + ECalSourceType type) { - g_signal_emit (memo_table, signals[USER_CREATED], 0); + gdouble percent = (gdouble) progress; + + memo_table_emit_status_message (memo_table, message, percent); +} + +static void +memo_table_model_cal_view_done_cb (EMemoTable *memo_table, + ECalendarStatus status, + ECalSourceType type) +{ + memo_table_emit_status_message (memo_table, NULL, -1.0); } static gboolean -query_tooltip_cb (GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, gpointer user_data) +memo_table_query_tooltip_cb (EMemoTable *memo_table, + gint x, + gint y, + gboolean keyboard_mode, + GtkTooltip *tooltip) { - EMemoTable *memo_table; + ECalModel *model; + ECalModelComponent *comp_data; + int row = -1, col = -1; + GtkWidget *box, *l, *w; + GtkStyle *style = gtk_widget_get_default_style (); + char *tmp; + const char *str; + GString *tmp2; + char buff[1001]; + gboolean free_text = FALSE; + ECalComponent *new_comp; + ECalComponentOrganizer organizer; + ECalComponentDateTime dtstart, dtdue; + icalcomponent *clone; + icaltimezone *zone, *default_zone; + GSList *desc, *p; + int len; + ETable *etable; + ESelectionModel *esm; + struct tm tmp_tm; + + if (keyboard_mode) + return FALSE; + + etable = e_memo_table_get_table (memo_table); + e_table_get_mouse_over_cell (etable, &row, &col); + if (row == -1 || !etable) + return FALSE; + + /* Respect sorting option; the 'e_table_get_mouse_over_cell' + * returns sorted row, not the model one. */ + esm = e_table_get_selection_model (etable); + if (esm && esm->sorter && e_sorter_needs_sorting (esm->sorter)) + row = e_sorter_sorted_to_model (esm->sorter, row); + + model = e_memo_table_get_model (memo_table); + comp_data = e_cal_model_get_component_at (model, row); + if (!comp_data || !comp_data->icalcomp) + return FALSE; + + new_comp = e_cal_component_new (); + clone = icalcomponent_new_clone (comp_data->icalcomp); + if (!e_cal_component_set_icalcomponent (new_comp, clone)) { + g_object_unref (new_comp); + return FALSE; + } + + box = gtk_vbox_new (FALSE, 0); + + str = e_calendar_view_get_icalcomponent_summary ( + comp_data->client, comp_data->icalcomp, &free_text); + if (!(str && *str)) { + if (free_text) + g_free ((char *)str); + free_text = FALSE; + str = _("* No Summary *"); + } + + l = gtk_label_new (NULL); + tmp = g_markup_printf_escaped ("<b>%s</b>", str); + gtk_label_set_line_wrap (GTK_LABEL (l), TRUE); + gtk_label_set_markup (GTK_LABEL (l), tmp); + gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5); + w = gtk_event_box_new (); + + gtk_widget_modify_bg (w, GTK_STATE_NORMAL, &(style->bg[GTK_STATE_SELECTED])); + gtk_widget_modify_fg (l, GTK_STATE_NORMAL, &(style->text[GTK_STATE_SELECTED])); + gtk_container_add (GTK_CONTAINER (w), l); + gtk_box_pack_start (GTK_BOX (box), w, TRUE, TRUE, 0); + g_free (tmp); + + if (free_text) + g_free ((char *)str); + free_text = FALSE; + + w = gtk_event_box_new (); + gtk_widget_modify_bg (w, GTK_STATE_NORMAL, &(style->bg[GTK_STATE_NORMAL])); + + l = gtk_vbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (w), l); + gtk_box_pack_start (GTK_BOX (box), w, FALSE, FALSE, 0); + w = l; + + e_cal_component_get_organizer (new_comp, &organizer); + if (organizer.cn) { + char *ptr ; + ptr = strchr( organizer.value, ':'); + + if (ptr) { + ptr++; + /* To Translators: It will display "Organizer: NameOfTheUser <email@ofuser.com>" */ + tmp = g_strdup_printf (_("Organizer: %s <%s>"), organizer.cn, ptr); + } else { + /* With SunOne accounts, there may be no ':' in organiser.value */ + tmp = g_strdup_printf (_("Organizer: %s"), organizer.cn); + } + + l = gtk_label_new (tmp); + gtk_label_set_line_wrap (GTK_LABEL (l), FALSE); + gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5); + gtk_box_pack_start (GTK_BOX (w), l, FALSE, FALSE, 0); + g_free (tmp); + } + + e_cal_component_get_dtstart (new_comp, &dtstart); + e_cal_component_get_due (new_comp, &dtdue); + + default_zone = e_cal_model_get_timezone (model); + + if (dtstart.tzid) { + zone = icalcomponent_get_timezone (e_cal_component_get_icalcomponent (new_comp), dtstart.tzid); + if (!zone) + e_cal_get_timezone ( + comp_data->client, dtstart.tzid, &zone, NULL); + if (!zone) + zone = default_zone; + } else { + zone = NULL; + } + + tmp2 = g_string_new (""); + + if (dtstart.value) { + buff[0] = 0; + + tmp_tm = icaltimetype_to_tm_with_zone ( + dtstart.value, zone, default_zone); + e_time_format_date_and_time ( + &tmp_tm, calendar_config_get_24_hour_format (), + FALSE, FALSE, buff, 1000); + + if (buff [0]) { + g_string_append (tmp2, _("Start: ")); + g_string_append (tmp2, buff); + } + } + + if (dtdue.value) { + buff[0] = 0; + + tmp_tm = icaltimetype_to_tm_with_zone ( + dtdue.value, zone, default_zone); + e_time_format_date_and_time ( + &tmp_tm, calendar_config_get_24_hour_format (), + FALSE, FALSE, buff, 1000); + + if (buff [0]) { + if (tmp2->len) + g_string_append (tmp2, "; "); + + g_string_append (tmp2, _("Due: ")); + g_string_append (tmp2, buff); + } + } + + if (tmp2->len) { + l = gtk_label_new (tmp2->str); + gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5); + gtk_box_pack_start (GTK_BOX (w), l, FALSE, FALSE, 0); + } + + g_string_free (tmp2, TRUE); + + e_cal_component_free_datetime (&dtstart); + e_cal_component_free_datetime (&dtdue); + + tmp2 = g_string_new (""); + e_cal_component_get_description_list (new_comp, &desc); + for (len = 0, p = desc; p != NULL; p = p->next) { + ECalComponentText *text = p->data; + + if (text->value != NULL) { + len += strlen (text->value); + g_string_append (tmp2, text->value); + if (len > 1024) { + g_string_set_size (tmp2, 1020); + g_string_append (tmp2, "..."); + break; + } + } + } + e_cal_component_free_text_list (desc); + + if (tmp2->len) { + l = gtk_label_new (tmp2->str); + gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5); + gtk_box_pack_start (GTK_BOX (box), l, FALSE, FALSE, 0); + } + + g_string_free (tmp2, TRUE); + + gtk_widget_show_all (box); + gtk_tooltip_set_custom (tooltip, box); + + g_object_unref (new_comp); + + return TRUE; +} + +static gboolean +memo_table_popup_menu_cb (EMemoTable *memo_table) +{ + memo_table_emit_popup_event (memo_table, NULL); + + return TRUE; +} + +static gint +memo_table_right_click_cb (EMemoTable *memo_table, + gint row, + gint col, + GdkEvent *event) +{ + memo_table_emit_popup_event (memo_table, event); + + return TRUE; +} + +static void +memo_table_set_model (EMemoTable *memo_table, + ECalModel *model) +{ + g_return_if_fail (memo_table->priv->model == NULL); + + memo_table->priv->model = g_object_ref (model); + + g_signal_connect_swapped ( + model, "row-appended", + G_CALLBACK (memo_table_emit_user_created), memo_table); + + g_signal_connect_swapped ( + model, "cal-view-progress", + G_CALLBACK (memo_table_model_cal_view_progress_cb), + memo_table); + + g_signal_connect_swapped ( + model, "cal-view-done", + G_CALLBACK (memo_table_model_cal_view_done_cb), + memo_table); +} + +static void +memo_table_set_shell_view (EMemoTable *memo_table, + EShellView *shell_view) +{ + g_return_if_fail (memo_table->priv->shell_view == NULL); + + memo_table->priv->shell_view = shell_view; + + g_object_add_weak_pointer ( + G_OBJECT (shell_view), + &memo_table->priv->shell_view); +} + +static void +memo_table_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_MODEL: + memo_table_set_model ( + E_MEMO_TABLE (object), + g_value_get_object (value)); + return; + + case PROP_SHELL_VIEW: + memo_table_set_shell_view ( + E_MEMO_TABLE (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +memo_table_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_MODEL: + g_value_set_object ( + value, e_memo_table_get_model ( + E_MEMO_TABLE (object))); + return; + + case PROP_SHELL_VIEW: + g_value_set_object ( + value, e_memo_table_get_shell_view ( + E_MEMO_TABLE (object))); + return; + } - g_return_val_if_fail (E_IS_MEMO_TABLE (user_data), FALSE); + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +memo_table_dispose (GObject *object) +{ + EMemoTablePrivate *priv; - memo_table = E_MEMO_TABLE (user_data); + priv = E_MEMO_TABLE_GET_PRIVATE (object); - return ec_query_tooltip (widget, x, y, keyboard_mode, tooltip, GTK_WIDGET (e_memo_table_get_table (memo_table)), memo_table->model); + if (priv->model != NULL) { + g_object_unref (priv->model); + priv->model = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); } static void -e_memo_table_init (EMemoTable *memo_table) +memo_table_constructed (GObject *object) { - GtkWidget *table; - ETable *e_table; + EMemoTable *memo_table; + GtkWidget *widget; + ECalModel *model; + ETable *table; ECell *cell, *popup_cell; ETableExtras *extras; gint i; AtkObject *a11y; gchar *etspecfile; - /* Create the model */ - - memo_table->model = (ECalModel *) e_cal_model_memos_new (); - g_signal_connect (memo_table->model, "row_appended", G_CALLBACK (row_appended_cb), memo_table); - - memo_table->user_created_cal = NULL; + memo_table = E_MEMO_TABLE (object); + model = e_memo_table_get_model (memo_table); /* Create the header columns */ - extras = e_table_extras_new(); + extras = e_table_extras_new (); /* * Normal string fields. */ cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT); - g_object_set (G_OBJECT (cell), - "bg_color_column", E_CAL_MODEL_FIELD_COLOR, - NULL); - + g_object_set (cell, "bg_color_column", E_CAL_MODEL_FIELD_COLOR, NULL); 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); + g_object_set (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); + 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); + e_table_extras_add_compare ( + extras, "date-compare", memo_table_date_compare_cb); /* Create pixmaps */ @@ -256,60 +584,180 @@ e_memo_table_init (EMemoTable *memo_table) } cell = e_cell_toggle_new (0, E_MEMO_MODEL_NUM_ICONS, icon_pixbufs); - e_table_extras_add_cell(extras, "icon", cell); - e_table_extras_add_pixbuf(extras, "icon", icon_pixbufs[0]); + e_table_extras_add_cell (extras, "icon", cell); + e_table_extras_add_pixbuf (extras, "icon", icon_pixbufs[0]); /* Create the table */ - etspecfile = g_build_filename (EVOLUTION_ETSPECDIR, - "e-memo-table.etspec", - NULL); - table = e_table_scrolled_new_from_spec_file (E_TABLE_MODEL (memo_table->model), - extras, - etspecfile, - NULL); + etspecfile = g_build_filename ( + EVOLUTION_ETSPECDIR, "e-memo-table.etspec", NULL); + widget = e_table_scrolled_new_from_spec_file ( + E_TABLE_MODEL (model), extras, etspecfile, NULL); + gtk_table_attach ( + GTK_TABLE (memo_table), widget, 0, 1, 0, 1, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + memo_table->etable = widget; + gtk_widget_show (widget); g_free (etspecfile); - /* FIXME: this causes a message from GLib about 'extras' having only a floating - reference */ - /* g_object_unref (extras); */ + table = e_table_scrolled_get_table (E_TABLE_SCROLLED (widget)); + g_signal_connect_swapped ( + table, "double-click", + G_CALLBACK (memo_table_double_click_cb), memo_table); + g_signal_connect_swapped ( + table, "query-tooltip", + G_CALLBACK (memo_table_query_tooltip_cb), memo_table); + g_signal_connect_swapped ( + table, "popup-menu", + G_CALLBACK (memo_table_popup_menu_cb), memo_table); + g_signal_connect_swapped ( + table, "right-click", + G_CALLBACK (memo_table_right_click_cb), memo_table); + gtk_widget_set_has_tooltip (GTK_WIDGET (table), TRUE); + + a11y = gtk_widget_get_accessible (GTK_WIDGET (table)); + if (a11y) + atk_object_set_name (a11y, _("Memos")); +} - memo_table->etable = table; - gtk_table_attach (GTK_TABLE (memo_table), table, 0, 1, 0, 1, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - gtk_widget_show (table); +static void +memo_table_class_init (EMemoTableClass *class) +{ + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EMemoTablePrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = memo_table_set_property; + object_class->get_property = memo_table_get_property; + object_class->dispose = memo_table_dispose; + object_class->constructed = memo_table_constructed; + + g_object_class_install_property ( + object_class, + PROP_MODEL, + g_param_spec_object ( + "model", + _("Model"), + NULL, + E_TYPE_CAL_MODEL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property ( + object_class, + PROP_SHELL_VIEW, + g_param_spec_object ( + "shell-view", + _("Shell View"), + NULL, + E_TYPE_SHELL_VIEW, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + + signals[OPEN_COMPONENT] = g_signal_new ( + "open-component", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (EMemoTableClass, open_component), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + E_TYPE_CAL_MODEL_COMPONENT); + + signals[POPUP_EVENT] = g_signal_new ( + "popup-event", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (EMemoTableClass, popup_event), + NULL, NULL, + g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, 1, + GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); + + signals[STATUS_MESSAGE] = g_signal_new ( + "status-message", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (EMemoTableClass, status_message), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, + G_TYPE_STRING); + + signals[USER_CREATED] = g_signal_new ( + "user-created", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (EMemoTableClass, user_created), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE); +} +static void +memo_table_init (EMemoTable *memo_table) +{ + memo_table->priv = E_MEMO_TABLE_GET_PRIVATE (memo_table); +} - e_table = e_table_scrolled_get_table (E_TABLE_SCROLLED (table)); - g_signal_connect (e_table, "double_click", G_CALLBACK (e_memo_table_on_double_click), memo_table); - g_signal_connect (e_table, "right_click", G_CALLBACK (e_memo_table_on_right_click), memo_table); - g_signal_connect (e_table, "key_press", G_CALLBACK (e_memo_table_on_key_press), memo_table); - g_signal_connect (e_table, "popup_menu", G_CALLBACK (e_memo_table_on_popup_menu), memo_table); - g_signal_connect (e_table, "query-tooltip", G_CALLBACK (query_tooltip_cb), memo_table); - gtk_widget_set_has_tooltip (GTK_WIDGET (e_table), TRUE); +GType +e_memo_table_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EMemoTableClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) memo_table_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EMemoTable), + 0, /* n_preallocs */ + (GInstanceInitFunc) memo_table_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + GTK_TYPE_TABLE, "EMemoTable", &type_info, 0); + } - a11y = gtk_widget_get_accessible (GTK_WIDGET(e_table)); - if (a11y) - atk_object_set_name (a11y, _("Memos")); + return type; } - /** * e_memo_table_new: - * @Returns: a new #EMemoTable. + * @shell_view: an #EShellView + * @model: an #ECalModel for the table + * + * Returns a new #EMemoTable. * - * Creates a new #EMemoTable. + * Returns: a new #EMemoTable **/ GtkWidget * -e_memo_table_new (void) +e_memo_table_new (EShellView *shell_view, + ECalModel *model) { - GtkWidget *memo_table; - - memo_table = GTK_WIDGET (g_object_new (e_memo_table_get_type (), NULL)); + g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); + g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL); - return memo_table; + return g_object_new ( + E_TYPE_MEMO_TABLE, + "model", model, "shell-view", shell_view, NULL); } +EShellView * +e_memo_table_get_shell_view (EMemoTable *memo_table) +{ + g_return_val_if_fail (E_IS_MEMO_TABLE (memo_table), NULL); + + return memo_table->priv->shell_view; +} /** * e_memo_table_get_model: @@ -325,25 +773,10 @@ e_memo_table_get_model (EMemoTable *memo_table) g_return_val_if_fail (memo_table != NULL, NULL); g_return_val_if_fail (E_IS_MEMO_TABLE (memo_table), NULL); - return memo_table->model; + return memo_table->priv->model; } -static void -e_memo_table_destroy (GtkObject *object) -{ - EMemoTable *memo_table; - - memo_table = E_MEMO_TABLE (object); - - if (memo_table->model) { - g_object_unref (memo_table->model); - memo_table->model = NULL; - } - - GTK_OBJECT_CLASS (e_memo_table_parent_class)->destroy (object); -} - /** * e_memo_table_get_table: * @memo_table: A calendar table. @@ -356,20 +789,13 @@ e_memo_table_destroy (GtkObject *object) ETable * e_memo_table_get_table (EMemoTable *memo_table) { - g_return_val_if_fail (memo_table != NULL, NULL); - g_return_val_if_fail (E_IS_MEMO_TABLE (memo_table), NULL); + ETableScrolled *table_scrolled; - return e_table_scrolled_get_table (E_TABLE_SCROLLED (memo_table->etable)); -} + g_return_val_if_fail (E_IS_MEMO_TABLE (memo_table), NULL); -void -e_memo_table_open_selected (EMemoTable *memo_table) -{ - ECalModelComponent *comp_data; + table_scrolled = E_TABLE_SCROLLED (memo_table->etable); - comp_data = get_selected_comp (memo_table); - if (comp_data != NULL) - open_memo (memo_table, comp_data); + return e_table_scrolled_get_table (table_scrolled); } /* Used from e_table_selected_row_foreach(); puts the selected row number in an @@ -391,10 +817,12 @@ get_selected_row_cb (int model_row, gpointer data) static ECalModelComponent * get_selected_comp (EMemoTable *memo_table) { + ECalModel *model; ETable *etable; int row; - etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (memo_table->etable)); + model = e_memo_table_get_model (memo_table); + etable = e_memo_table_get_table (memo_table); if (e_table_selected_count (etable) != 1) return NULL; @@ -404,7 +832,7 @@ get_selected_comp (EMemoTable *memo_table) &row); g_return_val_if_fail (row != -1, NULL); - return e_cal_model_get_component_at (memo_table->model, row); + return e_cal_model_get_component_at (model, row); } struct get_selected_uids_closure { @@ -418,38 +846,27 @@ add_uid_cb (int model_row, gpointer data) { struct get_selected_uids_closure *closure; ECalModelComponent *comp_data; + ECalModel *model; closure = data; - comp_data = e_cal_model_get_component_at (closure->memo_table->model, model_row); + model = e_memo_table_get_model (closure->memo_table); + comp_data = e_cal_model_get_component_at (model, model_row); closure->objects = g_slist_prepend (closure->objects, comp_data); } -static GSList * -get_selected_objects (EMemoTable *memo_table) -{ - struct get_selected_uids_closure closure; - ETable *etable; - - closure.memo_table = memo_table; - closure.objects = NULL; - - etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (memo_table->etable)); - e_table_selected_row_foreach (etable, add_uid_cb, &closure); - - return closure.objects; -} - /* Deletes all of the selected components in the table */ static void delete_selected_components (EMemoTable *memo_table) { GSList *objs, *l; + const gchar *status_message; - objs = get_selected_objects (memo_table); + objs = e_memo_table_get_selected (memo_table); - e_memo_table_set_status_message (memo_table, _("Deleting selected objects")); + status_message = _("Deleting selected objects"); + memo_table_emit_status_message (memo_table, status_message, -1.0); for (l = objs; l; l = l->next) { ECalModelComponent *comp_data = (ECalModelComponent *) l->data; @@ -461,27 +878,12 @@ delete_selected_components (EMemoTable *memo_table) g_clear_error (&error); } - e_memo_table_set_status_message (memo_table, NULL); + memo_table_emit_status_message (memo_table, NULL, -1.0); g_slist_free (objs); } /** - * e_memo_table_get_selected: - * @memo_table: - * - * Get the currently selected ECalModelComponent's on the table. - * - * Return value: A GSList of the components, which should be - * g_slist_free'd when finished with. - **/ -GSList * -e_memo_table_get_selected (EMemoTable *memo_table) -{ - return get_selected_objects(memo_table); -} - -/** * e_memo_table_delete_selected: * @memo_table: A memo table. * @@ -498,7 +900,7 @@ e_memo_table_delete_selected (EMemoTable *memo_table) g_return_if_fail (memo_table != NULL); g_return_if_fail (E_IS_MEMO_TABLE (memo_table)); - etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (memo_table->etable)); + etable = e_memo_table_get_table (memo_table); n_selected = e_table_selected_count (etable); if (n_selected <= 0) @@ -526,6 +928,30 @@ e_memo_table_delete_selected (EMemoTable *memo_table) } /** + * e_memo_table_get_selected: + * @memo_table: + * + * Get the currently selected ECalModelComponent's on the table. + * + * Return value: A GSList of the components, which should be + * g_slist_free'd when finished with. + **/ +GSList * +e_memo_table_get_selected (EMemoTable *memo_table) +{ + struct get_selected_uids_closure closure; + ETable *etable; + + closure.memo_table = memo_table; + closure.objects = NULL; + + etable = e_memo_table_get_table (memo_table); + e_table_selected_row_foreach (etable, add_uid_cb, &closure); + + return closure.objects; +} + +/** * e_memo_table_cut_clipboard: * @memo_table: A calendar table. * @@ -540,12 +966,33 @@ e_memo_table_cut_clipboard (EMemoTable *memo_table) delete_selected_components (memo_table); } +static void +clipboard_get_calendar_cb (GtkClipboard *clipboard, + GtkSelectionData *selection_data, + guint info, + gpointer data) +{ + gchar *comp_str = (gchar *) data; + + switch (info) { + case TARGET_TYPE_VCALENDAR: + gtk_selection_data_set (selection_data, + gdk_atom_intern (target_types[info].target, FALSE), 8, + (const guchar *) comp_str, + (gint) strlen (comp_str)); + break; + default: + break; + } +} + /* callback for e_table_selected_row_foreach */ static void copy_row_cb (int model_row, gpointer data) { EMemoTable *memo_table; ECalModelComponent *comp_data; + ECalModel *model; gchar *comp_str; icalcomponent *child; @@ -553,7 +1000,8 @@ copy_row_cb (int model_row, gpointer data) g_return_if_fail (memo_table->tmp_vcal != NULL); - comp_data = e_cal_model_get_component_at (memo_table->model, model_row); + model = e_memo_table_get_model (memo_table); + comp_data = e_cal_model_get_component_at (model, model_row); if (!comp_data) return; @@ -571,26 +1019,6 @@ copy_row_cb (int model_row, gpointer data) g_free (comp_str); } -static void -clipboard_get_calendar_cb (GtkClipboard *clipboard, - GtkSelectionData *selection_data, - guint info, - gpointer data) -{ - gchar *comp_str = (gchar *) data; - - switch (info) { - case TARGET_TYPE_VCALENDAR: - gtk_selection_data_set (selection_data, - gdk_atom_intern (target_types[info].target, FALSE), 8, - (const guchar *) comp_str, - (gint) strlen (comp_str)); - break; - default: - break; - } -} - /** * e_memo_table_copy_clipboard: * @memo_table: A calendar table. @@ -609,7 +1037,7 @@ e_memo_table_copy_clipboard (EMemoTable *memo_table) /* create temporary VCALENDAR object */ memo_table->tmp_vcal = e_cal_util_new_top_level (); - etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (memo_table->etable)); + etable = e_memo_table_get_table (memo_table); e_table_selected_row_foreach (etable, copy_row_cb, memo_table); comp_str = icalcomponent_as_ical_string_r (memo_table->tmp_vcal); clipboard = gtk_widget_get_clipboard (GTK_WIDGET (memo_table), clipboard_atom); @@ -634,7 +1062,9 @@ clipboard_get_calendar_data (EMemoTable *memo_table, const gchar *text) char *uid; ECalComponent *comp; ECal *client; + ECalModel *model; icalcomponent_kind kind; + const gchar *status_message; g_return_if_fail (E_IS_MEMO_TABLE (memo_table)); @@ -648,13 +1078,17 @@ clipboard_get_calendar_data (EMemoTable *memo_table, const gchar *text) /* check the type of the component */ kind = icalcomponent_isa (icalcomp); if (kind != ICAL_VCALENDAR_COMPONENT && + kind != ICAL_VEVENT_COMPONENT && + kind != ICAL_VTODO_COMPONENT && kind != ICAL_VJOURNAL_COMPONENT) { return; } - client = e_cal_model_get_default_client (memo_table->model); + model = e_memo_table_get_model (memo_table); + client = e_cal_model_get_default_client (model); - e_memo_table_set_status_message (memo_table, _("Updating objects")); + status_message = _("Updating objects"); + memo_table_emit_status_message (memo_table, status_message, -1.0); if (kind == ICAL_VCALENDAR_COMPONENT) { icalcomponent_kind child_kind; @@ -666,7 +1100,9 @@ clipboard_get_calendar_data (EMemoTable *memo_table, const gchar *text) vcal_comp, ICAL_ANY_COMPONENT); while (subcomp) { child_kind = icalcomponent_isa (subcomp); - if (child_kind == ICAL_VJOURNAL_COMPONENT) { + if (child_kind == ICAL_VEVENT_COMPONENT || + child_kind == ICAL_VTODO_COMPONENT || + child_kind == ICAL_VJOURNAL_COMPONENT) { ECalComponent *tmp_comp; uid = e_cal_component_gen_uid (); @@ -697,7 +1133,7 @@ clipboard_get_calendar_data (EMemoTable *memo_table, const gchar *text) g_object_unref (comp); } - e_memo_table_set_status_message (memo_table, NULL); + memo_table_emit_status_message (memo_table, NULL, -1.0); } static void @@ -706,7 +1142,7 @@ clipboard_paste_received_cb (GtkClipboard *clipboard, gpointer data) { EMemoTable *memo_table = E_MEMO_TABLE (data); - ETable *e_table = e_table_scrolled_get_table (E_TABLE_SCROLLED (memo_table->etable)); + ETable *e_table = e_memo_table_get_table (memo_table); GnomeCanvas *canvas = e_table->table_canvas; GnomeCanvasItem *item = GNOME_CANVAS (canvas)->focused_item; @@ -741,335 +1177,44 @@ void e_memo_table_paste_clipboard (EMemoTable *memo_table) { GtkClipboard *clipboard; - g_return_if_fail (E_IS_MEMO_TABLE (memo_table)); - - - clipboard = gtk_widget_get_clipboard (GTK_WIDGET (memo_table), clipboard_atom); - g_object_ref (memo_table); - - gtk_clipboard_request_contents (clipboard, - gdk_atom_intern (target_types[0].target, FALSE), - clipboard_paste_received_cb, memo_table); -} - -/* Opens a task in the task editor */ -static void -open_memo (EMemoTable *memo_table, ECalModelComponent *comp_data) -{ - CompEditor *medit; - const char *uid; - - uid = icalcomponent_get_uid (comp_data->icalcomp); - - medit = e_comp_editor_registry_find (comp_editor_registry, uid); - if (medit == NULL) { - ECalComponent *comp; - 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 = memo_editor_new (comp_data->client, flags); - - comp_editor_edit_comp (medit, comp); - g_object_unref (comp); - - e_comp_editor_registry_add (comp_editor_registry, medit, FALSE); - } - - gtk_window_present (GTK_WINDOW (medit)); -} - -/* Opens the task in the specified row */ -static void -open_memo_by_row (EMemoTable *memo_table, int row) -{ - ECalModelComponent *comp_data; - - comp_data = e_cal_model_get_component_at (memo_table->model, row); - open_memo (memo_table, comp_data); -} - -static void -e_memo_table_on_double_click (ETable *table, - gint row, - gint col, - GdkEvent *event, - EMemoTable *memo_table) -{ - open_memo_by_row (memo_table, row); -} - - -static void -e_memo_table_on_open_memo (EPopup *ep, EPopupItem *pitem, void *data) -{ - EMemoTable *memo_table = E_MEMO_TABLE (data); - ECalModelComponent *comp_data; - - comp_data = get_selected_comp (memo_table); - if (comp_data) - open_memo (memo_table, comp_data); -} - -static void -e_memo_table_on_save_as (EPopup *ep, EPopupItem *pitem, void *data) -{ - EMemoTable *memo_table = E_MEMO_TABLE (data); - ECalModelComponent *comp_data; - char *filename; - char *ical_string; - - comp_data = get_selected_comp (memo_table); - if (comp_data == NULL) - return; - - filename = e_file_dialog_save (_("Save as..."), NULL); - if (filename == NULL) - return; - - ical_string = e_cal_get_component_as_string (comp_data->client, comp_data->icalcomp); - if (ical_string == NULL) { - g_warning ("Couldn't convert item to a string"); - return; - } - - e_write_file_uri (filename, ical_string); - g_free (ical_string); -} - -static void -e_memo_table_on_print_memo (EPopup *ep, EPopupItem *pitem, void *data) -{ - EMemoTable *memo_table = E_MEMO_TABLE (data); - ECalModelComponent *comp_data; - ECalComponent *comp; - - comp_data = get_selected_comp (memo_table); - if (comp_data == NULL) - return; - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp)); - print_comp (comp, comp_data->client, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG); - - g_object_unref (comp); -} - -static void -e_memo_table_on_cut (EPopup *ep, EPopupItem *pitem, void *data) -{ - EMemoTable *memo_table = E_MEMO_TABLE (data); - - e_memo_table_cut_clipboard (memo_table); -} - -static void -e_memo_table_on_copy (EPopup *ep, EPopupItem *pitem, void *data) -{ - EMemoTable *memo_table = E_MEMO_TABLE (data); - - e_memo_table_copy_clipboard (memo_table); -} - -static void -e_memo_table_on_paste (EPopup *ep, EPopupItem *pitem, void *data) -{ - EMemoTable *memo_table = E_MEMO_TABLE (data); - - e_memo_table_paste_clipboard (memo_table); -} - -static void -e_memo_table_on_forward (EPopup *ep, EPopupItem *pitem, void *data) -{ - EMemoTable *memo_table = E_MEMO_TABLE (data); - ECalModelComponent *comp_data; - - comp_data = get_selected_comp (memo_table); - if (comp_data) { - ECalComponent *comp; - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp)); - itip_send_comp (E_CAL_COMPONENT_METHOD_PUBLISH, comp, comp_data->client, NULL, NULL, NULL, TRUE); - - g_object_unref (comp); - } -} - -/* Opens the URL of the memo */ -static void -open_url_cb (EPopup *ep, EPopupItem *pitem, void *data) -{ - EMemoTable *memo_table = E_MEMO_TABLE (data); - ECalModelComponent *comp_data; - icalproperty *prop; - - comp_data = get_selected_comp (memo_table); - if (!comp_data) - return; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_URL_PROPERTY); - if (!prop) - return; - - /* FIXME Pass a parent window. */ - e_show_uri (NULL, icalproperty_get_url (prop)); -} - -/* Callback for the "delete tasks" menu item */ -static void -delete_cb (EPopup *ep, EPopupItem *pitem, void *data) -{ - EMemoTable *memo_table = E_MEMO_TABLE (data); - - e_memo_table_delete_selected (memo_table); -} - -static EPopupItem memos_popup_items [] = { - { E_POPUP_ITEM, "00.open", N_("_Open"), e_memo_table_on_open_memo, NULL, GTK_STOCK_OPEN, E_CAL_POPUP_SELECT_ONE }, - { E_POPUP_ITEM, "05.openweb", N_("Open _Web Page"), open_url_cb, NULL, NULL, E_CAL_POPUP_SELECT_ONE, E_CAL_POPUP_SELECT_HASURL }, - { E_POPUP_ITEM, "10.saveas", N_("_Save As..."), e_memo_table_on_save_as, NULL, GTK_STOCK_SAVE_AS, E_CAL_POPUP_SELECT_ONE }, - { E_POPUP_ITEM, "20.print", N_("P_rint..."), e_memo_table_on_print_memo, NULL, GTK_STOCK_PRINT, E_CAL_POPUP_SELECT_ONE }, - - { E_POPUP_BAR, "30.bar" }, - - { E_POPUP_ITEM, "40.cut", N_("C_ut"), e_memo_table_on_cut, NULL, GTK_STOCK_CUT, 0, E_CAL_POPUP_SELECT_EDITABLE }, - { E_POPUP_ITEM, "50.copy", N_("_Copy"), e_memo_table_on_copy, NULL, GTK_STOCK_COPY, 0, 0 }, - { E_POPUP_ITEM, "60.paste", N_("_Paste"), e_memo_table_on_paste, NULL, GTK_STOCK_PASTE, 0, E_CAL_POPUP_SELECT_EDITABLE }, - - { E_POPUP_BAR, "70.bar" }, - - { E_POPUP_ITEM, "80.forward", N_("_Forward as iCalendar"), e_memo_table_on_forward, NULL, "mail-forward", E_CAL_POPUP_SELECT_ONE }, - - { E_POPUP_BAR, "90.bar" }, - { E_POPUP_ITEM, "a0.delete", N_("_Delete"), delete_cb, NULL, GTK_STOCK_DELETE, E_CAL_POPUP_SELECT_ONE, E_CAL_POPUP_SELECT_EDITABLE }, - { E_POPUP_ITEM, "b0.deletemany", N_("_Delete Selected Memos"), delete_cb, NULL, GTK_STOCK_DELETE, E_CAL_POPUP_SELECT_MANY, E_CAL_POPUP_SELECT_EDITABLE }, -}; - -static void -emt_popup_free(EPopup *ep, GSList *items, void *data) -{ - g_slist_free(items); -} - -static gint -e_memo_table_show_popup_menu (ETable *table, - GdkEvent *gdk_event, - EMemoTable *memo_table) -{ - GtkMenu *menu; - GSList *selection, *l, *menus = NULL; - GPtrArray *events; - ECalPopup *ep; - ECalPopupTargetSelect *t; - int i; - - selection = get_selected_objects (memo_table); - if (!selection) - return TRUE; - - /** @HookPoint-ECalPopup: Tasks Table Context Menu - * @Id: org.gnome.evolution.tasks.table.popup - * @Class: org.gnome.evolution.calendar.popup:1.0 - * @Target: ECalPopupTargetSelect - * - * The context menu on the tasks table. - */ - ep = e_cal_popup_new("org.gnome.evolution.memos.table.popup"); - - events = g_ptr_array_new(); - for (l=selection;l;l=g_slist_next(l)) - g_ptr_array_add(events, e_cal_model_copy_component_data((ECalModelComponent *)l->data)); - g_slist_free(selection); - - t = e_cal_popup_target_new_select(ep, memo_table->model, events); - t->target.widget = (GtkWidget *)memo_table; - - for (i=0;i<sizeof(memos_popup_items)/sizeof(memos_popup_items[0]);i++) - menus = g_slist_prepend(menus, &memos_popup_items[i]); - e_popup_add_items((EPopup *)ep, menus, NULL, emt_popup_free, memo_table); - - menu = e_popup_create_menu_once((EPopup *)ep, (EPopupTarget *)t, 0); - - gtk_menu_popup(menu, NULL, NULL, NULL, NULL, gdk_event?gdk_event->button.button:0, - gdk_event?gdk_event->button.time:gtk_get_current_event_time()); - - return TRUE; -} - -static gint -e_memo_table_on_right_click (ETable *table, - gint row, - gint col, - GdkEvent *event, - EMemoTable *memo_table) -{ - return e_memo_table_show_popup_menu (table, event, memo_table); -} + g_return_if_fail (E_IS_MEMO_TABLE (memo_table)); -static gboolean -e_memo_table_on_popup_menu (GtkWidget *widget, gpointer data) -{ - ETable *table = E_TABLE(widget); - g_return_val_if_fail(table, FALSE); + clipboard = gtk_widget_get_clipboard ( + GTK_WIDGET (memo_table), clipboard_atom); - return e_memo_table_show_popup_menu (table, NULL, - E_MEMO_TABLE(data)); -} - -static gint -e_memo_table_on_key_press (ETable *table, - gint row, - gint col, - GdkEventKey *event, - EMemoTable *memo_table) -{ - if (event->keyval == GDK_Delete) { - delete_cb (NULL, NULL, memo_table); - return TRUE; - } else if ((event->keyval == GDK_o) - &&(event->state & GDK_CONTROL_MASK)) { - open_memo_by_row (memo_table, row); - return TRUE; - } - - return FALSE; + gtk_clipboard_request_contents ( + clipboard, gdk_atom_intern (target_types[0].target, FALSE), + clipboard_paste_received_cb, g_object_ref (memo_table)); } /* Loads the state of the table (headers shown etc.) from the given file. */ void e_memo_table_load_state (EMemoTable *memo_table, - gchar *filename) + const gchar *filename) { - struct stat st; + ETable *table; g_return_if_fail (E_IS_MEMO_TABLE (memo_table)); + g_return_if_fail (filename != NULL); - if (g_stat (filename, &st) == 0 && st.st_size > 0 - && S_ISREG (st.st_mode)) { - e_table_load_state (e_table_scrolled_get_table (E_TABLE_SCROLLED (memo_table->etable)), filename); - } + table = e_memo_table_get_table (memo_table); + e_table_load_state (table, filename); } /* Saves the state of the table (headers shown etc.) to the given file. */ void -e_memo_table_save_state (EMemoTable *memo_table, - gchar *filename) +e_memo_table_save_state (EMemoTable *memo_table, + const gchar *filename) { + ETable *table; + g_return_if_fail (E_IS_MEMO_TABLE (memo_table)); + g_return_if_fail (filename != NULL); - e_table_save_state (e_table_scrolled_get_table (E_TABLE_SCROLLED (memo_table->etable)), - filename); + table = e_memo_table_get_table (memo_table); + e_table_save_state (table, filename); } /* Returns the current time, for the ECellDateEdit items. @@ -1098,45 +1243,3 @@ e_memo_table_get_current_time (ECellDateEdit *ecde, gpointer data) return tmp_tm; } - - -#ifdef TRANSLATORS_ONLY - -static char *test[] = { - N_("Click to add a memo") -}; - -#endif - -void -e_memo_table_set_activity_handler (EMemoTable *memo_table, EActivityHandler *activity_handler) -{ - g_return_if_fail (E_IS_MEMO_TABLE (memo_table)); - - memo_table->activity_handler = activity_handler; -} - -void -e_memo_table_set_status_message (EMemoTable *memo_table, const gchar *message) -{ - g_return_if_fail (E_IS_MEMO_TABLE (memo_table)); - - if (!memo_table->activity_handler) - return; - - if (!message || !*message) { - if (memo_table->activity_id != 0) { - e_activity_handler_operation_finished (memo_table->activity_handler, memo_table->activity_id); - memo_table->activity_id = 0; - } - } else if (memo_table->activity_id == 0) { - char *client_id = g_strdup_printf ("%p", memo_table); - - memo_table->activity_id = e_activity_handler_operation_started ( - memo_table->activity_handler, client_id, message, TRUE); - - g_free (client_id); - } else { - e_activity_handler_operation_progressing (memo_table->activity_handler, memo_table->activity_id, message, -1.0); - } -} diff --git a/calendar/gui/e-memo-table.h b/calendar/gui/e-memo-table.h index 58f398bfb5..0a13006262 100644 --- a/calendar/gui/e-memo-table.h +++ b/calendar/gui/e-memo-table.h @@ -25,34 +25,47 @@ #ifndef _E_MEMO_TABLE_H_ #define _E_MEMO_TABLE_H_ -#include <gtk/gtk.h> -#include <table/e-table-scrolled.h> +#include <shell/e-shell-view.h> +#include <widgets/table/e-table-scrolled.h> #include <widgets/misc/e-cell-date-edit.h> -#include "e-activity-handler.h" #include "e-cal-model.h" -G_BEGIN_DECLS - /* * EMemoTable - displays the iCalendar objects in a table (an ETable). * Used for memo events and tasks. + * + * XXX We should look at merging this back into ECalendarTable, or at + * least making ECalendarTable subclassable so we don't have so + * much duplicate code. */ +/* Standard GObject macros */ +#define E_TYPE_MEMO_TABLE \ + (e_memo_table_get_type ()) +#define E_MEMO_TABLE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_MEMO_TABLE, EMemoTable)) +#define E_MEMO_TABLE_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_MEMO_TABLE, EMemoTableClass)) +#define E_IS_MEMO_TABLE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_MEMO_TABLE)) +#define E_IS_MEMO_TABLE_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_MEMO_TABLE)) +#define E_MEMO_TABLE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_MEMO_TABLE, EMemoTableClass)) -#define E_MEMO_TABLE(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, e_memo_table_get_type (), EMemoTable) -#define E_MEMO_TABLE_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, e_memo_table_get_type (), EMemoTableClass) -#define E_IS_MEMO_TABLE(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, e_memo_table_get_type ()) - - -typedef struct _EMemoTable EMemoTable; -typedef struct _EMemoTableClass EMemoTableClass; +G_BEGIN_DECLS +typedef struct _EMemoTable EMemoTable; +typedef struct _EMemoTableClass EMemoTableClass; +typedef struct _EMemoTablePrivate EMemoTablePrivate; struct _EMemoTable { - GtkTable table; - - /* The model that we use */ - ECalModel *model; + GtkTable parent; GtkWidget *etable; @@ -62,51 +75,43 @@ struct _EMemoTable { /* Fields used for cut/copy/paste */ icalcomponent *tmp_vcal; - /* Activity ID for the EActivityHandler (i.e. the status bar). */ - EActivityHandler *activity_handler; - guint activity_id; - - /* We should know which calendar has been used to create object, so store it here - before emitting "user_created" signal and make it NULL just after the emit. */ - ECal *user_created_cal; + EMemoTablePrivate *priv; }; struct _EMemoTableClass { GtkTableClass parent_class; - /* Notification signals */ - void (* user_created) (EMemoTable *memo_table); + /* Signals */ + void (*open_component) (EMemoTable *memo_table, + ECalModelComponent *comp_data); + void (*popup_event) (EMemoTable *memo_table, + GdkEvent *event); + void (*status_message) (EMemoTable *memo_table, + const gchar *message, + gdouble percent); + void (*user_created) (EMemoTable *memo_table); }; - -GType e_memo_table_get_type (void); -GtkWidget* e_memo_table_new (void); - -ECalModel *e_memo_table_get_model (EMemoTable *memo_table); - -ETable *e_memo_table_get_table (EMemoTable *memo_table); - -void e_memo_table_open_selected (EMemoTable *memo_table); -void e_memo_table_delete_selected (EMemoTable *memo_table); - -GSList *e_memo_table_get_selected (EMemoTable *memo_table); +GType e_memo_table_get_type (void); +GtkWidget * e_memo_table_new (EShellView *shell_view, + ECalModel *model); +ECalModel * e_memo_table_get_model (EMemoTable *memo_table); +ETable * e_memo_table_get_table (EMemoTable *memo_table); +EShellView * e_memo_table_get_shell_view (EMemoTable *memo_table); +void e_memo_table_delete_selected (EMemoTable *memo_table); +GSList * e_memo_table_get_selected (EMemoTable *memo_table); /* Clipboard related functions */ -void e_memo_table_cut_clipboard (EMemoTable *memo_table); -void e_memo_table_copy_clipboard (EMemoTable *memo_table); -void e_memo_table_paste_clipboard (EMemoTable *memo_table); +void e_memo_table_cut_clipboard (EMemoTable *memo_table); +void e_memo_table_copy_clipboard (EMemoTable *memo_table); +void e_memo_table_paste_clipboard (EMemoTable *memo_table); /* These load and save the state of the table (headers shown etc.) to/from the given file. */ -void e_memo_table_load_state (EMemoTable *memo_table, - gchar *filename); -void e_memo_table_save_state (EMemoTable *memo_table, - gchar *filename); - -void e_memo_table_set_activity_handler (EMemoTable *memo_table, - EActivityHandler *activity_handler); -void e_memo_table_set_status_message (EMemoTable *memo_table, - const gchar *message); +void e_memo_table_load_state (EMemoTable *memo_table, + const gchar *filename); +void e_memo_table_save_state (EMemoTable *memo_table, + const gchar *filename); G_END_DECLS diff --git a/calendar/gui/e-memos.c b/calendar/gui/e-memos.c index 384743184a..04efd14dd1 100644 --- a/calendar/gui/e-memos.c +++ b/calendar/gui/e-memos.c @@ -38,7 +38,6 @@ #include "e-util/e-error.h" #include "e-util/e-categories-config.h" #include "e-util/e-util-private.h" -#include "shell/e-user-creatable-items-handler.h" #include <libecal/e-cal-time-util.h> #include <libedataserver/e-url.h> #include <libedataserver/e-categories.h> @@ -46,11 +45,9 @@ #include "dialogs/delete-error.h" #include "calendar-config.h" #include "cal-search-bar.h" -#include "calendar-component.h" #include "comp-util.h" #include "e-memo-table-config.h" #include "misc.h" -#include "memos-component.h" #include "e-cal-component-memo-preview.h" #include "e-memos.h" #include "common/authentication.h" @@ -72,9 +69,6 @@ struct _EMemosPrivate { /* Calendar search bar for memos */ GtkWidget *search_bar; - /* Paned widget */ - GtkWidget *paned; - /* The preview */ GtkWidget *preview; @@ -93,7 +87,6 @@ static void e_memos_destroy (GtkObject *object); static void update_view (EMemos *memos); static void categories_changed_cb (gpointer object, gpointer user_data); -static void backend_error_cb (ECal *client, const char *message, gpointer data); /* Signal IDs */ enum { @@ -103,100 +96,10 @@ enum { LAST_SIGNAL }; -enum DndTargetType { - TARGET_VCALENDAR -}; - -static GtkTargetEntry list_drag_types[] = { - { "text/calendar", 0, TARGET_VCALENDAR }, - { "text/x-calendar", 0, TARGET_VCALENDAR } -}; -static const int num_list_drag_types = sizeof (list_drag_types) / sizeof (list_drag_types[0]); - static guint e_memos_signals[LAST_SIGNAL] = { 0 }; G_DEFINE_TYPE (EMemos, e_memos, GTK_TYPE_TABLE) -/* Callback used when the cursor changes in the table */ -static void -table_cursor_change_cb (ETable *etable, int row, gpointer data) -{ - EMemos *memos; - EMemosPrivate *priv; - ECalModel *model; - ECalModelComponent *comp_data; - ECalComponent *comp; - const char *uid; - - int n_selected; - - memos = E_MEMOS (data); - priv = memos->priv; - - n_selected = e_table_selected_count (etable); - - /* update the HTML widget */ - if (n_selected != 1) { - e_cal_component_memo_preview_clear (E_CAL_COMPONENT_MEMO_PREVIEW (priv->preview)); - - return; - } - - model = e_memo_table_get_model (E_MEMO_TABLE (priv->memos_view)); - - comp_data = e_cal_model_get_component_at (model, e_table_get_cursor_row (etable)); - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp)); - - e_cal_component_memo_preview_display (E_CAL_COMPONENT_MEMO_PREVIEW (priv->preview), comp_data->client, comp); - - e_cal_component_get_uid (comp, &uid); - if (priv->current_uid) - g_free (priv->current_uid); - priv->current_uid = g_strdup (uid); - - g_object_unref (comp); -} - -/* Callback used when the selection changes in the table. */ -static void -table_selection_change_cb (ETable *etable, gpointer data) -{ - EMemos *memos; - int n_selected; - - memos = E_MEMOS (data); - - n_selected = e_table_selected_count (etable); - g_signal_emit (memos, e_memos_signals[SELECTION_CHANGED], 0, n_selected); - - if (n_selected != 1) - e_cal_component_memo_preview_clear (E_CAL_COMPONENT_MEMO_PREVIEW (memos->priv->preview)); - -} - -static void -user_created_cb (GtkWidget *view, EMemos *memos) -{ - EMemosPrivate *priv; - EMemoTable *memo_table; - ECal *ecal; - - priv = memos->priv; - memo_table = E_MEMO_TABLE (priv->memos_view); - - if (memo_table->user_created_cal) - ecal = memo_table->user_created_cal; - else { - ECalModel *model; - - model = e_memo_table_get_model (E_MEMO_TABLE (priv->memos_view)); - ecal = e_cal_model_get_default_client (model); - } - - e_memos_add_memo_source (memos, e_cal_get_source (ecal)); -} - /* Callback used when the sexp in the search bar changes */ static void search_bar_sexp_changed_cb (CalSearchBar *cal_search, const char *sexp, gpointer data) @@ -230,14 +133,6 @@ search_bar_category_changed_cb (CalSearchBar *cal_search, const char *category, e_cal_model_set_default_category (model, category); } -static gboolean -vpaned_resized_cb (GtkWidget *widget, GdkEventButton *event, EMemos *memos) -{ - calendar_config_set_task_vpane_pos (gtk_paned_get_position (GTK_PANED (widget))); - - return FALSE; -} - static void set_timezone (EMemos *memos) { @@ -256,10 +151,6 @@ set_timezone (EMemos *memos) e_cal_set_default_timezone (client, zone, NULL); } - if (priv->default_client && e_cal_get_load_state (priv->default_client) == E_CAL_LOAD_LOADED) - /* FIXME Error checking */ - e_cal_set_default_timezone (priv->default_client, zone, NULL); - if (priv->preview) e_cal_component_memo_preview_set_default_timezone (E_CAL_COMPONENT_MEMO_PREVIEW (priv->preview), zone); } @@ -288,33 +179,6 @@ update_view (EMemos *memos) } static void -model_row_changed_cb (ETableModel *etm, int row, gpointer data) -{ - EMemos *memos; - EMemosPrivate *priv; - ECalModelComponent *comp_data; - - memos = E_MEMOS (data); - priv = memos->priv; - - if (priv->current_uid) { - const char *uid; - - comp_data = e_cal_model_get_component_at (E_CAL_MODEL (etm), row); - if (comp_data) { - uid = icalcomponent_get_uid (comp_data->icalcomp); - if (!strcmp (uid ? uid : "", priv->current_uid)) { - ETable *etable; - - etable = e_table_scrolled_get_table ( - E_TABLE_SCROLLED (E_MEMO_TABLE (priv->memos_view)->etable)); - table_cursor_change_cb (etable, 0, memos); - } - } - } -} - -static void setup_config (EMemos *memos) { EMemosPrivate *priv; @@ -329,155 +193,6 @@ setup_config (EMemos *memos) priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); } -struct AffectedComponents { - EMemoTable *memo_table; - GSList *components; /* contains pointers to ECalModelComponent */ -}; - -/** - * get_selected_components_cb - * Helper function to fill list of selected components in EMemoTable. - * This function is called from e_table_selected_row_foreach. - **/ -static void -get_selected_components_cb (int model_row, gpointer data) -{ - struct AffectedComponents *ac = (struct AffectedComponents *) data; - - if (!ac || !ac->memo_table) - return; - - ac->components = g_slist_prepend (ac->components, e_cal_model_get_component_at (E_CAL_MODEL (e_memo_table_get_model (ac->memo_table)), model_row)); -} - -/** - * do_for_selected_components - * Calls function func for all selected components in memo_table. - * - * @param memo_table Table with selected components of our interest. - * @param func Function to be called on each selected component from cal_table. - * The first parameter of this function is a pointer to ECalModelComponent and - * the second parameter of this function is pointer to cal_table - * @param user_data User data, will be passed to func. - **/ -static void -do_for_selected_components (EMemoTable *memo_table, GFunc func, gpointer user_data) -{ - ETable *etable; - struct AffectedComponents ac; - - g_return_if_fail (memo_table != NULL); - - ac.memo_table = memo_table; - ac.components = NULL; - - etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (memo_table->etable)); - e_table_selected_row_foreach (etable, get_selected_components_cb, &ac); - - g_slist_foreach (ac.components, func, user_data); - g_slist_free (ac.components); -} - -/** - * obtain_list_of_components - * As a callback function to convert each ECalModelComponent to string - * of format "source_uid\ncomponent_str" and add this newly allocated - * string to the list of components. Strings should be freed with g_free. - * - * @param data ECalModelComponent object. - * @param user_data Pointer to GSList list, where to put new strings. - **/ -static void -obtain_list_of_components (gpointer data, gpointer user_data) -{ - GSList **list; - ECalModelComponent *comp_data; - - list = (GSList **) user_data; - comp_data = (ECalModelComponent *) data; - - if (list && comp_data) { - char *comp_str; - icalcomponent *vcal; - - vcal = e_cal_util_new_top_level (); - e_cal_util_add_timezones_from_component (vcal, comp_data->icalcomp); - icalcomponent_add_component (vcal, icalcomponent_new_clone (comp_data->icalcomp)); - - comp_str = icalcomponent_as_ical_string_r (vcal); - if (comp_str) { - ESource *source = e_cal_get_source (comp_data->client); - const char *source_uid = e_source_peek_uid (source); - - *list = g_slist_prepend (*list, g_strdup_printf ("%s\n%s", source_uid, comp_str)); - - /* do not free this pointer, it owns libical */ - /* g_free (comp_str); */ - } - - icalcomponent_free (vcal); - g_free (comp_str); - } -} - -static void -table_drag_data_get (ETable *table, - int row, - int col, - GdkDragContext *context, - GtkSelectionData *selection_data, - guint info, - guint time, - EMemos *memos) -{ - EMemosPrivate *priv; - - priv = memos->priv; - - if (info == TARGET_VCALENDAR) { - /* we will pass an icalcalendar component for both types */ - GSList *components = NULL; - - do_for_selected_components (E_MEMO_TABLE (priv->memos_view), obtain_list_of_components, &components); - - if (components) { - cal_comp_selection_set_string_list (selection_data, components); - - g_slist_foreach (components, (GFunc)g_free, NULL); - g_slist_free (components); - } - } -} - -static void -table_drag_data_delete (ETable *table, - int row, - int col, - GdkDragContext *context, - EMemos *memos) -{ - /* Moved components are deleted from source immediately when moved, - because some of them can be part of destination source, and we - don't want to delete not-moved tasks. There is no such information - which event has been moved and which not, so skip this method. - */ -} - -#define E_MEMOS_TABLE_DEFAULT_STATE \ - "<?xml version=\"1.0\"?>" \ - "<ETableState>" \ - "<column source=\"1\"/>" \ - "<column source=\"0\"/>" \ - "<column source=\"2\"/>" \ - "<grouping></grouping>" \ - "</ETableState>" - -static void -pane_realized (GtkWidget *widget, EMemos *memos) -{ - gtk_paned_set_position ((GtkPaned *)widget, calendar_config_get_task_vpane_pos ()); -} - static void setup_widgets (EMemos *memos) { @@ -499,51 +214,12 @@ setup_widgets (EMemos *memos) GTK_EXPAND | GTK_FILL | GTK_SHRINK, 0, 0, 0); gtk_widget_show (priv->search_bar); - /* add the paned widget for the memo list and memo detail areas */ - priv->paned = gtk_vpaned_new (); - g_signal_connect (priv->paned, "realize", G_CALLBACK (pane_realized), memos); - - g_signal_connect (G_OBJECT (priv->paned), "button_release_event", - G_CALLBACK (vpaned_resized_cb), memos); - gtk_table_attach (GTK_TABLE (memos), priv->paned, 0, 1, 1, 2, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - gtk_widget_show (priv->paned); - /* create the memo list */ priv->memos_view = e_memo_table_new (); priv->memos_view_config = e_memo_table_config_new (E_MEMO_TABLE (priv->memos_view)); - g_signal_connect (priv->memos_view, "user_created", G_CALLBACK (user_created_cb), memos); - - etable = e_table_scrolled_get_table ( - E_TABLE_SCROLLED (E_MEMO_TABLE (priv->memos_view)->etable)); - e_table_set_state (etable, E_MEMOS_TABLE_DEFAULT_STATE); - - gtk_paned_add1 (GTK_PANED (priv->paned), priv->memos_view); - gtk_widget_show (priv->memos_view); - - - e_table_drag_source_set (etable, GDK_BUTTON1_MASK, - list_drag_types, num_list_drag_types, - GDK_ACTION_MOVE|GDK_ACTION_COPY|GDK_ACTION_ASK); - g_signal_connect (etable, "table_drag_data_get", G_CALLBACK(table_drag_data_get), memos); - g_signal_connect (etable, "table_drag_data_delete", - G_CALLBACK(table_drag_data_delete), memos); - - g_signal_connect (etable, "cursor_change", G_CALLBACK (table_cursor_change_cb), memos); - g_signal_connect (etable, "selection_change", G_CALLBACK (table_selection_change_cb), memos); - - /* create the memo detail */ - priv->preview = e_cal_component_memo_preview_new (); - e_cal_component_memo_preview_set_default_timezone (E_CAL_COMPONENT_MEMO_PREVIEW (priv->preview), calendar_config_get_icaltimezone ()); - gtk_paned_add2 (GTK_PANED (priv->paned), priv->preview); - gtk_widget_show (priv->preview); - - model = e_memo_table_get_model (E_MEMO_TABLE (priv->memos_view)); - g_signal_connect (G_OBJECT (model), "model_row_changed", - G_CALLBACK (model_row_changed_cb), memos); } /* Class initialization function for the gnome calendar */ @@ -637,32 +313,9 @@ e_memos_init (EMemos *memos) priv->view_menus = NULL; priv->current_uid = NULL; priv->sexp = g_strdup ("#t"); - priv->default_client = NULL; update_view (memos); } -GtkWidget * -e_memos_new (void) -{ - EMemos *memos; - - memos = g_object_new (e_memos_get_type (), NULL); - - return GTK_WIDGET (memos); -} - - -void -e_memos_set_ui_component (EMemos *memos, - BonoboUIComponent *ui_component) -{ - g_return_if_fail (E_IS_MEMOS (memos)); - g_return_if_fail (ui_component == NULL || BONOBO_IS_UI_COMPONENT (ui_component)); - - e_search_bar_set_ui_component (E_SEARCH_BAR (memos->priv->search_bar), ui_component); -} - - static void e_memos_destroy (GtkObject *object) { @@ -689,10 +342,6 @@ e_memos_destroy (GtkObject *object) g_hash_table_destroy (priv->clients); g_list_free (priv->clients_list); - if (priv->default_client) - g_object_unref (priv->default_client); - priv->default_client = NULL; - if (priv->current_uid) { g_free (priv->current_uid); priv->current_uid = NULL; @@ -720,325 +369,6 @@ e_memos_destroy (GtkObject *object) (* GTK_OBJECT_CLASS (e_memos_parent_class)->destroy) (object); } -static void -set_status_message (EMemos *memos, const char *message, ...) -{ - EMemosPrivate *priv; - va_list args; - char sz[2048], *msg_string = NULL; - - if (message) { - va_start (args, message); - vsnprintf (sz, sizeof sz, message, args); - va_end (args); - msg_string = sz; - } - - priv = memos->priv; - - e_memo_table_set_status_message (E_MEMO_TABLE (priv->memos_view), msg_string); -} - -/* Callback from the calendar client when an error occurs in the backend */ -static void -backend_error_cb (ECal *client, const char *message, gpointer data) -{ - EMemos *memos; - GtkWidget *dialog; - char *urinopwd; - - memos = E_MEMOS (data); - - urinopwd = get_uri_without_password (e_cal_get_uri (client)); - - dialog = gtk_message_dialog_new ( - GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (memos))), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - _("Error on %s:\n %s"), urinopwd, message); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - - g_free (urinopwd); -} - -/* Callback from the calendar client when the backend dies */ -static void -backend_died_cb (ECal *client, gpointer data) -{ - EMemos *memos; - EMemosPrivate *priv; - ESource *source; - - memos = E_MEMOS (data); - priv = memos->priv; - - source = g_object_ref (e_cal_get_source (client)); - - priv->clients_list = g_list_remove (priv->clients_list, client); - g_hash_table_remove (priv->clients, e_source_peek_uid (source)); - - g_signal_emit (memos, e_memos_signals[SOURCE_REMOVED], 0, source); - - e_memo_table_set_status_message (E_MEMO_TABLE (e_memos_get_calendar_table (memos)), NULL); - - e_error_run (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (memos))), - "calendar:memos-crashed", NULL); - - g_object_unref (source); -} - -/* Callback from the calendar client when the calendar is opened */ -static void -client_cal_opened_cb (ECal *ecal, ECalendarStatus status, EMemos *memos) -{ - ECalModel *model; - ESource *source; - EMemosPrivate *priv; - - priv = memos->priv; - - source = e_cal_get_source (ecal); - - if (status == E_CALENDAR_STATUS_AUTHENTICATION_FAILED || status == E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED) - auth_cal_forget_password (ecal); - - switch (status) { - case E_CALENDAR_STATUS_OK : - g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, client_cal_opened_cb, NULL); - - set_status_message (memos, _("Loading memos")); - model = e_memo_table_get_model (E_MEMO_TABLE (priv->memos_view)); - e_cal_model_add_client (model, ecal); - - set_timezone (memos); - set_status_message (memos, NULL); - break; - case E_CALENDAR_STATUS_AUTHENTICATION_FAILED: - /* try to reopen calendar - it'll ask for a password once again */ - e_cal_open_async (ecal, FALSE); - return; - case E_CALENDAR_STATUS_BUSY : - break; - case E_CALENDAR_STATUS_REPOSITORY_OFFLINE: - e_error_run (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (memos))), "calendar:prompt-no-contents-offline-memos", NULL); - default : - /* Make sure the source doesn't disappear on us */ - g_object_ref (source); - - priv->clients_list = g_list_remove (priv->clients_list, ecal); - g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, memos); - - /* Do this last because it unrefs the client */ - g_hash_table_remove (priv->clients, e_source_peek_uid (source)); - - g_signal_emit (memos, e_memos_signals[SOURCE_REMOVED], 0, source); - - set_status_message (memos, NULL); - g_object_unref (source); - - break; - } -} - -static void -default_client_cal_opened_cb (ECal *ecal, ECalendarStatus status, EMemos *memos) -{ - ECalModel *model; - ESource *source; - EMemosPrivate *priv; - - priv = memos->priv; - - source = e_cal_get_source (ecal); - - if (status == E_CALENDAR_STATUS_AUTHENTICATION_FAILED || status == E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED) - auth_cal_forget_password (ecal); - - switch (status) { - case E_CALENDAR_STATUS_OK : - g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, default_client_cal_opened_cb, NULL); - model = e_memo_table_get_model (E_MEMO_TABLE (priv->memos_view)); - - set_timezone (memos); - e_cal_model_set_default_client (model, ecal); - set_status_message (memos, NULL); - break; - case E_CALENDAR_STATUS_AUTHENTICATION_FAILED: - /* try to reopen calendar - it'll ask for a password once again */ - e_cal_open_async (ecal, FALSE); - return; - case E_CALENDAR_STATUS_BUSY: - break; - default : - /* Make sure the source doesn't disappear on us */ - g_object_ref (source); - - priv->clients_list = g_list_remove (priv->clients_list, ecal); - g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, memos); - - /* Do this last because it unrefs the client */ - g_hash_table_remove (priv->clients, e_source_peek_uid (source)); - - g_signal_emit (memos, e_memos_signals[SOURCE_REMOVED], 0, source); - - set_status_message (memos, NULL); - g_object_unref (priv->default_client); - priv->default_client = NULL; - g_object_unref (source); - - break; - } -} - -typedef void (*open_func) (ECal *, ECalendarStatus, EMemos *); - -static gboolean -open_ecal (EMemos *memos, ECal *cal, gboolean only_if_exists, open_func of) -{ - set_status_message (memos, _("Opening memos at %s"), e_cal_get_uri (cal)); - - g_signal_connect (G_OBJECT (cal), "cal_opened", G_CALLBACK (of), memos); - e_cal_open_async (cal, only_if_exists); - - return TRUE; -} - -void -e_memos_open_memo (EMemos *memos) -{ - EMemoTable *cal_table; - - cal_table = e_memos_get_calendar_table (memos); - e_memo_table_open_selected (cal_table); -} - -void -e_memos_new_memo (EMemos *memos) -{ - /* used for click_to_add ?? Can't figure out anything else it's used for */ -} - -gboolean -e_memos_add_memo_source (EMemos *memos, ESource *source) -{ - EMemosPrivate *priv; - ECal *client; - const char *uid; - - g_return_val_if_fail (memos != NULL, FALSE); - g_return_val_if_fail (E_IS_MEMOS (memos), FALSE); - g_return_val_if_fail (E_IS_SOURCE (source), FALSE); - - priv = memos->priv; - - uid = e_source_peek_uid (source); - client = g_hash_table_lookup (priv->clients, uid); - if (client) { - /* We already have it */ - - return TRUE; - } else { - ESource *default_source; - - if (priv->default_client) { - default_source = e_cal_get_source (priv->default_client); - - /* We don't have it but the default client is it */ - if (!strcmp (e_source_peek_uid (default_source), uid)) - client = g_object_ref (priv->default_client); - } - - /* Create a new one */ - if (!client) { - client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_JOURNAL); - if (!client) - return FALSE; - } - } - - g_signal_connect (G_OBJECT (client), "backend_error", G_CALLBACK (backend_error_cb), memos); - g_signal_connect (G_OBJECT (client), "backend_died", G_CALLBACK (backend_died_cb), memos); - - /* add the client to internal structure */ - g_hash_table_insert (priv->clients, g_strdup (uid) , client); - priv->clients_list = g_list_prepend (priv->clients_list, client); - - g_signal_emit (memos, e_memos_signals[SOURCE_ADDED], 0, source); - - open_ecal (memos, client, FALSE, client_cal_opened_cb); - - return TRUE; -} - -gboolean -e_memos_remove_memo_source (EMemos *memos, ESource *source) -{ - EMemosPrivate *priv; - ECal *client; - ECalModel *model; - const char *uid; - - g_return_val_if_fail (memos != NULL, FALSE); - g_return_val_if_fail (E_IS_MEMOS (memos), FALSE); - g_return_val_if_fail (E_IS_SOURCE (source), FALSE); - - priv = memos->priv; - - uid = e_source_peek_uid (source); - client = g_hash_table_lookup (priv->clients, uid); - if (!client) - return TRUE; - - - priv->clients_list = g_list_remove (priv->clients_list, client); - g_signal_handlers_disconnect_matched (client, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, memos); - - model = e_memo_table_get_model (E_MEMO_TABLE (priv->memos_view)); - e_cal_model_remove_client (model, client); - - g_hash_table_remove (priv->clients, uid); - - - g_signal_emit (memos, e_memos_signals[SOURCE_REMOVED], 0, source); - - return TRUE; -} - -gboolean -e_memos_set_default_source (EMemos *memos, ESource *source) -{ - EMemosPrivate *priv; - ECal *ecal; - - g_return_val_if_fail (memos != NULL, FALSE); - g_return_val_if_fail (E_IS_MEMOS (memos), FALSE); - g_return_val_if_fail (E_IS_SOURCE (source), FALSE); - - priv = memos->priv; - - ecal = g_hash_table_lookup (priv->clients, e_source_peek_uid (source)); - - if (priv->default_client) - g_object_unref (priv->default_client); - - if (ecal) { - priv->default_client = g_object_ref (ecal); - } else { - priv->default_client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_JOURNAL); - if (!priv->default_client) - return FALSE; - } - - open_ecal (memos, priv->default_client, FALSE, default_client_cal_opened_cb); - - return TRUE; -} - ECal * e_memos_get_default_client (EMemos *memos) { @@ -1051,188 +381,3 @@ e_memos_get_default_client (EMemos *memos) return e_cal_model_get_default_client (e_memo_table_get_model (E_MEMO_TABLE (priv->memos_view))); } - - -/** - * e_memos_delete_selected: - * @memos: A memos control widget. - * - * Deletes the selected memos in the memo list. - **/ -void -e_memos_delete_selected (EMemos *memos) -{ - EMemosPrivate *priv; - EMemoTable *cal_table; - - g_return_if_fail (memos != NULL); - g_return_if_fail (E_IS_MEMOS (memos)); - - priv = memos->priv; - - cal_table = E_MEMO_TABLE (priv->memos_view); - set_status_message (memos, _("Deleting selected objects...")); - e_memo_table_delete_selected (cal_table); - set_status_message (memos, NULL); - - e_cal_component_memo_preview_clear (E_CAL_COMPONENT_MEMO_PREVIEW (priv->preview)); -} - - -/* Callback used from the view collection when we need to display a new view */ -static void -display_view_cb (GalViewInstance *instance, GalView *view, gpointer data) -{ - EMemos *memos; - - memos = E_MEMOS (data); - - if (GAL_IS_VIEW_ETABLE (view)) { - gal_view_etable_attach_table (GAL_VIEW_ETABLE (view), e_table_scrolled_get_table (E_TABLE_SCROLLED (E_MEMO_TABLE (memos->priv->memos_view)->etable))); - } - - gtk_paned_set_position ((GtkPaned *)memos->priv->paned, calendar_config_get_task_vpane_pos ()); -} - -/** - * e_memos_setup_view_menus: - * @memos: A memos widget. - * @uic: UI controller to use for the menus. - * - * Sets up the #GalView menus for a memos control. This function should be - * called from the Bonobo control activation callback for this memos control. - * Also, the menus should be discarded using e_memos_discard_view_menus(). - */ -void -e_memos_setup_view_menus (EMemos *memos, BonoboUIComponent *uic) -{ - EMemosPrivate *priv; - GalViewFactory *factory; - ETableSpecification *spec; - char *dir0, *dir1, *filename; - static GalViewCollection *collection = NULL; - - g_return_if_fail (memos != NULL); - g_return_if_fail (E_IS_MEMOS (memos)); - g_return_if_fail (uic != NULL); - g_return_if_fail (BONOBO_IS_UI_COMPONENT (uic)); - - priv = memos->priv; - - g_return_if_fail (priv->view_instance == NULL); - - g_return_if_fail (priv->view_instance == NULL); - g_return_if_fail (priv->view_menus == NULL); - - /* Create the view instance */ - - if (collection == NULL) { - collection = gal_view_collection_new (); - - gal_view_collection_set_title (collection, _("Memos")); - - dir0 = g_build_filename (EVOLUTION_GALVIEWSDIR, - "memos", - NULL); - dir1 = g_build_filename (memos_component_peek_base_directory (memos_component_peek ()), - "views", NULL); - gal_view_collection_set_storage_directories (collection, - dir0, - dir1); - g_free (dir1); - g_free (dir0); - - /* Create the views */ - - spec = e_table_specification_new (); - filename = g_build_filename (EVOLUTION_ETSPECDIR, - "e-memo-table.etspec", - NULL); - if (!e_table_specification_load_from_file (spec, filename)) - g_error ("Unable to load ETable specification file " - "for memos"); - g_free (filename); - - factory = gal_view_factory_etable_new (spec); - g_object_unref (spec); - gal_view_collection_add_factory (collection, factory); - g_object_unref (factory); - - /* Load the collection and create the menus */ - - gal_view_collection_load (collection); - } - - priv->view_instance = gal_view_instance_new (collection, NULL); - - priv->view_menus = gal_view_menus_new (priv->view_instance); - gal_view_menus_apply (priv->view_menus, uic, NULL); - g_signal_connect (priv->view_instance, "display_view", G_CALLBACK (display_view_cb), memos); - display_view_cb (priv->view_instance, gal_view_instance_get_current_view (priv->view_instance), memos); -} - -/** - * e_memos_discard_view_menus: - * @memos: A memos widget. - * - * Discards the #GalView menus used by a memos control. This function should be - * called from the Bonobo control deactivation callback for this memos control. - * The menus should have been set up with e_memos_setup_view_menus(). - **/ -void -e_memos_discard_view_menus (EMemos *memos) -{ - EMemosPrivate *priv; - - g_return_if_fail (memos != NULL); - g_return_if_fail (E_IS_MEMOS (memos)); - - priv = memos->priv; - - g_return_if_fail (priv->view_instance != NULL); - - g_return_if_fail (priv->view_instance != NULL); - g_return_if_fail (priv->view_menus != NULL); - - g_object_unref (priv->view_instance); - priv->view_instance = NULL; - - g_object_unref (priv->view_menus); - priv->view_menus = NULL; -} - -/** - * e_memos_get_calendar_table: - * @memos: A memos widget. - * - * Queries the #EMemoTable contained in a memos widget. - * - * Return value: The #EMemoTable that the memos widget uses to display its - * information. - **/ -EMemoTable * -e_memos_get_calendar_table (EMemos *memos) -{ - EMemosPrivate *priv; - - g_return_val_if_fail (memos != NULL, NULL); - g_return_val_if_fail (E_IS_MEMOS (memos), NULL); - - priv = memos->priv; - return E_MEMO_TABLE (priv->memos_view); -} - -/** - * e_memos_get_preview: - * @memos: A memos widget. - * - * Queries the #ECalComponentMemoPreview contained in a memos widget. - **/ -GtkWidget * -e_memos_get_preview (EMemos *memos) -{ - g_return_val_if_fail (memos != NULL, NULL); - g_return_val_if_fail (E_IS_MEMOS (memos), NULL); - - return memos->priv->preview; -} diff --git a/calendar/gui/e-memos.h b/calendar/gui/e-memos.h index 1b3f0b8c72..b97cc0ac68 100644 --- a/calendar/gui/e-memos.h +++ b/calendar/gui/e-memos.h @@ -25,7 +25,6 @@ #ifndef _E_MEMOS_H_ #define _E_MEMOS_H_ -#include <bonobo/bonobo-ui-component.h> #include <gtk/gtk.h> #include <libedataserver/e-source.h> #include <libecal/e-cal.h> @@ -64,9 +63,6 @@ GtkWidget *e_memos_construct (EMemos *memos); GtkWidget *e_memos_new (void); -void e_memos_set_ui_component (EMemos *memos, - BonoboUIComponent *ui_component); - gboolean e_memos_add_memo_source (EMemos *memos, ESource *source); gboolean e_memos_remove_memo_source (EMemos *memos, ESource *source); gboolean e_memos_set_default_source (EMemos *memos, ESource *source); diff --git a/calendar/gui/e-task-list-selector.c b/calendar/gui/e-task-list-selector.c new file mode 100644 index 0000000000..910ab3f33f --- /dev/null +++ b/calendar/gui/e-task-list-selector.c @@ -0,0 +1,288 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-task-list-selector.c + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "e-task-list-selector.h" + +#include <string.h> +#include <libecal/e-cal.h> +#include "calendar/common/authentication.h" +#include "calendar/gui/comp-util.h" + +#define E_TASK_LIST_SELECTOR_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_TASK_LIST_SELECTOR, ETaskListSelectorPrivate)) + +struct _ETaskListSelectorPrivate { + gint dummy_value; +}; + +enum { + DND_TARGET_TYPE_CALENDAR_LIST +}; + +static GtkTargetEntry drag_types[] = { + { "text/calendar", 0, DND_TARGET_TYPE_CALENDAR_LIST }, + { "text/x-calendar", 0, DND_TARGET_TYPE_CALENDAR_LIST } +}; + +static gpointer parent_class; + +static gboolean +task_list_selector_update_single_object (ECal *client, + icalcomponent *icalcomp) +{ + gchar *uid; + icalcomponent *tmp_icalcomp; + + uid = (gchar *) icalcomponent_get_uid (icalcomp); + + if (e_cal_get_object (client, uid, NULL, &tmp_icalcomp, NULL)) + return e_cal_modify_object ( + client, icalcomp, CALOBJ_MOD_ALL, NULL); + + return e_cal_create_object (client, icalcomp, &uid, NULL); +} + +static gboolean +task_list_selector_update_objects (ECal *client, + icalcomponent *icalcomp) +{ + icalcomponent *subcomp; + icalcomponent_kind kind; + + kind = icalcomponent_isa (icalcomp); + if (kind == ICAL_VTODO_COMPONENT || kind == ICAL_VEVENT_COMPONENT) + return task_list_selector_update_single_object ( + client, icalcomp); + else if (kind != ICAL_VCALENDAR_COMPONENT) + return FALSE; + + subcomp = icalcomponent_get_first_component ( + icalcomp, ICAL_ANY_COMPONENT); + while (subcomp != NULL) { + gboolean success; + + kind = icalcomponent_isa (subcomp); + if (kind == ICAL_VTIMEZONE_COMPONENT) { + icaltimezone *zone; + + zone = icaltimezone_new (); + icaltimezone_set_component (zone, subcomp); + + success = e_cal_add_timezone (client, zone, NULL); + icaltimezone_free (zone, 1); + if (!success) + return FALSE; + } else if (kind == ICAL_VTODO_COMPONENT || + kind == ICAL_VEVENT_COMPONENT) { + success = task_list_selector_update_single_object ( + client, subcomp); + if (!success) + return FALSE; + } + + subcomp = icalcomponent_get_next_component ( + icalcomp, ICAL_ANY_COMPONENT); + } + + return TRUE; +} + +static gboolean +task_list_selector_process_data (ESourceSelector *selector, + ECal *client, + const gchar *source_uid, + icalcomponent *icalcomp, + GdkDragAction action) +{ + ESourceList *source_list; + ESource *source; + icalcomponent *tmp_icalcomp = NULL; + const gchar *uid; + gchar *old_uid = NULL; + gboolean success = FALSE; + gboolean read_only = TRUE; + GError *error = NULL; + + /* FIXME Deal with GDK_ACTION_ASK. */ + if (action == GDK_ACTION_COPY) { + old_uid = g_strdup (icalcomponent_get_uid (icalcomp)); + uid = e_cal_component_gen_uid (); + icalcomponent_set_uid (icalcomp, uid); + } + + uid = icalcomponent_get_uid (icalcomp); + if (old_uid == NULL) + old_uid = g_strdup (uid); + + if (e_cal_get_object (client, uid, NULL, &tmp_icalcomp, &error)) { + icalcomponent_free (tmp_icalcomp); + success = TRUE; + goto exit; + } + + if (error != NULL && error->code != E_CALENDAR_STATUS_OBJECT_NOT_FOUND) { + g_message ( + "Failed to search the object in destination " + "task list: %s", error->message); + g_error_free (error); + goto exit; + } + + success = task_list_selector_update_objects (client, icalcomp); + + if (!success || action != GDK_ACTION_MOVE) + goto exit; + + source_list = e_source_selector_get_source_list (selector); + source = e_source_list_peek_source_by_uid (source_list, source_uid); + + if (!E_IS_SOURCE (source) || e_source_get_readonly (source)) + goto exit; + + client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_TODO); + if (client == NULL) { + g_message ("Cannot create source client to remove old task"); + goto exit; + } + + e_cal_is_read_only (client, &read_only, NULL); + if (!read_only && e_cal_open (client, TRUE, NULL)) + e_cal_remove_object (client, old_uid, NULL); + else if (!read_only) + g_message ("Cannot open source client to remove old task"); + + g_object_unref (client); + +exit: + g_free (old_uid); + + return success; +} + +static gboolean +task_list_selector_data_dropped (ESourceSelector *selector, + GtkSelectionData *selection_data, + ESource *destination, + GdkDragAction action, + guint info) +{ + ECal *client; + GSList *list, *iter; + gboolean success = FALSE; + + client = auth_new_cal_from_source ( + destination, E_CAL_SOURCE_TYPE_TODO); + + if (client == NULL || !e_cal_open (client, TRUE, NULL)) + goto exit; + + list = cal_comp_selection_get_string_list (selection_data); + + for (iter = list; iter != NULL; iter = iter->next) { + gchar *source_uid = iter->data; + icalcomponent *icalcomp; + gchar *component_string; + + /* Each string is "source_uid\ncomponent_string". */ + component_string = strchr (source_uid, '\n'); + if (component_string == NULL) + continue; + + *component_string++ = '\0'; + icalcomp = icalparser_parse_string (component_string); + if (icalcomp == NULL) + continue; + + success = task_list_selector_process_data ( + selector, client, source_uid, icalcomp, action); + + icalcomponent_free (icalcomp); + } + + g_slist_foreach (list, (GFunc) g_free, NULL); + g_slist_free (list); + +exit: + if (client != NULL) + g_object_unref (client); + + return success; +} + +static void +task_list_selector_class_init (ETaskListSelectorClass *class) +{ + ESourceSelectorClass *source_selector_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (ETaskListSelectorPrivate)); + + source_selector_class = E_SOURCE_SELECTOR_CLASS (class); + source_selector_class->data_dropped = task_list_selector_data_dropped; +} + +static void +task_list_selector_init (ETaskListSelector *selector) +{ + selector->priv = E_TASK_LIST_SELECTOR_GET_PRIVATE (selector); + + gtk_drag_dest_set ( + GTK_WIDGET (selector), GTK_DEST_DEFAULT_ALL, + drag_types, G_N_ELEMENTS (drag_types), + GDK_ACTION_COPY | GDK_ACTION_MOVE); +} + +GType +e_task_list_selector_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + const GTypeInfo type_info = { + sizeof (ETaskListSelectorClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) task_list_selector_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (ETaskListSelector), + 0, /* n_preallocs */ + (GInstanceInitFunc) task_list_selector_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + E_TYPE_SOURCE_SELECTOR, "ETaskListSelector", + &type_info, 0); + } + + return type; +} + +GtkWidget * +e_task_list_selector_new (ESourceList *source_list) +{ + g_return_val_if_fail (E_IS_SOURCE_LIST (source_list), NULL); + + return g_object_new ( + E_TYPE_TASK_LIST_SELECTOR, + "source-list", source_list, NULL); +} diff --git a/calendar/gui/e-task-list-selector.h b/calendar/gui/e-task-list-selector.h new file mode 100644 index 0000000000..847a221ba4 --- /dev/null +++ b/calendar/gui/e-task-list-selector.h @@ -0,0 +1,71 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-task-list-selector.h + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +/* XXX This widget is nearly identical to EMemoListSelector. If + * ECalendarSelector ever learns how to move selections from + * one source to another, perhaps these ESourceSelector sub- + * classes could someday be combined. */ + +#ifndef E_TASK_LIST_SELECTOR_H +#define E_TASK_LIST_SELECTOR_H + +#include <libedataserver/e-source-list.h> +#include <libedataserverui/e-source-selector.h> + +/* Standard GObject macros */ +#define E_TYPE_TASK_LIST_SELECTOR \ + (e_task_list_selector_get_type ()) +#define E_TASK_LIST_SELECTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_TASK_LIST_SELECTOR, ETaskListSelector)) +#define E_TASK_LIST_SELECTOR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_TASK_LIST_SELECTOR, ETaskListSelectorClass)) +#define E_IS_TASK_LIST_SELECTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_TASK_LIST_SELECTOR)) +#define E_IS_TASK_LIST_SELECTOR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_TASK_LIST_SELECTOR)) +#define E_TASK_LIST_SELECTOR_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_TASK_LIST_SELECTOR, ETaskListSelectorClass)) + +G_BEGIN_DECLS + +typedef struct _ETaskListSelector ETaskListSelector; +typedef struct _ETaskListSelectorClass ETaskListSelectorClass; +typedef struct _ETaskListSelectorPrivate ETaskListSelectorPrivate; + +struct _ETaskListSelector { + ESourceSelector parent; + ETaskListSelectorPrivate *priv; +}; + +struct _ETaskListSelectorClass { + ESourceSelectorClass parent_class; +}; + +GType e_task_list_selector_get_type (void); +GtkWidget * e_task_list_selector_new (ESourceList *source_list); + +G_END_DECLS + +#endif /* E_TASK_LIST_SELECTOR_H */ diff --git a/calendar/gui/e-tasks.c b/calendar/gui/e-tasks.c index 4efb688ae0..a314bc67d3 100644 --- a/calendar/gui/e-tasks.c +++ b/calendar/gui/e-tasks.c @@ -73,9 +73,6 @@ struct _ETasksPrivate { /* Calendar search bar for tasks */ GtkWidget *search_bar; - /* Tasks menu */ - ECalMenu *tasks_menu; - /* Paned widget */ GtkWidget *paned; @@ -86,18 +83,12 @@ struct _ETasksPrivate { char *sexp; guint update_timeout; - /* View instance and the view menus handler */ - GalViewInstance *view_instance; - GalViewMenus *view_menus; - GList *notifications; }; static void setup_widgets (ETasks *tasks); static void e_tasks_destroy (GtkObject *object); -static void update_view (ETasks *tasks); -static void categories_changed_cb (gpointer object, gpointer user_data); static void backend_error_cb (ECal *client, const char *message, gpointer data); /* Signal IDs */ @@ -108,126 +99,10 @@ enum { LAST_SIGNAL }; -enum DndTargetType { - TARGET_VCALENDAR -}; - -static GtkTargetEntry list_drag_types[] = { - { "text/calendar", 0, TARGET_VCALENDAR }, - { "text/x-calendar", 0, TARGET_VCALENDAR } -}; -static const int num_list_drag_types = sizeof (list_drag_types) / sizeof (list_drag_types[0]); - static guint e_tasks_signals[LAST_SIGNAL] = { 0 }; G_DEFINE_TYPE (ETasks, e_tasks, GTK_TYPE_TABLE) -/* Callback used when the cursor changes in the table */ -static void -table_cursor_change_cb (ETable *etable, int row, gpointer data) -{ - ETasks *tasks; - ETasksPrivate *priv; - ECalModel *model; - ECalModelComponent *comp_data; - ECalComponent *comp; - const char *uid; - - int n_selected; - - tasks = E_TASKS (data); - priv = tasks->priv; - - n_selected = e_table_selected_count (etable); - - /* update the HTML widget */ - if (n_selected != 1) { - e_cal_component_preview_clear (E_CAL_COMPONENT_PREVIEW (priv->preview)); - - return; - } - - model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view)); - - comp_data = e_cal_model_get_component_at (model, e_table_get_cursor_row (etable)); - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp)); - - e_cal_component_preview_display (E_CAL_COMPONENT_PREVIEW (priv->preview), comp_data->client, comp); - - e_cal_component_get_uid (comp, &uid); - if (priv->current_uid) - g_free (priv->current_uid); - priv->current_uid = g_strdup (uid); - - g_object_unref (comp); -} - -ECalMenu * -e_tasks_get_tasks_menu (ETasks *tasks) -{ - g_return_val_if_fail (E_IS_TASKS (tasks), NULL); - - return tasks->priv->tasks_menu; -} - - -/* Callback used when the selection changes in the table. */ -static void -table_selection_change_cb (ETable *etable, gpointer data) -{ - ETasks *tasks; - int n_selected; - - tasks = E_TASKS (data); - - n_selected = e_table_selected_count (etable); - g_signal_emit (tasks, e_tasks_signals[SELECTION_CHANGED], 0, n_selected); - - if (n_selected != 1) - e_cal_component_preview_clear (E_CAL_COMPONENT_PREVIEW (tasks->priv->preview)); -} - -static void -user_created_cb (GtkWidget *view, ETasks *tasks) -{ - ETasksPrivate *priv; - ECalendarTable *cal_table; - ECal *ecal; - - priv = tasks->priv; - cal_table = E_CALENDAR_TABLE (priv->tasks_view); - - if (cal_table->user_created_cal) - ecal = cal_table->user_created_cal; - else { - ECalModel *model; - - model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view)); - ecal = e_cal_model_get_default_client (model); - } - - e_tasks_add_todo_source (tasks, e_cal_get_source (ecal)); -} - -/* Callback used when the sexp in the search bar changes */ -static void -search_bar_sexp_changed_cb (CalSearchBar *cal_search, const char *sexp, gpointer data) -{ - ETasks *tasks; - ETasksPrivate *priv; - - tasks = E_TASKS (data); - priv = tasks->priv; - - if (priv->sexp) - g_free (priv->sexp); - - priv->sexp = g_strdup (sexp); - - update_view (tasks); -} - /* Callback used when the selected category in the search bar changes */ static void search_bar_category_changed_cb (CalSearchBar *cal_search, const char *category, gpointer data) @@ -243,194 +118,6 @@ search_bar_category_changed_cb (CalSearchBar *cal_search, const char *category, e_cal_model_set_default_category (model, category); } -static gboolean -vpaned_resized_cb (GtkWidget *widget, GdkEventButton *event, ETasks *tasks) -{ - calendar_config_set_task_vpane_pos (gtk_paned_get_position (GTK_PANED (widget))); - - return FALSE; -} - -static void -set_timezone (ETasks *tasks) -{ - ETasksPrivate *priv; - icaltimezone *zone; - GList *l; - - priv = tasks->priv; - - zone = calendar_config_get_icaltimezone (); - for (l = priv->clients_list; l != NULL; l = l->next) { - ECal *client = l->data; - /* FIXME Error checking */ - e_cal_set_default_timezone (client, zone, NULL); - } - - if (priv->default_client) - /* FIXME Error checking */ - e_cal_set_default_timezone (priv->default_client, zone, NULL); - - if (priv->preview) - e_cal_component_preview_set_default_timezone (E_CAL_COMPONENT_PREVIEW (priv->preview), zone); -} - -static void -timezone_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - ETasks *tasks = data; - - set_timezone (tasks); -} - -static void -update_view (ETasks *tasks) -{ - ETasksPrivate *priv; - ECalModel *model; - char *real_sexp = NULL; - char *new_sexp = NULL; - - priv = tasks->priv; - - model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view)); - - if ((new_sexp = calendar_config_get_hide_completed_tasks_sexp (FALSE)) != NULL) { - real_sexp = g_strdup_printf ("(and %s %s)", new_sexp, priv->sexp); - e_cal_model_set_search_query (model, real_sexp); - g_free (new_sexp); - g_free (real_sexp); - } else - e_cal_model_set_search_query (model, priv->sexp); - - e_cal_component_preview_clear (E_CAL_COMPONENT_PREVIEW (priv->preview)); -} - -static void -process_completed_tasks (ETasks *tasks, gboolean config_changed) -{ - ETasksPrivate *priv; - - g_return_if_fail (tasks != NULL); - g_return_if_fail (E_IS_TASKS (tasks)); - - priv = tasks->priv; - - e_calendar_table_process_completed_tasks (e_tasks_get_calendar_table (tasks), priv->clients_list, config_changed); -} - -static gboolean -update_view_cb (ETasks *tasks) -{ - ECalModel *model; - - model = e_calendar_table_get_model (E_CALENDAR_TABLE (tasks->priv->tasks_view)); - - process_completed_tasks (tasks, FALSE); - e_cal_model_tasks_update_due_tasks (E_CAL_MODEL_TASKS (model)); - - return TRUE; -} - -static void -config_hide_completed_tasks_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - process_completed_tasks (data, TRUE); - update_view (data); -} - -static void -model_row_changed_cb (ETableModel *etm, int row, gpointer data) -{ - ETasks *tasks; - ETasksPrivate *priv; - ECalModelComponent *comp_data; - - tasks = E_TASKS (data); - priv = tasks->priv; - - if (priv->current_uid) { - const char *uid; - - comp_data = e_cal_model_get_component_at (E_CAL_MODEL (etm), row); - if (comp_data) { - uid = icalcomponent_get_uid (comp_data->icalcomp); - if (!strcmp (uid ? uid : "", priv->current_uid)) { - ETable *etable; - - etable = e_table_scrolled_get_table ( - E_TABLE_SCROLLED (E_CALENDAR_TABLE (priv->tasks_view)->etable)); - table_cursor_change_cb (etable, 0, tasks); - } - } - } -} - -static void -view_progress_cb (ECalModel *model, const char *message, int percent, ECalSourceType type, ETasks *tasks) -{ - e_calendar_table_set_status_message (E_CALENDAR_TABLE (e_tasks_get_calendar_table (tasks)), - message, percent); -} - -static void -view_done_cb (ECalModel *model, ECalendarStatus status, ECalSourceType type, ETasks *tasks) -{ - e_calendar_table_set_status_message (E_CALENDAR_TABLE (e_tasks_get_calendar_table (tasks)), - NULL, -1); - -} - -static void -config_preview_state_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - gboolean state; - GConfValue *value; - ETasks *tasks = (ETasks *)data; - - g_return_if_fail (gconf_entry_get_key (entry) != NULL); - g_return_if_fail ((value = gconf_entry_get_value (entry)) != NULL); - - state = gconf_value_get_bool (value); - e_tasks_show_preview (tasks, state); - bonobo_ui_component_set_prop (E_SEARCH_BAR (tasks->priv->search_bar)->ui_component, "/commands/ViewPreview", "state", state ? "1" : "0", NULL); -} - -static void -setup_config (ETasks *tasks) -{ - ETasksPrivate *priv; - guint not; - - priv = tasks->priv; - - /* Timezone */ - set_timezone (tasks); - - not = calendar_config_add_notification_timezone (timezone_changed_cb, tasks); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - not = calendar_config_add_notification_hide_completed_tasks (config_hide_completed_tasks_changed_cb, - tasks); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - not = calendar_config_add_notification_hide_completed_tasks_units (config_hide_completed_tasks_changed_cb, - tasks); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - not = calendar_config_add_notification_hide_completed_tasks_value (config_hide_completed_tasks_changed_cb, - tasks); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - not = calendar_config_add_notification_preview_state (config_preview_state_changed_cb, tasks); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); -} - -struct AffectedComponents { - ECalendarTable *cal_table; - GSList *components; /* contains pointers to ECalModelComponent */ -}; - /** * get_selected_components_cb * Helper function to fill list of selected components in ECalendarTable. @@ -614,7 +301,6 @@ setup_widgets (ETasks *tasks) G_CALLBACK (search_bar_sexp_changed_cb), tasks); g_signal_connect (priv->search_bar, "category_changed", G_CALLBACK (search_bar_category_changed_cb), tasks); - categories_changed_cb (NULL, tasks); gtk_table_attach (GTK_TABLE (tasks), priv->search_bar, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL | GTK_SHRINK, 0, 0, 0); @@ -624,8 +310,6 @@ setup_widgets (ETasks *tasks) priv->paned = gtk_vpaned_new (); g_signal_connect (priv->paned, "realize", G_CALLBACK (pane_realized), tasks); - g_signal_connect (G_OBJECT (priv->paned), "button_release_event", - G_CALLBACK (vpaned_resized_cb), tasks); gtk_table_attach (GTK_TABLE (tasks), priv->paned, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); gtk_widget_show (priv->paned); @@ -665,12 +349,8 @@ setup_widgets (ETasks *tasks) "table_drag_data_received", G_CALLBACK(table_drag_data_received_cb), editor); */ - g_signal_connect (etable, "cursor_change", G_CALLBACK (table_cursor_change_cb), tasks); g_signal_connect (etable, "selection_change", G_CALLBACK (table_selection_change_cb), tasks); - /* Timeout check to hide completed items */ - priv->update_timeout = g_timeout_add_full (G_PRIORITY_LOW, 60000, (GSourceFunc) update_view_cb, tasks, NULL); - /* create the task detail */ priv->preview = e_cal_component_preview_new (); e_cal_component_preview_set_default_timezone (E_CAL_COMPONENT_PREVIEW (priv->preview), calendar_config_get_icaltimezone ()); @@ -679,15 +359,6 @@ setup_widgets (ETasks *tasks) if (state) gtk_widget_show (priv->preview); - - model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view)); - g_signal_connect (G_OBJECT (model), "model_row_changed", - G_CALLBACK (model_row_changed_cb), tasks); - - g_signal_connect (G_OBJECT (model), "cal_view_progress", - G_CALLBACK (view_progress_cb), tasks); - g_signal_connect (G_OBJECT (model), "cal_view_done", - G_CALLBACK (view_done_cb), tasks); } /* Class initialization function for the gnome calendar */ @@ -738,29 +409,6 @@ e_tasks_class_init (ETasksClass *class) } -static void -categories_changed_cb (gpointer object, gpointer user_data) -{ - GList *cat_list; - GPtrArray *cat_array; - ETasksPrivate *priv; - ETasks *tasks = user_data; - - priv = tasks->priv; - - cat_array = g_ptr_array_new (); - cat_list = e_categories_get_list (); - while (cat_list != NULL) { - if (e_categories_is_searchable ((const char *) cat_list->data)) - g_ptr_array_add (cat_array, cat_list->data); - cat_list = g_list_remove (cat_list, cat_list->data); - } - - cal_search_bar_set_categories ((CalSearchBar *)priv->search_bar, cat_array); - - g_ptr_array_free (cat_array, TRUE); -} - /* Object initialization function for the gnome calendar */ static void e_tasks_init (ETasks *tasks) @@ -770,20 +418,13 @@ e_tasks_init (ETasks *tasks) priv = g_new0 (ETasksPrivate, 1); tasks->priv = priv; - e_categories_register_change_listener (G_CALLBACK (categories_changed_cb), tasks); - - setup_config (tasks); setup_widgets (tasks); priv->clients = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); priv->query = NULL; - priv->view_instance = NULL; - priv->view_menus = NULL; priv->current_uid = NULL; priv->sexp = g_strdup ("#t"); priv->default_client = NULL; - priv->tasks_menu = e_cal_menu_new ("org.gnome.evolution.tasks.view"); - update_view (tasks); } GtkWidget * @@ -796,18 +437,6 @@ e_tasks_new (void) return GTK_WIDGET (tasks); } - -void -e_tasks_set_ui_component (ETasks *tasks, - BonoboUIComponent *ui_component) -{ - g_return_if_fail (E_IS_TASKS (tasks)); - g_return_if_fail (ui_component == NULL || BONOBO_IS_UI_COMPONENT (ui_component)); - - e_search_bar_set_ui_component (E_SEARCH_BAR (tasks->priv->search_bar), ui_component); -} - - static void e_tasks_destroy (GtkObject *object) { @@ -823,8 +452,6 @@ e_tasks_destroy (GtkObject *object) if (priv) { GList *l; - e_categories_unregister_change_listener (G_CALLBACK (categories_changed_cb), tasks); - /* disconnect from signals on all the clients */ for (l = priv->clients_list; l != NULL; l = l->next) { g_signal_handlers_disconnect_matched (l->data, G_SIGNAL_MATCH_DATA, @@ -848,11 +475,6 @@ e_tasks_destroy (GtkObject *object) priv->sexp = NULL; } - if (priv->update_timeout) { - g_source_remove (priv->update_timeout); - priv->update_timeout = 0; - } - if (priv->tasks_view_config) { g_object_unref (priv->tasks_view_config); priv->tasks_view_config = NULL; @@ -889,160 +511,6 @@ set_status_message (ETasks *tasks, const char *message, ...) e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->tasks_view), msg_string, -1); } -/* Callback from the calendar client when an error occurs in the backend */ -static void -backend_error_cb (ECal *client, const char *message, gpointer data) -{ - ETasks *tasks; - GtkWidget *dialog; - char *urinopwd; - - tasks = E_TASKS (data); - - urinopwd = get_uri_without_password (e_cal_get_uri (client)); - - dialog = gtk_message_dialog_new ( - GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tasks))), - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - _("Error on %s:\n %s"), - urinopwd, message); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - - g_free (urinopwd); -} - -/* Callback from the calendar client when the backend dies */ -static void -backend_died_cb (ECal *client, gpointer data) -{ - ETasks *tasks; - ETasksPrivate *priv; - ESource *source; - - tasks = E_TASKS (data); - priv = tasks->priv; - - source = g_object_ref (e_cal_get_source (client)); - - priv->clients_list = g_list_remove (priv->clients_list, client); - g_hash_table_remove (priv->clients, e_source_peek_uid (source)); - - g_signal_emit (tasks, e_tasks_signals[SOURCE_REMOVED], 0, source); - - e_calendar_table_set_status_message (E_CALENDAR_TABLE (e_tasks_get_calendar_table (tasks)), NULL, -1); - - e_error_run (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tasks))), - "calendar:tasks-crashed", NULL); - - g_object_unref (source); -} - -/* Callback from the calendar client when the calendar is opened */ -static void -client_cal_opened_cb (ECal *ecal, ECalendarStatus status, ETasks *tasks) -{ - ECalModel *model; - ESource *source; - ETasksPrivate *priv; - - priv = tasks->priv; - - source = e_cal_get_source (ecal); - - if (status == E_CALENDAR_STATUS_AUTHENTICATION_FAILED || status == E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED) - auth_cal_forget_password (ecal); - - switch (status) { - case E_CALENDAR_STATUS_OK : - g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, client_cal_opened_cb, NULL); - - set_status_message (tasks, _("Loading tasks")); - model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view)); - e_cal_model_add_client (model, ecal); - - set_status_message (tasks, NULL); - break; - case E_CALENDAR_STATUS_AUTHENTICATION_FAILED: - /* try to reopen calendar - it'll ask for a password once again */ - e_cal_open_async (ecal, FALSE); - return; - case E_CALENDAR_STATUS_BUSY : - break; - case E_CALENDAR_STATUS_REPOSITORY_OFFLINE: - e_error_run (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tasks))), "calendar:prompt-no-contents-offline-tasks", NULL); - default : - /* Make sure the source doesn't disappear on us */ - g_object_ref (source); - - priv->clients_list = g_list_remove (priv->clients_list, ecal); - g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, tasks); - - /* Do this last because it unrefs the client */ - g_hash_table_remove (priv->clients, e_source_peek_uid (source)); - - g_signal_emit (tasks, e_tasks_signals[SOURCE_REMOVED], 0, source); - - set_status_message (tasks, NULL); - g_object_unref (source); - - break; - } -} - -static void -default_client_cal_opened_cb (ECal *ecal, ECalendarStatus status, ETasks *tasks) -{ - ECalModel *model; - ESource *source; - ETasksPrivate *priv; - - priv = tasks->priv; - - source = e_cal_get_source (ecal); - - if (status == E_CALENDAR_STATUS_AUTHENTICATION_FAILED || status == E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED) - auth_cal_forget_password (ecal); - - switch (status) { - case E_CALENDAR_STATUS_OK : - g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, default_client_cal_opened_cb, NULL); - model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view)); - - e_cal_model_set_default_client (model, ecal); - set_status_message (tasks, NULL); - break; - case E_CALENDAR_STATUS_AUTHENTICATION_FAILED: - /* try to reopen calendar - it'll ask for a password once again */ - e_cal_open_async (ecal, FALSE); - return; - case E_CALENDAR_STATUS_BUSY: - break; - default : - /* Make sure the source doesn't disappear on us */ - g_object_ref (source); - - priv->clients_list = g_list_remove (priv->clients_list, ecal); - g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, tasks); - - /* Do this last because it unrefs the client */ - g_hash_table_remove (priv->clients, e_source_peek_uid (source)); - - g_signal_emit (tasks, e_tasks_signals[SOURCE_REMOVED], 0, source); - - set_status_message (tasks, NULL); - g_object_unref (priv->default_client); - priv->default_client = NULL; - g_object_unref (source); - - break; - } -} - typedef void (*open_func) (ECal *, ECalendarStatus, ETasks *); static gboolean @@ -1107,104 +575,6 @@ e_tasks_new_task (ETasks *tasks) gtk_window_present (GTK_WINDOW (editor)); } -void -e_tasks_show_preview (ETasks *tasks, gboolean state) -{ - ETasksPrivate *priv; - - g_return_if_fail (tasks != NULL); - g_return_if_fail (E_IS_TASKS (tasks)); - priv = tasks->priv; - - if (state) { - ECalModel *model; - ECalModelComponent *comp_data; - ECalComponent *comp; - ETable *etable; - const char *uid; - int n_selected; - - etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (E_CALENDAR_TABLE (priv->tasks_view)->etable)); - n_selected = e_table_selected_count (etable); - - if (n_selected != 1) { - e_cal_component_preview_clear (E_CAL_COMPONENT_PREVIEW (priv->preview)); - } else { - model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view)); - - comp_data = e_cal_model_get_component_at (model, e_table_get_cursor_row (etable)); - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp)); - - e_cal_component_preview_display (E_CAL_COMPONENT_PREVIEW (priv->preview), comp_data->client, comp); - - e_cal_component_get_uid (comp, &uid); - if (priv->current_uid) - g_free (priv->current_uid); - priv->current_uid = g_strdup (uid); - - g_object_unref (comp); - } - gtk_widget_show (priv->preview); - - } else { - e_cal_component_preview_clear (E_CAL_COMPONENT_PREVIEW (priv->preview)); - gtk_widget_hide (priv->preview); - } -} - -gboolean -e_tasks_add_todo_source (ETasks *tasks, ESource *source) -{ - ETasksPrivate *priv; - ECal *client; - const char *uid; - - g_return_val_if_fail (tasks != NULL, FALSE); - g_return_val_if_fail (E_IS_TASKS (tasks), FALSE); - g_return_val_if_fail (E_IS_SOURCE (source), FALSE); - - priv = tasks->priv; - - uid = e_source_peek_uid (source); - client = g_hash_table_lookup (priv->clients, uid); - if (client) { - /* We already have it */ - - return TRUE; - } else { - ESource *default_source; - - if (priv->default_client) { - default_source = e_cal_get_source (priv->default_client); - - /* We don't have it but the default client is it */ - if (!strcmp (e_source_peek_uid (default_source), uid)) - client = g_object_ref (priv->default_client); - } - - /* Create a new one */ - if (!client) { - client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_TODO); - if (!client) - return FALSE; - } - } - - g_signal_connect (G_OBJECT (client), "backend_error", G_CALLBACK (backend_error_cb), tasks); - g_signal_connect (G_OBJECT (client), "backend_died", G_CALLBACK (backend_died_cb), tasks); - - /* add the client to internal structure */ - g_hash_table_insert (priv->clients, g_strdup (uid) , client); - priv->clients_list = g_list_prepend (priv->clients_list, client); - - g_signal_emit (tasks, e_tasks_signals[SOURCE_ADDED], 0, source); - - open_ecal (tasks, client, FALSE, client_cal_opened_cb); - - return TRUE; -} - gboolean e_tasks_remove_todo_source (ETasks *tasks, ESource *source) { @@ -1270,68 +640,6 @@ e_tasks_set_default_source (ETasks *tasks, ESource *source) return TRUE; } -ECal * -e_tasks_get_default_client (ETasks *tasks) -{ - ETasksPrivate *priv; - - g_return_val_if_fail (tasks != NULL, NULL); - g_return_val_if_fail (E_IS_TASKS (tasks), NULL); - - priv = tasks->priv; - - return e_cal_model_get_default_client (e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view))); -} - -/** - * e_tasks_complete_selected: - * @tasks: A tasks control widget - * - * Marks the selected tasks complete - **/ -void -e_tasks_complete_selected (ETasks *tasks) -{ - ETasksPrivate *priv; - ECalendarTable *cal_table; - - g_return_if_fail (tasks != NULL); - g_return_if_fail (E_IS_TASKS (tasks)); - - priv = tasks->priv; - - cal_table = E_CALENDAR_TABLE (priv->tasks_view); - - set_status_message (tasks, _("Completing tasks...")); - e_calendar_table_complete_selected (cal_table); - set_status_message (tasks, NULL); -} - -/** - * e_tasks_delete_selected: - * @tasks: A tasks control widget. - * - * Deletes the selected tasks in the task list. - **/ -void -e_tasks_delete_selected (ETasks *tasks) -{ - ETasksPrivate *priv; - ECalendarTable *cal_table; - - g_return_if_fail (tasks != NULL); - g_return_if_fail (E_IS_TASKS (tasks)); - - priv = tasks->priv; - - cal_table = E_CALENDAR_TABLE (priv->tasks_view); - set_status_message (tasks, _("Deleting selected objects...")); - e_calendar_table_delete_selected (cal_table); - set_status_message (tasks, NULL); - - e_cal_component_preview_clear (E_CAL_COMPONENT_PREVIEW (priv->preview)); -} - /** * e_tasks_expunge: * @tasks: A tasks control widget @@ -1383,126 +691,6 @@ e_tasks_delete_completed (ETasks *tasks) g_free (sexp); } -/* Callback used from the view collection when we need to display a new view */ -static void -display_view_cb (GalViewInstance *instance, GalView *view, gpointer data) -{ - ETasks *tasks; - - tasks = E_TASKS (data); - - if (GAL_IS_VIEW_ETABLE (view)) { - gal_view_etable_attach_table (GAL_VIEW_ETABLE (view), e_table_scrolled_get_table (E_TABLE_SCROLLED (E_CALENDAR_TABLE (tasks->priv->tasks_view)->etable))); - } - - gtk_paned_set_position ((GtkPaned *)tasks->priv->paned, calendar_config_get_task_vpane_pos ()); -} - -/** - * e_tasks_setup_view_menus: - * @tasks: A tasks widget. - * @uic: UI controller to use for the menus. - * - * Sets up the #GalView menus for a tasks control. This function should be - * called from the Bonobo control activation callback for this tasks control. - * Also, the menus should be discarded using e_tasks_discard_view_menus(). - **/ -void -e_tasks_setup_view_menus (ETasks *tasks, BonoboUIComponent *uic) -{ - ETasksPrivate *priv; - GalViewFactory *factory; - ETableSpecification *spec; - char *dir0, *dir1, *filename; - static GalViewCollection *collection = NULL; - - g_return_if_fail (tasks != NULL); - g_return_if_fail (E_IS_TASKS (tasks)); - g_return_if_fail (uic != NULL); - g_return_if_fail (BONOBO_IS_UI_COMPONENT (uic)); - - priv = tasks->priv; - - g_return_if_fail (priv->view_instance == NULL); - - g_return_if_fail (priv->view_instance == NULL); - g_return_if_fail (priv->view_menus == NULL); - - /* Create the view instance */ - - if (collection == NULL) { - collection = gal_view_collection_new (); - - gal_view_collection_set_title (collection, _("Tasks")); - - dir0 = g_build_filename (EVOLUTION_GALVIEWSDIR, - "tasks", - NULL); - dir1 = g_build_filename (tasks_component_peek_base_directory (tasks_component_peek ()), - "tasks", "views", NULL); - gal_view_collection_set_storage_directories (collection, - dir0, - dir1); - g_free (dir1); - g_free (dir0); - - /* Create the views */ - - spec = e_table_specification_new (); - filename = g_build_filename (EVOLUTION_ETSPECDIR, - "e-calendar-table.etspec", - NULL); - if (!e_table_specification_load_from_file (spec, filename)) - g_error ("Unable to load ETable specification file " - "for tasks"); - g_free (filename); - - factory = gal_view_factory_etable_new (spec); - g_object_unref (spec); - gal_view_collection_add_factory (collection, factory); - g_object_unref (factory); - - /* Load the collection and create the menus */ - - gal_view_collection_load (collection); - } - - priv->view_instance = gal_view_instance_new (collection, NULL); - - priv->view_menus = gal_view_menus_new (priv->view_instance); - gal_view_menus_apply (priv->view_menus, uic, NULL); - g_signal_connect (priv->view_instance, "display_view", G_CALLBACK (display_view_cb), tasks); - display_view_cb (priv->view_instance, gal_view_instance_get_current_view (priv->view_instance), tasks); -} - -/** - * e_tasks_discard_view_menus: - * @tasks: A tasks widget. - * - * Discards the #GalView menus used by a tasks control. This function should be - * called from the Bonobo control deactivation callback for this tasks control. - * The menus should have been set up with e_tasks_setup_view_menus(). - **/ -void -e_tasks_discard_view_menus (ETasks *tasks) -{ - ETasksPrivate *priv; - - g_return_if_fail (tasks != NULL); - g_return_if_fail (E_IS_TASKS (tasks)); - - priv = tasks->priv; - - g_return_if_fail (priv->view_instance != NULL); - g_return_if_fail (priv->view_menus != NULL); - - g_object_unref (priv->view_instance); - priv->view_instance = NULL; - - g_object_unref (priv->view_menus); - priv->view_menus = NULL; -} - void e_tasks_open_task_id (ETasks *tasks, const char *src_uid, @@ -1541,39 +729,3 @@ e_tasks_open_task_id (ETasks *tasks, return; } - -/** - * e_tasks_get_calendar_table: - * @tasks: A tasks widget. - * - * Queries the #ECalendarTable contained in a tasks widget. - * - * Return value: The #ECalendarTable that the tasks widget uses to display its - * information. - **/ -ECalendarTable * -e_tasks_get_calendar_table (ETasks *tasks) -{ - ETasksPrivate *priv; - - g_return_val_if_fail (tasks != NULL, NULL); - g_return_val_if_fail (E_IS_TASKS (tasks), NULL); - - priv = tasks->priv; - return E_CALENDAR_TABLE (priv->tasks_view); -} - -/** - * e_tasks_get_preview: - * @tasks: A tasks widget. - * - * Queries the #ECalComponentPreview contained in a tasks widget. - **/ -GtkWidget * -e_tasks_get_preview (ETasks *tasks) -{ - g_return_val_if_fail (tasks != NULL, NULL); - g_return_val_if_fail (E_IS_TASKS (tasks), NULL); - - return tasks->priv->preview; -} diff --git a/calendar/gui/e-tasks.h b/calendar/gui/e-tasks.h index 41fcd2d78a..85444392d1 100644 --- a/calendar/gui/e-tasks.h +++ b/calendar/gui/e-tasks.h @@ -63,30 +63,15 @@ GtkWidget *e_tasks_construct (ETasks *tasks); GtkWidget *e_tasks_new (void); -void e_tasks_set_ui_component (ETasks *tasks, - BonoboUIComponent *ui_component); - gboolean e_tasks_add_todo_source (ETasks *tasks, ESource *source); gboolean e_tasks_remove_todo_source (ETasks *tasks, ESource *source); gboolean e_tasks_set_default_source (ETasks *tasks, ESource *source); -ECal *e_tasks_get_default_client (ETasks *tasks); - void e_tasks_open_task (ETasks *tasks); void e_tasks_open_task_id (ETasks *tasks, const char *src_uid, const char *comp_uid, const char *comp_rid); void e_tasks_new_task (ETasks *tasks); -void e_tasks_complete_selected (ETasks *tasks); -void e_tasks_delete_selected (ETasks *tasks); void e_tasks_delete_completed (ETasks *tasks); -void e_tasks_show_preview (ETasks *tasks, gboolean state); -void e_tasks_setup_view_menus (ETasks *tasks, BonoboUIComponent *uic); -void e_tasks_discard_view_menus (ETasks *tasks); - -struct _ECalMenu *e_tasks_get_tasks_menu (ETasks *tasks); -ECalendarTable *e_tasks_get_calendar_table (ETasks *tasks); -GtkWidget *e_tasks_get_preview (ETasks *tasks); - #endif /* _E_TASKS_H_ */ diff --git a/calendar/gui/e-week-view-main-item.c b/calendar/gui/e-week-view-main-item.c index be69282a4a..322acc6676 100644 --- a/calendar/gui/e-week-view-main-item.c +++ b/calendar/gui/e-week-view-main-item.c @@ -91,8 +91,10 @@ e_week_view_main_item_class_init (EWeekViewMainItemClass *class) NULL, G_PARAM_WRITABLE)); +#if 0 /* KILL-BONOBO */ /* init the accessibility support for e_week_view_main_item */ e_week_view_main_item_a11y_init (); +#endif } diff --git a/calendar/gui/e-week-view.c b/calendar/gui/e-week-view.c index 264e30271d..80248ec771 100644 --- a/calendar/gui/e-week-view.c +++ b/calendar/gui/e-week-view.c @@ -51,7 +51,6 @@ #include "comp-util.h" #include "itip-utils.h" #include <libecal/e-cal-time-util.h> -#include "calendar-commands.h" #include "calendar-config.h" #include "print.h" #include "goto.h" @@ -226,8 +225,10 @@ e_week_view_class_init (EWeekViewClass *class) view_class->get_visible_time_range = e_week_view_get_visible_time_range; view_class->paste_text = e_week_view_paste_text; +#if 0 /* KILL-BONOBO */ /* init the accessibility support for e_week_view */ e_week_view_a11y_init (); +#endif } static void @@ -1937,6 +1938,9 @@ set_text_as_bold (EWeekViewEvent *event, EWeekViewEventSpan *span) break; } } + e_cal_component_free_attendee_list (attendees); + g_free (address); + g_object_unref (comp); /* The attendee has not yet accepted the meeting, display the summary as bolded. If the attendee is not present, it might have come through a mailing list. @@ -3612,8 +3616,10 @@ e_week_view_on_editing_stopped (EWeekView *week_view, if (!on_server) { if (!e_cal_create_object (client, icalcomp, NULL, NULL)) g_message (G_STRLOC ": Could not create the object!"); +#if 0 /* KILL-BONOBO */ else gnome_calendar_emit_user_created_signal (week_view, e_calendar_view_get_calendar (E_CALENDAR_VIEW (week_view)), client); +#endif /* we remove the object since we either got the update from the server or failed */ e_week_view_remove_event_cb (week_view, event_num, NULL); @@ -3975,6 +3981,8 @@ e_week_view_cursor_key_right (EWeekView *week_view, GnomeCalendarViewType view_t static gboolean e_week_view_add_new_event_in_selected_range (EWeekView *week_view, const gchar *initial_text) { +#if 0 /* KILL-BONOBO */ + EWeekView *week_view; ECal *ecal; ECalModel *model; ECalComponent *comp; @@ -4163,6 +4171,7 @@ e_week_view_do_key_press (GtkWidget *widget, GdkEventKey *event) g_free (initial_text); return ret_val; +#endif } static gint @@ -4198,6 +4207,7 @@ e_week_view_get_adjust_days_for_move_right (EWeekView *week_view,gint current_da static gboolean e_week_view_key_press (GtkWidget *widget, GdkEventKey *event) { +#if 0 /* KILL-BONOBO */ gboolean handled = FALSE; handled = e_week_view_do_key_press (widget, event); @@ -4205,6 +4215,7 @@ e_week_view_key_press (GtkWidget *widget, GdkEventKey *event) if (!handled) handled = GTK_WIDGET_CLASS (e_week_view_parent_class)->key_press_event (widget, event); return handled; +#endif } static void @@ -4224,9 +4235,11 @@ e_week_view_show_popup_menu (EWeekView *week_view, week_view->popup_event_num = event_num; +#if 0 /* KILL-BONOBO */ popup = e_calendar_view_create_popup_menu (E_CALENDAR_VIEW (week_view)); g_object_weak_ref (G_OBJECT (popup), popup_destroyed_cb, week_view); gtk_menu_popup (popup, NULL, NULL, NULL, NULL, bevent?bevent->button:0, bevent?bevent->time:gtk_get_current_event_time()); +#endif } static gboolean @@ -4241,6 +4254,7 @@ e_week_view_popup_menu (GtkWidget *widget) void e_week_view_jump_to_button_item (EWeekView *week_view, GnomeCanvasItem *item) { +#if 0 /* KILL-BONOBO */ gint day; GnomeCalendar *calendar; @@ -4256,6 +4270,7 @@ e_week_view_jump_to_button_item (EWeekView *week_view, GnomeCanvasItem *item) return; } } +#endif } static gboolean diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c index 87c61bb418..2217cd5b0e 100644 --- a/calendar/gui/gnome-cal.c +++ b/calendar/gui/gnome-cal.c @@ -53,7 +53,6 @@ #include "e-comp-editor-registry.h" #include "dialogs/delete-error.h" #include "dialogs/event-editor.h" -#include "dialogs/task-editor.h" #include "comp-util.h" #include "e-cal-model-calendar.h" #include "e-day-view.h" @@ -65,11 +64,9 @@ #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" @@ -81,7 +78,6 @@ #include "common/authentication.h" #include "e-cal-popup.h" #include "e-cal-menu.h" -#include "e-cal-model-tasks.h" /* FIXME glib 2.4 and above has this */ #ifndef G_MAXINT32 @@ -97,9 +93,9 @@ static GHashTable *non_intrusive_error_table = NULL; struct _GnomeCalendarPrivate { /* The clients for display */ - GHashTable *clients[E_CAL_SOURCE_TYPE_LAST]; - GList *clients_list[E_CAL_SOURCE_TYPE_LAST]; - ECal *default_client[E_CAL_SOURCE_TYPE_LAST]; + GHashTable *clients; + GList *clients_list; + ECal *default_client; /* * Fields for the calendar view @@ -118,11 +114,6 @@ struct _GnomeCalendarPrivate { ECalendar *date_navigator; EMiniCalendarConfig *date_navigator_config; - GtkWidget *todo; - ECalendarTableConfig *todo_config; - - GtkWidget *memo; - EMemoTableConfig *memo_config; GtkWidget *day_view; GtkWidget *work_week_view; @@ -135,8 +126,6 @@ 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 */ @@ -167,10 +156,6 @@ struct _GnomeCalendarPrivate { /* The signal handler id for our GtkCalendar "day_selected" handler. */ guint day_selected_id; - /* View instance and menus for the control */ - GalViewInstance *view_instance; - GalViewMenus *view_menus; - /* Our current week start */ int week_start; @@ -201,11 +186,6 @@ struct _GnomeCalendarPrivate { 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, @@ -213,14 +193,6 @@ enum { LAST_SIGNAL }; -/* Used to indicate who has the focus within the calendar view */ -typedef enum { - FOCUS_CALENDAR, - FOCUS_TASKPAD, - FOCUS_MEMOPAD, - FOCUS_OTHER -} FocusLocation; - static guint gnome_calendar_signals[LAST_SIGNAL]; @@ -317,55 +289,6 @@ gnome_calendar_class_init (GnomeCalendarClass *class) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - gnome_calendar_signals[TASKPAD_SELECTION_CHANGED] = - g_signal_new ("taskpad_selection_changed", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GnomeCalendarClass, taskpad_selection_changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - gnome_calendar_signals[MEMOPAD_SELECTION_CHANGED] = - g_signal_new ("memopad_selection_changed", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GnomeCalendarClass, memopad_selection_changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - - gnome_calendar_signals[CALENDAR_FOCUS_CHANGE] = - g_signal_new ("calendar_focus_change", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GnomeCalendarClass, calendar_focus_change), - NULL, NULL, - g_cclosure_marshal_VOID__BOOLEAN, - G_TYPE_NONE, 1, - G_TYPE_BOOLEAN); - - gnome_calendar_signals[TASKPAD_FOCUS_CHANGE] = - g_signal_new ("taskpad_focus_change", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GnomeCalendarClass, taskpad_focus_change), - NULL, NULL, - g_cclosure_marshal_VOID__BOOLEAN, - G_TYPE_NONE, 1, - G_TYPE_BOOLEAN); - - gnome_calendar_signals[MEMOPAD_FOCUS_CHANGE] = - g_signal_new ("memopad_focus_change", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GnomeCalendarClass, memopad_focus_change), - NULL, NULL, - g_cclosure_marshal_VOID__BOOLEAN, - G_TYPE_NONE, 1, - G_TYPE_BOOLEAN); - gnome_calendar_signals[SOURCE_ADDED] = g_signal_new ("source_added", G_TYPE_FROM_CLASS (object_class), @@ -414,11 +337,6 @@ 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; @@ -725,69 +643,6 @@ get_times_for_views (GnomeCalendar *gcal, GnomeCalendarViewType view_type, time_ } } -/* Gets the focus location based on who is the focused widget within the - * calendar view. - */ -static FocusLocation -get_focus_location (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - 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; - EWeekView *wv; - ECalListView *lv; - - widget = gnome_calendar_get_current_view_widget (gcal); - - switch (priv->current_view_type) { - case GNOME_CAL_DAY_VIEW: - case GNOME_CAL_WORK_WEEK_VIEW: - dv = E_DAY_VIEW (widget); - - if (GTK_WIDGET_HAS_FOCUS (dv->top_canvas) - || GNOME_CANVAS (dv->top_canvas)->focused_item != NULL - || GTK_WIDGET_HAS_FOCUS (dv->main_canvas) - || GNOME_CANVAS (dv->main_canvas)->focused_item != NULL) - return FOCUS_CALENDAR; - else - return FOCUS_OTHER; - - case GNOME_CAL_WEEK_VIEW: - case GNOME_CAL_MONTH_VIEW: - wv = E_WEEK_VIEW (widget); - - if (GTK_WIDGET_HAS_FOCUS (wv->main_canvas) - || GNOME_CANVAS (wv->main_canvas)->focused_item != NULL) - return FOCUS_CALENDAR; - else - return FOCUS_OTHER; - - case GNOME_CAL_LIST_VIEW: - lv = E_CAL_LIST_VIEW (widget); - - if (GTK_WIDGET_HAS_FOCUS (e_table_scrolled_get_table (lv->table_scrolled))) - return FOCUS_CALENDAR; - else - return FOCUS_OTHER; - - default: - g_return_val_if_reached (FOCUS_OTHER); - } - } -} - /* Computes the range of time that the date navigator is showing */ static void get_date_navigator_range (GnomeCalendar *gcal, time_t *start_time, time_t *end_time) @@ -891,7 +746,7 @@ update_query_async (struct _date_query_msg *msg) } /* create queries for each loaded client */ - for (l = priv->clients_list[E_CAL_SOURCE_TYPE_EVENT]; l != NULL; l = l->next) { + for (l = priv->clients_list; l != NULL; l = l->next) { GError *error = NULL; gint tries = 0; @@ -1061,8 +916,9 @@ search_bar_category_changed_cb (CalSearchBar *cal_search, const char *category, category); } + /* [KILL-BONOBO] Delete this when moved to ECalShellView. model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo)); - e_cal_model_set_default_category (model, category); + e_cal_model_set_default_category (model, category); */ } static void @@ -1113,112 +969,6 @@ user_created_cb (GtkWidget *view, GnomeCalendar *gcal) } -/* Callback used when the taskpad receives a focus event. We emit the - * corresponding signal so that parents can change the menus as appropriate. - */ -static gint -table_canvas_focus_change_cb (GtkWidget *widget, GdkEventFocus *event, gpointer data) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - g_signal_emit (gcal, gnome_calendar_signals [TASKPAD_FOCUS_CHANGE], 0, - event->in ? TRUE : FALSE); - - return FALSE; -} - -static gint -memo_canvas_focus_change_cb (GtkWidget *widget, GdkEventFocus *event, gpointer data) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - g_signal_emit (gcal, gnome_calendar_signals [MEMOPAD_FOCUS_CHANGE], 0, - event->in ? TRUE : FALSE); - - return FALSE; -} - -static gint -calendar_focus_change_cb (GtkWidget *widget, GdkEventFocus *event, gpointer data) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - g_signal_emit (gcal, gnome_calendar_signals [CALENDAR_FOCUS_CHANGE], 0, - event->in ? TRUE : FALSE); - - return FALSE; -} - -/* Connects to the focus change signals of a day view widget */ -static void -connect_day_view_focus (GnomeCalendar *gcal, EDayView *dv) -{ - g_signal_connect_after (dv->top_canvas, "focus_in_event", - G_CALLBACK (calendar_focus_change_cb), gcal); - g_signal_connect_after (dv->top_canvas, "focus_out_event", - G_CALLBACK (calendar_focus_change_cb), gcal); - - g_signal_connect_after (dv->main_canvas, "focus_in_event", - G_CALLBACK (calendar_focus_change_cb), gcal); - g_signal_connect_after (dv->main_canvas, "focus_out_event", - G_CALLBACK (calendar_focus_change_cb), gcal); -} - -/* Connects to the focus change signals of a week view widget */ -static void -connect_week_view_focus (GnomeCalendar *gcal, EWeekView *wv) -{ - if (!E_IS_WEEK_VIEW (wv)) - return; - - g_signal_connect (wv->main_canvas, "focus_in_event", - G_CALLBACK (calendar_focus_change_cb), gcal); - g_signal_connect (wv->main_canvas, "focus_out_event", - G_CALLBACK (calendar_focus_change_cb), gcal); -} - -static void -connect_list_view_focus (GnomeCalendar *gcal, ECalListView *lv) -{ - ETable *etable; - - etable = e_table_scrolled_get_table (lv->table_scrolled); - - g_signal_connect (etable->table_canvas, "focus_in_event", - G_CALLBACK (calendar_focus_change_cb), gcal); - g_signal_connect (etable->table_canvas, "focus_out_event", - G_CALLBACK (calendar_focus_change_cb), gcal); -} - -/* Callback used when the selection in the taskpad table changes. We just proxy - * the signal with our own one. - */ -static void -table_selection_change_cb (ETable *etable, gpointer data) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - g_signal_emit (gcal, gnome_calendar_signals[TASKPAD_SELECTION_CHANGED], 0); -} - -static void -memo_selection_change_cb (ETable *etable, gpointer data) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - g_signal_emit (gcal, gnome_calendar_signals[MEMOPAD_SELECTION_CHANGED], 0); -} - static void set_week_start (GnomeCalendar *calendar) { @@ -1271,27 +1021,18 @@ static void set_timezone (GnomeCalendar *calendar) { GnomeCalendarPrivate *priv; - int i; + GList *l; priv = calendar->priv; priv->zone = calendar_config_get_icaltimezone (); - for (i = 0; i < E_CAL_SOURCE_TYPE_LAST; i++) { - GList *l; - - for (l = priv->clients_list[i]; l != NULL; l = l->next) { - ECal *client = l->data; - - if (e_cal_get_load_state (client) == E_CAL_LOAD_LOADED) - /* FIXME Error checking */ - e_cal_set_default_timezone (client, priv->zone, NULL); - } + for (l = priv->clients_list; l != NULL; l = l->next) { + ECal *client = l->data; - if (priv->default_client[i] - && e_cal_get_load_state (priv->default_client[i]) == E_CAL_LOAD_LOADED) + if (e_cal_get_load_state (client) == E_CAL_LOAD_LOADED) /* FIXME Error checking */ - e_cal_set_default_timezone (priv->default_client[i], priv->zone, NULL); + e_cal_set_default_timezone (client, priv->zone, NULL); } if (priv->views [priv->current_view_type]) @@ -1567,26 +1308,15 @@ categories_changed_cb (gpointer object, gpointer user_data) static void view_progress_cb (ECalModel *model, const char *message, int percent, ECalSourceType type, GnomeCalendar *gcal) { - if (type == E_CAL_SOURCE_TYPE_EVENT) { + if (type == E_CAL_SOURCE_TYPE_EVENT) 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); - } } static void view_done_cb (ECalModel *model, ECalendarStatus status, ECalSourceType type, GnomeCalendar *gcal) { - if (type == E_CAL_SOURCE_TYPE_EVENT) { + if (type == E_CAL_SOURCE_TYPE_EVENT) 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); - } - } GtkWidget * @@ -1691,36 +1421,11 @@ setup_widgets (GnomeCalendar *gcal) g_free (tmp); 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_pack1 (GTK_PANED (priv->vpane), vbox, FALSE, FALSE); - 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); - e_calendar_table_load_state (E_CALENDAR_TABLE (priv->todo), filename); - /* update_todo_view (gcal); */ - g_free (filename); - - etable = e_calendar_table_get_table (E_CALENDAR_TABLE (priv->todo)); - g_signal_connect (etable->table_canvas, "focus_in_event", - G_CALLBACK (table_canvas_focus_change_cb), gcal); - g_signal_connect (etable->table_canvas, "focus_out_event", - G_CALLBACK (table_canvas_focus_change_cb), gcal); - - g_signal_connect (etable, "selection_change", - G_CALLBACK (table_selection_change_cb), gcal); - - g_signal_connect (e_calendar_table_get_model ((ECalendarTable *)priv->todo), "cal_view_progress", - G_CALLBACK (view_progress_cb), gcal); - g_signal_connect (e_calendar_table_get_model ((ECalendarTable *)priv->todo), "cal_view_done", - G_CALLBACK (view_done_cb), gcal); /* Timeout check to hide completed items */ priv->update_timeout = g_timeout_add_full (G_PRIORITY_LOW, 60000, (GSourceFunc) update_todo_view_cb, gcal, NULL); @@ -1735,7 +1440,6 @@ setup_widgets (GnomeCalendar *gcal) e_calendar_view_set_timezone (E_CALENDAR_VIEW (priv->day_view), priv->zone); g_signal_connect (priv->day_view, "selection_changed", G_CALLBACK (view_selection_changed_cb), gcal); - connect_day_view_focus (gcal, E_DAY_VIEW (priv->day_view)); /* The Work Week View. */ priv->work_week_view = e_day_view_new (cal_model); @@ -1744,7 +1448,6 @@ setup_widgets (GnomeCalendar *gcal) e_day_view_set_days_shown (E_DAY_VIEW (priv->work_week_view), 5); e_calendar_view_set_calendar (E_CALENDAR_VIEW (priv->work_week_view), gcal); e_calendar_view_set_timezone (E_CALENDAR_VIEW (priv->work_week_view), priv->zone); - connect_day_view_focus (gcal, E_DAY_VIEW (priv->work_week_view)); /* The Marcus Bains line */ priv->update_marcus_bains_line_timeout = g_timeout_add_full (G_PRIORITY_LOW, 60000, (GSourceFunc) update_marcus_bains_line_cb, gcal, NULL); @@ -1756,8 +1459,6 @@ setup_widgets (GnomeCalendar *gcal) g_signal_connect (priv->week_view, "selection_changed", G_CALLBACK (view_selection_changed_cb), gcal); - connect_week_view_focus (gcal, E_WEEK_VIEW (priv->week_view)); - adjustment = gtk_range_get_adjustment (GTK_RANGE (E_WEEK_VIEW (priv->week_view)->vscrollbar)); g_signal_connect (adjustment, "value_changed", G_CALLBACK (week_view_adjustment_changed_cb), @@ -1777,8 +1478,6 @@ setup_widgets (GnomeCalendar *gcal) g_signal_connect (priv->month_view, "selection_changed", G_CALLBACK (view_selection_changed_cb), gcal); - connect_week_view_focus (gcal, E_WEEK_VIEW (priv->month_view)); - adjustment = gtk_range_get_adjustment (GTK_RANGE (E_WEEK_VIEW (priv->month_view)->vscrollbar)); g_signal_connect (adjustment, "value_changed", G_CALLBACK (month_view_adjustment_changed_cb), @@ -1792,8 +1491,6 @@ setup_widgets (GnomeCalendar *gcal) g_signal_connect (priv->list_view, "selection_changed", G_CALLBACK (view_selection_changed_cb), gcal); - connect_list_view_focus (gcal, E_CAL_LIST_VIEW (priv->list_view)); - priv->views[GNOME_CAL_DAY_VIEW] = E_CALENDAR_VIEW (priv->day_view); priv->configs[GNOME_CAL_DAY_VIEW] = G_OBJECT (e_day_view_config_new (E_DAY_VIEW (priv->views[GNOME_CAL_DAY_VIEW]))); priv->views[GNOME_CAL_WORK_WEEK_VIEW] = E_CALENDAR_VIEW (priv->work_week_view); @@ -1822,38 +1519,14 @@ setup_widgets (GnomeCalendar *gcal) gtk_label_set_markup ((GtkLabel *)label, tmp); g_free (tmp); 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, FALSE); - 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); + e_cal_model_set_default_time_func (e_memo_table_get_model (E_MEMO_TABLE (priv->memo)), gc_get_default_time, gcal); e_cal_model_set_default_time_func (e_memo_table_get_model (E_MEMO_TABLE (priv->memo)), gc_get_default_time, gcal); 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); - } /* Object initialization function for the gnome calendar */ @@ -1861,13 +1534,14 @@ static void gnome_calendar_init (GnomeCalendar *gcal) { GnomeCalendarPrivate *priv; - int i; priv = g_new0 (GnomeCalendarPrivate, 1); gcal->priv = priv; - for (i = 0; i < E_CAL_SOURCE_TYPE_LAST; i++) - priv->clients[i] = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + priv->clients = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + + if (non_intrusive_error_table == NULL) + non_intrusive_error_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); if (non_intrusive_error_table == NULL) non_intrusive_error_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); @@ -1884,8 +1558,6 @@ gnome_calendar_init (GnomeCalendar *gcal) setup_widgets (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 */ @@ -1893,7 +1565,6 @@ gnome_calendar_init (GnomeCalendar *gcal) priv->memo_sexp = g_strdup ("#t"); priv->view_instance = NULL; - priv->view_menus = NULL; priv->visible_start = -1; priv->visible_end = -1; @@ -1921,37 +1592,24 @@ gnome_calendar_destroy (GtkObject *object) e_categories_unregister_change_listener (G_CALLBACK (categories_changed_cb), gcal); /* Clean up the clients */ - for (i = 0; i < E_CAL_SOURCE_TYPE_LAST; i++) { - for (l = priv->clients_list[i]; l != NULL; l = l->next) { - ESource *source = e_cal_get_source (l->data); - - g_signal_handlers_disconnect_matched (l->data, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, gcal); - - if (source) - g_signal_handlers_disconnect_matched (source, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, gcal); - } - - g_hash_table_destroy (priv->clients[i]); - g_list_free (priv->clients_list[i]); - - priv->clients[i] = NULL; - priv->clients_list[i] = NULL; - - if (priv->default_client[i]) { - ESource *source = e_cal_get_source (priv->default_client[i]); + for (l = priv->clients_list; l != NULL; l = l->next) { + g_signal_handlers_disconnect_matched (l->data, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, gcal); + } - g_signal_handlers_disconnect_matched (priv->default_client[i], - G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, gcal); + g_hash_table_destroy (priv->clients); + g_list_free (priv->clients_list); - if (source) - g_signal_handlers_disconnect_matched (source, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, gcal); + priv->clients = NULL; + priv->clients_list = NULL; - g_object_unref (priv->default_client[i]); - } - priv->default_client[i] = NULL; + if (priv->default_client) { + g_signal_handlers_disconnect_matched (priv->default_client, + G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, gcal); + g_object_unref (priv->default_client); } + priv->default_client = NULL; for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) { if (priv->configs[i]) @@ -1959,26 +1617,12 @@ gnome_calendar_destroy (GtkObject *object) priv->configs[i] = NULL; } 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)); g_list_free (priv->notifications); priv->notifications = NULL; - /* Save the TaskPad layout. */ - filename = g_build_filename (calendar_component_peek_config_directory (calendar_component_peek ()), - "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) { g_signal_handlers_disconnect_matched ((ECalView *) l->data, G_SIGNAL_MATCH_DATA, @@ -2000,50 +1644,21 @@ gnome_calendar_destroy (GtkObject *object) priv->sexp = NULL; } - if (priv->todo_sexp) { - g_free (priv->todo_sexp); - 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; } - if (priv->view_instance) { - g_object_unref (priv->view_instance); - priv->view_instance = NULL; - } - if (priv->update_marcus_bains_line_timeout) { g_source_remove (priv->update_marcus_bains_line_timeout); priv->update_marcus_bains_line_timeout = 0; } - if (priv->view_menus) { - g_object_unref (priv->view_menus); - priv->view_menus = NULL; - } - if (priv->calendar_menu) { g_object_unref (priv->calendar_menu); priv->calendar_menu = NULL; } - if (priv->taskpad_menu) { - g_object_unref (priv->taskpad_menu); - priv->taskpad_menu = NULL; - } - - if (priv->memopad_menu) { - g_object_unref (priv->memopad_menu); - priv->memopad_menu = NULL; - } /* Disconnect all handlers */ cal_model = e_calendar_view_get_model ((ECalendarView *)priv->week_view); g_signal_handlers_disconnect_by_func (cal_model, @@ -2051,17 +1666,7 @@ gnome_calendar_destroy (GtkObject *object) g_signal_handlers_disconnect_by_func (cal_model, G_CALLBACK (view_done_cb), gcal); - cal_model = e_calendar_table_get_model ((ECalendarTable *) priv->todo); - g_signal_handlers_disconnect_by_func (cal_model, - G_CALLBACK (view_progress_cb), gcal); - g_signal_handlers_disconnect_by_func (cal_model, - G_CALLBACK (view_done_cb), gcal); - - cal_model = e_memo_table_get_model ((EMemoTable *)priv->memo); - g_signal_handlers_disconnect_by_func (cal_model, - G_CALLBACK (view_progress_cb), gcal); - g_signal_handlers_disconnect_by_func (cal_model, - G_CALLBACK (view_done_cb), gcal); + g_mutex_free (priv->todo_update_lock); g_mutex_free (priv->todo_update_lock); @@ -2486,272 +2091,55 @@ display_view_cb (GalViewInstance *view_instance, GalView *view, gpointer data) } -/** - * gnome_calendar_setup_view_menus: - * @gcal: A calendar. - * @uic: UI controller to use for the menus. - * - * Sets up the #GalView menus for a calendar. This function should be called - * from the Bonobo control activation callback for this calendar. Also, the - * menus should be discarded using gnome_calendar_discard_view_menus(). - **/ -void -gnome_calendar_setup_view_menus (GnomeCalendar *gcal, BonoboUIComponent *uic) +static void +gnome_calendar_set_pane_positions (GnomeCalendar *gcal) { GnomeCalendarPrivate *priv; - char *path0, *path1, *etspecfile; - CalendarViewFactory *factory; - GalViewFactory *gal_factory; - static GalViewCollection *collection = NULL; - - g_return_if_fail (gcal != NULL); - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - g_return_if_fail (uic != NULL); - g_return_if_fail (BONOBO_IS_UI_COMPONENT (uic)); priv = gcal->priv; - g_return_if_fail (priv->view_instance == NULL); - g_return_if_fail (priv->view_menus == NULL); - - /* Create the view instance */ - if (collection == NULL) { - ETableSpecification *spec; - - collection = gal_view_collection_new (); - - gal_view_collection_set_title (collection, _("Calendar")); - - path0 = g_build_filename (EVOLUTION_GALVIEWSDIR, - "calendar", - NULL); - path1 = g_build_filename (calendar_component_peek_base_directory (calendar_component_peek ()), - "views", NULL); - gal_view_collection_set_storage_directories (collection, - path0, - path1); - g_free (path1); - g_free (path0); - - /* Create the views */ - - factory = calendar_view_factory_new (GNOME_CAL_DAY_VIEW); - gal_view_collection_add_factory (collection, GAL_VIEW_FACTORY (factory)); - g_object_unref (factory); - - factory = calendar_view_factory_new (GNOME_CAL_WORK_WEEK_VIEW); - gal_view_collection_add_factory (collection, GAL_VIEW_FACTORY (factory)); - g_object_unref (factory); - - factory = calendar_view_factory_new (GNOME_CAL_WEEK_VIEW); - gal_view_collection_add_factory (collection, GAL_VIEW_FACTORY (factory)); - g_object_unref (factory); - - factory = calendar_view_factory_new (GNOME_CAL_MONTH_VIEW); - gal_view_collection_add_factory (collection, GAL_VIEW_FACTORY (factory)); - g_object_unref (factory); - - spec = e_table_specification_new (); - etspecfile = g_build_filename (EVOLUTION_ETSPECDIR, - "e-cal-list-view.etspec", - NULL); - if (!e_table_specification_load_from_file (spec, etspecfile)) - g_error ("Unable to load ETable specification file " - "for calendar"); - g_free (etspecfile); - gal_factory = gal_view_factory_etable_new (spec); - g_object_unref (spec); - gal_view_collection_add_factory (collection, GAL_VIEW_FACTORY (gal_factory)); - g_object_unref (gal_factory); - - /* Load the collection and create the menus */ - - gal_view_collection_load (collection); - + 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); } - - priv->view_instance = gal_view_instance_new (collection, NULL); - priv->view_menus = gal_view_menus_new (priv->view_instance); - gal_view_menus_apply (priv->view_menus, uic, NULL); - - g_signal_connect (priv->view_instance, "display_view", G_CALLBACK (display_view_cb), gcal); - display_view_cb (priv->view_instance, gal_view_instance_get_current_view (priv->view_instance), gcal); -} - -/** - * gnome_calendar_discard_view_menus: - * @gcal: A calendar. - * - * Discards the #GalView menus used by a calendar. This function should be - * called from the Bonobo control deactivation callback for this calendar. The - * menus should have been set up with gnome_calendar_setup_view_menus(). - **/ -void -gnome_calendar_discard_view_menus (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - - g_return_if_fail (gcal != NULL); - - priv = gcal->priv; - - g_return_if_fail (priv->view_instance != NULL); - g_return_if_fail (priv->view_menus != NULL); - - g_object_unref (priv->view_instance); - priv->view_instance = NULL; - - g_object_unref (priv->view_menus); - priv->view_menus = NULL; -} - -/* This is copied/moved from gal-view-instance, only the calendar uses this for a popup menu */ -static void -gc_set_view(EPopup *ep, EPopupItem *pitem, void *data) -{ - GnomeCalendar *gcal = data; - - if (pitem->type & E_POPUP_ACTIVE) - gal_view_instance_set_current_view_id(gcal->priv->view_instance, (char *)pitem->user_data); -} - -static void -gc_save_custom_view(EPopup *ep, EPopupItem *pitem, void *data) -{ - GnomeCalendar *gcal = data; - - gal_view_instance_save_as(gcal->priv->view_instance); -} - -static void -gc_define_views_response(GtkWidget *d, int id, GnomeCalendar *gcal) -{ - if (id == GTK_RESPONSE_OK) - gal_view_collection_save(gcal->priv->view_instance->collection); - - gtk_widget_destroy(d); -} - -static void -gc_define_views(EPopup *ep, EPopupItem *pitem, void *data) -{ - GnomeCalendar *gcal = data; - GtkWidget *dialog = gal_define_views_dialog_new(gcal->priv->view_instance->collection); - - g_signal_connect(dialog, "response", G_CALLBACK(gc_define_views_response), data); - gtk_widget_show(dialog); } -static EPopupItem gc_popups[] = { - /* Code generates the path to fit */ - { E_POPUP_BAR, NULL }, - { E_POPUP_RADIO|E_POPUP_ACTIVE, NULL, N_("_Custom View"), }, - { E_POPUP_ITEM, NULL, N_("_Save Custom View"), gc_save_custom_view }, - - /* index == 3, when we have non-custom view */ - - { E_POPUP_BAR, NULL }, - { E_POPUP_ITEM, NULL, N_("_Define Views..."), gc_define_views }, +struct _mclient_msg { + Message header; + ECalModel *model; + ECal *client; }; static void -gc_popup_free (EPopup *ep, GSList *list, void *data) +add_mclient_async (struct _mclient_msg *msg) { - while (list) { - GSList *n = list->next; - EPopupItem *pitem = list->data; - - g_free(pitem->path); - g_free(pitem->label); - g_free(pitem->user_data); - g_free(pitem); - g_slist_free_1(list); - list = n; - } -} + e_cal_model_add_client (msg->model, msg->client); -static void -gc_popup_free_static (EPopup *ep, GSList *list, void *data) -{ - while (list) { - GSList *n = list->next; - EPopupItem *pitem = list->data; - - g_free(pitem->path); - g_free(pitem); - g_slist_free_1(list); - list = n; - } + g_object_unref (msg->client); + g_object_unref (msg->model); + g_slice_free (struct _mclient_msg, msg); } -void -gnome_calendar_view_popup_factory (GnomeCalendar *gcal, EPopup *ep, const char *prefix) +static void +add_mclient (ECalModel *model, ECal *client) { - GnomeCalendarPrivate *priv; - int length; - int i; - gboolean found = FALSE; - char *id; - GSList *menus = NULL; - EPopupItem *pitem; - - g_return_if_fail (gcal != NULL); - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - g_return_if_fail (prefix != NULL); - - priv = gcal->priv; - - g_return_if_fail (priv->view_instance != NULL); - - length = gal_view_collection_get_count(priv->view_instance->collection); - id = gal_view_instance_get_current_view_id (priv->view_instance); - - for (i = 0; i < length; i++) { - GalViewCollectionItem *item = gal_view_collection_get_view_item(priv->view_instance->collection, i); - - pitem = g_malloc0(sizeof(*pitem)); - pitem->type = E_POPUP_RADIO; - pitem->path = g_strdup_printf("%s/%02d.item", prefix, i); - pitem->label = g_strdup(item->title); - pitem->activate = gc_set_view; - pitem->user_data = g_strdup(item->id); - - if (!found && id && !strcmp (id, item->id)) { - found = TRUE; - pitem->type |= E_POPUP_ACTIVE; - } - - menus = g_slist_prepend(menus, pitem); - } - - if (menus) - e_popup_add_items(ep, menus, NULL, gc_popup_free, gcal); + struct _mclient_msg *msg; - menus = NULL; - for (i = found?3:0; i<sizeof(gc_popups)/sizeof(gc_popups[0]);i++) { - pitem = g_malloc0(sizeof(*pitem)); - memcpy(pitem, &gc_popups[i], sizeof(*pitem)); - pitem->path = g_strdup_printf("%s/%02d.item", prefix, i+length); - menus = g_slist_prepend(menus, pitem); - } + msg = g_slice_new0 (struct _mclient_msg); + msg->header.func = (MessageFunc) add_mclient_async; + msg->model = g_object_ref (model); + msg->client = g_object_ref (client); - e_popup_add_items(ep, menus, NULL, gc_popup_free_static, gcal); + message_push ((Message *) msg); } -static void -gnome_calendar_set_pane_positions (GnomeCalendar *gcal) +static void +non_intrusive_error_remove(GtkWidget *w, void *data) { - GnomeCalendarPrivate *priv; - - priv = gcal->priv; - - 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); - } + g_hash_table_remove(non_intrusive_error_table, data); } struct _mclient_msg { @@ -2793,7 +2181,6 @@ static void client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal) { GnomeCalendarPrivate *priv; - ECalSourceType source_type; ESource *source; ECalModel *model; ECalLoadState state; @@ -2803,23 +2190,9 @@ client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal) priv = gcal->priv; - source_type = e_cal_get_source_type (ecal); source = e_cal_get_source (ecal); state = e_cal_get_load_state (ecal); - switch (source_type) { - case E_CAL_SOURCE_TYPE_EVENT: - e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL, -1); - break; - 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; - } - if (status == E_CALENDAR_STATUS_AUTHENTICATION_FAILED || status == E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED) auth_cal_forget_password (ecal); @@ -2851,32 +2224,27 @@ client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal) e_cal_open_async (ecal, FALSE); return; case E_CALENDAR_STATUS_REPOSITORY_OFFLINE: - if (source_type == E_CAL_SOURCE_TYPE_EVENT) - { - /* check to see if we have dialog already running for this operation */ - id = g_strdup ("calendar:unable-to-load-the-calendar"); - - if (g_hash_table_lookup(non_intrusive_error_table, id)) { - /* We already have it */ - g_message("Error occurred while existing dialog active:\n"); - return; - } + /* check to see if we have dialog already running for this operation */ + id = g_strdup ("calendar:unable-to-load-the-calendar"); - w = e_error_new(GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (gcal))), "calendar:unable-to-load-the-calendar", e_cal_get_error_message (status), NULL); - e_calendar_utils_show_error_silent (w); - g_hash_table_insert (non_intrusive_error_table, id, g_object_ref(w)); - g_signal_connect(w, "destroy", G_CALLBACK(non_intrusive_error_remove), id); + if (g_hash_table_lookup(non_intrusive_error_table, id)) { + /* We already have it */ + g_message("Error occurred while existing dialog active:\n"); + return; } + + w = e_error_new(GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (gcal))), "calendar:unable-to-load-the-calendar", e_cal_get_error_message (status), NULL); + e_calendar_utils_show_error_silent (w); + g_hash_table_insert (non_intrusive_error_table, id, g_object_ref(w)); + g_signal_connect(w, "destroy", G_CALLBACK(non_intrusive_error_remove), id); default: /* Make sure the source doesn't disappear on us */ g_object_ref (source); - g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, gcal); + priv->clients_list = g_list_remove (priv->clients_list, ecal); + g_hash_table_remove (priv->clients, e_source_peek_uid (source)); - priv->clients_list[source_type] = g_list_remove (priv->clients_list[source_type], ecal); - g_hash_table_remove (priv->clients[source_type], e_source_peek_uid (source)); - - g_signal_emit (gcal, gnome_calendar_signals[SOURCE_REMOVED], 0, source_type, source); + g_signal_emit (gcal, gnome_calendar_signals[SOURCE_REMOVED], 0, source); g_object_unref (source); g_warning ("Unable to load the calendar %s \n", e_cal_get_error_message (status)); @@ -2886,74 +2254,35 @@ client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal) g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, client_cal_opened_cb, NULL); - switch (source_type) { - case E_CAL_SOURCE_TYPE_EVENT : - msg = g_strdup_printf (_("Loading appointments at %s"), e_cal_get_uri (ecal)); - e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), msg, -1); - g_free (msg); - - /* add client to the views */ - model = e_calendar_view_get_model (priv->views[priv->current_view_type]); - add_mclient (model, ecal); - - /* update date navigator query */ - update_query (gcal); - - e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL, -1); - break; + msg = g_strdup_printf (_("Loading appointments at %s"), e_cal_get_uri (ecal)); + e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), msg, -1); + g_free (msg); - case E_CAL_SOURCE_TYPE_TODO : - msg = g_strdup_printf (_("Loading tasks at %s"), e_cal_get_uri (ecal)); - e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo), msg, -1); - g_free (msg); + /* add client to the views */ + model = e_calendar_view_get_model (priv->views[priv->current_view_type]); + add_mclient (model, ecal); - e_cal_model_add_client (e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo)), ecal); + /* update date navigator query */ + update_query (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_return_if_reached (); - } + e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL, -1); } static void default_client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal) { GnomeCalendarPrivate *priv; - ECalSourceType source_type; ESource *source; ECalLoadState state; priv = gcal->priv; - source_type = e_cal_get_source_type (ecal); source = e_cal_get_source (ecal); state = e_cal_get_load_state (ecal); if (status == E_CALENDAR_STATUS_AUTHENTICATION_FAILED || status == E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED) auth_cal_forget_password (ecal); - switch (source_type) { - case E_CAL_SOURCE_TYPE_EVENT: - e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL, -1); - break; - 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; - } - switch (status) { case E_CALENDAR_STATUS_OK: break; @@ -2974,15 +2303,15 @@ default_client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, gcal); /* FIXME should we do this to prevent multiple error dialogs? */ - priv->clients_list[source_type] = g_list_remove (priv->clients_list[source_type], ecal); - g_hash_table_remove (priv->clients[source_type], e_source_peek_uid (source)); + priv->clients_list = g_list_remove (priv->clients_list, ecal); + g_hash_table_remove (priv->clients, e_source_peek_uid (source)); /* FIXME Is there a better way to handle this? */ - if (priv->default_client[source_type]) - g_object_unref (priv->default_client[source_type]); - priv->default_client[source_type] = NULL; + if (priv->default_client) + g_object_unref (priv->default_client); + priv->default_client = NULL; - g_signal_emit (gcal, gnome_calendar_signals[SOURCE_REMOVED], 0, source_type, source); + g_signal_emit (gcal, gnome_calendar_signals[SOURCE_REMOVED], 0, source); g_object_unref (source); g_warning ("Unable to load the calendar %s \n", e_cal_get_error_message (status)); @@ -2992,22 +2321,10 @@ default_client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, default_client_cal_opened_cb, NULL); - switch (source_type) { - case E_CAL_SOURCE_TYPE_EVENT: - e_cal_model_set_default_client ( - e_calendar_view_get_model (E_CALENDAR_VIEW (priv->views[priv->current_view_type])), - ecal); - break; - - 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; - } + e_cal_model_set_default_client ( + e_calendar_view_get_model ( + E_CALENDAR_VIEW (priv->views[priv->current_view_type])), + ecal); } typedef void (*open_func) (ECal *, ECalendarStatus, GnomeCalendar *); @@ -3025,20 +2342,7 @@ open_ecal (GnomeCalendar *gcal, ECal *cal, gboolean only_if_exists, open_func of e_cal_set_default_timezone (cal, zone, NULL); msg = g_strdup_printf (_("Opening %s"), e_cal_get_uri (cal)); - switch (e_cal_get_source_type (cal)) { - case E_CAL_SOURCE_TYPE_EVENT : - e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), msg, -1); - break; - 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_free (msg); - g_return_val_if_reached (FALSE); - } + e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), msg, -1); g_free (msg); @@ -3083,7 +2387,6 @@ backend_died_cb (ECal *ecal, gpointer data) { GnomeCalendar *gcal; GnomeCalendarPrivate *priv; - ECalSourceType source_type; ESource *source; const char *id; GtkWidget *w = NULL; @@ -3094,39 +2397,16 @@ backend_died_cb (ECal *ecal, gpointer data) /* FIXME What about default sources? */ /* Make sure the source doesn't go away on us since we use it below */ - source_type = e_cal_get_source_type (ecal); source = g_object_ref (e_cal_get_source (ecal)); - priv->clients_list[source_type] = g_list_remove (priv->clients_list[source_type], ecal); - g_hash_table_remove (priv->clients[source_type], e_source_peek_uid (source)); - - switch (source_type) { - case E_CAL_SOURCE_TYPE_EVENT: - id = g_strdup ("calendar:calendar-crashed"); - - e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL, -1); - - g_signal_emit (gcal, gnome_calendar_signals[SOURCE_REMOVED], 0, source_type, source); - break; - - case E_CAL_SOURCE_TYPE_TODO: - id = g_strdup ("calendar:calendar-crashed"); + priv->clients_list = g_list_remove (priv->clients_list, ecal); + g_hash_table_remove (priv->clients, e_source_peek_uid (source)); - e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo), NULL, -1); + id = g_strdup ("calendar:calendar-crashed"); - g_signal_emit (gcal, gnome_calendar_signals[SOURCE_REMOVED], 0, source_type, source); - break; - - case E_CAL_SOURCE_TYPE_JOURNAL: - id = g_strdup ("calendar:calendar-crashed"); - - e_memo_table_set_status_message (E_MEMO_TABLE (priv->memo), NULL); + e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL, -1); - g_signal_emit (gcal, gnome_calendar_signals[SOURCE_REMOVED], 0, source_type, source); - break; - default: - g_return_if_reached (); - } + g_signal_emit (gcal, gnome_calendar_signals[SOURCE_REMOVED], 0, source); g_object_unref (source); @@ -3171,35 +2451,6 @@ gnome_calendar_new (void) return GTK_WIDGET (gcal); } -void -gnome_calendar_set_activity_handler (GnomeCalendar *cal, EActivityHandler *activity_handler) -{ - GnomeCalendarPrivate *priv; - int i; - - g_return_if_fail (cal != NULL); - g_return_if_fail (GNOME_IS_CALENDAR (cal)); - - priv = cal->priv; - - priv->activity_handler = activity_handler; - - for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) - e_calendar_view_set_activity_handler (priv->views[i], activity_handler); - - e_calendar_table_set_activity_handler (E_CALENDAR_TABLE (priv->todo), activity_handler); -} - -void -gnome_calendar_set_ui_component (GnomeCalendar *gcal, - BonoboUIComponent *ui_component) -{ - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - g_return_if_fail (ui_component == NULL || BONOBO_IS_UI_COMPONENT (ui_component)); - - e_search_bar_set_ui_component (E_SEARCH_BAR (gcal->priv->search_bar), ui_component); -} - /** * gnome_calendar_get_calendar_model: * @gcal: A calendar view. @@ -3247,7 +2498,7 @@ gnome_calendar_get_default_client (GnomeCalendar *gcal) * Returns: TRUE if successful, FALSE if error. */ gboolean -gnome_calendar_add_source (GnomeCalendar *gcal, ECalSourceType source_type, ESource *source) +gnome_calendar_add_source (GnomeCalendar *gcal, ESource *source) { GnomeCalendarPrivate *priv; ECal *client; @@ -3258,7 +2509,7 @@ gnome_calendar_add_source (GnomeCalendar *gcal, ECalSourceType source_type, ESou priv = gcal->priv; - client = g_hash_table_lookup (priv->clients[source_type], e_source_peek_uid (source)); + client = g_hash_table_lookup (priv->clients, e_source_peek_uid (source)); if (client) { /* We already have it */ @@ -3266,18 +2517,18 @@ gnome_calendar_add_source (GnomeCalendar *gcal, ECalSourceType source_type, ESou } else { ESource *default_source; - if (priv->default_client[source_type]) { - default_source = e_cal_get_source (priv->default_client[source_type]); + if (priv->default_client) { + default_source = e_cal_get_source (priv->default_client); g_message ("Check if default client matches (%s %s)", e_source_peek_uid (default_source), e_source_peek_uid (source)); /* We don't have it but the default client is it */ if (!strcmp (e_source_peek_uid (default_source), e_source_peek_uid (source))) - client = g_object_ref (priv->default_client[source_type]); + client = g_object_ref (priv->default_client); } /* Create a new one */ if (!client) { - client = auth_new_cal_from_source (source, source_type); + client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_EVENT); if (!client) return FALSE; } @@ -3287,10 +2538,10 @@ gnome_calendar_add_source (GnomeCalendar *gcal, ECalSourceType source_type, ESou g_signal_connect (G_OBJECT (client), "backend_died", G_CALLBACK (backend_died_cb), gcal); /* add the client to internal structure */ - g_hash_table_insert (priv->clients[source_type], g_strdup (e_source_peek_uid (source)), client); - priv->clients_list[source_type] = g_list_prepend (priv->clients_list[source_type], client); + g_hash_table_insert (priv->clients, g_strdup (e_source_peek_uid (source)), client); + priv->clients_list = g_list_prepend (priv->clients_list, client); - g_signal_emit (gcal, gnome_calendar_signals[SOURCE_ADDED], 0, source_type, source); + g_signal_emit (gcal, gnome_calendar_signals[SOURCE_ADDED], 0, source); open_ecal (gcal, client, FALSE, client_cal_opened_cb); @@ -3308,7 +2559,7 @@ gnome_calendar_add_source (GnomeCalendar *gcal, ECalSourceType source_type, ESou * Returns: TRUE if successful, FALSE otherwise. */ gboolean -gnome_calendar_remove_source (GnomeCalendar *gcal, ECalSourceType source_type, ESource *source) +gnome_calendar_remove_source (GnomeCalendar *gcal, ESource *source) { gboolean result; @@ -3316,15 +2567,15 @@ gnome_calendar_remove_source (GnomeCalendar *gcal, ECalSourceType source_type, E g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), FALSE); g_return_val_if_fail (E_IS_SOURCE (source), FALSE); - result = gnome_calendar_remove_source_by_uid (gcal, source_type, e_source_peek_uid (source)); + result = gnome_calendar_remove_source_by_uid (gcal, e_source_peek_uid (source)); if (result) - g_signal_emit (gcal, gnome_calendar_signals[SOURCE_REMOVED], 0, source_type, source); + g_signal_emit (gcal, gnome_calendar_signals[SOURCE_REMOVED], 0, source); return result; } gboolean -gnome_calendar_remove_source_by_uid (GnomeCalendar *gcal, ECalSourceType source_type, const char *uid) +gnome_calendar_remove_source_by_uid (GnomeCalendar *gcal, const char *uid) { GnomeCalendarPrivate *priv; ECal *client; @@ -3337,51 +2588,34 @@ gnome_calendar_remove_source_by_uid (GnomeCalendar *gcal, ECalSourceType source_ priv = gcal->priv; - client = g_hash_table_lookup (priv->clients[source_type], uid); + client = g_hash_table_lookup (priv->clients, uid); if (!client) return TRUE; - priv->clients_list[source_type] = g_list_remove (priv->clients_list[source_type], client); + priv->clients_list = g_list_remove (priv->clients_list, client); g_signal_handlers_disconnect_matched (client, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, gcal); - switch (source_type) { - case E_CAL_SOURCE_TYPE_EVENT: - /* remove the query for this client */ - for (l = priv->dn_queries; l != NULL; l = l->next) { - ECalView *query = l->data; + /* remove the query for this client */ + for (l = priv->dn_queries; l != NULL; l = l->next) { + ECalView *query = l->data; - if (query && (client == e_cal_view_get_client (query))) { - g_signal_handlers_disconnect_matched (query, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, gcal); - priv->dn_queries = g_list_remove (priv->dn_queries, query); - g_object_unref (query); - break; - } + if (query && (client == e_cal_view_get_client (query))) { + g_signal_handlers_disconnect_matched (query, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, gcal); + priv->dn_queries = g_list_remove (priv->dn_queries, query); + g_object_unref (query); + break; } + } - model = e_calendar_view_get_model (priv->views[priv->current_view_type]); - e_cal_model_remove_client (model, client); - - /* update date navigator query */ - update_query (gcal); - break; - - case E_CAL_SOURCE_TYPE_TODO: - 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; + model = e_calendar_view_get_model (priv->views[priv->current_view_type]); + e_cal_model_remove_client (model, client); - default: - g_return_val_if_reached (TRUE); - } + /* update date navigator query */ + update_query (gcal); - g_hash_table_remove (priv->clients[source_type], uid); + g_hash_table_remove (priv->clients, uid); return TRUE; } @@ -3399,7 +2633,7 @@ gnome_calendar_remove_source_by_uid (GnomeCalendar *gcal, ECalSourceType source_ * otherwise **/ gboolean -gnome_calendar_set_default_source (GnomeCalendar *gcal, ECalSourceType source_type, ESource *source) +gnome_calendar_set_default_source (GnomeCalendar *gcal, ESource *source) { GnomeCalendarPrivate *priv; ECal *client; @@ -3410,21 +2644,21 @@ gnome_calendar_set_default_source (GnomeCalendar *gcal, ECalSourceType source_ty priv = gcal->priv; - client = g_hash_table_lookup (priv->clients[source_type], e_source_peek_uid (source)); + client = g_hash_table_lookup (priv->clients, e_source_peek_uid (source)); - if (priv->default_client[source_type]) - g_object_unref (priv->default_client[source_type]); + if (priv->default_client) + g_object_unref (priv->default_client); if (client) { - priv->default_client[source_type] = g_object_ref (client); + priv->default_client = g_object_ref (client); } else { - priv->default_client[source_type] = auth_new_cal_from_source (source, source_type); - if (!priv->default_client[source_type]) + priv->default_client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_EVENT); + if (!priv->default_client) return FALSE; } - open_ecal (gcal, priv->default_client[source_type], FALSE, default_client_cal_opened_cb); + open_ecal (gcal, priv->default_client, FALSE, default_client_cal_opened_cb); return TRUE; } @@ -3787,55 +3021,34 @@ gnome_calendar_vpane_resized (GtkWidget *w, GdkEventButton *e, GnomeCalendar *gc void gnome_calendar_cut_clipboard (GnomeCalendar *gcal) { - GnomeCalendarPrivate *priv; - FocusLocation location; - - priv = gcal->priv; + GtkWidget *widget; - location = get_focus_location (gcal); + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - if (location == FOCUS_CALENDAR) { - 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_memo_table_cut_clipboard (E_MEMO_TABLE (priv->memo)); + widget = gnome_calendar_get_current_view_widget (gcal); + e_calendar_view_cut_clipboard (E_CALENDAR_VIEW (widget)); } void gnome_calendar_copy_clipboard (GnomeCalendar *gcal) { - GnomeCalendarPrivate *priv; - FocusLocation location; - - priv = gcal->priv; + GtkWidget *widget; - location = get_focus_location (gcal); + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - if (location == FOCUS_CALENDAR) { - 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_memo_table_copy_clipboard (E_MEMO_TABLE (priv->memo)); + widget = gnome_calendar_get_current_view_widget (gcal); + e_calendar_view_copy_clipboard (E_CALENDAR_VIEW (widget)); } void gnome_calendar_paste_clipboard (GnomeCalendar *gcal) { - GnomeCalendarPrivate *priv; - FocusLocation location; + GtkWidget *widget; - priv = gcal->priv; - - location = get_focus_location (gcal); + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - if (location == FOCUS_CALENDAR) { - 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)); + widget = gnome_calendar_get_current_view_widget (gcal); + e_calendar_view_paste_clipboard (E_CALENDAR_VIEW (widget)); } @@ -3897,69 +3110,26 @@ gnome_calendar_get_num_events_selected (GnomeCalendar *gcal) return retval; } -/** - * gnome_calendar_get_num_tasks_selected: - * @gcal: A calendar view. - * - * Queries the number of tasks that are currently selected in the task pad of a - * calendar view. - * - * Return value: Number of selected tasks. - **/ -gint -gnome_calendar_get_num_tasks_selected (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - ETable *etable; - - g_return_val_if_fail (gcal != NULL, -1); - g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), -1); - - priv = gcal->priv; - - etable = e_calendar_table_get_table (E_CALENDAR_TABLE (priv->todo)); - return e_table_selected_count (etable); -} - - void -gnome_calendar_delete_selection (GnomeCalendar *gcal) +gnome_calendar_delete_selection (GnomeCalendar *gcal) { - GnomeCalendarPrivate *priv; - FocusLocation location; - GtkWidget *view; + GtkWidget *widget; g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - priv = gcal->priv; - - location = get_focus_location (gcal); - - if (location == FOCUS_CALENDAR) { - view = gnome_calendar_get_current_view_widget (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)); + widget = gnome_calendar_get_current_view_widget (gcal); + e_calendar_view_delete_selected_events (E_CALENDAR_VIEW (widget)); } void gnome_calendar_delete_selected_occurrence (GnomeCalendar *gcal) { - FocusLocation location; - GtkWidget *view; + GtkWidget *widget; g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - location = get_focus_location (gcal); - - if (location == FOCUS_CALENDAR) { - - view = gnome_calendar_get_current_view_widget (gcal); - e_calendar_view_delete_selected_occurrence (E_CALENDAR_VIEW (view)); - } + widget = gnome_calendar_get_current_view_widget (gcal); + e_calendar_view_delete_selected_occurrence (E_CALENDAR_VIEW (widget)); } static gboolean @@ -4058,14 +3228,6 @@ gnome_calendar_purge (GnomeCalendar *gcal, time_t older_than) } -ECalendarTable* -gnome_calendar_get_task_pad (GnomeCalendar *gcal) -{ - g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL); - - return E_CALENDAR_TABLE (gcal->priv->todo); -} - GtkWidget * gnome_calendar_get_e_calendar_widget (GnomeCalendar *gcal) { @@ -4090,13 +3252,6 @@ gnome_calendar_get_view_notebook_widget (GnomeCalendar *gcal) return GTK_WIDGET(gcal->priv->notebook); } -ECalMenu *gnome_calendar_get_taskpad_menu (GnomeCalendar *gcal) -{ - g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL); - - return gcal->priv->taskpad_menu; -} - ECalMenu *gnome_calendar_get_calendar_menu (GnomeCalendar *gcal) { g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL); @@ -4104,14 +3259,6 @@ 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 e1a86dab25..92fe2cba70 100644 --- a/calendar/gui/gnome-cal.h +++ b/calendar/gui/gnome-cal.h @@ -87,17 +87,13 @@ struct _GnomeCalendarClass { void (* dates_shown_changed) (GnomeCalendar *gcal); 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); + void (* change_view) (GnomeCalendar *gcal, + GnomeCalendarViewType view_type); - void (* source_added) (GnomeCalendar *gcal, ECalSourceType source_type, ESource *source); - void (* source_removed) (GnomeCalendar *gcal, ECalSourceType source_type, ESource *source); + void (* source_added) (GnomeCalendar *gcal, ESource *source); + void (* source_removed) (GnomeCalendar *gcal, ESource *source); /* Action signals */ void (* goto_date) (GnomeCalendar *gcal, GnomeCalendarGotoDateType date); @@ -109,18 +105,15 @@ GtkWidget *gnome_calendar_construct (GnomeCalendar *gcal); GtkWidget *gnome_calendar_new (void); -void gnome_calendar_set_activity_handler (GnomeCalendar *cal, EActivityHandler *activity_handler); -void gnome_calendar_set_ui_component (GnomeCalendar *cal, BonoboUIComponent *ui_component); - ECalendarTable *gnome_calendar_get_task_pad (GnomeCalendar *gcal); ECalModel *gnome_calendar_get_calendar_model (GnomeCalendar *gcal); ECal *gnome_calendar_get_default_client (GnomeCalendar *gcal); -gboolean gnome_calendar_add_source (GnomeCalendar *gcal, ECalSourceType source_type, ESource *source); -gboolean gnome_calendar_remove_source (GnomeCalendar *gcal, ECalSourceType source_type, ESource *source); -gboolean gnome_calendar_remove_source_by_uid (GnomeCalendar *gcal, ECalSourceType source_type, const char *uid); -gboolean gnome_calendar_set_default_source (GnomeCalendar *gcal, ECalSourceType source_type, ESource *source); +gboolean gnome_calendar_add_source (GnomeCalendar *gcal, ESource *source); +gboolean gnome_calendar_remove_source (GnomeCalendar *gcal, ESource *source); +gboolean gnome_calendar_remove_source_by_uid (GnomeCalendar *gcal, const char *uid); +gboolean gnome_calendar_set_default_source (GnomeCalendar *gcal, ESource *source); void gnome_calendar_next (GnomeCalendar *gcal); void gnome_calendar_previous (GnomeCalendar *gcal); @@ -136,20 +129,12 @@ void gnome_calendar_set_view (GnomeCalendar *gcal, GnomeCalendarViewType view_ty GtkWidget *gnome_calendar_get_current_view_widget (GnomeCalendar *gcal); -ECalendarTable *gnome_calendar_get_task_pad (GnomeCalendar *gcal); GtkWidget *gnome_calendar_get_e_calendar_widget (GnomeCalendar *gcal); GtkWidget *gnome_calendar_get_search_bar_widget (GnomeCalendar *gcal); GtkWidget *gnome_calendar_get_view_notebook_widget (GnomeCalendar *gcal); GtkWidget *gnome_calendar_get_tag (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); - -void gnome_calendar_view_popup_factory (GnomeCalendar *gcal, struct _EPopup *ep, const char *prefix); void gnome_calendar_set_selected_time_range (GnomeCalendar *gcal, time_t start_time, @@ -176,9 +161,6 @@ gboolean gnome_calendar_get_visible_time_range (GnomeCalendar *gcal, /* Returns the number of selected events (0 or 1 at present). */ gint gnome_calendar_get_num_events_selected (GnomeCalendar *gcal); -/* Returns the number of selected tasks */ -gint gnome_calendar_get_num_tasks_selected (GnomeCalendar *gcal); - /* Get the current timezone. */ icaltimezone *gnome_calendar_get_timezone (GnomeCalendar *gcal); diff --git a/calendar/gui/goto.c b/calendar/gui/goto.c index ac4100160a..3c0cfc7576 100644 --- a/calendar/gui/goto.c +++ b/calendar/gui/goto.c @@ -28,7 +28,6 @@ #include <gtk/gtk.h> #include <glade/glade.h> #include "e-util/e-util-private.h" -#include "calendar-commands.h" #include "calendar-config.h" #include "tag-calendar.h" #include "goto.h" @@ -76,12 +75,14 @@ month_changed (GtkToggleButton *toggle, gpointer data) static void ecal_date_range_changed (ECalendarItem *calitem, gpointer user_data) { +#if 0 /* KILL-BONOBO */ GoToDialog *dlg = user_data; ECal *client; client = gnome_calendar_get_default_client (dlg->gcal); if (client) tag_calendar_by_client (dlg->ecal, client); +#endif } /* Event handler for day groups in the month item. A button press makes the calendar jump to the @@ -90,6 +91,7 @@ ecal_date_range_changed (ECalendarItem *calitem, gpointer user_data) static void ecal_event (ECalendarItem *calitem, gpointer user_data) { +#if 0 /* KILL-BONOBO */ GoToDialog *dlg = user_data; GDate start_date, end_date; struct icaltimetype tt = icaltime_null_time (); @@ -106,6 +108,7 @@ ecal_event (ECalendarItem *calitem, gpointer user_data) gnome_calendar_goto (dlg->gcal, et); gtk_dialog_response (GTK_DIALOG (dlg->dialog), GTK_RESPONSE_NONE); +#endif } /* Returns the current time, for the ECalendarItem. */ @@ -160,7 +163,9 @@ create_ecal (GoToDialog *dlg) static void goto_today (GoToDialog *dlg) { +#if 0 /* KILL-BONOBO */ gnome_calendar_goto_today (dlg->gcal); +#endif } /* Gets the widgets from the XML file and returns if they are all available. */ @@ -201,6 +206,7 @@ goto_dialog_init_widgets (GoToDialog *dlg) void goto_dialog (GnomeCalendar *gcal) { +#if 0 /* KILL-BONOBO */ time_t start_time; struct icaltimetype tt; int b; @@ -269,4 +275,5 @@ goto_dialog (GnomeCalendar *gcal) g_object_unref (dlg->xml); g_free (dlg); dlg = NULL; +#endif } diff --git a/calendar/gui/itip-bonobo-control.c b/calendar/gui/itip-bonobo-control.c deleted file mode 100644 index ccfb0254e8..0000000000 --- a/calendar/gui/itip-bonobo-control.c +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Evolution calendar - Control for displaying iTIP mail messages - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Jesse Pavel <jpavel@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#include <config.h> -#include <string.h> -#include <gtk/gtk.h> -#include <bonobo/bonobo-generic-factory.h> -#include <bonobo/bonobo-control.h> -#include <bonobo/bonobo-property-bag.h> -#include <bonobo/bonobo-persist-stream.h> -#include <bonobo/bonobo-stream-client.h> -#include <bonobo/bonobo-context.h> -#include <bonobo/bonobo-exception.h> -#include <libical/ical.h> - -#include "e-itip-control.h" -#include "itip-bonobo-control.h" - -extern gchar *evolution_dir; - -enum E_ITIP_BONOBO_ARGS { - FROM_ADDRESS_ARG_ID, - VIEW_ONLY_ARG_ID -}; - -/* - * Bonobo::PersistStream - * - * These two functions implement the Bonobo::PersistStream load and - * save methods which allow data to be loaded into and out of the - * BonoboObject. - */ - -static char * -stream_read (Bonobo_Stream stream) -{ - Bonobo_Stream_iobuf *buffer; - CORBA_Environment ev; - gchar *data = NULL; - gint length = 0; - - CORBA_exception_init (&ev); - do { -#define READ_CHUNK_SIZE 65536 - Bonobo_Stream_read (stream, READ_CHUNK_SIZE, - &buffer, &ev); - - if (BONOBO_EX (&ev)) { - CORBA_exception_free (&ev); - return NULL; - } - - if (buffer->_length <= 0) - break; - - data = g_realloc (data, length + buffer->_length + 1); - memcpy (data + length, buffer->_buffer, buffer->_length); - length += buffer->_length; - data[length] = '\0'; - - CORBA_free (buffer); -#undef READ_CHUNK_SIZE - } while (1); - - CORBA_free (buffer); - CORBA_exception_free (&ev); - - if (data == NULL) - data = g_strdup(""); - - return data; -} /* stream_read */ - -/* - * This function implements the Bonobo::PersistStream:load method. - */ -typedef struct { - EItipControl *itip; - char *text; -} idle_data; - -static gboolean -set_data_idle_cb (gpointer data) -{ - idle_data *id = data; - - e_itip_control_set_data (id->itip, id->text); - g_object_unref (id->itip); - g_free (id->text); - g_free (id); - - return FALSE; -} - -static void -pstream_load (BonoboPersistStream *ps, const Bonobo_Stream stream, - Bonobo_Persist_ContentType type, void *data, - CORBA_Environment *ev) -{ - EItipControl *itip = data; - idle_data *id; - - if (type && g_ascii_strcasecmp (type, "text/calendar") != 0 && - g_ascii_strcasecmp (type, "text/x-calendar") != 0) { - bonobo_exception_set (ev, ex_Bonobo_Persist_WrongDataType); - return; - } - - id = g_new0 (idle_data, 1); - if ((id->text = stream_read (stream)) == NULL) { - bonobo_exception_set (ev, ex_Bonobo_Persist_FileNotFound); - g_free (id); - return; - } - g_object_ref (itip); - id->itip = itip; - - g_idle_add (set_data_idle_cb, id); -} -/* - * This function implements the Bonobo::PersistStream:save method. - */ -static void -pstream_save (BonoboPersistStream *ps, const Bonobo_Stream stream, - Bonobo_Persist_ContentType type, void *data, - CORBA_Environment *ev) -{ - EItipControl *itip = data; - gchar *text; - gint len; - - if (type && g_ascii_strcasecmp (type, "text/calendar") != 0 && - g_ascii_strcasecmp (type, "text/x-calendar") != 0) { - bonobo_exception_set (ev, ex_Bonobo_Persist_WrongDataType); - return; - } - - text = e_itip_control_get_data (itip); - len = e_itip_control_get_data_size (itip); - - bonobo_stream_client_write (stream, text, len, ev); - g_free (text); -} /* pstream_save */ - -/* static CORBA_long */ -/* pstream_get_max_size (BonoboPersistStream *ps, void *data, */ -/* CORBA_Environment *ev) */ -/* { */ -/* EItipControl *itip = data; */ -/* gint len; */ - -/* len = e_itip_control_get_data_size (itip); */ - -/* if (len > 0) */ -/* return len; */ - -/* return 0L; */ -/* } */ - -static Bonobo_Persist_ContentTypeList * -pstream_get_content_types (BonoboPersistStream *ps, void *closure, - CORBA_Environment *ev) -{ - return bonobo_persist_generate_content_types (2, "text/calendar", "text/x-calendar"); -} - -static void -get_prop (BonoboPropertyBag *bag, - BonoboArg *arg, - guint arg_id, - CORBA_Environment *ev, - gpointer user_data) -{ - EItipControl *itip = user_data; - - switch (arg_id) { - case FROM_ADDRESS_ARG_ID: - BONOBO_ARG_SET_STRING (arg, e_itip_control_get_from_address (itip)); - break; - case VIEW_ONLY_ARG_ID: - BONOBO_ARG_SET_INT (arg, e_itip_control_get_view_only (itip)); - break; - } -} - -static void -set_prop ( BonoboPropertyBag *bag, - const BonoboArg *arg, - guint arg_id, - CORBA_Environment *ev, - gpointer user_data) -{ - EItipControl *itip = user_data; - - switch (arg_id) { - case FROM_ADDRESS_ARG_ID: - e_itip_control_set_from_address (itip, BONOBO_ARG_GET_STRING (arg)); - break; - case VIEW_ONLY_ARG_ID: - e_itip_control_set_view_only (itip, BONOBO_ARG_GET_INT (arg)); - break; - } -} - - -BonoboControl * -itip_bonobo_control_new (void) -{ - BonoboControl *control; - BonoboPropertyBag *prop_bag; - BonoboPersistStream *stream; - GtkWidget *itip; - - itip = e_itip_control_new (); - gtk_widget_show (itip); - control = bonobo_control_new (itip); - - /* create a property bag */ - prop_bag = bonobo_property_bag_new (get_prop, set_prop, itip); - bonobo_property_bag_add (prop_bag, "from_address", FROM_ADDRESS_ARG_ID, BONOBO_ARG_STRING, NULL, - "from_address", 0 ); - bonobo_property_bag_add (prop_bag, "view_only", VIEW_ONLY_ARG_ID, BONOBO_ARG_INT, NULL, - "view_only", 0 ); - - bonobo_control_set_properties (control, bonobo_object_corba_objref (BONOBO_OBJECT (prop_bag)), NULL); - bonobo_object_unref (BONOBO_OBJECT (prop_bag)); - - bonobo_control_set_automerge (control, TRUE); - - stream = bonobo_persist_stream_new (pstream_load, pstream_save, - pstream_get_content_types, - "OAFIID:GNOME_Evolution_Calendar_iTip_Control:" BASE_VERSION, - itip); - - if (stream == NULL) { - bonobo_object_unref (BONOBO_OBJECT (control)); - return NULL; - } - - bonobo_object_add_interface (BONOBO_OBJECT (control), - BONOBO_OBJECT (stream)); - - return control; -} diff --git a/calendar/gui/itip-utils.c b/calendar/gui/itip-utils.c index 829ac287ce..c6aa0214ca 100644 --- a/calendar/gui/itip-utils.c +++ b/calendar/gui/itip-utils.c @@ -37,7 +37,6 @@ #include <time.h> #include <composer/e-msg-composer.h> -#include <mail/em-composer-utils.h> #include <camel/camel-mime-filter-tohtml.h> static gchar *itip_methods[] = { @@ -1250,7 +1249,6 @@ itip_send_comp (ECalComponentItipMethod method, ECalComponent *send_comp, composer = e_msg_composer_new (); table = e_msg_composer_get_header_table (composer); - em_composer_utils_setup_default_callbacks (composer); e_composer_header_table_set_subject (table, subject); e_composer_header_table_set_account_name (table, from); @@ -1358,7 +1356,6 @@ reply_to_calendar_comp (ECalComponentItipMethod method, composer = e_msg_composer_new (); table = e_msg_composer_get_header_table (composer); - em_composer_utils_setup_default_callbacks (composer); e_composer_header_table_set_subject (table, subject); e_composer_header_table_set_account_name (table, from); diff --git a/calendar/gui/main.c b/calendar/gui/main.c deleted file mode 100644 index 2085bb20af..0000000000 --- a/calendar/gui/main.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Ettore Perazzoli <ettore@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <glib.h> -#include <glib/gi18n.h> -#include <libgnome/gnome-init.h> -#include <glade/glade.h> - -#include <bonobo/bonobo-main.h> -#include <bonobo/bonobo-shlib-factory.h> -#include <bonobo/bonobo-exception.h> - -#include "dialogs/cal-prefs-dialog.h" -#include "calendar-commands.h" -#include "calendar-config.h" -#include "calendar-component.h" -#include "e-comp-editor-registry.h" -#include "comp-editor-factory.h" -#include "control-factory.h" -#include "itip-bonobo-control.h" -#include "tasks-control.h" -#include "tasks-component.h" -#include "memos-component.h" - -#include <e-util/e-plugin.h> -#include <e-util/e-import.h> -#include "e-cal-config.h" -#include "e-cal-popup.h" -#include "e-cal-menu.h" -#include "e-cal-event.h" -#include "calendar/importers/evolution-calendar-importer.h" - -#define FACTORY_ID "OAFIID:GNOME_Evolution_Calendar_Factory:" BASE_VERSION - -#define CALENDAR_COMPONENT_ID "OAFIID:GNOME_Evolution_Calendar_Component:" BASE_VERSION -#define TASKS_COMPONENT_ID "OAFIID:GNOME_Evolution_Tasks_Component:" BASE_VERSION -#define MEMOS_COMPONENT_ID "OAFIID:GNOME_Evolution_Memos_Component:" BASE_VERSION -#define ITIP_CONTROL_ID "OAFIID:GNOME_Evolution_Calendar_iTip_Control:" BASE_VERSION -#define CONFIG_CONTROL_ID "OAFIID:GNOME_Evolution_Calendar_ConfigControl:" BASE_VERSION -#define COMP_EDITOR_FACTORY_ID "OAFIID:GNOME_Evolution_Calendar_CompEditorFactory:" BASE_VERSION - -ECompEditorRegistry *comp_editor_registry = NULL; - -/* The component editor factory */ -static CompEditorFactory *comp_editor_factory = NULL; - - -/* Factory function for the calendar component factory; just creates and - * references a singleton service object. - */ -static BonoboObject * -comp_editor_factory_fn (void) -{ - if (!comp_editor_factory) { - comp_editor_factory = comp_editor_factory_new (); - if (!comp_editor_factory) - return NULL; - } - - bonobo_object_ref (BONOBO_OBJECT (comp_editor_factory)); - return BONOBO_OBJECT (comp_editor_factory); -} - - -/* Does a simple activation and unreffing of the alarm notification service so - * that the daemon will be launched if it is not running yet. - */ -static gboolean -launch_alarm_daemon_cb (gpointer data) -{ - CORBA_Environment ev; - CORBA_Object an; - - /* activate the alarm daemon */ - CORBA_exception_init (&ev); - an = bonobo_activation_activate_from_id ("OAFIID:GNOME_Evolution_Calendar_AlarmNotify:" BASE_VERSION, 0, NULL, &ev); - - if (BONOBO_EX (&ev)) { - g_message ("launch_alarm_daemon_cb(): %s", bonobo_exception_get_text (&ev)); - CORBA_exception_free (&ev); - return FALSE; - } - CORBA_exception_free (&ev); - - /* Just get rid of it; what we are interested in is that it gets launched */ - - CORBA_exception_init (&ev); - bonobo_object_release_unref (an, &ev); - if (BONOBO_EX (&ev)) - g_message ("add_alarms(): Could not unref the alarm notification service"); - - CORBA_exception_free (&ev); - - return FALSE; -} - -static void -launch_alarm_daemon (void) -{ - g_idle_add ((GSourceFunc) launch_alarm_daemon_cb, NULL); -} - -static void -initialize (void) -{ - EImportClass *klass; - - comp_editor_registry = E_COMP_EDITOR_REGISTRY (e_comp_editor_registry_new ()); - -#if 0 - itip_control_factory_init (); - component_editor_factory_init (); -#endif - - launch_alarm_daemon (); - - - /* Initialize plugin system */ - e_plugin_hook_register_type (e_cal_popup_hook_get_type()); - e_plugin_hook_register_type (e_cal_menu_hook_get_type()); - e_plugin_hook_register_type (e_cal_config_hook_get_type ()); - e_plugin_hook_register_type (e_cal_event_hook_get_type ()); - - klass = g_type_class_ref(e_import_get_type()); - e_import_class_add_importer(klass, gnome_calendar_importer_peek(), NULL, NULL); - e_import_class_add_importer(klass, ical_importer_peek(), NULL, NULL); - e_import_class_add_importer(klass, vcal_importer_peek(), NULL, NULL); -} - -static BonoboObject * -factory (BonoboGenericFactory *factory, - const char *component_id, - void *closure) -{ - static gboolean initialized = FALSE; - - if (! initialized) { - initialize (); - initialized = TRUE; - } - - if (strcmp (component_id, CALENDAR_COMPONENT_ID) == 0) { - BonoboObject *object = BONOBO_OBJECT (calendar_component_peek ()); - bonobo_object_ref (object); - return object; - } else if (strcmp (component_id, TASKS_COMPONENT_ID) == 0) { - BonoboObject *object = BONOBO_OBJECT (tasks_component_peek ()); - bonobo_object_ref (object); - return object; - } else if (strcmp (component_id, MEMOS_COMPONENT_ID) == 0){ - BonoboObject *object = BONOBO_OBJECT (memos_component_peek ()); - bonobo_object_ref (object); - return object; - } else if (strcmp (component_id, ITIP_CONTROL_ID) == 0) - return BONOBO_OBJECT (itip_bonobo_control_new ()); - else if (strcmp (component_id, CONFIG_CONTROL_ID) == 0) { - GtkWidget *prefs; - EvolutionConfigControl *control; - - prefs = calendar_prefs_dialog_new (); - gtk_widget_show (prefs); - control = evolution_config_control_new (prefs); - - return BONOBO_OBJECT (control); - } else if (strcmp (component_id, COMP_EDITOR_FACTORY_ID) == 0) - return BONOBO_OBJECT (comp_editor_factory_fn ()); - - g_warning (FACTORY_ID ": Don't know what to do with %s", component_id); - return NULL; -} - -BONOBO_ACTIVATION_SHLIB_FACTORY (FACTORY_ID, "Evolution Calendar component factory", factory, NULL) diff --git a/calendar/gui/memos-component.c b/calendar/gui/memos-component.c index 0e422d548d..5e16d3118b 100644 --- a/calendar/gui/memos-component.c +++ b/calendar/gui/memos-component.c @@ -58,28 +58,13 @@ #define CREATE_SHARED_MEMO_ID "shared-memo" #define CREATE_MEMO_LIST_ID "memo-list" -enum DndTargetType { - DND_TARGET_TYPE_CALENDAR_LIST, -}; -#define CALENDAR_TYPE "text/calendar" -#define XCALENDAR_TYPE "text/x-calendar" #define WEB_BASE_URI "webcal://" #define PERSONAL_RELATIVE_URI "system" -static GtkTargetEntry drag_types[] = { - { CALENDAR_TYPE, 0, DND_TARGET_TYPE_CALENDAR_LIST }, - { XCALENDAR_TYPE, 0, DND_TARGET_TYPE_CALENDAR_LIST } -}; -static gint num_drag_types = sizeof(drag_types) / sizeof(drag_types[0]); - #define PARENT_TYPE bonobo_object_get_type () static BonoboObjectClass *parent_class = NULL; -/* Memos should have their own registry */ -extern ECompEditorRegistry *comp_editor_registry; - - typedef struct _MemosComponentView { ESourceList *source_list; @@ -90,29 +75,17 @@ typedef struct _MemosComponentView ETable *table; ETableModel *model; - EInfoLabel *info_label; GtkWidget *source_selector; - BonoboControl *view_control; - BonoboControl *sidebar_control; - BonoboControl *statusbar_control; - GList *notifications; - EUserCreatableItemsHandler *creatable_items_handler; - - EActivityHandler *activity_handler; } MemosComponentView; struct _MemosComponentPrivate { - char *base_directory; - char *config_directory; ESourceList *source_list; GSList *source_selection; - GList *views; - ECal *create_ecal; GList *notifications; @@ -120,109 +93,6 @@ struct _MemosComponentPrivate { #define d(x) -static void -ensure_sources (MemosComponent *component) -{ - ESourceList *source_list; - ESourceGroup *on_this_computer; - ESource *personal_source; - char *base_uri, *base_uri_proto, base_uri_proto_seventh; - const gchar *base_dir; - - personal_source = NULL; - - if (!e_cal_get_sources (&source_list, E_CAL_SOURCE_TYPE_JOURNAL, NULL)) { - g_warning ("Could not get memo source list from GConf!"); - return; - } - - base_dir = memos_component_peek_base_directory (component); - base_uri = g_build_filename (base_dir, "local", NULL); - - base_uri_proto = g_filename_to_uri (base_uri, NULL, NULL); - if (strlen (base_uri_proto) > 7) { - /* compare only file:// part. If user home dir name changes we do not want to create - one more group */ - base_uri_proto_seventh = base_uri_proto[7]; - base_uri_proto[7] = 0; - } else { - base_uri_proto_seventh = -1; - } - - on_this_computer = e_source_list_ensure_group (source_list, _("On This Computer"), base_uri_proto, TRUE); - e_source_list_ensure_group (source_list, _("On The Web"), WEB_BASE_URI, FALSE); - - if (base_uri_proto_seventh != -1) { - base_uri_proto[7] = base_uri_proto_seventh; - } - - if (on_this_computer) { - /* make sure "Personal" shows up as a source under - this group */ - GSList *sources = e_source_group_peek_sources (on_this_computer); - GSList *s; - for (s = sources; s; s = s->next) { - ESource *source = E_SOURCE (s->data); - const gchar *relative_uri; - - relative_uri = e_source_peek_relative_uri (source); - if (relative_uri == NULL) - continue; - if (!strcmp (PERSONAL_RELATIVE_URI, relative_uri)) { - personal_source = source; - break; - } - } - /* Make sure we have the correct base uri. This can change when user's - homedir name changes */ - if (strcmp (base_uri_proto, e_source_group_peek_base_uri (on_this_computer))) { - e_source_group_set_base_uri (on_this_computer, base_uri_proto); - - /* *sigh* . We shouldn't need this sync call here as set_base_uri - call results in synching to gconf, but that happens in idle loop - and too late to prevent user seeing "Can not Open ... because of invalid uri" error.*/ - e_source_list_sync (source_list,NULL); - } - } - - if (personal_source) { - /* ensure the source name is in current locale, not read from configuration */ - e_source_set_name (personal_source, _("Personal")); - } else { - GSList *memos_selected; - /* Create the default Person addressbook */ - ESource *source = e_source_new (_("Personal"), PERSONAL_RELATIVE_URI); - e_source_group_add_source (on_this_computer, source, -1); - g_object_unref (source); - - memos_selected = calendar_config_get_memos_selected (); - - if (!calendar_config_get_primary_memos () && !memos_selected) { - GSList selected; - - calendar_config_set_primary_memos (e_source_peek_uid (source)); - - selected.data = (gpointer)e_source_peek_uid (source); - selected.next = NULL; - calendar_config_set_memos_selected (&selected); - } - - if (memos_selected) { - g_slist_foreach (memos_selected, (GFunc) g_free, NULL); - g_slist_free (memos_selected); - } - - e_source_set_color_spec (source, "#BECEDD"); - personal_source = source; - } - - component->priv->source_list = source_list; - - g_object_unref (on_this_computer); - g_free (base_uri_proto); - g_free (base_uri); -} - /* Utility functions. */ /* FIXME Some of these are duplicated from calendar-component.c */ static gboolean @@ -256,7 +126,7 @@ is_in_uids (GSList *uids, ESource *source) } static void -update_uris_for_selection (MemosComponentView *component_view) +source_selection_changed_cb (ESourceSelector *selector, MemosComponentView *component_view) { GSList *selection, *l, *uids_selected = NULL; @@ -284,339 +154,8 @@ update_uris_for_selection (MemosComponentView *component_view) g_slist_free (uids_selected); } -static void -update_uri_for_primary_selection (MemosComponentView *component_view) -{ - ESource *source; - EMemoTable *cal_table; - ETable *etable; - - source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector)); - if (!source) - return; - - /* Set the default */ - e_memos_set_default_source (component_view->memos, source); - - cal_table = e_memos_get_calendar_table (component_view->memos); - etable = e_memo_table_get_table (cal_table); - - memos_control_sensitize_commands (component_view->view_control, component_view->memos, e_table_selected_count (etable)); - - /* Save the selection for next time we start up */ - calendar_config_set_primary_memos (e_source_peek_uid (source)); -} - -static void -update_selection (MemosComponentView *component_view) -{ - GSList *selection, *uids_selected, *l; - - d(g_message("memos-component.c: update_selection called");) - - /* Get the selection in gconf */ - uids_selected = calendar_config_get_memos_selected (); - - /* Remove any that aren't there any more */ - selection = e_source_selector_get_selection (E_SOURCE_SELECTOR (component_view->source_selector)); - - for (l = selection; l; l = l->next) { - ESource *source = l->data; - - if (!is_in_uids (uids_selected, source)) - e_source_selector_unselect_source (E_SOURCE_SELECTOR (component_view->source_selector), source); - } - - e_source_selector_free_selection (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->source_list, uid); - if (source) - e_source_selector_select_source (E_SOURCE_SELECTOR (component_view->source_selector), source); - - g_free (uid); - } - g_slist_free (uids_selected); -} - -static void -update_primary_selection (MemosComponentView *component_view) -{ - ESource *source = NULL; - char *uid; - - uid = calendar_config_get_primary_memos (); - if (uid) { - source = e_source_list_peek_source_by_uid (component_view->source_list, uid); - g_free (uid); - } - - if (source) { - e_source_selector_set_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector), source); - } else { - /* Try to create a default if there isn't one */ - source = e_source_list_peek_source_any (component_view->source_list); - if (source) - e_source_selector_set_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector), source); - } - -} - - -/* Callbacks. */ -/* TODO: doesn't work! */ -static void -copy_memo_list_cb (EPopup *ep, EPopupItem *pitem, void *data) -{ - MemosComponentView *component_view = data; - ESource *selected_source; - - selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector)); - if (!selected_source) - return; - - copy_source_dialog (GTK_WINDOW (gtk_widget_get_toplevel(ep->target->widget)), selected_source, E_CAL_SOURCE_TYPE_JOURNAL); -} - -static void -delete_memo_list_cb (EPopup *ep, EPopupItem *pitem, void *data) -{ - MemosComponentView *component_view = data; - ESource *selected_source; - ECal *cal; - char *uri; - - selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector)); - if (!selected_source) - return; - - if (e_error_run((GtkWindow *)gtk_widget_get_toplevel(ep->target->widget), - "calendar:prompt-delete-memo-list", e_source_peek_name(selected_source), NULL) != GTK_RESPONSE_YES) - return; - - /* first, ask the backend to remove the memo list */ - uri = e_source_get_uri (selected_source); - cal = e_cal_model_get_client_for_uri ( - e_memo_table_get_model (E_MEMO_TABLE (e_memos_get_calendar_table (component_view->memos))), - uri); - if (!cal) - cal = e_cal_new_from_uri (uri, E_CAL_SOURCE_TYPE_JOURNAL); - g_free (uri); - if (cal) { - if (e_cal_remove (cal, NULL)) { - if (e_source_selector_source_is_selected (E_SOURCE_SELECTOR (component_view->source_selector), - selected_source)) { - e_memos_remove_memo_source (component_view->memos, selected_source); - e_source_selector_unselect_source (E_SOURCE_SELECTOR (component_view->source_selector), - selected_source); - } - - e_source_group_remove_source (e_source_peek_group (selected_source), selected_source); - e_source_list_sync (component_view->source_list, NULL); - } - } -} - -static void -new_memo_list_cb (EPopup *ep, EPopupItem *pitem, void *data) -{ - calendar_setup_new_memo_list (GTK_WINDOW (gtk_widget_get_toplevel(ep->target->widget))); -} - -static void -rename_memo_list_cb (EPopup *ep, EPopupItem *pitem, void *data) -{ - MemosComponentView *component_view = data; - ESourceSelector *selector; - - selector = E_SOURCE_SELECTOR (component_view->source_selector); - e_source_selector_edit_primary_selection (selector); -} - -static void -edit_memo_list_cb (EPopup *ep, EPopupItem *pitem, void *data) -{ - MemosComponentView *component_view = data; - ESource *selected_source; - - selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector)); - if (!selected_source) - return; - - calendar_setup_edit_memo_list (GTK_WINDOW (gtk_widget_get_toplevel(ep->target->widget)), selected_source); -} - -static void -set_offline_availability (EPopup *ep, EPopupItem *pitem, void *data, const char *value) -{ - MemosComponentView *component_view = data; - ESource *selected_source; - - selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector)); - if (!selected_source) - return; - - e_source_set_property (selected_source, "offline_sync", value); -} - -static void -mark_no_offline_cb (EPopup *ep, EPopupItem *pitem, void *data) -{ - set_offline_availability (ep, pitem, data, "0"); -} - -static void -mark_offline_cb (EPopup *ep, EPopupItem *pitem, void *data) -{ - set_offline_availability (ep, pitem, data, "1"); -} - -static EPopupItem emc_source_popups[] = { - { E_POPUP_ITEM, "10.new", N_("_New Memo List"), new_memo_list_cb, NULL, "stock_notes", 0, 0 }, - { E_POPUP_ITEM, "15.copy", N_("_Copy..."), copy_memo_list_cb, NULL, "edit-copy", 0, E_CAL_POPUP_SOURCE_PRIMARY }, - { E_POPUP_ITEM, "18.rename", N_("_Rename..."), rename_memo_list_cb, NULL, NULL, 0, E_CAL_POPUP_SOURCE_PRIMARY }, - - { E_POPUP_BAR, "20.bar" }, - { E_POPUP_ITEM, "20.delete", N_("_Delete"), delete_memo_list_cb, NULL, "edit-delete", 0, E_CAL_POPUP_SOURCE_USER|E_CAL_POPUP_SOURCE_PRIMARY }, - { E_POPUP_ITEM, "30.mark_memos_offline", N_("_Make available for offline use"), mark_offline_cb, NULL, "stock_disconnect", E_CAL_POPUP_SOURCE_OFFLINE, E_CAL_POPUP_SOURCE_USER|E_CAL_POPUP_SOURCE_PRIMARY|E_CAL_POPUP_SOURCE_OFFLINE }, - { E_POPUP_ITEM, "40.mark_memos_no_offline", N_("_Do not make available for offline use"), mark_no_offline_cb, NULL, "stock_connect", E_CAL_POPUP_SOURCE_NO_OFFLINE, E_CAL_POPUP_SOURCE_USER|E_CAL_POPUP_SOURCE_PRIMARY|E_CAL_POPUP_SOURCE_NO_OFFLINE }, - - { E_POPUP_BAR, "99.bar" }, - { E_POPUP_ITEM, "99.properties", N_("_Properties"), edit_memo_list_cb, NULL, "document-properties", 0, E_CAL_POPUP_SOURCE_PRIMARY }, -}; - -static void -emc_source_popup_free(EPopup *ep, GSList *list, void *data) -{ - g_slist_free(list); -} - -static gboolean -popup_event_cb(ESourceSelector *selector, ESource *insource, GdkEventButton *event, MemosComponentView *component_view) -{ - ECalPopup *ep; - ECalPopupTargetSource *t; - GSList *menus = NULL; - int i; - GtkMenu *menu; - - /** @HookPoint-ECalPopup: Memos Source Selector Context Menu - * @Id: org.gnome.evolution.memos.source.popup - * @Class: org.gnome.evolution.calendar.popup:1.0 - * @Target: ECalPopupTargetSource - * - * The context menu on the source selector in the memos window. - */ - ep = e_cal_popup_new("org.gnome.evolution.memos.source.popup"); - t = e_cal_popup_target_new_source(ep, selector); - t->target.widget = (GtkWidget *)component_view->memos; - - for (i=0;i<sizeof(emc_source_popups)/sizeof(emc_source_popups[0]);i++) - menus = g_slist_prepend(menus, &emc_source_popups[i]); - - e_popup_add_items((EPopup *)ep, menus, NULL,emc_source_popup_free, component_view); - - menu = e_popup_create_menu_once((EPopup *)ep, (EPopupTarget *)t, 0); - gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event?event->button:0, event?event->time:gtk_get_current_event_time()); - - return TRUE; -} - -static void -source_selection_changed_cb (ESourceSelector *selector, MemosComponentView *component_view) -{ - update_uris_for_selection (component_view); -} - -static void -primary_source_selection_changed_cb (ESourceSelector *selector, MemosComponentView *component_view) -{ - update_uri_for_primary_selection (component_view); -} - -static void -source_added_cb (EMemos *memos, ESource *source, MemosComponentView *component_view) -{ - e_source_selector_select_source (E_SOURCE_SELECTOR (component_view->source_selector), source); -} - -static void -source_removed_cb (EMemos *memos, ESource *source, MemosComponentView *component_view) -{ - e_source_selector_unselect_source (E_SOURCE_SELECTOR (component_view->source_selector), source); -} - -static void -set_info (MemosComponentView *component_view) -{ - GString *message = g_string_new (NULL); - int rows, selected_rows; - - rows = e_table_model_row_count (component_view->model); - selected_rows = e_table_selected_count (component_view->table); - - g_string_append_printf(message, ngettext("%d memo", "%d memos", rows), rows); - if (selected_rows > 0) - g_string_append_printf(message, ngettext(", %d selected", ", %d selected", selected_rows), selected_rows); - - e_info_label_set_info (component_view->info_label, _("Memos"), message->str); - - g_string_free (message, TRUE); -} - -static void -table_selection_change_cb (ETableModel *etm, MemosComponentView *component_view) -{ - set_info (component_view); -} - -static void -model_changed_cb (ETableModel *etm, MemosComponentView *component_view) -{ - set_info (component_view); -} - -static void -model_rows_inserted_cb (ETableModel *etm, int row, int count, MemosComponentView *component_view) -{ - set_info (component_view); -} - -static void -model_rows_deleted_cb (ETableModel *etm, int row, int count, MemosComponentView *component_view) -{ - set_info (component_view); -} - /* Evolution::Component CORBA methods */ -static void -impl_upgradeFromVersion (PortableServer_Servant servant, - CORBA_short major, - CORBA_short minor, - CORBA_short revision, - CORBA_Environment *ev) -{ - GError *err = NULL; - MemosComponent *component = MEMOS_COMPONENT (bonobo_object_from_servant (servant)); - - if (!migrate_memos(component, major, minor, revision, &err)) { - GNOME_Evolution_Component_UpgradeFailed *failedex; - - failedex = GNOME_Evolution_Component_UpgradeFailed__alloc(); - failedex->what = CORBA_string_dup(_("Failed upgrading memos.")); - failedex->why = CORBA_string_dup(err->message); - CORBA_exception_set(ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Component_UpgradeFailed, failedex); - } - - if (err) - g_error_free(err); -} - static gboolean selector_tree_data_dropped (ESourceSelector *selector, GtkSelectionData *data, @@ -668,19 +207,6 @@ selector_tree_data_dropped (ESourceSelector *selector, } static void -control_activate_cb (BonoboControl *control, gboolean activate, gpointer data) -{ - MemosComponentView *component_view = data; - - if (activate) { - BonoboUIComponent *uic; - uic = bonobo_control_get_ui_component (component_view->view_control); - - e_user_creatable_items_handler_activate (component_view->creatable_items_handler, uic); - } -} - -static void config_create_ecal_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) { MemosComponent *component = data; @@ -812,140 +338,32 @@ create_new_memo (MemosComponent *memo_component, gboolean is_assigned, MemosComp return TRUE; } -static void -create_local_item_cb (EUserCreatableItemsHandler *handler, const char *item_type_name, void *data) -{ - MemosComponent *memos_component = data; - MemosComponentPrivate *priv; - MemosComponentView *component_view = NULL; - GList *l; - - priv = memos_component->priv; - - for (l = priv->views; l; l = l->next) { - component_view = l->data; - - if (component_view->creatable_items_handler == handler) - break; - - component_view = NULL; - } - - if (strcmp (item_type_name, CREATE_MEMO_ID) == 0) { - create_new_memo (memos_component, FALSE, component_view); - } 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)))); - } -} - static MemosComponentView * create_component_view (MemosComponent *memos_component) { MemosComponentPrivate *priv; MemosComponentView *component_view; - GtkWidget *selector_scrolled_window, *vbox; GtkWidget *statusbar_widget; - AtkObject *a11y; priv = memos_component->priv; /* Create the calendar component view */ component_view = g_new0 (MemosComponentView, 1); - /* Add the source lists */ - component_view->source_list = g_object_ref (priv->source_list); - /* Create sidebar selector */ - component_view->source_selector = e_source_selector_new (memos_component->priv->source_list); - e_source_selector_set_select_new ((ESourceSelector *)component_view->source_selector, TRUE); - a11y = gtk_widget_get_accessible (GTK_WIDGET (component_view->source_selector)); - atk_object_set_name (a11y, _("Memo Source Selector")); - - g_signal_connect ( - component_view->source_selector, "data-dropped", - G_CALLBACK (selector_tree_data_dropped), memos_component); - - gtk_drag_dest_set(component_view->source_selector, GTK_DEST_DEFAULT_ALL, drag_types, - num_drag_types, GDK_ACTION_COPY | GDK_ACTION_MOVE); - - gtk_widget_show (component_view->source_selector); - - selector_scrolled_window = gtk_scrolled_window_new (NULL, NULL); - gtk_container_add (GTK_CONTAINER (selector_scrolled_window), component_view->source_selector); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (selector_scrolled_window), - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (selector_scrolled_window), - GTK_SHADOW_IN); - gtk_widget_show (selector_scrolled_window); - - component_view->info_label = (EInfoLabel *)e_info_label_new("evolution-memos"); - e_info_label_set_info(component_view->info_label, _("Memos"), ""); - gtk_widget_show (GTK_WIDGET (component_view->info_label)); - - vbox = gtk_vbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX (vbox), GTK_WIDGET (component_view->info_label), FALSE, TRUE, 0); - gtk_box_pack_start(GTK_BOX (vbox), selector_scrolled_window, TRUE, TRUE, 0); - gtk_widget_show (vbox); - - component_view->sidebar_control = bonobo_control_new (vbox); - - /* Create main view */ - component_view->view_control = memos_control_new (); - if (!component_view->view_control) { - /* FIXME free memory */ - - return NULL; - } + g_signal_connect (component_view->source_selector, "drag-data-received", + G_CALLBACK (selector_tree_drag_data_received), memos_component); component_view->memos = (EMemos *) bonobo_control_get_widget (component_view->view_control); component_view->table = e_memo_table_get_table (e_memos_get_calendar_table (component_view->memos)); component_view->model = E_TABLE_MODEL (e_memo_table_get_model (e_memos_get_calendar_table (component_view->memos))); - /* This signal is thrown if backends die - we update the selector */ - g_signal_connect (component_view->memos, "source_added", - G_CALLBACK (source_added_cb), component_view); - g_signal_connect (component_view->memos, "source_removed", - G_CALLBACK (source_removed_cb), component_view); - - /* Create status bar */ - statusbar_widget = e_task_bar_new (); - component_view->activity_handler = e_activity_handler_new (); - e_activity_handler_attach_task_bar (component_view->activity_handler, E_TASK_BAR (statusbar_widget)); - gtk_widget_show (statusbar_widget); - - component_view->statusbar_control = bonobo_control_new (statusbar_widget); - - e_memo_table_set_activity_handler (e_memos_get_calendar_table (component_view->memos), component_view->activity_handler); - /* connect after setting the initial selections, or we'll get unwanted calls to calendar_control_sensitize_calendar_commands */ g_signal_connect (component_view->source_selector, "selection_changed", G_CALLBACK (source_selection_changed_cb), component_view); g_signal_connect (component_view->source_selector, "primary_selection_changed", G_CALLBACK (primary_source_selection_changed_cb), component_view); - g_signal_connect (component_view->source_selector, "popup_event", - G_CALLBACK (popup_event_cb), component_view); - - /* Set up the "new" item handler */ - component_view->creatable_items_handler = e_user_creatable_items_handler_new ("memos", create_local_item_cb, memos_component); - g_signal_connect (component_view->view_control, "activate", G_CALLBACK (control_activate_cb), component_view); - - /* We use this to update the component information */ - set_info (component_view); - g_signal_connect (component_view->table, "selection_change", - G_CALLBACK (table_selection_change_cb), component_view); - g_signal_connect (component_view->model, "model_changed", - G_CALLBACK (model_changed_cb), component_view); - g_signal_connect (component_view->model, "model_rows_inserted", - G_CALLBACK (model_rows_inserted_cb), component_view); - g_signal_connect (component_view->model, "model_rows_deleted", - G_CALLBACK (model_rows_deleted_cb), component_view); - - /* Load the selection from the last run */ - update_selection (component_view); - update_primary_selection (component_view); return component_view; } @@ -965,130 +383,9 @@ destroy_component_view (MemosComponentView *component_view) calendar_config_remove_notification (GPOINTER_TO_UINT (l->data)); g_list_free (component_view->notifications); - if (component_view->creatable_items_handler) - g_object_unref (component_view->creatable_items_handler); - - if (component_view->activity_handler) - g_object_unref (component_view->activity_handler); - g_free (component_view); } -static void -view_destroyed_cb (gpointer data, GObject *where_the_object_was) -{ - MemosComponent *memos_component = data; - MemosComponentPrivate *priv; - GList *l; - - priv = memos_component->priv; - - for (l = priv->views; l; l = l->next) { - MemosComponentView *component_view = l->data; - - if (G_OBJECT (component_view->view_control) == where_the_object_was) { - priv->views = g_list_remove (priv->views, component_view); - destroy_component_view (component_view); - - break; - } - } -} - -static GNOME_Evolution_ComponentView -impl_createView (PortableServer_Servant servant, - GNOME_Evolution_ShellView parent, - CORBA_boolean select_item, - CORBA_Environment *ev) -{ - MemosComponent *component = MEMOS_COMPONENT (bonobo_object_from_servant (servant)); - MemosComponentPrivate *priv; - MemosComponentView *component_view; - EComponentView *ecv; - - priv = component->priv; - - /* Create the calendar component view */ - component_view = create_component_view (component); - if (!component_view) { - /* FIXME Should we describe the problem in a control? */ - bonobo_exception_set (ev, ex_GNOME_Evolution_Component_Failed); - - return CORBA_OBJECT_NIL; - } - - g_object_weak_ref (G_OBJECT (component_view->view_control), view_destroyed_cb, component); - priv->views = g_list_append (priv->views, component_view); - - /* TODO: Make CalendarComponentView just subclass EComponentView */ - ecv = e_component_view_new_controls (parent, "memos", component_view->sidebar_control, - component_view->view_control, component_view->statusbar_control); - - return BONOBO_OBJREF(ecv); -} - -static GNOME_Evolution_CreatableItemTypeList * -impl__get_userCreatableItems (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - GNOME_Evolution_CreatableItemTypeList *list = GNOME_Evolution_CreatableItemTypeList__alloc (); - - list->_length = 3; - list->_maximum = list->_length; - list->_buffer = GNOME_Evolution_CreatableItemTypeList_allocbuf (list->_length); - - CORBA_sequence_set_release (list, FALSE); - - list->_buffer[0].id = CREATE_MEMO_ID; - list->_buffer[0].description = _("New memo"); - list->_buffer[0].menuDescription = (char *) C_("New", "Mem_o"); - list->_buffer[0].tooltip = _("Create a new memo"); - list->_buffer[0].menuShortcut = 'o'; - list->_buffer[0].iconName = "stock_insert-note"; - list->_buffer[0].type = GNOME_Evolution_CREATABLE_OBJECT; - - list->_buffer[1].id = CREATE_SHARED_MEMO_ID; - list->_buffer[1].description = _("New shared memo"); - list->_buffer[1].menuDescription = (char *) C_("New", "_Shared memo"); - list->_buffer[1].tooltip = _("Create a shared new memo"); - list->_buffer[1].menuShortcut = 'h'; - 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 = (char *) C_("New", "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; -} - -static void -impl_requestCreateItem (PortableServer_Servant servant, - const CORBA_char *item_type_name, - CORBA_Environment *ev) -{ - MemosComponent *memos_component = MEMOS_COMPONENT (bonobo_object_from_servant (servant)); - - if (strcmp (item_type_name, CREATE_MEMO_ID) == 0) { - if (!create_new_memo (memos_component, FALSE, NULL)) - bonobo_exception_set (ev, ex_GNOME_Evolution_Component_Failed); - } - 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); - } -} - /* GObject methods. */ static void @@ -1112,14 +409,6 @@ impl_dispose (GObject *object) priv->create_ecal = NULL; } - for (l = priv->views; l; l = l->next) { - MemosComponentView *component_view = l->data; - - g_object_weak_unref (G_OBJECT (component_view->view_control), view_destroyed_cb, memos_component); - } - g_list_free (priv->views); - priv->views = NULL; - for (l = priv->notifications; l; l = l->next) calendar_config_remove_notification (GPOINTER_TO_UINT (l->data)); g_list_free (priv->notifications); @@ -1127,98 +416,3 @@ impl_dispose (GObject *object) (* G_OBJECT_CLASS (parent_class)->dispose) (object); } - -static void -impl_finalize (GObject *object) -{ - MemosComponentPrivate *priv = MEMOS_COMPONENT (object)->priv; - GList *l; - - for (l = priv->views; l; l = l->next) { - MemosComponentView *component_view = l->data; - - destroy_component_view (component_view); - } - g_list_free (priv->views); - - g_free (priv->base_directory); - g_free (priv->config_directory); - g_free (priv); - - (* G_OBJECT_CLASS (parent_class)->finalize) (object); -} - -static void -memos_component_class_init (MemosComponentClass *klass) -{ - POA_GNOME_Evolution_Component__epv *epv = &klass->epv; - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - bindtextdomain (GETTEXT_PACKAGE, EVOLUTION_LOCALEDIR); - bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - - parent_class = g_type_class_peek_parent (klass); - - epv->upgradeFromVersion = impl_upgradeFromVersion; - epv->createView = impl_createView; - epv->_get_userCreatableItems = impl__get_userCreatableItems; - epv->requestCreateItem = impl_requestCreateItem; - - object_class->dispose = impl_dispose; - object_class->finalize = impl_finalize; -} - -static void -memos_component_init (MemosComponent *component, MemosComponentClass *klass) -{ - MemosComponentPrivate *priv; - - priv = g_new0 (MemosComponentPrivate, 1); - - priv->base_directory = g_build_filename (e_get_user_data_dir (), "memos", NULL); - priv->config_directory = g_build_filename (priv->base_directory, "config", NULL); - - component->priv = priv; - ensure_sources (component); -} - -/* Public API */ - -MemosComponent * -memos_component_peek (void) -{ - static MemosComponent *component = NULL; - - if (component == NULL) { - component = g_object_new (memos_component_get_type (), NULL); - - if (g_mkdir_with_parents (component->priv->config_directory, 0777) != 0) { - g_warning (G_STRLOC ": Cannot create directory %s: %s", - component->priv->config_directory, g_strerror (errno)); - g_object_unref (component); - component = NULL; - } - } - - return component; -} - -const char * -memos_component_peek_base_directory (MemosComponent *component) -{ - return component->priv->base_directory; -} - -const char * -memos_component_peek_config_directory (MemosComponent *component) -{ - return component->priv->config_directory; -} - -ESourceList * -memos_component_peek_source_list (MemosComponent *component) -{ - return component->priv->source_list; -} - -BONOBO_TYPE_FUNC_FULL (MemosComponent, GNOME_Evolution_Component, PARENT_TYPE, memos_component) diff --git a/calendar/gui/memos-component.h b/calendar/gui/memos-component.h index b3995628ab..4841ef4c3e 100644 --- a/calendar/gui/memos-component.h +++ b/calendar/gui/memos-component.h @@ -57,8 +57,4 @@ struct _MemosComponentClass { GType memos_component_get_type (void); MemosComponent *memos_component_peek (void); -const char *memos_component_peek_base_directory (MemosComponent *component); -const char *memos_component_peek_config_directory (MemosComponent *component); -ESourceList *memos_component_peek_source_list (MemosComponent *component); - #endif /* _MEMOS_COMPONENT_H_ */ diff --git a/calendar/gui/memos-control.c b/calendar/gui/memos-control.c deleted file mode 100644 index 54f1dbc2ae..0000000000 --- a/calendar/gui/memos-control.c +++ /dev/null @@ -1,407 +0,0 @@ -/* - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Damon Chaplin <damon@ximian.com> - * Ettore Perazzoli - * Nathan Owens <pianocomp81@yahoo.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtk.h> -#include <glib/gi18n.h> -#include <bonobo/bonobo-control.h> -#include <bonobo/bonobo-ui-util.h> -#include <e-util/e-dialog-utils.h> -#include <e-util/e-icon-factory.h> -#include <e-util/e-print.h> -#include <e-util/e-util-private.h> -#include <gtkhtml/gtkhtml.h> - -#include "calendar-config.h" -#include "e-memos.h" -#include "e-memo-table.h" -#include "print.h" -#include "memos-control.h" -#include "e-cal-component-memo-preview.h" -#include "evolution-shell-component-utils.h" - -#define FIXED_MARGIN .05 - - -static void memos_control_activate_cb (BonoboControl *control, - gboolean activate, - gpointer user_data); -static void memos_control_open_memo_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path); -static void memos_control_new_memo_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path); -static void memos_control_cut_cmd (BonoboUIComponent *uic, - gpointer data, - const gchar *path); -static void memos_control_copy_cmd (BonoboUIComponent *uic, - gpointer data, - const gchar *path); -static void memos_control_paste_cmd (BonoboUIComponent *uic, - gpointer data, - const gchar *path); -static void memos_control_delete_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path); -static void memos_control_print_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path); -static void memos_control_print_preview_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path); - -struct focus_changed_data { - BonoboControl *control; - EMemos *memos; -}; - -static gboolean memos_control_focus_changed (GtkWidget *widget, GdkEventFocus *event, struct focus_changed_data *fc_data); - -BonoboControl * -memos_control_new (void) -{ - BonoboControl *control; - GtkWidget *memos, *preview; - struct focus_changed_data *fc_data; - - memos = e_memos_new (); - if (!memos) - return NULL; - gtk_widget_show (memos); - - control = bonobo_control_new (memos); - if (!control) { - gtk_widget_destroy (memos); - g_message ("control_factory_fn(): could not create the control!"); - return NULL; - } - - g_signal_connect (control, "activate", G_CALLBACK (memos_control_activate_cb), memos); - - fc_data = g_new0 (struct focus_changed_data, 1); - fc_data->control = control; - fc_data->memos = E_MEMOS (memos); - - preview = e_cal_component_memo_preview_get_html (E_CAL_COMPONENT_MEMO_PREVIEW (e_memos_get_preview (fc_data->memos))); - g_object_set_data_full (G_OBJECT (preview), "memos-ctrl-fc-data", fc_data, g_free); - g_signal_connect (preview, "focus-in-event", G_CALLBACK (memos_control_focus_changed), fc_data); - g_signal_connect (preview, "focus-out-event", G_CALLBACK (memos_control_focus_changed), fc_data); - - return control; -} - - -static void -memos_control_activate_cb (BonoboControl *control, - gboolean activate, - gpointer user_data) -{ - EMemos *memos; - - memos = E_MEMOS (user_data); - - if (activate) - memos_control_activate (control, memos); - else - memos_control_deactivate (control, memos); -} - -/* Sensitizes the UI Component menu/toolbar commands based on the number of - * selected memos. - */ -void -memos_control_sensitize_commands (BonoboControl *control, EMemos *memos, int n_selected) -{ - BonoboUIComponent *uic; - gboolean read_only = TRUE, preview_active; - ECal *ecal; - ECalModel *model; - GtkWidget *preview; - - uic = bonobo_control_get_ui_component (control); - g_return_if_fail (uic != NULL); - - if (bonobo_ui_component_get_container (uic) == CORBA_OBJECT_NIL) - return; - - preview = e_cal_component_memo_preview_get_html (E_CAL_COMPONENT_MEMO_PREVIEW (e_memos_get_preview (memos))); - preview_active = preview && GTK_WIDGET_VISIBLE (preview) && GTK_WIDGET_HAS_FOCUS (preview); - - model = e_memo_table_get_model (e_memos_get_calendar_table (memos)); - ecal = e_cal_model_get_default_client (model); - if (ecal) - e_cal_is_read_only (ecal, &read_only, NULL); - - bonobo_ui_component_set_prop (uic, "/commands/MemosOpenMemo", "sensitive", - n_selected != 1 ? "0" : "1", - NULL); - bonobo_ui_component_set_prop (uic, "/commands/MemosCut", "sensitive", - n_selected == 0 || read_only || preview_active ? "0" : "1", - NULL); - bonobo_ui_component_set_prop (uic, "/commands/MemosCopy", "sensitive", - n_selected == 0 ? "0" : "1", - NULL); - bonobo_ui_component_set_prop (uic, "/commands/MemosPaste", "sensitive", - read_only || preview_active ? "0" : "1", - NULL); - bonobo_ui_component_set_prop (uic, "/commands/MemosDelete", "sensitive", - n_selected == 0 || read_only ? "0" : "1", - NULL); -} - -/* Callback used when the selection in the table changes */ -static void -selection_changed_cb (EMemos *memos, int n_selected, gpointer data) -{ - BonoboControl *control; - - control = BONOBO_CONTROL (data); - - memos_control_sensitize_commands (control, memos, n_selected); -} - -static gboolean -memos_control_focus_changed (GtkWidget *widget, GdkEventFocus *event, struct focus_changed_data *fc_data) -{ - g_return_val_if_fail (fc_data != NULL, FALSE); - - memos_control_sensitize_commands (fc_data->control, fc_data->memos, e_table_selected_count (e_memo_table_get_table (e_memos_get_calendar_table (fc_data->memos)))); - - return FALSE; -} - -static BonoboUIVerb verbs [] = { - BONOBO_UI_VERB ("MemosOpenMemo", memos_control_open_memo_cmd), - BONOBO_UI_VERB ("MemosNewMemo", memos_control_new_memo_cmd), - BONOBO_UI_VERB ("MemosCut", memos_control_cut_cmd), - BONOBO_UI_VERB ("MemosCopy", memos_control_copy_cmd), - BONOBO_UI_VERB ("MemosPaste", memos_control_paste_cmd), - BONOBO_UI_VERB ("MemosDelete", memos_control_delete_cmd), - BONOBO_UI_VERB ("MemosPrint", memos_control_print_cmd), - BONOBO_UI_VERB ("MemosPrintPreview", memos_control_print_preview_cmd), - - BONOBO_UI_VERB_END -}; - -static EPixmap pixmaps [] = { - E_PIXMAP ("/commands/MemosCopy", "edit-copy", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/MemosCut", "edit-cut", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/MemosDelete", "edit-delete", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/MemosPaste", "edit-paste", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/MemosPrint", "document-print", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/MemosPrintPreview", "document-print-preview", E_ICON_SIZE_MENU), - - E_PIXMAP ("/Toolbar/Cut", "edit-cut", E_ICON_SIZE_LARGE_TOOLBAR), - E_PIXMAP ("/Toolbar/Copy", "edit-copy", E_ICON_SIZE_LARGE_TOOLBAR), - E_PIXMAP ("/Toolbar/Paste", "edit-paste", E_ICON_SIZE_LARGE_TOOLBAR), - E_PIXMAP ("/Toolbar/Print", "document-print", E_ICON_SIZE_LARGE_TOOLBAR), - E_PIXMAP ("/Toolbar/Delete", "edit-delete", E_ICON_SIZE_LARGE_TOOLBAR), - - E_PIXMAP_END -}; - -void -memos_control_activate (BonoboControl *control, EMemos *memos) -{ - Bonobo_UIContainer remote_uih; - BonoboUIComponent *uic; - int n_selected; - EMemoTable *cal_table; - ETable *etable; - char *xmlfile; - - uic = bonobo_control_get_ui_component (control); - g_return_if_fail (uic != NULL); - - remote_uih = bonobo_control_get_remote_ui_container (control, NULL); - bonobo_ui_component_set_container (uic, remote_uih, NULL); - bonobo_object_release_unref (remote_uih, NULL); - - e_memos_set_ui_component (memos, uic); - - bonobo_ui_component_add_verb_list_with_data (uic, verbs, memos); - - bonobo_ui_component_freeze (uic, NULL); - - xmlfile = g_build_filename (EVOLUTION_UIDIR, - "evolution-memos.xml", - NULL); - bonobo_ui_util_set_ui (uic, PREFIX, - xmlfile, - "evolution-memos", - NULL); - g_free (xmlfile); - - e_pixmaps_update (uic, pixmaps); - - e_memos_setup_view_menus (memos, uic); - - /* Signals from the memos widget; also sensitize the menu items as appropriate */ - - g_signal_connect (memos, "selection_changed", G_CALLBACK (selection_changed_cb), control); - - cal_table = e_memos_get_calendar_table (memos); - etable = e_memo_table_get_table (cal_table); - n_selected = e_table_selected_count (etable); - - memos_control_sensitize_commands (control, memos, n_selected); - - bonobo_ui_component_thaw (uic, NULL); -} - - -void -memos_control_deactivate (BonoboControl *control, EMemos *memos) -{ - BonoboUIComponent *uic = bonobo_control_get_ui_component (control); - - g_return_if_fail (uic != NULL); - - e_memos_set_ui_component (memos, NULL); - - e_memos_discard_view_menus (memos); - - /* Stop monitoring the "selection_changed" signal */ - g_signal_handlers_disconnect_matched (memos, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, control); - - bonobo_ui_component_rm (uic, "/", NULL); - bonobo_ui_component_unset_container (uic, NULL); -} - -static void memos_control_open_memo_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path) -{ - EMemos *memos; - - memos = E_MEMOS (data); - e_memos_open_memo (memos); -} - -static void -memos_control_new_memo_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path) -{ - EMemos *memos; - - memos = E_MEMOS (data); - e_memos_new_memo (memos); -} - -static void -memos_control_cut_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path) -{ - EMemos *memos; - EMemoTable *cal_table; - - memos = E_MEMOS (data); - cal_table = e_memos_get_calendar_table (memos); - e_memo_table_cut_clipboard (cal_table); -} - -static void -memos_control_copy_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path) -{ - EMemos *memos; - EMemoTable *cal_table; - GtkWidget *preview; - - memos = E_MEMOS (data); - - preview = e_cal_component_memo_preview_get_html (E_CAL_COMPONENT_MEMO_PREVIEW (e_memos_get_preview (memos))); - if (preview && GTK_WIDGET_VISIBLE (preview) && GTK_WIDGET_HAS_FOCUS (preview)) { - /* copy selected text in a preview when that's shown and focused */ - gtk_html_copy (GTK_HTML (preview)); - } else { - cal_table = e_memos_get_calendar_table (memos); - e_memo_table_copy_clipboard (cal_table); - } -} - -static void -memos_control_paste_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path) -{ - EMemos *memos; - EMemoTable *cal_table; - - memos = E_MEMOS (data); - cal_table = e_memos_get_calendar_table (memos); - e_memo_table_paste_clipboard (cal_table); -} - -static void -memos_control_delete_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path) -{ - EMemos *memos; - - memos = E_MEMOS (data); - e_memos_delete_selected (memos); -} - -/* File/Print callback */ -static void -memos_control_print_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path) -{ - EMemos *memos = E_MEMOS (data); - ETable *table; - - table = e_memo_table_get_table ( - E_MEMO_TABLE (e_memos_get_calendar_table (memos))); - - print_table ( - table, _("Print Memos"), _("Memos"), - GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG); -} - -static void -memos_control_print_preview_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path) -{ - EMemos *memos = E_MEMOS (data); - ETable *table; - - table = e_memo_table_get_table ( - E_MEMO_TABLE (e_memos_get_calendar_table (memos))); - - print_table ( - table, _("Print Memos"), _("Memos"), - GTK_PRINT_OPERATION_ACTION_PREVIEW); -} diff --git a/calendar/gui/print.c b/calendar/gui/print.c index adbfc2cc77..52320eff25 100644 --- a/calendar/gui/print.c +++ b/calendar/gui/print.c @@ -43,7 +43,6 @@ #include <e-util/e-print.h> #include <libecal/e-cal-time-util.h> #include <libecal/e-cal-component.h> -#include "calendar-commands.h" #include "calendar-config.h" #include "e-cal-model.h" #include "e-day-view.h" @@ -579,6 +578,7 @@ print_month_small (GtkPrintContext *context, GnomeCalendar *gcal, time_t month, int titleflags, time_t greystart, time_t greyend, int bordertitle) { +#if 0 /* KILL-BONOBO */ icaltimezone *zone = calendar_config_get_icaltimezone (); PangoFontDescription *font, *font_bold, *font_normal; time_t now, next; @@ -703,6 +703,7 @@ print_month_small (GtkPrintContext *context, GnomeCalendar *gcal, time_t month, } pango_font_description_free (font_normal); pango_font_description_free (font_bold); +#endif } /* wraps text into the print context, not taking up more than its allowed space */ @@ -1246,6 +1247,7 @@ static void print_day_details (GtkPrintContext *context, GnomeCalendar *gcal, time_t whence, double left, double right, double top, double bottom) { +#if 0 /* KILL-BONOBO */ icaltimezone *zone = calendar_config_get_icaltimezone (); EDayViewEvent *event; PangoFontDescription *font; @@ -1364,6 +1366,7 @@ print_day_details (GtkPrintContext *context, GnomeCalendar *gcal, time_t whence, g_array_free (pdi.long_events, TRUE); free_event_array (pdi.events[0]); g_array_free (pdi.events[0], TRUE); +#endif } /* Returns TRUE if the event is a one-day event (i.e. not a long event). */ @@ -1738,6 +1741,7 @@ print_week_summary (GtkPrintContext *context, GnomeCalendar *gcal, int month, double font_size, double left, double right, double top, double bottom) { +#if 0 /* KILL-BONOBO */ icaltimezone *zone = calendar_config_get_icaltimezone (); EWeekViewEvent *event; struct psinfo psi; @@ -1831,6 +1835,7 @@ print_week_summary (GtkPrintContext *context, GnomeCalendar *gcal, } g_array_free (psi.events, TRUE); g_array_free (spans, TRUE); +#endif } @@ -1962,6 +1967,7 @@ print_todo_details (GtkPrintContext *context, GnomeCalendar *gcal, time_t start, time_t end, double left, double right, double top, double bottom) { +#if 0 /* KILL-BONOBO */ PangoFontDescription *font_summary; double y, yend, x, xend; struct icaltimetype *tt; @@ -2051,6 +2057,7 @@ print_todo_details (GtkPrintContext *context, GnomeCalendar *gcal, } pango_font_description_free (font_summary); +#endif } static void @@ -2388,6 +2395,7 @@ print_calendar_draw_page (GtkPrintOperation *operation, gint page_nr, PrintCalItem *pcali) { +#if 0 /* KILL-BONOBO */ switch (gnome_calendar_get_view (pcali->gcal)) { case GNOME_CAL_DAY_VIEW: print_day_view (context, pcali->gcal, pcali->start); @@ -2402,12 +2410,14 @@ print_calendar_draw_page (GtkPrintOperation *operation, default: g_return_if_reached (); } +#endif } void print_calendar (GnomeCalendar *gcal, GtkPrintOperationAction action, time_t start) { +#if 0 /* KILL-BONOBO */ GtkPrintOperation *operation; PrintCalItem pcali; @@ -2427,6 +2437,7 @@ print_calendar (GnomeCalendar *gcal, GtkPrintOperationAction action, gtk_print_operation_run (operation, action, NULL, NULL); g_object_unref (operation); +#endif } /* returns number of required pages, when page_nr is -1 */ diff --git a/calendar/gui/tasks-component.c b/calendar/gui/tasks-component.c index 9ed21d5186..cb7326e7d6 100644 --- a/calendar/gui/tasks-component.c +++ b/calendar/gui/tasks-component.c @@ -57,28 +57,13 @@ #define CREATE_TASK_ASSIGNED_ID "task-assigned" #define CREATE_TASK_LIST_ID "task-list" -enum DndTargetType { - DND_TARGET_TYPE_CALENDAR_LIST, -}; -#define CALENDAR_TYPE "text/calendar" -#define XCALENDAR_TYPE "text/x-calendar" #define WEB_BASE_URI "webcal://" #define PERSONAL_RELATIVE_URI "system" -static GtkTargetEntry drag_types[] = { - { CALENDAR_TYPE, 0, DND_TARGET_TYPE_CALENDAR_LIST }, - { XCALENDAR_TYPE, 0, DND_TARGET_TYPE_CALENDAR_LIST } -}; -static gint num_drag_types = sizeof(drag_types) / sizeof(drag_types[0]); - #define PARENT_TYPE bonobo_object_get_type () static BonoboObjectClass *parent_class = NULL; -/* Tasks should have their own registry */ -extern ECompEditorRegistry *comp_editor_registry; - - typedef struct { ESourceList *source_list; @@ -89,23 +74,15 @@ typedef struct ETable *table; ETableModel *model; - EInfoLabel *info_label; GtkWidget *source_selector; BonoboControl *view_control; - BonoboControl *sidebar_control; - BonoboControl *statusbar_control; GList *notifications; - EUserCreatableItemsHandler *creatable_items_handler; - - EActivityHandler *activity_handler; } TasksComponentView; struct _TasksComponentPrivate { - char *base_directory; - char *config_directory; ESourceList *source_list; GSList *source_selection; @@ -117,109 +94,6 @@ struct _TasksComponentPrivate { GList *notifications; }; -static void -ensure_sources (TasksComponent *component) -{ - ESourceList *source_list; - ESourceGroup *on_this_computer; - ESource *personal_source; - char *base_uri, *base_uri_proto, base_uri_proto_seventh; - const gchar *base_dir; - - personal_source = NULL; - - if (!e_cal_get_sources (&source_list, E_CAL_SOURCE_TYPE_TODO, NULL)) { - g_warning ("Could not get task source list from GConf!"); - return; - } - - base_dir = tasks_component_peek_base_directory (component); - base_uri = g_build_filename (base_dir, "local", NULL); - - base_uri_proto = g_filename_to_uri (base_uri, NULL, NULL); - if (strlen (base_uri_proto) > 7) { - /* compare only file:// part. If user home dir name changes we do not want to create - one more group */ - base_uri_proto_seventh = base_uri_proto[7]; - base_uri_proto[7] = 0; - } else { - base_uri_proto_seventh = -1; - } - - on_this_computer = e_source_list_ensure_group (source_list, _("On This Computer"), base_uri_proto, TRUE); - e_source_list_ensure_group (source_list, _("On The Web"), WEB_BASE_URI, FALSE); - - if (base_uri_proto_seventh != -1) { - base_uri_proto[7] = base_uri_proto_seventh; - } - - if (on_this_computer) { - /* make sure "Personal" shows up as a source under - this group */ - GSList *sources = e_source_group_peek_sources (on_this_computer); - GSList *s; - for (s = sources; s; s = s->next) { - ESource *source = E_SOURCE (s->data); - const gchar *relative_uri; - - relative_uri = e_source_peek_relative_uri (source); - if (relative_uri == NULL) - continue; - if (!strcmp (PERSONAL_RELATIVE_URI, relative_uri)) { - personal_source = source; - break; - } - } - /* Make sure we have the correct base uri. This can change when user's - homedir name changes */ - if (strcmp (base_uri_proto, e_source_group_peek_base_uri (on_this_computer))) { - e_source_group_set_base_uri (on_this_computer, base_uri_proto); - - /* *sigh* . We shouldn't need this sync call here as set_base_uri - call results in synching to gconf, but that happens in idle loop - and too late to prevent user seeing "Can not Open ... because of invalid uri" error.*/ - e_source_list_sync (source_list,NULL); - } - } - - if (personal_source) { - /* ensure the source name is in current locale, not read from configuration */ - e_source_set_name (personal_source, _("Personal")); - } else { - GSList *tasks_selected; - /* Create the default Person addressbook */ - ESource *source = e_source_new (_("Personal"), PERSONAL_RELATIVE_URI); - e_source_group_add_source (on_this_computer, source, -1); - g_object_unref (source); - - tasks_selected = calendar_config_get_tasks_selected (); - - if (!calendar_config_get_primary_tasks () && !tasks_selected) { - GSList selected; - - calendar_config_set_primary_tasks (e_source_peek_uid (source)); - - selected.data = (gpointer)e_source_peek_uid (source); - selected.next = NULL; - calendar_config_set_tasks_selected (&selected); - } - - if (tasks_selected) { - g_slist_foreach (tasks_selected, (GFunc) g_free, NULL); - g_slist_free (tasks_selected); - } - - e_source_set_color_spec (source, "#BECEDD"); - personal_source = source; - } - - component->priv->source_list = source_list; - - g_object_unref (on_this_computer); - g_free (base_uri_proto); - g_free (base_uri); -} - /* Utility functions. */ /* FIXME Some of these are duplicated from calendar-component.c */ static gboolean @@ -304,62 +178,6 @@ update_uri_for_primary_selection (TasksComponentView *component_view) calendar_config_set_primary_tasks (e_source_peek_uid (source)); } -static void -update_selection (TasksComponentView *component_view) -{ - GSList *selection, *uids_selected, *l; - - /* Get the selection in gconf */ - uids_selected = calendar_config_get_tasks_selected (); - - /* Remove any that aren't there any more */ - selection = e_source_selector_get_selection (E_SOURCE_SELECTOR (component_view->source_selector)); - - for (l = selection; l; l = l->next) { - ESource *source = l->data; - - if (!is_in_uids (uids_selected, source)) - e_source_selector_unselect_source (E_SOURCE_SELECTOR (component_view->source_selector), source); - } - - e_source_selector_free_selection (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->source_list, uid); - if (source) - e_source_selector_select_source (E_SOURCE_SELECTOR (component_view->source_selector), source); - - g_free (uid); - } - g_slist_free (uids_selected); -} - -static void -update_primary_selection (TasksComponentView *component_view) -{ - ESource *source = NULL; - char *uid; - - uid = calendar_config_get_primary_tasks (); - if (uid) { - source = e_source_list_peek_source_by_uid (component_view->source_list, uid); - g_free (uid); - } - - if (source) { - e_source_selector_set_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector), source); - } else { - /* Try to create a default if there isn't one */ - source = e_source_list_peek_source_any (component_view->source_list); - if (source) - e_source_selector_set_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector), source); - } -} - /* Callbacks. */ static void copy_task_list_cb (EPopup *ep, EPopupItem *pitem, void *data) @@ -531,84 +349,11 @@ primary_source_selection_changed_cb (ESourceSelector *selector, TasksComponentVi } static void -source_added_cb (ETasks *tasks, ESource *source, TasksComponentView *component_view) -{ - e_source_selector_select_source (E_SOURCE_SELECTOR (component_view->source_selector), source); -} - -static void source_removed_cb (ETasks *tasks, ESource *source, TasksComponentView *component_view) { e_source_selector_unselect_source (E_SOURCE_SELECTOR (component_view->source_selector), source); } -static void -set_info (TasksComponentView *component_view) -{ - GString *message = g_string_new (NULL); - int rows, selected_rows; - - rows = e_table_model_row_count (component_view->model); - selected_rows = e_table_selected_count (component_view->table); - - g_string_append_printf(message, ngettext("%d task", "%d tasks", rows), rows); - if (selected_rows > 0) - g_string_append_printf(message, ngettext(", %d selected", ", %d selected", selected_rows), selected_rows); - - e_info_label_set_info (component_view->info_label, _("Tasks"), message->str); - - g_string_free (message, TRUE); -} - -static void -table_selection_change_cb (ETableModel *etm, TasksComponentView *component_view) -{ - set_info (component_view); -} - -static void -model_changed_cb (ETableModel *etm, TasksComponentView *component_view) -{ - set_info (component_view); -} - -static void -model_rows_inserted_cb (ETableModel *etm, int row, int count, TasksComponentView *component_view) -{ - set_info (component_view); -} - -static void -model_rows_deleted_cb (ETableModel *etm, int row, int count, TasksComponentView *component_view) -{ - set_info (component_view); -} - -/* Evolution::Component CORBA methods */ - -static void -impl_upgradeFromVersion (PortableServer_Servant servant, - CORBA_short major, - CORBA_short minor, - CORBA_short revision, - CORBA_Environment *ev) -{ - GError *err = NULL; - TasksComponent *component = TASKS_COMPONENT (bonobo_object_from_servant (servant)); - - if (!migrate_tasks(component, major, minor, revision, &err)) { - GNOME_Evolution_Component_UpgradeFailed *failedex; - - failedex = GNOME_Evolution_Component_UpgradeFailed__alloc(); - failedex->what = CORBA_string_dup(_("Failed upgrading tasks.")); - failedex->why = CORBA_string_dup(err->message); - CORBA_exception_set(ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Component_UpgradeFailed, failedex); - } - - if (err) - g_error_free(err); -} - static gboolean selector_tree_data_dropped (ESourceSelector *selector, GtkSelectionData *data, @@ -659,19 +404,6 @@ selector_tree_data_dropped (ESourceSelector *selector, } static void -control_activate_cb (BonoboControl *control, gboolean activate, gpointer data) -{ - TasksComponentView *component_view = data; - - if (activate) { - BonoboUIComponent *uic; - uic = bonobo_control_get_ui_component (component_view->view_control); - - e_user_creatable_items_handler_activate (component_view->creatable_items_handler, uic); - } -} - -static void config_create_ecal_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) { TasksComponent *component = data; @@ -808,42 +540,11 @@ create_new_todo (TasksComponent *task_component, gboolean is_assigned, TasksComp return TRUE; } -static void -create_local_item_cb (EUserCreatableItemsHandler *handler, const char *item_type_name, void *data) -{ - TasksComponent *tasks_component = data; - TasksComponentPrivate *priv; - TasksComponentView *component_view = NULL; - GList *l; - - priv = tasks_component->priv; - - for (l = priv->views; l; l = l->next) { - component_view = l->data; - - if (component_view->creatable_items_handler == handler) - break; - - component_view = NULL; - } - - if (strcmp (item_type_name, CREATE_TASK_ID) == 0) { - create_new_todo (tasks_component, FALSE, component_view); - } else if (strcmp (item_type_name, CREATE_TASK_ASSIGNED_ID) == 0) { - create_new_todo (tasks_component, TRUE, component_view); - } else if (strcmp (item_type_name, CREATE_TASK_LIST_ID) == 0) { - calendar_setup_new_task_list (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (component_view->tasks)))); - } -} - static TasksComponentView * create_component_view (TasksComponent *tasks_component) { TasksComponentPrivate *priv; TasksComponentView *component_view; - GtkWidget *selector_scrolled_window, *vbox; - GtkWidget *statusbar_widget; - AtkObject *a11y; priv = tasks_component->priv; @@ -855,66 +556,18 @@ create_component_view (TasksComponent *tasks_component) /* Create sidebar selector */ component_view->source_selector = e_source_selector_new (tasks_component->priv->source_list); - e_source_selector_set_select_new ((ESourceSelector *)component_view->source_selector, TRUE); - a11y = gtk_widget_get_accessible (GTK_WIDGET (component_view->source_selector)); - atk_object_set_name (a11y, _("Task Source Selector")); - - g_signal_connect ( - component_view->source_selector, "data-dropped", - G_CALLBACK (selector_tree_data_dropped), tasks_component); - - gtk_drag_dest_set(component_view->source_selector, GTK_DEST_DEFAULT_ALL, drag_types, - num_drag_types, GDK_ACTION_COPY | GDK_ACTION_MOVE); - - gtk_widget_show (component_view->source_selector); - - selector_scrolled_window = gtk_scrolled_window_new (NULL, NULL); - gtk_container_add (GTK_CONTAINER (selector_scrolled_window), component_view->source_selector); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (selector_scrolled_window), - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (selector_scrolled_window), - GTK_SHADOW_IN); - gtk_widget_show (selector_scrolled_window); - - component_view->info_label = (EInfoLabel *)e_info_label_new("evolution-tasks"); - e_info_label_set_info(component_view->info_label, _("Tasks"), ""); - gtk_widget_show (GTK_WIDGET (component_view->info_label)); - vbox = gtk_vbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX (vbox), GTK_WIDGET (component_view->info_label), FALSE, TRUE, 0); - gtk_box_pack_start(GTK_BOX (vbox), selector_scrolled_window, TRUE, TRUE, 0); - gtk_widget_show (vbox); - - component_view->sidebar_control = bonobo_control_new (vbox); - - /* Create main view */ - component_view->view_control = tasks_control_new (); - if (!component_view->view_control) { - /* FIXME free memory */ - - return NULL; - } + g_signal_connect (component_view->source_selector, "drag-data-received", + G_CALLBACK (selector_tree_drag_data_received), tasks_component); component_view->tasks = (ETasks *) bonobo_control_get_widget (component_view->view_control); component_view->table = e_calendar_table_get_table (e_tasks_get_calendar_table (component_view->tasks)); component_view->model = E_TABLE_MODEL (e_calendar_table_get_model (e_tasks_get_calendar_table (component_view->tasks))); /* This signal is thrown if backends die - we update the selector */ - g_signal_connect (component_view->tasks, "source_added", - G_CALLBACK (source_added_cb), component_view); g_signal_connect (component_view->tasks, "source_removed", G_CALLBACK (source_removed_cb), component_view); - /* Create status bar */ - statusbar_widget = e_task_bar_new (); - component_view->activity_handler = e_activity_handler_new (); - e_activity_handler_attach_task_bar (component_view->activity_handler, E_TASK_BAR (statusbar_widget)); - gtk_widget_show (statusbar_widget); - - component_view->statusbar_control = bonobo_control_new (statusbar_widget); - - e_calendar_table_set_activity_handler (e_tasks_get_calendar_table (component_view->tasks), component_view->activity_handler); - /* connect after setting the initial selections, or we'll get unwanted calls to calendar_control_sensitize_calendar_commands */ g_signal_connect (component_view->source_selector, "selection_changed", @@ -924,25 +577,6 @@ create_component_view (TasksComponent *tasks_component) g_signal_connect (component_view->source_selector, "popup_event", G_CALLBACK (popup_event_cb), component_view); - /* Set up the "new" item handler */ - component_view->creatable_items_handler = e_user_creatable_items_handler_new ("tasks", create_local_item_cb, tasks_component); - g_signal_connect (component_view->view_control, "activate", G_CALLBACK (control_activate_cb), component_view); - - /* We use this to update the component information */ - set_info (component_view); - g_signal_connect (component_view->table, "selection_change", - G_CALLBACK (table_selection_change_cb), component_view); - g_signal_connect (component_view->model, "model_changed", - G_CALLBACK (model_changed_cb), component_view); - g_signal_connect (component_view->model, "model_rows_inserted", - G_CALLBACK (model_rows_inserted_cb), component_view); - g_signal_connect (component_view->model, "model_rows_deleted", - G_CALLBACK (model_rows_deleted_cb), component_view); - - /* Load the selection from the last run */ - update_selection (component_view); - update_primary_selection (component_view); - return component_view; } @@ -963,12 +597,6 @@ destroy_component_view (TasksComponentView *component_view) calendar_config_remove_notification (GPOINTER_TO_UINT (l->data)); g_list_free (component_view->notifications); - if (component_view->creatable_items_handler) - g_object_unref (component_view->creatable_items_handler); - - if (component_view->activity_handler) - g_object_unref (component_view->activity_handler); - g_free (component_view); } @@ -993,38 +621,6 @@ view_destroyed_cb (gpointer data, GObject *where_the_object_was) } } -static GNOME_Evolution_ComponentView -impl_createView (PortableServer_Servant servant, - GNOME_Evolution_ShellView parent, - CORBA_boolean select_item, - CORBA_Environment *ev) -{ - TasksComponent *component = TASKS_COMPONENT (bonobo_object_from_servant (servant)); - TasksComponentPrivate *priv; - TasksComponentView *component_view; - EComponentView *ecv; - - priv = component->priv; - - /* Create the calendar component view */ - component_view = create_component_view (component); - if (!component_view) { - /* FIXME Should we describe the problem in a control? */ - bonobo_exception_set (ev, ex_GNOME_Evolution_Component_Failed); - - return CORBA_OBJECT_NIL; - } - - g_object_weak_ref (G_OBJECT (component_view->view_control), view_destroyed_cb, component); - priv->views = g_list_append (priv->views, component_view); - - /* TODO: Make TasksComponentView just subclass EComponentView */ - ecv = e_component_view_new_controls (parent, "tasks", component_view->sidebar_control, - component_view->view_control, component_view->statusbar_control); - - return BONOBO_OBJREF(ecv); -} - static void impl_handleURI (PortableServer_Servant servant, const char *uri, CORBA_Environment *ev) { @@ -1098,45 +694,6 @@ impl_handleURI (PortableServer_Servant servant, const char *uri, CORBA_Environme return; } -static GNOME_Evolution_CreatableItemTypeList * -impl__get_userCreatableItems (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - GNOME_Evolution_CreatableItemTypeList *list = GNOME_Evolution_CreatableItemTypeList__alloc (); - - list->_length = 3; - list->_maximum = list->_length; - list->_buffer = GNOME_Evolution_CreatableItemTypeList_allocbuf (list->_length); - - CORBA_sequence_set_release (list, FALSE); - - list->_buffer[0].id = CREATE_TASK_ID; - list->_buffer[0].description = _("New task"); - list->_buffer[0].menuDescription = (char *) C_("New", "_Task"); - list->_buffer[0].tooltip = _("Create a new task"); - list->_buffer[0].menuShortcut = 't'; - list->_buffer[0].iconName = "stock_task"; - list->_buffer[0].type = GNOME_Evolution_CREATABLE_OBJECT; - - list->_buffer[1].id = CREATE_TASK_ASSIGNED_ID; - list->_buffer[1].description = _("New assigned task"); - list->_buffer[1].menuDescription = (char *) C_("New", "Assigne_d Task"); - list->_buffer[1].tooltip = _("Create a new assigned task"); - list->_buffer[1].menuShortcut = '\0'; - list->_buffer[1].iconName = "stock_task"; - list->_buffer[1].type = GNOME_Evolution_CREATABLE_OBJECT; - - list->_buffer[2].id = CREATE_TASK_LIST_ID; - list->_buffer[2].description = _("New task list"); - list->_buffer[2].menuDescription = (char *) C_("New", "Tas_k list"); - list->_buffer[2].tooltip = _("Create a new task list"); - list->_buffer[2].menuShortcut = '\0'; - list->_buffer[2].iconName = "stock_todo"; - list->_buffer[2].type = GNOME_Evolution_CREATABLE_FOLDER; - - return list; -} - static void impl_requestCreateItem (PortableServer_Servant servant, const CORBA_char *item_type_name, @@ -1210,8 +767,6 @@ impl_finalize (GObject *object) } g_list_free (priv->views); - g_free (priv->base_directory); - g_free (priv->config_directory); g_free (priv); (* G_OBJECT_CLASS (parent_class)->finalize) (object); @@ -1228,9 +783,6 @@ tasks_component_class_init (TasksComponentClass *klass) parent_class = g_type_class_peek_parent (klass); - epv->upgradeFromVersion = impl_upgradeFromVersion; - epv->createView = impl_createView; - epv->_get_userCreatableItems = impl__get_userCreatableItems; epv->requestCreateItem = impl_requestCreateItem; epv->handleURI = impl_handleURI; @@ -1245,50 +797,5 @@ tasks_component_init (TasksComponent *component, TasksComponentClass *klass) priv = g_new0 (TasksComponentPrivate, 1); - priv->base_directory = g_build_filename (e_get_user_data_dir (), "tasks", NULL); - priv->config_directory = g_build_filename (priv->base_directory, "config", NULL); - component->priv = priv; - ensure_sources (component); -} - -/* Public API */ - -TasksComponent * -tasks_component_peek (void) -{ - static TasksComponent *component = NULL; - - if (component == NULL) { - component = g_object_new (tasks_component_get_type (), NULL); - - if (g_mkdir_with_parents (component->priv->config_directory, 0777) != 0) { - g_warning (G_STRLOC ": Cannot create directory %s: %s", - component->priv->config_directory, g_strerror (errno)); - g_object_unref (component); - component = NULL; - } - } - - return component; -} - -const char * -tasks_component_peek_base_directory (TasksComponent *component) -{ - return component->priv->base_directory; -} - -const char * -tasks_component_peek_config_directory (TasksComponent *component) -{ - return component->priv->config_directory; -} - -ESourceList * -tasks_component_peek_source_list (TasksComponent *component) -{ - return component->priv->source_list; } - -BONOBO_TYPE_FUNC_FULL (TasksComponent, GNOME_Evolution_Component, PARENT_TYPE, tasks_component) diff --git a/calendar/gui/tasks-component.h b/calendar/gui/tasks-component.h index cbb25d793e..fc96c5a2a8 100644 --- a/calendar/gui/tasks-component.h +++ b/calendar/gui/tasks-component.h @@ -54,10 +54,5 @@ struct _TasksComponentClass { GType tasks_component_get_type (void); -TasksComponent *tasks_component_peek (void); - -const char *tasks_component_peek_base_directory (TasksComponent *component); -const char *tasks_component_peek_config_directory (TasksComponent *component); -ESourceList *tasks_component_peek_source_list (TasksComponent *component); #endif /* _TASKS_COMPONENT_H_ */ diff --git a/calendar/gui/tasks-control.c b/calendar/gui/tasks-control.c index a0633aa636..62a283f370 100644 --- a/calendar/gui/tasks-control.c +++ b/calendar/gui/tasks-control.c @@ -53,36 +53,15 @@ static void tasks_control_activate_cb (BonoboControl *control, gboolean activate, gpointer user_data); -static void tasks_control_open_task_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path); static void tasks_control_new_task_cmd (BonoboUIComponent *uic, gpointer data, const char *path); -static void tasks_control_cut_cmd (BonoboUIComponent *uic, - gpointer data, - const gchar *path); -static void tasks_control_copy_cmd (BonoboUIComponent *uic, - gpointer data, - const gchar *path); -static void tasks_control_paste_cmd (BonoboUIComponent *uic, - gpointer data, - const gchar *path); -static void tasks_control_delete_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path); static void tasks_control_complete_cmd (BonoboUIComponent *uic, gpointer data, const char *path); static void tasks_control_purge_cmd (BonoboUIComponent *uic, gpointer data, const char *path); -static void tasks_control_print_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path); -static void tasks_control_print_preview_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path); static void tasks_control_assign_cmd (BonoboUIComponent *uic, gpointer data, const char *path); @@ -91,68 +70,6 @@ static void tasks_control_forward_cmd (BonoboUIComponent *uic, gpointer data, const char *path); -static void tasks_control_view_preview (BonoboUIComponent *uic, - const char *path, - Bonobo_UIComponent_EventType type, - const char *state, - void *data); - -struct focus_changed_data { - BonoboControl *control; - ETasks *tasks; -}; - -static gboolean tasks_control_focus_changed (GtkWidget *widget, GdkEventFocus *event, struct focus_changed_data *fc_data); - -BonoboControl * -tasks_control_new (void) -{ - BonoboControl *control; - GtkWidget *tasks, *preview; - struct focus_changed_data *fc_data; - - tasks = e_tasks_new (); - if (!tasks) - return NULL; - gtk_widget_show (tasks); - - control = bonobo_control_new (tasks); - if (!control) { - gtk_widget_destroy (tasks); - g_message ("control_factory_fn(): could not create the control!"); - return NULL; - } - - g_signal_connect (control, "activate", G_CALLBACK (tasks_control_activate_cb), tasks); - - fc_data = g_new0 (struct focus_changed_data, 1); - fc_data->control = control; - fc_data->tasks = E_TASKS (tasks); - - preview = e_cal_component_preview_get_html (E_CAL_COMPONENT_PREVIEW (e_tasks_get_preview (fc_data->tasks))); - g_object_set_data_full (G_OBJECT (preview), "tasks-ctrl-fc-data", fc_data, g_free); - g_signal_connect (preview, "focus-in-event", G_CALLBACK (tasks_control_focus_changed), fc_data); - g_signal_connect (preview, "focus-out-event", G_CALLBACK (tasks_control_focus_changed), fc_data); - - return control; -} - - -static void -tasks_control_activate_cb (BonoboControl *control, - gboolean activate, - gpointer user_data) -{ - ETasks *tasks; - - tasks = E_TASKS (user_data); - - if (activate) - tasks_control_activate (control, tasks); - else - tasks_control_deactivate (control, tasks); -} - struct _tasks_sensitize_item { char *command; guint32 enable; @@ -267,38 +184,14 @@ tasks_control_focus_changed (GtkWidget *widget, GdkEventFocus *event, struct foc } static BonoboUIVerb verbs [] = { - BONOBO_UI_VERB ("TasksOpenTask", tasks_control_open_task_cmd), BONOBO_UI_VERB ("TasksNewTask", tasks_control_new_task_cmd), - BONOBO_UI_VERB ("TasksCut", tasks_control_cut_cmd), - BONOBO_UI_VERB ("TasksCopy", tasks_control_copy_cmd), - BONOBO_UI_VERB ("TasksPaste", tasks_control_paste_cmd), - BONOBO_UI_VERB ("TasksDelete", tasks_control_delete_cmd), BONOBO_UI_VERB ("TasksMarkComplete", tasks_control_complete_cmd), BONOBO_UI_VERB ("TasksPurge", tasks_control_purge_cmd), - BONOBO_UI_VERB ("TasksPrint", tasks_control_print_cmd), - BONOBO_UI_VERB ("TasksPrintPreview", tasks_control_print_preview_cmd), BONOBO_UI_VERB ("TasksAssign", tasks_control_assign_cmd), BONOBO_UI_VERB ("TasksForward", tasks_control_forward_cmd), BONOBO_UI_VERB_END }; -static EPixmap pixmaps [] = { - E_PIXMAP ("/commands/TasksCopy", "edit-copy", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/TasksCut", "edit-cut", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/TasksDelete", "edit-delete", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/TasksForward", "mail-forward", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/TasksPaste", "edit-paste", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/TasksPrint", "document-print", E_ICON_SIZE_MENU), - E_PIXMAP ("/commands/TasksPrintPreview", "document-print-preview", E_ICON_SIZE_MENU), - - E_PIXMAP ("/Toolbar/Cut", "edit-cut", E_ICON_SIZE_LARGE_TOOLBAR), - E_PIXMAP ("/Toolbar/Copy", "edit-copy", E_ICON_SIZE_LARGE_TOOLBAR), - E_PIXMAP ("/Toolbar/Paste", "edit-paste", E_ICON_SIZE_LARGE_TOOLBAR), - E_PIXMAP ("/Toolbar/Print", "document-print", E_ICON_SIZE_LARGE_TOOLBAR), - E_PIXMAP ("/Toolbar/Delete", "edit-delete", E_ICON_SIZE_LARGE_TOOLBAR), - - E_PIXMAP_END -}; void tasks_control_activate (BonoboControl *control, ETasks *tasks) { @@ -332,8 +225,6 @@ tasks_control_activate (BonoboControl *control, ETasks *tasks) NULL); g_free (xmlfile); - e_pixmaps_update (uic, pixmaps); - e_tasks_setup_view_menus (tasks, uic); /* Signals from the tasks widget; also sensitize the menu items as appropriate */ @@ -375,16 +266,6 @@ tasks_control_deactivate (BonoboControl *control, ETasks *tasks) bonobo_ui_component_unset_container (uic, NULL); } -static void tasks_control_open_task_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path) -{ - ETasks *tasks; - - tasks = E_TASKS (data); - e_tasks_open_task (tasks); -} - static void tasks_control_new_task_cmd (BonoboUIComponent *uic, gpointer data, @@ -397,65 +278,6 @@ tasks_control_new_task_cmd (BonoboUIComponent *uic, } static void -tasks_control_cut_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path) -{ - ETasks *tasks; - ECalendarTable *cal_table; - - tasks = E_TASKS (data); - cal_table = e_tasks_get_calendar_table (tasks); - e_calendar_table_cut_clipboard (cal_table); -} - -static void -tasks_control_copy_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path) -{ - ETasks *tasks; - ECalendarTable *cal_table; - GtkWidget *preview; - - tasks = E_TASKS (data); - - - preview = e_cal_component_preview_get_html (E_CAL_COMPONENT_PREVIEW (e_tasks_get_preview (tasks))); - if (preview && GTK_WIDGET_VISIBLE (preview) && GTK_WIDGET_HAS_FOCUS (preview)) { - /* copy selected text in a preview when that's shown and focused */ - gtk_html_copy (GTK_HTML (preview)); - } else { - cal_table = e_tasks_get_calendar_table (tasks); - e_calendar_table_copy_clipboard (cal_table); - } -} - -static void -tasks_control_paste_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path) -{ - ETasks *tasks; - ECalendarTable *cal_table; - - tasks = E_TASKS (data); - cal_table = e_tasks_get_calendar_table (tasks); - e_calendar_table_paste_clipboard (cal_table); -} - -static void -tasks_control_delete_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path) -{ - ETasks *tasks; - - tasks = E_TASKS (data); - e_tasks_delete_selected (tasks); -} - -static void tasks_control_complete_cmd (BonoboUIComponent *uic, gpointer data, const char *path) @@ -511,87 +333,3 @@ tasks_control_purge_cmd (BonoboUIComponent *uic, if (confirm_purge (tasks)) e_tasks_delete_completed (tasks); } - -/* File/Print callback */ -static void -tasks_control_print_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path) -{ - ETasks *tasks = E_TASKS (data); - ETable *table; - - table = e_calendar_table_get_table ( - E_CALENDAR_TABLE (e_tasks_get_calendar_table (tasks))); - - print_table ( - table, _("Print Tasks"), _("Tasks"), - GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG); -} - -static void -tasks_control_print_preview_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path) -{ - ETasks *tasks = E_TASKS (data); - ETable *table; - - table = e_calendar_table_get_table ( - E_CALENDAR_TABLE (e_tasks_get_calendar_table (tasks))); - - print_table ( - table, _("Print Tasks"), _("Tasks"), - GTK_PRINT_OPERATION_ACTION_PREVIEW); -} - -static void -tasks_control_assign_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path) -{ - ETasks *tasks; - ECalendarTable *cal_table; - ECalModelComponent *comp_data; - - tasks = E_TASKS (data); - cal_table = e_tasks_get_calendar_table (tasks); - comp_data = e_calendar_table_get_selected_comp (cal_table); - if (comp_data) - e_calendar_table_open_task (cal_table, comp_data->client, comp_data->icalcomp, TRUE); -} - -static void -tasks_control_forward_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path) -{ - ETasks *tasks; - ECalendarTable *cal_table; - ECalModelComponent *comp_data; - - tasks = E_TASKS (data); - cal_table = e_tasks_get_calendar_table (tasks); - comp_data = e_calendar_table_get_selected_comp (cal_table); - if (comp_data) { - ECalComponent *comp; - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp)); - itip_send_comp (E_CAL_COMPONENT_METHOD_PUBLISH, comp, comp_data->client, NULL, NULL, NULL, TRUE); - g_object_unref (comp); - } -} - -static void -tasks_control_view_preview (BonoboUIComponent *uic, const char *path, Bonobo_UIComponent_EventType type, const char *state, void *data) -{ - ETasks *tasks; - - if (type != Bonobo_UIComponent_STATE_CHANGED) - return; - - tasks = E_TASKS (data); - - calendar_config_set_preview_state (state[0] != '0'); - e_tasks_show_preview (tasks, state[0] != '0'); -} diff --git a/calendar/importers/main.c b/calendar/importers/main.c deleted file mode 100644 index b1a3a20501..0000000000 --- a/calendar/importers/main.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Evolution calendar importer component - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Rodrigo Moya <rodrigo@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <string.h> -#include <bonobo/bonobo-shlib-factory.h> -#include <bonobo/bonobo-context.h> -#include <bonobo/bonobo-main.h> -#include "evolution-calendar-importer.h" - -#define IMPORTER_FACTORY_ID "OAFIID:GNOME_Evolution_Calendar_ImporterFactory:" BASE_VERSION -#define ICALENDAR_IMPORTER_ID "OAFIID:GNOME_Evolution_Calendar_iCalendar_Importer:" BASE_VERSION -#define VCALENDAR_IMPORTER_ID "OAFIID:GNOME_Evolution_Calendar_vCalendar_Importer:" BASE_VERSION -#define GNOME_CALENDAR_IMPORTER_ID "OAFIID:GNOME_Evolution_Gnome_Calendar_Intelligent_Importer:" BASE_VERSION - -static BonoboObject * -importer_factory_fn (BonoboGenericFactory *factory, const char *id, void *closure) -{ - BonoboObject *object = NULL; - - g_return_val_if_fail (id != NULL, NULL); - - if (!strcmp (id, ICALENDAR_IMPORTER_ID)) - object = ical_importer_new (); - else if (!strcmp (id, VCALENDAR_IMPORTER_ID)) - object = vcal_importer_new (); - else if (!strcmp (id, GNOME_CALENDAR_IMPORTER_ID)) - object = gnome_calendar_importer_new (); - else - g_warning ("Component not supported by this factory"); - - return object; -} - -BONOBO_ACTIVATION_SHLIB_FACTORY (IMPORTER_FACTORY_ID, "Evolution Calendar importer factory", importer_factory_fn, NULL) diff --git a/calendar/modules/Makefile.am b/calendar/modules/Makefile.am new file mode 100644 index 0000000000..9a90c99794 --- /dev/null +++ b/calendar/modules/Makefile.am @@ -0,0 +1,84 @@ +INCLUDES = \ + -DG_LOG_DOMAIN=\"calendar-modules\" \ + -I$(top_srcdir) \ + -I$(top_srcdir)/widgets \ + -DEVOLUTION_ETSPECDIR=\""$(etspecdir)"\" \ + $(EVOLUTION_CALENDAR_CFLAGS) + +#module_LTLIBRARIES = \ +# libevolution-module-memos.la \ +# libevolution-module-tasks.la + +module_LTLIBRARIES = \ + libevolution-module-calendars.la \ + libevolution-module-memos.la \ + libevolution-module-tasks.la + +libevolution_module_calendars_la_SOURCES = \ + e-cal-shell-module.c \ + e-cal-shell-module-migrate.c \ + e-cal-shell-module-migrate.h \ + e-cal-shell-module-settings.c \ + e-cal-shell-module-settings.h \ + e-cal-shell-content.c \ + e-cal-shell-content.h \ + e-cal-shell-sidebar.c \ + e-cal-shell-sidebar.h \ + e-cal-shell-view.c \ + e-cal-shell-view.h \ + e-cal-shell-view-actions.c \ + e-cal-shell-view-actions.h \ + e-cal-shell-view-memopad.c \ + e-cal-shell-view-private.c \ + e-cal-shell-view-private.h \ + e-cal-shell-view-taskpad.c + +libevolution_module_memos_la_SOURCES = \ + e-memo-shell-module.c \ + e-memo-shell-module-migrate.c \ + e-memo-shell-module-migrate.h \ + e-memo-shell-content.c \ + e-memo-shell-content.h \ + e-memo-shell-sidebar.c \ + e-memo-shell-sidebar.h \ + e-memo-shell-view.c \ + e-memo-shell-view.h \ + e-memo-shell-view-actions.c \ + e-memo-shell-view-actions.h \ + e-memo-shell-view-private.c \ + e-memo-shell-view-private.h + +libevolution_module_tasks_la_SOURCES = \ + e-task-shell-module.c \ + e-task-shell-module-migrate.c \ + e-task-shell-module-migrate.h \ + e-task-shell-content.c \ + e-task-shell-content.h \ + e-task-shell-sidebar.c \ + e-task-shell-sidebar.h \ + e-task-shell-view.c \ + e-task-shell-view.h \ + e-task-shell-view-actions.c \ + e-task-shell-view-actions.h \ + e-task-shell-view-private.c \ + e-task-shell-view-private.h + +# Removed from all three +# $(top_builddir)/a11y/calendar/libevolution-calendar-a11y.la + +libevolution_module_calendars_la_LIBADD = \ + $(WIN32_BOOTSTRAP_LIBS) \ + $(top_builddir)/shell/libeshell.la \ + $(top_builddir)/calendar/gui/libcal-gui.la \ + $(top_builddir)/mail/libevolution-module-mail.la \ + $(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.la + +libevolution_module_memos_la_LIBADD = \ + $(WIN32_BOOTSTRAP_LIBS) \ + $(top_builddir)/shell/libeshell.la \ + $(top_builddir)/calendar/gui/libcal-gui.la + +libevolution_module_tasks_la_LIBADD = \ + $(WIN32_BOOTSTRAP_LIBS) \ + $(top_builddir)/shell/libeshell.la \ + $(top_builddir)/calendar/gui/libcal-gui.la diff --git a/calendar/modules/e-cal-shell-content.c b/calendar/modules/e-cal-shell-content.c new file mode 100644 index 0000000000..f0d2024f9b --- /dev/null +++ b/calendar/modules/e-cal-shell-content.c @@ -0,0 +1,826 @@ +/* + * e-cal-shell-content.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-cal-shell-content.h" + +#include <string.h> +#include <glib/gi18n.h> + +#include "e-util/gconf-bridge.h" + +#include "calendar/gui/calendar-config.h" +#include "calendar/gui/e-cal-list-view-config.h" +#include "calendar/gui/e-cal-model-calendar.h" +#include "calendar/gui/e-calendar-table.h" +#include "calendar/gui/e-calendar-table-config.h" +#include "calendar/gui/e-day-view-config.h" +#include "calendar/gui/e-memo-table-config.h" +#include "calendar/gui/e-week-view-config.h" + +#include "widgets/menus/gal-view-etable.h" + +#define E_CAL_SHELL_CONTENT_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_CAL_SHELL_CONTENT, ECalShellContentPrivate)) + +struct _ECalShellContentPrivate { + GtkWidget *hpaned; + GtkWidget *notebook; + GtkWidget *vpaned; + + GtkWidget *day_view; + GtkWidget *work_week_view; + GtkWidget *week_view; + GtkWidget *month_view; + GtkWidget *list_view; + GtkWidget *task_table; + GtkWidget *memo_table; + + EDayViewConfig *day_view_config; + EDayViewConfig *work_week_view_config; + EWeekViewConfig *week_view_config; + EWeekViewConfig *month_view_config; + ECalListViewConfig *list_view_config; + ECalendarTableConfig *task_table_config; + EMemoTableConfig *memo_table_config; + + GalViewInstance *view_instance; + + guint paned_binding_id; +}; + +enum { + PROP_0 +}; + +/* Used to indicate who has the focus within the calendar view. */ +typedef enum { + FOCUS_CALENDAR, + FOCUS_MEMO_TABLE, + FOCUS_TASK_TABLE, + FOCUS_OTHER +} FocusLocation; + +static gpointer parent_class; + +static void +cal_shell_content_display_view_cb (ECalShellContent *cal_shell_content, + GalView *gal_view) +{ + /* FIXME */ +} + +static void +cal_shell_content_notify_view_id_cb (ECalShellContent *cal_shell_content) +{ + EShellContent *shell_content; + EShellView *shell_view; + GConfBridge *bridge; + GtkWidget *paned; + guint binding_id; + const gchar *key; + const gchar *view_id; + + bridge = gconf_bridge_get (); + paned = cal_shell_content->priv->hpaned; + binding_id = cal_shell_content->priv->paned_binding_id; + + shell_content = E_SHELL_CONTENT (cal_shell_content); + shell_view = e_shell_content_get_shell_view (shell_content); + view_id = e_shell_view_get_view_id (shell_view); + + if (binding_id > 0) + gconf_bridge_unbind (bridge, binding_id); + + if (view_id != NULL && strcmp (view_id, "Month_View") == 0) + key = "/apps/evolution/calendar/display/month_hpane_position"; + else + key = "/apps/evolution/calendar/display/hpane_position"; + + binding_id = gconf_bridge_bind_property_delayed ( + bridge, key, G_OBJECT (paned), "position"); + + cal_shell_content->priv->paned_binding_id = binding_id; +} + +static FocusLocation +cal_shell_content_get_focus_location (ECalShellContent *cal_shell_content) +{ + return FOCUS_OTHER; +#if 0 /* TEMPORARILY DISABLED */ + GtkWidget *widget; + GnomeCalendar *calendar; + ECalendarTable *task_table; + EMemoTable *memo_table; + ETable *table; + ECalendarView *calendar_view; + + calendar = GNOME_CALENDAR (cal_shell_content->priv->calendar); + widget = gnome_calendar_get_current_view_widget (calendar); + + memo_table = E_MEMO_TABLE (cal_shell_content->priv->memo_table); + task_table = E_CALENDAR_TABLE (cal_shell_content->priv->task_table); + + table = e_memo_table_get_table (memo_table); + if (GTK_WIDGET_HAS_FOCUS (table->table_canvas)) + return FOCUS_MEMO_TABLE; + + table = e_calendar_table_get_table (task_table); + if (GTK_WIDGET_HAS_FOCUS (table->table_canvas)) + return FOCUS_TASK_TABLE; + + if (E_IS_DAY_VIEW (widget)) { + EDayView *view = E_DAY_VIEW (widget); + + if (GTK_WIDGET_HAS_FOCUS (view->top_canvas)) + return FOCUS_CALENDAR; + + if (GNOME_CANVAS (view->top_canvas)->focused_item != NULL) + return FOCUS_CALENDAR; + + if (GTK_WIDGET_HAS_FOCUS (view->main_canvas)) + return FOCUS_CALENDAR; + + if (GNOME_CANVAS (view->main_canvas)->focused_item != NULL) + return FOCUS_CALENDAR; + + } else if (E_IS_WEEK_VIEW (widget)) { + EWeekView *view = E_WEEK_VIEW (widget); + + if (GTK_WIDGET_HAS_FOCUS (view->main_canvas)) + return FOCUS_CALENDAR; + + if (GNOME_CANVAS (view->main_canvas)->focused_item != NULL) + return FOCUS_CALENDAR; + + } else if (E_IS_CAL_LIST_VIEW (widget)) { + ECalListView *view = E_CAL_LIST_VIEW (widget); + + table = e_table_scrolled_get_table (view->table_scrolled); + if (GTK_WIDGET_HAS_FOCUS (table)) + return FOCUS_CALENDAR; + } + + return FOCUS_OTHER; +#endif +} + +static void +cal_shell_content_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +cal_shell_content_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +cal_shell_content_dispose (GObject *object) +{ + ECalShellContentPrivate *priv; + + priv = E_CAL_SHELL_CONTENT_GET_PRIVATE (object); + + if (priv->hpaned != NULL) { + g_object_unref (priv->hpaned); + priv->hpaned = NULL; + } + + if (priv->notebook != NULL) { + g_object_unref (priv->notebook); + priv->notebook = NULL; + } + + if (priv->vpaned != NULL) { + g_object_unref (priv->vpaned); + priv->vpaned = NULL; + } + + if (priv->day_view != NULL) { + g_object_unref (priv->day_view); + priv->day_view = NULL; + } + + if (priv->work_week_view != NULL) { + g_object_unref (priv->work_week_view); + priv->work_week_view = NULL; + } + + if (priv->week_view != NULL) { + g_object_unref (priv->week_view); + priv->week_view = NULL; + } + + if (priv->month_view != NULL) { + g_object_unref (priv->month_view); + priv->month_view = NULL; + } + + if (priv->list_view != NULL) { + g_object_unref (priv->list_view); + priv->list_view = NULL; + } + + if (priv->task_table != NULL) { + g_object_unref (priv->task_table); + priv->task_table = NULL; + } + + if (priv->memo_table != NULL) { + g_object_unref (priv->memo_table); + priv->memo_table = NULL; + } + + if (priv->day_view_config != NULL) { + g_object_unref (priv->day_view_config); + priv->day_view_config = NULL; + } + + if (priv->work_week_view_config != NULL) { + g_object_unref (priv->work_week_view_config); + priv->work_week_view_config = NULL; + } + + if (priv->week_view_config != NULL) { + g_object_unref (priv->week_view_config); + priv->week_view_config = NULL; + } + + if (priv->month_view_config != NULL) { + g_object_unref (priv->month_view_config); + priv->month_view_config = NULL; + } + + if (priv->list_view_config != NULL) { + g_object_unref (priv->list_view_config); + priv->list_view_config = NULL; + } + + if (priv->task_table_config != NULL) { + g_object_unref (priv->task_table_config); + priv->task_table_config = NULL; + } + + if (priv->memo_table_config != NULL) { + g_object_unref (priv->memo_table_config); + priv->memo_table_config = NULL; + } + + if (priv->view_instance != NULL) { + g_object_unref (priv->view_instance); + priv->view_instance = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +cal_shell_content_finalize (GObject *object) +{ + ECalShellContentPrivate *priv; + + priv = E_CAL_SHELL_CONTENT_GET_PRIVATE (object); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +cal_shell_content_constructed (GObject *object) +{ + ECalShellContentPrivate *priv; + ECalModelCalendar *cal_model; + ECalModel *memo_model; + ECalModel *task_model; + EShellContent *shell_content; + EShellModule *shell_module; + EShellView *shell_view; + EShellWindow *shell_window; + EShellContent *foreign_content; + EShellView *foreign_view; + GalViewInstance *view_instance; + GConfBridge *bridge; + GtkWidget *container; + GtkWidget *widget; + const gchar *config_dir; + const gchar *key; + gchar *filename; + gchar *markup; + gint page_num; + + priv = E_CAL_SHELL_CONTENT_GET_PRIVATE (object); + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (parent_class)->constructed (object); + + shell_content = E_SHELL_CONTENT (object); + shell_view = e_shell_content_get_shell_view (shell_content); + shell_window = e_shell_view_get_shell_window (shell_view); + + shell_module = e_shell_view_get_shell_module (shell_view); + config_dir = e_shell_module_get_config_dir (shell_module); + + /* Calendar model for the views. */ + cal_model = e_cal_model_calendar_new (); + e_cal_model_set_flags ( + E_CAL_MODEL (cal_model), + E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES); + + /* We borrow the memopad and taskpad models from the memo + * and task views, loading the views if necessary. */ + + foreign_view = e_shell_window_get_shell_view (shell_window, "memos"); + foreign_content = e_shell_view_get_shell_content (foreign_view); + g_object_get (foreign_content, "model", &memo_model, NULL); + + foreign_view = e_shell_window_get_shell_view (shell_window, "tasks"); + foreign_content = e_shell_view_get_shell_content (foreign_view); + g_object_get (foreign_content, "model", &task_model, NULL); + + /* Build content widgets. */ + + container = GTK_WIDGET (object); + + /* FIXME Need to deal with saving and restoring the position. + * Month view has its own position. */ + widget = gtk_hpaned_new (); + gtk_container_add (GTK_CONTAINER (container), widget); + priv->hpaned = g_object_ref (widget); + gtk_widget_show (widget); + + container = priv->hpaned; + + widget = gtk_notebook_new (); + gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE); + gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), FALSE); + gtk_paned_pack1 (GTK_PANED (container), widget, FALSE, TRUE); + priv->notebook = g_object_ref (widget); + gtk_widget_show (widget); + + /* FIXME Need to deal with saving and restoring the position. + * Month view has its own position. */ + widget = gtk_vpaned_new (); + gtk_paned_pack2 (GTK_PANED (container), widget, TRUE, TRUE); + priv->vpaned = g_object_ref (widget); + gtk_widget_show (widget); + + container = priv->notebook; + + /* Add views in the order defined by GnomeCalendarViewType, such + * that the notebook page number corresponds to the view type. + * The assertions below ensure that stays true. */ + +#if 0 /* Not so fast... get the memo/task pads working first. */ + /* FIXME Need to establish a calendar and timezone first. */ + widget = e_day_view_new (E_CAL_MODEL (cal_model)); + e_calendar_view_set_calendar ( + E_CALENDAR_VIEW (widget), GNOME_CALENDAR (priv->calendar)); + e_calendar_view_set_timezone ( + E_CALENDAR_VIEW (widget), priv->timezone); + page_num = gtk_notebook_get_n_pages (GTK_NOTEBOOK (widget)); + gtk_notebook_append_page (GTK_NOTEBOOK (container), widget, NULL); + g_return_if_fail (page_num == GNOME_CAL_DAY_VIEW); + priv->day_view = g_object_ref (widget); + gtk_widget_show (widget); + + /* FIXME Need to establish a calendar and timezone first. */ + widget = e_day_view_new (E_CAL_MODEL (cal_model)); + e_day_view_set_work_week_view (E_DAY_VIEW (widget), TRUE); + e_day_view_set_days_shown (E_DAY_VIEW (widget), 5); + e_calendar_view_set_calendar ( + E_CALENDAR_VIEW (widget), GNOME_CALENDAR (priv->calendar)); + e_calendar_view_set_timezone ( + E_CALENDAR_VIEW (widget), priv->timezone); + page_num = gtk_notebook_get_n_pages (GTK_NOTEBOOK (widget)); + gtk_notebook_append_page (GTK_NOTEBOOK (container), widget, NULL); + g_return_if_fail (page_num == GNOME_CAL_WORK_WEEK_VIEW); + priv->work_week_view = g_object_ref (widget); + gtk_widget_show (widget); + + /* FIXME Need to establish a calendar and timezone first. */ + widget = e_week_view_new (E_CAL_MODEL (cal_model)); + e_calendar_view_set_calendar ( + E_CALENDAR_VIEW (widget), GNOME_CALENDAR (priv->calendar)); + e_calendar_view_set_timezone ( + E_CALENDAR_VIEW (widget), priv->timezone); + page_num = gtk_notebook_get_n_pages (GTK_NOTEBOOK (widget)); + gtk_notebook_append_page (GTK_NOTEBOOK (container), widget, NULL); + g_return_if_fail (page_num == GNOME_CAL_WEEK_VIEW); + priv->week_view = g_object_ref (widget); + gtk_widget_show (widget); + + /* FIXME Need to establish a calendar and timezone first. */ + widget = e_week_view_new (E_CAL_MODEL (cal_model)); + e_week_view_set_multi_week_view (E_WEEK_VIEW (widget), TRUE); + e_week_view_set_weeks_shown (E_WEEK_VIEW (widget), 6); + e_calendar_view_set_calendar ( + E_CALENDAR_VIEW (widget), GNOME_CALENDAR (priv->calendar)); + e_calendar_view_set_timezone ( + E_CALENDAR_VIEW (widget), priv->timezone); + page_num = gtk_notebook_get_n_pages (GTK_NOTEBOOK (widget)); + gtk_notebook_append_page (GTK_NOTEBOOK (container), widget, NULL); + g_return_if_fail (page_num == GNOME_CAL_MONTH_VIEW); + priv->month_view = g_object_ref (widget); + gtk_widget_show (widget); + + /* FIXME Need to establish a calendar and timezone first. */ + widget = e_cal_list_view_new (E_CAL_MODEL (cal_model)); + e_calendar_view_set_calendar ( + E_CALENDAR_VIEW (widget), GNOME_CALENDAR (priv->calendar)); + e_calendar_view_set_timezone ( + E_CALENDAR_VIEW (widget), priv->timezone); + page_num = gtk_notebook_get_n_pages (GTK_NOTEBOOK (widget)); + gtk_notebook_append_page (GTK_NOTEBOOK (container), widget, NULL); + g_return_if_fail (page_num == GNOME_CAL_LIST_VIEW); + priv->list_view = g_object_ref (widget); + gtk_widget_show (widget); +#endif + + container = priv->vpaned; + + widget = gtk_vbox_new (FALSE, 0); + gtk_paned_pack1 (GTK_PANED (container), widget, FALSE, FALSE); + gtk_widget_show (widget); + + container = widget; + + widget = gtk_hseparator_new (); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0); + gtk_widget_show (widget); + + widget = gtk_label_new (NULL); + markup = g_strdup_printf ("<b>%s</b>", _("Tasks")); + gtk_label_set_markup (GTK_LABEL (widget), markup); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0); + gtk_widget_show (widget); + g_free (markup); + + widget = e_calendar_table_new (shell_view, task_model); + gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); + priv->task_table = g_object_ref (widget); + gtk_widget_show (widget); + + filename = g_build_filename (config_dir, "TaskPad", NULL); + e_calendar_table_load_state (E_CALENDAR_TABLE (widget), filename); + g_free (filename); + + container = priv->vpaned; + + widget = gtk_vbox_new (FALSE, 0); + gtk_paned_pack2 (GTK_PANED (container), widget, TRUE, FALSE); + gtk_widget_show (widget); + + container = widget; + + widget = gtk_label_new (NULL); + markup = g_strdup_printf ("<b>%s</b>", _("Memos")); + gtk_label_set_markup (GTK_LABEL (widget), markup); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0); + gtk_widget_show (widget); + g_free (markup); + + widget = e_memo_table_new (shell_view, memo_model); + gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); + priv->memo_table = g_object_ref (widget); + gtk_widget_show (widget); + + filename = g_build_filename (config_dir, "MemoPad", NULL); + e_memo_table_load_state (E_MEMO_TABLE (widget), filename); + g_free (filename); + + /* Configuration managers for views and tables. */ + priv->day_view_config = e_day_view_config_new ( + E_DAY_VIEW (priv->day_view)); + priv->work_week_view_config = e_day_view_config_new ( + E_DAY_VIEW (priv->work_week_view)); + priv->week_view_config = e_week_view_config_new ( + E_WEEK_VIEW (priv->week_view)); + priv->month_view_config = e_week_view_config_new ( + E_WEEK_VIEW (priv->month_view)); + priv->list_view_config = e_cal_list_view_config_new ( + E_CAL_LIST_VIEW (priv->list_view)); + priv->task_table_config = e_calendar_table_config_new ( + E_CALENDAR_TABLE (priv->task_table)); + priv->memo_table_config = e_memo_table_config_new ( + E_MEMO_TABLE (priv->memo_table)); + + /* Load the view instance. */ + + view_instance = e_shell_view_new_view_instance (shell_view, NULL); + g_signal_connect_swapped ( + view_instance, "display-view", + G_CALLBACK (cal_shell_content_display_view_cb), + object); + gal_view_instance_load (view_instance); + priv->view_instance = view_instance; + + g_signal_connect_swapped ( + shell_view, "notify::view-id", + G_CALLBACK (cal_shell_content_notify_view_id_cb), + object); + + /* Bind GObject properties to GConf keys. */ + + bridge = gconf_bridge_get (); + + object = G_OBJECT (priv->vpaned); + key = "/apps/evolution/calendar/display/vpane_position"; + gconf_bridge_bind_property_delayed (bridge, key, object, "position"); + + g_object_unref (memo_model); + g_object_unref (task_model); +} + +static void +cal_shell_content_class_init (ECalShellContentClass *class) +{ + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (ECalShellContentPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = cal_shell_content_set_property; + object_class->get_property = cal_shell_content_get_property; + object_class->dispose = cal_shell_content_dispose; + object_class->finalize = cal_shell_content_finalize; + object_class->constructed = cal_shell_content_constructed; +} + +static void +cal_shell_content_init (ECalShellContent *cal_shell_content) +{ + cal_shell_content->priv = + E_CAL_SHELL_CONTENT_GET_PRIVATE (cal_shell_content); + + /* Postpone widget construction until we have a shell view. */ +} + +GType +e_cal_shell_content_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (ECalShellContentClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) cal_shell_content_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (ECalShellContent), + 0, /* n_preallocs */ + (GInstanceInitFunc) cal_shell_content_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + E_TYPE_SHELL_CONTENT, "ECalShellContent", + &type_info, 0); + } + + return type; +} + +GtkWidget * +e_cal_shell_content_new (EShellView *shell_view) +{ + g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); + + return g_object_new ( + E_TYPE_CAL_SHELL_CONTENT, + "shell-view", shell_view, NULL); +} + +GnomeCalendar * +e_cal_shell_content_get_calendar (ECalShellContent *cal_shell_content) +{ + g_return_val_if_fail ( + E_IS_CAL_SHELL_CONTENT (cal_shell_content), NULL); + + /* FIXME */ + /*return GNOME_CALENDAR (cal_shell_content->priv->calendar);*/ + return NULL; +} + +EMemoTable * +e_cal_shell_content_get_memo_table (ECalShellContent *cal_shell_content) +{ + g_return_val_if_fail ( + E_IS_CAL_SHELL_CONTENT (cal_shell_content), NULL); + + return E_MEMO_TABLE (cal_shell_content->priv->memo_table); +} + +ECalendarTable * +e_cal_shell_content_get_task_table (ECalShellContent *cal_shell_content) +{ + g_return_val_if_fail ( + E_IS_CAL_SHELL_CONTENT (cal_shell_content), NULL); + + return E_CALENDAR_TABLE (cal_shell_content->priv->task_table); +} + +icaltimezone * +e_cal_shell_content_get_timezone (ECalShellContent *cal_shell_content) +{ + g_return_val_if_fail ( + E_IS_CAL_SHELL_CONTENT (cal_shell_content), NULL); + + /* FIXME */ + /*return cal_shell_content->priv->timezone;*/ + return NULL; +} + +GalViewInstance * +e_cal_shell_content_get_view_instance (ECalShellContent *cal_shell_content) +{ + g_return_val_if_fail ( + E_IS_CAL_SHELL_CONTENT (cal_shell_content), NULL); + + return cal_shell_content->priv->view_instance; +} + +void +e_cal_shell_content_copy_clipboard (ECalShellContent *cal_shell_content) +{ +#if 0 + GnomeCalendar *calendar; + EMemoTable *memo_table; + ECalendarTable *task_table; + + g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content)); + + calendar = e_cal_shell_content_get_calendar (cal_shell_content); + memo_table = e_cal_shell_content_get_memo_table (cal_shell_content); + task_table = e_cal_shell_content_get_task_table (cal_shell_content); + + switch (cal_shell_content_get_focus_location (cal_shell_content)) { + case FOCUS_CALENDAR: + gnome_calendar_copy_clipboard (calendar); + break; + + case FOCUS_MEMO_TABLE: + e_memo_table_copy_clipboard (memo_table); + break; + + case FOCUS_TASK_TABLE: + e_calendar_table_copy_clipboard (task_table); + break; + + default: + g_return_if_reached (); + } +#endif +} + +void +e_cal_shell_content_cut_clipboard (ECalShellContent *cal_shell_content) +{ +#if 0 + GnomeCalendar *calendar; + EMemoTable *memo_table; + ECalendarTable *task_table; + + g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content)); + + calendar = e_cal_shell_content_get_calendar (cal_shell_content); + memo_table = e_cal_shell_content_get_memo_table (cal_shell_content); + task_table = e_cal_shell_content_get_task_table (cal_shell_content); + + switch (cal_shell_content_get_focus_location (cal_shell_content)) { + case FOCUS_CALENDAR: + gnome_calendar_cut_clipboard (calendar); + break; + + case FOCUS_MEMO_TABLE: + e_memo_table_copy_clipboard (memo_table); + break; + + case FOCUS_TASK_TABLE: + e_calendar_table_copy_clipboard (task_table); + break; + + default: + g_return_if_reached (); + } +#endif +} + +void +e_cal_shell_content_paste_clipboard (ECalShellContent *cal_shell_content) +{ +#if 0 + GnomeCalendar *calendar; + EMemoTable *memo_table; + ECalendarTable *task_table; + + g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content)); + + calendar = e_cal_shell_content_get_calendar (cal_shell_content); + memo_table = e_cal_shell_content_get_memo_table (cal_shell_content); + task_table = e_cal_shell_content_get_task_table (cal_shell_content); + + switch (cal_shell_content_get_focus_location (cal_shell_content)) { + case FOCUS_CALENDAR: + gnome_calendar_paste_clipboard (calendar); + break; + + case FOCUS_MEMO_TABLE: + e_memo_table_copy_clipboard (memo_table); + break; + + case FOCUS_TASK_TABLE: + e_calendar_table_copy_clipboard (task_table); + break; + + default: + g_return_if_reached (); + } +#endif +} + +void +e_cal_shell_content_delete_selection (ECalShellContent *cal_shell_content) +{ +#if 0 + GnomeCalendar *calendar; + EMemoTable *memo_table; + ECalendarTable *task_table; + + g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content)); + + calendar = e_cal_shell_content_get_calendar (cal_shell_content); + memo_table = e_cal_shell_content_get_memo_table (cal_shell_content); + task_table = e_cal_shell_content_get_task_table (cal_shell_content); + + switch (cal_shell_content_get_focus_location (cal_shell_content)) { + case FOCUS_CALENDAR: + gnome_calendar_delete_selection (calendar); + break; + + case FOCUS_MEMO_TABLE: + e_memo_table_delete_selected (memo_table); + break; + + case FOCUS_TASK_TABLE: + e_calendar_table_delete_selected (task_table); + break; + + default: + g_return_if_reached (); + } +#endif +} + +void +e_cal_shell_content_delete_selected_occurrence (ECalShellContent *cal_shell_content) +{ +#if 0 + GnomeCalendar *calendar; + FocusLocation focus; + + g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content)); + + focus = cal_shell_content_get_focus_location (cal_shell_content); + calendar = e_cal_shell_content_get_calendar (cal_shell_content); + + if (focus == FOCUS_CALENDAR) + gnome_calendar_delete_selected_occurrence (calendar); +#endif +} diff --git a/calendar/modules/e-cal-shell-content.h b/calendar/modules/e-cal-shell-content.h new file mode 100644 index 0000000000..f199be3b78 --- /dev/null +++ b/calendar/modules/e-cal-shell-content.h @@ -0,0 +1,104 @@ +/* + * e-cal-shell-content.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_CAL_SHELL_CONTENT_H +#define E_CAL_SHELL_CONTENT_H + +#include <shell/e-shell-content.h> +#include <shell/e-shell-view.h> + +#include <calendar/gui/e-memo-table.h> +#include <calendar/gui/gnome-cal.h> +#include <widgets/menus/gal-view-instance.h> + +/* Standard GObject macros */ +#define E_TYPE_CAL_SHELL_CONTENT \ + (e_cal_shell_content_get_type ()) +#define E_CAL_SHELL_CONTENT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_CAL_SHELL_CONTENT, ECalShellContent)) +#define E_CAL_SHELL_CONTENT_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_CAL_SHELL_CONTENT, ECalShellContentClass)) +#define E_IS_CAL_SHELL_CONTENT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_CAL_SHELL_CONTENT)) +#define E_IS_CAL_SHELL_CONTENT_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_CAL_SHELL_CONTENT)) +#define E_CAL_SHELL_CONTENT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_CAL_SHELL_CONTENT, ECalShellContentClass)) + +G_BEGIN_DECLS + +typedef struct _ECalShellContent ECalShellContent; +typedef struct _ECalShellContentClass ECalShellContentClass; +typedef struct _ECalShellContentPrivate ECalShellContentPrivate; + +enum { + E_CAL_SHELL_CONTENT_SELECTION_SINGLE = 1 << 0, + E_CAL_SHELL_CONTENT_SELECTION_MULTIPLE = 1 << 1, + E_CAL_SHELL_CONTENT_SELECTION_IS_ASSIGNABLE = 1 << 2, + E_CAL_SHELL_CONTENT_SELECTION_IS_COMPLETE = 1 << 3, + E_CAL_SHELL_CONTENT_SELECTION_IS_EDITABLE = 1 << 4, + E_CAL_SHELL_CONTENT_SELECTION_IS_MEETING = 1 << 5, + E_CAL_SHELL_CONTENT_SELECTION_IS_ORGANIZER = 1 << 6, + E_CAL_SHELL_CONTENT_SELECTION_IS_RECURRING = 1 << 7, + E_CAL_SHELL_CONTENT_SELECTION_CAN_ACCEPT = 1 << 8, + E_CAL_SHELL_CONTENT_SELECTION_CAN_DELEGATE = 1 << 9, + E_CAL_SHELL_CONTENT_SELECTION_CAN_SAVE = 1 << 10 +}; + +struct _ECalShellContent { + EShellContent parent; + ECalShellContentPrivate *priv; +}; + +struct _ECalShellContentClass { + EShellContentClass parent_class; +}; + +GType e_cal_shell_content_get_type (void); +GtkWidget * e_cal_shell_content_new (EShellView *shell_view); +GnomeCalendar * e_cal_shell_content_get_calendar(ECalShellContent *cal_shell_content); +EMemoTable * e_cal_shell_content_get_memo_table + (ECalShellContent *cal_shell_content); +ECalendarTable *e_cal_shell_content_get_task_table + (ECalShellContent *cal_shell_content); +icaltimezone * e_cal_shell_content_get_timezone(ECalShellContent *cal_shell_content); +GalViewInstance * + e_cal_shell_content_get_view_instance + (ECalShellContent *cal_shell_content); +void e_cal_shell_content_copy_clipboard + (ECalShellContent *cal_shell_content); +void e_cal_shell_content_cut_clipboard + (ECalShellContent *cal_shell_content); +void e_cal_shell_content_paste_clipboard + (ECalShellContent *cal_shell_content); +void e_cal_shell_content_delete_selection + (ECalShellContent *cal_shell_content); +void e_cal_shell_content_delete_selected_occurrence + (ECalShellContent *cal_shell_content); + +G_END_DECLS + +#endif /* E_CAL_SHELL_CONTENT_H */ diff --git a/calendar/gui/migration.c b/calendar/modules/e-cal-shell-module-migrate.c index 8a68e4ffdc..5ebb6af54f 100644 --- a/calendar/gui/migration.c +++ b/calendar/modules/e-cal-shell-module-migrate.c @@ -1,4 +1,6 @@ /* + * e-cal-shell-module-migrate.c + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either @@ -13,14 +15,11 @@ * License along with the program; if not, see <http://www.gnu.org/licenses/> * * - * Authors: - * Rodrigo Moya <rodrigo@ximian.com> - * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * */ -#include <config.h> +#include "e-cal-shell-module-migrate.h" #include <string.h> #include <sys/types.h> @@ -29,32 +28,26 @@ #include <fcntl.h> #include <errno.h> -#include <gtk/gtk.h> #include <glib/gi18n.h> #include <glib/gstdio.h> - -#include <libecal/e-cal.h> - #include <libebackend/e-dbhash.h> +#include <libedataserver/e-source.h> +#include <libedataserver/e-source-group.h> +#include <libedataserver/e-source-list.h> #include <libedataserver/e-xml-hash-utils.h> -#include <libedataserver/e-xml-utils.h> -#include <libedataserver/e-account-list.h> -#include <camel/camel-url.h> #include "e-util/e-bconf-map.h" #include "e-util/e-folder-map.h" #include "e-util/e-util-private.h" +#include "calendar/gui/calendar-config.h" +#include "calendar/gui/calendar-config-keys.h" +#include "calendar/gui/e-cal-event.h" +#include "shell/e-shell.h" -#include "calendar-config-keys.h" -#include "calendar-config.h" -#include "e-cal-event.h" -#include "migration.h" - -#ifndef G_OS_WIN32 - -/* No previous versions have been available on Win32, so don't - * bother with upgrade support from 1.x on Win32. - */ +#define WEBCAL_BASE_URI "webcal://" +#define CONTACTS_BASE_URI "contacts://" +#define BAD_CONTACTS_BASE_URI "contact://" +#define PERSONAL_RELATIVE_URI "system" static e_gconf_map_t calendar_display_map[] = { /* /Calendar/Display */ @@ -77,22 +70,6 @@ static e_gconf_map_t calendar_display_map[] = { { NULL }, }; -static e_gconf_map_t calendar_tasks_map[] = { - /* /Calendar/Tasks */ - { "HideCompletedTasks", "calendar/tasks/hide_completed", E_GCONF_MAP_BOOL }, - { "HideCompletedTasksUnits", "calendar/tasks/hide_completed_units", E_GCONF_MAP_STRING }, - { "HideCompletedTasksValue", "calendar/tasks/hide_completed_value", E_GCONF_MAP_INT }, - { NULL }, -}; - -static e_gconf_map_t calendar_tasks_colours_map[] = { - /* /Calendar/Tasks/Colors */ - { "TasksDueToday", "calendar/tasks/colors/due_today", E_GCONF_MAP_STRING }, - { "TasksOverDue", "calendar/tasks/colors/overdue", E_GCONF_MAP_STRING }, - { "TasksDueToday", "calendar/tasks/colors/due_today", E_GCONF_MAP_STRING }, - { NULL }, -}; - static e_gconf_map_t calendar_other_map[] = { /* /Calendar/Other */ { "ConfirmDelete", "calendar/prompts/confirm_delete", E_GCONF_MAP_BOOL }, @@ -127,20 +104,18 @@ static e_gconf_map_list_t calendar_remap_list[] = { { NULL }, }; -static e_gconf_map_list_t task_remap_list[] = { - - { "/Calendar/Tasks", calendar_tasks_map }, - { "/Calendar/Tasks/Colors", calendar_tasks_colours_map }, - - { NULL }, -}; - static GtkWidget *window; static GtkLabel *label; static GtkProgressBar *progress; +#ifndef G_OS_WIN32 + +/* No previous versions have been available on Win32, so don't + * bother with upgrade support from 1.x on Win32. + */ + static void -setup_progress_dialog (gboolean tasks) +setup_progress_dialog (void) { GtkWidget *vbox, *hbox, *w; @@ -153,30 +128,25 @@ setup_progress_dialog (gboolean tasks) gtk_widget_show (vbox); gtk_container_add ((GtkContainer *) window, vbox); - if (tasks) - w = gtk_label_new (_("The location and hierarchy of the Evolution task " - "folders has changed since Evolution 1.x.\n\nPlease be " - "patient while Evolution migrates your folders...")); - else - w = gtk_label_new (_("The location and hierarchy of the Evolution calendar " - "folders has changed since Evolution 1.x.\n\nPlease be " - "patient while Evolution migrates your folders...")); + w = gtk_label_new (_("The location and hierarchy of the Evolution calendar " + "folders has changed since Evolution 1.x.\n\nPlease be " + "patient while Evolution migrates your folders...")); gtk_label_set_line_wrap ((GtkLabel *) w, TRUE); gtk_widget_show (w); - gtk_box_pack_start ((GtkBox *) vbox, w, TRUE, TRUE, 0); + gtk_box_pack_start_defaults ((GtkBox *) vbox, w); hbox = gtk_hbox_new (FALSE, 6); gtk_widget_show (hbox); - gtk_box_pack_start ((GtkBox *) vbox, hbox, TRUE, TRUE, 0); + gtk_box_pack_start_defaults ((GtkBox *) vbox, hbox); label = (GtkLabel *) gtk_label_new (""); gtk_widget_show ((GtkWidget *) label); - gtk_box_pack_start ((GtkBox *) hbox, (GtkWidget *) label, TRUE, TRUE, 0); + gtk_box_pack_start_defaults ((GtkBox *) hbox, (GtkWidget *) label); progress = (GtkProgressBar *) gtk_progress_bar_new (); gtk_widget_show ((GtkWidget *) progress); - gtk_box_pack_start ((GtkBox *) hbox, (GtkWidget *) progress, TRUE, TRUE, 0); + gtk_box_pack_start_defaults ((GtkBox *) hbox, (GtkWidget *) progress); gtk_widget_show (window); } @@ -317,7 +287,7 @@ migrate_ical_folder_to_source (char *old_path, ESource *new_source, ECalSourceTy ECal *old_ecal = NULL, *new_ecal = NULL; ESource *old_source; ESourceGroup *group; - char *old_uri = g_filename_to_uri (old_path, NULL, NULL); + char *old_uri = g_strdup_printf ("file://%s", old_path); GError *error = NULL; gboolean retval = FALSE; @@ -380,11 +350,126 @@ migrate_ical_folder (char *old_path, ESourceGroup *dest_group, char *source_name #endif /* !G_OS_WIN32 */ -#define WEBCAL_BASE_URI "webcal://" -#define CONTACTS_BASE_URI "contacts://" -#define BAD_CONTACTS_BASE_URI "contact://" -#define PERSONAL_RELATIVE_URI "system" -#define GROUPWISE_BASE_URI "groupwise://" +#ifndef G_OS_WIN32 + +static void +migrate_pilot_db_key (const char *key, gpointer user_data) +{ + EXmlHash *xmlhash = user_data; + + e_xmlhash_add (xmlhash, key, ""); +} + +static void +migrate_pilot_data (const char *component, const char *conduit, const char *old_path, const char *new_path) +{ + char *changelog, *map; + const char *dent; + const char *ext; + char *filename; + GDir *dir; + + if (!(dir = g_dir_open (old_path, 0, NULL))) + return; + + map = g_alloca (12 + strlen (conduit)); + sprintf (map, "pilot-map-%s-", conduit); + + changelog = g_alloca (24 + strlen (conduit)); + sprintf (changelog, "pilot-sync-evolution-%s-", conduit); + + while ((dent = g_dir_read_name (dir))) { + if (!strncmp (dent, map, strlen (map)) && + ((ext = strrchr (dent, '.')) && !strcmp (ext, ".xml"))) { + /* pilot map file - src and dest file formats are identical */ + unsigned char inbuf[4096]; + size_t nread, nwritten; + int fd0, fd1; + ssize_t n; + + filename = g_build_filename (old_path, dent, NULL); + if ((fd0 = g_open (filename, O_RDONLY|O_BINARY, 0)) == -1) { + g_free (filename); + continue; + } + + g_free (filename); + filename = g_build_filename (new_path, dent, NULL); + if ((fd1 = g_open (filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666)) == -1) { + g_free (filename); + close (fd0); + continue; + } + + do { + do { + n = read (fd0, inbuf, sizeof (inbuf)); + } while (n == -1 && errno == EINTR); + + if (n < 1) + break; + + nread = n; + nwritten = 0; + do { + do { + n = write (fd1, inbuf + nwritten, nread - nwritten); + } while (n == -1 && errno == EINTR); + + if (n > 0) + nwritten += n; + } while (nwritten < nread && n != -1); + + if (n == -1) + break; + } while (1); + + if (n != -1) + n = fsync (fd1); + + if (n == -1) { + g_warning ("Failed to migrate %s: %s", dent, strerror (errno)); + g_unlink (filename); + } + + close (fd0); + close (fd1); + g_free (filename); + } else if (!strncmp (dent, changelog, strlen (changelog)) && + ((ext = strrchr (dent, '.')) && !strcmp (ext, ".db"))) { + /* src and dest formats differ, src format is db3 while dest format is xml */ + EXmlHash *xmlhash; + EDbHash *dbhash; + struct stat st; + + filename = g_build_filename (old_path, dent, NULL); + if (g_stat (filename, &st) == -1) { + g_free (filename); + continue; + } + + dbhash = e_dbhash_new (filename); + g_free (filename); + + filename = g_strdup_printf ("%s/%s.ics-%s", new_path, component, dent); + if (g_stat (filename, &st) != -1) + g_unlink (filename); + xmlhash = e_xmlhash_new (filename); + g_free (filename); + + e_dbhash_foreach_key (dbhash, migrate_pilot_db_key, xmlhash); + + e_dbhash_destroy (dbhash); + + e_xmlhash_write (xmlhash); + e_xmlhash_destroy (xmlhash); + } + } + + g_dir_close (dir); +} + +#endif static ESourceGroup * create_calendar_contact_source (ESourceList *source_list) @@ -407,13 +492,15 @@ create_calendar_contact_source (ESourceList *source_list) } static void -create_calendar_sources (CalendarComponent *component, - ESourceList *source_list, +create_calendar_sources (EShellModule *shell_module, + ESourceList *source_list, ESourceGroup **on_this_computer, ESource **personal_source, ESourceGroup **on_the_web, ESourceGroup **contacts) { + EShell *shell; + EShellSettings *shell_settings; GSList *groups; ESourceGroup *group; char *base_uri, *base_uri_proto; @@ -424,7 +511,10 @@ create_calendar_sources (CalendarComponent *component, *contacts = NULL; *personal_source = NULL; - base_dir = calendar_component_peek_base_directory (component); + shell = e_shell_module_get_shell (shell_module); + shell_settings = e_shell_get_shell_settings (shell); + + base_dir = e_shell_module_get_config_dir (shell_module); base_uri = g_build_filename (base_dir, "local", NULL); base_uri_proto = g_filename_to_uri (base_uri, NULL, NULL); @@ -479,16 +569,21 @@ create_calendar_sources (CalendarComponent *component, } if (!*personal_source) { - char *primary_calendar = calendar_config_get_primary_calendar (); + char *primary_calendar; /* Create the default Person calendar */ ESource *source = e_source_new (_("Personal"), PERSONAL_RELATIVE_URI); e_source_group_add_source (*on_this_computer, source, -1); + primary_calendar = e_shell_settings_get_string ( + shell_settings, "cal-primary-calendar"); + if (!primary_calendar && !calendar_config_get_calendars_selected ()) { GSList selected; - calendar_config_set_primary_calendar (e_source_peek_uid (source)); + e_shell_settings_set_string ( + shell_settings, "cal-primary-calendar", + e_source_peek_uid (source)); selected.data = (gpointer)e_source_peek_uid (source); selected.next = NULL; @@ -518,233 +613,29 @@ create_calendar_sources (CalendarComponent *component, g_free (base_uri); } -static void -create_task_sources (TasksComponent *component, - ESourceList *source_list, - ESourceGroup **on_this_computer, - ESourceGroup **on_the_web, - ESource **personal_source) -{ - GSList *groups; - ESourceGroup *group; - char *base_uri, *base_uri_proto; - const gchar *base_dir; - - *on_this_computer = NULL; - *on_the_web = NULL; - *personal_source = NULL; - - base_dir = tasks_component_peek_base_directory (component); - base_uri = g_build_filename (base_dir, "local", NULL); - - base_uri_proto = g_filename_to_uri (base_uri, NULL, NULL); - - groups = e_source_list_peek_groups (source_list); - if (groups) { - /* groups are already there, we need to search for things... */ - GSList *g; - - for (g = groups; g; g = g->next) { - - group = E_SOURCE_GROUP (g->data); - - if (!*on_this_computer && !strcmp (base_uri_proto, e_source_group_peek_base_uri (group))) - *on_this_computer = g_object_ref (group); - else if (!*on_the_web && !strcmp (WEBCAL_BASE_URI, e_source_group_peek_base_uri (group))) - *on_the_web = g_object_ref (group); - } - } - - if (*on_this_computer) { - /* make sure "Personal" shows up as a source under - this group */ - GSList *sources = e_source_group_peek_sources (*on_this_computer); - GSList *s; - for (s = sources; s; s = s->next) { - ESource *source = E_SOURCE (s->data); - const gchar *relative_uri; - - relative_uri = e_source_peek_relative_uri (source); - if (relative_uri == NULL) - continue; - if (!strcmp (PERSONAL_RELATIVE_URI, relative_uri)) { - *personal_source = g_object_ref (source); - break; - } - } - } else { - /* create the local source group */ - group = e_source_group_new (_("On This Computer"), base_uri_proto); - e_source_list_add_group (source_list, group, -1); - - *on_this_computer = group; - } - - if (!*personal_source) { - /* Create the default Person task list */ - ESource *source = e_source_new (_("Personal"), PERSONAL_RELATIVE_URI); - e_source_group_add_source (*on_this_computer, source, -1); - - if (!calendar_config_get_primary_tasks () && !calendar_config_get_tasks_selected ()) { - GSList selected; - - calendar_config_set_primary_tasks (e_source_peek_uid (source)); - - selected.data = (gpointer)e_source_peek_uid (source); - selected.next = NULL; - calendar_config_set_tasks_selected (&selected); - } - - e_source_set_color_spec (source, "#BECEDD"); - *personal_source = source; - } - - if (!*on_the_web) { - /* Create the Webcal source group */ - group = e_source_group_new (_("On The Web"), WEBCAL_BASE_URI); - e_source_list_add_group (source_list, group, -1); - - *on_the_web = group; - } - - g_free (base_uri_proto); - g_free (base_uri); -} - -#ifndef G_OS_WIN32 - -static void -migrate_pilot_db_key (const char *key, gpointer user_data) -{ - EXmlHash *xmlhash = user_data; - - e_xmlhash_add (xmlhash, key, ""); -} - -static void -migrate_pilot_data (const char *component, const char *conduit, const char *old_path, const char *new_path) -{ - char *changelog, *map; - const char *dent; - const char *ext; - char *filename; - GDir *dir; - - if (!(dir = g_dir_open (old_path, 0, NULL))) - return; - - map = g_alloca (12 + strlen (conduit)); - sprintf (map, "pilot-map-%s-", conduit); - - changelog = g_alloca (24 + strlen (conduit)); - sprintf (changelog, "pilot-sync-evolution-%s-", conduit); - - while ((dent = g_dir_read_name (dir))) { - if (!strncmp (dent, map, strlen (map)) && - ((ext = strrchr (dent, '.')) && !strcmp (ext, ".xml"))) { - /* pilot map file - src and dest file formats are identical */ - unsigned char inbuf[4096]; - size_t nread, nwritten; - int fd0, fd1; - ssize_t n; - - filename = g_build_filename (old_path, dent, NULL); - if ((fd0 = g_open (filename, O_RDONLY|O_BINARY, 0)) == -1) { - g_free (filename); - continue; - } - - g_free (filename); - filename = g_build_filename (new_path, dent, NULL); - if ((fd1 = g_open (filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666)) == -1) { - g_free (filename); - close (fd0); - continue; - } - - do { - do { - n = read (fd0, inbuf, sizeof (inbuf)); - } while (n == -1 && errno == EINTR); - - if (n < 1) - break; - - nread = n; - nwritten = 0; - do { - do { - n = write (fd1, inbuf + nwritten, nread - nwritten); - } while (n == -1 && errno == EINTR); - - if (n > 0) - nwritten += n; - } while (nwritten < nread && n != -1); - - if (n == -1) - break; - } while (1); - - if (n != -1) - n = fsync (fd1); - - if (n == -1) { - g_warning ("Failed to migrate %s: %s", dent, g_strerror (errno)); - g_unlink (filename); - } - - close (fd0); - close (fd1); - g_free (filename); - } else if (!strncmp (dent, changelog, strlen (changelog)) && - ((ext = strrchr (dent, '.')) && !strcmp (ext, ".db"))) { - /* src and dest formats differ, src format is db3 while dest format is xml */ - EXmlHash *xmlhash; - EDbHash *dbhash; - struct stat st; - - filename = g_build_filename (old_path, dent, NULL); - if (g_stat (filename, &st) == -1) { - g_free (filename); - continue; - } - - dbhash = e_dbhash_new (filename); - g_free (filename); - - filename = g_strdup_printf ("%s/%s.ics-%s", new_path, component, dent); - if (g_stat (filename, &st) != -1) - g_unlink (filename); - xmlhash = e_xmlhash_new (filename); - g_free (filename); - - e_dbhash_foreach_key (dbhash, migrate_pilot_db_key, xmlhash); - - e_dbhash_destroy (dbhash); - - e_xmlhash_write (xmlhash); - e_xmlhash_destroy (xmlhash); - } - } - - g_dir_close (dir); -} - -#endif - gboolean -migrate_calendars (CalendarComponent *component, int major, int minor, int revision, GError **err) +e_cal_shell_module_migrate (EShellModule *shell_module, + gint major, + gint minor, + gint micro, + GError **error) { ESourceGroup *on_this_computer = NULL, *on_the_web = NULL, *contacts = NULL; ESource *personal_source = NULL; + ESourceList *source_list; ECalEvent *ece; - ECalEventTargetComponent *target; + ECalEventTargetModule *target; gboolean retval = FALSE; + source_list = g_object_get_data ( + G_OBJECT (shell_module), "source-list"); + /* we call this unconditionally now - create_groups either creates the groups/sources or it finds the necessary groups/sources. */ - create_calendar_sources (component, calendar_component_peek_source_list (component), &on_this_computer, &personal_source, &on_the_web, &contacts); + create_calendar_sources ( + shell_module, source_list, &on_this_computer, + &personal_source, &on_the_web, &contacts); #ifndef G_OS_WIN32 if (major == 1) { @@ -772,7 +663,7 @@ migrate_calendars (CalendarComponent *component, int major, int minor, int revis if (res != 0) { /* FIXME: set proper domain/code */ - g_set_error(err, 0, 0, _("Unable to migrate old settings from evolution/config.xmldb")); + g_set_error(error, 0, 0, _("Unable to migrate old settings from evolution/config.xmldb")); goto fail; } } @@ -781,7 +672,7 @@ migrate_calendars (CalendarComponent *component, int major, int minor, int revis GSList *migration_dirs, *l; char *path, *local_cal_folder; - setup_progress_dialog (FALSE); + setup_progress_dialog (); path = g_build_filename (g_get_home_dir (), "evolution", "local", NULL); migration_dirs = e_folder_map_local_folders (path, "calendar"); @@ -801,7 +692,7 @@ migrate_calendars (CalendarComponent *component, int major, int minor, int revis if (!migrate_ical_folder (l->data, on_this_computer, source_name, E_CAL_SOURCE_TYPE_EVENT)) { /* FIXME: domain/code */ - g_set_error(err, 0, 0, _("Unable to migrate calendar `%s'"), source_name); + g_set_error(error, 0, 0, _("Unable to migrate calendar `%s'"), source_name); g_free(source_name); goto fail; } @@ -814,7 +705,7 @@ migrate_calendars (CalendarComponent *component, int major, int minor, int revis dialog_close (); } - if (minor <= 4 || (minor == 5 && revision < 5)) { + if (minor <= 4 || (minor == 5 && micro < 5)) { GConfClient *gconf; GConfValue *gconf_val; int i; @@ -840,11 +731,11 @@ migrate_calendars (CalendarComponent *component, int major, int minor, int revis g_object_unref (gconf); } - if (minor < 5 || (minor == 5 && revision <= 10)) { + if (minor < 5 || (minor == 5 && micro <= 10)) { char *old_path, *new_path; old_path = g_build_filename (g_get_home_dir (), "evolution", "local", "Calendar", NULL); - new_path = g_build_filename (calendar_component_peek_base_directory (component), + new_path = g_build_filename (e_shell_module_get_config_dir (shell_module), "local", "system", NULL); migrate_pilot_data ("calendar", "calendar", old_path, new_path); g_free (new_path); @@ -857,9 +748,9 @@ migrate_calendars (CalendarComponent *component, int major, int minor, int revis during one phase of development, as they take precedent over relative uris (but aren't updated when editing an ESource). */ - if (minor == 5 && revision <= 11) { + if (minor == 5 && micro <= 11) { GSList *g; - for (g = e_source_list_peek_groups (calendar_component_peek_source_list (component)); g; g = g->next) { + for (g = e_source_list_peek_groups (source_list); g; g = g->next) { ESourceGroup *group = g->data; GSList *s; @@ -873,7 +764,7 @@ migrate_calendars (CalendarComponent *component, int major, int minor, int revis } #endif /* !G_OS_WIN32 */ - e_source_list_sync (calendar_component_peek_source_list (component), NULL); + e_source_list_sync (source_list, NULL); /** @Event: component.migration * @Title: Migration step in component initialization @@ -886,8 +777,8 @@ migrate_calendars (CalendarComponent *component, int major, int minor, int revis */ /* Fire off migration event */ ece = e_cal_event_peek (); - target = e_cal_event_target_new_component (ece, calendar_component_peek (), 0); - e_event_emit ((EEvent *) ece, "component.migration", (EEventTarget *) target); + target = e_cal_event_target_new_module (ece, shell_module, 0); + e_event_emit ((EEvent *) ece, "module.migration", (EEventTarget *) target); retval = TRUE; fail: @@ -903,343 +794,3 @@ fail: return retval; } -gboolean -migrate_tasks (TasksComponent *component, int major, int minor, int revision, GError **err) -{ - ESourceGroup *on_this_computer = NULL; - ESourceGroup *on_the_web = NULL; - ESource *personal_source = NULL; - gboolean retval = FALSE; - - /* we call this unconditionally now - create_groups either - creates the groups/sources or it finds the necessary - groups/sources. */ - create_task_sources (component, tasks_component_peek_source_list (component), &on_this_computer, &on_the_web, &personal_source); - -#ifndef G_OS_WIN32 - if (major == 1) { - xmlDocPtr config_doc = NULL; - char *conf_file; - - conf_file = g_build_filename (g_get_home_dir (), "evolution", "config.xmldb", NULL); - if (g_file_test (conf_file, G_FILE_TEST_IS_REGULAR)) - config_doc = e_xml_parse_file (conf_file); - g_free (conf_file); - - if (config_doc && minor <= 2) { - GConfClient *gconf; - int res = 0; - - /* move bonobo config to gconf */ - gconf = gconf_client_get_default (); - - res = e_bconf_import (gconf, config_doc, task_remap_list); - - g_object_unref (gconf); - - xmlFreeDoc(config_doc); - - if (res != 0) { - g_set_error(err, 0, 0, _("Unable to migrate old settings from evolution/config.xmldb")); - goto fail; - } - } - - if (minor <= 4) { - GSList *migration_dirs, *l; - char *path, *local_task_folder; - - setup_progress_dialog (TRUE); - - path = g_build_filename (g_get_home_dir (), "evolution", "local", NULL); - migration_dirs = e_folder_map_local_folders (path, "tasks"); - local_task_folder = g_build_filename (path, "Tasks", NULL); - g_free (path); - - if (personal_source) - migrate_ical_folder_to_source (local_task_folder, personal_source, E_CAL_SOURCE_TYPE_TODO); - - for (l = migration_dirs; l; l = l->next) { - char *source_name; - - if (personal_source && !strcmp ((char*)l->data, local_task_folder)) - continue; - - source_name = get_source_name (on_this_computer, (char*)l->data); - - if (!migrate_ical_folder (l->data, on_this_computer, source_name, E_CAL_SOURCE_TYPE_TODO)) { - /* FIXME: domain/code */ - g_set_error(err, 0, 0, _("Unable to migrate tasks `%s'"), source_name); - g_free(source_name); - goto fail; - } - - g_free (source_name); - } - - g_free (local_task_folder); - - dialog_close (); - } - - if (minor < 5 || (minor == 5 && revision <= 10)) { - char *old_path, *new_path; - - old_path = g_build_filename (g_get_home_dir (), "evolution", "local", "Tasks", NULL); - new_path = g_build_filename (tasks_component_peek_base_directory (component), - "local", "system", NULL); - migrate_pilot_data ("tasks", "todo", old_path, new_path); - g_free (new_path); - g_free (old_path); - } - - /* we only need to do this next step if people ran - older versions of 1.5. We need to clear out the - absolute URI's that were assigned to ESources - during one phase of development, as they take - precedent over relative uris (but aren't updated - when editing an ESource). */ - if (minor == 5 && revision <= 11) { - GSList *g; - for (g = e_source_list_peek_groups (tasks_component_peek_source_list (component)); g; g = g->next) { - ESourceGroup *group = g->data; - GSList *s; - - for (s = e_source_group_peek_sources (group); s; s = s->next) { - ESource *source = s->data; - e_source_set_absolute_uri (source, NULL); - } - } - } - } -#endif /* !G_OS_WIN32 */ - e_source_list_sync (tasks_component_peek_source_list (component), NULL); - retval = TRUE; -fail: - if (on_this_computer) - g_object_unref (on_this_computer); - if (on_the_web) - g_object_unref (on_the_web); - if (personal_source) - g_object_unref (personal_source); - - return retval; -} - -/******************************************************************************************************** - * - * MEMOS - * - ********************************************************************************************************/ - -static void -create_memo_sources (MemosComponent *component, - ESourceList *source_list, - ESourceGroup **on_this_computer, - ESourceGroup **on_the_web, - ESource **personal_source) -{ - GSList *groups; - ESourceGroup *group; - char *base_uri, *base_uri_proto; - const gchar *base_dir; - - *on_this_computer = NULL; - *on_the_web = NULL; - *personal_source = NULL; - - base_dir = memos_component_peek_base_directory (component); - base_uri = g_build_filename (base_dir, "local", NULL); - - base_uri_proto = g_filename_to_uri (base_uri, NULL, NULL); - - groups = e_source_list_peek_groups (source_list); - if (groups) { - /* groups are already there, we need to search for things... */ - GSList *g; - - for (g = groups; g; g = g->next) { - - group = E_SOURCE_GROUP (g->data); - - if (!*on_this_computer && !strcmp (base_uri_proto, e_source_group_peek_base_uri (group))) - *on_this_computer = g_object_ref (group); - else if (!*on_the_web && !strcmp (WEBCAL_BASE_URI, e_source_group_peek_base_uri (group))) - *on_the_web = g_object_ref (group); - } - } - - if (*on_this_computer) { - /* make sure "Personal" shows up as a source under - this group */ - GSList *sources = e_source_group_peek_sources (*on_this_computer); - GSList *s; - for (s = sources; s; s = s->next) { - ESource *source = E_SOURCE (s->data); - const gchar *relative_uri; - - relative_uri = e_source_peek_relative_uri (source); - if (relative_uri == NULL) - continue; - if (!strcmp (PERSONAL_RELATIVE_URI, relative_uri)) { - *personal_source = g_object_ref (source); - break; - } - } - } else { - /* create the local source group */ - group = e_source_group_new (_("On This Computer"), base_uri_proto); - e_source_list_add_group (source_list, group, -1); - - *on_this_computer = group; - } - - if (!*personal_source) { - /* Create the default Person task list */ - ESource *source = e_source_new (_("Personal"), PERSONAL_RELATIVE_URI); - e_source_group_add_source (*on_this_computer, source, -1); - - if (!calendar_config_get_primary_memos () && !calendar_config_get_memos_selected ()) { - GSList selected; - - calendar_config_set_primary_memos (e_source_peek_uid (source)); - - selected.data = (gpointer)e_source_peek_uid (source); - selected.next = NULL; - calendar_config_set_memos_selected (&selected); - } - - e_source_set_color_spec (source, "#BECEDD"); - *personal_source = source; - } - - if (!*on_the_web) { - /* Create the Webcal source group */ - group = e_source_group_new (_("On The Web"), WEBCAL_BASE_URI); - e_source_list_add_group (source_list, group, -1); - - *on_the_web = group; - } - - g_free (base_uri_proto); - g_free (base_uri); -} - -static gboolean -is_groupwise_account (EAccount *account) -{ - if (account->source->url != NULL) { - return g_str_has_prefix (account->source->url, GROUPWISE_BASE_URI); - } else { - return FALSE; - } -} - -static void -add_gw_esource (ESourceList *source_list, const char *group_name, const char *source_name, CamelURL *url, GConfClient *client) -{ - ESourceGroup *group; - ESource *source; - GSList *ids, *temp ; - GError *error = NULL; - char *relative_uri; - const char *soap_port; - const char * use_ssl; - const char *poa_address; - const char *offline_sync; - - - poa_address = url->host; - if (!poa_address || strlen (poa_address) ==0) - return; - soap_port = camel_url_get_param (url, "soap_port"); - - if (!soap_port || strlen (soap_port) == 0) - soap_port = "7191"; - - use_ssl = camel_url_get_param (url, "use_ssl"); - offline_sync = camel_url_get_param (url, "offline_sync"); - - group = e_source_group_new (group_name, GROUPWISE_BASE_URI); - if (!e_source_list_add_group (source_list, group, -1)) - return; - relative_uri = g_strdup_printf ("%s@%s/", url->user, poa_address); - - source = e_source_new (source_name, relative_uri); - e_source_set_property (source, "auth", "1"); - e_source_set_property (source, "username", url->user); - e_source_set_property (source, "port", camel_url_get_param (url, "soap_port")); - e_source_set_property (source, "auth-domain", "Groupwise"); - e_source_set_property (source, "use_ssl", use_ssl); - e_source_set_property (source, "offline_sync", offline_sync ? "1" : "0" ); - - e_source_set_color_spec (source, "#EEBC60"); - e_source_group_add_source (group, source, -1); - - ids = gconf_client_get_list (client, CALENDAR_CONFIG_MEMOS_SELECTED_MEMOS, GCONF_VALUE_STRING, &error); - if ( error != NULL ) { - g_warning("%s (%s) %s\n", G_STRLOC, G_STRFUNC, error->message); - g_error_free(error); - } - ids = g_slist_append (ids, g_strdup (e_source_peek_uid (source))); - gconf_client_set_list (client, CALENDAR_CONFIG_MEMOS_SELECTED_MEMOS, GCONF_VALUE_STRING, ids, NULL); - temp = ids; - for (; temp != NULL; temp = g_slist_next (temp)) - g_free (temp->data); - - g_slist_free (ids); - g_object_unref (source); - g_object_unref (group); - g_free (relative_uri); -} - -gboolean -migrate_memos (MemosComponent *component, int major, int minor, int revision, struct _GError **err) -{ - ESourceGroup *on_this_computer = NULL; - ESourceGroup *on_the_web = NULL; - ESource *personal_source = NULL; - ESourceList *source_list = NULL; - gboolean retval = FALSE; - - source_list = memos_component_peek_source_list (component); - - /* we call this unconditionally now - create_groups either - creates the groups/sources or it finds the necessary - groups/sources. */ - create_memo_sources (component, source_list, &on_this_computer, &on_the_web, &personal_source); - - /* Migration for Gw accounts between versions < 2.8 */ - if (major == 2 && minor < 8) { - EAccountList *al; - EAccount *a; - CamelURL *url; - EIterator *it; - GConfClient *gconf_client = gconf_client_get_default (); - al = e_account_list_new (gconf_client); - for (it = e_list_get_iterator((EList *)al); - e_iterator_is_valid(it); - e_iterator_next(it)) { - a = (EAccount *) e_iterator_get(it); - if (!a->enabled || !is_groupwise_account (a)) - continue; - url = camel_url_new (a->source->url, NULL); - add_gw_esource (source_list, a->name, _("Notes"), url, gconf_client); - camel_url_free (url); - } - g_object_unref (al); - g_object_unref (gconf_client); - } - - e_source_list_sync (source_list, NULL); - retval = TRUE; - - if (on_this_computer) - g_object_unref (on_this_computer); - if (on_the_web) - g_object_unref (on_the_web); - if (personal_source) - g_object_unref (personal_source); - - return retval; -} diff --git a/calendar/gui/itip-bonobo-control.h b/calendar/modules/e-cal-shell-module-migrate.h index 7c2033656c..afef469df8 100644 --- a/calendar/gui/itip-bonobo-control.h +++ b/calendar/modules/e-cal-shell-module-migrate.h @@ -1,7 +1,6 @@ /* + * e-cal-shell-module-migrate.h * - * Evolution calendar - Control for displaying iTIP mail messages - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either @@ -16,19 +15,24 @@ * License along with the program; if not, see <http://www.gnu.org/licenses/> * * - * Authors: - * Jesse Pavel <jpavel@ximian.com> - * JP Rosevear <jpr@ximian.com> - * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * */ -#ifndef __ITIP_CONTROL_FACTORY_H__ -#define __ITIP_CONTROL_FACTORY_H__ +#ifndef E_CAL_SHELL_MODULE_MIGRATE_H +#define E_CAL_SHELL_MODULE_MIGRATE_H + +#include <glib.h> +#include <shell/e-shell-module.h> + +G_BEGIN_DECLS -#include <bonobo/bonobo-control.h> +gboolean e_cal_shell_module_migrate (EShellModule *shell_module, + gint major, + gint minor, + gint micro, + GError **error); -BonoboControl *itip_bonobo_control_new (void); +G_END_DECLS -#endif /* __ITIP_CONTROL_H__ */ +#endif /* E_CAL_SHELL_MODULE_MIGRATE_H */ diff --git a/calendar/modules/e-cal-shell-module-settings.c b/calendar/modules/e-cal-shell-module-settings.c new file mode 100644 index 0000000000..ff6bd8e500 --- /dev/null +++ b/calendar/modules/e-cal-shell-module-settings.c @@ -0,0 +1,59 @@ +/* + * e-cal-shell-module-settings.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-cal-shell-module-settings.h" + +#include <gconf/gconf-client.h> + +void +e_cal_shell_module_init_settings (EShell *shell) +{ + EShellSettings *shell_settings; + + shell_settings = e_shell_get_shell_settings (shell); + + /* XXX Default values should match the GConf schema. + * Yes it's redundant, but we're stuck with GConf. */ + + e_shell_settings_install_property ( + g_param_spec_string ( + "cal-primary-calendar", + NULL, + NULL, + NULL, + G_PARAM_READWRITE)); + + e_shell_settings_bind_to_gconf ( + shell_settings, "cal-primary-calendar", + "/apps/evolution/calendar/display/primary_calendar"); + + e_shell_settings_install_property ( + g_param_spec_boolean ( + "cal-use-system-timezone", + NULL, + NULL, + TRUE, + G_PARAM_READWRITE)); + + e_shell_settings_bind_to_gconf ( + shell_settings, "cal-use-system-timezone", + "/apps/evolution/calendar/display/use_system_timezone"); +} diff --git a/calendar/gui/control-factory.h b/calendar/modules/e-cal-shell-module-settings.h index 2103f458f1..92be6da749 100644 --- a/calendar/gui/control-factory.h +++ b/calendar/modules/e-cal-shell-module-settings.h @@ -1,4 +1,5 @@ /* + * e-cal-shell-module-settings.h * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -14,18 +15,19 @@ * License along with the program; if not, see <http://www.gnu.org/licenses/> * * - * Authors: - * Ettore Perazzoli <ettore@ximian.com> - * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * */ -#ifndef _CONTROL_FACTORY_H_ -#define _CONTROL_FACTORY_H_ +#ifndef E_CAL_SHELL_MODULE_SETTINGS_H +#define E_CAL_SHELL_MODULE_SETTINGS_H + +#include <shell/e-shell.h> + +G_BEGIN_DECLS -#include <bonobo/bonobo-control.h> +void e_cal_shell_module_init_settings (EShell *shell); -BonoboControl *control_factory_new_control (void); +G_END_DECLS -#endif /* _CONTROL_FACTORY_H_ */ +#endif /* E_CAL_SHELL_MODULE_SETTINGS_H */ diff --git a/calendar/modules/e-cal-shell-module.c b/calendar/modules/e-cal-shell-module.c new file mode 100644 index 0000000000..a73f0b5960 --- /dev/null +++ b/calendar/modules/e-cal-shell-module.c @@ -0,0 +1,570 @@ +/* + * e-cal-shell-module.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include <string.h> +#include <glib/gi18n.h> +#include <libecal/e-cal.h> +#include <libedataserver/e-url.h> +#include <libedataserver/e-source.h> +#include <libedataserver/e-source-list.h> +#include <libedataserver/e-source-group.h> + +#include "e-util/e-import.h" +#include "shell/e-shell.h" +#include "shell/e-shell-module.h" +#include "shell/e-shell-window.h" +#include "widgets/misc/e-preferences-window.h" + +#include "calendar/common/authentication.h" +#include "calendar/gui/calendar-config.h" +#include "calendar/gui/comp-util.h" +#include "calendar/gui/e-attachment-handler-calendar.h" +#include "calendar/gui/e-cal-config.h" +#include "calendar/gui/e-cal-event.h" +#include "calendar/gui/dialogs/cal-prefs-dialog.h" +#include "calendar/gui/dialogs/calendar-setup.h" +#include "calendar/gui/dialogs/event-editor.h" +#include "calendar/importers/evolution-calendar-importer.h" + +#include "e-cal-shell-view.h" +#include "e-cal-shell-module-migrate.h" +#include "e-cal-shell-module-settings.h" + +#define MODULE_NAME "calendar" +#define MODULE_ALIASES "" +#define MODULE_SCHEMES "calendar" +#define MODULE_SORT_ORDER 400 + +#define CONTACTS_BASE_URI "contacts://" +#define WEATHER_BASE_URI "weather://" +#define WEB_BASE_URI "webcal://" +#define PERSONAL_RELATIVE_URI "system" + +/* Module Entry Point */ +void e_shell_module_init (GTypeModule *type_module); + +static void +cal_shell_module_ensure_sources (EShellModule *shell_module) +{ + /* XXX This is basically the same algorithm across all modules. + * Maybe we could somehow integrate this into EShellModule? */ + + ESourceList *source_list; + ESourceGroup *on_this_computer; + ESourceGroup *on_the_web; + ESourceGroup *contacts; + ESourceGroup *weather; + ESource *birthdays; + ESource *personal; + EShell *shell; + EShellSettings *shell_settings; + GSList *groups, *iter; + const gchar *data_dir; + const gchar *name; + gchar *base_uri; + gchar *filename; + gchar *property; + + on_this_computer = NULL; + on_the_web = NULL; + contacts = NULL; + weather = NULL; + birthdays = NULL; + personal = NULL; + + shell = e_shell_module_get_shell (shell_module); + shell_settings = e_shell_get_shell_settings (shell); + + if (!e_cal_get_sources (&source_list, E_CAL_SOURCE_TYPE_EVENT, NULL)) { + g_warning ("Could not get calendar sources from GConf!"); + return; + } + + /* Share the source list with all calendar views. This + * is accessible via e_cal_shell_view_get_source_list(). + * Note: EShellModule takes ownership of the reference. + * + * XXX I haven't yet decided if I want to add a proper + * EShellModule API for this. The mail module would + * not use it. */ + g_object_set_data_full ( + G_OBJECT (shell_module), "source-list", + source_list, (GDestroyNotify) g_object_unref); + + data_dir = e_shell_module_get_data_dir (shell_module); + filename = g_build_filename (data_dir, "local", NULL); + base_uri = g_filename_to_uri (filename, NULL, NULL); + g_free (filename); + + groups = e_source_list_peek_groups (source_list); + for (iter = groups; iter != NULL; iter = iter->next) { + ESourceGroup *source_group = iter->data; + const gchar *group_base_uri; + + group_base_uri = e_source_group_peek_base_uri (source_group); + + /* Compare only "file://" part. if the user's home + * changes, we do not want to create another group. */ + if (on_this_computer == NULL && + strncmp (base_uri, group_base_uri, 7) == 0) + on_this_computer = source_group; + + else if (on_the_web == NULL && + strcmp (WEB_BASE_URI, group_base_uri) == 0) + on_the_web = source_group; + + else if (contacts == NULL && + strcmp (CONTACTS_BASE_URI, group_base_uri) == 0) + contacts = source_group; + + else if (weather == NULL && + strcmp (WEATHER_BASE_URI, group_base_uri) == 0) + weather = source_group; + } + + name = _("On This Computer"); + + if (on_this_computer != NULL) { + GSList *sources; + const gchar *group_base_uri; + + /* Force the group name to the current locale. */ + e_source_group_set_name (on_this_computer, name); + + sources = e_source_group_peek_sources (on_this_computer); + group_base_uri = e_source_group_peek_base_uri (on_this_computer); + + /* Make sure this group includes a "Personal" source. */ + for (iter = sources; iter != NULL; iter = iter->next) { + ESource *source = iter->data; + const gchar *relative_uri; + + relative_uri = e_source_peek_relative_uri (source); + if (relative_uri == NULL) + continue; + + if (strcmp (PERSONAL_RELATIVE_URI, relative_uri) != 0) + continue; + + personal = source; + break; + } + + /* Make sure we have the correct base URI. This can + * change when the user's home directory changes. */ + if (strcmp (base_uri, group_base_uri) != 0) { + e_source_group_set_base_uri ( + on_this_computer, base_uri); + + /* XXX We shouldn't need this sync call here as + * set_base_uri() results in synching to GConf, + * but that happens in an idle loop and too late + * to prevent the user from seeing a "Cannot + * Open ... because of invalid URI" error. */ + e_source_list_sync (source_list, NULL); + } + + } else { + ESourceGroup *source_group; + + source_group = e_source_group_new (name, base_uri); + e_source_list_add_group (source_list, source_group, -1); + g_object_unref (source_group); + } + + name = _("Personal"); + + if (personal == NULL) { + ESource *source; + GSList *selected; + gchar *primary; + + source = e_source_new (name, PERSONAL_RELATIVE_URI); + e_source_group_add_source (on_this_computer, source, -1); + g_object_unref (source); + + primary = e_shell_settings_get_string ( + shell_settings, "cal-primary-calendar"); + + selected = calendar_config_get_calendars_selected (); + + if (primary == NULL && selected == NULL) { + const gchar *uid; + + uid = e_source_peek_uid (source); + selected = g_slist_prepend (NULL, g_strdup (uid)); + + e_shell_settings_set_string ( + shell_settings, "cal-primary-calendar", uid); + calendar_config_set_calendars_selected (selected); + } + + g_slist_foreach (selected, (GFunc) g_free, NULL); + g_slist_free (selected); + g_free (primary); + } else { + /* Force the source name to the current locale. */ + e_source_set_name (personal, name); + } + + name = _("On The Web"); + + if (on_the_web == NULL) { + ESourceGroup *source_group; + + source_group = e_source_group_new (name, WEB_BASE_URI); + e_source_list_add_group (source_list, source_group, -1); + g_object_unref (source_group); + } else { + /* Force the group name to the current locale. */ + e_source_group_set_name (on_the_web, name); + } + + name = _("Contacts"); + + if (contacts != NULL) { + GSList *sources; + + /* Force the group name to the current locale. */ + e_source_group_set_name (contacts, name); + + sources = e_source_group_peek_sources (contacts); + + if (sources != NULL) { + GSList *trash; + + /* There is only one source under Contacts. */ + birthdays = E_SOURCE (sources->data); + sources = g_slist_next (sources); + + /* Delete any other sources in this group. + * Earlier versions allowed you to create + * additional sources under Contacts. */ + trash = g_slist_copy (sources); + while (trash != NULL) { + ESource *source = trash->data; + e_source_group_remove_source (contacts, source); + trash = g_slist_delete_link (trash, trash); + } + + } + } else { + ESourceGroup *source_group; + + source_group = e_source_group_new (name, CONTACTS_BASE_URI); + e_source_list_add_group (source_list, source_group, -1); + g_object_unref (source_group); + + /* This is now a borrowed reference. */ + contacts = source_group; + } + + /* XXX e_source_group_get_property() returns a newly-allocated + * string when it could just as easily return a const string. + * Unfortunately, fixing that would break the API. */ + property = e_source_group_get_property (contacts, "create_source"); + if (property == NULL) + e_source_group_set_property (contacts, "create_source", "no"); + g_free (property); + + name = _("Birthdays & Anniversaries"); + + if (birthdays == NULL) { + ESource *source; + const gchar *name; + + name = _("Birthdays & Anniversaries"); + source = e_source_new (name, "/"); + e_source_group_add_source (contacts, source, -1); + g_object_unref (source); + + /* This is now a borrowed reference. */ + birthdays = source; + } else { + /* Force the source name to the current locale. */ + e_source_set_name (birthdays, name); + } + + if (e_source_get_property (birthdays, "delete") == NULL) + e_source_set_property (birthdays, "delete", "no"); + + if (e_source_peek_color_spec (birthdays) == NULL) + e_source_set_color_spec (birthdays, "#DDBECE"); + + name = _("Weather"); + + if (weather == NULL) { + ESourceGroup *source_group; + + source_group = e_source_group_new (name, WEATHER_BASE_URI); + e_source_list_add_group (source_list, source_group, -1); + g_object_unref (source_group); + } else { + /* Force the group name to the current locale. */ + e_source_group_set_name (weather, name); + } + + g_free (base_uri); +} + +static void +cal_shell_module_cal_opened_cb (ECal *cal, + ECalendarStatus status, + GtkAction *action) +{ + EShell *shell; + ECalComponent *comp; + CompEditor *editor; + CompEditorFlags flags = 0; + const gchar *action_name; + gboolean all_day; + + /* FIXME Pass this in. */ + shell = e_shell_get_default (); + + /* XXX Handle errors better. */ + if (status != E_CALENDAR_STATUS_OK) + return; + + action_name = gtk_action_get_name (action); + + flags |= COMP_EDITOR_NEW_ITEM; + flags |= COMP_EDITOR_USER_ORG; + if (strcmp (action_name, "event-meeting-new") == 0) + flags |= COMP_EDITOR_MEETING; + + all_day = (strcmp (action_name, "event-all-day-new") == 0); + + editor = event_editor_new (cal, shell, flags); + comp = cal_comp_event_new_with_current_time (cal, all_day); + comp_editor_edit_comp (editor, comp); + + gtk_window_present (GTK_WINDOW (editor)); + + g_object_unref (comp); + g_object_unref (cal); +} + +static void +action_event_new_cb (GtkAction *action, + EShellWindow *shell_window) +{ + ECal *cal = NULL; + ECalSourceType source_type; + ESourceList *source_list; + EShellSettings *shell_settings; + EShell *shell; + gchar *uid; + + /* This callback is used for both appointments and meetings. */ + + source_type = E_CAL_SOURCE_TYPE_EVENT; + + shell = e_shell_window_get_shell (shell_window); + shell_settings = e_shell_get_shell_settings (shell); + + if (!e_cal_get_sources (&source_list, source_type, NULL)) { + g_warning ("Could not get calendar sources from GConf!"); + return; + } + + uid = e_shell_settings_get_string ( + shell_settings, "cal-primary-calendar"); + + if (uid != NULL) { + ESource *source; + + source = e_source_list_peek_source_by_uid (source_list, uid); + if (source != NULL) + cal = auth_new_cal_from_source (source, source_type); + g_free (uid); + } + + if (cal == NULL) + cal = auth_new_cal_from_default (source_type); + + g_return_if_fail (cal != NULL); + + g_signal_connect ( + cal, "cal-opened", + G_CALLBACK (cal_shell_module_cal_opened_cb), action); + + e_cal_open_async (cal, FALSE); +} + +static void +action_calendar_new_cb (GtkAction *action, + EShellWindow *shell_window) +{ + calendar_setup_new_calendar (GTK_WINDOW (shell_window)); +} + +static GtkActionEntry item_entries[] = { + + { "event-new", + "appointment-new", + NC_("New", "_Appointment"), + "<Shift><Control>a", + N_("Create a new appointment"), + G_CALLBACK (action_event_new_cb) }, + + { "event-all-day-new", + "stock_new-24h-appointment", + NC_("New", "All Day A_ppointment"), + NULL, + N_("Create a new all-day appointment"), + G_CALLBACK (action_event_new_cb) }, + + { "event-meeting-new", + "stock_new-meeting", + NC_("New", "M_eeting"), + "<Shift><Control>e", + N_("Create a new meeting request"), + G_CALLBACK (action_event_new_cb) } +}; + +static GtkActionEntry source_entries[] = { + + { "calendar-new", + "x-office-calendar", + NC_("New", "Cale_ndar"), + NULL, + N_("Create a new calendar"), + G_CALLBACK (action_calendar_new_cb) } +}; + +static void +cal_shell_module_init_hooks (void) +{ + e_plugin_hook_register_type (e_cal_config_hook_get_type ()); + e_plugin_hook_register_type (e_cal_event_hook_get_type ()); +} + +static void +cal_shell_module_init_importers (void) +{ + EImportClass *import_class; + EImportImporter *importer; + + import_class = g_type_class_ref (e_import_get_type ()); + + importer = gnome_calendar_importer_peek (); + e_import_class_add_importer (import_class, importer, NULL, NULL); + + importer = ical_importer_peek (); + e_import_class_add_importer (import_class, importer, NULL, NULL); + + importer = vcal_importer_peek (); + e_import_class_add_importer (import_class, importer, NULL, NULL); +} + +static void +cal_shell_module_init_preferences (EShell *shell) +{ + GtkWidget *preferences_window; + + preferences_window = e_shell_get_preferences_window (shell); + + e_preferences_window_add_page ( + E_PREFERENCES_WINDOW (preferences_window), + "calendar-and-tasks", + "preferences-calendar-and-tasks", + _("Calendar and Tasks"), + calendar_prefs_dialog_new (shell), + 600); +} + +static gboolean +cal_shell_module_handle_uri_cb (EShellModule *shell_module, + const gchar *uri) +{ + /* FIXME */ + return FALSE; +} + +static void +cal_shell_module_window_created_cb (EShellModule *shell_module, + GtkWindow *window) +{ + const gchar *module_name; + + if (!E_IS_SHELL_WINDOW (window)) + return; + + module_name = G_TYPE_MODULE (shell_module)->name; + + e_shell_window_register_new_item_actions ( + E_SHELL_WINDOW (window), module_name, + item_entries, G_N_ELEMENTS (item_entries)); + + e_shell_window_register_new_source_actions ( + E_SHELL_WINDOW (window), module_name, + source_entries, G_N_ELEMENTS (source_entries)); +} + +static EShellModuleInfo module_info = { + + MODULE_NAME, + MODULE_ALIASES, + MODULE_SCHEMES, + MODULE_SORT_ORDER, + + /* start */ NULL, + /* is_busy */ NULL, + /* shutdown */ NULL, + e_cal_shell_module_migrate +}; + +void +e_shell_module_init (GTypeModule *type_module) +{ + EShell *shell; + EShellModule *shell_module; + + shell_module = E_SHELL_MODULE (type_module); + shell = e_shell_module_get_shell (shell_module); + + e_shell_module_set_info ( + shell_module, &module_info, + e_cal_shell_view_get_type (type_module)); + + cal_shell_module_ensure_sources (shell_module); + + g_signal_connect_swapped ( + shell, "handle-uri", + G_CALLBACK (cal_shell_module_handle_uri_cb), + shell_module); + + g_signal_connect_swapped ( + shell, "window-created", + G_CALLBACK (cal_shell_module_window_created_cb), + shell_module); + + cal_shell_module_init_hooks (); + cal_shell_module_init_importers (); + + /* Initialize settings before initializing preferences, + * since the preferences bind to the shell settings. */ + e_cal_shell_module_init_settings (shell); + cal_shell_module_init_preferences (shell); + + e_attachment_handler_calendar_get_type (); +} diff --git a/calendar/modules/e-cal-shell-sidebar.c b/calendar/modules/e-cal-shell-sidebar.c new file mode 100644 index 0000000000..61a1a727e6 --- /dev/null +++ b/calendar/modules/e-cal-shell-sidebar.c @@ -0,0 +1,756 @@ +/* + * e-cal-shell-sidebar.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-cal-shell-sidebar.h" + +#include <string.h> +#include <glib/gi18n.h> + +#include "e-util/e-error.h" +#include "e-util/gconf-bridge.h" +#include "calendar/common/authentication.h" +#include "calendar/gui/calendar-config.h" +#include "calendar/gui/e-calendar-selector.h" +#include "calendar/gui/e-mini-calendar-config.h" +#include "calendar/gui/misc.h" + +#include "e-cal-shell-view.h" + +#define E_CAL_SHELL_SIDEBAR_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_CAL_SHELL_SIDEBAR, ECalShellSidebarPrivate)) + +struct _ECalShellSidebarPrivate { + GtkWidget *paned; + GtkWidget *selector; + GtkWidget *mini_calendar; + + /* UID -> Client */ + GHashTable *client_table; + + EMiniCalendarConfig *mini_calendar_config; +}; + +enum { + PROP_0, + PROP_MINI_CALENDAR, + PROP_SELECTOR +}; + +enum { + CLIENT_ADDED, + CLIENT_REMOVED, + STATUS_MESSAGE, + LAST_SIGNAL +}; + +static gpointer parent_class; +static guint signals[LAST_SIGNAL]; + +static void +cal_shell_sidebar_emit_client_added (ECalShellSidebar *cal_shell_sidebar, + ECal *client) +{ + guint signal_id = signals[CLIENT_ADDED]; + + g_signal_emit (cal_shell_sidebar, signal_id, 0, client); +} + +static void +cal_shell_sidebar_emit_client_removed (ECalShellSidebar *cal_shell_sidebar, + ECal *client) +{ + guint signal_id = signals[CLIENT_REMOVED]; + + g_signal_emit (cal_shell_sidebar, signal_id, 0, client); +} + +static void +cal_shell_sidebar_emit_status_message (ECalShellSidebar *cal_shell_sidebar, + const gchar *status_message) +{ + guint signal_id = signals[STATUS_MESSAGE]; + + g_signal_emit (cal_shell_sidebar, signal_id, 0, status_message); +} + +static void +cal_shell_sidebar_backend_died_cb (ECalShellSidebar *cal_shell_sidebar, + ECal *client) +{ + EShellView *shell_view; + EShellWindow *shell_window; + EShellSidebar *shell_sidebar; + GHashTable *client_table; + ESource *source; + const gchar *uid; + + client_table = cal_shell_sidebar->priv->client_table; + + shell_sidebar = E_SHELL_SIDEBAR (cal_shell_sidebar); + shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); + shell_window = e_shell_view_get_shell_window (shell_view); + + source = e_cal_get_source (client); + uid = e_source_peek_uid (source); + + g_object_ref (source); + + g_hash_table_remove (client_table, uid); + cal_shell_sidebar_emit_status_message (cal_shell_sidebar, NULL); + + e_error_run ( + GTK_WINDOW (shell_window), + "calendar:calendar-crashed", NULL); + + g_object_unref (source); +} + +static void +cal_shell_sidebar_backend_error_cb (ECalShellSidebar *cal_shell_sidebar, + const gchar *message, + ECal *client) +{ + EShellView *shell_view; + EShellWindow *shell_window; + EShellSidebar *shell_sidebar; + GtkWidget *dialog; + const gchar *uri; + gchar *uri_no_passwd; + + shell_sidebar = E_SHELL_SIDEBAR (cal_shell_sidebar); + shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); + shell_window = e_shell_view_get_shell_window (shell_view); + + uri = e_cal_get_uri (client); + uri_no_passwd = get_uri_without_password (uri); + + dialog = gtk_message_dialog_new ( + GTK_WINDOW (shell_window), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, + _("Error on %s\n%s"), + uri_no_passwd, message); + + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + + g_free (uri_no_passwd); +} + +static void +cal_shell_sidebar_client_opened_cb (ECalShellSidebar *cal_shell_sidebar, + ECalendarStatus status, + ECal *client) +{ + EShellView *shell_view; + EShellWindow *shell_window; + EShellSidebar *shell_sidebar; + ESource *source; + + source = e_cal_get_source (client); + + shell_sidebar = E_SHELL_SIDEBAR (cal_shell_sidebar); + shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); + shell_window = e_shell_view_get_shell_window (shell_view); + + if (status == E_CALENDAR_STATUS_AUTHENTICATION_FAILED || + status == E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED) + auth_cal_forget_password (client); + + switch (status) { + case E_CALENDAR_STATUS_OK: + g_signal_handlers_disconnect_matched ( + client, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, + cal_shell_sidebar_client_opened_cb, NULL); + + cal_shell_sidebar_emit_status_message ( + cal_shell_sidebar, _("Loading calendars")); + cal_shell_sidebar_emit_client_added ( + cal_shell_sidebar, client); + cal_shell_sidebar_emit_status_message ( + cal_shell_sidebar, NULL); + break; + + case E_CALENDAR_STATUS_AUTHENTICATION_FAILED: + e_cal_open_async (client, FALSE); + break; + + case E_CALENDAR_STATUS_BUSY: + break; + + case E_CALENDAR_STATUS_REPOSITORY_OFFLINE: + e_error_run ( + GTK_WINDOW (shell_window), + "calendar:prompt-no-contents-offline-calendar", + NULL); + break; + + default: + cal_shell_sidebar_emit_client_removed ( + cal_shell_sidebar, client); + break; + } +} + +static void +cal_shell_sidebar_row_changed_cb (ECalShellSidebar *cal_shell_sidebar, + GtkTreePath *tree_path, + GtkTreeIter *tree_iter, + GtkTreeModel *tree_model) +{ + ESourceSelector *selector; + ESource *source; + + /* XXX ESourceSelector's underlying tree store has only one + * column: ESource objects. While we're not supposed to + * know this, listening for "row-changed" signals from + * the model is easier to deal with than the selector's + * "selection-changed" signal, which doesn't tell you + * _which_ row changed. */ + + selector = e_cal_shell_sidebar_get_selector (cal_shell_sidebar); + gtk_tree_model_get (tree_model, tree_iter, 0, &source, -1); + + /* XXX This signal gets emitted a lot while the model is being + * rebuilt, during which time we won't get a valid ESource. + * ESourceSelector should probably block this signal while + * rebuilding the model, but we'll be forgiving and not + * emit a warning. */ + if (!E_IS_SOURCE (source)) + return; + + if (e_source_selector_source_is_selected (selector, source)) + e_cal_shell_sidebar_add_source (cal_shell_sidebar, source); + else + e_cal_shell_sidebar_remove_source (cal_shell_sidebar, source); +} + +static void +cal_shell_sidebar_selection_changed_cb (ECalShellSidebar *cal_shell_sidebar, + ESourceSelector *selector) +{ + GSList *list, *iter; + + /* This signal is emitted less frequently than "row-changed", + * especially when the model is being rebuilt. So we'll take + * it easy on poor GConf. */ + + list = e_source_selector_get_selection (selector); + + for (iter = list; iter != NULL; iter = iter->next) { + ESource *source = iter->data; + + iter->data = (gpointer) e_source_peek_uid (source); + g_object_unref (source); + } + + calendar_config_set_calendars_selected (list); + + g_slist_free (list); +} + +static void +cal_shell_sidebar_primary_selection_changed_cb (ECalShellSidebar *cal_shell_sidebar, + ESourceSelector *selector) +{ + EShell *shell; + EShellView *shell_view; + EShellWindow *shell_window; + EShellSidebar *shell_sidebar; + EShellSettings *shell_settings; + ESource *source; + + /* XXX ESourceSelector needs a "primary-selection-uid" property + * so we can just bind the property with GConfBridge. */ + + source = e_source_selector_peek_primary_selection (selector); + if (source == NULL) + return; + + shell_sidebar = E_SHELL_SIDEBAR (cal_shell_sidebar); + shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); + shell_window = e_shell_view_get_shell_window (shell_view); + + shell = e_shell_window_get_shell (shell_window); + shell_settings = e_shell_get_shell_settings (shell); + + e_shell_settings_set_string ( + shell_settings, "cal-primary-calendar", + e_source_peek_uid (source)); +} + +static void +cal_shell_sidebar_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_MINI_CALENDAR: + g_value_set_object ( + value, e_cal_shell_sidebar_get_mini_calendar ( + E_CAL_SHELL_SIDEBAR (object))); + return; + + case PROP_SELECTOR: + g_value_set_object ( + value, e_cal_shell_sidebar_get_selector ( + E_CAL_SHELL_SIDEBAR (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +cal_shell_sidebar_dispose (GObject *object) +{ + ECalShellSidebarPrivate *priv; + + priv = E_CAL_SHELL_SIDEBAR_GET_PRIVATE (object); + + if (priv->paned != NULL) { + g_object_unref (priv->paned); + priv->paned = NULL; + } + + if (priv->selector != NULL) { + g_object_unref (priv->selector); + priv->selector = NULL; + } + + if (priv->mini_calendar != NULL) { + g_object_unref (priv->mini_calendar); + priv->mini_calendar = NULL; + } + + g_hash_table_remove_all (priv->client_table); + + if (priv->mini_calendar_config != NULL) { + g_object_unref (priv->mini_calendar_config); + priv->mini_calendar = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +cal_shell_sidebar_finalize (GObject *object) +{ + ECalShellSidebarPrivate *priv; + + priv = E_CAL_SHELL_SIDEBAR_GET_PRIVATE (object); + + g_hash_table_destroy (priv->client_table); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +cal_shell_sidebar_constructed (GObject *object) +{ + ECalShellSidebarPrivate *priv; + EShell *shell; + EShellView *shell_view; + EShellWindow *shell_window; + EShellSidebar *shell_sidebar; + EShellSettings *shell_settings; + ECalShellView *cal_shell_view; + ESourceSelector *selector; + ESourceList *source_list; + ESource *source; + ECalendarItem *calitem; + GConfBridge *bridge; + GtkTreeModel *model; + GtkWidget *container; + GtkWidget *widget; + AtkObject *a11y; + GSList *list, *iter; + const gchar *key; + gchar *uid; + + priv = E_CAL_SHELL_SIDEBAR_GET_PRIVATE (object); + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (parent_class)->constructed (object); + + shell_sidebar = E_SHELL_SIDEBAR (object); + shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); + shell_window = e_shell_view_get_shell_window (shell_view); + + shell = e_shell_window_get_shell (shell_window); + shell_settings = e_shell_get_shell_settings (shell); + + cal_shell_view = E_CAL_SHELL_VIEW (shell_view); + source_list = e_cal_shell_view_get_source_list (cal_shell_view); + + container = GTK_WIDGET (shell_sidebar); + + widget = gtk_vpaned_new (); + gtk_container_add (GTK_CONTAINER (container), widget); + priv->paned = g_object_ref (widget); + gtk_widget_show (widget); + + container = widget; + + widget = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy ( + GTK_SCROLLED_WINDOW (widget), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type ( + GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN); + gtk_paned_add1 (GTK_PANED (container), widget); + gtk_widget_show (widget); + + container = widget; + + widget = e_calendar_selector_new (source_list); + e_source_selector_set_select_new (E_SOURCE_SELECTOR (widget), TRUE); + gtk_container_add (GTK_CONTAINER (container), widget); + a11y = gtk_widget_get_accessible (widget); + atk_object_set_name (a11y, _("Calendar Selector")); + priv->selector = g_object_ref (widget); + gtk_widget_show (widget); + + container = priv->paned; + + widget = e_calendar_new (); + calitem = E_CALENDAR (widget)->calitem; + e_calendar_item_set_days_start_week_sel (calitem, 9); + e_calendar_item_set_max_days_sel (calitem, 42); + gtk_paned_add2 (GTK_PANED (container), widget); + priv->mini_calendar = g_object_ref (widget); + gtk_widget_show (widget); + + priv->mini_calendar_config = + e_mini_calendar_config_new (E_CALENDAR (widget)); + + /* Restore the selector state from the last session. */ + + selector = E_SOURCE_SELECTOR (priv->selector); + model = gtk_tree_view_get_model (GTK_TREE_VIEW (selector)); + + g_signal_connect_swapped ( + model, "row-changed", + G_CALLBACK (cal_shell_sidebar_row_changed_cb), + object); + + source = NULL; + uid = e_shell_settings_get_string ( + shell_settings, "cal-primary-calendar"); + if (uid != NULL) + source = e_source_list_peek_source_by_uid (source_list, uid); + if (source == NULL) + source = e_source_list_peek_source_any (source_list); + if (source != NULL) + e_source_selector_set_primary_selection (selector, source); + g_free (uid); + + list = calendar_config_get_calendars_selected (); + for (iter = list; iter != NULL; iter = iter->next) { + uid = iter->data; + source = e_source_list_peek_source_by_uid (source_list, uid); + g_free (uid); + + if (source == NULL) + continue; + + e_source_selector_select_source (selector, source); + } + g_slist_free (list); + + /* Listen for subsequent changes to the selector. */ + + g_signal_connect_swapped ( + selector, "selection-changed", + G_CALLBACK (cal_shell_sidebar_selection_changed_cb), + object); + + g_signal_connect_swapped ( + selector, "primary-selection-changed", + G_CALLBACK (cal_shell_sidebar_primary_selection_changed_cb), + object); + + /* Bind GObject properties to GConf keys. */ + + bridge = gconf_bridge_get (); + + object = G_OBJECT (priv->paned); + key = "/apps/evolution/calendar/display/date_navigator_vpane_position"; + gconf_bridge_bind_property_delayed (bridge, key, object, "position"); +} + +static void +cal_shell_sidebar_client_removed (ECalShellSidebar *cal_shell_sidebar, + ECal *client) +{ + ESourceSelector *selector; + GHashTable *client_table; + ESource *source; + const gchar *uid; + + client_table = cal_shell_sidebar->priv->client_table; + selector = e_cal_shell_sidebar_get_selector (cal_shell_sidebar); + + g_signal_handlers_disconnect_matched ( + client, G_SIGNAL_MATCH_DATA, 0, 0, + NULL, NULL, cal_shell_sidebar); + + source = e_cal_get_source (client); + e_source_selector_unselect_source (selector, source); + + uid = e_source_peek_uid (source); + g_hash_table_remove (client_table, uid); + + cal_shell_sidebar_emit_status_message (cal_shell_sidebar, NULL); +} + +static void +cal_shell_sidebar_class_init (ECalShellSidebarClass *class) +{ + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (ECalShellSidebarPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->get_property = cal_shell_sidebar_get_property; + object_class->dispose = cal_shell_sidebar_dispose; + object_class->finalize = cal_shell_sidebar_finalize; + object_class->constructed = cal_shell_sidebar_constructed; + + class->client_removed = cal_shell_sidebar_client_removed; + + g_object_class_install_property ( + object_class, + PROP_MINI_CALENDAR, + g_param_spec_object ( + "mini-calendar", + _("Mini-Calendar Widget"), + _("This widget displays a miniature calendar"), + E_TYPE_CALENDAR, + G_PARAM_READABLE)); + + g_object_class_install_property ( + object_class, + PROP_SELECTOR, + g_param_spec_object ( + "selector", + _("Source Selector Widget"), + _("This widget displays groups of calendars"), + E_TYPE_SOURCE_SELECTOR, + G_PARAM_READABLE)); + + signals[CLIENT_ADDED] = g_signal_new ( + "client-added", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ECalShellSidebarClass, client_added), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + E_TYPE_CAL); + + signals[CLIENT_REMOVED] = g_signal_new ( + "client-removed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ECalShellSidebarClass, client_removed), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + E_TYPE_CAL); + + signals[STATUS_MESSAGE] = g_signal_new ( + "status-message", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (ECalShellSidebarClass, status_message), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, + G_TYPE_STRING); +} + +static void +cal_shell_sidebar_init (ECalShellSidebar *cal_shell_sidebar) +{ + GHashTable *client_table; + + client_table = g_hash_table_new_full ( + g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) g_object_unref); + + cal_shell_sidebar->priv = + E_CAL_SHELL_SIDEBAR_GET_PRIVATE (cal_shell_sidebar); + + cal_shell_sidebar->priv->client_table = client_table; + + /* Postpone widget construction until we have a shell view. */ +} + +GType +e_cal_shell_sidebar_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (ECalShellSidebarClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) cal_shell_sidebar_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (ECalShellSidebar), + 0, /* n_preallocs */ + (GInstanceInitFunc) cal_shell_sidebar_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + E_TYPE_SHELL_SIDEBAR, "ECalShellSidebar", + &type_info, 0); + } + + return type; +} + +GtkWidget * +e_cal_shell_sidebar_new (EShellView *shell_view) +{ + g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); + + return g_object_new ( + E_TYPE_CAL_SHELL_SIDEBAR, + "shell-view", shell_view, NULL); +} + +GList * +e_cal_shell_sidebar_get_clients (ECalShellSidebar *cal_shell_sidebar) +{ + GHashTable *client_table; + + g_return_val_if_fail ( + E_IS_CAL_SHELL_SIDEBAR (cal_shell_sidebar), NULL); + + client_table = cal_shell_sidebar->priv->client_table; + + return g_hash_table_get_values (client_table); +} + +ECalendar * +e_cal_shell_sidebar_get_mini_calendar (ECalShellSidebar *cal_shell_sidebar) +{ + g_return_val_if_fail ( + E_IS_CAL_SHELL_SIDEBAR (cal_shell_sidebar), NULL); + + return E_CALENDAR (cal_shell_sidebar->priv->mini_calendar); +} + +ESourceSelector * +e_cal_shell_sidebar_get_selector (ECalShellSidebar *cal_shell_sidebar) +{ + g_return_val_if_fail ( + E_IS_CAL_SHELL_SIDEBAR (cal_shell_sidebar), NULL); + + return E_SOURCE_SELECTOR (cal_shell_sidebar->priv->selector); +} + +void +e_cal_shell_sidebar_add_source (ECalShellSidebar *cal_shell_sidebar, + ESource *source) +{ + ESourceSelector *selector; + GHashTable *client_table; + ECal *client; + const gchar *uid; + const gchar *uri; + gchar *message; + + g_return_if_fail (E_IS_CAL_SHELL_SIDEBAR (cal_shell_sidebar)); + g_return_if_fail (E_IS_SOURCE (source)); + + client_table = cal_shell_sidebar->priv->client_table; + selector = e_cal_shell_sidebar_get_selector (cal_shell_sidebar); + + uid = e_source_peek_uid (source); + client = g_hash_table_lookup (client_table, uid); + + if (client != NULL) + return; + + client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_EVENT); + g_return_if_fail (client != NULL); + + g_signal_connect_swapped ( + client, "backend-died", + G_CALLBACK (cal_shell_sidebar_backend_died_cb), + cal_shell_sidebar); + + g_signal_connect_swapped ( + client, "backend-error", + G_CALLBACK (cal_shell_sidebar_backend_error_cb), + cal_shell_sidebar); + + g_hash_table_insert (client_table, g_strdup (uid), client); + e_source_selector_select_source (selector, source); + + uri = e_cal_get_uri (client); + message = g_strdup_printf (_("Opening calendar at %s"), uri); + cal_shell_sidebar_emit_status_message (cal_shell_sidebar, message); + g_free (message); + + g_signal_connect_swapped ( + client, "cal-opened", + G_CALLBACK (cal_shell_sidebar_client_opened_cb), + cal_shell_sidebar); + + e_cal_open_async (client, FALSE); +} + +void +e_cal_shell_sidebar_remove_source (ECalShellSidebar *cal_shell_sidebar, + ESource *source) +{ + ESourceSelector *selector; + GHashTable *client_table; + ECal *client; + const gchar *uid; + + g_return_if_fail (E_IS_CAL_SHELL_SIDEBAR (cal_shell_sidebar)); + g_return_if_fail (E_IS_SOURCE (source)); + + client_table = cal_shell_sidebar->priv->client_table; + selector = e_cal_shell_sidebar_get_selector (cal_shell_sidebar); + + uid = e_source_peek_uid (source); + client = g_hash_table_lookup (client_table, uid); + + if (client == NULL) + return; + + cal_shell_sidebar_emit_client_removed (cal_shell_sidebar, client); +} diff --git a/calendar/modules/e-cal-shell-sidebar.h b/calendar/modules/e-cal-shell-sidebar.h new file mode 100644 index 0000000000..d77482eb64 --- /dev/null +++ b/calendar/modules/e-cal-shell-sidebar.h @@ -0,0 +1,96 @@ +/* + * e-cal-shell-sidebar.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_CAL_SHELL_SIDEBAR_H +#define E_CAL_SHELL_SIDEBAR_H + +#include <libecal/e-cal.h> +#include <libedataserverui/e-source-selector.h> + +#include <shell/e-shell-sidebar.h> +#include <shell/e-shell-view.h> +#include <widgets/misc/e-calendar.h> + +/* Standard GObject macros */ +#define E_TYPE_CAL_SHELL_SIDEBAR \ + (e_cal_shell_sidebar_get_type ()) +#define E_CAL_SHELL_SIDEBAR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_CAL_SHELL_SIDEBAR, ECalShellSidebar)) +#define E_CAL_SHELL_SIDEBAR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_CAL_SHELL_SIDEBAR, ECalShellSidebarClass)) +#define E_IS_CAL_SHELL_SIDEBAR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_CAL_SHELL_SIDEBAR)) +#define E_IS_CAL_SHELL_SIDEBAR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_CAL_SHELL_SIDEBAR)) +#define E_CAL_SHELL_SIDEBAR_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_CAL_SHELL_SIDEBAR, ECalShellSidebarClass)) + +G_BEGIN_DECLS + +typedef struct _ECalShellSidebar ECalShellSidebar; +typedef struct _ECalShellSidebarClass ECalShellSidebarClass; +typedef struct _ECalShellSidebarPrivate ECalShellSidebarPrivate; + +enum { + E_CAL_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE = 1 << 0, + E_CAL_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_EMPTY = 1 << 1, + E_CAL_SHELL_SIDEBAR_SOURCE_CAN_GO_OFFLINE = 1 << 2, + E_CAL_SHELL_SIDEBAR_SOURCE_CAN_DELETE = 1 << 3 +}; + +struct _ECalShellSidebar { + EShellSidebar parent; + ECalShellSidebarPrivate *priv; +}; + +struct _ECalShellSidebarClass { + EShellSidebarClass parent_class; + + /* Signals */ + void (*client_added) (ECalShellSidebar *cal_shell_sidebar, + ECal *client); + void (*client_removed) (ECalShellSidebar *cal_shell_sidebar, + ECal *client); + void (*status_message) (ECalShellSidebar *cal_shell_sidebar, + const gchar *status_message); +}; + +GType e_cal_shell_sidebar_get_type (void); +GtkWidget * e_cal_shell_sidebar_new (EShellView *shell_view); +GList * e_cal_shell_sidebar_get_clients (ECalShellSidebar *cal_shell_sidebar); +ECalendar * e_cal_shell_sidebar_get_mini_calendar + (ECalShellSidebar *cal_shell_sidebar); +ESourceSelector * + e_cal_shell_sidebar_get_selector(ECalShellSidebar *cal_shell_sidebar); +void e_cal_shell_sidebar_add_source (ECalShellSidebar *cal_shell_sidebar, + ESource *source); +void e_cal_shell_sidebar_remove_source + (ECalShellSidebar *cal_shell_sidebar, + ESource *source); + +G_END_DECLS + +#endif /* E_CAL_SHELL_SIDEBAR_H */ diff --git a/calendar/modules/e-cal-shell-view-actions.c b/calendar/modules/e-cal-shell-view-actions.c new file mode 100644 index 0000000000..53898ffe12 --- /dev/null +++ b/calendar/modules/e-cal-shell-view-actions.c @@ -0,0 +1,1173 @@ +/* + * e-cal-shell-view-actions.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-cal-shell-view-private.h" + +static void +action_calendar_copy_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + ECalShellSidebar *cal_shell_sidebar; + EShellWindow *shell_window; + EShellView *shell_view; + ESourceSelector *selector; + ESource *source; + + shell_view = E_SHELL_VIEW (cal_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + cal_shell_sidebar = cal_shell_view->priv->cal_shell_sidebar; + selector = e_cal_shell_sidebar_get_selector (cal_shell_sidebar); + source = e_source_selector_peek_primary_selection (selector); + g_return_if_fail (E_IS_SOURCE (source)); + + copy_source_dialog ( + GTK_WINDOW (shell_window), + source, E_CAL_SOURCE_TYPE_EVENT); +} + +static void +action_calendar_delete_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ +#if 0 + ECalShellContent *cal_shell_content; + ECalShellSidebar *cal_shell_sidebar; + EShellWindow *shell_window; + EShellView *shell_view; + ECalendarView *calendar_view; + GnomeCalendarViewType view_type; + ECalModel *model; + ESourceSelector *selector; + ESourceGroup *source_group; + ESourceList *source_list; + ESource *source; + gint response; + gchar *uri; + GError *error = NULL; + + shell_view = E_SHELL_VIEW (cal_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + cal_shell_content = cal_shell_content->priv->cal_shell_content; + view_type = e_cal_shell_content_get_current_view (cal_shell_content); + calendar_view = e_cal_shell_content_get_calendar_view ( + cal_shell_content, view_type); + model = e_calendar_view_get_model (calendar_view); + + cal_shell_sidebar = cal_shell_sidebar->priv->cal_shell_sidebar; + selector = e_cal_shell_sidebar_get_selector (cal_shell_sidebar); + source = e_source_selector_peek_primary_selection (selector); + g_return_if_fail (E_IS_SOURCE (source)); + + /* Ask for confirmation. */ + response = e_error_run ( + GTK_WINDOW (shell_window), + "calendar:prompt-delete-calendar", + e_source_peek_name (source)); + if (response != GTK_RESPONSE_YES) + return; + + uri = e_source_get_uri (source); + client = e_cal_model_get_client_for_uri (model, uri); + if (client == NULL) + client = e_cal_new_from_uri (uri, E_CAL_SOURCE_TYPE_EVENT); + g_free (uri); + + g_return_if_fail (client != NULL); + + if (!e_cal_remove (client, &error)) { + g_warning ("%s", error->message); + g_error_free (error); + return; + } + + if (e_source_selector_source_is_selected (selector, source)) { + e_cal_shell_sidebar_remove_source ( + cal_shell_sidebar, source); + e_source_selector_unselect_source (selector, source); + } + + source_group = e_source_peek_group (source); + e_source_group_remove_source (source_group, source); + + source_list = cal_shell_view->priv->source_list; + if (!e_source_list_sync (source_list, &error)) { + g_warning ("%s", error->message); + g_error_free (error); + } +#endif +} + +static void +action_calendar_go_back_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ +#if 0 + ECalShellContent *cal_shell_content; + GnomeCalendar *calendar; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + calendar = e_cal_shell_content_get_calendar (cal_shell_content); + + gnome_calendar_previous (calendar); +#endif +} + +static void +action_calendar_go_forward_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ +#if 0 + ECalShellContent *cal_shell_content; + GnomeCalendar *calendar; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + calendar = e_cal_shell_content_get_calendar (cal_shell_content); + + gnome_calendar_next (calendar); +#endif +} + +static void +action_calendar_go_today_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ +#if 0 + ECalShellContent *cal_shell_content; + GnomeCalendar *calendar; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + calendar = e_cal_shell_content_get_calendar (cal_shell_content); + + gnome_calendar_goto_today (calendar); +#endif +} + +static void +action_calendar_jump_to_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ +#if 0 + ECalShellContent *cal_shell_content; + GnomeCalendar *calendar; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + calendar = e_cal_shell_content_get_calendar (cal_shell_content); + + goto_dialog (calendar); +#endif +} + +static void +action_calendar_new_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ +#if 0 + EShellView *shell_view; + EShellWindow *shell_window; + + shell_view = E_SHELL_VIEW (cal_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + calendar_setup_new_calendar (GTK_WINDOW (shell_window)); +#endif +} + +static void +action_calendar_print_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ +#if 0 + ECalShellContent *cal_shell_content; + GnomeCalendar *calendar; + GtkPrintOperationAction print_action; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + calendar = e_cal_shell_content_get_calendar (cal_shell_content); + print_action = GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG; + + if (gnome_calendar_get_view (calendar) == GNOME_CAL_LIST_VIEW) { + ECalListView *list_view; + GtkWidget *widget; + ETable *table; + + widget = gnome_calendar_get_current_view_widget (calendar); + list_view = E_CAL_LIST_VIEW (widget); + table = e_table_scrolled_get_table (list_view->table_scrolled); + print_table (table, _("Print"), _("Calendar"), action); + } else { + time_t start; + + gnome_calendar_get_current_time_range (calendar, &start, NULL); + print_calendar (calendar, action, start); + } +#endif +} + +static void +action_calendar_print_preview_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ +#if 0 + ECalShellContent *cal_shell_content; + GnomeCalendar *calendar; + GtkPrintOperationAction print_action; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + calendar = e_cal_shell_content_get_calendar (cal_shell_content); + print_action = GTK_PRINT_OPERATION_ACTION_PREVIEW; + + if (gnome_calendar_get_view (calendar) == GNOME_CAL_LIST_VIEW) { + ECalListView *list_view; + GtkWidget *widget; + ETable *table; + + widget = gnome_calendar_get_current_view_widget (calendar); + list_view = E_CAL_LIST_VIEW (widget); + table = e_table_scrolled_get_table (list_view->table_scrolled); + print_table (table, _("Print"), _("Calendar"), action); + } else { + time_t start; + + gnome_calendar_get_current_time_range (calendar, &start, NULL); + print_calendar (calendar, action, start); + } +#endif +} + +static void +action_calendar_properties_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ +#if 0 + ECalShellSidebar *cal_shell_sidebar; + EShellView *shell_view; + EShellWindow *shell_window; + ESource *source; + ESourceSelector *selector; + + shell_view = E_SHELL_VIEW (cal_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + cal_shell_sidebar = cal_shell_view->priv->cal_shell_sidebar; + selector = e_cal_shell_sidebar_get_selector (cal_shell_sidebar); + source = e_source_selector_peek_primary_selection (selector); + g_return_if_fail (E_IS_SOURCE (source)); + + calendar_setup_edit_calendar (GTK_WINDOW (shell_window), source); +#endif +} + +static void +action_calendar_purge_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + /* FIXME */ +} + +static void +action_calendar_rename_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + ECalShellSidebar *cal_shell_sidebar; + ESourceSelector *selector; + + cal_shell_sidebar = cal_shell_view->priv->cal_shell_sidebar; + selector = e_cal_shell_sidebar_get_selector (cal_shell_sidebar); + + e_source_selector_edit_primary_selection (selector); +} + +static void +action_calendar_select_one_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + ECalShellSidebar *cal_shell_sidebar; + ESourceSelector *selector; + ESource *primary; + GSList *list, *iter; + + /* XXX ESourceSelector should provide a function for this. */ + + cal_shell_sidebar = cal_shell_view->priv->cal_shell_sidebar; + selector = e_cal_shell_sidebar_get_selector (cal_shell_sidebar); + primary = e_source_selector_peek_primary_selection (selector); + g_return_if_fail (primary != NULL); + + list = e_source_selector_get_selection (selector); + for (iter = list; iter != NULL; iter = iter->next) { + ESource *source = iter->data; + + if (source == primary) + continue; + + e_source_selector_unselect_source (selector, source); + } + e_source_selector_free_selection (list); + + e_source_selector_select_source (selector, primary); +} + +static void +action_calendar_view_cb (GtkRadioAction *action, + GtkRadioAction *current, + ECalShellView *cal_shell_view) +{ + EShellView *shell_view; + GnomeCalendarViewType view_type; + const gchar *view_id; + + shell_view = E_SHELL_VIEW (cal_shell_view); + view_type = gtk_radio_action_get_current_value (action); + + switch (view_type) { + case GNOME_CAL_DAY_VIEW: + view_id = "Day_View"; + break; + + case GNOME_CAL_WORK_WEEK_VIEW: + view_id = "Work_Week_View"; + break; + + case GNOME_CAL_WEEK_VIEW: + view_id = "Week_View"; + break; + + case GNOME_CAL_MONTH_VIEW: + view_id = "Month_View"; + break; + + case GNOME_CAL_LIST_VIEW: + view_id = "List_View"; + break; + + default: + g_return_if_reached (); + } + + e_shell_view_set_view_id (shell_view, view_id); +} + +static void +action_event_all_day_new_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + /* FIXME */ +} + +static void +action_event_clipboard_copy_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + ECalShellContent *cal_shell_content; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + e_cal_shell_content_copy_clipboard (cal_shell_content); +} + +static void +action_event_clipboard_cut_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + ECalShellContent *cal_shell_content; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + e_cal_shell_content_cut_clipboard (cal_shell_content); +} + +static void +action_event_clipboard_paste_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + ECalShellContent *cal_shell_content; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + e_cal_shell_content_paste_clipboard (cal_shell_content); +} + +static void +action_event_copy_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + /* FIXME */ +} + +static void +action_event_delegate_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + /* FIXME */ +} + +static void +action_event_delete_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + ECalShellContent *cal_shell_content; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + e_cal_shell_content_delete_selection (cal_shell_content); +} + +static void +action_event_delete_occurrence_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + ECalShellContent *cal_shell_content; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + e_cal_shell_content_delete_selected_occurrence (cal_shell_content); +} + +static void +action_event_delete_occurrence_all_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + ECalShellContent *cal_shell_content; + + /* XXX Same as "event-delete". */ + cal_shell_content = cal_shell_view->priv->cal_shell_content; + e_cal_shell_content_delete_selection (cal_shell_content); +} + +static void +action_event_forward_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + /* FIXME */ +} + +static void +action_event_meeting_new_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + /* FIXME */ +} + +static void +action_event_move_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + /* FIXME */ +} + +static void +action_event_new_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + /* FIXME */ +} + +static void +action_event_occurrence_movable_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + /* FIXME */ +} + +static void +action_event_open_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ +#if 0 + ECalShellContent *cal_shell_content; + GnomeCalendar *calendar; + GtkWidget *widget; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + calendar = e_cal_shell_content_get_calendar (cal_shell_content); + widget = gnome_calendar_get_current_view_widget (calendar); + + e_calendar_view_open_event (E_CALENDAR_VIEW (widget)); +#endif +} + +static void +action_event_print_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + /* FIXME */ +} + +static void +action_event_reply_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + /* FIXME */ +} + +static void +action_event_reply_all_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + /* FIXME */ +} + +static void +action_event_save_as_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + /* FIXME */ +} + +static void +action_event_schedule_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + /* FIXME */ +} + +static void +action_gal_save_custom_view_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + ECalShellContent *cal_shell_content; + EShellView *shell_view; + GalViewInstance *view_instance; + + /* All shell views respond to the activation of this action, + * which is defined by EShellWindow. But only the currently + * active shell view proceeds with saving the custom view. */ + shell_view = E_SHELL_VIEW (cal_shell_view); + if (!e_shell_view_is_active (shell_view)) + return; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + view_instance = e_cal_shell_content_get_view_instance (cal_shell_content); + gal_view_instance_save_as (view_instance); +} + +static void +action_search_execute_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + EShellView *shell_view; + + /* All shell views respond to the activation of this action, + * which is defined by EShellWindow. But only the currently + * active shell view proceeds with executing the search. */ + shell_view = E_SHELL_VIEW (cal_shell_view); + if (!e_shell_view_is_active (shell_view)) + return; + + e_cal_shell_view_execute_search (cal_shell_view); +} + +static void +action_search_filter_cb (GtkRadioAction *action, + GtkRadioAction *current, + ECalShellView *cal_shell_view) +{ + e_cal_shell_view_execute_search (cal_shell_view); +} + +static GtkActionEntry calendar_entries[] = { + + { "calendar-copy", + GTK_STOCK_COPY, + N_("_Copy..."), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_calendar_copy_cb) }, + + { "calendar-delete", + GTK_STOCK_DELETE, + NULL, + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_calendar_delete_cb) }, + + { "calendar-go-back", + GTK_STOCK_GO_BACK, + N_("Previous"), + NULL, + N_("Go Back"), + G_CALLBACK (action_calendar_go_back_cb) }, + + { "calendar-go-forward", + GTK_STOCK_GO_FORWARD, + N_("Next"), + NULL, + N_("Go Forward"), + G_CALLBACK (action_calendar_go_forward_cb) }, + + { "calendar-go-today", + "go-today", + N_("Select _Today"), + "<Control>t", + N_("Select today"), + G_CALLBACK (action_calendar_go_today_cb) }, + + { "calendar-jump-to", + GTK_STOCK_JUMP_TO, + N_("Select _Date"), + "<Control>g", + N_("Select a specific date"), + G_CALLBACK (action_calendar_jump_to_cb) }, + + { "calendar-new", + "x-office-calendar", + N_("_New Calendar"), + NULL, + N_("Create a new calendar"), + G_CALLBACK (action_calendar_new_cb) }, + + { "calendar-properties", + GTK_STOCK_PROPERTIES, + NULL, + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_calendar_properties_cb) }, + + { "calendar-purge", + NULL, + N_("Purg_e"), + "<Control>e", + N_("Purge old appointments and meetings"), + G_CALLBACK (action_calendar_purge_cb) }, + + { "calendar-rename", + NULL, + N_("_Rename..."), + "F2", + N_("Rename the selected calendar"), + G_CALLBACK (action_calendar_rename_cb) }, + + { "calendar-select-one", + "stock_check-filled", + N_("Show _Only This Calendar"), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_calendar_select_one_cb) }, + + { "event-clipboard-copy", + GTK_STOCK_COPY, + NULL, + NULL, + N_("Copy the selection"), + G_CALLBACK (action_event_clipboard_copy_cb) }, + + { "event-clipboard-cut", + GTK_STOCK_CUT, + NULL, + NULL, + N_("Cut the selection"), + G_CALLBACK (action_event_clipboard_cut_cb) }, + + { "event-clipboard-paste", + GTK_STOCK_PASTE, + NULL, + NULL, + N_("Paste the clipboard"), + G_CALLBACK (action_event_clipboard_paste_cb) }, + + { "event-copy", + NULL, + N_("Cop_y to Calendar..."), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_event_copy_cb) }, + + { "event-delegate", + NULL, + N_("_Delegate Meeting..."), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_event_delegate_cb) }, + + { "event-delete", + GTK_STOCK_DELETE, + NULL, + NULL, + N_("Delete the appointment"), + G_CALLBACK (action_event_delete_cb) }, + + { "event-delete-occurrence", + GTK_STOCK_DELETE, + N_("Delete This _Occurrence"), + NULL, + N_("Delete this occurrence"), + G_CALLBACK (action_event_delete_occurrence_cb) }, + + { "event-delete-occurrence-all", + GTK_STOCK_DELETE, + N_("Delete _All Occurrences"), + NULL, + N_("Delete all occurrences"), + G_CALLBACK (action_event_delete_occurrence_all_cb) }, + + { "event-all-day-new", + NULL, + N_("New All Day _Event..."), + NULL, + N_("Create a new all day event"), + G_CALLBACK (action_event_all_day_new_cb) }, + + { "event-forward", + "mail-forward", + N_("_Forward as iCalendar..."), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_event_forward_cb) }, + + { "event-meeting-new", + NULL, + N_("New _Meeting..."), + NULL, + N_("Create a new meeting"), + G_CALLBACK (action_event_meeting_new_cb) }, + + { "event-move", + NULL, + N_("Mo_ve to Calendar..."), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_event_move_cb) }, + + { "event-new", + NULL, + N_("New _Appointment..."), + NULL, + N_("Create a new appointment"), + G_CALLBACK (action_event_new_cb) }, + + { "event-occurrence-movable", + NULL, + N_("Make this Occurrence _Movable"), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_event_occurrence_movable_cb) }, + + { "event-open", + NULL, + N_("_Open Appointment"), + "<Control>o", + N_("View the current appointment"), + G_CALLBACK (action_event_open_cb) }, + + { "event-reply", + "mail-reply-sender", + N_("_Reply"), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_event_reply_cb) }, + + { "event-reply-all", + "mail-reply-all", + N_("Reply to _All"), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_event_reply_all_cb) }, + + { "event-save-as", + GTK_STOCK_SAVE_AS, + NULL, + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_event_save_as_cb) }, + + { "event-schedule", + NULL, + N_("_Schedule Meeting..."), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_event_schedule_cb) }, + + /*** Menus ***/ + + { "calendar-actions-menu", + NULL, + N_("_Actions"), + NULL, + NULL, + NULL } +}; + +static EPopupActionEntry calendar_popup_entries[] = { + + /* FIXME No equivalent main menu items for the any of the calendar + * popup menu items and for many of the event popup menu items. + * This is an accessibility issue. */ + + { "calendar-popup-copy", + NULL, + "calendar-copy" }, + + { "calendar-popup-delete", + NULL, + "calendar-delete" }, + + { "calendar-popup-go-today", + NULL, + "calendar-go-today" }, + + { "calendar-popup-jump-to", + NULL, + "calendar-jump-to" }, + + { "calendar-popup-properties", + NULL, + "calendar-properties" }, + + { "calendar-popup-rename", + NULL, + "calendar-rename" }, + + { "calendar-popup-select-one", + NULL, + "calendar-select-one" }, + + { "event-popup-clipboard-copy", + NULL, + "event-clipboard-copy" }, + + { "event-popup-clipboard-cut", + NULL, + "event-clipboard-cut" }, + + { "event-popup-clipboard-paste", + NULL, + "event-clipboard-paste" }, + + { "event-popup-copy", + NULL, + "event-copy" }, + + { "event-popup-delegate", + NULL, + "event-delegate" }, + + { "event-popup-delete", + NULL, + "event-delete" }, + + { "event-popup-delete-occurrence", + NULL, + "event-delete-occurrence" }, + + { "event-popup-delete-occurrence-all", + NULL, + "event-delete-occurrence-all" }, + + { "event-popup-forward", + NULL, + "event-forward" }, + + { "event-popup-move", + NULL, + "event-move" }, + + { "event-popup-occurrence-movable", + NULL, + "event-occurrence-movable" }, + + { "event-popup-open", + NULL, + "event-open" }, + + { "event-popup-reply", + NULL, + "event-reply" }, + + { "event-popup-reply-all", + NULL, + "event-reply-all" }, + + { "event-popup-save-as", + NULL, + "event-save-as" }, + + { "event-popup-schedule", + NULL, + "event-schedule" } +}; + +static GtkRadioActionEntry calendar_view_entries[] = { + + { "calendar-view-day", + "view-calendar-day", + N_("Day"), + NULL, + N_("Show one day"), + GNOME_CAL_DAY_VIEW }, + + { "calendar-view-list", + "view-calendar-list", + N_("List"), + NULL, + N_("Show as list"), + GNOME_CAL_LIST_VIEW }, + + { "calendar-view-month", + "view-calendar-month", + N_("Month"), + NULL, + N_("Show one month"), + GNOME_CAL_MONTH_VIEW }, + + { "calendar-view-week", + "view-calendar-week", + N_("Week"), + NULL, + N_("Show one week"), + GNOME_CAL_WEEK_VIEW }, + + { "calendar-view-workweek", + "view-calendar-workweek", + N_("Work Week"), + NULL, + N_("Show one work week"), + GNOME_CAL_WORK_WEEK_VIEW } +}; + +static GtkRadioActionEntry calendar_filter_entries[] = { + + { "calendar-filter-active-appointments", + NULL, + N_("Active Appointements"), + NULL, + NULL, /* XXX Add a tooltip! */ + CALENDAR_FILTER_ACTIVE_APPOINTMENTS }, + + { "calendar-filter-any-category", + NULL, + N_("Any Category"), + NULL, + NULL, /* XXX Add a tooltip! */ + CALENDAR_FILTER_ANY_CATEGORY }, + + { "calendar-filter-next-7-days-appointments", + NULL, + N_("Next 7 Days' Appointments"), + NULL, + NULL, /* XXX Add a tooltip! */ + CALENDAR_FILTER_NEXT_7_DAYS_APPOINTMENTS }, + + { "calendar-filter-unmatched", + NULL, + N_("Unmatched"), + NULL, + NULL, /* XXX Add a tooltip! */ + CALENDAR_FILTER_UNMATCHED } +}; + +static GtkRadioActionEntry calendar_search_entries[] = { + + { "calendar-search-any-field-contains", + NULL, + N_("Any field contains"), + NULL, + NULL, /* XXX Add a tooltip! */ + CALENDAR_SEARCH_ANY_FIELD_CONTAINS }, + + { "calendar-search-description-contains", + NULL, + N_("Description contains"), + NULL, + NULL, /* XXX Add a tooltip! */ + CALENDAR_SEARCH_DESCRIPTION_CONTAINS }, + + { "calendar-search-summary-contains", + NULL, + N_("Summary contains"), + NULL, + NULL, /* XXX Add a tooltip! */ + CALENDAR_SEARCH_SUMMARY_CONTAINS } +}; + +static GtkActionEntry lockdown_printing_entries[] = { + + { "calendar-print", + GTK_STOCK_PRINT, + NULL, + "<Control>p", + N_("Print this calendar"), + G_CALLBACK (action_calendar_print_cb) }, + + { "calendar-print-preview", + GTK_STOCK_PRINT_PREVIEW, + NULL, + NULL, + N_("Preview the calendar to be printed"), + G_CALLBACK (action_calendar_print_preview_cb) }, + + { "event-print", + GTK_STOCK_PRINT, + NULL, + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_event_print_cb) } +}; + +static EPopupActionEntry lockdown_printing_popup_entries[] = { + + { "event-popup-print", + NULL, + "event-print" } +}; + +void +e_cal_shell_view_actions_init (ECalShellView *cal_shell_view) +{ + EShellView *shell_view; + EShellWindow *shell_window; + GtkActionGroup *action_group; + GtkAction *action; + + shell_view = E_SHELL_VIEW (cal_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + /* Calendar Actions */ + action_group = ACTION_GROUP (CALENDAR); + gtk_action_group_add_actions ( + action_group, calendar_entries, + G_N_ELEMENTS (calendar_entries), cal_shell_view); + e_action_group_add_popup_actions ( + action_group, calendar_popup_entries, + G_N_ELEMENTS (calendar_popup_entries)); + gtk_action_group_add_radio_actions ( + action_group, calendar_view_entries, + G_N_ELEMENTS (calendar_view_entries), GNOME_CAL_DAY_VIEW, + G_CALLBACK (action_calendar_view_cb), cal_shell_view); + gtk_action_group_add_radio_actions ( + action_group, calendar_search_entries, + G_N_ELEMENTS (calendar_search_entries), + CALENDAR_SEARCH_SUMMARY_CONTAINS, + NULL, NULL); + + /* Lockdown Printing Actions */ + action_group = ACTION_GROUP (LOCKDOWN_PRINTING); + gtk_action_group_add_actions ( + action_group, lockdown_printing_entries, + G_N_ELEMENTS (lockdown_printing_entries), cal_shell_view); + e_action_group_add_popup_actions ( + action_group, lockdown_printing_popup_entries, + G_N_ELEMENTS (lockdown_printing_popup_entries)); + + /* Fine tuning. */ + + action = ACTION (CALENDAR_GO_TODAY); + g_object_set (action, "short-label", _("Today"), NULL); + + action = ACTION (CALENDAR_JUMP_TO); + g_object_set (action, "short-label", _("Go To"), NULL); + + action = ACTION (EVENT_DELETE); + g_object_set (action, "short-label", _("Delete"), NULL); + + g_signal_connect ( + ACTION (GAL_SAVE_CUSTOM_VIEW), "activate", + G_CALLBACK (action_gal_save_custom_view_cb), cal_shell_view); + + g_signal_connect ( + ACTION (SEARCH_EXECUTE), "activate", + G_CALLBACK (action_search_execute_cb), cal_shell_view); + + /* Initialize the memo and task pad actions. */ + e_cal_shell_view_memopad_actions_init (cal_shell_view); + e_cal_shell_view_taskpad_actions_init (cal_shell_view); +} + +void +e_cal_shell_view_update_search_filter (ECalShellView *cal_shell_view) +{ + EShellContent *shell_content; + EShellWindow *shell_window; + EShellView *shell_view; + GtkActionGroup *action_group; + GtkRadioAction *radio_action; + GList *list, *iter; + GSList *group; + gint ii; + + shell_view = E_SHELL_VIEW (cal_shell_view); + shell_content = e_shell_view_get_shell_content (shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + action_group = ACTION_GROUP (CALENDAR_FILTER); + e_action_group_remove_all_actions (action_group); + + /* Add the standard filter actions. */ + gtk_action_group_add_radio_actions ( + action_group, calendar_filter_entries, + G_N_ELEMENTS (calendar_filter_entries), + CALENDAR_FILTER_ANY_CATEGORY, + G_CALLBACK (action_search_filter_cb), + cal_shell_view); + + /* Retrieve the radio group from an action we just added. */ + list = gtk_action_group_list_actions (action_group); + radio_action = GTK_RADIO_ACTION (list->data); + group = gtk_radio_action_get_group (radio_action); + g_list_free (list); + + /* Build the category actions. */ + + list = e_categories_get_list (); + for (iter = list, ii = 0; iter != NULL; iter = iter->next, ii++) { + const gchar *category_name = iter->data; + const gchar *filename; + GtkAction *action; + gchar *action_name; + + action_name = g_strdup_printf ( + "calendar-filter-category-%d", ii); + radio_action = gtk_radio_action_new ( + action_name, category_name, NULL, NULL, ii); + g_free (action_name); + + /* Convert the category icon file to a themed icon name. */ + filename = e_categories_get_icon_file_for (category_name); + if (filename != NULL && *filename != '\0') { + gchar *basename; + gchar *cp; + + basename = g_path_get_basename (filename); + + /* Lose the file extension. */ + if ((cp = strrchr (basename, '.')) != NULL) + *cp = '\0'; + + g_object_set ( + radio_action, "icon-name", basename, NULL); + + g_free (basename); + } + + gtk_radio_action_set_group (radio_action, group); + group = gtk_radio_action_get_group (radio_action); + + /* The action group takes ownership of the action. */ + action = GTK_ACTION (radio_action); + gtk_action_group_add_action (action_group, action); + g_object_unref (radio_action); + } + g_list_free (list); + + /* Use any action in the group; doesn't matter which. */ + e_shell_content_set_filter_action (shell_content, radio_action); + + ii = CALENDAR_FILTER_UNMATCHED; + e_shell_content_add_filter_separator_after (shell_content, ii); + + ii = CALENDAR_FILTER_NEXT_7_DAYS_APPOINTMENTS; + e_shell_content_add_filter_separator_after (shell_content, ii); +} diff --git a/calendar/modules/e-cal-shell-view-actions.h b/calendar/modules/e-cal-shell-view-actions.h new file mode 100644 index 0000000000..1ad6aa7d51 --- /dev/null +++ b/calendar/modules/e-cal-shell-view-actions.h @@ -0,0 +1,153 @@ +/* + * e-cal-shell-view-actions.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_CAL_SHELL_VIEW_ACTIONS_H +#define E_CAL_SHELL_VIEW_ACTIONS_H + +#include <shell/e-shell-window-actions.h> + +/* Calendar Actions */ +#define E_SHELL_WINDOW_ACTION_CALENDAR_COPY(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-copy") +#define E_SHELL_WINDOW_ACTION_CALENDAR_DELETE(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-delete") +#define E_SHELL_WINDOW_ACTION_CALENDAR_GO_BACK(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-go-back") +#define E_SHELL_WINDOW_ACTION_CALENDAR_GO_FORWARD(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-go-forward") +#define E_SHELL_WINDOW_ACTION_CALENDAR_GO_TODAY(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-go-today") +#define E_SHELL_WINDOW_ACTION_CALENDAR_JUMP_TO(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-jump-to") +#define E_SHELL_WINDOW_ACTION_CALENDAR_NEW(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-new") +#define E_SHELL_WINDOW_ACTION_CALENDAR_PRINT(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-print") +#define E_SHELL_WINDOW_ACTION_CALENDAR_PRINT_PREVIEW(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-print-preview") +#define E_SHELL_WINDOW_ACTION_CALENDAR_PROPERTIES(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-properties") +#define E_SHELL_WINDOW_ACTION_CALENDAR_PURGE(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-purge") +#define E_SHELL_WINDOW_ACTION_CALENDAR_RENAME(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-rename") +#define E_SHELL_WINDOW_ACTION_CALENDAR_SELECT_ONE(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-select-one") +#define E_SHELL_WINDOW_ACTION_CALENDAR_VIEW_DAY(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-view-day") +#define E_SHELL_WINDOW_ACTION_CALENDAR_VIEW_LIST(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-view-list") +#define E_SHELL_WINDOW_ACTION_CALENDAR_VIEW_MONTH(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-view-month") +#define E_SHELL_WINDOW_ACTION_CALENDAR_VIEW_WEEK(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-view-week") +#define E_SHELL_WINDOW_ACTION_CALENDAR_VIEW_WORKWEEK(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-view-workweek") + +/* Event Actions */ +#define E_SHELL_WINDOW_ACTION_EVENT_CLIPBOARD_COPY(window) \ + E_SHELL_WINDOW_ACTION ((window), "event-clipboard-copy") +#define E_SHELL_WINDOW_ACTION_EVENT_CLIPBOARD_CUT(window) \ + E_SHELL_WINDOW_ACTION ((window), "event-clipboard-cut") +#define E_SHELL_WINDOW_ACTION_EVENT_CLIPBOARD_PASTE(window) \ + E_SHELL_WINDOW_ACTION ((window), "event-clipboard-paste") +#define E_SHELL_WINDOW_ACTION_EVENT_DELETE(window) \ + E_SHELL_WINDOW_ACTION ((window), "event-delete") +#define E_SHELL_WINDOW_ACTION_EVENT_DELETE_OCCURRENCE(window) \ + E_SHELL_WINDOW_ACTION ((window), "event-delete-occurrence") +#define E_SHELL_WINDOW_ACTION_EVENT_DELETE_OCCURRENCE_ALL(window) \ + E_SHELL_WINDOW_ACTION ((window), "event-delete-occurrence-all") +#define E_SHELL_WINDOW_ACTION_EVENT_OPEN(window) \ + E_SHELL_WINDOW_ACTION ((window), "event-open") + +/* Memo Pad Actions */ +#define E_SHELL_WINDOW_ACTION_CALENDAR_MEMOPAD_CLIPBOARD_COPY(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-memopad-clipboard-copy") +#define E_SHELL_WINDOW_ACTION_CALENDAR_MEMOPAD_CLIPBOARD_CUT(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-memopad-clipboard-cut") +#define E_SHELL_WINDOW_ACTION_CALENDAR_MEMOPAD_CLIPBOARD_PASTE(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-memopad-clipboard-paste") +#define E_SHELL_WINDOW_ACTION_CALENDAR_MEMOPAD_DELETE(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-memopad-delete") +#define E_SHELL_WINDOW_ACTION_CALENDAR_MEMOPAD_FORWARD(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-memopad-forward") +#define E_SHELL_WINDOW_ACTION_CALENDAR_MEMOPAD_NEW(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-memopad-new") +#define E_SHELL_WINDOW_ACTION_CALENDAR_MEMOPAD_OPEN(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-memopad-open") +#define E_SHELL_WINDOW_ACTION_CALENDAR_MEMOPAD_OPEN_URL(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-memopad-open-url") +#define E_SHELL_WINDOW_ACTION_CALENDAR_MEMOPAD_PRINT(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-memopad-print") +#define E_SHELL_WINDOW_ACTION_CALENDAR_MEMOPAD_SAVE_AS(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-memopad-save-as") + +/* Task Pad Actions */ +#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_ASSIGN(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-assign") +#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_CLIPBOARD_COPY(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-clipboard-copy") +#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_CLIPBOARD_CUT(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-clipboard-cut") +#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_CLIPBOARD_PASTE(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-clipboard-paste") +#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_DELETE(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-delete") +#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_FORWARD(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-forward") +#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_MARK_COMPLETE(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-mark-complete") +#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_MARK_INCOMPLETE(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-mark-incomplete") +#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_NEW(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-new") +#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_OPEN(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-open") +#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_OPEN_URL(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-open-url") +#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_PRINT(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-print") +#define E_SHELL_WINDOW_ACTION_CALENDAR_TASKPAD_SAVE_AS(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-taskpad-save-as") + +/* Calendar Query Actions */ +#define E_SHELL_WINDOW_ACTION_CALENDAR_FILTER_ACTIVE_APPOINTMENTS(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-filter-active-appointments") +#define E_SHELL_WINDOW_ACTION_CALENDAR_FILTER_ANY_CATEGORY(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-filter-any-category") +#define E_SHELL_WINDOW_ACTION_CALENDAR_FILTER_NEXT_7_DAYS_APPOINTMENTS(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-filter-next-7-days-appointments") +#define E_SHELL_WINDOW_ACTION_CALENDAR_FILTER_UNMATCHED(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-filter-unmatched") +#define E_SHELL_WINDOW_ACTION_CALENDAR_SEARCH_ANY_FIELD_CONTAINS(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-search-any-field-contains") +#define E_SHELL_WINDOW_ACTION_CALENDAR_SEARCH_DESCRIPTION_CONTAINS(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-search-description-contains") +#define E_SHELL_WINDOW_ACTION_CALENDAR_SEARCH_SUMMARY_CONTAINS(window) \ + E_SHELL_WINDOW_ACTION ((window), "calendar-search-summary-contains") + +/* Action Groups */ +#define E_SHELL_WINDOW_ACTION_GROUP_CALENDAR(window) \ + E_SHELL_WINDOW_ACTION_GROUP ((window), "calendar") +#define E_SHELL_WINDOW_ACTION_GROUP_CALENDAR_FILTER(window) \ + E_SHELL_WINDOW_ACTION_GROUP ((window), "calendar-filter") + +#endif /* E_CAL_SHELL_VIEW_ACTIONS_H */ diff --git a/calendar/modules/e-cal-shell-view-memopad.c b/calendar/modules/e-cal-shell-view-memopad.c new file mode 100644 index 0000000000..dbde52d1eb --- /dev/null +++ b/calendar/modules/e-cal-shell-view-memopad.c @@ -0,0 +1,526 @@ +/* + * e-cal-shell-view-memopad.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-cal-shell-view-private.h" + +/* Much of this file is based on e-memo-shell-view-actions.c. */ + +static void +action_calendar_memopad_clipboard_copy_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + ECalShellContent *cal_shell_content; + EMemoTable *memo_table; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + memo_table = e_cal_shell_content_get_memo_table (cal_shell_content); + + e_memo_table_copy_clipboard (memo_table); +} + +static void +action_calendar_memopad_clipboard_cut_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + ECalShellContent *cal_shell_content; + EMemoTable *memo_table; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + memo_table = e_cal_shell_content_get_memo_table (cal_shell_content); + + e_memo_table_cut_clipboard (memo_table); +} + +static void +action_calendar_memopad_clipboard_paste_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + ECalShellContent *cal_shell_content; + EMemoTable *memo_table; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + memo_table = e_cal_shell_content_get_memo_table (cal_shell_content); + + e_memo_table_paste_clipboard (memo_table); +} + +static void +action_calendar_memopad_delete_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + ECalShellContent *cal_shell_content; + EMemoTable *memo_table; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + memo_table = e_cal_shell_content_get_memo_table (cal_shell_content); + + e_cal_shell_view_memopad_set_status_message ( + cal_shell_view, _("Deleting selected memos..."), -1.0); + e_memo_table_delete_selected (memo_table); + e_cal_shell_view_memopad_set_status_message ( + cal_shell_view, NULL, -1.0); +} + +static void +action_calendar_memopad_forward_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + ECalShellContent *cal_shell_content; + EMemoTable *memo_table; + ECalModelComponent *comp_data; + ECalComponent *comp; + icalcomponent *clone; + GSList *list; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + memo_table = e_cal_shell_content_get_memo_table (cal_shell_content); + + list = e_memo_table_get_selected (memo_table); + g_return_if_fail (list != NULL); + comp_data = list->data; + g_slist_free (list); + + /* XXX We only forward the first selected memo. */ + comp = e_cal_component_new (); + clone = icalcomponent_new_clone (comp_data->icalcomp); + e_cal_component_set_icalcomponent (comp, clone); + itip_send_comp ( + E_CAL_COMPONENT_METHOD_PUBLISH, comp, + comp_data->client, NULL, NULL, NULL, TRUE); + g_object_unref (comp); +} + +static void +action_calendar_memopad_new_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + EShell *shell; + EShellView *shell_view; + EShellWindow *shell_window; + ECalShellContent *cal_shell_content; + EMemoTable *memo_table; + ECalModelComponent *comp_data; + ECal *client; + ECalComponent *comp; + CompEditor *editor; + GSList *list; + + shell_view = E_SHELL_VIEW (cal_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + shell = e_shell_window_get_shell (shell_window); + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + memo_table = e_cal_shell_content_get_memo_table (cal_shell_content); + + list = e_memo_table_get_selected (memo_table); + g_return_if_fail (list != NULL); + comp_data = list->data; + g_slist_free (list); + + client = comp_data->client; + editor = memo_editor_new (client, shell, COMP_EDITOR_NEW_ITEM); + comp = cal_comp_memo_new_with_defaults (client); + comp_editor_edit_comp (editor, comp); + + gtk_window_present (GTK_WINDOW (editor)); + + g_object_unref (comp); + g_object_unref (client); +} + +static void +action_calendar_memopad_open_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + ECalShellContent *cal_shell_content; + EMemoTable *memo_table; + ECalModelComponent *comp_data; + GSList *list; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + memo_table = e_cal_shell_content_get_memo_table (cal_shell_content); + + list = e_memo_table_get_selected (memo_table); + g_return_if_fail (list != NULL); + comp_data = list->data; + g_slist_free (list); + + /* XXX We only open the first selected memo. */ + e_cal_shell_view_memopad_open_memo (cal_shell_view, comp_data); +} + +static void +action_calendar_memopad_open_url_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + EShellView *shell_view; + EShellWindow *shell_window; + ECalShellContent *cal_shell_content; + EMemoTable *memo_table; + ECalModelComponent *comp_data; + icalproperty *prop; + const gchar *uri; + GSList *list; + + shell_view = E_SHELL_VIEW (cal_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + memo_table = e_cal_shell_content_get_memo_table (cal_shell_content); + + list = e_memo_table_get_selected (memo_table); + g_return_if_fail (list != NULL); + comp_data = list->data; + g_slist_free (list); + + /* XXX We only open the URI of the first selected memo. */ + prop = icalcomponent_get_first_property ( + comp_data->icalcomp, ICAL_URL_PROPERTY); + g_return_if_fail (prop == NULL); + + uri = icalproperty_get_url (prop); + e_show_uri (GTK_WINDOW (shell_window), uri); +} + +static void +action_calendar_memopad_print_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + ECalShellContent *cal_shell_content; + EMemoTable *memo_table; + ECalModelComponent *comp_data; + ECalComponent *comp; + icalcomponent *clone; + GtkPrintOperationAction print_action; + GSList *list; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + memo_table = e_cal_shell_content_get_memo_table (cal_shell_content); + + list = e_memo_table_get_selected (memo_table); + g_return_if_fail (list != NULL); + comp_data = list->data; + g_slist_free (list); + + /* XXX We only print the first selected memo. */ + comp = e_cal_component_new (); + clone = icalcomponent_new_clone (comp_data->icalcomp); + print_action = GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG; + e_cal_component_set_icalcomponent (comp, clone); + print_comp (comp, comp_data->client, print_action); + g_object_unref (comp); +} + +static void +action_calendar_memopad_save_as_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + ECalShellContent *cal_shell_content; + EMemoTable *memo_table; + ECalModelComponent *comp_data; + GSList *list; + gchar *filename; + gchar *string; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + memo_table = e_cal_shell_content_get_memo_table (cal_shell_content); + + list = e_memo_table_get_selected (memo_table); + g_return_if_fail (list != NULL); + comp_data = list->data; + g_slist_free (list); + + filename = e_file_dialog_save (_("Save as..."), NULL); + if (filename == NULL) + return; + + /* XXX We only save the first selected memo. */ + string = e_cal_get_component_as_string ( + comp_data->client, comp_data->icalcomp); + if (string == NULL) { + g_warning ("Could not convert memo to a string."); + return; + } + + e_write_file_uri (filename, string); + + g_free (filename); + g_free (string); +} + +static GtkActionEntry calendar_memopad_entries[] = { + + { "calendar-memopad-clipboard-copy", + GTK_STOCK_COPY, + NULL, + NULL, + N_("Copy selected memo"), + G_CALLBACK (action_calendar_memopad_clipboard_copy_cb) }, + + { "calendar-memopad-clipboard-cut", + GTK_STOCK_CUT, + NULL, + NULL, + N_("Cut selected memo"), + G_CALLBACK (action_calendar_memopad_clipboard_cut_cb) }, + + { "calendar-memopad-clipboard-paste", + GTK_STOCK_PASTE, + NULL, + NULL, + N_("Paste memo from the clipboard"), + G_CALLBACK (action_calendar_memopad_clipboard_paste_cb) }, + + { "calendar-memopad-delete", + GTK_STOCK_DELETE, + N_("_Delete Memo"), + NULL, + N_("Delete selected memos"), + G_CALLBACK (action_calendar_memopad_delete_cb) }, + + { "calendar-memopad-forward", + "mail-forward", + N_("_Forward as iCalendar..."), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_calendar_memopad_forward_cb) }, + + { "calendar-memopad-new", + "stock_insert-note", + N_("New _Memo"), + NULL, + N_("Create a new memo"), + G_CALLBACK (action_calendar_memopad_new_cb) }, + + { "calendar-memopad-open", + GTK_STOCK_OPEN, + N_("_Open Memo"), + NULL, + N_("View the selected memo"), + G_CALLBACK (action_calendar_memopad_open_cb) }, + + { "calendar-memopad-open-url", + "applications-internet", + N_("Open _Web Page"), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_calendar_memopad_open_url_cb) }, + + { "calendar-memopad-save-as", + GTK_STOCK_SAVE_AS, + NULL, + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_calendar_memopad_save_as_cb) } +}; + +static GtkActionEntry lockdown_printing_entries[] = { + + { "calendar-memopad-print", + GTK_STOCK_PRINT, + NULL, + NULL, + N_("Print the selected memo"), + G_CALLBACK (action_calendar_memopad_print_cb) } +}; + +void +e_cal_shell_view_memopad_actions_init (ECalShellView *cal_shell_view) +{ + EShellView *shell_view; + EShellWindow *shell_window; + GtkActionGroup *action_group; + + shell_view = E_SHELL_VIEW (cal_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + /* Calendar Actions */ + action_group = ACTION_GROUP (CALENDAR); + gtk_action_group_add_actions ( + action_group, calendar_memopad_entries, + G_N_ELEMENTS (calendar_memopad_entries), cal_shell_view); + + /* Lockdown Printing Actions */ + action_group = ACTION_GROUP (LOCKDOWN_PRINTING); + gtk_action_group_add_actions ( + action_group, lockdown_printing_entries, + G_N_ELEMENTS (lockdown_printing_entries), cal_shell_view); +} + +void +e_cal_shell_view_memopad_actions_update (ECalShellView *cal_shell_view) +{ + ECalShellContent *cal_shell_content; + EShellWindow *shell_window; + EShellView *shell_view; + EMemoTable *memo_table; + ETable *table; + GtkAction *action; + GSList *list, *iter; + const gchar *label; + gboolean editable = TRUE; + gboolean has_url = FALSE; + gboolean sensitive; + gint n_selected; + + shell_view = E_SHELL_VIEW (cal_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + memo_table = e_cal_shell_content_get_memo_table (cal_shell_content); + + table = e_memo_table_get_table (memo_table); + n_selected = e_table_selected_count (table); + + list = e_memo_table_get_selected (memo_table); + for (iter = list; iter != NULL; iter = iter->next) { + ECalModelComponent *comp_data = iter->data; + icalproperty *prop; + gboolean read_only; + + e_cal_is_read_only (comp_data->client, &read_only, NULL); + editable &= !read_only; + + prop = icalcomponent_get_first_property ( + comp_data->icalcomp, ICAL_URL_PROPERTY); + has_url |= (prop != NULL); + } + g_slist_free (list); + + action = ACTION (CALENDAR_MEMOPAD_CLIPBOARD_COPY); + sensitive = (n_selected > 0); + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CALENDAR_MEMOPAD_CLIPBOARD_CUT); + sensitive = (n_selected > 0) && editable; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CALENDAR_MEMOPAD_CLIPBOARD_PASTE); + sensitive = editable; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CALENDAR_MEMOPAD_DELETE); + sensitive = (n_selected > 0) && editable; + gtk_action_set_sensitive (action, sensitive); + label = ngettext ("Delete Memo", "Delete Memos", n_selected); + g_object_set (action, "label", label, NULL); + + action = ACTION (CALENDAR_MEMOPAD_FORWARD); + sensitive = (n_selected == 1); + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CALENDAR_MEMOPAD_OPEN); + sensitive = (n_selected == 1); + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CALENDAR_MEMOPAD_OPEN_URL); + sensitive = (n_selected == 1) && has_url; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CALENDAR_MEMOPAD_PRINT); + sensitive = (n_selected == 1); + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CALENDAR_MEMOPAD_SAVE_AS); + sensitive = (n_selected == 1); + gtk_action_set_sensitive (action, sensitive); +} + +void +e_cal_shell_view_memopad_open_memo (ECalShellView *cal_shell_view, + ECalModelComponent *comp_data) +{ + EShell *shell; + EShellView *shell_view; + EShellWindow *shell_window; + CompEditor *editor; + CompEditorFlags flags = 0; + ECalComponent *comp; + icalcomponent *clone; + const gchar *uid; + + g_return_if_fail (E_IS_CAL_SHELL_VIEW (cal_shell_view)); + g_return_if_fail (E_IS_CAL_MODEL_COMPONENT (comp_data)); + + shell_view = E_SHELL_VIEW (cal_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + shell = e_shell_window_get_shell (shell_window); + + uid = icalcomponent_get_uid (comp_data->icalcomp); + editor = comp_editor_find_instance (uid); + + if (editor != NULL) + goto exit; + + comp = e_cal_component_new (); + clone = icalcomponent_new_clone (comp_data->icalcomp); + e_cal_component_set_icalcomponent (comp, clone); + + 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; + + editor = memo_editor_new (comp_data->client, shell, flags); + comp_editor_edit_comp (editor, comp); + + g_object_unref (comp); + +exit: + gtk_window_present (GTK_WINDOW (editor)); +} + +void +e_cal_shell_view_memopad_set_status_message (ECalShellView *cal_shell_view, + const gchar *status_message, + gdouble percent) +{ + EActivity *activity; + EShellView *shell_view; + EShellModule *shell_module; + + g_return_if_fail (E_IS_CAL_SHELL_VIEW (cal_shell_view)); + + shell_view = E_SHELL_VIEW (cal_shell_view); + shell_module = e_shell_view_get_shell_module (shell_view); + + activity = cal_shell_view->priv->memopad_activity; + + if (status_message == NULL || *status_message == '\0') { + if (activity != NULL) { + e_activity_complete (activity); + g_object_unref (activity); + activity = NULL; + } + + } else if (activity == NULL) { + activity = e_activity_new (status_message); + e_activity_set_percent (activity, percent); + e_shell_module_add_activity (shell_module, activity); + + } else { + e_activity_set_percent (activity, percent); + e_activity_set_primary_text (activity, status_message); + } + + cal_shell_view->priv->memopad_activity = activity; +} diff --git a/calendar/modules/e-cal-shell-view-private.c b/calendar/modules/e-cal-shell-view-private.c new file mode 100644 index 0000000000..f344333598 --- /dev/null +++ b/calendar/modules/e-cal-shell-view-private.c @@ -0,0 +1,659 @@ +/* + * e-cal-shell-view-private.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-cal-shell-view-private.h" + +#include "calendar/gui/calendar-view-factory.h" +#include "widgets/menus/gal-view-factory-etable.h" + +static void +cal_shell_view_process_completed_tasks (ECalShellView *cal_shell_view, + gboolean config_changed) +{ +#if 0 + ECalShellContent *cal_shell_content; + ECalendarTable *task_table; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + task_table = e_cal_shell_content_get_task_table (cal_shell_content); + + e_calendar_table_process_completed_tasks ( + task_table, clients, config_changed); +#endif +} + +static void +cal_shell_view_config_timezone_changed_cb (GConfClient *client, + guint id, + GConfEntry *entry, + gpointer user_data) +{ + ECalShellView *cal_shell_view = user_data; + + e_cal_shell_view_update_timezone (cal_shell_view); +} + +static struct tm +cal_shell_view_get_current_time (ECalendarItem *calitem, + ECalShellView *cal_shell_view) +{ + ECalShellContent *cal_shell_content; + struct icaltimetype tt; + icaltimezone *timezone; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + timezone = e_cal_shell_content_get_timezone (cal_shell_content); + + tt = icaltime_from_timet_with_zone (time (NULL), FALSE, timezone); + + return icaltimetype_to_tm (&tt); +} + +static void +cal_shell_view_mini_calendar_date_range_changed_cb (ECalShellView *cal_shell_view, + ECalendarItem *calitem) +{ + /* FIXME gnome-calendar.c calls update_query() here. */ +} + +static void +cal_shell_view_mini_calendar_selection_changed_cb (ECalShellView *cal_shell_view, + ECalendarItem *calitem) +{ + /* FIXME */ +} + +static void +cal_shell_view_mini_calendar_scroll_event_cb (ECalShellView *cal_shell_view, + GdkEventScroll *event, + ECalendar *mini_calendar) +{ + ECalendarItem *calitem; + GDate start_date, end_date; + + calitem = mini_calendar->calitem; + if (!e_calendar_item_get_selection (calitem, &start_date, &end_date)) + return; + + switch (event->direction) { + case GDK_SCROLL_UP: + g_date_subtract_months (&start_date, 1); + g_date_subtract_months (&end_date, 1); + break; + + case GDK_SCROLL_DOWN: + g_date_add_months (&start_date, 1); + g_date_add_months (&end_date, 1); + break; + + default: + g_return_if_reached (); + } + + /* XXX Does ECalendarItem emit a signal for this? If so, maybe + * we could move this handler into ECalShellSidebar. */ + e_calendar_item_set_selection (calitem, &start_date, &end_date); + + cal_shell_view_mini_calendar_date_range_changed_cb ( + cal_shell_view, calitem); +} + +static gboolean +cal_shell_view_selector_popup_event_cb (EShellView *shell_view, + ESource *primary_source, + GdkEventButton *event) +{ + const gchar *widget_path; + + widget_path = "/calendar-popup"; + e_shell_view_show_popup_menu (shell_view, widget_path, event); + + return TRUE; +} + +static void +cal_shell_view_memopad_popup_event_cb (EShellView *shell_view, + GdkEventButton *event) +{ + const gchar *widget_path; + + widget_path = "/calendar-memopad-popup"; + e_shell_view_show_popup_menu (shell_view, widget_path, event); +} + +static void +cal_shell_view_taskpad_popup_event_cb (EShellView *shell_view, + GdkEventButton *event) +{ + const gchar *widget_path; + + widget_path = "/calendar-taskpad-popup"; + e_shell_view_show_popup_menu (shell_view, widget_path, event); +} + +static void +cal_shell_view_load_view_collection (EShellViewClass *shell_view_class) +{ + GalViewCollection *collection; + GalViewFactory *factory; + ETableSpecification *spec; + const gchar *base_dir; + gchar *filename; + + collection = shell_view_class->view_collection; + + base_dir = EVOLUTION_ETSPECDIR; + spec = e_table_specification_new (); + filename = g_build_filename (base_dir, ETSPEC_FILENAME, NULL); + if (!e_table_specification_load_from_file (spec, filename)) + g_critical ("Unable to load ETable specification file " + "for calendars"); + g_free (filename); + + factory = calendar_view_factory_new (GNOME_CAL_DAY_VIEW); + gal_view_collection_add_factory (collection, factory); + g_object_unref (factory); + + factory = calendar_view_factory_new (GNOME_CAL_WORK_WEEK_VIEW); + gal_view_collection_add_factory (collection, factory); + g_object_unref (factory); + + factory = calendar_view_factory_new (GNOME_CAL_WEEK_VIEW); + gal_view_collection_add_factory (collection, factory); + g_object_unref (factory); + + factory = calendar_view_factory_new (GNOME_CAL_MONTH_VIEW); + gal_view_collection_add_factory (collection, factory); + g_object_unref (factory); + + factory = gal_view_factory_etable_new (spec); + gal_view_collection_add_factory (collection, factory); + g_object_unref (factory); + g_object_unref (spec); + + gal_view_collection_load (collection); +} + +static void +cal_shell_view_notify_view_id_cb (ECalShellView *cal_shell_view) +{ + ECalShellContent *cal_shell_content; + GalViewInstance *view_instance; + const gchar *view_id; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + view_instance = + e_cal_shell_content_get_view_instance (cal_shell_content); + view_id = e_shell_view_get_view_id (E_SHELL_VIEW (cal_shell_view)); + + /* A NULL view ID implies we're in a custom view. But you can + * only get to a custom view via the "Define Views" dialog, which + * would have already modified the view instance appropriately. + * Furthermore, there's no way to refer to a custom view by ID + * anyway, since custom views have no IDs. */ + if (view_id == NULL) + return; + + gal_view_instance_set_current_view_id (view_instance, view_id); +} + +void +e_cal_shell_view_private_init (ECalShellView *cal_shell_view, + EShellViewClass *shell_view_class) +{ + ECalShellViewPrivate *priv = cal_shell_view->priv; + ESourceList *source_list; + GObject *object; + guint notification_id; + + object = G_OBJECT (shell_view_class->type_module); + source_list = g_object_get_data (object, "source-list"); + g_return_if_fail (E_IS_SOURCE_LIST (source_list)); + + priv->source_list = g_object_ref (source_list); + + if (!gal_view_collection_loaded (shell_view_class->view_collection)) + cal_shell_view_load_view_collection (shell_view_class); + + g_signal_connect ( + cal_shell_view, "notify::view-id", + G_CALLBACK (cal_shell_view_notify_view_id_cb), NULL); +} + +void +e_cal_shell_view_private_constructed (ECalShellView *cal_shell_view) +{ + ECalShellViewPrivate *priv = cal_shell_view->priv; + ECalShellContent *cal_shell_content; + ECalShellSidebar *cal_shell_sidebar; + EShellContent *shell_content; + EShellSidebar *shell_sidebar; + EShellWindow *shell_window; + EShellView *shell_view; + GnomeCalendar *calendar; + ECalendar *mini_calendar; + EMemoTable *memo_table; + ECalendarTable *task_table; + ESourceSelector *selector; + guint id; + + shell_view = E_SHELL_VIEW (cal_shell_view); + shell_content = e_shell_view_get_shell_content (shell_view); + shell_sidebar = e_shell_view_get_shell_sidebar (shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + e_shell_window_add_action_group (shell_window, "calendar"); + e_shell_window_add_action_group (shell_window, "calendar-filter"); + + /* Cache these to avoid lots of awkward casting. */ + priv->cal_shell_content = g_object_ref (shell_content); + priv->cal_shell_sidebar = g_object_ref (shell_sidebar); + + cal_shell_content = E_CAL_SHELL_CONTENT (shell_content); + calendar = e_cal_shell_content_get_calendar (cal_shell_content); + memo_table = e_cal_shell_content_get_memo_table (cal_shell_content); + task_table = e_cal_shell_content_get_task_table (cal_shell_content); + + cal_shell_sidebar = E_CAL_SHELL_SIDEBAR (shell_sidebar); + selector = e_cal_shell_sidebar_get_selector (cal_shell_sidebar); + mini_calendar = e_cal_shell_sidebar_get_mini_calendar (cal_shell_sidebar); + + e_calendar_item_set_get_time_callback ( + mini_calendar->calitem, (ECalendarItemGetTimeCallback) + cal_shell_view_get_current_time, cal_shell_view, NULL); + +#if 0 /* KILL-BONOBO */ + g_signal_connect_swapped ( + calendar, "dates-shown-changed", + G_CALLBACK (e_cal_shell_view_update_sidebar), + cal_shell_view); +#endif + + g_signal_connect_swapped ( + mini_calendar, "scroll-event", + G_CALLBACK (cal_shell_view_mini_calendar_scroll_event_cb), + cal_shell_view); + + g_signal_connect_swapped ( + mini_calendar->calitem, "date-range-changed", + G_CALLBACK (cal_shell_view_mini_calendar_date_range_changed_cb), + cal_shell_view); + + g_signal_connect_swapped ( + mini_calendar->calitem, "selection-changed", + G_CALLBACK (cal_shell_view_mini_calendar_selection_changed_cb), + cal_shell_view); + + g_signal_connect_swapped ( + selector, "popup-event", + G_CALLBACK (cal_shell_view_selector_popup_event_cb), + cal_shell_view); + + g_signal_connect_swapped ( + memo_table, "popup-event", + G_CALLBACK (cal_shell_view_memopad_popup_event_cb), + cal_shell_view); + + g_signal_connect_swapped ( + memo_table, "status-message", + G_CALLBACK (e_cal_shell_view_memopad_set_status_message), + cal_shell_view); + + g_signal_connect_swapped ( + task_table, "popup-event", + G_CALLBACK (cal_shell_view_taskpad_popup_event_cb), + cal_shell_view); + + g_signal_connect_swapped ( + task_table, "status-message", + G_CALLBACK (e_cal_shell_view_taskpad_set_status_message), + cal_shell_view); + + g_signal_connect_swapped ( + e_memo_table_get_table (memo_table), "selection-change", + G_CALLBACK (e_cal_shell_view_memopad_actions_update), + cal_shell_view); + + g_signal_connect_swapped ( + e_calendar_table_get_table (task_table), "selection-change", + G_CALLBACK (e_cal_shell_view_taskpad_actions_update), + cal_shell_view); + + e_categories_register_change_listener ( + G_CALLBACK (e_cal_shell_view_update_search_filter), + cal_shell_view); + + /* Listen for configuration changes. */ + + /* Timezone */ + id = calendar_config_add_notification_timezone ( + cal_shell_view_config_timezone_changed_cb, cal_shell_view); + priv->notifications = g_list_prepend ( + priv->notifications, GUINT_TO_POINTER (id)); + + e_cal_shell_view_actions_init (cal_shell_view); + e_cal_shell_view_update_sidebar (cal_shell_view); + e_cal_shell_view_update_search_filter (cal_shell_view); + e_cal_shell_view_update_timezone (cal_shell_view); +} + +void +e_cal_shell_view_private_dispose (ECalShellView *cal_shell_view) +{ + ECalShellViewPrivate *priv = cal_shell_view->priv; + GList *iter; + + DISPOSE (priv->source_list); + + DISPOSE (priv->cal_shell_content); + DISPOSE (priv->cal_shell_sidebar); + + if (priv->calendar_activity != NULL) { + /* XXX Activity is not cancellable. */ + e_activity_complete (priv->calendar_activity); + g_object_unref (priv->calendar_activity); + priv->calendar_activity = NULL; + } + + if (priv->memopad_activity != NULL) { + /* XXX Activity is not cancellable. */ + e_activity_complete (priv->memopad_activity); + g_object_unref (priv->memopad_activity); + priv->memopad_activity = NULL; + } + + if (priv->taskpad_activity != NULL) { + /* XXX Activity is not cancellable. */ + e_activity_complete (priv->taskpad_activity); + g_object_unref (priv->taskpad_activity); + priv->taskpad_activity = NULL; + } + + for (iter = priv->notifications; iter != NULL; iter = iter->next) { + guint notification_id = GPOINTER_TO_UINT (iter->data); + calendar_config_remove_notification (notification_id); + } + g_list_free (priv->notifications); + priv->notifications = NULL; +} + +void +e_cal_shell_view_private_finalize (ECalShellView *cal_shell_view) +{ + /* XXX Nothing to do? */ +} + +void +e_cal_shell_view_execute_search (ECalShellView *cal_shell_view) +{ + /* FIXME */ +} + +void +e_cal_shell_view_open_event (ECalShellView *cal_shell_view, + ECalModelComponent *comp_data) +{ + EShell *shell; + EShellView *shell_view; + EShellWindow *shell_window; + CompEditor *editor; + CompEditorFlags flags = 0; + ECalComponent *comp; + icalcomponent *clone; + icalproperty *prop; + const gchar *uid; + + g_return_if_fail (E_IS_CAL_SHELL_VIEW (cal_shell_view)); + g_return_if_fail (E_IS_CAL_MODEL_COMPONENT (comp_data)); + + shell_view = E_SHELL_VIEW (cal_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + shell = e_shell_window_get_shell (shell_window); + + uid = icalcomponent_get_uid (comp_data->icalcomp); + editor = comp_editor_find_instance (uid); + + if (editor != NULL) + goto exit; + + comp = e_cal_component_new (); + clone = icalcomponent_new_clone (comp_data->icalcomp); + e_cal_component_set_icalcomponent (comp, clone); + + prop = icalcomponent_get_first_property ( + comp_data->icalcomp, ICAL_ATTENDEE_PROPERTY); + if (prop != NULL) + flags |= COMP_EDITOR_MEETING; + + if (itip_organizer_is_user (comp, comp_data->client)) + flags |= COMP_EDITOR_USER_ORG; + + if (itip_sentby_is_user (comp, comp_data->client)) + flags |= COMP_EDITOR_USER_ORG; + + if (!e_cal_component_has_attendees (comp)) + flags |= COMP_EDITOR_USER_ORG; + + editor = event_editor_new (comp_data->client, shell, flags); + comp_editor_edit_comp (editor, comp); + + g_object_ref (comp); + +exit: + gtk_window_present (GTK_WINDOW (editor)); +} + +void +e_cal_shell_view_set_status_message (ECalShellView *cal_shell_view, + const gchar *status_message, + gdouble percent) +{ + EActivity *activity; + EShellView *shell_view; + EShellModule *shell_module; + + g_return_if_fail (E_IS_CAL_SHELL_VIEW (cal_shell_view)); + + shell_view = E_SHELL_VIEW (cal_shell_view); + shell_module = e_shell_view_get_shell_module (shell_view); + + activity = cal_shell_view->priv->calendar_activity; + + if (status_message == NULL || *status_message == '\0') { + if (activity != NULL) { + e_activity_complete (activity); + g_object_unref (activity); + activity = NULL; + } + + } else if (activity == NULL) { + activity = e_activity_new (status_message); + e_activity_set_percent (activity, percent); + e_shell_module_add_activity (shell_module, activity); + + } else { + e_activity_set_percent (activity, percent); + e_activity_set_primary_text (activity, status_message); + } + + cal_shell_view->priv->calendar_activity = activity; +} + +void +e_cal_shell_view_update_sidebar (ECalShellView *cal_shell_view) +{ +#if 0 /* KILL-BONOBO */ + EShellView *shell_view; + EShellSidebar *shell_sidebar; + GnomeCalendar *calendar; + GnomeCalendarViewType view; + time_t start_time, end_time; + struct tm start_tm, end_tm; + struct icaltimetype start_tt, end_tt; + icaltimezone *timezone; + gchar buffer[512]; + gchar end_buffer[512]; + + g_return_if_fail (E_IS_CAL_SHELL_VIEW (cal_shell_view)); + + shell_view = E_SHELL_VIEW (cal_shell_view); + shell_sidebar = e_shell_view_get_shell_sidebar (shell_view); + + calendar = e_cal_shell_view_get_calendar (cal_shell_view); + + gnome_calendar_get_visible_time_range ( + calendar, &start_time, &end_time); + timezone = gnome_calendar_get_timezone (calendar); + view = gnome_calendar_get_view (calendar); + + start_tt = icaltime_from_timet_with_zone (start_time, FALSE, timezone); + start_tm.tm_year = start_tt.year - 1900; + start_tm.tm_mon = start_tt.month - 1; + start_tm.tm_mday = start_tt.day; + start_tm.tm_hour = start_tt.hour; + start_tm.tm_min = start_tt.minute; + start_tm.tm_sec = start_tt.second; + start_tm.tm_isdst = -1; + start_tm.tm_wday = time_day_of_week ( + start_tt.day, start_tt.month - 1, start_tt.year); + + /* Subtract one from end_time so we don't get an extra day. */ + end_tt = icaltime_from_timet_with_zone (end_time - 1, FALSE, timezone); + end_tm.tm_year = end_tt.year - 1900; + end_tm.tm_mon = end_tt.month - 1; + end_tm.tm_mday = end_tt.day; + end_tm.tm_hour = end_tt.hour; + end_tm.tm_min = end_tt.minute; + end_tm.tm_sec = end_tt.second; + end_tm.tm_isdst = -1; + end_tm.tm_wday = time_day_of_week ( + end_tt.day, end_tt.month - 1, end_tt.year); + + switch (view) { + case GNOME_CAL_DAY_VIEW: + case GNOME_CAL_WORK_WEEK_VIEW: + case GNOME_CAL_WEEK_VIEW: + if (start_tm.tm_year == end_tm.tm_year && + start_tm.tm_mon == end_tm.tm_mon && + start_tm.tm_mday == end_tm.tm_mday) { + e_utf8_strftime ( + buffer, sizeof (buffer), + _("%A %d %b %Y"), &start_tm); + } else if (start_tm.tm_year == end_tm.tm_year) { + e_utf8_strftime ( + buffer, sizeof (buffer), + _("%a %d %b"), &start_tm); + e_utf8_strftime ( + end_buffer, sizeof (end_buffer), + _("%a %d %b %Y"), &end_tm); + strcat (buffer, " - "); + strcat (buffer, end_buffer); + } else { + e_utf8_strftime ( + buffer, sizeof (buffer), + _("%a %d %b %Y"), &start_tm); + e_utf8_strftime ( + end_buffer, sizeof (end_buffer), + _("%a %d %b %Y"), &end_tm); + strcat (buffer, " - "); + strcat (buffer, end_buffer); + } + break; + + case GNOME_CAL_MONTH_VIEW: + case GNOME_CAL_LIST_VIEW: + if (start_tm.tm_year == end_tm.tm_year) { + if (start_tm.tm_mon == end_tm.tm_mon) { + e_utf8_strftime ( + buffer, + sizeof (buffer), + "%d", &start_tm); + e_utf8_strftime ( + end_buffer, + sizeof (end_buffer), + _("%d %b %Y"), &end_tm); + strcat (buffer, " - "); + strcat (buffer, end_buffer); + } else { + e_utf8_strftime ( + buffer, + sizeof (buffer), + _("%d %b"), &start_tm); + e_utf8_strftime ( + end_buffer, + sizeof (end_buffer), + _("%d %b %Y"), &end_tm); + strcat (buffer, " - "); + strcat (buffer, end_buffer); + } + } else { + e_utf8_strftime ( + buffer, sizeof (buffer), + _("%d %b %Y"), &start_tm); + e_utf8_strftime ( + end_buffer, sizeof (end_buffer), + _("%d %b %Y"), &end_tm); + strcat (buffer, " - "); + strcat (buffer, end_buffer); + } + break; + + default: + g_return_if_reached (); + } + + e_shell_sidebar_set_secondary_text (shell_sidebar, buffer); +#endif +} + +void +e_cal_shell_view_update_timezone (ECalShellView *cal_shell_view) +{ +#if 0 + ECalShellContent *cal_shell_content; + ECalShellSidebar *cal_shell_sidebar; + GnomeCalendarViewType view_type; + ECalendarView *calendar_view; + icaltimezone *timezone; + GList *clients, *iter; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + view_type = e_cal_shell_content_get_current_view (cal_shell_content); + calendar_view = e_cal_shell_content_get_calendar_view ( + cal_shell_content, view_type); + + cal_shell_sidebar = cal_shell_view->priv->cal_shell_sidebar; + clients = e_cal_shell_sidebar_get_clients (cal_shell_sidebar); + + timezone = calendar_config_get_icaltimezone (); + + for (iter = clients; iter != NULL; iter = iter->next) { + ECal *client = iter->data; + + if (e_cal_get_load_state (client) == E_CAL_LOAD_LOADED) + e_cal_set_default_timezone (client, timezone, NULL); + } + + e_calendar_view_set_icaltimezone (calendar_view, timezone); + + g_list_free (clients); +#endif +} diff --git a/calendar/modules/e-cal-shell-view-private.h b/calendar/modules/e-cal-shell-view-private.h new file mode 100644 index 0000000000..af492618e9 --- /dev/null +++ b/calendar/modules/e-cal-shell-view-private.h @@ -0,0 +1,172 @@ +/* + * e-cal-shell-view-private.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_CAL_SHELL_VIEW_PRIVATE_H +#define E_CAL_SHELL_VIEW_PRIVATE_H + +#include "e-cal-shell-view.h" + +#include <string.h> +#include <glib/gi18n.h> +#include <libecal/e-cal-time-util.h> +#include <libedataserver/e-categories.h> +#include <libedataserver/e-data-server-util.h> + +#include "e-util/e-util.h" +#include "e-util/e-dialog-utils.h" +#include "widgets/misc/e-popup-action.h" + +#include "calendar/gui/calendar-config.h" +#include "calendar/gui/comp-util.h" +#include "calendar/gui/e-cal-list-view.h" +#include "calendar/gui/e-cal-model-tasks.h" +#include "calendar/gui/e-calendar-view.h" +#include "calendar/gui/gnome-cal.h" +/*#include "calendar/gui/goto.h"*/ +#include "calendar/gui/print.h" +#include "calendar/gui/dialogs/copy-source-dialog.h" +#include "calendar/gui/dialogs/event-editor.h" +#include "calendar/gui/dialogs/memo-editor.h" +#include "calendar/gui/dialogs/task-editor.h" + +#include "e-cal-shell-content.h" +#include "e-cal-shell-sidebar.h" +#include "e-cal-shell-view-actions.h" + +#define E_CAL_SHELL_VIEW_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_CAL_SHELL_VIEW, ECalShellViewPrivate)) + +/* Shorthand, requires a variable named "shell_window". */ +#define ACTION(name) \ + (E_SHELL_WINDOW_ACTION_##name (shell_window)) +#define ACTION_GROUP(name) \ + (E_SHELL_WINDOW_ACTION_GROUP_##name (shell_window)) + +/* For use in dispose() methods. */ +#define DISPOSE(obj) \ + G_STMT_START { \ + if ((obj) != NULL) { g_object_unref (obj); (obj) = NULL; } \ + } G_STMT_END + +/* ETable Specifications */ +#define ETSPEC_FILENAME "e-calendar-table.etspec" + +G_BEGIN_DECLS + +/* Filter items are displayed in ascending order. + * Non-negative values are reserved for categories. */ +enum { + CALENDAR_FILTER_ANY_CATEGORY = -4, + CALENDAR_FILTER_UNMATCHED = -3, + CALENDAR_FILTER_ACTIVE_APPOINTMENTS = -2, + CALENDAR_FILTER_NEXT_7_DAYS_APPOINTMENTS = -1 +}; + +/* Search items are displayed in ascending order. */ +enum { + CALENDAR_SEARCH_SUMMARY_CONTAINS, + CALENDAR_SEARCH_DESCRIPTION_CONTAINS, + CALENDAR_SEARCH_ANY_FIELD_CONTAINS +}; + +struct _ECalShellViewPrivate { + + /*** Module Data ***/ + + ESourceList *source_list; + + /* These are just for convenience. */ + ECalShellContent *cal_shell_content; + ECalShellSidebar *cal_shell_sidebar; + + /* The last time explicitly selected by the user. */ + time_t base_view_time; + + EActivity *calendar_activity; + EActivity *memopad_activity; + EActivity *taskpad_activity; + + /* GConf notification IDs */ + GList *notifications; +}; + +void e_cal_shell_view_private_init + (ECalShellView *cal_shell_view, + EShellViewClass *shell_view_class); +void e_cal_shell_view_private_constructed + (ECalShellView *cal_shell_view); +void e_cal_shell_view_private_dispose + (ECalShellView *cal_shell_view); +void e_cal_shell_view_private_finalize + (ECalShellView *cal_shell_view); + +/* Private Utilities */ + +void e_cal_shell_view_actions_init + (ECalShellView *cal_shell_view); +void e_cal_shell_view_execute_search + (ECalShellView *cal_shell_view); +void e_cal_shell_view_open_event + (ECalShellView *cal_shell_view, + ECalModelComponent *comp_data); +void e_cal_shell_view_set_status_message + (ECalShellView *cal_shell_view, + const gchar *status_message, + gdouble percent); +void e_cal_shell_view_update_sidebar + (ECalShellView *cal_shell_view); +void e_cal_shell_view_update_search_filter + (ECalShellView *cal_shell_view); +void e_cal_shell_view_update_timezone + (ECalShellView *cal_shell_view); + +/* Memo Pad Utilities */ + +void e_cal_shell_view_memopad_actions_init + (ECalShellView *cal_shell_view); +void e_cal_shell_view_memopad_actions_update + (ECalShellView *cal_shell_view); +void e_cal_shell_view_memopad_open_memo + (ECalShellView *cal_shell_view, + ECalModelComponent *comp_data); +void e_cal_shell_view_memopad_set_status_message + (ECalShellView *cal_shell_view, + const gchar *status_message, + gdouble percent); + +/* Task Pad Utilities */ + +void e_cal_shell_view_taskpad_actions_init + (ECalShellView *cal_shell_view); +void e_cal_shell_view_taskpad_actions_update + (ECalShellView *cal_shell_view); +void e_cal_shell_view_taskpad_open_task + (ECalShellView *cal_shell_view, + ECalModelComponent *comp_data); +void e_cal_shell_view_taskpad_set_status_message + (ECalShellView *cal_shell_view, + const gchar *status_message, + gdouble percent); + +G_END_DECLS + +#endif /* E_CAL_SHELL_VIEW_PRIVATE_H */ diff --git a/calendar/modules/e-cal-shell-view-taskpad.c b/calendar/modules/e-cal-shell-view-taskpad.c new file mode 100644 index 0000000000..92fcdba69f --- /dev/null +++ b/calendar/modules/e-cal-shell-view-taskpad.c @@ -0,0 +1,654 @@ +/* + * e-cal-shell-view-taskpad.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-cal-shell-view-private.h" + +/* Much of this file is based on e-task-shell-view-actions.c. */ + +static void +action_calendar_taskpad_assign_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + ECalShellContent *cal_shell_content; + ECalendarTable *task_table; + ECalModelComponent *comp_data; + GSList *list; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + task_table = e_cal_shell_content_get_task_table (cal_shell_content); + + list = e_calendar_table_get_selected (task_table); + g_return_if_fail (list != NULL); + comp_data = list->data; + g_slist_free (list); + + /* XXX We only open the first selected task. */ + e_cal_shell_view_taskpad_open_task (cal_shell_view, comp_data); + + /* FIXME Need to actually assign the task. */ +} + +static void +action_calendar_taskpad_clipboard_copy_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + ECalShellContent *cal_shell_content; + ECalendarTable *task_table; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + task_table = e_cal_shell_content_get_task_table (cal_shell_content); + + e_calendar_table_copy_clipboard (task_table); +} + +static void +action_calendar_taskpad_clipboard_cut_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + ECalShellContent *cal_shell_content; + ECalendarTable *task_table; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + task_table = e_cal_shell_content_get_task_table (cal_shell_content); + + e_calendar_table_cut_clipboard (task_table); +} + +static void +action_calendar_taskpad_clipboard_paste_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + ECalShellContent *cal_shell_content; + ECalendarTable *task_table; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + task_table = e_cal_shell_content_get_task_table (cal_shell_content); + + e_calendar_table_paste_clipboard (task_table); +} + +static void +action_calendar_taskpad_delete_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + ECalShellContent *cal_shell_content; + ECalendarTable *task_table; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + task_table = e_cal_shell_content_get_task_table (cal_shell_content); + + e_cal_shell_view_taskpad_set_status_message ( + cal_shell_view, _("Deleting selected tasks..."), -1.0); + e_calendar_table_delete_selected (task_table); + e_cal_shell_view_taskpad_set_status_message ( + cal_shell_view, NULL, -1.0); +} + +static void +action_calendar_taskpad_forward_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + ECalShellContent *cal_shell_content; + ECalendarTable *task_table; + ECalModelComponent *comp_data; + ECalComponent *comp; + icalcomponent *clone; + GSList *list; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + task_table = e_cal_shell_content_get_task_table (cal_shell_content); + + list = e_calendar_table_get_selected (task_table); + g_return_if_fail (list != NULL); + comp_data = list->data; + g_slist_free (list); + + /* XXX We only forward the first selected task. */ + comp = e_cal_component_new (); + clone = icalcomponent_new_clone (comp_data->icalcomp); + e_cal_component_set_icalcomponent (comp, clone); + itip_send_comp ( + E_CAL_COMPONENT_METHOD_PUBLISH, comp, + comp_data->client, NULL, NULL, NULL, TRUE); + g_object_unref (comp); +} + +static void +action_calendar_taskpad_mark_complete_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + ECalShellContent *cal_shell_content; + ECalendarTable *task_table; + ECalModel *model; + GSList *list, *iter; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + task_table = e_cal_shell_content_get_task_table (cal_shell_content); + list = e_calendar_table_get_selected (task_table); + model = e_calendar_table_get_model (task_table); + + for (iter = list; iter != NULL; iter = iter->next) { + ECalModelComponent *comp_data = iter->data; + e_cal_model_tasks_mark_comp_complete ( + E_CAL_MODEL_TASKS (model), comp_data); + } + + g_slist_free (list); +} + +static void +action_calendar_taskpad_mark_incomplete_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + ECalShellContent *cal_shell_content; + ECalendarTable *task_table; + ECalModel *model; + GSList *list, *iter; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + task_table = e_cal_shell_content_get_task_table (cal_shell_content); + list = e_calendar_table_get_selected (task_table); + model = e_calendar_table_get_model (task_table); + + for (iter = list; iter != NULL; iter = iter->next) { + ECalModelComponent *comp_data = iter->data; + e_cal_model_tasks_mark_comp_incomplete ( + E_CAL_MODEL_TASKS (model), comp_data); + } + + g_slist_free (list); +} + +static void +action_calendar_taskpad_new_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + EShell *shell; + EShellView *shell_view; + EShellWindow *shell_window; + ECalShellContent *cal_shell_content; + ECalendarTable *task_table; + ECalModelComponent *comp_data; + ECal *client; + ECalComponent *comp; + CompEditor *editor; + GSList *list; + + shell_view = E_SHELL_VIEW (cal_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + shell = e_shell_window_get_shell (shell_window); + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + task_table = e_cal_shell_content_get_task_table (cal_shell_content); + + list = e_calendar_table_get_selected (task_table); + g_return_if_fail (list != NULL); + comp_data = list->data; + g_slist_free (list); + + client = comp_data->client; + editor = task_editor_new (client, shell, COMP_EDITOR_NEW_ITEM); + comp = cal_comp_task_new_with_defaults (client); + comp_editor_edit_comp (editor, comp); + + gtk_window_present (GTK_WINDOW (editor)); + + g_object_unref (comp); + g_object_unref (client); +} + +static void +action_calendar_taskpad_open_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + ECalShellContent *cal_shell_content; + ECalendarTable *task_table; + ECalModelComponent *comp_data; + GSList *list; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + task_table = e_cal_shell_content_get_task_table (cal_shell_content); + + list = e_calendar_table_get_selected (task_table); + g_return_if_fail (list != NULL); + comp_data = list->data; + g_slist_free (list); + + /* XXX We only open the first selected task. */ + e_cal_shell_view_taskpad_open_task (cal_shell_view, comp_data); +} + +static void +action_calendar_taskpad_open_url_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + EShellView *shell_view; + EShellWindow *shell_window; + ECalShellContent *cal_shell_content; + ECalendarTable *task_table; + ECalModelComponent *comp_data; + icalproperty *prop; + const gchar *uri; + GSList *list; + + shell_view = E_SHELL_VIEW (cal_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + task_table = e_cal_shell_content_get_task_table (cal_shell_content); + + list = e_calendar_table_get_selected (task_table); + g_return_if_fail (list != NULL); + comp_data = list->data; + + /* XXX We only open the URI of the first selected task. */ + prop = icalcomponent_get_first_property ( + comp_data->icalcomp, ICAL_URL_PROPERTY); + g_return_if_fail (prop == NULL); + + uri = icalproperty_get_url (prop); + e_show_uri (GTK_WINDOW (shell_window), uri); +} + +static void +action_calendar_taskpad_print_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + ECalShellContent *cal_shell_content; + ECalendarTable *task_table; + ECalModelComponent *comp_data; + ECalComponent *comp; + icalcomponent *clone; + GtkPrintOperationAction print_action; + GSList *list; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + task_table = e_cal_shell_content_get_task_table (cal_shell_content); + + list = e_calendar_table_get_selected (task_table); + g_return_if_fail (list != NULL); + comp_data = list->data; + g_slist_free (list); + + /* XXX We only print the first selected task. */ + comp = e_cal_component_new (); + clone = icalcomponent_new_clone (comp_data->icalcomp); + print_action = GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG; + e_cal_component_set_icalcomponent (comp, clone); + print_comp (comp, comp_data->client, print_action); + g_object_unref (comp); +} + +static void +action_calendar_taskpad_save_as_cb (GtkAction *action, + ECalShellView *cal_shell_view) +{ + ECalShellContent *cal_shell_content; + ECalendarTable *task_table; + ECalModelComponent *comp_data; + GSList *list; + gchar *filename; + gchar *string; + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + task_table = e_cal_shell_content_get_task_table (cal_shell_content); + + list = e_calendar_table_get_selected (task_table); + g_return_if_fail (list != NULL); + comp_data = list->data; + g_slist_free (list); + + filename = e_file_dialog_save (_("Save as..."), NULL); + if (filename == NULL) + return; + + string = e_cal_get_component_as_string ( + comp_data->client, comp_data->icalcomp); + if (string == NULL) { + g_warning ("Could not convert task to a string"); + return; + } + + e_write_file_uri (filename, string); + + g_free (filename); + g_free (string); +} + +static GtkActionEntry calendar_taskpad_entries[] = { + + { "calendar-taskpad-assign", + NULL, + N_("_Assign Task"), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_calendar_taskpad_assign_cb) }, + + { "calendar-taskpad-clipboard-copy", + GTK_STOCK_COPY, + NULL, + NULL, + N_("Copy selected tasks"), + G_CALLBACK (action_calendar_taskpad_clipboard_copy_cb) }, + + { "calendar-taskpad-clipboard-cut", + GTK_STOCK_CUT, + NULL, + NULL, + N_("Cut selected tasks"), + G_CALLBACK (action_calendar_taskpad_clipboard_cut_cb) }, + + { "calendar-taskpad-clipboard-paste", + GTK_STOCK_PASTE, + NULL, + NULL, + N_("Paste tasks from the clipboard"), + G_CALLBACK (action_calendar_taskpad_clipboard_paste_cb) }, + + { "calendar-taskpad-delete", + GTK_STOCK_DELETE, + N_("_Delete Task"), + NULL, + N_("Delete selected tasks"), + G_CALLBACK (action_calendar_taskpad_delete_cb) }, + + { "calendar-taskpad-forward", + "mail-forward", + N_("_Forward as iCalendar..."), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_calendar_taskpad_forward_cb) }, + + { "calendar-taskpad-mark-complete", + NULL, + N_("_Mark as Complete"), + NULL, + N_("Mark selected tasks as complete"), + G_CALLBACK (action_calendar_taskpad_mark_complete_cb) }, + + { "calendar-taskpad-mark-incomplete", + NULL, + N_("_Mar_k as Incomplete"), + NULL, + N_("Mark selected tasks as incomplete"), + G_CALLBACK (action_calendar_taskpad_mark_incomplete_cb) }, + + { "calendar-taskpad-new", + "stock_task", + N_("New _Task"), + NULL, + N_("Create a new task"), + G_CALLBACK (action_calendar_taskpad_new_cb) }, + + { "calendar-taskpad-open", + GTK_STOCK_OPEN, + N_("_Open Task"), + NULL, + N_("View the selected task"), + G_CALLBACK (action_calendar_taskpad_open_cb) }, + + { "calendar-taskpad-open-url", + "applications-internet", + N_("Open _Web Page"), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_calendar_taskpad_open_url_cb) }, + + { "calendar-taskpad-save-as", + GTK_STOCK_SAVE_AS, + N_("_Save as iCalendar..."), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_calendar_taskpad_save_as_cb) } +}; + +static GtkActionEntry lockdown_printing_entries[] = { + + { "calendar-taskpad-print", + GTK_STOCK_PRINT, + NULL, + NULL, + N_("Print the selected task"), + G_CALLBACK (action_calendar_taskpad_print_cb) } +}; + +void +e_cal_shell_view_taskpad_actions_init (ECalShellView *cal_shell_view) +{ + EShellView *shell_view; + EShellWindow *shell_window; + GtkActionGroup *action_group; + + shell_view = E_SHELL_VIEW (cal_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + /* Calendar Actions */ + action_group = ACTION_GROUP (CALENDAR); + gtk_action_group_add_actions ( + action_group, calendar_taskpad_entries, + G_N_ELEMENTS (calendar_taskpad_entries), cal_shell_view); + + /* Lockdown Printing Actions */ + action_group = ACTION_GROUP (LOCKDOWN_PRINTING); + gtk_action_group_add_actions ( + action_group, lockdown_printing_entries, + G_N_ELEMENTS (lockdown_printing_entries), cal_shell_view); +} + +void +e_cal_shell_view_taskpad_actions_update (ECalShellView *cal_shell_view) +{ + ECalShellContent *cal_shell_content; + EShellWindow *shell_window; + EShellView *shell_view; + ECalendarTable *task_table; + ETable *table; + GtkAction *action; + GSList *list, *iter; + const gchar *label; + gboolean assignable = TRUE; + gboolean editable = TRUE; + gboolean has_url = FALSE; + gboolean sensitive; + gint n_selected; + gint n_complete = 0; + gint n_incomplete = 0; + + shell_view = E_SHELL_VIEW (cal_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + cal_shell_content = cal_shell_view->priv->cal_shell_content; + task_table = e_cal_shell_content_get_task_table (cal_shell_content); + + table = e_calendar_table_get_table (task_table); + n_selected = e_table_selected_count (table); + + list = e_calendar_table_get_selected (task_table); + for (iter = list; iter != NULL; iter = iter->next) { + ECalModelComponent *comp_data = iter->data; + icalproperty *prop; + const gchar *cap; + gboolean read_only; + + e_cal_is_read_only (comp_data->client, &read_only, NULL); + editable &= !read_only; + + cap = CAL_STATIC_CAPABILITY_NO_TASK_ASSIGNMENT; + if (e_cal_get_static_capability (comp_data->client, cap)) + assignable = FALSE; + + cap = CAL_STATIC_CAPABILITY_NO_CONV_TO_ASSIGN_TASK; + if (e_cal_get_static_capability (comp_data->client, cap)) + assignable = FALSE; + + prop = icalcomponent_get_first_property ( + comp_data->icalcomp, ICAL_URL_PROPERTY); + has_url |= (prop != NULL); + + prop = icalcomponent_get_first_property ( + comp_data->icalcomp, ICAL_COMPLETED_PROPERTY); + if (prop != NULL) + n_complete++; + else + n_incomplete++; + } + g_slist_free (list); + + action = ACTION (CALENDAR_TASKPAD_ASSIGN); + sensitive = (n_selected == 1) && editable && assignable; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CALENDAR_TASKPAD_CLIPBOARD_COPY); + sensitive = (n_selected > 0); + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CALENDAR_TASKPAD_CLIPBOARD_CUT); + sensitive = (n_selected > 0) && editable; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CALENDAR_TASKPAD_CLIPBOARD_PASTE); + sensitive = editable; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CALENDAR_TASKPAD_DELETE); + sensitive = (n_selected > 0) && editable; + gtk_action_set_sensitive (action, sensitive); + label = ngettext ("Delete Task", "Delete Tasks", n_selected); + g_object_set (action, "label", label, NULL); + + action = ACTION (CALENDAR_TASKPAD_FORWARD); + sensitive = (n_selected == 1); + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CALENDAR_TASKPAD_MARK_COMPLETE); + sensitive = (n_selected > 0) && editable && (n_incomplete > 0); + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CALENDAR_TASKPAD_MARK_INCOMPLETE); + sensitive = (n_selected > 0) && editable && (n_complete > 0); + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CALENDAR_TASKPAD_OPEN); + sensitive = (n_selected == 1); + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CALENDAR_TASKPAD_OPEN_URL); + sensitive = (n_selected == 1) && has_url; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CALENDAR_TASKPAD_PRINT); + sensitive = (n_selected == 1); + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CALENDAR_TASKPAD_SAVE_AS); + sensitive = (n_selected == 1); + gtk_action_set_sensitive (action, sensitive); +} + +void +e_cal_shell_view_taskpad_open_task (ECalShellView *cal_shell_view, + ECalModelComponent *comp_data) +{ + EShell *shell; + EShellView *shell_view; + EShellWindow *shell_window; + CompEditor *editor; + CompEditorFlags flags = 0; + ECalComponent *comp; + icalcomponent *clone; + icalproperty *prop; + const gchar *uid; + + g_return_if_fail (E_IS_CAL_SHELL_VIEW (cal_shell_view)); + g_return_if_fail (E_IS_CAL_MODEL_COMPONENT (comp_data)); + + shell_view = E_SHELL_VIEW (cal_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + shell = e_shell_window_get_shell (shell_window); + + uid = icalcomponent_get_uid (comp_data->icalcomp); + editor = comp_editor_find_instance (uid); + + if (editor != NULL) + goto exit; + + comp = e_cal_component_new (); + clone = icalcomponent_new_clone (comp_data->icalcomp); + e_cal_component_set_icalcomponent (comp, clone); + + prop = icalcomponent_get_first_property ( + comp_data->icalcomp, ICAL_ATTENDEE_PROPERTY); + if (prop != NULL) + flags |= COMP_EDITOR_IS_ASSIGNED; + + if (itip_organizer_is_user (comp, comp_data->client)) + flags |= COMP_EDITOR_USER_ORG; + + if (!e_cal_component_has_attendees (comp)) + flags |= COMP_EDITOR_USER_ORG; + + editor = task_editor_new (comp_data->client, shell, flags); + comp_editor_edit_comp (editor, comp); + + g_object_ref (comp); + + if (flags & COMP_EDITOR_IS_ASSIGNED) + task_editor_show_assignment (TASK_EDITOR (editor)); + +exit: + gtk_window_present (GTK_WINDOW (editor)); +} + +void +e_cal_shell_view_taskpad_set_status_message (ECalShellView *cal_shell_view, + const gchar *status_message, + gdouble percent) +{ + EActivity *activity; + EShellView *shell_view; + EShellModule *shell_module; + + g_return_if_fail (E_IS_CAL_SHELL_VIEW (cal_shell_view)); + + shell_view = E_SHELL_VIEW (cal_shell_view); + shell_module = e_shell_view_get_shell_module (shell_view); + + activity = cal_shell_view->priv->taskpad_activity; + + if (status_message == NULL || *status_message == '\0') { + if (activity != NULL) { + e_activity_complete (activity); + g_object_unref (activity); + activity = NULL; + } + + } else if (activity == NULL) { + activity = e_activity_new (status_message); + e_activity_set_percent (activity, percent); + e_shell_module_add_activity (shell_module, activity); + + } else { + e_activity_set_percent (activity, percent); + e_activity_set_primary_text (activity, status_message); + } + + cal_shell_view->priv->taskpad_activity = activity; +} diff --git a/calendar/modules/e-cal-shell-view.c b/calendar/modules/e-cal-shell-view.c new file mode 100644 index 0000000000..67f7d788a4 --- /dev/null +++ b/calendar/modules/e-cal-shell-view.c @@ -0,0 +1,267 @@ +/* + * e-cal-shell-view.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-cal-shell-view-private.h" + +enum { + PROP_0, + PROP_SOURCE_LIST +}; + +GType e_cal_shell_view_type = 0; +static gpointer parent_class; + +static void +cal_shell_view_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_SOURCE_LIST: + g_value_set_object ( + value, e_cal_shell_view_get_source_list ( + E_CAL_SHELL_VIEW (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +cal_shell_view_dispose (GObject *object) +{ + e_cal_shell_view_private_dispose (E_CAL_SHELL_VIEW (object)); + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +cal_shell_view_finalize (GObject *object) +{ + e_cal_shell_view_private_finalize (E_CAL_SHELL_VIEW (object)); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +cal_shell_view_constructed (GObject *object) +{ + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (parent_class)->constructed (object); + + e_cal_shell_view_private_constructed (E_CAL_SHELL_VIEW (object)); +} + +static void +cal_shell_view_update_actions (EShellView *shell_view) +{ +#if 0 + ECalShellViewPrivate *priv; + ECalShellContent *cal_shell_content; + ECalShellSidebar *cal_shell_sidebar; + EShellWindow *shell_window; + GnomeCalendar *calendar; + ECalModel *model; + ESourceSelector *selector; + ESource *source; + GtkAction *action; + GtkWidget *widget; + GList *list, *iter; + const gchar *uri = NULL; + gboolean user_created_source; + gboolean editable = TRUE; + gboolean recurring = FALSE; + gboolean sensitive; + gint n_selected; + + priv = E_CAL_SHELL_VIEW_GET_PRIVATE (shell_view); + + shell_window = e_shell_view_get_shell_window (shell_view); + + cal_shell_content = priv->cal_shell_content; + calendar = e_cal_shell_content_get_calendar (cal_shell_content); + widget = gnome_calendar_get_current_view_widget (calendar); + model = e_calendar_view_get_model (E_CALENDAR_VIEW (widget)); + + cal_shell_sidebar = priv->cal_shell_sidebar; + selector = e_cal_shell_sidebar_get_selector (cal_shell_sidebar); + + list = e_calendar_view_get_selected_events (E_CALENDAR_VIEW (widget)); + n_selected = g_list_length (list); + + for (iter = list; iter != NULL; iter = iter->next) { + ECalModelComponent *comp_data = iter->data; + gboolean read_only; + + e_cal_is_read_only (comp_data->client, &read_only, NULL); + editable &= !read_only; + + if (e_cal_util_component_has_recurrences (comp_data->icalcomp)) + recurring |= TRUE; + else if (e_cal_util_component_is_instance (comp_data->icalcomp)) + recurring |= TRUE; + } + + source = e_source_selector_peek_primary_selection (selector); + if (source != NULL) + uri = e_source_peek_relative_uri (source); + user_created_source = (uri != NULL && strcmp (uri, "system") != 0); + + action = ACTION (CALENDAR_COPY); + sensitive = (source != NULL); + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CALENDAR_DELETE); + sensitive = user_created_source; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CALENDAR_PROPERTIES); + sensitive = (source != NULL); + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CALENDAR_RENAME); + sensitive = has_primary_source; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (EVENT_CLIPBOARD_COPY); + sensitive = (n_selected > 0); + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (EVENT_CLIPBOARD_CUT); + sensitive = (n_selected > 0) && editable; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (EVENT_CLIPBOARD_PASTE); + sensitive = editable; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (EVENT_DELETE); + sensitive = (n_selected > 0) && editable && !recurring; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (EVENT_DELETE_OCCURRENCE); + sensitive = (n_selected > 0) && editable && recurring; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (EVENT_DELETE_OCCURRENCE_ALL); + sensitive = (n_selected > 0) && editable && recurring; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (EVENT_OPEN); + sensitive = (n_selected == 1); + gtk_action_set_sensitive (action, sensitive); +#endif +} + +static void +cal_shell_view_class_init (ECalShellViewClass *class, + GTypeModule *type_module) +{ + GObjectClass *object_class; + EShellViewClass *shell_view_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (ECalShellViewPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->get_property = cal_shell_view_get_property; + object_class->dispose = cal_shell_view_dispose; + object_class->finalize = cal_shell_view_finalize; + object_class->constructed = cal_shell_view_constructed; + + shell_view_class = E_SHELL_VIEW_CLASS (class); + shell_view_class->label = _("Calendar"); + shell_view_class->icon_name = "x-office-calendar"; + shell_view_class->ui_definition = "evolution-calendars.ui"; + shell_view_class->ui_manager_id = "org.gnome.evolution.calendars"; + shell_view_class->search_options = "/calendar-search-options"; + shell_view_class->search_rules = "caltypes.xml"; + shell_view_class->type_module = type_module; + shell_view_class->new_shell_content = e_cal_shell_content_new; + shell_view_class->new_shell_sidebar = e_cal_shell_sidebar_new; + shell_view_class->update_actions = cal_shell_view_update_actions; + + g_object_class_install_property ( + object_class, + PROP_SOURCE_LIST, + g_param_spec_object ( + "source-list", + _("Source List"), + _("The registry of calendars"), + E_TYPE_SOURCE_LIST, + G_PARAM_READABLE)); +} + +static void +cal_shell_view_init (ECalShellView *cal_shell_view, + EShellViewClass *shell_view_class) +{ + cal_shell_view->priv = + E_CAL_SHELL_VIEW_GET_PRIVATE (cal_shell_view); + + e_cal_shell_view_private_init (cal_shell_view, shell_view_class); +} + +GType +e_cal_shell_view_get_type (GTypeModule *type_module) +{ + if (e_cal_shell_view_type == 0) { + const GTypeInfo type_info = { + sizeof (ECalShellViewClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) cal_shell_view_class_init, + (GClassFinalizeFunc) NULL, + type_module, + sizeof (ECalShellView), + 0, /* n_preallocs */ + (GInstanceInitFunc) cal_shell_view_init, + NULL /* value_table */ + }; + + e_cal_shell_view_type = + g_type_module_register_type ( + type_module, E_TYPE_SHELL_VIEW, + "ECalShellView", &type_info, 0); + } + + return e_cal_shell_view_type; +} + +GnomeCalendar * +e_cal_shell_view_get_calendar (ECalShellView *cal_shell_view) +{ + g_return_val_if_fail (E_IS_CAL_SHELL_VIEW (cal_shell_view), NULL); + + /* FIXME */ + return NULL; +} + +ESourceList * +e_cal_shell_view_get_source_list (ECalShellView *cal_shell_view) +{ + g_return_val_if_fail (E_IS_CAL_SHELL_VIEW (cal_shell_view), NULL); + + return cal_shell_view->priv->source_list; +} diff --git a/calendar/modules/e-cal-shell-view.h b/calendar/modules/e-cal-shell-view.h new file mode 100644 index 0000000000..a301572972 --- /dev/null +++ b/calendar/modules/e-cal-shell-view.h @@ -0,0 +1,74 @@ +/* + * e-cal-shell-view.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_CAL_SHELL_VIEW_H +#define E_CAL_SHELL_VIEW_H + +#include <shell/e-shell-view.h> +#include <calendar/gui/gnome-cal.h> +#include <libedataserver/e-source-list.h> + +/* Standard GObject macros */ +#define E_TYPE_CAL_SHELL_VIEW \ + (e_cal_shell_view_type) +#define E_CAL_SHELL_VIEW(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_CAL_SHELL_VIEW, ECalShellView)) +#define E_CAL_SHELL_VIEW_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_CAL_SHELL_VIEW, ECalShellViewClass)) +#define E_IS_CAL_SHELL_VIEW(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_CAL_SHELL_VIEW)) +#define E_IS_CAL_SHELL_VIEW_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_CAL_SHELL_VIEW)) +#define E_CAL_SHELL_VIEW_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_CAL_SHELL_VIEW, ECalShellViewClass)) + +G_BEGIN_DECLS + +extern GType e_cal_shell_view_type; + +typedef struct _ECalShellView ECalShellView; +typedef struct _ECalShellViewClass ECalShellViewClass; +typedef struct _ECalShellViewPrivate ECalShellViewPrivate; + +struct _ECalShellView { + EShellView parent; + ECalShellViewPrivate *priv; +}; + +struct _ECalShellViewClass { + EShellViewClass parent_class; +}; + +GType e_cal_shell_view_get_type + (GTypeModule *type_module); +GnomeCalendar * e_cal_shell_view_get_calendar + (ECalShellView *cal_shell_view); +ESourceList * e_cal_shell_view_get_source_list + (ECalShellView *cal_shell_view); + +G_END_DECLS + +#endif /* E_CAL_SHELL_VIEW_H */ diff --git a/calendar/modules/e-memo-shell-content.c b/calendar/modules/e-memo-shell-content.c new file mode 100644 index 0000000000..006e988c41 --- /dev/null +++ b/calendar/modules/e-memo-shell-content.c @@ -0,0 +1,675 @@ +/* + * e-memo-shell-content.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-memo-shell-content.h" + +#include <glib/gi18n.h> + +#include "e-util/gconf-bridge.h" + +#include "calendar/gui/calendar-config.h" +#include "calendar/gui/comp-util.h" +#include "calendar/gui/e-cal-model-memos.h" +#include "calendar/gui/e-memo-table.h" +#include "calendar/gui/e-memo-table-config.h" + +#include "widgets/menus/gal-view-etable.h" + +#define E_MEMO_SHELL_CONTENT_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_MEMO_SHELL_CONTENT, EMemoShellContentPrivate)) + +#define E_MEMO_TABLE_DEFAULT_STATE \ + "<?xml version=\"1.0\"?>" \ + "<ETableState>" \ + " <column source=\"1\"/>" \ + " <column source=\"0\"/>" \ + " <column source=\"2\"/>" \ + " <grouping/>" \ + "</ETableState>" + +struct _EMemoShellContentPrivate { + GtkWidget *paned; + GtkWidget *memo_table; + GtkWidget *memo_preview; + + ECalModel *memo_model; + EMemoTableConfig *table_config; + GalViewInstance *view_instance; + + gchar *current_uid; +}; + +enum { + PROP_0, + PROP_MODEL, + PROP_PREVIEW_VISIBLE +}; + +enum { + TARGET_VCALENDAR +}; + +static GtkTargetEntry drag_types[] = { + { "text/calendar", 0, TARGET_VCALENDAR }, + { "text/x-calendar", 0, TARGET_VCALENDAR } +}; + +static gpointer parent_class; + +static void +memo_shell_content_display_view_cb (EMemoShellContent *memo_shell_content, + GalView *gal_view) +{ + EMemoTable *memo_table; + ETable *table; + + if (!GAL_IS_VIEW_ETABLE (gal_view)) + return; + + memo_table = e_memo_shell_content_get_memo_table (memo_shell_content); + table = e_memo_table_get_table (memo_table); + + gal_view_etable_attach_table (GAL_VIEW_ETABLE (gal_view), table); +} + +static void +memo_shell_content_table_foreach_cb (gint model_row, + gpointer user_data) +{ + ECalModelComponent *comp_data; + icalcomponent *clone; + icalcomponent *vcal; + gchar *string; + + struct { + ECalModel *model; + GSList *list; + } *foreach_data = user_data; + + comp_data = e_cal_model_get_component_at ( + foreach_data->model, model_row); + + vcal = e_cal_util_new_top_level (); + clone = icalcomponent_new_clone (comp_data->icalcomp); + e_cal_util_add_timezones_from_component (vcal, comp_data->icalcomp); + icalcomponent_add_component (vcal, clone); + + /* String is owned by libical; do not free. */ + string = icalcomponent_as_ical_string (vcal); + if (string != NULL) { + ESource *source; + const gchar *source_uid; + + source = e_cal_get_source (comp_data->client); + source_uid = e_source_peek_uid (source); + + foreach_data->list = g_slist_prepend ( + foreach_data->list, + g_strdup_printf ("%s\n%s", source_uid, string)); + } + + icalcomponent_free (vcal); +} + +static void +memo_shell_content_table_drag_data_get_cb (EMemoShellContent *memo_shell_content, + gint row, + gint col, + GdkDragContext *context, + GtkSelectionData *selection_data, + guint info, + guint time) +{ + EMemoTable *memo_table; + ETable *table; + + struct { + ECalModel *model; + GSList *list; + } foreach_data; + + if (info != TARGET_VCALENDAR) + return; + + memo_table = e_memo_shell_content_get_memo_table (memo_shell_content); + table = e_memo_table_get_table (memo_table); + + foreach_data.model = e_memo_table_get_model (memo_table); + foreach_data.list = NULL; + + e_table_selected_row_foreach ( + table, memo_shell_content_table_foreach_cb, + &foreach_data); + + if (foreach_data.list != NULL) { + cal_comp_selection_set_string_list ( + selection_data, foreach_data.list); + g_slist_foreach (foreach_data.list, (GFunc) g_free, NULL); + g_slist_free (foreach_data.list); + } +} + +static void +memo_shell_content_table_drag_data_delete_cb (EMemoShellContent *memo_shell_content, + gint row, + gint col, + GdkDragContext *context) +{ + /* Moved components are deleted from source immediately when moved, + * because some of them can be part of destination source, and we + * don't want to delete not-moved memos. There is no such information + * which event has been moved and which not, so skip this method. */ +} + +static void +memo_shell_content_cursor_change_cb (EMemoShellContent *memo_shell_content, + gint row, + ETable *table) +{ + ECalComponentPreview *memo_preview; + EMemoTable *memo_table; + ECalModel *memo_model; + ECalModelComponent *comp_data; + ECalComponent *comp; + const gchar *uid; + + memo_model = e_memo_shell_content_get_memo_model (memo_shell_content); + memo_table = e_memo_shell_content_get_memo_table (memo_shell_content); + memo_preview = e_memo_shell_content_get_memo_preview (memo_shell_content); + + if (e_table_selected_count (table) != 1) { + e_cal_component_preview_clear (memo_preview); + return; + } + + row = e_table_get_cursor_row (table); + comp_data = e_cal_model_get_component_at (memo_model, row); + + comp = e_cal_component_new (); + e_cal_component_set_icalcomponent ( + comp, icalcomponent_new_clone (comp_data->icalcomp)); + e_cal_component_preview_display ( + memo_preview, comp_data->client, comp); + + e_cal_component_get_uid (comp, &uid); + g_free (memo_shell_content->priv->current_uid); + memo_shell_content->priv->current_uid = g_strdup (uid); + + g_object_unref (comp); +} + +static void +memo_shell_content_selection_change_cb (EMemoShellContent *memo_shell_content, + ETable *table) +{ + ECalComponentPreview *memo_preview; + + memo_preview = e_memo_shell_content_get_memo_preview (memo_shell_content); + + /* XXX Old code emits a "selection-changed" signal here. */ + + if (e_table_selected_count (table) != 1) + e_cal_component_preview_clear (memo_preview); +} + +static void +memo_shell_content_model_row_changed_cb (EMemoShellContent *memo_shell_content, + gint row, + ETableModel *model) +{ + ECalModelComponent *comp_data; + EMemoTable *memo_table; + ETable *table; + const gchar *current_uid; + const gchar *uid; + + current_uid = memo_shell_content->priv->current_uid; + if (current_uid == NULL) + return; + + comp_data = e_cal_model_get_component_at (E_CAL_MODEL (model), row); + if (comp_data == NULL) + return; + + uid = icalcomponent_get_uid (comp_data->icalcomp); + if (g_strcmp0 (uid, current_uid) != 0) + return; + + memo_table = e_memo_shell_content_get_memo_table (memo_shell_content); + table = e_memo_table_get_table (memo_table); + + memo_shell_content_cursor_change_cb (memo_shell_content, 0, table); +} + +static void +memo_shell_content_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_PREVIEW_VISIBLE: + e_memo_shell_content_set_preview_visible ( + E_MEMO_SHELL_CONTENT (object), + g_value_get_boolean (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +memo_shell_content_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_MODEL: + g_value_set_object ( + value, e_memo_shell_content_get_memo_model ( + E_MEMO_SHELL_CONTENT (object))); + return; + + case PROP_PREVIEW_VISIBLE: + g_value_set_boolean ( + value, e_memo_shell_content_get_preview_visible ( + E_MEMO_SHELL_CONTENT (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +memo_shell_content_dispose (GObject *object) +{ + EMemoShellContentPrivate *priv; + + priv = E_MEMO_SHELL_CONTENT_GET_PRIVATE (object); + + if (priv->paned != NULL) { + g_object_unref (priv->paned); + priv->paned = NULL; + } + + if (priv->memo_table != NULL) { + g_object_unref (priv->memo_table); + priv->memo_table = NULL; + } + + if (priv->memo_preview != NULL) { + g_object_unref (priv->memo_preview); + priv->memo_preview = NULL; + } + + if (priv->memo_model != NULL) { + g_object_unref (priv->memo_model); + priv->memo_model = NULL; + } + + if (priv->table_config != NULL) { + g_object_unref (priv->table_config); + priv->table_config = NULL; + } + + if (priv->view_instance != NULL) { + g_object_unref (priv->view_instance); + priv->view_instance = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +memo_shell_content_finalize (GObject *object) +{ + EMemoShellContentPrivate *priv; + + priv = E_MEMO_SHELL_CONTENT_GET_PRIVATE (object); + + g_free (priv->current_uid); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +memo_shell_content_constructed (GObject *object) +{ + EMemoShellContentPrivate *priv; + EShellContent *shell_content; + EShellView *shell_view; + GalViewInstance *view_instance; + ETable *table; + GConfBridge *bridge; + GtkWidget *container; + GtkWidget *widget; + const gchar *key; + + priv = E_MEMO_SHELL_CONTENT_GET_PRIVATE (object); + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (parent_class)->constructed (object); + + shell_content = E_SHELL_CONTENT (object); + shell_view = e_shell_content_get_shell_view (shell_content); + + /* Build content widgets. */ + + container = GTK_WIDGET (object); + + widget = gtk_vpaned_new (); + gtk_container_add (GTK_CONTAINER (container), widget); + priv->paned = g_object_ref (widget); + gtk_widget_show (widget); + + container = widget; + + widget = e_memo_table_new (shell_view, priv->memo_model); + gtk_paned_add1 (GTK_PANED (container), widget); + priv->memo_table = g_object_ref (widget); + gtk_widget_show (widget); + + widget = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy ( + GTK_SCROLLED_WINDOW (widget), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type ( + GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN); + gtk_paned_add2 (GTK_PANED (container), widget); + gtk_widget_show (widget); + + container = widget; + + widget = e_cal_component_preview_new (); + e_cal_component_preview_set_default_timezone ( + E_CAL_COMPONENT_PREVIEW (widget), + calendar_config_get_icaltimezone ()); + gtk_container_add (GTK_CONTAINER (container), widget); + priv->memo_preview = g_object_ref (widget); + gtk_widget_show (widget); + + /* Configure the memo table. */ + + widget = E_MEMO_TABLE (priv->memo_table)->etable; + table = e_table_scrolled_get_table (E_TABLE_SCROLLED (widget)); + + priv->table_config = e_memo_table_config_new ( + E_MEMO_TABLE (priv->memo_table)); + + e_table_set_state (table, E_MEMO_TABLE_DEFAULT_STATE); + + e_table_drag_source_set ( + table, GDK_BUTTON1_MASK, + drag_types, G_N_ELEMENTS (drag_types), + GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_ASK); + + g_signal_connect_swapped ( + table, "table-drag-data-get", + G_CALLBACK (memo_shell_content_table_drag_data_get_cb), + object); + + g_signal_connect_swapped ( + table, "table-drag-data-delete", + G_CALLBACK (memo_shell_content_table_drag_data_delete_cb), + object); + + g_signal_connect_swapped ( + table, "cursor-change", + G_CALLBACK (memo_shell_content_cursor_change_cb), + object); + + g_signal_connect_swapped ( + table, "selection-change", + G_CALLBACK (memo_shell_content_selection_change_cb), + object); + + g_signal_connect_swapped ( + priv->memo_model, "model-row-changed", + G_CALLBACK (memo_shell_content_model_row_changed_cb), + object); + + /* Load the view instance. */ + + view_instance = e_shell_view_new_view_instance (shell_view, NULL); + g_signal_connect_swapped ( + view_instance, "display-view", + G_CALLBACK (memo_shell_content_display_view_cb), + object); + gal_view_instance_load (view_instance); + priv->view_instance = view_instance; + + /* Bind GObject properties to GConf keys. */ + + bridge = gconf_bridge_get (); + + object = G_OBJECT (priv->paned); + key = "/apps/evolution/calendar/display/memo_vpane_position"; + gconf_bridge_bind_property_delayed (bridge, key, object, "position"); +} + +static guint32 +memo_shell_content_check_state (EShellContent *shell_content) +{ + EMemoShellContent *memo_shell_content; + EMemoTable *memo_table; + ETable *table; + GSList *list, *iter; + gboolean editable = TRUE; + gboolean has_url = FALSE; + gint n_selected; + guint32 state = 0; + + memo_shell_content = E_MEMO_SHELL_CONTENT (shell_content); + memo_table = e_memo_shell_content_get_memo_table (memo_shell_content); + + table = e_memo_table_get_table (memo_table); + n_selected = e_table_selected_count (table); + + list = e_memo_table_get_selected (memo_table); + for (iter = list; iter != NULL; iter = iter->next) { + ECalModelComponent *comp_data = iter->data; + icalproperty *prop; + gboolean read_only; + + e_cal_is_read_only (comp_data->client, &read_only, NULL); + editable &= !read_only; + + prop = icalcomponent_get_first_property ( + comp_data->icalcomp, ICAL_URL_PROPERTY); + has_url |= (prop != NULL); + } + g_slist_free (list); + + if (n_selected == 1) + state |= E_MEMO_SHELL_CONTENT_SELECTION_SINGLE; + if (n_selected > 1) + state |= E_MEMO_SHELL_CONTENT_SELECTION_MULTIPLE; + if (editable) + state |= E_MEMO_SHELL_CONTENT_SELECTION_CAN_EDIT; + if (has_url) + state |= E_MEMO_SHELL_CONTENT_SELECTION_HAS_URL; + + return state; +} + +static void +memo_shell_content_class_init (EMemoShellContentClass *class) +{ + GObjectClass *object_class; + EShellContentClass *shell_content_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EMemoShellContentPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = memo_shell_content_set_property; + object_class->get_property = memo_shell_content_get_property; + object_class->dispose = memo_shell_content_dispose; + object_class->finalize = memo_shell_content_finalize; + object_class->constructed = memo_shell_content_constructed; + + shell_content_class = E_SHELL_CONTENT_CLASS (class); + shell_content_class->check_state = memo_shell_content_check_state; + + g_object_class_install_property ( + object_class, + PROP_MODEL, + g_param_spec_object ( + "model", + _("Model"), + _("The memo table model"), + E_TYPE_CAL_MODEL, + G_PARAM_READABLE)); + + g_object_class_install_property ( + object_class, + PROP_PREVIEW_VISIBLE, + g_param_spec_boolean ( + "preview-visible", + _("Preview is Visible"), + _("Whether the preview pane is visible"), + TRUE, + G_PARAM_READWRITE)); +} + +static void +memo_shell_content_init (EMemoShellContent *memo_shell_content) +{ + memo_shell_content->priv = + E_MEMO_SHELL_CONTENT_GET_PRIVATE (memo_shell_content); + + memo_shell_content->priv->memo_model = e_cal_model_memos_new (); + + /* Postpone widget construction until we have a shell view. */ +} + +GType +e_memo_shell_content_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EMemoShellContentClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) memo_shell_content_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EMemoShellContent), + 0, /* n_preallocs */ + (GInstanceInitFunc) memo_shell_content_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + E_TYPE_SHELL_CONTENT, "EMemoShellContent", + &type_info, 0); + } + + return type; +} + +GtkWidget * +e_memo_shell_content_new (EShellView *shell_view) +{ + g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); + + return g_object_new ( + E_TYPE_MEMO_SHELL_CONTENT, + "shell-view", shell_view, NULL); +} + +ECalModel * +e_memo_shell_content_get_memo_model (EMemoShellContent *memo_shell_content) +{ + g_return_val_if_fail ( + E_IS_MEMO_SHELL_CONTENT (memo_shell_content), NULL); + + return memo_shell_content->priv->memo_model; +} + +ECalComponentPreview * +e_memo_shell_content_get_memo_preview (EMemoShellContent *memo_shell_content) +{ + g_return_val_if_fail ( + E_IS_MEMO_SHELL_CONTENT (memo_shell_content), NULL); + + return E_CAL_COMPONENT_PREVIEW ( + memo_shell_content->priv->memo_preview); +} + +EMemoTable * +e_memo_shell_content_get_memo_table (EMemoShellContent *memo_shell_content) +{ + g_return_val_if_fail ( + E_IS_MEMO_SHELL_CONTENT (memo_shell_content), NULL); + + return E_MEMO_TABLE (memo_shell_content->priv->memo_table); +} + +GalViewInstance * +e_memo_shell_content_get_view_instance (EMemoShellContent *memo_shell_content) +{ + g_return_val_if_fail ( + E_IS_MEMO_SHELL_CONTENT (memo_shell_content), NULL); + + return memo_shell_content->priv->view_instance; +} + +gboolean +e_memo_shell_content_get_preview_visible (EMemoShellContent *memo_shell_content) +{ + GtkPaned *paned; + GtkWidget *child; + + g_return_val_if_fail ( + E_IS_MEMO_SHELL_CONTENT (memo_shell_content), FALSE); + + paned = GTK_PANED (memo_shell_content->priv->paned); + child = gtk_paned_get_child2 (paned); + + return GTK_WIDGET_VISIBLE (child); +} + +void +e_memo_shell_content_set_preview_visible (EMemoShellContent *memo_shell_content, + gboolean preview_visible) +{ + GtkPaned *paned; + GtkWidget *child; + + g_return_if_fail (E_IS_MEMO_SHELL_CONTENT (memo_shell_content)); + + paned = GTK_PANED (memo_shell_content->priv->paned); + child = gtk_paned_get_child2 (paned); + + if (preview_visible) + gtk_widget_show (child); + else + gtk_widget_hide (child); + + g_object_notify (G_OBJECT (memo_shell_content), "preview-visible"); +} diff --git a/calendar/modules/e-memo-shell-content.h b/calendar/modules/e-memo-shell-content.h new file mode 100644 index 0000000000..9edb986cc1 --- /dev/null +++ b/calendar/modules/e-memo-shell-content.h @@ -0,0 +1,94 @@ +/* + * e-memo-shell-content.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_MEMO_SHELL_CONTENT_H +#define E_MEMO_SHELL_CONTENT_H + +#include <shell/e-shell-content.h> +#include <shell/e-shell-view.h> + +#include <calendar/gui/e-memo-table.h> +#include <calendar/gui/e-cal-component-preview.h> + +#include <widgets/menus/gal-view-instance.h> + +/* Standard GObject macros */ +#define E_TYPE_MEMO_SHELL_CONTENT \ + (e_memo_shell_content_get_type ()) +#define E_MEMO_SHELL_CONTENT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_MEMO_SHELL_CONTENT, EMemoShellContent)) +#define E_MEMO_SHELL_CONTENT_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_MEMO_SHELL_CONTENT, EMemoShellContentClass)) +#define E_IS_MEMO_SHELL_CONTENT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_MEMO_SHELL_CONTENT)) +#define E_IS_MEMO_SHELL_CONTENT_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_MEMO_SHELL_CONTENT)) +#define E_MEMO_SHELL_CONTENT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_MEMO_SHELL_CONTENT, EMemoShellContentClass)) + +G_BEGIN_DECLS + +typedef struct _EMemoShellContent EMemoShellContent; +typedef struct _EMemoShellContentClass EMemoShellContentClass; +typedef struct _EMemoShellContentPrivate EMemoShellContentPrivate; + +enum { + E_MEMO_SHELL_CONTENT_SELECTION_SINGLE = 1 << 0, + E_MEMO_SHELL_CONTENT_SELECTION_MULTIPLE = 1 << 1, + E_MEMO_SHELL_CONTENT_SELECTION_CAN_EDIT = 1 << 2, + E_MEMO_SHELL_CONTENT_SELECTION_HAS_URL = 1 << 3 +}; + +struct _EMemoShellContent { + EShellContent parent; + EMemoShellContentPrivate *priv; +}; + +struct _EMemoShellContentClass { + EShellContentClass parent_class; +}; + +GType e_memo_shell_content_get_type (void); +GtkWidget * e_memo_shell_content_new (EShellView *shell_view); +ECalModel * e_memo_shell_content_get_memo_model + (EMemoShellContent *memo_shell_conent); +ECalComponentPreview * + e_memo_shell_content_get_memo_preview + (EMemoShellContent *memo_shell_content); +EMemoTable * e_memo_shell_content_get_memo_table + (EMemoShellContent *memo_shell_content); +GalViewInstance * + e_memo_shell_content_get_view_instance + (EMemoShellContent *memo_shell_content); +gboolean e_memo_shell_content_get_preview_visible + (EMemoShellContent *memo_shell_content); +void e_memo_shell_content_set_preview_visible + (EMemoShellContent *memo_shell_content, + gboolean preview_visible); + +G_END_DECLS + +#endif /* E_MEMO_SHELL_CONTENT_H */ diff --git a/calendar/modules/e-memo-shell-module-migrate.c b/calendar/modules/e-memo-shell-module-migrate.c new file mode 100644 index 0000000000..7fe9442d5e --- /dev/null +++ b/calendar/modules/e-memo-shell-module-migrate.c @@ -0,0 +1,257 @@ +/* + * e-memo-shell-module-migrate.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-memo-shell-module-migrate.h" + +#include <string.h> +#include <glib/gi18n.h> +#include <camel/camel-url.h> +#include <libedataserver/e-account.h> +#include <libedataserver/e-account-list.h> +#include <libedataserver/e-source.h> +#include <libedataserver/e-source-group.h> +#include <libedataserver/e-source-list.h> + +#include "calendar/gui/calendar-config.h" +#include "calendar/gui/calendar-config-keys.h" + +#define WEBCAL_BASE_URI "webcal://" +#define PERSONAL_RELATIVE_URI "system" +#define GROUPWISE_BASE_URI "groupwise://" + +static void +create_memo_sources (EShellModule *shell_module, + ESourceList *source_list, + ESourceGroup **on_this_computer, + ESourceGroup **on_the_web, + ESource **personal_source) +{ + GSList *groups; + ESourceGroup *group; + char *base_uri, *base_uri_proto; + const gchar *base_dir; + + *on_this_computer = NULL; + *on_the_web = NULL; + *personal_source = NULL; + + base_dir = e_shell_module_get_config_dir (shell_module); + base_uri = g_build_filename (base_dir, "local", NULL); + + base_uri_proto = g_filename_to_uri (base_uri, NULL, NULL); + + groups = e_source_list_peek_groups (source_list); + if (groups) { + /* groups are already there, we need to search for things... */ + GSList *g; + + for (g = groups; g; g = g->next) { + + group = E_SOURCE_GROUP (g->data); + + if (!*on_this_computer && !strcmp (base_uri_proto, e_source_group_peek_base_uri (group))) + *on_this_computer = g_object_ref (group); + else if (!*on_the_web && !strcmp (WEBCAL_BASE_URI, e_source_group_peek_base_uri (group))) + *on_the_web = g_object_ref (group); + } + } + + if (*on_this_computer) { + /* make sure "Personal" shows up as a source under + this group */ + GSList *sources = e_source_group_peek_sources (*on_this_computer); + GSList *s; + for (s = sources; s; s = s->next) { + ESource *source = E_SOURCE (s->data); + const gchar *relative_uri; + + relative_uri = e_source_peek_relative_uri (source); + if (relative_uri == NULL) + continue; + if (!strcmp (PERSONAL_RELATIVE_URI, relative_uri)) { + *personal_source = g_object_ref (source); + break; + } + } + } else { + /* create the local source group */ + group = e_source_group_new (_("On This Computer"), base_uri_proto); + e_source_list_add_group (source_list, group, -1); + + *on_this_computer = group; + } + + if (!*personal_source) { + /* Create the default Person task list */ + ESource *source = e_source_new (_("Personal"), PERSONAL_RELATIVE_URI); + e_source_group_add_source (*on_this_computer, source, -1); + + if (!calendar_config_get_primary_memos () && !calendar_config_get_memos_selected ()) { + GSList selected; + + calendar_config_set_primary_memos (e_source_peek_uid (source)); + + selected.data = (gpointer)e_source_peek_uid (source); + selected.next = NULL; + calendar_config_set_memos_selected (&selected); + } + + e_source_set_color_spec (source, "#BECEDD"); + *personal_source = source; + } + + if (!*on_the_web) { + /* Create the Webcal source group */ + group = e_source_group_new (_("On The Web"), WEBCAL_BASE_URI); + e_source_list_add_group (source_list, group, -1); + + *on_the_web = group; + } + + g_free (base_uri_proto); + g_free (base_uri); +} + +static gboolean +is_groupwise_account (EAccount *account) +{ + if (account->source->url != NULL) { + return g_str_has_prefix (account->source->url, GROUPWISE_BASE_URI); + } else { + return FALSE; + } +} + +static void +add_gw_esource (ESourceList *source_list, const char *group_name, const char *source_name, CamelURL *url, GConfClient *client) +{ + ESourceGroup *group; + ESource *source; + GSList *ids, *temp ; + GError *error = NULL; + char *relative_uri; + const char *soap_port; + const char * use_ssl; + const char *poa_address; + const char *offline_sync; + + + poa_address = url->host; + if (!poa_address || strlen (poa_address) ==0) + return; + soap_port = camel_url_get_param (url, "soap_port"); + + if (!soap_port || strlen (soap_port) == 0) + soap_port = "7191"; + + use_ssl = camel_url_get_param (url, "use_ssl"); + offline_sync = camel_url_get_param (url, "offline_sync"); + + group = e_source_group_new (group_name, GROUPWISE_BASE_URI); + if (!e_source_list_add_group (source_list, group, -1)) + return; + relative_uri = g_strdup_printf ("%s@%s/", url->user, poa_address); + + source = e_source_new (source_name, relative_uri); + e_source_set_property (source, "auth", "1"); + e_source_set_property (source, "username", url->user); + e_source_set_property (source, "port", camel_url_get_param (url, "soap_port")); + e_source_set_property (source, "auth-domain", "Groupwise"); + e_source_set_property (source, "use_ssl", use_ssl); + e_source_set_property (source, "offline_sync", offline_sync ? "1" : "0" ); + + e_source_set_color_spec (source, "#EEBC60"); + e_source_group_add_source (group, source, -1); + + ids = gconf_client_get_list (client, CALENDAR_CONFIG_MEMOS_SELECTED_MEMOS, GCONF_VALUE_STRING, &error); + if ( error != NULL ) { + g_warning("%s (%s) %s\n", G_STRLOC, G_STRFUNC, error->message); + g_error_free(error); + } + ids = g_slist_append (ids, g_strdup (e_source_peek_uid (source))); + gconf_client_set_list (client, CALENDAR_CONFIG_MEMOS_SELECTED_MEMOS, GCONF_VALUE_STRING, ids, NULL); + temp = ids; + for (; temp != NULL; temp = g_slist_next (temp)) + g_free (temp->data); + + g_slist_free (ids); + g_object_unref (source); + g_object_unref (group); + g_free (relative_uri); +} + +gboolean +e_memo_shell_module_migrate (EShellModule *shell_module, + gint major, + gint minor, + gint revision, + GError **error) +{ + ESourceGroup *on_this_computer = NULL; + ESourceGroup *on_the_web = NULL; + ESource *personal_source = NULL; + ESourceList *source_list = NULL; + gboolean retval = FALSE; + + source_list = g_object_get_data ( + G_OBJECT (shell_module), "source-list"); + + /* we call this unconditionally now - create_groups either + creates the groups/sources or it finds the necessary + groups/sources. */ + create_memo_sources ( + shell_module, source_list, &on_this_computer, + &on_the_web, &personal_source); + + /* Migration for Gw accounts between versions < 2.8 */ + if (major == 2 && minor < 8) { + EAccountList *al; + EAccount *a; + CamelURL *url; + EIterator *it; + GConfClient *gconf_client = gconf_client_get_default (); + al = e_account_list_new (gconf_client); + for (it = e_list_get_iterator((EList *)al); + e_iterator_is_valid(it); + e_iterator_next(it)) { + a = (EAccount *) e_iterator_get(it); + if (!a->enabled || !is_groupwise_account (a)) + continue; + url = camel_url_new (a->source->url, NULL); + add_gw_esource (source_list, a->name, _("Notes"), url, gconf_client); + camel_url_free (url); + } + g_object_unref (al); + g_object_unref (gconf_client); + } + + e_source_list_sync (source_list, NULL); + retval = TRUE; + + if (on_this_computer) + g_object_unref (on_this_computer); + if (on_the_web) + g_object_unref (on_the_web); + if (personal_source) + g_object_unref (personal_source); + + return retval; +} diff --git a/calendar/gui/migration.h b/calendar/modules/e-memo-shell-module-migrate.h index 4073e31fac..e40e2ff00f 100644 --- a/calendar/gui/migration.h +++ b/calendar/modules/e-memo-shell-module-migrate.h @@ -1,4 +1,5 @@ /* + * e-memo-shell-module-migrate.h * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -14,24 +15,24 @@ * License along with the program; if not, see <http://www.gnu.org/licenses/> * * - * Authors: - * Rodrigo Moya <rodrigo@ximian.com> - * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * */ -#ifndef MIGRATION_H -#define MIGRATION_H +#ifndef E_MEMO_SHELL_MODULE_MIGRATE_H +#define E_MEMO_SHELL_MODULE_MIGRATE_H + +#include <glib.h> +#include <shell/e-shell-module.h> + +G_BEGIN_DECLS -#include <libedataserver/e-source-group.h> -#include "calendar-component.h" -#include "tasks-component.h" -#include "memos-component.h" +gboolean e_memo_shell_module_migrate (EShellModule *shell_module, + gint major, + gint minor, + gint micro, + GError **error); -struct _GError; +G_END_DECLS -gboolean migrate_calendars (CalendarComponent *component, int major, int minor, int revision, struct _GError **err); -gboolean migrate_tasks (TasksComponent *component, int major, int minor, int revision, struct _GError **err); -gboolean migrate_memos (MemosComponent *component, int major, int minor, int revision, struct _GError **err); -#endif +#endif /* E_MEMO_SHELL_MODULE_MIGRATE_H */ diff --git a/calendar/modules/e-memo-shell-module.c b/calendar/modules/e-memo-shell-module.c new file mode 100644 index 0000000000..913d5b3a26 --- /dev/null +++ b/calendar/modules/e-memo-shell-module.c @@ -0,0 +1,516 @@ +/* + * e-memo-shell-module.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include <string.h> +#include <glib/gi18n.h> +#include <libecal/e-cal.h> +#include <libedataserver/e-url.h> +#include <libedataserver/e-source.h> +#include <libedataserver/e-source-list.h> +#include <libedataserver/e-source-group.h> + +#include "shell/e-shell.h" +#include "shell/e-shell-module.h" +#include "shell/e-shell-window.h" + +#include "calendar/common/authentication.h" +#include "calendar/gui/calendar-config.h" +#include "calendar/gui/comp-util.h" +#include "calendar/gui/dialogs/calendar-setup.h" +#include "calendar/gui/dialogs/memo-editor.h" + +#include "e-memo-shell-view.h" +#include "e-memo-shell-module-migrate.h" + +#define MODULE_NAME "memos" +#define MODULE_ALIASES "" +#define MODULE_SCHEMES "memo" +#define MODULE_SORT_ORDER 500 + +#define WEB_BASE_URI "webcal://" +#define PERSONAL_RELATIVE_URI "system" + +/* Module Entry Point */ +void e_shell_module_init (GTypeModule *type_module); + +static void +memo_module_ensure_sources (EShellModule *shell_module) +{ + /* XXX This is basically the same algorithm across all modules. + * Maybe we could somehow integrate this into EShellModule? */ + + ESourceList *source_list; + ESourceGroup *on_this_computer; + ESourceGroup *on_the_web; + ESource *personal; + GSList *groups, *iter; + const gchar *data_dir; + const gchar *name; + gchar *base_uri; + gchar *filename; + + on_this_computer = NULL; + on_the_web = NULL; + personal = NULL; + + if (!e_cal_get_sources (&source_list, E_CAL_SOURCE_TYPE_JOURNAL, NULL)) { + g_warning ("Could not get memo sources from GConf!"); + return; + } + + /* Share the source list with all memo views. This is + * accessible via e_memo_shell_view_get_source_list(). + * Note: EShellModule takes ownership of the reference. + * + * XXX I haven't yet decided if I want to add a proper + * EShellModule API for this. The mail module would + * not use it. */ + g_object_set_data_full ( + G_OBJECT (shell_module), "source-list", + source_list, (GDestroyNotify) g_object_unref); + + data_dir = e_shell_module_get_data_dir (shell_module); + filename = g_build_filename (data_dir, "local", NULL); + base_uri = g_filename_to_uri (filename, NULL, NULL); + g_free (filename); + + groups = e_source_list_peek_groups (source_list); + for (iter = groups; iter != NULL; iter = iter->next) { + ESourceGroup *source_group = iter->data; + const gchar *group_base_uri; + + group_base_uri = e_source_group_peek_base_uri (source_group); + + /* Compare only "file://" part. If the user's home + * changes, we do not want to create another group. */ + if (on_this_computer == NULL && + strncmp (base_uri, group_base_uri, 7) == 0) + on_this_computer = source_group; + + else if (on_the_web == NULL && + strcmp (WEB_BASE_URI, group_base_uri) == 0) + on_the_web = source_group; + } + + name = _("On This Computer"); + + if (on_this_computer != NULL) { + GSList *sources; + const gchar *group_base_uri; + + /* Force the group name to the current locale. */ + e_source_group_set_name (on_this_computer, name); + + sources = e_source_group_peek_sources (on_this_computer); + group_base_uri = e_source_group_peek_base_uri (on_this_computer); + + /* Make sure this group includes a "Personal" source. */ + for (iter = sources; iter != NULL; iter = iter->next) { + ESource *source = iter->data; + const gchar *relative_uri; + + relative_uri = e_source_peek_relative_uri (source); + if (relative_uri == NULL) + continue; + + if (strcmp (PERSONAL_RELATIVE_URI, relative_uri) != 0) + continue; + + personal = source; + break; + } + + /* Make sure we have the correct base URI. This can + * change when the user's home directory changes. */ + if (strcmp (base_uri, group_base_uri) != 0) { + e_source_group_set_base_uri ( + on_this_computer, base_uri); + + /* XXX We shouldn't need this sync call here as + * set_base_uri() results in synching to GConf, + * but that happens in an idle loop and too late + * to prevent the user from seeing a "Cannot + * Open ... because of invalid URI" error. */ + e_source_list_sync (source_list, NULL); + } + + } else { + ESourceGroup *source_group; + + source_group = e_source_group_new (name, base_uri); + e_source_list_add_group (source_list, source_group, -1); + g_object_unref (source_group); + } + + name = _("Personal"); + + if (personal == NULL) { + ESource *source; + GSList *selected; + gchar *primary; + + source = e_source_new (name, PERSONAL_RELATIVE_URI); + e_source_group_add_source (on_this_computer, source, -1); + g_object_unref (source); + + primary = calendar_config_get_primary_memos (); + selected = calendar_config_get_memos_selected (); + + if (primary == NULL && selected == NULL) { + const gchar *uid; + + uid = e_source_peek_uid (source); + selected = g_slist_prepend (NULL, g_strdup (uid)); + + calendar_config_set_primary_memos (uid); + calendar_config_set_memos_selected (selected); + } + + g_slist_foreach (selected, (GFunc) g_free, NULL); + g_slist_free (selected); + g_free (primary); + } else { + /* Force the source name to the current locale. */ + e_source_set_name (personal, name); + } + + name = _("On The Web"); + + if (on_the_web == NULL) { + ESourceGroup *source_group; + + source_group = e_source_group_new (name, WEB_BASE_URI); + e_source_list_add_group (source_list, source_group, -1); + g_object_unref (source_group); + } else { + /* Force the group name to the current locale. */ + e_source_group_set_name (on_the_web, name); + } + + g_free (base_uri); +} + +static void +memo_module_cal_opened_cb (ECal *cal, + ECalendarStatus status, + GtkAction *action) +{ + EShell *shell; + ECalComponent *comp; + CompEditor *editor; + CompEditorFlags flags = 0; + const gchar *action_name; + + /* FIXME Pass this in. */ + shell = e_shell_get_default (); + + /* XXX Handle errors better. */ + if (status != E_CALENDAR_STATUS_OK) + return; + + action_name = gtk_action_get_name (action); + + flags |= COMP_EDITOR_NEW_ITEM; + if (strcmp (action_name, "memo-shared-new") == 0) { + flags |= COMP_EDITOR_IS_SHARED; + flags |= COMP_EDITOR_USER_ORG; + } + + editor = memo_editor_new (cal, shell, flags); + comp = cal_comp_memo_new_with_defaults (cal); + comp_editor_edit_comp (editor, comp); + + gtk_window_present (GTK_WINDOW (editor)); + + g_object_unref (comp); + g_object_unref (cal); +} + +static void +action_memo_new_cb (GtkAction *action, + EShellWindow *shell_window) +{ + ECal *cal = NULL; + ECalSourceType source_type; + ESourceList *source_list; + gchar *uid; + + /* This callback is used for both memos and shared memos. */ + + source_type = E_CAL_SOURCE_TYPE_JOURNAL; + + if (!e_cal_get_sources (&source_list, source_type, NULL)) { + g_warning ("Could not get memo sources from GConf!"); + return; + } + + uid = calendar_config_get_primary_memos (); + + if (uid != NULL) { + ESource *source; + + source = e_source_list_peek_source_by_uid (source_list, uid); + if (source != NULL) + cal = auth_new_cal_from_source (source, source_type); + g_free (uid); + } + + if (cal == NULL) + cal = auth_new_cal_from_default (source_type); + + g_return_if_fail (cal != NULL); + + g_signal_connect ( + cal, "cal-opened", + G_CALLBACK (memo_module_cal_opened_cb), action); + + e_cal_open_async (cal, FALSE); +} + +static void +action_memo_list_new_cb (GtkAction *action, + EShellWindow *shell_window) +{ + calendar_setup_new_memo_list (GTK_WINDOW (shell_window)); +} + +static GtkActionEntry item_entries[] = { + + { "memo-new", + "stock_insert-note", + NC_("New", "Mem_o"), + "<Shift><Control>o", + N_("Create a new memo"), + G_CALLBACK (action_memo_new_cb) }, + + { "memo-shared-new", + "stock_insert-note", + N_("_Shared Memo"), + "<Shift><Control>h", + N_("Create a new shared memo"), + G_CALLBACK (action_memo_new_cb) } +}; + +static GtkActionEntry source_entries[] = { + + { "memo-list-new", + "stock_notes", + NC_("New", "Memo Li_st"), + NULL, + N_("Create a new memo list"), + G_CALLBACK (action_memo_list_new_cb) } +}; + +static gboolean +memo_module_handle_uri_cb (EShellModule *shell_module, + const gchar *uri) +{ + EShell *shell; + 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; + shell = e_shell_module_get_shell (shell_module); + + 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, shell, 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 +memo_module_window_created_cb (EShellModule *shell_module, + GtkWindow *window) +{ + const gchar *module_name; + + if (!E_IS_SHELL_WINDOW (window)) + return; + + module_name = G_TYPE_MODULE (shell_module)->name; + + e_shell_window_register_new_item_actions ( + E_SHELL_WINDOW (window), module_name, + item_entries, G_N_ELEMENTS (item_entries)); + + e_shell_window_register_new_source_actions ( + E_SHELL_WINDOW (window), module_name, + source_entries, G_N_ELEMENTS (source_entries)); +} + +static EShellModuleInfo module_info = { + + MODULE_NAME, + MODULE_ALIASES, + MODULE_SCHEMES, + MODULE_SORT_ORDER, + + /* start */ NULL, + /* is_busy */ NULL, + /* shutdown */ NULL, + e_memo_shell_module_migrate +}; + +void +e_shell_module_init (GTypeModule *type_module) +{ + EShell *shell; + EShellModule *shell_module; + + shell_module = E_SHELL_MODULE (type_module); + shell = e_shell_module_get_shell (shell_module); + + e_shell_module_set_info ( + shell_module, &module_info, + e_memo_shell_view_get_type (type_module)); + + memo_module_ensure_sources (shell_module); + + g_signal_connect_swapped ( + shell, "handle-uri", + G_CALLBACK (memo_module_handle_uri_cb), shell_module); + + g_signal_connect_swapped ( + shell, "window-created", + G_CALLBACK (memo_module_window_created_cb), shell_module); +} diff --git a/calendar/modules/e-memo-shell-sidebar.c b/calendar/modules/e-memo-shell-sidebar.c new file mode 100644 index 0000000000..4dcff2ff35 --- /dev/null +++ b/calendar/modules/e-memo-shell-sidebar.c @@ -0,0 +1,714 @@ +/* + * e-memo-shell-sidebar.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-memo-shell-sidebar.h" + +#include <string.h> +#include <glib/gi18n.h> +#include <libecal/e-cal.h> + +#include "e-util/e-error.h" +#include "e-util/e-util.h" +#include "calendar/common/authentication.h" +#include "calendar/gui/calendar-config.h" +#include "calendar/gui/e-memo-list-selector.h" +#include "calendar/gui/misc.h" + +#include "e-memo-shell-view.h" + +#define E_MEMO_SHELL_SIDEBAR_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_MEMO_SHELL_SIDEBAR, EMemoShellSidebarPrivate)) + +struct _EMemoShellSidebarPrivate { + GtkWidget *selector; + + /* UID -> Client */ + GHashTable *client_table; +}; + +enum { + PROP_0, + PROP_SELECTOR +}; + +enum { + CLIENT_ADDED, + CLIENT_REMOVED, + STATUS_MESSAGE, + LAST_SIGNAL +}; + +static gpointer parent_class; +static guint signals[LAST_SIGNAL]; + +static void +memo_shell_sidebar_emit_client_added (EMemoShellSidebar *memo_shell_sidebar, + ECal *client) +{ + guint signal_id = signals[CLIENT_ADDED]; + + g_signal_emit (memo_shell_sidebar, signal_id, 0, client); +} + +static void +memo_shell_sidebar_emit_client_removed (EMemoShellSidebar *memo_shell_sidebar, + ECal *client) +{ + guint signal_id = signals[CLIENT_REMOVED]; + + g_signal_emit (memo_shell_sidebar, signal_id, 0, client); +} + +static void +memo_shell_sidebar_emit_status_message (EMemoShellSidebar *memo_shell_sidebar, + const gchar *status_message) +{ + guint signal_id = signals[STATUS_MESSAGE]; + + g_signal_emit (memo_shell_sidebar, signal_id, 0, status_message, -1.0); +} + +static void +memo_shell_sidebar_update_timezone (EMemoShellSidebar *memo_shell_sidebar) +{ + GHashTable *client_table; + icaltimezone *zone; + GList *values; + + zone = calendar_config_get_icaltimezone (); + client_table = memo_shell_sidebar->priv->client_table; + values = g_hash_table_get_values (client_table); + + while (values != NULL) { + ECal *client = values->data; + + if (e_cal_get_load_state (client) == E_CAL_LOAD_LOADED) + e_cal_set_default_timezone (client, zone, NULL); + + values = g_list_delete_link (values, values); + } + + /* XXX Need to call e_cal_component_preview_set_default_timezone() + * here but the sidebar is not really supposed to access content + * stuff. I guess we could emit an "update-timezone" signal + * here, but that feels wrong. Maybe this whole thing should + * be in EMemoShellView instead. */ +} + +static void +memo_shell_sidebar_backend_died_cb (EMemoShellSidebar *memo_shell_sidebar, + ECal *client) +{ + EShellView *shell_view; + EShellWindow *shell_window; + EShellSidebar *shell_sidebar; + GHashTable *client_table; + ESource *source; + const gchar *uid; + + client_table = memo_shell_sidebar->priv->client_table; + + shell_sidebar = E_SHELL_SIDEBAR (memo_shell_sidebar); + shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); + shell_window = e_shell_view_get_shell_window (shell_view); + + source = e_cal_get_source (client); + uid = e_source_peek_uid (source); + + g_object_ref (source); + + g_hash_table_remove (client_table, uid); + memo_shell_sidebar_emit_status_message (memo_shell_sidebar, NULL); + + e_error_run ( + GTK_WINDOW (shell_window), + "calendar:memos-crashed", NULL); + + g_object_unref (source); +} + +static void +memo_shell_sidebar_backend_error_cb (EMemoShellSidebar *memo_shell_sidebar, + const gchar *message, + ECal *client) +{ + EShellView *shell_view; + EShellWindow *shell_window; + EShellSidebar *shell_sidebar; + GtkWidget *dialog; + const gchar *uri; + gchar *uri_no_passwd; + + shell_sidebar = E_SHELL_SIDEBAR (memo_shell_sidebar); + shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); + shell_window = e_shell_view_get_shell_window (shell_view); + + uri = e_cal_get_uri (client); + uri_no_passwd = get_uri_without_password (uri); + + dialog = gtk_message_dialog_new ( + GTK_WINDOW (shell_window), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, + _("Error on %s\n%s"), + uri_no_passwd, message); + + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + + g_free (uri_no_passwd); +} + +static void +memo_shell_sidebar_client_opened_cb (EMemoShellSidebar *memo_shell_sidebar, + ECalendarStatus status, + ECal *client) +{ + EShellView *shell_view; + EShellWindow *shell_window; + EShellSidebar *shell_sidebar; + ESource *source; + + source = e_cal_get_source (client); + + shell_sidebar = E_SHELL_SIDEBAR (memo_shell_sidebar); + shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); + shell_window = e_shell_view_get_shell_window (shell_view); + + if (status == E_CALENDAR_STATUS_AUTHENTICATION_FAILED || + status == E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED) + auth_cal_forget_password (client); + + switch (status) { + case E_CALENDAR_STATUS_OK: + g_signal_handlers_disconnect_matched ( + client, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, + memo_shell_sidebar_client_opened_cb, NULL); + + memo_shell_sidebar_emit_status_message ( + memo_shell_sidebar, _("Loading memos")); + memo_shell_sidebar_emit_client_added ( + memo_shell_sidebar, client); + memo_shell_sidebar_emit_status_message ( + memo_shell_sidebar, NULL); + break; + + case E_CALENDAR_STATUS_AUTHENTICATION_FAILED: + e_cal_open_async (client, FALSE); + break; + + case E_CALENDAR_STATUS_BUSY: + break; + + case E_CALENDAR_STATUS_REPOSITORY_OFFLINE: + e_error_run ( + GTK_WINDOW (shell_window), + "calendar:prompt-no-contents-offline-memos", + NULL); + break; + + default: + memo_shell_sidebar_emit_client_removed ( + memo_shell_sidebar, client); + break; + } +} + +static void +memo_shell_sidebar_row_changed_cb (EMemoShellSidebar *memo_shell_sidebar, + GtkTreePath *tree_path, + GtkTreeIter *tree_iter, + GtkTreeModel *tree_model) +{ + ESourceSelector *selector; + ESource *source; + + /* XXX ESourceSelector's underlying tree store has only one + * column: ESource objects. While we're not supposed to + * know this, listening for "row-changed" signals from + * the model is easier to deal with than the selector's + * "selection-changed" signal, which doesn't tell you + * _which_ row changed. */ + + selector = e_memo_shell_sidebar_get_selector (memo_shell_sidebar); + gtk_tree_model_get (tree_model, tree_iter, 0, &source, -1); + + /* XXX This signal gets emitted a lot while the model is being + * rebuilt, during which time we won't get a valid ESource. + * ESourceSelector should probably block this signal while + * rebuilding the model, but we'll be forgiving and not + * emit a warning. */ + if (!E_IS_SOURCE (source)) + return; + + if (e_source_selector_source_is_selected (selector, source)) + e_memo_shell_sidebar_add_source (memo_shell_sidebar, source); + else + e_memo_shell_sidebar_remove_source (memo_shell_sidebar, source); +} + +static void +memo_shell_sidebar_selection_changed_cb (EMemoShellSidebar *memo_shell_sidebar, + ESourceSelector *selector) +{ + GSList *list, *iter; + + /* This signal is emitted less frequently than "row-changed", + * especially when the model is being rebuilt. So we'll take + * it easy on poor GConf. */ + + list = e_source_selector_get_selection (selector); + + for (iter = list; iter != NULL; iter = iter->next) { + ESource *source = iter->data; + + iter->data = (gpointer) e_source_peek_uid (source); + g_object_unref (source); + } + + calendar_config_set_memos_selected (list); + + g_slist_free (list); +} + +static void +memo_shell_sidebar_primary_selection_changed_cb (EMemoShellSidebar *memo_shell_sidebar, + ESourceSelector *selector) +{ + ESource *source; + const gchar *uid; + + /* XXX ESourceSelector needs a "primary-selection-uid" property + * so we can just bind the property with GConfBridge. */ + + source = e_source_selector_peek_primary_selection (selector); + if (source == NULL) + return; + + uid = e_source_peek_uid (source); + calendar_config_set_primary_memos (uid); +} + +static void +memo_shell_sidebar_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_SELECTOR: + g_value_set_object ( + value, e_memo_shell_sidebar_get_selector ( + E_MEMO_SHELL_SIDEBAR (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +memo_shell_sidebar_dispose (GObject *object) +{ + EMemoShellSidebarPrivate *priv; + + priv = E_MEMO_SHELL_SIDEBAR_GET_PRIVATE (object); + + if (priv->selector != NULL) { + g_object_unref (priv->selector); + priv->selector = NULL; + } + + g_hash_table_remove_all (priv->client_table); + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +memo_shell_sidebar_finalize (GObject *object) +{ + EMemoShellSidebarPrivate *priv; + + priv = E_MEMO_SHELL_SIDEBAR_GET_PRIVATE (object); + + g_hash_table_destroy (priv->client_table); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +memo_shell_sidebar_constructed (GObject *object) +{ + EMemoShellSidebarPrivate *priv; + EShellView *shell_view; + EShellSidebar *shell_sidebar; + EMemoShellView *memo_shell_view; + ESourceSelector *selector; + ESourceList *source_list; + ESource *source; + GtkContainer *container; + GtkTreeModel *model; + GtkWidget *widget; + AtkObject *a11y; + GSList *list, *iter; + gchar *uid; + + priv = E_MEMO_SHELL_SIDEBAR_GET_PRIVATE (object); + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (parent_class)->constructed (object); + + shell_sidebar = E_SHELL_SIDEBAR (object); + shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); + memo_shell_view = E_MEMO_SHELL_VIEW (shell_view); + source_list = e_memo_shell_view_get_source_list (memo_shell_view); + + container = GTK_CONTAINER (shell_sidebar); + + widget = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy ( + GTK_SCROLLED_WINDOW (widget), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type ( + GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN); + gtk_container_add (container, widget); + gtk_widget_show (widget); + + container = GTK_CONTAINER (widget); + + widget = e_memo_list_selector_new (source_list); + e_source_selector_set_select_new (E_SOURCE_SELECTOR (widget), TRUE); + gtk_container_add (container, widget); + a11y = gtk_widget_get_accessible (widget); + atk_object_set_name (a11y, _("Memo List Selector")); + priv->selector = g_object_ref (widget); + gtk_widget_show (widget); + + /* Restore the selector state from the last session. */ + + selector = E_SOURCE_SELECTOR (priv->selector); + model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget)); + + g_signal_connect_swapped ( + model, "row-changed", + G_CALLBACK (memo_shell_sidebar_row_changed_cb), + object); + + source = NULL; + uid = calendar_config_get_primary_memos (); + if (uid != NULL) + source = e_source_list_peek_source_by_uid (source_list, uid); + if (source == NULL) + source = e_source_list_peek_source_any (source_list); + if (source != NULL) + e_source_selector_set_primary_selection (selector, source); + g_free (uid); + + list = calendar_config_get_memos_selected (); + for (iter = list; iter != NULL; iter = iter->next) { + uid = iter->data; + source = e_source_list_peek_source_by_uid (source_list, uid); + g_free (uid); + + if (source == NULL) + continue; + + e_source_selector_select_source (selector, source); + } + g_slist_free (list); + + /* Listen for subsequent changes to the selector. */ + + g_signal_connect_swapped ( + widget, "selection-changed", + G_CALLBACK (memo_shell_sidebar_selection_changed_cb), + object); + + g_signal_connect_swapped ( + widget, "primary-selection-changed", + G_CALLBACK (memo_shell_sidebar_primary_selection_changed_cb), + object); +} + +static guint32 +memo_shell_sidebar_check_state (EShellSidebar *shell_sidebar) +{ + EMemoShellSidebar *memo_shell_sidebar; + ESourceSelector *selector; + ESource *source; + gboolean is_system = FALSE; + guint32 state = 0; + + memo_shell_sidebar = E_MEMO_SHELL_SIDEBAR (shell_sidebar); + selector = e_memo_shell_sidebar_get_selector (memo_shell_sidebar); + source = e_source_selector_peek_primary_selection (selector); + + if (source != NULL) { + const gchar *uri; + + uri = e_source_peek_relative_uri (source); + is_system = (uri == NULL || strcmp (uri, "system") == 0); + } + + if (source != NULL) + state |= E_MEMO_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE; + if (is_system) + state |= E_MEMO_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_SYSTEM; + + return state; +} + +static void +memo_shell_sidebar_client_added (EMemoShellSidebar *memo_shell_sidebar, + ECal *client) +{ + memo_shell_sidebar_update_timezone (memo_shell_sidebar); +} + +static void +memo_shell_sidebar_client_removed (EMemoShellSidebar *memo_shell_sidebar, + ECal *client) +{ + ESourceSelector *selector; + GHashTable *client_table; + ESource *source; + const gchar *uid; + + client_table = memo_shell_sidebar->priv->client_table; + selector = e_memo_shell_sidebar_get_selector (memo_shell_sidebar); + + g_signal_handlers_disconnect_matched ( + client, G_SIGNAL_MATCH_DATA, 0, 0, + NULL, NULL, memo_shell_sidebar); + + source = e_cal_get_source (client); + e_source_selector_unselect_source (selector, source); + + uid = e_source_peek_uid (source); + g_hash_table_remove (client_table, uid); + + memo_shell_sidebar_emit_status_message (memo_shell_sidebar, NULL); +} + +static void +memo_shell_sidebar_class_init (EMemoShellSidebarClass *class) +{ + GObjectClass *object_class; + EShellSidebarClass *shell_sidebar_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EMemoShellSidebarPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->get_property = memo_shell_sidebar_get_property; + object_class->dispose = memo_shell_sidebar_dispose; + object_class->finalize = memo_shell_sidebar_finalize; + object_class->constructed = memo_shell_sidebar_constructed; + + shell_sidebar_class = E_SHELL_SIDEBAR_CLASS (class); + shell_sidebar_class->check_state = memo_shell_sidebar_check_state; + + class->client_added = memo_shell_sidebar_client_added; + class->client_removed = memo_shell_sidebar_client_removed; + + g_object_class_install_property ( + object_class, + PROP_SELECTOR, + g_param_spec_object ( + "selector", + _("Source Selector Widget"), + _("This widget displays groups of memo lists"), + E_TYPE_SOURCE_SELECTOR, + G_PARAM_READABLE)); + + signals[CLIENT_ADDED] = g_signal_new ( + "client-added", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EMemoShellSidebarClass, client_added), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + E_TYPE_CAL); + + signals[CLIENT_REMOVED] = g_signal_new ( + "client-removed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EMemoShellSidebarClass, client_removed), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + E_TYPE_CAL); + + signals[STATUS_MESSAGE] = g_signal_new ( + "status-message", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (EMemoShellSidebarClass, status_message), + NULL, NULL, + e_marshal_VOID__STRING_DOUBLE, + G_TYPE_NONE, 2, + G_TYPE_STRING, + G_TYPE_DOUBLE); +} + +static void +memo_shell_sidebar_init (EMemoShellSidebar *memo_shell_sidebar) +{ + GHashTable *client_table; + + client_table = g_hash_table_new_full ( + g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) g_object_unref); + + memo_shell_sidebar->priv = + E_MEMO_SHELL_SIDEBAR_GET_PRIVATE (memo_shell_sidebar); + + memo_shell_sidebar->priv->client_table = client_table; + + /* Postpone widget construction until we have a shell view. */ +} + +GType +e_memo_shell_sidebar_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EMemoShellSidebarClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) memo_shell_sidebar_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EMemoShellSidebar), + 0, /* n_preallocs */ + (GInstanceInitFunc) memo_shell_sidebar_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + E_TYPE_SHELL_SIDEBAR, "EMemoShellSidebar", + &type_info, 0); + } + + return type; +} + +GtkWidget * +e_memo_shell_sidebar_new (EShellView *shell_view) +{ + g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); + + return g_object_new ( + E_TYPE_MEMO_SHELL_SIDEBAR, + "shell-view", shell_view, NULL); +} + +ESourceSelector * +e_memo_shell_sidebar_get_selector (EMemoShellSidebar *memo_shell_sidebar) +{ + g_return_val_if_fail ( + E_IS_MEMO_SHELL_SIDEBAR (memo_shell_sidebar), NULL); + + return E_SOURCE_SELECTOR (memo_shell_sidebar->priv->selector); +} + +void +e_memo_shell_sidebar_add_source (EMemoShellSidebar *memo_shell_sidebar, + ESource *source) +{ + ESourceSelector *selector; + GHashTable *client_table; + ECal *client; + const gchar *uid; + const gchar *uri; + gchar *message; + + g_return_if_fail (E_IS_MEMO_SHELL_SIDEBAR (memo_shell_sidebar)); + g_return_if_fail (E_IS_SOURCE (source)); + + client_table = memo_shell_sidebar->priv->client_table; + selector = e_memo_shell_sidebar_get_selector (memo_shell_sidebar); + + uid = e_source_peek_uid (source); + client = g_hash_table_lookup (client_table, uid); + + if (client != NULL) + return; + + client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_JOURNAL); + g_return_if_fail (client != NULL); + + g_signal_connect_swapped ( + client, "backend-died", + G_CALLBACK (memo_shell_sidebar_backend_died_cb), + memo_shell_sidebar); + + g_signal_connect_swapped ( + client, "backend-error", + G_CALLBACK (memo_shell_sidebar_backend_error_cb), + memo_shell_sidebar); + + g_hash_table_insert (client_table, g_strdup (uid), client); + e_source_selector_select_source (selector, source); + + uri = e_cal_get_uri (client); + message = g_strdup_printf (_("Opening memos at %s"), uri); + memo_shell_sidebar_emit_status_message (memo_shell_sidebar, message); + g_free (message); + + g_signal_connect_swapped ( + client, "cal-opened", + G_CALLBACK (memo_shell_sidebar_client_opened_cb), + memo_shell_sidebar); + + e_cal_open_async (client, FALSE); +} + +void +e_memo_shell_sidebar_remove_source (EMemoShellSidebar *memo_shell_sidebar, + ESource *source) +{ + ESourceSelector *selector; + GHashTable *client_table; + ECal *client; + const gchar *uid; + + g_return_if_fail (E_IS_MEMO_SHELL_SIDEBAR (memo_shell_sidebar)); + g_return_if_fail (E_IS_SOURCE (source)); + + client_table = memo_shell_sidebar->priv->client_table; + selector = e_memo_shell_sidebar_get_selector (memo_shell_sidebar); + + uid = e_source_peek_uid (source); + client = g_hash_table_lookup (client_table, uid); + + if (client == NULL) + return; + + memo_shell_sidebar_emit_client_removed (memo_shell_sidebar, client); +} diff --git a/calendar/modules/e-memo-shell-sidebar.h b/calendar/modules/e-memo-shell-sidebar.h new file mode 100644 index 0000000000..50ece794b2 --- /dev/null +++ b/calendar/modules/e-memo-shell-sidebar.h @@ -0,0 +1,92 @@ +/* + * e-memo-shell-sidebar.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_MEMO_SHELL_SIDEBAR_H +#define E_MEMO_SHELL_SIDEBAR_H + +#include <libecal/e-cal.h> +#include <libedataserverui/e-source-selector.h> + +#include <shell/e-shell-sidebar.h> +#include <shell/e-shell-view.h> + +/* Standard GObject macros */ +#define E_TYPE_MEMO_SHELL_SIDEBAR \ + (e_memo_shell_sidebar_get_type ()) +#define E_MEMO_SHELL_SIDEBAR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_MEMO_SHELL_SIDEBAR, EMemoShellSidebar)) +#define E_MEMO_SHELL_SIDEBAR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_MEMO_SHELL_SIDEBAR, EMemoShellSidebarClass)) +#define E_IS_MEMO_SHELL_SIDEBAR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_MEMO_SHELL_SIDEBAR)) +#define E_IS_MEMO_SHELL_SIDEBAR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_MEMO_SHELL_SIDEBAR)) +#define E_MEMO_SHELL_SIDEBAR_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_MEMO_SHELL_SIDEBAR, EMemoShellSidebarClass)) + +G_BEGIN_DECLS + +typedef struct _EMemoShellSidebar EMemoShellSidebar; +typedef struct _EMemoShellSidebarClass EMemoShellSidebarClass; +typedef struct _EMemoShellSidebarPrivate EMemoShellSidebarPrivate; + +enum { + E_MEMO_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE = 1 << 0, + E_MEMO_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_SYSTEM = 1 << 1 +}; + +struct _EMemoShellSidebar { + EShellSidebar parent; + EMemoShellSidebarPrivate *priv; +}; + +struct _EMemoShellSidebarClass { + EShellSidebarClass parent_class; + + /* Signals */ + void (*client_added) (EMemoShellSidebar *memo_shell_sidebar, + ECal *client); + void (*client_removed) (EMemoShellSidebar *memo_shell_sidebar, + ECal *client); + void (*status_message) (EMemoShellSidebar *memo_shell_sidebar, + const gchar *status_message, + gdouble percent); +}; + +GType e_memo_shell_sidebar_get_type (void); +GtkWidget * e_memo_shell_sidebar_new (EShellView *shell_view); +ESourceSelector * + e_memo_shell_sidebar_get_selector + (EMemoShellSidebar *memo_shell_sidebar); +void e_memo_shell_sidebar_add_source (EMemoShellSidebar *memo_shell_sidebar, + ESource *source); +void e_memo_shell_sidebar_remove_source + (EMemoShellSidebar *memo_shell_sidebar, + ESource *source); + +G_END_DECLS + +#endif /* E_MEMO_SHELL_SIDEBAR_H */ diff --git a/calendar/modules/e-memo-shell-view-actions.c b/calendar/modules/e-memo-shell-view-actions.c new file mode 100644 index 0000000000..d45f74fc38 --- /dev/null +++ b/calendar/modules/e-memo-shell-view-actions.c @@ -0,0 +1,917 @@ +/* + * e-memo-shell-view-actions.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-memo-shell-view-private.h" + +static void +action_gal_save_custom_view_cb (GtkAction *action, + EMemoShellView *memo_shell_view) +{ + EMemoShellContent *memo_shell_content; + EShellView *shell_view; + GalViewInstance *view_instance; + + /* All shell views respond to the activation of this action, + * which is defined by EShellWindow. But only the currently + * active shell view proceeds with saving the custom view. */ + shell_view = E_SHELL_VIEW (memo_shell_view); + if (!e_shell_view_is_active (shell_view)) + return; + + memo_shell_content = memo_shell_view->priv->memo_shell_content; + view_instance = e_memo_shell_content_get_view_instance (memo_shell_content); + gal_view_instance_save_as (view_instance); +} + +static void +action_memo_clipboard_copy_cb (GtkAction *action, + EMemoShellView *memo_shell_view) +{ + EMemoShellContent *memo_shell_content; + EMemoTable *memo_table; + + memo_shell_content = memo_shell_view->priv->memo_shell_content; + memo_table = e_memo_shell_content_get_memo_table (memo_shell_content); + + e_memo_table_copy_clipboard (memo_table); +} + +static void +action_memo_clipboard_cut_cb (GtkAction *action, + EMemoShellView *memo_shell_view) +{ + EMemoShellContent *memo_shell_content; + EMemoTable *memo_table; + + memo_shell_content = memo_shell_view->priv->memo_shell_content; + memo_table = e_memo_shell_content_get_memo_table (memo_shell_content); + + e_memo_table_cut_clipboard (memo_table); +} + +static void +action_memo_clipboard_paste_cb (GtkAction *action, + EMemoShellView *memo_shell_view) +{ + EMemoShellContent *memo_shell_content; + EMemoTable *memo_table; + + memo_shell_content = memo_shell_view->priv->memo_shell_content; + memo_table = e_memo_shell_content_get_memo_table (memo_shell_content); + + e_memo_table_paste_clipboard (memo_table); +} + +static void +action_memo_delete_cb (GtkAction *action, + EMemoShellView *memo_shell_view) +{ + EMemoShellContent *memo_shell_content; + ECalComponentPreview *memo_preview; + EMemoTable *memo_table; + + memo_shell_content = memo_shell_view->priv->memo_shell_content; + memo_table = e_memo_shell_content_get_memo_table (memo_shell_content); + memo_preview = e_memo_shell_content_get_memo_preview (memo_shell_content); + + e_memo_shell_view_set_status_message ( + memo_shell_view, _("Deleting selected memos..."), -1.0); + e_memo_table_delete_selected (memo_table); + e_memo_shell_view_set_status_message (memo_shell_view, NULL, -1.0); + + e_cal_component_preview_clear (memo_preview); +} + +static void +action_memo_forward_cb (GtkAction *action, + EMemoShellView *memo_shell_view) +{ + EMemoShellContent *memo_shell_content; + EMemoTable *memo_table; + ECalModelComponent *comp_data; + ECalComponent *comp; + icalcomponent *clone; + GSList *list; + + memo_shell_content = memo_shell_view->priv->memo_shell_content; + memo_table = e_memo_shell_content_get_memo_table (memo_shell_content); + + list = e_memo_table_get_selected (memo_table); + g_return_if_fail (list != NULL); + comp_data = list->data; + g_slist_free (list); + + /* XXX We only forward the first selected memo. */ + comp = e_cal_component_new (); + clone = icalcomponent_new_clone (comp_data->icalcomp); + e_cal_component_set_icalcomponent (comp, clone); + itip_send_comp ( + E_CAL_COMPONENT_METHOD_PUBLISH, comp, + comp_data->client, NULL, NULL, NULL, TRUE); + g_object_unref (comp); +} + +static void +action_memo_list_copy_cb (GtkAction *action, + EMemoShellView *memo_shell_view) +{ + EMemoShellSidebar *memo_shell_sidebar; + EShellWindow *shell_window; + EShellView *shell_view; + ESourceSelector *selector; + ESource *source; + + shell_view = E_SHELL_VIEW (memo_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + memo_shell_sidebar = memo_shell_view->priv->memo_shell_sidebar; + selector = e_memo_shell_sidebar_get_selector (memo_shell_sidebar); + source = e_source_selector_peek_primary_selection (selector); + g_return_if_fail (E_IS_SOURCE (source)); + + copy_source_dialog ( + GTK_WINDOW (shell_window), + source, E_CAL_SOURCE_TYPE_JOURNAL); +} + +static void +action_memo_list_delete_cb (GtkAction *action, + EMemoShellView *memo_shell_view) +{ + EMemoShellContent *memo_shell_content; + EMemoShellSidebar *memo_shell_sidebar; + EShellWindow *shell_window; + EShellView *shell_view; + EMemoTable *memo_table; + ECal *client; + ECalModel *model; + ESourceSelector *selector; + ESourceGroup *source_group; + ESourceList *source_list; + ESource *source; + gint response; + gchar *uri; + GError *error = NULL; + + shell_view = E_SHELL_VIEW (memo_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + memo_shell_content = memo_shell_view->priv->memo_shell_content; + memo_table = e_memo_shell_content_get_memo_table (memo_shell_content); + model = e_memo_table_get_model (memo_table); + + memo_shell_sidebar = memo_shell_view->priv->memo_shell_sidebar; + selector = e_memo_shell_sidebar_get_selector (memo_shell_sidebar); + source = e_source_selector_peek_primary_selection (selector); + g_return_if_fail (E_IS_SOURCE (source)); + + /* Ask for confirmation. */ + response = e_error_run ( + GTK_WINDOW (shell_window), + "calendar:prompt-delete-memo-list", + e_source_peek_name (source)); + if (response != GTK_RESPONSE_YES) + return; + + uri = e_source_get_uri (source); + client = e_cal_model_get_client_for_uri (model, uri); + if (client == NULL) + client = e_cal_new_from_uri (uri, E_CAL_SOURCE_TYPE_JOURNAL); + g_free (uri); + + g_return_if_fail (client != NULL); + + if (!e_cal_remove (client, &error)) { + g_warning ("%s", error->message); + g_error_free (error); + return; + } + + if (e_source_selector_source_is_selected (selector, source)) { + e_memo_shell_sidebar_remove_source ( + memo_shell_sidebar, source); + e_source_selector_unselect_source (selector, source); + } + + source_group = e_source_peek_group (source); + e_source_group_remove_source (source_group, source); + + source_list = memo_shell_view->priv->source_list; + if (!e_source_list_sync (source_list, &error)) { + g_warning ("%s", error->message); + g_error_free (error); + } +} + +static void +action_memo_list_new_cb (GtkAction *action, + EMemoShellView *memo_shell_view) +{ + EShellView *shell_view; + EShellWindow *shell_window; + + shell_view = E_SHELL_VIEW (memo_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + calendar_setup_new_memo_list (GTK_WINDOW (shell_window)); +} + +static void +action_memo_list_print_cb (GtkAction *action, + EMemoShellView *memo_shell_view) +{ + EMemoShellContent *memo_shell_content; + EMemoTable *memo_table; + ETable *table; + GtkPrintOperationAction print_action; + + memo_shell_content = memo_shell_view->priv->memo_shell_content; + memo_table = e_memo_shell_content_get_memo_table (memo_shell_content); + table = e_memo_table_get_table (memo_table); + + print_action = GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG; + print_table (table, _("Print Memos"), _("Memos"), print_action); +} + +static void +action_memo_list_print_preview_cb (GtkAction *action, + EMemoShellView *memo_shell_view) +{ + EMemoShellContent *memo_shell_content; + EMemoTable *memo_table; + ETable *table; + GtkPrintOperationAction print_action; + + memo_shell_content = memo_shell_view->priv->memo_shell_content; + memo_table = e_memo_shell_content_get_memo_table (memo_shell_content); + table = e_memo_table_get_table (memo_table); + + print_action = GTK_PRINT_OPERATION_ACTION_PREVIEW; + print_table (table, _("Print Memos"), _("Memos"), print_action); +} + +static void +action_memo_list_properties_cb (GtkAction *action, + EMemoShellView *memo_shell_view) +{ + EMemoShellSidebar *memo_shell_sidebar; + EShellView *shell_view; + EShellWindow *shell_window; + ESource *source; + ESourceSelector *selector; + + shell_view = E_SHELL_VIEW (memo_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + memo_shell_sidebar = memo_shell_view->priv->memo_shell_sidebar; + selector = e_memo_shell_sidebar_get_selector (memo_shell_sidebar); + source = e_source_selector_peek_primary_selection (selector); + g_return_if_fail (E_IS_SOURCE (source)); + + calendar_setup_edit_memo_list (GTK_WINDOW (shell_window), source); +} + +static void +action_memo_list_rename_cb (GtkAction *action, + EMemoShellView *memo_shell_view) +{ + EMemoShellSidebar *memo_shell_sidebar; + ESourceSelector *selector; + + memo_shell_sidebar = memo_shell_view->priv->memo_shell_sidebar; + selector = e_memo_shell_sidebar_get_selector (memo_shell_sidebar); + + e_source_selector_edit_primary_selection (selector); +} + +static void +action_memo_list_select_one_cb (GtkAction *action, + EMemoShellView *memo_shell_view) +{ + EMemoShellSidebar *memo_shell_sidebar; + ESourceSelector *selector; + ESource *primary; + GSList *list, *iter; + + /* XXX ESourceSelector should provide a function for this. */ + + memo_shell_sidebar = memo_shell_view->priv->memo_shell_sidebar; + selector = e_memo_shell_sidebar_get_selector (memo_shell_sidebar); + primary = e_source_selector_peek_primary_selection (selector); + g_return_if_fail (primary != NULL); + + list = e_source_selector_get_selection (selector); + for (iter = list; iter != NULL; iter = iter->next) { + ESource *source = iter->data; + + if (source == primary) + continue; + + e_source_selector_unselect_source (selector, source); + } + e_source_selector_free_selection (list); + + e_source_selector_select_source (selector, primary); +} + +static void +action_memo_new_cb (GtkAction *action, + EMemoShellView *memo_shell_view) +{ + EShell *shell; + EShellView *shell_view; + EShellWindow *shell_window; + EMemoShellContent *memo_shell_content; + EMemoTable *memo_table; + ECalModelComponent *comp_data; + ECal *client; + ECalComponent *comp; + CompEditor *editor; + GSList *list; + + shell_view = E_SHELL_VIEW (memo_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + shell = e_shell_window_get_shell (shell_window); + + memo_shell_content = memo_shell_view->priv->memo_shell_content; + memo_table = e_memo_shell_content_get_memo_table (memo_shell_content); + + list = e_memo_table_get_selected (memo_table); + g_return_if_fail (list != NULL); + comp_data = list->data; + g_slist_free (list); + + client = comp_data->client; + editor = memo_editor_new (client, shell, COMP_EDITOR_NEW_ITEM); + comp = cal_comp_memo_new_with_defaults (client); + comp_editor_edit_comp (editor, comp); + + gtk_window_present (GTK_WINDOW (editor)); + + g_object_unref (comp); + g_object_unref (client); +} + +static void +action_memo_open_cb (GtkAction *action, + EMemoShellView *memo_shell_view) +{ + EMemoShellContent *memo_shell_content; + EMemoTable *memo_table; + ECalModelComponent *comp_data; + GSList *list; + + memo_shell_content = memo_shell_view->priv->memo_shell_content; + memo_table = e_memo_shell_content_get_memo_table (memo_shell_content); + + list = e_memo_table_get_selected (memo_table); + g_return_if_fail (list != NULL); + comp_data = list->data; + g_slist_free (list); + + /* XXX We only open the first selected memo. */ + e_memo_shell_view_open_memo (memo_shell_view, comp_data); +} + +static void +action_memo_open_url_cb (GtkAction *action, + EMemoShellView *memo_shell_view) +{ + EShellView *shell_view; + EShellWindow *shell_window; + EMemoShellContent *memo_shell_content; + EMemoTable *memo_table; + ECalModelComponent *comp_data; + icalproperty *prop; + const gchar *uri; + GSList *list; + + shell_view = E_SHELL_VIEW (memo_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + memo_shell_content = memo_shell_view->priv->memo_shell_content; + memo_table = e_memo_shell_content_get_memo_table (memo_shell_content); + + list = e_memo_table_get_selected (memo_table); + g_return_if_fail (list != NULL); + comp_data = list->data; + g_slist_free (list); + + /* XXX We only open the URI of the first selected memo. */ + prop = icalcomponent_get_first_property ( + comp_data->icalcomp, ICAL_URL_PROPERTY); + g_return_if_fail (prop == NULL); + + uri = icalproperty_get_url (prop); + e_show_uri (GTK_WINDOW (shell_window), uri); +} + +static void +action_memo_preview_cb (GtkToggleAction *action, + EMemoShellView *memo_shell_view) +{ + EMemoShellContent *memo_shell_content; + gboolean visible; + + memo_shell_content = memo_shell_view->priv->memo_shell_content; + visible = gtk_toggle_action_get_active (action); + e_memo_shell_content_set_preview_visible (memo_shell_content, visible); +} + +static void +action_memo_print_cb (GtkAction *action, + EMemoShellView *memo_shell_view) +{ + EMemoShellContent *memo_shell_content; + EMemoTable *memo_table; + ECalModelComponent *comp_data; + ECalComponent *comp; + icalcomponent *clone; + GtkPrintOperationAction print_action; + GSList *list; + + memo_shell_content = memo_shell_view->priv->memo_shell_content; + memo_table = e_memo_shell_content_get_memo_table (memo_shell_content); + + list = e_memo_table_get_selected (memo_table); + g_return_if_fail (list != NULL); + comp_data = list->data; + g_slist_free (list); + + /* XXX We only print the first selected memo. */ + comp = e_cal_component_new (); + clone = icalcomponent_new_clone (comp_data->icalcomp); + print_action = GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG; + e_cal_component_set_icalcomponent (comp, clone); + print_comp (comp, comp_data->client, print_action); + g_object_unref (comp); +} + +static void +action_memo_save_as_cb (GtkAction *action, + EMemoShellView *memo_shell_view) +{ + EMemoShellContent *memo_shell_content; + EMemoTable *memo_table; + ECalModelComponent *comp_data; + GSList *list; + gchar *filename; + gchar *string; + + memo_shell_content = memo_shell_view->priv->memo_shell_content; + memo_table = e_memo_shell_content_get_memo_table (memo_shell_content); + + list = e_memo_table_get_selected (memo_table); + g_return_if_fail (list != NULL); + comp_data = list->data; + g_slist_free (list); + + filename = e_file_dialog_save (_("Save as..."), NULL); + if (filename == NULL) + return; + + /* XXX We only save the first selected memo. */ + string = e_cal_get_component_as_string ( + comp_data->client, comp_data->icalcomp); + if (string == NULL) { + g_warning ("Could not convert memo to a string"); + return; + } + + e_write_file_uri (filename, string); + + g_free (filename); + g_free (string); +} + +static void +action_search_execute_cb (GtkAction *action, + EMemoShellView *memo_shell_view) +{ + EShellView *shell_view; + + /* All shell views respond to the activation of this action, + * which is defined by EShellWindow. But only the currently + * active shell view proceeds with executing the search. */ + shell_view = E_SHELL_VIEW (memo_shell_view); + if (!e_shell_view_is_active (shell_view)) + return; + + e_memo_shell_view_execute_search (memo_shell_view); +} + +static void +action_search_filter_cb (GtkRadioAction *action, + GtkRadioAction *current, + EMemoShellView *memo_shell_view) +{ + e_memo_shell_view_execute_search (memo_shell_view); +} + +static GtkActionEntry memo_entries[] = { + + { "memo-clipboard-copy", + GTK_STOCK_COPY, + NULL, + NULL, + N_("Copy selected memo"), + G_CALLBACK (action_memo_clipboard_copy_cb) }, + + { "memo-clipboard-cut", + GTK_STOCK_CUT, + NULL, + NULL, + N_("Cut selected memo"), + G_CALLBACK (action_memo_clipboard_cut_cb) }, + + { "memo-clipboard-paste", + GTK_STOCK_PASTE, + NULL, + NULL, + N_("Paste memo from the clipboard"), + G_CALLBACK (action_memo_clipboard_paste_cb) }, + + { "memo-delete", + GTK_STOCK_DELETE, + N_("_Delete Memo"), + NULL, + N_("Delete selected memos"), + G_CALLBACK (action_memo_delete_cb) }, + + { "memo-forward", + "mail-forward", + N_("_Forward as iCalendar..."), + "<Control>f", + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_memo_forward_cb) }, + + { "memo-list-copy", + GTK_STOCK_COPY, + N_("_Copy..."), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_memo_list_copy_cb) }, + + { "memo-list-delete", + GTK_STOCK_DELETE, + N_("_Delete"), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_memo_list_delete_cb) }, + + { "memo-list-new", + "stock_notes", + N_("_New Memo List"), + NULL, + N_("Create a new memo list"), + G_CALLBACK (action_memo_list_new_cb) }, + + { "memo-list-properties", + GTK_STOCK_PROPERTIES, + NULL, + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_memo_list_properties_cb) }, + + { "memo-list-rename", + NULL, + N_("_Rename..."), + "F2", + N_("Rename the selected memo list"), + G_CALLBACK (action_memo_list_rename_cb) }, + + { "memo-list-select-one", + "stock_check-filled", + N_("Show _Only This Memo List"), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_memo_list_select_one_cb) }, + + { "memo-new", + "stock_insert-note", + N_("New _Memo"), + NULL, + N_("Create a new memo"), + G_CALLBACK (action_memo_new_cb) }, + + { "memo-open", + GTK_STOCK_OPEN, + N_("_Open Memo"), + "<Control>o", + N_("View the selected memo"), + G_CALLBACK (action_memo_open_cb) }, + + { "memo-open-url", + "applications-internet", + N_("Open _Web Page"), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_memo_open_url_cb) }, + + { "memo-save-as", + GTK_STOCK_SAVE_AS, + N_("_Save as iCalendar..."), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_memo_save_as_cb) } +}; + +static EPopupActionEntry memo_popup_entries[] = { + + { "memo-list-popup-copy", + NULL, + "memo-list-copy" }, + + { "memo-list-popup-delete", + NULL, + "memo-list-delete" }, + + { "memo-list-popup-properties", + NULL, + "memo-list-properties" }, + + { "memo-list-popup-rename", + NULL, + "memo-list-rename" }, + + { "memo-list-popup-select-one", + NULL, + "memo-list-select-one" }, + + { "memo-popup-clipboard-copy", + NULL, + "memo-clipboard-copy" }, + + { "memo-popup-clipboard-cut", + NULL, + "memo-clipboard-cut" }, + + { "memo-popup-clipboard-paste", + NULL, + "memo-clipboard-paste" }, + + { "memo-popup-delete", + NULL, + "memo-delete" }, + + { "memo-popup-forward", + NULL, + "memo-forward" }, + + { "memo-popup-open", + NULL, + "memo-open" }, + + { "memo-popup-open-url", + NULL, + "memo-open-url" }, + + { "memo-popup-save-as", + NULL, + "memo-save-as" } +}; + +static GtkToggleActionEntry memo_toggle_entries[] = { + + { "memo-preview", + NULL, + N_("Memo _Preview"), + "<Control>m", + N_("Show memo preview pane"), + G_CALLBACK (action_memo_preview_cb), + TRUE } +}; + +static GtkRadioActionEntry memo_filter_entries[] = { + + { "memo-filter-any-category", + NULL, + N_("Any Category"), + NULL, + NULL, + MEMO_FILTER_ANY_CATEGORY }, + + { "memo-filter-unmatched", + NULL, + N_("Unmatched"), + NULL, + NULL, + MEMO_FILTER_UNMATCHED } +}; + +static GtkRadioActionEntry memo_search_entries[] = { + + { "memo-search-any-field-contains", + NULL, + N_("Any field contains"), + NULL, + NULL, /* XXX Add a tooltip! */ + MEMO_SEARCH_ANY_FIELD_CONTAINS }, + + { "memo-search-description-contains", + NULL, + N_("Description contains"), + NULL, + NULL, /* XXX Add a tooltip! */ + MEMO_SEARCH_DESCRIPTION_CONTAINS }, + + { "memo-search-summary-contains", + NULL, + N_("Summary contains"), + NULL, + NULL, /* XXX Add a tooltip! */ + MEMO_SEARCH_SUMMARY_CONTAINS } +}; + +static GtkActionEntry lockdown_printing_entries[] = { + + { "memo-list-print", + GTK_STOCK_PRINT, + NULL, + "<Control>p", + N_("Print the list of memos"), + G_CALLBACK (action_memo_list_print_cb) }, + + { "memo-list-print-preview", + GTK_STOCK_PRINT_PREVIEW, + NULL, + NULL, + N_("Preview the list of memos to be printed"), + G_CALLBACK (action_memo_list_print_preview_cb) }, + + { "memo-print", + GTK_STOCK_PRINT, + NULL, + NULL, + N_("Print the selected memo"), + G_CALLBACK (action_memo_print_cb) } +}; + +static EPopupActionEntry lockdown_printing_popup_entries[] = { + + { "memo-popup-print", + NULL, + "memo-print" } +}; + +void +e_memo_shell_view_actions_init (EMemoShellView *memo_shell_view) +{ + EShellView *shell_view; + EShellWindow *shell_window; + GtkActionGroup *action_group; + GConfBridge *bridge; + GtkAction *action; + GObject *object; + const gchar *key; + + shell_view = E_SHELL_VIEW (memo_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + /* Memo Actions */ + action_group = ACTION_GROUP (MEMOS); + gtk_action_group_add_actions ( + action_group, memo_entries, + G_N_ELEMENTS (memo_entries), memo_shell_view); + e_action_group_add_popup_actions ( + action_group, memo_popup_entries, + G_N_ELEMENTS (memo_popup_entries)); + gtk_action_group_add_toggle_actions ( + action_group, memo_toggle_entries, + G_N_ELEMENTS (memo_toggle_entries), memo_shell_view); + gtk_action_group_add_radio_actions ( + action_group, memo_search_entries, + G_N_ELEMENTS (memo_search_entries), + MEMO_SEARCH_SUMMARY_CONTAINS, + NULL, NULL); + + /* Lockdown Printing Actions */ + action_group = ACTION_GROUP (LOCKDOWN_PRINTING); + gtk_action_group_add_actions ( + action_group, lockdown_printing_entries, + G_N_ELEMENTS (lockdown_printing_entries), memo_shell_view); + e_action_group_add_popup_actions ( + action_group, lockdown_printing_popup_entries, + G_N_ELEMENTS (lockdown_printing_popup_entries)); + + /* Bind GObject properties to GConf keys. */ + + bridge = gconf_bridge_get (); + + object = G_OBJECT (ACTION (MEMO_PREVIEW)); + key = "/apps/evolution/calendar/display/show_memo_preview"; + gconf_bridge_bind_property (bridge, key, object, "active"); + + /* Fine tuning. */ + + action = ACTION (MEMO_DELETE); + g_object_set (action, "short-label", _("Delete"), NULL); + + g_signal_connect ( + ACTION (GAL_SAVE_CUSTOM_VIEW), "activate", + G_CALLBACK (action_gal_save_custom_view_cb), memo_shell_view); + + g_signal_connect ( + ACTION (SEARCH_EXECUTE), "activate", + G_CALLBACK (action_search_execute_cb), memo_shell_view); +} + +void +e_memo_shell_view_update_search_filter (EMemoShellView *memo_shell_view) +{ + EShellContent *shell_content; + EShellWindow *shell_window; + EShellView *shell_view; + GtkActionGroup *action_group; + GtkRadioAction *radio_action; + GList *list, *iter; + GSList *group; + gint ii; + + shell_view = E_SHELL_VIEW (memo_shell_view); + shell_content = e_shell_view_get_shell_content (shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + action_group = ACTION_GROUP (MEMOS_FILTER); + e_action_group_remove_all_actions (action_group); + + /* Add the standard filter actions. */ + gtk_action_group_add_radio_actions ( + action_group, memo_filter_entries, + G_N_ELEMENTS (memo_filter_entries), + MEMO_FILTER_ANY_CATEGORY, + G_CALLBACK (action_search_filter_cb), + memo_shell_view); + + /* Retrieve the radio group from an action we just added. */ + list = gtk_action_group_list_actions (action_group); + radio_action = GTK_RADIO_ACTION (list->data); + group = gtk_radio_action_get_group (radio_action); + g_list_free (list); + + /* Build the category actions. */ + + list = e_categories_get_list (); + for (iter = list, ii = 0; iter != NULL; iter = iter->next, ii++) { + const gchar *category_name = iter->data; + const gchar *filename; + GtkAction *action; + gchar *action_name; + + action_name = g_strdup_printf ( + "memo-filter-category-%d", ii); + radio_action = gtk_radio_action_new ( + action_name, category_name, NULL, NULL, ii); + g_free (action_name); + + /* Convert the category icon file to a themed icon name. */ + filename = e_categories_get_icon_file_for (category_name); + if (filename != NULL && *filename != '\0') { + gchar *basename; + gchar *cp; + + basename = g_path_get_basename (filename); + + /* Lose the file extension. */ + if ((cp = strrchr (basename, '.')) != NULL) + *cp = '\0'; + + g_object_set ( + radio_action, "icon-name", basename, NULL); + + g_free (basename); + } + + gtk_radio_action_set_group (radio_action, group); + group = gtk_radio_action_get_group (radio_action); + + /* The action group takes ownership of the action. */ + action = GTK_ACTION (radio_action); + gtk_action_group_add_action (action_group, action); + g_object_unref (radio_action); + } + g_list_free (list); + + /* Use any action in the group; doesn't matter which. */ + e_shell_content_set_filter_action (shell_content, radio_action); + + ii = MEMO_FILTER_UNMATCHED; + e_shell_content_add_filter_separator_after (shell_content, ii); +} diff --git a/calendar/modules/e-memo-shell-view-actions.h b/calendar/modules/e-memo-shell-view-actions.h new file mode 100644 index 0000000000..97fd9a6c2b --- /dev/null +++ b/calendar/modules/e-memo-shell-view-actions.h @@ -0,0 +1,87 @@ +/* + * e-memo-shell-view-actions.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_MEMO_SHELL_VIEW_ACTIONS_H +#define E_MEMO_SHELL_VIEW_ACTIONS_H + +#include <shell/e-shell-window-actions.h> + +/* Memo Actions */ +#define E_SHELL_WINDOW_ACTION_MEMO_CLIPBOARD_COPY(window) \ + E_SHELL_WINDOW_ACTION ((window), "memo-clipboard-copy") +#define E_SHELL_WINDOW_ACTION_MEMO_CLIPBOARD_CUT(window) \ + E_SHELL_WINDOW_ACTION ((window), "memo-clipboard-cut") +#define E_SHELL_WINDOW_ACTION_MEMO_CLIPBOARD_PASTE(window) \ + E_SHELL_WINDOW_ACTION ((window), "memo-clipboard-paste") +#define E_SHELL_WINDOW_ACTION_MEMO_DELETE(window) \ + E_SHELL_WINDOW_ACTION ((window), "memo-delete") +#define E_SHELL_WINDOW_ACTION_MEMO_FORWARD(window) \ + E_SHELL_WINDOW_ACTION ((window), "memo-forward") +#define E_SHELL_WINDOW_ACTION_MEMO_NEW(window) \ + E_SHELL_WINDOW_ACTION ((window), "memo-new") +#define E_SHELL_WINDOW_ACTION_MEMO_OPEN(window) \ + E_SHELL_WINDOW_ACTION ((window), "memo-open") +#define E_SHELL_WINDOW_ACTION_MEMO_OPEN_URL(window) \ + E_SHELL_WINDOW_ACTION ((window), "memo-open-url") +#define E_SHELL_WINDOW_ACTION_MEMO_PREVIEW(window) \ + E_SHELL_WINDOW_ACTION ((window), "memo-preview") +#define E_SHELL_WINDOW_ACTION_MEMO_PRINT(window) \ + E_SHELL_WINDOW_ACTION ((window), "memo-print") +#define E_SHELL_WINDOW_ACTION_MEMO_SAVE_AS(window) \ + E_SHELL_WINDOW_ACTION ((window), "memo-save-as") + +/* Memo List Actions */ +#define E_SHELL_WINDOW_ACTION_MEMO_LIST_COPY(window) \ + E_SHELL_WINDOW_ACTION ((window), "memo-list-copy") +#define E_SHELL_WINDOW_ACTION_MEMO_LIST_DELETE(window) \ + E_SHELL_WINDOW_ACTION ((window), "memo-list-delete") +#define E_SHELL_WINDOW_ACTION_MEMO_LIST_NEW(window) \ + E_SHELL_WINDOW_ACTION ((window), "memo-list-new") +#define E_SHELL_WINDOW_ACTION_MEMO_LIST_PRINT(window) \ + E_SHELL_WINDOW_ACTION ((window), "memo-list-print") +#define E_SHELL_WINDOW_ACTION_MEMO_LIST_PRINT_PREVIEW(window) \ + E_SHELL_WINDOW_ACTION ((window), "memo-list-print-preview") +#define E_SHELL_WINDOW_ACTION_MEMO_LIST_PROPERTIES(window) \ + E_SHELL_WINDOW_ACTION ((window), "memo-list-properties") +#define E_SHELL_WINDOW_ACTION_MEMO_LIST_RENAME(window) \ + E_SHELL_WINDOW_ACTION ((window), "memo-list-rename") +#define E_SHELL_WINDOW_ACTION_MEMO_LIST_SELECT_ONE(window) \ + E_SHELL_WINDOW_ACTION ((window), "memo-list-select-one") + +/* Memo Query Actions */ +#define E_SHELL_WINDOW_ACTION_MEMO_FILTER_ANY_CATEGORY(window) \ + E_SHELL_WINDOW_ACTION ((window), "memo-filter-any-category") +#define E_SHELL_WINDOW_ACTION_MEMO_FILTER_UNMATCHED(window) \ + E_SHELL_WINDOW_ACTION ((window), "memo-filter-unmatched") +#define E_SHELL_WINDOW_ACTION_MEMO_SEARCH_ANY_FIELD_CONTAINS(window) \ + E_SHELL_WINDOW_ACTION ((window), "memo-search-any-field-contains") +#define E_SHELL_WINDOW_ACTION_MEMO_SEARCH_DESCRIPTION_CONTAINS(window) \ + E_SHELL_WINDOW_ACTION ((window), "memo-search-description-contains") +#define E_SHELL_WINDOW_ACTION_MEMO_SEARCH_SUMMARY_CONTAINS(window) \ + E_SHELL_WINDOW_ACTION ((window), "memo-search-summary-contains") + +/* Action Groups */ +#define E_SHELL_WINDOW_ACTION_GROUP_MEMOS(window) \ + E_SHELL_WINDOW_ACTION_GROUP ((window), "memos") +#define E_SHELL_WINDOW_ACTION_GROUP_MEMOS_FILTER(window) \ + E_SHELL_WINDOW_ACTION_GROUP ((window), "memos-filter") + +#endif /* E_MEMO_SHELL_VIEW_ACTIONS_H */ diff --git a/calendar/modules/e-memo-shell-view-private.c b/calendar/modules/e-memo-shell-view-private.c new file mode 100644 index 0000000000..113def55ad --- /dev/null +++ b/calendar/modules/e-memo-shell-view-private.c @@ -0,0 +1,532 @@ +/* + * e-memo-shell-view-private.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-memo-shell-view-private.h" + +#include "widgets/menus/gal-view-factory-etable.h" + +static void +memo_shell_view_table_popup_event_cb (EShellView *shell_view, + GdkEventButton *event) +{ + const gchar *widget_path; + + widget_path = "/memo-popup"; + e_shell_view_show_popup_menu (shell_view, widget_path, event); +} + +static void +memo_shell_view_table_user_created_cb (EMemoShellView *memo_shell_view, + EMemoTable *memo_table) +{ + EMemoShellSidebar *memo_shell_sidebar; + ECalModel *model; + ECal *client; + ESource *source; + + /* This is the "Click to Add" handler. */ + + model = e_memo_table_get_model (memo_table); + client = e_cal_model_get_default_client (model); + source = e_cal_get_source (client); + + memo_shell_sidebar = memo_shell_view->priv->memo_shell_sidebar; + e_memo_shell_sidebar_add_source (memo_shell_sidebar, source); + + e_cal_model_add_client (model, client); +} + +static void +memo_shell_view_selector_client_added_cb (EMemoShellView *memo_shell_view, + ECal *client) +{ + EMemoShellContent *memo_shell_content; + EMemoTable *memo_table; + ECalModel *model; + + memo_shell_content = memo_shell_view->priv->memo_shell_content; + memo_table = e_memo_shell_content_get_memo_table (memo_shell_content); + model = e_memo_table_get_model (memo_table); + + e_cal_model_add_client (model, client); +} + +static void +memo_shell_view_selector_client_removed_cb (EMemoShellView *memo_shell_view, + ECal *client) +{ + EMemoShellContent *memo_shell_content; + EMemoTable *memo_table; + ECalModel *model; + + memo_shell_content = memo_shell_view->priv->memo_shell_content; + memo_table = e_memo_shell_content_get_memo_table (memo_shell_content); + model = e_memo_table_get_model (memo_table); + + e_cal_model_remove_client (model, client); +} + +static gboolean +memo_shell_view_selector_popup_event_cb (EShellView *shell_view, + ESource *primary_source, + GdkEventButton *event) +{ + const gchar *widget_path; + + widget_path = "/memo-list-popup"; + e_shell_view_show_popup_menu (shell_view, widget_path, event); + + return TRUE; +} + +static void +memo_shell_view_load_view_collection (EShellViewClass *shell_view_class) +{ + GalViewCollection *collection; + GalViewFactory *factory; + ETableSpecification *spec; + const gchar *base_dir; + gchar *filename; + + collection = shell_view_class->view_collection; + + base_dir = EVOLUTION_ETSPECDIR; + spec = e_table_specification_new (); + filename = g_build_filename (base_dir, ETSPEC_FILENAME, NULL); + if (!e_table_specification_load_from_file (spec, filename)) + g_critical ("Unable to load ETable specification file " + "for memos"); + g_free (filename); + + factory = gal_view_factory_etable_new (spec); + gal_view_collection_add_factory (collection, factory); + g_object_unref (factory); + g_object_unref (spec); + + gal_view_collection_load (collection); +} + +static void +memo_shell_view_notify_view_id_cb (EMemoShellView *memo_shell_view) +{ + EMemoShellContent *memo_shell_content; + GalViewInstance *view_instance; + const gchar *view_id; + + memo_shell_content = memo_shell_view->priv->memo_shell_content; + view_instance = + e_memo_shell_content_get_view_instance (memo_shell_content); + view_id = e_shell_view_get_view_id (E_SHELL_VIEW (memo_shell_view)); + + /* A NULL view ID implies we're in a custom view. But you can + * only get to a custom view via the "Define Views" dialog, which + * would have already modified the view instance appropriately. + * Furthermore, there's no way to refer to a custom view by ID + * anyway, since custom views have no IDs. */ + if (view_id == NULL) + return; + + gal_view_instance_set_current_view_id (view_instance, view_id); +} + +void +e_memo_shell_view_private_init (EMemoShellView *memo_shell_view, + EShellViewClass *shell_view_class) +{ + EMemoShellViewPrivate *priv = memo_shell_view->priv; + ESourceList *source_list; + GObject *object; + + object = G_OBJECT (shell_view_class->type_module); + source_list = g_object_get_data (object, "source-list"); + g_return_if_fail (E_IS_SOURCE_LIST (source_list)); + + priv->source_list = g_object_ref (source_list); + + if (!gal_view_collection_loaded (shell_view_class->view_collection)) + memo_shell_view_load_view_collection (shell_view_class); + + g_signal_connect ( + memo_shell_view, "notify::view-id", + G_CALLBACK (memo_shell_view_notify_view_id_cb), NULL); +} + +void +e_memo_shell_view_private_constructed (EMemoShellView *memo_shell_view) +{ + EMemoShellViewPrivate *priv = memo_shell_view->priv; + EMemoShellContent *memo_shell_content; + EMemoShellSidebar *memo_shell_sidebar; + EShellView *shell_view; + EShellContent *shell_content; + EShellSidebar *shell_sidebar; + EShellWindow *shell_window; + EMemoTable *memo_table; + ECalModel *model; + ETable *table; + ESourceSelector *selector; + + shell_view = E_SHELL_VIEW (memo_shell_view); + shell_content = e_shell_view_get_shell_content (shell_view); + shell_sidebar = e_shell_view_get_shell_sidebar (shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + e_shell_window_add_action_group (shell_window, "memos"); + e_shell_window_add_action_group (shell_window, "memos-filter"); + + /* Cache these to avoid lots of awkward casting. */ + priv->memo_shell_content = g_object_ref (shell_content); + priv->memo_shell_sidebar = g_object_ref (shell_sidebar); + + memo_shell_content = E_MEMO_SHELL_CONTENT (shell_content); + memo_table = e_memo_shell_content_get_memo_table (memo_shell_content); + model = e_memo_table_get_model (memo_table); + table = e_memo_table_get_table (memo_table); + + memo_shell_sidebar = E_MEMO_SHELL_SIDEBAR (shell_sidebar); + selector = e_memo_shell_sidebar_get_selector (memo_shell_sidebar); + + g_signal_connect_swapped ( + memo_table, "open-component", + G_CALLBACK (e_memo_shell_view_open_memo), + memo_shell_view); + + g_signal_connect_swapped ( + memo_table, "popup-event", + G_CALLBACK (memo_shell_view_table_popup_event_cb), + memo_shell_view); + + g_signal_connect_swapped ( + memo_table, "status-message", + G_CALLBACK (e_memo_shell_view_set_status_message), + memo_shell_view); + + g_signal_connect_swapped ( + memo_table, "user-created", + G_CALLBACK (memo_shell_view_table_user_created_cb), + memo_shell_view); + + g_signal_connect_swapped ( + model, "model-changed", + G_CALLBACK (e_memo_shell_view_update_sidebar), + memo_shell_view); + + g_signal_connect_swapped ( + model, "model-rows-deleted", + G_CALLBACK (e_memo_shell_view_update_sidebar), + memo_shell_view); + + g_signal_connect_swapped ( + model, "model-rows-inserted", + G_CALLBACK (e_memo_shell_view_update_sidebar), + memo_shell_view); + + g_signal_connect_swapped ( + table, "selection-change", + G_CALLBACK (e_memo_shell_view_update_sidebar), + memo_shell_view); + + g_signal_connect_swapped ( + memo_shell_sidebar, "client-added", + G_CALLBACK (memo_shell_view_selector_client_added_cb), + memo_shell_view); + + g_signal_connect_swapped ( + memo_shell_sidebar, "client-removed", + G_CALLBACK (memo_shell_view_selector_client_removed_cb), + memo_shell_view); + + g_signal_connect_swapped ( + memo_shell_sidebar, "status-message", + G_CALLBACK (e_memo_shell_view_set_status_message), + memo_shell_view); + + g_signal_connect_swapped ( + selector, "popup-event", + G_CALLBACK (memo_shell_view_selector_popup_event_cb), + memo_shell_view); + + g_signal_connect_swapped ( + selector, "primary-selection-changed", + G_CALLBACK (e_shell_view_update_actions), + memo_shell_view); + + e_categories_register_change_listener ( + G_CALLBACK (e_memo_shell_view_update_search_filter), + memo_shell_view); + + e_memo_shell_view_actions_init (memo_shell_view); + e_memo_shell_view_update_sidebar (memo_shell_view); + e_memo_shell_view_update_search_filter (memo_shell_view); + + e_memo_shell_view_execute_search (memo_shell_view); +} + +void +e_memo_shell_view_private_dispose (EMemoShellView *memo_shell_view) +{ + EMemoShellViewPrivate *priv = memo_shell_view->priv; + + DISPOSE (priv->source_list); + + DISPOSE (priv->memo_shell_content); + DISPOSE (priv->memo_shell_sidebar); + + if (memo_shell_view->priv->activity != NULL) { + /* XXX Activity is not cancellable. */ + e_activity_complete (memo_shell_view->priv->activity); + g_object_unref (memo_shell_view->priv->activity); + memo_shell_view->priv->activity = NULL; + } +} + +void +e_memo_shell_view_private_finalize (EMemoShellView *memo_shell_view) +{ + /* XXX Nothing to do? */ +} + +void +e_memo_shell_view_execute_search (EMemoShellView *memo_shell_view) +{ + EMemoShellContent *memo_shell_content; + EShellView *shell_view; + EShellWindow *shell_window; + EShellContent *shell_content; + GtkAction *action; + GString *string; + ECalComponentPreview *memo_preview; + EMemoTable *memo_table; + ECalModel *model; + FilterRule *rule; + const gchar *format; + const gchar *text; + gchar *query; + gchar *temp; + gint value; + + shell_view = E_SHELL_VIEW (memo_shell_view); + shell_content = e_shell_view_get_shell_content (shell_view); + text = e_shell_content_get_search_text (shell_content); + + shell_window = e_shell_view_get_shell_window (shell_view); + action = ACTION (MEMO_SEARCH_ANY_FIELD_CONTAINS); + value = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action)); + + if (text == NULL || *text == '\0') { + text = ""; + value = MEMO_SEARCH_SUMMARY_CONTAINS; + } + + switch (value) { + default: + text = ""; + /* fall through */ + + case MEMO_SEARCH_SUMMARY_CONTAINS: + format = "(contains? \"summary\" %s)"; + break; + + case MEMO_SEARCH_DESCRIPTION_CONTAINS: + format = "(contains? \"description\" %s)"; + break; + + case MEMO_SEARCH_ANY_FIELD_CONTAINS: + format = "(contains? \"any\" %s)"; + break; + } + + /* Build the query. */ + string = g_string_new (""); + e_sexp_encode_string (string, text); + query = g_strdup_printf (format, string->str); + g_string_free (string, TRUE); + + /* Apply selected filter. */ + value = e_shell_content_get_filter_value (shell_content); + 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 + * FilterRule, tell it to build code, and pass the resulting + * expression string to ECalModel. */ + rule = filter_rule_new (); + e_shell_content_set_search_rule (shell_content, rule); + g_object_unref (rule); + + /* Submit the query. */ + memo_shell_content = memo_shell_view->priv->memo_shell_content; + memo_table = e_memo_shell_content_get_memo_table (memo_shell_content); + model = e_memo_table_get_model (memo_table); + e_cal_model_set_search_query (model, query); + g_free (query); + + memo_preview = + e_memo_shell_content_get_memo_preview (memo_shell_content); + e_cal_component_preview_clear (memo_preview); +} + +void +e_memo_shell_view_open_memo (EMemoShellView *memo_shell_view, + ECalModelComponent *comp_data) +{ + EShell *shell; + EShellView *shell_view; + EShellWindow *shell_window; + CompEditor *editor; + CompEditorFlags flags = 0; + ECalComponent *comp; + icalcomponent *clone; + const gchar *uid; + + g_return_if_fail (E_IS_MEMO_SHELL_VIEW (memo_shell_view)); + g_return_if_fail (E_IS_CAL_MODEL_COMPONENT (comp_data)); + + shell_view = E_SHELL_VIEW (memo_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + shell = e_shell_window_get_shell (shell_window); + + uid = icalcomponent_get_uid (comp_data->icalcomp); + editor = comp_editor_find_instance (uid); + + if (editor != NULL) + goto exit; + + comp = e_cal_component_new (); + clone = icalcomponent_new_clone (comp_data->icalcomp); + e_cal_component_set_icalcomponent (comp, clone); + + 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; + + editor = memo_editor_new (comp_data->client, shell, flags); + comp_editor_edit_comp (editor, comp); + + g_object_unref (comp); + +exit: + gtk_window_present (GTK_WINDOW (editor)); +} + +void +e_memo_shell_view_set_status_message (EMemoShellView *memo_shell_view, + const gchar *status_message, + gdouble percent) +{ + EActivity *activity; + EShellView *shell_view; + EShellModule *shell_module; + + g_return_if_fail (E_IS_MEMO_SHELL_VIEW (memo_shell_view)); + + activity = memo_shell_view->priv->activity; + shell_view = E_SHELL_VIEW (memo_shell_view); + shell_module = e_shell_view_get_shell_module (shell_view); + + if (status_message == NULL || *status_message == '\0') { + if (activity != NULL) { + e_activity_complete (activity); + g_object_unref (activity); + activity = NULL; + } + + } else if (activity == NULL) { + activity = e_activity_new (status_message); + e_activity_set_percent (activity, percent); + e_shell_module_add_activity (shell_module, activity); + + } else { + e_activity_set_percent (activity, percent); + e_activity_set_primary_text (activity, status_message); + } + + memo_shell_view->priv->activity = activity; +} + +void +e_memo_shell_view_update_sidebar (EMemoShellView *memo_shell_view) +{ + EMemoShellContent *memo_shell_content; + EShellView *shell_view; + EShellSidebar *shell_sidebar; + EMemoTable *memo_table; + ECalModel *model; + ETable *table; + GString *string; + const gchar *format; + gint n_rows; + gint n_selected; + + shell_view = E_SHELL_VIEW (memo_shell_view); + shell_sidebar = e_shell_view_get_shell_sidebar (shell_view); + + memo_shell_content = memo_shell_view->priv->memo_shell_content; + memo_table = e_memo_shell_content_get_memo_table (memo_shell_content); + + model = e_memo_table_get_model (memo_table); + table = e_memo_table_get_table (memo_table); + + n_rows = e_table_model_row_count (E_TABLE_MODEL (model)); + n_selected = e_table_selected_count (table); + + string = g_string_sized_new (64); + + format = ngettext ("%d memo", "%d memos", n_rows); + g_string_append_printf (string, format, n_rows); + + if (n_selected > 0) { + format = _("%d selected"); + g_string_append_len (string, ", ", 2); + g_string_append_printf (string, format, n_selected); + } + + e_shell_sidebar_set_secondary_text (shell_sidebar, string->str); + + g_string_free (string, TRUE); +} diff --git a/calendar/modules/e-memo-shell-view-private.h b/calendar/modules/e-memo-shell-view-private.h new file mode 100644 index 0000000000..9667bc5ec7 --- /dev/null +++ b/calendar/modules/e-memo-shell-view-private.h @@ -0,0 +1,130 @@ +/* + * e-memo-shell-view-private.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_MEMO_SHELL_VIEW_PRIVATE_H +#define E_MEMO_SHELL_VIEW_PRIVATE_H + +#include "e-memo-shell-view.h" + +#include <string.h> +#include <glib/gi18n.h> +#include <libedataserver/e-categories.h> +#include <libedataserver/e-sexp.h> + +#include "e-util/e-dialog-utils.h" +#include "e-util/e-error.h" +#include "e-util/e-util.h" +#include "e-util/gconf-bridge.h" +#include "widgets/misc/e-popup-action.h" + +#include "calendar/gui/comp-util.h" +#include "calendar/gui/e-cal-component-preview.h" +#include "calendar/gui/e-calendar-selector.h" +#include "calendar/gui/print.h" +#include "calendar/gui/dialogs/calendar-setup.h" +#include "calendar/gui/dialogs/copy-source-dialog.h" +#include "calendar/gui/dialogs/memo-editor.h" + +#include "e-memo-shell-content.h" +#include "e-memo-shell-sidebar.h" +#include "e-memo-shell-view-actions.h" + +#define E_MEMO_SHELL_VIEW_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_MEMO_SHELL_VIEW, EMemoShellViewPrivate)) + +/* Shorthand, requires a variable named "shell_window". */ +#define ACTION(name) \ + (E_SHELL_WINDOW_ACTION_##name (shell_window)) +#define ACTION_GROUP(name) \ + (E_SHELL_WINDOW_ACTION_GROUP_##name (shell_window)) + +/* For use in dispose() methods. */ +#define DISPOSE(obj) \ + G_STMT_START { \ + if ((obj) != NULL) { g_object_unref (obj); (obj) = NULL; } \ + } G_STMT_END + +/* ETable Specifications */ +#define ETSPEC_FILENAME "e-memo-table.etspec" + +G_BEGIN_DECLS + +/* Filter items are displayed in ascending order. + * Non-negative values are reserved for categories. */ +enum { + MEMO_FILTER_ANY_CATEGORY = -2, + MEMO_FILTER_UNMATCHED = -1 +}; + +/* Search items are displayed in ascending order. */ +enum { + MEMO_SEARCH_SUMMARY_CONTAINS, + MEMO_SEARCH_DESCRIPTION_CONTAINS, + MEMO_SEARCH_ANY_FIELD_CONTAINS +}; + +struct _EMemoShellViewPrivate { + + /*** Module Data ***/ + + ESourceList *source_list; + + /*** Other Stuff ***/ + + /* These are just for convenience. */ + EMemoShellContent *memo_shell_content; + EMemoShellSidebar *memo_shell_sidebar; + + EActivity *activity; +}; + +void e_memo_shell_view_private_init + (EMemoShellView *memo_shell_view, + EShellViewClass *shell_view_class); +void e_memo_shell_view_private_constructed + (EMemoShellView *memo_shell_view); +void e_memo_shell_view_private_dispose + (EMemoShellView *memo_shell_view); +void e_memo_shell_view_private_finalize + (EMemoShellView *memo_shell_view); + +/* Private Utilities */ + +void e_memo_shell_view_actions_init + (EMemoShellView *memo_shell_view); +void e_memo_shell_view_execute_search + (EMemoShellView *memo_shell_view); +void e_memo_shell_view_open_memo + (EMemoShellView *memo_shell_view, + ECalModelComponent *comp_data); +void e_memo_shell_view_set_status_message + (EMemoShellView *memo_shell_view, + const gchar *status_message, + gdouble percent); +void e_memo_shell_view_update_sidebar + (EMemoShellView *memo_shell_view); +void e_memo_shell_view_update_search_filter + (EMemoShellView *memo_shell_view); + +G_END_DECLS + +#endif /* E_MEMO_SHELL_VIEW_PRIVATE_H */ diff --git a/calendar/modules/e-memo-shell-view.c b/calendar/modules/e-memo-shell-view.c new file mode 100644 index 0000000000..89efd8f15d --- /dev/null +++ b/calendar/modules/e-memo-shell-view.c @@ -0,0 +1,263 @@ +/* + * e-memo-shell-view.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-memo-shell-view-private.h" + +enum { + PROP_0, + PROP_SOURCE_LIST +}; + +GType e_memo_shell_view_type = 0; +static gpointer parent_class; + +static void +memo_shell_view_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_SOURCE_LIST: + g_value_set_object ( + value, e_memo_shell_view_get_source_list ( + E_MEMO_SHELL_VIEW (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +memo_shell_view_dispose (GObject *object) +{ + e_memo_shell_view_private_dispose (E_MEMO_SHELL_VIEW (object)); + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +memo_shell_view_finalize (GObject *object) +{ + e_memo_shell_view_private_finalize (E_MEMO_SHELL_VIEW (object)); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +memo_shell_view_constructed (GObject *object) +{ + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (parent_class)->constructed (object); + + e_memo_shell_view_private_constructed (E_MEMO_SHELL_VIEW (object)); +} + +static void +memo_shell_view_update_actions (EShellView *shell_view) +{ + EMemoShellViewPrivate *priv; + EShellContent *shell_content; + EShellSidebar *shell_sidebar; + EShellWindow *shell_window; + GtkAction *action; + const gchar *label; + gboolean sensitive; + guint32 state; + + /* Be descriptive. */ + gboolean any_memos_selected; + gboolean has_primary_source; + gboolean multiple_memos_selected; + gboolean primary_source_is_system; + gboolean selection_has_url; + gboolean single_memo_selected; + gboolean sources_are_editable; + + priv = E_MEMO_SHELL_VIEW_GET_PRIVATE (shell_view); + + shell_window = e_shell_view_get_shell_window (shell_view); + + shell_content = e_shell_view_get_shell_content (shell_view); + state = e_shell_content_check_state (shell_content); + + single_memo_selected = + (state & E_MEMO_SHELL_CONTENT_SELECTION_SINGLE); + multiple_memos_selected = + (state & E_MEMO_SHELL_CONTENT_SELECTION_MULTIPLE); + sources_are_editable = + (state & E_MEMO_SHELL_CONTENT_SELECTION_CAN_EDIT); + selection_has_url = + (state & E_MEMO_SHELL_CONTENT_SELECTION_HAS_URL); + + shell_sidebar = e_shell_view_get_shell_sidebar (shell_view); + state = e_shell_sidebar_check_state (shell_sidebar); + + has_primary_source = + (state & E_MEMO_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE); + primary_source_is_system = + (state & E_MEMO_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_SYSTEM); + + any_memos_selected = + (single_memo_selected || multiple_memos_selected); + + action = ACTION (MEMO_CLIPBOARD_COPY); + sensitive = any_memos_selected; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (MEMO_CLIPBOARD_CUT); + sensitive = any_memos_selected && sources_are_editable; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (MEMO_CLIPBOARD_PASTE); + sensitive = sources_are_editable; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (MEMO_DELETE); + sensitive = any_memos_selected && sources_are_editable; + gtk_action_set_sensitive (action, sensitive); + if (multiple_memos_selected) + label = _("Delete Memos"); + else + label = _("Delete Memo"); + g_object_set (action, "label", label, NULL); + + action = ACTION (MEMO_FORWARD); + sensitive = single_memo_selected; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (MEMO_LIST_COPY); + sensitive = has_primary_source; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (MEMO_LIST_DELETE); + sensitive = has_primary_source && !primary_source_is_system; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (MEMO_LIST_PROPERTIES); + sensitive = has_primary_source; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (MEMO_LIST_RENAME); + sensitive = has_primary_source; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (MEMO_OPEN); + sensitive = single_memo_selected; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (MEMO_OPEN_URL); + sensitive = single_memo_selected && selection_has_url; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (MEMO_PRINT); + sensitive = single_memo_selected; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (MEMO_SAVE_AS); + sensitive = single_memo_selected; + gtk_action_set_sensitive (action, sensitive); +} + +static void +memo_shell_view_class_init (EMemoShellViewClass *class, + GTypeModule *type_module) +{ + GObjectClass *object_class; + EShellViewClass *shell_view_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EMemoShellViewPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->get_property = memo_shell_view_get_property; + object_class->dispose = memo_shell_view_dispose; + object_class->finalize = memo_shell_view_finalize; + object_class->constructed = memo_shell_view_constructed; + + shell_view_class = E_SHELL_VIEW_CLASS (class); + shell_view_class->label = _("Memos"); + shell_view_class->icon_name = "evolution-memos"; + shell_view_class->ui_definition = "evolution-memos.ui"; + shell_view_class->ui_manager_id = "org.gnome.evolution.memos"; + shell_view_class->search_options = "/memo-search-options"; + shell_view_class->search_rules = "memotypes.xml"; + shell_view_class->type_module = type_module; + shell_view_class->new_shell_content = e_memo_shell_content_new; + shell_view_class->new_shell_sidebar = e_memo_shell_sidebar_new; + shell_view_class->update_actions = memo_shell_view_update_actions; + + g_object_class_install_property ( + object_class, + PROP_SOURCE_LIST, + g_param_spec_object ( + "source-list", + _("Source List"), + _("The registry of memo lists"), + E_TYPE_SOURCE_LIST, + G_PARAM_READABLE)); +} + +static void +memo_shell_view_init (EMemoShellView *memo_shell_view, + EShellViewClass *shell_view_class) +{ + memo_shell_view->priv = + E_MEMO_SHELL_VIEW_GET_PRIVATE (memo_shell_view); + + e_memo_shell_view_private_init (memo_shell_view, shell_view_class); +} + +GType +e_memo_shell_view_get_type (GTypeModule *type_module) +{ + if (e_memo_shell_view_type == 0) { + const GTypeInfo type_info = { + sizeof (EMemoShellViewClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) memo_shell_view_class_init, + (GClassFinalizeFunc) NULL, + type_module, + sizeof (EMemoShellView), + 0, /* n_preallocs */ + (GInstanceInitFunc) memo_shell_view_init, + NULL /* value_table */ + }; + + e_memo_shell_view_type = + g_type_module_register_type ( + type_module, E_TYPE_SHELL_VIEW, + "EMemoShellView", &type_info, 0); + } + + return e_memo_shell_view_type; +} + +ESourceList * +e_memo_shell_view_get_source_list (EMemoShellView *memo_shell_view) +{ + g_return_val_if_fail (E_IS_MEMO_SHELL_VIEW (memo_shell_view), NULL); + + return memo_shell_view->priv->source_list; +} diff --git a/calendar/modules/e-memo-shell-view.h b/calendar/modules/e-memo-shell-view.h new file mode 100644 index 0000000000..0cc77ad1d7 --- /dev/null +++ b/calendar/modules/e-memo-shell-view.h @@ -0,0 +1,71 @@ +/* + * e-memo-shell-view.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_MEMO_SHELL_VIEW_H +#define E_MEMO_SHELL_VIEW_H + +#include <shell/e-shell-view.h> +#include <libedataserver/e-source-list.h> + +/* Standard GObject macros */ +#define E_TYPE_MEMO_SHELL_VIEW \ + (e_memo_shell_view_type) +#define E_MEMO_SHELL_VIEW(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_MEMO_SHELL_VIEW, EMemoShellView)) +#define E_MEMO_SHELL_VIEW_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_MEMO_SHELL_VIEW, EMemoShellViewClass)) +#define E_IS_MEMO_SHELL_VIEW(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_MEMO_SHELL_VIEW)) +#define E_IS_MEMO_SHELL_VIEW_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_MEMO_SHELL_VIEW)) +#define E_MEMO_SHELL_VIEW_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_MEMO_SHELL_VIEW, EMemoShellViewClass)) + +G_BEGIN_DECLS + +extern GType e_memo_shell_view_type; + +typedef struct _EMemoShellView EMemoShellView; +typedef struct _EMemoShellViewClass EMemoShellViewClass; +typedef struct _EMemoShellViewPrivate EMemoShellViewPrivate; + +struct _EMemoShellView { + EShellView parent; + EMemoShellViewPrivate *priv; +}; + +struct _EMemoShellViewClass { + EShellViewClass parent_class; +}; + +GType e_memo_shell_view_get_type + (GTypeModule *type_module); +ESourceList * e_memo_shell_view_get_source_list + (EMemoShellView *memo_shell_view); + +G_END_DECLS + +#endif /* E_MEMO_SHELL_VIEW_H */ diff --git a/calendar/modules/e-task-shell-content.c b/calendar/modules/e-task-shell-content.c new file mode 100644 index 0000000000..5e98bf2f49 --- /dev/null +++ b/calendar/modules/e-task-shell-content.c @@ -0,0 +1,699 @@ +/* + * e-task-shell-content.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-task-shell-content.h" + +#include <glib/gi18n.h> + +#include "e-util/gconf-bridge.h" + +#include "calendar/gui/calendar-config.h" +#include "calendar/gui/comp-util.h" +#include "calendar/gui/e-cal-model-tasks.h" +#include "calendar/gui/e-calendar-table.h" +#include "calendar/gui/e-calendar-table-config.h" + +#include "widgets/menus/gal-view-etable.h" + +#define E_TASK_SHELL_CONTENT_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_TASK_SHELL_CONTENT, ETaskShellContentPrivate)) + +#define E_CALENDAR_TABLE_DEFAULT_STATE \ + "<?xml version=\"1.0\"?>" \ + "<ETableState>" \ + " <column source=\"13\"/>" \ + " <column source=\"14\"/>" \ + " <column source=\"9\"/>" \ + " <column source=\"5\"/>" \ + " <grouping/>" \ + "</ETableState>" + +struct _ETaskShellContentPrivate { + GtkWidget *paned; + GtkWidget *task_table; + GtkWidget *task_preview; + + ECalModel *task_model; + ECalendarTableConfig *table_config; + GalViewInstance *view_instance; + + gchar *current_uid; +}; + +enum { + PROP_0, + PROP_MODEL, + PROP_PREVIEW_VISIBLE +}; + +enum { + TARGET_VCALENDAR +}; + +static GtkTargetEntry drag_types[] = { + { "text/calendar", 0, TARGET_VCALENDAR }, + { "text/x-calendar", 0, TARGET_VCALENDAR } +}; + +static gpointer parent_class; + +static void +task_shell_content_display_view_cb (ETaskShellContent *task_shell_content, + GalView *gal_view) +{ + ECalendarTable *task_table; + ETable *table; + + if (!GAL_IS_VIEW_ETABLE (gal_view)) + return; + + task_table = e_task_shell_content_get_task_table (task_shell_content); + table = e_calendar_table_get_table (task_table); + + gal_view_etable_attach_table (GAL_VIEW_ETABLE (gal_view), table); +} + +static void +task_shell_content_table_foreach_cb (gint model_row, + gpointer user_data) +{ + ECalModelComponent *comp_data; + icalcomponent *clone; + icalcomponent *vcal; + gchar *string; + + struct { + ECalModel *model; + GSList *list; + } *foreach_data = user_data; + + comp_data = e_cal_model_get_component_at ( + foreach_data->model, model_row); + + vcal = e_cal_util_new_top_level (); + clone = icalcomponent_new_clone (comp_data->icalcomp); + e_cal_util_add_timezones_from_component (vcal, comp_data->icalcomp); + icalcomponent_add_component (vcal, clone); + + /* String is owned by libical; do not free. */ + string = icalcomponent_as_ical_string (vcal); + if (string != NULL) { + ESource *source; + const gchar *source_uid; + + source = e_cal_get_source (comp_data->client); + source_uid = e_source_peek_uid (source); + + foreach_data->list = g_slist_prepend ( + foreach_data->list, + g_strdup_printf ("%s\n%s", source_uid, string)); + } + + icalcomponent_free (vcal); +} + +static void +task_shell_content_table_drag_data_get_cb (ETaskShellContent *task_shell_content, + gint row, + gint col, + GdkDragContext *context, + GtkSelectionData *selection_data, + guint info, + guint time) +{ + ECalendarTable *task_table; + ETable *table; + + struct { + ECalModel *model; + GSList *list; + } foreach_data; + + if (info != TARGET_VCALENDAR) + return; + + task_table = e_task_shell_content_get_task_table (task_shell_content); + table = e_calendar_table_get_table (task_table); + + foreach_data.model = e_calendar_table_get_model (task_table); + foreach_data.list = NULL; + + e_table_selected_row_foreach ( + table, task_shell_content_table_foreach_cb, + &foreach_data); + + if (foreach_data.list != NULL) { + cal_comp_selection_set_string_list ( + selection_data, foreach_data.list); + g_slist_foreach (foreach_data.list, (GFunc) g_free, NULL); + g_slist_free (foreach_data.list); + } +} + +static void +task_shell_content_table_drag_data_delete_cb (ETaskShellContent *task_shell_content, + gint row, + gint col, + GdkDragContext *context) +{ + /* Moved components are deleted from source immediately when moved, + * because some of them can be part of destination source, and we + * don't want to delete not-moved tasks. There is no such information + * which event has been moved and which not, so skip this method. */ +} + +static void +task_shell_content_cursor_change_cb (ETaskShellContent *task_shell_content, + gint row, + ETable *table) +{ + ECalComponentPreview *task_preview; + ECalendarTable *task_table; + ECalModel *task_model; + ECalModelComponent *comp_data; + ECalComponent *comp; + const gchar *uid; + + task_model = e_task_shell_content_get_task_model (task_shell_content); + task_table = e_task_shell_content_get_task_table (task_shell_content); + task_preview = e_task_shell_content_get_task_preview (task_shell_content); + + if (e_table_selected_count (table) != 1) { + e_cal_component_preview_clear (task_preview); + return; + } + + row = e_table_get_cursor_row (table); + comp_data = e_cal_model_get_component_at (task_model, row); + + comp = e_cal_component_new (); + e_cal_component_set_icalcomponent ( + comp, icalcomponent_new_clone (comp_data->icalcomp)); + e_cal_component_preview_display ( + task_preview, comp_data->client, comp); + + e_cal_component_get_uid (comp, &uid); + g_free (task_shell_content->priv->current_uid); + task_shell_content->priv->current_uid = g_strdup (uid); + + g_object_unref (comp); +} + +static void +task_shell_content_selection_change_cb (ETaskShellContent *task_shell_content, + ETable *table) +{ + ECalComponentPreview *task_preview; + + task_preview = e_task_shell_content_get_task_preview (task_shell_content); + + if (e_table_selected_count (table) != 1) + e_cal_component_preview_clear (task_preview); +} + +static void +task_shell_content_model_row_changed_cb (ETaskShellContent *task_shell_content, + gint row, + ETableModel *model) +{ + ECalModelComponent *comp_data; + ECalendarTable *task_table; + ETable *table; + const gchar *current_uid; + const gchar *uid; + + current_uid = task_shell_content->priv->current_uid; + if (current_uid == NULL) + return; + + comp_data = e_cal_model_get_component_at (E_CAL_MODEL (model), row); + if (comp_data == NULL) + return; + + uid = icalcomponent_get_uid (comp_data->icalcomp); + if (g_strcmp0 (uid, current_uid) != 0) + return; + + task_table = e_task_shell_content_get_task_table (task_shell_content); + table = e_calendar_table_get_table (task_table); + + task_shell_content_cursor_change_cb (task_shell_content, 0, table); +} + +static void +task_shell_content_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_PREVIEW_VISIBLE: + e_task_shell_content_set_preview_visible ( + E_TASK_SHELL_CONTENT (object), + g_value_get_boolean (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +task_shell_content_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_MODEL: + g_value_set_object ( + value, e_task_shell_content_get_task_model ( + E_TASK_SHELL_CONTENT (object))); + return; + + case PROP_PREVIEW_VISIBLE: + g_value_set_boolean ( + value, e_task_shell_content_get_preview_visible ( + E_TASK_SHELL_CONTENT (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +task_shell_content_dispose (GObject *object) +{ + ETaskShellContentPrivate *priv; + + priv = E_TASK_SHELL_CONTENT_GET_PRIVATE (object); + + if (priv->paned != NULL) { + g_object_unref (priv->paned); + priv->paned = NULL; + } + + if (priv->task_table != NULL) { + g_object_unref (priv->task_table); + priv->task_table = NULL; + } + + if (priv->task_preview != NULL) { + g_object_unref (priv->task_preview); + priv->task_preview = NULL; + } + + if (priv->task_model != NULL) { + g_object_unref (priv->task_model); + priv->task_model = NULL; + } + + if (priv->table_config != NULL) { + g_object_unref (priv->table_config); + priv->table_config = NULL; + } + + if (priv->view_instance != NULL) { + g_object_unref (priv->view_instance); + priv->view_instance = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +task_shell_content_finalize (GObject *object) +{ + ETaskShellContentPrivate *priv; + + priv = E_TASK_SHELL_CONTENT_GET_PRIVATE (object); + + g_free (priv->current_uid); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +task_shell_content_constructed (GObject *object) +{ + ETaskShellContentPrivate *priv; + EShellContent *shell_content; + EShellView *shell_view; + GalViewInstance *view_instance; + ETable *table; + GConfBridge *bridge; + GtkWidget *container; + GtkWidget *widget; + const gchar *key; + + priv = E_TASK_SHELL_CONTENT_GET_PRIVATE (object); + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (parent_class)->constructed (object); + + shell_content = E_SHELL_CONTENT (object); + shell_view = e_shell_content_get_shell_view (shell_content); + + /* Build content widgets. */ + + container = GTK_WIDGET (object); + + widget = gtk_vpaned_new (); + gtk_container_add (GTK_CONTAINER (container), widget); + priv->paned = g_object_ref (widget); + gtk_widget_show (widget); + + container = widget; + + widget = e_calendar_table_new (shell_view, priv->task_model); + gtk_paned_add1 (GTK_PANED (container), widget); + priv->task_table = g_object_ref (widget); + gtk_widget_show (widget); + + widget = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy ( + GTK_SCROLLED_WINDOW (widget), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type ( + GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN); + gtk_paned_add2 (GTK_PANED (container), widget); + gtk_widget_show (widget); + + container = widget; + + widget = e_cal_component_preview_new (); + e_cal_component_preview_set_default_timezone ( + E_CAL_COMPONENT_PREVIEW (widget), + calendar_config_get_icaltimezone ()); + gtk_container_add (GTK_CONTAINER (container), widget); + priv->task_preview = g_object_ref (widget); + gtk_widget_show (widget); + + /* Configure the task table. */ + + widget = E_CALENDAR_TABLE (priv->task_table)->etable; + table = e_table_scrolled_get_table (E_TABLE_SCROLLED (widget)); + + priv->table_config = e_calendar_table_config_new ( + E_CALENDAR_TABLE (priv->task_table)); + + e_table_set_state (table, E_CALENDAR_TABLE_DEFAULT_STATE); + + e_table_drag_source_set ( + table, GDK_BUTTON1_MASK, + drag_types, G_N_ELEMENTS (drag_types), + GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_ASK); + + g_signal_connect_swapped ( + table, "table-drag-data-get", + G_CALLBACK (task_shell_content_table_drag_data_get_cb), + object); + + g_signal_connect_swapped ( + table, "table-drag-data-delete", + G_CALLBACK (task_shell_content_table_drag_data_delete_cb), + object); + + g_signal_connect_swapped ( + table, "cursor-change", + G_CALLBACK (task_shell_content_cursor_change_cb), + object); + + g_signal_connect_swapped ( + table, "selection-change", + G_CALLBACK (task_shell_content_selection_change_cb), + object); + + g_signal_connect_swapped ( + priv->task_model, "model-row-changed", + G_CALLBACK (task_shell_content_model_row_changed_cb), + object); + + /* Load the view instance. */ + + view_instance = e_shell_view_new_view_instance (shell_view, NULL); + g_signal_connect_swapped ( + view_instance, "display-view", + G_CALLBACK (task_shell_content_display_view_cb), + object); + gal_view_instance_load (view_instance); + priv->view_instance = view_instance; + + /* Bind GObject properties to GConf keys. */ + + bridge = gconf_bridge_get (); + + object = G_OBJECT (priv->paned); + key = "/apps/evolution/calendar/display/task_vpane_position"; + gconf_bridge_bind_property_delayed (bridge, key, object, "position"); +} + +static guint32 +task_shell_content_check_state (EShellContent *shell_content) +{ + ETaskShellContent *task_shell_content; + ECalendarTable *task_table; + ETable *table; + GSList *list, *iter; + gboolean assignable = TRUE; + gboolean editable = TRUE; + gboolean has_url = FALSE; + gint n_selected; + gint n_complete = 0; + gint n_incomplete = 0; + guint32 state = 0; + + task_shell_content = E_TASK_SHELL_CONTENT (shell_content); + task_table = e_task_shell_content_get_task_table (task_shell_content); + + table = e_calendar_table_get_table (task_table); + n_selected = e_table_selected_count (table); + + list = e_calendar_table_get_selected (task_table); + for (iter = list; iter != NULL; iter = iter->next) { + ECalModelComponent *comp_data = iter->data; + icalproperty *prop; + const gchar *cap; + gboolean read_only; + + e_cal_is_read_only (comp_data->client, &read_only, NULL); + editable &= !read_only; + + cap = CAL_STATIC_CAPABILITY_NO_TASK_ASSIGNMENT; + if (e_cal_get_static_capability (comp_data->client, cap)) + assignable = FALSE; + + cap = CAL_STATIC_CAPABILITY_NO_CONV_TO_ASSIGN_TASK; + if (e_cal_get_static_capability (comp_data->client, cap)) + assignable = FALSE; + + prop = icalcomponent_get_first_property ( + comp_data->icalcomp, ICAL_URL_PROPERTY); + has_url |= (prop != NULL); + + prop = icalcomponent_get_first_property ( + comp_data->icalcomp, ICAL_COMPLETED_PROPERTY); + if (prop != NULL) + n_complete++; + else + n_incomplete++; + } + g_slist_free (list); + + if (n_selected == 1) + state |= E_TASK_SHELL_CONTENT_SELECTION_SINGLE; + if (n_selected > 1) + state |= E_TASK_SHELL_CONTENT_SELECTION_MULTIPLE; + if (assignable) + state |= E_TASK_SHELL_CONTENT_SELECTION_CAN_ASSIGN; + if (editable) + state |= E_TASK_SHELL_CONTENT_SELECTION_CAN_EDIT; + if (n_complete > 0) + state |= E_TASK_SHELL_CONTENT_SELECTION_HAS_COMPLETE; + if (n_incomplete > 0) + state |= E_TASK_SHELL_CONTENT_SELECTION_HAS_INCOMPLETE; + if (has_url) + state |= E_TASK_SHELL_CONTENT_SELECTION_HAS_URL; + + return state; +} + +static void +task_shell_content_class_init (ETaskShellContentClass *class) +{ + GObjectClass *object_class; + EShellContentClass *shell_content_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (ETaskShellContentPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = task_shell_content_set_property; + object_class->get_property = task_shell_content_get_property; + object_class->dispose = task_shell_content_dispose; + object_class->finalize = task_shell_content_finalize; + object_class->constructed = task_shell_content_constructed; + + shell_content_class = E_SHELL_CONTENT_CLASS (class); + shell_content_class->check_state = task_shell_content_check_state; + + g_object_class_install_property ( + object_class, + PROP_MODEL, + g_param_spec_object ( + "model", + _("Model"), + _("The task table model"), + E_TYPE_CAL_MODEL, + G_PARAM_READABLE)); + + g_object_class_install_property ( + object_class, + PROP_PREVIEW_VISIBLE, + g_param_spec_boolean ( + "preview-visible", + _("Preview is Visible"), + _("Whether the preview pane is visible"), + TRUE, + G_PARAM_READWRITE)); +} + +static void +task_shell_content_init (ETaskShellContent *task_shell_content) +{ + task_shell_content->priv = + E_TASK_SHELL_CONTENT_GET_PRIVATE (task_shell_content); + + task_shell_content->priv->task_model = e_cal_model_tasks_new (); + + /* Postpone widget construction until we have a shell view. */ +} + +GType +e_task_shell_content_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (ETaskShellContentClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) task_shell_content_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (ETaskShellContent), + 0, /* n_preallocs */ + (GInstanceInitFunc) task_shell_content_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + E_TYPE_SHELL_CONTENT, "ETaskShellContent", + &type_info, 0); + } + + return type; +} + +GtkWidget * +e_task_shell_content_new (EShellView *shell_view) +{ + g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); + + return g_object_new ( + E_TYPE_TASK_SHELL_CONTENT, + "shell-view", shell_view, NULL); +} + +ECalModel * +e_task_shell_content_get_task_model (ETaskShellContent *task_shell_content) +{ + g_return_val_if_fail ( + E_IS_TASK_SHELL_CONTENT (task_shell_content), NULL); + + return task_shell_content->priv->task_model; +} + +ECalComponentPreview * +e_task_shell_content_get_task_preview (ETaskShellContent *task_shell_content) +{ + g_return_val_if_fail ( + E_IS_TASK_SHELL_CONTENT (task_shell_content), NULL); + + return E_CAL_COMPONENT_PREVIEW ( + task_shell_content->priv->task_preview); +} + +ECalendarTable * +e_task_shell_content_get_task_table (ETaskShellContent *task_shell_content) +{ + g_return_val_if_fail ( + E_IS_TASK_SHELL_CONTENT (task_shell_content), NULL); + + return E_CALENDAR_TABLE (task_shell_content->priv->task_table); +} + +GalViewInstance * +e_task_shell_content_get_view_instance (ETaskShellContent *task_shell_content) +{ + g_return_val_if_fail ( + E_IS_TASK_SHELL_CONTENT (task_shell_content), NULL); + + return task_shell_content->priv->view_instance; +} + +gboolean +e_task_shell_content_get_preview_visible (ETaskShellContent *task_shell_content) +{ + GtkPaned *paned; + GtkWidget *child; + + g_return_val_if_fail ( + E_IS_TASK_SHELL_CONTENT (task_shell_content), FALSE); + + paned = GTK_PANED (task_shell_content->priv->paned); + child = gtk_paned_get_child2 (paned); + + return GTK_WIDGET_VISIBLE (child); +} + +void +e_task_shell_content_set_preview_visible (ETaskShellContent *task_shell_content, + gboolean preview_visible) +{ + GtkPaned *paned; + GtkWidget *child; + + g_return_if_fail (E_IS_TASK_SHELL_CONTENT (task_shell_content)); + + paned = GTK_PANED (task_shell_content->priv->paned); + child = gtk_paned_get_child2 (paned); + + if (preview_visible) + gtk_widget_show (child); + else + gtk_widget_hide (child); + + g_object_notify (G_OBJECT (task_shell_content), "preview-visible"); +} diff --git a/calendar/modules/e-task-shell-content.h b/calendar/modules/e-task-shell-content.h new file mode 100644 index 0000000000..e6f64f7406 --- /dev/null +++ b/calendar/modules/e-task-shell-content.h @@ -0,0 +1,98 @@ +/* + * e-task-shell-content.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_TASK_SHELL_CONTENT_H +#define E_TASK_SHELL_CONTENT_H + +#include <shell/e-shell-content.h> +#include <shell/e-shell-view.h> + +#include <calendar/gui/e-cal-model.h> +#include <calendar/gui/e-calendar-table.h> +#include <calendar/gui/e-cal-component-preview.h> + +#include <widgets/menus/gal-view-instance.h> + +/* Standard GObject macros */ +#define E_TYPE_TASK_SHELL_CONTENT \ + (e_task_shell_content_get_type ()) +#define E_TASK_SHELL_CONTENT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_TASK_SHELL_CONTENT, ETaskShellContent)) +#define E_TASK_SHELL_CONTENT_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_TASK_SHELL_CONTENT, ETaskShellContentClass)) +#define E_IS_TASK_SHELL_CONTENT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_TASK_SHELL_CONTENT)) +#define E_IS_TASK_SHELL_CONTENT_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_TASK_SHELL_CONTENT)) +#define E_TASK_SHELL_CONTENT_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_TASK_SHELL_CONTENT, ETaskShellContentClass)) + +G_BEGIN_DECLS + +typedef struct _ETaskShellContent ETaskShellContent; +typedef struct _ETaskShellContentClass ETaskShellContentClass; +typedef struct _ETaskShellContentPrivate ETaskShellContentPrivate; + +enum { + E_TASK_SHELL_CONTENT_SELECTION_SINGLE = 1 << 0, + E_TASK_SHELL_CONTENT_SELECTION_MULTIPLE = 1 << 1, + E_TASK_SHELL_CONTENT_SELECTION_CAN_ASSIGN = 1 << 2, + E_TASK_SHELL_CONTENT_SELECTION_CAN_EDIT = 1 << 3, + E_TASK_SHELL_CONTENT_SELECTION_HAS_COMPLETE = 1 << 4, + E_TASK_SHELL_CONTENT_SELECTION_HAS_INCOMPLETE = 1 << 5, + E_TASK_SHELL_CONTENT_SELECTION_HAS_URL = 1 << 6 +}; + +struct _ETaskShellContent { + EShellContent parent; + ETaskShellContentPrivate *priv; +}; + +struct _ETaskShellContentClass { + EShellContentClass parent_class; +}; + +GType e_task_shell_content_get_type (void); +GtkWidget * e_task_shell_content_new (EShellView *shell_view); +ECalModel * e_task_shell_content_get_task_model + (ETaskShellContent *task_shell_content); +ECalComponentPreview * + e_task_shell_content_get_task_preview + (ETaskShellContent *task_shell_content); +ECalendarTable *e_task_shell_content_get_task_table + (ETaskShellContent *task_shell_content); +GalViewInstance * + e_task_shell_content_get_view_instance + (ETaskShellContent *task_shell_content); +gboolean e_task_shell_content_get_preview_visible + (ETaskShellContent *task_shell_content); +void e_task_shell_content_set_preview_visible + (ETaskShellContent *task_shell_content, + gboolean preview_visible); + +G_END_DECLS + +#endif /* E_TASK_SHELL_CONTENT_H */ diff --git a/calendar/modules/e-task-shell-module-migrate.c b/calendar/modules/e-task-shell-module-migrate.c new file mode 100644 index 0000000000..2bd34e89a9 --- /dev/null +++ b/calendar/modules/e-task-shell-module-migrate.c @@ -0,0 +1,664 @@ +/* + * e-task-shell-module-migrate.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-task-shell-module-migrate.h" + +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> + +#include <glib/gi18n.h> +#include <glib/gstdio.h> +#include <libebackend/e-dbhash.h> +#include <libedataserver/e-source.h> +#include <libedataserver/e-source-group.h> +#include <libedataserver/e-source-list.h> +#include <libedataserver/e-xml-hash-utils.h> +#include <libedataserver/e-xml-utils.h> + +#include "e-util/e-bconf-map.h" +#include "e-util/e-folder-map.h" +#include "e-util/e-util-private.h" +#include "calendar/gui/calendar-config.h" +#include "calendar/gui/calendar-config-keys.h" + +#define WEBCAL_BASE_URI "webcal://" +#define PERSONAL_RELATIVE_URI "system" + +static e_gconf_map_t calendar_tasks_map[] = { + /* /Calendar/Tasks */ + { "HideCompletedTasks", "calendar/tasks/hide_completed", E_GCONF_MAP_BOOL }, + { "HideCompletedTasksUnits", "calendar/tasks/hide_completed_units", E_GCONF_MAP_STRING }, + { "HideCompletedTasksValue", "calendar/tasks/hide_completed_value", E_GCONF_MAP_INT }, + { NULL }, +}; + +static e_gconf_map_t calendar_tasks_colours_map[] = { + /* /Calendar/Tasks/Colors */ + { "TasksDueToday", "calendar/tasks/colors/due_today", E_GCONF_MAP_STRING }, + { "TasksOverDue", "calendar/tasks/colors/overdue", E_GCONF_MAP_STRING }, + { "TasksDueToday", "calendar/tasks/colors/due_today", E_GCONF_MAP_STRING }, + { NULL }, +}; + +static e_gconf_map_list_t task_remap_list[] = { + + { "/Calendar/Tasks", calendar_tasks_map }, + { "/Calendar/Tasks/Colors", calendar_tasks_colours_map }, + + { NULL }, +}; + +static GtkWidget *window; +static GtkLabel *label; +static GtkProgressBar *progress; + +#ifndef G_OS_WIN32 + +/* No previous versions have been available on Win32, so don't + * bother with upgrade support from 1.x on Win32. + */ + +static void +setup_progress_dialog (void) +{ + GtkWidget *vbox, *hbox, *w; + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title ((GtkWindow *) window, _("Migrating...")); + gtk_window_set_modal ((GtkWindow *) window, TRUE); + gtk_container_set_border_width ((GtkContainer *) window, 6); + + vbox = gtk_vbox_new (FALSE, 6); + gtk_widget_show (vbox); + gtk_container_add ((GtkContainer *) window, vbox); + + w = gtk_label_new (_("The location and hierarchy of the Evolution task " + "folders has changed since Evolution 1.x.\n\nPlease be " + "patient while Evolution migrates your folders...")); + + gtk_label_set_line_wrap ((GtkLabel *) w, TRUE); + gtk_widget_show (w); + gtk_box_pack_start_defaults ((GtkBox *) vbox, w); + + hbox = gtk_hbox_new (FALSE, 6); + gtk_widget_show (hbox); + gtk_box_pack_start_defaults ((GtkBox *) vbox, hbox); + + label = (GtkLabel *) gtk_label_new (""); + gtk_widget_show ((GtkWidget *) label); + gtk_box_pack_start_defaults ((GtkBox *) hbox, (GtkWidget *) label); + + progress = (GtkProgressBar *) gtk_progress_bar_new (); + gtk_widget_show ((GtkWidget *) progress); + gtk_box_pack_start_defaults ((GtkBox *) hbox, (GtkWidget *) progress); + + gtk_widget_show (window); +} + +static void +dialog_close (void) +{ + gtk_widget_destroy ((GtkWidget *) window); +} + +static void +dialog_set_folder_name (const char *folder_name) +{ + char *text; + + text = g_strdup_printf (_("Migrating '%s':"), folder_name); + gtk_label_set_text (label, text); + g_free (text); + + gtk_progress_bar_set_fraction (progress, 0.0); + + while (gtk_events_pending ()) + gtk_main_iteration (); +} + +static void +dialog_set_progress (double percent) +{ + char text[5]; + + snprintf (text, sizeof (text), "%d%%", (int) (percent * 100.0f)); + + gtk_progress_bar_set_fraction (progress, percent); + gtk_progress_bar_set_text (progress, text); + + while (gtk_events_pending ()) + gtk_main_iteration (); +} + +static gboolean +check_for_conflict (ESourceGroup *group, char *name) +{ + GSList *sources; + GSList *s; + + sources = e_source_group_peek_sources (group); + + for (s = sources; s; s = s->next) { + ESource *source = E_SOURCE (s->data); + + if (!strcmp (e_source_peek_name (source), name)) + return TRUE; + } + + return FALSE; +} + +static char * +get_source_name (ESourceGroup *group, const char *path) +{ + char **p = g_strsplit (path, "/", 0); + int i, j, starting_index; + int num_elements; + gboolean conflict; + GString *s = g_string_new (NULL); + + for (i = 0; p[i]; i ++) ; + + num_elements = i; + i--; + + /* p[i] is now the last path element */ + + /* check if it conflicts */ + starting_index = i; + do { + for (j = starting_index; j < num_elements; j += 2) { + if (j != starting_index) + g_string_append_c (s, '_'); + g_string_append (s, p[j]); + } + + conflict = check_for_conflict (group, s->str); + + + /* if there was a conflict back up 2 levels (skipping the /subfolder/ element) */ + if (conflict) + starting_index -= 2; + + /* we always break out if we can't go any further, + regardless of whether or not we conflict. */ + if (starting_index < 0) + break; + + } while (conflict); + g_strfreev (p); + + return g_string_free (s, FALSE); +} + +static gboolean +migrate_ical (ECal *old_ecal, ECal *new_ecal) +{ + GList *l, *objects; + int num_added = 0; + int num_objects; + gboolean retval = TRUE; + + /* both ecals are loaded, start the actual migration */ + if (!e_cal_get_object_list (old_ecal, "#t", &objects, NULL)) + return FALSE; + + num_objects = g_list_length (objects); + for (l = objects; l; l = l->next) { + icalcomponent *ical_comp = l->data; + GError *error = NULL; + + if (!e_cal_create_object (new_ecal, ical_comp, NULL, &error)) { + g_warning ("Migration of object failed: %s", error->message); + retval = FALSE; + } + + g_clear_error (&error); + + num_added ++; + dialog_set_progress ((double)num_added / num_objects); + } + + g_list_foreach (objects, (GFunc) icalcomponent_free, NULL); + g_list_free (objects); + + return retval; +} + +static gboolean +migrate_ical_folder_to_source (char *old_path, ESource *new_source, ECalSourceType type) +{ + ECal *old_ecal = NULL, *new_ecal = NULL; + ESource *old_source; + ESourceGroup *group; + char *old_uri = g_strdup_printf ("file://%s", old_path); + GError *error = NULL; + gboolean retval = FALSE; + + group = e_source_group_new ("", old_uri); + old_source = e_source_new ("", ""); + e_source_group_add_source (group, old_source, -1); + + dialog_set_folder_name (e_source_peek_name (new_source)); + + if (!(old_ecal = e_cal_new (old_source, type))) { + g_warning ("could not find a backend for '%s'", e_source_get_uri (old_source)); + goto finish; + } + if (!e_cal_open (old_ecal, FALSE, &error)) { + g_warning ("failed to load source ecal for migration: '%s' (%s)", error->message, + e_source_get_uri (old_source)); + goto finish; + } + + if (!(new_ecal = e_cal_new (new_source, type))) { + g_warning ("could not find a backend for '%s'", e_source_get_uri (new_source)); + goto finish; + } + if (!e_cal_open (new_ecal, FALSE, &error)) { + g_warning ("failed to load destination ecal for migration: '%s' (%s)", error->message, + e_source_get_uri (new_source)); + goto finish; + } + + retval = migrate_ical (old_ecal, new_ecal); + +finish: + g_clear_error (&error); + if (old_ecal) + g_object_unref (old_ecal); + g_object_unref (group); + if (new_ecal) + g_object_unref (new_ecal); + g_free (old_uri); + + return retval; +} + +static gboolean +migrate_ical_folder (char *old_path, ESourceGroup *dest_group, char *source_name, ECalSourceType type) +{ + ESource *new_source; + gboolean retval; + + new_source = e_source_new (source_name, source_name); + e_source_set_relative_uri (new_source, e_source_peek_uid (new_source)); + e_source_group_add_source (dest_group, new_source, -1); + + retval = migrate_ical_folder_to_source (old_path, new_source, type); + + g_object_unref (new_source); + + return retval; +} + +#endif /* !G_OS_WIN32 */ + +#ifndef G_OS_WIN32 + +static void +migrate_pilot_db_key (const char *key, gpointer user_data) +{ + EXmlHash *xmlhash = user_data; + + e_xmlhash_add (xmlhash, key, ""); +} + +static void +migrate_pilot_data (const char *component, const char *conduit, const char *old_path, const char *new_path) +{ + char *changelog, *map; + const char *dent; + const char *ext; + char *filename; + GDir *dir; + + if (!(dir = g_dir_open (old_path, 0, NULL))) + return; + + map = g_alloca (12 + strlen (conduit)); + sprintf (map, "pilot-map-%s-", conduit); + + changelog = g_alloca (24 + strlen (conduit)); + sprintf (changelog, "pilot-sync-evolution-%s-", conduit); + + while ((dent = g_dir_read_name (dir))) { + if (!strncmp (dent, map, strlen (map)) && + ((ext = strrchr (dent, '.')) && !strcmp (ext, ".xml"))) { + /* pilot map file - src and dest file formats are identical */ + unsigned char inbuf[4096]; + size_t nread, nwritten; + int fd0, fd1; + ssize_t n; + + filename = g_build_filename (old_path, dent, NULL); + if ((fd0 = g_open (filename, O_RDONLY|O_BINARY, 0)) == -1) { + g_free (filename); + continue; + } + + g_free (filename); + filename = g_build_filename (new_path, dent, NULL); + if ((fd1 = g_open (filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666)) == -1) { + g_free (filename); + close (fd0); + continue; + } + + do { + do { + n = read (fd0, inbuf, sizeof (inbuf)); + } while (n == -1 && errno == EINTR); + + if (n < 1) + break; + + nread = n; + nwritten = 0; + do { + do { + n = write (fd1, inbuf + nwritten, nread - nwritten); + } while (n == -1 && errno == EINTR); + + if (n > 0) + nwritten += n; + } while (nwritten < nread && n != -1); + + if (n == -1) + break; + } while (1); + + if (n != -1) + n = fsync (fd1); + + if (n == -1) { + g_warning ("Failed to migrate %s: %s", dent, strerror (errno)); + g_unlink (filename); + } + + close (fd0); + close (fd1); + g_free (filename); + } else if (!strncmp (dent, changelog, strlen (changelog)) && + ((ext = strrchr (dent, '.')) && !strcmp (ext, ".db"))) { + /* src and dest formats differ, src format is db3 while dest format is xml */ + EXmlHash *xmlhash; + EDbHash *dbhash; + struct stat st; + + filename = g_build_filename (old_path, dent, NULL); + if (g_stat (filename, &st) == -1) { + g_free (filename); + continue; + } + + dbhash = e_dbhash_new (filename); + g_free (filename); + + filename = g_strdup_printf ("%s/%s.ics-%s", new_path, component, dent); + if (g_stat (filename, &st) != -1) + g_unlink (filename); + xmlhash = e_xmlhash_new (filename); + g_free (filename); + + e_dbhash_foreach_key (dbhash, migrate_pilot_db_key, xmlhash); + + e_dbhash_destroy (dbhash); + + e_xmlhash_write (xmlhash); + e_xmlhash_destroy (xmlhash); + } + } + + g_dir_close (dir); +} + +#endif + +static void +create_task_sources (EShellModule *shell_module, + ESourceList *source_list, + ESourceGroup **on_this_computer, + ESourceGroup **on_the_web, + ESource **personal_source) +{ + GSList *groups; + ESourceGroup *group; + char *base_uri, *base_uri_proto; + const gchar *base_dir; + + *on_this_computer = NULL; + *on_the_web = NULL; + *personal_source = NULL; + + base_dir = e_shell_module_get_config_dir (shell_module); + base_uri = g_build_filename (base_dir, "local", NULL); + + base_uri_proto = g_filename_to_uri (base_uri, NULL, NULL); + + groups = e_source_list_peek_groups (source_list); + if (groups) { + /* groups are already there, we need to search for things... */ + GSList *g; + + for (g = groups; g; g = g->next) { + + group = E_SOURCE_GROUP (g->data); + + if (!*on_this_computer && !strcmp (base_uri_proto, e_source_group_peek_base_uri (group))) + *on_this_computer = g_object_ref (group); + else if (!*on_the_web && !strcmp (WEBCAL_BASE_URI, e_source_group_peek_base_uri (group))) + *on_the_web = g_object_ref (group); + } + } + + if (*on_this_computer) { + /* make sure "Personal" shows up as a source under + this group */ + GSList *sources = e_source_group_peek_sources (*on_this_computer); + GSList *s; + for (s = sources; s; s = s->next) { + ESource *source = E_SOURCE (s->data); + const gchar *relative_uri; + + relative_uri = e_source_peek_relative_uri (source); + if (relative_uri == NULL) + continue; + if (!strcmp (PERSONAL_RELATIVE_URI, relative_uri)) { + *personal_source = g_object_ref (source); + break; + } + } + } else { + /* create the local source group */ + group = e_source_group_new (_("On This Computer"), base_uri_proto); + e_source_list_add_group (source_list, group, -1); + + *on_this_computer = group; + } + + if (!*personal_source) { + /* Create the default Person task list */ + ESource *source = e_source_new (_("Personal"), PERSONAL_RELATIVE_URI); + e_source_group_add_source (*on_this_computer, source, -1); + + if (!calendar_config_get_primary_tasks () && !calendar_config_get_tasks_selected ()) { + GSList selected; + + calendar_config_set_primary_tasks (e_source_peek_uid (source)); + + selected.data = (gpointer)e_source_peek_uid (source); + selected.next = NULL; + calendar_config_set_tasks_selected (&selected); + } + + e_source_set_color_spec (source, "#BECEDD"); + *personal_source = source; + } + + if (!*on_the_web) { + /* Create the Webcal source group */ + group = e_source_group_new (_("On The Web"), WEBCAL_BASE_URI); + e_source_list_add_group (source_list, group, -1); + + *on_the_web = group; + } + + g_free (base_uri_proto); + g_free (base_uri); +} + +gboolean +e_task_shell_module_migrate (EShellModule *shell_module, + gint major, + gint minor, + gint micro, + GError **error) +{ + ESourceGroup *on_this_computer = NULL; + ESourceGroup *on_the_web = NULL; + ESource *personal_source = NULL; + ESourceList *source_list; + gboolean retval = FALSE; + + source_list = g_object_get_data ( + G_OBJECT (source_list), "source-list"); + + /* we call this unconditionally now - create_groups either + creates the groups/sources or it finds the necessary + groups/sources. */ + create_task_sources ( + shell_module, source_list, &on_this_computer, + &on_the_web, &personal_source); + +#ifndef G_OS_WIN32 + if (major == 1) { + xmlDocPtr config_doc = NULL; + char *conf_file; + + conf_file = g_build_filename (g_get_home_dir (), "evolution", "config.xmldb", NULL); + if (g_file_test (conf_file, G_FILE_TEST_IS_REGULAR)) + config_doc = e_xml_parse_file (conf_file); + g_free (conf_file); + + if (config_doc && minor <= 2) { + GConfClient *gconf; + int res = 0; + + /* move bonobo config to gconf */ + gconf = gconf_client_get_default (); + + res = e_bconf_import (gconf, config_doc, task_remap_list); + + g_object_unref (gconf); + + xmlFreeDoc(config_doc); + + if (res != 0) { + g_set_error(error, 0, 0, _("Unable to migrate old settings from evolution/config.xmldb")); + goto fail; + } + } + + if (minor <= 4) { + GSList *migration_dirs, *l; + char *path, *local_task_folder; + + setup_progress_dialog (); + + path = g_build_filename (g_get_home_dir (), "evolution", "local", NULL); + migration_dirs = e_folder_map_local_folders (path, "tasks"); + local_task_folder = g_build_filename (path, "Tasks", NULL); + g_free (path); + + if (personal_source) + migrate_ical_folder_to_source (local_task_folder, personal_source, E_CAL_SOURCE_TYPE_TODO); + + for (l = migration_dirs; l; l = l->next) { + char *source_name; + + if (personal_source && !strcmp ((char*)l->data, local_task_folder)) + continue; + + source_name = get_source_name (on_this_computer, (char*)l->data); + + if (!migrate_ical_folder (l->data, on_this_computer, source_name, E_CAL_SOURCE_TYPE_TODO)) { + /* FIXME: domain/code */ + g_set_error(error, 0, 0, _("Unable to migrate tasks `%s'"), source_name); + g_free(source_name); + goto fail; + } + + g_free (source_name); + } + + g_free (local_task_folder); + + dialog_close (); + } + + if (minor < 5 || (minor == 5 && micro <= 10)) { + char *old_path, *new_path; + + old_path = g_build_filename (g_get_home_dir (), "evolution", "local", "Tasks", NULL); + new_path = g_build_filename (e_shell_module_get_config_dir (shell_module), + "local", "system", NULL); + migrate_pilot_data ("tasks", "todo", old_path, new_path); + g_free (new_path); + g_free (old_path); + } + + /* we only need to do this next step if people ran + older versions of 1.5. We need to clear out the + absolute URI's that were assigned to ESources + during one phase of development, as they take + precedent over relative uris (but aren't updated + when editing an ESource). */ + if (minor == 5 && micro <= 11) { + GSList *g; + for (g = e_source_list_peek_groups (source_list); g; g = g->next) { + ESourceGroup *group = g->data; + GSList *s; + + for (s = e_source_group_peek_sources (group); s; s = s->next) { + ESource *source = s->data; + e_source_set_absolute_uri (source, NULL); + } + } + } + } +#endif /* !G_OS_WIN32 */ + e_source_list_sync (source_list, NULL); + retval = TRUE; +fail: + if (on_this_computer) + g_object_unref (on_this_computer); + if (on_the_web) + g_object_unref (on_the_web); + if (personal_source) + g_object_unref (personal_source); + + return retval; +} diff --git a/calendar/gui/memos-control.h b/calendar/modules/e-task-shell-module-migrate.h index 5861ae50e5..b20a342e0d 100644 --- a/calendar/gui/memos-control.h +++ b/calendar/modules/e-task-shell-module-migrate.h @@ -1,4 +1,5 @@ /* + * e-task-shell-module-migrate.h * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -14,23 +15,24 @@ * License along with the program; if not, see <http://www.gnu.org/licenses/> * * - * Authors: - * Federico Mena Quintero <federico@ximian.com> - * Damon Chaplin <damon@ximian.com> - * Nathan Owens <pianocomp81@yahoo.com> - * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * */ -#ifndef _MEMOS_CONTROL_H_ -#define _MEMOS_CONTROL_H_ +#ifndef E_TASK_SHELL_MODULE_MIGRATE_H +#define E_TASK_SHELL_MODULE_MIGRATE_H + +#include <glib.h> +#include <shell/e-shell-module.h> + +G_BEGIN_DECLS -#include "e-memos.h" +gboolean e_task_shell_module_migrate (EShellModule *shell_module, + gint major, + gint minor, + gint micro, + GError **error); -BonoboControl *memos_control_new (void); -void memos_control_activate (BonoboControl *control, EMemos *memos); -void memos_control_deactivate (BonoboControl *control, EMemos *memos); -void memos_control_sensitize_commands (BonoboControl *control, EMemos *memos, int n_selected); +G_END_DECLS -#endif /* _MEMOS_CONTROL_H_ */ +#endif /* E_TASK_SHELL_MODULE_MIGRATE_H */ diff --git a/calendar/modules/e-task-shell-module.c b/calendar/modules/e-task-shell-module.c new file mode 100644 index 0000000000..5e35008541 --- /dev/null +++ b/calendar/modules/e-task-shell-module.c @@ -0,0 +1,522 @@ +/* + * e-task-shell-module.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include <string.h> +#include <glib/gi18n.h> +#include <libecal/e-cal.h> +#include <libedataserver/e-url.h> +#include <libedataserver/e-source.h> +#include <libedataserver/e-source-list.h> +#include <libedataserver/e-source-group.h> + +#include "shell/e-shell.h" +#include "shell/e-shell-module.h" +#include "shell/e-shell-window.h" + +#include "calendar/common/authentication.h" +#include "calendar/gui/calendar-config.h" +#include "calendar/gui/comp-util.h" +#include "calendar/gui/dialogs/calendar-setup.h" +#include "calendar/gui/dialogs/task-editor.h" + +#include "e-task-shell-view.h" +#include "e-task-shell-module-migrate.h" + +#define MODULE_NAME "tasks" +#define MODULE_ALIASES "" +#define MODULE_SCHEMES "task" +#define MODULE_SORT_ORDER 600 + +#define WEB_BASE_URI "webcal://" +#define PERSONAL_RELATIVE_URI "system" + +/* Module Entry Point */ +void e_shell_module_init (GTypeModule *type_module); + +static void +task_module_ensure_sources (EShellModule *shell_module) +{ + /* XXX This is basically the same algorithm across all modules. + * Maybe we could somehow integrate this into EShellModule? */ + + ESourceList *source_list; + ESourceGroup *on_this_computer; + ESourceGroup *on_the_web; + ESource *personal; + GSList *groups, *iter; + const gchar *data_dir; + const gchar *name; + gchar *base_uri; + gchar *filename; + + on_this_computer = NULL; + on_the_web = NULL; + personal = NULL; + + if (!e_cal_get_sources (&source_list, E_CAL_SOURCE_TYPE_TODO, NULL)) { + g_warning ("Could not get task sources from GConf!"); + return; + } + + /* Share the source list with all task views. This is + * accessible via e_task_shell_view_get_source_list(). + * Note: EShellModule takes ownership of the reference. + * + * XXX I haven't yet decided if I want to add a proper + * EShellModule API for this. The mail module would + * not use it. */ + g_object_set_data_full ( + G_OBJECT (shell_module), "source-list", + source_list, (GDestroyNotify) g_object_unref); + + data_dir = e_shell_module_get_data_dir (shell_module); + filename = g_build_filename (data_dir, "local", NULL); + base_uri = g_filename_to_uri (filename, NULL, NULL); + g_free (filename); + + groups = e_source_list_peek_groups (source_list); + for (iter = groups; iter != NULL; iter = iter->next) { + ESourceGroup *source_group = iter->data; + const gchar *group_base_uri; + + group_base_uri = e_source_group_peek_base_uri (source_group); + + /* Compare only "file://" part. If the user's home + * changes, we do not want to create another group. */ + if (on_this_computer == NULL && + strncmp (base_uri, group_base_uri, 7) == 0) + on_this_computer = source_group; + + else if (on_the_web == NULL && + strcmp (WEB_BASE_URI, group_base_uri) == 0) + on_the_web = source_group; + } + + name = _("On This Computer"); + + if (on_this_computer != NULL) { + GSList *sources; + const gchar *group_base_uri; + + /* Force the group name to the current locale. */ + e_source_group_set_name (on_this_computer, name); + + sources = e_source_group_peek_sources (on_this_computer); + group_base_uri = e_source_group_peek_base_uri (on_this_computer); + + /* Make sure this group includes a "Personal" source. */ + for (iter = sources; iter != NULL; iter = iter->next) { + ESource *source = iter->data; + const gchar *relative_uri; + + relative_uri = e_source_peek_relative_uri (source); + if (relative_uri == NULL) + continue; + + if (strcmp (PERSONAL_RELATIVE_URI, relative_uri) != 0) + continue; + + personal = source; + break; + } + + /* Make sure we have the correct base URI. This can + * change when the user's home directory changes. */ + if (strcmp (base_uri, group_base_uri) != 0) { + e_source_group_set_base_uri ( + on_this_computer, base_uri); + + /* XXX We shouldn't need this sync call here as + * set_base_uri() results in synching to GConf, + * but that happens in an idle loop and too late + * to prevent the user from seeing a "Cannot + * Open ... because of invalid URI" error. */ + e_source_list_sync (source_list, NULL); + } + + } else { + ESourceGroup *source_group; + + source_group = e_source_group_new (name, base_uri); + e_source_list_add_group (source_list, source_group, -1); + g_object_unref (source_group); + } + + name = _("Personal"); + + if (personal == NULL) { + ESource *source; + GSList *selected; + gchar *primary; + + source = e_source_new (name, PERSONAL_RELATIVE_URI); + e_source_group_add_source (on_this_computer, source, -1); + g_object_unref (source); + + primary = calendar_config_get_primary_tasks (); + selected = calendar_config_get_tasks_selected (); + + if (primary == NULL && selected == NULL) { + const gchar *uid; + + uid = e_source_peek_uid (source); + selected = g_slist_prepend (NULL, g_strdup (uid)); + + calendar_config_set_primary_tasks (uid); + calendar_config_set_tasks_selected (selected); + } + + g_slist_foreach (selected, (GFunc) g_free, NULL); + g_slist_free (selected); + g_free (primary); + } else { + /* Force the source name to the current locale. */ + e_source_set_name (personal, name); + } + + name = _("On The Web"); + + if (on_the_web == NULL) { + ESourceGroup *source_group; + + source_group = e_source_group_new (name, WEB_BASE_URI); + e_source_list_add_group (source_list, source_group, -1); + g_object_unref (source_group); + } else { + /* Force the group name to the current locale. */ + e_source_group_set_name (on_the_web, name); + } + + g_free (base_uri); +} + +static void +task_module_cal_opened_cb (ECal *cal, + ECalendarStatus status, + GtkAction *action) +{ + EShell *shell; + ECalComponent *comp; + CompEditor *editor; + CompEditorFlags flags = 0; + const gchar *action_name; + + /* FIXME Pass this in. */ + shell = e_shell_get_default (); + + /* XXX Handle errors better. */ + if (status != E_CALENDAR_STATUS_OK) + return; + + action_name = gtk_action_get_name (action); + + flags |= COMP_EDITOR_NEW_ITEM; + if (strcmp (action_name, "task-assigned-new") == 0) { + flags |= COMP_EDITOR_IS_ASSIGNED; + flags |= COMP_EDITOR_USER_ORG; + } + + editor = task_editor_new (cal, shell, flags); + comp = cal_comp_task_new_with_defaults (cal); + comp_editor_edit_comp (editor, comp); + + gtk_window_present (GTK_WINDOW (editor)); + + g_object_unref (comp); + g_object_unref (cal); +} + +static void +action_task_new_cb (GtkAction *action, + EShellWindow *shell_window) +{ + ECal *cal = NULL; + ECalSourceType source_type; + ESourceList *source_list; + gchar *uid; + + /* This callback is used for both tasks and assigned tasks. */ + + source_type = E_CAL_SOURCE_TYPE_TODO; + + if (!e_cal_get_sources (&source_list, source_type, NULL)) { + g_warning ("Could not get task sources from GConf!"); + return; + } + + uid = calendar_config_get_primary_tasks (); + + if (uid != NULL) { + ESource *source; + + source = e_source_list_peek_source_by_uid (source_list, uid); + if (source != NULL) + cal = auth_new_cal_from_source (source, source_type); + g_free (uid); + } + + if (cal == NULL) + cal = auth_new_cal_from_default (source_type); + + g_return_if_fail (cal != NULL); + + g_signal_connect ( + cal, "cal-opened", + G_CALLBACK (task_module_cal_opened_cb), action); + + e_cal_open_async (cal, FALSE); +} + +static void +action_task_list_new_cb (GtkAction *action, + EShellWindow *shell_window) +{ + calendar_setup_new_task_list (GTK_WINDOW (shell_window)); +} + +static GtkActionEntry item_entries[] = { + + { "task-new", + "stock_task", + NC_("New", "_Task"), + "<Shift><Control>t", + N_("Create a new task"), + G_CALLBACK (action_task_new_cb) }, + + { "task-assigned-new", + "stock_task", + N_("Assigne_d Task"), + NULL, + N_("Create a new assigned task"), + G_CALLBACK (action_task_new_cb) } +}; + +static GtkActionEntry source_entries[] = { + + { "task-list-new", + "stock_todo", + NC_("New", "Tas_k List"), + NULL, + N_("Create a new task list"), + G_CALLBACK (action_task_list_new_cb) } +}; + +static gboolean +task_module_handle_uri_cb (EShellModule *shell_module, + const gchar *uri) +{ + EShell *shell; + 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; + shell = e_shell_module_get_shell (shell_module); + + 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, shell, 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 +task_module_window_created_cb (EShellModule *shell_module, + GtkWindow *window) +{ + const gchar *module_name; + + if (!E_IS_SHELL_WINDOW (window)) + return; + + module_name = G_TYPE_MODULE (shell_module)->name; + + e_shell_window_register_new_item_actions ( + E_SHELL_WINDOW (window), module_name, + item_entries, G_N_ELEMENTS (item_entries)); + + e_shell_window_register_new_source_actions ( + E_SHELL_WINDOW (window), module_name, + source_entries, G_N_ELEMENTS (source_entries)); +} + +static EShellModuleInfo module_info = { + + MODULE_NAME, + MODULE_ALIASES, + MODULE_SCHEMES, + MODULE_SORT_ORDER, + + /* start */ NULL, + /* is_busy */ NULL, + /* shutdown */ NULL, + e_task_shell_module_migrate +}; + +void +e_shell_module_init (GTypeModule *type_module) +{ + EShell *shell; + EShellModule *shell_module; + + shell_module = E_SHELL_MODULE (type_module); + shell = e_shell_module_get_shell (shell_module); + + e_shell_module_set_info ( + shell_module, &module_info, + e_task_shell_view_get_type (type_module)); + + task_module_ensure_sources (shell_module); + + g_signal_connect_swapped ( + shell, "handle-uri", + G_CALLBACK (task_module_handle_uri_cb), shell_module); + + g_signal_connect_swapped ( + shell, "window-created", + G_CALLBACK (task_module_window_created_cb), shell_module); +} diff --git a/calendar/modules/e-task-shell-sidebar.c b/calendar/modules/e-task-shell-sidebar.c new file mode 100644 index 0000000000..9631321edb --- /dev/null +++ b/calendar/modules/e-task-shell-sidebar.c @@ -0,0 +1,692 @@ +/* + * e-task-shell-sidebar.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-task-shell-sidebar.h" + +#include <string.h> +#include <glib/gi18n.h> +#include <libecal/e-cal.h> + +#include "e-util/e-error.h" +#include "e-util/e-util.h" +#include "calendar/common/authentication.h" +#include "calendar/gui/calendar-config.h" +#include "calendar/gui/e-task-list-selector.h" +#include "calendar/gui/misc.h" + +#include "e-task-shell-view.h" + +#define E_TASK_SHELL_SIDEBAR_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_TASK_SHELL_SIDEBAR, ETaskShellSidebarPrivate)) + +struct _ETaskShellSidebarPrivate { + GtkWidget *selector; + + /* UID -> Client */ + GHashTable *client_table; +}; + +enum { + PROP_0, + PROP_SELECTOR +}; + +enum { + CLIENT_ADDED, + CLIENT_REMOVED, + STATUS_MESSAGE, + LAST_SIGNAL +}; + +static gpointer parent_class; +static guint signals[LAST_SIGNAL]; + +static void +task_shell_sidebar_emit_client_added (ETaskShellSidebar *task_shell_sidebar, + ECal *client) +{ + guint signal_id = signals[CLIENT_ADDED]; + + g_signal_emit (task_shell_sidebar, signal_id, 0, client); +} + +static void +task_shell_sidebar_emit_client_removed (ETaskShellSidebar *task_shell_sidebar, + ECal *client) +{ + guint signal_id = signals[CLIENT_REMOVED]; + + g_signal_emit (task_shell_sidebar, signal_id, 0, client); +} + +static void +task_shell_sidebar_emit_status_message (ETaskShellSidebar *task_shell_sidebar, + const gchar *status_message) +{ + guint signal_id = signals[STATUS_MESSAGE]; + + g_signal_emit (task_shell_sidebar, signal_id, 0, status_message, -1.0); +} + +static void +task_shell_sidebar_backend_died_cb (ETaskShellSidebar *task_shell_sidebar, + ECal *client) +{ + EShellView *shell_view; + EShellWindow *shell_window; + EShellSidebar *shell_sidebar; + GHashTable *client_table; + ESource *source; + const gchar *uid; + + client_table = task_shell_sidebar->priv->client_table; + + shell_sidebar = E_SHELL_SIDEBAR (task_shell_sidebar); + shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); + shell_window = e_shell_view_get_shell_window (shell_view); + + source = e_cal_get_source (client); + uid = e_source_peek_uid (source); + + g_object_ref (source); + + g_hash_table_remove (client_table, uid); + task_shell_sidebar_emit_status_message (task_shell_sidebar, NULL); + + e_error_run ( + GTK_WINDOW (shell_window), + "calendar:tasks-crashed", NULL); + + g_object_unref (source); +} + +static void +task_shell_sidebar_backend_error_cb (ETaskShellSidebar *task_shell_sidebar, + const gchar *message, + ECal *client) +{ + EShellView *shell_view; + EShellWindow *shell_window; + EShellSidebar *shell_sidebar; + GtkWidget *dialog; + const gchar *uri; + gchar *uri_no_passwd; + + shell_sidebar = E_SHELL_SIDEBAR (task_shell_sidebar); + shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); + shell_window = e_shell_view_get_shell_window (shell_view); + + uri = e_cal_get_uri (client); + uri_no_passwd = get_uri_without_password (uri); + + dialog = gtk_message_dialog_new ( + GTK_WINDOW (shell_window), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, + _("Error on %s\n%s"), + uri_no_passwd, message); + + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + + g_free (uri_no_passwd); +} + +static void +task_shell_sidebar_client_opened_cb (ETaskShellSidebar *task_shell_sidebar, + ECalendarStatus status, + ECal *client) +{ + EShellView *shell_view; + EShellWindow *shell_window; + EShellSidebar *shell_sidebar; + ESource *source; + + source = e_cal_get_source (client); + + shell_sidebar = E_SHELL_SIDEBAR (task_shell_sidebar); + shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); + shell_window = e_shell_view_get_shell_window (shell_view); + + if (status == E_CALENDAR_STATUS_AUTHENTICATION_FAILED || + status == E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED) + auth_cal_forget_password (client); + + switch (status) { + case E_CALENDAR_STATUS_OK: + g_signal_handlers_disconnect_matched ( + client, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, + task_shell_sidebar_client_opened_cb, NULL); + + task_shell_sidebar_emit_status_message ( + task_shell_sidebar, _("Loading tasks")); + task_shell_sidebar_emit_client_added ( + task_shell_sidebar, client); + task_shell_sidebar_emit_status_message ( + task_shell_sidebar, NULL); + break; + + case E_CALENDAR_STATUS_AUTHENTICATION_FAILED: + e_cal_open_async (client, FALSE); + break; + + case E_CALENDAR_STATUS_BUSY: + break; + + case E_CALENDAR_STATUS_REPOSITORY_OFFLINE: + e_error_run ( + GTK_WINDOW (shell_window), + "calendar:prompt-no-contents-offline-tasks", + NULL); + break; + + default: + task_shell_sidebar_emit_client_removed ( + task_shell_sidebar, client); + break; + } +} + +static void +task_shell_sidebar_row_changed_cb (ETaskShellSidebar *task_shell_sidebar, + GtkTreePath *tree_path, + GtkTreeIter *tree_iter, + GtkTreeModel *tree_model) +{ + ESourceSelector *selector; + ESource *source; + + /* XXX ESourceSelector's underlying tree store has only one + * column: ESource objects. While we're not supposed to + * know this, listening for "row-changed" signals from + * the model is easier to deal with than the selector's + * "selection-changed" signal, which doesn't tell you + * _which_ row changed. */ + + selector = e_task_shell_sidebar_get_selector (task_shell_sidebar); + gtk_tree_model_get (tree_model, tree_iter, 0, &source, -1); + + /* XXX This signal gets emitted a lot while the model is being + * rebuilt, during which time we won't get a valid ESource. + * ESourceSelector should probably block this signal while + * rebuilding the model, but we'll be forgiving and not + * emit a warning. */ + if (!E_IS_SOURCE (source)) + return; + + if (e_source_selector_source_is_selected (selector, source)) + e_task_shell_sidebar_add_source (task_shell_sidebar, source); + else + e_task_shell_sidebar_remove_source (task_shell_sidebar, source); +} + +static void +task_shell_sidebar_selection_changed_cb (ETaskShellSidebar *task_shell_sidebar, + ESourceSelector *selector) +{ + GSList *list, *iter; + + /* This signal is emitted less frequently than "row-changed", + * especially when the model is being rebuilt. So we'll take + * it easy on poor GConf. */ + + list = e_source_selector_get_selection (selector); + + for (iter = list; iter != NULL; iter = iter->next) { + ESource *source = iter->data; + + iter->data = (gpointer) e_source_peek_uid (source); + g_object_unref (source); + } + + calendar_config_set_tasks_selected (list); + + g_slist_free (list); +} + +static void +task_shell_sidebar_primary_selection_changed_cb (ETaskShellSidebar *task_shell_sidebar, + ESourceSelector *selector) +{ + ESource *source; + const gchar *uid; + + /* XXX ESourceSelector needs a "primary-selection-uid" property + * so we can just bind the property with GConfBridge. */ + + source = e_source_selector_peek_primary_selection (selector); + if (source == NULL) + return; + + uid = e_source_peek_uid (source); + calendar_config_set_primary_tasks (uid); +} + +static void +task_shell_sidebar_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_SELECTOR: + g_value_set_object ( + value, e_task_shell_sidebar_get_selector ( + E_TASK_SHELL_SIDEBAR (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +task_shell_sidebar_dispose (GObject *object) +{ + ETaskShellSidebarPrivate *priv; + + priv = E_TASK_SHELL_SIDEBAR_GET_PRIVATE (object); + + if (priv->selector != NULL) { + g_object_unref (priv->selector); + priv->selector = NULL; + } + + g_hash_table_remove_all (priv->client_table); + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +task_shell_sidebar_finalize (GObject *object) +{ + ETaskShellSidebarPrivate *priv; + + priv = E_TASK_SHELL_SIDEBAR_GET_PRIVATE (object); + + g_hash_table_destroy (priv->client_table); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +task_shell_sidebar_constructed (GObject *object) +{ + ETaskShellSidebarPrivate *priv; + EShellView *shell_view; + EShellSidebar *shell_sidebar; + ETaskShellView *task_shell_view; + ESourceSelector *selector; + ESourceList *source_list; + ESource *source; + GtkContainer *container; + GtkTreeModel *model; + GtkWidget *widget; + AtkObject *a11y; + GSList *list, *iter; + gchar *uid; + + priv = E_TASK_SHELL_SIDEBAR_GET_PRIVATE (object); + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (parent_class)->constructed (object); + + shell_sidebar = E_SHELL_SIDEBAR (object); + shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); + task_shell_view = E_TASK_SHELL_VIEW (shell_view); + source_list = e_task_shell_view_get_source_list (task_shell_view); + + container = GTK_CONTAINER (shell_sidebar); + + widget = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy ( + GTK_SCROLLED_WINDOW (widget), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type ( + GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN); + gtk_container_add (container, widget); + gtk_widget_show (widget); + + container = GTK_CONTAINER (widget); + + widget = e_task_list_selector_new (source_list); + e_source_selector_set_select_new (E_SOURCE_SELECTOR (widget), TRUE); + gtk_container_add (container, widget); + a11y = gtk_widget_get_accessible (widget); + atk_object_set_name (a11y, _("Task List Selector")); + priv->selector = g_object_ref (widget); + gtk_widget_show (widget); + + /* Restore the selector state from the last session. */ + + selector = E_SOURCE_SELECTOR (priv->selector); + model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget)); + + g_signal_connect_swapped ( + model, "row-changed", + G_CALLBACK (task_shell_sidebar_row_changed_cb), + object); + + source = NULL; + uid = calendar_config_get_primary_tasks (); + if (uid != NULL) + source = e_source_list_peek_source_by_uid (source_list, uid); + if (source == NULL) + source = e_source_list_peek_source_any (source_list); + if (source != NULL) + e_source_selector_set_primary_selection (selector, source); + g_free (uid); + + list = calendar_config_get_tasks_selected (); + for (iter = list; iter != NULL; iter = iter->next) { + uid = iter->data; + source = e_source_list_peek_source_by_uid (source_list, uid); + g_free (uid); + + if (source == NULL) + continue; + + e_source_selector_select_source (selector, source); + } + g_slist_free (list); + + /* Listen for subsequent changes to the selector. */ + + g_signal_connect_swapped ( + widget, "selection-changed", + G_CALLBACK (task_shell_sidebar_selection_changed_cb), + object); + + g_signal_connect_swapped ( + widget, "primary-selection-changed", + G_CALLBACK (task_shell_sidebar_primary_selection_changed_cb), + object); +} + +static guint32 +task_shell_sidebar_check_state (EShellSidebar *shell_sidebar) +{ + ETaskShellSidebar *task_shell_sidebar; + ESourceSelector *selector; + ESource *source; + gboolean is_system = FALSE; + guint32 state = 0; + + task_shell_sidebar = E_TASK_SHELL_SIDEBAR (shell_sidebar); + selector = e_task_shell_sidebar_get_selector (task_shell_sidebar); + source = e_source_selector_peek_primary_selection (selector); + + if (source != NULL) { + const gchar *uri; + + uri = e_source_peek_relative_uri (source); + is_system = (uri == NULL || strcmp (uri, "system") == 0); + } + + if (source != NULL) + state |= E_TASK_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE; + if (is_system) + state |= E_TASK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_SYSTEM; + + return state; +} + +static void +task_shell_sidebar_client_removed (ETaskShellSidebar *task_shell_sidebar, + ECal *client) +{ + ESourceSelector *selector; + GHashTable *client_table; + ESource *source; + const gchar *uid; + + client_table = task_shell_sidebar->priv->client_table; + selector = e_task_shell_sidebar_get_selector (task_shell_sidebar); + + g_signal_handlers_disconnect_matched ( + client, G_SIGNAL_MATCH_DATA, 0, 0, + NULL, NULL, task_shell_sidebar); + + source = e_cal_get_source (client); + e_source_selector_unselect_source (selector, source); + + uid = e_source_peek_uid (source); + g_hash_table_remove (client_table, uid); + + task_shell_sidebar_emit_status_message (task_shell_sidebar, NULL); +} + +static void +task_shell_sidebar_class_init (ETaskShellSidebarClass *class) +{ + GObjectClass *object_class; + EShellSidebarClass *shell_sidebar_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (ETaskShellSidebarPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->get_property = task_shell_sidebar_get_property; + object_class->dispose = task_shell_sidebar_dispose; + object_class->finalize = task_shell_sidebar_finalize; + object_class->constructed = task_shell_sidebar_constructed; + + shell_sidebar_class = E_SHELL_SIDEBAR_CLASS (class); + shell_sidebar_class->check_state = task_shell_sidebar_check_state; + + class->client_removed = task_shell_sidebar_client_removed; + + g_object_class_install_property ( + object_class, + PROP_SELECTOR, + g_param_spec_object ( + "selector", + _("Source Selector Widget"), + _("This widget displays groups of task lists"), + E_TYPE_SOURCE_SELECTOR, + G_PARAM_READABLE)); + + signals[CLIENT_ADDED] = g_signal_new ( + "client-added", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ETaskShellSidebarClass, client_added), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + E_TYPE_CAL); + + signals[CLIENT_REMOVED] = g_signal_new ( + "client-removed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ETaskShellSidebarClass, client_removed), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + E_TYPE_CAL); + + signals[STATUS_MESSAGE] = g_signal_new ( + "status-message", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (ETaskShellSidebarClass, status_message), + NULL, NULL, + e_marshal_VOID__STRING_DOUBLE, + G_TYPE_NONE, 2, + G_TYPE_STRING, + G_TYPE_DOUBLE); +} + +static void +task_shell_sidebar_init (ETaskShellSidebar *task_shell_sidebar) +{ + GHashTable *client_table; + + client_table = g_hash_table_new_full ( + g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) g_object_unref); + + task_shell_sidebar->priv = + E_TASK_SHELL_SIDEBAR_GET_PRIVATE (task_shell_sidebar); + + task_shell_sidebar->priv->client_table = client_table; + + /* Postpone widget construction until we have a shell view. */ +} + +GType +e_task_shell_sidebar_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (ETaskShellSidebarClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) task_shell_sidebar_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (ETaskShellSidebar), + 0, /* n_preallocs */ + (GInstanceInitFunc) task_shell_sidebar_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + E_TYPE_SHELL_SIDEBAR, "ETaskShellSidebar", + &type_info, 0); + } + + return type; +} + +GtkWidget * +e_task_shell_sidebar_new (EShellView *shell_view) +{ + g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); + + return g_object_new ( + E_TYPE_TASK_SHELL_SIDEBAR, + "shell-view", shell_view, NULL); +} + +GList * +e_task_shell_sidebar_get_clients (ETaskShellSidebar *task_shell_sidebar) +{ + GHashTable *client_table; + + g_return_val_if_fail ( + E_IS_TASK_SHELL_SIDEBAR (task_shell_sidebar), NULL); + + client_table = task_shell_sidebar->priv->client_table; + + return g_hash_table_get_values (client_table); +} + +ESourceSelector * +e_task_shell_sidebar_get_selector (ETaskShellSidebar *task_shell_sidebar) +{ + g_return_val_if_fail ( + E_IS_TASK_SHELL_SIDEBAR (task_shell_sidebar), NULL); + + return E_SOURCE_SELECTOR (task_shell_sidebar->priv->selector); +} + +void +e_task_shell_sidebar_add_source (ETaskShellSidebar *task_shell_sidebar, + ESource *source) +{ + ESourceSelector *selector; + GHashTable *client_table; + ECal *client; + const gchar *uid; + const gchar *uri; + gchar *message; + + g_return_if_fail (E_IS_TASK_SHELL_SIDEBAR (task_shell_sidebar)); + g_return_if_fail (E_IS_SOURCE (source)); + + client_table = task_shell_sidebar->priv->client_table; + selector = e_task_shell_sidebar_get_selector (task_shell_sidebar); + + uid = e_source_peek_uid (source); + client = g_hash_table_lookup (client_table, uid); + + if (client != NULL) + return; + + client = auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_TODO); + g_return_if_fail (client != NULL); + + g_signal_connect_swapped ( + client, "backend-died", + G_CALLBACK (task_shell_sidebar_backend_died_cb), + task_shell_sidebar); + + g_signal_connect_swapped ( + client, "backend-error", + G_CALLBACK (task_shell_sidebar_backend_error_cb), + task_shell_sidebar); + + g_hash_table_insert (client_table, g_strdup (uid), client); + e_source_selector_select_source (selector, source); + + uri = e_cal_get_uri (client); + message = g_strdup_printf (_("Opening tasks at %s"), uri); + task_shell_sidebar_emit_status_message (task_shell_sidebar, message); + g_free (message); + + g_signal_connect_swapped ( + client, "cal-opened", + G_CALLBACK (task_shell_sidebar_client_opened_cb), + task_shell_sidebar); + + e_cal_open_async (client, FALSE); +} + +void +e_task_shell_sidebar_remove_source (ETaskShellSidebar *task_shell_sidebar, + ESource *source) +{ + ESourceSelector *selector; + GHashTable *client_table; + ECal *client; + const gchar *uid; + + g_return_if_fail (E_IS_TASK_SHELL_SIDEBAR (task_shell_sidebar)); + g_return_if_fail (E_IS_SOURCE (source)); + + client_table = task_shell_sidebar->priv->client_table; + selector = e_task_shell_sidebar_get_selector (task_shell_sidebar); + + uid = e_source_peek_uid (source); + client = g_hash_table_lookup (client_table, uid); + + if (client == NULL) + return; + + task_shell_sidebar_emit_client_removed (task_shell_sidebar, client); +} diff --git a/calendar/modules/e-task-shell-sidebar.h b/calendar/modules/e-task-shell-sidebar.h new file mode 100644 index 0000000000..2d8fceaeb8 --- /dev/null +++ b/calendar/modules/e-task-shell-sidebar.h @@ -0,0 +1,93 @@ +/* + * e-task-shell-sidebar.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_TASK_SHELL_SIDEBAR_H +#define E_TASK_SHELL_SIDEBAR_H + +#include <libecal/e-cal.h> +#include <libedataserverui/e-source-selector.h> + +#include <shell/e-shell-sidebar.h> +#include <shell/e-shell-view.h> + +/* Standard GObject macros */ +#define E_TYPE_TASK_SHELL_SIDEBAR \ + (e_task_shell_sidebar_get_type ()) +#define E_TASK_SHELL_SIDEBAR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_TASK_SHELL_SIDEBAR, ETaskShellSidebar)) +#define E_TASK_SHELL_SIDEBAR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_TASK_SHELL_SIDEBAR, ETaskShellSidebarClass)) +#define E_IS_TASK_SHELL_SIDEBAR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_TASK_SHELL_SIDEBAR)) +#define E_IS_TASK_SHELL_SIDEBAR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_TASK_SHELL_SIDEBAR)) +#define E_TASK_SHELL_SIDEBAR_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_TASK_SHELL_SIDEBAR, ETaskShellSidebarClass)) + +G_BEGIN_DECLS + +typedef struct _ETaskShellSidebar ETaskShellSidebar; +typedef struct _ETaskShellSidebarClass ETaskShellSidebarClass; +typedef struct _ETaskShellSidebarPrivate ETaskShellSidebarPrivate; + +enum { + E_TASK_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE = 1 << 0, + E_TASK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_SYSTEM = 1 << 1 +}; + +struct _ETaskShellSidebar { + EShellSidebar parent; + ETaskShellSidebarPrivate *priv; +}; + +struct _ETaskShellSidebarClass { + EShellSidebarClass parent_class; + + /* Signals */ + void (*client_added) (ETaskShellSidebar *task_shell_sidebar, + ECal *client); + void (*client_removed) (ETaskShellSidebar *task_shell_sidebar, + ECal *client); + void (*status_message) (ETaskShellSidebar *task_shell_sidebar, + const gchar *status_message, + gdouble percent); +}; + +GType e_task_shell_sidebar_get_type (void); +GtkWidget * e_task_shell_sidebar_new (EShellView *shell_view); +GList * e_task_shell_sidebar_get_clients(ETaskShellSidebar *task_shell_sidebar); +ESourceSelector * + e_task_shell_sidebar_get_selector + (ETaskShellSidebar *task_shell_sidebar); +void e_task_shell_sidebar_add_source (ETaskShellSidebar *task_shell_sidebar, + ESource *source); +void e_task_shell_sidebar_remove_source + (ETaskShellSidebar *task_shell_sidebar, + ESource *source); + +G_END_DECLS + +#endif /* E_TASK_SHELL_SIDEBAR_H */ diff --git a/calendar/modules/e-task-shell-view-actions.c b/calendar/modules/e-task-shell-view-actions.c new file mode 100644 index 0000000000..d924043e5f --- /dev/null +++ b/calendar/modules/e-task-shell-view-actions.c @@ -0,0 +1,1122 @@ +/* + * e-task-shell-view-actions.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-task-shell-view-private.h" + +static void +action_gal_save_custom_view_cb (GtkAction *action, + ETaskShellView *task_shell_view) +{ + ETaskShellContent *task_shell_content; + EShellView *shell_view; + GalViewInstance *view_instance; + + /* All shell views respond to the activation of this action, + * which is defined by EShellWindow. But only the currently + * active shell view proceeds with saving the custom view. */ + shell_view = E_SHELL_VIEW (task_shell_view); + if (!e_shell_view_is_active (shell_view)) + return; + + task_shell_content = task_shell_view->priv->task_shell_content; + view_instance = e_task_shell_content_get_view_instance (task_shell_content); + gal_view_instance_save_as (view_instance); +} + +static void +action_search_execute_cb (GtkAction *action, + ETaskShellView *task_shell_view) +{ + EShellView *shell_view; + + /* All shell views respond to the activation of this action, + * which is defined by EShellWindow. But only the currently + * active shell view proceeds with executing the search. */ + shell_view = E_SHELL_VIEW (task_shell_view); + if (!e_shell_view_is_active (shell_view)) + return; + + e_task_shell_view_execute_search (task_shell_view); +} + +static void +action_search_filter_cb (GtkRadioAction *action, + GtkRadioAction *current, + ETaskShellView *task_shell_view) +{ + e_task_shell_view_execute_search (task_shell_view); +} + +static void +action_task_assign_cb (GtkAction *action, + ETaskShellView *task_shell_view) +{ + ETaskShellContent *task_shell_content; + ECalendarTable *task_table; + ECalModelComponent *comp_data; + GSList *list; + + task_shell_content = task_shell_view->priv->task_shell_content; + task_table = e_task_shell_content_get_task_table (task_shell_content); + + list = e_calendar_table_get_selected (task_table); + g_return_if_fail (list != NULL); + comp_data = list->data; + g_slist_free (list); + + /* XXX We only open the first selected task. */ + e_task_shell_view_open_task (task_shell_view, comp_data); + + /* FIXME Need to actually assign the task. */ +} + +static void +action_task_clipboard_copy_cb (GtkAction *action, + ETaskShellView *task_shell_view) +{ + ETaskShellContent *task_shell_content; + ECalendarTable *task_table; + + task_shell_content = task_shell_view->priv->task_shell_content; + task_table = e_task_shell_content_get_task_table (task_shell_content); + + e_calendar_table_copy_clipboard (task_table); +} + +static void +action_task_clipboard_cut_cb (GtkAction *action, + ETaskShellView *task_shell_view) +{ + ETaskShellContent *task_shell_content; + ECalendarTable *task_table; + + task_shell_content = task_shell_view->priv->task_shell_content; + task_table = e_task_shell_content_get_task_table (task_shell_content); + + e_calendar_table_cut_clipboard (task_table); +} + +static void +action_task_clipboard_paste_cb (GtkAction *action, + ETaskShellView *task_shell_view) +{ + ETaskShellContent *task_shell_content; + ECalendarTable *task_table; + + task_shell_content = task_shell_view->priv->task_shell_content; + task_table = e_task_shell_content_get_task_table (task_shell_content); + + e_calendar_table_paste_clipboard (task_table); +} + +static void +action_task_delete_cb (GtkAction *action, + ETaskShellView *task_shell_view) +{ + ETaskShellContent *task_shell_content; + ECalComponentPreview *task_preview; + ECalendarTable *task_table; + + task_shell_content = task_shell_view->priv->task_shell_content; + task_table = e_task_shell_content_get_task_table (task_shell_content); + task_preview = e_task_shell_content_get_task_preview (task_shell_content); + + e_task_shell_view_set_status_message ( + task_shell_view, _("Deleting selected tasks..."), -1.0); + e_calendar_table_delete_selected (task_table); + e_task_shell_view_set_status_message (task_shell_view, NULL, -1.0); + + e_cal_component_preview_clear (task_preview); +} + +static void +action_task_forward_cb (GtkAction *action, + ETaskShellView *task_shell_view) +{ + ETaskShellContent *task_shell_content; + ECalendarTable *task_table; + ECalModelComponent *comp_data; + ECalComponent *comp; + icalcomponent *clone; + GSList *list; + + task_shell_content = task_shell_view->priv->task_shell_content; + task_table = e_task_shell_content_get_task_table (task_shell_content); + + list = e_calendar_table_get_selected (task_table); + g_return_if_fail (list != NULL); + comp_data = list->data; + g_slist_free (list); + + /* XXX We only forward the first selected task. */ + comp = e_cal_component_new (); + clone = icalcomponent_new_clone (comp_data->icalcomp); + e_cal_component_set_icalcomponent (comp, clone); + itip_send_comp ( + E_CAL_COMPONENT_METHOD_PUBLISH, comp, + comp_data->client, NULL, NULL, NULL, TRUE); + g_object_unref (comp); +} + +static void +action_task_list_copy_cb (GtkAction *action, + ETaskShellView *task_shell_view) +{ + ETaskShellSidebar *task_shell_sidebar; + EShellWindow *shell_window; + EShellView *shell_view; + ESourceSelector *selector; + ESource *source; + + shell_view = E_SHELL_VIEW (task_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + task_shell_sidebar = task_shell_view->priv->task_shell_sidebar; + selector = e_task_shell_sidebar_get_selector (task_shell_sidebar); + source = e_source_selector_peek_primary_selection (selector); + g_return_if_fail (E_IS_SOURCE (source)); + + copy_source_dialog ( + GTK_WINDOW (shell_window), + source, E_CAL_SOURCE_TYPE_TODO); +} + +static void +action_task_list_delete_cb (GtkAction *action, + ETaskShellView *task_shell_view) +{ + ETaskShellContent *task_shell_content; + ETaskShellSidebar *task_shell_sidebar; + EShellWindow *shell_window; + EShellView *shell_view; + ECalendarTable *task_table; + ECal *client; + ECalModel *model; + ESourceSelector *selector; + ESourceGroup *source_group; + ESourceList *source_list; + ESource *source; + gint response; + gchar *uri; + GError *error = NULL; + + shell_view = E_SHELL_VIEW (task_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + task_shell_content = task_shell_view->priv->task_shell_content; + task_table = e_task_shell_content_get_task_table (task_shell_content); + model = e_calendar_table_get_model (task_table); + + task_shell_sidebar = task_shell_view->priv->task_shell_sidebar; + selector = e_task_shell_sidebar_get_selector (task_shell_sidebar); + source = e_source_selector_peek_primary_selection (selector); + g_return_if_fail (E_IS_SOURCE (source)); + + /* Ask for confirmation. */ + response = e_error_run ( + GTK_WINDOW (shell_window), + "calendar:prompt-delete-task-list", + e_source_peek_name (source)); + if (response != GTK_RESPONSE_YES) + return; + + uri = e_source_get_uri (source); + client = e_cal_model_get_client_for_uri (model, uri); + if (client == NULL) + client = e_cal_new_from_uri (uri, E_CAL_SOURCE_TYPE_JOURNAL); + g_free (uri); + + g_return_if_fail (client != NULL); + + if (!e_cal_remove (client, &error)) { + g_warning ("%s", error->message); + g_error_free (error); + return; + } + + if (e_source_selector_source_is_selected (selector, source)) { + e_task_shell_sidebar_remove_source ( + task_shell_sidebar, source); + e_source_selector_unselect_source (selector, source); + } + + source_group = e_source_peek_group (source); + e_source_group_remove_source (source_group, source); + + source_list = task_shell_view->priv->source_list; + if (!e_source_list_sync (source_list, &error)) { + g_warning ("%s", error->message); + g_error_free (error); + } +} + +static void +action_task_list_new_cb (GtkAction *action, + ETaskShellView *task_shell_view) +{ + EShellView *shell_view; + EShellWindow *shell_window; + + shell_view = E_SHELL_VIEW (task_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + calendar_setup_new_task_list (GTK_WINDOW (shell_window)); +} + +static void +action_task_list_print_cb (GtkAction *action, + ETaskShellView *task_shell_view) +{ + ETaskShellContent *task_shell_content; + ECalendarTable *task_table; + ETable *table; + GtkPrintOperationAction print_action; + + task_shell_content = task_shell_view->priv->task_shell_content; + task_table = e_task_shell_content_get_task_table (task_shell_content); + table = e_calendar_table_get_table (task_table); + + print_action = GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG; + print_table (table, _("Print Tasks"), _("Tasks"), print_action); +} + +static void +action_task_list_print_preview_cb (GtkAction *action, + ETaskShellView *task_shell_view) +{ + ETaskShellContent *task_shell_content; + ECalendarTable *task_table; + ETable *table; + GtkPrintOperationAction print_action; + + task_shell_content = task_shell_view->priv->task_shell_content; + task_table = e_task_shell_content_get_task_table (task_shell_content); + table = e_calendar_table_get_table (task_table); + + print_action = GTK_PRINT_OPERATION_ACTION_PREVIEW; + print_table (table, _("Print Tasks"), _("Tasks"), print_action); +} + +static void +action_task_list_properties_cb (GtkAction *action, + ETaskShellView *task_shell_view) +{ + ETaskShellSidebar *task_shell_sidebar; + EShellView *shell_view; + EShellWindow *shell_window; + ESource *source; + ESourceSelector *selector; + + shell_view = E_SHELL_VIEW (task_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + task_shell_sidebar = task_shell_view->priv->task_shell_sidebar; + selector = e_task_shell_sidebar_get_selector (task_shell_sidebar); + source = e_source_selector_peek_primary_selection (selector); + g_return_if_fail (E_IS_SOURCE (source)); + + calendar_setup_edit_task_list (GTK_WINDOW (shell_window), source); +} + +static void +action_task_list_rename_cb (GtkAction *action, + ETaskShellView *task_shell_view) +{ + ETaskShellSidebar *task_shell_sidebar; + ESourceSelector *selector; + + task_shell_sidebar = task_shell_view->priv->task_shell_sidebar; + selector = e_task_shell_sidebar_get_selector (task_shell_sidebar); + + e_source_selector_edit_primary_selection (selector); +} + +static void +action_task_list_select_one_cb (GtkAction *action, + ETaskShellView *task_shell_view) +{ + ETaskShellSidebar *task_shell_sidebar; + ESourceSelector *selector; + ESource *primary; + GSList *list, *iter; + + /* XXX ESourceSelector should provide a function for this. */ + + task_shell_sidebar = task_shell_view->priv->task_shell_sidebar; + selector = e_task_shell_sidebar_get_selector (task_shell_sidebar); + primary = e_source_selector_peek_primary_selection (selector); + g_return_if_fail (primary != NULL); + + list = e_source_selector_get_selection (selector); + for (iter = list; iter != NULL; iter = iter->next) { + ESource *source = iter->data; + + if (source == primary) + continue; + + e_source_selector_unselect_source (selector, source); + } + e_source_selector_free_selection (list); + + e_source_selector_select_source (selector, primary); +} + +static void +action_task_mark_complete_cb (GtkAction *action, + ETaskShellView *task_shell_view) +{ + ETaskShellContent *task_shell_content; + ECalendarTable *task_table; + ECalModel *model; + GSList *list, *iter; + + task_shell_content = task_shell_view->priv->task_shell_content; + task_table = e_task_shell_content_get_task_table (task_shell_content); + list = e_calendar_table_get_selected (task_table); + model = e_calendar_table_get_model (task_table); + + for (iter = list; iter != NULL; iter = iter->next) { + ECalModelComponent *comp_data = iter->data; + e_cal_model_tasks_mark_comp_complete ( + E_CAL_MODEL_TASKS (model), comp_data); + } + + g_slist_free (list); +} + +static void +action_task_mark_incomplete_cb (GtkAction *action, + ETaskShellView *task_shell_view) +{ + ETaskShellContent *task_shell_content; + ECalendarTable *task_table; + ECalModel *model; + GSList *list, *iter; + + task_shell_content = task_shell_view->priv->task_shell_content; + task_table = e_task_shell_content_get_task_table (task_shell_content); + list = e_calendar_table_get_selected (task_table); + model = e_calendar_table_get_model (task_table); + + for (iter = list; iter != NULL; iter = iter->next) { + ECalModelComponent *comp_data = iter->data; + e_cal_model_tasks_mark_comp_incomplete ( + E_CAL_MODEL_TASKS (model), comp_data); + } + + g_slist_free (list); +} + +static void +action_task_new_cb (GtkAction *action, + ETaskShellView *task_shell_view) +{ + EShell *shell; + EShellView *shell_view; + EShellWindow *shell_window; + ETaskShellContent *task_shell_content; + ECalendarTable *task_table; + ECalModelComponent *comp_data; + ECal *client; + ECalComponent *comp; + CompEditor *editor; + GSList *list; + + shell_view = E_SHELL_VIEW (task_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + shell = e_shell_window_get_shell (shell_window); + + task_shell_content = task_shell_view->priv->task_shell_content; + task_table = e_task_shell_content_get_task_table (task_shell_content); + + list = e_calendar_table_get_selected (task_table); + g_return_if_fail (list != NULL); + comp_data = list->data; + g_slist_free (list); + + client = comp_data->client; + editor = task_editor_new (client, shell, COMP_EDITOR_NEW_ITEM); + comp = cal_comp_task_new_with_defaults (client); + comp_editor_edit_comp (editor, comp); + + gtk_window_present (GTK_WINDOW (editor)); + + g_object_unref (comp); + g_object_unref (client); +} + +static void +action_task_open_cb (GtkAction *action, + ETaskShellView *task_shell_view) +{ + ETaskShellContent *task_shell_content; + ECalendarTable *task_table; + ECalModelComponent *comp_data; + GSList *list; + + task_shell_content = task_shell_view->priv->task_shell_content; + task_table = e_task_shell_content_get_task_table (task_shell_content); + + list = e_calendar_table_get_selected (task_table); + g_return_if_fail (list != NULL); + comp_data = list->data; + g_slist_free (list); + + /* XXX We only open the first selected task. */ + e_task_shell_view_open_task (task_shell_view, comp_data); +} + +static void +action_task_open_url_cb (GtkAction *action, + ETaskShellView *task_shell_view) +{ + EShellView *shell_view; + EShellWindow *shell_window; + ETaskShellContent *task_shell_content; + ECalendarTable *task_table; + ECalModelComponent *comp_data; + icalproperty *prop; + const gchar *uri; + GSList *list; + + shell_view = E_SHELL_VIEW (task_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + task_shell_content = task_shell_view->priv->task_shell_content; + task_table = e_task_shell_content_get_task_table (task_shell_content); + + list = e_calendar_table_get_selected (task_table); + g_return_if_fail (list != NULL); + comp_data = list->data; + + /* XXX We only open the URI of the first selected task. */ + prop = icalcomponent_get_first_property ( + comp_data->icalcomp, ICAL_URL_PROPERTY); + g_return_if_fail (prop == NULL); + + uri = icalproperty_get_url (prop); + e_show_uri (GTK_WINDOW (shell_window), uri); +} + +static void +action_task_preview_cb (GtkToggleAction *action, + ETaskShellView *task_shell_view) +{ + ETaskShellContent *task_shell_content; + gboolean visible; + + task_shell_content = task_shell_view->priv->task_shell_content; + visible = gtk_toggle_action_get_active (action); + e_task_shell_content_set_preview_visible (task_shell_content, visible); +} + +static void +action_task_print_cb (GtkAction *action, + ETaskShellView *task_shell_view) +{ + ETaskShellContent *task_shell_content; + ECalendarTable *task_table; + ECalModelComponent *comp_data; + ECalComponent *comp; + icalcomponent *clone; + GtkPrintOperationAction print_action; + GSList *list; + + task_shell_content = task_shell_view->priv->task_shell_content; + task_table = e_task_shell_content_get_task_table (task_shell_content); + + list = e_calendar_table_get_selected (task_table); + g_return_if_fail (list != NULL); + comp_data = list->data; + g_slist_free (list); + + /* XXX We only print the first selected task. */ + comp = e_cal_component_new (); + clone = icalcomponent_new_clone (comp_data->icalcomp); + print_action = GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG; + e_cal_component_set_icalcomponent (comp, clone); + print_comp (comp, comp_data->client, print_action); + g_object_unref (comp); +} + +static void +action_task_purge_cb (GtkAction *action, + ETaskShellView *task_shell_view) +{ + EShellView *shell_view; + EShellWindow *shell_window; + GtkWidget *dialog; + GtkWidget *widget; + gboolean active; + gint response; + + shell_view = E_SHELL_VIEW (task_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + if (!calendar_config_get_confirm_purge ()) + goto purge; + + /* XXX This needs reworked. The dialog looks like ass. */ + + dialog = gtk_message_dialog_new ( + GTK_WINDOW (shell_window), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_WARNING, + GTK_BUTTONS_YES_NO, + "%s", _("This operation will permanently erase all tasks " + "marked as completed. If you continue, you will not be able " + "to recover these tasks.\n\nReally erase these tasks?")); + + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_NO); + + widget = gtk_check_button_new_with_label (_("Do not ask me again")); + gtk_box_pack_start ( + GTK_BOX (GTK_DIALOG (dialog)->vbox), widget, TRUE, TRUE, 6); + gtk_widget_show (widget); + + response = gtk_dialog_run (GTK_DIALOG (dialog)); + active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); + gtk_widget_destroy (dialog); + + if (response != GTK_RESPONSE_YES) + return; + + if (active) + calendar_config_set_confirm_purge (FALSE); + +purge: + + /* FIXME */ + ; +} + +static void +action_task_save_as_cb (GtkAction *action, + ETaskShellView *task_shell_view) +{ + ETaskShellContent *task_shell_content; + ECalendarTable *task_table; + ECalModelComponent *comp_data; + GSList *list; + gchar *filename; + gchar *string; + + task_shell_content = task_shell_view->priv->task_shell_content; + task_table = e_task_shell_content_get_task_table (task_shell_content); + + list = e_calendar_table_get_selected (task_table); + g_return_if_fail (list != NULL); + comp_data = list->data; + g_slist_free (list); + + filename = e_file_dialog_save (_("Save as..."), NULL); + if (filename == NULL) + return; + + string = e_cal_get_component_as_string ( + comp_data->client, comp_data->icalcomp); + if (string == NULL) { + g_warning ("Could not convert task to a string"); + return; + } + + e_write_file_uri (filename, string); + + g_free (filename); + g_free (string); +} + +static GtkActionEntry task_entries[] = { + + { "task-assign", + NULL, + N_("_Assign Task"), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_task_assign_cb) }, + + { "task-clipboard-copy", + GTK_STOCK_COPY, + NULL, + NULL, + N_("Copy selected tasks"), + G_CALLBACK (action_task_clipboard_copy_cb) }, + + { "task-clipboard-cut", + GTK_STOCK_CUT, + NULL, + NULL, + N_("Cut selected tasks"), + G_CALLBACK (action_task_clipboard_cut_cb) }, + + { "task-clipboard-paste", + GTK_STOCK_PASTE, + NULL, + NULL, + N_("Paste tasks from the clipboard"), + G_CALLBACK (action_task_clipboard_paste_cb) }, + + { "task-delete", + GTK_STOCK_DELETE, + N_("_Delete Task"), + NULL, + N_("Delete selected tasks"), + G_CALLBACK (action_task_delete_cb) }, + + { "task-forward", + "mail-forward", + N_("_Forward as iCalendar..."), + "<Control>f", + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_task_forward_cb) }, + + { "task-list-copy", + GTK_STOCK_COPY, + N_("Copy..."), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_task_list_copy_cb) }, + + { "task-list-delete", + GTK_STOCK_DELETE, + N_("_Delete"), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_task_list_delete_cb) }, + + { "task-list-new", + "stock_todo", + N_("_New Task List"), + NULL, + N_("Create a new task list"), + G_CALLBACK (action_task_list_new_cb) }, + + { "task-list-properties", + GTK_STOCK_PROPERTIES, + NULL, + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_task_list_properties_cb) }, + + { "task-list-rename", + NULL, + N_("_Rename..."), + "F2", + N_("Rename the selected task list"), + G_CALLBACK (action_task_list_rename_cb) }, + + { "task-list-select-one", + "stock_check-filled", + N_("Show _Only This Task List"), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_task_list_select_one_cb) }, + + { "task-mark-complete", + NULL, + N_("_Mark as Complete"), + "<Control>k", + N_("Mark selected tasks as complete"), + G_CALLBACK (action_task_mark_complete_cb) }, + + { "task-mark-incomplete", + NULL, + N_("Mar_k as Incomplete"), + NULL, + N_("Mark selected tasks as incomplete"), + G_CALLBACK (action_task_mark_incomplete_cb) }, + + { "task-new", + "stock_task", + N_("New _Task"), + NULL, + N_("Create a new task"), + G_CALLBACK (action_task_new_cb) }, + + { "task-open", + GTK_STOCK_OPEN, + N_("_Open Task"), + "<Control>o", + N_("View the selected task"), + G_CALLBACK (action_task_open_cb) }, + + { "task-open-url", + "applications-internet", + N_("Open _Web Page"), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_task_open_url_cb) }, + + { "task-purge", + NULL, + N_("Purg_e"), + "<Control>e", + N_("Delete completed tasks"), + G_CALLBACK (action_task_purge_cb) }, + + { "task-save-as", + GTK_STOCK_SAVE_AS, + N_("_Save as iCalendar..."), + NULL, + NULL, /* XXX Add a tooltip! */ + G_CALLBACK (action_task_save_as_cb) }, + + /*** Menus ***/ + + { "task-actions-menu", + NULL, + N_("_Actions"), + NULL, + NULL, + NULL } +}; + +static EPopupActionEntry task_popup_entries[] = { + + { "task-list-popup-copy", + NULL, + "task-list-copy" }, + + { "task-list-popup-delete", + NULL, + "task-list-delete" }, + + { "task-list-popup-properties", + NULL, + "task-list-properties" }, + + { "task-list-popup-rename", + NULL, + "task-list-rename" }, + + { "task-list-popup-select-one", + NULL, + "task-list-select-one" }, + + { "task-popup-assign", + NULL, + "task-assign" }, + + { "task-popup-clipboard-copy", + NULL, + "task-clipboard-copy" }, + + { "task-popup-clipboard-cut", + NULL, + "task-clipboard-cut" }, + + { "task-popup-clipboard-paste", + NULL, + "task-clipboard-paste" }, + + { "task-popup-delete", + NULL, + "task-delete" }, + + { "task-popup-forward", + NULL, + "task-forward" }, + + { "task-popup-mark-complete", + NULL, + "task-mark-complete" }, + + { "task-popup-mark-incomplete", + NULL, + "task-mark-incomplete" }, + + { "task-popup-open", + NULL, + "task-open" }, + + { "task-popup-open-url", + NULL, + "task-open-url" }, + + { "task-popup-save-as", + NULL, + "task-save-as" }, +}; + +static GtkToggleActionEntry task_toggle_entries[] = { + + { "task-preview", + NULL, + N_("Task _Preview"), + "<Control>m", + N_("Show task preview pane"), + G_CALLBACK (action_task_preview_cb), + TRUE } +}; + +static GtkRadioActionEntry task_filter_entries[] = { + + { "task-filter-active-tasks", + NULL, + N_("Active Tasks"), + NULL, + NULL, /* XXX Add a tooltip! */ + TASK_FILTER_ACTIVE_TASKS }, + + { "task-filter-any-category", + NULL, + N_("Any Category"), + NULL, + NULL, /* XXX Add a tooltip! */ + TASK_FILTER_ANY_CATEGORY }, + + { "task-filter-completed-tasks", + NULL, + N_("Completed Tasks"), + NULL, + NULL, /* XXX Add a tooltip! */ + TASK_FILTER_COMPLETED_TASKS }, + + { "task-filter-next-7-days-tasks", + NULL, + N_("Next 7 Days' Tasks"), + NULL, + NULL, /* XXX Add a tooltip! */ + TASK_FILTER_NEXT_7_DAYS_TASKS }, + + { "task-filter-overdue-tasks", + NULL, + N_("Overdue Tasks"), + NULL, + NULL, /* XXX Add a tooltip! */ + TASK_FILTER_OVERDUE_TASKS }, + + { "task-filter-tasks-with-attachments", + NULL, + N_("Tasks with Attachments"), + NULL, + NULL, /* XXX Add a tooltip! */ + 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[] = { + + { "task-search-any-field-contains", + NULL, + N_("Any field contains"), + NULL, + NULL, /* XXX Add a tooltip! */ + TASK_SEARCH_ANY_FIELD_CONTAINS }, + + { "task-search-description-contains", + NULL, + N_("Description contains"), + NULL, + NULL, /* XXX Add a tooltip! */ + TASK_SEARCH_DESCRIPTION_CONTAINS }, + + { "task-search-summary-contains", + NULL, + N_("Summary contains"), + NULL, + NULL, /* XXX Add a tooltip! */ + TASK_SEARCH_SUMMARY_CONTAINS } +}; + +static GtkActionEntry lockdown_printing_entries[] = { + + { "task-list-print", + GTK_STOCK_PRINT, + NULL, + "<Control>p", + N_("Print the list of tasks"), + G_CALLBACK (action_task_list_print_cb) }, + + { "task-list-print-preview", + GTK_STOCK_PRINT_PREVIEW, + NULL, + NULL, + N_("Preview the list of tasks to be printed"), + G_CALLBACK (action_task_list_print_preview_cb) }, + + { "task-print", + GTK_STOCK_PRINT, + NULL, + NULL, + N_("Print the selected task"), + G_CALLBACK (action_task_print_cb) } +}; + +static EPopupActionEntry lockdown_printing_popup_entries[] = { + + { "task-popup-print", + NULL, + "task-print" } +}; + +void +e_task_shell_view_actions_init (ETaskShellView *task_shell_view) +{ + EShellView *shell_view; + EShellWindow *shell_window; + GtkActionGroup *action_group; + GConfBridge *bridge; + GtkAction *action; + GObject *object; + const gchar *key; + + shell_view = E_SHELL_VIEW (task_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + /* Task Actions */ + action_group = ACTION_GROUP (TASKS); + gtk_action_group_add_actions ( + action_group, task_entries, + G_N_ELEMENTS (task_entries), task_shell_view); + e_action_group_add_popup_actions ( + action_group, task_popup_entries, + G_N_ELEMENTS (task_popup_entries)); + gtk_action_group_add_toggle_actions ( + action_group, task_toggle_entries, + G_N_ELEMENTS (task_toggle_entries), task_shell_view); + gtk_action_group_add_radio_actions ( + action_group, task_search_entries, + G_N_ELEMENTS (task_search_entries), + TASK_SEARCH_SUMMARY_CONTAINS, + NULL, NULL); + + /* Lockdown Printing Actions */ + action_group = ACTION_GROUP (LOCKDOWN_PRINTING); + gtk_action_group_add_actions ( + action_group, lockdown_printing_entries, + G_N_ELEMENTS (lockdown_printing_entries), task_shell_view); + e_action_group_add_popup_actions ( + action_group, lockdown_printing_popup_entries, + G_N_ELEMENTS (lockdown_printing_popup_entries)); + + /* Bind GObject properties to GConf keys. */ + + bridge = gconf_bridge_get (); + + object = G_OBJECT (ACTION (TASK_PREVIEW)); + key = "/apps/evolution/calendar/display/show_task_preview"; + gconf_bridge_bind_property (bridge, key, object, "active"); + + /* Fine tuning. */ + + action = ACTION (TASK_DELETE); + g_object_set (action, "short-label", _("Delete"), NULL); + + g_signal_connect ( + ACTION (GAL_SAVE_CUSTOM_VIEW), "activate", + G_CALLBACK (action_gal_save_custom_view_cb), task_shell_view); + + g_signal_connect ( + ACTION (SEARCH_EXECUTE), "activate", + G_CALLBACK (action_search_execute_cb), task_shell_view); +} + +void +e_task_shell_view_update_search_filter (ETaskShellView *task_shell_view) +{ + EShellContent *shell_content; + EShellWindow *shell_window; + EShellView *shell_view; + GtkActionGroup *action_group; + GtkRadioAction *radio_action; + GList *list, *iter; + GSList *group; + gint ii; + + shell_view = E_SHELL_VIEW (task_shell_view); + shell_content = e_shell_view_get_shell_content (shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + action_group = ACTION_GROUP (TASKS_FILTER); + e_action_group_remove_all_actions (action_group); + + /* Add the standard filter actions. */ + gtk_action_group_add_radio_actions ( + action_group, task_filter_entries, + G_N_ELEMENTS (task_filter_entries), + TASK_FILTER_ANY_CATEGORY, + G_CALLBACK (action_search_filter_cb), + task_shell_view); + + /* Retrieve the radio group from an action we just added. */ + list = gtk_action_group_list_actions (action_group); + radio_action = GTK_RADIO_ACTION (list->data); + group = gtk_radio_action_get_group (radio_action); + g_list_free (list); + + /* Build the category actions. */ + + list = e_categories_get_list (); + for (iter = list, ii = 0; iter != NULL; iter = iter->next, ii++) { + const gchar *category_name = iter->data; + const gchar *filename; + GtkAction *action; + gchar *action_name; + + action_name = g_strdup_printf ( + "task-filter-category-%d", ii); + radio_action = gtk_radio_action_new ( + action_name, category_name, NULL, NULL, ii); + g_free (action_name); + + /* Convert the category icon file to a themed icon name. */ + filename = e_categories_get_icon_file_for (category_name); + if (filename != NULL && *filename != '\0') { + gchar *basename; + gchar *cp; + + basename = g_path_get_basename (filename); + + /* Lose the file extension. */ + if ((cp = strrchr (basename, '.')) != NULL) + *cp = '\0'; + + g_object_set ( + radio_action, "icon-name", basename, NULL); + + g_free (basename); + } + + gtk_radio_action_set_group (radio_action, group); + group = gtk_radio_action_get_group (radio_action); + + /* The action group takes ownership of the action. */ + action = GTK_ACTION (radio_action); + gtk_action_group_add_action (action_group, action); + g_object_unref (radio_action); + } + g_list_free (list); + + /* Use any action in the group; doesn't matter which. */ + e_shell_content_set_filter_action (shell_content, radio_action); + + 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-actions.h b/calendar/modules/e-task-shell-view-actions.h new file mode 100644 index 0000000000..163a6400cd --- /dev/null +++ b/calendar/modules/e-task-shell-view-actions.h @@ -0,0 +1,105 @@ +/* + * e-task-shell-view-actions.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_TASK_SHELL_VIEW_ACTIONS_H +#define E_TASK_SHELL_VIEW_ACTIONS_H + +#include <shell/e-shell-window-actions.h> + +/* Task Actions */ +#define E_SHELL_WINDOW_ACTION_TASK_ASSIGN(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-assign") +#define E_SHELL_WINDOW_ACTION_TASK_CLIPBOARD_COPY(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-clipboard-copy") +#define E_SHELL_WINDOW_ACTION_TASK_CLIPBOARD_CUT(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-clipboard-cut") +#define E_SHELL_WINDOW_ACTION_TASK_CLIPBOARD_PASTE(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-clipboard-paste") +#define E_SHELL_WINDOW_ACTION_TASK_DELETE(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-delete") +#define E_SHELL_WINDOW_ACTION_TASK_FORWARD(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-forward") +#define E_SHELL_WINDOW_ACTION_TASK_MARK_COMPLETE(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-mark-complete") +#define E_SHELL_WINDOW_ACTION_TASK_MARK_INCOMPLETE(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-mark-incomplete") +#define E_SHELL_WINDOW_ACTION_TASK_NEW(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-new") +#define E_SHELL_WINDOW_ACTION_TASK_OPEN(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-open") +#define E_SHELL_WINDOW_ACTION_TASK_OPEN_URL(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-open-url") +#define E_SHELL_WINDOW_ACTION_TASK_PREVIEW(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-preview") +#define E_SHELL_WINDOW_ACTION_TASK_PRINT(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-print") +#define E_SHELL_WINDOW_ACTION_TASK_PURGE(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-purge") +#define E_SHELL_WINDOW_ACTION_TASK_SAVE_AS(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-save-as") + +/* Task List Actions */ +#define E_SHELL_WINDOW_ACTION_TASK_LIST_COPY(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-list-copy") +#define E_SHELL_WINDOW_ACTION_TASK_LIST_DELETE(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-list-delete") +#define E_SHELL_WINDOW_ACTION_TASK_LIST_NEW(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-list-new") +#define E_SHELL_WINDOW_ACTION_TASK_LIST_PRINT(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-list-print") +#define E_SHELL_WINDOW_ACTION_TASK_LIST_PRINT_PREVIEW(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-list-print-preview") +#define E_SHELL_WINDOW_ACTION_TASK_LIST_PROPERTIES(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-list-properties") +#define E_SHELL_WINDOW_ACTION_TASK_LIST_RENAME(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-list-rename") +#define E_SHELL_WINDOW_ACTION_TASK_LIST_SELECT_ONE(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-list-select-one") + +/* Task Query Actions */ +#define E_SHELL_WINDOW_ACTION_TASK_FILTER_ACTIVE_TASKS(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-filter-active-tasks") +#define E_SHELL_WINDOW_ACTION_TASK_FILTER_ANY_CATEGORY(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-filter-any-category") +#define E_SHELL_WINDOW_ACTION_TASK_FILTER_COMPLETED_TASKS(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-filter-completed-tasks") +#define E_SHELL_WINDOW_ACTION_TASK_FILTER_NEXT_7_DAYS_TASKS(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-filter-next-7-days-tasks") +#define E_SHELL_WINDOW_ACTION_TASK_FILTER_OVERDUE_TASKS(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-filter-overdue-tasks") +#define E_SHELL_WINDOW_ACTION_TASK_FILTER_TASKS_WITH_ATTACHMENTS(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-filter-tasks-with-attachments") +#define E_SHELL_WINDOW_ACTION_TASK_FILTER_UNMATCHED(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-filter-unmatched") +#define E_SHELL_WINDOW_ACTION_TASK_SEARCH_ANY_FIELD_CONTAINS(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-search-any-field-contains") +#define E_SHELL_WINDOW_ACTION_TASK_SEARCH_DESCRIPTION_CONTAINS(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-search-description-contains") +#define E_SHELL_WINDOW_ACTION_TASK_SEARCH_SUMMARY_CONTAINS(window) \ + E_SHELL_WINDOW_ACTION ((window), "task-search-summary-contains") + +/* Action Groups */ +#define E_SHELL_WINDOW_ACTION_GROUP_TASKS(window) \ + E_SHELL_WINDOW_ACTION_GROUP ((window), "tasks") +#define E_SHELL_WINDOW_ACTION_GROUP_TASKS_FILTER(window) \ + E_SHELL_WINDOW_ACTION_GROUP ((window), "tasks-filter") + +#endif /* E_TASK_SHELL_VIEW_ACTIONS_H */ diff --git a/calendar/modules/e-task-shell-view-private.c b/calendar/modules/e-task-shell-view-private.c new file mode 100644 index 0000000000..9c6a3a94bb --- /dev/null +++ b/calendar/modules/e-task-shell-view-private.c @@ -0,0 +1,752 @@ +/* + * e-task-shell-view-private.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-task-shell-view-private.h" + +#include <widgets/menus/gal-view-factory-etable.h> + +static void +task_shell_view_config_hide_completed_tasks_changed_cb (GConfClient *client, + guint id, + GConfEntry *entry, + gpointer user_data) +{ + ETaskShellView *task_shell_view = user_data; + ETaskShellContent *task_shell_content; + ETaskShellSidebar *task_shell_sidebar; + ECalendarTable *task_table; + GList *clients; + + task_shell_content = task_shell_view->priv->task_shell_content; + task_table = e_task_shell_content_get_task_table (task_shell_content); + + task_shell_sidebar = task_shell_view->priv->task_shell_sidebar; + clients = e_task_shell_sidebar_get_clients (task_shell_sidebar); + + e_calendar_table_process_completed_tasks (task_table, clients, TRUE); + + /* Search query takes whether to show completed tasks into account, + * so if the preference has changed we need to update the query. */ + e_task_shell_view_execute_search (task_shell_view); + + g_list_free (clients); +} + +static void +task_shell_view_config_timezone_changed_cb (GConfClient *client, + guint id, + GConfEntry *entry, + gpointer user_data) +{ + ETaskShellView *task_shell_view = user_data; + + e_task_shell_view_update_timezone (task_shell_view); +} + +static void +task_shell_view_table_popup_event_cb (EShellView *shell_view, + GdkEventButton *event) +{ + const gchar *widget_path; + + widget_path = "/task-popup"; + e_shell_view_show_popup_menu (shell_view, widget_path, event); +} + +static void +task_shell_view_table_user_created_cb (ETaskShellView *task_shell_view, + ECalendarTable *task_table) +{ + ETaskShellSidebar *task_shell_sidebar; + ECalModel *model; + ECal *client; + ESource *source; + + /* This is the "Click to Add" handler. */ + + model = e_calendar_table_get_model (task_table); + client = e_cal_model_get_default_client (model); + source = e_cal_get_source (client); + + task_shell_sidebar = task_shell_view->priv->task_shell_sidebar; + e_task_shell_sidebar_add_source (task_shell_sidebar, source); + + e_cal_model_add_client (model, client); +} + +static void +task_shell_view_selector_client_added_cb (ETaskShellView *task_shell_view, + ECal *client) +{ + ETaskShellContent *task_shell_content; + ECalendarTable *task_table; + ECalModel *model; + + task_shell_content = task_shell_view->priv->task_shell_content; + task_table = e_task_shell_content_get_task_table (task_shell_content); + model = e_calendar_table_get_model (task_table); + + e_cal_model_add_client (model, client); + e_task_shell_view_update_timezone (task_shell_view); +} + +static void +task_shell_view_selector_client_removed_cb (ETaskShellView *task_shell_view, + ECal *client) +{ + ETaskShellContent *task_shell_content; + ECalendarTable *task_table; + ECalModel *model; + + task_shell_content = task_shell_view->priv->task_shell_content; + task_table = e_task_shell_content_get_task_table (task_shell_content); + model = e_calendar_table_get_model (task_table); + + e_cal_model_remove_client (model, client); +} + +static gboolean +task_shell_view_selector_popup_event_cb (EShellView *shell_view, + ESource *primary_source, + GdkEventButton *event) +{ + const gchar *widget_path; + + widget_path = "/task-list-popup"; + e_shell_view_show_popup_menu (shell_view, widget_path, event); + + return TRUE; +} + +static gboolean +task_shell_view_update_timeout_cb (ETaskShellView *task_shell_view) +{ + ETaskShellContent *task_shell_content; + ETaskShellSidebar *task_shell_sidebar; + ECalendarTable *task_table; + ECalModel *model; + GList *clients; + + task_shell_content = task_shell_view->priv->task_shell_content; + task_table = e_task_shell_content_get_task_table (task_shell_content); + model = e_calendar_table_get_model (task_table); + + task_shell_sidebar = task_shell_view->priv->task_shell_sidebar; + clients = e_task_shell_sidebar_get_clients (task_shell_sidebar); + + e_calendar_table_process_completed_tasks (task_table, clients, FALSE); + e_cal_model_tasks_update_due_tasks (E_CAL_MODEL_TASKS (model)); + + g_list_free (clients); + + return TRUE; +} + +static void +task_shell_view_load_view_collection (EShellViewClass *shell_view_class) +{ + GalViewCollection *collection; + GalViewFactory *factory; + ETableSpecification *spec; + const gchar *base_dir; + gchar *filename; + + collection = shell_view_class->view_collection; + + base_dir = EVOLUTION_ETSPECDIR; + spec = e_table_specification_new (); + filename = g_build_filename (base_dir, ETSPEC_FILENAME, NULL); + if (!e_table_specification_load_from_file (spec, filename)) + g_critical ("Unable to load ETable specification file " + "for tasks"); + g_free (filename); + + factory = gal_view_factory_etable_new (spec); + gal_view_collection_add_factory (collection, factory); + g_object_unref (factory); + g_object_unref (spec); + + gal_view_collection_load (collection); +} + +static void +task_shell_view_notify_view_id_cb (ETaskShellView *task_shell_view) +{ + ETaskShellContent *task_shell_content; + GalViewInstance *view_instance; + const gchar *view_id; + + task_shell_content = task_shell_view->priv->task_shell_content; + view_instance = + e_task_shell_content_get_view_instance (task_shell_content); + view_id = e_shell_view_get_view_id (E_SHELL_VIEW (task_shell_view)); + + /* A NULL view ID implies we're in a custom view. But you can + * only get to a custom view via the "Define Views" dialog, which + * would have already modified the view instance appropriately. + * Furthermore, there's no way to refer to a custom view by ID + * anyway, since custom views have no IDs. */ + if (view_id == NULL) + return; + + gal_view_instance_set_current_view_id (view_instance, view_id); +} + +void +e_task_shell_view_private_init (ETaskShellView *task_shell_view, + EShellViewClass *shell_view_class) +{ + ETaskShellViewPrivate *priv = task_shell_view->priv; + ESourceList *source_list; + GObject *object; + + object = G_OBJECT (shell_view_class->type_module); + source_list = g_object_get_data (object, "source-list"); + g_return_if_fail (E_IS_SOURCE_LIST (source_list)); + + priv->source_list = g_object_ref (source_list); + + if (!gal_view_collection_loaded (shell_view_class->view_collection)) + task_shell_view_load_view_collection (shell_view_class); + + g_signal_connect ( + task_shell_view, "notify::view-id", + G_CALLBACK (task_shell_view_notify_view_id_cb), NULL); +} + +void +e_task_shell_view_private_constructed (ETaskShellView *task_shell_view) +{ + ETaskShellViewPrivate *priv = task_shell_view->priv; + ETaskShellContent *task_shell_content; + ETaskShellSidebar *task_shell_sidebar; + EShellView *shell_view; + EShellContent *shell_content; + EShellSidebar *shell_sidebar; + EShellWindow *shell_window; + ECalendarTable *task_table; + ECalModel *model; + ETable *table; + ESourceSelector *selector; + guint id; + + shell_view = E_SHELL_VIEW (task_shell_view); + shell_content = e_shell_view_get_shell_content (shell_view); + shell_sidebar = e_shell_view_get_shell_sidebar (shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + + e_shell_window_add_action_group (shell_window, "tasks"); + e_shell_window_add_action_group (shell_window, "tasks-filter"); + + /* Cache these to avoid lots of awkward casting. */ + priv->task_shell_content = g_object_ref (shell_content); + priv->task_shell_sidebar = g_object_ref (shell_sidebar); + + task_shell_content = E_TASK_SHELL_CONTENT (shell_content); + task_table = e_task_shell_content_get_task_table (task_shell_content); + model = e_calendar_table_get_model (task_table); + table = e_calendar_table_get_table (task_table); + + task_shell_sidebar = E_TASK_SHELL_SIDEBAR (shell_sidebar); + selector = e_task_shell_sidebar_get_selector (task_shell_sidebar); + + g_signal_connect_swapped ( + task_table, "open-component", + G_CALLBACK (e_task_shell_view_open_task), + task_shell_view); + + g_signal_connect_swapped ( + task_table, "popup-event", + G_CALLBACK (task_shell_view_table_popup_event_cb), + task_shell_view); + + g_signal_connect_swapped ( + task_table, "status-message", + G_CALLBACK (e_task_shell_view_set_status_message), + task_shell_view); + + g_signal_connect_swapped ( + task_table, "user-created", + G_CALLBACK (task_shell_view_table_user_created_cb), + task_shell_view); + + g_signal_connect_swapped ( + model, "model-changed", + G_CALLBACK (e_task_shell_view_update_sidebar), + task_shell_view); + + g_signal_connect_swapped ( + model, "model-rows-deleted", + G_CALLBACK (e_task_shell_view_update_sidebar), + task_shell_view); + + g_signal_connect_swapped ( + model, "model-rows-inserted", + G_CALLBACK (e_task_shell_view_update_sidebar), + task_shell_view); + + g_signal_connect_swapped ( + table, "selection-change", + G_CALLBACK (e_task_shell_view_update_sidebar), + task_shell_view); + + g_signal_connect_swapped ( + task_shell_sidebar, "client-added", + G_CALLBACK (task_shell_view_selector_client_added_cb), + task_shell_view); + + g_signal_connect_swapped ( + task_shell_sidebar, "client-removed", + G_CALLBACK (task_shell_view_selector_client_removed_cb), + task_shell_view); + + g_signal_connect_swapped ( + task_shell_sidebar, "status-message", + G_CALLBACK (e_task_shell_view_set_status_message), + task_shell_view); + + g_signal_connect_swapped ( + selector, "popup-event", + G_CALLBACK (task_shell_view_selector_popup_event_cb), + task_shell_view); + + g_signal_connect_swapped ( + selector, "primary-selection-changed", + G_CALLBACK (e_shell_view_update_actions), + task_shell_view); + + e_categories_register_change_listener ( + G_CALLBACK (e_task_shell_view_update_search_filter), + task_shell_view); + + task_shell_view_update_timeout_cb (task_shell_view); + priv->update_timeout = g_timeout_add_full ( + G_PRIORITY_LOW, 60000, (GSourceFunc) + task_shell_view_update_timeout_cb, + task_shell_view, NULL); + + /* Listen for configuration changes. */ + + /* Timezone */ + id = calendar_config_add_notification_timezone ( + task_shell_view_config_timezone_changed_cb, task_shell_view); + priv->notifications = g_list_prepend ( + priv->notifications, GUINT_TO_POINTER (id)); + + /* Hide Completed Tasks (enable/units/value) */ + id = calendar_config_add_notification_hide_completed_tasks ( + task_shell_view_config_hide_completed_tasks_changed_cb, + task_shell_view); + priv->notifications = g_list_prepend ( + priv->notifications, GUINT_TO_POINTER (id)); + id = calendar_config_add_notification_hide_completed_tasks_units ( + task_shell_view_config_hide_completed_tasks_changed_cb, + task_shell_view); + priv->notifications = g_list_prepend ( + priv->notifications, GUINT_TO_POINTER (id)); + id = calendar_config_add_notification_hide_completed_tasks_value ( + task_shell_view_config_hide_completed_tasks_changed_cb, + task_shell_view); + priv->notifications = g_list_prepend ( + priv->notifications, GUINT_TO_POINTER (id)); + + e_task_shell_view_actions_init (task_shell_view); + e_task_shell_view_update_sidebar (task_shell_view); + e_task_shell_view_update_search_filter (task_shell_view); + e_task_shell_view_update_timezone (task_shell_view); + + e_task_shell_view_execute_search (task_shell_view); +} + +void +e_task_shell_view_private_dispose (ETaskShellView *task_shell_view) +{ + ETaskShellViewPrivate *priv = task_shell_view->priv; + GList *iter; + + DISPOSE (priv->source_list); + + DISPOSE (priv->task_shell_content); + DISPOSE (priv->task_shell_sidebar); + + if (task_shell_view->priv->activity != NULL) { + /* XXX Activity is no cancellable. */ + e_activity_complete (task_shell_view->priv->activity); + g_object_unref (task_shell_view->priv->activity); + task_shell_view->priv->activity = NULL; + } + + if (priv->update_timeout > 0) { + g_source_remove (priv->update_timeout); + priv->update_timeout = 0; + } + + for (iter = priv->notifications; iter != NULL; iter = iter->next) { + guint notification_id = GPOINTER_TO_UINT (iter->data); + calendar_config_remove_notification (notification_id); + } + g_list_free (priv->notifications); + priv->notifications = NULL; +} + +void +e_task_shell_view_private_finalize (ETaskShellView *task_shell_view) +{ + /* XXX Nothing to do? */ +} + +void +e_task_shell_view_execute_search (ETaskShellView *task_shell_view) +{ + ETaskShellContent *task_shell_content; + EShellView *shell_view; + EShellWindow *shell_window; + EShellContent *shell_content; + GtkAction *action; + GString *string; + ECalComponentPreview *task_preview; + ECalendarTable *task_table; + ECalModel *model; + 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); + shell_content = e_shell_view_get_shell_content (shell_view); + text = e_shell_content_get_search_text (shell_content); + + shell_window = e_shell_view_get_shell_window (shell_view); + action = ACTION (TASK_SEARCH_ANY_FIELD_CONTAINS); + value = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action)); + + if (text == NULL || *text == '\0') { + text = ""; + value = TASK_SEARCH_SUMMARY_CONTAINS; + } + + switch (value) { + default: + text = ""; + /* fall through */ + + case TASK_SEARCH_SUMMARY_CONTAINS: + format = "(contains? \"summary\" %s)"; + break; + + case TASK_SEARCH_DESCRIPTION_CONTAINS: + format = "(contains? \"description\" %s)"; + break; + + case TASK_SEARCH_ANY_FIELD_CONTAINS: + format = "(contains? \"any\" %s)"; + break; + } + + /* Build the query. */ + string = g_string_new (""); + e_sexp_encode_string (string, text); + query = g_strdup_printf (format, string->str); + g_string_free (string, TRUE); + + /* Apply selected filter. */ + value = e_shell_content_get_filter_value (shell_content); + 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; + } + } + + /* Honor the user's preference to hide completed tasks. */ + temp = calendar_config_get_hide_completed_tasks_sexp (FALSE); + if (temp != NULL) { + gchar *temp2; + + temp2 = g_strdup_printf ("(and %s %s)", temp, query); + g_free (query); + g_free (temp); + query = temp2; + } + + /* XXX This is wrong. We need to programmatically construct a + * FilterRule, tell it to build code, and pass the resulting + * expression string to ECalModel. */ + rule = filter_rule_new (); + e_shell_content_set_search_rule (shell_content, rule); + g_object_unref (rule); + + /* Submit the query. */ + task_shell_content = task_shell_view->priv->task_shell_content; + task_table = e_task_shell_content_get_task_table (task_shell_content); + model = e_calendar_table_get_model (task_table); + e_cal_model_set_search_query (model, query); + g_free (query); + + task_preview = + e_task_shell_content_get_task_preview (task_shell_content); + e_cal_component_preview_clear (task_preview); +} + +void +e_task_shell_view_open_task (ETaskShellView *task_shell_view, + ECalModelComponent *comp_data) +{ + EShell *shell; + EShellView *shell_view; + EShellWindow *shell_window; + CompEditor *editor; + CompEditorFlags flags = 0; + ECalComponent *comp; + icalcomponent *clone; + icalproperty *prop; + const gchar *uid; + + g_return_if_fail (E_IS_TASK_SHELL_VIEW (task_shell_view)); + g_return_if_fail (E_IS_CAL_MODEL_COMPONENT (comp_data)); + + shell_view = E_SHELL_VIEW (task_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + shell = e_shell_window_get_shell (shell_window); + + uid = icalcomponent_get_uid (comp_data->icalcomp); + editor = comp_editor_find_instance (uid); + + if (editor != NULL) + goto exit; + + comp = e_cal_component_new (); + clone = icalcomponent_new_clone (comp_data->icalcomp); + e_cal_component_set_icalcomponent (comp, clone); + + prop = icalcomponent_get_first_property ( + comp_data->icalcomp, ICAL_ATTENDEE_PROPERTY); + if (prop != NULL) + flags |= COMP_EDITOR_IS_ASSIGNED; + + if (itip_organizer_is_user (comp, comp_data->client)) + flags |= COMP_EDITOR_USER_ORG; + + if (!e_cal_component_has_attendees (comp)) + flags |= COMP_EDITOR_USER_ORG; + + editor = task_editor_new (comp_data->client, shell, flags); + comp_editor_edit_comp (editor, comp); + + g_object_ref (comp); + + if (flags & COMP_EDITOR_IS_ASSIGNED) + task_editor_show_assignment (TASK_EDITOR (editor)); + +exit: + gtk_window_present (GTK_WINDOW (editor)); +} + +void +e_task_shell_view_set_status_message (ETaskShellView *task_shell_view, + const gchar *status_message, + gdouble percent) +{ + EActivity *activity; + EShellView *shell_view; + EShellModule *shell_module; + + g_return_if_fail (E_IS_TASK_SHELL_VIEW (task_shell_view)); + + activity = task_shell_view->priv->activity; + shell_view = E_SHELL_VIEW (task_shell_view); + shell_module = e_shell_view_get_shell_module (shell_view); + + if (status_message == NULL || *status_message == '\0') { + if (activity != NULL) { + e_activity_complete (activity); + g_object_unref (activity); + activity = NULL; + } + + } else if (activity == NULL) { + activity = e_activity_new (status_message); + e_activity_set_percent (activity, percent); + e_shell_module_add_activity (shell_module, activity); + + } else { + e_activity_set_percent (activity, percent); + e_activity_set_primary_text (activity, status_message); + } + + task_shell_view->priv->activity = activity; +} + +void +e_task_shell_view_update_sidebar (ETaskShellView *task_shell_view) +{ + ETaskShellContent *task_shell_content; + EShellView *shell_view; + EShellSidebar *shell_sidebar; + ECalendarTable *task_table; + ECalModel *model; + ETable *table; + GString *string; + const gchar *format; + gint n_rows; + gint n_selected; + + shell_view = E_SHELL_VIEW (task_shell_view); + shell_sidebar = e_shell_view_get_shell_sidebar (shell_view); + + task_shell_content = task_shell_view->priv->task_shell_content; + task_table = e_task_shell_content_get_task_table (task_shell_content); + + model = e_calendar_table_get_model (task_table); + table = e_calendar_table_get_table (task_table); + + n_rows = e_table_model_row_count (E_TABLE_MODEL (model)); + n_selected = e_table_selected_count (table); + + string = g_string_sized_new (64); + + format = ngettext ("%d task", "%d tasks", n_rows); + g_string_append_printf (string, format, n_rows); + + if (n_selected > 0) { + format = _("%d selected"); + g_string_append_len (string, ", ", 2); + g_string_append_printf (string, format, n_selected); + } + + e_shell_sidebar_set_secondary_text (shell_sidebar, string->str); + + g_string_free (string, TRUE); +} + +void +e_task_shell_view_update_timezone (ETaskShellView *task_shell_view) +{ + ETaskShellContent *task_shell_content; + ETaskShellSidebar *task_shell_sidebar; + ECalComponentPreview *task_preview; + icaltimezone *timezone; + GList *clients, *iter; + + task_shell_content = task_shell_view->priv->task_shell_content; + task_preview = e_task_shell_content_get_task_preview (task_shell_content); + + task_shell_sidebar = task_shell_view->priv->task_shell_sidebar; + clients = e_task_shell_sidebar_get_clients (task_shell_sidebar); + + timezone = calendar_config_get_icaltimezone (); + + for (iter = clients; iter != NULL; iter = iter->next) { + ECal *client = iter->data; + + if (e_cal_get_load_state (client) == E_CAL_LOAD_LOADED) + e_cal_set_default_timezone (client, timezone, NULL); + } + + e_cal_component_preview_set_default_timezone (task_preview, timezone); + + g_list_free (clients); +} diff --git a/calendar/modules/e-task-shell-view-private.h b/calendar/modules/e-task-shell-view-private.h new file mode 100644 index 0000000000..415363730a --- /dev/null +++ b/calendar/modules/e-task-shell-view-private.h @@ -0,0 +1,145 @@ +/* + * e-task-shell-view-private.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_TASK_SHELL_VIEW_PRIVATE_H +#define E_TASK_SHELL_VIEW_PRIVATE_H + +#include "e-task-shell-view.h" + +#include <string.h> +#include <glib/gi18n.h> +#include <libecal/e-cal-time-util.h> +#include <libedataserver/e-categories.h> +#include <libedataserver/e-sexp.h> + +#include "e-util/e-dialog-utils.h" +#include "e-util/e-error.h" +#include "e-util/e-util.h" +#include "e-util/gconf-bridge.h" +#include "widgets/misc/e-popup-action.h" + +#include "calendar/common/authentication.h" +#include "calendar/gui/calendar-config.h" +#include "calendar/gui/comp-util.h" +#include "calendar/gui/e-cal-component-preview.h" +#include "calendar/gui/e-cal-model-tasks.h" +#include "calendar/gui/e-calendar-selector.h" +#include "calendar/gui/print.h" +#include "calendar/gui/dialogs/calendar-setup.h" +#include "calendar/gui/dialogs/copy-source-dialog.h" +#include "calendar/gui/dialogs/task-editor.h" + +#include "e-task-shell-content.h" +#include "e-task-shell-sidebar.h" +#include "e-task-shell-view-actions.h" + +#define E_TASK_SHELL_VIEW_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_TASK_SHELL_VIEW, ETaskShellViewPrivate)) + +/* Shorthand, requires a variable named "shell_window". */ +#define ACTION(name) \ + (E_SHELL_WINDOW_ACTION_##name (shell_window)) +#define ACTION_GROUP(name) \ + (E_SHELL_WINDOW_ACTION_GROUP_##name (shell_window)) + +/* For use in dispose() methods. */ +#define DISPOSE(obj) \ + G_STMT_START { \ + if ((obj) != NULL) { g_object_unref (obj); (obj) = NULL; } \ + } G_STMT_END + +/* ETable Specifications */ +#define ETSPEC_FILENAME "e-calendar-table.etspec" + +G_BEGIN_DECLS + +/* Filter items are displayed in ascending order. + * Non-negative values are reserved for categories. */ +enum { + TASK_FILTER_ANY_CATEGORY = -7, + TASK_FILTER_UNMATCHED = -6, + TASK_FILTER_NEXT_7_DAYS_TASKS = -5, + TASK_FILTER_ACTIVE_TASKS = -4, + TASK_FILTER_OVERDUE_TASKS = -3, + TASK_FILTER_COMPLETED_TASKS = -2, + TASK_FILTER_TASKS_WITH_ATTACHMENTS = -1 +}; + +/* Search items are displayed in ascending order. */ +enum { + TASK_SEARCH_SUMMARY_CONTAINS, + TASK_SEARCH_DESCRIPTION_CONTAINS, + TASK_SEARCH_ANY_FIELD_CONTAINS +}; + +struct _ETaskShellViewPrivate { + + /*** Module Data ***/ + + ESourceList *source_list; + + /*** Other Stuff ***/ + + /* These are just for convenience. */ + ETaskShellContent *task_shell_content; + ETaskShellSidebar *task_shell_sidebar; + + EActivity *activity; + guint update_timeout; + + /* GConf notification IDs */ + GList *notifications; +}; + +void e_task_shell_view_private_init + (ETaskShellView *task_shell_view, + EShellViewClass *shell_view_class); +void e_task_shell_view_private_constructed + (ETaskShellView *task_shell_view); +void e_task_shell_view_private_dispose + (ETaskShellView *task_shell_view); +void e_task_shell_view_private_finalize + (ETaskShellView *task_shell_view); + +/* Private Utilities */ + +void e_task_shell_view_actions_init + (ETaskShellView *task_shell_view); +void e_task_shell_view_execute_search + (ETaskShellView *task_shell_view); +void e_task_shell_view_open_task + (ETaskShellView *task_shell_view, + ECalModelComponent *comp_data); +void e_task_shell_view_set_status_message + (ETaskShellView *task_shell_view, + const gchar *status_message, + gdouble percent); +void e_task_shell_view_update_sidebar + (ETaskShellView *task_shell_view); +void e_task_shell_view_update_search_filter + (ETaskShellView *task_shell_view); +void e_task_shell_view_update_timezone + (ETaskShellView *task_shell_view); + +G_END_DECLS + +#endif /* E_TASK_SHELL_VIEW_PRIVATE_H */ diff --git a/calendar/modules/e-task-shell-view.c b/calendar/modules/e-task-shell-view.c new file mode 100644 index 0000000000..3bf84100cc --- /dev/null +++ b/calendar/modules/e-task-shell-view.c @@ -0,0 +1,296 @@ +/* + * e-task-shell-view.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-task-shell-view-private.h" + +enum { + PROP_0, + PROP_SOURCE_LIST +}; + +GType e_task_shell_view_type = 0; +static gpointer parent_class; + +static void +task_shell_view_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_SOURCE_LIST: + g_value_set_object ( + value, e_task_shell_view_get_source_list ( + E_TASK_SHELL_VIEW (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +task_shell_view_dispose (GObject *object) +{ + e_task_shell_view_private_dispose (E_TASK_SHELL_VIEW (object)); + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +task_shell_view_finalize (GObject *object) +{ + e_task_shell_view_private_finalize (E_TASK_SHELL_VIEW (object)); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +task_shell_view_constructed (GObject *object) +{ + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (parent_class)->constructed (object); + + e_task_shell_view_private_constructed (E_TASK_SHELL_VIEW (object)); +} + +static void +task_shell_view_update_actions (EShellView *shell_view) +{ + ETaskShellViewPrivate *priv; + EShellContent *shell_content; + EShellSidebar *shell_sidebar; + EShellWindow *shell_window; + GtkAction *action; + const gchar *label; + gboolean sensitive; + guint32 state; + + /* Be descriptive. */ + gboolean any_tasks_selected; + gboolean has_primary_source; + gboolean multiple_tasks_selected; + gboolean primary_source_is_system; + gboolean selection_has_url; + gboolean selection_is_assignable; + gboolean single_task_selected; + gboolean some_tasks_complete; + gboolean some_tasks_incomplete; + gboolean sources_are_editable; + + priv = E_TASK_SHELL_VIEW_GET_PRIVATE (shell_view); + + shell_window = e_shell_view_get_shell_window (shell_view); + + shell_content = e_shell_view_get_shell_content (shell_view); + state = e_shell_content_check_state (shell_content); + + single_task_selected = + (state & E_TASK_SHELL_CONTENT_SELECTION_SINGLE); + multiple_tasks_selected = + (state & E_TASK_SHELL_CONTENT_SELECTION_MULTIPLE); + selection_is_assignable = + (state & E_TASK_SHELL_CONTENT_SELECTION_CAN_ASSIGN); + sources_are_editable = + (state & E_TASK_SHELL_CONTENT_SELECTION_CAN_EDIT); + some_tasks_complete = + (state & E_TASK_SHELL_CONTENT_SELECTION_HAS_COMPLETE); + some_tasks_incomplete = + (state & E_TASK_SHELL_CONTENT_SELECTION_HAS_INCOMPLETE); + selection_has_url = + (state & E_TASK_SHELL_CONTENT_SELECTION_HAS_URL); + + shell_sidebar = e_shell_view_get_shell_sidebar (shell_view); + state = e_shell_sidebar_check_state (shell_sidebar); + + has_primary_source = + (state & E_TASK_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE); + primary_source_is_system = + (state & E_TASK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_SYSTEM); + + any_tasks_selected = + (single_task_selected || multiple_tasks_selected); + + action = ACTION (TASK_ASSIGN); + sensitive = + single_task_selected && sources_are_editable && + selection_is_assignable; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (TASK_CLIPBOARD_COPY); + sensitive = any_tasks_selected; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (TASK_CLIPBOARD_CUT); + sensitive = any_tasks_selected && sources_are_editable; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (TASK_CLIPBOARD_PASTE); + sensitive = sources_are_editable; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (TASK_DELETE); + sensitive = any_tasks_selected && sources_are_editable; + gtk_action_set_sensitive (action, sensitive); + if (multiple_tasks_selected) + label = _("Delete Tasks"); + else + label = _("Delete Task"); + g_object_set (action, "label", label, NULL); + + action = ACTION (TASK_FORWARD); + sensitive = single_task_selected; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (TASK_LIST_COPY); + sensitive = has_primary_source; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (TASK_LIST_DELETE); + sensitive = has_primary_source && !primary_source_is_system; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (TASK_LIST_PROPERTIES); + sensitive = has_primary_source; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (TASK_LIST_RENAME); + sensitive = has_primary_source; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (TASK_MARK_COMPLETE); + sensitive = + any_tasks_selected && + sources_are_editable && + some_tasks_incomplete; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (TASK_MARK_INCOMPLETE); + sensitive = + any_tasks_selected && + sources_are_editable && + some_tasks_complete; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (TASK_OPEN); + sensitive = single_task_selected; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (TASK_OPEN_URL); + sensitive = single_task_selected && selection_has_url; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (TASK_PRINT); + sensitive = single_task_selected; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (TASK_PURGE); + sensitive = sources_are_editable; + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (TASK_SAVE_AS); + sensitive = single_task_selected; + gtk_action_set_sensitive (action, sensitive); +} + +static void +task_shell_view_class_init (ETaskShellViewClass *class, + GTypeModule *type_module) +{ + GObjectClass *object_class; + EShellViewClass *shell_view_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (ETaskShellViewPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->get_property = task_shell_view_get_property; + object_class->dispose = task_shell_view_dispose; + object_class->finalize = task_shell_view_finalize; + object_class->constructed = task_shell_view_constructed; + + shell_view_class = E_SHELL_VIEW_CLASS (class); + shell_view_class->label = _("Tasks"); + shell_view_class->icon_name = "evolution-tasks"; + shell_view_class->ui_definition = "evolution-tasks.ui"; + shell_view_class->ui_manager_id = "org.gnome.evolution.tasks"; + shell_view_class->search_options = "/task-search-options"; + shell_view_class->search_rules = "tasktypes.xml"; + shell_view_class->type_module = type_module; + shell_view_class->new_shell_content = e_task_shell_content_new; + shell_view_class->new_shell_sidebar = e_task_shell_sidebar_new; + shell_view_class->update_actions = task_shell_view_update_actions; + + g_object_class_install_property ( + object_class, + PROP_SOURCE_LIST, + g_param_spec_object ( + "source-list", + _("Source List"), + _("The registry of task lists"), + E_TYPE_SOURCE_LIST, + G_PARAM_READABLE)); +} + +static void +task_shell_view_init (ETaskShellView *task_shell_view, + EShellViewClass *shell_view_class) +{ + task_shell_view->priv = + E_TASK_SHELL_VIEW_GET_PRIVATE (task_shell_view); + + e_task_shell_view_private_init (task_shell_view, shell_view_class); +} + +GType +e_task_shell_view_get_type (GTypeModule *type_module) +{ + if (e_task_shell_view_type == 0) { + const GTypeInfo type_info = { + sizeof (ETaskShellViewClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) task_shell_view_class_init, + (GClassFinalizeFunc) NULL, + type_module, + sizeof (ETaskShellView), + 0, /* n_preallocs */ + (GInstanceInitFunc) task_shell_view_init, + NULL /* value_table */ + }; + + e_task_shell_view_type = + g_type_module_register_type ( + type_module, E_TYPE_SHELL_VIEW, + "ETaskShellView", &type_info, 0); + } + + return e_task_shell_view_type; +} + +ESourceList * +e_task_shell_view_get_source_list (ETaskShellView *task_shell_view) +{ + g_return_val_if_fail (E_IS_TASK_SHELL_VIEW (task_shell_view), NULL); + + return task_shell_view->priv->source_list; +} diff --git a/calendar/modules/e-task-shell-view.h b/calendar/modules/e-task-shell-view.h new file mode 100644 index 0000000000..cc5b2350c1 --- /dev/null +++ b/calendar/modules/e-task-shell-view.h @@ -0,0 +1,71 @@ +/* + * e-task-shell-view.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_TASK_SHELL_VIEW_H +#define E_TASK_SHELL_VIEW_H + +#include <shell/e-shell-view.h> +#include <libedataserver/e-source-list.h> + +/* Standard GObject macros */ +#define E_TYPE_TASK_SHELL_VIEW \ + (e_task_shell_view_type) +#define E_TASK_SHELL_VIEW(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_TASK_SHELL_VIEW, ETaskShellView)) +#define E_TASK_SHELL_VIEW_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_TASK_SHELL_VIEW, ETaskShellViewClass)) +#define E_IS_TASK_SHELL_VIEW(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_TASK_SHELL_VIEW)) +#define E_IS_TASK_SHELL_VIEW_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_TASK_SHELL_VIEW)) +#define E_TASK_SHELL_VIEW_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_TASK_SHELL_VIEW, ETaskShellViewClass)) + +G_BEGIN_DECLS + +extern GType e_task_shell_view_type; + +typedef struct _ETaskShellView ETaskShellView; +typedef struct _ETaskShellViewClass ETaskShellViewClass; +typedef struct _ETaskShellViewPrivate ETaskShellViewPrivate; + +struct _ETaskShellView { + EShellView parent; + ETaskShellViewPrivate *priv; +}; + +struct _ETaskShellViewClass { + EShellViewClass parent_class; +}; + +GType e_task_shell_view_get_type + (GTypeModule *type_module); +ESourceList * e_task_shell_view_get_source_list + (ETaskShellView *task_shell_view); + +G_END_DECLS + +#endif /* E_TASK_SHELL_VIEW_H */ |