aboutsummaryrefslogtreecommitdiffstats
path: root/calendar
diff options
context:
space:
mode:
authorEttore Perazzoli <ettore@src.gnome.org>2003-10-22 02:49:34 +0800
committerEttore Perazzoli <ettore@src.gnome.org>2003-10-22 02:49:34 +0800
commit653cfffc0e00dfb59b36813c1b45c53d3f773c65 (patch)
tree9b486d5e383ec1391d60973d9cc548be0ef6d9d5 /calendar
parent0fb08f3ff81575a4749d851404233f34252dd2f2 (diff)
downloadgsoc2013-evolution-653cfffc0e00dfb59b36813c1b45c53d3f773c65.tar
gsoc2013-evolution-653cfffc0e00dfb59b36813c1b45c53d3f773c65.tar.gz
gsoc2013-evolution-653cfffc0e00dfb59b36813c1b45c53d3f773c65.tar.bz2
gsoc2013-evolution-653cfffc0e00dfb59b36813c1b45c53d3f773c65.tar.lz
gsoc2013-evolution-653cfffc0e00dfb59b36813c1b45c53d3f773c65.tar.xz
gsoc2013-evolution-653cfffc0e00dfb59b36813c1b45c53d3f773c65.tar.zst
gsoc2013-evolution-653cfffc0e00dfb59b36813c1b45c53d3f773c65.zip
Merge new-ui-branch to the trunk.
svn path=/trunk/; revision=22965
Diffstat (limited to 'calendar')
-rw-r--r--calendar/ChangeLog2071
-rw-r--r--calendar/cal-client/.cvsignore2
-rw-r--r--calendar/cal-client/Makefile.am7
-rw-r--r--calendar/cal-client/cal-client-types.h26
-rw-r--r--calendar/cal-client/cal-client.c3710
-rw-r--r--calendar/cal-client/cal-client.h101
-rw-r--r--calendar/cal-client/cal-listener.c895
-rw-r--r--calendar/cal-client/cal-listener.h53
-rw-r--r--calendar/cal-client/cal-marshal.list6
-rw-r--r--calendar/cal-client/cal-query.c470
-rw-r--r--calendar/cal-client/cal-query.h37
-rw-r--r--calendar/cal-client/client-test.c155
-rw-r--r--calendar/cal-client/query-listener.c393
-rw-r--r--calendar/cal-client/query-listener.h44
-rw-r--r--calendar/cal-util/cal-util.c24
-rw-r--r--calendar/conduits/calendar/calendar-conduit.c125
-rw-r--r--calendar/conduits/todo/todo-conduit.c101
-rw-r--r--calendar/gui/GNOME_Evolution_Calendar.server.in.in26
-rw-r--r--calendar/gui/Makefile.am5
-rw-r--r--calendar/gui/alarm-notify/alarm-notify.c209
-rw-r--r--calendar/gui/alarm-notify/alarm-queue.c2
-rw-r--r--calendar/gui/calendar-commands.c157
-rw-r--r--calendar/gui/calendar-commands.h2
-rw-r--r--calendar/gui/calendar-component.c849
-rw-r--r--calendar/gui/calendar-component.h48
-rw-r--r--calendar/gui/calendar-offline-handler.c18
-rw-r--r--calendar/gui/comp-editor-factory.c46
-rw-r--r--calendar/gui/comp-util.c46
-rw-r--r--calendar/gui/control-factory.c18
-rw-r--r--calendar/gui/control-factory.h2
-rw-r--r--calendar/gui/dialogs/Makefile.am3
-rw-r--r--calendar/gui/dialogs/alarm-options.c34
-rw-r--r--calendar/gui/e-cal-model-calendar.c10
-rw-r--r--calendar/gui/e-cal-model-tasks.c14
-rw-r--r--calendar/gui/e-cal-model.c282
-rw-r--r--calendar/gui/e-cal-model.h2
-rw-r--r--calendar/gui/e-cal-view.c497
-rw-r--r--calendar/gui/e-cal-view.h13
-rw-r--r--calendar/gui/e-calendar-table.c38
-rw-r--r--calendar/gui/e-calendar-view.c497
-rw-r--r--calendar/gui/e-calendar-view.h13
-rw-r--r--calendar/gui/e-day-view.c352
-rw-r--r--calendar/gui/e-day-view.h7
-rw-r--r--calendar/gui/e-itip-control.c162
-rw-r--r--calendar/gui/e-meeting-list-view.c101
-rw-r--r--calendar/gui/e-meeting-model.c1780
-rw-r--r--calendar/gui/e-meeting-model.h116
-rw-r--r--calendar/gui/e-meeting-store.c36
-rw-r--r--calendar/gui/e-meeting-time-sel.c6
-rw-r--r--calendar/gui/e-select-names-editable.c18
-rw-r--r--calendar/gui/e-tasks.c128
-rw-r--r--calendar/gui/e-week-view-event-item.c7
-rw-r--r--calendar/gui/e-week-view.c173
-rw-r--r--calendar/gui/e-week-view.h8
-rw-r--r--calendar/gui/gnome-cal.c617
-rw-r--r--calendar/gui/gnome-cal.h18
-rw-r--r--calendar/gui/itip-utils.c53
-rw-r--r--calendar/gui/main.c28
-rw-r--r--calendar/gui/migration.c126
-rw-r--r--calendar/gui/migration.h30
-rw-r--r--calendar/gui/print.c31
-rw-r--r--calendar/gui/tag-calendar.c3
-rw-r--r--calendar/gui/tasks-control.c4
63 files changed, 9850 insertions, 5005 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog
index 0d6fb57dfe..023e9f7ecd 100644
--- a/calendar/ChangeLog
+++ b/calendar/ChangeLog
@@ -1,9 +1,239 @@
-2003-10-17 Jeffrey Stedfast <fejj@ximian.com>
+2003-10-21 Rodrigo Moya <rodrigo@ximian.com>
- * conduits/calendar/Makefile.am: Fixed for libical changes.
+ * gui/calendar-component.c (calendar_component_init): fixed
+ a leak caused by only freeing 'base_uri' in some cases.
+
+2003-10-21 JP Rosevear <jpr@ximian.com>
+
+ * gui/control-factory.c (get_prop): fix parse error
+ (set_prop): gnome_calendar_open was renamed
+
+ * conduits/todo/todo-conduit.c (start_calendar_server): adapt to
+ the cal_client_new changes and the lack of a default calendar
+ routine
+ (pre_sync): don't have to pass a type for the default object any
+ more
+
+ * conduits/calendar/calendar-conduit.c (start_calendar_server):
+ adapt to the cal_client_new changes and the lack of a default
+ calendar routine
+ (pre_sync): don't have to pass a type for the default object any
+ more
+
+ * cal-client/cal-client.c (cal_client_open_async): add FIXME
+ comment
+
+2003-10-21 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/cal-backend-file.c: store recurrences per object.
+ (free_object): free correctly the CalBackendFileObject's
+ contained in 'priv->comp_uid_hash'.
+ (lookup_component, check_dup_uid, add_component, remove_component,
+ match_object_sexp):
+ adapted to changes in comp_uid_hash.
+
+2003-10-20 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/gnome-cal.[ch] (gnome_calendar_add_event_uri): renamed
+ from gnome_calendar_open.
+
+ * gui/calendar-component.c (load_uri_for_source): call
+ gnome_calendar_add_event_uri instead of setting the URI property on
+ the Bonobo control.
+
+2003-10-17 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/migration.c (process_calendar_dir): process subfolders.
+
+2003-10-17 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/migration.[ch] (migrate_old_calendars): new function.
+
+ * gui/calendar-component.c (calendar_component_init): call
+ the above function to migrate from old setups.
+
+ * gui/Makefile.am: added new files.
+
+2003-10-17 Jeffrey Stedfast <fejj@ximian.com>
+
+ * conduits/calendar/Makefile.am: Fixed for libical build changes.
* conduits/todo/Makefile.am: Same.
+2003-10-17 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-cal-view.c (on_print): call
+ e_cal_view_get_visible_time_range, not the gnome_calendar_
+ version.
+ (e_cal_view_new_appointment_for, e_cal_view_new_appointment,
+ e_cal_view_edit_appointment): new functions.
+
+ * gui/gnome-cal.[ch] (gnome_calendar_new_appointment_for,
+ gnome_calendar_new_appointment, gnome_calendar_edit_object):
+ removed these functions, now available in e-cal-view.
+
+ * gui/calendar-commands.c:
+ * gui/e-day-view.c:
+ * gui/e-week-view-event-item.c:
+ * gui/e-week-view.c: replaced calls to gnome_calendar_* with
+ e_cal_view_* equivalents.
+
+2003-10-17 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-cal-view.[ch] (e_cal_view_get_default_category):
+ (e_cal_view_set_default_category): new functions.
+ (e_cal_view_destroy): free the default_category field.
+
+ * gui/e-day-view.[ch] (e_day_view_set_default_category):
+ removed obsolete function.
+ (e_day_view_init, e_day_view_destroy, e_day_view_do_key_press):
+ use the ECalView's default_category.
+
+ * gui/e-week-view.[ch] (e_week_view_set_default_category):
+ removed obsolete function.
+ (e_week_view_init, e_week_view_destroy, e_week_view_do_key_press):
+ use the ECalView's default_category.
+
+ * gui/gnome-cal.c (gnome_calendar_set_query): set the query
+ also on the list view by using the priv->views array.
+ (search_bar_category_changed_cb, gnome_calendar_set_default_client):
+ use the priv->views array.
+ (gnome_calendar_get_calendar_model): return the model for the
+ current view widget.
+ (gnome_calendar_open): removed tasks opening code.
+
+2003-10-16 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/dialogs/new-calendar.c (new_calendar_dialog): if the user
+ presses Cancel, just terminate.
+
+2003-10-16 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/calendar-component.c (calendar_component_init): create
+ directories for the newly-created calendars.
+
+ * gui/dialogs/new-calendar.c (create_new_source_with_group): use
+ e_mkdir_hier instead of mkdir.
+
+2003-10-16 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/calendar-component.c (calendar_component_init): if no groups
+ are present in the configuration, create the "On This Computer"
+ group and the "Personal" and "Work" calendars on it.
+
+ * gui/dialogs/new-calendar.c (new_calendar_dialog): moved the
+ source creation...
+ (create_new_source_with_group): ...here, and made the code create
+ the directory for the new calendar.
+
+2003-10-15 Hans Petter Jansson <hpj@ximian.com>
+
+ * gui/e-select-names-editable.c (e_selct_names_editable_get_address):
+ EDestination -> EABDestination.
+
+ * gui/gnome-cal.c (setup_widgets): evolution_dir -> ".evolution".
+
+2003-10-15 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-select-names-editable.c (e_select_names_editable_get_address):
+ use EABDestination instead of EDestination.
+
+ * gui/gnome-cal.c (gnome_calendar_open): disabled tasks opening code.
+
+2003-10-15 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-meeting-list-view.c: adapted to new addressbook API.
+
+ * gui/e-meeting-store.c: adapted to new addressbook API.
+ (find_zone): fixed usage of icalcomponent where an icalproperty
+ is expected.
+ (refresh_busy_periods): fixed call to cal_client_get_free_busy().
+
+ * gui/e-meeting-time-sel.c (e_meeting_time_selector_construct):
+ added missing variable.
+
+2003-10-15 Jeffrey Stedfast <fejj@ximian.com>
+
+ * gui/dialogs/meeting-page.c: #include <gal/e-table/e-table.h>
+
+2003-10-15 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-meeting-list-view.c (start_addressbook_server):
+ updated to new addressbook API.
+ (book_open_cb): removed unneeded function, since we load
+ the local addressbook synchronously.
+
+2003-10-15 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/Makefile.am: added missing header directories.
+
+ * pcs/cal-factory.h: include <libical/ical.h>, not <ical.h>.
+
+ * gui/dialogs/meeting-page.c: added missing headers.
+ (meeting_page_construct): free 'backend_address' as returned
+ by cal_client_get_cal_address(). Removed code to create the
+ meeting model's ETable not removed with the merge.
+
+ * gui/e-meeting-list-view.c: updated addressbook headers.
+
+ * gui/gnome-cal.h: added missing ',' in the GnomeCalendarViewType
+ enum.
+
+2003-10-14 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-day-view.c (e_day_view_update_query): dont set status
+ messages here, already set in e_cal_view_update_query.
+ (update_query): removed this function.
+ (e_day_view_recalc_day_starts): call e_day_view_update_query,
+ not update_query.
+
+ * gui/e-week-view.c (e_week_view_update_query): dont set status
+ messages here, already set in e_cal_view_update_query.
+
+ * gui/gnome-cal.c (adjust_query_for_view): new function to adjust
+ the query for the visible time range on a given view.
+ (gnome_calendar_set_query): call adjust_query_for_view for each
+ one of the views.
+
+2003-10-14 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-cal-view.c (e_cal_view_init): connect to signals on the
+ model we create here, so that we get notifications for changes.
+
+ * gui/gnome-cal.c (gnome_calendar_set_query): set the query
+ on all models.
+ (gnome_calendar_open): update the date navigator query.
+
+2003-10-14 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/cal.c (cal_notify_timezone_requested): never send NULL
+ strings to ORBit.
+
+ * gui/e-cal-view.c (e_cal_view_create_popup_menu): removed
+ unneeded variables. Also, fixed a typo that was making the
+ menu options be disabled when they should be enabled.
+
+2003-10-13 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-cal-model.[ch] (e_cal_model_get_client_for_uri): new function.
+
+ * gui/gnome-cal.[ch] (gnome_calendar_set_default_client): new function.
+
+ * gui/calendar-component.c (primary_source_selection_changed_callback):
+ set the default client on the calendar view to be the primary
+ selection on the source list.
+
+2003-10-13 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/dialogs/new-calendar.c (new_calendar_dialog): set a default group
+ on the calendar group option menu and create the source if all checks
+ are passed.
+
+2003-10-12 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/dialogs/new-calendar.c (new_calendar_dialog): set up widgets
+ loaded from the Glade file.
+
2003-10-10 Hans Petter Jansson <hpj@ximian.com>
* gui/Makefile.am (etspec_DATA): Add e-cal-list-view.etspec.
@@ -44,6 +274,66 @@
* gui/e-cal-list-view.[ch]: Implement ECalListView, subclassing
ECalView.
+2003-10-10 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/dialogs/new-calendar.[ch]: added new widget, which implements
+ the dialog to create new calendars.
+
+ * gui/dialogs/new-calendar.glade: basic mockup of the dialog.
+
+ * gui/dialogs/Makefile.am: added new files.
+
+ * gui/calendar-commands.c (file_new_calendar_cb): open the new calendar
+ dialog to allow user to create a new cal.
+
+2003-10-10 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/control-factory.c (calendar_properties_init): pass the
+ BonoboControl to get_prop/set_prop.
+ (get_prop): obtain the GnomeCalendar from the control.
+ (set_prop): ditto, and when the URI property is changed,
+ sensitize the UI as approppriate.
+
+ * gui/calendar-commands.c (calendar_control_sensitize_calendar_commands):
+ made this function public.
+
+ * gui/calendar-commands.h: added new prototype.
+
+2003-10-10 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/calendar-commands.c (file_new_calendar_cb,
+ file_new_appointment_cb, file_new_event_cb, file_new_meeting_cb,
+ file_new_task_cb): callbacks for "New..." verbs.
+ (sensitize_calendar_commands): sensitize new verbs, and made it
+ sensitize correctly based on the set of clients currently loaded.
+ (sensitize_taskpad_commands): likewise.
+
+2003-10-09 Hans Petter Jansson <hpj@ximian.com>
+
+ * gui/e-cal-model.c (get_classification): Adapt to libical API changes.
+ (ecm_set_value_at): Break after each case, so we don't set the passed value
+ in more than one field.
+
+2003-10-09 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-cal-view.c (e_cal_view_delete_selected_occurrence):
+ * cal-client/cal-client.c (cal_client_remove_object): added missing
+ argument when calling cal_client_remove_object_with_mod().
+
+2003-10-09 Rodrigo Moya <rodrigo@ximian.com>
+
+ * idl/evolution-calendar.idl: added missing 'rid' argument to the
+ removeObject method.
+
+ * cal-client/cal-client.c (cal_client_remove_object_with_mod):
+ * pcs/cal-backend.h:
+ * pcs/cal-backend.c (cal_backend_remove_object):
+ * pcs/cal-backend-sync.h:
+ * pcs/cal-backend-sync.c (cal_backend_sync_remove_object,
+ _cal_backend_remove_object):
+ * pcs/cal-backend-file.c (cal_backend_file_remove_object):
+ * pcs/cal.c (impl_cal_removeObject): adapted to changes in IDL.
+
2003-10-09 Jeffrey Stedfast <fejj@ximian.com>
* cal-client/Makefile.am: INCLUDE path fixes for changes made to
@@ -90,6 +380,165 @@
* gui/dialogs/task-details-page.glade: Make percent-complete of
task details dialog numeric only.
+2003-10-08 Chris Toshok <toshok@ximian.com>
+
+ * gui/dialogs/e-delegate-dialog.c (e_delegate_dialog_construct):
+ EDestination => EABDestination, and e_destination =>
+ eab_destination.
+ (e_delegate_dialog_get_delegate): same.
+ (e_delegate_dialog_get_delegate_name): same.
+
+ * gui/dialogs/comp-editor-util.c: remove unnecessary #include of
+ e-destination.h.
+
+ * gui/dialogs/alarm-options.c (alarm_to_malarm_widgets):
+ EDestination => EABDestination, and e_destination =>
+ eab_destination.
+ (malarm_widgets_to_alarm): same.
+
+ * gui/e-meeting-model.c (book_open_cb): track change to error
+ return codes.
+ (start_addressbook_server): use
+ e_book_async_get_default_addressbook.
+ (contacts_cb): rename cursor_cb to this, as we no longer get
+ passed a cursur, and we don't need to check the email address
+ since the query is now "is" instead of "contains".
+ (refresh_busy_periods): use an "is" query, and use
+ e_book_async_get_contacts instead of getting a CardCursor.
+ (process_section): this takes an EABDestination** instead of a
+ SimpleCardList*, which is gone.
+ (select_names_ok_cb): get "destinations" instead of
+ "simple_card_list".
+
+2003-10-08 Rodrigo Moya <rodrigo@ximian.com>
+
+ * cal-client/cal-client.c (cal_client_is_read_only): fixed
+ documentation comments.
+
+ * gui/calendar-commands.c (sensitize_calendar_commands): figure
+ out read-only menu items to disable based on the currently
+ selected object's CalClient.
+
+2003-10-08 Rodrigo Moya <rodrigo@ximian.com>
+
+ * cal-client/cal-client.c: set better error m,essages on the
+ E_CALENDAR_CHECK_STATUS macro.
+ (cal_client_get_error_message): new function.
+
+ * cal-client/cal-client.h: added new prototype.
+
+ * gui/dialogs/comp-editor.c (save_comp): use the GError argument
+ for the cal_client_create/_modify_object calls, and display the
+ error message coming from the backend.
+
+ * gui/comp-util.c (cal_comp_is_on_server): likewise.
+
+2003-10-07 Dan Winship <danw@ximian.com>
+
+ * idl/evolution-calendar.idl (getDefaultObject): Remove the "type"
+ arg; the backend knows what type it is
+
+ * pcs/cal.c (impl_Cal_getDefaultObject): Likewise
+
+ * pcs/cal-backend.c (cal_backend_get_default_object): Likewise
+
+ * pcs/cal-backend-sync.c (cal_backend_sync_get_default_object,
+ _cal_backend_get_default_object): Likewise
+
+ * pcs/cal-backend-file.c (cal_backend_file_get_default_object):
+ Likewise. (Use cal_backend_get_kind() instead.)
+
+ * cal-client/cal-client.c (cal_client_get_default_object):
+ Likewise
+
+ * gui/comp-util.c (cal_comp_event_new_with_defaults,
+ cal_comp_task_new_with_defaults): Update calls to
+ cal_client_get_default_object().
+
+ * pcs/cal-backend-sync.c (_cal_backend_get_static_capabilities):
+ Use the right cal notification
+
+2003-10-07 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-cal-model.c (e_cal_model_create_component_with_defaults):
+ dont clone NULL icalcomponent's.
+
+2003-10-07 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-cal-model.c (e_cal_model_get_default_client): make sure we
+ always return a default client, if possible, since we rely on having
+ a default client in many places.
+
+ * gui/e-day-view.c (e_day_view_do_key_press): dont create event if
+ e_cal_model_create_component_with_defaults returns NULL.
+
+ * gui/e-week-view.c (e_week_view_do_key_press): dont create event if
+ e_cal_model_create_component_with_defaults returns NULL.
+
+2003-10-06 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-cal-model.c (e_cal_model_create_component_with_defaults):
+ make sure the component has always an UID.
+
+ * gui/e-day-view.c (e_day_view_find_event_from_uid):
+ * gui/e-week-view.c (e_week_view_find_event_from_uid): check
+ pointers passed to strcmp().
+
+2003-10-06 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/gnome-cal.c (gnome_calendar_open): added missing call to
+ cal_client_open().
+
+ * cal-client/cal-client.c (cal_client_new): fixed documentation
+ comments.
+ (cal_client_open): emit CAL_OPENED signal with appropriate status codes.
+ (open_sync): dont emit CAL_OPENED signal, it's already emitted in
+ cal_client_open().
+
+2003-10-06 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/comp-editor-factory.c (open_client):
+ * gui/gnome-cal.c (gnome_calendar_open, gnome_calendar_construct):
+ * gui/calendar-offline-handler.c (backend_go_offline, backend_go_online,
+ calendar_offline_handler_init): adapted to changes in cal_client and
+ manage GError's returned by cal_client_open.
+
+ * gui/e-itip-control.c: dont run anymore sub event loops.
+ (start_calendar_server): use synchronous interface for opening calendars.
+ (start_default_server): renamed it from *_async.
+ (start_calendar_server_cb): removed unneeded function.
+ (object_requested_cb): use sync interface.
+
+ * gui/e-tasks.c (e_tasks_construct): dont create the CalClient here.
+ (e_tasks_open): do it here, where we've got all the info needed.
+
+ * importers/icalendar-importer.c (update_single_object): killed warning.
+ (ical_importer_new, vcal_importer_new): don't create CalClient's here.
+ (load_file_fn): create them here.
+ (vcal_load_file_fn): and here.
+ (gnome_calendar_import_data_fn): fixed usage of cal_client_*.
+
+ * */*: integrated JP's changes for synchronous open's in cal_client
+ and one model per view instead of one model for all views.
+
+2003-10-02 Rodrigo Moya <rodrigo@ximian.com>
+
+ * cal-client/cal-client.c (cal_client_modify_object): return FALSE
+ if the icalcomponent is NULL.
+
+ * gui/e-day-view.c (e_day_view_finish_resize): commit sequence on
+ CalComponent after changing start/end dates.
+
+2003-10-01 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-day-view.c (process_component):
+ * gui/e-week-view.c (process_component): expand recurrences here.
+
+2003-09-30 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/cal-backend-file.c (match_recurrence_sexp): removed.
+ (match_object_sexp): dont expand recurrences here.
+
2003-09-30 Mike Kestner <mkestner@ximian.com>
* cal-util/cal-util-marshal.list : new VOID:STRING,STRING,STRING
@@ -113,6 +562,519 @@
* conduits/calendar/Makefile.am: ditto
+2003-09-26 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal-backend.c (cal_backend_class_init): remove cal_added
+ signal
+
+2003-09-26 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal.h: add protos
+
+ * pcs/cal.c (cal_get_backend): accessor
+ (cal_get_listener): ditto
+
+ * pcs/cal-factory.c (impl_CalFactory_getCal): update to new
+ routine name
+
+ * pcs/cal-backend.h: add protos
+
+ * pcs/cal-backend.c (cal_backend_init): init client mutex
+ (cal_backend_finalize): destroy client mutex
+ (cal_destroy_cb): just remove the client
+ (listener_died_cb): remove the client, the listener died so it
+ can't really do anything
+ (last_client_gone): signal the last client gone
+ (cal_backend_add_client): add a client with locking and listen for
+ the death of the listener
+ (cal_backend_remove_client): remove client
+
+2003-09-26 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/cal-backend-sync.c (_cal_backend_create_object): only free the
+ returned UID if it's not NULL.
+
+ * pcs/cal.c (cal_notify_object_created): dont send NULL strings to
+ ORBit code.
+
+2003-09-26 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/comp-util.c (cal_comp_is_on_server): free the icalcomponent
+ returned from cal_client_get_object, and return TRUE if we find
+ the component on the backend.
+
+ * gui/e-day-view.c (process_component):
+ * gui/e-week-view.c (process_component): added missing case, so that
+ we also display recurrent meetings starting before the time range and
+ ending after the time range.
+
+ * cal-client/cal-listener.c (impl_notifyReadOnly): pass the
+ 'read_only' argument to the signal callback correctly (a gboolean
+ not a 'gboolean *').
+
+ * gui/comp-editor-factory.c (resolve_pending_requests): removed
+ the g_assert on 'oc->pending != NULL', since there are now cases
+ (local calendar) where we get to call this function (cal_opened_cb)
+ with no pending requests yet.
+
+2003-09-25 JP Rosevear <jpr@ximian.com>
+
+ * gui/calendar-commands.c (publish_freebusy_cmd): adapt to new
+ get_free_busy api
+
+ * conduits/calendar/calendar-conduit.c (post_sync): ditto
+ (pre_sync): ditto
+
+ * conduits/todo/todo-conduit.c (pre_sync): ditto
+ (post_sync): ditto
+
+ * gui/e-meeting-model.c (refresh_busy_periods): ditto
+
+ * gui/e-itip-control.c (send_freebusy): ditto
+
+ * gui/e-cal-view.c (on_publish): ditto
+
+ * cal-client/cal-listener.h: add signals
+
+ * cal-client/cal-listener.c (build_change_list): move here from
+ cal-client.c
+ (impl_notifyChanges): implement
+ (build_free_busy_list): util to create the GList of free busy
+ objects
+ (impl_notifyFreeBusy): implement
+ (cal_listener_class_init): set free busy and changes epv methods,
+ add signals
+
+ * cal-client/cal-client.h: update protos
+
+ * cal-client/cal-client.c (cal_get_changes_cb): get changes call
+ back
+ (cal_get_free_busy_cb): get free busy call back
+ (cal_client_init): listen for free busy and changes signals
+ (cal_client_get_changes): convert to new threaded sync api
+ (cal_client_get_free_busy): ditto
+
+ * pcs/cal.h: add protos
+
+ * pcs/cal.c: remove dead type conversion function
+ (impl_Cal_getChanges): implement by just calling, no return stuff
+ (impl_Cal_getFreeBusy): ditto
+ (cal_notify_changes): do getChanges callback
+ (cal_notify_free_busy): do getFreeBusy callback
+
+ * pcs/cal-backend.h: update protos, vmethods
+
+ * pcs/cal-backend.c (cal_backend_get_free_busy): call through
+ (cal_backend_get_changes): ditto
+
+ * pcs/cal-backend-sync.h: add vmethods, protos
+
+ * pcs/cal-backend-sync.c (cal_backend_sync_get_changes): call
+ through
+ (cal_backend_sync_get_free_busy): ditto
+ (_cal_backend_get_changes): backend implementation, notify
+ (_cal_backend_get_free_busy): ditto
+ (cal_backend_sync_class_init): set free busy and changes
+ implementations
+
+ * pcs/cal-backend-file.c (cal_backend_file_get_free_busy): convert
+ to sync backend method
+ (cal_backend_file_compute_changes_foreach_key): remove from the
+ hash here
+ (cal_backend_file_compute_changes): no need to build the sequence
+ here
+ (cal_backend_file_get_changes): convert to sync backend method
+ (cal_backend_file_class_init): set sync backend methods for free
+ busy and changes
+
+ * idl/evolution-calendar.idl: convert getChanges and getFreeBusy
+ to new async api
+
+2003-09-25 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal-backend.h: remove dead result enums
+
+ * pcs/cal-backend.c: fix comments
+
+ * idl/evolution-calendar.idl: remove dead exceptions
+
+2003-09-25 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal.c (cal_notify_default_object): send back the empty
+ string if the object is NULL
+ (cal_notify_object): ditto
+
+2003-09-25 JP Rosevear <jpr@ximian.com>
+
+ * gui/comp-editor-factory.c (edit_existing): convert to api
+ changes
+
+ * conduits/todo/todo-conduit.c (local_record_from_uid): ditto
+ (pre_sync): ditto
+
+ * conduits/calendar/calendar-conduit.c (local_record_from_uid):
+ ditto
+ (pre_sync): ditto
+
+ * importers/icalendar-importer.c (update_single_object): ditto
+
+ * gui/dialogs/comp-editor.c (obj_updated_cb): ditto
+
+ * gui/e-itip-control.c (get_real_item): ditto
+ (find_server): ditto
+
+ * gui/comp-util.c (cal_comp_is_on_server): ditto
+ (cal_comp_event_new_with_defaults): ditto
+ (cal_comp_task_new_with_defaults): ditto
+
+ * cal-client/cal-listener.h: add signals
+
+ * cal-client/cal-listener.c (impl_notifyDefaultObjectRequested):
+ implement
+ (impl_notifyObjectRequested): ditto
+ (cal_listener_class_init): set above epv implementations, add signals
+
+ * cal-client/cal-client.h: update protos
+
+ * cal-client/cal-client.c (cal_default_object_requested_cb): get
+ default object callback
+ (cal_object_requested_cb): get object callback
+ (cal_client_init): listen for get and get default object signals
+ (cal_client_get_default_object): convert to new sync api
+ (cal_client_get_object): ditto
+
+ * pcs/cal.h: add protos
+
+ * pcs/cal.c (impl_Cal_getDefaultObject): just call the backend, it
+ does the notification now
+ (impl_Cal_getObject): ditto
+ (cal_notify_default_object): do getDefaultObject response
+ (cal_notify_object): do getObject response
+
+ * pcs/cal-backend.h: remove vmethods, protos
+
+ * pcs/cal-backend.c: remove a couple of dead functions
+ (cal_backend_class_init): get_object_component is no longer a
+ vmethod
+ (cal_backend_get_default_object): call through
+ (cal_backend_get_object): ditto
+
+ * pcs/cal-backend-sync.h: add protos, vmethods
+
+ * pcs/cal-backend-sync.c (cal_backend_sync_get_default_object):
+ call through
+ (cal_backend_sync_get_object): ditto
+ (_cal_backend_discard_alarm): pass correct params to
+ cal_notify_discard_alarm
+ (_cal_backend_get_default_object): call through and notify
+ (_cal_backend_get_object): ditto
+ (cal_backend_sync_class_init): set backend implementations
+
+ * pcs/cal-backend-file.c (cal_backend_file_get_default_object):
+ convert to sync backend method
+ (cal_backend_file_get_object): ditto
+ (cal_backend_file_compute_changes_foreach_key): just look up the
+ component rather than using the backend vmethod
+ (cal_backend_file_remove_object): return valid sync status codes
+ (cal_backend_file_class_init): move get_object, get_default_object
+ to sync class
+
+ * idl/evolution-calendar.idl: convert getObject and
+ getDefaultObject to new async idl
+
+2003-09-25 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal.c (impl_Cal_discardAlarm): just call the backend
+ function, it does the notification
+ (cal_notify_alarm_discarded): notify of discard alarm call
+
+ * pcs/cal-backend.h: update proto
+
+ * pcs/cal-backend.c (cal_backend_discard_alarm): call through
+
+ * pcs/cal-backend-sync.h: add proto, vmethod
+
+ * pcs/cal-backend-sync.c (cal_backend_sync_discard_alarm): call
+ through
+ (_cal_backend_discard_alarm): call through and notify
+ (cal_backend_sync_class_init): set discard alarm implementation
+
+ * pcs/cal-backend-file.c (cal_backend_file_discard_alarm): match
+ sync backend vmethod
+ (cal_backend_file_class_init): set alarm vmethod implementation
+
+ * idl/evolution-calendar.idl: switch discardAlarm to new api
+
+ * gui/alarm-notify/alarm-queue.c (remove_queued_alarm): match new
+ api
+
+ * cal-client/cal-listener.h: add signal
+
+ * cal-client/cal-listener.c (impl_notifyAlarmDiscarded): implement
+ (cal_listener_class_init): add alarm, send, receive epv functions,
+ alarm signal
+
+ * cal-client/cal-client.h: update proto
+
+ * cal-client/cal-client.c (cal_alarm_discarded_cb): discardAlarm
+ callback
+ (cal_client_init): listen to discard alarm signal
+ (cal_client_discard_alarm): implement with new threaded sync api
+
+2003-09-25 JP Rosevear <jpr@ximian.com>
+
+ * idl/evolution-calendar.idl: remove unused user exceptions
+
+2003-09-24 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/cal-backend-util.[ch] (cal_backend_util_fill_alarm_instances_seq):
+ removed unneeded function.
+
+2003-09-24 JP Rosevear <jpr@ximian.com>
+
+ * conduits/*/*.c: adjust to new timezone api calls
+
+ * gui/*.c: ditto
+
+ * gui/dialogs/*.c: ditto
+
+ * cal-client/cal-listener.h: add new signals
+
+ * cal-client/cal-listener.c (convert_status): convert invalid
+ object as well
+ (impl_notifyTimezoneRequested): implement
+ (impl_notifyDefaultTimezoneSet): ditto
+ (cal_listener_class_init): set epv implementations for timezone
+ functions
+ (cal_listener_class_init): create timezone response signals
+
+ * cal-client/cal-client.h: update protos
+
+ * cal-client/cal-client.c: fix return values all over the place
+ (cal_get_timezone_cb): getTimezone response
+ (cal_query_cb): setDefaultTimezone response
+ (cal_client_init): listen for new response signals
+ (cal_client_get_timezone): implement using new thread sync api
+ (cal_client_ensure_timezone_on_server): use add timezone call
+ (cal_client_set_default_timezone): oimplement using new thread sync
+ api
+
+ * cal-client/cal-client-types.h: add invalid object status code
+
+ * idl/evolution-calendar.idl: getQuery no longer raises any user
+ exceptions, remove dead types and exceptions
+
+2003-09-24 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal.h: new protos
+
+ * pcs/cal.c (impl_Cal_getTimezone): call backend implementation
+ (impl_Cal_addTimezone): ditto
+ (impl_Cal_setDefaultTimezone): ditto
+ (cal_class_init): set epv implementations of timezone functions
+ (cal_notify_timezone_requested): notify of get timezone response
+ (cal_notify_default_timezone_set): notify of default timezone
+ being set
+
+ * pcs/cal-backend.h: new vmethods, protos
+
+ * pcs/cal-backend.c (cal_backend_class_init): init new timezone
+ vmethods
+ (cal_backend_get_timezone): call through
+ (cal_backend_set_default_timezone): ditto
+ (cal_backend_add_timezone): ditto
+ (cal_backend_internal_get_default_timezone): ditto
+ (cal_backend_internal_get_timezone): ditto
+
+ * pcs/cal-backend-sync.h: add vmethods, protos
+
+ * pcs/cal-backend-sync.c (cal_backend_sync_get_timezone): call
+ through
+ (cal_backend_sync_set_default_timezone): ditto
+ (_cal_backend_set_default_timezone): call through and notify
+ (_cal_backend_get_timezone): ditto
+ (cal_backend_sync_class_init): set backend implementations for new
+ funcs
+
+ * pcs/cal-backend-object-sexp.c (func_occur_in_time_range): get
+ time_t values based on the zone
+
+ * pcs/cal-backend-file.c: reorg so we don't have to prototype
+ everything
+ (cal_backend_file_get_timezone): implement the sync backend way
+ (cal_backend_file_add_timezone): ditto
+ (cal_backend_file_set_default_timezone): ditto
+ (cal_backend_file_internal_get_default_timezone): internal method,
+ for sexp comparison
+ (cal_backend_file_internal_get_timezone): ditto
+
+ * idl/evolution-calendar.idl: convert timezone routines to async
+ api
+
+2003-09-23 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/cal-backend-object-sexp.c (func_occur_in_time_range): dont expand
+ recurrences, since they are supposed to be expanded in the backends.
+ (instance_occur_cb, resolve_tzid): removed unneeded functions.
+
+ * pcs/cal-backend-file.c (cal_backend_file_add_timezone): guard against
+ adding the timezone if it's already there.
+
+2003-09-23 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal.c (cal_notify_object_created): notify with the object,
+ not the uid
+
+ * gui/e-cal-model.c (add_new_client): don't listen for
+ non-existent signal
+
+2003-09-23 JP Rosevear <jpr@ximian.com>
+
+ * cal-client/cal-client.h: remove dead proto
+
+2003-09-23 JP Rosevear <jpr@ximian.com>
+
+ * cal-client/cal-client.h: remove send result enum
+
+ * gui/itip-utils.c (comp_server_send): use the new send_objects
+ routine
+
+2003-09-23 JP Rosevear <jpr@ximian.com>
+
+ * cal-client/cal-client.h: remove send result enum
+
+2003-09-23 JP Rosevear <jpr@ximian.com>
+
+ * cal-client/cal-client.h: remove enum, protos
+
+ * cal-client/cal-client.c: remove remove status enum typing
+
+2003-09-23 Rodrigo Moya <rodrigo@ximian.com>
+
+ * importers/icalendar-importer.c (update_objects): new function
+ to manage the update of components, taking into account
+ VTIMEZONE components.
+ (process_item_fn, gnome_calendar_import_data_fn): use
+ update_objects instead of cal_client_update_objects.
+
+2003-09-23 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal.h: update proto
+
+ * pcs/cal.c (impl_Cal_addTimezone): just call add_timezone, it
+ does the notification
+ (cal_notify_object_created): only notify the query if the object
+ matches
+ (cal_notify_object_removed): ditto
+
+ * pcs/cal-backend.h: update proto, vmethod
+
+ * pcs/cal-backend.c (cal_backend_add_timezone): returns void
+
+ * pcs/cal-backend-sync.h: update proto, vmethod
+
+ * pcs/cal-backend-sync.c (cal_backend_sync_remove_object): add the
+ object as an out param
+ (_cal_backend_remove_object): get the object and pass it in the
+ notification
+
+ * pcs/cal-backend-file.c (cal_backend_file_create_object): kill
+ cal_backend_file_update_objects call, its more efficient to create
+ the comp ourselves; stamp the creation time, add the component to
+ the toplevel
+ (cal_backend_file_modify_object): kill the
+ cal_backend_file_update_objects call, add the component to the
+ toplevel
+ (cal_backend_file_remove_object): pass back the object when
+ removing
+
+2003-09-23 JP Rosevear <jpr@ximian.com>
+
+ * cal-client/cal-query.c (cal_query_finalize): disconnect the
+ signal handlers
+
+ * cal-client/cal-client.c (cal_client_get_query): unref the
+ listener when done
+
+2003-09-23 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-cal-view.c (selection_received): add VTIMEZONE components
+ contained in the clipboard data to the backend.
+
+2003-09-22 JP Rosevear <jpr@ximian.com>
+
+ * gui/dialogs/comp-editor.c (save_comp): modify and create instead
+ of update, simplify mod code
+
+2003-09-22 JP Rosevear <jpr@ximian.com>
+
+ * gui/e-day-view.c (e_day_view_finish_long_event_resize): modify
+ the object instead of update, simplify the instance handling
+ (e_day_view_finish_resize): ditto
+ (e_day_view_on_top_canvas_drag_data_received): ditto
+ (e_day_view_on_main_canvas_drag_data_received): ditto
+
+2003-09-22 Rodrigo Moya <rodrigo@ximian.com>
+
+ * cal-client/cal-client.c (cal_client_get_alarms_in_range): use
+ 'has-alarms' function in the search expression.
+
+ * pcs/cal-backend-object-sexp.c (func_has_alarms): new SExp function.
+
+2003-09-22 JP Rosevear <jpr@ximian.com>
+
+ * gui/e-day-view.c (e_day_view_on_editing_stopped): create the
+ object if its not on the server or modify it if it is
+
+ * gui/e-week-view.c (e_week_view_on_editing_stopped): we return if
+ there is no text and it *not* on the server
+
+2003-09-22 JP Rosevear <jpr@ximian.com>
+
+ * gui/e-week-view.c (e_week_view_on_editing_stopped): create the
+ object if its not on the server or modify it if it is
+
+2003-09-22 JP Rosevear <jpr@ximian.com>
+
+ * gui/gnome-cal.h: remove proto
+
+ * gui/gnome-cal.c: remove gnome_calendar_unrecur_selection
+
+ * gui/e-week-view.h: remove proto
+
+ * gui/e-week-view.c: remove e_week_view_unrecur_appointment
+
+ * gui/e-day-view.h: remove proto
+
+ * gui/e-day-view.c: remove e_day_view_unrecur_appointment
+
+ * gui/e-cal-view.c: remove on_unrecur_appointment (this is handled
+ better via recurrence id's now)
+
+2003-09-22 JP Rosevear <jpr@ximian.com>
+
+ * gui/e-itip-control.c (update_attendee_status): ifdef out, leave
+ temporarily for reference, but otherwise it shouldn't be needed
+ (update_item): switch to using receive objects
+ (ok_clicked_cb): update item when receiving a reply
+
+ * gui/e-calendar-table.c (selection_received): switch to using
+ create object from update_objects
+
+ * gui/e-cal-view.c (selection_received_add_event): util routine to
+ prevent duplication
+ (selection_received): use above
+
+ * gui/e-cal-model.c (ecm_set_value_at): switch to using modify
+ object from update_objects
+ (ecm_append_row): switch to using create object from
+ update_objects
+
+ * gui/e-cal-model-calendar.c (ecmc_set_value_at): switch to using
+ modify object from update_objects
+
+ * gui/e-cal-model-tasks.c (ecmt_set_value_at): ditto
+
2003-09-22 Hans Petter Jansson <hpj@ximian.com>
* cal-util/Makefile.am (libical_util_la_LIBADD):
@@ -121,10 +1083,177 @@
* importers/Makefile.am (libevolution_calendar_importers_la_LIBADD):
libicalvcal.la -> libicalvcal-evolution.la
+
+2003-09-19 Rodrigo Moya <rodrigo@ximian.com>
+
+ * idl/evolution-calendar.idl: removed getAlarmsInRange and
+ getAlarmsForObject methods.
+
+ * pcs/cal.c (impl_Cal_getAlarmsInRange, impl_Cal_getAlarmsForObject):
+ removed unneeded CORBA methods.
+ (cal_class_init): dont set removed methods in the epv.
+
+ * pcs/cal-backend.[ch]: removed get_alarms_in_range and
+ get_alarms_for_object virtual methods.
+ (cal_backend_get_alarms_in_range, cal_backend_get_alarms_for_object):
+ removed.
+ (cal_backend_class_init): dont set removed virtual methods.
+
+ * pcs/cal-backend-file.c (cal_backend_file_get_alarms_in_range,
+ cal_backend_file_get_alarms_for_object): removed.
+ (cal_backend_file_class_init): dont set removed virtual methods.
+
+2003-09-19 Rodrigo Moya <rodrigo@ximian.com>
+
+ * cal-client/cal-client.c (cal_client_get_alarms_in_range): changed
+ to use queries.
+ (build_component_alarms_list): create the alarm list from a list
+ of iCalendar strings.
+ (build_alarm_instance_list): removed.
+ (cal_client_get_alarms_for_object): dont call the CORBA methods,
+ just get alarms by itself.
+
+2003-09-18 Rodrigo Moya <rodrigo@ximian.com>
+
+ * cal-client/cal-listener.[ch]: added "add_timezone" signal.
+ (impl_notifyTimezoneAdded): implemented new CalListener method.
+ (cal_listener_class_init): create "add_timezone" signal for the class.
+
+ * cal-client/cal-client.[ch] (cal_client_add_timezone): new function.
+ (cal_client_init): connect to "add_timezone" signal on the
+ CalListener.
+ (cal_add_timezone_cb): callback for the "add_timezone" signal.
+
+2003-09-18 Rodrigo Moya <rodrigo@ximian.com>
+
+ * idl/evolution-calendar.idl: added 'notifyTimezoneAdded' method
+ to the Calendar::Listener interface.
+
+ * pcs/cal-backend-sync.[ch] (cal_backend_sync_add_timezone):
+ (_cal_backend_add_timezone): new functions for the new virtual
+ method implementation.
+
+ * pcs/cal.[ch] (cal_notify_timezone_added): new function.
+
+ * pcs/cal-backend-file.c (cal_backend_add_timezone): converted to
+ return a CalBackendSyncStatus.
+ (cal_backend_file_class_init): the 'add_timezone' method we implement
+ is the one in the CalBackendSync class.
+ (cancel_receive_object): added missing 'return'.
+ (free_cal_component): removed unused function.
+
+2003-09-17 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/cal-backend-file.c (cal_backend_add_timezone): added new
+ virtual method implementation.
+
+ * pcs/cal.c (impl_Cal_addTimezone): check return value from
+ cal_backend_add_timezone, and set an exception if an error is
+ returned.
+
+2003-09-16 Rodrigo Moya <rodrigo@ximian.com>
+
+ * idl/evolution-calendar.idl: added addTimezone method.
+
+ * pcs/cal.c (impl_Cal_addTimezone): implemented new method.
+ (cal_class_init): set new method on the epv.
+
+ * pcs/cal-backend.[ch]: added 'add_timezone' virtual method.
+ (cal_backend_add_timezone): implemented new virtual method.
+
+ * pcs/cal-backend-file.c (cal_backend_file_modify_object): it's
+ cal_component_get_as_string, not cal_component_as_string.
+
+ * cal-client/cal-client.c (cal_client_ensure_timezone_on_server):
+ dont use anymore updateObjects method, use addTimezone instead.
+
2003-09-16 Rodrigo Moya <rodrigo@ximian.com>
* conduits/todo/Makefile.am: removed libwombat reference.
+2003-09-15 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/cal-backend-file.c (cal_backend_file_create_object): return
+ the UID of the added object.
+ (cal_backend_file_remove_object): ditto for old_object.
+
+2003-09-15 JP Rosevear <jpr@ximian.com>
+
+ * conduits/todo/todo-conduit.c (replace_record): switch to modify
+ object
+ (add_record): switch to using create object
+
+ * conduits/calendar/calendar-conduit.c (process_multi_day): switch
+ to using create object
+ (add_record): switch to using create object
+ (replace_record): switch to modify object
+
+ * cal-client/cal-listener.h: add signals
+
+ * cal-client/cal-listener.c (impl_notifyObjectsReceived):
+ implement listener method
+ (build_object_list): ditto
+ (cal_listener_class_init): create receive_objects and send_objects
+ signals
+
+ * cal-client/cal-client.h: add, update protos
+
+ * cal-client/cal-client.c (cal_objects_received_cb):
+ receive_objects callback
+ (cal_objects_sent_cb): send_objects callback
+ (cal_client_init): listen for above signals
+ (cal_client_create_object): pass back uid
+ (cal_client_receive_objects): implement
+ (cal_client_send_objects): ditto
+
+ * idl/evolution-calendar.idl: add receive/send objects methods and
+ yank updateObjects
+
+ * pcs/cal.h: add protos
+
+ * pcs/cal.c (impl_Cal_receiveObjects): implement
+ (impl_Cal_sendObjects): ditto
+ (cal_class_init): add epv methods
+ (cal_notify_objects_received): notify of objects received call,
+ updating queries
+ (cal_notify_objects_sent): notify of objects sent
+
+ * pcs/cal-backend.h: remove proto
+
+ * pcs/cal-backend.c (cal_backend_class_init): remove obj_updated
+ signal
+ (cal_backend_class_init): init vmethods properly
+ (cal_backend_receive_objects): call through
+ (cal_backend_send_objects): ditto
+
+ * pcs/cal-backend-sync.h: add protos, vmethods
+
+ * pcs/cal-backend-sync.c (cal_backend_sync_receive_objects): call
+ through
+ (cal_backend_sync_send_objects): ditto
+ (_cal_backend_receive_objects): call backend method and notify
+ (_cal_backend_send_objects): ditto
+ (cal_backend_sync_class_init): override send/receive object
+ vmethods
+
+ * pcs/cal-backend-file.c (cal_backend_file_class_init): set
+ remove/send objects sync vmethods
+ (cal_backend_file_create_object): remove call to dead method
+ (cal_backend_file_remove_object): ditto
+ (cal_backend_file_modify_object): ditto
+ (cancel_received_object): cancel an object
+ (check_tzids): check we have all the tzid's for the object
+ (cal_backend_file_receive_objects): receive a bunch of objects via
+ itip
+ (cal_backend_file_send_objects): skeleton implementation
+
+2003-09-15 Rodrigo Moya <rodrigo@ximian.com>
+
+ * idl/evolution-calendar.idl: added InvalidObject CallStatus.
+
+ * pcs/cal-backend-file.c (cal_backend_file_create_object): implemented.
+ (cal_backend_file_modify_object): implemented.
+
2003-09-15 Harry Lu <harry.lu@sun.com>
* gui/apps_evolution_calendar.schemas: change last_notification_time's
@@ -137,6 +1266,219 @@
(e_week_view_jump_to_button_item): new function, jump to the day view.
(e_week_view_is_jump_button_visible): new function.
+
+2003-09-12 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/cal.c (cal_notify_cal_address, cal_notify_alarm_email_address,
+ cal_notify_ldap_attribute, cal_notify_static_capability):
+ make sure we always notify listeners, regardless of whether the
+ string is empty or not.
+
+ * cal-client/cal-client.c (check_capability): guard against using
+ NULL strings with strstr.
+
+2003-09-12 JP Rosevear <jpr@ximian.com>
+
+ * cal-client/client-test.c (cal_opened_cb): listen for other query
+ signals
+
+ * cal-client/cal-listener.h: add signals
+
+ * cal-client/cal-listener.c (impl_notifyObjectCreated): implement
+ (impl_notifyObjectModified): implement
+ (cal_listener_class_init): assign epv implementations
+ (cal_listener_class_init): add create/modify object signals
+
+ * cal-client/cal-client.h: add protos
+
+ * cal-client/cal-client.c (cal_object_created_cb): object created
+ callback
+ (cal_object_modified_cb): object modified callback
+ (cal_client_init): listen for create/modify object signals from
+ the listener
+ (cal_client_create_object): call the create object method
+ (cal_client_modify_object): call the modify object method
+
+ * cal-client/client-test.c (cal_opened_cb): listen for all the
+ query signals, tidy
+
+2003-09-12 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal.c (impl_Cal_createObject): implement
+ (impl_Cal_modifyObject): ditto
+ (cal_class_init): set epv methods for create/modify
+
+ * pcs/cal-backend.h: add protos, vmethod
+
+ * pcs/cal-backend.c (cal_backend_class_init): init new vmethods
+ (cal_backend_create_object): call through
+ (cal_backend_modify_object): ditto
+
+ * pcs/cal-backend-sync.h: add protos, vmethods
+
+ * pcs/cal-backend-sync.c (cal_backend_sync_create_object): call
+ through
+ (cal_backend_sync_modify_object): ditto
+ (_cal_backend_create_object): create object and notify
+ (_cal_backend_modify_object): modify object and notify
+
+ * pcs/cal-backend-file.c (cal_backend_file_create_object):
+ skeleton routine for creating objects
+ (cal_backend_file_modify_object): ditto for modifying
+
+ * idl/evolution-calendar.idl: add createObject and modifyObject
+ calls
+
+2003-09-12 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal.c (cal_notify_object_removed): its uid, not uids
+
+2003-09-12 JP Rosevear <jpr@ximian.com>
+
+ * pcs/query.h: add protos
+
+ * pcs/query.c (query_object_matches): use the sexp to check for a
+ match
+ (query_notify_objects_added_1): notify of one object added to
+ query
+ (query_notify_objects_modified_1): ditto for modification
+ (query_notify_objects_removed_1): ditto for removal
+
+ * pcs/cal.h: add protos
+
+ * pcs/cal.c (cal_notify_object_created): notify of object creation
+ (cal_notify_object_modified): notify of object modification
+ (cal_notify_object_removed): use the _1 routines
+
+ * pcs/cal-backend-file.c (match_recurrence_sexp): this returns a
+ boolean
+ (cal_backend_file_update_objects): don't signal removals here now
+
+ * idl/evolution-calendar.idl: add object created and modified
+ responses
+
+
+2003-09-11 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal.h: update proto
+
+ * pcs/cal.c (cal_notify_object_removed): notify relevant queries
+ of removal
+
+ * pcs/cal-backend.c (cal_backend_get_queries): ref the list before
+ passing it back
+
+ * pcs/cal-backend-sync.c (_cal_backend_remove_object): pass uid to
+ notification
+
+2003-09-11 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal-backend-file.c (match_recurrence_sexp): don't unref the
+ component
+
+ * cal-client/client-test.c (cal_opened_cb): listen to objects
+ added signal
+ (objects_added_cb): print the object uid
+
+2003-09-11 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal-backend-object-sexp.c (cal_backend_object_sexp_text):
+ return the base text
+
+2003-09-11 JP Rosevear <jpr@ximian.com>
+
+ * gui/gnome-cal.c (update_query): fix c/p typo
+
+2003-09-11 JP Rosevear <jpr@ximian.com>
+
+ * gui/gnome-cal.c (update_query): start the query
+
+ * gui/e-cal-model.c (update_query_for_client): ditto
+
+ * cal-client/client-test.c (cal_opened_cb): ditto
+
+2003-09-11 JP Rosevear <jpr@ximian.com>
+
+ * cal-client/cal-query.h: add proto
+
+ * cal-client/cal-query.c (cal_query_start): start the query
+
+2003-09-11 JP Rosevear <jpr@ximian.com>
+
+ * gui/dialogs/delete-error.c (delete_error_dialog): accept GError
+ and base error messages on that
+
+ * gui/dialogs/delete-error.h: update proto
+
+ * gui/e-tasks.c (e_tasks_delete_completed): pass extra param to
+ cal_client_remove_object
+
+ * conduits/todo/todo-conduit.c (delete_record): ditto
+
+ * conduits/calendar/calendar-conduit.c (process_multi_day): ditto
+ (delete_record): ditto
+
+ * gui/gnome-cal.c (gnome_calendar_purge): ditto
+
+ * gui/dialogs/comp-editor.c (delete_comp): ditto
+
+ * gui/e-cal-view.c (e_cal_view_cut_clipboard): pass the error to
+ delete_error_dialog
+ (delete_event): ditto
+ (e_cal_view_delete_selected_occurrence): ditto
+
+ * gui/e-itip-control.c (remove_item): ditto
+
+ * gui/e-calendar-table.c (delete_selected_components): ditto
+
+ * cal-client/cal-listener.h: add signal
+
+ * cal-client/cal-listener.c (impl_notifyObjectRemoved): implement
+ (cal_listener_class_init): set object removed implementation and
+ create signal
+
+ * cal-client/cal-client.h: update protos
+
+ * cal-client/cal-client.c (cal_object_removed_cb): object removal
+ callback
+ (cal_client_init): listen for object removal signal
+ (cal_client_remove_object_with_mod): make call synchronous
+ (cal_client_remove_object): pass new params
+
+ * pcs/cal.h: add proto
+
+ * pcs/cal.c (impl_Cal_removeObject): just call the backend
+ function
+ (cal_notify_object_removed): notify of removal
+
+ * pcs/cal-backend.h: remove and update protos, remove signal
+
+ * pcs/cal-backend.c (cal_backend_class_init): kill obj_removed
+ signal
+ (cal_backend_remove_object): there is no return value now
+
+ * pcs/cal-backend-sync.h: add vmethod, proto
+
+ * pcs/cal-backend-sync.c (cal_backend_sync_remove_object): call
+ through
+ (_cal_backend_remove_object): remove the object and then do the
+ notification
+
+ * pcs/cal-backend-file.c (cal_backend_file_class_init): remove
+ object is not part of the sync class
+ (cal_backend_file_update_objects): there is no more removed signal
+ (cal_backend_file_remove_object): return sync status codes
+
+ * idl/evolution-calendar.idl: make removeObject oneway and and a
+ notification method in the listener
+
+2003-09-11 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/query.[ch] (query_get_text): new function.
+ (query_get_object_sexp): new function.
+
+ * pcs/cal-backend-file.c (cal_backend_file_start_query): implemented.
+
2003-09-11 Hans Petter Jansson <hpj@ximian.com>
* cal-util/Makefile.am (libcal_util_la_LIBADD):
@@ -193,12 +1535,279 @@
Statically link with wombat. Fix ETodo conduit.
(Mdk bug #5348)
+
+2003-09-10 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal.h: update proto
+
+ * pcs/cal.c (impl_Cal_getObjectList): just call the backend, it
+ will do the notification now
+ (cal_notify_object_list): the list is a list of strings
+
+ * pcs/cal-backend.h: update vmethod, proto
+
+ * pcs/cal-backend.c (cal_backend_get_object_list): call through
+
+ * pcs/cal-backend-sync.h: add proto, vmethod
+
+ * pcs/cal-backend-sync.c (cal_backend_sync_get_object_list): call
+ through
+ (_cal_backend_get_object_list): get the list of objects from the
+ sync backend and do the notification
+ (cal_backend_sync_class_init): set vmethod implementation
+
+ * pcs/cal-backend-file.c (cal_backend_file_class_init): the get
+ object list call is now part of the sync backend
+ (cal_backend_file_get_object_list): return a status and put the
+ object list in the passed in param
+
+2003-09-10 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal-backend.c (cal_backend_finalize): unref the elist
+ (cal_backend_init): init the query elist
+
+2003-09-10 JP Rosevear <jpr@ximian.com>
+
+ * gui/gnome-cal.c (dn_query_objects_added_cb): match new query
+ signals - just tag here
+ (dn_query_objects_modified_cb): always retag
+ (dn_query_objects_removed_cb): ditto
+ (update_query): connect to new signals
+ (gnome_calendar_destroy): we don't keep a list of expunging
+ queries
+ (gnome_calendar_purge): no need to do the
+ expunge async, just get the object list immediately
+
+ * gui/e-tasks.c (e_tasks_delete_completed): no need to do the
+ expunge async, just get the object list immediately
+
+ * gui/e-cal-model.c (query_objects_added_cb): callback for objects
+ added to the query
+ (query_objects_modified_cb): ditto for modifications
+ (query_objects_removed_cb): ditto for removed
+ (query_progress_cb): progress of the query
+ (query_done_cb): query is done
+ (update_query_for_client): connect to the new signals
+
+ * cal-client/client-test.c (cal_opened_cb): run a query
+
+ * cal-client/cal-query.c: we are given the listener now - listen
+ for signals from the listener and emit signals matching the api
+ changes
+
+ * cal-client/query-listener.[hc]: rewrite to match new query
+ listener methods and emit signals rather than using function
+ callbacks
+
+ * cal-client/cal-marshal.list: add to marshallers
+
+ * cal-client/cal-listener.h: add query signal
+
+ * cal-client/cal-listener.c (impl_notifyQuery): implement
+ (cal_listener_class_init): set notifyQuery method
+ (cal_listener_class_init): add query signal
+
+ * cal-client/cal-client.h: update protos
+
+ * cal-client/cal-client.c (cal_query_cb): handle response to
+ getQuery
+ (cal_client_init): listen for query signal
+ (cal_client_get_query): get a query from the calendar
+
+ * pcs/query.h: update protos
+
+ * pcs/query.c: rewrite to implement the query start method and
+ provide notification calls
+
+ * pcs/cal.h: add proto
+
+ * pcs/cal.c (impl_Cal_getQuery): re-implement so the backend
+ doesn't create the query for us
+ (cal_notify_query): respond with the query
+
+ * pcs/cal-factory.c: re-order includes
+
+ * pcs/cal-common.h: add types
+
+ * pcs/cal-backend.h: update protos, vmethods
+
+ * pcs/cal-backend.c (cal_backend_class_init): init start_query
+ vmethod
+ (cal_backend_finalize): free mutex
+ (cal_backend_start_query): call through
+ (cal_backend_add_query): add a query to the list the backend is
+ running
+ (cal_backend_get_queries): get the query list
+
+ * pcs/cal-backend-object-sexp.h: add proto
+
+ * pcs/cal-backend-file.c (cal_backend_file_start_query): skeleton
+ for new backend implementation
+
+ * pcs/Makefile.am: don't build dead files
+
+ * idl/evolution-calendar.idl: make the getQuery call async, make
+ the query listener calls oneway and match the addressbook
+
+2003-09-09 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/cal-backend-file.c (cal_backend_file_get_object_component):
+ added case for getting the individual recurrences if 'rid' is
+ not NULL,
+
+2003-09-09 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/cal-backend-file.c (match_object_sexp): expand recurrences
+ for recurrent objects.
+ (match_recurrence_sexp): add the recurrences that match the query
+ expression to the object list.
+
+2003-09-08 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/cal-backend-file.c: don't store all recurrences in the
+ private structure.
+
+2003-09-04 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-day-view.c (process_component):
+ * gui/e-week-view.c (process_component): dont expand recurrences,
+ since they are now expanded by the backends.
+
+2003-09-02 JP Rosevear <jpr@ximian.com>
+
+ * gui/tasks-control.c (sensitize_commands): adapt to cal-client
+ threaded sync api changes
+
+ * gui/itip-utils.c (itip_organizer_is_user): ditto
+
+ * gui/gnome-cal.c (gnome_calendar_purge): ditto
+
+ * gui/e-meeting-model.c (process_section): ditto
+
+ * gui/e-calendar-table.c (e_calendar_table_show_popup_menu): ditto
+
+ * gui/e-cal-view.c (e_cal_view_create_popup_menu): ditto
+
+ * gui/calendar-commands.c (sensitize_calendar_commands): ditto
+ (sensitize_taskpad_commands): ditto
+
+ * gui/dialogs/task-editor.c (set_menu_sens): ditto
+
+ * gui/dialogs/meeting-page.c (meeting_page_construct): ditto
+
+ * gui/dialogs/event-editor.c (set_menu_sens): ditto
+
+ * gui/dialogs/alarm-page.c (add_clicked_cb): ditto
+
+ * conduits/calendar/calendar-conduit.c (pre_sync): convert to
+ cal_client api changes
+
+ * conduits/todo/todo-conduit.c (pre_sync): ditto
+
+ * cal-client/client-test.c (list_uids): match new error handling
+
+ * cal-client/cal-marshal.list: marshallers
+
+ * cal-client/cal-listener.[hc]: emit signals for corba listener
+ callbacks - start with is_read_only, get_static_capabilities,
+ get_cal_address, get_ldap_attribute, open, remove and object_list
+
+ * cal-client/cal-client.h: move the status enum away from here,
+ update protos to new thread sync api standard
+
+ * cal-client/cal-client.c: the listener emits signals instead of
+ using callback functions now and we return booleans + GError in
+ outs for results
+ (e_calendar_error_quark): for GError handling
+ (cal_read_only_cb): handle listener op callback
+ (cal_cal_address_cb): ditto
+ (cal_alarm_address_cb): ditto
+ (cal_ldap_attribute_cb): ditto
+ (cal_static_capabilities_cb): ditto
+ (cal_opened_cb): ditto
+ (cal_removed_cb): ditto
+ (cal_object_list_cb): ditto
+
+ * cal-client/cal-client-types.h: add GError stuff
+
+ * cal-client/Makefile.am: build glib marshal stuff
+
+ * pcs/query.c (backend_opened_cb): comment out some break
+ temporarily
+
+ * pcs/cal.h: add protos
+
+ * pcs/cal.c (impl_Cal_open): just call the backend method, it will
+ handle the notification
+ (impl_Cal_remove): ditto
+ (impl_Cal_isReadOnly): ditto
+ (impl_Cal_getCalAddress): ditto
+ (impl_Cal_getAlarmEmailAddress): ditto
+ (impl_Cal_getLdapAttribute): ditto
+ (impl_Cal_getStaticCapabilities): ditto
+ (impl_Cal_getObjectList): simplify
+ (cal_new): set poa to be threaded
+ (cal_notify_read_only): notification utils
+ (cal_notify_cal_address): ditto
+ (cal_notify_alarm_email_address): ditto
+ (cal_notify_ldap_attribute): ditto
+ (cal_notify_static_capabilities): ditto
+ (cal_notify_open): ditto
+ (cal_notify_remove): ditto
+ (cal_notify_object_list): ditto
+
+ * pcs/cal-factory.c (impl_CalFactory_getCal): dup the key and the
+ object
+ (cal_factory_new): set poa to be threaded
+
+ * pcs/cal-backend.h: update vmethods and protos
+
+ * pcs/cal-backend.c (cal_backend_get_cal_address): we no longer
+ return anything - the callee is responsible for notification
+ (cal_backend_get_alarm_email_address): ditto
+ (cal_backend_get_ldap_attribute): ditto
+ (cal_backend_get_static_capabilities): ditto
+ (cal_backend_open): ditto
+ (cal_backend_remove): ditto
+
+ * pcs/cal-backend-file.h: update inheritance
+
+ * pcs/cal-backend-file.c: inherit from CalBackendSync and make
+ is_read_only, get_static_capabilities, get_cal_address, get_ldap_attribute, open and
+ remove match
+
+ * pcs/Makefile.am: build new files
+
+2003-09-02 JP Rosevear <jpr@ximian.com>
+
+ * idl/evolution-calendar.idl: make all listener callbacks one ways
+
+2003-09-02 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/cal-backend-file.c (match_recurrence_sexp, match_object_sexp):
+ new callbacks for g_hash_table_foreach in get_object_list.
+ (cal_backend_file_get_object_list): don't use the priv->comp list
+ to check the components, use the hash table, which contains all
+ the recurrences already expanded.
+ (add_component): only expand recurrences for recurrent components.
+
2003-09-01 Andrew Wu <Yang.Wu@sun.com>
- * gui/e-day-view.c:
- (e_day_view_change_event_end_time_up):
- (e_day_view_change_event_end_time_down):
- Use "ctrl+shift+alt+Up/Down" to change the end time of the editing event.
+ * gui/e-day-view.c:
+ (e_day_view_change_event_end_time_up):
+ (e_day_view_change_event_end_time_down): Use
+ "ctrl+shift+alt+Up/Down" to change the end time of the editing
+ event.
+
+2003-08-29 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/cal-backend-file.c (lookup_component): take into account the 'rid'
+ argument.
+ (get_rid_string): new function to convert the recurrence ID to string.
+ (add_recurrence_to_object): callback for cal_recur_generate_instances.
+ (add_component): expand recurrences and g_strdup the hash's key.
+ (free_cal_component): free also the hash's key.
+
2003-08-28 Hans Petter Jansson <hpj@ximian.com>
* gui/alarm-notify/alarm-queue.c (tray_icon_blink_cb)
@@ -243,6 +1852,72 @@
* gui/alarm-notify/alarm-notify.c (AlarmNotify_removeCalendar): set
the initial value of lc_ptr and orig_str_ptr to NULL to avoid crash.
+
+2003-08-26 Rodrigo Moya <rodrigo@ximian.com>
+
+ * idl/evolution-calendar.idl: QueryListener::notifyObjUpdated now gets
+ a sequence of CalObj's.
+
+ * pcs/query.c (add_component): send the whole object to the listener,
+ not just the UID. Improved the way the listeners are notified, by allocating
+ a CORBA sequence to be used for all listeners, not one for each.
+ (match_component): pass the CalComponent to add_component, not only the UID.
+ (start_cached_query_cb): send the whole object to the listener.
+
+ * cal-client/cal-query.[ch]: changed argument names for "obj_updated"
+ signal.
+ (obj_updated_cb): pass the calobj's, not uid's.
+
+ * gui/e-tasks.c (query_obj_updated_cb):
+ * gui/gnome-cal.c (dn_query_obj_updated_cb, purging_obj_updated_cb):
+ * gui/e-cal-model.c (query_obj_updated_cb): we now get the object's
+ string representation instead of the UID.
+
+2003-08-25 Rodrigo Moya <rodrigo@ximian.com>
+
+ * cal-client/cal-client.c (cal_client_get_object): added a 'rid' argument
+ to match the IDL method.
+
+ * conduits/calendar/calendar-conduit.c (local_record_from_uid):
+ * conduits/todo/todo-conduit.c (local_record_from_uid):
+ * gui/comp-editor-factory.c (edit_existing):
+ * gui/comp-util.c (cal_comp_is_on_server):
+ * gui/e-cal-model.c (query_obj_updated_cb):
+ * gui/e-itip-control.c (find_server, get_real_item, update_attendee_status):
+ * gui/gnome-cal.c (dn_query_obj_updated_cb, purging_obj_updated_cb):
+ * gui/dialogs/comp-editor.c (obj_updated_cb): adapted to changes in
+ cal_client_get_object().
+
+2003-08-23 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/query-backend.c (object_updated_cb):
+ * pcs/cal-backend.c (cal_backend_get_type_by_uid): use 'rid' parameter
+ where appropriate.
+
+ * pcs/cal-backend-file.c (check_dup_uid): removed unused variables.
+ (cal_backend_file_compute_changes_foreach_key): pass a NULL 'rid'
+ to cal_backend_get_object().
+ (lookup_component): get a 'rid' argument also.
+ (cal_backend_file_cancel_object, cal_backend_file_remove_object):
+ pass correct number of parameters to lookup_component().
+
+2003-08-22 Rodrigo Moya <rodrigo@ximian.com>
+
+ * idl/evolution-calendar.idl: use UID/RID pairs to identify objects.
+
+ * pcs/cal.c (impl_Cal_getObject): added 'rid' parameter.
+
+ * pcs/cal-backend.c (cal_backend_get_object): added 'rid' parameter.
+ (cal_backend_get_object_component): ditto.
+ (get_object): ditto.
+
+ * pcs/cal-backend-file.c (cal_backend_file_get_object_component):
+ added 'rid' parameter.
+ (lookup_component): added 'rid' parameter and made it search for the
+ recurrence when that parameter is not NULL.
+ (cal_backend_file_get_alarms_for_object, cal_backend_file_update_object):
+ adapted to changes in lookup_component().
+
2003-08-22 Frederic Crozat <fcrozat@mandrakesoft.com>
* gui/alarm-notify/notify-main.c: (main):
@@ -300,6 +1975,111 @@
(gnome_calendar_get_search_bar_widget),
(gnome_calendar_get_view_notebook_widget): new functions
+
+2003-08-20 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/query-backend.c (foreach_uid_cb): use the icalcomponent
+ to call icalcomponent_get_uid, not the string.
+
+2003-08-20 Rodrigo Moya <rodrigo@ximian.com>
+
+ * pcs/cal-backend-file.c: store objects by UID and RID.
+ (free_object): new function to free the CalBackendFileObject structure.
+ (cal_backend_file_dispose): use free_object callback to remove the
+ objects in the comp_uid_hash.
+ (lookup_component): search correctly the component in the new hash
+ table organizarion.
+ (check_dup_uid): ditto.
+ (add_component): ditto.
+ (remove_component): ditto.
+
+2003-08-19 JP Rosevear <jpr@ximian.com>
+
+ * gui/gnome-cal.c (setup_widgets): set up models here
+ (gnome_calendar_construct): not here
+
+ * conduits/calendar/calendar-conduit.c
+ (e_calendar_context_destroy): we have a list of calcomponents
+ rather than uids now
+ (process_multi_day): build a list of components rather than uids
+ (pre_sync): use get_object_list instead of getting uids
+ (for_each): create local records from calcomponents
+
+ * conduits/todo/todo-conduit.c: as above
+
+ * gui/print.c (instance_cb): mark as true if we found an instance
+ (print_month_small): see if atleast one instance exists in a
+ slight different way
+
+ * cal-client/client-test.c (list_uids): use get_object_list
+
+ * cal-client/cal-listener.h: update protos
+
+ * cal-client/cal-listener.c (cal_listener_class_init): set object
+ list callback implementation
+ (impl_notifyObjectListRequested): implement
+ (cal_listener_construct): take object list callback function
+ (cal_listener_new): ditto
+
+ * cal-client/cal-client.h: update protos, add status
+
+ * cal-client/cal-client.c (e_calendar_new_op): create new op
+ (e_calendar_get_op): retrieve current op
+ (e_calendar_free_op): free the op
+ (e_calendar_remove_op): clear current op
+ (cal_client_init): create new mutex
+ (cal_client_finalize): destroy mutex
+ (build_object_list): build list of icalcomponents
+ (cal_object_list_cb): handle getObjectList response
+ (real_open_calendar): pass extra listener arg
+ (cal_client_get_object_list): implement using thread safe mutex
+ locking
+ (cal_client_get_object_list_as_comp): return calcomponents instead
+ of icalcomponents
+ (cal_client_generate_instances): just get the object list - no
+ need to make it atomic since get_object_list is already atomic
+
+ * pcs/query.c (query_finalize): free new sexp class
+ (parse_sexp): use new sexp class
+ (match_component): ditto
+
+ * pcs/query-backend.c (foreach_uid_cb): use icalcomponent to
+ extract uid
+ (query_backend_new): get all objects using object list call
+
+ * pcs/cal.c (impl_Cal_getObjectList): implement
+ (cal_class_init): adjust for idl method changes
+
+ * pcs/cal-backend.h: update vmethods, add proto
+
+ * pcs/cal-backend.c (cal_backend_class_init): remove get_uids and
+ get_objects_in_range vmethods, add get_object_list vmethod
+ (cal_backend_get_object_list): call through to vmethod implementation
+
+ * pcs/cal-backend-object-sexp.[hc]: nice class to represent a sexp
+ and search cal components
+
+ * pcs/cal-backend-file.c (cal_backend_file_class_init): remove
+ get_uids and get_objects_in_range calls and set get_object_list
+ call
+ (cal_backend_file_get_object_list): implement
+ (create_user_free_busy): use sexp ops to implement
+ (cal_backend_file_compute_changes): just iterate over the
+ component list rather than fetching uids
+
+ * pcs/Makefile.am: build new files
+
+ * idl/evolution-calendar.idl: make opening a oneway call, add
+ getObjectList call, remove getUIDS and getObjectsInRange call -
+ both can be done with getObjectList; make listener callbacks
+ oneway
+
+2003-08-19 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/gnome-cal.c (gnome_calendar_purge): don't leak the client list.
+ (gnome_calendar_destroy): disconnect from all callbacks on all
+ loaded clients.
+
2003-08-19 Rodrigo Moya <rodrigo@ximian.com>
* gui/e-cal-model-tasks.c (ecmt_get_color_for_component): use
@@ -321,6 +2101,51 @@
* gui/e-week-view.c (e_week_view_add_event, e_week_view_do_key_press):
same as e-day-view.c
+2003-08-18 Ettore Perazzoli <ettore@ximian.com>
+
+ * gui/calendar-component.c (impl_createControls): Oops, pass
+ [NULL, NULL] to gtk_scrolled_window_new().
+
+2003-08-18 Ettore Perazzoli <ettore@ximian.com>
+
+ * gui/main.c (factory): Ref the object from
+ calendar_component_peek() before returning it.
+
+2003-08-17 Ettore Perazzoli <ettore@ximian.com>
+
+ * gui/control-factory.h: #include <bonobo/bonobo-control.h>.
+
+ * gui/Makefile.am (libevolution_calendar_la_LIBADD): Link to
+ libeutil.
+
+ * gui/e-calendar-table.c (e_calendar_table_set_status_message):
+ Don't use the global_shell_client.
+
+ * gui/main.c (factory): Call calendar_component_peek() for the
+ GNOME_Evolution_Calendar_Component OAFIID.
+
+ * gui/GNOME_Evolution_Calendar.server.in.in: Set up the
+ GNOME_Evolution_Calendar_Component server and rename
+ GNOME_Evolution_Calendar_Factory to
+ GNOME_Evolution_Calendar_Factory_2.
+ * gui/main.c: Updated IDs accordingly.
+
+ * gui/e-meeting-time-sel.c (e_meeting_time_selector_construct):
+ Use calendar_component_peek_config_directory() instead of
+ evolution_dir.
+ * gui/gnome-cal.c (setup_widgets): Likewise.
+ (gnome_calendar_destroy): Likewise.
+ * gui/dialogs/meeting-page.c (meeting_page_construct): Likewise.
+
+ * gui/gnome-cal.c (gnome_calendar_open): #if 0 some code for
+ figuring out where the task list is.
+
+ * gui/calendar-component.c: New file.
+ * gui/calendar-component.h: New file.
+
+ * gui/itip-utils.c (itip_addresses_get): Unref the GConf client
+ from gconf_client_get_default.
+
2003-08-15 Rodrigo Moya <rodrigo@ximian.com>
* gui/e-cal-model.c (ecm_get_color_for_component): use tigert's
@@ -341,16 +2166,6 @@
2003-08-14 Rodrigo Moya <rodrigo@ximian.com>
- * gui/e-cal-model.c (e_cal_model_create_component_with_defaults):
- use the default client to call cal_comp_*_new_with_defaults, and
- if no client is available, just create an empty icalcomponent.
-
- * gui/e-cal-view.c (e_cal_view_init): create an empty model.
-
- * gui/e-week-view.c (e_week_view_add_event): use the event's client.
-
-2003-08-14 Rodrigo Moya <rodrigo@ximian.com>
-
* gui/e-cal-model.[ch] (e_cal_model_free_component_data): new
function.
@@ -367,6 +2182,46 @@
e_week_view_update_event_cb, e_week_view_remove_event_cb,
e_week_view_free_events): same as EDayView.
+2003-08-14 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-cal-model.c (e_cal_model_create_component_with_defaults):
+ use the default client to call cal_comp_*_new_with_defaults, and
+ if no client is available, just create an empty icalcomponent.
+
+ * gui/e-cal-view.c (e_cal_view_init): create an empty model.
+
+ * gui/e-week-view.c (e_week_view_add_event): use the event's client.
+
+2003-08-13 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/gnome-cal.c (gnome_calendar_open): unref the client if there
+ is an error.
+ (update_query): set status bar messages for progress.
+ (update_query_timeout): re-enabled.
+ (client_cal_opened_cb): install timeout handler for the query updates.
+
+ * gui/e-cal-view.c (e_cal_view_set_model): connect to all appropriate
+ signals on the model, to be called for every change.
+ (model_row_changed_cb, model_rows_changed_cb): new model callbacks.
+
+ * gui/e-week-view-event-item.c (e_week_view_event_item_draw): colorize
+ the background for multiple days events.
+
+2003-08-13 Rodrigo Moya <rodrigo@ximian.com>
+
+ * gui/e-cal-model.c (ecm_append_row, ecm_get_color_for_component):
+ * gui/e-cal-model-tasks.c (ecmt_get_color_for_component): merged
+ missing bith from calendar-views-with-model branch.
+
+2003-08-13 JP Rosevear <jpr@ximian.com>
+
+ * cal-client/cal-client.c (real_open_calendar): set the priv->cal
+ pointer in a slightly different spot so we have it in the call
+ back
+
+ * gui/e-cal-model.c (e_cal_model_get_client_list): merge this in
+ properly
+
2003-08-13 Rodrigo Moya <rodrigo@ximian.com>
* gui/e-cal-model.c (ecm_get_color_for_component): assign the colors
@@ -393,7 +2248,170 @@
* gui/e-week-view-event-item.c (e_week_view_event_item_draw): colorize
the background for multiple days events.
+
+2003-08-13 JP Rosevear <jpr@ximian.com>
+
+ * cal-client/client-test.c (create_client): there is no more
+ object updated signal
+
+ * cal-client/cal-listener.c: clean up comment
+
+ * cal-client/cal-client.c (cal_client_class_init): remove
+ obj_updated and obj_removed signals
+
+ * cal-client/cal-client.h: ditto
+
+2003-08-12 JP Rosevear <jpr@ximian.com>
+
+ * pcs/cal-backend.h: remove get_uri vmethod
+
+ * pcs/cal-backend.c (cal_backend_class_init): remove get_uri
+ vmethod init
+
+ * pcs/cal-backend-file.c (cal_backend_file_class_init): no longer
+ a get uri vmethod
+ (cal_backend_file_get_uri): remove implementation of above
+
+2003-08-12 JP Rosevear <jpr@ximian.com>
+
+ * cal-client/client-test.c (main): use tmp uris
+
+ * cal-client/cal-listener.h: update protos
+
+ * cal-client/cal-listener.c (cal_listener_init): init removed
+ function
+ (cal_listener_finalize): clear removed function
+ (impl_notifyCalOpened): take file status
+ (impl_notifyCalRemoved): implement
+ (cal_listener_construct): take remove function arg
+ (cal_listener_new): ditto
+
+ * cal-client/cal-client.h: update protos, add remove status
+
+ * cal-client/cal-client.c
+ (cal_client_remove_status_enum_get_type): add remove status type
+ (cal_client_class_init): add removed signal
+ (cal_opened_cb): can no longer get unsupported exception here
+ (cal_removed_cb): emit removed status
+ (real_open_calendar): pass removed callback function to listener
+ (get_fall_back_uri): no longer append tasks.ics or calendar.ics
+ (cal_client_remove_calendar): new c wrapper for corba function -
+ calendar must be open currently
+
+ * pcs/query.c (backend_opened_cb): only disconnect the open
+ callback
+ (backend_removed_cb): handle calendar removal
+ (query_construct): listen for remove signal as well
+
+ * pcs/cal.h: cal no longer takes uri during construction
+
+ * pcs/cal.c (backend_to_listener_status): convert backend to corba
+ status code
+ (impl_Cal_open): backend open no longer takes uri, use above to
+ send back status
+ (impl_Cal_remove): implement
+ (cal_construct): we no longer track the uri
+ (cal_finalize): ditto
+ (cal_class_init): set remove epv method
+
+ * pcs/cal-factory.c (impl_CalFactory_getCal): instantiate backend
+ with uri and kind properties
+
+ * pcs/cal-backend.h: list file status enum, add protos
+
+ * pcs/cal-backend.c (cal_backend_set_property): implement object
+ properties
+ (cal_backend_get_property): ditto
+ (cal_backend_class_init): add properties vmethods and uri, kind
+ properties, removed signal
+ (cal_backend_get_uri): don't get the uri from the backend
+ (cal_backend_get_kind): get the kind from the backend
+ (cal_backend_open): adapt to new open call, no uri passed in
+ (cal_backend_remove): call through to remove implementation
+ (cal_backend_opened): use new file status
+ (cal_backend_removed): emit removed signal
+
+ * pcs/cal-backend-file.h: update protos
+
+ * pcs/cal-backend-file.c (cal_backend_file_class_init): override
+ remove vmethod
+ (cal_backend_file_init): default file name to calendar.ics
+ (cal_backend_file_set_file_name): accessor for filename tacked on
+ to uri
+ (cal_backend_file_get_file_name): ditto
+ (open_cal): return "file" type status codes
+ (create_cal): ditto
+ (get_uri_string): construct the full uri string
+ (cal_backend_file_open): use above
+ (cal_backend_file_remove): implement
+
+ * pcs/cal-backend-file-todos.c (cal_backend_file_todos_init): set
+ the file name to tasks.ics
+
+ * pcs/cal-backend-file-events.c (cal_backend_file_events_init):
+ set the file name to calendar.ics
+
+ * cal-util/cal-util.c (cal_util_expand_uri): just return a copy of
+ the uri now
+
+ * idl/evolution-calendar.idl: convert OpenStatus to FileStatus so
+ remove() can use it as well
+
+ * gui/gnome-cal.c (gnome_calendar_open): just open the default
+ folder in all cases
+
+2003-08-12 Rodrigo Moya <rodrigo@ximian.com>
+
+ * cal-util/cal-util.[ch] (cal_util_component_has_alarms): new function.
+
+ * gui/gnome-cal.[ch]:
+ * gui/goto.c:
+ * gui/itip-bonobo-control.c:
+ * gui/print.c:
+ * gui/e-week-view.[ch]:
+ * gui/e-day-view.[ch]: lots of fixes to make all compile with no
+ warnings.
+
+2003-08-12 Rodrigo Moya <rodrigo@ximian.com>
+ * cal-util/cal-util.[ch] (cal_util_component_has_organizer):
+ new function.
+
+ * gui/e-day-view-main-item.c:
+ * gui/e-day-view-top-item.c:
+ * gui/e-week-view-event-item.c:
+ * gui/e-week-view.c: adaptated to changes in ECalViewEvent.
+
+ * gui/e-cal-model.[ch] (e_cal_model_get_client_list): new function.
+ (ecm_append_row): fixed usage of icalcomponent variable.
+
+ * gui/e-cal-view.c (e_cal_view_class_init): removed unused variable.
+ (selection_received): use default client for pasting from clipboard.
+ (e_cal_view_cut_clipboard): cut the appointment from its client.
+ (e_cal_view_copy_clipboard, delete_event, on_save_as, om_print_event,
+ e_cal_view_delete_selected_occurrence, on_meeting, on_forward,
+ e_cal_view_create_popup_menu): adapted to changes in ECalViewEvent.
+ (e_cal_view_delete_selected_event, e_cal_view_delete_selected_events):
+ pass the ECalViewEvent to delete_event, so that it knows which
+ CalClient to use.
+ (on_edit_appointment): pass CalClient and icalcomponent to
+ gnome_calendar_edit_object.
+ (on_publish): publish F/B info for all the clients currently loaded
+ in the view.
+ (setup_popup_icons): added missing argument to gtk_image_new_from_stock.
+
+ * gui/calendar-commands.c (publish_freebusy_cmd): publish F/B info
+ for all the clients currently loaded in the view.
+ (sensitize_calendar_commands): use icalcomponent functions.
+
+ * gui/e-day-view.c:
+ * gui/comp-editor-factory.c (impl_editExisting):
+ * gui/calendar-offline-handler.c (backend_cal_opened_online):
+ * gui/e-alarm-list.c (e_alarm_list_finalize):
+ * gui/e-cal-model-tasks.c (ecmt_get_color_for_component):
+ * gui/e-date-time-list.c (e_date_time_list_finalize):
+ * gui/control-factory.c (get_prop): fixed warnings.
+
2003-08-12 Hans Petter Jansson <hpj@ximian.com>
* gui/calendar-offline-handler.c (impl_dispose): Chain. Prevent
@@ -799,6 +2817,27 @@
* cal-client/cal-client-multi.[ch]:
* cal-client/Makefile.am: removed obsolete code.
+2003-07-30 Ettore Perazzoli <ettore@ximian.com>
+
+ * gui/main.c (factory): Do not depend on global_shell_client being
+ not NULL for creating the calendar preferences dialog.
+
+ * gui/e-itip-control.c (show_current): Don't call get_servers
+ anymore [to be fixed].
+ (get_servers): #if 0ed out.
+ (object_requested_cb): Don't create the folder selector button.
+
+ * gui/e-cal-view.c (e_cal_view_set_status_message): Don't create
+ an activity client.
+
+ * gui/calendar-model.c (calendar_model_set_status_message): Don't
+ create an activity client.
+
+ * gui/calendar-component.c: Removed global variable
+ global_shell_client.
+ (owner_set_cb): Don't set global_shell_client.
+ (owner_unset_cb): Don't set it here either.
+
2003-07-29 Rodrigo Moya <rodrigo@ximian.com>
Fixes all "alarm daemon doesn't start with session"
diff --git a/calendar/cal-client/.cvsignore b/calendar/cal-client/.cvsignore
index 1537e6e01d..f2aa4f92ae 100644
--- a/calendar/cal-client/.cvsignore
+++ b/calendar/cal-client/.cvsignore
@@ -10,6 +10,8 @@ evolution-calendar.h
evolution-calendar-common.lo
evolution-calendar-skels.lo
evolution-calendar-stubs.lo
+cal-marshal.c
+cal-marshal.h
*.lo
*.la
client-test
diff --git a/calendar/cal-client/Makefile.am b/calendar/cal-client/Makefile.am
index 5e48e7db23..5f8b5a3cf1 100644
--- a/calendar/cal-client/Makefile.am
+++ b/calendar/cal-client/Makefile.am
@@ -38,6 +38,8 @@ libcal_clientincludedir = $(privincludedir)/cal-client
libcal_client_la_SOURCES = \
$(CORBA_GENERATED_C) \
cal-client-types.c \
+ cal-marshal.c \
+ cal--marshal.h \
cal-client.c \
cal-listener.c \
cal-listener.h \
@@ -72,7 +74,10 @@ client_test_LDADD = \
libcal-client.la \
$(EVOLUTION_CALENDAR_LIBS)
-BUILT_SOURCES = $(CORBA_GENERATED)
+MARSHAL_GENERATED = cal-marshal.c cal-marshal.h
+@EVO_MARSHAL_RULE@
+
+BUILT_SOURCES = $(CORBA_GENERATED) $(MARSHAL_GENERATED)
CLEANFILES = $(BUILT_SOURCES)
dist-hook:
diff --git a/calendar/cal-client/cal-client-types.h b/calendar/cal-client/cal-client-types.h
index c160a1fa94..925628337b 100644
--- a/calendar/cal-client/cal-client-types.h
+++ b/calendar/cal-client/cal-client-types.h
@@ -29,6 +29,10 @@ G_BEGIN_DECLS
+#define E_CALENDAR_ERROR e_calendar_error_quark()
+
+GQuark e_calendar_error_quark (void) G_GNUC_CONST;
+
typedef enum {
CAL_CLIENT_CHANGE_ADDED = 1 << 0,
CAL_CLIENT_CHANGE_MODIFIED = 1 << 1,
@@ -41,6 +45,28 @@ typedef struct
CalClientChangeType type;
} CalClientChange;
+typedef enum {
+ E_CALENDAR_STATUS_OK,
+ E_CALENDAR_STATUS_INVALID_ARG,
+ E_CALENDAR_STATUS_BUSY,
+ E_CALENDAR_STATUS_REPOSITORY_OFFLINE,
+ E_CALENDAR_STATUS_NO_SUCH_CALENDAR,
+ E_CALENDAR_STATUS_OBJECT_NOT_FOUND,
+ E_CALENDAR_STATUS_INVALID_OBJECT,
+ E_CALENDAR_STATUS_URI_NOT_LOADED,
+ E_CALENDAR_STATUS_URI_ALREADY_LOADED,
+ E_CALENDAR_STATUS_PERMISSION_DENIED,
+ E_CALENDAR_STATUS_CARD_NOT_FOUND,
+ E_CALENDAR_STATUS_CARD_ID_ALREADY_EXISTS,
+ E_CALENDAR_STATUS_PROTOCOL_NOT_SUPPORTED,
+ E_CALENDAR_STATUS_CANCELLED,
+ E_CALENDAR_STATUS_COULD_NOT_CANCEL,
+ E_CALENDAR_STATUS_AUTHENTICATION_FAILED,
+ E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED,
+ E_CALENDAR_STATUS_CORBA_EXCEPTION,
+ E_CALENDAR_STATUS_OTHER_ERROR
+} ECalendarStatus;
+
void cal_client_change_list_free (GList *list);
G_END_DECLS
diff --git a/calendar/cal-client/cal-client.c b/calendar/cal-client/cal-client.c
index e40d405120..95efdd6d5d 100644
--- a/calendar/cal-client/cal-client.c
+++ b/calendar/cal-client/cal-client.c
@@ -22,20 +22,39 @@
#include <config.h>
#endif
+#include <pthread.h>
#include <string.h>
#include <bonobo-activation/bonobo-activation.h>
#include <bonobo/bonobo-exception.h>
+#include <bonobo/bonobo-i18n.h>
#include <libgnome/gnome-util.h>
#include "e-util/e-component-listener.h"
#include "e-util/e-config-listener.h"
+#include "e-util/e-url.h"
+#include "e-util/e-msgport.h"
#include "cal-util/cal-util-marshal.h"
-#include "cal-client-types.h"
+#include "cal-util/timeutil.h"
#include "cal-client.h"
#include "cal-listener.h"
+#include "query-listener.h"
+typedef struct {
+ EMutex *mutex;
+ pthread_cond_t cond;
+ ECalendarStatus status;
+
+ char *uid;
+ GList *list;
+ gboolean bool;
+ char *string;
+
+ CalQuery *query;
+ QueryListener *listener;
+} ECalendarOp;
+
/* Private part of the CalClient structure */
struct _CalClientPrivate {
/* Load state to avoid multiple loads */
@@ -45,7 +64,12 @@ struct _CalClientPrivate {
* NULL if we are not loaded.
*/
char *uri;
+ CalObjType type;
+
+ ECalendarOp *current_op;
+ EMutex *mutex;
+
/* Email address associated with this calendar, or NULL */
char *cal_address;
char *alarm_email_address;
@@ -85,8 +109,6 @@ struct _CalClientPrivate {
enum {
CAL_OPENED,
CAL_SET_MODE,
- OBJ_UPDATED,
- OBJ_REMOVED,
BACKEND_ERROR,
CATEGORIES_CHANGED,
FORGET_PASSWORD,
@@ -94,10 +116,6 @@ enum {
LAST_SIGNAL
};
-static void cal_client_class_init (CalClientClass *klass);
-static void cal_client_init (CalClient *client, CalClientClass *klass);
-static void cal_client_finalize (GObject *object);
-
static void cal_client_get_object_timezones_cb (icalparameter *param,
void *data);
@@ -105,36 +123,28 @@ static guint cal_client_signals[LAST_SIGNAL];
static GObjectClass *parent_class;
+#define E_CALENDAR_CHECK_STATUS(status,error) G_STMT_START{ \
+ if ((status) == E_CALENDAR_STATUS_OK) { \
+ return TRUE; \
+ } \
+ else { \
+ const char *msg; \
+ msg = cal_client_get_error_message ((status)); \
+ g_set_error ((error), E_CALENDAR_ERROR, (status), msg, (status)); \
+ return FALSE; \
+ } }G_STMT_END
+
-/**
- * cal_client_get_type:
- *
- * Registers the #CalClient class if necessary, and returns the type ID assigned
- * to it.
- *
- * Return value: The type ID of the #CalClient class.
- **/
-GType
-cal_client_get_type (void)
+/* Error quark */
+GQuark
+e_calendar_error_quark (void)
{
- static GType cal_client_type = 0;
-
- if (!cal_client_type) {
- static GTypeInfo info = {
- sizeof (CalClientClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) cal_client_class_init,
- NULL, NULL,
- sizeof (CalClient),
- 0,
- (GInstanceInitFunc) cal_client_init
- };
- cal_client_type = g_type_register_static (G_TYPE_OBJECT, "CalClient", &info, 0);
- }
+ static GQuark q = 0;
+ if (q == 0)
+ q = g_quark_from_static_string ("e-calendar-error-quark");
- return cal_client_type;
+ return q;
}
GType
@@ -198,118 +208,48 @@ cal_mode_enum_get_type (void)
return cal_mode_enum_type;
}
-/* Class initialization function for the calendar client */
-static void
-cal_client_class_init (CalClientClass *klass)
+/* EBookOp calls */
+
+static ECalendarOp*
+e_calendar_new_op (CalClient *client)
{
- GObjectClass *object_class;
+ ECalendarOp *op = g_new0 (ECalendarOp, 1);
- object_class = (GObjectClass *) klass;
+ op->mutex = e_mutex_new (E_MUTEX_SIMPLE);
+ pthread_cond_init (&op->cond, 0);
- parent_class = g_type_class_peek_parent (klass);
-
- cal_client_signals[CAL_OPENED] =
- g_signal_new ("cal_opened",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalClientClass, cal_opened),
- NULL, NULL,
- g_cclosure_marshal_VOID__ENUM,
- G_TYPE_NONE, 1,
- CAL_CLIENT_OPEN_STATUS_ENUM_TYPE);
- cal_client_signals[CAL_SET_MODE] =
- g_signal_new ("cal_set_mode",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalClientClass, cal_set_mode),
- NULL, NULL,
- cal_util_marshal_VOID__ENUM_ENUM,
- G_TYPE_NONE, 2,
- CAL_CLIENT_SET_MODE_STATUS_ENUM_TYPE,
- CAL_MODE_ENUM_TYPE);
- cal_client_signals[OBJ_UPDATED] =
- g_signal_new ("obj_updated",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalClientClass, obj_updated),
- NULL, NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
- cal_client_signals[OBJ_REMOVED] =
- g_signal_new ("obj_removed",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalClientClass, obj_removed),
- NULL, NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
- cal_client_signals[BACKEND_ERROR] =
- g_signal_new ("backend_error",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalClientClass, backend_error),
- NULL, NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
- cal_client_signals[CATEGORIES_CHANGED] =
- g_signal_new ("categories_changed",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalClientClass, categories_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1,
- G_TYPE_POINTER);
- cal_client_signals[FORGET_PASSWORD] =
- g_signal_new ("forget_password",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalClientClass, forget_password),
- NULL, NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
- cal_client_signals[BACKEND_DIED] =
- g_signal_new ("backend_died",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalClientClass, backend_died),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
+ client->priv->current_op = op;
- klass->cal_opened = NULL;
- klass->obj_updated = NULL;
- klass->obj_removed = NULL;
- klass->categories_changed = NULL;
- klass->forget_password = NULL;
- klass->backend_died = NULL;
+ return op;
+}
- object_class->finalize = cal_client_finalize;
+static ECalendarOp*
+e_calendar_get_op (CalClient *client)
+{
+ if (!client->priv->current_op) {
+ g_warning (G_STRLOC ": Unexpected response");
+ return NULL;
+ }
+
+ return client->priv->current_op;
}
-/* Object initialization function for the calendar client */
static void
-cal_client_init (CalClient *client, CalClientClass *klass)
+e_calendar_free_op (ECalendarOp *op)
{
- CalClientPrivate *priv;
+ /* XXX more stuff here */
+ pthread_cond_destroy (&op->cond);
+ e_mutex_destroy (op->mutex);
+ g_free (op);
+}
- priv = g_new0 (CalClientPrivate, 1);
- client->priv = priv;
+static void
+e_calendar_remove_op (CalClient *client, ECalendarOp *op)
+{
+ if (client->priv->current_op != op)
+ g_warning (G_STRLOC ": Cannot remove op, it's not current");
- priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED;
- priv->uri = NULL;
- priv->cal_address = NULL;
- priv->alarm_email_address = NULL;
- priv->ldap_attribute = NULL;
- priv->capabilities = FALSE;
- priv->factories = NULL;
- priv->timezones = g_hash_table_new (g_str_hash, g_str_equal);
- priv->default_zone = icaltimezone_get_utc_timezone ();
- priv->comp_listener = NULL;
+ client->priv->current_op = NULL;
}
/* Gets rid of the factories that a client knows about */
@@ -364,7 +304,7 @@ destroy_cal (CalClient *client)
CORBA_exception_init (&ev);
result = CORBA_Object_is_nil (priv->cal, &ev);
if (BONOBO_EX (&ev)) {
- g_message ("destroy_cal(): could not see if the "
+ g_message (G_STRLOC ": could not see if the "
"calendar client interface object was nil");
priv->cal = CORBA_OBJECT_NIL;
CORBA_exception_free (&ev);
@@ -375,19 +315,7 @@ destroy_cal (CalClient *client)
if (result)
return;
- CORBA_exception_init (&ev);
- GNOME_Evolution_Calendar_Cal_unref (priv->cal, &ev);
- if (BONOBO_EX (&ev))
- g_message ("destroy_cal(): could not unref the calendar client interface object");
-
- CORBA_exception_free (&ev);
-
- CORBA_exception_init (&ev);
- CORBA_Object_release (priv->cal, &ev);
- if (BONOBO_EX (&ev))
- g_message ("destroy_cal(): could not release the calendar client interface object");
-
- CORBA_exception_free (&ev);
+ bonobo_object_release_unref (priv->cal, NULL);
priv->cal = CORBA_OBJECT_NIL;
}
@@ -400,184 +328,541 @@ free_timezone (gpointer key, gpointer value, gpointer data)
icaltimezone_free (value, TRUE);
}
-/* Finalize handler for the calendar client */
+
+
static void
-cal_client_finalize (GObject *object)
+backend_died_cb (EComponentListener *cl, gpointer user_data)
{
- CalClient *client;
CalClientPrivate *priv;
+ CalClient *client = (CalClient *) user_data;
- g_return_if_fail (object != NULL);
- g_return_if_fail (IS_CAL_CLIENT (object));
+ g_return_if_fail (IS_CAL_CLIENT (client));
- client = CAL_CLIENT (object);
priv = client->priv;
+ priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED;
+ g_signal_emit (G_OBJECT (client), cal_client_signals[BACKEND_DIED], 0);
+}
- if (priv->listener) {
- cal_listener_stop_notification (priv->listener);
- bonobo_object_unref (priv->listener);
- priv->listener = NULL;
+/* Signal handlers for the listener's signals */
+/* Handle the cal_opened notification from the listener */
+
+static void
+cal_read_only_cb (CalListener *listener, ECalendarStatus status, gboolean read_only, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
}
- if (priv->comp_listener) {
- g_signal_handlers_disconnect_matched (G_OBJECT (priv->comp_listener),
- G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL,
- client);
- g_object_unref (G_OBJECT (priv->comp_listener));
- priv->comp_listener = NULL;
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->bool = read_only;
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_cal_address_cb (CalListener *listener, ECalendarStatus status, const char *address, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
}
- destroy_factories (client);
- destroy_cal (client);
+ e_mutex_lock (op->mutex);
- priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED;
+ op->status = status;
+ op->string = g_strdup (address);
- if (priv->uri) {
- g_free (priv->uri);
- priv->uri = NULL;
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_alarm_address_cb (CalListener *listener, ECalendarStatus status, const char *address, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
}
- if (priv->cal_address) {
- g_free (priv->cal_address);
- priv->cal_address = NULL;
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->string = g_strdup (address);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_ldap_attribute_cb (CalListener *listener, ECalendarStatus status, const char *attribute, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
}
- if (priv->alarm_email_address) {
- g_free (priv->alarm_email_address);
- priv->alarm_email_address = NULL;
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->string = g_strdup (attribute);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_static_capabilities_cb (CalListener *listener, ECalendarStatus status, const char *capabilities, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
}
- if (priv->ldap_attribute) {
- g_free (priv->ldap_attribute);
- priv->ldap_attribute = NULL;
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->string = g_strdup (capabilities);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_opened_cb (CalListener *listener, ECalendarStatus status, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
}
- if (priv->capabilities) {
- g_free (priv->capabilities);
- priv->capabilities = NULL;
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_removed_cb (CalListener *listener, ECalendarStatus status, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
}
- g_hash_table_foreach (priv->timezones, free_timezone, NULL);
- g_hash_table_destroy (priv->timezones);
- priv->timezones = NULL;
+ e_mutex_lock (op->mutex);
- g_free (priv);
- client->priv = NULL;
+ op->status = status;
- if (G_OBJECT_CLASS (parent_class)->finalize)
- (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
}
-
+static void
+cal_object_created_cb (CalListener *listener, ECalendarStatus status, const char *uid, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->uid = g_strdup (uid);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
static void
-backend_died_cb (EComponentListener *cl, gpointer user_data)
+cal_object_modified_cb (CalListener *listener, ECalendarStatus status, gpointer data)
{
- CalClientPrivate *priv;
- CalClient *client = (CalClient *) user_data;
+ CalClient *client = data;
+ ECalendarOp *op;
- g_return_if_fail (IS_CAL_CLIENT (client));
+ op = e_calendar_get_op (client);
- priv = client->priv;
- priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED;
- g_signal_emit (G_OBJECT (client), cal_client_signals[BACKEND_DIED], 0);
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
}
-/* Signal handlers for the listener's signals */
-/* Handle the cal_opened notification from the listener */
static void
-cal_opened_cb (CalListener *listener,
- GNOME_Evolution_Calendar_Listener_OpenStatus status,
- GNOME_Evolution_Calendar_Cal cal,
- gpointer data)
+cal_object_removed_cb (CalListener *listener, ECalendarStatus status, gpointer data)
{
- CalClient *client;
- CalClientPrivate *priv;
- CORBA_Environment ev;
- GNOME_Evolution_Calendar_Cal cal_copy;
- CalClientOpenStatus client_status;
+ CalClient *client = data;
+ ECalendarOp *op;
- client = CAL_CLIENT (data);
- priv = client->priv;
+ op = e_calendar_get_op (client);
- g_assert (priv->load_state == CAL_CLIENT_LOAD_LOADING);
- g_assert (priv->uri != NULL);
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
- client_status = CAL_CLIENT_OPEN_ERROR;
+ e_mutex_lock (op->mutex);
- switch (status) {
- case GNOME_Evolution_Calendar_Listener_SUCCESS:
- CORBA_exception_init (&ev);
- cal_copy = CORBA_Object_duplicate (cal, &ev);
- if (BONOBO_EX (&ev)) {
- g_message ("cal_opened_cb(): could not duplicate the "
- "calendar client interface");
- CORBA_exception_free (&ev);
- goto error;
- }
- CORBA_exception_free (&ev);
+ op->status = status;
- priv->cal = cal_copy;
- priv->load_state = CAL_CLIENT_LOAD_LOADED;
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
- client_status = CAL_CLIENT_OPEN_SUCCESS;
+static void
+cal_alarm_discarded_cb (CalListener *listener, ECalendarStatus status, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
- /* setup component listener */
- priv->comp_listener = e_component_listener_new (priv->cal);
- g_signal_connect (G_OBJECT (priv->comp_listener), "component_died",
- G_CALLBACK (backend_died_cb), client);
- goto out;
+ op = e_calendar_get_op (client);
- case GNOME_Evolution_Calendar_Listener_ERROR:
- client_status = CAL_CLIENT_OPEN_ERROR;
- goto error;
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
- case GNOME_Evolution_Calendar_Listener_NOT_FOUND:
- client_status = CAL_CLIENT_OPEN_NOT_FOUND;
- goto error;
+ e_mutex_lock (op->mutex);
- case GNOME_Evolution_Calendar_Listener_METHOD_NOT_SUPPORTED:
- client_status = CAL_CLIENT_OPEN_METHOD_NOT_SUPPORTED;
- goto error;
+ op->status = status;
- case GNOME_Evolution_Calendar_Listener_PERMISSION_DENIED :
- client_status = CAL_CLIENT_OPEN_PERMISSION_DENIED;
- goto error;
+ pthread_cond_signal (&op->cond);
- default:
- g_assert_not_reached ();
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_objects_received_cb (CalListener *listener, ECalendarStatus status, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
}
- error:
+ e_mutex_lock (op->mutex);
- bonobo_object_unref (BONOBO_OBJECT (priv->listener));
- priv->listener = NULL;
+ op->status = status;
- /* We free the priv->uri and set the priv->load_state until after the
- * "cal_opened" signal has been emitted so that handlers will be able to
- * access this information.
- */
+ pthread_cond_signal (&op->cond);
- out:
+ e_mutex_unlock (op->mutex);
+}
- /* We are *not* inside a signal handler (this is just a simple callback
- * called from the listener), so there is not a temporary reference to
- * the client object. We ref() so that we can safely emit our own
- * signal and clean up.
- */
+static void
+cal_objects_sent_cb (CalListener *listener, ECalendarStatus status, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
- g_object_ref (G_OBJECT (client));
+ op = e_calendar_get_op (client);
- g_signal_emit (G_OBJECT (client), cal_client_signals[CAL_OPENED],
- 0, client_status);
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
- if (client_status != CAL_CLIENT_OPEN_SUCCESS) {
- priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED;
- g_free (priv->uri);
- priv->uri = NULL;
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_default_object_requested_cb (CalListener *listener, ECalendarStatus status, const char *object, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
}
- g_assert (priv->load_state != CAL_CLIENT_LOAD_LOADING);
+ e_mutex_lock (op->mutex);
- g_object_unref (G_OBJECT (client));
+ op->status = status;
+ op->string = g_strdup (object);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_object_requested_cb (CalListener *listener, ECalendarStatus status, const char *object, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->string = g_strdup (object);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_object_list_cb (CalListener *listener, ECalendarStatus status, GList *objects, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+ GList *l;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->list = g_list_copy (objects);
+
+ for (l = op->list; l; l = l->next)
+ l->data = icalcomponent_new_clone (l->data);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_get_timezone_cb (CalListener *listener, ECalendarStatus status, const char *object, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->string = g_strdup (object);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+
+}
+
+static void
+cal_add_timezone_cb (CalListener *listener, ECalendarStatus status, const char *tzid, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->uid = g_strdup (tzid);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+
+}
+
+static void
+cal_set_default_timezone_cb (CalListener *listener, ECalendarStatus status, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_get_changes_cb (CalListener *listener, ECalendarStatus status, GList *changes, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+ GList *l;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->list = g_list_copy (changes);
+
+ for (l = op->list; l; l = l->next) {
+ CalClientChange *ccc = l->data, *new_ccc;
+
+ new_ccc = g_new (CalClientChange, 1);
+ new_ccc->comp = cal_component_clone (ccc->comp);
+ new_ccc->type = ccc->type;
+
+ l->data = new_ccc;
+ }
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_get_free_busy_cb (CalListener *listener, ECalendarStatus status, GList *freebusy, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+ GList *l;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->list = g_list_copy (freebusy);
+
+ for (l = op->list; l; l = l->next)
+ l->data = cal_component_clone (l->data);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
+}
+
+static void
+cal_query_cb (CalListener *listener, ECalendarStatus status, GNOME_Evolution_Calendar_Query query, gpointer data)
+{
+ CalClient *client = data;
+ ECalendarOp *op;
+
+ op = e_calendar_get_op (client);
+
+ if (op == NULL) {
+ g_warning (G_STRLOC ": Cannot find operation ");
+ return;
+ }
+
+ e_mutex_lock (op->mutex);
+
+ op->status = status;
+ op->query = cal_query_new (query, op->listener, client);
+
+ pthread_cond_signal (&op->cond);
+
+ e_mutex_unlock (op->mutex);
}
/* Handle the cal_set_mode notification from the listener */
@@ -624,26 +909,6 @@ cal_set_mode_cb (CalListener *listener,
g_object_unref (G_OBJECT (client));
}
-/* Handle the obj_updated signal from the listener */
-static void
-obj_updated_cb (CalListener *listener, const CORBA_char *uid, gpointer data)
-{
- CalClient *client;
-
- client = CAL_CLIENT (data);
- g_signal_emit (G_OBJECT (client), cal_client_signals[OBJ_UPDATED], 0, uid);
-}
-
-/* Handle the obj_removed signal from the listener */
-static void
-obj_removed_cb (CalListener *listener, const CORBA_char *uid, gpointer data)
-{
- CalClient *client;
-
- client = CAL_CLIENT (data);
- g_signal_emit (G_OBJECT (client), cal_client_signals[OBJ_REMOVED], 0, uid);
-}
-
/* Handle the error_occurred signal from the listener */
static void
backend_error_cb (CalListener *listener, const char *message, gpointer data)
@@ -678,97 +943,343 @@ categories_changed_cb (CalListener *listener, const GNOME_Evolution_Calendar_Str
-static GList *
-get_factories (void)
+static gboolean
+get_factories (const char *str_uri, GList **factories)
{
- GList *factories = NULL;
GNOME_Evolution_Calendar_CalFactory factory;
Bonobo_ServerInfoList *servers;
- CORBA_Environment ev;
+ EUri *uri;
+ char *query;
int i;
- CORBA_exception_init (&ev);
- servers = bonobo_activation_query ("repo_ids.has ('IDL:GNOME/Evolution/Calendar/CalFactory:1.0')", NULL, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_message ("Cannot perform OAF query for Calendar servers.");
- CORBA_exception_free (&ev);
- return NULL;
+ /* Determine the protocol and query for factory supporting that */
+ uri = e_uri_new (str_uri);
+ if (!uri) {
+ g_warning (G_STRLOC ": Invalid uri string");
+
+ return FALSE;
}
- if (servers->_length == 0)
- g_warning ("No Calendar servers installed.");
+ query = g_strdup_printf ("repo_ids.has ('IDL:GNOME/Evolution/Calendar/CalFactory:1.0')"
+ " AND calendar:supported_protocols.has ('%s')", uri->protocol);
+
+
+ servers = bonobo_activation_query (query, NULL, NULL);
+
+ g_free (query);
+ e_uri_free (uri);
+ if (!servers) {
+ g_warning (G_STRLOC ": Unable to query for calendar factories");
+
+ return FALSE;
+ }
+
+ /* Try to activate the servers for the protocol */
for (i = 0; i < servers->_length; i++) {
const Bonobo_ServerInfo *info;
info = servers->_buffer + i;
- factory = (GNOME_Evolution_Calendar_CalFactory)
- bonobo_activation_activate_from_id (info->iid, 0, NULL, &ev);
- if (BONOBO_EX (&ev)) {
-#if 0
- g_warning ("cal_client_construct: Could not activate calendar server %s", info->iid);
- CORBA_free (servers);
- CORBA_exception_free (&ev);
- return NULL;
-#endif
- }
+ g_message (G_STRLOC ": Activating calendar factory (%s)", info->iid);
+ factory = bonobo_activation_activate_from_id (info->iid, 0, NULL, NULL);
+
+ if (factory == CORBA_OBJECT_NIL)
+ g_warning (G_STRLOC ": Could not activate calendar factory (%s)", info->iid);
else
- factories = g_list_prepend (factories, factory);
+ *factories = g_list_append (*factories, factory);
}
CORBA_free (servers);
- CORBA_exception_free (&ev);
- return factories;
+
+ return TRUE;
+}
+
+/* Object initialization function for the calendar client */
+static void
+cal_client_init (CalClient *client, CalClientClass *klass)
+{
+ CalClientPrivate *priv;
+
+ priv = g_new0 (CalClientPrivate, 1);
+ client->priv = priv;
+
+ priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED;
+ priv->uri = NULL;
+ priv->mutex = e_mutex_new (E_MUTEX_REC);
+ priv->listener = cal_listener_new (cal_set_mode_cb,
+ backend_error_cb,
+ categories_changed_cb,
+ client);
+
+ priv->cal_address = NULL;
+ priv->alarm_email_address = NULL;
+ priv->ldap_attribute = NULL;
+ priv->capabilities = FALSE;
+ priv->factories = NULL;
+ priv->timezones = g_hash_table_new (g_str_hash, g_str_equal);
+ priv->default_zone = icaltimezone_get_utc_timezone ();
+ priv->comp_listener = NULL;
+
+ g_signal_connect (G_OBJECT (priv->listener), "read_only", G_CALLBACK (cal_read_only_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "cal_address", G_CALLBACK (cal_cal_address_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "alarm_address", G_CALLBACK (cal_alarm_address_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "ldap_attribute", G_CALLBACK (cal_ldap_attribute_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "static_capabilities", G_CALLBACK (cal_static_capabilities_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "open", G_CALLBACK (cal_opened_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "remove", G_CALLBACK (cal_removed_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "create_object", G_CALLBACK (cal_object_created_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "modify_object", G_CALLBACK (cal_object_modified_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "remove_object", G_CALLBACK (cal_object_removed_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "discard_alarm", G_CALLBACK (cal_alarm_discarded_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "receive_objects", G_CALLBACK (cal_objects_received_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "send_objects", G_CALLBACK (cal_objects_sent_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "default_object", G_CALLBACK (cal_default_object_requested_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "object", G_CALLBACK (cal_object_requested_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "object_list", G_CALLBACK (cal_object_list_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "get_timezone", G_CALLBACK (cal_get_timezone_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "add_timezone", G_CALLBACK (cal_add_timezone_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "set_default_timezone", G_CALLBACK (cal_set_default_timezone_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "get_changes", G_CALLBACK (cal_get_changes_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "get_free_busy", G_CALLBACK (cal_get_free_busy_cb), client);
+ g_signal_connect (G_OBJECT (priv->listener), "query", G_CALLBACK (cal_query_cb), client);
+}
+
+/* Finalize handler for the calendar client */
+static void
+cal_client_finalize (GObject *object)
+{
+ CalClient *client;
+ CalClientPrivate *priv;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (IS_CAL_CLIENT (object));
+
+ client = CAL_CLIENT (object);
+ priv = client->priv;
+
+ if (priv->listener) {
+ cal_listener_stop_notification (priv->listener);
+ bonobo_object_unref (priv->listener);
+ priv->listener = NULL;
+ }
+
+ if (priv->comp_listener) {
+ g_signal_handlers_disconnect_matched (G_OBJECT (priv->comp_listener),
+ G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL,
+ client);
+ g_object_unref (G_OBJECT (priv->comp_listener));
+ priv->comp_listener = NULL;
+ }
+
+ destroy_factories (client);
+ destroy_cal (client);
+
+ priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED;
+
+ if (priv->uri) {
+ g_free (priv->uri);
+ priv->uri = NULL;
+ }
+
+ if (priv->mutex) {
+ e_mutex_destroy (priv->mutex);
+ priv->mutex = NULL;
+ }
+
+ if (priv->cal_address) {
+ g_free (priv->cal_address);
+ priv->cal_address = NULL;
+ }
+ if (priv->alarm_email_address) {
+ g_free (priv->alarm_email_address);
+ priv->alarm_email_address = NULL;
+ }
+ if (priv->ldap_attribute) {
+ g_free (priv->ldap_attribute);
+ priv->ldap_attribute = NULL;
+ }
+ if (priv->capabilities) {
+ g_free (priv->capabilities);
+ priv->capabilities = NULL;
+ }
+
+ g_hash_table_foreach (priv->timezones, free_timezone, NULL);
+ g_hash_table_destroy (priv->timezones);
+ priv->timezones = NULL;
+
+ g_free (priv);
+ client->priv = NULL;
+
+ if (G_OBJECT_CLASS (parent_class)->finalize)
+ (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+}
+
+/* Class initialization function for the calendar client */
+static void
+cal_client_class_init (CalClientClass *klass)
+{
+ GObjectClass *object_class;
+
+ object_class = (GObjectClass *) klass;
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ cal_client_signals[CAL_OPENED] =
+ g_signal_new ("cal_opened",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalClientClass, cal_opened),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__ENUM,
+ G_TYPE_NONE, 1,
+ CAL_CLIENT_OPEN_STATUS_ENUM_TYPE);
+ cal_client_signals[CAL_SET_MODE] =
+ g_signal_new ("cal_set_mode",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalClientClass, cal_set_mode),
+ NULL, NULL,
+ cal_util_marshal_VOID__ENUM_ENUM,
+ G_TYPE_NONE, 2,
+ CAL_CLIENT_SET_MODE_STATUS_ENUM_TYPE,
+ CAL_MODE_ENUM_TYPE);
+ cal_client_signals[BACKEND_ERROR] =
+ g_signal_new ("backend_error",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalClientClass, backend_error),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+ cal_client_signals[CATEGORIES_CHANGED] =
+ g_signal_new ("categories_changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalClientClass, categories_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1,
+ G_TYPE_POINTER);
+ cal_client_signals[FORGET_PASSWORD] =
+ g_signal_new ("forget_password",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalClientClass, forget_password),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+ cal_client_signals[BACKEND_DIED] =
+ g_signal_new ("backend_died",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalClientClass, backend_died),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ klass->cal_opened = NULL;
+ klass->categories_changed = NULL;
+ klass->forget_password = NULL;
+ klass->backend_died = NULL;
+
+ object_class->finalize = cal_client_finalize;
}
/**
- * cal_client_construct:
- * @client: A calendar client.
+ * cal_client_get_type:
*
- * Constructs a calendar client object by contacting all available
- * calendar factories.
+ * Registers the #CalClient class if necessary, and returns the type ID assigned
+ * to it.
*
- * Return value: The same object as the @client argument, or NULL if the
- * calendar factory could not be contacted.
+ * Return value: The type ID of the #CalClient class.
**/
-CalClient *
-cal_client_construct (CalClient *client)
+GType
+cal_client_get_type (void)
{
- CalClientPrivate *priv;
+ static GType cal_client_type = 0;
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
+ if (!cal_client_type) {
+ static GTypeInfo info = {
+ sizeof (CalClientClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) cal_client_class_init,
+ NULL, NULL,
+ sizeof (CalClient),
+ 0,
+ (GInstanceInitFunc) cal_client_init
+ };
+ cal_client_type = g_type_register_static (G_TYPE_OBJECT, "CalClient", &info, 0);
+ }
+ return cal_client_type;
+}
+
+
+static gboolean
+fetch_corba_cal (CalClient *client, const char *str_uri, CalObjType type)
+{
+ CalClientPrivate *priv;
+ GList *f;
+ CORBA_Environment ev;
+
priv = client->priv;
- priv->factories = get_factories ();
+ g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_NOT_LOADED, FALSE);
+ g_assert (priv->uri == NULL);
- return client;
+ g_return_val_if_fail (str_uri != NULL, FALSE);
+
+ if (!get_factories (str_uri, &priv->factories))
+ return FALSE;
+
+ priv->uri = g_strdup (str_uri);
+ priv->type = type;
+
+ for (f = priv->factories; f; f = f->next) {
+ GNOME_Evolution_Calendar_Cal cal;
+
+ CORBA_exception_init (&ev);
+
+ cal = GNOME_Evolution_Calendar_CalFactory_getCal (f->data, priv->uri, priv->type,
+ BONOBO_OBJREF (priv->listener), &ev);
+ if (BONOBO_EX (&ev))
+ continue;
+
+ priv->cal = cal;
+
+ return TRUE;
+ }
+
+ return FALSE;
}
/**
* cal_client_new:
*
* Creates a new calendar client. It should be initialized by calling
- * cal_client_open_calendar().
+ * cal_client_open().
*
* Return value: A newly-created calendar client, or NULL if the client could
* not be constructed because it could not contact the calendar server.
**/
CalClient *
-cal_client_new (void)
+cal_client_new (const char *uri, CalObjType type)
{
CalClient *client;
client = g_object_new (CAL_CLIENT_TYPE, NULL);
- if (!cal_client_construct (client)) {
- g_message ("cal_client_new(): could not construct the calendar client");
- g_object_unref (G_OBJECT (client));
+ if (!fetch_corba_cal (client, uri, type)) {
+ g_object_unref (client);
+
return NULL;
}
-
+
return client;
}
@@ -800,74 +1311,8 @@ cal_client_set_auth_func (CalClient *client, CalClientAuthFunc func, gpointer da
client->priv->auth_user_data = data;
}
-static gboolean
-real_open_calendar (CalClient *client, const char *str_uri, gboolean only_if_exists, gboolean *supported)
-{
- CalClientPrivate *priv;
- GNOME_Evolution_Calendar_Listener corba_listener;
- int unsupported;
- GList *f;
- CORBA_Environment ev;
-
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_NOT_LOADED, FALSE);
- g_assert (priv->uri == NULL);
-
- g_return_val_if_fail (str_uri != NULL, FALSE);
-
- priv->listener = cal_listener_new (cal_opened_cb,
- cal_set_mode_cb,
- obj_updated_cb,
- obj_removed_cb,
- backend_error_cb,
- categories_changed_cb,
- client);
- if (!priv->listener) {
- g_message ("cal_client_open_calendar(): could not create the listener");
- return FALSE;
- }
-
- corba_listener = (GNOME_Evolution_Calendar_Listener) (BONOBO_OBJREF (priv->listener));
-
- priv->load_state = CAL_CLIENT_LOAD_LOADING;
- priv->uri = g_strdup (str_uri);
-
- unsupported = 0;
- for (f = priv->factories; f; f = f->next) {
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_Calendar_CalFactory_open (f->data, str_uri,
- only_if_exists,
- corba_listener, &ev);
- if (!BONOBO_EX (&ev)) {
- if (supported != NULL)
- *supported = TRUE;
- return TRUE;
- }
-
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_CalFactory_UnsupportedMethod))
- unsupported++;
- CORBA_exception_free (&ev);
- }
-
- if (supported != NULL) {
- if (unsupported == g_list_length (priv->factories))
- *supported = FALSE;
- else
- *supported = TRUE;
- }
-
- bonobo_object_unref (BONOBO_OBJECT (priv->listener));
- priv->listener = NULL;
- priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED;
- g_free (priv->uri);
- priv->uri = NULL;
-
- return FALSE;
-}
-
/**
- * cal_client_open_calendar:
+ * cal_client_open
* @client: A calendar client.
* @str_uri: URI of calendar to open.
* @only_if_exists: FALSE if the calendar should be opened even if there
@@ -882,93 +1327,167 @@ real_open_calendar (CalClient *client, const char *str_uri, gboolean only_if_exi
* Return value: TRUE on success, FALSE on failure to issue the open request.
**/
gboolean
-cal_client_open_calendar (CalClient *client, const char *str_uri, gboolean only_if_exists)
+cal_client_open (CalClient *client, gboolean only_if_exists, GError **error)
{
+ CalClientPrivate *priv;
+ CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
+
g_return_val_if_fail (client != NULL, FALSE);
g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
- return real_open_calendar (client, str_uri, only_if_exists, NULL);
-}
+ priv = client->priv;
+
+ e_mutex_lock (client->priv->mutex);
-static char *
-get_fall_back_uri (gboolean tasks)
-{
- if (tasks)
- return g_concat_dir_and_file (g_get_home_dir (),
- "evolution/local/"
- "Tasks/tasks.ics");
- else
- return g_concat_dir_and_file (g_get_home_dir (),
- "evolution/local/"
- "Calendar/calendar.ics");
-}
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
-static char *
-get_default_uri (gboolean tasks)
-{
- EConfigListener *db;
- char *uri;
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
+
+ CORBA_exception_init (&ev);
+
+ priv->load_state = CAL_CLIENT_LOAD_LOADING;
+
+ GNOME_Evolution_Calendar_Cal_open (priv->cal, only_if_exists, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ g_signal_emit (G_OBJECT (client), cal_client_signals[CAL_OPENED], 0,
+ E_CALENDAR_STATUS_CORBA_EXCEPTION);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
+
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
- db = e_config_listener_new ();
+ status = our_op->status;
- if (tasks)
- uri = e_config_listener_get_string (db, "/apps/evolution/shell/default_folders/tasks_uri");
- else
- uri = e_config_listener_get_string (db, "/apps/evolution/shell/default_folders/calendar_uri");
- g_object_unref (G_OBJECT (db));
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- if (!uri || *uri == '\0')
- uri = get_fall_back_uri (tasks);
+ if (status == E_CALENDAR_STATUS_OK)
+ priv->load_state = CAL_CLIENT_LOAD_LOADED;
else
- uri = cal_util_expand_uri (uri, tasks);
-
- return uri;
+ priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED;
+
+ g_signal_emit (G_OBJECT (client), cal_client_signals[CAL_OPENED], 0, status);
+ E_CALENDAR_CHECK_STATUS (status, error);
}
-gboolean
-cal_client_open_default_calendar (CalClient *client, gboolean only_if_exists)
+typedef struct {
+ CalClient *client;
+
+ gboolean exists;
+} CalClientAsyncData;
+
+static gboolean
+open_async (gpointer data)
{
- char *default_uri, *fall_back;
- gboolean result, supported;
+ CalClientAsyncData *ccad = data;
+ GError *error = NULL;
- g_return_val_if_fail (client != NULL, FALSE);
- g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
+ cal_client_open (ccad->client, ccad->exists, &error);
- default_uri = get_default_uri (FALSE);
- fall_back = get_fall_back_uri (FALSE);
-
- result = real_open_calendar (client, default_uri, only_if_exists, &supported);
- if (!supported && strcmp (fall_back, default_uri))
- result = real_open_calendar (client, fall_back, only_if_exists, NULL);
+ g_clear_error (&error);
- g_free (default_uri);
- g_free (fall_back);
+ g_object_unref (ccad);
+ g_free (ccad);
- return result;
+ return FALSE;
}
-gboolean
-cal_client_open_default_tasks (CalClient *client, gboolean only_if_exists)
+void
+cal_client_open_async (CalClient *client, gboolean only_if_exists)
{
- char *default_uri, *fall_back;
- gboolean result, supported;
+ CalClientAsyncData *ccad;
+
+ g_return_if_fail (client != NULL);
+ g_return_if_fail (IS_CAL_CLIENT (client));
+
+ ccad = g_new0 (CalClientAsyncData, 1);
+ ccad->client = g_object_ref (client);
+ ccad->exists = only_if_exists;
+ /* FIXME This should really spawn a new thread */
+ g_idle_add (open_async, ccad);
+}
+
+gboolean
+cal_client_remove_calendar (CalClient *client, GError **error)
+{
+ CalClientPrivate *priv;
+ CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
+
g_return_val_if_fail (client != NULL, FALSE);
g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
- default_uri = get_default_uri (TRUE);
- fall_back = get_fall_back_uri (TRUE);
+ priv = client->priv;
+
+ e_mutex_lock (client->priv->mutex);
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
- result = real_open_calendar (client, default_uri, only_if_exists, &supported);
- if (!supported && strcmp (fall_back, default_uri))
- result = real_open_calendar (client, fall_back, only_if_exists, NULL);
+ e_mutex_lock (our_op->mutex);
- g_free (default_uri);
- g_free (fall_back);
+ e_mutex_unlock (client->priv->mutex);
+
+
+ CORBA_exception_init (&ev);
- return result;
+ GNOME_Evolution_Calendar_Cal_remove (priv->cal, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
+
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
+#if 0
/* Builds an URI list out of a CORBA string sequence */
static GList *
build_uri_list (GNOME_Evolution_Calendar_StringSeq *seq)
@@ -981,6 +1500,7 @@ build_uri_list (GNOME_Evolution_Calendar_StringSeq *seq)
return uris;
}
+#endif
/**
* cal_client_uri_list:
@@ -993,6 +1513,7 @@ build_uri_list (GNOME_Evolution_Calendar_StringSeq *seq)
GList *
cal_client_uri_list (CalClient *client, CalMode mode)
{
+#if 0
CalClientPrivate *priv;
GNOME_Evolution_Calendar_StringSeq *uri_seq;
GList *uris = NULL;
@@ -1026,8 +1547,12 @@ cal_client_uri_list (CalClient *client, CalMode mode)
}
return uris;
+#endif
+
+ return NULL;
}
+
/**
* cal_client_get_load_state:
* @client: A calendar client.
@@ -1076,33 +1601,72 @@ cal_client_get_uri (CalClient *client)
* @client: A calendar client.
*
* Queries whether the calendar client can perform modifications
- * on the calendar or not.
+ * on the calendar or not. Whether the backend is read only or not
+ * is specified, on exit, in the @read_only argument.
*
- * Return value: TRUE if the calendar is read-only, FALSE otherwise.
+ * Return value: TRUE if the call was successful, FALSE if there was an error.
*/
gboolean
-cal_client_is_read_only (CalClient *client)
+cal_client_is_read_only (CalClient *client, gboolean *read_only, GError **error)
{
CalClientPrivate *priv;
CORBA_Environment ev;
- CORBA_boolean read_only;
-
+ ECalendarStatus status;
+ ECalendarOp *our_op;
+
g_return_val_if_fail (client != NULL, FALSE);
g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
priv = client->priv;
+
+ e_mutex_lock (client->priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
- if (priv->load_state != CAL_CLIENT_LOAD_LOADED)
- return FALSE;
CORBA_exception_init (&ev);
- read_only = GNOME_Evolution_Calendar_Cal_isReadOnly (priv->cal, &ev);
+
+ GNOME_Evolution_Calendar_Cal_isReadOnly (priv->cal, &ev);
if (BONOBO_EX (&ev)) {
- g_message ("cal_client_is_read_only: could not call isReadOnly method");
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
+
CORBA_exception_free (&ev);
- return read_only;
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+ *read_only = our_op->bool;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ return status;
}
/**
@@ -1115,119 +1679,269 @@ cal_client_is_read_only (CalClient *client)
* is loaded or being loaded, or %NULL if the client has not started a
* load request yet or the calendar has no associated email address.
**/
-const char *
-cal_client_get_cal_address (CalClient *client)
+gboolean
+cal_client_get_cal_address (CalClient *client, char **cal_address, GError **error)
{
CalClientPrivate *priv;
-
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
+ CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
+
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL);
+
+ e_mutex_lock (client->priv->mutex);
- if (priv->cal_address == NULL) {
- CORBA_Environment ev;
- CORBA_char *cal_address;
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
+
+
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Calendar_Cal_getCalAddress (priv->cal, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- CORBA_exception_init (&ev);
- cal_address = GNOME_Evolution_Calendar_Cal_getCalAddress (priv->cal, &ev);
- if (!BONOBO_EX (&ev)) {
- priv->cal_address = g_strdup (cal_address);
- CORBA_free (cal_address);
- }
CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
- return priv->cal_address;
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+ *cal_address = our_op->string;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
-const char *
-cal_client_get_alarm_email_address (CalClient *client)
+gboolean
+cal_client_get_alarm_email_address (CalClient *client, char **alarm_address, GError **error)
{
CalClientPrivate *priv;
+ CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL);
- if (priv->alarm_email_address == NULL) {
- CORBA_Environment ev;
- CORBA_char *email_address;
+ e_mutex_lock (client->priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
+
+
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Calendar_Cal_getAlarmEmailAddress (priv->cal, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- CORBA_exception_init (&ev);
- email_address = GNOME_Evolution_Calendar_Cal_getAlarmEmailAddress (priv->cal, &ev);
- if (!BONOBO_EX (&ev)) {
- priv->alarm_email_address = g_strdup (email_address);
- CORBA_free (email_address);
- }
CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
- return priv->alarm_email_address;
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+ *alarm_address = our_op->string;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
-const char *
-cal_client_get_ldap_attribute (CalClient *client)
+gboolean
+cal_client_get_ldap_attribute (CalClient *client, char **ldap_attribute, GError **error)
{
CalClientPrivate *priv;
+ CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL);
- if (priv->ldap_attribute == NULL) {
- CORBA_Environment ev;
- CORBA_char *ldap_attribute;
+ e_mutex_lock (client->priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
+
+
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Calendar_Cal_getLdapAttribute (priv->cal, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- CORBA_exception_init (&ev);
- ldap_attribute = GNOME_Evolution_Calendar_Cal_getLdapAttribute (priv->cal, &ev);
- if (!BONOBO_EX (&ev)) {
- priv->ldap_attribute = g_strdup (ldap_attribute);
- CORBA_free (ldap_attribute);
- }
CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
- return priv->ldap_attribute;
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+ *ldap_attribute = our_op->string;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
-static void
-load_static_capabilities (CalClient *client)
+static gboolean
+load_static_capabilities (CalClient *client, GError **error)
{
CalClientPrivate *priv;
CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
char *cap;
priv = client->priv;
if (priv->capabilities)
- return;
-
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
+
+ e_mutex_lock (client->priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
+
+
CORBA_exception_init (&ev);
- cap = GNOME_Evolution_Calendar_Cal_getStaticCapabilities (priv->cal, &ev);
- if (!BONOBO_EX (&ev))
- priv->capabilities = g_strdup (cap);
- else
- priv->capabilities = g_strdup ("");
- CORBA_free (cap);
+ GNOME_Evolution_Calendar_Cal_getStaticCapabilities (priv->cal, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
+
CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+ cap = our_op->string;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
static gboolean
check_capability (CalClient *client, const char *cap)
{
CalClientPrivate *priv;
-
+
priv = client->priv;
- load_static_capabilities (client);
- if (strstr (priv->capabilities, cap))
+ /* FIXME Check result */
+ load_static_capabilities (client, NULL);
+ if (priv->capabilities && strstr (priv->capabilities, cap))
return TRUE;
return FALSE;
@@ -1269,15 +1983,6 @@ cal_client_get_save_schedules (CalClient *client)
return check_capability (client, CAL_STATIC_CAPABILITY_SAVE_SCHEDULES);
}
-/* Converts our representation of a calendar component type into its CORBA representation */
-static GNOME_Evolution_Calendar_CalObjType
-corba_obj_type (CalObjType type)
-{
- return (((type & CALOBJ_TYPE_EVENT) ? GNOME_Evolution_Calendar_TYPE_EVENT : 0)
- | ((type & CALOBJ_TYPE_TODO) ? GNOME_Evolution_Calendar_TYPE_TODO : 0)
- | ((type & CALOBJ_TYPE_JOURNAL) ? GNOME_Evolution_Calendar_TYPE_JOURNAL : 0));
-}
-
gboolean
cal_client_set_mode (CalClient *client, CalMode mode)
{
@@ -1302,45 +2007,6 @@ cal_client_set_mode (CalClient *client, CalMode mode)
return retval;
}
-/**
- * cal_client_get_n_objects:
- * @client: A calendar client.
- * @type: Type of objects that will be counted.
- *
- * Counts the number of calendar components of the specified @type. This can be
- * used to count how many events, to-dos, or journals there are, for example.
- *
- * Return value: Number of components.
- **/
-int
-cal_client_get_n_objects (CalClient *client, CalObjType type)
-{
- CalClientPrivate *priv;
- CORBA_Environment ev;
- int n;
- int t;
-
- g_return_val_if_fail (client != NULL, -1);
- g_return_val_if_fail (IS_CAL_CLIENT (client), -1);
-
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, -1);
-
- t = corba_obj_type (type);
-
- CORBA_exception_init (&ev);
- n = GNOME_Evolution_Calendar_Cal_countObjects (priv->cal, t, &ev);
-
- if (BONOBO_EX (&ev)) {
- g_message ("cal_client_get_n_objects(): could not get the number of objects");
- CORBA_exception_free (&ev);
- return -1;
- }
-
- CORBA_exception_free (&ev);
- return n;
-}
-
/* This is used in the callback which fetches all the timezones needed for an
object. */
@@ -1348,68 +2014,93 @@ typedef struct _CalClientGetTimezonesData CalClientGetTimezonesData;
struct _CalClientGetTimezonesData {
CalClient *client;
- /* This starts out at CAL_CLIENT_GET_SUCCESS. If an error occurs this
+ /* This starts out at E_CALENDAR_STATUS_OK. If an error occurs this
contains the last error. */
- CalClientGetStatus status;
+ ECalendarStatus status;
};
-CalClientGetStatus
-cal_client_get_default_object (CalClient *client, CalObjType type, icalcomponent **icalcomp)
+gboolean
+cal_client_get_default_object (CalClient *client, icalcomponent **icalcomp, GError **error)
{
CalClientPrivate *priv;
CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalObj comp_str;
- CalClientGetStatus retval;
- CalClientGetTimezonesData cb_data;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
- g_return_val_if_fail (client != NULL, CAL_CLIENT_GET_NOT_FOUND);
- g_return_val_if_fail (IS_CAL_CLIENT (client), CAL_CLIENT_GET_NOT_FOUND);
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, CAL_CLIENT_GET_NOT_FOUND);
- g_return_val_if_fail (icalcomp != NULL, CAL_CLIENT_GET_NOT_FOUND);
+ e_mutex_lock (client->priv->mutex);
- retval = CAL_CLIENT_GET_NOT_FOUND;
- *icalcomp = NULL;
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
CORBA_exception_init (&ev);
- comp_str = GNOME_Evolution_Calendar_Cal_getDefaultObject (priv->cal, type, &ev);
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
- goto out;
- else if (BONOBO_EX (&ev)) {
- g_message ("cal_client_get_default_object(): could not get the object");
- goto out;
- }
+ GNOME_Evolution_Calendar_Cal_getDefaultObject (priv->cal, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- *icalcomp = icalparser_parse_string (comp_str);
- CORBA_free (comp_str);
+ CORBA_exception_free (&ev);
- if (!*icalcomp) {
- retval = CAL_CLIENT_GET_SYNTAX_ERROR;
- goto out;
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
- /* Now make sure we have all timezones needed for this object.
- We do this to try to avoid any problems caused by getting a timezone
- in the middle of other code. Any calls to ORBit result in a
- recursive call of the GTK+ main loop, which can cause problems for
- code that doesn't expect it. Currently GnomeCanvas has problems if
- we try to get a timezone in the middle of a redraw, and there is a
- resize pending, which leads to an assert failure and an abort. */
- cb_data.client = client;
- cb_data.status = CAL_CLIENT_GET_SUCCESS;
- icalcomponent_foreach_tzid (*icalcomp,
- cal_client_get_object_timezones_cb,
- &cb_data);
+ CORBA_exception_free (&ev);
- retval = cb_data.status;
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
- out:
+ status = our_op->status;
+ *icalcomp = icalparser_parse_string (our_op->string);
+ g_free (our_op->string);
- CORBA_exception_free (&ev);
- return retval;
+ if (!*icalcomp) {
+ status = E_CALENDAR_STATUS_INVALID_OBJECT;
+ } else {
+ CalClientGetTimezonesData cb_data;
+
+ /* Now make sure we have all timezones needed for this object.
+ We do this to try to avoid any problems caused by getting a timezone
+ in the middle of other code. Any calls to ORBit result in a
+ recursive call of the GTK+ main loop, which can cause problems for
+ code that doesn't expect it. Currently GnomeCanvas has problems if
+ we try to get a timezone in the middle of a redraw, and there is a
+ resize pending, which leads to an assert failure and an abort. */
+ cb_data.client = client;
+ cb_data.status = E_CALENDAR_STATUS_OK;
+ icalcomponent_foreach_tzid (*icalcomp,
+ cal_client_get_object_timezones_cb,
+ &cb_data);
+
+ status = cb_data.status;
+ }
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
/**
@@ -1423,64 +2114,89 @@ cal_client_get_default_object (CalClient *client, CalObjType type, icalcomponent
*
* Return value: Result code based on the status of the operation.
**/
-CalClientGetStatus
-cal_client_get_object (CalClient *client, const char *uid, icalcomponent **icalcomp)
+gboolean
+cal_client_get_object (CalClient *client, const char *uid, const char *rid, icalcomponent **icalcomp, GError **error)
{
+
CalClientPrivate *priv;
CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalObj comp_str;
- CalClientGetStatus retval;
- CalClientGetTimezonesData cb_data;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
- g_return_val_if_fail (client != NULL, CAL_CLIENT_GET_NOT_FOUND);
- g_return_val_if_fail (IS_CAL_CLIENT (client), CAL_CLIENT_GET_NOT_FOUND);
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, CAL_CLIENT_GET_NOT_FOUND);
- g_return_val_if_fail (uid != NULL, CAL_CLIENT_GET_NOT_FOUND);
- g_return_val_if_fail (icalcomp != NULL, CAL_CLIENT_GET_NOT_FOUND);
+ e_mutex_lock (client->priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
- retval = CAL_CLIENT_GET_NOT_FOUND;
- *icalcomp = NULL;
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
CORBA_exception_init (&ev);
- comp_str = GNOME_Evolution_Calendar_Cal_getObject (priv->cal, (char *) uid, &ev);
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
- goto out;
- else if (BONOBO_EX (&ev)) {
- g_message ("cal_client_get_object(): could not get the object");
- goto out;
- }
+ GNOME_Evolution_Calendar_Cal_getObject (priv->cal, uid, rid ? rid : "", &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- *icalcomp = icalparser_parse_string (comp_str);
- CORBA_free (comp_str);
+ CORBA_exception_free (&ev);
- if (!*icalcomp) {
- retval = CAL_CLIENT_GET_SYNTAX_ERROR;
- goto out;
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
- /* Now make sure we have all timezones needed for this object.
- We do this to try to avoid any problems caused by getting a timezone
- in the middle of other code. Any calls to ORBit result in a
- recursive call of the GLib main loop, which can cause problems for
- code that doesn't expect it. Currently GnomeCanvas has problems if
- we try to get a timezone in the middle of a redraw, and there is a
- resize pending, which leads to an assert failure and an abort. */
- cb_data.client = client;
- cb_data.status = CAL_CLIENT_GET_SUCCESS;
- icalcomponent_foreach_tzid (*icalcomp,
- cal_client_get_object_timezones_cb,
- &cb_data);
+ CORBA_exception_free (&ev);
- retval = cb_data.status;
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
- out:
+ status = our_op->status;
+ *icalcomp = icalparser_parse_string (our_op->string);
+ g_free (our_op->string);
- CORBA_exception_free (&ev);
- return retval;
+ if (!*icalcomp) {
+ status = E_CALENDAR_STATUS_INVALID_OBJECT;
+ } else {
+ CalClientGetTimezonesData cb_data;
+
+ /* Now make sure we have all timezones needed for this object.
+ We do this to try to avoid any problems caused by getting a timezone
+ in the middle of other code. Any calls to ORBit result in a
+ recursive call of the GTK+ main loop, which can cause problems for
+ code that doesn't expect it. Currently GnomeCanvas has problems if
+ we try to get a timezone in the middle of a redraw, and there is a
+ resize pending, which leads to an assert failure and an abort. */
+ cb_data.client = client;
+ cb_data.status = E_CALENDAR_STATUS_OK;
+ icalcomponent_foreach_tzid (*icalcomp,
+ cal_client_get_object_timezones_cb,
+ &cb_data);
+
+ status = cb_data.status;
+ }
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
@@ -1491,106 +2207,18 @@ cal_client_get_object_timezones_cb (icalparameter *param,
CalClientGetTimezonesData *cb_data = data;
const char *tzid;
icaltimezone *zone;
- CalClientGetStatus status;
+ GError *error = NULL;
tzid = icalparameter_get_tzid (param);
if (!tzid) {
- cb_data->status = CAL_CLIENT_GET_SYNTAX_ERROR;
+ cb_data->status = E_CALENDAR_STATUS_INVALID_OBJECT;
return;
}
- status = cal_client_get_timezone (cb_data->client, tzid, &zone);
- if (status != CAL_CLIENT_GET_SUCCESS)
- cb_data->status = status;
-}
-
-
-CalClientGetStatus
-cal_client_get_timezone (CalClient *client,
- const char *tzid,
- icaltimezone **zone)
-{
- CalClientPrivate *priv;
- CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalObj comp_str;
- CalClientGetStatus retval;
- icalcomponent *icalcomp;
- icaltimezone *tmp_zone;
-
- g_return_val_if_fail (client != NULL, CAL_CLIENT_GET_NOT_FOUND);
- g_return_val_if_fail (IS_CAL_CLIENT (client), CAL_CLIENT_GET_NOT_FOUND);
-
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED,
- CAL_CLIENT_GET_NOT_FOUND);
-
- g_return_val_if_fail (zone != NULL, CAL_CLIENT_GET_NOT_FOUND);
-
- /* If tzid is NULL or "" we return NULL, since it is a 'local time'. */
- if (!tzid || !tzid[0]) {
- *zone = NULL;
- return CAL_CLIENT_GET_SUCCESS;
- }
-
- /* If it is UTC, we return the special UTC timezone. */
- if (!strcmp (tzid, "UTC")) {
- *zone = icaltimezone_get_utc_timezone ();
- return CAL_CLIENT_GET_SUCCESS;
- }
-
- /* See if we already have it in the cache. */
- tmp_zone = g_hash_table_lookup (priv->timezones, tzid);
- if (tmp_zone) {
- *zone = tmp_zone;
- return CAL_CLIENT_GET_SUCCESS;
- }
-
- retval = CAL_CLIENT_GET_NOT_FOUND;
- *zone = NULL;
-
- /* We don't already have it, so we try to get it from the server. */
- CORBA_exception_init (&ev);
- comp_str = GNOME_Evolution_Calendar_Cal_getTimezoneObject (priv->cal, (char *) tzid, &ev);
-
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
- goto out;
- else if (BONOBO_EX (&ev)) {
- g_message ("cal_client_get_timezone(): could not get the object");
- goto out;
- }
-
- icalcomp = icalparser_parse_string (comp_str);
- CORBA_free (comp_str);
-
- if (!icalcomp) {
- retval = CAL_CLIENT_GET_SYNTAX_ERROR;
- goto out;
- }
-
- tmp_zone = icaltimezone_new ();
- if (!tmp_zone) {
- /* FIXME: Needs better error code - out of memory. Or just
- abort like GLib does? */
- retval = CAL_CLIENT_GET_NOT_FOUND;
- goto out;
- }
-
- if (!icaltimezone_set_component (tmp_zone, icalcomp)) {
- retval = CAL_CLIENT_GET_SYNTAX_ERROR;
- goto out;
- }
-
- /* Now add it to the cache, to avoid the server call in future. */
- g_hash_table_insert (priv->timezones, icaltimezone_get_tzid (tmp_zone),
- tmp_zone);
-
- *zone = tmp_zone;
- retval = CAL_CLIENT_GET_SUCCESS;
-
- out:
-
- CORBA_exception_free (&ev);
- return retval;
+ if (!cal_client_get_timezone (cb_data->client, tzid, &zone, &error))
+ cb_data->status = error->code;
+
+ g_clear_error (&error);
}
/* Resolves TZIDs for the recurrence generator. */
@@ -1599,7 +2227,6 @@ cal_client_resolve_tzid_cb (const char *tzid, gpointer data)
{
CalClient *client;
icaltimezone *zone = NULL;
- CalClientGetStatus status;
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (IS_CAL_CLIENT (data), NULL);
@@ -1607,219 +2234,180 @@ cal_client_resolve_tzid_cb (const char *tzid, gpointer data)
client = CAL_CLIENT (data);
/* FIXME: Handle errors. */
- status = cal_client_get_timezone (client, tzid, &zone);
+ cal_client_get_timezone (client, tzid, &zone, NULL);
return zone;
}
-
-/* Builds an UID list out of a CORBA UID sequence */
-static GList *
-build_uid_list (GNOME_Evolution_Calendar_CalObjUIDSeq *seq)
-{
- GList *uids;
- int i;
-
- uids = NULL;
-
- for (i = 0; i < seq->_length; i++)
- uids = g_list_prepend (uids, g_strdup (seq->_buffer[i]));
-
- return uids;
-}
-
-/**
- * cal_client_get_uids:
- * @client: A calendar client.
- * @type: Bitmask with types of objects to return.
- *
- * Queries a calendar for a list of unique identifiers corresponding to calendar
- * objects whose type matches one of the types specified in the @type flags.
- *
- * Return value: A list of strings that are the sought UIDs. This should be
- * freed using the cal_obj_uid_list_free() function.
- **/
-GList *
-cal_client_get_uids (CalClient *client, CalObjType type)
+gboolean
+cal_client_get_changes (CalClient *client, CalObjType type, const char *change_id, GList **changes, GError **error)
{
- CalClientPrivate *priv;
CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalObjUIDSeq *seq;
- int t;
- GList *uids;
+ ECalendarOp *our_op;
+ ECalendarStatus status;
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
+ g_return_val_if_fail (client != NULL, E_CALENDAR_STATUS_INVALID_ARG);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), E_CALENDAR_STATUS_INVALID_ARG);
+ g_return_val_if_fail (change_id != NULL, E_CALENDAR_STATUS_INVALID_ARG);
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL);
+ e_mutex_lock (client->priv->mutex);
- t = corba_obj_type (type);
-
- CORBA_exception_init (&ev);
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
- seq = GNOME_Evolution_Calendar_Cal_getUIDs (priv->cal, t, &ev);
- if (BONOBO_EX (&ev)) {
- g_message ("cal_client_get_uids(): could not get the list of UIDs");
- CORBA_exception_free (&ev);
- return NULL;
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
}
- CORBA_exception_free (&ev);
+ our_op = e_calendar_new_op (client);
- uids = build_uid_list (seq);
- CORBA_free (seq);
+ e_mutex_lock (our_op->mutex);
- return uids;
-}
+ e_mutex_unlock (client->priv->mutex);
-/* Builds a GList of CalClientChange structures from the CORBA sequence */
-static GList *
-build_change_list (GNOME_Evolution_Calendar_CalObjChangeSeq *seq)
-{
- GList *list = NULL;
- icalcomponent *icalcomp;
- int i;
+ CORBA_exception_init (&ev);
- /* Create the list in reverse order */
- for (i = 0; i < seq->_length; i++) {
- GNOME_Evolution_Calendar_CalObjChange *corba_coc;
- CalClientChange *ccc;
+ GNOME_Evolution_Calendar_Cal_getChanges (client->priv->cal, type, change_id, &ev);
- corba_coc = &seq->_buffer[i];
- ccc = g_new (CalClientChange, 1);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- icalcomp = icalparser_parse_string (corba_coc->calobj);
- if (!icalcomp)
- continue;
+ CORBA_exception_free (&ev);
- ccc->comp = cal_component_new ();
- if (!cal_component_set_icalcomponent (ccc->comp, icalcomp)) {
- icalcomponent_free (icalcomp);
- g_object_unref (G_OBJECT (ccc->comp));
- continue;
- }
- ccc->type = corba_coc->type;
+ g_warning (G_STRLOC ": Unable to contact backend");
- list = g_list_prepend (list, ccc);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
+
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
- list = g_list_reverse (list);
+ status = our_op->status;
+ *changes = our_op->list;
- return list;
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
-GList *
-cal_client_get_changes (CalClient *client, CalObjType type, const char *change_id)
+
+/**
+ * cal_client_get_object_list:
+ * @client:
+ * @query:
+ *
+ *
+ *
+ * Return value:
+ **/
+gboolean
+cal_client_get_object_list (CalClient *client, const char *query, GList **objects, GError **error)
{
- CalClientPrivate *priv;
CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalObjChangeSeq *seq;
- int t;
- GList *changes;
+ ECalendarOp *our_op;
+ ECalendarStatus status;
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
+ g_return_val_if_fail (client != NULL, E_CALENDAR_STATUS_INVALID_ARG);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), E_CALENDAR_STATUS_INVALID_ARG);
+ g_return_val_if_fail (query != NULL, E_CALENDAR_STATUS_INVALID_ARG);
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL);
+ e_mutex_lock (client->priv->mutex);
- t = corba_obj_type (type);
- CORBA_exception_init (&ev);
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
- seq = GNOME_Evolution_Calendar_Cal_getChanges (priv->cal, t, change_id, &ev);
- if (BONOBO_EX (&ev)) {
- g_message ("cal_client_get_changes(): could not get the list of changes");
- CORBA_exception_free (&ev);
- return NULL;
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
}
- CORBA_exception_free (&ev);
+ our_op = e_calendar_new_op (client);
- changes = build_change_list (seq);
- CORBA_free (seq);
+ e_mutex_lock (our_op->mutex);
- return changes;
-}
+ e_mutex_unlock (client->priv->mutex);
-/* FIXME: Not used? */
-#if 0
-/* Builds a GList of CalObjInstance structures from the CORBA sequence */
-static GList *
-build_object_instance_list (GNOME_Evolution_Calendar_CalObjInstanceSeq *seq)
-{
- GList *list;
- int i;
+ CORBA_exception_init (&ev);
- /* Create the list in reverse order */
+ GNOME_Evolution_Calendar_Cal_getObjectList (client->priv->cal, query, &ev);
- list = NULL;
- for (i = 0; i < seq->_length; i++) {
- GNOME_Evolution_Calendar_CalObjInstance *corba_icoi;
- CalObjInstance *icoi;
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- corba_icoi = &seq->_buffer[i];
- icoi = g_new (CalObjInstance, 1);
+ CORBA_exception_free (&ev);
- icoi->uid = g_strdup (corba_icoi->uid);
- icoi->start = corba_icoi->start;
- icoi->end = corba_icoi->end;
+ g_warning (G_STRLOC ": Unable to contact backend");
- list = g_list_prepend (list, icoi);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
+
+ CORBA_exception_free (&ev);
- list = g_list_reverse (list);
- return list;
-}
-#endif
-
-/**
- * cal_client_get_objects_in_range:
- * @client: A calendar client.
- * @type: Bitmask with types of objects to return.
- * @start: Start time for query.
- * @end: End time for query.
- *
- * Queries a calendar for the objects that occur or recur in the specified range
- * of time.
- *
- * Return value: A list of UID strings. This should be freed using the
- * cal_obj_uid_list_free() function.
- **/
-GList *
-cal_client_get_objects_in_range (CalClient *client, CalObjType type, time_t start, time_t end)
-{
- CalClientPrivate *priv;
- CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalObjUIDSeq *seq;
- GList *uids;
- int t;
-
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL);
+ status = our_op->status;
+ *objects = our_op->list;
- g_return_val_if_fail (start != -1 && end != -1, NULL);
- g_return_val_if_fail (start <= end, NULL);
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- CORBA_exception_init (&ev);
-
- t = corba_obj_type (type);
+ E_CALENDAR_CHECK_STATUS (status, error);
+}
- seq = GNOME_Evolution_Calendar_Cal_getObjectsInRange (priv->cal, t, start, end, &ev);
- if (BONOBO_EX (&ev)) {
- g_message ("cal_client_get_objects_in_range(): could not get the objects");
- CORBA_exception_free (&ev);
- return NULL;
+gboolean
+cal_client_get_object_list_as_comp (CalClient *client, const char *query, GList **objects, GError **error)
+{
+ GList *ical_objects = NULL;
+ GList *l;
+
+ g_return_val_if_fail (client != NULL, E_CALENDAR_STATUS_INVALID_ARG);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), E_CALENDAR_STATUS_INVALID_ARG);
+ g_return_val_if_fail (query != NULL, E_CALENDAR_STATUS_INVALID_ARG);
+ g_return_val_if_fail (objects != NULL, E_CALENDAR_STATUS_INVALID_ARG);
+
+ if (!cal_client_get_object_list (client, query, &ical_objects, error))
+ return FALSE;
+
+ *objects = NULL;
+ for (l = ical_objects; l; l = l->next) {
+ CalComponent *comp;
+
+ comp = cal_component_new ();
+ cal_component_set_icalcomponent (comp, l->data);
+ *objects = g_list_prepend (*objects, comp);
}
- CORBA_exception_free (&ev);
+
+ g_list_free (ical_objects);
- uids = build_uid_list (seq);
- CORBA_free (seq);
+ return TRUE;
+}
+
+void
+cal_client_free_object_list (GList *objects)
+{
+ GList *l;
+
+ for (l = objects; l; l = l->next)
+ icalcomponent_free (l->data);
- return uids;
+ g_list_free (objects);
}
/**
@@ -1833,57 +2421,81 @@ cal_client_get_objects_in_range (CalClient *client, CalObjType type, time_t star
*
* Returns: a GList of VFREEBUSY CalComponents
*/
-GList *
-cal_client_get_free_busy (CalClient *client, GList *users,
- time_t start, time_t end)
+gboolean
+cal_client_get_free_busy (CalClient *client, GList *users, time_t start, time_t end,
+ GList **freebusy, GError **error)
{
- CalClientPrivate *priv;
CORBA_Environment ev;
- GNOME_Evolution_Calendar_UserList *corba_list;
- GNOME_Evolution_Calendar_CalObjSeq *calobj_list;
+ ECalendarOp *our_op;
+ ECalendarStatus status;
+ GNOME_Evolution_Calendar_UserList corba_users;
GList *l;
- GList *comp_list = NULL;
- int len, i;
+ int i, len;
+
+ g_return_val_if_fail (client != NULL, E_CALENDAR_STATUS_INVALID_ARG);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), E_CALENDAR_STATUS_INVALID_ARG);
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
+ e_mutex_lock (client->priv->mutex);
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL);
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
- g_return_val_if_fail (start != -1 && end != -1, NULL);
- g_return_val_if_fail (start <= end, NULL);
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
/* create the CORBA user list to be passed to the backend */
len = g_list_length (users);
- corba_list = GNOME_Evolution_Calendar_UserList__alloc ();
- CORBA_sequence_set_release (corba_list, TRUE);
- corba_list->_length = len;
- corba_list->_buffer = CORBA_sequence_GNOME_Evolution_Calendar_User_allocbuf (len);
+ corba_users._length = len;
+ corba_users._buffer = CORBA_sequence_GNOME_Evolution_Calendar_User_allocbuf (len);
- for (l = g_list_first (users), i = 0; l; l = l->next, i++)
- corba_list->_buffer[i] = CORBA_string_dup ((CORBA_char *) l->data);
+ for (l = users, i = 0; l; l = l->next, i++)
+ corba_users._buffer[i] = CORBA_string_dup (l->data);
- /* call the method on the backend */
CORBA_exception_init (&ev);
- calobj_list = GNOME_Evolution_Calendar_Cal_getFreeBusy (priv->cal, corba_list,
- start, end, &ev);
- CORBA_free (corba_list);
- if (BONOBO_EX (&ev) || !calobj_list) {
- if (!BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
- g_message ("cal_client_get_free_busy(): could not get the objects");
+ GNOME_Evolution_Calendar_Cal_getFreeBusy (client->priv->cal, &corba_users, start, end, &ev);
+
+ CORBA_free (corba_users._buffer);
+
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
CORBA_exception_free (&ev);
- return NULL;
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
+
+ CORBA_exception_free (&ev);
- for (i = 0; i < calobj_list->_length; i++) {
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+
+ *freebusy = NULL;
+ for (l = our_op->list; l; l = l->next) {
CalComponent *comp;
+
icalcomponent *icalcomp;
icalcomponent_kind kind;
- icalcomp = icalparser_parse_string (calobj_list->_buffer[i]);
+ icalcomp = icalparser_parse_string (l->data);
if (!icalcomp)
continue;
@@ -1896,184 +2508,17 @@ cal_client_get_free_busy (CalClient *client, GList *users,
continue;
}
- comp_list = g_list_append (comp_list, comp);
+ *freebusy = g_list_append (*freebusy, comp);
}
else
icalcomponent_free (icalcomp);
}
- CORBA_exception_free (&ev);
- CORBA_free (calobj_list);
-
- return comp_list;
-}
-
-/* Callback used when an object is updated and we must update the copy we have */
-static void
-generate_instances_obj_updated_cb (CalClient *client, const char *uid, gpointer data)
-{
- GHashTable *uid_comp_hash;
- CalComponent *comp;
- icalcomponent *icalcomp;
- CalClientGetStatus status;
- const char *comp_uid;
-
- uid_comp_hash = data;
-
- comp = g_hash_table_lookup (uid_comp_hash, uid);
- if (!comp)
- /* OK, so we don't care about new objects that may indeed be in
- * the requested time range. We only care about the ones that
- * were returned by the first query to
- * cal_client_get_objects_in_range().
- */
- return;
-
- g_hash_table_remove (uid_comp_hash, uid);
- g_object_unref (G_OBJECT (comp));
-
- status = cal_client_get_object (client, uid, &icalcomp);
-
- switch (status) {
- case CAL_CLIENT_GET_SUCCESS:
- comp = cal_component_new ();
- if (cal_component_set_icalcomponent (comp, icalcomp)) {
- /* The hash key comes from the component's internal data */
- cal_component_get_uid (comp, &comp_uid);
- g_hash_table_insert (uid_comp_hash, (char *) comp_uid, comp);
- } else {
- g_object_unref (comp);
- icalcomponent_free (icalcomp);
- }
- break;
-
- case CAL_CLIENT_GET_NOT_FOUND:
- /* No longer in the server, too bad */
- break;
-
- case CAL_CLIENT_GET_SYNTAX_ERROR:
- g_message ("obj_updated_cb(): Syntax error when getting "
- "object `%s'; ignoring...", uid);
- break;
-
- }
-}
-
-/* Callback used when an object is removed and we must delete the copy we have */
-static void
-generate_instances_obj_removed_cb (CalClient *client, const char *uid, gpointer data)
-{
- GHashTable *uid_comp_hash;
- CalComponent *comp;
-
- uid_comp_hash = data;
-
- comp = g_hash_table_lookup (uid_comp_hash, uid);
- if (!comp)
- return;
-
- g_hash_table_remove (uid_comp_hash, uid);
- g_object_unref (G_OBJECT (comp));
-}
-
-/* Adds a component to the list; called from g_hash_table_foreach() */
-static void
-add_component (gpointer key, gpointer value, gpointer data)
-{
- CalComponent *comp;
- GList **list;
-
- comp = CAL_COMPONENT (value);
- list = data;
-
- *list = g_list_prepend (*list, comp);
-}
-
-/* Gets a list of components that recur within the specified range of time. It
- * ensures that the resulting list of CalComponent objects contains only objects
- * that are actually in the server at the time the initial
- * cal_client_get_objects_in_range() query ends.
- */
-static GList *
-get_objects_atomically (CalClient *client, CalObjType type, time_t start, time_t end)
-{
- GList *uids;
- GHashTable *uid_comp_hash;
- GList *objects;
- guint obj_updated_id;
- guint obj_removed_id;
- GList *l;
-
- uids = cal_client_get_objects_in_range (client, type, start, end);
-
- uid_comp_hash = g_hash_table_new (g_str_hash, g_str_equal);
-
- /* While we are getting the actual object data, keep track of changes */
-
- obj_updated_id = g_signal_connect (G_OBJECT (client), "obj_updated",
- G_CALLBACK (generate_instances_obj_updated_cb),
- uid_comp_hash);
-
- obj_removed_id = g_signal_connect (G_OBJECT (client), "obj_removed",
- G_CALLBACK (generate_instances_obj_removed_cb),
- uid_comp_hash);
-
- /* Get the objects */
-
- for (l = uids; l; l = l->next) {
- CalComponent *comp;
- icalcomponent *icalcomp;
- CalClientGetStatus status;
- char *uid;
- const char *comp_uid;
-
- uid = l->data;
-
- status = cal_client_get_object (client, uid, &icalcomp);
-
- switch (status) {
- case CAL_CLIENT_GET_SUCCESS:
- comp = cal_component_new ();
- if (cal_component_set_icalcomponent (comp, icalcomp)) {
- /* The hash key comes from the component's internal data
- * instead of the duped UID from the list of UIDS.
- */
- cal_component_get_uid (comp, &comp_uid);
- g_hash_table_insert (uid_comp_hash, (char *) comp_uid, comp);
- } else {
- g_object_unref (comp);
- icalcomponent_free (icalcomp);
- }
- break;
-
- case CAL_CLIENT_GET_NOT_FOUND:
- /* Object disappeared from the server, so don't log it */
- break;
-
- case CAL_CLIENT_GET_SYNTAX_ERROR:
- g_message ("get_objects_atomically(): Syntax error when getting "
- "object `%s'; ignoring...", uid);
- break;
-
- default:
- g_assert_not_reached ();
- }
- }
-
- cal_obj_uid_list_free (uids);
-
- /* Now our state is consistent with the server, so disconnect from the
- * notification signals and generate the final list of components.
- */
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- g_signal_handler_disconnect (client, obj_updated_id);
- g_signal_handler_disconnect (client, obj_removed_id);
-
- objects = NULL;
- g_hash_table_foreach (uid_comp_hash, add_component, &objects);
- g_hash_table_destroy (uid_comp_hash);
-
- return objects;
+ E_CALENDAR_CHECK_STATUS (status, error);
}
struct comp_instance {
@@ -2127,10 +2572,8 @@ compare_comp_instance (gconstpointer a, gconstpointer b)
* @cb: Callback for each generated instance.
* @cb_data: Closure data for the callback.
*
- * Does a combination of cal_client_get_objects_in_range() and
- * cal_recur_generate_instances(). It fetches the list of objects in an atomic
- * way so that the generated instances are actually in the server at the time
- * the initial cal_client_get_objects_in_range() query ends.
+ * Does a combination of cal_client_get_object_list () and
+ * cal_recur_generate_instances().
*
* The callback function should do a g_object_ref() of the calendar component
* it gets passed if it intends to keep it around.
@@ -2144,7 +2587,8 @@ cal_client_generate_instances (CalClient *client, CalObjType type,
GList *objects;
GList *instances;
GList *l;
-
+ char *query;
+
g_return_if_fail (client != NULL);
g_return_if_fail (IS_CAL_CLIENT (client));
@@ -2156,8 +2600,13 @@ cal_client_generate_instances (CalClient *client, CalObjType type,
g_return_if_fail (cb != NULL);
/* Generate objects */
+ query = g_strdup_printf ("(occur-in-time-range? (%lu) (%lu))", start, end);
+ if (!cal_client_get_object_list (client, query, &objects, NULL)) {
+ g_free (query);
+ return;
+ }
+ g_free (query);
- objects = get_objects_atomically (client, type, start, end);
instances = NULL;
for (l = objects; l; l = l->next) {
@@ -2201,64 +2650,22 @@ cal_client_generate_instances (CalClient *client, CalObjType type,
g_list_free (instances);
}
-/* Builds a list of CalAlarmInstance structures */
-static GSList *
-build_alarm_instance_list (CalComponent *comp, GNOME_Evolution_Calendar_CalAlarmInstanceSeq *seq)
-{
- GSList *alarms;
- int i;
-
- alarms = NULL;
-
- for (i = 0; i < seq->_length; i++) {
- GNOME_Evolution_Calendar_CalAlarmInstance *corba_instance;
- CalComponentAlarm *alarm;
- const char *auid;
- CalAlarmInstance *instance;
-
- corba_instance = seq->_buffer + i;
-
- /* Since we want the in-commponent auid, we look for the alarm
- * in the component and fetch its "real" auid.
- */
-
- alarm = cal_component_get_alarm (comp, corba_instance->auid);
- if (!alarm)
- continue;
-
- auid = cal_component_alarm_get_uid (alarm);
- cal_component_alarm_free (alarm);
-
- instance = g_new (CalAlarmInstance, 1);
- instance->auid = auid;
- instance->trigger = corba_instance->trigger;
- instance->occur_start = corba_instance->occur_start;
- instance->occur_end = corba_instance->occur_end;
-
- alarms = g_slist_prepend (alarms, instance);
- }
-
- return g_slist_reverse (alarms);
-}
-
/* Builds a list of CalComponentAlarms structures */
static GSList *
-build_component_alarms_list (GNOME_Evolution_Calendar_CalComponentAlarmsSeq *seq)
+build_component_alarms_list (CalClient *client, GList *object_list, time_t start, time_t end)
{
GSList *comp_alarms;
- int i;
+ GList *l;
comp_alarms = NULL;
- for (i = 0; i < seq->_length; i++) {
- GNOME_Evolution_Calendar_CalComponentAlarms *corba_alarms;
+ for (l = object_list; l != NULL; l = l->next) {
CalComponent *comp;
CalComponentAlarms *alarms;
icalcomponent *icalcomp;
+ CalAlarmAction omit[] = {-1};
- corba_alarms = seq->_buffer + i;
-
- icalcomp = icalparser_parse_string (corba_alarms->calobj);
+ icalcomp = icalparser_parse_string (l->data);
if (!icalcomp)
continue;
@@ -2269,11 +2676,10 @@ build_component_alarms_list (GNOME_Evolution_Calendar_CalComponentAlarmsSeq *seq
continue;
}
- alarms = g_new (CalComponentAlarms, 1);
- alarms->comp = comp;
- alarms->alarms = build_alarm_instance_list (comp, &corba_alarms->alarms);
-
- comp_alarms = g_slist_prepend (comp_alarms, alarms);
+ alarms = cal_util_generate_alarms_for_comp (comp, start, end, omit, cal_client_resolve_tzid_cb,
+ icalcomp, client->priv->default_zone);
+ if (alarms)
+ comp_alarms = g_slist_prepend (comp_alarms, alarms);
}
return comp_alarms;
@@ -2297,9 +2703,9 @@ GSList *
cal_client_get_alarms_in_range (CalClient *client, time_t start, time_t end)
{
CalClientPrivate *priv;
- CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalComponentAlarmsSeq *seq;
GSList *alarms;
+ char *sexp;
+ GList *object_list = NULL;
g_return_val_if_fail (client != NULL, NULL);
g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
@@ -2310,18 +2716,20 @@ cal_client_get_alarms_in_range (CalClient *client, time_t start, time_t end)
g_return_val_if_fail (start != -1 && end != -1, NULL);
g_return_val_if_fail (start <= end, NULL);
- CORBA_exception_init (&ev);
+ /* build the query string */
+ sexp = g_strdup ("(and (has-alarms? #t))");
- seq = GNOME_Evolution_Calendar_Cal_getAlarmsInRange (priv->cal, start, end, &ev);
- if (BONOBO_EX (&ev)) {
- g_message ("cal_client_get_alarms_in_range(): could not get the alarm range");
- CORBA_exception_free (&ev);
+ /* execute the query on the server */
+ if (!cal_client_get_object_list (client, sexp, &object_list, NULL)) {
+ g_free (sexp);
return NULL;
}
- CORBA_exception_free (&ev);
- alarms = build_component_alarms_list (seq);
- CORBA_free (seq);
+ alarms = build_component_alarms_list (client, object_list, start, end);
+
+ g_list_foreach (object_list, (GFunc) g_free, NULL);
+ g_list_free (object_list);
+ g_free (sexp);
return alarms;
}
@@ -2371,11 +2779,9 @@ cal_client_get_alarms_for_object (CalClient *client, const char *uid,
CalComponentAlarms **alarms)
{
CalClientPrivate *priv;
- CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalComponentAlarms *corba_alarms;
- gboolean retval;
icalcomponent *icalcomp;
CalComponent *comp;
+ CalAlarmAction omit[] = {-1};
g_return_val_if_fail (client != NULL, FALSE);
g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
@@ -2389,40 +2795,23 @@ cal_client_get_alarms_for_object (CalClient *client, const char *uid,
g_return_val_if_fail (alarms != NULL, FALSE);
*alarms = NULL;
- retval = FALSE;
-
- CORBA_exception_init (&ev);
-
- corba_alarms = GNOME_Evolution_Calendar_Cal_getAlarmsForObject (priv->cal, (char *) uid,
- start, end, &ev);
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
- goto out;
- else if (BONOBO_EX (&ev)) {
- g_message ("cal_client_get_alarms_for_object(): could not get the alarm range");
- goto out;
- }
- icalcomp = icalparser_parse_string (corba_alarms->calobj);
+ if (!cal_client_get_object (client, uid, NULL, &icalcomp, NULL))
+ return FALSE;
if (!icalcomp)
- goto out;
+ return FALSE;
comp = cal_component_new ();
if (!cal_component_set_icalcomponent (comp, icalcomp)) {
icalcomponent_free (icalcomp);
g_object_unref (G_OBJECT (comp));
- goto out;
+ return FALSE;
}
- retval = TRUE;
-
- *alarms = g_new (CalComponentAlarms, 1);
- (*alarms)->comp = comp;
- (*alarms)->alarms = build_alarm_instance_list (comp, &corba_alarms->alarms);
- CORBA_free (corba_alarms);
+ *alarms = cal_util_generate_alarms_for_comp (comp, start, end, omit, cal_client_resolve_tzid_cb,
+ icalcomp, priv->default_zone);
- out:
- CORBA_exception_free (&ev);
- return retval;
+ return TRUE;
}
/**
@@ -2439,33 +2828,68 @@ cal_client_get_alarms_for_object (CalClient *client, const char *uid,
* Return value: a #CalClientResult value indicating the result of the
* operation.
*/
-CalClientResult
-cal_client_discard_alarm (CalClient *client, CalComponent *comp, const char *auid)
+gboolean
+cal_client_discard_alarm (CalClient *client, CalComponent *comp, const char *auid, GError **error)
{
CalClientPrivate *priv;
- CalClientResult retval;
CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
const char *uid;
-
- g_return_val_if_fail (IS_CAL_CLIENT (client), CAL_CLIENT_RESULT_NOT_FOUND);
- g_return_val_if_fail (IS_CAL_COMPONENT (comp), CAL_CLIENT_RESULT_NOT_FOUND);
- g_return_val_if_fail (auid != NULL, CAL_CLIENT_RESULT_NOT_FOUND);
+
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
priv = client->priv;
+ e_mutex_lock (client->priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
+
cal_component_get_uid (comp, &uid);
CORBA_exception_init (&ev);
+
GNOME_Evolution_Calendar_Cal_discardAlarm (priv->cal, uid, auid, &ev);
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
- retval = CAL_CLIENT_RESULT_NOT_FOUND;
- else if (BONOBO_EX (&ev))
- retval = CAL_CLIENT_RESULT_CORBA_ERROR;
- else
- retval = CAL_CLIENT_RESULT_SUCCESS;
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
CORBA_exception_free (&ev);
- return retval;
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
typedef struct _ForeachTZIDCallbackData ForeachTZIDCallbackData;
@@ -2500,10 +2924,7 @@ foreach_tzid_callback (icalparameter *param, void *cbdata)
return;
if (data->include_all_timezones) {
- CalClientGetStatus status;
-
- status = cal_client_get_timezone (data->client, tzid, &zone);
- if (status != CAL_CLIENT_GET_SUCCESS) {
+ if (!cal_client_get_timezone (data->client, tzid, &zone, NULL)) {
data->success = FALSE;
return;
}
@@ -2642,163 +3063,192 @@ cal_client_get_component_as_string (CalClient *client, icalcomponent *icalcomp)
return cal_client_get_component_as_string_internal (client, icalcomp, TRUE);
}
-CalClientResult
-cal_client_update_object_with_mod (CalClient *client, CalComponent *comp, CalObjModType mod)
+gboolean
+cal_client_create_object (CalClient *client, icalcomponent *icalcomp, char **uid, GError **error)
{
CalClientPrivate *priv;
CORBA_Environment ev;
- CalClientResult retval;
- char *obj_string;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
- g_return_val_if_fail (client != NULL, CAL_CLIENT_RESULT_INVALID_OBJECT);
- g_return_val_if_fail (IS_CAL_CLIENT (client), CAL_CLIENT_RESULT_INVALID_OBJECT);
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, CAL_CLIENT_RESULT_INVALID_OBJECT);
- g_return_val_if_fail (comp != NULL, CAL_CLIENT_RESULT_INVALID_OBJECT);
+ e_mutex_lock (client->priv->mutex);
- cal_component_commit_sequence (comp);
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
- obj_string = cal_client_get_component_as_string_internal (client,
- cal_component_get_icalcomponent (comp),
- FALSE);
- if (obj_string == NULL)
- return CAL_CLIENT_RESULT_INVALID_OBJECT;
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
CORBA_exception_init (&ev);
- GNOME_Evolution_Calendar_Cal_updateObjects (priv->cal, obj_string, mod, &ev);
- g_free (obj_string);
-
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_InvalidObject))
- retval = CAL_CLIENT_RESULT_INVALID_OBJECT;
- else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
- retval = CAL_CLIENT_RESULT_NOT_FOUND;
- else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_PermissionDenied))
- retval = CAL_CLIENT_RESULT_PERMISSION_DENIED;
- else if (BONOBO_EX (&ev)) {
- g_message ("cal_client_update_object(): could not update the object");
- retval = CAL_CLIENT_RESULT_CORBA_ERROR;
+
+ GNOME_Evolution_Calendar_Cal_createObject (priv->cal, icalcomponent_as_ical_string (icalcomp), &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
- else
- retval = CAL_CLIENT_RESULT_SUCCESS;
CORBA_exception_free (&ev);
- return retval;
-}
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
-/**
- * cal_client_update_object:
- * @client: A calendar client.
- * @comp: A calendar component object.
- *
- * Asks a calendar to update a component. Any existing component with the
- * specified component's UID will be replaced. The client program should not
- * assume that the object is actually in the server's storage until it has
- * received the "obj_updated" notification signal.
- *
- * Return value: a #CalClientResult value indicating the result of the
- * operation.
- **/
-CalClientResult
-cal_client_update_object (CalClient *client, CalComponent *comp)
-{
+ status = our_op->status;
+ if (uid)
+ *uid = our_op->uid;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
- return cal_client_update_object_with_mod (client, comp, CALOBJ_MOD_ALL);
+ E_CALENDAR_CHECK_STATUS (status, error);
}
-/**
- * cal_client_update_objects:
- * @client: A calendar client.
- * @icalcomp: A toplevel VCALENDAR libical component.
- *
- * Asks a calendar to add or update one or more components, possibly including
- * VTIMEZONE data. Any existing components with the same UIDs will be
- * replaced. The VTIMEZONE data will be compared to existing VTIMEZONEs in
- * the calendar, and the VTIMEZONEs may possibly be renamed, as well as all
- * references to them throughout the VCALENDAR.
- *
- * The client program should not assume that the objects are actually in the
- * server's storage until it has received the "obj_updated" notification
- * signal.
- *
- * Return value: a #CalClientResult value indicating the result of the
- * operation.
- **/
-CalClientResult
-cal_client_update_objects (CalClient *client, icalcomponent *icalcomp)
+gboolean
+cal_client_modify_object (CalClient *client, icalcomponent *icalcomp, CalObjModType mod, GError **error)
{
CalClientPrivate *priv;
CORBA_Environment ev;
- CalClientResult retval;
- char *obj_string;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
- g_return_val_if_fail (client != NULL, CAL_CLIENT_RESULT_INVALID_OBJECT);
- g_return_val_if_fail (IS_CAL_CLIENT (client), CAL_CLIENT_RESULT_INVALID_OBJECT);
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
+ g_return_val_if_fail (icalcomp != NULL, FALSE);
priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED,
- CAL_CLIENT_RESULT_INVALID_OBJECT);
- g_return_val_if_fail (icalcomp != NULL, CAL_CLIENT_RESULT_INVALID_OBJECT);
+ e_mutex_lock (client->priv->mutex);
- /* Libical owns this memory, using one of its temporary buffers. */
- obj_string = icalcomponent_as_ical_string (icalcomp);
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
CORBA_exception_init (&ev);
- GNOME_Evolution_Calendar_Cal_updateObjects (priv->cal, obj_string, GNOME_Evolution_Calendar_MOD_ALL, &ev);
-
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_InvalidObject))
- retval = CAL_CLIENT_RESULT_INVALID_OBJECT;
- else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
- retval = CAL_CLIENT_RESULT_NOT_FOUND;
- else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_PermissionDenied))
- retval = CAL_CLIENT_RESULT_PERMISSION_DENIED;
- else if (BONOBO_EX (&ev)) {
- g_message ("cal_client_update_objects(): could not update the objects");
- retval = CAL_CLIENT_RESULT_CORBA_ERROR;
+
+ GNOME_Evolution_Calendar_Cal_modifyObject (priv->cal, icalcomponent_as_ical_string (icalcomp), mod, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
- else
- retval = CAL_CLIENT_RESULT_SUCCESS;
CORBA_exception_free (&ev);
- return retval;
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
-CalClientResult
-cal_client_remove_object_with_mod (CalClient *client, const char *uid, CalObjModType mod)
+gboolean
+cal_client_remove_object_with_mod (CalClient *client, const char *uid,
+ const char *rid, CalObjModType mod, GError **error)
{
CalClientPrivate *priv;
CORBA_Environment ev;
- CalClientResult retval;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
- g_return_val_if_fail (client != NULL, CAL_CLIENT_RESULT_INVALID_OBJECT);
- g_return_val_if_fail (IS_CAL_CLIENT (client), CAL_CLIENT_RESULT_INVALID_OBJECT);
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, CAL_CLIENT_RESULT_INVALID_OBJECT);
- g_return_val_if_fail (uid != NULL, CAL_CLIENT_RESULT_NOT_FOUND);
+ e_mutex_lock (client->priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
+
CORBA_exception_init (&ev);
- GNOME_Evolution_Calendar_Cal_removeObject (priv->cal, (char *) uid, mod, &ev);
-
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_InvalidObject))
- retval = CAL_CLIENT_RESULT_INVALID_OBJECT;
- else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
- retval = CAL_CLIENT_RESULT_NOT_FOUND;
- else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_PermissionDenied))
- retval = CAL_CLIENT_RESULT_PERMISSION_DENIED;
- else if (BONOBO_EX (&ev)) {
- g_message ("cal_client_remove_object(): could not remove the object");
- retval = CAL_CLIENT_RESULT_CORBA_ERROR;
+
+ GNOME_Evolution_Calendar_Cal_removeObject (priv->cal, uid, rid ? rid : "", mod, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
}
- else
- retval = CAL_CLIENT_RESULT_SUCCESS;
CORBA_exception_free (&ev);
- return retval;
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
/**
@@ -2813,69 +3263,319 @@ cal_client_remove_object_with_mod (CalClient *client, const char *uid, CalObjMod
* Return value: a #CalClientResult value indicating the result of the
* operation.
**/
-CalClientResult
-cal_client_remove_object (CalClient *client, const char *uid)
+gboolean
+cal_client_remove_object (CalClient *client, const char *uid, GError **error)
{
- return cal_client_remove_object_with_mod (client, uid, CALOBJ_MOD_ALL);
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
+
+ return cal_client_remove_object_with_mod (client, uid, NULL, CALOBJ_MOD_ALL, error);
}
-CalClientResult
-cal_client_send_object (CalClient *client, icalcomponent *icalcomp,
- icalcomponent **new_icalcomp, GList **users,
- char **error_msg)
+gboolean
+cal_client_receive_objects (CalClient *client, icalcomponent *icalcomp, GError **error)
{
CalClientPrivate *priv;
CORBA_Environment ev;
- CalClientResult retval;
- GNOME_Evolution_Calendar_UserList *user_list;
- char *obj_string;
- int i;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
+
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
+
+ priv = client->priv;
+
+ e_mutex_lock (client->priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
+
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Calendar_Cal_receiveObjects (priv->cal, icalcomponent_as_ical_string (icalcomp), &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
+
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
- g_return_val_if_fail (client != NULL, CAL_CLIENT_RESULT_INVALID_OBJECT);
- g_return_val_if_fail (IS_CAL_CLIENT (client), CAL_CLIENT_RESULT_INVALID_OBJECT);
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
+}
+
+gboolean
+cal_client_send_objects (CalClient *client, icalcomponent *icalcomp, GError **error)
+{
+ CalClientPrivate *priv;
+ CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
+
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED,
- CAL_CLIENT_RESULT_INVALID_OBJECT);
- g_return_val_if_fail (icalcomp != NULL, CAL_CLIENT_RESULT_INVALID_OBJECT);
+ e_mutex_lock (client->priv->mutex);
- /* Libical owns this memory, using one of its temporary buffers. */
- obj_string = icalcomponent_as_ical_string (icalcomp);
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
CORBA_exception_init (&ev);
- obj_string = GNOME_Evolution_Calendar_Cal_sendObject (priv->cal, obj_string, &user_list, &ev);
-
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_InvalidObject)) {
- retval = CAL_CLIENT_SEND_INVALID_OBJECT;
- } else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_Busy)) {
- retval = CAL_CLIENT_SEND_BUSY;
- if (error_msg)
- *error_msg = g_strdup (((GNOME_Evolution_Calendar_Cal_Busy *)(CORBA_exception_value (&ev)))->errorMsg);
- } else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_PermissionDenied)) {
- retval = CAL_CLIENT_SEND_PERMISSION_DENIED;
- } else if (BONOBO_EX (&ev)) {
- g_message ("cal_client_update_objects(): could not send the objects");
- retval = CAL_CLIENT_SEND_CORBA_ERROR;
+
+ GNOME_Evolution_Calendar_Cal_sendObjects (priv->cal, icalcomponent_as_ical_string (icalcomp), &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
+
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
+}
+
+gboolean
+cal_client_get_timezone (CalClient *client, const char *tzid, icaltimezone **zone, GError **error)
+{
+ CalClientPrivate *priv;
+ CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
+ icalcomponent *icalcomp;
+
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
+ g_return_val_if_fail (tzid != NULL, FALSE);
+
+ priv = client->priv;
+
+ e_mutex_lock (priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (priv->mutex);
+
+ /* Check for well known zones and in the cache */
+ *zone = NULL;
+
+ /* If tzid is NULL or "" we return NULL, since it is a 'local time'. */
+ if (!tzid || !tzid[0]) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
+ }
+
+ /* If it is UTC, we return the special UTC timezone. */
+ if (!strcmp (tzid, "UTC")) {
+ *zone = icaltimezone_get_utc_timezone ();
} else {
- retval = CAL_CLIENT_RESULT_SUCCESS;
-
- *new_icalcomp = icalparser_parse_string (obj_string);
- CORBA_free (obj_string);
-
- if (*new_icalcomp == NULL) {
- retval = CAL_CLIENT_RESULT_INVALID_OBJECT;
- } else {
- *users = NULL;
- for (i = 0; i < user_list->_length; i++)
- *users = g_list_append (*users, g_strdup (user_list->_buffer[i]));
- CORBA_free (user_list);
- }
+ /* See if we already have it in the cache. */
+ *zone = g_hash_table_lookup (priv->timezones, tzid);
+ }
+
+ if (*zone) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
}
+ /* call the backend */
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Calendar_Cal_getTimezone (priv->cal, tzid, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
+
CORBA_exception_free (&ev);
- return retval;
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+
+ icalcomp = icalparser_parse_string (our_op->string);
+ g_free (our_op->string);
+
+ /* FIXME Invalid object status? */
+ if (!icalcomp)
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OBJECT_NOT_FOUND, error);
+
+ *zone = icaltimezone_new ();
+ if (!icaltimezone_set_component (*zone, icalcomp)) {
+ icaltimezone_free (*zone, 1);
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OBJECT_NOT_FOUND, error);
+ }
+
+ /* Now add it to the cache, to avoid the server call in future. */
+ g_hash_table_insert (priv->timezones, icaltimezone_get_tzid (*zone), *zone);
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
+}
+
+/**
+ * cal_client_add_timezone
+ * @client: A calendar client.
+ * @izone: The timezone to add.
+ * @error: Placeholder for error information.
+ *
+ * Add a VTIMEZONE object to the given calendar.
+ *
+ * Returns: TRUE if successful, FALSE otherwise.
+ */
+gboolean
+cal_client_add_timezone (CalClient *client, icaltimezone *izone, GError **error)
+{
+ CalClientPrivate *priv;
+ CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
+ const char *tzobj;
+
+ g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
+ g_return_val_if_fail (izone != NULL, FALSE);
+
+ priv = client->priv;
+
+ e_mutex_lock (priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
+
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (priv->mutex);
+
+ /* convert icaltimezone into a string */
+ tzobj = icalcomponent_as_ical_string (icaltimezone_get_component (izone));
+
+ /* call the backend */
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Calendar_Cal_addTimezone (priv->cal, tzobj, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
+
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
/**
@@ -2888,20 +3588,68 @@ cal_client_send_object (CalClient *client, icalcomponent *icalcomp,
* Return value: A query object that will emit notification signals as calendar
* components are added and removed from the query in the server.
**/
-CalQuery *
-cal_client_get_query (CalClient *client, const char *sexp)
+gboolean
+cal_client_get_query (CalClient *client, const char *sexp, CalQuery **query, GError **error)
{
- CalClientPrivate *priv;
+ CORBA_Environment ev;
+ ECalendarOp *our_op;
+ ECalendarStatus status;
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
+ g_return_val_if_fail (client != NULL, E_CALENDAR_STATUS_INVALID_ARG);
+ g_return_val_if_fail (IS_CAL_CLIENT (client), E_CALENDAR_STATUS_INVALID_ARG);
+ g_return_val_if_fail (query != NULL, E_CALENDAR_STATUS_INVALID_ARG);
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, FALSE);
+ e_mutex_lock (client->priv->mutex);
+
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
+ }
- g_return_val_if_fail (sexp != NULL, NULL);
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (client->priv->mutex);
+
+ CORBA_exception_init (&ev);
+
+ our_op->listener = query_listener_new ();
+ GNOME_Evolution_Calendar_Cal_getQuery (client->priv->cal, sexp, BONOBO_OBJREF (our_op->listener), &ev);
- return cal_query_new (client, priv->cal, sexp);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
+
+ CORBA_exception_free (&ev);
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+ *query = our_op->query;
+
+ bonobo_object_unref (BONOBO_OBJECT (our_op->listener));
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
@@ -2910,19 +3658,16 @@ cal_client_get_query (CalClient *client, const char *sexp)
DATE-TIME values into specific times. (Most of our IDL interface uses
time_t values to pass specific times from the server to the client.) */
static gboolean
-cal_client_ensure_timezone_on_server (CalClient *client, icaltimezone *zone)
+cal_client_ensure_timezone_on_server (CalClient *client, icaltimezone *zone, GError **error)
{
CalClientPrivate *priv;
- char *tzid, *obj_string;
+ char *tzid;
icaltimezone *tmp_zone;
- GString *vcal_string;
- gboolean retval = FALSE;
- icalcomponent *vtimezone_comp;
- char *vtimezone_as_string;
- CORBA_Environment ev;
priv = client->priv;
+ /* FIXME This is highly broken since there is no locking */
+
/* If the zone is NULL or UTC we don't need to do anything. */
if (!zone)
return TRUE;
@@ -2940,89 +3685,128 @@ cal_client_ensure_timezone_on_server (CalClient *client, icaltimezone *zone)
/* Now we have to send it to the server, in case it doesn't already
have it. */
-
- vcal_string = g_string_new (NULL);
- g_string_append (vcal_string,
- "BEGIN:VCALENDAR\n"
- "PRODID:-//Ximian//NONSGML Evolution Calendar//EN\n"
- "VERSION:2.0\n");
-
- /* Convert the timezone to a string and add it. */
- vtimezone_comp = icaltimezone_get_component (zone);
- if (!vtimezone_comp) {
- g_string_free (vcal_string, TRUE);
- return FALSE;
- }
-
- /* We don't need to free this string as libical owns it. */
- vtimezone_as_string = icalcomponent_as_ical_string (vtimezone_comp);
- g_string_append (vcal_string, vtimezone_as_string);
-
- g_string_append (vcal_string, "END:VCALENDAR\n");
-
- obj_string = vcal_string->str;
- g_string_free (vcal_string, FALSE);
-
- CORBA_exception_init (&ev);
- GNOME_Evolution_Calendar_Cal_updateObjects (priv->cal, obj_string, GNOME_Evolution_Calendar_MOD_ALL, &ev);
- g_free (obj_string);
-
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_InvalidObject))
- goto out;
- else if (BONOBO_EX (&ev)) {
- g_message ("cal_client_ensure_timezone_on_server(): could not add the timezone to the server");
- goto out;
- }
-
- retval = TRUE;
-
- out:
- CORBA_exception_free (&ev);
- return retval;
+ return cal_client_add_timezone (client, zone, error);
}
-
gboolean
-cal_client_set_default_timezone (CalClient *client, icaltimezone *zone)
+cal_client_set_default_timezone (CalClient *client, icaltimezone *zone, GError **error)
{
CalClientPrivate *priv;
- gboolean retval = FALSE;
CORBA_Environment ev;
+ ECalendarStatus status;
+ ECalendarOp *our_op;
const char *tzid;
-
- g_return_val_if_fail (client != NULL, FALSE);
+
g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
g_return_val_if_fail (zone != NULL, FALSE);
priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED,
- FALSE);
-
/* Make sure the server has the VTIMEZONE data. */
- if (!cal_client_ensure_timezone_on_server (client, zone))
+ if (!cal_client_ensure_timezone_on_server (client, zone, error))
return FALSE;
- /* Now set the default timezone on the server. */
- CORBA_exception_init (&ev);
- tzid = icaltimezone_get_tzid (zone);
- GNOME_Evolution_Calendar_Cal_setDefaultTimezone (priv->cal,
- (char *) tzid, &ev);
+ e_mutex_lock (priv->mutex);
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound))
- goto out;
- else if (BONOBO_EX (&ev)) {
- g_message ("cal_client_set_default_timezone(): could not set the default timezone");
- goto out;
+ if (client->priv->load_state != CAL_CLIENT_LOAD_LOADED) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_URI_NOT_LOADED, error);
}
- retval = TRUE;
+ if (client->priv->current_op != NULL) {
+ e_mutex_unlock (client->priv->mutex);
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_BUSY, error);
+ }
+
+ our_op = e_calendar_new_op (client);
+
+ e_mutex_lock (our_op->mutex);
+
+ e_mutex_unlock (priv->mutex);
- priv->default_zone = zone;
+ /* FIXME Adding it to the server to change the tzid */
+ tzid = icaltimezone_get_tzid (zone);
+
+ /* call the backend */
+ CORBA_exception_init (&ev);
- out:
+ GNOME_Evolution_Calendar_Cal_setDefaultTimezone (priv->cal, tzid, &ev);
+ if (BONOBO_EX (&ev)) {
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ CORBA_exception_free (&ev);
+
+ g_warning (G_STRLOC ": Unable to contact backend");
+
+ E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_CORBA_EXCEPTION, error);
+ }
CORBA_exception_free (&ev);
- return retval;
+
+ /* wait for something to happen (both cancellation and a
+ successful response will notity us via our cv */
+ e_mutex_cond_wait (&our_op->cond, our_op->mutex);
+
+ status = our_op->status;
+
+ e_calendar_remove_op (client, our_op);
+ e_mutex_unlock (our_op->mutex);
+ e_calendar_free_op (our_op);
+
+ E_CALENDAR_CHECK_STATUS (status, error);
}
+/**
+ * cal_client_get_error_message
+ * @status: A status code.
+ *
+ * Get an error message for the given status code.
+ *
+ * Returns: the error message.
+ */
+const char *
+cal_client_get_error_message (ECalendarStatus status)
+{
+ switch (status) {
+ case E_CALENDAR_STATUS_INVALID_ARG :
+ return _("Invalid argument");
+ case E_CALENDAR_STATUS_BUSY :
+ return _("Backend is busy");
+ case E_CALENDAR_STATUS_REPOSITORY_OFFLINE :
+ return _("Repository is offline");
+ case E_CALENDAR_STATUS_NO_SUCH_CALENDAR :
+ return _("No such calendar");
+ case E_CALENDAR_STATUS_OBJECT_NOT_FOUND :
+ return _("Object not found");
+ case E_CALENDAR_STATUS_INVALID_OBJECT :
+ return _("Invalid object");
+ case E_CALENDAR_STATUS_URI_NOT_LOADED :
+ return _("URI not loaded");
+ case E_CALENDAR_STATUS_URI_ALREADY_LOADED :
+ return _("URI already loaded");
+ case E_CALENDAR_STATUS_PERMISSION_DENIED :
+ return _("Permission denied");
+ case E_CALENDAR_STATUS_CARD_NOT_FOUND :
+ return _("Object not found");
+ case E_CALENDAR_STATUS_CARD_ID_ALREADY_EXISTS :
+ return _("Object ID already exists");
+ case E_CALENDAR_STATUS_PROTOCOL_NOT_SUPPORTED :
+ return _("Protocol not supported");
+ case E_CALENDAR_STATUS_CANCELLED :
+ return _("Operation has been cancelled");
+ case E_CALENDAR_STATUS_COULD_NOT_CANCEL :
+ return _("Could not cancel operation");
+ case E_CALENDAR_STATUS_AUTHENTICATION_FAILED :
+ return _("Authentication failed");
+ case E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED :
+ return _("Authentication required");
+ case E_CALENDAR_STATUS_CORBA_EXCEPTION :
+ return _("A CORBA esception has occurred");
+ case E_CALENDAR_STATUS_OTHER_ERROR :
+ return _("Unknown error");
+ }
+
+ return NULL;
+}
diff --git a/calendar/cal-client/cal-client.h b/calendar/cal-client/cal-client.h
index 961ba5d993..277522f097 100644
--- a/calendar/cal-client/cal-client.h
+++ b/calendar/cal-client/cal-client.h
@@ -25,6 +25,7 @@
#include <cal-util/cal-recur.h>
#include <cal-util/cal-util.h>
#include <cal-client/cal-query.h>
+#include "cal-client-types.h"
G_BEGIN_DECLS
@@ -37,6 +38,7 @@ G_BEGIN_DECLS
#define IS_CAL_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CAL_CLIENT_TYPE))
#define CAL_CLIENT_OPEN_STATUS_ENUM_TYPE (cal_client_open_status_enum_get_type ())
+#define CAL_CLIENT_REMOVE_STATUS_ENUM_TYPE (cal_client_remove_status_enum_get_type ())
#define CAL_CLIENT_SET_MODE_STATUS_ENUM_TYPE (cal_client_set_mode_status_enum_get_type ())
#define CAL_MODE_ENUM_TYPE (cal_mode_enum_get_type ())
@@ -76,14 +78,6 @@ typedef enum {
CAL_CLIENT_RESULT_PERMISSION_DENIED
} CalClientResult;
-typedef enum {
- CAL_CLIENT_SEND_SUCCESS,
- CAL_CLIENT_SEND_CORBA_ERROR,
- CAL_CLIENT_SEND_INVALID_OBJECT,
- CAL_CLIENT_SEND_BUSY,
- CAL_CLIENT_SEND_PERMISSION_DENIED
-} CalClientSendResult;
-
/* Whether the client is not loaded, is being loaded, or is already loaded */
typedef enum {
CAL_CLIENT_LOAD_NOT_LOADED,
@@ -104,10 +98,7 @@ struct _CalClientClass {
/* Notification signals */
void (* cal_opened) (CalClient *client, CalClientOpenStatus status);
- void (* cal_set_mode) (CalClient *client, CalClientSetModeStatus status, CalMode mode);
-
- void (* obj_updated) (CalClient *client, const char *uid);
- void (* obj_removed) (CalClient *client, const char *uid);
+ void (* cal_set_mode) (CalClient *client, CalClientSetModeStatus status, CalMode mode);
void (* backend_error) (CalClient *client, const char *message);
@@ -129,21 +120,13 @@ GType cal_client_open_status_enum_get_type (void);
GType cal_client_set_mode_status_enum_get_type (void);
GType cal_mode_enum_get_type (void);
-CalClient *cal_client_construct (CalClient *client);
-
-CalClient *cal_client_new (void);
+CalClient *cal_client_new (const char *uri, CalObjType type);
void cal_client_set_auth_func (CalClient *client, CalClientAuthFunc func, gpointer data);
-/* Sets the default timezone to use to resolve DATE and floating DATE-TIME
- values. This will typically be from the user's timezone setting. Call this
- before using any other functions. It will pass the default timezone on to
- the server. Returns TRUE on success. */
-gboolean cal_client_set_default_timezone (CalClient *client, icaltimezone *zone);
-
-gboolean cal_client_open_calendar (CalClient *client, const char *str_uri, gboolean only_if_exists);
-gboolean cal_client_open_default_calendar (CalClient *client, gboolean only_if_exists);
-gboolean cal_client_open_default_tasks (CalClient *client, gboolean only_if_exists);
+gboolean cal_client_open (CalClient *client, gboolean only_if_exists, GError **error);
+void cal_client_open_async (CalClient *client, gboolean only_if_exists);
+gboolean cal_client_remove_calendar (CalClient *client, GError **error);
GList *cal_client_uri_list (CalClient *client, CalMode mode);
@@ -151,11 +134,10 @@ CalClientLoadState cal_client_get_load_state (CalClient *client);
const char *cal_client_get_uri (CalClient *client);
-gboolean cal_client_is_read_only (CalClient *client);
-
-const char *cal_client_get_cal_address (CalClient *client);
-const char *cal_client_get_alarm_email_address (CalClient *client);
-const char *cal_client_get_ldap_attribute (CalClient *client);
+gboolean cal_client_is_read_only (CalClient *client, gboolean *read_only, GError **error);
+gboolean cal_client_get_cal_address (CalClient *client, char **cal_address, GError **error);
+gboolean cal_client_get_alarm_email_address (CalClient *client, char **alarm_address, GError **error);
+gboolean cal_client_get_ldap_attribute (CalClient *client, char **ldap_attribute, GError **error);
gboolean cal_client_get_one_alarm_only (CalClient *client);
gboolean cal_client_get_organizer_must_attend (CalClient *client);
@@ -164,28 +146,23 @@ gboolean cal_client_get_static_capability (CalClient *client, const char *cap);
gboolean cal_client_set_mode (CalClient *client, CalMode mode);
-int cal_client_get_n_objects (CalClient *client, CalObjType type);
-
-CalClientGetStatus cal_client_get_default_object (CalClient *client,
- CalObjType type,
- icalcomponent **icalcomp);
+gboolean cal_client_get_default_object (CalClient *client,
+ icalcomponent **icalcomp, GError **error);
-CalClientGetStatus cal_client_get_object (CalClient *client,
- const char *uid,
- icalcomponent **icalcomp);
+gboolean cal_client_get_object (CalClient *client,
+ const char *uid,
+ const char *rid,
+ icalcomponent **icalcomp,
+ GError **error);
-CalClientGetStatus cal_client_get_timezone (CalClient *client,
- const char *tzid,
- icaltimezone **zone);
+gboolean cal_client_get_changes (CalClient *client, CalObjType type, const char *change_id, GList **changes, GError **error);
-GList *cal_client_get_uids (CalClient *client, CalObjType type);
-GList *cal_client_get_changes (CalClient *client, CalObjType type, const char *change_id);
+gboolean cal_client_get_object_list (CalClient *client, const char *query, GList **objects, GError **error);
+gboolean cal_client_get_object_list_as_comp (CalClient *client, const char *query, GList **objects, GError **error);
+void cal_client_free_object_list (GList *objects);
-GList *cal_client_get_objects_in_range (CalClient *client, CalObjType type,
- time_t start, time_t end);
-
-GList *cal_client_get_free_busy (CalClient *client, GList *users,
- time_t start, time_t end);
+gboolean cal_client_get_free_busy (CalClient *client, GList *users, time_t start, time_t end,
+ GList **freebusy, GError **error);
void cal_client_generate_instances (CalClient *client, CalObjType type,
time_t start, time_t end,
@@ -199,24 +176,25 @@ gboolean cal_client_get_alarms_for_object (CalClient *client, const char *uid,
time_t start, time_t end,
CalComponentAlarms **alarms);
-CalClientResult cal_client_discard_alarm (CalClient *client, CalComponent *comp, const char *auid);
-
-/* Add or update a single object. When adding an object only builtin timezones
- are allowed. To use external VTIMEZONE data call update_objects() instead.*/
-CalClientResult cal_client_update_object (CalClient *client, CalComponent *comp);
-CalClientResult cal_client_update_object_with_mod (CalClient *client, CalComponent *comp, CalObjModType mod);
+gboolean cal_client_create_object (CalClient *client, icalcomponent *icalcomp, char **uid, GError **error);
+gboolean cal_client_modify_object (CalClient *client, icalcomponent *icalcomp, CalObjModType mod, GError **error);
+gboolean cal_client_remove_object (CalClient *client, const char *uid, GError **error);
+gboolean cal_client_remove_object_with_mod (CalClient *client, const char *uid, const char *rid, CalObjModType mod, GError **error);
-/* Add or update multiple objects, possibly including VTIMEZONE data. */
-CalClientResult cal_client_update_objects (CalClient *client, icalcomponent *icalcomp);
+gboolean cal_client_discard_alarm (CalClient *client, CalComponent *comp, const char *auid, GError **error);
-CalClientResult cal_client_remove_object (CalClient *client, const char *uid);
-CalClientResult cal_client_remove_object_with_mod (CalClient *client, const char *uid, CalObjModType mod);
+gboolean cal_client_receive_objects (CalClient *client, icalcomponent *icalcomp, GError **error);
+gboolean cal_client_send_objects (CalClient *client, icalcomponent *icalcomp, GError **error);
-CalClientSendResult cal_client_send_object (CalClient *client, icalcomponent *icalcomp,
- icalcomponent **new_icalcomp, GList **users,
- char **error_msg);
+gboolean cal_client_get_timezone (CalClient *client, const char *tzid, icaltimezone **zone, GError **error);
+gboolean cal_client_add_timezone (CalClient *client, icaltimezone *izone, GError **error);
+/* Sets the default timezone to use to resolve DATE and floating DATE-TIME
+ values. This will typically be from the user's timezone setting. Call this
+ before using any other functions. It will pass the default timezone on to
+ the server. Returns TRUE on success. */
+gboolean cal_client_set_default_timezone (CalClient *client, icaltimezone *zone, GError **error);
-CalQuery *cal_client_get_query (CalClient *client, const char *sexp);
+gboolean cal_client_get_query (CalClient *client, const char *sexp, CalQuery **query, GError **error);
/* Resolves TZIDs for the recurrence generator. */
icaltimezone *cal_client_resolve_tzid_cb (const char *tzid, gpointer data);
@@ -225,6 +203,7 @@ icaltimezone *cal_client_resolve_tzid_cb (const char *tzid, gpointer data);
used by the component. It also includes a 'METHOD:PUBLISH' property. */
char* cal_client_get_component_as_string (CalClient *client, icalcomponent *icalcomp);
+const char * cal_client_get_error_message (ECalendarStatus status);
diff --git a/calendar/cal-client/cal-listener.c b/calendar/cal-client/cal-listener.c
index c7beef8c97..ac04be7c07 100644
--- a/calendar/cal-client/cal-listener.c
+++ b/calendar/cal-client/cal-listener.c
@@ -19,6 +19,9 @@
*/
#include <config.h>
+
+#include <bonobo/bonobo-main.h>
+#include "cal-marshal.h"
#include "cal-listener.h"
@@ -26,10 +29,7 @@
/* Private part of the CalListener structure */
struct CalListenerPrivate {
/* Notification functions and their closure data */
- CalListenerCalOpenedFn cal_opened_fn;
CalListenerCalSetModeFn cal_set_mode_fn;
- CalListenerObjUpdatedFn obj_updated_fn;
- CalListenerObjRemovedFn obj_removed_fn;
CalListenerErrorOccurredFn error_occurred_fn;
CalListenerCategoriesChangedFn categories_changed_fn;
gpointer fn_data;
@@ -38,124 +38,178 @@ struct CalListenerPrivate {
gboolean notify : 1;
};
-
+/* Signal IDs */
+enum {
+ READ_ONLY,
+ CAL_ADDRESS,
+ ALARM_ADDRESS,
+ LDAP_ATTRIBUTE,
+ STATIC_CAPABILITIES,
+ OPEN,
+ REMOVE,
+ CREATE_OBJECT,
+ MODIFY_OBJECT,
+ REMOVE_OBJECT,
+ DISCARD_ALARM,
+ RECEIVE_OBJECTS,
+ SEND_OBJECTS,
+ DEFAULT_OBJECT,
+ OBJECT,
+ OBJECT_LIST,
+ GET_TIMEZONE,
+ ADD_TIMEZONE,
+ SET_DEFAULT_TIMEZONE,
+ GET_CHANGES,
+ GET_FREE_BUSY,
+ QUERY,
+ LAST_SIGNAL
+};
-static void cal_listener_class_init (CalListenerClass *klass);
-static void cal_listener_init (CalListener *listener, CalListenerClass *klass);
-static void cal_listener_finalize (GObject *object);
-
-static void impl_notifyCalOpened (PortableServer_Servant servant,
- GNOME_Evolution_Calendar_Listener_OpenStatus status,
- GNOME_Evolution_Calendar_Cal cal,
- CORBA_Environment *ev);
-static void impl_notifyCalSetMode (PortableServer_Servant servant,
- GNOME_Evolution_Calendar_Listener_SetModeStatus status,
- GNOME_Evolution_Calendar_CalMode mode,
- CORBA_Environment *ev);
-static void impl_notifyObjUpdated (PortableServer_Servant servant,
- const CORBA_char *uid,
- CORBA_Environment *ev);
-static void impl_notifyObjRemoved (PortableServer_Servant servant,
- const CORBA_char *uid,
- CORBA_Environment *ev);
-static void impl_notifyErrorOccurred (PortableServer_Servant servant,
- const CORBA_char *message,
- CORBA_Environment *ev);
-static void impl_notifyCategoriesChanged (PortableServer_Servant servant,
- const GNOME_Evolution_Calendar_StringSeq *categories,
- CORBA_Environment *ev);
+static guint signals[LAST_SIGNAL] = { 0 };
static BonoboObjectClass *parent_class;
-
-
-BONOBO_TYPE_FUNC_FULL (CalListener,
- GNOME_Evolution_Calendar_Listener,
- BONOBO_TYPE_OBJECT,
- cal_listener);
+static ECalendarStatus
+convert_status (const GNOME_Evolution_Calendar_CallStatus status)
+{
+ switch (status) {
+ case GNOME_Evolution_Calendar_Success:
+ return E_CALENDAR_STATUS_OK;
+ case GNOME_Evolution_Calendar_RepositoryOffline:
+ return E_CALENDAR_STATUS_REPOSITORY_OFFLINE;
+ case GNOME_Evolution_Calendar_PermissionDenied:
+ return E_CALENDAR_STATUS_PERMISSION_DENIED;
+ case GNOME_Evolution_Calendar_ObjectNotFound:
+ return E_CALENDAR_STATUS_OBJECT_NOT_FOUND;
+ case GNOME_Evolution_Calendar_InvalidObject:
+ return E_CALENDAR_STATUS_INVALID_OBJECT;
+ case GNOME_Evolution_Calendar_CardIdAlreadyExists:
+ return E_CALENDAR_STATUS_CARD_ID_ALREADY_EXISTS;
+ case GNOME_Evolution_Calendar_AuthenticationFailed:
+ return E_CALENDAR_STATUS_AUTHENTICATION_FAILED;
+ case GNOME_Evolution_Calendar_AuthenticationRequired:
+ return E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED;
+ case GNOME_Evolution_Calendar_OtherError:
+ default:
+ return E_CALENDAR_STATUS_OTHER_ERROR;
+ }
+}
-/* Class initialization function for the calendar listener */
static void
-cal_listener_class_init (CalListenerClass *klass)
+impl_notifyReadOnly (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ const CORBA_boolean read_only,
+ CORBA_Environment *ev)
{
- GObjectClass *object_class;
-
- object_class = (GObjectClass *) klass;
+ CalListener *listener;
+ CalListenerPrivate *priv;
- parent_class = g_type_class_peek_parent (klass);
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
- klass->epv.notifyCalOpened = impl_notifyCalOpened;
- klass->epv.notifyCalSetMode = impl_notifyCalSetMode;
- klass->epv.notifyObjUpdated = impl_notifyObjUpdated;
- klass->epv.notifyObjRemoved = impl_notifyObjRemoved;
- klass->epv.notifyErrorOccurred = impl_notifyErrorOccurred;
- klass->epv.notifyCategoriesChanged = impl_notifyCategoriesChanged;
+ if (!priv->notify)
+ return;
- object_class->finalize = cal_listener_finalize;
+ g_signal_emit (G_OBJECT (listener), signals[READ_ONLY], 0, convert_status (status), read_only);
}
-/* Object initialization function for the calendar listener */
static void
-cal_listener_init (CalListener *listener, CalListenerClass *klass)
+impl_notifyCalAddress (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ const CORBA_char *address,
+ CORBA_Environment *ev)
{
+ CalListener *listener;
CalListenerPrivate *priv;
- priv = g_new0 (CalListenerPrivate, 1);
- listener->priv = priv;
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
- priv->cal_opened_fn = NULL;
- priv->obj_updated_fn = NULL;
- priv->obj_removed_fn = NULL;
- priv->error_occurred_fn = NULL;
- priv->categories_changed_fn = NULL;
+ if (!priv->notify)
+ return;
- priv->notify = TRUE;
+ g_signal_emit (G_OBJECT (listener), signals[CAL_ADDRESS], 0, convert_status (status), address);
}
-/* Finalize handler for the calendar listener */
static void
-cal_listener_finalize (GObject *object)
+impl_notifyAlarmEmailAddress (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ const CORBA_char *address,
+ CORBA_Environment *ev)
{
CalListener *listener;
CalListenerPrivate *priv;
- g_return_if_fail (object != NULL);
- g_return_if_fail (IS_CAL_LISTENER (object));
-
- listener = CAL_LISTENER (object);
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
priv = listener->priv;
- priv->cal_opened_fn = NULL;
- priv->obj_updated_fn = NULL;
- priv->obj_removed_fn = NULL;
- priv->error_occurred_fn = NULL;
- priv->categories_changed_fn = NULL;
- priv->fn_data = NULL;
+ if (!priv->notify)
+ return;
- priv->notify = FALSE;
+ g_signal_emit (G_OBJECT (listener), signals[ALARM_ADDRESS], 0, convert_status (status), address);
+}
- g_free (priv);
- listener->priv = NULL;
+static void
+impl_notifyLDAPAttribute (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ const CORBA_char *ldap_attribute,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
- if (G_OBJECT_CLASS (parent_class)->finalize)
- (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[LDAP_ATTRIBUTE], 0, convert_status (status), ldap_attribute);
}
-
+static void
+impl_notifyStaticCapabilities (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ const CORBA_char *capabilities,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
-/* CORBA servant implementation */
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[STATIC_CAPABILITIES], 0, convert_status (status));
+}
/* ::notifyCalOpened method */
static void
impl_notifyCalOpened (PortableServer_Servant servant,
- GNOME_Evolution_Calendar_Listener_OpenStatus status,
- GNOME_Evolution_Calendar_Cal cal,
+ GNOME_Evolution_Calendar_CallStatus status,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[OPEN], 0, convert_status (status));
+}
+
+static void
+impl_notifyCalRemoved (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
CORBA_Environment *ev)
{
CalListener *listener;
CalListenerPrivate *priv;
- CORBA_Environment aev;
- GNOME_Evolution_Calendar_Cal cal_copy;
listener = CAL_LISTENER (bonobo_object_from_servant (servant));
priv = listener->priv;
@@ -163,63 +217,388 @@ impl_notifyCalOpened (PortableServer_Servant servant,
if (!priv->notify)
return;
- CORBA_exception_init (&aev);
- cal_copy = CORBA_Object_duplicate (cal, &aev);
+ g_signal_emit (G_OBJECT (listener), signals[REMOVE], 0, convert_status (status));
+}
+
+static void
+impl_notifyObjectCreated (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ const CORBA_char *uid,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[CREATE_OBJECT], 0, convert_status (status), uid);
+}
+
+static void
+impl_notifyObjectModified (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
- if (aev._major != CORBA_NO_EXCEPTION) {
- g_message ("Listener_notifyCalOpened(): could not duplicate the calendar");
- CORBA_exception_free (&aev);
+ if (!priv->notify)
return;
+
+ g_signal_emit (G_OBJECT (listener), signals[MODIFY_OBJECT], 0, convert_status (status));
+}
+
+static void
+impl_notifyObjectRemoved (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[REMOVE_OBJECT], 0, convert_status (status));
+}
+
+static void
+impl_notifyAlarmDiscarded (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[DISCARD_ALARM], 0, convert_status (status));
+}
+
+static void
+impl_notifyObjectsReceived (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[RECEIVE_OBJECTS], 0, convert_status (status));
+}
+
+static void
+impl_notifyObjectsSent (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_CallStatus status,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[SEND_OBJECTS], 0, convert_status (status));
+}
+
+static void
+impl_notifyDefaultObjectRequested (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_CallStatus status,
+ const CORBA_char *object,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[DEFAULT_OBJECT], 0, convert_status (status), object);
+}
+
+static void
+impl_notifyObjectRequested (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_CallStatus status,
+ const CORBA_char *object,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[OBJECT], 0, convert_status (status), object);
+}
+
+static GList *
+build_object_list (const GNOME_Evolution_Calendar_stringlist *seq)
+{
+ GList *list;
+ int i;
+
+ list = NULL;
+ for (i = 0; i < seq->_length; i++) {
+ icalcomponent *comp;
+
+ comp = icalcomponent_new_from_string (seq->_buffer[i]);
+ if (!comp)
+ continue;
+
+ list = g_list_prepend (list, comp);
}
- CORBA_exception_free (&aev);
- g_assert (priv->cal_opened_fn != NULL);
- (* priv->cal_opened_fn) (listener, status, cal, priv->fn_data);
+ return list;
+}
+
+static void
+impl_notifyObjectListRequested (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_CallStatus status,
+ const GNOME_Evolution_Calendar_stringlist *objects,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+ GList *object_list, *l;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ object_list = build_object_list (objects);
+
+ g_signal_emit (G_OBJECT (listener), signals[OBJECT_LIST], 0, convert_status (status), object_list);
+
+ for (l = object_list; l; l = l->next)
+ icalcomponent_free (l->data);
+ g_list_free (object_list);
}
-/* ::notifyCalSetMode method */
static void
-impl_notifyCalSetMode (PortableServer_Servant servant,
- GNOME_Evolution_Calendar_Listener_SetModeStatus status,
- GNOME_Evolution_Calendar_CalMode mode,
- CORBA_Environment *ev)
+impl_notifyTimezoneRequested (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_CallStatus status,
+ const CORBA_char *object,
+ CORBA_Environment *ev)
{
CalListener *listener;
CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[GET_TIMEZONE], 0, convert_status (status), object);
+}
+static void
+impl_notifyTimezoneAdded (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_CallStatus status,
+ const CORBA_char *tzid,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
listener = CAL_LISTENER (bonobo_object_from_servant (servant));
priv = listener->priv;
if (!priv->notify)
return;
+
+ g_signal_emit (G_OBJECT (listener), signals[ADD_TIMEZONE], 0, convert_status (status), tzid);
+}
- g_assert (priv->cal_set_mode_fn != NULL);
- (* priv->cal_set_mode_fn) (listener, status, mode, priv->fn_data);
+static void
+impl_notifyDefaultTimezoneSet (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_CallStatus status,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[SET_DEFAULT_TIMEZONE], 0, convert_status (status));
+}
+
+static GList *
+build_change_list (const GNOME_Evolution_Calendar_CalObjChangeSeq *seq)
+{
+ GList *list = NULL;
+ icalcomponent *icalcomp;
+ int i;
+
+ /* Create the list in reverse order */
+ for (i = 0; i < seq->_length; i++) {
+ GNOME_Evolution_Calendar_CalObjChange *corba_coc;
+ CalClientChange *ccc;
+
+ corba_coc = &seq->_buffer[i];
+ ccc = g_new (CalClientChange, 1);
+
+ icalcomp = icalparser_parse_string (corba_coc->calobj);
+ if (!icalcomp)
+ continue;
+
+ ccc->comp = cal_component_new ();
+ if (!cal_component_set_icalcomponent (ccc->comp, icalcomp)) {
+ icalcomponent_free (icalcomp);
+ g_object_unref (G_OBJECT (ccc->comp));
+ continue;
+ }
+ ccc->type = corba_coc->type;
+
+ list = g_list_prepend (list, ccc);
+ }
+
+ list = g_list_reverse (list);
+
+ return list;
}
-/* ::notifyObjUpdated method */
static void
-impl_notifyObjUpdated (PortableServer_Servant servant,
- const CORBA_char *uid,
- CORBA_Environment *ev)
+impl_notifyChanges (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_CallStatus status,
+ const GNOME_Evolution_Calendar_CalObjChangeSeq *seq,
+ CORBA_Environment *ev)
{
CalListener *listener;
CalListenerPrivate *priv;
+ GList *changes, *l;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+ if (!priv->notify)
+ return;
+
+ changes = build_change_list (seq);
+
+ g_signal_emit (G_OBJECT (listener), signals[GET_CHANGES], 0, convert_status (status), changes);
+
+ for (l = changes; l; l = l->next)
+ g_free (l->data);
+ g_list_free (changes);
+}
+
+static GList *
+build_free_busy_list (const GNOME_Evolution_Calendar_CalObjSeq *seq)
+{
+ GList *list = NULL;
+ int i;
+
+ /* Create the list in reverse order */
+ for (i = 0; i < seq->_length; i++) {
+ CalComponent *comp;
+ icalcomponent *icalcomp;
+ icalcomponent_kind kind;
+
+ icalcomp = icalcomponent_new_from_string (seq->_buffer[i]);
+ if (!icalcomp)
+ continue;
+
+ kind = icalcomponent_isa (icalcomp);
+ if (kind == ICAL_VFREEBUSY_COMPONENT) {
+ comp = cal_component_new ();
+ if (!cal_component_set_icalcomponent (comp, icalcomp)) {
+ icalcomponent_free (icalcomp);
+ g_object_unref (G_OBJECT (comp));
+ continue;
+ }
+
+ list = g_list_append (list, comp);
+ } else {
+ icalcomponent_free (icalcomp);
+ }
+ }
+
+ return list;
+}
+
+static void
+impl_notifyFreeBusy (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_CallStatus status,
+ const GNOME_Evolution_Calendar_CalObjSeq *seq,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+ GList *freebusy, *l;
+
listener = CAL_LISTENER (bonobo_object_from_servant (servant));
priv = listener->priv;
if (!priv->notify)
return;
+
+ freebusy = build_free_busy_list (seq);
+
+ g_signal_emit (G_OBJECT (listener), signals[GET_FREE_BUSY], 0, convert_status (status), freebusy);
+
+ for (l = freebusy; l; l = l->next)
+ g_free (l->data);
+ g_list_free (freebusy);
+}
- g_assert (priv->obj_updated_fn != NULL);
- (* priv->obj_updated_fn) (listener, uid, priv->fn_data);
+static void
+impl_notifyQuery (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_CallStatus status,
+ const GNOME_Evolution_Calendar_Query query,
+ CORBA_Environment *ev)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ listener = CAL_LISTENER (bonobo_object_from_servant (servant));
+ priv = listener->priv;
+
+ if (!priv->notify)
+ return;
+
+ g_signal_emit (G_OBJECT (listener), signals[QUERY], 0, convert_status (status), query);
}
-/* ::notifyObjRemoved method */
+/* ::notifyCalSetMode method */
static void
-impl_notifyObjRemoved (PortableServer_Servant servant,
- const CORBA_char *uid,
+impl_notifyCalSetMode (PortableServer_Servant servant,
+ GNOME_Evolution_Calendar_Listener_SetModeStatus status,
+ GNOME_Evolution_Calendar_CalMode mode,
CORBA_Environment *ev)
{
CalListener *listener;
@@ -231,10 +610,13 @@ impl_notifyObjRemoved (PortableServer_Servant servant,
if (!priv->notify)
return;
- g_assert (priv->obj_removed_fn != NULL);
- (* priv->obj_removed_fn) (listener, uid, priv->fn_data);
+ g_message ("notify_set_mode");
+
+ g_assert (priv->cal_set_mode_fn != NULL);
+ (* priv->cal_set_mode_fn) (listener, status, mode, priv->fn_data);
}
+
/* ::notifyErrorOccurred method */
static void
impl_notifyErrorOccurred (PortableServer_Servant servant,
@@ -250,6 +632,8 @@ impl_notifyErrorOccurred (PortableServer_Servant servant,
if (!priv->notify)
return;
+ g_message ("notify_error");
+
g_assert (priv->error_occurred_fn != NULL);
(* priv->error_occurred_fn) (listener, message, priv->fn_data);
}
@@ -269,21 +653,283 @@ impl_notifyCategoriesChanged (PortableServer_Servant servant,
if (!priv->notify)
return;
+ g_message ("notify_categories");
+
g_assert (priv->categories_changed_fn != NULL);
(* priv->categories_changed_fn) (listener, categories, priv->fn_data);
}
+/* Object initialization function for the calendar listener */
+static void
+cal_listener_init (CalListener *listener, CalListenerClass *klass)
+{
+ CalListenerPrivate *priv;
+
+ priv = g_new0 (CalListenerPrivate, 1);
+ listener->priv = priv;
+
+ priv->error_occurred_fn = NULL;
+ priv->categories_changed_fn = NULL;
+
+ priv->notify = TRUE;
+}
+
+/* Finalize handler for the calendar listener */
+static void
+cal_listener_finalize (GObject *object)
+{
+ CalListener *listener;
+ CalListenerPrivate *priv;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (IS_CAL_LISTENER (object));
+
+ listener = CAL_LISTENER (object);
+ priv = listener->priv;
+
+ priv->error_occurred_fn = NULL;
+ priv->categories_changed_fn = NULL;
+ priv->fn_data = NULL;
+
+ priv->notify = FALSE;
+
+ g_free (priv);
+ listener->priv = NULL;
+
+ if (G_OBJECT_CLASS (parent_class)->finalize)
+ (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+}
+
+/* Class initialization function for the calendar listener */
+static void
+cal_listener_class_init (CalListenerClass *klass)
+{
+ GObjectClass *object_class;
+
+ object_class = (GObjectClass *) klass;
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ klass->epv.notifyReadOnly = impl_notifyReadOnly;
+ klass->epv.notifyCalAddress = impl_notifyCalAddress;
+ klass->epv.notifyAlarmEmailAddress = impl_notifyAlarmEmailAddress;
+ klass->epv.notifyLDAPAttribute = impl_notifyLDAPAttribute;
+ klass->epv.notifyStaticCapabilities = impl_notifyStaticCapabilities;
+ klass->epv.notifyCalOpened = impl_notifyCalOpened;
+ klass->epv.notifyCalRemoved = impl_notifyCalRemoved;
+ klass->epv.notifyObjectCreated = impl_notifyObjectCreated;
+ klass->epv.notifyObjectModified = impl_notifyObjectModified;
+ klass->epv.notifyObjectRemoved = impl_notifyObjectRemoved;
+ klass->epv.notifyAlarmDiscarded = impl_notifyAlarmDiscarded;
+ klass->epv.notifyObjectsReceived = impl_notifyObjectsReceived;
+ klass->epv.notifyObjectsSent = impl_notifyObjectsSent;
+ klass->epv.notifyDefaultObjectRequested = impl_notifyDefaultObjectRequested;
+ klass->epv.notifyObjectRequested = impl_notifyObjectRequested;
+ klass->epv.notifyObjectListRequested = impl_notifyObjectListRequested;
+ klass->epv.notifyTimezoneRequested = impl_notifyTimezoneRequested;
+ klass->epv.notifyTimezoneAdded = impl_notifyTimezoneAdded;
+ klass->epv.notifyDefaultTimezoneSet = impl_notifyDefaultTimezoneSet;
+ klass->epv.notifyChanges = impl_notifyChanges;
+ klass->epv.notifyFreeBusy = impl_notifyFreeBusy;
+ klass->epv.notifyQuery = impl_notifyQuery;
+ klass->epv.notifyCalSetMode = impl_notifyCalSetMode;
+ klass->epv.notifyErrorOccurred = impl_notifyErrorOccurred;
+ klass->epv.notifyCategoriesChanged = impl_notifyCategoriesChanged;
+
+ object_class->finalize = cal_listener_finalize;
+
+ signals[READ_ONLY] =
+ g_signal_new ("read_only",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, read_only),
+ NULL, NULL,
+ cal_marshal_VOID__INT_BOOLEAN,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_BOOLEAN);
+ signals[CAL_ADDRESS] =
+ g_signal_new ("cal_address",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, cal_address),
+ NULL, NULL,
+ cal_marshal_VOID__INT_STRING,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING);
+ signals[ALARM_ADDRESS] =
+ g_signal_new ("alarm_address",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, alarm_address),
+ NULL, NULL,
+ cal_marshal_VOID__INT_STRING,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING);
+ signals[LDAP_ATTRIBUTE] =
+ g_signal_new ("ldap_attribute",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, ldap_attribute),
+ NULL, NULL,
+ cal_marshal_VOID__INT_STRING,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING);
+ signals[STATIC_CAPABILITIES] =
+ g_signal_new ("static_capabilities",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, static_capabilities),
+ NULL, NULL,
+ cal_marshal_VOID__INT_STRING,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING);
+ signals[OPEN] =
+ g_signal_new ("open",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, open),
+ NULL, NULL,
+ cal_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+ signals[REMOVE] =
+ g_signal_new ("remove",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, remove),
+ NULL, NULL,
+ cal_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+ signals[CREATE_OBJECT] =
+ g_signal_new ("create_object",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, create_object),
+ NULL, NULL,
+ cal_marshal_VOID__INT_STRING,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING);
+ signals[MODIFY_OBJECT] =
+ g_signal_new ("modify_object",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, modify_object),
+ NULL, NULL,
+ cal_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+ signals[REMOVE_OBJECT] =
+ g_signal_new ("remove_object",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, remove_object),
+ NULL, NULL,
+ cal_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+ signals[DISCARD_ALARM] =
+ g_signal_new ("discard_alarm",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, discard_alarm),
+ NULL, NULL,
+ cal_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+ signals[RECEIVE_OBJECTS] =
+ g_signal_new ("receive_objects",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, receive_objects),
+ NULL, NULL,
+ cal_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+ signals[SEND_OBJECTS] =
+ g_signal_new ("send_objects",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, send_objects),
+ NULL, NULL,
+ cal_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+ signals[DEFAULT_OBJECT] =
+ g_signal_new ("default_object",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, default_object),
+ NULL, NULL,
+ cal_marshal_VOID__INT_STRING,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING);
+ signals[OBJECT] =
+ g_signal_new ("object",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, object),
+ NULL, NULL,
+ cal_marshal_VOID__INT_STRING,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING);
+ signals[OBJECT_LIST] =
+ g_signal_new ("object_list",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, object_list),
+ NULL, NULL,
+ cal_marshal_VOID__INT_POINTER,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_POINTER);
+ signals[GET_TIMEZONE] =
+ g_signal_new ("get_timezone",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, get_timezone),
+ NULL, NULL,
+ cal_marshal_VOID__INT_STRING,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING);
+ signals[ADD_TIMEZONE] =
+ g_signal_new ("add_timezone",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, add_timezone),
+ NULL, NULL,
+ cal_marshal_VOID__INT_STRING,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING);
+ signals[SET_DEFAULT_TIMEZONE] =
+ g_signal_new ("set_default_timezone",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, set_default_timezone),
+ NULL, NULL,
+ cal_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+ signals[GET_CHANGES] =
+ g_signal_new ("get_changes",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, get_changes),
+ NULL, NULL,
+ cal_marshal_VOID__INT_POINTER,
+ G_TYPE_NONE, 1, G_TYPE_INT, G_TYPE_POINTER);
+ signals[GET_FREE_BUSY] =
+ g_signal_new ("get_free_busy",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, get_free_busy),
+ NULL, NULL,
+ cal_marshal_VOID__INT_POINTER,
+ G_TYPE_NONE, 1, G_TYPE_INT, G_TYPE_POINTER);
+ signals[QUERY] =
+ g_signal_new ("query",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CalListenerClass, query),
+ NULL, NULL,
+ cal_marshal_VOID__INT_POINTER,
+ G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_POINTER);
+}
+
+BONOBO_TYPE_FUNC_FULL (CalListener,
+ GNOME_Evolution_Calendar_Listener,
+ BONOBO_TYPE_OBJECT,
+ cal_listener);
+
/**
* cal_listener_construct:
* @listener: A calendar listener.
* @cal_opened_fn: Function that will be called to notify that a calendar was
* opened.
- * @obj_updated_fn: Function that will be called to notify that an object in the
- * calendar was updated.
- * @obj_removed_fn: Function that will be called to notify that an object in the
- * calendar was removed.
+ * @cal_removed_fn: Function that will be called to notify that a calendar was
+ * removed
* @error_occurred_fn: Function that will be called to notify errors.
* @categories_changed_fn: Function that will be called to notify that the list
* of categories that are present in the calendar's objects has changed.
@@ -297,10 +943,7 @@ impl_notifyCategoriesChanged (PortableServer_Servant servant,
**/
CalListener *
cal_listener_construct (CalListener *listener,
- CalListenerCalOpenedFn cal_opened_fn,
CalListenerCalSetModeFn cal_set_mode_fn,
- CalListenerObjUpdatedFn obj_updated_fn,
- CalListenerObjRemovedFn obj_removed_fn,
CalListenerErrorOccurredFn error_occurred_fn,
CalListenerCategoriesChangedFn categories_changed_fn,
gpointer fn_data)
@@ -309,19 +952,13 @@ cal_listener_construct (CalListener *listener,
g_return_val_if_fail (listener != NULL, NULL);
g_return_val_if_fail (IS_CAL_LISTENER (listener), NULL);
- g_return_val_if_fail (cal_opened_fn != NULL, NULL);
g_return_val_if_fail (cal_set_mode_fn != NULL, NULL);
- g_return_val_if_fail (obj_updated_fn != NULL, NULL);
- g_return_val_if_fail (obj_removed_fn != NULL, NULL);
g_return_val_if_fail (error_occurred_fn != NULL, NULL);
g_return_val_if_fail (categories_changed_fn != NULL, NULL);
priv = listener->priv;
- priv->cal_opened_fn = cal_opened_fn;
priv->cal_set_mode_fn = cal_set_mode_fn;
- priv->obj_updated_fn = obj_updated_fn;
- priv->obj_removed_fn = obj_removed_fn;
priv->error_occurred_fn = error_occurred_fn;
priv->categories_changed_fn = categories_changed_fn;
priv->fn_data = fn_data;
@@ -333,10 +970,6 @@ cal_listener_construct (CalListener *listener,
* cal_listener_new:
* @cal_opened_fn: Function that will be called to notify that a calendar was
* opened.
- * @obj_updated_fn: Function that will be called to notify that an object in the
- * calendar was updated.
- * @obj_removed_fn: Function that will be called to notify that an object in the
- * calendar was removed.
* @error_occurred_fn: Function that will be called to notify errors.
* @categories_changed_fn: Function that will be called to notify that the list
* of categories that are present in the calendar's objects has changed.
@@ -348,28 +981,22 @@ cal_listener_construct (CalListener *listener,
* Return value: A newly-created #CalListener object.
**/
CalListener *
-cal_listener_new (CalListenerCalOpenedFn cal_opened_fn,
- CalListenerCalSetModeFn cal_set_mode_fn,
- CalListenerObjUpdatedFn obj_updated_fn,
- CalListenerObjRemovedFn obj_removed_fn,
+cal_listener_new (CalListenerCalSetModeFn cal_set_mode_fn,
CalListenerErrorOccurredFn error_occurred_fn,
CalListenerCategoriesChangedFn categories_changed_fn,
gpointer fn_data)
{
CalListener *listener;
- g_return_val_if_fail (cal_opened_fn != NULL, NULL);
- g_return_val_if_fail (obj_updated_fn != NULL, NULL);
- g_return_val_if_fail (obj_removed_fn != NULL, NULL);
g_return_val_if_fail (error_occurred_fn != NULL, NULL);
g_return_val_if_fail (categories_changed_fn != NULL, NULL);
- listener = g_object_new (CAL_LISTENER_TYPE, NULL);
+ listener = g_object_new (CAL_LISTENER_TYPE,
+ "poa", bonobo_poa_get_threaded (ORBIT_THREAD_HINT_PER_REQUEST, NULL),
+ NULL);
+
return cal_listener_construct (listener,
- cal_opened_fn,
cal_set_mode_fn,
- obj_updated_fn,
- obj_removed_fn,
error_occurred_fn,
categories_changed_fn,
fn_data);
diff --git a/calendar/cal-client/cal-listener.h b/calendar/cal-client/cal-listener.h
index d0f9a718a4..1230104999 100644
--- a/calendar/cal-client/cal-listener.h
+++ b/calendar/cal-client/cal-listener.h
@@ -23,6 +23,7 @@
#include <bonobo/bonobo-object.h>
#include "evolution-calendar.h"
+#include "cal-client-types.h"
G_BEGIN_DECLS
@@ -48,26 +49,46 @@ typedef struct {
BonoboObjectClass parent_class;
POA_GNOME_Evolution_Calendar_Listener__epv epv;
+
+ /* Signals */
+ void (*read_only) (CalListener *listener, ECalendarStatus status, gboolean read_only);
+ void (*cal_address) (CalListener *listener, ECalendarStatus status, const char *address);
+ void (*alarm_address) (CalListener *listener, ECalendarStatus status, const char *address);
+ void (*ldap_attribute) (CalListener *listener, ECalendarStatus status, const char *ldap_attribute);
+ void (*static_capabilities) (CalListener *listener, ECalendarStatus status, const char *capabilities);
+
+ void (*open) (CalListener *listener, ECalendarStatus status);
+ void (*remove) (CalListener *listener, ECalendarStatus status);
+
+ void (*create_object) (CalListener *listener, ECalendarStatus status, const char *id);
+ void (*modify_object) (CalListener *listener, ECalendarStatus status);
+ void (*remove_object) (CalListener *listener, ECalendarStatus status);
+
+ void (*discard_alarm) (CalListener *listener, ECalendarStatus status);
+
+ void (*receive_objects) (CalListener *listener, ECalendarStatus status);
+ void (*send_objects) (CalListener *listener, ECalendarStatus status);
+
+ void (*default_object) (CalListener *listener, ECalendarStatus status, const char *object);
+ void (*object) (CalListener *listener, ECalendarStatus status, const char *object);
+ void (*object_list) (CalListener *listener, ECalendarStatus status, GList **objects);
+
+ void (*get_timezone) (CalListener *listener, ECalendarStatus status, const char *object);
+ void (*add_timezone) (CalListener *listener, ECalendarStatus status, const char *tzid);
+ void (*set_default_timezone) (CalListener *listener, ECalendarStatus status, const char *tzid);
+
+ void (*get_changes) (CalListener *listener, ECalendarStatus status, GList *changes);
+ void (*get_free_busy) (CalListener *listener, ECalendarStatus status, GList *freebusy);
+
+ void (*query) (CalListener *listener, ECalendarStatus status, GNOME_Evolution_Calendar_Query query);
} CalListenerClass;
/* Notification functions */
-typedef void (* CalListenerCalOpenedFn) (CalListener *listener,
- GNOME_Evolution_Calendar_Listener_OpenStatus status,
- GNOME_Evolution_Calendar_Cal cal,
- gpointer data);
-
typedef void (* CalListenerCalSetModeFn) (CalListener *listener,
GNOME_Evolution_Calendar_Listener_SetModeStatus status,
GNOME_Evolution_Calendar_CalMode mode,
gpointer data);
-typedef void (* CalListenerObjUpdatedFn) (CalListener *listener,
- const CORBA_char *uid,
- gpointer data);
-typedef void (* CalListenerObjRemovedFn) (CalListener *listener,
- const CORBA_char *uid,
- gpointer data);
-
typedef void (* CalListenerErrorOccurredFn) (CalListener *listener,
const char *message,
gpointer data);
@@ -80,18 +101,12 @@ typedef void (* CalListenerCategoriesChangedFn) (CalListener *listener,
GType cal_listener_get_type (void);
CalListener *cal_listener_construct (CalListener *listener,
- CalListenerCalOpenedFn cal_opened_fn,
CalListenerCalSetModeFn cal_set_mode_fn,
- CalListenerObjUpdatedFn obj_updated_fn,
- CalListenerObjRemovedFn obj_removed_fn,
CalListenerErrorOccurredFn error_occurred_fn,
CalListenerCategoriesChangedFn categories_changed_fn,
gpointer fn_data);
-CalListener *cal_listener_new (CalListenerCalOpenedFn cal_opened_fn,
- CalListenerCalSetModeFn cal_set_mode_fn,
- CalListenerObjUpdatedFn obj_updated_fn,
- CalListenerObjRemovedFn obj_removed_fn,
+CalListener *cal_listener_new (CalListenerCalSetModeFn cal_set_mode_fn,
CalListenerErrorOccurredFn error_occurred_fn,
CalListenerCategoriesChangedFn categories_changed_fn,
gpointer fn_data);
diff --git a/calendar/cal-client/cal-marshal.list b/calendar/cal-client/cal-marshal.list
new file mode 100644
index 0000000000..e0ca019669
--- /dev/null
+++ b/calendar/cal-client/cal-marshal.list
@@ -0,0 +1,6 @@
+NONE:INT
+NONE:POINTER
+NONE:INT,STRING
+NONE:INT,BOOL
+NONE:INT,POINTER
+NONE:STRING,INT
diff --git a/calendar/cal-client/cal-query.c b/calendar/cal-client/cal-query.c
index 914af5db28..e77f5ad3e9 100644
--- a/calendar/cal-client/cal-query.c
+++ b/calendar/cal-client/cal-query.c
@@ -24,7 +24,8 @@
#include <string.h>
#include <bonobo/bonobo-exception.h>
-#include "cal-util/cal-util-marshal.h"
+#include "cal-marshal.h"
+#include "cal-client.h"
#include "cal-query.h"
#include "query-listener.h"
@@ -32,143 +33,88 @@
/* Private part of the CalQuery structure */
struct _CalQueryPrivate {
- /* Our query listener implementation */
- QueryListener *ql;
-
/* Handle to the query in the server */
- GNOME_Evolution_Calendar_Query corba_query;
+ GNOME_Evolution_Calendar_Query query;
+
+ /* Our query listener implementation */
+ QueryListener *listener;
/* The CalClient associated with this query */
CalClient *client;
};
-
-
-static void cal_query_class_init (CalQueryClass *klass);
-static void cal_query_init (CalQuery *query, CalQueryClass *klass);
-static void cal_query_finalize (GObject *object);
+/* Property IDs */
+enum props {
+ PROP_0,
+ PROP_QUERY,
+ PROP_LISTENER,
+ PROP_CLIENT
+};
/* Signal IDs */
enum {
- OBJ_UPDATED,
- OBJ_REMOVED,
+ OBJECTS_ADDED,
+ OBJECTS_MODIFIED,
+ OBJECTS_REMOVED,
+ QUERY_PROGRESS,
QUERY_DONE,
- EVAL_ERROR,
LAST_SIGNAL
};
-static guint query_signals[LAST_SIGNAL];
+static guint signals[LAST_SIGNAL];
static GObjectClass *parent_class;
-/**
- * cal_query_get_type:
- *
- * Registers the #CalQuery class if necessary, and returns the type ID assigned
- * to it.
- *
- * Return value: The type ID of the #CalQuery class.
- **/
-GType
-cal_query_get_type (void)
+static void
+objects_added_cb (QueryListener *listener, GList *objects, gpointer data)
{
- static GType cal_query_type = 0;
+ CalQuery *query;
- if (!cal_query_type) {
- static GTypeInfo info = {
- sizeof (CalQueryClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) cal_query_class_init,
- NULL, NULL,
- sizeof (CalQuery),
- 0,
- (GInstanceInitFunc) cal_query_init
- };
- cal_query_type = g_type_register_static (G_TYPE_OBJECT, "CalQuery", &info, 0);
- }
+ query = CAL_QUERY (data);
- return cal_query_type;
+ g_signal_emit (G_OBJECT (query), signals[OBJECTS_ADDED], 0, objects);
}
-GType
-cal_query_done_status_enum_get_type (void)
+static void
+objects_modified_cb (QueryListener *listener, GList *objects, gpointer data)
{
- static GType cal_query_done_status_enum_type = 0;
+ CalQuery *query;
- if (!cal_query_done_status_enum_type) {
- static GEnumValue values [] = {
- { CAL_QUERY_DONE_SUCCESS, "CalQueryDoneSuccess", "success" },
- { CAL_QUERY_DONE_PARSE_ERROR, "CalQueryDoneParseError", "parse-error" },
- { -1, NULL, NULL }
- };
+ query = CAL_QUERY (data);
- cal_query_done_status_enum_type =
- g_enum_register_static ("CalQueryDoneStatusEnum", values);
- }
+ g_signal_emit (G_OBJECT (query), signals[OBJECTS_MODIFIED], 0, objects);
+}
+
+static void
+objects_removed_cb (QueryListener *listener, GList *uids, gpointer data)
+{
+ CalQuery *query;
+
+ query = CAL_QUERY (data);
- return cal_query_done_status_enum_type;
+ g_signal_emit (G_OBJECT (query), signals[OBJECTS_REMOVED], 0, uids);
}
-/* Class initialization function for the calendar query */
static void
-cal_query_class_init (CalQueryClass *klass)
+query_progress_cb (QueryListener *listener, const char *message, int percent, gpointer data)
{
- GObjectClass *object_class;
+ CalQuery *query;
- object_class = (GObjectClass *) klass;
+ query = CAL_QUERY (data);
- parent_class = g_type_class_peek_parent (klass);
+ g_signal_emit (G_OBJECT (query), signals[QUERY_PROGRESS], 0, message, percent);
+}
- query_signals[OBJ_UPDATED] =
- g_signal_new ("obj_updated",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalQueryClass, obj_updated),
- NULL, NULL,
- cal_util_marshal_VOID__STRING_BOOLEAN_INT_INT,
- G_TYPE_NONE, 4,
- G_TYPE_STRING,
- G_TYPE_BOOLEAN,
- G_TYPE_INT,
- G_TYPE_INT);
- query_signals[OBJ_REMOVED] =
- g_signal_new ("obj_removed",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalQueryClass, obj_removed),
- NULL, NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
- query_signals[QUERY_DONE] =
- g_signal_new ("query_done",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalQueryClass, query_done),
- NULL, NULL,
- cal_util_marshal_VOID__ENUM_STRING,
- G_TYPE_NONE, 2,
- CAL_QUERY_DONE_STATUS_ENUM_TYPE,
- G_TYPE_STRING);
- query_signals[EVAL_ERROR] =
- g_signal_new ("eval_error",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (CalQueryClass, eval_error),
- NULL, NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
+static void
+query_done_cb (QueryListener *listener, ECalendarStatus status, gpointer data)
+{
+ CalQuery *query;
- klass->obj_updated = NULL;
- klass->obj_removed = NULL;
- klass->query_done = NULL;
- klass->eval_error = NULL;
+ query = CAL_QUERY (data);
- object_class->finalize = cal_query_finalize;
+ g_signal_emit (G_OBJECT (query), signals[QUERY_DONE], 0, status);
}
/* Object initialization function for the calendar query */
@@ -180,191 +126,193 @@ cal_query_init (CalQuery *query, CalQueryClass *klass)
priv = g_new0 (CalQueryPrivate, 1);
query->priv = priv;
- priv->ql = NULL;
- priv->corba_query = CORBA_OBJECT_NIL;
+ priv->listener = NULL;
+ priv->query = CORBA_OBJECT_NIL;
}
-/* Finalize handler for the calendar query */
static void
-cal_query_finalize (GObject *object)
+cal_query_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
{
CalQuery *query;
CalQueryPrivate *priv;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (IS_CAL_QUERY (object));
-
+
query = CAL_QUERY (object);
priv = query->priv;
-
- /* The server keeps a copy of the query listener, so we must unref it */
- query_listener_stop_notification (priv->ql);
- bonobo_object_unref (BONOBO_OBJECT (priv->ql));
- priv->ql = NULL;
-
- if (priv->corba_query != CORBA_OBJECT_NIL) {
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
- bonobo_object_release_unref (priv->corba_query, &ev);
-
- if (BONOBO_EX (&ev))
- g_message ("cal_query_destroy(): Could not release/unref the query");
-
- CORBA_exception_free (&ev);
- priv->corba_query = CORBA_OBJECT_NIL;
+
+ switch (property_id) {
+ case PROP_QUERY:
+ priv->query = bonobo_object_dup_ref (g_value_get_pointer (value), NULL);
+ break;
+ case PROP_LISTENER:
+ priv->listener = bonobo_object_ref (g_value_get_pointer (value));
+
+ g_signal_connect (G_OBJECT (priv->listener), "objects_added",
+ G_CALLBACK (objects_added_cb), query);
+ g_signal_connect (G_OBJECT (priv->listener), "objects_modified",
+ G_CALLBACK (objects_modified_cb), query);
+ g_signal_connect (G_OBJECT (priv->listener), "objects_removed",
+ G_CALLBACK (objects_removed_cb), query);
+ g_signal_connect (G_OBJECT (priv->listener), "query_progress",
+ G_CALLBACK (query_progress_cb), query);
+ g_signal_connect (G_OBJECT (priv->listener), "query_done",
+ G_CALLBACK (query_done_cb), query);
+ break;
+ case PROP_CLIENT:
+ priv->client = CAL_CLIENT (g_value_dup_object (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
}
-
- g_free (priv);
- query->priv = NULL;
-
- if (G_OBJECT_CLASS (parent_class)->finalize)
- (* G_OBJECT_CLASS (parent_class)->finalize) (object);
}
-
-
-/* Callback used when an object is updated in the query */
static void
-obj_updated_cb (QueryListener *ql,
- const GNOME_Evolution_Calendar_CalObjUIDSeq *uids,
- CORBA_boolean query_in_progress,
- CORBA_long n_scanned,
- CORBA_long total,
- gpointer data)
+cal_query_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
{
CalQuery *query;
- int n;
-
- query = CAL_QUERY (data);
+ CalQueryPrivate *priv;
+
+ query = CAL_QUERY (object);
+ priv = query->priv;
- for (n = 0; n < uids->_length; n++) {
- g_signal_emit (G_OBJECT (query), query_signals[OBJ_UPDATED], 0,
- uids->_buffer[n], query_in_progress,
- (int) n_scanned, (int) total);
+ switch (property_id) {
+ case PROP_QUERY:
+ g_value_set_pointer (value, priv->query);
+ break;
+ case PROP_LISTENER:
+ g_value_set_pointer (value, priv->listener);
+ break;
+ case PROP_CLIENT:
+ g_value_set_object (value, priv->client);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
}
}
-/* Callback used when an object is removed from the query */
-static void
-obj_removed_cb (QueryListener *ql,
- const CORBA_char *uid,
- gpointer data)
-{
- CalQuery *query;
-
- query = CAL_QUERY (data);
-
- g_signal_emit (G_OBJECT (query), query_signals[OBJ_REMOVED],
- 0, uid);
-}
-/* Callback used when the query terminates */
+/* Finalize handler for the calendar query */
static void
-query_done_cb (QueryListener *ql,
- GNOME_Evolution_Calendar_QueryListener_QueryDoneStatus corba_status,
- const CORBA_char *error_str,
- gpointer data)
+cal_query_finalize (GObject *object)
{
CalQuery *query;
- CalQueryDoneStatus status;
+ CalQueryPrivate *priv;
- query = CAL_QUERY (data);
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (IS_CAL_QUERY (object));
- switch (corba_status) {
- case GNOME_Evolution_Calendar_QueryListener_SUCCESS:
- status = CAL_QUERY_DONE_SUCCESS;
- break;
+ query = CAL_QUERY (object);
+ priv = query->priv;
- case GNOME_Evolution_Calendar_QueryListener_PARSE_ERROR:
- status = CAL_QUERY_DONE_PARSE_ERROR;
- break;
+ /* The server keeps a copy of the query listener, so we must unref it */
+ g_signal_handlers_disconnect_matched (priv->listener, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, query);
+ bonobo_object_unref (BONOBO_OBJECT (priv->listener));
- default:
- g_assert_not_reached ();
- return;
- }
+ if (priv->query != CORBA_OBJECT_NIL)
+ bonobo_object_release_unref (priv->query, NULL);
- g_signal_emit (G_OBJECT (query), query_signals[QUERY_DONE], 0,
- status, error_str);
+ g_free (priv);
+
+ if (G_OBJECT_CLASS (parent_class)->finalize)
+ (* G_OBJECT_CLASS (parent_class)->finalize) (object);
}
-/* Callback used when an error occurs when evaluating the query */
+/* Class initialization function for the calendar query */
static void
-eval_error_cb (QueryListener *ql,
- const CORBA_char *error_str,
- gpointer data)
+cal_query_class_init (CalQueryClass *klass)
{
- CalQuery *query;
+ GObjectClass *object_class;
+ GParamSpec *param;
+
+ object_class = (GObjectClass *) klass;
- query = CAL_QUERY (data);
+ parent_class = g_type_class_peek_parent (klass);
+
+ object_class->set_property = cal_query_set_property;
+ object_class->get_property = cal_query_get_property;
+ object_class->finalize = cal_query_finalize;
- g_signal_emit (G_OBJECT (query), query_signals[EVAL_ERROR], 0,
- error_str);
+ param = g_param_spec_pointer ("query", NULL, NULL,
+ G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
+ g_object_class_install_property (object_class, PROP_QUERY, param);
+ param = g_param_spec_pointer ("listener", NULL, NULL,
+ G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
+ g_object_class_install_property (object_class, PROP_LISTENER, param);
+ param = g_param_spec_object ("client", NULL, NULL, CAL_CLIENT_TYPE,
+ G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
+ g_object_class_install_property (object_class, PROP_CLIENT, param);
+
+ signals[OBJECTS_ADDED] =
+ g_signal_new ("objects_added",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalQueryClass, objects_added),
+ NULL, NULL,
+ cal_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+ signals[OBJECTS_MODIFIED] =
+ g_signal_new ("objects_modified",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalQueryClass, objects_modified),
+ NULL, NULL,
+ cal_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+ signals[OBJECTS_REMOVED] =
+ g_signal_new ("objects_removed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalQueryClass, objects_removed),
+ NULL, NULL,
+ cal_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+ signals[QUERY_PROGRESS] =
+ g_signal_new ("query_progress",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalQueryClass, query_progress),
+ NULL, NULL,
+ cal_marshal_VOID__POINTER,
+ G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT);
+ signals[QUERY_DONE] =
+ g_signal_new ("query_done",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CalQueryClass, query_done),
+ NULL, NULL,
+ cal_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
}
/**
- * cal_query_construct:
- * @query: A calendar query.
- * @cal: Handle to an open calendar.
- * @sexp: S-expression that defines the query.
+ * cal_query_get_type:
*
- * Constructs a query object by issuing the query creation request to the
- * calendar server.
+ * Registers the #CalQuery class if necessary, and returns the type ID assigned
+ * to it.
*
- * Return value: The same value as @query on success, or NULL if the request
- * failed.
+ * Return value: The type ID of the #CalQuery class.
**/
-CalQuery *
-cal_query_construct (CalQuery *query,
- GNOME_Evolution_Calendar_Cal cal,
- const char *sexp)
+GType
+cal_query_get_type (void)
{
- CalQueryPrivate *priv;
- GNOME_Evolution_Calendar_QueryListener corba_ql;
- CORBA_Environment ev;
-
- g_return_val_if_fail (query != NULL, NULL);
- g_return_val_if_fail (IS_CAL_QUERY (query), NULL);
- g_return_val_if_fail (sexp != NULL, NULL);
-
- priv = query->priv;
-
- priv->ql = query_listener_new (obj_updated_cb,
- obj_removed_cb,
- query_done_cb,
- eval_error_cb,
- query);
- if (!priv->ql) {
- g_message ("cal_query_construct(): Could not create the query listener");
- return NULL;
- }
+ static GType cal_query_type = 0;
- corba_ql = BONOBO_OBJREF (priv->ql);
-
- CORBA_exception_init (&ev);
- priv->corba_query = GNOME_Evolution_Calendar_Cal_getQuery (cal, sexp, corba_ql, &ev);
-
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_CouldNotCreate)) {
- g_message ("cal_query_construct(): The server could not create the query");
- goto error;
- } else if (BONOBO_EX (&ev)) {
- g_message ("cal_query_construct(): Could not issue the getQuery() request");
- goto error;
+ if (!cal_query_type) {
+ static GTypeInfo info = {
+ sizeof (CalQueryClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) cal_query_class_init,
+ NULL, NULL,
+ sizeof (CalQuery),
+ 0,
+ (GInstanceInitFunc) cal_query_init
+ };
+ cal_query_type = g_type_register_static (G_TYPE_OBJECT, "CalQuery", &info, 0);
}
- CORBA_exception_free (&ev);
-
- return query;
-
- error:
-
- CORBA_exception_free (&ev);
-
- bonobo_object_unref (BONOBO_OBJECT (priv->ql));
- priv->ql = NULL;
- priv->corba_query = CORBA_OBJECT_NIL;
- return NULL;
+ return cal_query_type;
}
/**
@@ -379,20 +327,12 @@ cal_query_construct (CalQuery *query,
* Return value: A newly-created query object, or NULL if the request failed.
**/
CalQuery *
-cal_query_new (CalClient *client,
- GNOME_Evolution_Calendar_Cal cal,
- const char *sexp)
+cal_query_new (GNOME_Evolution_Calendar_Query corba_query, QueryListener *listener, CalClient *client)
{
CalQuery *query;
- query = g_object_new (CAL_QUERY_TYPE, NULL);
-
- if (!cal_query_construct (query, cal, sexp)) {
- g_object_unref (G_OBJECT (query));
- return NULL;
- }
-
- query->priv->client = client;
+ query = g_object_new (CAL_QUERY_TYPE, "query", corba_query, "listener",
+ listener, "client", client, NULL);
return query;
}
@@ -412,3 +352,23 @@ cal_query_get_client (CalQuery *query)
return query->priv->client;
}
+
+void
+cal_query_start (CalQuery *query)
+{
+ CalQueryPrivate *priv;
+ CORBA_Environment ev;
+
+ g_return_if_fail (query != NULL);
+ g_return_if_fail (IS_CAL_QUERY (query));
+
+ priv = query->priv;
+
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Calendar_Query_start (priv->query, &ev);
+ if (BONOBO_EX (&ev))
+ g_warning (G_STRLOC ": Unable to start query");
+
+ CORBA_exception_free (&ev);
+}
diff --git a/calendar/cal-client/cal-query.h b/calendar/cal-client/cal-query.h
index 77429035fa..05390dd12a 100644
--- a/calendar/cal-client/cal-query.h
+++ b/calendar/cal-client/cal-query.h
@@ -22,7 +22,8 @@
#define CAL_QUERY_H
#include <glib-object.h>
-
+#include "cal-client-types.h"
+#include "query-listener.h"
#include "evolution-calendar.h"
G_BEGIN_DECLS
@@ -37,14 +38,6 @@ typedef struct _CalClient CalClient;
#define IS_CAL_QUERY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CAL_QUERY_TYPE))
#define IS_CAL_QUERY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CAL_QUERY_TYPE))
-#define CAL_QUERY_DONE_STATUS_ENUM_TYPE (cal_query_done_status_enum_get_type ())
-
-/* Status values when a query terminates */
-typedef enum {
- CAL_QUERY_DONE_SUCCESS,
- CAL_QUERY_DONE_PARSE_ERROR
-} CalQueryDoneStatus;
-
typedef struct _CalQueryPrivate CalQueryPrivate;
typedef struct {
@@ -58,30 +51,18 @@ typedef struct {
GObjectClass parent_class;
/* Notification signals */
-
- void (* obj_updated) (CalQuery *query, const char *uid,
- gboolean query_in_progress, int n_scanned, int total);
- void (* obj_removed) (CalQuery *query, const char *uid);
-
- void (* query_done) (CalQuery *query, CalQueryDoneStatus status, const char *error_str);
-
- void (* eval_error) (CalQuery *query, const char *error_str);
+ void (* objects_added) (CalQuery *query, GList *objects);
+ void (* objects_modified) (CalQuery *query, GList *objects);
+ void (* objects_removed) (CalQuery *query, GList *uids);
+ void (* query_progress) (CalQuery *query, char *message, int percent);
+ void (* query_done) (CalQuery *query, ECalendarStatus status);
} CalQueryClass;
GType cal_query_get_type (void);
-GType cal_query_done_status_enum_get_type (void);
-
-CalQuery *cal_query_construct (CalQuery *query,
- GNOME_Evolution_Calendar_Cal cal,
- const char *sexp);
-
-CalQuery *cal_query_new (CalClient *client,
- GNOME_Evolution_Calendar_Cal cal,
- const char *sexp);
+CalQuery *cal_query_new (GNOME_Evolution_Calendar_Query corba_query, QueryListener *listener, CalClient *client);
CalClient *cal_query_get_client (CalQuery *query);
-
-
+void cal_query_start (CalQuery *query);
G_END_DECLS
diff --git a/calendar/cal-client/client-test.c b/calendar/cal-client/client-test.c
index cb6eed17b2..48763be50a 100644
--- a/calendar/cal-client/client-test.c
+++ b/calendar/cal-client/client-test.c
@@ -45,24 +45,37 @@ cl_printf (CalClient *client, const char *format, ...)
va_end (args);
}
-/* Dumps some interesting data from a component */
static void
-dump_component (CalComponent *comp)
+objects_added_cb (GObject *object, GList *objects, gpointer data)
{
- const char *uid;
- CalComponentText summary;
+ GList *l;
+
+ for (l = objects; l; l = l->next)
+ cl_printf (data, "Object added %s\n", icalcomponent_get_uid (l->data));
+}
- cal_component_get_uid (comp, &uid);
+static void
+objects_modified_cb (GObject *object, GList *objects, gpointer data)
+{
+ GList *l;
+
+ for (l = objects; l; l = l->next)
+ cl_printf (data, "Object modified %s\n", icalcomponent_get_uid (l->data));
+}
- printf ("UID %s\n", uid);
+static void
+objects_removed_cb (GObject *object, GList *objects, gpointer data)
+{
+ GList *l;
+
+ for (l = objects; l; l = l->next)
+ cl_printf (data, "Object removed %s\n", icalcomponent_get_uid (l->data));
+}
- cal_component_get_summary (comp, &summary);
- if (summary.value)
- printf ("\tSummary: `%s', altrep `%s'\n",
- summary.value,
- summary.altrep ? summary.altrep : "NONE");
- else
- printf ("\tNo summary\n");
+static void
+query_done_cb (GObject *object, ECalendarStatus status, gpointer data)
+{
+ cl_printf (data, "Query done\n");
}
/* Lists the UIDs of objects in a calendar, called as an idle handler */
@@ -70,47 +83,38 @@ static gboolean
list_uids (gpointer data)
{
CalClient *client;
- GList *uids;
+ GList *objects = NULL;
GList *l;
-
+
client = CAL_CLIENT (data);
- uids = cal_client_get_uids (client, CALOBJ_TYPE_ANY);
-
- cl_printf (client, "UIDs: ");
+ g_message ("Blah");
+
+ if (!cal_client_get_object_list (client, "(contains? \"any\" \"Test4\")", &objects, NULL))
+ return FALSE;
+
+ cl_printf (client, "UIDS: ");
- if (!uids)
+ if (!objects)
printf ("none\n");
else {
- for (l = uids; l; l = l->next) {
- char *uid;
+ for (l = objects; l; l = l->next) {
+ const char *uid;
- uid = l->data;
+ uid = icalcomponent_get_uid (l->data);
printf ("`%s' ", uid);
}
printf ("\n");
- for (l = uids; l; l = l->next) {
- char *uid;
- CalComponent *comp;
- CalClientGetStatus status;
-
- uid = l->data;
- status = cal_client_get_object (client, uid, &comp);
-
- if (status == CAL_CLIENT_GET_SUCCESS) {
- printf ("------------------------------\n");
- dump_component (comp);
- printf ("------------------------------\n");
- g_object_unref (comp);
- } else {
- printf ("FAILED: %d\n", status);
- }
+ for (l = objects; l; l = l->next) {
+ printf ("------------------------------\n");
+ printf ("%s", icalcomponent_as_ical_string (l->data));
+ printf ("------------------------------\n");
}
}
- cal_obj_uid_list_free (uids);
+ cal_client_free_object_list (objects);
g_object_unref (client);
@@ -121,6 +125,8 @@ list_uids (gpointer data)
static void
cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data)
{
+ CalQuery *query;
+
cl_printf (client, "Load/create %s\n",
((status == CAL_CLIENT_OPEN_SUCCESS) ? "success" :
(status == CAL_CLIENT_OPEN_ERROR) ? "error" :
@@ -129,40 +135,29 @@ cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data)
"unknown status value"));
if (status == CAL_CLIENT_OPEN_SUCCESS) {
- GList *comp_list;
-
- /* get free/busy information */
- comp_list = cal_client_get_free_busy (client, NULL, 0, time (NULL));
- if (comp_list) {
- GList *l;
-
- for (l = comp_list; l; l = l->next) {
- char *comp_str;
-
- comp_str = cal_component_get_as_string (CAL_COMPONENT (l->data));
- g_object_unref (l->data);
- cl_printf (client, "Free/Busy -> %s\n", comp_str);
- g_free (comp_str);
- }
- g_list_free (comp_list);
- }
-
+ if (!cal_client_get_query (client, "(contains? \"any\" \"Test4\")", &query, NULL))
+ g_warning (G_STRLOC ": Unable to obtain query");
+
+ g_signal_connect (G_OBJECT (query), "objects_added",
+ G_CALLBACK (objects_added_cb), client);
+ g_signal_connect (G_OBJECT (query), "objects_modified",
+ G_CALLBACK (objects_modified_cb), client);
+ g_signal_connect (G_OBJECT (query), "objects_removed",
+ G_CALLBACK (objects_removed_cb), client);
+ g_signal_connect (G_OBJECT (query), "query_done",
+ G_CALLBACK (query_done_cb), client);
+
+ cal_query_start (query);
+
g_idle_add (list_uids, client);
}
else
g_object_unref (client);
}
-/* Callback used when an object is updated */
-static void
-obj_updated_cb (CalClient *client, const char *uid, gpointer data)
-{
- cl_printf (client, "Object updated: %s\n", uid);
-}
-
/* Callback used when a client is destroyed */
static void
-client_destroy_cb (GObject *object, gpointer data)
+client_destroy_cb (gpointer data, GObject *object)
{
if (CAL_CLIENT (object) == client1)
client1 = NULL;
@@ -177,33 +172,24 @@ client_destroy_cb (GObject *object, gpointer data)
/* Creates a calendar client and tries to load the specified URI into it */
static void
-create_client (CalClient **client, const char *uri, gboolean only_if_exists)
+create_client (CalClient **client, const char *uri, CalObjType type, gboolean only_if_exists)
{
- gboolean result;
-
- *client = cal_client_new ();
+ *client = cal_client_new (uri, type);
if (!*client) {
- g_message ("create_client(): could not create the client");
+ g_message (G_STRLOC ": could not create the client");
exit (1);
}
- g_signal_connect (*client, "destroy",
- G_CALLBACK (client_destroy_cb),
- NULL);
+ g_object_weak_ref (G_OBJECT (*client), client_destroy_cb, NULL);
g_signal_connect (*client, "cal_opened",
G_CALLBACK (cal_opened_cb),
NULL);
- g_signal_connect (*client, "obj_updated",
- G_CALLBACK (obj_updated_cb),
- NULL);
printf ("Calendar loading `%s'...\n", uri);
- result = cal_client_open_calendar (*client, uri, only_if_exists);
-
- if (!result) {
- g_message ("create_client(): failure when issuing calendar open request `%s'",
+ if (!cal_client_open (*client, only_if_exists, NULL)) {
+ g_message (G_STRLOC ": failure when issuing calendar open request `%s'",
uri);
exit (1);
}
@@ -212,8 +198,6 @@ create_client (CalClient **client, const char *uri, gboolean only_if_exists)
int
main (int argc, char **argv)
{
- char *dir;
-
bindtextdomain (GETTEXT_PACKAGE, EVOLUTION_LOCALEDIR);
textdomain (GETTEXT_PACKAGE);
@@ -225,10 +209,9 @@ main (int argc, char **argv)
exit (1);
}
- dir = g_strdup_printf ("%s/evolution/local/Calendar/calendar.ics", g_get_home_dir ());
- create_client (&client1, dir, FALSE);
- g_free (dir);
- create_client (&client2, "/cvs/evolution/calendar/cal-client/test.ics", TRUE);
+ create_client (&client1, "file:///home/gnome24-evolution-new-calendar/evolution/local/Calendar",
+ CALOBJ_TYPE_EVENT, FALSE);
+// create_client (&client2, "file:///tmp/tasks", TRUE);
bonobo_main ();
return 0;
diff --git a/calendar/cal-client/query-listener.c b/calendar/cal-client/query-listener.c
index 6bd7bfc6f7..4c8cbb4fe5 100644
--- a/calendar/cal-client/query-listener.c
+++ b/calendar/cal-client/query-listener.c
@@ -22,6 +22,7 @@
#include <config.h>
#endif
+#include "cal-marshal.h"
#include "query-listener.h"
@@ -29,166 +30,164 @@
/* Private part of the QueryListener structure */
struct _QueryListenerPrivate {
- /* Callbacks for notification and their closure data */
- QueryListenerObjUpdatedFn obj_updated_fn;
- QueryListenerObjRemovedFn obj_removed_fn;
- QueryListenerQueryDoneFn query_done_fn;
- QueryListenerEvalErrorFn eval_error_fn;
- gpointer fn_data;
-
- /* Whether notification is desired */
- gboolean notify : 1;
+ int dummy;
};
-
-
-static void query_listener_class_init (QueryListenerClass *class);
-static void query_listener_init (QueryListener *ql, QueryListenerClass *class);
-static void query_listener_finalize (GObject *object);
-
-static void impl_notifyObjUpdated (PortableServer_Servant servant,
- const GNOME_Evolution_Calendar_CalObjUIDSeq *uids,
- CORBA_boolean query_in_progress,
- CORBA_long n_scanned,
- CORBA_long total,
- CORBA_Environment *ev);
-
-static void impl_notifyObjRemoved (PortableServer_Servant servant,
- const CORBA_char *uid,
- CORBA_Environment *ev);
-
-static void impl_notifyQueryDone (PortableServer_Servant servant,
- GNOME_Evolution_Calendar_QueryListener_QueryDoneStatus corba_status,
- const CORBA_char *error_str,
- CORBA_Environment *ev);
+/* Signal IDs */
+enum {
+ OBJECTS_ADDED,
+ OBJECTS_MODIFIED,
+ OBJECTS_REMOVED,
+ QUERY_PROGRESS,
+ QUERY_DONE,
+ LAST_SIGNAL
+};
-static void impl_notifyEvalError (PortableServer_Servant servant,
- const CORBA_char *error_str,
- CORBA_Environment *ev);
+static guint signals[LAST_SIGNAL] = { 0 };
static BonoboObjectClass *parent_class;
-
-
-BONOBO_TYPE_FUNC_FULL (QueryListener,
- GNOME_Evolution_Calendar_QueryListener,
- BONOBO_TYPE_OBJECT,
- query_listener);
-
-/* Class initialization function for the live search query listener */
-static void
-query_listener_class_init (QueryListenerClass *class)
+/* CORBA method implementations */
+/* FIXME This is duplicated from cal-listener.c */
+static ECalendarStatus
+convert_status (const GNOME_Evolution_Calendar_CallStatus status)
{
- GObjectClass *object_class;
+ switch (status) {
+ case GNOME_Evolution_Calendar_Success:
+ return E_CALENDAR_STATUS_OK;
+ case GNOME_Evolution_Calendar_RepositoryOffline:
+ return E_CALENDAR_STATUS_REPOSITORY_OFFLINE;
+ case GNOME_Evolution_Calendar_PermissionDenied:
+ return E_CALENDAR_STATUS_PERMISSION_DENIED;
+ case GNOME_Evolution_Calendar_ObjectNotFound:
+ return E_CALENDAR_STATUS_OBJECT_NOT_FOUND;
+ case GNOME_Evolution_Calendar_CardIdAlreadyExists:
+ return E_CALENDAR_STATUS_CARD_ID_ALREADY_EXISTS;
+ case GNOME_Evolution_Calendar_AuthenticationFailed:
+ return E_CALENDAR_STATUS_AUTHENTICATION_FAILED;
+ case GNOME_Evolution_Calendar_AuthenticationRequired:
+ return E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED;
+ case GNOME_Evolution_Calendar_OtherError:
+ default:
+ return E_CALENDAR_STATUS_OTHER_ERROR;
+ }
+}
- object_class = (GObjectClass *) class;
+/* FIXME This is duplicated from cal-listener.c */
+static GList *
+build_object_list (const GNOME_Evolution_Calendar_stringlist *seq)
+{
+ GList *list;
+ int i;
+
+ list = NULL;
+ for (i = 0; i < seq->_length; i++) {
+ icalcomponent *comp;
+
+ comp = icalcomponent_new_from_string (seq->_buffer[i]);
+ if (!comp)
+ continue;
+
+ list = g_list_prepend (list, comp);
+ }
+
+ return list;
+}
- parent_class = g_type_class_peek_parent (class);
+static GList *
+build_uid_list (const GNOME_Evolution_Calendar_CalObjUIDSeq *seq)
+{
+ GList *list;
+ int i;
- object_class->finalize = query_listener_finalize;
+ list = NULL;
+ for (i = 0; i < seq->_length; i++)
+ list = g_list_prepend (list, g_strdup (seq->_buffer[i]));
- class->epv.notifyObjUpdated = impl_notifyObjUpdated;
- class->epv.notifyObjRemoved = impl_notifyObjRemoved;
- class->epv.notifyQueryDone = impl_notifyQueryDone;
- class->epv.notifyEvalError = impl_notifyEvalError;
+ return list;
}
-/* Object initialization function for the live search query listener */
static void
-query_listener_init (QueryListener *ql, QueryListenerClass *class)
+impl_notifyObjectsAdded (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_stringlist *objects,
+ CORBA_Environment *ev)
{
+ QueryListener *ql;
QueryListenerPrivate *priv;
+ GList *object_list, *l;
+
+ ql = QUERY_LISTENER (bonobo_object_from_servant (servant));
+ priv = ql->priv;
- priv = g_new0 (QueryListenerPrivate, 1);
- ql->priv = priv;
-
- priv->obj_updated_fn = NULL;
- priv->obj_removed_fn = NULL;
- priv->query_done_fn = NULL;
- priv->eval_error_fn = NULL;
- priv->fn_data = NULL;
+ object_list = build_object_list (objects);
+
+ g_signal_emit (G_OBJECT (ql), signals[OBJECTS_ADDED], 0, object_list);
- priv->notify = TRUE;
+ for (l = object_list; l; l = l->next)
+ icalcomponent_free (l->data);
+ g_list_free (object_list);
}
-/* Finalize handler for the live search query listener */
static void
-query_listener_finalize (GObject *object)
+impl_notifyObjectsModified (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_stringlist *objects,
+ CORBA_Environment *ev)
{
QueryListener *ql;
QueryListenerPrivate *priv;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (IS_QUERY_LISTENER (object));
-
- ql = QUERY_LISTENER (object);
+ GList *object_list, *l;
+
+ ql = QUERY_LISTENER (bonobo_object_from_servant (servant));
priv = ql->priv;
- priv->obj_updated_fn = NULL;
- priv->obj_removed_fn = NULL;
- priv->query_done_fn = NULL;
- priv->eval_error_fn = NULL;
- priv->fn_data = NULL;
-
- priv->notify = FALSE;
+ object_list = build_object_list (objects);
+
+ g_signal_emit (G_OBJECT (ql), signals[OBJECTS_MODIFIED], 0, object_list);
- g_free (priv);
- ql->priv = NULL;
-
- if (G_OBJECT_CLASS (parent_class)->finalize)
- (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+ for (l = object_list; l; l = l->next)
+ icalcomponent_free (l->data);
+ g_list_free (object_list);
}
-
-
-/* CORBA method implementations */
-
-/* ::notifyObjUpdated() method */
static void
-impl_notifyObjUpdated (PortableServer_Servant servant,
- const GNOME_Evolution_Calendar_CalObjUIDSeq *uids,
- CORBA_boolean query_in_progress,
- CORBA_long n_scanned,
- CORBA_long total,
- CORBA_Environment *ev)
+impl_notifyObjectsRemoved (PortableServer_Servant servant,
+ const GNOME_Evolution_Calendar_CalObjUIDSeq *uids,
+ CORBA_Environment *ev)
{
QueryListener *ql;
QueryListenerPrivate *priv;
-
+ GList *uid_list, *l;
+
ql = QUERY_LISTENER (bonobo_object_from_servant (servant));
priv = ql->priv;
- if (!priv->notify)
- return;
+ uid_list = build_uid_list (uids);
+
+ g_signal_emit (G_OBJECT (ql), signals[OBJECTS_REMOVED], 0, uid_list);
- g_assert (priv->obj_updated_fn != NULL);
- (* priv->obj_updated_fn) (ql, uids, query_in_progress, n_scanned, total, priv->fn_data);
+ for (l = uid_list; l; l = l->next)
+ g_free (l->data);
+ g_list_free (uid_list);
}
-/* ::notifyObjRemoved() method */
static void
-impl_notifyObjRemoved (PortableServer_Servant servant,
- const CORBA_char *uid,
- CORBA_Environment *ev)
+impl_notifyQueryProgress (PortableServer_Servant servant,
+ const CORBA_char *message,
+ const CORBA_short percent,
+ CORBA_Environment *ev)
{
QueryListener *ql;
QueryListenerPrivate *priv;
ql = QUERY_LISTENER (bonobo_object_from_servant (servant));
priv = ql->priv;
-
- if (!priv->notify)
- return;
-
- g_assert (priv->obj_removed_fn != NULL);
- (* priv->obj_removed_fn) (ql, uid, priv->fn_data);
+
+ g_signal_emit (G_OBJECT (ql), signals[QUERY_PROGRESS], 0, message, percent);
}
-/* ::notifyQueryDone() method */
static void
impl_notifyQueryDone (PortableServer_Servant servant,
- GNOME_Evolution_Calendar_QueryListener_QueryDoneStatus corba_status,
- const CORBA_char *error_str,
+ const GNOME_Evolution_Calendar_CallStatus status,
CORBA_Environment *ev)
{
QueryListener *ql;
@@ -196,126 +195,110 @@ impl_notifyQueryDone (PortableServer_Servant servant,
ql = QUERY_LISTENER (bonobo_object_from_servant (servant));
priv = ql->priv;
+
+ g_signal_emit (G_OBJECT (ql), signals[QUERY_DONE], 0, convert_status (status));
+}
- if (!priv->notify)
- return;
+/* Object initialization function for the live search query listener */
+static void
+query_listener_init (QueryListener *ql, QueryListenerClass *class)
+{
+ QueryListenerPrivate *priv;
- g_assert (priv->query_done_fn != NULL);
- (* priv->query_done_fn) (ql, corba_status, error_str, priv->fn_data);
+ priv = g_new0 (QueryListenerPrivate, 1);
+ ql->priv = priv;
}
-/* ::notifyEvalError() method */
+/* Finalize handler for the live search query listener */
static void
-impl_notifyEvalError (PortableServer_Servant servant,
- const CORBA_char *error_str,
- CORBA_Environment *ev)
+query_listener_finalize (GObject *object)
{
QueryListener *ql;
QueryListenerPrivate *priv;
- ql = QUERY_LISTENER (bonobo_object_from_servant (servant));
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (IS_QUERY_LISTENER (object));
+
+ ql = QUERY_LISTENER (object);
priv = ql->priv;
- if (!priv->notify)
- return;
+ g_free (priv);
- g_assert (priv->eval_error_fn != NULL);
- (* priv->eval_error_fn) (ql, error_str, priv->fn_data);
+ if (G_OBJECT_CLASS (parent_class)->finalize)
+ (* G_OBJECT_CLASS (parent_class)->finalize) (object);
}
-
-
-/**
- * query_listener_construct:
- * @ql: A query listener.
- * @obj_updated_fn: Callback to use when a component is updated in the query.
- * @obj_removed_fn: Callback to use when a component is removed from the query.
- * @query_done_fn: Callback to use when a query is done.
- * @eval_error_fn: Callback to use when an evaluation error happens during a query.
- * @fn_data: Closure data to pass to the callbacks.
- *
- * Constructs a query listener by setting the callbacks it will use for
- * notification from the calendar server.
- *
- * Return value: The same value as @ql.
- **/
-QueryListener *
-query_listener_construct (QueryListener *ql,
- QueryListenerObjUpdatedFn obj_updated_fn,
- QueryListenerObjRemovedFn obj_removed_fn,
- QueryListenerQueryDoneFn query_done_fn,
- QueryListenerEvalErrorFn eval_error_fn,
- gpointer fn_data)
+/* Class initialization function for the live search query listener */
+static void
+query_listener_class_init (QueryListenerClass *klass)
{
- QueryListenerPrivate *priv;
+ GObjectClass *object_class;
- g_return_val_if_fail (ql != NULL, NULL);
- g_return_val_if_fail (IS_QUERY_LISTENER (ql), NULL);
- g_return_val_if_fail (obj_updated_fn != NULL, NULL);
- g_return_val_if_fail (obj_removed_fn != NULL, NULL);
- g_return_val_if_fail (query_done_fn != NULL, NULL);
- g_return_val_if_fail (eval_error_fn != NULL, NULL);
+ object_class = (GObjectClass *) klass;
- priv = ql->priv;
+ parent_class = g_type_class_peek_parent (klass);
- priv->obj_updated_fn = obj_updated_fn;
- priv->obj_removed_fn = obj_removed_fn;
- priv->query_done_fn = query_done_fn;
- priv->eval_error_fn = eval_error_fn;
- priv->fn_data = fn_data;
+ object_class->finalize = query_listener_finalize;
- return ql;
+ klass->epv.notifyObjectsAdded = impl_notifyObjectsAdded;
+ klass->epv.notifyObjectsModified = impl_notifyObjectsModified;
+ klass->epv.notifyObjectsRemoved = impl_notifyObjectsRemoved;
+ klass->epv.notifyQueryProgress = impl_notifyQueryProgress;
+ klass->epv.notifyQueryDone = impl_notifyQueryDone;
+
+ signals[OBJECTS_ADDED] =
+ g_signal_new ("objects_added",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (QueryListenerClass, objects_added),
+ NULL, NULL,
+ cal_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+ signals[OBJECTS_MODIFIED] =
+ g_signal_new ("objects_modified",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (QueryListenerClass, objects_modified),
+ NULL, NULL,
+ cal_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+ signals[OBJECTS_REMOVED] =
+ g_signal_new ("objects_removed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (QueryListenerClass, objects_removed),
+ NULL, NULL,
+ cal_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+ signals[QUERY_PROGRESS] =
+ g_signal_new ("query_progress",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (QueryListenerClass, query_progress),
+ NULL, NULL,
+ cal_marshal_VOID__POINTER,
+ G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_INT);
+ signals[QUERY_DONE] =
+ g_signal_new ("query_done",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (QueryListenerClass, query_done),
+ NULL, NULL,
+ cal_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
}
-/**
- * query_listener_new:
- * @obj_updated_fn: Callback to use when a component is updated in the query.
- * @obj_removed_fn: Callback to use when a component is removed from the query.
- * @query_done_fn: Callback to use when a query is done.
- * @eval_error_fn: Callback to use when an evaluation error happens during a query.
- * @fn_data: Closure data to pass to the callbacks.
- *
- * Creates a new query listener object.
- *
- * Return value: A newly-created query listener object.
- **/
+BONOBO_TYPE_FUNC_FULL (QueryListener,
+ GNOME_Evolution_Calendar_QueryListener,
+ BONOBO_TYPE_OBJECT,
+ query_listener);
+
QueryListener *
-query_listener_new (QueryListenerObjUpdatedFn obj_updated_fn,
- QueryListenerObjRemovedFn obj_removed_fn,
- QueryListenerQueryDoneFn query_done_fn,
- QueryListenerEvalErrorFn eval_error_fn,
- gpointer fn_data)
+query_listener_new (void)
{
QueryListener *ql;
ql = g_object_new (QUERY_LISTENER_TYPE, NULL);
- return query_listener_construct (ql,
- obj_updated_fn,
- obj_removed_fn,
- query_done_fn,
- eval_error_fn,
- fn_data);
-}
-
-/**
- * query_listener_stop_notification:
- * @ql: A query listener.
- *
- * Informs a query listener that no further notification is desired. The
- * callbacks specified when the listener was created will no longer be invoked
- * after this function is called.
- **/
-void
-query_listener_stop_notification (QueryListener *ql)
-{
- QueryListenerPrivate *priv;
-
- g_return_if_fail (ql != NULL);
- g_return_if_fail (IS_QUERY_LISTENER (ql));
-
- priv = ql->priv;
- g_return_if_fail (priv->notify != FALSE);
-
- priv->notify = FALSE;
+ return ql;
}
diff --git a/calendar/cal-client/query-listener.h b/calendar/cal-client/query-listener.h
index eeb42afc7e..6a204bbf77 100644
--- a/calendar/cal-client/query-listener.h
+++ b/calendar/cal-client/query-listener.h
@@ -22,6 +22,7 @@
#define QUERY_LISTENER_H
#include <bonobo/bonobo-object.h>
+#include "cal-client-types.h"
#include "evolution-calendar.h"
G_BEGIN_DECLS
@@ -48,47 +49,18 @@ typedef struct {
BonoboObjectClass parent_class;
POA_GNOME_Evolution_Calendar_QueryListener__epv epv;
+
+ void (*objects_added) (QueryListener *listener, GList *objects);
+ void (*objects_modified) (QueryListener *listener, GList *objects);
+ void (*objects_removed) (QueryListener *listener, GList *uids);
+ void (*query_progress) (QueryListener *listener, const char *message, int percent);
+ void (*query_done) (QueryListener *listener, ECalendarStatus status);
} QueryListenerClass;
/* Notification functions */
-typedef void (* QueryListenerObjUpdatedFn) (QueryListener *ql,
- const GNOME_Evolution_Calendar_CalObjUIDSeq *uids,
- CORBA_boolean query_in_progress,
- CORBA_long n_scanned,
- CORBA_long total,
- gpointer data);
-
-typedef void (* QueryListenerObjRemovedFn) (QueryListener *ql,
- const CORBA_char *uid,
- gpointer data);
-
-typedef void (* QueryListenerQueryDoneFn) (
- QueryListener *ql,
- GNOME_Evolution_Calendar_QueryListener_QueryDoneStatus status,
- const CORBA_char *error_str,
- gpointer data);
-
-typedef void (* QueryListenerEvalErrorFn) (QueryListener *ql,
- const CORBA_char *error_str,
- gpointer data);
-
GType query_listener_get_type (void);
-
-QueryListener *query_listener_construct (QueryListener *ql,
- QueryListenerObjUpdatedFn obj_updated_fn,
- QueryListenerObjRemovedFn obj_removed_fn,
- QueryListenerQueryDoneFn query_done_fn,
- QueryListenerEvalErrorFn eval_error_fn,
- gpointer fn_data);
-
-QueryListener *query_listener_new (QueryListenerObjUpdatedFn obj_updated_fn,
- QueryListenerObjRemovedFn obj_removed_fn,
- QueryListenerQueryDoneFn query_done_fn,
- QueryListenerEvalErrorFn eval_error_fn,
- gpointer fn_data);
-
-void query_listener_stop_notification (QueryListener *ql);
+QueryListener *query_listener_new (void);
diff --git a/calendar/cal-util/cal-util.c b/calendar/cal-util/cal-util.c
index 1e03c86d75..f1c32610c1 100644
--- a/calendar/cal-util/cal-util.c
+++ b/calendar/cal-util/cal-util.c
@@ -584,29 +584,7 @@ cal_util_priority_from_string (const char *string)
char *
cal_util_expand_uri (char *uri, gboolean tasks)
{
- char *file_uri, *file_name;
-
- if (!strncmp (uri, "file://", 7)) {
- file_uri = uri + 7;
- if (strlen (file_uri) > 4
- && !strcmp (file_uri + strlen (file_uri) - 4, ".ics")) {
-
- /* it's a .ics file */
- return g_strdup (uri);
- }
-
- /* we assume it's a dir and glom <type>.ics onto the end. */
- if (tasks)
- file_name = g_concat_dir_and_file (file_uri, "tasks.ics");
- else
- file_name = g_concat_dir_and_file (file_uri, "calendar.ics");
- file_uri = g_strdup_printf("file://%s", file_name);
- g_free(file_name);
- } else {
- file_uri = g_strdup (uri);
- }
-
- return file_uri;
+ return g_strdup (uri);
}
/* callback for icalcomponent_foreach_tzid */
diff --git a/calendar/conduits/calendar/calendar-conduit.c b/calendar/conduits/calendar/calendar-conduit.c
index 1893e6b34c..05ddde2c7f 100644
--- a/calendar/conduits/calendar/calendar-conduit.c
+++ b/calendar/conduits/calendar/calendar-conduit.c
@@ -253,7 +253,7 @@ struct _ECalConduitContext {
icaltimezone *timezone;
CalComponent *default_comp;
- GList *uids;
+ GList *comps;
GList *changed;
GHashTable *changed_hash;
GList *locals;
@@ -276,7 +276,7 @@ e_calendar_context_new (guint32 pilot_id)
ctxt->client = NULL;
ctxt->timezone = NULL;
ctxt->default_comp = NULL;
- ctxt->uids = NULL;
+ ctxt->comps = NULL;
ctxt->changed = NULL;
ctxt->changed_hash = NULL;
ctxt->locals = NULL;
@@ -311,8 +311,11 @@ e_calendar_context_destroy (ECalConduitContext *ctxt)
g_object_unref (ctxt->client);
if (ctxt->default_comp != NULL)
g_object_unref (ctxt->default_comp);
- if (ctxt->uids != NULL)
- cal_obj_uid_list_free (ctxt->uids);
+ if (ctxt->comps != NULL) {
+ for (l = ctxt->comps; l; l = l->next)
+ g_object_unref (l->data);
+ g_list_free (ctxt->comps);
+ }
if (ctxt->changed != NULL)
cal_client_change_list_free (ctxt->changed);
@@ -404,16 +407,24 @@ start_calendar_server_cb (CalClient *cal_client,
static int
start_calendar_server (ECalConduitContext *ctxt)
{
+ char *uri;
gboolean success = FALSE;
g_return_val_if_fail (ctxt != NULL, -2);
- ctxt->client = cal_client_new ();
-
+ /* FIXME Need a mechanism for the user to select uri's */
+ /* FIXME Can we use the cal model? */
+ uri = g_strdup_printf ("file://%s/local/Calendar/", g_get_home_dir ());
+ ctxt->client = cal_client_new (uri, CALOBJ_TYPE_EVENT);
+ g_free (uri);
+
+ if (!ctxt->client)
+ return -1;
+
g_signal_connect (ctxt->client, "cal_opened",
G_CALLBACK (start_calendar_server_cb), &success);
- if (!cal_client_open_default_calendar (ctxt->client, FALSE))
+ if (!cal_client_open (ctxt->client, FALSE, NULL))
return -1;
/* run a sub event loop to turn cal-client's async load
@@ -433,8 +444,8 @@ get_timezone (CalClient *client, const char *tzid)
icaltimezone *timezone = NULL;
timezone = icaltimezone_get_builtin_timezone_from_tzid (tzid);
- if (timezone == NULL)
- cal_client_get_timezone (client, tzid, &timezone);
+ if (timezone == NULL)
+ cal_client_get_timezone (client, tzid, &timezone, NULL);
return timezone;
}
@@ -550,7 +561,7 @@ is_all_day (CalClient *client, CalComponentDateTime *dt_start, CalComponentDateT
}
static gboolean
-process_multi_day (ECalConduitContext *ctxt, CalClientChange *ccc, GList **multi_uid, GList **multi_ccc)
+process_multi_day (ECalConduitContext *ctxt, CalClientChange *ccc, GList **multi_comp, GList **multi_ccc)
{
CalComponentDateTime dt_start, dt_end;
icaltimezone *tz_start, *tz_end;
@@ -562,7 +573,7 @@ process_multi_day (ECalConduitContext *ctxt, CalClientChange *ccc, GList **multi
gboolean ret = TRUE;
*multi_ccc = NULL;
- *multi_uid = NULL;
+ *multi_comp = NULL;
if (ccc->type == CAL_CLIENT_CHANGE_DELETED)
return FALSE;
@@ -617,13 +628,14 @@ process_multi_day (ECalConduitContext *ctxt, CalClientChange *ccc, GList **multi
dt_end.value = &end_value;
cal_component_set_dtend (clone, &dt_end);
- cal_client_update_object (ctxt->client, clone);
+ /* FIXME Error handling */
+ cal_client_create_object (ctxt->client, cal_component_get_icalcomponent (clone), NULL, NULL);
c->comp = clone;
c->type = CAL_CLIENT_CHANGE_ADDED;
*multi_ccc = g_list_prepend (*multi_ccc, c);
- *multi_uid = g_list_prepend (*multi_uid, new_uid);
+ *multi_comp = g_list_prepend (*multi_comp, g_object_ref (c->comp));
event_start = day_end;
day_end = time_day_end_with_zone (event_start, ctxt->timezone);
@@ -632,7 +644,8 @@ process_multi_day (ECalConduitContext *ctxt, CalClientChange *ccc, GList **multi
dt_end.value = old_end_value;
cal_component_get_uid (ccc->comp, &uid);
- cal_client_remove_object (ctxt->client, uid);
+ /* FIXME Error handling */
+ cal_client_remove_object (ctxt->client, uid, NULL);
ccc->type = CAL_CLIENT_CHANGE_DELETED;
cleanup:
@@ -1007,13 +1020,11 @@ local_record_from_uid (ECalLocalRecord *local,
{
CalComponent *comp;
icalcomponent *icalcomp;
- CalClientGetStatus status;
+ GError *error = NULL;
g_assert(local!=NULL);
- status = cal_client_get_object (ctxt->client, uid, &icalcomp);
-
- if (status == CAL_CLIENT_GET_SUCCESS) {
+ if (cal_client_get_object (ctxt->client, uid, NULL, &icalcomp, &error)) {
comp = cal_component_new ();
if (!cal_component_set_icalcomponent (comp, icalcomp)) {
g_object_unref (comp);
@@ -1023,7 +1034,7 @@ local_record_from_uid (ECalLocalRecord *local,
local_record_from_comp (local, comp, ctxt);
g_object_unref (comp);
- } else if (status == CAL_CLIENT_GET_NOT_FOUND) {
+ } else if (error->code == E_CALENDAR_STATUS_OBJECT_NOT_FOUND) {
comp = cal_component_new ();
cal_component_set_new_vtype (comp, CAL_COMPONENT_EVENT);
cal_component_set_uid (comp, uid);
@@ -1031,7 +1042,9 @@ local_record_from_uid (ECalLocalRecord *local,
g_object_unref (comp);
} else {
INFO ("Object did not exist");
- }
+ }
+
+ g_clear_error (&error);
}
static CalComponent *
@@ -1283,21 +1296,6 @@ comp_from_remote_record (GnomePilotConduitSyncAbs *conduit,
}
static void
-update_comp (GnomePilotConduitSyncAbs *conduit, CalComponent *comp,
- ECalConduitContext *ctxt)
-{
- CalClientResult success;
-
- g_return_if_fail (conduit != NULL);
- g_return_if_fail (comp != NULL);
-
- success = cal_client_update_object (ctxt->client, comp);
-
- if (success != CAL_CLIENT_RESULT_SUCCESS)
- WARN (_("Error while communicating with calendar server"));
-}
-
-static void
check_for_slow_setting (GnomePilotConduit *c, ECalConduitContext *ctxt)
{
GnomePilotConduitStandard *conduit = GNOME_PILOT_CONDUIT_STANDARD (c);
@@ -1360,11 +1358,13 @@ pre_sync (GnomePilotConduit *conduit,
LOG (g_message ( " Using timezone: %s", icaltimezone_get_tzid (ctxt->timezone) ));
/* Set the default timezone on the backend. */
- if (ctxt->timezone)
- cal_client_set_default_timezone (ctxt->client, ctxt->timezone);
+ if (ctxt->timezone) {
+ if (!cal_client_set_default_timezone (ctxt->client, ctxt->timezone, NULL))
+ return -1;
+ }
/* Get the default component */
- if (cal_client_get_default_object (ctxt->client, CALOBJ_TYPE_EVENT, &icalcomp) != CAL_CLIENT_GET_SUCCESS)
+ if (!cal_client_get_default_object (ctxt->client, &icalcomp, NULL))
return -1;
ctxt->default_comp = cal_component_new ();
@@ -1374,27 +1374,36 @@ pre_sync (GnomePilotConduit *conduit,
return -1;
}
+ ctxt->default_comp = cal_component_new ();
+ if (!cal_component_set_icalcomponent (ctxt->default_comp, icalcomp)) {
+ g_object_unref (ctxt->default_comp);
+ icalcomponent_free (icalcomp);
+ return -1;
+ }
+
/* Load the uid <--> pilot id mapping */
filename = map_name (ctxt);
e_pilot_map_read (filename, &ctxt->map);
g_free (filename);
/* Get the local database */
- ctxt->uids = cal_client_get_uids (ctxt->client, CALOBJ_TYPE_EVENT);
+ if (!cal_client_get_object_list_as_comp (ctxt->client, "(#t)", &ctxt->comps, NULL))
+ return -1;
/* Find the added, modified and deleted items */
change_id = g_strdup_printf ("pilot-sync-evolution-calendar-%d", ctxt->cfg->pilot_id);
- ctxt->changed = cal_client_get_changes (ctxt->client, CALOBJ_TYPE_EVENT, change_id);
+ if (!cal_client_get_changes (ctxt->client, CALOBJ_TYPE_EVENT, change_id, &ctxt->changed, NULL))
+ return -1;
ctxt->changed_hash = g_hash_table_new (g_str_hash, g_str_equal);
g_free (change_id);
/* See if we need to split up any events */
for (l = ctxt->changed; l != NULL; l = l->next) {
CalClientChange *ccc = l->data;
- GList *multi_uid = NULL, *multi_ccc = NULL;
+ GList *multi_comp = NULL, *multi_ccc = NULL;
- if (process_multi_day (ctxt, ccc, &multi_uid, &multi_ccc)) {
- ctxt->uids = g_list_concat (ctxt->uids, multi_uid);
+ if (process_multi_day (ctxt, ccc, &multi_comp, &multi_ccc)) {
+ ctxt->comps = g_list_concat (ctxt->comps, multi_comp);
added = g_list_concat (added, multi_ccc);
removed = g_list_prepend (removed, ccc);
@@ -1442,7 +1451,7 @@ pre_sync (GnomePilotConduit *conduit,
}
/* Set the count information */
- num_records = cal_client_get_n_objects (ctxt->client, CALOBJ_TYPE_EVENT);
+ num_records = g_list_length (ctxt->comps);
gnome_pilot_conduit_sync_abs_set_num_local_records(abs_conduit, num_records);
gnome_pilot_conduit_sync_abs_set_num_new_local_records (abs_conduit, add_records);
gnome_pilot_conduit_sync_abs_set_num_updated_local_records (abs_conduit, mod_records);
@@ -1492,8 +1501,8 @@ post_sync (GnomePilotConduit *conduit,
* a race condition if anyone changes a record elsewhere during sycnc
*/
change_id = g_strdup_printf ("pilot-sync-evolution-calendar-%d", ctxt->cfg->pilot_id);
- changed = cal_client_get_changes (ctxt->client, CALOBJ_TYPE_EVENT, change_id);
- cal_client_change_list_free (changed);
+ if (cal_client_get_changes (ctxt->client, CALOBJ_TYPE_EVENT, change_id, &changed, NULL))
+ cal_client_change_list_free (changed);
g_free (change_id);
LOG (g_message ( "---------------------------------------------------------\n" ));
@@ -1537,7 +1546,7 @@ for_each (GnomePilotConduitSyncAbs *conduit,
ECalLocalRecord **local,
ECalConduitContext *ctxt)
{
- static GList *uids, *iterator;
+ static GList *comps, *iterator;
static int count;
g_return_val_if_fail (local != NULL, -1);
@@ -1545,17 +1554,17 @@ for_each (GnomePilotConduitSyncAbs *conduit,
if (*local == NULL) {
LOG (g_message ( "beginning for_each" ));
- uids = ctxt->uids;
+ comps = ctxt->comps;
count = 0;
- if (uids != NULL) {
- LOG (g_message ( "iterating over %d records", g_list_length (uids) ));
+ if (comps != NULL) {
+ LOG (g_message ( "iterating over %d records", g_list_length (comps)));
*local = g_new0 (ECalLocalRecord, 1);
- local_record_from_uid (*local, uids->data, ctxt);
+ local_record_from_comp (*local, comps->data, ctxt);
g_list_prepend (ctxt->locals, *local);
- iterator = uids;
+ iterator = comps;
} else {
LOG (g_message ( "no events" ));
(*local) = NULL;
@@ -1681,8 +1690,10 @@ add_record (GnomePilotConduitSyncAbs *conduit,
/* Give it a new UID otherwise it will be the uid of the default comp */
uid = cal_component_gen_uid ();
cal_component_set_uid (comp, uid);
+
+ if (!cal_client_create_object (ctxt->client, cal_component_get_icalcomponent (comp), NULL, NULL))
+ return -1;
- update_comp (conduit, comp, ctxt);
e_pilot_map_insert (ctxt->map, remote->ID, uid, FALSE);
g_free (uid);
@@ -1709,7 +1720,10 @@ replace_record (GnomePilotConduitSyncAbs *conduit,
new_comp = comp_from_remote_record (conduit, remote, local->comp, ctxt->client, ctxt->timezone);
g_object_unref (local->comp);
local->comp = new_comp;
- update_comp (conduit, local->comp, ctxt);
+
+ if (!cal_client_modify_object (ctxt->client, cal_component_get_icalcomponent (new_comp),
+ CALOBJ_MOD_ALL, NULL))
+ return -1;
return retval;
}
@@ -1729,7 +1743,8 @@ delete_record (GnomePilotConduitSyncAbs *conduit,
LOG (g_message ( "delete_record: deleting %s\n", uid ));
e_pilot_map_remove_by_uid (ctxt->map, uid);
- cal_client_remove_object (ctxt->client, uid);
+ /* FIXME Error handling */
+ cal_client_remove_object (ctxt->client, uid, NULL);
return 0;
}
diff --git a/calendar/conduits/todo/todo-conduit.c b/calendar/conduits/todo/todo-conduit.c
index 6868368129..35251f4eb6 100644
--- a/calendar/conduits/todo/todo-conduit.c
+++ b/calendar/conduits/todo/todo-conduit.c
@@ -255,7 +255,7 @@ struct _EToDoConduitContext {
icaltimezone *timezone;
CalComponent *default_comp;
- GList *uids;
+ GList *comps;
GList *changed;
GHashTable *changed_hash;
GList *locals;
@@ -275,7 +275,7 @@ e_todo_context_new (guint32 pilot_id)
ctxt->client = NULL;
ctxt->timezone = NULL;
ctxt->default_comp = NULL;
- ctxt->uids = NULL;
+ ctxt->comps = NULL;
ctxt->changed_hash = NULL;
ctxt->changed = NULL;
ctxt->locals = NULL;
@@ -311,8 +311,11 @@ e_todo_context_destroy (EToDoConduitContext *ctxt)
if (ctxt->default_comp != NULL)
g_object_unref (ctxt->default_comp);
- if (ctxt->uids != NULL)
- cal_obj_uid_list_free (ctxt->uids);
+ if (ctxt->comps != NULL) {
+ for (l = ctxt->comps; l; l = l->next)
+ g_object_unref (l->data);
+ g_list_free (ctxt->comps);
+ }
if (ctxt->changed_hash != NULL) {
g_hash_table_foreach_remove (ctxt->changed_hash, e_todo_context_foreach_change, NULL);
@@ -411,16 +414,24 @@ start_calendar_server_cb (CalClient *cal_client,
static int
start_calendar_server (EToDoConduitContext *ctxt)
{
+ char *uri;
gboolean success = FALSE;
g_return_val_if_fail (ctxt != NULL, -2);
- ctxt->client = cal_client_new ();
+ /* FIXME Need a mechanism for the user to select uri's */
+ /* FIXME Can we use the cal model? */
+ uri = g_strdup_printf ("file://%s/local/Tasks/", g_get_home_dir ());
+ ctxt->client = cal_client_new (uri, CALOBJ_TYPE_TODO);
+ g_free (uri);
+
+ if (!ctxt->client)
+ return -1;
g_signal_connect (ctxt->client, "cal_opened",
G_CALLBACK (start_calendar_server_cb), &success);
- if (!cal_client_open_default_tasks (ctxt->client, FALSE))
+ if (!cal_client_open (ctxt->client, FALSE, NULL))
return -1;
/* run a sub event loop to turn cal-client's async load
@@ -441,7 +452,7 @@ get_timezone (CalClient *client, const char *tzid)
timezone = icaltimezone_get_builtin_timezone_from_tzid (tzid);
if (timezone == NULL)
- cal_client_get_timezone (client, tzid, &timezone);
+ cal_client_get_timezone (client, tzid, &timezone, NULL);
return timezone;
}
@@ -676,13 +687,11 @@ local_record_from_uid (EToDoLocalRecord *local,
{
CalComponent *comp;
icalcomponent *icalcomp;
- CalClientGetStatus status;
+ GError *error = NULL;
g_assert(local!=NULL);
- status = cal_client_get_object (ctxt->client, uid, &icalcomp);
-
- if (status == CAL_CLIENT_GET_SUCCESS) {
+ if (cal_client_get_object (ctxt->client, uid, NULL, &icalcomp, &error)) {
comp = cal_component_new ();
if (!cal_component_set_icalcomponent (comp, icalcomp)) {
g_object_unref (comp);
@@ -692,7 +701,7 @@ local_record_from_uid (EToDoLocalRecord *local,
local_record_from_comp (local, comp, ctxt);
g_object_unref (comp);
- } else if (status == CAL_CLIENT_GET_NOT_FOUND) {
+ } else if (error->code == E_CALENDAR_STATUS_OBJECT_NOT_FOUND) {
comp = cal_component_new ();
cal_component_set_new_vtype (comp, CAL_COMPONENT_TODO);
cal_component_set_uid (comp, uid);
@@ -702,7 +711,7 @@ local_record_from_uid (EToDoLocalRecord *local,
INFO ("Object did not exist");
}
-
+ g_clear_error (&error);
}
@@ -824,21 +833,6 @@ comp_from_remote_record (GnomePilotConduitSyncAbs *conduit,
}
static void
-update_comp (GnomePilotConduitSyncAbs *conduit, CalComponent *comp,
- EToDoConduitContext *ctxt)
-{
- CalClientResult success;
-
- g_return_if_fail (conduit != NULL);
- g_return_if_fail (comp != NULL);
-
- success = cal_client_update_object (ctxt->client, comp);
-
- if (success != CAL_CLIENT_RESULT_SUCCESS)
- WARN (_("Error while communicating with calendar server"));
-}
-
-static void
check_for_slow_setting (GnomePilotConduit *c, EToDoConduitContext *ctxt)
{
GnomePilotConduitStandard *conduit = GNOME_PILOT_CONDUIT_STANDARD (c);
@@ -902,11 +896,13 @@ pre_sync (GnomePilotConduit *conduit,
LOG (g_message ( " Using timezone: %s", icaltimezone_get_tzid (ctxt->timezone) ));
/* Set the default timezone on the backend. */
- if (ctxt->timezone)
- cal_client_set_default_timezone (ctxt->client, ctxt->timezone);
+ if (ctxt->timezone) {
+ if (!cal_client_set_default_timezone (ctxt->client, ctxt->timezone, NULL))
+ return -1;
+ }
/* Get the default component */
- if (cal_client_get_default_object (ctxt->client, CALOBJ_TYPE_TODO, &icalcomp) != CAL_CLIENT_GET_SUCCESS)
+ if (!cal_client_get_default_object (ctxt->client, &icalcomp, NULL))
return -1;
ctxt->default_comp = cal_component_new ();
@@ -916,17 +912,26 @@ pre_sync (GnomePilotConduit *conduit,
return -1;
}
+ ctxt->default_comp = cal_component_new ();
+ if (!cal_component_set_icalcomponent (ctxt->default_comp, icalcomp)) {
+ g_object_unref (ctxt->default_comp);
+ icalcomponent_free (icalcomp);
+ return -1;
+ }
+
/* Load the uid <--> pilot id map */
filename = map_name (ctxt);
e_pilot_map_read (filename, &ctxt->map);
g_free (filename);
/* Get the local database */
- ctxt->uids = cal_client_get_uids (ctxt->client, CALOBJ_TYPE_TODO);
+ if (!cal_client_get_object_list_as_comp (ctxt->client, "(#t)", &ctxt->comps, NULL))
+ return -1;
/* Count and hash the changes */
change_id = g_strdup_printf ("pilot-sync-evolution-todo-%d", ctxt->cfg->pilot_id);
- ctxt->changed = cal_client_get_changes (ctxt->client, CALOBJ_TYPE_TODO, change_id);
+ if (!cal_client_get_changes (ctxt->client, CALOBJ_TYPE_TODO, change_id, &ctxt->changed, NULL))
+ return -1;
ctxt->changed_hash = g_hash_table_new (g_str_hash, g_str_equal);
g_free (change_id);
@@ -956,7 +961,7 @@ pre_sync (GnomePilotConduit *conduit,
}
/* Set the count information */
- num_records = cal_client_get_n_objects (ctxt->client, CALOBJ_TYPE_TODO);
+ num_records = g_list_length (ctxt->comps);
gnome_pilot_conduit_sync_abs_set_num_local_records(abs_conduit, num_records);
gnome_pilot_conduit_sync_abs_set_num_new_local_records (abs_conduit, add_records);
gnome_pilot_conduit_sync_abs_set_num_updated_local_records (abs_conduit, mod_records);
@@ -1006,8 +1011,8 @@ post_sync (GnomePilotConduit *conduit,
* a race condition if anyone changes a record elsewhere during sycnc
*/
change_id = g_strdup_printf ("pilot-sync-evolution-todo-%d", ctxt->cfg->pilot_id);
- changed = cal_client_get_changes (ctxt->client, CALOBJ_TYPE_TODO, change_id);
- cal_client_change_list_free (changed);
+ if (cal_client_get_changes (ctxt->client, CALOBJ_TYPE_TODO, change_id, &changed, NULL))
+ cal_client_change_list_free (changed);
g_free (change_id);
LOG (g_message ( "---------------------------------------------------------\n" ));
@@ -1051,7 +1056,7 @@ for_each (GnomePilotConduitSyncAbs *conduit,
EToDoLocalRecord **local,
EToDoConduitContext *ctxt)
{
- static GList *uids, *iterator;
+ static GList *comps, *iterator;
static int count;
g_return_val_if_fail (local != NULL, -1);
@@ -1059,17 +1064,17 @@ for_each (GnomePilotConduitSyncAbs *conduit,
if (*local == NULL) {
LOG (g_message ( "beginning for_each" ));
- uids = ctxt->uids;
+ comps = ctxt->comps;
count = 0;
- if (uids != NULL) {
- LOG (g_message ( "iterating over %d records", g_list_length (uids) ));
+ if (comps != NULL) {
+ LOG (g_message ( "iterating over %d records", g_list_length (comps)));
*local = g_new0 (EToDoLocalRecord, 1);
- local_record_from_uid (*local, uids->data, ctxt);
+ local_record_from_comp (*local, comps->data, ctxt);
g_list_prepend (ctxt->locals, *local);
- iterator = uids;
+ iterator = comps;
} else {
LOG (g_message ( "no events" ));
(*local) = NULL;
@@ -1196,7 +1201,9 @@ add_record (GnomePilotConduitSyncAbs *conduit,
uid = cal_component_gen_uid ();
cal_component_set_uid (comp, uid);
- update_comp (conduit, comp, ctxt);
+ if (!cal_client_create_object (ctxt->client, cal_component_get_icalcomponent (comp), NULL, NULL))
+ return -1;
+
e_pilot_map_insert (ctxt->map, remote->ID, uid, FALSE);
g_object_unref (comp);
@@ -1221,7 +1228,10 @@ replace_record (GnomePilotConduitSyncAbs *conduit,
new_comp = comp_from_remote_record (conduit, remote, local->comp, ctxt->timezone);
g_object_unref (local->comp);
local->comp = new_comp;
- update_comp (conduit, local->comp, ctxt);
+
+ if (!cal_client_modify_object (ctxt->client, cal_component_get_icalcomponent (new_comp),
+ CALOBJ_MOD_ALL, NULL))
+ return -1;
return retval;
}
@@ -1241,7 +1251,8 @@ delete_record (GnomePilotConduitSyncAbs *conduit,
LOG (g_message ( "delete_record: deleting %s\n", uid ));
e_pilot_map_remove_by_uid (ctxt->map, uid);
- cal_client_remove_object (ctxt->client, uid);
+ /* FIXME Error handling */
+ cal_client_remove_object (ctxt->client, uid, NULL);
return 0;
}
diff --git a/calendar/gui/GNOME_Evolution_Calendar.server.in.in b/calendar/gui/GNOME_Evolution_Calendar.server.in.in
index 801cada120..09f424f69a 100644
--- a/calendar/gui/GNOME_Evolution_Calendar.server.in.in
+++ b/calendar/gui/GNOME_Evolution_Calendar.server.in.in
@@ -1,6 +1,6 @@
<oaf_info>
-<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_Factory"
+<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_Factory_2"
type="shlib"
location="@COMPONENTDIR@/libevolution-calendar.so">
@@ -15,7 +15,7 @@
<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_iTip_Control"
type="factory"
- location="OAFIID:GNOME_Evolution_Calendar_Factory">
+ location="OAFIID:GNOME_Evolution_Calendar_Factory_2">
<oaf_attribute name="repo_ids" type="stringv">
<item value="IDL:Bonobo/Control:1.0"/>
@@ -31,26 +31,20 @@
_value="Evolution Calendar scheduling message viewer"/>
</oaf_server>
-<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_ShellComponent"
+<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_Component"
type="factory"
- location="OAFIID:GNOME_Evolution_Calendar_Factory">
+ location="OAFIID:GNOME_Evolution_Calendar_Factory_2">
<oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/Evolution/ShellComponent:1.0"/>
+ <item value="IDL:GNOME/Evolution/Component:1.0"/>
</oaf_attribute>
- <oaf_attribute name="name" type="string"
- _value="Evolution Calendar and Tasks component"/>
-
- <oaf_attribute name="evolution:shell_component_icon" type="string"
- value="evolution-calendar.png"/>
- <oaf_attribute name="evolution:shell_component_launch_order" type="number"
- value="3"/>
+ <oaf_attribute name="name" type="string" _value="Evolution's Calendar component"/>
</oaf_server>
<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_Control"
type="factory"
- location="OAFIID:GNOME_Evolution_Calendar_Factory">
+ location="OAFIID:GNOME_Evolution_Calendar_Factory_2">
<oaf_attribute name="repo_ids" type="stringv">
<item value="IDL:BonoboControl/calendar-control:1.0"/>
@@ -68,7 +62,7 @@
<oaf_server iid="OAFIID:GNOME_Evolution_Tasks_Control"
type="factory"
- location="OAFIID:GNOME_Evolution_Calendar_Factory">
+ location="OAFIID:GNOME_Evolution_Calendar_Factory_2">
<oaf_attribute name="repo_ids" type="stringv">
<item value="IDL:BonoboControl/tasks-control:1.0"/>
@@ -86,7 +80,7 @@
<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_CompEditorFactory"
type="factory"
- location="OAFIID:GNOME_Evolution_Calendar_Factory">
+ location="OAFIID:GNOME_Evolution_Calendar_Factory_2">
<oaf_attribute name="repo_ids" type="stringv">
<item value="IDL:GNOME/Evolution/Calendar/CompEditorFactory:1.0"/>
@@ -99,7 +93,7 @@
<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_ConfigControl"
type="factory"
- location="OAFIID:GNOME_Evolution_Calendar_Factory">
+ location="OAFIID:GNOME_Evolution_Calendar_Factory_2">
<oaf_attribute name="repo_ids" type="stringv">
<item value="IDL:GNOME/Evolution/ConfigControl:1.0"/>
diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am
index 3ee9362b65..19edf95953 100644
--- a/calendar/gui/Makefile.am
+++ b/calendar/gui/Makefile.am
@@ -169,6 +169,8 @@ libevolution_calendar_la_SOURCES = \
itip-utils.c \
itip-utils.h \
main.c \
+ migration.c \
+ migration.h \
misc.c \
misc.h \
print.c \
@@ -189,7 +191,8 @@ libevolution_calendar_la_LIBADD = \
$(top_builddir)/calendar/gui/dialogs/libcal-dialogs.la \
$(top_builddir)/widgets/e-timezone-dialog/libetimezonedialog.la \
$(top_builddir)/widgets/misc/libemiscwidgets.la \
- $(top_builddir)/a11y/calendar/libevolution-calendar-a11y.la \
+ $(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/a11y/calendar/libevolution-calendar-a11y.la \
$(EVOLUTION_CALENDAR_LIBS)
libevolution_calendar_la_LDFLAGS = -avoid-version -module
diff --git a/calendar/gui/alarm-notify/alarm-notify.c b/calendar/gui/alarm-notify/alarm-notify.c
index 133448e7cd..006533c6bf 100644
--- a/calendar/gui/alarm-notify/alarm-notify.c
+++ b/calendar/gui/alarm-notify/alarm-notify.c
@@ -31,26 +31,6 @@
-/* A loaded client */
-typedef struct {
- /* The actual client */
- CalClient *client;
-
- /* The URI of the client in gnome-vfs's format. This *is* the key that
- * is stored in the uri_client_hash hash table below.
- */
- EUri *uri;
-
- /* Number of times clients have requested this URI to be added to the
- * alarm notification system.
- */
- int refcount;
-
- /* the ID of the retry timeout function
- */
- int timeout_id;
-} LoadedClient;
-
/* Private part of the AlarmNotify structure */
struct _AlarmNotifyPrivate {
/* Mapping from EUri's to LoadedClient structures */
@@ -105,23 +85,7 @@ alarm_notify_init (AlarmNotify *an, AlarmNotifyClass *klass)
priv = g_new0 (AlarmNotifyPrivate, 1);
an->priv = priv;
- priv->uri_client_hash = g_hash_table_new (g_str_hash, g_str_equal);
-}
-
-/* Callback used from g_hash-table_forach(), used to destroy a loade client */
-static void
-destroy_loaded_client_cb (gpointer key, gpointer value, gpointer data)
-{
- LoadedClient *lc;
- char *str_uri;
-
- str_uri = key;
- lc = value;
-
- g_free (str_uri);
- g_object_unref (G_OBJECT (lc->client));
- e_uri_free (lc->uri);
- g_free (lc);
+ priv->uri_client_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
}
/* Finalize handler for the alarm notify system */
@@ -137,13 +101,9 @@ alarm_notify_finalize (GObject *object)
an = ALARM_NOTIFY (object);
priv = an->priv;
- g_hash_table_foreach (priv->uri_client_hash, destroy_loaded_client_cb, NULL);
-
g_hash_table_destroy (priv->uri_client_hash);
- priv->uri_client_hash = NULL;
g_free (priv);
- an->priv = NULL;
if (G_OBJECT_CLASS (parent_class)->finalize)
(* G_OBJECT_CLASS (parent_class)->finalize) (object);
@@ -193,21 +153,15 @@ free_uris (GPtrArray *uris)
/* Adds an URI to the list of calendars to load on startup */
static void
-add_uri_to_load (EUri *uri)
+add_uri_to_load (const char *str_uri)
{
- char *str_uri;
GPtrArray *loaded_uris;
int i;
- /* Canonicalize the URI */
- str_uri = e_uri_to_string (uri, FALSE);
- g_assert (str_uri != NULL);
-
loaded_uris = get_calendars_to_load ();
if (!loaded_uris) {
g_message ("add_uri_to_load(): Could not get the list of calendars to load; "
"will not add `%s'", str_uri);
- g_free (str_uri);
return;
}
@@ -219,12 +173,11 @@ add_uri_to_load (EUri *uri)
* calendars.
*/
if (i != -1) {
- g_free (str_uri);
free_uris (loaded_uris);
return;
}
- g_ptr_array_add (loaded_uris, str_uri);
+ g_ptr_array_add (loaded_uris, g_strdup (str_uri));
save_calendars_to_load (loaded_uris);
free_uris (loaded_uris);
@@ -232,29 +185,22 @@ add_uri_to_load (EUri *uri)
/* Removes an URI from the list of calendars to load on startup */
static void
-remove_uri_to_load (EUri *uri)
+remove_uri_to_load (const char *str_uri)
{
- char *str_uri;
GPtrArray *loaded_uris;
char *loaded_uri;
int i;
- /* Canonicalize the URI */
- str_uri = e_uri_to_string (uri, FALSE);
- g_assert (str_uri != NULL);
-
loaded_uris = get_calendars_to_load ();
if (!loaded_uris) {
g_message ("remove_uri_to_load(): Could not get the list of calendars to load; "
"will not add `%s'", str_uri);
- g_free (str_uri);
return;
}
/* Look for the URI in the list of calendars to load */
i = find_uri_index (loaded_uris, str_uri);
- g_free (str_uri);
/* If we didn't find it, there is no need to remove it */
if (i == -1) {
@@ -291,61 +237,19 @@ AlarmNotify_removeCalendar (PortableServer_Servant servant,
{
AlarmNotify *an;
AlarmNotifyPrivate *priv;
- LoadedClient *lc;
- EUri *uri;
- char *orig_str;
- gpointer lc_ptr, orig_str_ptr;
- gboolean found;
-
- lc_ptr = NULL;
- orig_str_ptr = NULL;
+ CalClient *client;
an = ALARM_NOTIFY (bonobo_object_from_servant (servant));
priv = an->priv;
- uri = e_uri_new (str_uri);
- if (!uri) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Calendar_AlarmNotify_InvalidURI,
- NULL);
- return;
- }
+ client = g_hash_table_lookup (priv->uri_client_hash, str_uri);
+ if (client) {
+ alarm_queue_remove_client (client);
- remove_uri_to_load (uri);
-
- found = g_hash_table_lookup_extended (priv->uri_client_hash, str_uri,
- &orig_str_ptr,
- &lc_ptr);
- orig_str = orig_str_ptr;
- lc = lc_ptr;
-
- e_uri_free (uri);
-
- if (!lc) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Calendar_AlarmNotify_NotFound,
- NULL);
- return;
+ g_hash_table_remove (priv->uri_client_hash, str_uri);
}
- g_assert (lc->refcount > 0);
-
- lc->refcount--;
- if (lc->refcount > 0)
- return;
-
- g_hash_table_remove (priv->uri_client_hash, str_uri);
-
- g_free (orig_str);
- g_signal_handlers_disconnect_matched (lc->client,
- G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, lc);
- if (lc->timeout_id != -1)
- g_source_remove (lc->timeout_id);
- alarm_queue_remove_client (lc->client);
- g_object_unref (G_OBJECT (lc->client));
- e_uri_free (lc->uri);
- g_free (lc);
+ remove_uri_to_load (str_uri);
}
@@ -367,40 +271,6 @@ alarm_notify_new (void)
return an;
}
-static gboolean
-retry_timeout_cb (gpointer data)
-{
- LoadedClient *lc = data;
- char *str_uri;
-
- if (cal_client_get_load_state (lc->client) != CAL_CLIENT_LOAD_LOADED) {
- str_uri = e_uri_to_string (lc->uri, FALSE);
- cal_client_open_calendar (lc->client, str_uri, FALSE);
-
- g_free (str_uri);
- }
-
- return FALSE;
-}
-
-static void
-cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data)
-{
- LoadedClient *lc = (LoadedClient *) data;
-
- if (status == CAL_CLIENT_OPEN_SUCCESS) {
- add_uri_to_load (lc->uri);
- alarm_queue_add_client (client);
- lc->timeout_id = -1;
- }
- else {
- remove_uri_to_load (lc->uri);
-
- /* we set a timeout of 5 mins before retrying */
- lc->timeout_id = g_timeout_add (300000, (GSourceFunc) retry_timeout_cb, lc);
- }
-}
-
/**
* alarm_notify_add_calendar:
* @an: An alarm notification service.
@@ -418,10 +288,7 @@ alarm_notify_add_calendar (AlarmNotify *an, const char *str_uri, gboolean load_a
CORBA_Environment *ev)
{
AlarmNotifyPrivate *priv;
- EUri *uri;
CalClient *client;
- LoadedClient *lc;
- gpointer lc_ptr, s_ptr;
g_return_if_fail (an != NULL);
g_return_if_fail (IS_ALARM_NOTIFY (an));
@@ -430,49 +297,23 @@ alarm_notify_add_calendar (AlarmNotify *an, const char *str_uri, gboolean load_a
priv = an->priv;
- uri = e_uri_new (str_uri);
- if (!uri) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Calendar_AlarmNotify_InvalidURI,
- NULL);
+ /* See if we already know about this uri */
+ if (g_hash_table_lookup (priv->uri_client_hash, str_uri))
return;
- }
- if (g_hash_table_lookup_extended (priv->uri_client_hash, str_uri, &s_ptr, &lc_ptr)) {
- lc = lc_ptr;
- lc->refcount++;
- } else {
- client = cal_client_new ();
-
- if (client) {
- /* we only add the URI to load_afterwards if we open it
- correctly */
- lc = g_new (LoadedClient, 1);
- lc->client = client;
- lc->uri = uri;
- lc->refcount = 1;
- lc->timeout_id = -1;
-
-
- g_signal_connect (G_OBJECT (client), "cal_opened",
- G_CALLBACK (cal_opened_cb),
- lc);
-
- if (cal_client_open_calendar (client, str_uri, FALSE)) {
- g_hash_table_insert (priv->uri_client_hash,
- g_strdup (str_uri), lc);
- } else {
- g_free (lc);
- g_object_unref (G_OBJECT (client));
- client = NULL;
- }
- } else {
- e_uri_free (uri);
-
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Calendar_AlarmNotify_BackendContactError,
- NULL);
- return;
+ client = cal_client_new (str_uri, CALOBJ_TYPE_EVENT);
+
+ if (client) {
+ if (cal_client_open (client, FALSE, NULL)) {
+ add_uri_to_load (str_uri);
+
+ g_hash_table_insert (priv->uri_client_hash,
+ g_strdup (str_uri), client);
}
+ } else {
+ CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
+ ex_GNOME_Evolution_Calendar_AlarmNotify_BackendContactError,
+ NULL);
+ return;
}
}
diff --git a/calendar/gui/alarm-notify/alarm-queue.c b/calendar/gui/alarm-notify/alarm-queue.c
index cb792e466f..cee17bd97e 100644
--- a/calendar/gui/alarm-notify/alarm-queue.c
+++ b/calendar/gui/alarm-notify/alarm-queue.c
@@ -227,7 +227,7 @@ remove_queued_alarm (CompQueuedAlarms *cqa, gpointer alarm_id,
if (remove_alarm) {
cqa->expecting_update = TRUE;
cal_client_discard_alarm (cqa->parent_client->client, cqa->alarms->comp,
- qa->instance->auid);
+ qa->instance->auid, NULL);
cqa->expecting_update = FALSE;
}
diff --git a/calendar/gui/calendar-commands.c b/calendar/gui/calendar-commands.c
index c0d1b3c589..77305098bc 100644
--- a/calendar/gui/calendar-commands.c
+++ b/calendar/gui/calendar-commands.c
@@ -59,6 +59,7 @@
#include "goto.h"
#include "print.h"
#include "dialogs/cal-prefs-dialog.h"
+#include "dialogs/new-calendar.h"
#include "itip-utils.h"
#include "evolution-shell-component-utils.h"
@@ -73,6 +74,68 @@ typedef struct {
guint taskpad_focused : 1;
} FocusData;
+static void
+file_new_calendar_cb (BonoboUIComponent *uic, gpointer data, const char *path)
+{
+ GnomeCalendar *gcal;
+
+ gcal = GNOME_CALENDAR (data);
+
+ new_calendar_dialog (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (gcal))));
+}
+
+static void
+file_new_appointment_cb (BonoboUIComponent *uic, gpointer data, const char *path)
+{
+ GnomeCalendar *gcal;
+ time_t dtstart, dtend;
+ ECalView *cal_view;
+
+ gcal = GNOME_CALENDAR (data);
+
+ cal_view = (ECalView *) gnome_calendar_get_current_view_widget (gcal);
+ e_cal_view_get_selected_time_range (cal_view, &dtstart, &dtend);
+ e_cal_view_new_appointment_for (cal_view, dtstart, dtend, FALSE, FALSE);
+}
+
+static void
+file_new_event_cb (BonoboUIComponent *uic, gpointer data, const char *path)
+{
+ GnomeCalendar *gcal;
+ time_t dtstart, dtend;
+ ECalView *cal_view;
+
+ gcal = GNOME_CALENDAR (data);
+
+ cal_view = (ECalView *) gnome_calendar_get_current_view_widget (gcal);
+ e_cal_view_get_selected_time_range (cal_view, &dtstart, &dtend);
+ e_cal_view_new_appointment_for (cal_view, dtstart, dtend, TRUE, FALSE);
+}
+
+static void
+file_new_meeting_cb (BonoboUIComponent *uic, gpointer data, const char *path)
+{
+ GnomeCalendar *gcal;
+ time_t dtstart, dtend;
+ ECalView *cal_view;
+
+ gcal = GNOME_CALENDAR (data);
+
+ cal_view = (ECalView *) gnome_calendar_get_current_view_widget (gcal);
+ e_cal_view_get_selected_time_range (cal_view, &dtstart, &dtend);
+ e_cal_view_new_appointment_for (cal_view, dtstart, dtend, FALSE, TRUE);
+}
+
+static void
+file_new_task_cb (BonoboUIComponent *uic, gpointer data, const char *path)
+{
+ GnomeCalendar *gcal;
+
+ gcal = GNOME_CALENDAR (data);
+
+ gnome_calendar_new_task (gcal);
+}
+
/* Prints the calendar at its current view and time range */
static void
print (GnomeCalendar *gcal, gboolean preview)
@@ -335,12 +398,10 @@ publish_freebusy_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path)
start = time_day_begin_with_zone (start, utc);
end = time_add_week_with_zone (start, 6, utc);
+ /* FIXME Should we aggregate the data? */
client_list = e_cal_model_get_client_list (gnome_calendar_get_calendar_model (gcal));
for (cl = client_list; cl != NULL; cl = cl->next) {
- GList *tmp_comp_list;
-
- tmp_comp_list = cal_client_get_free_busy ((CalClient *) cl->data, NULL, start, end);
- if (tmp_comp_list) {
+ if (cal_client_get_free_busy ((CalClient *) cl->data, NULL, start, end, &comp_list, NULL)) {
GList *l;
for (l = comp_list; l; l = l->next) {
@@ -599,19 +660,42 @@ control_util_show_settings (GnomeCalendar *gcal)
* is FALSE, all will be disabled. Otherwise, the currently-selected number of
* events will be used.
*/
-static void
-sensitize_calendar_commands (GnomeCalendar *gcal, BonoboControl *control, gboolean enable)
+void
+calendar_control_sensitize_calendar_commands (BonoboControl *control, GnomeCalendar *gcal, gboolean enable)
{
BonoboUIComponent *uic;
+ ECalViewEvent *event;
+ GList *list;
int n_selected;
- gboolean read_only, has_recurrences;
+ GtkWidget *view;
+ CalClient *cal_client;
+ gboolean read_only = FALSE, has_recurrences;
uic = bonobo_control_get_ui_component (control);
g_assert (uic != NULL);
- n_selected = enable ? gnome_calendar_get_num_events_selected (gcal) : 0;
- read_only = cal_client_is_read_only (e_cal_model_get_default_client (gnome_calendar_get_calendar_model (gcal)));
+ view = gnome_calendar_get_current_view_widget (gcal);
+ list = e_cal_view_get_selected_events (E_CAL_VIEW (view));
+
+ n_selected = enable ? g_list_length (list) : 0;
+ event = (ECalViewEvent *) list ? list->data : NULL;
+ if (event) {
+ cal_client_is_read_only (event->comp_data->client, &read_only, NULL);
+ } else {
+ cal_client = e_cal_model_get_default_client (gnome_calendar_get_calendar_model (gcal));
+ if (cal_client)
+ cal_client_is_read_only (cal_client, &read_only, NULL);
+ else
+ read_only = TRUE;
+ }
+
+ bonobo_ui_component_set_prop (uic, "/commands/NewAppointment", "sensitive",
+ read_only ? "0" : "1", NULL);
+ bonobo_ui_component_set_prop (uic, "/commands/NewAllDayEvent", "sensitive",
+ read_only ? "0" : "1", NULL);
+ bonobo_ui_component_set_prop (uic, "/commands/NewMeeting", "sensitive",
+ read_only ? "0" : "1", NULL);
bonobo_ui_component_set_prop (uic, "/commands/Cut", "sensitive",
n_selected == 0 || read_only ? "0" : "1",
NULL);
@@ -628,19 +712,8 @@ sensitize_calendar_commands (GnomeCalendar *gcal, BonoboControl *control, gboole
/* occurrence-related menu items */
has_recurrences = FALSE;
if (n_selected > 0 && !read_only) {
- ECalViewEvent *event;
- GList *list;
- GtkWidget *view;
-
- view = gnome_calendar_get_current_view_widget (gcal);
- list = e_cal_view_get_selected_events (E_CAL_VIEW (view));
if (list) {
event = (ECalViewEvent *) list->data;
- g_list_free (list);
- } else
- event = NULL;
-
- if (event) {
if (cal_util_component_has_recurrences (event->comp_data->icalcomp))
has_recurrences = TRUE;
}
@@ -652,6 +725,10 @@ sensitize_calendar_commands (GnomeCalendar *gcal, BonoboControl *control, gboole
bonobo_ui_component_set_prop (uic, "/commands/DeleteAllOccurrences", "sensitive",
has_recurrences ? "1" : "0",
NULL);
+
+ /* free memory */
+ if (list)
+ g_list_free (list);
}
/* Sensitizes the UI Component menu/toolbar tasks commands based on the number
@@ -663,14 +740,21 @@ sensitize_taskpad_commands (GnomeCalendar *gcal, BonoboControl *control, gboolea
{
BonoboUIComponent *uic;
int n_selected;
- gboolean read_only;
+ CalClient *cal_client;
+ gboolean read_only = TRUE;
uic = bonobo_control_get_ui_component (control);
g_assert (uic != NULL);
n_selected = enable ? gnome_calendar_get_num_tasks_selected (gcal) : 0;
- read_only = cal_client_is_read_only (gnome_calendar_get_task_pad_cal_client (gcal));
-
+ cal_client = gnome_calendar_get_task_pad_cal_client (gcal);
+ if (cal_client)
+ cal_client_is_read_only (cal_client, &read_only, NULL);
+ else
+ read_only = TRUE;
+
+ bonobo_ui_component_set_prop (uic, "/commands/NewTask", "sensitive",
+ read_only ? "0" : "1", NULL);
bonobo_ui_component_set_prop (uic, "/commands/Cut", "sensitive",
n_selected == 0 || read_only ? "0" : "1",
NULL);
@@ -705,7 +789,7 @@ gcal_calendar_selection_changed_cb (GnomeCalendar *gcal, gpointer data)
control = BONOBO_CONTROL (data);
- sensitize_calendar_commands (gcal, control, TRUE);
+ calendar_control_sensitize_calendar_commands (control, gcal, TRUE);
}
/* Callback used when the selection in the taskpad changes */
@@ -734,13 +818,13 @@ gcal_calendar_focus_change_cb (GnomeCalendar *gcal, gboolean in, gpointer data)
if (in) {
g_signal_connect (gcal, "calendar_selection_changed",
G_CALLBACK (gcal_calendar_selection_changed_cb), control);
- sensitize_calendar_commands (gcal, control, TRUE);
+ calendar_control_sensitize_calendar_commands (control, gcal, TRUE);
focus->calendar_focused = TRUE;
} else if (focus->calendar_focused) {
gtk_signal_disconnect_by_func (GTK_OBJECT (gcal),
G_CALLBACK (gcal_calendar_selection_changed_cb),
control);
- sensitize_calendar_commands (gcal, control, FALSE);
+ calendar_control_sensitize_calendar_commands (control, gcal, FALSE);
focus->calendar_focused = FALSE;
}
}
@@ -779,6 +863,11 @@ gcal_taskpad_focus_change_cb (GnomeCalendar *gcal, gboolean in, gpointer data)
static BonoboUIVerb verbs [] = {
+ BONOBO_UI_VERB ("NewCalendar", file_new_calendar_cb),
+ BONOBO_UI_VERB ("NewAppointment", file_new_appointment_cb),
+ BONOBO_UI_VERB ("NewAllDayEvent", file_new_event_cb),
+ BONOBO_UI_VERB ("NewMeeting", file_new_meeting_cb),
+ BONOBO_UI_VERB ("NewTask", file_new_task_cb),
BONOBO_UI_VERB ("CalendarPrint", file_print_cb),
BONOBO_UI_VERB ("CalendarPrintPreview", file_print_preview_cb),
@@ -808,11 +897,15 @@ static BonoboUIVerb verbs [] = {
static EPixmap pixmaps [] =
{
- E_PIXMAP ("/Toolbar/DayView", "buttons/dayview.xpm"),
- E_PIXMAP ("/Toolbar/WorkWeekView", "buttons/workweekview.xpm"),
- E_PIXMAP ("/Toolbar/WeekView", "buttons/weekview.xpm"),
- E_PIXMAP ("/Toolbar/MonthView", "buttons/monthview.xpm"),
- E_PIXMAP ("/Toolbar/ListView", "buttons/listview.xpm"),
+ E_PIXMAP ("/commands/NewAppointment", "new_appointment.xpm"),
+ E_PIXMAP ("/commands/NewAllDayEvent", "new_all_day_event.png"),
+ E_PIXMAP ("/commands/NewMeeting", "meeting-request-16.png"),
+ E_PIXMAP ("/commands/NewTask", "new_task-16.png"),
+ E_PIXMAP ("/Toolbar/DayView", "buttons/dayview.xpm"),
+ E_PIXMAP ("/Toolbar/WorkWeekView", "buttons/workweekview.xpm"),
+ E_PIXMAP ("/Toolbar/WeekView", "buttons/weekview.xpm"),
+ E_PIXMAP ("/Toolbar/MonthView", "buttons/monthview.xpm"),
+ E_PIXMAP ("/Toolbar/ListView", "buttons/listview.xpm"),
E_PIXMAP_END
};
@@ -855,7 +948,7 @@ calendar_control_activate (BonoboControl *control,
g_signal_connect (gcal, "taskpad_focus_change",
G_CALLBACK (gcal_taskpad_focus_change_cb), control);
- sensitize_calendar_commands (gcal, control, FALSE);
+ calendar_control_sensitize_calendar_commands (control, gcal, FALSE);
sensitize_taskpad_commands (gcal, control, FALSE);
bonobo_ui_component_thaw (uic, NULL);
diff --git a/calendar/gui/calendar-commands.h b/calendar/gui/calendar-commands.h
index 6f418799d2..3e74074140 100644
--- a/calendar/gui/calendar-commands.h
+++ b/calendar/gui/calendar-commands.h
@@ -38,6 +38,8 @@ GnomeCalendar *new_calendar (void);
void calendar_control_activate (BonoboControl *control, GnomeCalendar *gcal);
void calendar_control_deactivate (BonoboControl *control, GnomeCalendar *gcal);
+void calendar_control_sensitize_calendar_commands (BonoboControl *control, GnomeCalendar *gcal, gboolean enable);
+
void calendar_goto_today (GnomeCalendar *gcal);
void calendar_set_folder_bar_label (GnomeCalendar *gcal, BonoboControl *control);
diff --git a/calendar/gui/calendar-component.c b/calendar/gui/calendar-component.c
index 98f0964cc4..3e8782f45b 100644
--- a/calendar/gui/calendar-component.c
+++ b/calendar/gui/calendar-component.c
@@ -1,7 +1,7 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* component-factory.c
+/* calendar-component.c
*
- * Copyright (C) 2000, 2001, 2002, 2003 Ximian, Inc.
+ * Copyright (C) 2003 Ettore Perazzoli
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
@@ -20,752 +20,269 @@
* Author: Ettore Perazzoli <ettore@ximian.com>
*/
+#ifdef CONFIG_H
#include <config.h>
+#endif
-#include <errno.h>
-#include <libgnome/gnome-util.h>
-#include <libgnomevfs/gnome-vfs-types.h>
-#include <libgnomevfs/gnome-vfs-uri.h>
-#include <libgnomevfs/gnome-vfs-ops.h>
-#include <libgnomevfs/gnome-vfs-directory.h>
-#include <libgnomevfs/gnome-vfs-file-info.h>
-
-#include <bonobo/bonobo-generic-factory.h>
-#include <bonobo/bonobo-context.h>
-#include <bonobo/bonobo-exception.h>
-
-#include "evolution-shell-component.h"
-#include "calendar-offline-handler.h"
#include "calendar-component.h"
-#include "tasks-control.h"
#include "control-factory.h"
-#include "calendar-config.h"
-#include "tasks-control.h"
-#include "e-comp-editor-registry.h"
-#include "dialogs/comp-editor.h"
-
-
-/* OAFIID for the component. */
-#define COMPONENT_ID "OAFIID:GNOME_Evolution_Calendar_ShellComponent"
-
-/* Folder type IDs */
-#define FOLDER_CALENDAR "calendar"
-#define FOLDER_TASKS "tasks"
-#define FOLDER_PUBLIC_CALENDAR "calendar/public"
-#define FOLDER_PUBLIC_TASKS "tasks/public"
-
-/* IDs for user creatable items */
-#define CREATE_EVENT_ID "event"
-#define CREATE_ALLDAY_EVENT_ID "allday-event"
-#define CREATE_MEETING_ID "meeting"
-#define CREATE_TASK_ID "task"
-
-char *evolution_dir = NULL;
-EvolutionShellClient *global_shell_client = NULL;
-extern ECompEditorRegistry *comp_editor_registry;
-
-static const EvolutionShellComponentFolderType folder_types[] = {
- { FOLDER_CALENDAR,
- "evolution-calendar.png",
- N_("Calendar"),
- N_("Folder containing appointments and events"),
- TRUE, NULL, NULL },
- { FOLDER_PUBLIC_CALENDAR,
- "evolution-calendar.png",
- N_("Public Calendar"),
- N_("Public folder containing appointments and events"),
- FALSE, NULL, NULL },
- { FOLDER_TASKS,
- "evolution-tasks.png",
- N_("Tasks"),
- N_("Folder containing to-do items"),
- TRUE, NULL, NULL },
- { FOLDER_PUBLIC_TASKS,
- "evolution-tasks.png",
- N_("Public Tasks"),
- N_("Public folder containing to-do items"),
- FALSE, NULL, NULL },
- { NULL, NULL }
-};
+#include "gnome-cal.h"
+#include "migration.h"
-
-
-static inline gboolean
-type_is_calendar (const char *type)
-{
- return !strcmp (type, FOLDER_CALENDAR) ||
- !strcmp (type, FOLDER_PUBLIC_CALENDAR);
-}
+#include "widgets/misc/e-source-selector.h"
-static inline gboolean
-type_is_tasks (const char *type)
-{
- return !strcmp (type, FOLDER_TASKS) ||
- !strcmp (type, FOLDER_PUBLIC_TASKS);
-}
+#include <bonobo/bonobo-control.h>
+#include <bonobo/bonobo-i18n.h>
+#include <gal/util/e-util.h>
-/* EvolutionShellComponent methods and signals. */
+#include <errno.h>
-static EvolutionShellComponentResult
-create_view (EvolutionShellComponent *shell_component,
- const char *physical_uri,
- const char *type,
- const char *view_info,
- BonoboControl **control_return,
- void *closure)
-{
- BonoboControl *control;
-
- if (type_is_calendar (type)) {
- control = control_factory_new_control ();
- if (!control)
- return EVOLUTION_SHELL_COMPONENT_CORBAERROR;
- } else if (type_is_tasks (type)) {
- control = tasks_control_new ();
- if (!control)
- return EVOLUTION_SHELL_COMPONENT_CORBAERROR;
- } else {
- return EVOLUTION_SHELL_COMPONENT_UNSUPPORTEDTYPE;
- }
- bonobo_control_set_property (control, NULL, "folder_uri", TC_CORBA_string, physical_uri, NULL);
- if (type_is_calendar (type) && *view_info)
- bonobo_control_set_property (control, NULL, "view", TC_CORBA_string, view_info, NULL);
+#define PARENT_TYPE bonobo_object_get_type ()
+static BonoboObjectClass *parent_class = NULL;
- *control_return = control;
- return EVOLUTION_SHELL_COMPONENT_OK;
-}
+struct _CalendarComponentPrivate {
+ char *config_directory;
-static void
-create_folder (EvolutionShellComponent *shell_component,
- const char *physical_uri,
- const char *type,
- const GNOME_Evolution_ShellComponentListener listener,
- void *closure)
-{
- CORBA_Environment ev;
- GnomeVFSURI *uri;
+ GConfClient *gconf_client;
+ ESourceList *source_list;
+};
- CORBA_exception_init (&ev);
- if (!type_is_calendar (type) && !type_is_tasks (type)) {
- GNOME_Evolution_ShellComponentListener_notifyResult (
- listener,
- GNOME_Evolution_ShellComponentListener_UNSUPPORTED_TYPE,
- &ev);
- CORBA_exception_free (&ev);
- return;
- }
+/* Utility functions. */
- uri = gnome_vfs_uri_new (physical_uri);
- if (uri) {
- /* we don't need to do anything */
- GNOME_Evolution_ShellComponentListener_notifyResult (
- listener,
- GNOME_Evolution_ShellComponentListener_OK, &ev);
- gnome_vfs_uri_unref (uri);
- }
- else {
- GNOME_Evolution_ShellComponentListener_notifyResult (
- listener,
- GNOME_Evolution_ShellComponentListener_INVALID_URI,
- &ev);
- }
+static void
+load_uri_for_source (ESource *source, BonoboControl *view_control)
+{
+ GnomeCalendar *gcal;
+ char *uri = e_source_get_uri (source);
- CORBA_exception_free (&ev);
+ gcal = (GnomeCalendar *) bonobo_control_get_widget (view_control);
+ gnome_calendar_add_event_uri (gcal, uri);
+ g_free (uri);
}
-/* Asks the alarm daemon to stop monitoring the specified URI */
static void
-stop_alarms (GnomeVFSURI *uri)
+load_uri_for_selection (ESourceSelector *selector, BonoboControl *view_control)
{
- char *str_uri;
- CORBA_Environment ev;
- GNOME_Evolution_Calendar_AlarmNotify an;
-
- /* Activate the alarm notification service */
-
- CORBA_exception_init (&ev);
- an = bonobo_activation_activate_from_id ("OAFIID:GNOME_Evolution_Calendar_AlarmNotify", 0, NULL, &ev);
-
- if (BONOBO_EX (&ev)) {
- g_message ("stop_alarms(): Could not activate the alarm notification service");
- CORBA_exception_free (&ev);
- return;
- }
- CORBA_exception_free (&ev);
-
- /* Ask the service to remove the URI from its list of calendars */
-
- str_uri = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE);
- g_assert (str_uri != NULL);
-
- CORBA_exception_init (&ev);
- GNOME_Evolution_Calendar_AlarmNotify_removeCalendar (an, str_uri, &ev);
- g_free (str_uri);
-
- if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_AlarmNotify_InvalidURI)) {
- g_message ("stop_alarms(): Invalid URI reported from the alarm notification service");
- } else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_AlarmNotify_NotFound)) {
- /* This is OK; the service may not have loaded that calendar */
- } else if (BONOBO_EX (&ev)) {
- g_message ("stop_alarms(): Could not issue the removeCalendar request");
- }
+ GSList *selection, *l;
- CORBA_exception_free (&ev);
-
- /* Get rid of the service */
-
- CORBA_exception_init (&ev);
- bonobo_object_release_unref (an, &ev);
- if (BONOBO_EX (&ev))
- g_message ("stop_alarms(): Could not unref the alarm notification service");
- CORBA_exception_free (&ev);
+ selection = e_source_selector_get_selection (selector);
+ for (l = selection; l; l = l->next) {
+ ESource *selected_source = l->data;
+
+ load_uri_for_source (selected_source, view_control);
+ }
}
+/* Callbacks. */
static void
-remove_folder (EvolutionShellComponent *shell_component,
- const char *physical_uri,
- const char *type,
- const GNOME_Evolution_ShellComponentListener listener,
- void *closure)
+source_selection_changed_callback (ESourceSelector *selector,
+ BonoboControl *view_control)
{
- GnomeVFSURI *dir_uri, *data_uri, *backup_uri;
- GnomeVFSResult data_result, backup_result;
-
- /* check type */
- if (!type_is_calendar (type) && !type_is_tasks (type)) {
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
- GNOME_Evolution_ShellComponentListener_notifyResult (
- listener,
- GNOME_Evolution_ShellComponentListener_UNSUPPORTED_TYPE,
- &ev);
-
- if (BONOBO_EX (&ev))
- g_message ("remove_folder(): Could not notify the listener of "
- "an unsupported folder type");
+
+ load_uri_for_selection (selector, view_control);
+}
- CORBA_exception_free (&ev);
- return;
- }
+static void
+primary_source_selection_changed_callback (ESourceSelector *selector,
+ BonoboControl *view_control)
+{
+ ESource *source;
+ GnomeCalendar *gcal;
+ ECalModel *model;
+ CalClient *client;
- /* check URI */
- dir_uri = gnome_vfs_uri_new (physical_uri);
- if (!dir_uri) {
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
- GNOME_Evolution_ShellComponentListener_notifyResult (
- listener,
- GNOME_Evolution_ShellComponentListener_INVALID_URI,
- &ev);
- CORBA_exception_free (&ev);
+ source = e_source_selector_peek_primary_selection (selector);
+ if (!source)
return;
- }
- /* Compute the URIs of the appropriate files */
-
- if (type_is_calendar (type)) {
- data_uri = gnome_vfs_uri_append_file_name (dir_uri, "calendar.ics");
- backup_uri = gnome_vfs_uri_append_file_name (dir_uri, "calendar.ics~");
- } else if (type_is_tasks (type)) {
- data_uri = gnome_vfs_uri_append_file_name (dir_uri, "tasks.ics");
- backup_uri = gnome_vfs_uri_append_file_name (dir_uri, "tasks.ics~");
- } else {
- g_assert_not_reached ();
+ /* set the default client on the GnomeCalendar */
+ gcal = (GnomeCalendar *) bonobo_control_get_widget (view_control);
+ if (!GNOME_IS_CALENDAR (gcal))
return;
- }
-
- if (!data_uri || !backup_uri) {
- CORBA_Environment ev;
-
- g_message ("remove_folder(): Could not generate the data/backup URIs");
-
- CORBA_exception_init (&ev);
- GNOME_Evolution_ShellComponentListener_notifyResult (
- listener,
- GNOME_Evolution_ShellComponentListener_INVALID_URI,
- &ev);
-
- if (BONOBO_EX (&ev))
- g_message ("remove_folder(): Could not notify the listener "
- "of an invalid URI");
-
- CORBA_exception_free (&ev);
-
- goto out;
- }
-
- /* Ask the alarm daemon to stop monitoring this URI */
-
- stop_alarms (data_uri);
-
- /* Delete the data and backup files; the shell will take care of the rest */
-
- data_result = gnome_vfs_unlink_from_uri (data_uri);
- backup_result = gnome_vfs_unlink_from_uri (backup_uri);
-
- if ((data_result == GNOME_VFS_OK || data_result == GNOME_VFS_ERROR_NOT_FOUND)
- && (backup_result == GNOME_VFS_OK || backup_result == GNOME_VFS_ERROR_NOT_FOUND)) {
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
- GNOME_Evolution_ShellComponentListener_notifyResult (
- listener,
- GNOME_Evolution_ShellComponentListener_OK,
- &ev);
-
- if (BONOBO_EX (&ev))
- g_message ("remove_folder(): Could not notify the listener about success");
-
- CORBA_exception_free (&ev);
- } else {
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
- GNOME_Evolution_ShellComponentListener_notifyResult (
- listener,
- GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED,
- &ev);
-
- if (BONOBO_EX (&ev))
- g_message ("remove_folder(): Could not notify the listener about failure");
-
- CORBA_exception_free (&ev);
- }
- out:
-
- gnome_vfs_uri_unref (dir_uri);
-
- if (data_uri)
- gnome_vfs_uri_unref (data_uri);
-
- if (backup_uri)
- gnome_vfs_uri_unref (backup_uri);
+ model = gnome_calendar_get_calendar_model (gcal);
+ client = e_cal_model_get_client_for_uri (model, e_source_get_uri (source));
+ if (client)
+ gnome_calendar_set_default_client (gcal, client);
}
-static GNOME_Evolution_ShellComponentListener_Result
-xfer_file (GnomeVFSURI *base_src_uri,
- GnomeVFSURI *base_dest_uri,
- const char *file_name,
- int remove_source)
-{
- GnomeVFSURI *src_uri, *dest_uri;
- GnomeVFSHandle *hin, *hout;
- GnomeVFSResult result;
- GnomeVFSFileInfo file_info;
- GnomeVFSFileSize size;
- char *buffer;
-
- src_uri = gnome_vfs_uri_append_file_name (base_src_uri, file_name);
-
- result = gnome_vfs_open_uri (&hin, src_uri, GNOME_VFS_OPEN_READ);
- if (result == GNOME_VFS_ERROR_NOT_FOUND) {
- gnome_vfs_uri_unref (src_uri);
- return GNOME_Evolution_ShellComponentListener_OK; /* No need to xfer anything. */
- }
- if (result != GNOME_VFS_OK) {
- gnome_vfs_uri_unref (src_uri);
- return GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED;
- }
-
- result = gnome_vfs_get_file_info_uri (src_uri, &file_info, GNOME_VFS_FILE_INFO_DEFAULT);
- if (result != GNOME_VFS_OK) {
- gnome_vfs_uri_unref (src_uri);
- return GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED;
- }
-
- dest_uri = gnome_vfs_uri_append_file_name (base_dest_uri, file_name);
-
- result = gnome_vfs_create_uri (&hout, dest_uri, GNOME_VFS_OPEN_WRITE, FALSE, 0600);
- if (result != GNOME_VFS_OK) {
- gnome_vfs_close (hin);
- gnome_vfs_uri_unref (src_uri);
- gnome_vfs_uri_unref (dest_uri);
- return GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED;
- }
+/* GObject methods. */
- /* write source file to destination file */
- buffer = g_malloc (file_info.size);
- result = gnome_vfs_read (hin, buffer, file_info.size, &size);
- if (result != GNOME_VFS_OK) {
- gnome_vfs_close (hin);
- gnome_vfs_close (hout);
- gnome_vfs_uri_unref (src_uri);
- gnome_vfs_uri_unref (dest_uri);
- g_free (buffer);
- return GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED;
- }
+static void
+impl_dispose (GObject *object)
+{
+ CalendarComponentPrivate *priv = CALENDAR_COMPONENT (object)->priv;
- result = gnome_vfs_write (hout, buffer, file_info.size, &size);
- if (result != GNOME_VFS_OK) {
- gnome_vfs_close (hin);
- gnome_vfs_close (hout);
- gnome_vfs_uri_unref (src_uri);
- gnome_vfs_uri_unref (dest_uri);
- g_free (buffer);
- return GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED;
+ if (priv->source_list != NULL) {
+ g_object_unref (priv->source_list);
+ priv->source_list = NULL;
}
- if (remove_source) {
- char *text_uri;
-
- /* Sigh, we have to do this as there is no gnome_vfs_unlink_uri(). :-( */
-
- text_uri = gnome_vfs_uri_to_string (src_uri, GNOME_VFS_URI_HIDE_NONE);
- result = gnome_vfs_unlink (text_uri);
- g_free (text_uri);
+ if (priv->gconf_client != NULL) {
+ g_object_unref (priv->gconf_client);
+ priv->gconf_client = NULL;
}
- gnome_vfs_close (hin);
- gnome_vfs_close (hout);
- gnome_vfs_uri_unref (src_uri);
- gnome_vfs_uri_unref (dest_uri);
- g_free (buffer);
-
- return GNOME_Evolution_ShellComponentListener_OK;
+ (* G_OBJECT_CLASS (parent_class)->dispose) (object);
}
static void
-xfer_folder (EvolutionShellComponent *shell_component,
- const char *source_physical_uri,
- const char *destination_physical_uri,
- const char *type,
- gboolean remove_source,
- const GNOME_Evolution_ShellComponentListener listener,
- void *closure)
+impl_finalize (GObject *object)
{
- CORBA_Environment ev;
- GnomeVFSURI *src_uri;
- GnomeVFSURI *dest_uri;
- GnomeVFSResult result;
- char *filename, *backup_filename;
-
- CORBA_exception_init (&ev);
-
- /* check type */
- if (!type_is_calendar (type) && !type_is_tasks (type)) {
- GNOME_Evolution_ShellComponentListener_notifyResult (
- listener,
- GNOME_Evolution_ShellComponentListener_UNSUPPORTED_TYPE,
- &ev);
- CORBA_exception_free (&ev);
- return;
- }
-
- /* check URIs */
- src_uri = gnome_vfs_uri_new (source_physical_uri);
- dest_uri = gnome_vfs_uri_new (destination_physical_uri);
- if (!src_uri || ! dest_uri) {
- GNOME_Evolution_ShellComponentListener_notifyResult (
- listener,
- GNOME_Evolution_ShellComponentListener_INVALID_URI,
- &ev);
- gnome_vfs_uri_unref (src_uri);
- gnome_vfs_uri_unref (dest_uri);
- CORBA_exception_free (&ev);
- return;
- }
-
- if (type_is_calendar (type)) {
- filename = "calendar.ics";
- backup_filename = "calendar.ics~";
- } else if (type_is_tasks (type)) {
- filename = "tasks.ics";
- backup_filename = "tasks.ics~";
- } else {
- g_assert_not_reached ();
- return;
- }
-
- result = xfer_file (src_uri, dest_uri, filename, remove_source);
- if (result == GNOME_Evolution_ShellComponentListener_OK)
- result = xfer_file (src_uri, dest_uri, backup_filename, remove_source);
-
- GNOME_Evolution_ShellComponentListener_notifyResult (listener, result, &ev);
+ CalendarComponentPrivate *priv = CALENDAR_COMPONENT (object)->priv;
- gnome_vfs_uri_unref (src_uri);
- gnome_vfs_uri_unref (dest_uri);
+ g_free (priv->config_directory);
+ g_free (priv);
- CORBA_exception_free (&ev);
+ (* G_OBJECT_CLASS (parent_class)->finalize) (object);
}
-static gboolean
-request_quit (EvolutionShellComponent *shell_component, void *closure)
-{
- return e_comp_editor_registry_close_all (comp_editor_registry);
-}
-static void
-owner_set_cb (EvolutionShellComponent *shell_component,
- EvolutionShellClient *shell_client,
- const char *evolution_homedir,
- gpointer user_data)
-{
- if (evolution_dir)
- g_free (evolution_dir);
- evolution_dir = g_strdup (evolution_homedir);
- global_shell_client = shell_client;
-}
+/* Evolution::Component CORBA methods. */
static void
-owner_unset_cb (EvolutionShellComponent *shell_component,
- gpointer user_data)
+impl_createControls (PortableServer_Servant servant,
+ Bonobo_Control *corba_sidebar_control,
+ Bonobo_Control *corba_view_control,
+ CORBA_Environment *ev)
{
- global_shell_client = NULL;
-}
+ CalendarComponent *calendar_component = CALENDAR_COMPONENT (bonobo_object_from_servant (servant));
+ GtkWidget *selector;
+ GtkWidget *selector_scrolled_window;
+ BonoboControl *sidebar_control;
+ BonoboControl *view_control;
-/* Computes the final URI for a calendar component */
-static char *
-get_data_uri (const char *uri, CalComponentVType vtype)
-{
- if (uri) {
- if (*uri != '/' && strncmp (uri, "file:", 5) != 0)
- return g_strdup (uri);
-
- if (vtype == CAL_COMPONENT_EVENT)
- return cal_util_expand_uri ((char *) uri, FALSE);
- else if (vtype == CAL_COMPONENT_TODO)
- return cal_util_expand_uri ((char *) uri, TRUE);
- else
- g_assert_not_reached ();
- } else {
- if (vtype == CAL_COMPONENT_EVENT)
- return g_concat_dir_and_file (g_get_home_dir (),
- "evolution/local/Calendar/calendar.ics");
- else if (vtype == CAL_COMPONENT_TODO)
- return g_concat_dir_and_file (g_get_home_dir (),
- "evolution/local/Tasks/tasks.ics");
- else
- g_assert_not_reached ();
- }
+ selector = e_source_selector_new (calendar_component->priv->source_list);
+ gtk_widget_show (selector);
- return NULL;
-}
+ selector_scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+ gtk_container_add (GTK_CONTAINER (selector_scrolled_window), selector);
+ gtk_widget_show (selector_scrolled_window);
-/* Creates a calendar component at a specified URI. If the URI is NULL then it
- * uses the default folder for that type of component.
- */
-static void
-create_component (const char *uri, GNOME_Evolution_Calendar_CompEditorFactory_CompEditorMode type)
-{
- char *real_uri;
- CORBA_Environment ev;
- GNOME_Evolution_Calendar_CompEditorFactory factory;
- CalComponentVType vtype;
-
- switch (type) {
- case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_EVENT:
- case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_ALLDAY_EVENT:
- case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_MEETING:
- vtype = CAL_COMPONENT_EVENT;
- break;
- case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_TODO:
- vtype = CAL_COMPONENT_TODO;
- break;
- default:
- g_assert_not_reached ();
- return;
- }
+ sidebar_control = bonobo_control_new (selector_scrolled_window);
- real_uri = get_data_uri (uri, vtype);
+ view_control = control_factory_new_control ();
- /* Get the factory */
+ g_signal_connect_object (selector, "selection_changed",
+ G_CALLBACK (source_selection_changed_callback),
+ G_OBJECT (view_control), 0);
+ g_signal_connect_object (selector, "primary_selection_changed",
+ G_CALLBACK (primary_source_selection_changed_callback),
+ G_OBJECT (view_control), 0);
- CORBA_exception_init (&ev);
- factory = bonobo_activation_activate_from_id ("OAFIID:GNOME_Evolution_Calendar_CompEditorFactory",
- 0, NULL, &ev);
+ load_uri_for_selection (E_SOURCE_SELECTOR (selector), view_control);
- if (BONOBO_EX (&ev)) {
- g_message ("create_component(): Could not activate the component editor factory");
- CORBA_exception_free (&ev);
- g_free (real_uri);
- return;
- }
- CORBA_exception_free (&ev);
+ *corba_sidebar_control = CORBA_Object_duplicate (BONOBO_OBJREF (sidebar_control), ev);
+ *corba_view_control = CORBA_Object_duplicate (BONOBO_OBJREF (view_control), ev);
+}
- /* Create the item */
- CORBA_exception_init (&ev);
- GNOME_Evolution_Calendar_CompEditorFactory_editNew (factory, real_uri, type, &ev);
+/* Initialization. */
- if (BONOBO_EX (&ev))
- g_message ("create_component(): Exception while creating the component");
+static void
+calendar_component_class_init (CalendarComponentClass *class)
+{
+ POA_GNOME_Evolution_Component__epv *epv = &class->epv;
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
- CORBA_exception_free (&ev);
- g_free (real_uri);
+ parent_class = g_type_class_peek_parent (class);
- /* Get rid of the factory */
+ epv->createControls = impl_createControls;
- CORBA_exception_init (&ev);
- bonobo_object_release_unref (factory, &ev);
- if (BONOBO_EX (&ev))
- g_message ("create_component(): Could not unref the calendar component factory");
+ object_class->dispose = impl_dispose;
+ object_class->finalize = impl_finalize;
- CORBA_exception_free (&ev);
+ epv->createControls = impl_createControls;
}
-/* Callback used when we must create a user-creatable item */
static void
-sc_user_create_new_item_cb (EvolutionShellComponent *shell_component,
- const char *id,
- const char *parent_folder_physical_uri,
- const char *parent_folder_type)
+calendar_component_init (CalendarComponent *component)
{
- char *tmp_uri;
-
- if (strcmp (id, CREATE_EVENT_ID) == 0) {
- if (type_is_calendar (parent_folder_type))
- create_component (parent_folder_physical_uri,
- GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_EVENT);
- else {
- tmp_uri = calendar_config_default_calendar_folder ();
- create_component (tmp_uri,
- GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_EVENT);
- g_free (tmp_uri);
- }
- } else if (strcmp (id, CREATE_ALLDAY_EVENT_ID) == 0) {
- if (type_is_calendar (parent_folder_type))
- create_component (parent_folder_physical_uri,
- GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_ALLDAY_EVENT);
- else {
- tmp_uri = calendar_config_default_calendar_folder ();
- create_component (tmp_uri,
- GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_ALLDAY_EVENT);
- g_free (tmp_uri);
- }
- } else if (strcmp (id, CREATE_MEETING_ID) == 0) {
- if (type_is_calendar (parent_folder_type))
- create_component (parent_folder_physical_uri,
- GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_MEETING);
- else {
- tmp_uri = calendar_config_default_calendar_folder ();
- create_component (tmp_uri,
- GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_MEETING);
- g_free (tmp_uri);
+ CalendarComponentPrivate *priv;
+ GSList *groups;
+
+ priv = g_new0 (CalendarComponentPrivate, 1);
+
+ priv->config_directory = g_build_filename (g_get_home_dir (),
+ ".evolution", "calendar", "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 ();
+
+ priv->source_list = e_source_list_new_for_gconf (priv->gconf_client,
+ "/apps/evolution/calendar/sources");
+
+ /* create default calendars if there are no groups */
+ groups = e_source_list_peek_groups (priv->source_list);
+ if (!groups) {
+ ESourceGroup *group;
+ ESource *source;
+ char *base_uri, *new_dir;
+
+ /* create the source group */
+ base_uri = g_build_filename (g_get_home_dir (),
+ "/.evolution/calendar/local/OnThisComputer/",
+ NULL);
+ group = e_source_group_new (_("On This Computer"), base_uri);
+ e_source_list_add_group (priv->source_list, group, -1);
+
+ /* migrate calendars from older setup */
+ if (!migrate_old_calendars (group)) {
+ /* create default calendars */
+ new_dir = g_build_filename (base_uri, "Personal/", NULL);
+ if (!e_mkdir_hier (new_dir, 0700)) {
+ source = e_source_new (_("Personal"), "Personal");
+ e_source_group_add_source (group, source, -1);
+ }
+ g_free (new_dir);
+
+ new_dir = g_build_filename (base_uri, "Work/", NULL);
+ if (!e_mkdir_hier (new_dir, 0700)) {
+ source = e_source_new (_("Work"), "Work");
+ e_source_group_add_source (group, source, -1);
+ }
+ g_free (new_dir);
}
- } else if (strcmp (id, CREATE_TASK_ID) == 0) {
- if (type_is_tasks (parent_folder_type))
- create_component (parent_folder_physical_uri,
- GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_TODO);
- else {
- tmp_uri = calendar_config_default_tasks_folder ();
- create_component (tmp_uri,
- GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_TODO);
- g_free (tmp_uri);
- }
- } else
- g_assert_not_reached ();
-}
-
-/* The factory function. */
-
-static void
-add_creatable_item (EvolutionShellComponent *shell_component,
- const char *id,
- const char *description,
- const char *menu_description,
- const char *tooltip,
- const char *folder_type,
- char menu_shortcut,
- const char *icon_name)
-{
- char *icon_path;
- GdkPixbuf *icon;
-
- if (icon_name == NULL) {
- icon_path = NULL;
- icon = NULL;
- } else {
- icon_path = g_concat_dir_and_file (EVOLUTION_IMAGESDIR, icon_name);
- icon = gdk_pixbuf_new_from_file (icon_path, NULL);
+ g_free (base_uri);
}
- evolution_shell_component_add_user_creatable_item (shell_component,
- id,
- description,
- menu_description,
- tooltip,
- folder_type,
- menu_shortcut,
- icon);
-
- if (icon != NULL)
- gdk_pixbuf_unref (icon);
- g_free (icon_path);
+ component->priv = priv;
}
-static BonoboObject *
-create_object (void)
-{
- EvolutionShellComponent *shell_component;
- CalendarOfflineHandler *offline_handler;
-
- shell_component = evolution_shell_component_new (folder_types,
- NULL,
- create_view,
- create_folder,
- remove_folder,
- xfer_folder,
- NULL, /* populate_folder_context_menu_fn */
- NULL, /* unpopulate_folder_context_menu_fn */
- NULL, /* get_dnd_selection_fn */
- request_quit,
- NULL /* closure */);
-
- /* Offline handler */
- offline_handler = calendar_offline_handler_new ();
- bonobo_object_add_interface (BONOBO_OBJECT (shell_component),
- BONOBO_OBJECT (offline_handler));
-
- g_signal_connect (shell_component, "owner_set", G_CALLBACK (owner_set_cb), NULL);
- g_signal_connect (shell_component, "owner_unset", G_CALLBACK (owner_unset_cb), NULL);
-
- /* User creatable items */
- add_creatable_item (shell_component, CREATE_EVENT_ID,
- _("New appointment"), _("_Appointment"),
- _("Create a new appointment"),
- FOLDER_CALENDAR, 'a', "new_appointment.xpm");
+/* Public API. */
- add_creatable_item (shell_component, CREATE_MEETING_ID,
- _("New meeting"), _("M_eeting"),
- _("Create a new meeting request"),
- FOLDER_CALENDAR, 'e', "meeting-request-16.png");
-
- add_creatable_item (shell_component, CREATE_TASK_ID,
- _("New task"), _("_Task"),
- _("Create a new task"),
- FOLDER_TASKS, 't', "new_task-16.png");
+CalendarComponent *
+calendar_component_peek (void)
+{
+ static CalendarComponent *component = NULL;
- add_creatable_item (shell_component, CREATE_ALLDAY_EVENT_ID,
- _("New All Day Appointment"), _("All _Day Appointment"),
- _("Create a new all-day appointment"),
- FOLDER_CALENDAR, 'd', "new_all_day_event.png");
+ if (component == NULL) {
+ component = g_object_new (calendar_component_get_type (), NULL);
- g_signal_connect (shell_component, "user_create_new_item",
- G_CALLBACK (sc_user_create_new_item_cb), NULL);
+ if (e_mkdir_hier (calendar_component_peek_config_directory (component), 0777) != 0) {
+ g_warning ("Cannot create directory %s: %s",
+ calendar_component_peek_config_directory (component),
+ g_strerror (errno));
+ g_object_unref (component);
+ component = NULL;
+ }
+ }
- return BONOBO_OBJECT (shell_component);
+ return component;
}
-
-BonoboObject *
-calendar_component_get_object (void)
+const char *
+calendar_component_peek_config_directory (CalendarComponent *component)
{
- static BonoboObject *object = NULL;
+ return component->priv->config_directory;
+}
- if (object != NULL) {
- bonobo_object_ref (BONOBO_OBJECT (object));
- } else {
- object = create_object ();
- g_object_add_weak_pointer (G_OBJECT (object), (void *) &object);
- }
- return object;
-}
+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 2d94920adc..96630add5f 100644
--- a/calendar/gui/calendar-component.h
+++ b/calendar/gui/calendar-component.h
@@ -1,7 +1,7 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* component-factory.h
+/* calendar-component.h
*
- * Copyright (C) 2000, 2001, 2002, 2003 Ximian, Inc.
+ * Copyright (C) 2003 Ettore Perazzoli
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public
@@ -20,13 +20,47 @@
* Author: Ettore Perazzoli <ettore@ximian.com>
*/
-#ifndef _COMPONENT_FACTORY_H_
-#define _COMPONENT_FACTORY_H_
+#ifndef _CALENDAR_COMPONENT_H_
+#define _CALENDAR_COMPONENT_H_
+
#include <bonobo/bonobo-object.h>
-extern char *evolution_dir;
+#include "Evolution.h"
+#include "e-util/e-source-list.h"
+
+
+#define CALENDAR_TYPE_COMPONENT (calendar_component_get_type ())
+#define CALENDAR_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALENDAR_TYPE_COMPONENT, CalendarComponent))
+#define CALENDAR_COMPONENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALENDAR_TYPE_COMPONENT, CalendarComponentClass))
+#define CALENDAR_IS_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALENDAR_TYPE_COMPONENT))
+#define CALENDAR_IS_COMPONENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), CALENDAR_TYPE_COMPONENT))
+
+
+typedef struct _CalendarComponent CalendarComponent;
+typedef struct _CalendarComponentPrivate CalendarComponentPrivate;
+typedef struct _CalendarComponentClass CalendarComponentClass;
+
+struct _CalendarComponent {
+ BonoboObject parent;
+
+ CalendarComponentPrivate *priv;
+};
+
+struct _CalendarComponentClass {
+ BonoboObjectClass parent_class;
+
+ POA_GNOME_Evolution_Component__epv epv;
+};
+
+
+GType calendar_component_get_type (void);
+
+CalendarComponent *calendar_component_peek (void);
+
+const char *calendar_component_peek_config_directory (CalendarComponent *component);
+
+ESourceList *calendar_component_peek_source_list (CalendarComponent *component);
-BonoboObject *calendar_component_get_object (void);
-#endif /* _COMPONENT_FACTORY_H_ */
+#endif /* _CALENDAR_COMPONENT_H_ */
diff --git a/calendar/gui/calendar-offline-handler.c b/calendar/gui/calendar-offline-handler.c
index 458f951d9a..ff30299746 100644
--- a/calendar/gui/calendar-offline-handler.c
+++ b/calendar/gui/calendar-offline-handler.c
@@ -29,6 +29,7 @@
#include <gtk/gtkmain.h>
#include <gtk/gtksignal.h>
#include <bonobo/bonobo-exception.h>
+#include <bonobo/bonobo-i18n.h>
#include <gal/util/e-util.h>
#include "e-util/e-url.h"
#include <cal-client/cal-client.h>
@@ -180,13 +181,16 @@ backend_go_offline (gpointer data, gpointer user_data)
char *uri = data;
CalClient *client;
gboolean success;
+ GError *error = NULL;
- client = cal_client_new ();
+ client = cal_client_new (uri, CALOBJ_TYPE_ANY);
g_signal_connect (client, "cal_opened", G_CALLBACK (backend_cal_opened_offline), offline_handler);
- success = cal_client_open_calendar (client, uri, TRUE);
+ success = cal_client_open (client, TRUE, &error);
if (!success) {
+ g_warning (_("backend_go_offline(): %s"), error->message);
update_offline (offline_handler);
g_object_unref (client);
+ g_error_free (error);
return;
}
}
@@ -198,13 +202,16 @@ backend_go_online (gpointer data, gpointer user_data)
char *uri = data;
CalClient *client;
gboolean success;
+ GError *error = NULL;
- client = cal_client_new ();
+ client = cal_client_new (uri, CALOBJ_TYPE_ANY);
g_signal_connect (G_OBJECT (client), "cal_opened",
G_CALLBACK (backend_cal_opened_online), offline_handler);
- success = cal_client_open_calendar (client, uri, TRUE);
+ success = cal_client_open (client, TRUE, &error);
if (!success) {
+ g_warning (_("backend_go_online(): %s"), error->message);
g_object_unref (G_OBJECT (client));
+ g_error_free (error);
return;
}
}
@@ -319,7 +326,8 @@ calendar_offline_handler_init (CalendarOfflineHandler *offline_handler)
priv = g_new (CalendarOfflineHandlerPrivate, 1);
offline_handler->priv = priv;
- priv->client = cal_client_new ();
+ /* FIXME: what URI to use? */
+ priv->client = cal_client_new ("", CALOBJ_TYPE_ANY);
priv->listener_interface = CORBA_OBJECT_NIL;
priv->is_offline = FALSE;
}
diff --git a/calendar/gui/comp-editor-factory.c b/calendar/gui/comp-editor-factory.c
index f76e0d4f03..7b7dcb4c87 100644
--- a/calendar/gui/comp-editor-factory.c
+++ b/calendar/gui/comp-editor-factory.c
@@ -241,39 +241,26 @@ edit_existing (OpenClient *oc, const char *uid)
{
CalComponent *comp;
icalcomponent *icalcomp;
- CalClientGetStatus status;
CompEditor *editor;
CalComponentVType vtype;
g_assert (oc->open);
/* Get the object */
+ if (!cal_client_get_object (oc->client, uid, NULL, &icalcomp, NULL)) {
+ /* FIXME Better error handling */
+ g_warning (G_STRLOC ": Syntax error while getting component `%s'", uid);
- status = cal_client_get_object (oc->client, uid, &icalcomp);
-
- switch (status) {
- case CAL_CLIENT_GET_SUCCESS:
- comp = cal_component_new ();
- if (!cal_component_set_icalcomponent (comp, icalcomp)) {
- g_object_unref (comp);
- icalcomponent_free (icalcomp);
- return;
- }
- break;
-
- case CAL_CLIENT_GET_NOT_FOUND:
- /* The object disappeared from the server */
- return;
-
- case CAL_CLIENT_GET_SYNTAX_ERROR:
- g_message ("edit_exiting(): Syntax error while getting component `%s'", uid);
return;
-
- default:
- g_assert_not_reached ();
+ }
+
+ comp = cal_component_new ();
+ if (!cal_component_set_icalcomponent (comp, icalcomp)) {
+ g_object_unref (comp);
+ icalcomponent_free (icalcomp);
return;
}
-
+
/* Create the appropriate type of editor */
vtype = cal_component_get_vtype (comp);
@@ -405,13 +392,15 @@ resolve_pending_requests (OpenClient *oc)
factory = oc->factory;
priv = factory->priv;
- g_assert (oc->pending != NULL);
+ if (!oc->pending)
+ return;
/* Set the default timezone in the backend. */
location = calendar_config_get_timezone ();
zone = icaltimezone_get_builtin_timezone (location);
if (zone)
- cal_client_set_default_timezone (oc->client, zone);
+ /* FIXME Error handling? */
+ cal_client_set_default_timezone (oc->client, zone, NULL);
for (l = oc->pending; l; l = l->next) {
Request *request;
@@ -501,10 +490,11 @@ open_client (CompEditorFactory *factory, const char *uristr)
CompEditorFactoryPrivate *priv;
CalClient *client;
OpenClient *oc;
+ GError *error = NULL;
priv = factory->priv;
- client = cal_client_new ();
+ client = cal_client_new (uristr, CALOBJ_TYPE_ANY);
if (!client)
return NULL;
@@ -522,10 +512,12 @@ open_client (CompEditorFactory *factory, const char *uristr)
g_hash_table_insert (priv->uri_client_hash, oc->uri, oc);
- if (!cal_client_open_calendar (oc->client, uristr, FALSE)) {
+ if (!cal_client_open (oc->client, FALSE, &error)) {
+ g_warning (_("open_client(): %s"), error->message);
g_free (oc->uri);
g_object_unref (oc->client);
g_free (oc);
+ g_error_free (error);
return NULL;
}
diff --git a/calendar/gui/comp-util.c b/calendar/gui/comp-util.c
index 28bc66bd54..aceff667c2 100644
--- a/calendar/gui/comp-util.c
+++ b/calendar/gui/comp-util.c
@@ -95,7 +95,6 @@ cal_comp_util_compare_event_timezones (CalComponent *comp,
CalClient *client,
icaltimezone *zone)
{
- CalClientGetStatus status;
CalComponentDateTime start_datetime, end_datetime;
const char *tzid;
gboolean retval = FALSE;
@@ -143,10 +142,8 @@ cal_comp_util_compare_event_timezones (CalComponent *comp,
/* If the TZIDs differ, we have to compare the UTC offsets
of the start and end times, using their own timezones and
the given timezone. */
- status = cal_client_get_timezone (client,
- start_datetime.tzid,
- &start_zone);
- if (status != CAL_CLIENT_GET_SUCCESS)
+ if (!cal_client_get_timezone (client, start_datetime.tzid,
+ &start_zone, NULL))
goto out;
if (start_datetime.value) {
@@ -160,10 +157,8 @@ cal_comp_util_compare_event_timezones (CalComponent *comp,
goto out;
}
- status = cal_client_get_timezone (client,
- end_datetime.tzid,
- &end_zone);
- if (status != CAL_CLIENT_GET_SUCCESS)
+ if (!cal_client_get_timezone (client, end_datetime.tzid,
+ &end_zone, NULL))
goto out;
if (end_datetime.value) {
@@ -210,8 +205,8 @@ gboolean
cal_comp_is_on_server (CalComponent *comp, CalClient *client)
{
const char *uid;
- CalClientGetStatus status;
icalcomponent *icalcomp;
+ GError *error = NULL;
g_return_val_if_fail (comp != NULL, FALSE);
g_return_val_if_fail (IS_CAL_COMPONENT (comp), FALSE);
@@ -226,24 +221,15 @@ cal_comp_is_on_server (CalComponent *comp, CalClient *client)
*/
cal_component_get_uid (comp, &uid);
- status = cal_client_get_object (client, uid, &icalcomp);
-
- switch (status) {
- case CAL_CLIENT_GET_SUCCESS:
+ if (cal_client_get_object (client, uid, NULL, &icalcomp, &error)) {
icalcomponent_free (icalcomp);
- return TRUE;
- case CAL_CLIENT_GET_SYNTAX_ERROR:
- g_message ("confirm_delete_empty_appointment(): Syntax error when getting "
- "object `%s'",
- uid);
return TRUE;
+ }
- case CAL_CLIENT_GET_NOT_FOUND:
- return FALSE;
-
- default:
- g_assert_not_reached ();
+ if (error) {
+ g_warning ("cal_comp_is_on_server(): %s", error->message);
+ g_error_free (error);
}
return FALSE;
@@ -268,7 +254,7 @@ cal_comp_event_new_with_defaults (CalClient *client)
icalproperty *icalprop;
CalAlarmTrigger trigger;
- if (cal_client_get_default_object (client, CALOBJ_TYPE_EVENT, &icalcomp) != CAL_CLIENT_GET_SUCCESS)
+ if (!cal_client_get_default_object (client, &icalcomp, NULL))
return NULL;
comp = cal_component_new ();
@@ -334,8 +320,16 @@ cal_comp_task_new_with_defaults (CalClient *client)
CalComponent *comp;
icalcomponent *icalcomp;
- if (cal_client_get_default_object (client, CALOBJ_TYPE_TODO, &icalcomp) != CAL_CLIENT_GET_SUCCESS)
+ if (!cal_client_get_default_object (client, &icalcomp, NULL))
+ return NULL;
+
+ comp = cal_component_new ();
+ if (!cal_component_set_icalcomponent (comp, icalcomp)) {
+ g_object_unref (comp);
+ icalcomponent_free (icalcomp);
+
return NULL;
+ }
comp = cal_component_new ();
if (!cal_component_set_icalcomponent (comp, icalcomp)) {
diff --git a/calendar/gui/control-factory.c b/calendar/gui/control-factory.c
index 191a8d85ea..7adc5e83df 100644
--- a/calendar/gui/control-factory.c
+++ b/calendar/gui/control-factory.c
@@ -69,8 +69,11 @@ get_prop (BonoboPropertyBag *bag,
CORBA_Environment *ev,
gpointer user_data)
{
- GnomeCalendar *gcal = user_data;
+ GnomeCalendar *gcal;
const char *uri;
+ BonoboControl *control = user_data;
+
+ gcal = (GnomeCalendar *) bonobo_control_get_widget (control);
switch (arg_id) {
@@ -96,6 +99,7 @@ get_prop (BonoboPropertyBag *bag,
case GNOME_CAL_LIST_VIEW:
BONOBO_ARG_SET_STRING (arg, "list");
break;
+ default:
}
break;
@@ -104,7 +108,6 @@ get_prop (BonoboPropertyBag *bag,
}
}
-
static void
set_prop (BonoboPropertyBag *bag,
const BonoboArg *arg,
@@ -112,14 +115,19 @@ set_prop (BonoboPropertyBag *bag,
CORBA_Environment *ev,
gpointer user_data)
{
- GnomeCalendar *gcal = user_data;
+ GnomeCalendar *gcal;
char *string;
GnomeCalendarViewType view;
+ BonoboControl *control = user_data;
+
+ gcal = (GnomeCalendar *) bonobo_control_get_widget (control);
switch (arg_id) {
case PROPERTY_CALENDAR_URI_IDX:
string = BONOBO_ARG_GET_STRING (arg);
- if (!gnome_calendar_open (gcal, string)) {
+ if (gnome_calendar_add_event_uri (gcal, string)) {
+ calendar_control_sensitize_calendar_commands (control, gcal, TRUE);
+ } else {
char *msg;
msg = g_strdup_printf (_("Could not open the folder in '%s'"), string);
@@ -161,7 +169,7 @@ calendar_properties_init (GnomeCalendar *gcal, BonoboControl *control)
{
BonoboPropertyBag *pbag;
- pbag = bonobo_property_bag_new (get_prop, set_prop, gcal);
+ pbag = bonobo_property_bag_new (get_prop, set_prop, control);
bonobo_property_bag_add (pbag,
PROPERTY_CALENDAR_URI,
diff --git a/calendar/gui/control-factory.h b/calendar/gui/control-factory.h
index f599f7b3b8..bab1611c03 100644
--- a/calendar/gui/control-factory.h
+++ b/calendar/gui/control-factory.h
@@ -23,6 +23,8 @@
#ifndef _CONTROL_FACTORY_H_
#define _CONTROL_FACTORY_H_
+#include <bonobo/bonobo-control.h>
+
BonoboControl *control_factory_new_control (void);
#endif /* _CONTROL_FACTORY_H_ */
diff --git a/calendar/gui/dialogs/Makefile.am b/calendar/gui/dialogs/Makefile.am
index 2466ffaa14..84424f8cc0 100644
--- a/calendar/gui/dialogs/Makefile.am
+++ b/calendar/gui/dialogs/Makefile.am
@@ -61,6 +61,8 @@ libcal_dialogs_la_SOURCES = \
event-page.h \
meeting-page.c \
meeting-page.h \
+ new-calendar.c \
+ new-calendar.h \
recurrence-page.c \
recurrence-page.h \
recur-comp.c \
@@ -85,6 +87,7 @@ glade_DATA = \
e-delegate-dialog.glade \
event-page.glade \
meeting-page.glade \
+ new-calendar.glade \
recurrence-page.glade \
schedule-page.glade \
task-details-page.glade \
diff --git a/calendar/gui/dialogs/alarm-options.c b/calendar/gui/dialogs/alarm-options.c
index ef13b78b13..b105dc3c23 100644
--- a/calendar/gui/dialogs/alarm-options.c
+++ b/calendar/gui/dialogs/alarm-options.c
@@ -39,7 +39,7 @@
#include <bonobo/bonobo-widget.h>
#include <libgnomeui/gnome-file-entry.h>
#include <glade/glade.h>
-#include <ebook/e-destination.h>
+#include <addressbook/util/eab-destination.h>
#include "Evolution-Addressbook-SelectNames.h"
#include "e-util/e-dialog-widgets.h"
#include "alarm-options.h"
@@ -307,7 +307,7 @@ alarm_to_malarm_widgets (Dialog *dialog, CalComponentAlarm *alarm)
CalComponentText description;
GtkTextBuffer *text_buffer;
GSList *attendee_list, *l;
- EDestination **destv;
+ EABDestination **destv;
int len, i;
/* Recipients */
@@ -315,22 +315,22 @@ alarm_to_malarm_widgets (Dialog *dialog, CalComponentAlarm *alarm)
len = g_slist_length (attendee_list);
if (len <= 0) {
- destv = g_new0 (EDestination *, 2);
- destv[0] = e_destination_new ();
- e_destination_set_email (destv[0], dialog->email);
+ destv = g_new0 (EABDestination *, 2);
+ destv[0] = eab_destination_new ();
+ eab_destination_set_email (destv[0], dialog->email);
destv[1] = NULL;
len = 1;
} else {
- destv = g_new0 (EDestination *, len + 1);
+ destv = g_new0 (EABDestination *, len + 1);
for (l = attendee_list, i = 0; l != NULL; l = l->next, i++) {
CalComponentAttendee *a = l->data;
- EDestination *dest;
+ EABDestination *dest;
- dest = e_destination_new ();
+ dest = eab_destination_new ();
if (a->cn != NULL && *a->cn)
- e_destination_set_name (dest, a->cn);
+ eab_destination_set_name (dest, a->cn);
if (a->value != NULL && *a->value)
- e_destination_set_email (dest, a->value);
+ eab_destination_set_email (dest, a->value);
destv[i] = dest;
}
@@ -338,7 +338,7 @@ alarm_to_malarm_widgets (Dialog *dialog, CalComponentAlarm *alarm)
}
bonobo_widget_set_property (BONOBO_WIDGET (dialog->malarm_addresses),
- "destinations", e_destination_exportv (destv), NULL);
+ "destinations", eab_destination_exportv (destv), NULL);
for (i = 0; i < len; i++)
g_object_unref (GTK_OBJECT (destv[i]));
@@ -617,7 +617,7 @@ malarm_widgets_to_alarm (Dialog *dialog, CalComponentAlarm *alarm)
char *str;
CalComponentText description;
GSList *attendee_list = NULL;
- EDestination **destv;
+ EABDestination **destv;
GtkTextBuffer *text_buffer;
GtkTextIter text_iter_start, text_iter_end;
icalcomponent *icalcomp;
@@ -627,18 +627,18 @@ malarm_widgets_to_alarm (Dialog *dialog, CalComponentAlarm *alarm)
/* Attendees */
bonobo_widget_get_property (BONOBO_WIDGET (dialog->malarm_addresses), "destinations",
TC_CORBA_string, &str, NULL);
- destv = e_destination_importv (str);
+ destv = eab_destination_importv (str);
g_free (str);
for (i = 0; destv[i] != NULL; i++) {
- EDestination *dest;
+ EABDestination *dest;
CalComponentAttendee *a;
dest = destv[i];
a = g_new0 (CalComponentAttendee, 1);
- a->value = e_destination_get_email (dest);
- a->cn = e_destination_get_name (dest);
+ a->value = eab_destination_get_email (dest);
+ a->cn = eab_destination_get_name (dest);
attendee_list = g_slist_append (attendee_list, a);
}
@@ -646,7 +646,7 @@ malarm_widgets_to_alarm (Dialog *dialog, CalComponentAlarm *alarm)
cal_component_alarm_set_attendee_list (alarm, attendee_list);
cal_component_free_attendee_list (attendee_list);
- e_destination_freev (destv);
+ eab_destination_freev (destv);
/* Description */
text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (dialog->dalarm_description));
diff --git a/calendar/gui/e-cal-model-calendar.c b/calendar/gui/e-cal-model-calendar.c
index 82de4e6d5a..593d342e70 100644
--- a/calendar/gui/e-cal-model-calendar.c
+++ b/calendar/gui/e-cal-model-calendar.c
@@ -129,7 +129,7 @@ get_dtend (ECalModelComponent *comp_data)
/* FIXME: handle errors */
cal_client_get_timezone (comp_data->client,
icaltime_get_tzid (tt_end),
- &zone);
+ &zone, NULL);
comp_data->dtend->zone = zone;
}
@@ -308,8 +308,12 @@ ecmc_set_value_at (ETableModel *etm, int col, int row, const void *value)
break;
}
- if (cal_client_update_objects (comp_data->client, comp_data->icalcomp) != CAL_CLIENT_RESULT_SUCCESS)
- g_message ("ecmc_set_value_at(): Could not update the object!");
+ /* FIXME ask about mod type */
+ if (!cal_client_modify_object (comp_data->client, comp_data->icalcomp, CALOBJ_MOD_ALL, NULL)) {
+ g_warning (G_STRLOC ": Could not modify the object!");
+
+ /* FIXME Show error dialog */
+ }
}
static gboolean
diff --git a/calendar/gui/e-cal-model-tasks.c b/calendar/gui/e-cal-model-tasks.c
index 6bca52586c..76e2e140f3 100644
--- a/calendar/gui/e-cal-model-tasks.c
+++ b/calendar/gui/e-cal-model-tasks.c
@@ -223,7 +223,7 @@ get_completed (ECalModelComponent *comp_data)
/* FIXME: handle errors */
cal_client_get_timezone (comp_data->client,
icaltime_get_tzid (tt_completed),
- &zone);
+ &zone, NULL);
comp_data->completed->zone = zone;
}
@@ -253,7 +253,7 @@ get_due (ECalModelComponent *comp_data)
/* FIXME: handle errors */
cal_client_get_timezone (comp_data->client,
icaltime_get_tzid (tt_due),
- &zone);
+ &zone, NULL);
comp_data->due->zone = zone;
}
@@ -399,7 +399,7 @@ get_due_status (ECalModelTasks *model, ECalModelComponent *comp_data)
/* Get the current time in the same timezone as the DUE date.*/
status = cal_client_get_timezone (comp_data->client,
icaltime_get_tzid (due_tt),
- &zone);
+ &zone, NULL);
if (status != CAL_CLIENT_GET_SUCCESS)
return E_CAL_MODEL_TASKS_DUE_FUTURE;
@@ -756,8 +756,12 @@ ecmt_set_value_at (ETableModel *etm, int col, int row, const void *value)
break;
}
- if (cal_client_update_objects (comp_data->client, comp_data->icalcomp) != CAL_CLIENT_RESULT_SUCCESS)
- g_message ("ecmt_set_value_at(): Could not update the object!");
+ /* FIXME ask about mod type */
+ if (!cal_client_modify_object (comp_data->client, comp_data->icalcomp, CALOBJ_MOD_ALL, NULL)) {
+ g_warning (G_STRLOC ": Could not modify the object!");
+
+ /* FIXME Show error dialog */
+ }
}
static gboolean
diff --git a/calendar/gui/e-cal-model.c b/calendar/gui/e-cal-model.c
index 1c231f9c72..c8b706c66e 100644
--- a/calendar/gui/e-cal-model.c
+++ b/calendar/gui/e-cal-model.c
@@ -41,6 +41,9 @@ struct _ECalModelPrivate {
/* The list of clients we are managing. Each element is of type ECalModelClient */
GList *clients;
+ /* The default client in the list */
+ CalClient *default_client;
+
/* Array for storing the objects. Each element is of type ECalModelComponent */
GPtrArray *objects;
@@ -352,7 +355,7 @@ get_dtstart (ECalModel *model, ECalModelComponent *comp_data)
/* FIXME: handle errors */
cal_client_get_timezone (comp_data->client,
icaltime_get_tzid (tt_start),
- &zone);
+ &zone, NULL);
comp_data->dtstart->zone = zone;
}
@@ -609,8 +612,12 @@ ecm_set_value_at (ETableModel *etm, int col, int row, const void *value)
break;
}
- if (cal_client_update_objects (comp_data->client, comp_data->icalcomp) != CAL_CLIENT_RESULT_SUCCESS)
- g_message ("ecm_set_value_at(): Could not update the object!");
+ /* FIXME ask about mod type */
+ if (!cal_client_modify_object (comp_data->client, comp_data->icalcomp, CALOBJ_MOD_ALL, NULL)) {
+ g_warning (G_STRLOC ": Could not modify the object!");
+
+ /* FIXME Show error dialog */
+ }
}
static gboolean
@@ -673,7 +680,10 @@ ecm_append_row (ETableModel *etm, ETableModel *source, int row)
model_class->fill_component_from_model (model, &comp_data, source_model, row);
}
- if (cal_client_update_objects (comp_data.client, comp_data.icalcomp) != CAL_CLIENT_RESULT_SUCCESS) {
+
+ if (!cal_client_create_object (comp_data.client, comp_data.icalcomp, NULL, NULL)) {
+ g_warning (G_STRLOC ": Could not create the object!");
+
/* FIXME: show error dialog */
}
@@ -987,46 +997,53 @@ CalClient *
e_cal_model_get_default_client (ECalModel *model)
{
ECalModelPrivate *priv;
- GList *l;
- gchar *default_uri = NULL;
- EConfigListener *db;
ECalModelClient *client_data;
+ g_return_val_if_fail (model != NULL, NULL);
g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL);
-
+
priv = model->priv;
+ /* we always return a valid CalClient, since we rely on it in many places */
+ if (priv->default_client)
+ return priv->default_client;
+
if (!priv->clients)
return NULL;
- db = e_config_listener_new ();
+ client_data = (ECalModelClient *) priv->clients->data;
- /* look at the configuration and return the real default calendar if we've got it loaded */
- if (priv->kind == ICAL_VEVENT_COMPONENT)
- default_uri = e_config_listener_get_string (db, "/apps/evolution/shell/default_folders/calendar_uri");
- else if (priv->kind == ICAL_VTODO_COMPONENT)
- default_uri = e_config_listener_get_string (db, "/apps/evolution/shell/default_folders/tasks_uri");
+ return client_data ? client_data->client : NULL;
+}
- g_object_unref (db);
+void
+e_cal_model_set_default_client (ECalModel *model, CalClient *client)
+{
+ ECalModelPrivate *priv;
+ GList *l;
+ gboolean found = FALSE;
+
+ g_return_if_fail (model != NULL);
+ g_return_if_fail (E_IS_CAL_MODEL (model));
+ g_return_if_fail (client != NULL);
+ g_return_if_fail (IS_CAL_CLIENT (client));
- if (!default_uri) {
- client_data = (ECalModelClient *) priv->clients->data;
- return client_data->client;
- }
+ priv = model->priv;
+ /* See if we already know about the client */
for (l = priv->clients; l != NULL; l = l->next) {
- client_data = (ECalModelClient *) l->data;
+ ECalModelClient *client_data = l->data;
- if (!strcmp (default_uri, cal_client_get_uri (client_data->client))) {
- g_free (default_uri);
- return client_data->client;
- }
+ if (client == client_data->client)
+ found = TRUE;
}
- g_free (default_uri);
-
- client_data = (ECalModelClient *) priv->clients->data;
- return client_data->client;
+ /* If its not found, add it */
+ if (!found)
+ e_cal_model_add_client (model, client);
+
+ /* Store the default client */
+ priv->default_client = client;
}
/**
@@ -1048,6 +1065,29 @@ e_cal_model_get_client_list (ECalModel *model)
return list;
}
+/**
+ * e_cal_model_get_client_for_uri
+ * @model: A calendar model.
+ * @uri: Uri for the client to get.
+ */
+CalClient *
+e_cal_model_get_client_for_uri (ECalModel *model, const char *uri)
+{
+ GList *l;
+
+ g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL);
+ g_return_val_if_fail (uri != NULL, NULL);
+
+ for (l = model->priv->clients; l != NULL; l = l->next) {
+ ECalModelClient *client_data = (ECalModelClient *) l->data;
+
+ if (!strcmp (uri, cal_client_get_uri (client_data->client)))
+ return client_data->client;
+ }
+
+ return NULL;
+}
+
static ECalModelComponent *
search_by_uid_and_client (ECalModelPrivate *priv, CalClient *client, const char *uid)
{
@@ -1084,124 +1124,119 @@ get_position_in_array (GPtrArray *objects, gpointer item)
}
static void
-query_obj_updated_cb (CalQuery *query, const char *uid,
- gboolean query_in_progress,
- int n_scanned, int total,
- gpointer user_data)
+query_objects_added_cb (CalQuery *query, GList *objects, gpointer user_data)
{
- ECalModelPrivate *priv;
- icalcomponent *new_icalcomp;
- CalClientGetStatus status;
- ECalModelComponent *comp_data;
- gint pos;
ECalModel *model = (ECalModel *) user_data;
-
- g_return_if_fail (E_IS_CAL_MODEL (model));
-
+ ECalModelPrivate *priv;
+ GList *l;
+ int start_row;
+
priv = model->priv;
e_table_model_pre_change (E_TABLE_MODEL (model));
- comp_data = search_by_uid_and_client (priv, cal_query_get_client (query), uid);
- status = cal_client_get_object (cal_query_get_client (query), uid, &new_icalcomp);
- switch (status) {
- case CAL_CLIENT_GET_SUCCESS :
- if (comp_data) {
- if (comp_data->icalcomp)
- icalcomponent_free (comp_data->icalcomp);
- if (comp_data->dtstart) {
- g_free (comp_data->dtstart);
- comp_data->dtstart = NULL;
- }
- if (comp_data->dtend) {
- g_free (comp_data->dtend);
- comp_data->dtend = NULL;
- }
- if (comp_data->due) {
- g_free (comp_data->due);
- comp_data->due = NULL;
- }
- if (comp_data->completed) {
- g_free (comp_data->completed);
- comp_data->completed = NULL;
- }
+ start_row = priv->objects->len ? priv->objects->len - 1 : 0;
+
+ for (l = objects; l; l = l->next) {
+ ECalModelComponent *comp_data;
- comp_data->icalcomp = new_icalcomp;
+ comp_data = g_new0 (ECalModelComponent, 1);
+ comp_data->client = cal_query_get_client (query);
+ comp_data->icalcomp = icalcomponent_new_clone (l->data);
- e_table_model_row_changed (E_TABLE_MODEL (model), get_position_in_array (priv->objects, comp_data));
- } else {
- comp_data = g_new0 (ECalModelComponent, 1);
- comp_data->client = cal_query_get_client (query);
- comp_data->icalcomp = new_icalcomp;
+ g_ptr_array_add (priv->objects, comp_data);
+ }
- g_ptr_array_add (priv->objects, comp_data);
- e_table_model_row_inserted (E_TABLE_MODEL (model), priv->objects->len - 1);
- }
- break;
- case CAL_CLIENT_GET_NOT_FOUND :
- case CAL_CLIENT_GET_SYNTAX_ERROR :
- if (comp_data) {
- /* Nothing; the object may have been removed from the server. We just
- notify that the old object was deleted.
- */
- pos = get_position_in_array (priv->objects, comp_data);
+ e_table_model_rows_inserted (E_TABLE_MODEL (model), start_row, priv->objects->len - start_row);
+}
- g_ptr_array_remove (priv->objects, comp_data);
- free_comp_data (comp_data);
+static void
+query_objects_modified_cb (CalQuery *query, GList *objects, gpointer user_data)
+{
+ ECalModelPrivate *priv;
+ ECalModel *model = (ECalModel *) user_data;
+ GList *l;
+
+ priv = model->priv;
- e_table_model_row_deleted (E_TABLE_MODEL (model), pos);
- } else
- e_table_model_no_change (E_TABLE_MODEL (model));
- break;
- default :
- g_assert_not_reached ();
+ for (l = objects; l; l = l->next) {
+ ECalModelComponent *comp_data;
+
+ e_table_model_pre_change (E_TABLE_MODEL (model));
+
+ comp_data = search_by_uid_and_client (priv, cal_query_get_client (query), icalcomponent_get_uid (l->data));
+ g_assert (comp_data);
+
+ if (comp_data->icalcomp)
+ icalcomponent_free (comp_data->icalcomp);
+ if (comp_data->dtstart) {
+ g_free (comp_data->dtstart);
+ comp_data->dtstart = NULL;
+ }
+ if (comp_data->dtend) {
+ g_free (comp_data->dtend);
+ comp_data->dtend = NULL;
+ }
+ if (comp_data->due) {
+ g_free (comp_data->due);
+ comp_data->due = NULL;
+ }
+ if (comp_data->completed) {
+ g_free (comp_data->completed);
+ comp_data->completed = NULL;
+ }
+
+ comp_data->icalcomp = icalcomponent_new_clone (l->data);
+
+ e_table_model_row_changed (E_TABLE_MODEL (model), get_position_in_array (priv->objects, comp_data));
}
}
static void
-query_obj_removed_cb (CalQuery *query, const char *uid, gpointer user_data)
+query_objects_removed_cb (CalQuery *query, GList *uids, gpointer user_data)
{
- ECalModelComponent *comp_data;
ECalModelPrivate *priv;
ECalModel *model = (ECalModel *) user_data;
-
- g_return_if_fail (E_IS_CAL_MODEL (model));
-
+ GList *l;
+
priv = model->priv;
- e_table_model_pre_change (E_TABLE_MODEL (model));
-
- comp_data = search_by_uid_and_client (priv, cal_query_get_client (query), uid);
- if (comp_data) {
- gint pos = get_position_in_array (priv->objects, comp_data);
+ for (l = uids; l; l = l->next) {
+ ECalModelComponent *comp_data;
+ int pos;
+ e_table_model_pre_change (E_TABLE_MODEL (model));
+
+ comp_data = search_by_uid_and_client (priv, cal_query_get_client (query), l->data);
+ g_assert (comp_data);
+
+ pos = get_position_in_array (priv->objects, comp_data);
+
g_ptr_array_remove (priv->objects, comp_data);
free_comp_data (comp_data);
-
+
e_table_model_row_deleted (E_TABLE_MODEL (model), pos);
- } else
- e_table_model_no_change (E_TABLE_MODEL (model));
+ }
}
static void
-query_done_cb (CalQuery *query, CalQueryDoneStatus status, const char *error_str, gpointer user_data)
+query_progress_cb (CalQuery *query, const char *message, int percent, gpointer user_data)
{
ECalModel *model = (ECalModel *) user_data;
g_return_if_fail (E_IS_CAL_MODEL (model));
- if (status != CAL_QUERY_DONE_SUCCESS)
- g_warning ("query done: %s\n", error_str);
+ /* FIXME Update status bar */
}
static void
-query_eval_error_cb (CalQuery *query, const char *error_str, gpointer user_data)
+query_done_cb (CalQuery *query, ECalendarStatus status, gpointer user_data)
{
- ECalModel *model = (ECalModel *) user_data;
+ ECalModel *model = (ECalModel *) user_data;
g_return_if_fail (E_IS_CAL_MODEL (model));
- g_warning ("eval error: %s\n", error_str);
+ /* FIXME Clear status bar */
}
/* Builds a complete query sexp for the calendar model by adding the predicates
@@ -1248,24 +1283,28 @@ update_query_for_client (ECalModel *model, ECalModelClient *client_data)
g_signal_handlers_disconnect_matched (client_data->query, G_SIGNAL_MATCH_DATA,
0, 0, NULL, NULL, model);
g_object_unref (client_data->query);
+ client_data->query = NULL;
}
/* prepare the query */
g_assert (priv->sexp != NULL);
real_sexp = adjust_query_sexp (model, priv->sexp);
- client_data->query = cal_client_get_query (client_data->client, real_sexp);
- g_free (real_sexp);
+ if (!cal_client_get_query (client_data->client, real_sexp, &client_data->query, NULL)) {
+ g_warning (G_STRLOC ": Unable to get query");
+ g_free (real_sexp);
- if (!client_data->query) {
- g_message ("update_query_for_client(): Could not create the query");
return;
- }
+ }
+ g_free (real_sexp);
- g_signal_connect (client_data->query, "obj_updated", G_CALLBACK (query_obj_updated_cb), model);
- g_signal_connect (client_data->query, "obj_removed", G_CALLBACK (query_obj_removed_cb), model);
+ g_signal_connect (client_data->query, "objects_added", G_CALLBACK (query_objects_added_cb), model);
+ g_signal_connect (client_data->query, "objects_modified", G_CALLBACK (query_objects_modified_cb), model);
+ g_signal_connect (client_data->query, "objects_removed", G_CALLBACK (query_objects_removed_cb), model);
+ g_signal_connect (client_data->query, "query_progress", G_CALLBACK (query_progress_cb), model);
g_signal_connect (client_data->query, "query_done", G_CALLBACK (query_done_cb), model);
- g_signal_connect (client_data->query, "eval_error", G_CALLBACK (query_eval_error_cb), model);
+
+ cal_query_start (client_data->query);
}
static void
@@ -1465,9 +1504,22 @@ e_cal_model_create_component_with_defaults (ECalModel *model)
return NULL;
}
+ if (!comp)
+ return icalcomponent_new (priv->kind);
+
icalcomp = icalcomponent_new_clone (cal_component_get_icalcomponent (comp));
g_object_unref (comp);
+ /* make sure the component has an UID */
+ if (!icalcomponent_get_uid (icalcomp)) {
+ char *uid;
+
+ uid = cal_component_gen_uid ();
+ icalcomponent_set_uid (icalcomp, uid);
+
+ g_free (uid);
+ }
+
return icalcomp;
}
diff --git a/calendar/gui/e-cal-model.h b/calendar/gui/e-cal-model.h
index ec8ab36c44..9c673ca439 100644
--- a/calendar/gui/e-cal-model.h
+++ b/calendar/gui/e-cal-model.h
@@ -88,7 +88,9 @@ void e_cal_model_set_default_category (ECalModel *model, const gc
void e_cal_model_set_use_24_hour_format (ECalModel *model, gboolean use24);
CalClient *e_cal_model_get_default_client (ECalModel *model);
+void e_cal_model_set_default_client (ECalModel *model, CalClient *client);
GList *e_cal_model_get_client_list (ECalModel *model);
+CalClient *e_cal_model_get_client_for_uri (ECalModel *model, const char *uri);
void e_cal_model_add_client (ECalModel *model, CalClient *client);
void e_cal_model_remove_client (ECalModel *model, CalClient *client);
void e_cal_model_remove_all_clients (ECalModel *model);
diff --git a/calendar/gui/e-cal-view.c b/calendar/gui/e-cal-view.c
index 381dca2542..869c8001a3 100644
--- a/calendar/gui/e-cal-view.c
+++ b/calendar/gui/e-cal-view.c
@@ -37,9 +37,11 @@
#include "comp-util.h"
#include "e-cal-model-calendar.h"
#include "e-cal-view.h"
+#include "e-comp-editor-registry.h"
#include "itip-utils.h"
#include "dialogs/delete-comp.h"
#include "dialogs/delete-error.h"
+#include "dialogs/event-editor.h"
#include "dialogs/send-comp.h"
#include "dialogs/cancel-comp.h"
#include "dialogs/recur-comp.h"
@@ -70,15 +72,28 @@ struct _ECalViewPrivate {
/* The timezone. */
icaltimezone *zone;
+
+ /* The default category */
+ char *default_category;
};
static void e_cal_view_class_init (ECalViewClass *klass);
static void e_cal_view_init (ECalView *cal_view, ECalViewClass *klass);
+static void e_cal_view_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
+static void e_cal_view_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
static void e_cal_view_destroy (GtkObject *object);
static GObjectClass *parent_class = NULL;
static GdkAtom clipboard_atom = GDK_NONE;
+extern ECompEditorRegistry *comp_editor_registry;
+
+/* Property IDs */
+enum props {
+ PROP_0,
+ PROP_MODEL,
+};
+/* FIXME Why are we emitting these event signals here? Can't the model just be listened to? */
/* Signal IDs */
enum {
SELECTION_CHANGED,
@@ -91,12 +106,71 @@ enum {
static guint e_cal_view_signals[LAST_SIGNAL] = { 0 };
static void
+e_cal_view_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+ ECalView *cal_view;
+ ECalViewPrivate *priv;
+
+ cal_view = E_CAL_VIEW (object);
+ priv = cal_view->priv;
+
+ switch (property_id) {
+ case PROP_MODEL:
+ e_cal_view_set_model (cal_view, E_CAL_MODEL (g_value_get_object (value)));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+e_cal_view_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+ ECalView *cal_view;
+ ECalViewPrivate *priv;
+
+ cal_view = E_CAL_VIEW (object);
+ priv = cal_view->priv;
+
+ switch (property_id) {
+ case PROP_MODEL:
+ g_value_set_object (value, e_cal_view_get_model (cal_view));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
e_cal_view_class_init (ECalViewClass *klass)
{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
+ /* Method override */
+ gobject_class->set_property = e_cal_view_set_property;
+ gobject_class->get_property = e_cal_view_get_property;
+ object_class->destroy = e_cal_view_destroy;
+
+ klass->selection_changed = NULL;
+ klass->event_changed = NULL;
+ klass->event_added = NULL;
+
+ klass->get_selected_events = NULL;
+ klass->get_selected_time_range = NULL;
+ klass->set_selected_time_range = NULL;
+ klass->get_visible_time_range = NULL;
+ klass->update_query = NULL;
+
+ g_object_class_install_property (gobject_class, PROP_MODEL,
+ g_param_spec_object ("model", NULL, NULL, E_TYPE_CAL_MODEL,
+ G_PARAM_READABLE | G_PARAM_WRITABLE
+ | G_PARAM_CONSTRUCT));
+
/* Create class' signals */
e_cal_view_signals[SELECTION_CHANGED] =
g_signal_new ("selection_changed",
@@ -135,19 +209,6 @@ e_cal_view_class_init (ECalViewClass *klass)
G_TYPE_NONE, 1,
G_TYPE_POINTER);
- /* Method override */
- object_class->destroy = e_cal_view_destroy;
-
- klass->selection_changed = NULL;
- klass->event_changed = NULL;
- klass->event_added = NULL;
-
- klass->get_selected_events = NULL;
- klass->get_selected_time_range = NULL;
- klass->set_selected_time_range = NULL;
- klass->get_visible_time_range = NULL;
- klass->update_query = NULL;
-
/* clipboard atom */
if (!clipboard_atom)
clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
@@ -208,6 +269,45 @@ selection_clear_event (GtkWidget *invisible,
}
static void
+selection_received_add_event (ECalView *cal_view, CalClient *client, time_t selected_time_start,
+ icaltimezone *default_zone, icalcomponent *icalcomp)
+{
+ CalComponent *comp;
+ struct icaltimetype itime;
+ time_t tt_start, tt_end;
+ struct icaldurationtype ic_dur;
+ char *uid;
+
+ tt_start = icaltime_as_timet (icalcomponent_get_dtstart (icalcomp));
+ tt_end = icaltime_as_timet (icalcomponent_get_dtend (icalcomp));
+ ic_dur = icaldurationtype_from_int (tt_end - tt_start);
+ itime = icaltime_from_timet_with_zone (selected_time_start, FALSE, default_zone);
+
+ icalcomponent_set_dtstart (icalcomp, itime);
+ itime = icaltime_add (itime, ic_dur);
+ icalcomponent_set_dtend (icalcomp, itime);
+
+ /* FIXME The new uid stuff can go away once we actually set it in the backend */
+ uid = cal_component_gen_uid ();
+ comp = cal_component_new ();
+ cal_component_set_icalcomponent (
+ comp, icalcomponent_new_clone (icalcomp));
+ cal_component_set_uid (comp, uid);
+
+ /* FIXME Error handling */
+ cal_client_create_object (client, cal_component_get_icalcomponent (comp), NULL, NULL);
+ if (itip_organizer_is_user (comp, client) &&
+ send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)),
+ client, comp, TRUE)) {
+ itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
+ client, NULL);
+ }
+
+ free (uid);
+ g_object_unref (comp);
+}
+
+static void
selection_received (GtkWidget *invisible,
GtkSelectionData *selection_data,
guint time,
@@ -216,12 +316,7 @@ selection_received (GtkWidget *invisible,
char *comp_str, *default_tzid;
icalcomponent *icalcomp;
icalcomponent_kind kind;
- CalComponent *comp;
time_t selected_time_start, selected_time_end;
- struct icaltimetype itime;
- time_t tt_start, tt_end;
- struct icaldurationtype ic_dur;
- char *uid;
icaltimezone *default_zone;
CalClient *client;
@@ -238,21 +333,21 @@ selection_received (GtkWidget *invisible,
return;
default_tzid = calendar_config_get_timezone ();
+
client = e_cal_model_get_default_client (cal_view->priv->model);
- cal_client_get_timezone (client, default_tzid, &default_zone);
+ /* FIXME Error checking */
+ cal_client_get_timezone (client, default_tzid, &default_zone, NULL);
/* check the type of the component */
+ /* FIXME An error dialog if we return? */
kind = icalcomponent_isa (icalcomp);
- if (kind != ICAL_VCALENDAR_COMPONENT &&
- kind != ICAL_VEVENT_COMPONENT &&
- kind != ICAL_VTODO_COMPONENT &&
- kind != ICAL_VJOURNAL_COMPONENT) {
+ if (kind != ICAL_VCALENDAR_COMPONENT && kind != ICAL_VEVENT_COMPONENT)
return;
- }
e_cal_view_set_status_message (cal_view, _("Updating objects"));
e_cal_view_get_selected_time_range (cal_view, &selected_time_start, &selected_time_end);
+ /* FIXME Timezone handling */
if (kind == ICAL_VCALENDAR_COMPONENT) {
icalcomponent_kind child_kind;
icalcomponent *subcomp;
@@ -260,69 +355,27 @@ selection_received (GtkWidget *invisible,
subcomp = icalcomponent_get_first_component (icalcomp, ICAL_ANY_COMPONENT);
while (subcomp) {
child_kind = icalcomponent_isa (subcomp);
- if (child_kind == ICAL_VEVENT_COMPONENT ||
- child_kind == ICAL_VTODO_COMPONENT ||
- child_kind == ICAL_VJOURNAL_COMPONENT) {
- tt_start = icaltime_as_timet (icalcomponent_get_dtstart (subcomp));
- tt_end = icaltime_as_timet (icalcomponent_get_dtend (subcomp));
- ic_dur = icaldurationtype_from_int (tt_end - tt_start);
- itime = icaltime_from_timet_with_zone (selected_time_start,
- FALSE, default_zone);
-
- icalcomponent_set_dtstart (subcomp, itime);
- itime = icaltime_add (itime, ic_dur);
- icalcomponent_set_dtend (subcomp, itime);
-
- uid = cal_component_gen_uid ();
- comp = cal_component_new ();
- cal_component_set_icalcomponent (
- comp, icalcomponent_new_clone (subcomp));
- cal_component_set_uid (comp, uid);
-
- cal_client_update_object (client, comp);
- if (itip_organizer_is_user (comp, client) &&
- send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)),
- client, comp, TRUE)) {
- itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
- client, NULL);
- }
-
- free (uid);
- g_object_unref (comp);
+ if (child_kind == ICAL_VEVENT_COMPONENT)
+ selection_received_add_event (cal_view, client, selected_time_start,
+ default_zone, subcomp);
+ else if (child_kind == ICAL_VTIMEZONE_COMPONENT) {
+ icaltimezone *zone;
+
+ zone = icaltimezone_new ();
+ icaltimezone_set_component (zone, subcomp);
+ cal_client_add_timezone (client, zone, NULL);
+
+ icaltimezone_free (zone, 1);
}
+
subcomp = icalcomponent_get_next_component (
icalcomp, ICAL_ANY_COMPONENT);
}
icalcomponent_free (icalcomp);
- }
- else {
- tt_start = icaltime_as_timet (icalcomponent_get_dtstart (icalcomp));
- tt_end = icaltime_as_timet (icalcomponent_get_dtend (icalcomp));
- ic_dur = icaldurationtype_from_int (tt_end - tt_start);
- itime = icaltime_from_timet_with_zone (selected_time_start, FALSE, default_zone);
-
- icalcomponent_set_dtstart (icalcomp, itime);
- itime = icaltime_add (itime, ic_dur);
- icalcomponent_set_dtend (icalcomp, itime);
-
- uid = cal_component_gen_uid ();
- comp = cal_component_new ();
- cal_component_set_icalcomponent (
- comp, icalcomponent_new_clone (icalcomp));
- cal_component_set_uid (comp, uid);
-
- cal_client_update_object (client, comp);
- if (itip_organizer_is_user (comp, client) &&
- send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)),
- client, comp, TRUE)) {
- itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
- client, NULL);
- }
-
- free (uid);
- g_object_unref (comp);
+ } else {
+ selection_received_add_event (cal_view, client, selected_time_start, default_zone, icalcomp);
}
e_cal_view_set_status_message (cal_view, NULL);
@@ -334,6 +387,14 @@ e_cal_view_init (ECalView *cal_view, ECalViewClass *klass)
cal_view->priv = g_new0 (ECalViewPrivate, 1);
cal_view->priv->model = (ECalModel *) e_cal_model_calendar_new ();
+ g_signal_connect (G_OBJECT (cal_view->priv->model), "model_changed",
+ G_CALLBACK (model_changed_cb), cal_view);
+ g_signal_connect (G_OBJECT (cal_view->priv->model), "model_row_changed",
+ G_CALLBACK (model_row_changed_cb), cal_view);
+ g_signal_connect (G_OBJECT (cal_view->priv->model), "model_rows_inserted",
+ G_CALLBACK (model_rows_changed_cb), cal_view);
+ g_signal_connect (G_OBJECT (cal_view->priv->model), "model_rows_deleted",
+ G_CALLBACK (model_rows_changed_cb), cal_view);
/* Set up the invisible widget for the clipboard selections */
cal_view->priv->invisible = gtk_invisible_new ();
@@ -380,6 +441,11 @@ e_cal_view_destroy (GtkObject *object)
cal_view->priv->clipboard_selection = NULL;
}
+ if (cal_view->priv->default_category) {
+ g_free (cal_view->priv->default_category);
+ cal_view->priv->default_category = NULL;
+ }
+
g_free (cal_view->priv);
cal_view->priv = NULL;
}
@@ -460,11 +526,35 @@ e_cal_view_set_timezone (ECalView *cal_view, icaltimezone *zone)
old_zone, cal_view->priv->zone);
}
+const char *
+e_cal_view_get_default_category (ECalView *cal_view)
+{
+ g_return_val_if_fail (E_IS_CAL_VIEW (cal_view), NULL);
+ return (const char *) cal_view->priv->default_category;
+}
+
+/**
+ * e_cal_view_set_default_category
+ * @cal_view: A calendar view.
+ * @category: Default category name or NULL for no category.
+ *
+ * Sets the default category that will be used when creating new calendar
+ * components from the given calendar view.
+ */
void
-e_cal_view_set_status_message (ECalView *cal_view, const gchar *message)
+e_cal_view_set_default_category (ECalView *cal_view, const char *category)
{
- extern EvolutionShellClient *global_shell_client; /* ugly */
+ g_return_if_fail (E_IS_CAL_VIEW (cal_view));
+
+ if (cal_view->priv->default_category)
+ g_free (cal_view->priv->default_category);
+
+ cal_view->priv->default_category = g_strdup (category);
+}
+void
+e_cal_view_set_status_message (ECalView *cal_view, const gchar *message)
+{
g_return_if_fail (E_IS_CAL_VIEW (cal_view));
if (!message || !*message) {
@@ -473,14 +563,19 @@ e_cal_view_set_status_message (ECalView *cal_view, const gchar *message)
cal_view->priv->activity = NULL;
}
} else if (!cal_view->priv->activity) {
+#if 0
int display;
+#endif
char *client_id = g_strdup_printf ("%p", cal_view);
if (progress_icon[0] == NULL)
progress_icon[0] = gdk_pixbuf_new_from_file (EVOLUTION_IMAGESDIR "/" EVOLUTION_CALENDAR_PROGRESS_IMAGE, NULL);
+
+#if 0
cal_view->priv->activity = evolution_activity_client_new (
global_shell_client, client_id,
progress_icon, message, TRUE, &display);
+#endif
g_free (client_id);
} else
@@ -564,9 +659,9 @@ e_cal_view_cut_clipboard (ECalView *cal_view)
e_cal_view_copy_clipboard (cal_view);
for (l = selected; l != NULL; l = l->next) {
CalComponent *comp;
-
ECalViewEvent *event = (ECalViewEvent *) l->data;
-
+ GError *error = NULL;
+
if (!event)
continue;
@@ -580,9 +675,11 @@ e_cal_view_cut_clipboard (ECalView *cal_view)
event->comp_data->client, NULL);
cal_component_get_uid (comp, &uid);
- delete_error_dialog (cal_client_remove_object (event->comp_data->client, uid),
- CAL_COMPONENT_EVENT);
+ cal_client_remove_object (event->comp_data->client, uid, &error);
+ delete_error_dialog (error, CAL_COMPONENT_EVENT);
+ g_clear_error (&error);
+
g_object_unref (comp);
}
@@ -657,7 +754,8 @@ delete_event (ECalView *cal_view, ECalViewEvent *event)
if (delete_component_dialog (comp, FALSE, 1, vtype, GTK_WIDGET (cal_view))) {
const char *uid;
-
+ GError *error = NULL;
+
if (itip_organizer_is_user (comp, event->comp_data->client)
&& cancel_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)),
event->comp_data->client,
@@ -670,9 +768,10 @@ delete_event (ECalView *cal_view, ECalViewEvent *event)
g_object_unref (comp);
return;
}
-
- delete_error_dialog (
- cal_client_remove_object (event->comp_data->client, uid), CAL_COMPONENT_EVENT);
+
+ cal_client_remove_object (event->comp_data->client, uid, &error);
+ delete_error_dialog (error, CAL_COMPONENT_EVENT);
+ g_clear_error (&error);
}
g_object_unref (comp);
@@ -719,35 +818,21 @@ e_cal_view_delete_selected_occurrence (ECalView *cal_view)
{
ECalViewEvent *event;
GList *selected;
-
+ const char *uid;
+ GError *error = NULL;
+
selected = e_cal_view_get_selected_events (cal_view);
if (!selected)
return;
event = (ECalViewEvent *) selected->data;
- if (cal_util_component_is_instance (event->comp_data->icalcomp)) {
- const char *uid;
-
- uid = icalcomponent_get_uid (event->comp_data->icalcomp);
- delete_error_dialog (
- cal_client_remove_object_with_mod (event->comp_data->client, uid, CALOBJ_MOD_THIS),
- CAL_COMPONENT_EVENT);
- } else {
- CalComponent *comp;
+ uid = icalcomponent_get_uid (event->comp_data->icalcomp);
+ /* FIXME: use 'rid' argument */
+ cal_client_remove_object_with_mod (event->comp_data->client, uid, NULL, CALOBJ_MOD_THIS, &error);
- /* we must duplicate the CalComponent, or we won't know it has changed
- when we get the "update_event" signal */
- comp = cal_component_new ();
- cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp));
- cal_comp_util_add_exdate (comp, event->start, cal_view->priv->zone);
-
- if (cal_client_update_object (event->comp_data->client, comp)
- != CAL_CLIENT_RESULT_SUCCESS)
- g_message ("e_cal_view_delete_selected_occurrence(): Could not update the object!");
-
- g_object_unref (comp);
- }
+ delete_error_dialog (error, CAL_COMPONENT_EVENT);
+ g_clear_error (&error);
/* free memory */
g_list_free (selected);
@@ -756,11 +841,9 @@ e_cal_view_delete_selected_occurrence (ECalView *cal_view)
static void
on_new_appointment (GtkWidget *widget, gpointer user_data)
{
- time_t dtstart, dtend;
ECalView *cal_view = (ECalView *) user_data;
- e_cal_view_get_selected_time_range (cal_view, &dtstart, &dtend);
- gnome_calendar_new_appointment_for (cal_view->priv->calendar, dtstart, dtend, FALSE, FALSE);
+ e_cal_view_new_appointment (cal_view);
}
static void
@@ -770,7 +853,7 @@ on_new_event (GtkWidget *widget, gpointer user_data)
ECalView *cal_view = (ECalView *) user_data;
e_cal_view_get_selected_time_range (cal_view, &dtstart, &dtend);
- gnome_calendar_new_appointment_for (cal_view->priv->calendar, dtstart, dtend, TRUE, FALSE);
+ e_cal_view_new_appointment_for (cal_view, dtstart, dtend, TRUE, FALSE);
}
static void
@@ -780,7 +863,7 @@ on_new_meeting (GtkWidget *widget, gpointer user_data)
ECalView *cal_view = (ECalView *) user_data;
e_cal_view_get_selected_time_range (cal_view, &dtstart, &dtend);
- gnome_calendar_new_appointment_for (cal_view->priv->calendar, dtstart, dtend, FALSE, TRUE);
+ e_cal_view_new_appointment_for (cal_view, dtstart, dtend, FALSE, TRUE);
}
static void
@@ -817,8 +900,8 @@ on_edit_appointment (GtkWidget *widget, gpointer user_data)
ECalViewEvent *event = (ECalViewEvent *) selected->data;
if (event)
- gnome_calendar_edit_object (cal_view->priv->calendar, event->comp_data->client,
- event->comp_data->icalcomp, FALSE);
+ e_cal_view_edit_appointment (cal_view, event->comp_data->client,
+ event->comp_data->icalcomp, FALSE);
g_list_free (selected);
}
@@ -834,7 +917,7 @@ on_print (GtkWidget *widget, gpointer user_data)
cal_view = E_CAL_VIEW (user_data);
- gnome_calendar_get_current_time_range (cal_view->priv->calendar, &start, NULL);
+ e_cal_view_get_visible_time_range (cal_view, &start, NULL);
view_type = gnome_calendar_get_view (cal_view->priv->calendar);
switch (view_type) {
@@ -930,7 +1013,7 @@ on_meeting (GtkWidget *widget, gpointer user_data)
selected = e_cal_view_get_selected_events (cal_view);
if (selected) {
ECalViewEvent *event = (ECalViewEvent *) selected->data;
- gnome_calendar_edit_object (cal_view->priv->calendar, event->comp_data->client, event->comp_data->icalcomp, TRUE);
+ e_cal_view_edit_appointment (cal_view, event->comp_data->client, event->comp_data->icalcomp, TRUE);
g_list_free (selected);
}
@@ -962,7 +1045,7 @@ on_publish (GtkWidget *widget, gpointer user_data)
ECalView *cal_view;
icaltimezone *utc;
time_t start = time (NULL), end;
- GList *comp_list, *client_list, *cl;
+ GList *comp_list = NULL, *client_list, *cl;
cal_view = E_CAL_VIEW (user_data);
@@ -972,8 +1055,7 @@ on_publish (GtkWidget *widget, gpointer user_data)
client_list = e_cal_model_get_client_list (cal_view->priv->model);
for (cl = client_list; cl != NULL; cl = cl->next) {
- comp_list = cal_client_get_free_busy ((CalClient *) cl->data, NULL, start, end);
- if (comp_list) {
+ if (cal_client_get_free_busy ((CalClient *) cl->data, NULL, start, end, &comp_list, NULL)) {
GList *l;
for (l = comp_list; l; l = l->next) {
@@ -1041,14 +1123,6 @@ on_paste (GtkWidget *widget, gpointer user_data)
e_cal_view_paste_clipboard (cal_view);
}
-static void
-on_unrecur_appointment (GtkWidget *widget, gpointer user_data)
-{
- ECalView *cal_view = E_CAL_VIEW (user_data);
-
- gnome_calendar_unrecur_selection (cal_view->priv->calendar);
-}
-
enum {
/*
* This is used to "flag" events that can not be editted
@@ -1142,7 +1216,6 @@ static EPopupMenu child_items [] = {
E_POPUP_SEPARATOR,
E_POPUP_ITEM (N_("_Delete"), GTK_SIGNAL_FUNC (on_delete_appointment), MASK_EDITABLE | MASK_SINGLE | MASK_EDITING),
- E_POPUP_ITEM (N_("Make this Occurrence _Movable"), GTK_SIGNAL_FUNC (on_unrecur_appointment), MASK_RECURRING | MASK_EDITING | MASK_EDITABLE | MASK_INSTANCE),
E_POPUP_ITEM (N_("Delete this _Occurrence"), GTK_SIGNAL_FUNC (on_delete_occurrence), MASK_RECURRING | MASK_EDITING | MASK_EDITABLE),
E_POPUP_ITEM (N_("Delete _All Occurrences"), GTK_SIGNAL_FUNC (on_delete_appointment), MASK_RECURRING | MASK_EDITING | MASK_EDITABLE),
@@ -1209,21 +1282,18 @@ setup_popup_icons (EPopupMenu *context_menu)
GtkMenu *
e_cal_view_create_popup_menu (ECalView *cal_view)
{
- gboolean being_edited, have_selection;
GList *selected;
EPopupMenu *context_menu;
guint32 disable_mask = 0, hide_mask = 0;
GtkMenu *popup;
CalClient *client = NULL;
-
+ gboolean read_only = TRUE;
+
g_return_val_if_fail (E_IS_CAL_VIEW (cal_view), NULL);
/* get the selection */
- being_edited = FALSE;
selected = e_cal_view_get_selected_events (cal_view);
- have_selection = GTK_WIDGET_HAS_FOCUS (cal_view) && selected != NULL;
-
if (selected == NULL) {
cal_view->priv->view_menu = gnome_calendar_setup_view_popup (cal_view->priv->calendar);
main_items[9].submenu = cal_view->priv->view_menu;
@@ -1260,15 +1330,158 @@ e_cal_view_create_popup_menu (ECalView *cal_view)
client = event->comp_data->client;
}
- if (cal_client_is_read_only (client))
+ cal_client_is_read_only (client, &read_only, NULL);
+ if (read_only)
disable_mask |= MASK_EDITABLE;
- if (being_edited)
- disable_mask |= MASK_EDITING;
-
setup_popup_icons (context_menu);
popup = e_popup_menu_create (context_menu, disable_mask, hide_mask, cal_view);
g_signal_connect (popup, "selection-done", G_CALLBACK (free_view_popup), cal_view);
return popup;
}
+
+/**
+ * e_cal_view_new_appointment_for
+ * @cal_view: A calendar view.
+ * @dtstart: A Unix time_t that marks the beginning of the appointment.
+ * @dtend: A Unix time_t that marks the end of the appointment.
+ * @all_day: If TRUE, the dtstart and dtend are expanded to cover
+ * the entire day, and the event is set to TRANSPARENT.
+ * @meeting: Whether the appointment is a meeting or not.
+ *
+ * Opens an event editor dialog for a new appointment.
+ */
+void
+e_cal_view_new_appointment_for (ECalView *cal_view,
+ time_t dtstart, time_t dtend,
+ gboolean all_day,
+ gboolean meeting)
+{
+ ECalViewPrivate *priv;
+ struct icaltimetype itt;
+ CalComponentDateTime dt;
+ CalComponent *comp;
+ icalcomponent *icalcomp;
+ CalComponentTransparency transparency;
+
+ g_return_if_fail (E_IS_CAL_VIEW (cal_view));
+
+ priv = cal_view->priv;
+
+ dt.value = &itt;
+ if (all_day)
+ dt.tzid = NULL;
+ else
+ dt.tzid = icaltimezone_get_tzid (priv->zone);
+
+ icalcomp = e_cal_model_create_component_with_defaults (priv->model);
+ comp = cal_component_new ();
+ cal_component_set_icalcomponent (comp, icalcomp);
+
+ /* DTSTART, DTEND */
+ itt = icaltime_from_timet_with_zone (dtstart, FALSE, priv->zone);
+ if (all_day) {
+ itt.hour = itt.minute = itt.second = 0;
+ itt.is_date = TRUE;
+ }
+ cal_component_set_dtstart (comp, &dt);
+
+ itt = icaltime_from_timet_with_zone (dtend, FALSE, priv->zone);
+ if (all_day) {
+ /* We round it up to the end of the day, unless it is
+ already set to midnight */
+ if (itt.hour != 0 || itt.minute != 0 || itt.second != 0) {
+ icaltime_adjust (&itt, 1, 0, 0, 0);
+ }
+ itt.hour = itt.minute = itt.second = 0;
+ itt.is_date = TRUE;
+ }
+ cal_component_set_dtend (comp, &dt);
+
+ /* TRANSPARENCY */
+ transparency = all_day ? CAL_COMPONENT_TRANSP_TRANSPARENT
+ : CAL_COMPONENT_TRANSP_OPAQUE;
+ cal_component_set_transparency (comp, transparency);
+
+ /* CATEGORY */
+ cal_component_set_categories (comp, priv->default_category);
+
+ /* edit the object */
+ cal_component_commit_sequence (comp);
+
+ e_cal_view_edit_appointment (cal_view,
+ e_cal_model_get_default_client (priv->model),
+ icalcomp, meeting);
+
+ g_object_unref (comp);
+}
+
+/**
+ * e_cal_view_new_appointment
+ * @cal_view: A calendar view.
+ *
+ * Opens an event editor dialog for a new appointment. The appointment's
+ * start and end times are set to the currently selected time range in
+ * the calendar view.
+ */
+void
+e_cal_view_new_appointment (ECalView *cal_view)
+{
+ time_t dtstart, dtend;
+
+ g_return_if_fail (E_IS_CAL_VIEW (cal_view));
+
+ e_cal_view_get_selected_time_range (cal_view, &dtstart, &dtend);
+ e_cal_view_new_appointment_for (cal_view, dtstart, dtend, FALSE, FALSE);
+}
+
+/**
+ * e_cal_view_edit_appointment
+ * @cal_view: A calendar view.
+ * @client: Calendar client.
+ * @icalcomp: The object to be edited.
+ * @meeting: Whether the appointment is a meeting or not.
+ *
+ * Opens an editor window to allow the user to edit the selected
+ * object.
+ */
+void
+e_cal_view_edit_appointment (ECalView *cal_view,
+ CalClient *client,
+ icalcomponent *icalcomp,
+ gboolean meeting)
+{
+ ECalViewPrivate *priv;
+ CompEditor *ce;
+ const char *uid;
+ CalComponent *comp;
+
+ g_return_if_fail (E_IS_CAL_VIEW (cal_view));
+ g_return_if_fail (IS_CAL_CLIENT (client));
+ g_return_if_fail (icalcomp != NULL);
+
+ priv = cal_view->priv;
+
+ uid = icalcomponent_get_uid (icalcomp);
+
+ ce = e_comp_editor_registry_find (comp_editor_registry, uid);
+ if (!ce) {
+ EventEditor *ee;
+
+ ee = event_editor_new (client);
+ ce = COMP_EDITOR (ee);
+
+ comp = cal_component_new ();
+ cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp));
+ comp_editor_edit_comp (ce, comp);
+ if (meeting)
+ event_editor_show_meeting (ee);
+
+ e_comp_editor_registry_add (comp_editor_registry, ce, FALSE);
+
+ g_object_unref (comp);
+ }
+
+ comp_editor_focus (ce);
+}
diff --git a/calendar/gui/e-cal-view.h b/calendar/gui/e-cal-view.h
index ea7c11a00d..9a09a5236a 100644
--- a/calendar/gui/e-cal-view.h
+++ b/calendar/gui/e-cal-view.h
@@ -96,6 +96,8 @@ ECalModel *e_cal_view_get_model (ECalView *cal_view);
void e_cal_view_set_model (ECalView *cal_view, ECalModel *model);
icaltimezone *e_cal_view_get_timezone (ECalView *cal_view);
void e_cal_view_set_timezone (ECalView *cal_view, icaltimezone *zone);
+const char *e_cal_view_get_default_category (ECalView *cal_view);
+void e_cal_view_set_default_category (ECalView *cal_view, const char *category);
void e_cal_view_set_status_message (ECalView *cal_view, const gchar *message);
@@ -114,6 +116,17 @@ void e_cal_view_delete_selected_occurrence (ECalView *cal_view);
GtkMenu *e_cal_view_create_popup_menu (ECalView *cal_view);
+void e_cal_view_new_appointment_for (ECalView *cal_view,
+ time_t dtstart,
+ time_t dtend,
+ gboolean all_day,
+ gboolean meeting);
+void e_cal_view_new_appointment (ECalView *cal_view);
+void e_cal_view_edit_appointment (ECalView *cal_view,
+ CalClient *client,
+ icalcomponent *icalcomp,
+ gboolean meeting);
+
G_END_DECLS
#endif
diff --git a/calendar/gui/e-calendar-table.c b/calendar/gui/e-calendar-table.c
index 5b3f98f373..fdea4d33bb 100644
--- a/calendar/gui/e-calendar-table.c
+++ b/calendar/gui/e-calendar-table.c
@@ -725,10 +725,12 @@ delete_selected_components (ECalendarTable *cal_table)
for (l = objs; l; l = l->next) {
ECalModelComponent *comp_data = (ECalModelComponent *) l->data;
-
- delete_error_dialog (cal_client_remove_object (comp_data->client,
- icalcomponent_get_uid (comp_data->icalcomp)),
- CAL_COMPONENT_TODO);
+ GError *error = NULL;
+
+ cal_client_remove_object (comp_data->client,
+ icalcomponent_get_uid (comp_data->icalcomp), &error);
+ delete_error_dialog (error, CAL_COMPONENT_TODO);
+ g_clear_error (&error);
}
e_calendar_table_set_status_message (cal_table, NULL);
@@ -1052,7 +1054,8 @@ e_calendar_table_show_popup_menu (ETable *table,
GtkMenu *gtk_menu;
icalproperty *prop;
ECalModelComponent *comp_data;
-
+ gboolean read_only = TRUE;
+
n_selected = e_table_selected_count (table);
if (n_selected <= 0)
return TRUE;
@@ -1071,7 +1074,8 @@ e_calendar_table_show_popup_menu (ETable *table,
} else
hide_mask = MASK_SINGLE;
- if (cal_client_is_read_only (comp_data->client))
+ cal_client_is_read_only (comp_data->client, &read_only, NULL);
+ if (!read_only)
disable_mask |= MASK_EDITABLE;
if (cal_client_get_static_capability (comp_data->client, CAL_STATIC_CAPABILITY_NO_TASK_ASSIGNMENT))
@@ -1315,6 +1319,7 @@ selection_received (GtkWidget *invisible,
icalcomponent *icalcomp;
char *uid;
CalComponent *comp;
+ CalClient *client;
icalcomponent_kind kind;
g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
@@ -1338,6 +1343,8 @@ selection_received (GtkWidget *invisible,
return;
}
+ client = e_cal_model_get_default_client (cal_table->model);
+
e_calendar_table_set_status_message (cal_table, _("Updating objects"));
if (kind == ICAL_VCALENDAR_COMPONENT) {
@@ -1360,11 +1367,12 @@ selection_received (GtkWidget *invisible,
cal_component_set_icalcomponent (
tmp_comp, icalcomponent_new_clone (subcomp));
cal_component_set_uid (tmp_comp, uid);
-
- cal_client_update_object (
- e_cal_model_get_default_client (cal_table->model),
- tmp_comp);
free (uid);
+
+ /* FIXME should we convert start/due/complete times? */
+ /* FIXME Error handling */
+ cal_client_create_object (client, cal_component_get_icalcomponent (tmp_comp), NULL, NULL);
+
g_object_unref (tmp_comp);
}
subcomp = icalcomponent_get_next_component (
@@ -1378,9 +1386,8 @@ selection_received (GtkWidget *invisible,
cal_component_set_uid (comp, (const char *) uid);
free (uid);
- cal_client_update_object (
- e_cal_model_get_default_client (cal_table->model),
- comp);
+ cal_client_create_object (client, cal_component_get_icalcomponent (comp), NULL, NULL);
+
g_object_unref (comp);
}
@@ -1433,8 +1440,6 @@ static GdkPixbuf *progress_icon[2] = { NULL, NULL };
void
e_calendar_table_set_status_message (ECalendarTable *cal_table, const gchar *message)
{
- extern EvolutionShellClient *global_shell_client; /* ugly */
-
g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
if (!message || !*message) {
@@ -1448,9 +1453,12 @@ e_calendar_table_set_status_message (ECalendarTable *cal_table, const gchar *mes
if (progress_icon[0] == NULL)
progress_icon[0] = gdk_pixbuf_new_from_file (EVOLUTION_IMAGESDIR "/" EVOLUTION_TASKS_PROGRESS_IMAGE, NULL);
+
+#if 0 /* EPFIXME */
cal_table->activity = evolution_activity_client_new (
global_shell_client, client_id,
progress_icon, message, TRUE, &display);
+#endif
g_free (client_id);
} else
diff --git a/calendar/gui/e-calendar-view.c b/calendar/gui/e-calendar-view.c
index 381dca2542..869c8001a3 100644
--- a/calendar/gui/e-calendar-view.c
+++ b/calendar/gui/e-calendar-view.c
@@ -37,9 +37,11 @@
#include "comp-util.h"
#include "e-cal-model-calendar.h"
#include "e-cal-view.h"
+#include "e-comp-editor-registry.h"
#include "itip-utils.h"
#include "dialogs/delete-comp.h"
#include "dialogs/delete-error.h"
+#include "dialogs/event-editor.h"
#include "dialogs/send-comp.h"
#include "dialogs/cancel-comp.h"
#include "dialogs/recur-comp.h"
@@ -70,15 +72,28 @@ struct _ECalViewPrivate {
/* The timezone. */
icaltimezone *zone;
+
+ /* The default category */
+ char *default_category;
};
static void e_cal_view_class_init (ECalViewClass *klass);
static void e_cal_view_init (ECalView *cal_view, ECalViewClass *klass);
+static void e_cal_view_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
+static void e_cal_view_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
static void e_cal_view_destroy (GtkObject *object);
static GObjectClass *parent_class = NULL;
static GdkAtom clipboard_atom = GDK_NONE;
+extern ECompEditorRegistry *comp_editor_registry;
+
+/* Property IDs */
+enum props {
+ PROP_0,
+ PROP_MODEL,
+};
+/* FIXME Why are we emitting these event signals here? Can't the model just be listened to? */
/* Signal IDs */
enum {
SELECTION_CHANGED,
@@ -91,12 +106,71 @@ enum {
static guint e_cal_view_signals[LAST_SIGNAL] = { 0 };
static void
+e_cal_view_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
+{
+ ECalView *cal_view;
+ ECalViewPrivate *priv;
+
+ cal_view = E_CAL_VIEW (object);
+ priv = cal_view->priv;
+
+ switch (property_id) {
+ case PROP_MODEL:
+ e_cal_view_set_model (cal_view, E_CAL_MODEL (g_value_get_object (value)));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+e_cal_view_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
+{
+ ECalView *cal_view;
+ ECalViewPrivate *priv;
+
+ cal_view = E_CAL_VIEW (object);
+ priv = cal_view->priv;
+
+ switch (property_id) {
+ case PROP_MODEL:
+ g_value_set_object (value, e_cal_view_get_model (cal_view));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
e_cal_view_class_init (ECalViewClass *klass)
{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
+ /* Method override */
+ gobject_class->set_property = e_cal_view_set_property;
+ gobject_class->get_property = e_cal_view_get_property;
+ object_class->destroy = e_cal_view_destroy;
+
+ klass->selection_changed = NULL;
+ klass->event_changed = NULL;
+ klass->event_added = NULL;
+
+ klass->get_selected_events = NULL;
+ klass->get_selected_time_range = NULL;
+ klass->set_selected_time_range = NULL;
+ klass->get_visible_time_range = NULL;
+ klass->update_query = NULL;
+
+ g_object_class_install_property (gobject_class, PROP_MODEL,
+ g_param_spec_object ("model", NULL, NULL, E_TYPE_CAL_MODEL,
+ G_PARAM_READABLE | G_PARAM_WRITABLE
+ | G_PARAM_CONSTRUCT));
+
/* Create class' signals */
e_cal_view_signals[SELECTION_CHANGED] =
g_signal_new ("selection_changed",
@@ -135,19 +209,6 @@ e_cal_view_class_init (ECalViewClass *klass)
G_TYPE_NONE, 1,
G_TYPE_POINTER);
- /* Method override */
- object_class->destroy = e_cal_view_destroy;
-
- klass->selection_changed = NULL;
- klass->event_changed = NULL;
- klass->event_added = NULL;
-
- klass->get_selected_events = NULL;
- klass->get_selected_time_range = NULL;
- klass->set_selected_time_range = NULL;
- klass->get_visible_time_range = NULL;
- klass->update_query = NULL;
-
/* clipboard atom */
if (!clipboard_atom)
clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
@@ -208,6 +269,45 @@ selection_clear_event (GtkWidget *invisible,
}
static void
+selection_received_add_event (ECalView *cal_view, CalClient *client, time_t selected_time_start,
+ icaltimezone *default_zone, icalcomponent *icalcomp)
+{
+ CalComponent *comp;
+ struct icaltimetype itime;
+ time_t tt_start, tt_end;
+ struct icaldurationtype ic_dur;
+ char *uid;
+
+ tt_start = icaltime_as_timet (icalcomponent_get_dtstart (icalcomp));
+ tt_end = icaltime_as_timet (icalcomponent_get_dtend (icalcomp));
+ ic_dur = icaldurationtype_from_int (tt_end - tt_start);
+ itime = icaltime_from_timet_with_zone (selected_time_start, FALSE, default_zone);
+
+ icalcomponent_set_dtstart (icalcomp, itime);
+ itime = icaltime_add (itime, ic_dur);
+ icalcomponent_set_dtend (icalcomp, itime);
+
+ /* FIXME The new uid stuff can go away once we actually set it in the backend */
+ uid = cal_component_gen_uid ();
+ comp = cal_component_new ();
+ cal_component_set_icalcomponent (
+ comp, icalcomponent_new_clone (icalcomp));
+ cal_component_set_uid (comp, uid);
+
+ /* FIXME Error handling */
+ cal_client_create_object (client, cal_component_get_icalcomponent (comp), NULL, NULL);
+ if (itip_organizer_is_user (comp, client) &&
+ send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)),
+ client, comp, TRUE)) {
+ itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
+ client, NULL);
+ }
+
+ free (uid);
+ g_object_unref (comp);
+}
+
+static void
selection_received (GtkWidget *invisible,
GtkSelectionData *selection_data,
guint time,
@@ -216,12 +316,7 @@ selection_received (GtkWidget *invisible,
char *comp_str, *default_tzid;
icalcomponent *icalcomp;
icalcomponent_kind kind;
- CalComponent *comp;
time_t selected_time_start, selected_time_end;
- struct icaltimetype itime;
- time_t tt_start, tt_end;
- struct icaldurationtype ic_dur;
- char *uid;
icaltimezone *default_zone;
CalClient *client;
@@ -238,21 +333,21 @@ selection_received (GtkWidget *invisible,
return;
default_tzid = calendar_config_get_timezone ();
+
client = e_cal_model_get_default_client (cal_view->priv->model);
- cal_client_get_timezone (client, default_tzid, &default_zone);
+ /* FIXME Error checking */
+ cal_client_get_timezone (client, default_tzid, &default_zone, NULL);
/* check the type of the component */
+ /* FIXME An error dialog if we return? */
kind = icalcomponent_isa (icalcomp);
- if (kind != ICAL_VCALENDAR_COMPONENT &&
- kind != ICAL_VEVENT_COMPONENT &&
- kind != ICAL_VTODO_COMPONENT &&
- kind != ICAL_VJOURNAL_COMPONENT) {
+ if (kind != ICAL_VCALENDAR_COMPONENT && kind != ICAL_VEVENT_COMPONENT)
return;
- }
e_cal_view_set_status_message (cal_view, _("Updating objects"));
e_cal_view_get_selected_time_range (cal_view, &selected_time_start, &selected_time_end);
+ /* FIXME Timezone handling */
if (kind == ICAL_VCALENDAR_COMPONENT) {
icalcomponent_kind child_kind;
icalcomponent *subcomp;
@@ -260,69 +355,27 @@ selection_received (GtkWidget *invisible,
subcomp = icalcomponent_get_first_component (icalcomp, ICAL_ANY_COMPONENT);
while (subcomp) {
child_kind = icalcomponent_isa (subcomp);
- if (child_kind == ICAL_VEVENT_COMPONENT ||
- child_kind == ICAL_VTODO_COMPONENT ||
- child_kind == ICAL_VJOURNAL_COMPONENT) {
- tt_start = icaltime_as_timet (icalcomponent_get_dtstart (subcomp));
- tt_end = icaltime_as_timet (icalcomponent_get_dtend (subcomp));
- ic_dur = icaldurationtype_from_int (tt_end - tt_start);
- itime = icaltime_from_timet_with_zone (selected_time_start,
- FALSE, default_zone);
-
- icalcomponent_set_dtstart (subcomp, itime);
- itime = icaltime_add (itime, ic_dur);
- icalcomponent_set_dtend (subcomp, itime);
-
- uid = cal_component_gen_uid ();
- comp = cal_component_new ();
- cal_component_set_icalcomponent (
- comp, icalcomponent_new_clone (subcomp));
- cal_component_set_uid (comp, uid);
-
- cal_client_update_object (client, comp);
- if (itip_organizer_is_user (comp, client) &&
- send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)),
- client, comp, TRUE)) {
- itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
- client, NULL);
- }
-
- free (uid);
- g_object_unref (comp);
+ if (child_kind == ICAL_VEVENT_COMPONENT)
+ selection_received_add_event (cal_view, client, selected_time_start,
+ default_zone, subcomp);
+ else if (child_kind == ICAL_VTIMEZONE_COMPONENT) {
+ icaltimezone *zone;
+
+ zone = icaltimezone_new ();
+ icaltimezone_set_component (zone, subcomp);
+ cal_client_add_timezone (client, zone, NULL);
+
+ icaltimezone_free (zone, 1);
}
+
subcomp = icalcomponent_get_next_component (
icalcomp, ICAL_ANY_COMPONENT);
}
icalcomponent_free (icalcomp);
- }
- else {
- tt_start = icaltime_as_timet (icalcomponent_get_dtstart (icalcomp));
- tt_end = icaltime_as_timet (icalcomponent_get_dtend (icalcomp));
- ic_dur = icaldurationtype_from_int (tt_end - tt_start);
- itime = icaltime_from_timet_with_zone (selected_time_start, FALSE, default_zone);
-
- icalcomponent_set_dtstart (icalcomp, itime);
- itime = icaltime_add (itime, ic_dur);
- icalcomponent_set_dtend (icalcomp, itime);
-
- uid = cal_component_gen_uid ();
- comp = cal_component_new ();
- cal_component_set_icalcomponent (
- comp, icalcomponent_new_clone (icalcomp));
- cal_component_set_uid (comp, uid);
-
- cal_client_update_object (client, comp);
- if (itip_organizer_is_user (comp, client) &&
- send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)),
- client, comp, TRUE)) {
- itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
- client, NULL);
- }
-
- free (uid);
- g_object_unref (comp);
+ } else {
+ selection_received_add_event (cal_view, client, selected_time_start, default_zone, icalcomp);
}
e_cal_view_set_status_message (cal_view, NULL);
@@ -334,6 +387,14 @@ e_cal_view_init (ECalView *cal_view, ECalViewClass *klass)
cal_view->priv = g_new0 (ECalViewPrivate, 1);
cal_view->priv->model = (ECalModel *) e_cal_model_calendar_new ();
+ g_signal_connect (G_OBJECT (cal_view->priv->model), "model_changed",
+ G_CALLBACK (model_changed_cb), cal_view);
+ g_signal_connect (G_OBJECT (cal_view->priv->model), "model_row_changed",
+ G_CALLBACK (model_row_changed_cb), cal_view);
+ g_signal_connect (G_OBJECT (cal_view->priv->model), "model_rows_inserted",
+ G_CALLBACK (model_rows_changed_cb), cal_view);
+ g_signal_connect (G_OBJECT (cal_view->priv->model), "model_rows_deleted",
+ G_CALLBACK (model_rows_changed_cb), cal_view);
/* Set up the invisible widget for the clipboard selections */
cal_view->priv->invisible = gtk_invisible_new ();
@@ -380,6 +441,11 @@ e_cal_view_destroy (GtkObject *object)
cal_view->priv->clipboard_selection = NULL;
}
+ if (cal_view->priv->default_category) {
+ g_free (cal_view->priv->default_category);
+ cal_view->priv->default_category = NULL;
+ }
+
g_free (cal_view->priv);
cal_view->priv = NULL;
}
@@ -460,11 +526,35 @@ e_cal_view_set_timezone (ECalView *cal_view, icaltimezone *zone)
old_zone, cal_view->priv->zone);
}
+const char *
+e_cal_view_get_default_category (ECalView *cal_view)
+{
+ g_return_val_if_fail (E_IS_CAL_VIEW (cal_view), NULL);
+ return (const char *) cal_view->priv->default_category;
+}
+
+/**
+ * e_cal_view_set_default_category
+ * @cal_view: A calendar view.
+ * @category: Default category name or NULL for no category.
+ *
+ * Sets the default category that will be used when creating new calendar
+ * components from the given calendar view.
+ */
void
-e_cal_view_set_status_message (ECalView *cal_view, const gchar *message)
+e_cal_view_set_default_category (ECalView *cal_view, const char *category)
{
- extern EvolutionShellClient *global_shell_client; /* ugly */
+ g_return_if_fail (E_IS_CAL_VIEW (cal_view));
+
+ if (cal_view->priv->default_category)
+ g_free (cal_view->priv->default_category);
+
+ cal_view->priv->default_category = g_strdup (category);
+}
+void
+e_cal_view_set_status_message (ECalView *cal_view, const gchar *message)
+{
g_return_if_fail (E_IS_CAL_VIEW (cal_view));
if (!message || !*message) {
@@ -473,14 +563,19 @@ e_cal_view_set_status_message (ECalView *cal_view, const gchar *message)
cal_view->priv->activity = NULL;
}
} else if (!cal_view->priv->activity) {
+#if 0
int display;
+#endif
char *client_id = g_strdup_printf ("%p", cal_view);
if (progress_icon[0] == NULL)
progress_icon[0] = gdk_pixbuf_new_from_file (EVOLUTION_IMAGESDIR "/" EVOLUTION_CALENDAR_PROGRESS_IMAGE, NULL);
+
+#if 0
cal_view->priv->activity = evolution_activity_client_new (
global_shell_client, client_id,
progress_icon, message, TRUE, &display);
+#endif
g_free (client_id);
} else
@@ -564,9 +659,9 @@ e_cal_view_cut_clipboard (ECalView *cal_view)
e_cal_view_copy_clipboard (cal_view);
for (l = selected; l != NULL; l = l->next) {
CalComponent *comp;
-
ECalViewEvent *event = (ECalViewEvent *) l->data;
-
+ GError *error = NULL;
+
if (!event)
continue;
@@ -580,9 +675,11 @@ e_cal_view_cut_clipboard (ECalView *cal_view)
event->comp_data->client, NULL);
cal_component_get_uid (comp, &uid);
- delete_error_dialog (cal_client_remove_object (event->comp_data->client, uid),
- CAL_COMPONENT_EVENT);
+ cal_client_remove_object (event->comp_data->client, uid, &error);
+ delete_error_dialog (error, CAL_COMPONENT_EVENT);
+ g_clear_error (&error);
+
g_object_unref (comp);
}
@@ -657,7 +754,8 @@ delete_event (ECalView *cal_view, ECalViewEvent *event)
if (delete_component_dialog (comp, FALSE, 1, vtype, GTK_WIDGET (cal_view))) {
const char *uid;
-
+ GError *error = NULL;
+
if (itip_organizer_is_user (comp, event->comp_data->client)
&& cancel_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)),
event->comp_data->client,
@@ -670,9 +768,10 @@ delete_event (ECalView *cal_view, ECalViewEvent *event)
g_object_unref (comp);
return;
}
-
- delete_error_dialog (
- cal_client_remove_object (event->comp_data->client, uid), CAL_COMPONENT_EVENT);
+
+ cal_client_remove_object (event->comp_data->client, uid, &error);
+ delete_error_dialog (error, CAL_COMPONENT_EVENT);
+ g_clear_error (&error);
}
g_object_unref (comp);
@@ -719,35 +818,21 @@ e_cal_view_delete_selected_occurrence (ECalView *cal_view)
{
ECalViewEvent *event;
GList *selected;
-
+ const char *uid;
+ GError *error = NULL;
+
selected = e_cal_view_get_selected_events (cal_view);
if (!selected)
return;
event = (ECalViewEvent *) selected->data;
- if (cal_util_component_is_instance (event->comp_data->icalcomp)) {
- const char *uid;
-
- uid = icalcomponent_get_uid (event->comp_data->icalcomp);
- delete_error_dialog (
- cal_client_remove_object_with_mod (event->comp_data->client, uid, CALOBJ_MOD_THIS),
- CAL_COMPONENT_EVENT);
- } else {
- CalComponent *comp;
+ uid = icalcomponent_get_uid (event->comp_data->icalcomp);
+ /* FIXME: use 'rid' argument */
+ cal_client_remove_object_with_mod (event->comp_data->client, uid, NULL, CALOBJ_MOD_THIS, &error);
- /* we must duplicate the CalComponent, or we won't know it has changed
- when we get the "update_event" signal */
- comp = cal_component_new ();
- cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp));
- cal_comp_util_add_exdate (comp, event->start, cal_view->priv->zone);
-
- if (cal_client_update_object (event->comp_data->client, comp)
- != CAL_CLIENT_RESULT_SUCCESS)
- g_message ("e_cal_view_delete_selected_occurrence(): Could not update the object!");
-
- g_object_unref (comp);
- }
+ delete_error_dialog (error, CAL_COMPONENT_EVENT);
+ g_clear_error (&error);
/* free memory */
g_list_free (selected);
@@ -756,11 +841,9 @@ e_cal_view_delete_selected_occurrence (ECalView *cal_view)
static void
on_new_appointment (GtkWidget *widget, gpointer user_data)
{
- time_t dtstart, dtend;
ECalView *cal_view = (ECalView *) user_data;
- e_cal_view_get_selected_time_range (cal_view, &dtstart, &dtend);
- gnome_calendar_new_appointment_for (cal_view->priv->calendar, dtstart, dtend, FALSE, FALSE);
+ e_cal_view_new_appointment (cal_view);
}
static void
@@ -770,7 +853,7 @@ on_new_event (GtkWidget *widget, gpointer user_data)
ECalView *cal_view = (ECalView *) user_data;
e_cal_view_get_selected_time_range (cal_view, &dtstart, &dtend);
- gnome_calendar_new_appointment_for (cal_view->priv->calendar, dtstart, dtend, TRUE, FALSE);
+ e_cal_view_new_appointment_for (cal_view, dtstart, dtend, TRUE, FALSE);
}
static void
@@ -780,7 +863,7 @@ on_new_meeting (GtkWidget *widget, gpointer user_data)
ECalView *cal_view = (ECalView *) user_data;
e_cal_view_get_selected_time_range (cal_view, &dtstart, &dtend);
- gnome_calendar_new_appointment_for (cal_view->priv->calendar, dtstart, dtend, FALSE, TRUE);
+ e_cal_view_new_appointment_for (cal_view, dtstart, dtend, FALSE, TRUE);
}
static void
@@ -817,8 +900,8 @@ on_edit_appointment (GtkWidget *widget, gpointer user_data)
ECalViewEvent *event = (ECalViewEvent *) selected->data;
if (event)
- gnome_calendar_edit_object (cal_view->priv->calendar, event->comp_data->client,
- event->comp_data->icalcomp, FALSE);
+ e_cal_view_edit_appointment (cal_view, event->comp_data->client,
+ event->comp_data->icalcomp, FALSE);
g_list_free (selected);
}
@@ -834,7 +917,7 @@ on_print (GtkWidget *widget, gpointer user_data)
cal_view = E_CAL_VIEW (user_data);
- gnome_calendar_get_current_time_range (cal_view->priv->calendar, &start, NULL);
+ e_cal_view_get_visible_time_range (cal_view, &start, NULL);
view_type = gnome_calendar_get_view (cal_view->priv->calendar);
switch (view_type) {
@@ -930,7 +1013,7 @@ on_meeting (GtkWidget *widget, gpointer user_data)
selected = e_cal_view_get_selected_events (cal_view);
if (selected) {
ECalViewEvent *event = (ECalViewEvent *) selected->data;
- gnome_calendar_edit_object (cal_view->priv->calendar, event->comp_data->client, event->comp_data->icalcomp, TRUE);
+ e_cal_view_edit_appointment (cal_view, event->comp_data->client, event->comp_data->icalcomp, TRUE);
g_list_free (selected);
}
@@ -962,7 +1045,7 @@ on_publish (GtkWidget *widget, gpointer user_data)
ECalView *cal_view;
icaltimezone *utc;
time_t start = time (NULL), end;
- GList *comp_list, *client_list, *cl;
+ GList *comp_list = NULL, *client_list, *cl;
cal_view = E_CAL_VIEW (user_data);
@@ -972,8 +1055,7 @@ on_publish (GtkWidget *widget, gpointer user_data)
client_list = e_cal_model_get_client_list (cal_view->priv->model);
for (cl = client_list; cl != NULL; cl = cl->next) {
- comp_list = cal_client_get_free_busy ((CalClient *) cl->data, NULL, start, end);
- if (comp_list) {
+ if (cal_client_get_free_busy ((CalClient *) cl->data, NULL, start, end, &comp_list, NULL)) {
GList *l;
for (l = comp_list; l; l = l->next) {
@@ -1041,14 +1123,6 @@ on_paste (GtkWidget *widget, gpointer user_data)
e_cal_view_paste_clipboard (cal_view);
}
-static void
-on_unrecur_appointment (GtkWidget *widget, gpointer user_data)
-{
- ECalView *cal_view = E_CAL_VIEW (user_data);
-
- gnome_calendar_unrecur_selection (cal_view->priv->calendar);
-}
-
enum {
/*
* This is used to "flag" events that can not be editted
@@ -1142,7 +1216,6 @@ static EPopupMenu child_items [] = {
E_POPUP_SEPARATOR,
E_POPUP_ITEM (N_("_Delete"), GTK_SIGNAL_FUNC (on_delete_appointment), MASK_EDITABLE | MASK_SINGLE | MASK_EDITING),
- E_POPUP_ITEM (N_("Make this Occurrence _Movable"), GTK_SIGNAL_FUNC (on_unrecur_appointment), MASK_RECURRING | MASK_EDITING | MASK_EDITABLE | MASK_INSTANCE),
E_POPUP_ITEM (N_("Delete this _Occurrence"), GTK_SIGNAL_FUNC (on_delete_occurrence), MASK_RECURRING | MASK_EDITING | MASK_EDITABLE),
E_POPUP_ITEM (N_("Delete _All Occurrences"), GTK_SIGNAL_FUNC (on_delete_appointment), MASK_RECURRING | MASK_EDITING | MASK_EDITABLE),
@@ -1209,21 +1282,18 @@ setup_popup_icons (EPopupMenu *context_menu)
GtkMenu *
e_cal_view_create_popup_menu (ECalView *cal_view)
{
- gboolean being_edited, have_selection;
GList *selected;
EPopupMenu *context_menu;
guint32 disable_mask = 0, hide_mask = 0;
GtkMenu *popup;
CalClient *client = NULL;
-
+ gboolean read_only = TRUE;
+
g_return_val_if_fail (E_IS_CAL_VIEW (cal_view), NULL);
/* get the selection */
- being_edited = FALSE;
selected = e_cal_view_get_selected_events (cal_view);
- have_selection = GTK_WIDGET_HAS_FOCUS (cal_view) && selected != NULL;
-
if (selected == NULL) {
cal_view->priv->view_menu = gnome_calendar_setup_view_popup (cal_view->priv->calendar);
main_items[9].submenu = cal_view->priv->view_menu;
@@ -1260,15 +1330,158 @@ e_cal_view_create_popup_menu (ECalView *cal_view)
client = event->comp_data->client;
}
- if (cal_client_is_read_only (client))
+ cal_client_is_read_only (client, &read_only, NULL);
+ if (read_only)
disable_mask |= MASK_EDITABLE;
- if (being_edited)
- disable_mask |= MASK_EDITING;
-
setup_popup_icons (context_menu);
popup = e_popup_menu_create (context_menu, disable_mask, hide_mask, cal_view);
g_signal_connect (popup, "selection-done", G_CALLBACK (free_view_popup), cal_view);
return popup;
}
+
+/**
+ * e_cal_view_new_appointment_for
+ * @cal_view: A calendar view.
+ * @dtstart: A Unix time_t that marks the beginning of the appointment.
+ * @dtend: A Unix time_t that marks the end of the appointment.
+ * @all_day: If TRUE, the dtstart and dtend are expanded to cover
+ * the entire day, and the event is set to TRANSPARENT.
+ * @meeting: Whether the appointment is a meeting or not.
+ *
+ * Opens an event editor dialog for a new appointment.
+ */
+void
+e_cal_view_new_appointment_for (ECalView *cal_view,
+ time_t dtstart, time_t dtend,
+ gboolean all_day,
+ gboolean meeting)
+{
+ ECalViewPrivate *priv;
+ struct icaltimetype itt;
+ CalComponentDateTime dt;
+ CalComponent *comp;
+ icalcomponent *icalcomp;
+ CalComponentTransparency transparency;
+
+ g_return_if_fail (E_IS_CAL_VIEW (cal_view));
+
+ priv = cal_view->priv;
+
+ dt.value = &itt;
+ if (all_day)
+ dt.tzid = NULL;
+ else
+ dt.tzid = icaltimezone_get_tzid (priv->zone);
+
+ icalcomp = e_cal_model_create_component_with_defaults (priv->model);
+ comp = cal_component_new ();
+ cal_component_set_icalcomponent (comp, icalcomp);
+
+ /* DTSTART, DTEND */
+ itt = icaltime_from_timet_with_zone (dtstart, FALSE, priv->zone);
+ if (all_day) {
+ itt.hour = itt.minute = itt.second = 0;
+ itt.is_date = TRUE;
+ }
+ cal_component_set_dtstart (comp, &dt);
+
+ itt = icaltime_from_timet_with_zone (dtend, FALSE, priv->zone);
+ if (all_day) {
+ /* We round it up to the end of the day, unless it is
+ already set to midnight */
+ if (itt.hour != 0 || itt.minute != 0 || itt.second != 0) {
+ icaltime_adjust (&itt, 1, 0, 0, 0);
+ }
+ itt.hour = itt.minute = itt.second = 0;
+ itt.is_date = TRUE;
+ }
+ cal_component_set_dtend (comp, &dt);
+
+ /* TRANSPARENCY */
+ transparency = all_day ? CAL_COMPONENT_TRANSP_TRANSPARENT
+ : CAL_COMPONENT_TRANSP_OPAQUE;
+ cal_component_set_transparency (comp, transparency);
+
+ /* CATEGORY */
+ cal_component_set_categories (comp, priv->default_category);
+
+ /* edit the object */
+ cal_component_commit_sequence (comp);
+
+ e_cal_view_edit_appointment (cal_view,
+ e_cal_model_get_default_client (priv->model),
+ icalcomp, meeting);
+
+ g_object_unref (comp);
+}
+
+/**
+ * e_cal_view_new_appointment
+ * @cal_view: A calendar view.
+ *
+ * Opens an event editor dialog for a new appointment. The appointment's
+ * start and end times are set to the currently selected time range in
+ * the calendar view.
+ */
+void
+e_cal_view_new_appointment (ECalView *cal_view)
+{
+ time_t dtstart, dtend;
+
+ g_return_if_fail (E_IS_CAL_VIEW (cal_view));
+
+ e_cal_view_get_selected_time_range (cal_view, &dtstart, &dtend);
+ e_cal_view_new_appointment_for (cal_view, dtstart, dtend, FALSE, FALSE);
+}
+
+/**
+ * e_cal_view_edit_appointment
+ * @cal_view: A calendar view.
+ * @client: Calendar client.
+ * @icalcomp: The object to be edited.
+ * @meeting: Whether the appointment is a meeting or not.
+ *
+ * Opens an editor window to allow the user to edit the selected
+ * object.
+ */
+void
+e_cal_view_edit_appointment (ECalView *cal_view,
+ CalClient *client,
+ icalcomponent *icalcomp,
+ gboolean meeting)
+{
+ ECalViewPrivate *priv;
+ CompEditor *ce;
+ const char *uid;
+ CalComponent *comp;
+
+ g_return_if_fail (E_IS_CAL_VIEW (cal_view));
+ g_return_if_fail (IS_CAL_CLIENT (client));
+ g_return_if_fail (icalcomp != NULL);
+
+ priv = cal_view->priv;
+
+ uid = icalcomponent_get_uid (icalcomp);
+
+ ce = e_comp_editor_registry_find (comp_editor_registry, uid);
+ if (!ce) {
+ EventEditor *ee;
+
+ ee = event_editor_new (client);
+ ce = COMP_EDITOR (ee);
+
+ comp = cal_component_new ();
+ cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp));
+ comp_editor_edit_comp (ce, comp);
+ if (meeting)
+ event_editor_show_meeting (ee);
+
+ e_comp_editor_registry_add (comp_editor_registry, ce, FALSE);
+
+ g_object_unref (comp);
+ }
+
+ comp_editor_focus (ce);
+}
diff --git a/calendar/gui/e-calendar-view.h b/calendar/gui/e-calendar-view.h
index ea7c11a00d..9a09a5236a 100644
--- a/calendar/gui/e-calendar-view.h
+++ b/calendar/gui/e-calendar-view.h
@@ -96,6 +96,8 @@ ECalModel *e_cal_view_get_model (ECalView *cal_view);
void e_cal_view_set_model (ECalView *cal_view, ECalModel *model);
icaltimezone *e_cal_view_get_timezone (ECalView *cal_view);
void e_cal_view_set_timezone (ECalView *cal_view, icaltimezone *zone);
+const char *e_cal_view_get_default_category (ECalView *cal_view);
+void e_cal_view_set_default_category (ECalView *cal_view, const char *category);
void e_cal_view_set_status_message (ECalView *cal_view, const gchar *message);
@@ -114,6 +116,17 @@ void e_cal_view_delete_selected_occurrence (ECalView *cal_view);
GtkMenu *e_cal_view_create_popup_menu (ECalView *cal_view);
+void e_cal_view_new_appointment_for (ECalView *cal_view,
+ time_t dtstart,
+ time_t dtend,
+ gboolean all_day,
+ gboolean meeting);
+void e_cal_view_new_appointment (ECalView *cal_view);
+void e_cal_view_edit_appointment (ECalView *cal_view,
+ CalClient *client,
+ icalcomponent *icalcomp,
+ gboolean meeting);
+
G_END_DECLS
#endif
diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c
index a2a4f09d56..b4ec9faea0 100644
--- a/calendar/gui/e-day-view.c
+++ b/calendar/gui/e-day-view.c
@@ -65,6 +65,7 @@
#include "calendar-commands.h"
#include "calendar-config.h"
#include "goto.h"
+#include "e-cal-model-calendar.h"
#include "e-day-view-time-item.h"
#include "e-day-view-top-item.h"
#include "e-day-view-layout.h"
@@ -592,8 +593,6 @@ e_day_view_init (EDayView *day_view)
day_view->auto_scroll_timeout_id = 0;
- day_view->default_category = NULL;
-
day_view->large_font_desc = NULL;
/* String to use in 12-hour time format for times in the morning. */
@@ -850,8 +849,11 @@ GtkWidget *
e_day_view_new (void)
{
GtkWidget *day_view;
+ ECalModel *model;
+
+ model = E_CAL_MODEL (e_cal_model_calendar_new ());
- day_view = GTK_WIDGET (g_object_new (e_day_view_get_type (), NULL));
+ day_view = GTK_WIDGET (g_object_new (e_day_view_get_type (), "model", model, NULL));
return day_view;
}
@@ -881,12 +883,6 @@ e_day_view_destroy (GtkObject *object)
day_view->large_font_desc = NULL;
}
- if (day_view->default_category) {
- g_free (day_view->default_category);
- day_view->default_category = NULL;
- }
-
-
if (day_view->normal_cursor) {
gdk_cursor_unref (day_view->normal_cursor);
day_view->normal_cursor = NULL;
@@ -1429,26 +1425,6 @@ e_day_view_focus_out (GtkWidget *widget, GdkEventFocus *event)
return FALSE;
}
-/**
- * e_day_view_set_default_category:
- * @day_view: A day view.
- * @category: Default category name or NULL for no category.
- *
- * Sets the default category that will be used when creating new calendar
- * components from the day view.
- **/
-void
-e_day_view_set_default_category (EDayView *day_view, const char *category)
-{
- g_return_if_fail (day_view != NULL);
- g_return_if_fail (E_IS_DAY_VIEW (day_view));
-
- if (day_view->default_category)
- g_free (day_view->default_category);
-
- day_view->default_category = g_strdup (category);
-}
-
static gboolean
e_day_view_update_event_cb (EDayView *day_view,
gint day,
@@ -1794,6 +1770,9 @@ e_day_view_find_event_from_uid (EDayView *day_view,
gint day, event_num;
const char *u;
+ if (!uid)
+ return FALSE;
+
for (day = 0; day < day_view->days_shown; day++) {
for (event_num = 0; event_num < day_view->events[day]->len;
event_num++) {
@@ -2048,7 +2027,6 @@ e_day_view_find_work_week_start (EDayView *day_view,
return icaltime_as_timet_with_zone (tt, e_cal_view_get_timezone (E_CAL_VIEW (day_view)));
}
-
/* Returns the selected time range. */
static void
e_day_view_get_selected_time_range (ECalView *cal_view, time_t *start_time, time_t *end_time)
@@ -2123,6 +2101,8 @@ e_day_view_recalc_day_starts (EDayView *day_view,
day_view->lower = start_time;
day_view->upper = day_view->day_starts[day_view->days_shown];
+
+ e_day_view_update_query (day_view);
}
@@ -2588,9 +2568,9 @@ e_day_view_on_top_canvas_button_press (GtkWidget *widget,
time_t dtstart, dtend;
e_day_view_get_selected_time_range ((ECalView *) day_view, &dtstart, &dtend);
- gnome_calendar_new_appointment_for (e_cal_view_get_calendar (E_CAL_VIEW (day_view)),
- dtstart, dtend,
- TRUE, FALSE);
+ e_cal_view_new_appointment_for (E_CAL_VIEW (day_view),
+ dtstart, dtend,
+ TRUE, FALSE);
return TRUE;
}
@@ -2709,9 +2689,9 @@ e_day_view_on_main_canvas_button_press (GtkWidget *widget,
time_t dtstart, dtend;
e_day_view_get_selected_time_range ((ECalView *) day_view, &dtstart, &dtend);
- gnome_calendar_new_appointment_for (e_cal_view_get_calendar (E_CAL_VIEW (day_view)),
- dtstart, dtend,
- FALSE, FALSE);
+ e_cal_view_new_appointment_for (E_CAL_VIEW (day_view),
+ dtstart, dtend,
+ FALSE, FALSE);
return TRUE;
}
@@ -3101,7 +3081,6 @@ e_day_view_on_event_double_click (EDayView *day_view,
gint event_num)
{
EDayViewEvent *event;
- GnomeCalendar *calendar;
if (day == -1)
event = &g_array_index (day_view->long_events, EDayViewEvent,
@@ -3112,11 +3091,9 @@ e_day_view_on_event_double_click (EDayView *day_view,
e_day_view_stop_editing_event (day_view);
- calendar = e_cal_view_get_calendar (E_CAL_VIEW (day_view));
- if (calendar)
- gnome_calendar_edit_object (calendar, event->comp_data->client, event->comp_data->icalcomp, FALSE);
- else
- g_warning ("Calendar not set");
+ e_cal_view_edit_appointment (E_CAL_VIEW (day_view),
+ event->comp_data->client,
+ event->comp_data->icalcomp, FALSE);
}
static void
@@ -3207,7 +3184,6 @@ process_component (EDayView *day_view, ECalModelComponent *comp_data)
EDayViewEvent, event_num);
if (!cal_util_component_has_recurrences (comp_data->icalcomp)
- && !cal_component_has_recurrences (event->comp_data->icalcomp)
&& cal_util_event_dates_match (event->comp_data->icalcomp, comp_data->icalcomp)) {
#if 0
g_print ("updated object's dates unchanged\n");
@@ -3228,17 +3204,18 @@ process_component (EDayView *day_view, ECalModelComponent *comp_data)
NULL);
}
- /* Add the occurrences of the event. */
+ /* Add the occurrences of the event */
comp = cal_component_new ();
cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp));
+
add_event_data.day_view = day_view;
add_event_data.comp_data = comp_data;
cal_recur_generate_instances (comp, day_view->lower,
day_view->upper,
e_day_view_add_event, &add_event_data,
- cal_client_resolve_tzid_cb,
- comp_data->client,
+ cal_client_resolve_tzid_cb, comp_data->client,
e_cal_view_get_timezone (E_CAL_VIEW (day_view)));
+
g_object_unref (comp);
e_day_view_queue_layout (day_view);
@@ -3258,8 +3235,6 @@ e_day_view_update_query (ECalView *cal_view)
e_day_view_free_events (day_view);
e_day_view_queue_layout (day_view);
- e_cal_view_set_status_message (E_CAL_VIEW (day_view), _("Searching"));
-
rows = e_table_model_row_count (E_TABLE_MODEL (e_cal_view_get_model (E_CAL_VIEW (day_view))));
for (r = 0; r < rows; r++) {
ECalModelComponent *comp_data;
@@ -3268,8 +3243,6 @@ e_day_view_update_query (ECalView *cal_view)
g_assert (comp_data != NULL);
process_component (day_view, comp_data);
}
-
- e_cal_view_set_status_message (E_CAL_VIEW (day_view), NULL);
}
static void
@@ -3282,67 +3255,6 @@ e_day_view_on_event_right_click (EDayView *day_view,
day, event_num);
}
-void
-e_day_view_unrecur_appointment (EDayView *day_view)
-{
- EDayViewEvent *event;
- CalComponent *comp, *new_comp;
- CalComponentDateTime date;
- struct icaltimetype itt;
-
- event = e_day_view_get_popup_menu_event (day_view);
- if (event == NULL)
- return;
-
- date.value = &itt;
- date.tzid = NULL;
-
- /* For the recurring object, we add an exception to get rid of the
- instance. */
-
- comp = cal_component_new ();
- cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp));
- cal_comp_util_add_exdate (comp, event->start, e_cal_view_get_timezone (E_CAL_VIEW (day_view)));
-
- /* For the unrecurred instance we duplicate the original object,
- create a new uid for it, get rid of the recurrence rules, and set
- the start & end times to the instances times. */
- new_comp = cal_component_new ();
- cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp));
- cal_component_set_uid (new_comp, cal_component_gen_uid ());
- cal_component_set_rdate_list (new_comp, NULL);
- cal_component_set_rrule_list (new_comp, NULL);
- cal_component_set_exdate_list (new_comp, NULL);
- cal_component_set_exrule_list (new_comp, NULL);
-
- date.value = &itt;
- date.tzid = icaltimezone_get_tzid (e_cal_view_get_timezone (E_CAL_VIEW (day_view)));
-
- *date.value = icaltime_from_timet_with_zone (event->start, FALSE,
- e_cal_view_get_timezone (E_CAL_VIEW (day_view)));
- cal_component_set_dtstart (new_comp, &date);
- *date.value = icaltime_from_timet_with_zone (event->end, FALSE,
- e_cal_view_get_timezone (E_CAL_VIEW (day_view)));
- cal_component_set_dtend (new_comp, &date);
-
-
- /* Now update both CalComponents. Note that we do this last since at
- * present the updates happen synchronously so our event may disappear.
- */
- if (cal_client_update_object (event->comp_data->client, comp)
- != CAL_CLIENT_RESULT_SUCCESS)
- g_message ("e_day_view_on_unrecur_appointment(): Could not update the object!");
-
- g_object_unref (comp);
-
- if (cal_client_update_object (event->comp_data->client, new_comp)
- != CAL_CLIENT_RESULT_SUCCESS)
- g_message ("e_day_view_on_unrecur_appointment(): Could not update the object!");
-
- g_object_unref (new_comp);
-}
-
-
static EDayViewEvent*
e_day_view_get_popup_menu_event (EDayView *day_view)
{
@@ -3841,7 +3753,9 @@ e_day_view_finish_long_event_resize (EDayView *day_view)
struct icaltimetype itt;
time_t dt;
CalClient *client;
-
+ CalObjModType mod = CALOBJ_MOD_ALL;
+ GtkWindow *toplevel;
+
event_num = day_view->resize_event_num;
event = &g_array_index (day_view->long_events, EDayViewEvent,
event_num);
@@ -3870,31 +3784,26 @@ e_day_view_finish_long_event_resize (EDayView *day_view)
e_cal_view_get_timezone (E_CAL_VIEW (day_view)));
cal_component_set_dtend (comp, &date);
}
-
- if (cal_component_is_instance (comp)) {
- CalObjModType mod;
-
- if (recur_component_dialog (comp, &mod, NULL)) {
- if (cal_client_update_object_with_mod (client, comp, mod) == CAL_CLIENT_RESULT_SUCCESS) {
- if (itip_organizer_is_user (comp, client) &&
- send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (day_view)),
- client, comp, FALSE))
- itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, client, NULL);
- } else {
- g_message ("e_day_view_finish_resize(): Could not update the object!");
- }
- } else {
+
+ if (cal_component_has_recurrences (comp)) {
+ if (!recur_component_dialog (comp, &mod, NULL)) {
gtk_widget_queue_draw (day_view->top_canvas);
- }
- } else if (cal_client_update_object (client, comp) == CAL_CLIENT_RESULT_SUCCESS) {
- if (itip_organizer_is_user (comp, client) &&
- send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (day_view)),
- client, comp, TRUE))
- itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, client, NULL);
- } else {
- g_message ("e_day_view_finish_long_event_resize(): Could not update the object!");
- }
-
+ goto out;
+ }
+ }
+
+ toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (day_view)));
+
+ if (cal_client_modify_object (client, cal_component_get_icalcomponent (comp), mod, NULL)) {
+ if (itip_organizer_is_user (comp, client) &&
+ send_component_dialog (toplevel, client, comp, TRUE)) {
+ itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, client, NULL);
+ } else {
+ g_message (G_STRLOC ": Could not update the object!");
+ }
+ }
+
+ out:
gnome_canvas_item_hide (day_view->resize_long_event_rect_item);
day_view->resize_drag_pos = E_CAL_VIEW_POS_NONE;
@@ -3915,6 +3824,8 @@ e_day_view_finish_resize (EDayView *day_view)
struct icaltimetype itt;
time_t dt;
CalClient *client;
+ CalObjModType mod = CALOBJ_MOD_ALL;
+ GtkWindow *toplevel;
day = day_view->resize_event_day;
event_num = day_view->resize_event_num;
@@ -3957,29 +3868,26 @@ e_day_view_finish_resize (EDayView *day_view)
day_view->resize_drag_pos = E_CAL_VIEW_POS_NONE;
- if (cal_component_is_instance (comp)) {
- CalObjModType mod;
+ if (cal_component_has_recurrences (comp)) {
+ if (!recur_component_dialog (comp, &mod, NULL)) {
+ gtk_widget_queue_draw (day_view->top_canvas);
+ goto out;
+ }
+ }
+
+ toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (day_view)));
- if (recur_component_dialog (comp, &mod, NULL)) {
- if (cal_client_update_object_with_mod (client, comp, mod) == CAL_CLIENT_RESULT_SUCCESS) {
- if (itip_organizer_is_user (comp, client) &&
- send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (day_view)),
- client, comp, FALSE))
- itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, client, NULL);
- } else {
- g_message ("e_day_view_finish_resize(): Could not update the object!");
- }
- } else {
- gtk_widget_queue_draw (day_view->main_canvas);
- }
- } else if (cal_client_update_object (client, comp) == CAL_CLIENT_RESULT_SUCCESS) {
+ cal_component_commit_sequence (comp);
+ if (cal_client_modify_object (client, cal_component_get_icalcomponent (comp), mod, NULL)) {
if (itip_organizer_is_user (comp, client) &&
- send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (day_view)), client, comp, FALSE))
+ send_component_dialog (toplevel, client, comp, TRUE)) {
itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, client, NULL);
- } else {
- g_message ("e_day_view_finish_resize(): Could not update the object!");
- }
-
+ } else {
+ g_message (G_STRLOC ": Could not update the object!");
+ }
+ }
+
+ out:
g_object_unref (comp);
}
@@ -4774,6 +4682,8 @@ e_day_view_do_key_press (GtkWidget *widget, GdkEventKey *event)
/* Add a new event covering the selected range */
icalcomp = e_cal_model_create_component_with_defaults (e_cal_view_get_model (E_CAL_VIEW (day_view)));
+ if (!icalcomp)
+ return FALSE;
uid = icalcomponent_get_uid (icalcomp);
comp = cal_component_new ();
@@ -4801,7 +4711,8 @@ e_day_view_do_key_press (GtkWidget *widget, GdkEventKey *event)
cal_component_set_dtstart (comp, &start_dt);
cal_component_set_dtend (comp, &end_dt);
- cal_component_set_categories (comp, day_view->default_category);
+ cal_component_set_categories (
+ comp, e_cal_view_get_default_category (E_CAL_VIEW (day_view)));
/* We add the event locally and start editing it. We don't send it
to the server until the user finishes editing it. */
@@ -5777,7 +5688,8 @@ e_day_view_on_editing_stopped (EDayView *day_view,
gchar *text = NULL;
CalComponentText summary;
CalComponent *comp;
-
+ gboolean on_server;
+
/* Note: the item we are passed here isn't reliable, so we just stop
the edit of whatever item was being edited. We also receive this
event twice for some reason. */
@@ -5822,8 +5734,9 @@ e_day_view_on_editing_stopped (EDayView *day_view,
comp = cal_component_new ();
cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp));
- if (string_is_empty (text) &&
- !cal_comp_is_on_server (comp, event->comp_data->client)) {
+ on_server = cal_comp_is_on_server (comp, event->comp_data->client);
+
+ if (string_is_empty (text) && !on_server) {
const char *uid;
cal_component_get_uid (comp, &uid);
@@ -5845,34 +5758,34 @@ e_day_view_on_editing_stopped (EDayView *day_view,
e_day_view_update_event_label (day_view, day,
event_num);
} else if (summary.value || !string_is_empty (text)) {
+ icalcomponent *icalcomp = cal_component_get_icalcomponent (comp);
+
summary.value = text;
summary.altrep = NULL;
cal_component_set_summary (comp, &summary);
- if (cal_component_is_instance (comp)) {
- CalObjModType mod;
-
- if (recur_component_dialog (comp, &mod, NULL)) {
- if (cal_client_update_object_with_mod (event->comp_data->client, comp, mod)
- == CAL_CLIENT_RESULT_SUCCESS) {
- if (itip_organizer_is_user (comp, event->comp_data->client)
- && send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (day_view)),
- event->comp_data->client, comp, FALSE))
- itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
- event->comp_data->client, NULL);
- } else {
- g_message ("e_day_view_on_editing_stopped(): Could not update the object!");
+ if (!on_server) {
+ if (!cal_client_create_object (event->comp_data->client, icalcomp, NULL, NULL))
+ g_message (G_STRLOC ": Could not create the object!");
+ } else {
+ CalObjModType mod = CALOBJ_MOD_ALL;
+ GtkWindow *toplevel;
+ if (cal_component_has_recurrences (comp)) {
+ if (!recur_component_dialog (comp, &mod, NULL)) {
+ goto out;
}
}
- } else if (cal_client_update_object (event->comp_data->client, comp) == CAL_CLIENT_RESULT_SUCCESS) {
- if (itip_organizer_is_user (comp, event->comp_data->client) &&
- send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (day_view)),
- event->comp_data->client, comp, FALSE))
- itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
- event->comp_data->client, NULL);
- } else {
- g_message ("e_day_view_on_editing_stopped(): Could not update the object!");
+
+ /* FIXME When sending here, what exactly should we send? */
+ toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (day_view)));
+ if (cal_client_modify_object (event->comp_data->client, icalcomp, mod, NULL)) {
+ if (itip_organizer_is_user (comp, event->comp_data->client)
+ && send_component_dialog (toplevel, event->comp_data->client, comp, FALSE))
+ itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
+ event->comp_data->client, NULL);
+ }
}
+
}
out:
@@ -6881,7 +6794,10 @@ e_day_view_on_top_canvas_drag_data_received (GtkWidget *widget,
x, y, &day,
NULL);
if (pos != E_CAL_VIEW_POS_OUTSIDE) {
+ CalObjModType mod = CALOBJ_MOD_ALL;
+ GtkWindow *toplevel;
const char *uid;
+
num_days = 1;
start_offset = 0;
end_offset = 0;
@@ -6972,33 +6888,20 @@ e_day_view_on_top_canvas_drag_data_received (GtkWidget *widget,
if (event->canvas_item)
gnome_canvas_item_show (event->canvas_item);
- if (cal_component_is_instance (comp)) {
- CalObjModType mod;
-
- if (recur_component_dialog (comp, &mod, NULL)) {
- if (cal_client_update_object_with_mod (client, comp, mod) == CAL_CLIENT_RESULT_SUCCESS) {
- if (itip_organizer_is_user (comp, client)
- && send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (day_view)),
- client, comp, FALSE))
- itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
- client, NULL);
- } else {
- g_message ("e_day_view_on_top_canvas_drag_data_received(): Could "
- "not update the object!");
- }
- }
- } else if (cal_client_update_object (client, comp)
- == CAL_CLIENT_RESULT_SUCCESS) {
- if (itip_organizer_is_user (comp, client) &&
- send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (day_view)),
- client, comp, FALSE))
- itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
- client, NULL);
- } else {
- g_message ("e_day_view_on_top_canvas_drag_data_received(): Could "
- "not update the object!");
+ if (cal_component_has_recurrences (comp)) {
+ if (!recur_component_dialog (comp, &mod, NULL))
+ return;
}
+ toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (day_view)));
+
+ if (cal_client_modify_object (client, cal_component_get_icalcomponent (comp), mod, NULL)) {
+ if (itip_organizer_is_user (comp, client)
+ && send_component_dialog (toplevel, client, comp, FALSE))
+ itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
+ client, NULL);
+ }
+
g_object_unref (comp);
return;
@@ -7044,7 +6947,10 @@ e_day_view_on_main_canvas_drag_data_received (GtkWidget *widget,
x, y, &day,
&row, NULL);
if (pos != E_CAL_VIEW_POS_OUTSIDE) {
+ CalObjModType mod = CALOBJ_MOD_ALL;
+ GtkWindow *toplevel;
const char *uid;
+
num_rows = 1;
start_offset = 0;
end_offset = 0;
@@ -7109,30 +7015,20 @@ e_day_view_on_main_canvas_drag_data_received (GtkWidget *widget,
if (event->canvas_item)
gnome_canvas_item_show (event->canvas_item);
- if (cal_component_is_instance (comp)) {
- CalObjModType mod;
-
- if (recur_component_dialog (comp, &mod, NULL)) {
- if (cal_client_update_object_with_mod (client, comp, mod) == CAL_CLIENT_RESULT_SUCCESS) {
- if (itip_organizer_is_user (comp, client)
- && send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (day_view)),
- client, comp, FALSE))
- itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
- client, NULL);
- } else {
- g_message ("e_day_view_on_top_canvas_drag_data_received(): Could "
- "not update the object!");
- }
+ if (cal_component_has_recurrences (comp)) {
+ if (!recur_component_dialog (comp, &mod, NULL)) {
+ g_object_unref (comp);
+ return;
}
- } else if (cal_client_update_object (client, comp) == CAL_CLIENT_RESULT_SUCCESS) {
- if (itip_organizer_is_user (comp, client) &&
- send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (day_view)),
- client, comp, FALSE))
- itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
+ }
+
+ toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (day_view)));
+
+ if (cal_client_modify_object (client, cal_component_get_icalcomponent (comp), mod, NULL)) {
+ if (itip_organizer_is_user (comp, client)
+ && send_component_dialog (toplevel, client, comp, FALSE))
+ itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
client, NULL);
- } else {
- g_message ("e_day_view_on_main_canvas_drag_data_received(): "
- "Could not update the object!");
}
g_object_unref (comp);
diff --git a/calendar/gui/e-day-view.h b/calendar/gui/e-day-view.h
index 1c39fd5844..decd281127 100644
--- a/calendar/gui/e-day-view.h
+++ b/calendar/gui/e-day-view.h
@@ -453,9 +453,6 @@ struct _EDayView
gint am_string_width;
gint pm_string_width;
- /* The default category for new events */
- char *default_category;
-
/* The activity client used to show messages on the status bar. */
EvolutionActivityClient *activity;
};
@@ -472,9 +469,6 @@ GtkWidget* e_day_view_new (void);
void e_day_view_set_query (EDayView *day_view,
const char *sexp);
-void e_day_view_set_default_category (EDayView *day_view,
- const char *category);
-
/* Whether we are displaying a work-week, in which case the display always
starts on the first day of the working week. */
gboolean e_day_view_get_work_week_view (EDayView *day_view);
@@ -528,7 +522,6 @@ void e_day_view_set_week_start_day (EDayView *day_view,
gint week_start_day);
void e_day_view_delete_occurrence (EDayView *day_view);
-void e_day_view_unrecur_appointment (EDayView *day_view);
/* Returns the number of selected events (0 or 1 at present). */
gint e_day_view_get_num_events_selected (EDayView *day_view);
diff --git a/calendar/gui/e-itip-control.c b/calendar/gui/e-itip-control.c
index 8b39b82b8c..d5e24c8936 100644
--- a/calendar/gui/e-itip-control.c
+++ b/calendar/gui/e-itip-control.c
@@ -94,8 +94,6 @@ struct _EItipControlPrivate {
#define HTML_BODY_END "</body>"
#define HTML_FOOTER "</html>"
-extern EvolutionShellClient *global_shell_client;
-
/* We intentionally use "calendar" instead of "calendar / *" here. We
* don't want public calendars.
*/
@@ -132,63 +130,26 @@ class_init (EItipControlClass *klass)
object_class->finalize = finalize;
}
-
-/* Calendar Server routines */
-static void
-start_calendar_server_cb (CalClient *cal_client,
- CalClientOpenStatus status,
- gpointer data)
-{
- int *success = data;
- int orig = *success;
-
- if (status == CAL_CLIENT_OPEN_SUCCESS)
- *success = 1;
- else
- *success = 0;
-
- if (orig != -1)
- gtk_main_quit (); /* end the sub event loop */
-}
-
static CalClient *
start_calendar_server (EItipControl *itip, char *uri)
{
CalClient *client;
- int success = -1;
-
- client = cal_client_new ();
-
- g_signal_connect (client, "cal_opened", G_CALLBACK (start_calendar_server_cb), &success);
-
- if (!cal_client_open_calendar (client, uri, TRUE))
- goto error;
-
- /* run a sub event loop to turn cal-client's async load
- notification into a synchronous call */
- if (success == -1 && !itip->priv->destroyed) {
- success = 0;
-
- gtk_signal_connect (GTK_OBJECT (itip), "destroy",
- gtk_main_quit, NULL);
-
- gtk_main ();
-
- gtk_signal_disconnect_by_func (GTK_OBJECT (itip),
- gtk_main_quit, NULL);
- }
+ GError *error = NULL;
- if (success == 1)
- return client;
+ client = cal_client_new (uri, CALOBJ_TYPE_EVENT);
-error:
- g_object_unref (client);
+ if (!cal_client_open (client, TRUE, &error)) {
+ g_warning (_("start_calendar_server(): %s"), error->message);
+ g_error_free (error);
+ g_object_unref (client);
+ return NULL;
+ }
- return NULL;
+ return client;
}
static gboolean
-start_default_server_async (EItipControl *itip, CalClient *client, gboolean tasks)
+start_default_server (EItipControl *itip, CalClient *client, gboolean tasks)
{
if (tasks)
return cal_client_open_default_tasks (client, FALSE);
@@ -196,6 +157,7 @@ start_default_server_async (EItipControl *itip, CalClient *client, gboolean task
return cal_client_open_default_calendar (client, FALSE);
}
+#if 0 /* EPFIXME, rewrite this */
static GPtrArray *
get_servers (EItipControl *itip, EvolutionShellClient *shell_client, const char *possible_types[], gboolean tasks)
{
@@ -263,6 +225,7 @@ get_servers (EItipControl *itip, EvolutionShellClient *shell_client, const char
return servers;
}
+#endif
static CalClient *
find_server (GPtrArray *servers, CalComponent *comp)
@@ -274,11 +237,9 @@ find_server (GPtrArray *servers, CalComponent *comp)
for (i = 0; i < servers->len; i++) {
CalClient *client;
icalcomponent *icalcomp;
- CalClientGetStatus status;
client = g_ptr_array_index (servers, i);
- status = cal_client_get_object (client, uid, &icalcomp);
- if (status == CAL_CLIENT_GET_SUCCESS) {
+ if (cal_client_get_object (client, uid, NULL, &icalcomp, NULL)) {
icalcomponent_free (icalcomp);
g_object_ref (client);
@@ -540,8 +501,7 @@ find_attendee (icalcomponent *ical_comp, const char *address)
for (prop = icalcomponent_get_first_property (ical_comp, ICAL_ATTENDEE_PROPERTY);
prop != NULL;
- prop = icalcomponent_get_next_property (ical_comp, ICAL_ATTENDEE_PROPERTY))
- {
+ prop = icalcomponent_get_next_property (ical_comp, ICAL_ATTENDEE_PROPERTY)) {
icalvalue *value;
const char *attendee;
char *text;
@@ -762,6 +722,7 @@ write_recurrence_piece (EItipControl *itip, CalComponent *comp,
} else if (!icaltime_is_null_time (r->until)) {
CalComponentDateTime dt;
+ /* FIXME This should get the tzid id, not the whole zone */
dt.value = &r->until;
dt.tzid = r->until.zone;
@@ -1220,7 +1181,7 @@ get_real_item (EItipControl *itip)
CalComponent *comp;
icalcomponent *icalcomp;
CalComponentVType type;
- CalClientGetStatus status = CAL_CLIENT_GET_NOT_FOUND;
+ gboolean found = FALSE;
const char *uid;
priv = itip->priv;
@@ -1231,17 +1192,17 @@ get_real_item (EItipControl *itip)
switch (type) {
case CAL_COMPONENT_EVENT:
if (priv->event_client != NULL)
- status = cal_client_get_object (priv->event_client, uid, &icalcomp);
+ found = cal_client_get_object (priv->event_client, uid, NULL, &icalcomp, NULL);
break;
case CAL_COMPONENT_TODO:
if (priv->task_client != NULL)
- status = cal_client_get_object (priv->task_client, uid, &icalcomp);
+ found = cal_client_get_object (priv->task_client, uid, NULL, &icalcomp, NULL);
break;
default:
- status = CAL_CLIENT_GET_NOT_FOUND;
+ found = FALSE;
}
- if (status != CAL_CLIENT_GET_SUCCESS)
+ if (!found)
return NULL;
comp = cal_component_new ();
@@ -1568,13 +1529,18 @@ show_current (EItipControl *itip)
switch (type) {
case CAL_COMPONENT_EVENT:
- if (!priv->event_clients)
- priv->event_clients = get_servers (itip, global_shell_client, calendar_types, FALSE);
+ if (!priv->event_clients) {
+ priv->event_clients = g_ptr_array_new ();
+ /* EPFIXME */
+ /* priv->event_clients = get_servers (itip, global_shell_client, calendar_types, FALSE); */
+ }
show_current_event (itip);
break;
case CAL_COMPONENT_TODO:
- if (!priv->task_clients)
- priv->task_clients = get_servers (itip, global_shell_client, tasks_types, TRUE);
+ if (!priv->task_clients) {
+ /* EPFIXME */
+ /* priv->task_clients = get_servers (itip, global_shell_client, tasks_types, TRUE); */
+ }
show_current_todo (itip);
break;
case CAL_COMPONENT_FREEBUSY:
@@ -1853,7 +1819,6 @@ update_item (EItipControl *itip)
CalClient *client;
CalComponentVType type;
GtkWidget *dialog;
- CalClientResult result;
priv = itip->priv;
@@ -1881,32 +1846,18 @@ update_item (EItipControl *itip)
icalcomponent_add_component (priv->top_level, clone);
icalcomponent_set_method (priv->top_level, priv->method);
- result = cal_client_update_objects (client, priv->top_level);
- switch (result) {
- case CAL_CLIENT_RESULT_INVALID_OBJECT :
- dialog = gnome_warning_dialog (_("Object is invalid and cannot be updated\n"));
- break;
- case CAL_CLIENT_RESULT_CORBA_ERROR :
- dialog = gnome_warning_dialog (_("There was an error on the CORBA system\n"));
- break;
- case CAL_CLIENT_RESULT_NOT_FOUND :
- dialog = gnome_warning_dialog (_("Object could not be found\n"));
- break;
- case CAL_CLIENT_RESULT_PERMISSION_DENIED :
- dialog = gnome_warning_dialog (_("You do not have the right permissions to update the calendar\n"));
- break;
- case CAL_CLIENT_RESULT_SUCCESS :
- dialog = gnome_ok_dialog (_("Update complete\n"));
- break;
- default :
+ /* FIXME Better error dialog */
+ if (!cal_client_receive_objects (client, priv->top_level, NULL)) {
dialog = gnome_warning_dialog (_("Calendar file could not be updated!\n"));
- break;
+ } else {
+ dialog = gnome_ok_dialog (_("Update complete\n"));
}
gnome_dialog_run_and_close (GNOME_DIALOG (dialog));
icalcomponent_remove_component (priv->top_level, clone);
}
+#if 0
static void
update_attendee_status (EItipControl *itip)
{
@@ -1936,7 +1887,7 @@ update_attendee_status (EItipControl *itip)
/* Obtain our version */
cal_component_get_uid (priv->comp, &uid);
- status = cal_client_get_object (client, uid, &icalcomp);
+ status = cal_client_get_object (client, uid, NULL, &icalcomp);
if (status == CAL_CLIENT_GET_SUCCESS) {
GSList *attendees;
@@ -2010,6 +1961,7 @@ update_attendee_status (EItipControl *itip)
g_object_unref (comp);
gnome_dialog_run_and_close (GNOME_DIALOG (dialog));
}
+#endif
static void
remove_item (EItipControl *itip)
@@ -2019,7 +1971,7 @@ remove_item (EItipControl *itip)
CalComponentVType type;
const char *uid;
GtkWidget *dialog;
- CalClientResult result;
+ GError *error = NULL;
priv = itip->priv;
@@ -2033,13 +1985,15 @@ remove_item (EItipControl *itip)
return;
cal_component_get_uid (priv->comp, &uid);
- result = cal_client_remove_object (client, uid);
- if (result == CAL_CLIENT_RESULT_SUCCESS || result == CAL_CLIENT_RESULT_NOT_FOUND) {
+ cal_client_remove_object (client, uid, &error);
+ if (!error || error->code == E_CALENDAR_STATUS_OBJECT_NOT_FOUND) {
dialog = gnome_ok_dialog (_("Removal Complete"));
gnome_dialog_run_and_close (GNOME_DIALOG (dialog));
} else {
- delete_error_dialog (result, type);
- }
+ delete_error_dialog (error, type);
+ }
+
+ g_clear_error (&error);
}
static void
@@ -2081,7 +2035,7 @@ send_freebusy (EItipControl *itip)
CalComponentDateTime datetime;
time_t start, end;
GtkWidget *dialog;
- GList *comp_list;
+ GList *comp_list = NULL;
icaltimezone *zone;
priv = itip->priv;
@@ -2106,9 +2060,7 @@ send_freebusy (EItipControl *itip)
end = icaltime_as_timet_with_zone (*datetime.value, zone);
cal_component_free_datetime (&datetime);
- comp_list = cal_client_get_free_busy (priv->event_client, NULL, start, end);
-
- if (comp_list) {
+ if (cal_client_get_free_busy (priv->event_client, NULL, start, end, &comp_list, NULL)) {
GList *l;
for (l = comp_list; l; l = l->next) {
@@ -2210,6 +2162,7 @@ default_server_started_cb (CalClient *client, CalClientOpenStatus status, gpoint
vtype = cal_component_get_vtype (priv->comp);
switch (vtype) {
+#if 0 /* EPFIXME */
case CAL_COMPONENT_EVENT:
button = evolution_folder_selector_button_new (
global_shell_client, _("Select Calendar Folder"),
@@ -2222,6 +2175,7 @@ default_server_started_cb (CalClient *client, CalClientOpenStatus status, gpoint
calendar_config_default_tasks_folder (),
tasks_types);
break;
+#endif
default:
button = NULL;
}
@@ -2251,29 +2205,30 @@ object_requested_cb (GtkHTML *html, GtkHTMLEmbedded *eb, gpointer data)
context = g_new0 (ObjectRequestContext, 1);
context->itip = itip;
context->eb = eb;
- context->client = cal_client_new ();
-
- g_object_ref (itip);
- g_signal_connect (context->client, "cal_opened",
- G_CALLBACK (default_server_started_cb), context);
+ /* FIXME: use the default URIs */
switch (vtype) {
case CAL_COMPONENT_EVENT:
- success = start_default_server_async (itip, context->client, FALSE);
+ context->client = cal_client_new ("", CALOBJ_TYPE_EVENT);
+ success = start_default_server (itip, context->client, FALSE);
break;
case CAL_COMPONENT_TODO:
- success = start_default_server_async (itip, context->client, TRUE);
+ context->client = cal_client_new ("", CALOBJ_TYPE_TODO);
+ success = start_default_server (itip, context->client, TRUE);
break;
default:
- success = FALSE;
+ g_free (context);
+ return FALSE;
}
if (!success) {
- g_object_unref (itip);
g_object_unref (context->client);
g_free (context);
+ return FALSE;
}
+ g_object_ref (itip);
+
return TRUE;
}
@@ -2330,7 +2285,8 @@ ok_clicked_cb (GtkHTML *html, const gchar *method, const gchar *url, const gchar
send_freebusy (itip);
break;
case 'R':
- update_attendee_status (itip);
+ /* FIXME Make sure this does the right thing in the backend */
+ update_item (itip);
break;
case 'S':
send_item (itip);
diff --git a/calendar/gui/e-meeting-list-view.c b/calendar/gui/e-meeting-list-view.c
index 7d3a4ce6c6..64463fdcb6 100644
--- a/calendar/gui/e-meeting-list-view.c
+++ b/calendar/gui/e-meeting-list-view.c
@@ -35,11 +35,7 @@
#include <libgnome/gnome-util.h>
#include <libgnomevfs/gnome-vfs.h>
#include <ebook/e-book.h>
-#include <ebook/e-book-util.h>
-#include <ebook/e-card-types.h>
-#include <ebook/e-card-cursor.h>
-#include <ebook/e-card.h>
-#include <ebook/e-card-simple.h>
+#include <ebook/e-vcard.h>
#include <cal-util/cal-component.h>
#include <cal-util/cal-util.h>
#include <cal-util/timeutil.h>
@@ -47,6 +43,7 @@
#include "calendar-config.h"
#include "e-meeting-list-view.h"
#include <misc/e-cell-renderer-combo.h>
+#include <addressbook/util/eab-destination.h>
#include "e-select-names-renderer.h"
#define SELECT_NAMES_OAFID "OAFIID:GNOME_Evolution_Addressbook_SelectNames"
@@ -56,8 +53,6 @@ struct _EMeetingListViewPrivate
EMeetingStore *store;
EBook *ebook;
- gboolean book_loaded;
- gboolean book_load_wait;
GNOME_Evolution_Addressbook_SelectNames corba_select_names;
};
@@ -78,26 +73,17 @@ static icalparameter_role roles[] = {ICAL_ROLE_CHAIR,
static GtkTreeViewClass *parent_class = NULL;
static void
-book_open_cb (EBook *book, EBookStatus status, gpointer data)
-{
- EMeetingListView *view = E_MEETING_LIST_VIEW (data);
-
- if (status == E_BOOK_STATUS_SUCCESS)
- view->priv->book_loaded = TRUE;
- else
- g_warning ("Book not loaded");
-
- if (view->priv->book_load_wait) {
- view->priv->book_load_wait = FALSE;
- gtk_main_quit ();
- }
-}
-
-static void
start_addressbook_server (EMeetingListView *view)
{
+ GError *error = NULL;
+
view->priv->ebook = e_book_new ();
- e_book_load_default_book (view->priv->ebook, book_open_cb, view);
+ if (!e_book_load_local_addressbook (view->priv->ebook, &error)) {
+ g_warning ("start_addressbook_server(): %s", error->message);
+ g_error_free (error);
+
+ return;
+ }
}
static void
@@ -319,49 +305,41 @@ e_meeting_list_view_column_set_visible (EMeetingListView *view, const gchar *col
}
static void
-process_section (EMeetingListView *view, GNOME_Evolution_Addressbook_SimpleCardList *cards, icalparameter_role role)
+process_section (EMeetingListView *view, EABDestination **cards, icalparameter_role role)
{
EMeetingListViewPrivate *priv;
int i;
priv = view->priv;
- for (i = 0; i < cards->_length; i++) {
- const char *name, *attendee = NULL, *attr;
- GNOME_Evolution_Addressbook_SimpleCard card;
- CORBA_Environment ev;
+ for (i = 0; i < G_N_ELEMENTS (cards); i++) {
+ const char *name, *attendee = NULL;
+ char *attr = NULL;
- card = cards->_buffer[i];
-
- CORBA_exception_init (&ev);
-
- /* Get the CN */
- name = GNOME_Evolution_Addressbook_SimpleCard_get (card, GNOME_Evolution_Addressbook_SimpleCard_FullName, &ev);
- if (BONOBO_EX (&ev)) {
- CORBA_exception_free (&ev);
- continue;
- }
+ name = eab_destination_get_name (cards[i]);
/* Get the field as attendee from the backend */
- attr = cal_client_get_ldap_attribute (e_meeting_store_get_cal_client (priv->store));
- if (attr) {
+ if (cal_client_get_ldap_attribute (e_meeting_store_get_cal_client (priv->store),
+ &attr, NULL)) {
/* FIXME this should be more general */
- if (!g_ascii_strcasecmp (attr, "icscalendar"))
- attendee = GNOME_Evolution_Addressbook_SimpleCard_get (card, GNOME_Evolution_Addressbook_SimpleCard_Icscalendar, &ev);
+ if (!g_ascii_strcasecmp (attr, "icscalendar")) {
+ EContact *contact;
+
+ /* FIXME: this does not work, have to use first
+ eab_destination_use_contact() */
+ contact = eab_destination_get_contact (cards[i]);
+ if (contact) {
+ attendee = e_contact_get (contact, E_CONTACT_FREEBUSY_URL);
+ if (!attendee)
+ attendee = e_contact_get (contact, E_CONTACT_CALENDAR_URI);
+ }
+ }
}
- CORBA_exception_init (&ev);
-
/* If we couldn't get the attendee prior, get the email address as the default */
if (attendee == NULL || *attendee == '\0') {
- attendee = GNOME_Evolution_Addressbook_SimpleCard_get (card, GNOME_Evolution_Addressbook_SimpleCard_Email, &ev);
- if (BONOBO_EX (&ev)) {
- CORBA_exception_free (&ev);
- continue;
- }
+ attendee = eab_destination_get_email (cards[i]);
}
- CORBA_exception_free (&ev);
-
if (attendee == NULL || *attendee == '\0')
continue;
@@ -381,22 +359,21 @@ static void
select_names_ok_cb (BonoboListener *listener, const char *event_name, const CORBA_any *arg, CORBA_Environment *ev, gpointer data)
{
EMeetingListView *view = E_MEETING_LIST_VIEW (data);
- BonoboArg *card_arg;
int i;
for (i = 0; sections[i] != NULL; i++) {
+ EABDestination **destv;
+ char *string = NULL;
Bonobo_Control corba_control = GNOME_Evolution_Addressbook_SelectNames_getEntryBySection
(view->priv->corba_select_names, sections[i], ev);
GtkWidget *control_widget = bonobo_widget_new_control_from_objref (corba_control, CORBA_OBJECT_NIL);
- BonoboControlFrame *control_frame = bonobo_widget_get_control_frame (BONOBO_WIDGET (control_widget));
- Bonobo_PropertyBag pb = bonobo_control_frame_get_control_property_bag (control_frame, NULL);
- card_arg = bonobo_property_bag_client_get_value_any (pb, "simple_card_list", NULL);
- if (card_arg != NULL) {
- GNOME_Evolution_Addressbook_SimpleCardList cards;
- cards = BONOBO_ARG_GET_GENERAL (card_arg, TC_GNOME_Evolution_Addressbook_SimpleCardList,
- GNOME_Evolution_Addressbook_SimpleCardList, NULL);
- process_section (view, &cards, roles[i]);
- bonobo_arg_release (card_arg);
+
+ bonobo_widget_get_property (BONOBO_WIDGET (control_widget), "destinations",
+ TC_CORBA_string, &string, NULL);
+ destv = eab_destination_importv (string);
+ if (destv) {
+ process_section (view, destv, roles[i]);
+ g_free (destv);
}
}
}
diff --git a/calendar/gui/e-meeting-model.c b/calendar/gui/e-meeting-model.c
new file mode 100644
index 0000000000..4742116cf2
--- /dev/null
+++ b/calendar/gui/e-meeting-model.c
@@ -0,0 +1,1780 @@
+/* -*- Mod:e C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* itip-model.c
+ *
+ * Copyright (C) 2001 Ximian, Inc.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: JP Rosevear
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <bonobo/bonobo-control.h>
+#include <bonobo/bonobo-widget.h>
+#include <bonobo/bonobo-exception.h>
+#include <libgnome/gnome-i18n.h>
+#include <libgnome/gnome-util.h>
+#include <libgnomevfs/gnome-vfs.h>
+#include <gal/e-table/e-table-without.h>
+#include <gal/e-table/e-cell-text.h>
+#include <gal/e-table/e-cell-popup.h>
+#include <gal/e-table/e-cell-combo.h>
+#include <addressbook/util/eab-destination.h>
+#include <ebook/e-book.h>
+#include <ebook/e-book-async.h>
+#include <ebook/e-contact.h>
+#include <cal-util/cal-component.h>
+#include <cal-util/cal-util.h>
+#include <cal-util/timeutil.h>
+#include "Evolution-Addressbook-SelectNames.h"
+#include "calendar-config.h"
+#include "itip-utils.h"
+#include "e-meeting-utils.h"
+#include "e-meeting-attendee.h"
+#include "e-meeting-model.h"
+
+#define SELECT_NAMES_OAFID "OAFIID:GNOME_Evolution_Addressbook_SelectNames"
+
+struct _EMeetingModelPrivate
+{
+ GPtrArray *attendees;
+
+ GList *tables;
+
+ CalClient *client;
+ icaltimezone *zone;
+
+ EBook *ebook;
+ gboolean book_loaded;
+ gboolean book_load_wait;
+
+ GPtrArray *refresh_queue;
+ GHashTable *refresh_data;
+ guint refresh_idle_id;
+
+ /* For invite others dialogs */
+ GNOME_Evolution_Addressbook_SelectNames corba_select_names;
+};
+
+#define BUF_SIZE 1024
+
+static char *sections[] = {N_("Chair Persons"),
+ N_("Required Participants"),
+ N_("Optional Participants"),
+ N_("Resources"),
+ NULL};
+static icalparameter_role roles[] = {ICAL_ROLE_CHAIR,
+ ICAL_ROLE_REQPARTICIPANT,
+ ICAL_ROLE_OPTPARTICIPANT,
+ ICAL_ROLE_NONPARTICIPANT,
+ ICAL_ROLE_NONE};
+
+typedef struct _EMeetingModelQueueData EMeetingModelQueueData;
+struct _EMeetingModelQueueData {
+ EMeetingModel *im;
+ EMeetingAttendee *ia;
+
+ gboolean refreshing;
+
+ EMeetingTime start;
+ EMeetingTime end;
+
+ char buffer[BUF_SIZE];
+ GString *string;
+
+ GPtrArray *call_backs;
+ GPtrArray *data;
+};
+
+
+static void class_init (EMeetingModelClass *klass);
+static void init (EMeetingModel *model);
+static void finalize (GObject *obj);
+
+static void refresh_queue_add (EMeetingModel *im, int row,
+ EMeetingTime *start,
+ EMeetingTime *end,
+ EMeetingModelRefreshCallback call_back,
+ gpointer data);
+static void refresh_queue_remove (EMeetingModel *im,
+ EMeetingAttendee *ia);
+static gboolean refresh_busy_periods (gpointer data);
+
+static void attendee_changed_cb (EMeetingAttendee *ia, gpointer data);
+static void select_names_ok_cb (BonoboListener *listener,
+ const char *event_name,
+ const CORBA_any *arg,
+ CORBA_Environment *ev,
+ gpointer data);
+
+static void table_destroy_state_cb (ETableScrolled *etable, gpointer data);
+static void table_destroy_list_cb (ETableScrolled *etable, gpointer data);
+
+static ETableModelClass *parent_class = NULL;
+
+E_MAKE_TYPE (e_meeting_model, "EMeetingModel", EMeetingModel,
+ class_init, init, E_TABLE_MODEL_TYPE);
+
+static void
+book_open_cb (EBook *book, EBookStatus status, gpointer data)
+{
+ EMeetingModel *im = E_MEETING_MODEL (data);
+ EMeetingModelPrivate *priv;
+
+ priv = im->priv;
+
+ priv->ebook = book;
+
+ if (status == E_BOOK_ERROR_OK)
+ priv->book_loaded = TRUE;
+ else
+ g_warning ("Book not loaded");
+
+ if (priv->book_load_wait) {
+ priv->book_load_wait = FALSE;
+ gtk_main_quit ();
+ }
+}
+
+static void
+start_addressbook_server (EMeetingModel *im)
+{
+ e_book_async_get_default_addressbook (book_open_cb, im);
+}
+
+static EMeetingAttendee *
+find_match (EMeetingModel *im, const char *address, int *pos)
+{
+ EMeetingModelPrivate *priv;
+ EMeetingAttendee *ia;
+ const gchar *ia_address;
+ int i;
+
+ priv = im->priv;
+
+ if (address == NULL)
+ return NULL;
+
+ /* Make sure we can add the new delegatee person */
+ for (i = 0; i < priv->attendees->len; i++) {
+ ia = g_ptr_array_index (priv->attendees, i);
+
+ ia_address = e_meeting_attendee_get_address (ia);
+ if (ia_address != NULL && !g_strcasecmp (itip_strip_mailto (ia_address), itip_strip_mailto (address))) {
+ if (pos != NULL)
+ *pos = i;
+ return ia;
+ }
+ }
+
+ return NULL;
+}
+
+static icalparameter_cutype
+text_to_type (const char *type)
+{
+ if (!g_strcasecmp (type, _("Individual")))
+ return ICAL_CUTYPE_INDIVIDUAL;
+ else if (!g_strcasecmp (type, _("Group")))
+ return ICAL_CUTYPE_GROUP;
+ else if (!g_strcasecmp (type, _("Resource")))
+ return ICAL_CUTYPE_RESOURCE;
+ else if (!g_strcasecmp (type, _("Room")))
+ return ICAL_CUTYPE_ROOM;
+ else
+ return ICAL_CUTYPE_NONE;
+}
+
+static char *
+type_to_text (icalparameter_cutype type)
+{
+ switch (type) {
+ case ICAL_CUTYPE_INDIVIDUAL:
+ return _("Individual");
+ case ICAL_CUTYPE_GROUP:
+ return _("Group");
+ case ICAL_CUTYPE_RESOURCE:
+ return _("Resource");
+ case ICAL_CUTYPE_ROOM:
+ return _("Room");
+ default:
+ return _("Unknown");
+ }
+
+ return NULL;
+
+}
+
+static icalparameter_role
+text_to_role (const char *role)
+{
+ if (!g_strcasecmp (role, _("Chair")))
+ return ICAL_ROLE_CHAIR;
+ else if (!g_strcasecmp (role, _("Required Participant")))
+ return ICAL_ROLE_REQPARTICIPANT;
+ else if (!g_strcasecmp (role, _("Optional Participant")))
+ return ICAL_ROLE_OPTPARTICIPANT;
+ else if (!g_strcasecmp (role, _("Non-Participant")))
+ return ICAL_ROLE_NONPARTICIPANT;
+ else
+ return ICAL_ROLE_NONE;
+}
+
+static char *
+role_to_text (icalparameter_role role)
+{
+ switch (role) {
+ case ICAL_ROLE_CHAIR:
+ return _("Chair");
+ case ICAL_ROLE_REQPARTICIPANT:
+ return _("Required Participant");
+ case ICAL_ROLE_OPTPARTICIPANT:
+ return _("Optional Participant");
+ case ICAL_ROLE_NONPARTICIPANT:
+ return _("Non-Participant");
+ default:
+ return _("Unknown");
+ }
+
+ return NULL;
+}
+
+static gboolean
+text_to_boolean (const char *role)
+{
+ if (!g_strcasecmp (role, _("Yes")))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static char *
+boolean_to_text (gboolean b)
+{
+ if (b)
+ return _("Yes");
+ else
+ return _("No");
+}
+
+static icalparameter_partstat
+text_to_partstat (const char *partstat)
+{
+ if (!g_strcasecmp (partstat, _("Needs Action")))
+ return ICAL_PARTSTAT_NEEDSACTION;
+ else if (!g_strcasecmp (partstat, _("Accepted")))
+ return ICAL_PARTSTAT_ACCEPTED;
+ else if (!g_strcasecmp (partstat, _("Declined")))
+ return ICAL_PARTSTAT_DECLINED;
+ else if (!g_strcasecmp (partstat, _("Tentative")))
+ return ICAL_PARTSTAT_TENTATIVE;
+ else if (!g_strcasecmp (partstat, _("Delegated")))
+ return ICAL_PARTSTAT_DELEGATED;
+ else if (!g_strcasecmp (partstat, _("Completed")))
+ return ICAL_PARTSTAT_COMPLETED;
+ else if (!g_strcasecmp (partstat, _("In Process")))
+ return ICAL_PARTSTAT_INPROCESS;
+ else
+ return ICAL_PARTSTAT_NONE;
+}
+
+static char *
+partstat_to_text (icalparameter_partstat partstat)
+{
+ switch (partstat) {
+ case ICAL_PARTSTAT_NEEDSACTION:
+ return _("Needs Action");
+ case ICAL_PARTSTAT_ACCEPTED:
+ return _("Accepted");
+ case ICAL_PARTSTAT_DECLINED:
+ return _("Declined");
+ case ICAL_PARTSTAT_TENTATIVE:
+ return _("Tentative");
+ case ICAL_PARTSTAT_DELEGATED:
+ return _("Delegated");
+ case ICAL_PARTSTAT_COMPLETED:
+ return _("Completed");
+ case ICAL_PARTSTAT_INPROCESS:
+ return _("In Process");
+ case ICAL_PARTSTAT_NONE:
+ default:
+ return _("Unknown");
+ }
+
+ return NULL;
+}
+
+static int
+column_count (ETableModel *etm)
+{
+ return E_MEETING_MODEL_COLUMN_COUNT;
+}
+
+static int
+row_count (ETableModel *etm)
+{
+ EMeetingModel *im;
+ EMeetingModelPrivate *priv;
+
+ im = E_MEETING_MODEL (etm);
+ priv = im->priv;
+
+ return (priv->attendees->len);
+}
+
+static void
+append_row (ETableModel *etm, ETableModel *source, int row)
+{
+ EMeetingModel *im;
+ EMeetingModelPrivate *priv;
+ EMeetingAttendee *ia;
+ char *address;
+
+ im = E_MEETING_MODEL (etm);
+ priv = im->priv;
+
+ address = (char *) e_table_model_value_at (source, E_MEETING_MODEL_ADDRESS_COL, row);
+ if (find_match (im, address, NULL) != NULL) {
+ return;
+ }
+
+ ia = E_MEETING_ATTENDEE (e_meeting_attendee_new ());
+
+ e_meeting_attendee_set_address (ia, g_strdup_printf ("MAILTO:%s", address));
+ e_meeting_attendee_set_member (ia, g_strdup (e_table_model_value_at (source, E_MEETING_MODEL_MEMBER_COL, row)));
+ e_meeting_attendee_set_cutype (ia, text_to_type (e_table_model_value_at (source, E_MEETING_MODEL_TYPE_COL, row)));
+ e_meeting_attendee_set_role (ia, text_to_role (e_table_model_value_at (source, E_MEETING_MODEL_ROLE_COL, row)));
+ e_meeting_attendee_set_rsvp (ia, text_to_boolean (e_table_model_value_at (source, E_MEETING_MODEL_RSVP_COL, row)));
+ e_meeting_attendee_set_delto (ia, g_strdup (e_table_model_value_at (source, E_MEETING_MODEL_DELTO_COL, row)));
+ e_meeting_attendee_set_delfrom (ia, g_strdup (e_table_model_value_at (source, E_MEETING_MODEL_DELFROM_COL, row)));
+ e_meeting_attendee_set_status (ia, text_to_partstat (e_table_model_value_at (source, E_MEETING_MODEL_STATUS_COL, row)));
+ e_meeting_attendee_set_cn (ia, g_strdup (e_table_model_value_at (source, E_MEETING_MODEL_CN_COL, row)));
+ e_meeting_attendee_set_language (ia, g_strdup (e_table_model_value_at (source, E_MEETING_MODEL_LANGUAGE_COL, row)));
+
+ e_meeting_model_add_attendee (E_MEETING_MODEL (etm), ia);
+ g_object_unref (ia);
+}
+
+static void *
+value_at (ETableModel *etm, int col, int row)
+{
+ EMeetingModel *im;
+ EMeetingModelPrivate *priv;
+ EMeetingAttendee *ia;
+
+ im = E_MEETING_MODEL (etm);
+ priv = im->priv;
+
+ ia = g_ptr_array_index (priv->attendees, row);
+
+ switch (col) {
+ case E_MEETING_MODEL_ADDRESS_COL:
+ return (void *)itip_strip_mailto (e_meeting_attendee_get_address (ia));
+ case E_MEETING_MODEL_MEMBER_COL:
+ return (void *)e_meeting_attendee_get_member (ia);
+ case E_MEETING_MODEL_TYPE_COL:
+ return type_to_text (e_meeting_attendee_get_cutype (ia));
+ case E_MEETING_MODEL_ROLE_COL:
+ return role_to_text (e_meeting_attendee_get_role (ia));
+ case E_MEETING_MODEL_RSVP_COL:
+ return boolean_to_text (e_meeting_attendee_get_rsvp (ia));
+ case E_MEETING_MODEL_DELTO_COL:
+ return (void *)itip_strip_mailto (e_meeting_attendee_get_delto (ia));
+ case E_MEETING_MODEL_DELFROM_COL:
+ return (void *)itip_strip_mailto (e_meeting_attendee_get_delfrom (ia));
+ case E_MEETING_MODEL_STATUS_COL:
+ return partstat_to_text (e_meeting_attendee_get_status (ia));
+ case E_MEETING_MODEL_CN_COL:
+ return (void *)e_meeting_attendee_get_cn (ia);
+ case E_MEETING_MODEL_LANGUAGE_COL:
+ return (void *)e_meeting_attendee_get_language (ia);
+ }
+
+ return NULL;
+}
+
+static void
+set_value_at (ETableModel *etm, int col, int row, const void *val)
+{
+ EMeetingModel *im;
+ EMeetingModelPrivate *priv;
+ EMeetingAttendee *ia;
+ icalparameter_cutype type;
+
+ im = E_MEETING_MODEL (etm);
+ priv = im->priv;
+
+ ia = g_ptr_array_index (priv->attendees, row);
+
+ e_table_model_pre_change (etm);
+
+ switch (col) {
+ case E_MEETING_MODEL_ADDRESS_COL:
+ if (val != NULL && *((char *)val))
+ e_meeting_attendee_set_address (ia, g_strdup_printf ("MAILTO:%s", (char *) val));
+ break;
+ case E_MEETING_MODEL_MEMBER_COL:
+ e_meeting_attendee_set_member (ia, g_strdup (val));
+ break;
+ case E_MEETING_MODEL_TYPE_COL:
+ type = text_to_type (val);
+ e_meeting_attendee_set_cutype (ia, text_to_type (val));
+ if (type == ICAL_CUTYPE_RESOURCE) {
+ e_meeting_attendee_set_role (ia, ICAL_ROLE_NONPARTICIPANT);
+ e_table_model_cell_changed (etm, E_MEETING_MODEL_ROLE_COL, row);
+ }
+ break;
+ case E_MEETING_MODEL_ROLE_COL:
+ e_meeting_attendee_set_role (ia, text_to_role (val));
+ break;
+ case E_MEETING_MODEL_RSVP_COL:
+ e_meeting_attendee_set_rsvp (ia, text_to_boolean (val));
+ break;
+ case E_MEETING_MODEL_DELTO_COL:
+ e_meeting_attendee_set_delto (ia, g_strdup (val));
+ break;
+ case E_MEETING_MODEL_DELFROM_COL:
+ e_meeting_attendee_set_delfrom (ia, g_strdup (val));
+ break;
+ case E_MEETING_MODEL_STATUS_COL:
+ e_meeting_attendee_set_status (ia, text_to_partstat (val));
+ break;
+ case E_MEETING_MODEL_CN_COL:
+ e_meeting_attendee_set_cn (ia, g_strdup (val));
+ break;
+ case E_MEETING_MODEL_LANGUAGE_COL:
+ e_meeting_attendee_set_language (ia, g_strdup (val));
+ break;
+ }
+
+ e_table_model_cell_changed (etm, col, row);
+}
+
+static gboolean
+is_cell_editable (ETableModel *etm, int col, int row)
+{
+ EMeetingModel *im;
+ EMeetingModelPrivate *priv;
+ EMeetingAttendee *ia;
+ EMeetingAttendeeEditLevel level;
+
+ im = E_MEETING_MODEL (etm);
+ priv = im->priv;
+
+ if (col == E_MEETING_MODEL_DELTO_COL
+ || col == E_MEETING_MODEL_DELFROM_COL)
+ return FALSE;
+
+ if (row == -1)
+ return TRUE;
+ if (row >= priv->attendees->len)
+ return TRUE;
+
+ ia = g_ptr_array_index (priv->attendees, row);
+ level = e_meeting_attendee_get_edit_level (ia);
+
+ switch (level) {
+ case E_MEETING_ATTENDEE_EDIT_FULL:
+ return TRUE;
+ case E_MEETING_ATTENDEE_EDIT_STATUS:
+ return col == E_MEETING_MODEL_STATUS_COL;
+ case E_MEETING_ATTENDEE_EDIT_NONE:
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void *
+duplicate_value (ETableModel *etm, int col, const void *val)
+{
+ return g_strdup (val);
+}
+
+static void
+free_value (ETableModel *etm, int col, void *val)
+{
+ g_free (val);
+}
+
+static void *
+init_value (ETableModel *etm, int col)
+{
+ switch (col) {
+ case E_MEETING_MODEL_ADDRESS_COL:
+ return g_strdup ("");
+ case E_MEETING_MODEL_MEMBER_COL:
+ return g_strdup ("");
+ case E_MEETING_MODEL_TYPE_COL:
+ return g_strdup (_("Individual"));
+ case E_MEETING_MODEL_ROLE_COL:
+ return g_strdup (_("Required Participant"));
+ case E_MEETING_MODEL_RSVP_COL:
+ return g_strdup (_("Yes"));
+ case E_MEETING_MODEL_DELTO_COL:
+ return g_strdup ("");
+ case E_MEETING_MODEL_DELFROM_COL:
+ return g_strdup ("");
+ case E_MEETING_MODEL_STATUS_COL:
+ return g_strdup (_("Needs Action"));
+ case E_MEETING_MODEL_CN_COL:
+ return g_strdup ("");
+ case E_MEETING_MODEL_LANGUAGE_COL:
+ return g_strdup ("en");
+ }
+
+ return g_strdup ("");
+}
+
+static gboolean
+value_is_empty (ETableModel *etm, int col, const void *val)
+{
+
+ switch (col) {
+ case E_MEETING_MODEL_ADDRESS_COL:
+ case E_MEETING_MODEL_MEMBER_COL:
+ case E_MEETING_MODEL_DELTO_COL:
+ case E_MEETING_MODEL_DELFROM_COL:
+ case E_MEETING_MODEL_CN_COL:
+ if (val && !g_strcasecmp (val, ""))
+ return TRUE;
+ else
+ return FALSE;
+ default:
+ ;
+ }
+
+ return TRUE;
+}
+
+static char *
+value_to_string (ETableModel *etm, int col, const void *val)
+{
+ return g_strdup (val);
+}
+
+static void
+class_init (EMeetingModelClass *klass)
+{
+ GObjectClass *gobject_class;
+ ETableModelClass *etm_class;
+
+ gobject_class = G_OBJECT_CLASS (klass);
+ etm_class = E_TABLE_MODEL_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ gobject_class->finalize = finalize;
+
+ etm_class->column_count = column_count;
+ etm_class->row_count = row_count;
+ etm_class->value_at = value_at;
+ etm_class->set_value_at = set_value_at;
+ etm_class->is_cell_editable = is_cell_editable;
+ etm_class->append_row = append_row;
+ etm_class->duplicate_value = duplicate_value;
+ etm_class->free_value = free_value;
+ etm_class->initialize_value = init_value;
+ etm_class->value_is_empty = value_is_empty;
+ etm_class->value_to_string = value_to_string;
+}
+
+
+static void
+init (EMeetingModel *im)
+{
+ EMeetingModelPrivate *priv;
+
+ priv = g_new0 (EMeetingModelPrivate, 1);
+
+ im->priv = priv;
+
+ priv->attendees = g_ptr_array_new ();
+
+ priv->tables = NULL;
+
+ priv->client = NULL;
+ priv->zone = icaltimezone_get_builtin_timezone (calendar_config_get_timezone ());
+
+ priv->ebook = NULL;
+ priv->book_loaded = FALSE;
+ priv->book_load_wait = FALSE;
+
+ priv->refresh_queue = g_ptr_array_new ();
+ priv->refresh_data = g_hash_table_new (g_direct_hash, g_direct_equal);
+ priv->refresh_idle_id = 0;
+
+ priv->corba_select_names = CORBA_OBJECT_NIL;
+
+ start_addressbook_server (im);
+}
+
+static void
+finalize (GObject *obj)
+{
+ EMeetingModel *im = E_MEETING_MODEL (obj);
+ EMeetingModelPrivate *priv;
+ GList *l;
+ int i;
+
+ priv = im->priv;
+
+ for (i = 0; i < priv->attendees->len; i++)
+ g_object_unref (g_ptr_array_index (priv->attendees, i));
+ g_ptr_array_free (priv->attendees, TRUE);
+
+ for (l = priv->tables; l != NULL; l = l->next)
+ g_signal_handlers_disconnect_matched (G_OBJECT (l->data), G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, im);
+ g_list_free (priv->tables);
+
+ if (priv->client != NULL)
+ g_object_unref (priv->client);
+
+ if (priv->ebook != NULL)
+ g_object_unref (priv->ebook);
+
+ if (priv->corba_select_names != CORBA_OBJECT_NIL) {
+ CORBA_Environment ev;
+ CORBA_exception_init (&ev);
+ bonobo_object_release_unref (priv->corba_select_names, &ev);
+ CORBA_exception_free (&ev);
+ }
+
+ while (priv->refresh_queue->len > 0)
+ refresh_queue_remove (im, g_ptr_array_index (priv->refresh_queue, 0));
+ g_ptr_array_free (priv->refresh_queue, TRUE);
+ g_hash_table_destroy (priv->refresh_data);
+
+ if (priv->refresh_idle_id)
+ g_source_remove (priv->refresh_idle_id);
+
+ g_free (priv);
+
+ if (G_OBJECT_CLASS (parent_class)->finalize)
+ (* G_OBJECT_CLASS (parent_class)->finalize) (obj);
+}
+
+GtkObject *
+e_meeting_model_new (void)
+{
+ return g_object_new (E_TYPE_MEETING_MODEL, NULL);
+}
+
+
+CalClient *
+e_meeting_model_get_cal_client (EMeetingModel *im)
+{
+ EMeetingModelPrivate *priv;
+
+ priv = im->priv;
+
+ return priv->client;
+}
+
+void
+e_meeting_model_set_cal_client (EMeetingModel *im, CalClient *client)
+{
+ EMeetingModelPrivate *priv;
+
+ priv = im->priv;
+
+ if (priv->client != NULL)
+ g_object_unref (priv->client);
+
+ if (client != NULL)
+ g_object_ref (client);
+ priv->client = client;
+}
+
+icaltimezone *
+e_meeting_model_get_zone (EMeetingModel *im)
+{
+ EMeetingModelPrivate *priv;
+
+ g_return_val_if_fail (im != NULL, NULL);
+ g_return_val_if_fail (E_IS_MEETING_MODEL (im), NULL);
+
+ priv = im->priv;
+
+ return priv->zone;
+}
+
+void
+e_meeting_model_set_zone (EMeetingModel *im, icaltimezone *zone)
+{
+ EMeetingModelPrivate *priv;
+
+ g_return_if_fail (im != NULL);
+ g_return_if_fail (E_IS_MEETING_MODEL (im));
+
+ priv = im->priv;
+
+ priv->zone = zone;
+}
+
+static ETableScrolled *
+build_etable (ETableModel *model, const gchar *spec_file, const gchar *state_file)
+{
+ GtkWidget *etable;
+ ETable *real_table;
+ ETableExtras *extras;
+ GList *strings;
+ ECell *popup_cell, *cell;
+
+ extras = e_table_extras_new ();
+
+ /* For type */
+ cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT);
+ popup_cell = e_cell_combo_new ();
+ e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell);
+ g_object_unref (cell);
+
+ strings = NULL;
+ strings = g_list_append (strings, (char*) _("Individual"));
+ strings = g_list_append (strings, (char*) _("Group"));
+ strings = g_list_append (strings, (char*) _("Resource"));
+ strings = g_list_append (strings, (char*) _("Room"));
+ strings = g_list_append (strings, (char*) _("Unknown"));
+
+ e_cell_combo_set_popdown_strings (E_CELL_COMBO (popup_cell), strings);
+ e_table_extras_add_cell (extras, "typeedit", popup_cell);
+
+ /* For role */
+ cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT);
+ popup_cell = e_cell_combo_new ();
+ e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell);
+ g_object_unref (cell);
+
+ strings = NULL;
+ strings = g_list_append (strings, (char*) _("Chair"));
+ strings = g_list_append (strings, (char*) _("Required Participant"));
+ strings = g_list_append (strings, (char*) _("Optional Participant"));
+ strings = g_list_append (strings, (char*) _("Non-Participant"));
+ strings = g_list_append (strings, (char*) _("Unknown"));
+
+ e_cell_combo_set_popdown_strings (E_CELL_COMBO (popup_cell), strings);
+ e_table_extras_add_cell (extras, "roleedit", popup_cell);
+
+ /* For rsvp */
+ cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT);
+ popup_cell = e_cell_combo_new ();
+ e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell);
+ g_object_unref (cell);
+
+ strings = NULL;
+ strings = g_list_append (strings, (char*) _("Yes"));
+ strings = g_list_append (strings, (char*) _("No"));
+
+ e_cell_combo_set_popdown_strings (E_CELL_COMBO (popup_cell), strings);
+ e_table_extras_add_cell (extras, "rsvpedit", popup_cell);
+
+ /* For status */
+ cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT);
+ popup_cell = e_cell_combo_new ();
+ e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell);
+ g_object_unref (cell);
+
+ strings = NULL;
+ strings = g_list_append (strings, (char*) _("Needs Action"));
+ strings = g_list_append (strings, (char*) _("Accepted"));
+ strings = g_list_append (strings, (char*) _("Declined"));
+ strings = g_list_append (strings, (char*) _("Tentative"));
+ strings = g_list_append (strings, (char*) _("Delegated"));
+
+ e_cell_combo_set_popdown_strings (E_CELL_COMBO (popup_cell), strings);
+ e_table_extras_add_cell (extras, "statusedit", popup_cell);
+
+ etable = e_table_scrolled_new_from_spec_file (model, extras, spec_file, NULL);
+ real_table = e_table_scrolled_get_table (E_TABLE_SCROLLED (etable));
+ g_object_set (G_OBJECT (real_table), "uniform_row_height", TRUE, NULL);
+ e_table_load_state (real_table, state_file);
+
+#if 0
+ g_signal_connect (real_table, "right_click", G_CALLBACK (right_click_cb), mpage);
+#endif
+
+ g_signal_connect (etable, "destroy", G_CALLBACK (table_destroy_state_cb), g_strdup (state_file));
+
+ g_object_unref (extras);
+
+ return E_TABLE_SCROLLED (etable);
+}
+
+void
+e_meeting_model_add_attendee (EMeetingModel *im, EMeetingAttendee *ia)
+{
+ EMeetingModelPrivate *priv;
+
+ priv = im->priv;
+
+ e_table_model_pre_change (E_TABLE_MODEL (im));
+
+ g_object_ref (ia);
+ g_ptr_array_add (priv->attendees, ia);
+
+ g_signal_connect (ia, "changed", G_CALLBACK (attendee_changed_cb), im);
+
+ e_table_model_row_inserted (E_TABLE_MODEL (im), row_count (E_TABLE_MODEL (im)) - 1);
+}
+
+EMeetingAttendee *
+e_meeting_model_add_attendee_with_defaults (EMeetingModel *im)
+{
+ EMeetingAttendee *ia;
+ char *str;
+
+ ia = E_MEETING_ATTENDEE (e_meeting_attendee_new ());
+
+ e_meeting_attendee_set_address (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_ADDRESS_COL));
+ e_meeting_attendee_set_member (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_MEMBER_COL));
+
+ str = init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_TYPE_COL);
+ e_meeting_attendee_set_cutype (ia, text_to_type (str));
+ g_free (str);
+ str = init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_ROLE_COL);
+ e_meeting_attendee_set_role (ia, text_to_role (str));
+ g_free (str);
+ str = init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_RSVP_COL);
+ e_meeting_attendee_set_rsvp (ia, text_to_boolean (str));
+ g_free (str);
+
+ e_meeting_attendee_set_delto (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_DELTO_COL));
+ e_meeting_attendee_set_delfrom (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_DELFROM_COL));
+
+ str = init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_STATUS_COL);
+ e_meeting_attendee_set_status (ia, text_to_partstat (str));
+ g_free (str);
+
+ e_meeting_attendee_set_cn (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_CN_COL));
+ e_meeting_attendee_set_language (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_LANGUAGE_COL));
+
+ e_meeting_model_add_attendee (im, ia);
+
+ return ia;
+}
+
+void
+e_meeting_model_remove_attendee (EMeetingModel *im, EMeetingAttendee *ia)
+{
+ EMeetingModelPrivate *priv;
+ gint i, row = -1;
+
+ priv = im->priv;
+
+ for (i = 0; i < priv->attendees->len; i++) {
+ if (ia == g_ptr_array_index (priv->attendees, i)) {
+ row = i;
+ break;
+ }
+ }
+
+ if (row != -1) {
+ e_table_model_pre_change (E_TABLE_MODEL (im));
+
+ g_ptr_array_remove_index (priv->attendees, row);
+ g_object_unref (ia);
+
+ e_table_model_row_deleted (E_TABLE_MODEL (im), row);
+ }
+}
+
+void
+e_meeting_model_remove_all_attendees (EMeetingModel *im)
+{
+ EMeetingModelPrivate *priv;
+ gint i, len;
+
+ priv = im->priv;
+
+ e_table_model_pre_change (E_TABLE_MODEL (im));
+
+ len = priv->attendees->len;
+
+ for (i = 0; i < len; i++) {
+ EMeetingAttendee *ia = g_ptr_array_index (priv->attendees, i);
+ g_object_unref (ia);
+ }
+ g_ptr_array_set_size (priv->attendees, 0);
+
+ e_table_model_rows_deleted (E_TABLE_MODEL (im), 0, len);
+}
+
+EMeetingAttendee *
+e_meeting_model_find_attendee (EMeetingModel *im, const gchar *address, gint *row)
+{
+ EMeetingModelPrivate *priv;
+ EMeetingAttendee *ia;
+ int i;
+
+ priv = im->priv;
+
+ if (address == NULL)
+ return NULL;
+
+ for (i = 0; i < priv->attendees->len; i++) {
+ const gchar *ia_address;
+
+ ia = g_ptr_array_index (priv->attendees, i);
+
+ ia_address = e_meeting_attendee_get_address (ia);
+ if (ia_address && !g_strcasecmp (itip_strip_mailto (ia_address), itip_strip_mailto (address))) {
+ if (row != NULL)
+ *row = i;
+
+ return ia;
+ }
+ }
+
+ return NULL;
+}
+
+EMeetingAttendee *
+e_meeting_model_find_attendee_at_row (EMeetingModel *im, gint row)
+{
+ EMeetingModelPrivate *priv;
+
+ g_return_val_if_fail (im != NULL, NULL);
+ g_return_val_if_fail (E_IS_MEETING_MODEL (im), NULL);
+ g_return_val_if_fail (row >= 0, NULL);
+
+ priv = im->priv;
+ g_return_val_if_fail (row < priv->attendees->len, NULL);
+
+ return g_ptr_array_index (priv->attendees, row);
+}
+
+gint
+e_meeting_model_count_actual_attendees (EMeetingModel *im)
+{
+ EMeetingModelPrivate *priv;
+
+ priv = im->priv;
+
+ return e_table_model_row_count (E_TABLE_MODEL (im));
+}
+
+const GPtrArray *
+e_meeting_model_get_attendees (EMeetingModel *im)
+{
+ EMeetingModelPrivate *priv;
+
+ priv = im->priv;
+
+ return priv->attendees;
+}
+
+static icaltimezone *
+find_zone (icalproperty *ip, icalcomponent *tz_top_level)
+{
+ icalparameter *param;
+ icalcomponent *sub_comp;
+ const char *tzid;
+ icalcompiter iter;
+
+ if (tz_top_level == NULL)
+ return NULL;
+
+ param = icalproperty_get_first_parameter (ip, ICAL_TZID_PARAMETER);
+ if (param == NULL)
+ return NULL;
+ tzid = icalparameter_get_tzid (param);
+
+ iter = icalcomponent_begin_component (tz_top_level, ICAL_VTIMEZONE_COMPONENT);
+ while ((sub_comp = icalcompiter_deref (&iter)) != NULL) {
+ icalcomponent *clone;
+ const char *tz_tzid;
+
+ /* FIXME We aren't passing a property here */
+ tz_tzid = icalproperty_get_tzid (sub_comp);
+ if (!strcmp (tzid, tz_tzid)) {
+ icaltimezone *zone;
+
+ zone = icaltimezone_new ();
+ clone = icalcomponent_new_clone (sub_comp);
+ icaltimezone_set_component (zone, clone);
+
+ return zone;
+ }
+
+ icalcompiter_next (&iter);
+ }
+
+ return NULL;
+}
+
+
+static void
+refresh_queue_add (EMeetingModel *im, int row,
+ EMeetingTime *start,
+ EMeetingTime *end,
+ EMeetingModelRefreshCallback call_back,
+ gpointer data)
+{
+ EMeetingModelPrivate *priv;
+ EMeetingAttendee *ia;
+ EMeetingModelQueueData *qdata;
+
+ priv = im->priv;
+
+ ia = g_ptr_array_index (priv->attendees, row);
+ if (ia == NULL)
+ return;
+
+ qdata = g_hash_table_lookup (priv->refresh_data, ia);
+ if (qdata == NULL) {
+ qdata = g_new0 (EMeetingModelQueueData, 1);
+
+ qdata->im = im;
+ qdata->ia = ia;
+ e_meeting_attendee_clear_busy_periods (ia);
+ e_meeting_attendee_set_has_calendar_info (ia, FALSE);
+
+ qdata->start = *start;
+ qdata->end = *end;
+ qdata->string = g_string_new (NULL);
+ qdata->call_backs = g_ptr_array_new ();
+ qdata->data = g_ptr_array_new ();
+ g_ptr_array_add (qdata->call_backs, call_back);
+ g_ptr_array_add (qdata->data, data);
+
+ g_hash_table_insert (priv->refresh_data, ia, qdata);
+ } else {
+ if (e_meeting_time_compare_times (start, &qdata->start) == -1)
+ qdata->start = *start;
+ if (e_meeting_time_compare_times (end, &qdata->end) == 1)
+ qdata->end = *end;
+ g_ptr_array_add (qdata->call_backs, call_back);
+ g_ptr_array_add (qdata->data, data);
+ }
+
+ g_object_ref (ia);
+ g_ptr_array_add (priv->refresh_queue, ia);
+
+ if (priv->refresh_idle_id == 0)
+ priv->refresh_idle_id = g_idle_add (refresh_busy_periods, im);
+}
+
+static void
+refresh_queue_remove (EMeetingModel *im, EMeetingAttendee *ia)
+{
+ EMeetingModelPrivate *priv;
+ EMeetingModelQueueData *qdata;
+
+ priv = im->priv;
+
+ /* Free the queue data */
+ qdata = g_hash_table_lookup (priv->refresh_data, ia);
+ g_assert (qdata != NULL);
+
+ g_hash_table_remove (priv->refresh_data, ia);
+ g_ptr_array_free (qdata->call_backs, TRUE);
+ g_ptr_array_free (qdata->data, TRUE);
+ g_free (qdata);
+
+ /* Unref the attendee */
+ g_ptr_array_remove (priv->refresh_queue, ia);
+ g_object_unref (ia);
+}
+
+static void
+process_callbacks (EMeetingModelQueueData *qdata)
+{
+ EMeetingModel *im;
+ int i;
+
+ for (i = 0; i < qdata->call_backs->len; i++) {
+ EMeetingModelRefreshCallback call_back;
+ gpointer *data;
+
+ call_back = g_ptr_array_index (qdata->call_backs, i);
+ data = g_ptr_array_index (qdata->data, i);
+
+ call_back (data);
+ }
+
+ im = qdata->im;
+ refresh_queue_remove (qdata->im, qdata->ia);
+ g_object_unref (im);
+}
+
+static void
+process_free_busy_comp (EMeetingAttendee *ia,
+ icalcomponent *fb_comp,
+ icaltimezone *zone,
+ icalcomponent *tz_top_level)
+{
+ icalproperty *ip;
+
+ ip = icalcomponent_get_first_property (fb_comp, ICAL_DTSTART_PROPERTY);
+ if (ip != NULL) {
+ struct icaltimetype dtstart;
+ icaltimezone *ds_zone;
+
+ dtstart = icalproperty_get_dtstart (ip);
+ if (!dtstart.is_utc)
+ ds_zone = find_zone (ip, tz_top_level);
+ else
+ ds_zone = icaltimezone_get_utc_timezone ();
+ icaltimezone_convert_time (&dtstart, ds_zone, zone);
+ e_meeting_attendee_set_start_busy_range (ia,
+ dtstart.year,
+ dtstart.month,
+ dtstart.day,
+ dtstart.hour,
+ dtstart.minute);
+ }
+
+ ip = icalcomponent_get_first_property (fb_comp, ICAL_DTEND_PROPERTY);
+ if (ip != NULL) {
+ struct icaltimetype dtend;
+ icaltimezone *de_zone;
+
+ dtend = icalproperty_get_dtend (ip);
+ if (!dtend.is_utc)
+ de_zone = find_zone (ip, tz_top_level);
+ else
+ de_zone = icaltimezone_get_utc_timezone ();
+ icaltimezone_convert_time (&dtend, de_zone, zone);
+ e_meeting_attendee_set_end_busy_range (ia,
+ dtend.year,
+ dtend.month,
+ dtend.day,
+ dtend.hour,
+ dtend.minute);
+ }
+
+ ip = icalcomponent_get_first_property (fb_comp, ICAL_FREEBUSY_PROPERTY);
+ while (ip != NULL) {
+ icalparameter *param;
+ struct icalperiodtype fb;
+ EMeetingFreeBusyType busy_type = E_MEETING_FREE_BUSY_LAST;
+ icalparameter_fbtype fbtype = ICAL_FBTYPE_BUSY;
+
+ fb = icalproperty_get_freebusy (ip);
+ param = icalproperty_get_first_parameter (ip, ICAL_FBTYPE_PARAMETER);
+ if (param != NULL)
+ fbtype = icalparameter_get_fbtype (param);
+
+ switch (fbtype) {
+ case ICAL_FBTYPE_BUSY:
+ busy_type = E_MEETING_FREE_BUSY_BUSY;
+ break;
+
+ case ICAL_FBTYPE_BUSYUNAVAILABLE:
+ busy_type = E_MEETING_FREE_BUSY_OUT_OF_OFFICE;
+ break;
+
+ case ICAL_FBTYPE_BUSYTENTATIVE:
+ busy_type = E_MEETING_FREE_BUSY_TENTATIVE;
+ break;
+
+ default:
+ break;
+ }
+
+ if (busy_type != E_MEETING_FREE_BUSY_LAST) {
+ icaltimezone *utc_zone = icaltimezone_get_utc_timezone ();
+
+ icaltimezone_convert_time (&fb.start, utc_zone, zone);
+ icaltimezone_convert_time (&fb.end, utc_zone, zone);
+ e_meeting_attendee_add_busy_period (ia,
+ fb.start.year,
+ fb.start.month,
+ fb.start.day,
+ fb.start.hour,
+ fb.start.minute,
+ fb.end.year,
+ fb.end.month,
+ fb.end.day,
+ fb.end.hour,
+ fb.end.minute,
+ busy_type);
+ }
+
+ ip = icalcomponent_get_next_property (fb_comp, ICAL_FREEBUSY_PROPERTY);
+ }
+}
+
+static void
+process_free_busy (EMeetingModelQueueData *qdata, char *text)
+{
+ EMeetingModel *im = qdata->im;
+ EMeetingModelPrivate *priv;
+ EMeetingAttendee *ia = qdata->ia;
+ icalcomponent *main_comp;
+ icalcomponent_kind kind = ICAL_NO_COMPONENT;
+
+ priv = im->priv;
+
+ main_comp = icalparser_parse_string (text);
+ if (main_comp == NULL) {
+ process_callbacks (qdata);
+ return;
+ }
+
+ kind = icalcomponent_isa (main_comp);
+ if (kind == ICAL_VCALENDAR_COMPONENT) {
+ icalcompiter iter;
+ icalcomponent *tz_top_level, *sub_comp;
+
+ tz_top_level = cal_util_new_top_level ();
+
+ iter = icalcomponent_begin_component (main_comp, ICAL_VTIMEZONE_COMPONENT);
+ while ((sub_comp = icalcompiter_deref (&iter)) != NULL) {
+ icalcomponent *clone;
+
+ clone = icalcomponent_new_clone (sub_comp);
+ icalcomponent_add_component (tz_top_level, clone);
+
+ icalcompiter_next (&iter);
+ }
+
+ iter = icalcomponent_begin_component (main_comp, ICAL_VFREEBUSY_COMPONENT);
+ while ((sub_comp = icalcompiter_deref (&iter)) != NULL) {
+ process_free_busy_comp (ia, sub_comp, priv->zone, tz_top_level);
+
+ icalcompiter_next (&iter);
+ }
+ icalcomponent_free (tz_top_level);
+ } else if (kind == ICAL_VFREEBUSY_COMPONENT) {
+ process_free_busy_comp (ia, main_comp, priv->zone, NULL);
+ }
+
+ icalcomponent_free (main_comp);
+
+ process_callbacks (qdata);
+}
+
+static void
+async_close (GnomeVFSAsyncHandle *handle,
+ GnomeVFSResult result,
+ gpointer data)
+{
+ EMeetingModelQueueData *qdata = data;
+
+ process_free_busy (qdata, qdata->string->str);
+}
+
+static void
+async_read (GnomeVFSAsyncHandle *handle,
+ GnomeVFSResult result,
+ gpointer buffer,
+ GnomeVFSFileSize requested,
+ GnomeVFSFileSize read,
+ gpointer data)
+{
+ EMeetingModelQueueData *qdata = data;
+ GnomeVFSFileSize buf_size = BUF_SIZE - 1;
+
+ if (result != GNOME_VFS_OK && result != GNOME_VFS_ERROR_EOF) {
+ gnome_vfs_async_close (handle, async_close, qdata);
+ return;
+ }
+
+ ((char *)buffer)[read] = '\0';
+ qdata->string = g_string_append (qdata->string, buffer);
+
+ if (result == GNOME_VFS_ERROR_EOF) {
+ gnome_vfs_async_close (handle, async_close, qdata);
+ return;
+ }
+
+ gnome_vfs_async_read (handle, qdata->buffer, buf_size, async_read, qdata);
+}
+
+static void
+async_open (GnomeVFSAsyncHandle *handle,
+ GnomeVFSResult result,
+ gpointer data)
+{
+ EMeetingModelQueueData *qdata = data;
+ GnomeVFSFileSize buf_size = BUF_SIZE - 1;
+
+ if (result != GNOME_VFS_OK) {
+ gnome_vfs_async_close (handle, async_close, qdata);
+ return;
+ }
+
+ gnome_vfs_async_read (handle, qdata->buffer, buf_size, async_read, qdata);
+}
+
+static void
+contacts_cb (EBook *book, EBookStatus status, GList *contacts, gpointer data)
+{
+ EMeetingModelQueueData *qdata = data;
+ GList *l;
+
+ if (status != E_BOOK_ERROR_OK)
+ return;
+
+ for (l = contacts; l; l = l->next) {
+ GnomeVFSAsyncHandle *handle;
+ EContact *contact = E_CONTACT (l->data);
+ const char *fburl = e_contact_get_const (contact, E_CONTACT_FREEBUSY_URL);
+
+ if (!fburl || !*fburl)
+ continue;
+
+ /* Read in free/busy data from the url */
+ gnome_vfs_async_open (&handle, fburl, GNOME_VFS_OPEN_READ,
+ GNOME_VFS_PRIORITY_DEFAULT, async_open, qdata);
+
+ e_free_object_list (contacts);
+ return;
+ }
+
+ process_callbacks (qdata);
+ e_free_object_list (contacts);
+}
+
+static gboolean
+refresh_busy_periods (gpointer data)
+{
+ EMeetingModel *im = E_MEETING_MODEL (data);
+ EMeetingModelPrivate *priv;
+ EMeetingAttendee *ia = NULL;
+ EMeetingModelQueueData *qdata = NULL;
+ char *query;
+ int i;
+
+ priv = im->priv;
+
+ /* Check to see if there are any remaining attendees in the queue */
+ for (i = 0; i < priv->refresh_queue->len; i++) {
+ ia = g_ptr_array_index (priv->refresh_queue, i);
+ g_assert (ia != NULL);
+
+ qdata = g_hash_table_lookup (priv->refresh_data, ia);
+ g_assert (qdata != NULL);
+
+ if (!qdata->refreshing)
+ break;
+ }
+
+ /* The everything in the queue is being refreshed */
+ if (i >= priv->refresh_queue->len) {
+ priv->refresh_idle_id = 0;
+ return FALSE;
+ }
+
+ /* Indicate we are trying to refresh it */
+ qdata->refreshing = TRUE;
+
+ /* We take a ref in case we get destroyed in the gui during a callback */
+ g_object_ref (qdata->im);
+
+ /* Check the server for free busy data */
+ if (priv->client) {
+ GList *fb_data = NULL, *users = NULL;
+ struct icaltimetype itt;
+ time_t startt, endt;
+ const char *user;
+
+ itt = icaltime_null_time ();
+ itt.year = g_date_year (&qdata->start.date);
+ itt.month = g_date_month (&qdata->start.date);
+ itt.day = g_date_day (&qdata->start.date);
+ itt.hour = qdata->start.hour;
+ itt.minute = qdata->start.minute;
+ startt = icaltime_as_timet_with_zone (itt, priv->zone);
+
+ itt = icaltime_null_time ();
+ itt.year = g_date_year (&qdata->end.date);
+ itt.month = g_date_month (&qdata->end.date);
+ itt.day = g_date_day (&qdata->end.date);
+ itt.hour = qdata->end.hour;
+ itt.minute = qdata->end.minute;
+ endt = icaltime_as_timet_with_zone (itt, priv->zone);
+
+ user = itip_strip_mailto (e_meeting_attendee_get_address (ia));
+ users = g_list_append (users, g_strdup (user));
+
+ /* FIXME Error checking */
+ cal_client_get_free_busy (priv->client, users, startt, endt, &fb_data, NULL);
+
+ g_list_foreach (users, (GFunc)g_free, NULL);
+ g_list_free (users);
+
+ if (fb_data != NULL) {
+ CalComponent *comp = fb_data->data;
+ char *comp_str;
+
+ comp_str = cal_component_get_as_string (comp);
+ process_free_busy (qdata, comp_str);
+ g_free (comp_str);
+ return TRUE;
+ }
+ }
+
+ /* Look for fburl's of attendee with no free busy info on server */
+ if (!priv->book_loaded) {
+ priv->book_load_wait = TRUE;
+ gtk_main ();
+ }
+
+ if (!e_meeting_attendee_is_set_address (ia)) {
+ process_callbacks (qdata);
+ return TRUE;
+ }
+
+ query = g_strdup_printf ("(is \"email\" \"%s\")",
+ itip_strip_mailto (e_meeting_attendee_get_address (ia)));
+ if (!e_book_async_get_contacts (priv->ebook, query, contacts_cb, qdata))
+ process_callbacks (qdata);
+ g_free (query);
+
+ return TRUE;
+}
+
+void
+e_meeting_model_refresh_all_busy_periods (EMeetingModel *im,
+ EMeetingTime *start,
+ EMeetingTime *end,
+ EMeetingModelRefreshCallback call_back,
+ gpointer data)
+{
+ EMeetingModelPrivate *priv;
+ int i;
+
+ g_return_if_fail (im != NULL);
+ g_return_if_fail (E_IS_MEETING_MODEL (im));
+
+ priv = im->priv;
+
+ for (i = 0; i < priv->attendees->len; i++)
+ refresh_queue_add (im, i, start, end, call_back, data);
+}
+
+void
+e_meeting_model_refresh_busy_periods (EMeetingModel *im,
+ int row,
+ EMeetingTime *start,
+ EMeetingTime *end,
+ EMeetingModelRefreshCallback call_back,
+ gpointer data)
+{
+ EMeetingModelPrivate *priv;
+
+ g_return_if_fail (im != NULL);
+ g_return_if_fail (E_IS_MEETING_MODEL (im));
+
+ priv = im->priv;
+
+ refresh_queue_add (im, row, start, end, call_back, data);
+}
+
+ETableScrolled *
+e_meeting_model_etable_from_model (EMeetingModel *im, const gchar *spec_file, const gchar *state_file)
+{
+ EMeetingModelPrivate *priv;
+ ETableScrolled *ets;
+
+ g_return_val_if_fail (im != NULL, NULL);
+ g_return_val_if_fail (E_IS_MEETING_MODEL (im), NULL);
+
+ priv = im->priv;
+
+ ets = build_etable (E_TABLE_MODEL (im), spec_file, state_file);
+
+ priv->tables = g_list_prepend (priv->tables, ets);
+
+ g_signal_connect (ets, "destroy", G_CALLBACK (table_destroy_list_cb), im);
+
+ return ets;
+}
+
+void
+e_meeting_model_etable_click_to_add (EMeetingModel *im, gboolean click_to_add)
+{
+ EMeetingModelPrivate *priv;
+ GList *l;
+
+ g_return_if_fail (im != NULL);
+ g_return_if_fail (E_IS_MEETING_MODEL (im));
+
+ priv = im->priv;
+
+ for (l = priv->tables; l != NULL; l = l->next) {
+ ETableScrolled *ets;
+ ETable *real_table;
+
+ ets = l->data;
+ real_table = e_table_scrolled_get_table (ets);
+
+ g_object_set (G_OBJECT (real_table), "use_click_to_add", click_to_add, NULL);
+ }
+}
+
+int
+e_meeting_model_etable_model_to_view_row (ETable *et, EMeetingModel *im, int model_row)
+{
+ EMeetingModelPrivate *priv;
+
+ g_return_val_if_fail (im != NULL, -1);
+ g_return_val_if_fail (E_IS_MEETING_MODEL (im), -1);
+
+ priv = im->priv;
+
+ return e_table_model_to_view_row (et, model_row);
+}
+
+int
+e_meeting_model_etable_view_to_model_row (ETable *et, EMeetingModel *im, int view_row)
+{
+ EMeetingModelPrivate *priv;
+
+ g_return_val_if_fail (im != NULL, -1);
+ g_return_val_if_fail (E_IS_MEETING_MODEL (im), -1);
+
+ priv = im->priv;
+
+ return e_table_view_to_model_row (et, view_row);
+}
+
+
+static void
+add_section (GNOME_Evolution_Addressbook_SelectNames corba_select_names, const char *name)
+{
+ CORBA_Environment ev;
+
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Addressbook_SelectNames_addSection (corba_select_names,
+ name,
+ gettext (name),
+ &ev);
+
+ CORBA_exception_free (&ev);
+}
+
+static gboolean
+get_select_name_dialog (EMeetingModel *im)
+{
+ EMeetingModelPrivate *priv;
+ CORBA_Environment ev;
+ int i;
+
+ priv = im->priv;
+
+ if (priv->corba_select_names != CORBA_OBJECT_NIL) {
+ Bonobo_Control corba_control;
+ GtkWidget *control_widget;
+ int i;
+
+ CORBA_exception_init (&ev);
+ for (i = 0; sections[i] != NULL; i++) {
+ corba_control = GNOME_Evolution_Addressbook_SelectNames_getEntryBySection
+ (priv->corba_select_names, sections[i], &ev);
+ if (BONOBO_EX (&ev)) {
+ CORBA_exception_free (&ev);
+ return FALSE;
+ }
+
+ control_widget = bonobo_widget_new_control_from_objref (corba_control, CORBA_OBJECT_NIL);
+
+ bonobo_widget_set_property (BONOBO_WIDGET (control_widget), "text", TC_CORBA_string, "", NULL);
+ }
+ CORBA_exception_free (&ev);
+
+ return TRUE;
+ }
+
+ CORBA_exception_init (&ev);
+
+ priv->corba_select_names = bonobo_activation_activate_from_id (SELECT_NAMES_OAFID, 0, NULL, &ev);
+
+ for (i = 0; sections[i] != NULL; i++)
+ add_section (priv->corba_select_names, sections[i]);
+
+ bonobo_event_source_client_add_listener (priv->corba_select_names,
+ (BonoboListenerCallbackFn) select_names_ok_cb,
+ "GNOME/Evolution:ok:dialog",
+ NULL, im);
+
+ if (BONOBO_EX (&ev)) {
+ CORBA_exception_free (&ev);
+ return FALSE;
+ }
+
+ CORBA_exception_free (&ev);
+
+ return TRUE;
+}
+
+void
+e_meeting_model_invite_others_dialog (EMeetingModel *im)
+{
+ EMeetingModelPrivate *priv;
+ CORBA_Environment ev;
+
+ priv = im->priv;
+
+ if (!get_select_name_dialog (im))
+ return;
+
+ CORBA_exception_init (&ev);
+
+ GNOME_Evolution_Addressbook_SelectNames_activateDialog (
+ priv->corba_select_names, _("Required Participants"), &ev);
+
+ CORBA_exception_free (&ev);
+}
+
+static void
+process_section (EMeetingModel *im, EABDestination **destv, icalparameter_role role)
+{
+ EMeetingModelPrivate *priv;
+ int i;
+
+ if (!destv)
+ return;
+
+ priv = im->priv;
+ for (i = 0; destv[i]; i++) {
+ EMeetingAttendee *ia;
+ const char *name, *attendee = NULL;
+ char *attr;
+ CORBA_Environment ev;
+ EABDestination *dest = destv[i];
+
+ CORBA_exception_init (&ev);
+
+ /* Get the CN */
+ name = eab_destination_get_name (dest);
+
+ /* Get the field as attendee from the backend */
+ if (cal_client_get_ldap_attribute (priv->client, &attr, NULL) && attr) {
+ /* FIXME this should be more general */
+ if (!strcmp (attr, "icscalendar")) {
+ EContact *contact = eab_destination_get_contact (dest);
+ if (contact)
+ attendee = e_contact_get_const (contact, E_CONTACT_ICS_CALENDAR);
+ }
+
+ g_free (attr);
+ }
+
+ CORBA_exception_init (&ev);
+
+ /* If we couldn't get the attendee prior, get the email address as the default */
+ if (attendee == NULL || *attendee == '\0') {
+ attendee = eab_destination_get_email (dest);
+ }
+
+ CORBA_exception_free (&ev);
+
+ if (attendee == NULL || *attendee == '\0')
+ continue;
+
+ if (e_meeting_model_find_attendee (im, attendee, NULL) == NULL) {
+ ia = e_meeting_model_add_attendee_with_defaults (im);
+
+ e_meeting_attendee_set_address (ia, g_strdup_printf ("MAILTO:%s", attendee));
+ e_meeting_attendee_set_role (ia, role);
+ if (role == ICAL_ROLE_NONPARTICIPANT)
+ e_meeting_attendee_set_cutype (ia, ICAL_CUTYPE_RESOURCE);
+ e_meeting_attendee_set_cn (ia, g_strdup (name));
+ }
+ }
+}
+
+static void
+select_names_ok_cb (BonoboListener *listener,
+ const char *event_name,
+ const CORBA_any *arg,
+ CORBA_Environment *ev,
+ gpointer data)
+{
+ EMeetingModel *im = data;
+ EMeetingModelPrivate *priv;
+ Bonobo_Control corba_control;
+ GtkWidget *control_widget;
+ BonoboControlFrame *control_frame;
+ Bonobo_PropertyBag pb;
+ char *dest_str;
+ EABDestination **dest;
+ int i;
+
+ priv = im->priv;
+
+ for (i = 0; sections[i] != NULL; i++) {
+ corba_control = GNOME_Evolution_Addressbook_SelectNames_getEntryBySection
+ (priv->corba_select_names, sections[i], ev);
+ control_widget = bonobo_widget_new_control_from_objref
+ (corba_control, CORBA_OBJECT_NIL);
+
+ control_frame = bonobo_widget_get_control_frame (BONOBO_WIDGET (control_widget));
+ pb = bonobo_control_frame_get_control_property_bag (control_frame, NULL);
+ dest_str = bonobo_pbclient_get_string (pb, "destinations", NULL);
+ dest = eab_destination_importv (dest_str);
+ process_section (im, dest, roles[i]);
+ eab_destination_freev (dest);
+ }
+}
+
+static void
+attendee_changed_cb (EMeetingAttendee *ia, gpointer data)
+{
+ EMeetingModel *im = E_MEETING_MODEL (data);
+ EMeetingModelPrivate *priv;
+ gint row = -1, i;
+
+ priv = im->priv;
+
+ /* FIXME: Ideally I think you are supposed to call pre_change() before
+ the data structures are changed. */
+ e_table_model_pre_change (E_TABLE_MODEL (im));
+
+ for (i = 0; i < priv->attendees->len; i++) {
+ if (ia == g_ptr_array_index (priv->attendees, i)) {
+ row = i;
+ break;
+ }
+ }
+
+ if (row == -1)
+ e_table_model_no_change (E_TABLE_MODEL (im));
+ else
+ e_table_model_row_changed (E_TABLE_MODEL (im), row);
+}
+
+static void
+table_destroy_state_cb (ETableScrolled *etable, gpointer data)
+{
+ ETable *real_table;
+ char *filename = data;
+
+ real_table = e_table_scrolled_get_table (etable);
+ e_table_save_state (real_table, filename);
+
+ g_free (data);
+}
+
+static void
+table_destroy_list_cb (ETableScrolled *etable, gpointer data)
+{
+ EMeetingModel *im = E_MEETING_MODEL (data);
+ EMeetingModelPrivate *priv;
+
+ priv = im->priv;
+
+ priv->tables = g_list_remove (priv->tables, etable);
+}
+
diff --git a/calendar/gui/e-meeting-model.h b/calendar/gui/e-meeting-model.h
new file mode 100644
index 0000000000..50fba6c7a6
--- /dev/null
+++ b/calendar/gui/e-meeting-model.h
@@ -0,0 +1,116 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-model.h
+ *
+ * Copyright (C) 2001 Ximian, Inc.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: JP Rosevear
+ */
+
+#ifndef _E_MEETING_MODEL_H_
+#define _E_MEETING_MODEL_H_
+
+#include <gtk/gtk.h>
+#include <gal/e-table/e-table-scrolled.h>
+#include <gal/e-table/e-table-model.h>
+#include <cal-client/cal-client.h>
+#include "e-meeting-attendee.h"
+
+G_BEGIN_DECLS
+
+#define E_TYPE_MEETING_MODEL (e_meeting_model_get_type ())
+#define E_MEETING_MODEL(obj) (GTK_CHECK_CAST ((obj), E_TYPE_MEETING_MODEL, EMeetingModel))
+#define E_MEETING_MODEL_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_MEETING_MODEL, EMeetingModelClass))
+#define E_IS_MEETING_MODEL(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_MEETING_MODEL))
+#define E_IS_MEETING_MODEL_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_MEETING_MODEL))
+
+
+typedef struct _EMeetingModel EMeetingModel;
+typedef struct _EMeetingModelPrivate EMeetingModelPrivate;
+typedef struct _EMeetingModelClass EMeetingModelClass;
+
+typedef enum {
+ E_MEETING_MODEL_ADDRESS_COL,
+ E_MEETING_MODEL_MEMBER_COL,
+ E_MEETING_MODEL_TYPE_COL,
+ E_MEETING_MODEL_ROLE_COL,
+ E_MEETING_MODEL_RSVP_COL,
+ E_MEETING_MODEL_DELTO_COL,
+ E_MEETING_MODEL_DELFROM_COL,
+ E_MEETING_MODEL_STATUS_COL,
+ E_MEETING_MODEL_CN_COL,
+ E_MEETING_MODEL_LANGUAGE_COL,
+ E_MEETING_MODEL_COLUMN_COUNT
+} EMeetingModelColumns;
+
+struct _EMeetingModel {
+ ETableModel parent;
+
+ EMeetingModelPrivate *priv;
+};
+
+struct _EMeetingModelClass {
+ ETableModelClass parent_class;
+};
+
+typedef void (* EMeetingModelRefreshCallback) (gpointer data);
+
+
+GtkType e_meeting_model_get_type (void);
+GtkObject *e_meeting_model_new (void);
+
+CalClient *e_meeting_model_get_cal_client (EMeetingModel *im);
+void e_meeting_model_set_cal_client (EMeetingModel *im, CalClient *client);
+
+icaltimezone *e_meeting_model_get_zone (EMeetingModel *im);
+void e_meeting_model_set_zone (EMeetingModel *im, icaltimezone *zone);
+
+void e_meeting_model_add_attendee (EMeetingModel *im, EMeetingAttendee *ia);
+EMeetingAttendee *e_meeting_model_add_attendee_with_defaults (EMeetingModel *im);
+
+void e_meeting_model_remove_attendee (EMeetingModel *im, EMeetingAttendee *ia);
+void e_meeting_model_remove_all_attendees (EMeetingModel *im);
+
+EMeetingAttendee *e_meeting_model_find_attendee (EMeetingModel *im, const gchar *address, gint *row);
+EMeetingAttendee *e_meeting_model_find_attendee_at_row (EMeetingModel *im, gint row);
+
+gint e_meeting_model_count_actual_attendees (EMeetingModel *im);
+const GPtrArray *e_meeting_model_get_attendees (EMeetingModel *im);
+
+void e_meeting_model_refresh_all_busy_periods (EMeetingModel *im,
+ EMeetingTime *start,
+ EMeetingTime *end,
+ EMeetingModelRefreshCallback call_back,
+ gpointer data);
+void e_meeting_model_refresh_busy_periods (EMeetingModel *im,
+ int row,
+ EMeetingTime *start,
+ EMeetingTime *end,
+ EMeetingModelRefreshCallback call_back,
+ gpointer data);
+
+
+/* Helpful functions */
+ETableScrolled *e_meeting_model_etable_from_model (EMeetingModel *im, const gchar *spec_file, const gchar *state_file);
+void e_meeting_model_etable_click_to_add (EMeetingModel *im, gboolean click_to_add);
+int e_meeting_model_etable_model_to_view_row (ETable *et, EMeetingModel *im, int model_row);
+int e_meeting_model_etable_view_to_model_row (ETable *et, EMeetingModel *im, int view_row);
+
+void e_meeting_model_invite_others_dialog (EMeetingModel *im);
+
+G_END_DECLS
+
+#endif
diff --git a/calendar/gui/e-meeting-store.c b/calendar/gui/e-meeting-store.c
index 0129756e7c..6064971d9f 100644
--- a/calendar/gui/e-meeting-store.c
+++ b/calendar/gui/e-meeting-store.c
@@ -30,7 +30,6 @@
#include <libgnome/gnome-util.h>
#include <libgnomevfs/gnome-vfs.h>
#include <ebook/e-book.h>
-#include <ebook/e-book-util.h>
#include <cal-util/cal-component.h>
#include <cal-util/cal-util.h>
#include <cal-util/timeutil.h>
@@ -50,8 +49,6 @@ struct _EMeetingStorePrivate {
icaltimezone *zone;
EBook *ebook;
- gboolean book_loaded;
- gboolean book_load_wait;
GPtrArray *refresh_queue;
GHashTable *refresh_data;
@@ -81,26 +78,10 @@ struct _EMeetingStoreQueueData {
static GObjectClass *parent_class = NULL;
static void
-book_open_cb (EBook *book, EBookStatus status, gpointer data)
-{
- EMeetingStore *store = E_MEETING_STORE (data);
-
- if (status == E_BOOK_STATUS_SUCCESS)
- store->priv->book_loaded = TRUE;
- else
- g_warning ("Book not loaded");
-
- if (store->priv->book_load_wait) {
- store->priv->book_load_wait = FALSE;
- gtk_main_quit ();
- }
-}
-
-static void
start_addressbook_server (EMeetingStore *store)
{
store->priv->ebook = e_book_new ();
- e_book_load_default_book (store->priv->ebook, book_open_cb, store);
+ e_book_load_local_addressbook (store->priv->ebook, NULL);
}
static icalparameter_cutype
@@ -914,9 +895,11 @@ find_zone (icalproperty *ip, icalcomponent *tz_top_level)
iter = icalcomponent_begin_component (tz_top_level, ICAL_VTIMEZONE_COMPONENT);
while ((sub_comp = icalcompiter_deref (&iter)) != NULL) {
icalcomponent *clone;
+ icalproperty *prop;
const char *tz_tzid;
-
- tz_tzid = icalproperty_get_tzid (sub_comp);
+
+ prop = icalcomponent_get_first_property (sub_comp, ICAL_TZID_PROPERTY);
+ tz_tzid = icalproperty_get_tzid (prop);
if (!strcmp (tzid, tz_tzid)) {
icaltimezone *zone;
@@ -1141,7 +1124,7 @@ refresh_busy_periods (gpointer data)
/* Check the server for free busy data */
if (priv->client) {
- GList *fb_data, *users = NULL;
+ GList *fb_data = NULL, *users = NULL;
struct icaltimetype itt;
time_t startt, endt;
const char *user;
@@ -1164,7 +1147,7 @@ refresh_busy_periods (gpointer data)
user = itip_strip_mailto (e_meeting_attendee_get_address (attendee));
users = g_list_append (users, g_strdup (user));
- fb_data = cal_client_get_free_busy (priv->client, users, startt, endt);
+ cal_client_get_free_busy (priv->client, users, startt, endt, &fb_data, NULL);
g_list_foreach (users, (GFunc)g_free, NULL);
g_list_free (users);
@@ -1181,11 +1164,6 @@ refresh_busy_periods (gpointer data)
}
/* Look for fburl's of attendee with no free busy info on server */
- if (!priv->book_loaded) {
- priv->book_load_wait = TRUE;
- gtk_main ();
- }
-
if (!e_meeting_attendee_is_set_address (attendee)) {
process_callbacks (qdata);
return TRUE;
diff --git a/calendar/gui/e-meeting-time-sel.c b/calendar/gui/e-meeting-time-sel.c
index 157320ef16..91d915a4d7 100644
--- a/calendar/gui/e-meeting-time-sel.c
+++ b/calendar/gui/e-meeting-time-sel.c
@@ -265,6 +265,7 @@ e_meeting_time_selector_init (EMeetingTimeSelector * mts)
void
e_meeting_time_selector_construct (EMeetingTimeSelector * mts, EMeetingStore *ems)
{
+ char *filename;
GtkWidget *hbox, *vbox, *separator, *button, *label, *table;
GtkWidget *alignment, *child_hbox, *arrow, *menuitem;
GSList *group;
@@ -313,7 +314,12 @@ e_meeting_time_selector_construct (EMeetingTimeSelector * mts, EMeetingStore *em
gtk_box_pack_start (GTK_BOX (vbox), mts->attendees_vbox, TRUE, TRUE, 0);
gtk_widget_show (mts->attendees_vbox);
+
+ /* build the etable */
+ filename = g_build_filename (calendar_component_peek_config_directory (calendar_component_peek ()),
+ "config", "et-header-meeting-time-sel", NULL);
mts->model = ems;
+
if (mts->model)
g_object_ref (mts->model);
diff --git a/calendar/gui/e-select-names-editable.c b/calendar/gui/e-select-names-editable.c
index 2fcc93397a..29c54c7979 100644
--- a/calendar/gui/e-select-names-editable.c
+++ b/calendar/gui/e-select-names-editable.c
@@ -25,7 +25,7 @@
#include <gtk/gtkcelleditable.h>
#include <bonobo/bonobo-exception.h>
#include <bonobo/bonobo-widget.h>
-#include <ebook/e-destination.h>
+#include <addressbook/util/eab-destination.h>
#include "e-select-names-editable.h"
#include "Evolution-Addressbook-SelectNames.h"
@@ -187,16 +187,16 @@ e_select_names_editable_new ()
gchar *
e_select_names_editable_get_address (ESelectNamesEditable *esne)
{
- EDestination **dest;
+ EABDestination **dest;
gchar *dest_str;
gchar *result;
g_return_val_if_fail (E_SELECT_NAMES_EDITABLE (esne), NULL);
dest_str = bonobo_pbclient_get_string (esne->priv->bag, "destinations", NULL);
- dest = e_destination_importv (dest_str);
- result = g_strdup (e_destination_get_email (*dest));
- e_destination_freev (dest);
+ dest = eab_destination_importv (dest_str);
+ result = g_strdup (eab_destination_get_email (*dest));
+ eab_destination_freev (dest);
return result;
}
@@ -204,16 +204,16 @@ e_select_names_editable_get_address (ESelectNamesEditable *esne)
gchar *
e_select_names_editable_get_name (ESelectNamesEditable *esne)
{
- EDestination **dest;
+ EABDestination **dest;
gchar *dest_str;
gchar *result;
g_return_val_if_fail (E_SELECT_NAMES_EDITABLE (esne), NULL);
dest_str = bonobo_pbclient_get_string (esne->priv->bag, "destinations", NULL);
- dest = e_destination_importv (dest_str);
- result = g_strdup (e_destination_get_name (*dest));
- e_destination_freev (dest);
+ dest = eab_destination_importv (dest_str);
+ result = g_strdup (eab_destination_get_name (*dest));
+ eab_destination_freev (dest);
return result;
}
diff --git a/calendar/gui/e-tasks.c b/calendar/gui/e-tasks.c
index b441aee09d..768b2e587c 100644
--- a/calendar/gui/e-tasks.c
+++ b/calendar/gui/e-tasks.c
@@ -572,7 +572,6 @@ GtkWidget *
e_tasks_construct (ETasks *tasks)
{
ETasksPrivate *priv;
- ECalModel *model;
g_return_val_if_fail (tasks != NULL, NULL);
g_return_val_if_fail (E_IS_TASKS (tasks), NULL);
@@ -581,24 +580,6 @@ e_tasks_construct (ETasks *tasks)
setup_widgets (tasks);
- priv->client = cal_client_new ();
- if (!priv->client)
- return NULL;
-
- g_signal_connect (priv->client, "cal_opened",
- G_CALLBACK (cal_opened_cb), tasks);
- g_signal_connect (priv->client, "backend_error",
- G_CALLBACK (backend_error_cb), tasks);
- g_signal_connect (priv->client, "categories_changed",
- G_CALLBACK (client_categories_changed_cb), tasks);
- g_signal_connect (priv->client, "obj_updated",
- G_CALLBACK (client_obj_updated_cb), tasks);
-
- model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view));
- g_assert (model != NULL);
-
- e_cal_model_add_client (model, priv->client);
-
return GTK_WIDGET (tasks);
}
@@ -685,6 +666,8 @@ e_tasks_open (ETasks *tasks,
EUri *uri;
char *real_uri;
char *urinopwd;
+ ECalModel *model;
+ GError *error = NULL;
g_return_val_if_fail (tasks != NULL, FALSE);
g_return_val_if_fail (E_IS_TASKS (tasks), FALSE);
@@ -704,10 +687,30 @@ e_tasks_open (ETasks *tasks,
g_free (message);
g_free (urinopwd);
- if (!cal_client_open_calendar (priv->client, real_uri, FALSE)) {
- g_message ("e_tasks_open(): Could not issue the request");
+ /* create the CalClient */
+ priv->client = cal_client_new (real_uri, CALOBJ_TYPE_TODO);
+ if (!priv->client)
+ return NULL;
+
+ g_signal_connect (priv->client, "cal_opened",
+ G_CALLBACK (cal_opened_cb), tasks);
+ g_signal_connect (priv->client, "backend_error",
+ G_CALLBACK (backend_error_cb), tasks);
+ g_signal_connect (priv->client, "categories_changed",
+ G_CALLBACK (client_categories_changed_cb), tasks);
+ g_signal_connect (priv->client, "obj_updated",
+ G_CALLBACK (client_obj_updated_cb), tasks);
+
+ model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view));
+ g_assert (model != NULL);
+
+ e_cal_model_add_client (model, priv->client);
+
+ if (cal_client_open (priv->client, FALSE, &error)) {
+ g_message ("e_tasks_open(): %s", error->message);
g_free (real_uri);
e_uri_free (uri);
+ g_error_free (error);
return FALSE;
}
@@ -787,7 +790,8 @@ cal_opened_cb (CalClient *client,
location = calendar_config_get_timezone ();
zone = icaltimezone_get_builtin_timezone (location);
if (zone)
- cal_client_set_default_timezone (client, zone);
+ /* FIXME Error checking */
+ cal_client_set_default_timezone (client, zone, NULL);
return;
case CAL_CLIENT_OPEN_ERROR:
@@ -937,60 +941,6 @@ create_sexp (void)
return sexp;
}
-/* Callback used when a component is updated in the live query */
-static void
-query_obj_updated_cb (CalQuery *query, const char *uid,
- gboolean query_in_progress, int n_scanned, int total,
- gpointer data)
-{
- ETasks *tasks;
- ETasksPrivate *priv;
-
- tasks = E_TASKS (data);
- priv = tasks->priv;
-
- delete_error_dialog (cal_client_remove_object (priv->client, uid), CAL_COMPONENT_TODO);
-}
-
-/* Callback used when an evaluation error occurs when running a query */
-static void
-query_eval_error_cb (CalQuery *query, const char *error_str, gpointer data)
-{
- ETasks *tasks;
- ETasksPrivate *priv;
-
- tasks = E_TASKS (data);
- priv = tasks->priv;
-
- g_warning ("eval error: %s\n", error_str);
-
- set_status_message (tasks, NULL);
-
- g_signal_handlers_disconnect_matched (priv->query, G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, tasks);
- g_object_unref (priv->query);
- priv->query = NULL;
-}
-
-static void
-query_query_done_cb (CalQuery *query, CalQueryDoneStatus status, const char *error_str, gpointer data)
-{
- ETasks *tasks;
- ETasksPrivate *priv;
-
- tasks = E_TASKS (data);
- priv = tasks->priv;
-
- if (status != CAL_QUERY_DONE_SUCCESS)
- g_warning ("query done: %s\n", error_str);
-
- set_status_message (tasks, NULL);
-
- g_signal_handlers_disconnect_matched (priv->query, G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, tasks);
- g_object_unref (priv->query);
- priv->query = NULL;
-}
/**
* e_tasks_expunge:
* @tasks: A tasks control widget
@@ -1002,31 +952,32 @@ e_tasks_delete_completed (ETasks *tasks)
{
ETasksPrivate *priv;
char *sexp;
+ GList *objects, *l;
g_return_if_fail (tasks != NULL);
g_return_if_fail (E_IS_TASKS (tasks));
priv = tasks->priv;
- /* If we have a query, we are already expunging */
- if (priv->query)
- return;
+ /* FIXME Confirm expunge */
sexp = create_sexp ();
set_status_message (tasks, _("Expunging"));
- priv->query = cal_client_get_query (priv->client, sexp);
- g_free (sexp);
-
- if (!priv->query) {
+
+ if (!cal_client_get_object_list (priv->client, sexp, &objects, NULL)) {
set_status_message (tasks, NULL);
- g_message ("update_query(): Could not create the query");
+ g_warning (G_STRLOC ": Could not get the objects");
+
return;
}
+
+ for (l = objects; l; l = l->next) {
+ /* FIXME Better error handling */
+ cal_client_remove_object (priv->client, icalcomponent_get_uid (l->data), NULL);
+ }
- g_signal_connect (priv->query, "obj_updated", G_CALLBACK (query_obj_updated_cb), tasks);
- g_signal_connect (priv->query, "query_done", G_CALLBACK (query_query_done_cb), tasks);
- g_signal_connect (priv->query, "eval_error", G_CALLBACK (query_eval_error_cb), tasks);
+ set_status_message (tasks, NULL);
}
/* Callback used from the view collection when we need to display a new view */
@@ -1181,6 +1132,7 @@ e_tasks_update_all_config_settings (void)
calendar_config_configure_e_calendar_table (E_CALENDAR_TABLE (priv->tasks_view));
if (zone)
- cal_client_set_default_timezone (priv->client, zone);
+ /* FIXME Error checking */
+ cal_client_set_default_timezone (priv->client, zone, NULL);
}
}
diff --git a/calendar/gui/e-week-view-event-item.c b/calendar/gui/e-week-view-event-item.c
index 139f28bb13..fd68130bc5 100644
--- a/calendar/gui/e-week-view-event-item.c
+++ b/calendar/gui/e-week-view-event-item.c
@@ -890,7 +890,6 @@ e_week_view_event_item_double_click (EWeekViewEventItem *wveitem,
EWeekView *week_view;
EWeekViewEvent *event;
GnomeCanvasItem *item;
- GnomeCalendar *calendar;
item = GNOME_CANVAS_ITEM (wveitem);
@@ -902,11 +901,7 @@ e_week_view_event_item_double_click (EWeekViewEventItem *wveitem,
e_week_view_stop_editing_event (week_view);
- calendar = e_cal_view_get_calendar (E_CAL_VIEW (week_view));
- if (calendar)
- gnome_calendar_edit_object (calendar, event->comp_data->client, event->comp_data->icalcomp, FALSE);
- else
- g_warning ("Calendar not set");
+ e_cal_view_edit_appointment (E_CAL_VIEW (week_view), event->comp_data->client, event->comp_data->icalcomp, FALSE);
return TRUE;
}
diff --git a/calendar/gui/e-week-view.c b/calendar/gui/e-week-view.c
index 8028bf13e6..1be94fc1de 100644
--- a/calendar/gui/e-week-view.c
+++ b/calendar/gui/e-week-view.c
@@ -62,6 +62,7 @@
#include "calendar-config.h"
#include "print.h"
#include "goto.h"
+#include "e-cal-model-calendar.h"
#include "e-week-view-event-item.h"
#include "e-week-view-layout.h"
#include "e-week-view-main-item.h"
@@ -312,8 +313,6 @@ e_week_view_init (EWeekView *week_view)
week_view->main_gc = NULL;
- week_view->default_category = NULL;
-
/* Create the small font. */
week_view->use_small_font = TRUE;
@@ -423,8 +422,11 @@ GtkWidget *
e_week_view_new (void)
{
GtkWidget *week_view;
+ ECalModel *model;
+
+ model = E_CAL_MODEL (e_cal_model_calendar_new ());
- week_view = GTK_WIDGET (g_object_new (e_week_view_get_type (), NULL));
+ week_view = GTK_WIDGET (g_object_new (e_week_view_get_type (), "model", model, NULL));
return week_view;
}
@@ -457,11 +459,6 @@ e_week_view_destroy (GtkObject *object)
week_view->small_font_desc = NULL;
}
- if (week_view->default_category) {
- g_free (week_view->default_category);
- week_view->default_category = NULL;
- }
-
if (week_view->normal_cursor) {
gdk_cursor_unref (week_view->normal_cursor);
week_view->normal_cursor = NULL;
@@ -1149,7 +1146,7 @@ process_component (EWeekView *week_view, ECalModelComponent *comp_data)
g_object_unref (tmp_comp);
}
- /* Add the occurrences of the event. */
+ /* Add the occurrences of the event */
num_days = week_view->multi_week_view ? week_view->weeks_shown * 7 : 7;
add_event_data.week_view = week_view;
@@ -1158,8 +1155,7 @@ process_component (EWeekView *week_view, ECalModelComponent *comp_data)
week_view->day_starts[0],
week_view->day_starts[num_days],
e_week_view_add_event, &add_event_data,
- cal_client_resolve_tzid_cb,
- comp_data->client,
+ cal_client_resolve_tzid_cb, comp_data->client,
e_cal_view_get_timezone (E_CAL_VIEW (week_view)));
g_object_unref (comp);
@@ -1178,8 +1174,6 @@ e_week_view_update_query (ECalView *cal_view)
e_week_view_free_events (week_view);
e_week_view_queue_layout (week_view);
- e_cal_view_set_status_message (E_CAL_VIEW (week_view), _("Searching"));
-
rows = e_table_model_row_count (E_TABLE_MODEL (e_cal_view_get_model (E_CAL_VIEW (week_view))));
for (r = 0; r < rows; r++) {
ECalModelComponent *comp_data;
@@ -1188,8 +1182,6 @@ e_week_view_update_query (ECalView *cal_view)
g_assert (comp_data != NULL);
process_component (week_view, comp_data);
}
-
- e_cal_view_set_status_message (E_CAL_VIEW (week_view), NULL);
}
static void
@@ -1217,27 +1209,6 @@ e_week_view_draw_shadow (EWeekView *week_view)
gdk_draw_line (window, light_gc, x1, y2, x2, y2);
}
-/**
- * e_week_view_set_default_category:
- * @week_view: A week view.
- * @category: Default category name or NULL for no category.
- *
- * Sets the default category that will be used when creating new calendar
- * components from the week view.
- **/
-void
-e_week_view_set_default_category (EWeekView *week_view, const char *category)
-{
- g_return_if_fail (week_view != NULL);
- g_return_if_fail (E_IS_WEEK_VIEW (week_view));
-
- if (week_view->default_category)
- g_free (week_view->default_category);
-
- week_view->default_category = g_strdup (category);
-}
-
-
/* This sets the selected time range. The EWeekView will show the corresponding
month and the days between start_time and end_time will be selected.
To select a single day, use the same value for start_time & end_time. */
@@ -2015,7 +1986,7 @@ e_week_view_on_button_press (GtkWidget *widget,
return FALSE;
if (event->button == 1 && event->type == GDK_2BUTTON_PRESS) {
- gnome_calendar_new_appointment (e_cal_view_get_calendar (E_CAL_VIEW (week_view)));
+ e_cal_view_new_appointment (E_CAL_VIEW (week_view));
return TRUE;
}
@@ -2876,14 +2847,11 @@ e_week_view_on_text_item_event (GnomeCanvasItem *item,
{
EWeekViewEvent *event;
gint event_num, span_num;
- GnomeCalendar *calendar;
#if 0
g_print ("In e_week_view_on_text_item_event\n");
#endif
- calendar = e_cal_view_get_calendar (E_CAL_VIEW (week_view));
-
switch (gdkevent->type) {
case GDK_KEY_PRESS:
if (gdkevent && gdkevent->key.keyval == GDK_Return) {
@@ -2912,10 +2880,9 @@ e_week_view_on_text_item_event (GnomeCanvasItem *item,
event = &g_array_index (week_view->events, EWeekViewEvent,
event_num);
- if (calendar)
- gnome_calendar_edit_object (calendar, event->comp_data->client, event->comp_data->icalcomp, FALSE);
- else
- g_warning ("Calendar not set");
+ e_cal_view_edit_appointment (E_CAL_VIEW (week_view),
+ event->comp_data->client,
+ event->comp_data->icalcomp, FALSE);
gtk_signal_emit_stop_by_name (GTK_OBJECT (item), "event");
return TRUE;
@@ -3049,7 +3016,8 @@ e_week_view_on_editing_stopped (EWeekView *week_view,
CalComponent *comp;
CalComponentText summary;
const char *uid;
-
+ gboolean on_server;
+
/* Note: the item we are passed here isn't reliable, so we just stop
the edit of whatever item was being edited. We also receive this
event twice for some reason. */
@@ -3079,8 +3047,9 @@ e_week_view_on_editing_stopped (EWeekView *week_view,
comp = cal_component_new ();
cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp));
- if (string_is_empty (text) &&
- !cal_comp_is_on_server (comp, event->comp_data->client)) {
+ on_server = cal_comp_is_on_server (comp, event->comp_data->client);
+
+ if (string_is_empty (text) && !on_server) {
const char *uid;
cal_component_get_uid (comp, &uid);
@@ -3099,33 +3068,33 @@ e_week_view_on_editing_stopped (EWeekView *week_view,
e_week_view_reshape_event_span (week_view, event_num,
span_num);
} else if (summary.value || !string_is_empty (text)) {
+ icalcomponent *icalcomp = cal_component_get_icalcomponent (comp);
+
summary.value = text;
summary.altrep = NULL;
cal_component_set_summary (comp, &summary);
-
- if (cal_component_is_instance (comp)) {
- CalObjModType mod;
-
- if (recur_component_dialog (comp, &mod, NULL)) {
- if (cal_client_update_object_with_mod (event->comp_data->client, comp, mod)
- == CAL_CLIENT_RESULT_SUCCESS) {
- if (itip_organizer_is_user (comp, event->comp_data->client)
- && send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (week_view)),
- event->comp_data->client, comp, FALSE))
- itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
- event->comp_data->client, NULL);
- } else {
- g_message ("e_week_view_on_editing_stopped(): Could not update the object!");
+
+ if (!on_server) {
+ if (!cal_client_create_object (event->comp_data->client, icalcomp, NULL, NULL))
+ g_message (G_STRLOC ": Could not create the object!");
+ } else {
+ CalObjModType mod = CALOBJ_MOD_ALL;
+ GtkWindow *toplevel;
+
+ if (cal_component_has_recurrences (comp)) {
+ if (!recur_component_dialog (comp, &mod, NULL)) {
+ goto out;
}
}
- } else if (cal_client_update_object (event->comp_data->client, comp) == CAL_CLIENT_RESULT_SUCCESS) {
- if (itip_organizer_is_user (comp, event->comp_data->client) &&
- send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (week_view)),
- event->comp_data->client, comp, FALSE))
- itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
- event->comp_data->client, NULL);
- } else {
- g_message ("e_week_view_on_editing_stopped(): Could not update the object!");
+
+ /* FIXME When sending here, what exactly should we send? */
+ toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (week_view)));
+ if (cal_client_modify_object (event->comp_data->client, icalcomp, mod, NULL)) {
+ if (itip_organizer_is_user (comp, event->comp_data->client)
+ && send_component_dialog (toplevel, event->comp_data->client, comp, FALSE))
+ itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp,
+ event->comp_data->client, NULL);
+ }
}
}
@@ -3182,6 +3151,10 @@ e_week_view_find_event_from_uid (EWeekView *week_view,
EWeekViewEvent *event;
gint event_num, num_events;
+ *event_num_return = -1;
+ if (!uid)
+ return FALSE;
+
num_events = week_view->events->len;
for (event_num = 0; event_num < num_events; event_num++) {
const char *u;
@@ -3291,6 +3264,8 @@ e_week_view_do_key_press (GtkWidget *widget, GdkEventKey *event)
/* Add a new event covering the selected range. */
icalcomp = e_cal_model_create_component_with_defaults (e_cal_view_get_model (E_CAL_VIEW (week_view)));
+ if (!icalcomp)
+ return FALSE;
uid = icalcomponent_get_uid (icalcomp);
comp = cal_component_new ();
@@ -3313,7 +3288,8 @@ e_week_view_do_key_press (GtkWidget *widget, GdkEventKey *event)
e_cal_view_get_timezone (E_CAL_VIEW (week_view)));
cal_component_set_dtend (comp, &date);
- cal_component_set_categories (comp, week_view->default_category);
+ cal_component_set_categories (
+ comp, e_cal_view_get_default_category (E_CAL_VIEW (week_view)));
/* We add the event locally and start editing it. We don't send it
to the server until the user finishes editing it. */
@@ -3546,63 +3522,6 @@ e_week_view_popup_menu (GtkWidget *widget)
}
void
-e_week_view_unrecur_appointment (EWeekView *week_view)
-{
- EWeekViewEvent *event;
- CalComponent *comp, *new_comp;
- CalComponentDateTime date;
- struct icaltimetype itt;
-
- if (week_view->popup_event_num == -1)
- return;
-
- event = &g_array_index (week_view->events, EWeekViewEvent,
- week_view->popup_event_num);
-
- /* For the recurring object, we add a exception to get rid of the
- instance. */
- comp = cal_component_new ();
- cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp));
- cal_comp_util_add_exdate (comp, event->start, e_cal_view_get_timezone (E_CAL_VIEW (week_view)));
-
- /* For the unrecurred instance we duplicate the original object,
- create a new uid for it, get rid of the recurrence rules, and set
- the start & end times to the instances times. */
- new_comp = cal_component_new ();
- cal_component_set_icalcomponent (new_comp, icalcomponent_new_clone (event->comp_data->icalcomp));
- cal_component_set_uid (new_comp, cal_component_gen_uid ());
- cal_component_set_rdate_list (new_comp, NULL);
- cal_component_set_rrule_list (new_comp, NULL);
- cal_component_set_exdate_list (new_comp, NULL);
- cal_component_set_exrule_list (new_comp, NULL);
-
- date.value = &itt;
- date.tzid = icaltimezone_get_tzid (e_cal_view_get_timezone (E_CAL_VIEW (week_view)));
-
- *date.value = icaltime_from_timet_with_zone (event->start, FALSE,
- e_cal_view_get_timezone (E_CAL_VIEW (week_view)));
- cal_component_set_dtstart (new_comp, &date);
- *date.value = icaltime_from_timet_with_zone (event->end, FALSE,
- e_cal_view_get_timezone (E_CAL_VIEW (week_view)));
- cal_component_set_dtend (new_comp, &date);
-
- /* Now update both CalComponents. Note that we do this last since at
- present the updates happen synchronously so our event may disappear.
- */
- if (cal_client_update_object (event->comp_data->client, comp)
- != CAL_CLIENT_RESULT_SUCCESS)
- g_message ("e_week_view_on_unrecur_appointment(): Could not update the object!");
-
- g_object_unref (comp);
-
- if (cal_client_update_object (event->comp_data->client, new_comp)
- != CAL_CLIENT_RESULT_SUCCESS)
- g_message ("e_week_view_on_unrecur_appointment(): Could not update the object!");
-
- g_object_unref (new_comp);
-}
-
-void
e_week_view_jump_to_button_item (EWeekView *week_view, GnomeCanvasItem *item)
{
gint day;
diff --git a/calendar/gui/e-week-view.h b/calendar/gui/e-week-view.h
index c24470155d..0296c19c42 100644
--- a/calendar/gui/e-week-view.h
+++ b/calendar/gui/e-week-view.h
@@ -331,9 +331,6 @@ struct _EWeekView
gchar *pm_string;
gint am_string_width;
gint pm_string_width;
-
- /* The default category for new events */
- char *default_category;
};
struct _EWeekViewClass
@@ -353,9 +350,6 @@ void e_week_view_get_first_day_shown (EWeekView *week_view,
void e_week_view_set_first_day_shown (EWeekView *week_view,
GDate *date);
-void e_week_view_set_default_category (EWeekView *week_view,
- const char *category);
-
/* The selected time range. The EWeekView will show the corresponding
month and the days between start_time and end_time will be selected.
To select a single day, use the same value for start_time & end_time. */
@@ -396,8 +390,6 @@ void e_week_view_set_24_hour_format (EWeekView *week_view,
void e_week_view_delete_occurrence (EWeekView *week_view);
-void e_week_view_unrecur_appointment (EWeekView *week_view);
-
/* Returns the number of selected events (0 or 1 at present). */
gint e_week_view_get_num_events_selected (EWeekView *week_view);
diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c
index c2a0c2c61e..bcefd8eeee 100644
--- a/calendar/gui/gnome-cal.c
+++ b/calendar/gui/gnome-cal.c
@@ -61,8 +61,6 @@
#include "misc.h"
#include "ea-calendar.h"
-extern ECompEditorRegistry *comp_editor_registry;
-
/* Private part of the GnomeCalendar structure */
@@ -71,6 +69,8 @@ struct _GnomeCalendarPrivate {
* The Calendar Folder.
*/
+ GHashTable *clients;
+
/* Set of categories from the calendar client */
GPtrArray *cal_categories;
@@ -119,6 +119,7 @@ struct _GnomeCalendarPrivate {
/* This is the view currently shown. We use it to keep track of the
positions of the panes. range_selected is TRUE if a range of dates
was selected in the date navigator to show the view. */
+ ECalView *views[GNOME_CAL_LAST_VIEW];
GnomeCalendarViewType current_view_type;
gboolean range_selected;
@@ -145,10 +146,6 @@ struct _GnomeCalendarPrivate {
'dates-shown-changed' signal.*/
time_t visible_start;
time_t visible_end;
-
- /* Calendar query for purging old events */
- GList *exp_queries;
- time_t exp_older_than;
};
/* Signal IDs */
@@ -361,97 +358,70 @@ gnome_calendar_class_init (GnomeCalendarClass *class)
/* Callback used when the calendar query reports of an updated object */
static void
-dn_query_obj_updated_cb (CalQuery *query, const char *uid,
- gboolean query_in_progress, int n_scanned, int total,
- gpointer data)
+dn_query_objects_added_cb (CalQuery *query, GList *objects, gpointer data)
{
GnomeCalendar *gcal;
GnomeCalendarPrivate *priv;
- CalComponent *comp = NULL;
- icalcomponent *icalcomp;
- CalClientGetStatus status;
-
+ GList *l;
+
gcal = GNOME_CALENDAR (data);
priv = gcal->priv;
- /* If this is an update that is not part of an ongoing query, we have to
- * retag the whole thing: an event may change dates and the
- * tag_calendar_by_comp() below would not know how to untag the old
- * dates.
- */
- if (!query_in_progress) {
- update_query (gcal);
- return;
- }
+ for (l = objects; l; l = l->next) {
+ CalComponent *comp = NULL;
- status = cal_client_get_object (cal_query_get_client (query), uid, &icalcomp);
-
- switch (status) {
- case CAL_CLIENT_GET_SUCCESS:
comp = cal_component_new ();
- if (!cal_component_set_icalcomponent (comp, icalcomp)) {
+ if (!cal_component_set_icalcomponent (comp, icalcomponent_new_clone (l->data))) {
g_object_unref (comp);
- icalcomponent_free (icalcomp);
- return;
+
+ continue;
}
- break;
-
- case CAL_CLIENT_GET_SYNTAX_ERROR:
- g_message ("dn_query_obj_updated_cb(): Syntax error while getting object `%s'", uid);
- return;
-
- case CAL_CLIENT_GET_NOT_FOUND:
- /* The object is no longer in the server, so do nothing */
- return;
- default:
- g_assert_not_reached ();
- return;
+ tag_calendar_by_comp (priv->date_navigator, comp, cal_query_get_client (query), NULL,
+ FALSE, TRUE);
+ g_object_unref (comp);
}
-
- tag_calendar_by_comp (priv->date_navigator, comp, cal_query_get_client (query), NULL,
- FALSE, TRUE);
- g_object_unref (comp);
}
-/* Callback used when the calendar query reports of a removed object */
static void
-dn_query_obj_removed_cb (CalQuery *query, const char *uid, gpointer data)
+dn_query_objects_modified_cb (CalQuery *query, GList *objects, gpointer data)
{
GnomeCalendar *gcal;
+ GnomeCalendarPrivate *priv;
gcal = GNOME_CALENDAR (data);
+ priv = gcal->priv;
- /* Just retag the whole thing */
+ /* We have to retag the whole thing: an event may change dates
+ * and the tag_calendar_by_comp() below would not know how to
+ * untag the old dates.
+ */
update_query (gcal);
}
-/* Callback used when the calendar query is done */
+/* Callback used when the calendar query reports of a removed object */
static void
-dn_query_query_done_cb (CalQuery *query, CalQueryDoneStatus status, const char *error_str,
- gpointer data)
+dn_query_objects_removed_cb (CalQuery *query, GList *uids, gpointer data)
{
GnomeCalendar *gcal;
gcal = GNOME_CALENDAR (data);
- /* FIXME */
-
- if (status != CAL_QUERY_DONE_SUCCESS)
- fprintf (stderr, "query done: %s\n", error_str);
+ /* Just retag the whole thing */
+ update_query (gcal);
}
-/* Callback used when the calendar query reports an evaluation error */
+/* Callback used when the calendar query is done */
static void
-dn_query_eval_error_cb (CalQuery *query, const char *error_str, gpointer data)
+dn_query_done_cb (CalQuery *query, ECalendarStatus status, gpointer data)
{
GnomeCalendar *gcal;
gcal = GNOME_CALENDAR (data);
- /* FIXME */
-
- fprintf (stderr, "eval error: %s\n", error_str);
+ /* FIXME Better error reporting */
+ if (status != E_CALENDAR_STATUS_OK)
+ g_warning (G_STRLOC ": Query did not successfully complete");
}
/* Returns the current view widget, an EDayView, EWeekView or ECalListView. */
@@ -603,6 +573,7 @@ adjust_query_sexp (GnomeCalendar *gcal, const char *sexp)
start, end,
sexp);
+
g_free (start);
g_free (end);
@@ -649,22 +620,24 @@ update_query (GnomeCalendar *gcal)
/* create queries for each loaded client */
client_list = e_cal_model_get_client_list (e_cal_view_get_model (E_CAL_VIEW (priv->day_view)));
for (l = client_list; l != NULL; l = l->next) {
- old_query = cal_client_get_query ((CalClient *) l->data, real_sexp);
- if (!old_query) {
- g_message ("update_query(): Could not create the query");
+ if (!cal_client_get_query ((CalClient *) l->data, real_sexp, &old_query, NULL)) {
+ g_warning (G_STRLOC ": Could not create the query");
+
continue;
}
- g_signal_connect (old_query, "obj_updated",
- G_CALLBACK (dn_query_obj_updated_cb), gcal);
- g_signal_connect (old_query, "obj_removed",
- G_CALLBACK (dn_query_obj_removed_cb), gcal);
+ g_signal_connect (old_query, "objects_added",
+ G_CALLBACK (dn_query_objects_added_cb), gcal);
+ g_signal_connect (old_query, "objects_modified",
+ G_CALLBACK (dn_query_objects_modified_cb), gcal);
+ g_signal_connect (old_query, "objects_removed",
+ G_CALLBACK (dn_query_objects_removed_cb), gcal);
g_signal_connect (old_query, "query_done",
- G_CALLBACK (dn_query_query_done_cb), gcal);
- g_signal_connect (old_query, "eval_error",
- G_CALLBACK (dn_query_eval_error_cb), gcal);
+ G_CALLBACK (dn_query_done_cb), gcal);
priv->dn_queries = g_list_append (priv->dn_queries, old_query);
+
+ cal_query_start (old_query);
}
g_list_free (client_list);
@@ -673,6 +646,30 @@ update_query (GnomeCalendar *gcal)
e_cal_view_set_status_message (E_CAL_VIEW (priv->week_view), NULL);
}
+static void
+adjust_query_for_view (ECalView *cal_view, const char *sexp)
+{
+ char *real_sexp, *start, *end;
+ time_t ttstart, ttend;
+
+ e_cal_view_get_visible_time_range (cal_view, &ttstart, &ttend);
+
+ start = isodate_from_time_t (ttstart);
+ end = isodate_from_time_t (ttend);
+
+ real_sexp = g_strdup_printf (
+ "(and (occur-in-time-range? (make-time \"%s\")"
+ " (make-time \"%s\"))"
+ " %s)",
+ start, end, sexp);
+
+ e_cal_model_set_query (e_cal_view_get_model (cal_view), real_sexp);
+
+ g_free (start);
+ g_free (end);
+ g_free (real_sexp);
+}
+
/**
* gnome_calendar_set_query:
* @gcal: A calendar.
@@ -685,6 +682,7 @@ gnome_calendar_set_query (GnomeCalendar *gcal, const char *sexp)
{
GnomeCalendarPrivate *priv;
ECalModel *model;
+ int i;
g_return_if_fail (gcal != NULL);
g_return_if_fail (GNOME_IS_CALENDAR (gcal));
@@ -701,9 +699,9 @@ gnome_calendar_set_query (GnomeCalendar *gcal, const char *sexp)
update_query (gcal);
- /* Set the query on the main view */
- model = e_cal_view_get_model (E_CAL_VIEW (gnome_calendar_get_current_view_widget (gcal)));
- e_cal_model_set_query (model, sexp);
+ /* Set the query on the views */
+ for (i = 0; i < GNOME_CAL_LAST_VIEW; i++)
+ adjust_query_for_view (E_CAL_VIEW (priv->views[i]), sexp);
/* Set the query on the task pad */
model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo));
@@ -747,14 +745,15 @@ search_bar_category_changed_cb (CalSearchBar *cal_search, const char *category,
GnomeCalendar *gcal;
GnomeCalendarPrivate *priv;
ECalModel *model;
+ int i;
gcal = GNOME_CALENDAR (data);
priv = gcal->priv;
- e_day_view_set_default_category (E_DAY_VIEW (priv->day_view), category);
- e_day_view_set_default_category (E_DAY_VIEW (priv->work_week_view), category);
- e_week_view_set_default_category (E_WEEK_VIEW (priv->week_view), category);
- e_week_view_set_default_category (E_WEEK_VIEW (priv->month_view), category);
+ for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) {
+ e_cal_view_set_default_category (E_CAL_VIEW (priv->views[i]),
+ category);
+ }
model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo));
e_cal_model_set_default_category (model, category);
@@ -853,7 +852,6 @@ setup_widgets (GnomeCalendar *gcal)
GtkWidget *w;
gchar *filename;
ETable *etable;
- ECalModel *model;
priv = gcal->priv;
@@ -915,7 +913,8 @@ setup_widgets (GnomeCalendar *gcal)
gtk_paned_pack2 (GTK_PANED (priv->vpane), priv->todo, TRUE, TRUE);
gtk_widget_show (priv->todo);
- filename = g_strdup_printf ("%s/config/TaskPad", evolution_dir);
+ 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);
g_free (filename);
@@ -977,7 +976,7 @@ setup_widgets (GnomeCalendar *gcal)
connect_week_view_focus (gcal, E_WEEK_VIEW (priv->month_view));
/* The List View. */
- filename = g_strdup_printf ("%s/config/CalListView", evolution_dir);
+ filename = g_strdup_printf (".evolution/config/CalListView");
priv->list_view = e_cal_list_view_new (filename);
g_free (filename);
@@ -988,14 +987,12 @@ setup_widgets (GnomeCalendar *gcal)
connect_list_view_focus (gcal, E_CAL_LIST_VIEW (priv->list_view));
- model = (ECalModel *) e_cal_model_calendar_new ();
- e_cal_view_set_model (E_CAL_VIEW (priv->day_view), model);
- e_cal_view_set_model (E_CAL_VIEW (priv->work_week_view), model);
- e_cal_view_set_model (E_CAL_VIEW (priv->week_view), model);
- e_cal_view_set_model (E_CAL_VIEW (priv->month_view), model);
- e_cal_view_set_model (E_CAL_VIEW (priv->list_view), model);
+ priv->views[GNOME_CAL_DAY_VIEW] = E_CAL_VIEW (priv->day_view);
+ priv->views[GNOME_CAL_WORK_WEEK_VIEW] = E_CAL_VIEW (priv->work_week_view);
+ priv->views[GNOME_CAL_WEEK_VIEW] = E_CAL_VIEW (priv->week_view);
+ priv->views[GNOME_CAL_MONTH_VIEW] = E_CAL_VIEW (priv->month_view);
+ priv->views[GNOME_CAL_LIST_VIEW] = E_CAL_VIEW (priv->list_view);
- g_object_unref (model);
gnome_calendar_update_config_settings (gcal, TRUE);
}
@@ -1008,6 +1005,8 @@ gnome_calendar_init (GnomeCalendar *gcal)
priv = g_new0 (GnomeCalendarPrivate, 1);
gcal->priv = priv;
+ priv->clients = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
+
priv->cal_categories = NULL;
priv->tasks_categories = NULL;
@@ -1027,8 +1026,6 @@ gnome_calendar_init (GnomeCalendar *gcal)
priv->visible_start = -1;
priv->visible_end = -1;
-
- priv->exp_queries = NULL;
}
/* Frees a set of categories */
@@ -1062,6 +1059,8 @@ gnome_calendar_destroy (GtkObject *object)
if (priv) {
GList *l, *client_list;
+ g_hash_table_destroy (priv->clients);
+
free_categories (priv->cal_categories);
priv->cal_categories = NULL;
@@ -1078,7 +1077,8 @@ gnome_calendar_destroy (GtkObject *object)
g_list_free (client_list);
/* Save the TaskPad layout. */
- filename = g_strdup_printf ("%s/config/TaskPad", evolution_dir);
+ 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);
@@ -1120,19 +1120,6 @@ gnome_calendar_destroy (GtkObject *object)
priv->view_menus = NULL;
}
- if (priv->exp_queries) {
- GList *l;
-
- for (l = priv->exp_queries; l != NULL; l = l->next) {
- g_signal_handlers_disconnect_matched ((CalQuery *) l->data, G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, gcal);
- g_object_unref (l->data);
- }
-
- g_list_free (priv->exp_queries);
- priv->exp_queries = NULL;
- }
-
g_free (priv);
gcal->priv = NULL;
}
@@ -1764,7 +1751,8 @@ client_cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer da
case CAL_CLIENT_OPEN_SUCCESS:
/* Set the client's default timezone, if we have one. */
if (priv->zone) {
- cal_client_set_default_timezone (client, priv->zone);
+ /* FIXME Error checking */
+ cal_client_set_default_timezone (client, priv->zone, NULL);
}
/* add the alarms for this client */
@@ -1996,7 +1984,7 @@ gnome_calendar_construct (GnomeCalendar *gcal)
/*
* TaskPad Folder Client.
*/
- priv->task_pad_client = cal_client_new ();
+ priv->task_pad_client = cal_client_new ("", CALOBJ_TYPE_TODO); /* FIXME: use default tasks */
if (!priv->task_pad_client)
return NULL;
@@ -2063,7 +2051,8 @@ gnome_calendar_get_calendar_model (GnomeCalendar *gcal)
priv = gcal->priv;
- return e_cal_view_get_model (E_CAL_VIEW (priv->week_view));
+ return e_cal_view_get_model (
+ gnome_calendar_get_current_view_widget (gcal));
}
/**
@@ -2078,6 +2067,28 @@ gnome_calendar_get_default_client (GnomeCalendar *gcal)
}
/**
+ * gnome_calendar_set_default_client
+ * @gcal: A calendar view.
+ * @client: The client to use as default.
+ *
+ * Set the default client on the given calendar view. The default calendar will
+ * be used as the default when creating events in the view.
+ */
+void
+gnome_calendar_set_default_client (GnomeCalendar *gcal, CalClient *client)
+{
+ int i;
+
+ g_return_if_fail (GNOME_IS_CALENDAR (gcal));
+
+ for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) {
+ e_cal_model_set_default_client (
+ e_cal_view_get_model (E_CAL_VIEW (gcal->priv->views[i])),
+ client);
+ }
+}
+
+/**
* gnome_calendar_get_task_pad_cal_client:
* @gcal: A calendar view.
*
@@ -2145,67 +2156,56 @@ add_alarms (const char *uri)
CORBA_exception_free (&ev);
}
+/**
+ * gnome_calendar_add_event_uri:
+ * @gcal: A GnomeCalendar.
+ * @str_uri: URI to add to the calendar views.
+ *
+ * Adds the given calendar URI to the calendar views.
+ *
+ * Returns: TRUE if successful, FALSE if error.
+ */
gboolean
-gnome_calendar_open (GnomeCalendar *gcal, const char *str_uri)
+gnome_calendar_add_event_uri (GnomeCalendar *gcal, const char *str_uri)
{
GnomeCalendarPrivate *priv;
- gboolean success;
- EUri *uri;
- char *message;
- char *real_uri;
- char *urinopwd;
CalClient *client;
-
+ int i;
+
g_return_val_if_fail (gcal != NULL, FALSE);
g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), FALSE);
g_return_val_if_fail (str_uri != NULL, FALSE);
priv = gcal->priv;
- g_return_val_if_fail (
- cal_client_get_load_state (priv->task_pad_client) == CAL_CLIENT_LOAD_NOT_LOADED,
- FALSE);
-
- uri = e_uri_new (str_uri);
- if (!uri || !g_strncasecmp (uri->protocol, "file", 4))
- real_uri = g_concat_dir_and_file (str_uri, "calendar.ics");
- else
- real_uri = g_strdup (str_uri);
-
- urinopwd = get_uri_without_password (str_uri);
- message = g_strdup_printf (_("Opening calendar at %s"), urinopwd);
- g_free (urinopwd);
- e_cal_view_set_status_message (E_CAL_VIEW (priv->week_view), message);
- g_free (message);
-
- client = cal_client_new ();
- g_signal_connect (G_OBJECT (client), "cal_opened", G_CALLBACK (client_cal_opened_cb), gcal);
+ client = g_hash_table_lookup (priv->clients, str_uri);
+ if (client)
+ return TRUE;
+
+ client = cal_client_new (str_uri, CALOBJ_TYPE_EVENT);
+ g_hash_table_insert (priv->clients, g_strdup (str_uri), g_object_ref (client));
+
g_signal_connect (G_OBJECT (client), "backend_error", G_CALLBACK (backend_error_cb), gcal);
g_signal_connect (G_OBJECT (client), "categories_changed", G_CALLBACK (client_categories_changed_cb), gcal);
g_signal_connect (G_OBJECT (client), "backend_died", G_CALLBACK (backend_died_cb), gcal);
- if (!cal_client_open_calendar (client, real_uri, FALSE)) {
- g_warning (G_STRLOC ": Could not issue the request to open the calendar folder");
+ if (!cal_client_open (client, FALSE, NULL)) {
+ g_hash_table_remove (priv->clients, str_uri);
g_object_unref (client);
- e_cal_view_set_status_message (E_CAL_VIEW (priv->week_view), NULL);
return FALSE;
}
- /* Open the appropriate Tasks folder to show in the TaskPad */
- e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo),
- _("Opening default tasks folder"));
- success = cal_client_open_default_tasks (priv->task_pad_client, FALSE);
-
- g_free (real_uri);
- e_uri_free (uri);
-
- if (!success) {
- g_message ("gnome_calendar_open(): Could not issue the request to open the tasks folder");
- e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo), NULL);
- return FALSE;
+ for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) {
+ ECalModel *model;
+
+ model = e_cal_view_get_model (priv->views[i]);
+ e_cal_model_add_client (model, client);
}
+ /* update date navigator query */
+ update_query (gcal);
+
return TRUE;
}
@@ -2308,7 +2308,8 @@ gnome_calendar_update_config_settings (GnomeCalendar *gcal,
CalClient *client = l->data;
if (cal_client_get_load_state (client) == CAL_CLIENT_LOAD_LOADED)
- cal_client_set_default_timezone (client, priv->zone);
+ /* FIXME Error checking */
+ cal_client_set_default_timezone (client, priv->zone, NULL);
}
g_list_free (client_list);
@@ -2316,8 +2317,9 @@ gnome_calendar_update_config_settings (GnomeCalendar *gcal,
if (priv->task_pad_client
&& cal_client_get_load_state (priv->task_pad_client) == CAL_CLIENT_LOAD_LOADED) {
+ /* FIXME Error Checking */
cal_client_set_default_timezone (priv->task_pad_client,
- priv->zone);
+ priv->zone, NULL);
}
e_cal_view_set_timezone (E_CAL_VIEW (priv->day_view), priv->zone);
@@ -2383,147 +2385,6 @@ gnome_calendar_get_selected_time_range (GnomeCalendar *gcal,
*end_time = priv->selection_end_time;
}
-void
-gnome_calendar_edit_object (GnomeCalendar *gcal, CalClient *client, icalcomponent *icalcomp, gboolean meeting)
-{
- GnomeCalendarPrivate *priv;
- CompEditor *ce;
- const char *uid;
- CalComponent *comp;
-
- g_return_if_fail (GNOME_IS_CALENDAR (gcal));
- g_return_if_fail (IS_CAL_CLIENT (client));
- g_return_if_fail (icalcomp != NULL);
-
- priv = gcal->priv;
-
- uid = icalcomponent_get_uid (icalcomp);
-
- ce = e_comp_editor_registry_find (comp_editor_registry, uid);
- if (!ce) {
- EventEditor *ee;
-
- ee = event_editor_new (client);
- if (!ee) {
- g_message ("gnome_calendar_edit_object(): Could not create the event editor");
- return;
- }
- ce = COMP_EDITOR (ee);
-
- comp = cal_component_new ();
- cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp));
-
- comp_editor_edit_comp (ce, comp);
- if (meeting)
- event_editor_show_meeting (ee);
-
- e_comp_editor_registry_add (comp_editor_registry, ce, FALSE);
-
- g_object_unref (comp);
- }
-
- comp_editor_focus (ce);
-}
-
-/**
- * gnome_calendar_new_appointment_for:
- * @gcal: An Evolution calendar.
- * @dtstart: a Unix time_t that marks the beginning of the appointment.
- * @dtend: a Unix time_t that marks the end of the appointment.
- * @all_day: if true, the dtstart and dtend are expanded to cover the entire
- * day, and the event is set to TRANSPARENT.
- *
- * Opens an event editor dialog for a new appointment.
- *
- **/
-void
-gnome_calendar_new_appointment_for (GnomeCalendar *cal,
- time_t dtstart, time_t dtend,
- gboolean all_day,
- gboolean meeting)
-{
- GnomeCalendarPrivate *priv;
- struct icaltimetype itt;
- CalComponentDateTime dt;
- CalComponent *comp;
- icalcomponent *icalcomp;
- CalComponentTransparency transparency;
- const char *category;
-
- g_return_if_fail (cal != NULL);
- g_return_if_fail (GNOME_IS_CALENDAR (cal));
-
- priv = cal->priv;
-
- dt.value = &itt;
- if (all_day)
- dt.tzid = NULL;
- else
- dt.tzid = icaltimezone_get_tzid (priv->zone);
-
- icalcomp = e_cal_model_create_component_with_defaults (e_cal_view_get_model (E_CAL_VIEW (priv->week_view)));
- comp = cal_component_new ();
- cal_component_set_icalcomponent (comp, icalcomp);
-
- /* DTSTART, DTEND */
-
- itt = icaltime_from_timet_with_zone (dtstart, FALSE, priv->zone);
- if (all_day) {
- itt.hour = itt.minute = itt.second = 0;
- itt.is_date = TRUE;
- }
- cal_component_set_dtstart (comp, &dt);
-
- itt = icaltime_from_timet_with_zone (dtend, FALSE, priv->zone);
- if (all_day) {
- /* We round it up to the end of the day, unless it is already
- set to midnight. */
- if (itt.hour != 0 || itt.minute != 0 || itt.second != 0) {
- icaltime_adjust (&itt, 1, 0, 0, 0);
- }
- itt.hour = itt.minute = itt.second = 0;
- itt.is_date = TRUE;
- }
- cal_component_set_dtend (comp, &dt);
-
- transparency = all_day ? CAL_COMPONENT_TRANSP_TRANSPARENT
- : CAL_COMPONENT_TRANSP_OPAQUE;
- cal_component_set_transparency (comp, transparency);
-
-
- /* Category */
-
- category = cal_search_bar_get_category (CAL_SEARCH_BAR (priv->search_bar));
- cal_component_set_categories (comp, category);
-
- /* Edit! */
-
- cal_component_commit_sequence (comp);
-
- gnome_calendar_edit_object (cal, gnome_calendar_get_default_client (cal), icalcomp, meeting);
- g_object_unref (comp);
-}
-
-/**
- * gnome_calendar_new_appointment:
- * @gcal: An Evolution calendar.
- *
- * Opens an event editor dialog for a new appointment. The appointment's start
- * and end times are set to the currently selected time range in the calendar
- * views.
- **/
-void
-gnome_calendar_new_appointment (GnomeCalendar *gcal)
-{
- time_t dtstart, dtend;
-
- g_return_if_fail (gcal != NULL);
- g_return_if_fail (GNOME_IS_CALENDAR (gcal));
-
- gnome_calendar_get_current_time_range (gcal, &dtstart, &dtend);
- gnome_calendar_new_appointment_for (gcal, dtstart, dtend, FALSE, FALSE);
-}
-
/**
* gnome_calendar_new_task:
* @gcal: An Evolution calendar.
@@ -3020,136 +2881,17 @@ gnome_calendar_delete_selected_occurrence (GnomeCalendar *gcal)
}
}
-void
-gnome_calendar_unrecur_selection (GnomeCalendar *gcal)
-{
- GnomeCalendarPrivate *priv;
- FocusLocation location;
- GtkWidget *view;
-
- 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);
-
- if (E_IS_DAY_VIEW (view))
- e_day_view_unrecur_appointment (E_DAY_VIEW (view));
- else
- e_week_view_unrecur_appointment (E_WEEK_VIEW (view));
- }
-}
-
-typedef struct {
- gboolean remove;
- GnomeCalendar *gcal;
-} obj_updated_closure;
-
static gboolean
check_instance_cb (CalComponent *comp,
time_t instance_start,
time_t instance_end,
gpointer data)
{
- obj_updated_closure *closure = data;
-
- if (instance_start >= closure->gcal->priv->exp_older_than ||
- instance_end >= closure->gcal->priv->exp_older_than) {
- closure->remove = FALSE;
- return FALSE;
- }
-
- closure->remove = TRUE;
- return TRUE;
-}
-
-static void
-purging_obj_updated_cb (CalQuery *query, const char *uid,
- gboolean query_in_progress, int n_scanned, int total,
- gpointer data)
-{
- GnomeCalendarPrivate *priv;
- GnomeCalendar *gcal = data;
- CalComponent *comp;
- icalcomponent *icalcomp;
- obj_updated_closure closure;
- gchar *msg;
-
- priv = gcal->priv;
-
- if (cal_client_get_object (cal_query_get_client (query), uid, &icalcomp) != CAL_CLIENT_GET_SUCCESS)
- return;
-
- comp = cal_component_new ();
- if (!cal_component_set_icalcomponent (comp, icalcomp)) {
- g_object_unref (comp);
- icalcomponent_free (icalcomp);
- return;
- }
-
- msg = g_strdup_printf (_("Purging event %s"), uid);
-
- /* further filter the event, to check the last recurrence end date */
- if (cal_component_has_recurrences (comp)) {
- closure.remove = TRUE;
- closure.gcal = gcal;
-
- cal_recur_generate_instances (comp, priv->exp_older_than, -1,
- (CalRecurInstanceFn) check_instance_cb,
- &closure,
- (CalRecurResolveTimezoneFn) cal_client_resolve_tzid_cb,
- cal_query_get_client (query), priv->zone);
-
- if (closure.remove) {
- e_cal_view_set_status_message (E_CAL_VIEW (priv->week_view), msg);
- delete_error_dialog (cal_client_remove_object (cal_query_get_client (query), uid),
- CAL_COMPONENT_EVENT);
- }
- } else {
- e_cal_view_set_status_message (E_CAL_VIEW (priv->week_view), msg);
- delete_error_dialog (cal_client_remove_object (cal_query_get_client (query), uid), CAL_COMPONENT_EVENT);
- }
-
- g_object_unref (comp);
- g_free (msg);
-}
-
-static void
-purging_eval_error_cb (CalQuery *query, const char *error_str, gpointer data)
-{
- GnomeCalendarPrivate *priv;
- GnomeCalendar *gcal = data;
-
- priv = gcal->priv;
-
- e_cal_view_set_status_message (E_CAL_VIEW (priv->week_view), NULL);
-
- g_signal_handlers_disconnect_matched (query, G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, gcal);
-
- priv->exp_queries = g_list_remove (priv->exp_queries, query);
- g_object_unref (query);
-}
+ gboolean *remove = data;
-static void
-purging_query_done_cb (CalQuery *query, CalQueryDoneStatus status, const char *error_str, gpointer data)
-{
- GnomeCalendarPrivate *priv;
- GnomeCalendar *gcal = data;
-
- priv = gcal->priv;
-
- e_cal_view_set_status_message (E_CAL_VIEW (priv->week_view), NULL);
+ *remove = FALSE;
- g_signal_handlers_disconnect_matched (query, G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, gcal);
-
- priv->exp_queries = g_list_remove (priv->exp_queries, query);
- g_object_unref (query);
+ return FALSE;
}
void
@@ -3163,11 +2905,6 @@ gnome_calendar_purge (GnomeCalendar *gcal, time_t older_than)
priv = gcal->priv;
- /* if we have a query, we are already purging */
- if (priv->exp_queries)
- return;
-
- priv->exp_older_than = older_than;
start = isodate_from_time_t (0);
end = isodate_from_time_t (older_than);
sexp = g_strdup_printf ("(and (= (get-vtype) \"VEVENT\")"
@@ -3177,27 +2914,47 @@ gnome_calendar_purge (GnomeCalendar *gcal, time_t older_than)
e_cal_view_set_status_message (E_CAL_VIEW (priv->week_view), _("Purging"));
+ /* FIXME Confirm expunge */
+
client_list = e_cal_model_get_client_list (e_cal_view_get_model (E_CAL_VIEW (priv->week_view)));
for (l = client_list; l != NULL; l = l->next) {
- CalQuery *exp_query;
-
- if (cal_client_is_read_only ((CalClient *) l->data))
+ CalClient *client = l->data;
+ GList *objects, *l;
+ gboolean read_only = TRUE;
+
+ cal_client_is_read_only (client, &read_only, NULL);
+ if (!read_only)
continue;
-
- exp_query = cal_client_get_query ((CalClient *) l->data, sexp);
- if (!exp_query) {
- e_cal_view_set_status_message (E_CAL_VIEW (priv->week_view), NULL);
- g_message ("gnome_calendar_purge(): Could not create the query");
+
+ if (!cal_client_get_object_list (client, sexp, &objects, NULL)) {
+ g_warning (G_STRLOC ": Could not get the objects");
+
continue;
}
-
- g_signal_connect (exp_query, "obj_updated", G_CALLBACK (purging_obj_updated_cb), gcal);
- g_signal_connect (exp_query, "query_done", G_CALLBACK (purging_query_done_cb), gcal);
- g_signal_connect (exp_query, "eval_error", G_CALLBACK (purging_eval_error_cb), gcal);
-
- priv->exp_queries = g_list_append (priv->exp_queries, exp_query);
+
+ for (l = objects; l; l = l->next) {
+ CalComponent *comp;
+ gboolean remove = TRUE;
+
+ comp = cal_component_new ();
+ cal_component_set_icalcomponent (comp, icalcomponent_new_clone (l->data));
+
+ cal_recur_generate_instances (comp, older_than, -1,
+ (CalRecurInstanceFn) check_instance_cb,
+ &remove,
+ (CalRecurResolveTimezoneFn) cal_client_resolve_tzid_cb,
+ client, priv->zone);
+
+ /* FIXME Better error handling */
+ if (remove)
+ cal_client_remove_object (client, icalcomponent_get_uid (l->data), NULL);
+
+ g_object_unref (comp);
+ }
}
+ e_cal_view_set_status_message (E_CAL_VIEW (priv->week_view), NULL);
+
g_list_free (client_list);
g_free (sexp);
g_free (start);
diff --git a/calendar/gui/gnome-cal.h b/calendar/gui/gnome-cal.h
index c9bbcbaff4..f56ec69211 100644
--- a/calendar/gui/gnome-cal.h
+++ b/calendar/gui/gnome-cal.h
@@ -55,7 +55,8 @@ typedef enum {
GNOME_CAL_WORK_WEEK_VIEW,
GNOME_CAL_WEEK_VIEW,
GNOME_CAL_MONTH_VIEW,
- GNOME_CAL_LIST_VIEW
+ GNOME_CAL_LIST_VIEW,
+ GNOME_CAL_LAST_VIEW
} GnomeCalendarViewType;
typedef enum
@@ -106,9 +107,10 @@ ECalendarTable *gnome_calendar_get_task_pad (GnomeCalendar *gcal);
ECalModel *gnome_calendar_get_calendar_model (GnomeCalendar *gcal);
CalClient *gnome_calendar_get_default_client (GnomeCalendar *gcal);
+void gnome_calendar_set_default_client (GnomeCalendar *gcal, CalClient *client);
CalClient *gnome_calendar_get_task_pad_cal_client(GnomeCalendar *gcal);
-gboolean gnome_calendar_open (GnomeCalendar *gcal, const char *str_uri);
+gboolean gnome_calendar_add_event_uri (GnomeCalendar *gcal, const char *str_uri);
void gnome_calendar_set_query (GnomeCalendar *gcal, const char *sexp);
@@ -145,17 +147,6 @@ void gnome_calendar_get_selected_time_range (GnomeCalendar *gcal,
time_t *start_time,
time_t *end_time);
-void gnome_calendar_edit_object (GnomeCalendar *gcal,
- CalClient *client,
- icalcomponent *icalcomp,
- gboolean meeting);
-
-void gnome_calendar_new_appointment (GnomeCalendar *gcal);
-void gnome_calendar_new_appointment_for (GnomeCalendar *cal,
- time_t dtstart, time_t dtend,
- gboolean all_day,
- gboolean meeting);
-
void gnome_calendar_new_task (GnomeCalendar *gcal);
/* Returns the selected time range for the current view. Note that this may be
@@ -193,7 +184,6 @@ void gnome_calendar_paste_clipboard (GnomeCalendar *gcal);
void gnome_calendar_delete_selection (GnomeCalendar *gcal);
void gnome_calendar_delete_selected_occurrence (GnomeCalendar *gcal);
-void gnome_calendar_unrecur_selection (GnomeCalendar *gcal);
void gnome_calendar_purge (GnomeCalendar *gcal,
time_t older_than);
diff --git a/calendar/gui/itip-utils.c b/calendar/gui/itip-utils.c
index f5baa8bb05..e2640f01f4 100644
--- a/calendar/gui/itip-utils.c
+++ b/calendar/gui/itip-utils.c
@@ -70,8 +70,11 @@ static EAccountList *accounts = NULL;
EAccountList *
itip_addresses_get (void)
{
- if (accounts == NULL)
- accounts = e_account_list_new(gconf_client_get_default());
+ if (accounts == NULL) {
+ GConfClient *gconf_client = gconf_client_get_default ();
+ accounts = e_account_list_new (gconf_client);
+ g_object_unref (gconf_client);
+ }
return accounts;
}
@@ -98,12 +101,14 @@ itip_organizer_is_user (CalComponent *comp, CalClient *client)
strip = itip_strip_mailto (organizer.value);
if (cal_client_get_static_capability (client, CAL_STATIC_CAPABILITY_ORGANIZER_NOT_EMAIL_ADDRESS)) {
- const char *email;
+ char *email;
- email = cal_client_get_cal_address (client);
- if (email && !g_strcasecmp (email, strip))
+ if (cal_client_get_cal_address (client, &email, NULL) && !g_strcasecmp (email, strip)) {
+ g_free (email);
+
return TRUE;
-
+ }
+
return FALSE;
}
@@ -185,8 +190,8 @@ foreach_tzid_callback (icalparameter *param, gpointer data)
zone = icalcomponent_get_timezone (tz_data->zones, tzid);
if (zone == NULL)
zone = icaltimezone_get_builtin_timezone_from_tzid (tzid);
- if (zone == NULL && tz_data->client != NULL)
- cal_client_get_timezone (tz_data->client, tzid, &zone);
+ if (zone == NULL && tz_data->client != NULL)
+ cal_client_get_timezone (tz_data->client, tzid, &zone, NULL);
if (zone == NULL)
return;
@@ -528,28 +533,23 @@ static gboolean
comp_server_send (CalComponentItipMethod method, CalComponent *comp, CalClient *client,
icalcomponent *zones, GList **users)
{
- CalClientSendResult result;
- icalcomponent *top_level, *new_top_level = NULL;
- char *error_msg;
+ icalcomponent *top_level;
gboolean retval = TRUE;
+ GError *error = NULL;
top_level = comp_toplevel_with_zones (method, comp, client, zones);
- result = cal_client_send_object (client, top_level, &new_top_level, users, &error_msg);
-
- if (result == CAL_CLIENT_SEND_SUCCESS) {
- icalcomponent *ical_comp;
-
- ical_comp = icalcomponent_get_inner (new_top_level);
- icalcomponent_remove_component (new_top_level, ical_comp);
- cal_component_set_icalcomponent (comp, ical_comp);
- icalcomponent_free (new_top_level);
- } else if (result == CAL_CLIENT_SEND_BUSY) {
- e_notice (NULL, GTK_MESSAGE_ERROR, error_msg);
-
- g_free (error_msg);
- retval = FALSE;
+ if (!cal_client_send_objects (client, top_level, &error)) {
+ /* FIXME Really need a book problem status code */
+ if (error->code != E_CALENDAR_STATUS_OK) {
+ /* FIXME Better error message */
+ e_notice (NULL, GTK_MESSAGE_ERROR, "Unable to book");
+
+ retval = FALSE;
+ }
}
+ g_clear_error (&error);
+
icalcomponent_free (top_level);
return retval;
@@ -755,7 +755,8 @@ comp_compliant (CalComponentItipMethod method, CalComponent *comp, CalClient *cl
if (from_zone == NULL)
from_zone = icaltimezone_get_builtin_timezone_from_tzid (dt.tzid);
if (from_zone == NULL && client != NULL)
- cal_client_get_timezone (client, dt.tzid, &from_zone);
+ /* FIXME Error checking */
+ cal_client_get_timezone (client, dt.tzid, &from_zone, NULL);
}
to_zone = icaltimezone_get_utc_timezone ();
diff --git a/calendar/gui/main.c b/calendar/gui/main.c
index a15c0ef846..681417f1df 100644
--- a/calendar/gui/main.c
+++ b/calendar/gui/main.c
@@ -49,9 +49,9 @@
#include "tasks-control.h"
-#define FACTORY_ID "OAFIID:GNOME_Evolution_Calendar_Factory"
+#define FACTORY_ID "OAFIID:GNOME_Evolution_Calendar_Factory_2"
-#define CALENDAR_COMPONENT_ID "OAFIID:GNOME_Evolution_Calendar_ShellComponent"
+#define CALENDAR_COMPONENT_ID "OAFIID:GNOME_Evolution_Calendar_Component"
#define CALENDAR_CONTROL_ID "OAFIID:GNOME_Evolution_Calendar_Control"
#define TASKS_CONTROL_ID "OAFIID:GNOME_Evolution_Tasks_Control"
#define ITIP_CONTROL_ID "OAFIID:GNOME_Evolution_Calendar_iTip_Control"
@@ -155,23 +155,19 @@ factory (BonoboGenericFactory *factory,
initialized = TRUE;
}
- if (strcmp (component_id, CALENDAR_COMPONENT_ID) == 0)
- return calendar_component_get_object ();
- if (strcmp (component_id, CALENDAR_CONTROL_ID) == 0)
+ 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, CALENDAR_CONTROL_ID) == 0)
return BONOBO_OBJECT (control_factory_new_control ());
- if (strcmp (component_id, TASKS_CONTROL_ID) == 0)
+ else if (strcmp (component_id, TASKS_CONTROL_ID) == 0)
return BONOBO_OBJECT (tasks_control_new ());
- if (strcmp (component_id, ITIP_CONTROL_ID) == 0)
+ else if (strcmp (component_id, ITIP_CONTROL_ID) == 0)
return BONOBO_OBJECT (itip_bonobo_control_new ());
- if (strcmp (component_id, CONFIG_CONTROL_ID) == 0) {
- extern EvolutionShellClient *global_shell_client; /* FIXME ugly */
-
- if (global_shell_client == NULL)
- return NULL;
- else
- return BONOBO_OBJECT (cal_prefs_dialog_new ());
- }
- if (strcmp (component_id, COMP_EDITOR_FACTORY_ID) == 0)
+ else if (strcmp (component_id, CONFIG_CONTROL_ID) == 0)
+ return BONOBO_OBJECT (cal_prefs_dialog_new ());
+ 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);
diff --git a/calendar/gui/migration.c b/calendar/gui/migration.c
new file mode 100644
index 0000000000..be93309f1f
--- /dev/null
+++ b/calendar/gui/migration.c
@@ -0,0 +1,126 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* calendar-component.c
+ *
+ * Copyright (C) 2003 Ximian, Inc
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Rodrigo Moya <rodrigo@ximian.com>
+ */
+
+#include <bonobo/bonobo-i18n.h>
+#include <libgnomevfs/gnome-vfs-uri.h>
+#include <libgnomevfs/gnome-vfs-xfer.h>
+#include <gal/util/e-util.h>
+#include "migration.h"
+
+static gboolean
+process_calendar_dir (ESourceGroup *source_group, const char *path,
+ const char *name, const char *base_uri)
+{
+ char *s;
+ GnomeVFSURI *from, *to;
+ GnomeVFSResult vres;
+ ESource *source;
+ GDir *dir;
+ gboolean retval = TRUE;
+
+ s = g_build_filename (path, "calendar.ics", NULL);
+ if (!g_file_test (s, G_FILE_TEST_EXISTS)) {
+ g_free (s);
+ return FALSE;
+ }
+
+ /* transfer the old file to its new location */
+ from = gnome_vfs_uri_new (s);
+ g_free (s);
+ if (!from)
+ return FALSE;
+
+ s = g_build_filename (e_source_group_peek_base_uri (source_group), base_uri,
+ "calendar.ics", NULL);
+ if (e_mkdir_hier (s, 0700) != 0) {
+ gnome_vfs_uri_unref (from);
+ g_free (s);
+ return FALSE;
+ }
+ to = gnome_vfs_uri_new (s);
+ g_free (s);
+ if (!to) {
+ gnome_vfs_uri_unref (from);
+ return FALSE;
+ }
+
+ vres = gnome_vfs_xfer_uri ((const GnomeVFSURI *) from,
+ (const GnomeVFSURI *) to,
+ GNOME_VFS_XFER_DEFAULT,
+ GNOME_VFS_XFER_ERROR_MODE_ABORT,
+ GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE,
+ NULL, NULL);
+ gnome_vfs_uri_unref (from);
+ gnome_vfs_uri_unref (to);
+
+ if (vres != GNOME_VFS_OK)
+ return FALSE;
+
+ /* create the new source */
+ source = e_source_new (name, base_uri);
+ e_source_group_add_source (source_group, source, -1);
+
+ /* process subfolders */
+ s = g_build_filename (path, "subfolders", NULL);
+ dir = g_dir_open (s, 0, NULL);
+ if (dir) {
+ const char *name, *tmp_s;
+
+ while ((name = g_dir_read_name (dir))) {
+ tmp_s = g_build_filename (s, name, NULL);
+ if (g_file_test (tmp_s, G_FILE_TEST_IS_DIR)) {
+ retval = process_calendar_dir (source_group, tmp_s, name, name);
+ }
+
+ g_free (tmp_s);
+ }
+
+ g_dir_close (dir);
+ }
+
+ g_free (s);
+
+ return retval;
+}
+
+gboolean
+migrate_old_calendars (ESourceGroup *source_group)
+{
+ char *path;
+ gboolean retval;
+
+ g_return_val_if_fail (E_IS_SOURCE_GROUP (source_group), FALSE);
+
+ path = g_build_filename (g_get_home_dir (), "evolution", NULL);
+ if (!g_file_test (path, G_FILE_TEST_IS_DIR)) {
+ g_free (path);
+ return FALSE;
+ }
+ g_free (path);
+
+ /* look for the top-level calendar */
+ path = g_build_filename (g_get_home_dir (), "evolution/local/Calendar", NULL);
+ retval = process_calendar_dir (source_group, path, _("Personal"), "Personal");
+ g_free (path);
+
+ return retval;
+}
diff --git a/calendar/gui/migration.h b/calendar/gui/migration.h
new file mode 100644
index 0000000000..2453d47abd
--- /dev/null
+++ b/calendar/gui/migration.h
@@ -0,0 +1,30 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* calendar-component.c
+ *
+ * Copyright (C) 2003 Ximian, Inc
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Rodrigo Moya <rodrigo@ximian.com>
+ */
+
+#ifndef MIGRATION_H
+#define MIGRATION_H
+
+#include <e-util/e-source-group.h>
+
+gboolean migrate_old_calendars (ESourceGroup *source_group);
+
+#endif
diff --git a/calendar/gui/print.c b/calendar/gui/print.c
index 6aeb9f6566..0c0fa44886 100644
--- a/calendar/gui/print.c
+++ b/calendar/gui/print.c
@@ -522,6 +522,16 @@ format_date(time_t time, int flags, char *buffer, int bufflen)
return buffer;
}
+static gboolean
+instance_cb (CalComponent *comp, time_t instance_start, time_t instance_end, gpointer data)
+{
+ gboolean *found = data;
+
+ *found = TRUE;
+
+ return FALSE;
+}
+
/*
print out the month small, embolden any days with events.
@@ -625,16 +635,16 @@ print_month_small (GnomePrintContext *pc, GnomeCalendar *gcal, time_t month,
day = days[y * 7 + x];
if (day != 0) {
- GList *uids;
+ gboolean found = FALSE;
sprintf (buf, "%d", day);
/* this is a slow messy way to do this ... but easy ... */
- uids = cal_client_get_objects_in_range (client,
- CALOBJ_TYPE_EVENT,
- now, time_day_end_with_zone (now, zone));
- font = uids ? font_bold : font_normal;
- cal_obj_uid_list_free (uids);
+ cal_client_generate_instances (client, now, CALOBJ_TYPE_EVENT,
+ time_day_end_with_zone (now, zone),
+ instance_cb, &found);
+
+ font = found ? font_bold : font_normal;
next = time_add_day_with_zone (now, 1, zone);
if ((now >= greystart && now < greyend)
@@ -1805,7 +1815,7 @@ print_todo_details (GnomePrintContext *pc, GnomeCalendar *gcal,
comp = cal_component_new ();
cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp));
- cal_component_get_summary (comp_data->icalcomp, &summary);
+ cal_component_get_summary (comp, &summary);
if (!summary.value) {
g_object_unref (comp);
continue;
@@ -2161,11 +2171,8 @@ get_zone_from_tzid (CalClient *client, const char *tzid)
the builtin timezone with the TZID first. */
zone = icaltimezone_get_builtin_timezone_from_tzid (tzid);
if (!zone) {
- CalClientGetStatus status;
-
- status = cal_client_get_timezone (client, tzid, &zone);
- /* FIXME: Handle error better. */
- if (status != CAL_CLIENT_GET_SUCCESS)
+ if (!cal_client_get_timezone (client, tzid, &zone, NULL))
+ /* FIXME: Handle error better. */
g_warning ("Couldn't get timezone from server: %s",
tzid ? tzid : "");
}
diff --git a/calendar/gui/tag-calendar.c b/calendar/gui/tag-calendar.c
index 03e0b3dee4..147a69f246 100644
--- a/calendar/gui/tag-calendar.c
+++ b/calendar/gui/tag-calendar.c
@@ -162,7 +162,6 @@ resolve_tzid_cb (const char *tzid, gpointer data)
{
CalClient *client;
icaltimezone *zone = NULL;
- CalClientGetStatus status;
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (IS_CAL_CLIENT (data), NULL);
@@ -174,7 +173,7 @@ resolve_tzid_cb (const char *tzid, gpointer data)
if (!zone) {
/* FIXME: Handle errors. */
- status = cal_client_get_timezone (client, tzid, &zone);
+ cal_client_get_timezone (client, tzid, &zone, NULL);
}
return zone;
diff --git a/calendar/gui/tasks-control.c b/calendar/gui/tasks-control.c
index 5ed9faa0d6..d97ed2d585 100644
--- a/calendar/gui/tasks-control.c
+++ b/calendar/gui/tasks-control.c
@@ -235,12 +235,12 @@ static void
sensitize_commands (ETasks *tasks, BonoboControl *control, int n_selected)
{
BonoboUIComponent *uic;
- gboolean read_only;
+ gboolean read_only = TRUE;
uic = bonobo_control_get_ui_component (control);
g_assert (uic != NULL);
- read_only = cal_client_is_read_only (e_tasks_get_cal_client (tasks));
+ cal_client_is_read_only (e_tasks_get_cal_client (tasks), &read_only, NULL);
bonobo_ui_component_set_prop (uic, "/commands/TasksCut", "sensitive",
n_selected == 0 || read_only ? "0" : "1",