diff options
author | nobody <nobody@localhost> | 2001-02-22 03:34:27 +0800 |
---|---|---|
committer | nobody <nobody@localhost> | 2001-02-22 03:34:27 +0800 |
commit | 19d71e1c5029e8c4048d9b8ace72affc28f2d04f (patch) | |
tree | f1ea97702781d0b26bb97bd28213ed46368377b6 /calendar | |
parent | 535fea211a9a35f5b04017124a71764daf926723 (diff) | |
download | gsoc2013-evolution-19d71e1c5029e8c4048d9b8ace72affc28f2d04f.tar gsoc2013-evolution-19d71e1c5029e8c4048d9b8ace72affc28f2d04f.tar.gz gsoc2013-evolution-19d71e1c5029e8c4048d9b8ace72affc28f2d04f.tar.bz2 gsoc2013-evolution-19d71e1c5029e8c4048d9b8ace72affc28f2d04f.tar.lz gsoc2013-evolution-19d71e1c5029e8c4048d9b8ace72affc28f2d04f.tar.xz gsoc2013-evolution-19d71e1c5029e8c4048d9b8ace72affc28f2d04f.tar.zst gsoc2013-evolution-19d71e1c5029e8c4048d9b8ace72affc28f2d04f.zip |
This commit was manufactured by cvs2svn to create tagGNUMERIC_0_63
'GNUMERIC_0_63'.
svn path=/tags/GNUMERIC_0_63/; revision=8333
Diffstat (limited to 'calendar')
188 files changed, 0 insertions, 78512 deletions
diff --git a/calendar/.cvsignore b/calendar/.cvsignore deleted file mode 100644 index b7f7dea650..0000000000 --- a/calendar/.cvsignore +++ /dev/null @@ -1,6 +0,0 @@ -Makefile.in -Makefile -.deps -_libs -.libs -*.lo diff --git a/calendar/AUTHORS b/calendar/AUTHORS deleted file mode 100644 index 0049fa248e..0000000000 --- a/calendar/AUTHORS +++ /dev/null @@ -1,5 +0,0 @@ -Miguel de Icaza <miguel@kernel.org> -Federico Mena <federico@helixcode.com> -Arturo Esponosa <arturo@nuclecu.unam.mx> -Russell Steinthal <rms39@columbia.edu> -Rodrigo Moya <rodrigo@ximian.com> diff --git a/calendar/ChangeLog b/calendar/ChangeLog deleted file mode 100644 index acdead7cf6..0000000000 --- a/calendar/ChangeLog +++ /dev/null @@ -1,9487 +0,0 @@ -2001-02-16 Federico Mena Quintero <federico@ximian.com> - - * pcs/cal-factory.c (CalFactoryPrivate): Added a `registered' - field. - (cal_factory_oaf_register): New function; now the factory performs - its own registration with OAF. - (cal_factory_destroy): Unregister from OAF if appropriate. - -2001-02-19 JP Rosevear <jpr@ximian.com> - - * conduits/todo/Makefile.am: Remove PISOCK_LIBDIR - - * conduits/calendar/Makefile.am: ditto - -2001-02-16 Rodrigo Moya <rodrigo@ximian.com> - - * pcs/calbackend-db.c (cal_backend_db_destroy): close DB environment. - Some compilation warnings removed - -2001-02-13 Christopher James Lahey <clahey@ximian.com> - - * gui/Makefile.am (evolution_calendar_LDADD): Added libmenus.la. - - * gui/e-calendar-table.c, gui/e-calendar-table.h - (e_calendar_table_get_spec): Added this function. - - * gui/e-tasks.c, gui/e-tasks.h (e_tasks_setup_menus): Added this - function. - - * gui/tasks-control.c (tasks_control_activate): Call - e_tasks_setup_menus. - -2001-02-13 JP Rosevear <jpr@ximian.com> - - * gui/e-tasks.c (e_tasks_new_task): call task_editor_focus - -2001-02-13 JP Rosevear <jpr@ximian.com> - - * gui/calendar-commands.c (update_pixmaps): Set toolbar new - appointment icon - (set_pixmap): load files rather than create from xpm file - - * gui/*view.xpm: move to the art directory - -2001-02-13 Rodrigo Moya <rodrigo@ximian.com> - - * pcs/cal-backend-db.c (cal_backend_db_get_alarms_for_object): - implemented - -2001-02-13 JP Rosevear <jpr@ximian.com> - - * gui/calendar-commands.c (update_pixmaps): Set toolbar new command - - * gui/e-calendar-table.c: Add titles to pixbuf column for grouping - - * gui/calendar-model.c (calendar_model_class_init): override value - to string virtual method - (calendar_model_value_to_string): implement value to string for - etable (necessary for group by) - -2001-02-12 Rodrigo Moya <rodrigo@ximian.com> - - * pcs/cal-backend-file.c: - cal_backend_db_update_object(): manage both updates and additions/add notification - cal_backend_db_get_object(): don't use DB cursors - cal_backend_db_get_type_by_uid(): don't use DB cursors - cal_backend_db_remove_object(): don't use DB cursors/add notification - cal_backend_db_get_alarms_in_range(): implemented - -2001-02-12 Kjartan Maraas <kmaraas@gnome.org> - - * gui/Makefile.am: Hook up the xml-i18n-tools + .oaf.in stuff. - * gui/GNOME_Evolution_Calendar*.oaf.in: Marked strings for translation. - -2001-02-11 Rodrigo Moya <rodrigo@ximian.com> - - * pcs/cal-backend-db.c: added DB3 transactions support - * pcs/cal-backend-db.[ch]: added the new DB3-based backend. This is just - the beginning, there are some missing things still. - -2001-02-11 Gediminas Paulauskas <menesis@delfi.lt> - - Really use xml-i18n-tools. - - * conduits/calendar/e-calendar-conduit-control-applet.desktop, - conduits/todo/e-todo-conduit-control-applet.desktop: removed. - - * conduits/calendar/e-calendar-conduit-control-applet.desktop.in, - conduits/todo/e-todo-conduit-control-applet.desktop.in: added empty. - - * conduits/calendar/Makefile.am, conduits/todo/Makefile.am: - reflect above changes, merge translations. - - * gui/*.glade.h, gui/dialogs/*.glade.h: removed, xml-i18n-extract - takes care of strings itself. - - * gui/*.glade, gui/dialogs/*.glade: do not output_translatable_strings - - * gui/Makefile.am, gui/dialogs/Makefile.am: do not include removed - files in EXTRA_DIST. - -2001-02-08 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/task-editor-dialog.glade: Oops, remove old widget - -2001-02-08 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/task-editor.c (fill_widgets): fill in new - classification stuff properly - (get_widgets): load new class. widgets - (init_widgets): if the class. widgets change, mark the dialog - dirty - (dialog_to_comp_object): set the comp class. from the new widgets - - * gui/dialogs/task-editor-dialog.glade: Make more consistent, - fixing bugs 1247 and 1249 - - * gui/dialogs/task-editor.c (fill_widgets): - - * gui/event-editor-dialog.glade: Gui tidying - - * gui/event-editor.c: Remove old alarm cruft - - * cal-util/cal-component.c (cal_component_set_url): Don't try and - write an empty string as a property - - -2001-02-08 JP Rosevear <jpr@ximian.com> - - * pcs/cal-backend-file.c: Move the get_change code here - - * pcs/cal-backend.c: Remove get_changes related stuff and - implement by calling the virtual method instead - - * pcs/cal-backend.h: New virtual method. - - * pcs/cal-backend-file.c (compute_alarm_range): Use - icaldurationtype_as_int (replace _as_timet) - (add_alarm_occurrences_cb): ditto - -2001-02-08 JP Rosevear <jpr@ximian.com> - - * pcs/cal-backend-file.c (compute_alarm_range): Use - icaldurationtype_as_int (replace _as_timet) - (add_alarm_occurrences_cb): ditto - - * gui/e-week-view.c (e_week_view_on_schedule_meet): new routine to - throw up the meeting schedule dialog - (e_week_view_show_popup_menu): add schedule meeting to the - contextual menu where appropriate - -2001-02-08 JP Rosevear <jpr@ximian.com> - - * gui/event-editor.c: Remove assorted menu/bonobo stuff - - * gui/dialogs/task-editor.c: Remove assorted menu/bonobo stuff - (task_editor_construct): no longer suck out the glade contents - into a bonobo win, listen for apply and close signals - (tedit_apply_event_cb): listen for apply signal and save object - (tedit_close_event_cb): listen for close signal and prompt to save - if need be - (task_editor_focus): new function to bring the dialog to the front - - * gui/dialogs/task-editor.h: new prototype - - * gui/e-meeting-edit.c (schedule_button_clicked_cb): no need to - update widgets in the event editor since the event editor won't be - open - (e_meeting_editor_new): don't need the event editor reference any - more - - * gui/e-meeting-edit.h: Change prototype - - * gui/e-day-view.c (e_day_view_on_event_right_click): Make - schedule meeting a new contextual menu item - (e_day_view_on_schedule_meet): new routine to schedule a meeting - from the contextual menu - - * gui/e-calendar-table.c (e_calendar_table_open_task): Call - task_editor_focus - - * gui/event-editor-dialog.glade: Update to be a property box - - * gui/dialogs/task-editor-dialog.glade: Update to be a property - box - -2001-02-07 Iain Holmes <iain@ximian.com> - - * gui/calendar-summary.c (create_summary_view): Add a setter to the - property bag. - (set_property): The setter. - (generate_html_summary): Sort the UIDs accodring to time. - -2001-02-06 JP Rosevear <jpr@ximian.com> - - * gui/event-editor.c (fill_reminder_widgets): Match new - append_alarm signature - (reminder_to_comp_object): only add alarms tagged as new, no - longer delete all alarms first - (append_reminder): the row data is now of type ReminderData, - rename from append_alarm - (reminder_add_cb): math new append_alarm signature - (reminder_delete_cb): if the alarm existed before the dialog was - loaded, delete it immediately from the cal component - -2001-02-06 JP Rosevear <jpr@ximian.com> - - * gui/event-editor-dialog.glade: Gui tweaks for bugs 1248 and 1246 - - * gui/dialogs/task-editor-dialog.glade: ditto - -2001-02-07 JP Rosevear <jpr@ximian.com> - - * gui/event-editor-dialog.glade: Fix spacing - -2001-02-06 JP Rosevear <jpr@ximian.com> - - * gui/event-editor-dialog.glade: Gui tweaks for bugs 1248 and 1246 - - * gui/dialogs/task-editor-dialog.glade: ditto - -2001-02-06 JP Rosevear <jpr@ximian.com> - - * gui/e-week-view.c (e_week_view_show_popup_menu): Make the menus more - consistent - - * gui/e-day-view.c (e_day_view_on_event_right_click): ditto - - * gui/e-calendar-table.c: ditto - -2001-02-06 JP Rosevear <jpr@ximian.com> - - * cal-util/cal-component.c (cal_component_set_categories): If the - categories string is empty, remove the property - (get_period_list): Fixes from clahey to handle the new rdate - format in libical - (set_period_list): ditto - -2001-02-05 JP Rosevear <jpr@ximian.com> - - * cal-util/cal-component.c (cal_component_alarm_set_trigger): Set - the time and duration values in the trigger to null by default - (cal_component_free_alarm_uids): properly free the list of alarm - uids - -2001-02-05 JP Rosevear <jpr@ximian.com> - - * gui/event-editor.c (get_widgets): get the new reminder widgets - (sync_entries): different callback data - (summary_changed_cb): take different data and handle various cases - (init_widgets): connect signals for the new widgets - (get_alarm_duration_string): give a text string of the alarm - duration - (get_alarm_string): give a string representing the alarm - (fill_widgets): make sure we don't loop infinitely and remove old - alarm cruft - (reminder_to_comp_object): dump alarm info in the gui into the cal - component - (append_alarm): add alarm to the clist - (reminder_add_cb): create new alarm - (reminder_delete_cb): remove the alarm from the list - - * gui/event-editor-dialog.glade: Update gui - - * gui/e-calendar-table.c: include gnome.h for all the menu stuff - - * gui/calendar-summary.c: for internationalization - - * gui/tasks-control.c: include gnome.h - - * gui/e-tasks.c: ditto - - * gui/e-itip-control.c: ditto - - * cal-util/cal-recur.c (cal_recur_set_rule_end_date): Update for - libical changes - -2001-02-05 Christopher James Lahey <clahey@helixcode.com> - - * gui/calendar-model.c: Fixed up these #includes. - -2001-02-03 Federico Mena Quintero <federico@ximian.com> - - * gui/dialogs/save-comp.c (save_component_dialog): - gnome_dialog_grab_focus() on the Yes button. Fixes bug #1242. - -2001-01-30 Kjartan Maraas <kmaraas@gnome.org> - - * gui/e-calendar-table.c: Mark a string for translation. - * gui/e-itip-control.c: Mark a bunch of strings for translation. - -2001-01-30 Ettore Perazzoli <ettore@ximian.com> - - * gui/print.c: #include <sys/time.h>. - -2001-01-29 Federico Mena Quintero <federico@ximian.com> - - * gui/calendar-config.c: <gnome.h> trimming to reduce compilation - time. - * gui/calendar-summary.c: Likewise. - * gui/e-calendar-table.c: Likewise. - * gui/e-day-view-time-item.c: Likewise. - * gui/e-day-view.c: Likewise. - * gui/e-itip-control.c: Likewise. - * gui/e-meeting-edit.c: Likewise. - * gui/e-meeting-edit.h: Likewise. - * gui/e-tasks.c: Likewise. - * gui/e-week-view.c: Likewise. - * gui/event-editor.c: Likewise. - * gui/gnome-cal.c: Likewise. - * gui/goto.c: Likewise. - * gui/itip-utils.h: Likewise. - * gui/main.c: Likewise. - * gui/popup-menu.c: Likewise. - * gui/print.c: Likewise. - * gui/tasks-control-factory.c: Likewise. - * gui/tasks-control.c: Likewise. - * gui/tasks-migrate.c: Likewise. - -2001-01-25 Federico Mena Quintero <federico@ximian.com> - - * cal-util/timeutil.c: <gnome.h> trimming to reduce compilation time. - * gui/dialogs/task-editor.c: Ditto. - * gui/dialogs/cal-prefs-dialog.c: Ditto. - * gui/dialogs/save-comp.c: Ditto. - * gui/dialogs/delete-comp.c: Ditto. - * gui/calendar-commands.c: Ditto. - * gui/calendar-model.c: Ditto. - -2001-01-26 Ettore Perazzoli <ettore@ximian.com> - - * gui/e-itip-control.c (itip_control_destroy_cb): Don't attempt to - call `icalcomponent_remove_component()' on a NULL component or a - NULL subcomponent. - -2001-01-25 Damon Chaplin <damon@ximian.com> - - * gui/tag-calendar.c: don't tag the calendar if no dates are shown. - (e_calendar_item_get_date_range() now returns FALSE in this case.) - -2001-01-23 Damon Chaplin <damon@helixcode.com> - - * gui/calendar-model.c (ensure_task_complete): make sure the status - is set to "Completed". Fixes bug #1253. - - * gui/e-tasks.c (e_tasks_open): load the ETable state after opening - the tasks folder, since it relies on the folder uri, which isn't set - now until you open the folder. - - * gui/calendar-model.c (obj_updated_cb): add the categories from the - updated object to our tree, and emit the "categories-changed" signal - if they have changed. Fixes bug #1255. - - * gui/e-tasks.c: removed debug messages. - -2001-01-23 JP Rosevear <jpr@ximian.com> - - * libical import cleanup - -2001-01-23 JP Rosevear <jpr@ximian.com> - - * conduits/todo/todo-conduit.c (local_record_from_comp): properly ref - the cal component when we use it, prevents double free - - * conduits/calendar/calendar-conduit.c (local_record_from_comp): ditto - -2001-01-22 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/Makefile.am: compile new stuff - - * gui/dialogs/task-editor.c (prompt_to_save_changes): use new - standard dialog - - * gui/event-editor.c (prompt_to_save_changes): ditto - - * gui/dialogs/save-comp.h: new header - - * gui/dialogs/save-comp.c (save_component_dialog): shows the save - dialog - -2001-01-22 JP Rosevear <jpr@ximian.com> - - * conduits/todo/todo-conduit.c (for_each_modified): remove duplicate - message - - * conduits/calendar/Makefile.am: Remove vfs lib dependency - - * conduits/todo/Makefile.am: ditto - - * conduits/calendar/calendar-conduit.c: Remove alarm foo for now - (for_each_modified): remove duplicate message - -2001-01-21 JP Rosevear <jpr@ximian.com> - - * conduits/calendar/calendar-conduit.c (delete_record): Remove - deleted records from the pilot map so we don't have dupes in the future - - * conduits/todo/todo-conduit.c (delete_record): ditto - -2001-01-21 Federico Mena Quintero <federico@ximian.com> - - * gui/dialogs/task-editor.c (file_delete_cb): Fix bug #1250; now - we present a confirmation dialog before deleting the component. - -2001-01-20 Federico Mena Quintero <federico@ximian.com> - - * gui/event-editor-dialog.glade: Fix bug #1243. Turn on the Y - expand/fill options for the date widgets in the General page. - This makes them be vertically aligned with the "All day event" - toggle so that they will get the focus in the proper order; the - toggle would get the focus before them because it was a pixel or - two above them. - -2001-01-19 Federico Mena Quintero <federico@ximian.com> - - * gui/weekday-picker.c (weekday_picker_init): Unset the - GTK_CAN_FOCUS flag on the weekday picker. This will do until it - supports being used with the keyboard. - -2001-01-19 JP Rosevear <jpr@ximian.com> - - * cal-util/cal-component.c (cal_component_alarm_new): create a new - cal component alarm - (cal_component_add_alarm): add alarm to the cal component - (cal_component_remove_alarm): remove alarm from the cal component - (remove_alarm): remove alarm from hash - - * cal-util/cal-component.h: new protos - - * conduits/calendar/calendar-conduit.c (comp_from_remote_record): - add alarm information, still needs to be hacked to replace an already - existing alarm. questions abound about the heuristic for doing this. - -2001-01-17 JP Rosevear <jpr@ximian.com> - - * gui/event-editor.c (dialog_to_comp_object): Properly set categories - to NULL if there are none - -2001-01-18 Federico Mena Quintero <federico@ximian.com> - - * gui/tasks-migrate.[ch]: New files with a simple sequence to - migrate the task components from the old calendar folder into the - new tasks folder. - - * gui/component-factory.c (owner_set_cb): Call tasks_migrate() - once evolution_dir is set. It sucks to have to do this here. - - * cal-client/cal-client.c (cal_client_get_uids): In the inline - docs, indicate how to free the return value. - (cal_opened_cb): Ahem, moved assertion to the right place. Also, - ref() and unref() around our own signal emission because we are - not inside a signal handler, rather a simple callback from the - listener object; we want to have a chance to clean up even if the - client is unrefed during the emission. - - * gui/Makefile.am (evolution_calendar_SOURCES): Added - tasks-migrate.[ch] to the list of sources. - -2001-01-17 Federico Mena Quintero <federico@ximian.com> - - * gui/event-editor.c (init_widgets): Use - e_calendar_item_set_max_days_sel() instead of setting GTK+ object - arguments. - - * gui/e-day-view.c (e_day_view_set_cal_client): Oops, we had a - reversed test for the client being loaded. - - * gui/tag-calendar.c (tag_calendar_by_client): Fixed similarly - reversed test. - -2001-01-17 Damon Chaplin <damon@helixcode.com> - - * gui/e-week-view*.c - * gui/e-day-view*.c: don't use the theme colors at all within - the graphical parts of the widgets, since they may clash with - our colors. May make them configurable in future so people can tweak - them to go with their theme. At least the calendars are usable in any - theme now, even though the colors may not go well with the theme. - Also set the font of all the EText items in style_set. - - * gui/e-week-view-event-item.c (e_week_view_event_item_draw): don't - draw the icons if we are editing the event. - - * gui/e-day-view.c: - * gui/e-week-view.c: reinstated the optimizations so we don't do a - complete relayout if the event's dates haven't been changed. - (Though we still do a re-layout when recurring events change, since - comparing all the RDATES/RRULES/EXDATES/EXRULES is too much hassle.) - A side-effect of this change is that the EWeekView won't crash so - often - only recurring events will be a problem. - - * cal-util/cal-component.[hc]: added function to check if the start - and end dates of a component match. Used for optimizing the updating - of the EDayView & EWeekView. - -2001-01-17 JP Rosevear <jpr@ximian.com> - - * conduits/calendar/calendar-conduit.c (start_calendar_server): Check - for open error and handled - - * conduits/todo/todo-conduit.c (start_calendar_server): ditto - -2001-01-17 JP Rosevear <jpr@ximian.com> - - * conduits/calendar/calendar-conduit.c (start_calendar_server): Check - for open error and handled - - * pcs/cal-backend.c (cal_backend_compute_changes): Fix transposition - of sync db location - -2001-01-17 Federico Mena Quintero <federico@ximian.com> - - * */*: Ximianified email addresses and copyrights. - - * idl/evolution-calendar.idl (CalFactory::open): Renamed from - ::load(), and added an only_if_exists argument. - (CalFactory::create): Removed method. - (Listener::OpenStatus): Removed the IN_USE error and replaced it - with a NOT_FOUND one; renamed the enum from LoadStatus. - (Listener::notifyCalOpened): Renamed from notifyCalLoaded(). - - * pcs/cal-backend.h (CalBackend): Removed the uri field. - (CalBackendOpenStatus): Renamed from CalBackendLoadStatus and - added a NOT_FOUND value. - (CalBackendClass::open): Put in a slot for the open method. - - * pcs/cal-backend.c (cal_backend_create): Removed function. - - * pcs/cal-backend-file.c (cal_backend_file_open): Return the - appropriate value when only_if_exists is TRUE. - (create_cal): We are Ximian now, so set the PRODID property to - the appropriate foo. - - * pcs/cal-factory.c (CalFactory_open): implemented, replacing - CalFactory_load() and CalFactory_create(). - (CalFactory_open): Moved the queue_load_create_job() stuff to - here, since we now only need to contemplate the open case instead - of load/create ones. - (open_backend): Do everything here; replaces load_backend() and - create_backend(). - - * cal-client/cal-listener.h (CalListenerClass::cal_opened): - Renamed from cal_loaded. - (CalListenerClass): Replaced the silly signals, which are - gratuitous abstraction, by a set of function pointers in the - instance structure. - - * cal-client/cal-listener.c (cal_listener_get_calendar): Removed - unused function. - (cal_listener_construct): Added the listener notification functions. - (cal_listener_new): Ditto. - (Listener_notifyCalOpened): Renamed to our new naming convention - for servant implementations. - (Listener_notifyObjUpdated): Ditto. - (Listener_notifyObjRemoved): Ditto. - - * cal-client/cal-client.h (CalClientOpenStatus): Renamed from - CalClientLoadStatus. - (CalClientClass::cal_opened): Renamed from ::cal_loaded(). - (CalClientLoadState): New enum; basically make LoadState public so - that users of this code do not have to maintain their own states. - - * cal-client/cal-client.c (cal_client_create_calendar): Removed - function. - (cal_client_open_calendar): Moved the functionality over from - load_or_create(); now we do everything here. - (*): Use the CalClientLoadState enum values instead of the old - LoadState values. - (cal_client_get_load_state): Renamed from cal_client_is_loaded(), - and return the appropriate value. - (CalClientPrivate): Added an uri field. - (cal_client_init): Initialize priv->uri. - (cal_client_destroy): Free the priv->uri. - (cal_opened_cb): Maintain the priv->uri. - (cal_client_open_calendar): Fill in the priv->uri. - (cal_client_get_uri): New function. - - * gui/calendar-model.c (calendar_model_set_new_comp_vtype): New - function to configure the type of calendar components to create - when doing click-to-add. This makes the model usable for - something other than task lists. - (calendar_model_get_new_comp_vtype): New function. - - * gui/e-calendar-table.c (e_calendar_table_get_model): New function. - (e_calendar_table_destroy): Unref the subset_model. - - * gui/gnome-cal.h (GnomeCalendarOpenMode): Removed enum. - - * gui/gnome-cal.c (LoadState): Removed enum; we now use the - CalClientLoadState from the client objects. - (GnomeCalendarPrivate): Removed the loading_uri and - task_pad_loading_uri fields as well as the load_state and - task_pad_load_state fields, as we can now query them directly from - the CalClient. - (open_error): Renamed from load_error(). - (create_error): Removed function. - (gnome_calendar_open): Do not take in the mode parameter. - (cal_opened_cb): Get rid of our beautifully-crafted state machine - and replace it with simple code; all the loading smarts are in the - Wombat now. - (setup_widgets): Set the new component vtype of the table model to - CAL_COMPONENT_TODO. - - * gui/Makefile.am (evolution_calendar_SOURCES): Removed - gnome-month-item.[ch] from the list of sources. - - * gui/calendar-summary.c (CalSummary): Removed unused cal_loaded - field. - (create_summary_view): Do not check if the file exists; this is - the job of the Wombat. - (generate_html_summary): Fixed prototype. - (alarm_fn): Fixed prototype. - (property_dialog): Fixed prototype. Wonder if/how this ever - worked. - (create_summary_view): Cast the component and view as - appropriate. Removed unused html variable. - - [Iain dude, are you compiling with -Wall?] - - * gui/e-itip-control.c (cal_opened_cb): Sigh, this function - signature was *very* wrong. It was using CalClientGetStatus - instead of CalClientOpenStatus. - - * gui/e-tasks.h (ETasksOpenMode): Removed enum. - - * gui/e-tasks.c (setup_widgets): Set the new component vtype of - the table model to CAL_COMPONENT_TODO. - (LoadState): Removed the state machine foo. - (e_tasks_open): Removed the mode parameter. - (initial_load): Removed function. - (create_error): Removed function. - (ETasksPrivate): Removed folder_uri field. - (cal_opened_cb): Remove the state machine. - - * gui/component-factory.c: #include "tasks-control.h" - - * conduits/calendar/calendar-conduit.h (ECalConduitContext): - Removed calendar_load_tried field. - - * conduits/calendar/calendar-conduit.c (start_calendar_server_cb): - Sigh, fixed function prototype. - - * conduits/todo/todo-conduit.h (EToDoConduitContext): Removed - calendar_load_tried field. - - * conduits/todo/todo-conduit.c (start_calendar_server_cb): Fixed - function prototype. - -2001-01-16 JP Rosevear <jpr@ximian.com> - - * conduits/todo/todo-conduit.c (print_local): fix debug output - (print_remote): ditto - -2001-01-15 JP Rosevear <jpr@ximian.com> - - * pcs/cal-backend.c (cal_backend_compute_changes): accomadate tasks - in their new dir - - * conduits/todo/todo-conduit.c (start_calendar_server): ditto - -2001-01-15 JP Rosevear <jpr@ximian.com> - - * conduits/todo/todo-conduit.c (print_local): prevent segfaults and - buffer overflows. - (print_remote): ditto - - * conduits/calendar/calendar-conduit.c: as above - -2001-01-14 Damon Chaplin <damon@helixcode.com> - - * gui/e-calendar-table.c (E_CALENDAR_TABLE_SPEC): changed the expansion - values so that small text fields are 1.0, all the date fields and the - URL field are 2.0, and the Summary is 3.0. Hopefully the user will - resize the fields as desired, but at least this is a better start. - -2001-01-14 JP Rosevear <jpr@ximian.com> - - * conduits/calendar/Makefile.am: pass -module and -avoid-version to - conduit linker - - * conduits/todo/Makefile.am: ditto - -2001-01-14 Damon Chaplin <damon@helixcode.com> - - * gui/dialogs/task-editor.[hc]: moved #include - <cal-client/cal-client.h> to the .h file. - - * gui/e-tasks.c: load & save the Tasks folders' ETable layout. - Added an option menu to filter tasks by category. - - * gui/gnome-cal.c: use the "Tasks" folder for the TaskPad. - (We may make the actual tasks folder shown a per-calendar option.) - - * gui/tasks-control.c (tasks_control_new_task_cmd): added support for - the New Task icon on the toolbar. - - * gui/e-calendar-table.[hc]: we now use an ETableSubsetVariable model - to filter the tasks by a category. And tidied up a little. - - * gui/calendar-model.[hc]: added way to get all the categories used by - the tasks, so we can show an option menu of them. Also a signal which - is emitted when they are changed. - Also allows a default category to be set, which is used to initialize - the 'click-to-add' row. - Also made sure the initialize_value()/get_value() functions don't - return NULL since that can cause a SEGV. - - * gui/e-week-view.c: - * gui/e-day-view.c: set the "fill_color_rgba" arg of the EText items - to black since it doesn't seem to set up a default color properly. - Hopefully this fixes the bug on Solaris where the items appear with - strange colors. - - * gui/widget-util.c (date_edit_new): use the calendar_config function - to set most of the options. It wasn't setting the 12/24 hour option - before. - - * gui/dialogs/task-editor-dialog.glade: added "Undefined" priority. - -2001-01-12 Ettore Perazzoli <ettore@helixcode.com> - - * gui/component-factory.c (factory_fn): Pass NULL as the - @copy_folder_fn arg to `evolution_shell_component_new()'. - -2001-01-12 Miguel de Icaza <miguel@ximian.com> - - * gui/e-calendar-table.c: Add translation strings. - -2001-01-08 Iain Holmes <iain@helixcode.com> - - * gui/calendar-summary.c (create_summary_view): Add a PropertyControl - interface to set whether or not to show tasks and appointments. Add - a PersistStream to remember this. - -2001-01-09 Dave Camp <dave@helixcode.com> - - * gui/Makefile.am: Replaced e-meet-dialog.glade.h with - e-meeting-dialog.glade in glade_messages. - - * gui/e-meeting-dialog.glade: Enabled the translatable string option. - - * gui/e-itip-control.glade: Likewise. - -2001-01-09 Federico Mena Quintero <federico@helixcode.com> - - * idl/evolution-calendar.idl (AlarmNotify): New interface for the - alarm notification system. - - * gui/alarm-notify: New directory for the alarm notification - daemon and its auxiliary stuff. - - * gui/alarm-notify/alarm.[ch]: Moved over from gui/alarm.[ch]. - - * gui/alarm-notify/alarm-queue.[ch]: Moved over from - gui/alarm-notify.[ch]. Renamed functions from alarm_notify_*() to - alarm_queue_*(). - - * gui/alarm-notify/alarm-notify.[ch]: Implementation of the - GNOME::Evolution::Calendar::AlarmNotify interface. - - * gui/Makefile.am (evolution_calendar_LDADD): Removed the - LINK_FLAGS variable and reordered the libraries to remove some - duplicated ones. - (SUBDIRS): Added the alarm-notify directory. - -2001-01-08 Iain Holmes <iain@helixcode.com> - - * gui/calendar-summary.c (generate_html_summary): Get the tasks - correctly. - (generate_html_summary): Mark the tasks as completed if so. - -2001-01-08 Damon Chaplin <damon@helixcode.com> - - * gui/Makefile.am: added new source files for the Tasks folders. - - * gui/e-tasks.[hc]: new widget to encapsulate the Tasks view. - - * gui/tasks-control.[hc]: new files to implement the Tasks control. - - * gui/tasks-control-factory.[hc]: new files to implement the factory - for the Tasks controls. (I think the way I've split the code up is a - lot cleaner than the GnomeCal implementation - the factory file just - contains the factory functions and the control file contains all the - control functions. Maybe we should make GnomeCal like this.) - - * gui/main.c: initialize the Tasks control factory. - - * gui/component-factory.c: added support for the Tasks control. - Also added a "create_folder" function so we can now create new Tasks - and Calendar folders within Evolution. - I'm not a Bonobo expert so someone might want to check these over. - - * gui/calendar-config.[hc]: added convenience functions to configure - the common settings of ECalendar and EDateEdit widgets. - - * gui/dialogs/task-editor.c (task_editor_create_date_edit): - * gui/gnome-cal.c (gnome_calendar_update_config_settings): - * gui/event-editor.c: used function to configure the ECalendars - and EDateEdits. - - * gui/e-day-view-top-item.c (e_day_view_top_item_draw_long_event): - fixed minor bug in format strings. - -2001-01-06 Iain Holmes <iain@helixcode.com> - - * gui/calendar-summary.c (generate_html_summary): Neaten the HTML, - and fix the time printing stuff. Add stuff the get Tasks. - (alarm_fn): Set up an alarm for midnight everynight and regenerate - the HTML for the new day. - -2001-01-05 JP Rosevear <jpr@helixcode.com> - - * gui/event-editor.c (get_widgets): get categories button - (init_widgets): listen for button click - (fill_widgets): fill in the categories area - (dialog_to_comp_object): set the cal component categories - (categories_clicked): throw up the categories dialog and update - when ok is clicked - - * gui/event-editor-dialog.glade: Add categories and contacts buttons - and fields - - * gui/dialogs/task-editor-dialog.glade: Rename button - -2001-01-05 JP Rosevear <jpr@helixcode.com> - - * gui/dialogs/task-editor.c (get_widgets): get categories button - (init_widgets): listen for button click - (fill_widgets): fill in the categories area - (dialog_to_comp_object): set the cal component categories - (categories_clicked): throw up the categories dialog and update - when ok is clicked - - * gui/dialogs/task-editor-dialog.glade: Tweak to name the categories - button and make it active - - * gui/calendar-model.c (get_categories): We can get the string list of - categories directly now - - * cal-util/cal-component.c (cal_component_get_categories): new function - to get the categories list as a string - (cal_component_set_categories): same but for setting - (free_icalcomponent): init the categories var - (scan_categories): kill - (scan_property): assign the prop to the categories var - (cal_component_get_categories_list): deal with renaming var to categories - (cal_component_set_categories_list): fix brokeness - -2001-01-03 Federico Mena Quintero <federico@helixcode.com> - - * gui/calendar-commands.c (new_calendar): Handle the case where - the calendar view cannot be created; present a warning dialog box. - (new_calendar): Do not show the widget here, since we already show - it in control-factory.c. - - * gui/control-factory.c (control_factory_new_control): Handle the - case where the calendar view cannot be created. - - * gui/component-factory.c (create_view): Ditto. - - * gui/calendar-summary.h: Added prototype for - calendar_summary_factory_init(). - -2001-01-02 Federico Mena Quintero <federico@helixcode.com> - - * gui/alarm-notify.c (add_component_alarms): If the component has - no alarms, do not try to queue them. - (remove_client_alarms): New function to remove all the queued - alarms for a calendar client. - (alarm_notify_remove_client): Remove the client's alarms. - -2001-01-02 Federico Mena Quintero <federico@helixcode.com> - - * gui/dialogs/delete-comp.c (delete_component_dialog): Do not - compose strings so that they can be localized correctly. Also, - convert from UTF8 into the font's encoding. Fixes bug #1030. - - * gui/e-calendar-table.c (delete_component): Pass the widget - argument to delete_component_dialog(). - - * gui/e-day-view.c (e_day_view_on_delete_appointment): Likewise. - - * gui/e-week-view.c (e_week_view_on_delete_appointment): Likewise. - - * gui/event-editor.c (file_delete_cb): Likewise. - - * gui/calendar-commands.c: Use BONOBO_UI_VERB() instead of - BONOBO_UI_UNSAFE_VERB(). Guess what, all of our handler - signatures were wrong. - - * gui/event-editor.c: Likewise. - - * gui/dialogs/task-editor.c: Likewise. - - * gui/goto-dialog.glade: Added some spacing between the month/year - widgets and the calendar widget. - -2001-01-01 Federico Mena Quintero <federico@helixcode.com> - - * gui/gnome-cal.c (gnome_calendar_destroy): Unconditionally remove - the client from the alarm notification system. - Removed all the obsolete alarm code. - - * gui/event-editor.c: Removed some crufty externs left over from - Gnomecal. - - * gui/calendar-commands.c: #include "goto.h" - Removed crufty variables left over from Gnomecal. - (new_calendar): Do not take a full_name parameter. - (init_username): Removed function. - (init_calendar): Wheeeeeeee! Removed crufty function. - (quit_cmd): Removed function. - - * gui/print.c (WEEK_STARTS_ON_MONDAY): Made it unconditionally - FALSE because we do not use the configuration setting anyways. - Sigh, all the printing code needs to be revamped. - -2000-12-26 Iain Holmes <iain@helixcode.com> - - * gui/calendar-summary.c (create_summary_view): Create a shared - BonoboEventSource object. - -2000-12-25 Miguel de Icaza <miguel@helixcode.com> - - * gui/e-day-view.c (e_day_view_init): Set draw background to FALSE. - (e_day_view_reshape_long_event): ditto. - (e_day_view_reshape_day_event): ditto. - -2000-12-22 JP Rosevear <jpr@helixcode.com> - - * gui/dialogs/delete-comp.c (delete_component_dialog): Clean up - translatable strings for translators, fixes bug 993 - -2000-12-22 JP Rosevear <jpr@helixcode.com> - - * gui/goto.c (create_ecal): Make sure the current month is shown - when the dialog pops up. - - * gui/goto-dialog.glade: Remove flicker - -2000-12-22 JP Rosevear <jpr@helixcode.com> - - * pcs/cal-backend-file.c (cal_backend_file_get_alarms_for_object): - account for the case where there are no alarms, fixes crash - -2000-12-22 JP Rosevear <jpr@helixcode.com> - - * gui/goto.c (ecal_date_range_changed): New function to keep the - ecal marked properly - (create_ecal): move more creation code here, update marks - (goto_dialog_init_widgets): listen for date_range_changed signal - in the ecal - - * gui/calendar-commands.c (init_calendar): Remove ancient gnomecal - cruft - - * gui/mark.[hc], gui/prop.c: Remove ancient gnomecal code that is - no longer needed, last bit of bug 904 - -2000-12-22 JP Rosevear <jpr@helixcode.com> - - * gui/goto-dialog.glade.h: translations - - * gui/goto-dialog.glade: new glade file for goto dialog - - * gui/gnome-cal.c (setup_widgets): Set date navigator attributes - - * gui/calendar-commands.h: remove prototype - - * gui/goto.h: Add prototype - - * gui/Makefile.am: Add glade file stuff - - * gui/gnome-cal.c (setup_widgets): Use accessors to configure the - calendar item properly - -2000-12-21 Federico Mena Quintero <federico@helixcode.com> - - Alarm trigger queueing for the GUI part. - - * gui/alarm-notify.[ch]: New files with the high-level alarm - notification system; mostly moved over from gnome-cal.c. The - low-level timer stuff is still in alarm.[ch]. - - * gui/alarm-notify.c (alarm_notify_init): New function to - initialize the alarm notification system. - (alarm_notify_done): New function to shut down the alarm - notification system. - (alarm_notify_add_client): New function to start monitoring a - calendar client for alarm notification. - (alarm_notify_remove_client): New function to stop monitoring a - client. - - * gui/alarm.h (AlarmDestroyNotify): Also pass in the alarm ID so - the callback may know which ID is being destroyed. - - * gui/alarm.c (clear_itimer): New function. - (pop_alarm): Use clear_itimer(). - (alarm_done): New function to shut down the timer system. - (alarm_add): Add some preconditions. Do not call the destroy - notification function if we could not create the alarm. - (alarm_ready): Pass the alarm ID to the destroy notify function. - (alarm_remove): Likewise. Also, add some preconditions. - - * gui/gnome-cal.c: Removed the alarm notification functions from - here since they are now in alarm-notify.c. - (gnome_calendar_construct): Register the client with - alarm_notify_add_client(). - (gnome_calendar_destroy): Use alarm_notify_remove_client() to - unregister the client. - (obj_updated_cb): Do not do any alarm-related stuff. - (obj_removed_cb): Likewise. - - * gui/main.c (main): Shut down the alarm timer system. - (main): Initialize and shut down the alarm notification system. - - * gui/Makefile.am (evolution_calendar_SOURCES): Added - alarm-notify.[ch] to the list of sources. - - * gui/calendar-model.c (calendar_model_set_cal_client): Only - connect to the "cal_loaded" signal if the client is not already - loaded. - - * gui/e-day-view.c (e_day_view_set_cal_client): Likewise. - - * gui/e-week-view.c (e_week_view_set_cal_client): Likewise. - - * gui/e-itip-control.c (update_calendar): Connect to "cal_loaded" - before issuing the load request. - -2000-12-21 Iain Holmes <iain@helixcode.com> - - * gui/calendar-summary.c: Updated for new executive summary. - - * gui/component-factory.c: Reenabled the summary. - - * gui/GNOME_Evolution_Calendar.oafinfo: Added the summary. - -2000-12-20 JP Rosevear <jpr@helixcode.com> - - * conduits/todo/todo-conduit.h: Fix erroneous documentation - - * conduits/todo/todo-conduit.c (comp_from_remote_record): if - !is_empty_time rather than is_empty_time - (e_todo_context_new): Return a pointer rather than fill in - a parameter - (e_todo_context_foreach_change): Free just the key - (e_todo_context_destroy): Plug this enormous leakage. I had assumed - i had done this earlier, which isn't too bright when anything beyond - 2 minutes ago is fuzzy. - (comp_from_remote_record): Kill warnings - (post_sync): Destroy the map later - (conduit_get_gpilot_conduit): Fix e_todo_context_new params - - * conduits/calendar/calendar-conduit.[hc]: Similar to above - -2000-12-19 JP Rosevear <jpr@helixcode.com> - - * conduits/calendar/calendar-conduit.c: Remove pointless comment - - * conduits/todo/todo-conduit.c (is_empty_time): add utility function - (comp_from_remote_record): use it - -2000-12-19 JP Rosevear <jpr@helixcode.com> - - * conduits/calendar/calendar-conduit.c (local_record_from_comp): - Convert cal component strings to pilot character set - (comp_from_remote_record): vice versa - - * conduits/todo/todo-conduit.c: Same as above - -2000-12-19 Federico Mena Quintero <federico@helixcode.com> - - * pcs/cal-backend-file.c (compute_alarm_range): Fix confusion in - the way the range is expanded. - - * cal-util/cal-component.c (cal_component_alarms_free): Doh, - alarms->alarms is a list, not a generic pointer. Free it properly. - (cal_component_free_pilot_id): Removed unused function. - (cal_component_free_pilot_status): Likewise. - - * gui/main.c (init_bonobo): Use VERSION instead of a hardcoded - string. Pass argc by value, not by reference. Test the return - value of gnome_init_with_popt_table(). - - * cal-client/cal-client.c (cal_client_free_alarms): Oops, missed - implementing this function. - - * cal-util/timeutil.c (print_time_t): Better printing format. - (isodiff_to_secs): Removed unused function. - (isodiff_from_secs): Removed unused function. - (time_day_end): Removed crufty part. - (time_day_begin): Removed crufty part. - (time_day_hour): Removed unused function. - (format_simple_hour): Removed unused function. - (get_time_t_hour): Removed unused function. - (time_from_start_duration): Removed unused function. - - * cal-util/timeutil.h (parse_date): Removed unimplemented, unused - function prototype. - -2000-12-19 Christopher James Lahey <clahey@helixcode.com> - - * gui/gnome-cal.c: Removed prototype for setup_alarm to fix a - warning. - -2000-12-18 Federico Mena Quintero <federico@helixcode.com> - - Alarm instance generation support for the Wombat. - - * idl/evolution-calendar.idl (Cal::CalAlarmInstance): Changed to - have an alarm UID, the trigger time, and the actual occurrence - time. - (Cal::CalComponentAlarms): New structure to hold a pair of a - component and its alarms that trigger in a particular range of - time. - (Cal::getAlarmsInRange): Changed to return a CalComponentAlarmsSeq. - - * cal-util/cal-component.h (CalAlarmInstance): New C-side - structure to match the one on the IDL. - (CalComponentAlarms): Ditto. - (CalAlarmAction): Renamed from CalComponentAlarmAction. - (CalAlarmTriggerType): Renamed from CalComponentAlarmTriggerType. - Encoded the START and END parameters for the RELATED parameter in - this enum, too. Added a NONE value for invalid or missing trigger - specifications. - (CalComponentAlarmTriggerRelated): Removed. - (CalAlarmTrigger): Renamed from CalComponentAlarmTrigger. Renamed - the duration/time fields to rel_duration/abs_time, respectively. - - * cal-util/cal-component.c (cal_component_alarm_get_trigger): - Changed to use the new trigger structure. - (cal_component_alarm_set_trigger): Likewise. - (cal_component_alarm_free_trigger): Removed function. - (cal_component_has_alarms): Count the elements in the - alarm_uid_hash instead of trying to fetch the first alarm subcomponent. - (cal_component_alarms_free): New function to free a - CalComponentAlarms structure. - (CalComponentAlarmPrivate): Added an uid property pointer. - (scan_alarm_property): Scan for the our extension UID property. - (cal_component_alarm_get_uid): New function. - - * pcs/cal-backend.h (CalBackendClass): Changed the signatures of - the ::get_alarms_in_range() and ::get_alarms_for_object() methods. - - * pcs/cal-backend.c (cal_backend_get_alarms_in_range): Changed - signature; use the new method. - (cal_backend_get_alarms_for_object): Likewise. - - * pcs/cal-backend-file.c (compute_alarm_range): New spiffy - function to compute a range of time for alarm occurrences. - (add_alarm_occurrences_cb): New function to add alarms for a - particular occurrence of the component. - (generate_absolute_triggers): New function to add the absolute - alarm triggers. - (generate_alarms_for_comp): New function to generate all the alarm - instances for a component. - (cal_backend_file_get_alarms_in_range): Implemented. - - * pcs/cal.c (Cal_get_alarms_in_range): Use the new CalBackend API. - (Cal_get_alarms_for_object): Likewise. - (build_alarm_instance_seq): Removed old function. - - * cal-util/cal-util.c (cal_alarm_instance_list_free): Removed - function. - - * cal-client/cal-client.c (build_component_alarms_list): New - function to demarshal the component alarms sequence. - (build_alarm_instance_list): New function to demarshal the alarm - instances sequence. - (cal_client_get_alarms_in_range): Updated for the new API. - (cal_client_get_alarms_for_object): Updated for the new API. - - * gui/gnome-cal.c: Temporary #ifdef-ing out of alarm-related stuff - to make it build. - -2000-12-15 Federico Mena Quintero <federico@helixcode.com> - - * cal-util/timeutil.[ch] (time_from_isodate): Removed unused - function, a relic from Gnomecal. - -2000-12-15 Dan Winship <danw@helixcode.com> - - * cal-util/timeutil.c (time_from_isodate): Fix the sign in the - HAVE_TM_GMTOFF case - -2000-12-15 Federico Mena Quintero <federico@helixcode.com> - - * gui/Makefile.am (evolution_calendar_SOURCES): Removed getdate.y. - We no longer use it; it is a relic from Gnomecal. - - * gui/getdate.y: Removed file. - -2000-12-14 Federico Mena Quintero <federico@helixcode.com> - - Fixes bug #955. - - * gui/weekday-picker.c (WeekdayPickerPrivate): Added a field for - the week_start_day, to be used in the same way as - calendar-config.h defines it. Removed the week_starts_on_monday - flag. - (day_event_cb): Use the week_start_day. - (colorize_items): Likewise. - (configure_items): Likewise. - (weekday_picker_set_week_start_day): New function. - (weekday_picker_get_week_start_day): New function. - (weekday_picker_set_week_starts_on_monday): Removed function. - (weekday_picker_get_week_starts_on_monday): Removed function. - - * gui/widget-util.[ch]: New files with utilities for creating or - configuring widgets. - - * gui/widget-util.c (date_edit_new): New function to create an - EDateEdit configured with the calendar's preferences; moved over - from event-editor.c. - - * gui/event-editor.c (make_recur_weekly_special): Use - weekday_picker_set_week_start_day() and the corresponding function - from calendar-config.h. - (init_widgets): Likewise. - (make_date_edit_with_time): Removed function. - (make_recur_ending_until_special): Use date_edit_new(). - (make_date_edit): Likewise. - - * gui/dialogs/task-editor.c (task_editor_create_date_edit): Likewise. - - * gui/event-editor-dialog.glade: Removed references to - make_date_edit_with_time(); replace them with make_date_edit(). - - * gui/Makefile.am (evolution_calendar_SOURCES): Added - widget-util.[ch] to the list of sources. - -2000-12-14 Federico Mena Quintero <federico@helixcode.com> - - * gui/e-calendar-table.c (E_CALENDAR_TABLE_SPEC): Reset the widths - of the columns with pixbufs to the actual pixbufs' sizes; now - ETable properly computes its column widths so we do not need to - add extra padding here. - -2000-12-14 Dan Winship <danw@helixcode.com> - - * gui/calendar-model.c (_XOPEN_SOURCE): #define this to 500, not - nothing. Also, move this bit after the other #includes to - prevent potential messiness. - -2000-12-13 Federico Mena Quintero <federico@helixcode.com> - - * cal-util/cal-component.c (ensure_mandatory_properties): Even - though icaltime_from_timet() now properly ignores the is_utc - argument since time_t values *are* in UTC by definition, we were - passing FALSE for that argument's value in a bunch of places. So - although it is ignored, changed them to TRUE for consistency. - Hopefully newer versions of libical will remove that argument - entirely since it does not make sense to speak of non-absolute - time_t values. - - * cal-util/cal-recur.c (cal_recur_set_rule_end_date): Likewise. - - * conduits/calendar/calendar-conduit.c (comp_from_remote_record): Likewise. - - * conduits/todo/todo-conduit.c (comp_from_remote_record): Likewise. - - * gui/dialogs/task-editor.c (dialog_to_comp_object): Likewise. - - * gui/e-day-view.c (e_day_view_on_new_appointment): Likewise. - (e_day_view_on_delete_occurrence): Likewise. - (e_day_view_on_unrecur_appointment): Likewise. - (e_day_view_on_unrecur_appointment): Likewise. - (e_day_view_finish_long_event_resize): Likewise. - (e_day_view_finish_resize): Likewise. - (e_day_view_key_press): Likewise. - (e_day_view_on_top_canvas_drag_data_received): Likewise. - (e_day_view_on_main_canvas_drag_data_received): Likewise. - - * gui/e-week-view.c (e_week_view_key_press): Likewise. - (e_week_view_on_new_appointment): Likewise. - (e_week_view_on_delete_occurrence): Likewise. - (e_week_view_on_unrecur_appointment): Likewise. - - * gui/event-editor.c (simple_recur_to_comp_object): Likewise. - (recur_to_comp_object): Likewise. - (dialog_to_comp_object): Likewise. - - * gui/gnome-cal.c (gnome_calendar_new_appointment): Likewise. - -2000-12-13 Christopher James Lahey <clahey@helixcode.com> - - * cal-util/cal-recur.c: #if 0ed cal_obj_date_only_compare_func. - (cal_object_get_rdate_end): Changed this function to get rid of a - possible uninitialized error on the rdate function. - - * gui/calendar-model.c: Fixed some warnings involving the #define - _XOPEN_SOURCE lines here. - - * gui/component-factory.c: #ifdef WANT_THE_EXECUTIVE_SUMMARYed out - the summary_factory object since it's unused if - WANT_THE_EXCUTIVE_SUMMARY is not defined. - - * gui/e-day-view.c: #if 0ed out e_day_view_remove_event_cb. - (obj_updated_cb): #ifndef NO_WARNINGSed out a #warning. - - * gui/e-week-view-event-item.c (e_week_view_event_item_draw): Made - it so that - - * gui/e-week-view.c (obj_updated_cb): #ifndef NO_WARNINGSed out a - #warning. - -2000-12-13 JP Rosevear <jpr@helixcode.com> - - * conduits/todo/Makefile.am: Revert federico's change for now - because of libtool limitations with ldadding shared libtool - libs - - * conduits/calendar/Makefile.am: ditto - -2000-12-12 JP Rosevear <jpr@helixcode.com> - - * gui/dialogs/task-editor.c (task_editor_set_todo_object): Use - set_title_from_comp - (save_todo_object): ditto - (set_title_from_comp): Make sure the title is encoded properly (as in - event-editor) - -2000-12-12 Federico Mena Quintero <federico@helixcode.com> - - * cal-util/cal-component.c (get_text_list): Constify for new - libical API. - (set_text_list): Likewise. - - * cal-util/cal-recur.c (cal_recur_get_rule_end_date): Likewise. - (cal_recur_set_rule_end_date): Likewise. - - * gui/e-itip-control.c (find_attendee): Likewise. - (pstream_load): Likewise. - - * gui/gnome-cal.c (released_event_object_cb): Removed unused function. - - * gui/dialogs/task-editor.c (status_string_map): Removed unused - variable. - -2000-12-11 Federico Mena Quintero <federico@helixcode.com> - - * cal-util/Makefile.am (test_recur_LDADD): Link to the libical - shared library. - - * cal-client/Makefile.am (client_test_LDADD): Likewise. - - * conduits/calendar/Makefile.am (libecalendar_conduit_la_LIBADD): - Likewise. - - * gui/Makefile.am (LINK_FLAGS): Likewise. - -2000-12-11 Federico Mena Quintero <federico@helixcode.com> - - This is to make things work with libical 0.21helix1 and later. - Warnings remain because at last libical was constified; will take - care of those tomorrow. - - * cal-util/timeutil.h: #include <ical.h> instead of <icaltypes.h> - - * gui/e-itip-control.c: Likewise. - - * gui/e-meeting-edit.c: Likewise. - - * gui/itip-utils.h: Likewise. - - * cal-util/cal-component.c (alarm_uid_from_prop): constify. - (cal_component_get_status): Updated for new libical API. - (cal_component_set_status): Likewise. - - * gui/calendar-model.c (ensure_task_complete): Removed unused - status code. - (ensure_task_not_complete): Update for new status API. - - * gui/dialogs/task-editor.c (status_string_to_value): Removed - function. - (status_value_to_string): Removed function. - (status_string_map): Removed variable. - (fill_widgets): Update for new status API. - (dialog_to_comp_object): Likewise. - -2000-12-11 Damon Chaplin <damon@helixcode.com> - - * cal-util/cal-recur.c (generate_instances_for_chunk): updated the - tests on the start & end time just before calling the callback. It - was skipping occurrences that started before the required interval's - start time, which was wrong. We want all occurrences that intersect - the interval. - (cal_obj_time_weekday): removed the CalRecurrence* argument, since it - isn't needed. - -2000-12-11 Damon Chaplin <damon@helixcode.com> - - * gui/event-editor.c: added changed flags and added calls to a new - function event_editor_set_changed() to set & reset this flag. - Added prompt_to_save_changed() which is called when the user - selects File/Close or the window's close button. - Fixed the 'All day event' toggle button. - Made the 'Alarm' page sensitive as appropriate when filling widgets. - (Though note that the alarm widgets are not being set yet.) - - * gui/dialogs/task-editor.c: added changed flag as above. - - * gui/event-editor-dialog.glade: used good names for all the - classification radio buttons so we can access them in the code. - - * gui/event-editor.c (init_widgets): use the "show week numbers" config - option in the recurrence preview calendar. - - * gui/e-day-view.c (e_day_view_update_event_label): use 9:00 instead - of 09:00 in the main view, as we do everywhere else now. It means the - times won't line up, but they are easier to read which I think is - better. - Added support for Page Up/Down, though I think it should move the - selection rather than just scroll the canvas. - - * cal-util/cal-recur.c (generate_instances_for_chunk): removed the - end parameter since we should be using the chunk end time now. - Added single_rule parameter for when we are generating the - occurrences of a single RRULE, in which case the event's start date is - not included in the occurrences output (unless it results from the - RRULE expansion). Both of these fix problems when using COUNT. - - * gui/gnome-cal.c (gnome_calendar_on_date_navigator_selection_changed): - fixed bug when checking if the new start day starts on the week start - day. If you select a complete week it should now show the Week view. - -2000-12-08 Federico Mena Quintero <federico@helixcode.com> - - * gui/event-editor.c (dialog_to_comp_object): Free the strings we - get from the editables. - - * gui/dialogs/task-editor.c (dialog_to_comp_object): Likewise. - This sucks; this code should be shared between the two dialogs. - -2000-12-08 Federico Mena Quintero <federico@helixcode.com> - - * gui/event-editor.c (fill_widgets): Free the dates we get from - the component. - -2000-12-08 JP Rosevear <jpr@helixcode.com> - - * gui/e-calendar-table.c (e_calendar_table_init): Attach signal - handlers to the e_scrolled_table's etable rather than to the - e_scrolled_table directly - (e_calendar_table_on_double_click): This signal provides more - params now - -2000-12-07 Christopher James Lahey <clahey@helixcode.com> - - * gui/e-calendar-table.c: Got rid of code referencing the - ETableScrolled proxy functions. - -2000-12-07 JP Rosevear <jpr@helixcode.com> - - * conduits/calendar/calendar-conduit.c (post_sync): Ugly hack for syncing - until pcs can be altered (longer term) - - * conduits/todo/todo-conduit.c (post_sync): ditto - -2000-12-07 Chris Toshok <toshok@helixcode.com> - - * cal-client/Makefile.am (client_test_LDADD): add - EXTRA_GNOME_LIBS. - -2000-12-07 JP Rosevear <jpr@helixcode.com> - - * pcs/cal-backend.c (cal_backend_compute_changes_foreach_key): Create - an empty cal component if the object has been deleted. - - * idl/evolution-calendar.idl: Bit shift the change type constants - properly - -2000-12-07 Federico Mena Quintero <federico@helixcode.com> - - * cal-client/cal-client.c (cal_client_generate_instances): Unref - the component from the objects list; it got referenced as many - times as appropriate for the instances list. - -2000-12-06 Federico Mena Quintero <federico@helixcode.com> - - * gui/event-editor.c (file_delete_cb): Confirm before deleting the - event. - -2000-12-06 JP Rosevear <jpr@helixcode.com> - - * gui/e-week-view.c (e_week_view_init): unref the pixbuf when - finished with it - -2000-12-06 Federico Mena Quintero <federico@helixcode.com> - - Fixes bug #920. - - * gui/e-calendar-table.c (delete_component): New function. - (e_calendar_table_on_delete_task): Use delete_component(). - (e_calendar_table_on_key_press): Likewise. Also, mark the event - as handled. - - * gui/calendar-model.c (calendar_model_get_component): Renamed - function from calendar_model_get_cal_object(). - (calendar_model_delete_task): Removed function. - - * gui/dialogs/delete-comp.[ch]: New files with the dialog for - deleting a calendar component. - - * gui/e-day-view.c (e_day_view_on_delete_appointment): Confirm - before actually deleting the appointment. - - * gui/e-week-view.c (e_week_view_on_delete_appointment): Likewise. - - * gui/dialogs/Makefile.am (libcal_dialogs_a_SOURCES): Added - delete-comp.[ch] to the list of sources. - - * cal-util/cal-component.c (cal_component_destroy): Free the alarm - UID hash. - -2000-12-06 JP Rosevear <jpr@helixcode.com> - - * pcs/cal.c (build_change_seq): kill - (Cal_get_changes): return the corba sequence directly - - * pcs/cal-backend.h: update prototype - - * pcs/cal-backend.c (cal_backend_compute_changes_foreach_key): Build - the corba struct rather than the old calobjchange thing - (cal_backend_compute_changes): ditto. build and return the actual - corba sequence rather than the list of calobjchanges - (cal_backend_get_changes): return the corba sequence - - * cal-util/cal-util.h: Remove CalObjChange cruft - - * cal-util/cal-util.c (cal_obj_change_list_free): Kill - -2000-12-06 JP Rosevear <jpr@helixcode.com> - - * cal-util/cal-util.c: - - * conduits/calendar/calendar-conduit.c (map_name): Update so as not to conflict - with calendar - (next_changed_item): update to use CalClientChange instead of CalObjChange - (compute_status): ditto - (pre_sync): ditto - (for_each_modified): since we now have the cal component we can call - local_record_from_comp directly - - * conduits/todo/todo-conduit.c: same as above - - * pcs/cal-backend.c: Remove much logging cruft - (cal_backend_compute_changes): Calculate the changes based on the - hashed database - (cal_backend_get_changes): call cal_backend_compute_changes - (cal_backend_compute_changes_foreach_key): hash callback for - calculating deletions - - * pcs/cal-backend.h: update protype, remove logging cruft from - object - - * pcs/cal.c (build_change_seq): dup the calobj rather than the uid - now - (Cal_get_changes): rename from Cal_get_changed_uids - (cal_get_epv): reflect name change in epv - - * cal-util/cal-util.c (cal_obj_change_list_free): update assertion - - * cal-util/cal-util.h: CalObjChange now returns the entire ical - component, update the change types. This should all go away shortly - - * idl/evolution-calendar.idl: getChangedUIds -> getChanges. - CalObjChange now contains the calobj rather than the uid, update - the change types - - * cal-client/cal-client.c (cal_client_get_changes): rename from - cal_client_get_changed_uids to make idl and addressbook - - * cal-client/cal-client.h: Update prototype - - * cal-client/cal-client.c (build_change_list): Build a list of - CalClientChange instead of CalObjChange - - * cal-client/cal-client-types.c (cal_client_change_list_free): Free - a glist of CalClientChanges - - * cal-client/cal-client-types.h: New file. Declarations for - CalClientChange. - - * cal-client/Makefile.am: Build new files - -2000-12-06 JP Rosevear <jpr@helixcode.com> - - * conduits/todo/Makefile.am: Fix my build stupidty READ THE MACRO - - * conduits/calendar/Makefile.am: ditto - -2000-12-04 JP Rosevear <jpr@helixcode.com> - - * gui/e-day-view-time-item.c (e_day_view_time_item_get_column_width): - Initialize max_large_digit_width to 0 to prevent crazy sizing issues. - -2000-12-04 Dan Winship <danw@helixcode.com> - - * gui/e-itip-control.c: Remove mysterious #include inserted by - mmeeks to break the build. - -2000-12-01 Federico Mena Quintero <federico@helixcode.com> - - Fixes bug #918. - - * gui/weekday-picker.c (WeekdayPickerPrivate): Added a field for a - set of blocked days. - (weekday_picker_set_blocked_days): New function to configure a set - of days that cannot be modified by the user. - (weekday_picker_get_blocked_days): Query function for the above. - (day_event_cb): Block the appropriate days from being modified. - - * gui/event-editor.c (get_start_weekday_mask): New function to - compute a day mask for the start day of a calendar component. - (set_recur_special_defaults): New function to set sane defaults - for the recurrence special widgets. - (fill_recurrence_widgets): Use set_recur_special_defaults(). - (make_recur_weekly_special): Block the appropriate days. - -2000-12-01 Federico Mena Quintero <federico@helixcode.com> - - * gui/control-factory.c (set_prop): Removed debugging message. - (control_factory_init): Ditto. - - * gui/calendar-commands.c (calendar_set_uri): Ditto. - - * gui/main.c (main): Ditto. - - * gui/event-editor.c (set_title_from_comp): New function to - generate a title and convert it from UTF8 before setting it on the - window. - (save_event_object): Uset set_title_from_comp(). - (event_editor_set_event_object): Likewise. - -2000-11-30 JP Rosevear <jpr@helixcode.com> - - * conduits/todo/todo-conduit.c: Debug message cleanups - (comp_from_remote_record): Properly set the ical description field - - * conduits/calendar/calendar-conduit.c (is_empty_time): New utility - functions that look for all 0's in a struct tm - (comp_from_remote_record): use above - (local_record_from_comp): Correctly set the repeatForever value so - that we repeat forever instead of a really long time - (comp_from_remote_record): Only set the cal component recurrence - until field when repeatForever is 0 - -2000-11-30 Jesse Pavel <jpavel@helixcode.com> - - * gui/e-itip-control.c: fixed a bug that caused the calendar to - segfault when the iTip control was destroyed. - -2000-11-30 JP Rosevear <jpr@helixcode.com> - - * conduits/calendar/calendar-conduit.c (local_record_from_comp): Empty - by_day entries are no longer indicated by ICAL_RECURRENCE_ARRAY_MAX not - SHRT_MAX. Calculate weekly and monthly by date recurrences properly - (get_pilot_day): Convert ical day to corresponding integer for pilot day - -2000-11-30 JP Rosevear <jpr@helixcode.com> - - * conduits/calendar/calendar-conduit.c: Debug message cleanups - (get_ical_day): Fix off-by-one error which affected weekly occurences. - (comp_from_remote_record): Monthly by day and by date were reversed - (nth_weekday): function taken from event-editor.c that encodes BYDAY - values - this needs to be in libical really. - (comp_from_remote_record): Don't set the description if the pilot note - is null. Rejig so that we don't have to free objects. - -2000-11-28 Federico Mena Quintero <federico@helixcode.com> - - Upgrade of the alarm framework. We now access alarms by a unique - identifier. This UID is added as an extension property to alarm - subcomponents when their parent components are scanned by - CalComponent. - - * cal-util/cal-component.c (CalComponentPrivate): Added a hash - table of alarm UIDs -> alarm properties. - (cal_component_init): Initialize priv->alarm_uid_hash. - (free_icalcomponent): Free the elements in the - priv->alarm_uid_hash. - (scan_alarm): New function to add scan an alarm subcomponent and - ensure that it has an alarm UID extension property so that we can - add it to our mapping table. - (cal_component_get_first_alarm): Removed function. - (cal_component_get_next_alarm): Removed function. - (cal_component_get_alarm_uids): New function. - (cal_component_get_alarm): New function. - -2000-11-28 JP Rosevear <jpr@helixcode.com> - - * conduits/todo/todo-conduit.c (local_record_to_pilot_record): Return - a struct rather than a pointer to a struct - (compare): local_record_to_pilot_record now returns a struct - (prepare): ditto - (free_prepare): remove as per gnome-pilot changes - (conduit_get_gpilot_conduit): don't listen for free_prepare signal - - * conduits/calendar/calendar-conduit.c: Same as above - -2000-11-28 Federico Mena Quintero <federico@helixcode.com> - - * gui/e-calendar-table.c (E_CALENDAR_TABLE_SPEC): Reformatted the - table spec to make it easier to read. - - * gui/tag-calendar.c: Oops, Damon wrote this, not me. Fixed the - Authors line. - -2000-11-28 Damon Chaplin <damon@helixcode.com> - - * gui/e-day-view*.[hc]: - * gui/e-week-view*.[hc]: finished 12-hour support and tried to tidy - up & comment the drawing code in places. Also fixed a couple of bugs I - spotted. All the options on the 'Calendar' page should now work. - -2000-11-28 Jesse Pavel <jpavel@helixcode.com> - - * gui/e-meeting-edit.c: removed some debugging code that I had, - which might have caused problems. - -2000-11-27 Jesse Pavel <jpavel@helixcode.com> - - * gui/calendar-model.c: added a preliminary change to have - Assigned To-Do items have a corresponding icon. - -2000-11-27 JP Rosevear <jpr@helixcode.com> - - * conduits/todo/todo-conduit.c (free_prepare): Ditto - - * conduits/calendar/calendar-conduit.c (free_prepare): Adjust - free_prepare to the correct signal parameters. Don't actually - do anything - there is a semantic discrepancy that needs to be - resolved. - -2000-11-26 Damon Chaplin <damon@helixcode.com> - - * gui/e-day-view.c (e_day_view_set_days_shown): == instead of =. - -2000-11-26 Damon Chaplin <damon@helixcode.com> - - * gui/gnome-cal.c: added more support for config settings. - - * gui/e-week-view.[hc]: - * gui/e-day-view.[hc]: added support for setting - show event end - times, week start day and 12-hour format (unfinished). - - * gui/e-day-view-time-item.c: started 12-hour support. - - * gui/tag-calendar.c (prepare_tag): use end_day + 1 since we want to - include the last day. - - * gui/event-editor.c (set_all_day): minor change when turning all_day - off - set the event end to one hour after the event start if it is on - or before the start time. Also added more comments to make it a bit - clearer. - - * cal-util/cal-recur.c (cal_obj_time_add_days): use a gint for day - rather than a guint since we now support -ve days. - Also fixed bug with weekly recurrences. - - * gui/dialogs/task-editor.c (task_editor_create_date_edit): use - config settings. - - * gui/dialogs/cal-prefs-dialog.c (cal_prefs_dialog_update_config): - updated EDateEdit calls. - -2000-11-24 Federico Mena Quintero <federico@helixcode.com> - - * gui/e-calendar-table.c (e_calendar_table_init): Unref the ETable - extras. - -2000-11-24 Federico Mena Quintero <federico@helixcode.com> - - * cal-util/cal-component.c (free_icalcomponent): DOH, fixed - reversed test for the presence of the icalcomp's parent. This was - causing memory leaks in the Wombat and elsewhere. - - * pcs/cal-backend.c (cal_backend_set_node_timet): Plug leak. - -2000-11-24 Federico Mena Quintero <federico@helixcode.com> - - * pcs/cal-backend-file.c (scan_vcalendar): Use the new libical - external iterators (icalcomponent_begin_component() and friends); - the internal iterators are deprecated. - - * cal-util/test-recur.c (generate_occurrences): Likewise. - - * gui/e-itip-control.c (pstream_load): Likewise. - - * gui/e-meeting-edit.c (e_meeting_edit): Likewise. - - * pcs/cal-backend.c (cal_backend_log_entry): Plug leak. - (cal_backend_log_sync): Free the entry->uid. - - * util/icalendar-save.[ch]: - * util/icalendar-test.c: - * util/icalendar.[ch]: Removed obsolete files. - -2000-11-21 Federico Mena Quintero <federico@helixcode.com> - - * gui/task.xpm: Remove the check because it makes it look like the - task is already completed. This fixes bug #819. - - * gui/task-recurring.xpm: Make it use a prettier overlaid icon. - - * gui/task-*.xpm: Made the things look like little spiral-bound - notebooks. - - * gui/e-calendar-table.c (E_CALENDAR_TABLE_SPEC): Make the default - column order be icon/completed/summary. You may need to erase - your ~/evolution/config/TaskPad for this to appear. - -2000-11-21 Federico Mena Quintero <federico@helixcode.com> - - * gui/calendar-model.c (calendar_model_is_cell_editable): The icon - column is not editable! - - * gui/calendar-commands.c (todo_properties_changed): Removed. - (time_format_changed): Removed. - (colors_changed): Removed. - - * gui/calendar-commands.h: - * gui/prop.c (prop_apply): - * gui/calendar-commands.c (init_calendar): Removed the old to-do - list crap. - - * gui/gncal-todo.[ch]: Removed obsolete files. - - * gui/Makefile.am (evolution_calendar_SOURCES): Removed gncal-todo.[ch]. - - * gui/gnome-cal.c (gnome_calendar_todo_properties_changed): Removed. - (gnome_calendar_time_format_changed): Removed. - (gnome_calendar_colors_changed): Removed. - -2000-11-21 Jesse Pavel <jpavel@helixcode.com> - - * gui/e-itip-control.c: fixed the stupid Bonobo widget size - allocation bug that had been vexing me. - - * gui/e-itip-control.glade: I removed some hacks that were - necessary for said size bug. - -2000-11-16 Jesse Pavel <jpavel@helixcode.com> - - * gui/e-itip-control.c, gui/e-meeting-edit.c: added cancellation - code to our program; people can cancel meetings, which is the best - thing to do for most meetings. - -2000-11-13 Jesse Pavel <jpavel@helixcode.com> - - * gui/e-itip-control.c: made the REPLY code actually work. - -2000-11-13 Jesse Pavel <jpavel@helixcode.com> - - * gui/itip-utils.[ch]: I created this file to store some commonly used enumeration to - string mappings and functions. - - * gui/Makefile.am: this was changed to reflect the addition of the above file. - - * gui/e-itip-control.c: added code to take action on a REPLY message. - - * gui/e-meeting-edit.c: bug fixes. - -2000-11-12 Federico Mena Quintero <federico@helixcode.com> - - OK, bugzilla bug #829 is fixed and that does not redeem me from - extreme procrastination. Wheeeeeeeeeeeeeeee! - - * gui/event-editor-dialog.c: Changed the "Rule view" label to - "Preview" - -2000-11-12 Federico Mena Quintero <federico@helixcode.com> - - * gui/event-editor.c (make_recur_ending_count_special): Misspelled - "occurrences". - (fill_recurrence_widgets): Sensitize the "Custom recurrence" radio - button as appropriate. - (sensitize_recur_widgets): Resurrected the recurrence custom - warning label. - (get_widgets): Load the recurrence custom warning bin. - - * gui/event-editor-dialog.glade: Add an empty alignment for the - recurrence custom warning label. - -2000-11-12 Federico Mena Quintero <federico@helixcode.com> - - * gui/event-editor.c (recur_preview_date_range_changed_cb): New - function; re-tag the calendar when its date range changes. - (init_widgets): Connect to "date_range_changed" on the recurrence - preview calendar. - (make_recur_weekly_special): Connect to "changed" on the weekday - picker. - (recur_weekday_picker_changed_cb): New function; re-tag the calendar. - (month_day_menu_selection_done_cb): Re-tag the calendar. - (recur_month_index_value_changed_cb): Likewise. - (recur_ending_until_changed_cb): Likewise. - (recur_ending_count_value_changed_cb): Likewise. - (make_recur_monthly_special): Connect to "value_changed" on the - adjustment of the month index. - (make_recur_ending_until_special): Connect to "changed" on the - ending-until date picker. - (make_recur_ending_count_special): Connect to "value_changed" on - the ending-count adjustment. - (init_widgets): Set to zero the maximum number of selectable days - in the recurrence preview calendar. Set the week_start_day from - the calendar's configuration. - -2000-11-12 Federico Mena Quintero <federico@helixcode.com> - - * gui/event-editor.c (clear_widgets): Block the signals as appropriate. - (fill_ending_date): Ditto. - (fill_recurrence_widgets): Ditto. - (recurrence_type_toggled_cb): Only sensitize the widgets and - preview the recurrence if the toggle button is active. - -2000-11-12 Federico Mena Quintero <federico@helixcode.com> - - * gui/event-editor.c (recur_to_comp_object): Clear the rdate and - exrule lists from the component if we are setting a simple - recurrence. - (recur_to_comp_object): Set the exdate list here instead of in - dialog_to_comp_object(). - (preview_recur): New function to tag the recurrence preview - calendar based on the information from the dialog box. - (fill_exception_widgets): Fill the exception widgets here; moved - over from fill_widgets(). - (fill_recurrence_widgets): Call preview_recur(). Also, call - fill_exception_widgets() first of all. - (recurrence_type_toggled_cb): Call preview_recur(). - (recur_interval_selection_done_cb): Likewise. - (recur_ending_selection_done_cb): Likewise. - (recurrence_exception_add_cb): Likewise. - (recurrence_exception_modify_cb): Likewise. - (recurrence_exception_delete_cb): Likewise. - (date_changed_cb): Likewise. - (recur_interval_value_changed_cb): Likewise, new function. - - * gui/tag-calendar.[ch]: New files with utilities for tagging - calendars. mark.[ch] should go away some day. - - * gui/tag-calendar.c (tag_calendar): Moved over from - gnome_calendar_tag_calendar(). Take in a CalClient instead of a - GnomeCalendar. Added API docs. - (tag_calendar_by_comp): New function to tag a calendar based on a - single calendar component instead of a whole client. - - * gui/gnome-cal.c (initial_load): Use tag_calendar_by_client(). - (obj_updated_cb): Likewise. - (obj_removed_cb): Likewise. - (gnome_calendar_on_date_navigator_date_range_changed): Likewise. - (editor_closed_cb): Free the closure. - (destroy_editor_cb): Renamed from free_uid(). Do not free the - UID; just unref the event editor. Our destroy handler to it will - free things properly. This will also cause the corresponding - calendar client to be unrefed. - (editor_closed_cb): Use a flag on the GnomeCalendar to decide - whether to remove the editor from the hash table. This is sort of - icky. - - * gui/calendar-model.c (obj_updated_cb): If the object is new, we - have to use e_table_model_row_inserted(), not row_changed(). - Thanks to JP Rosevear for reporting this. - - * gui/Makefile.am (evolution_calendar_SOURCES): Added - tag-calendar.[ch] to the list of sources. - -2000-11-11 Matt Bissiri <bissiri@eecs.umich.edu> - - * gui/evolution-calendar.oafinfo: - Update the remaining "IDL:Evolution*" to "IDL:GNOME/Evolution*" - to sync up with yesterday's IDL re-scoping. - -2000-11-10 Michael Meeks <michael@helixcode.com> - - * gui/Makefile.am ($(IDL_GENERATED)): sort include order. - - * pcs/Makefile.am (idl_flags): ditto. - -2000-11-10 JP Rosevear <jpr@helixcode.com> - - * conduits/calendar/calendar-conduit.c (for_each_modified): Inc the - iterator before finding the next changed item. - - * conduits/todo/todo-conduit.c (for_each_modified): ditto - -2000-11-09 Jesse Pavel <jpavel@helixcode.com> - - * gui/e-itip-control.c: I wrote the code so that recipients of meeting requests - can reply appropriately. - -2000-11-09 Jesse Pavel <jpavel@helixcode.com> - - * gui/e-meeting-edit.c: fixed a bug that would make the calendar segfault - if the meeting editor were called up twice without first saving the - component. - -2000-11-08 Jesse Pavel <jpavel@helixcode.com> - - * gui/e-itip-control.c, gui/e-itip-control.glade: updated the GUI - to allow the user to add PUBLISHed events to his calendar, and created - unworking buttons for meeting requests. - -2000-11-08 Federico Mena Quintero <federico@helixcode.com> - - These changes fix bugzilla bugs #874 and #875. - - * cal-util/cal-component.c (cal_component_get_exdate_list): Return - a list of CalComponentDateTime instead of simple struct - icaltimetype objects. Exception date properties *can* contain a - timezone parameter, so we need to include those if they are - present. - (cal_component_set_exdate_list): On the input, handle a list of - CalComponentDateTime structures. On the internals, handle a list - of struct datetime instead of plain properties. - (cal_component_free_exdate_list): Handle a list of - CalComponentDateTime structures. - (scan_exdate): Create a list of struct datetime structures. - (free_icalcomponent): Free the exdate_list properly. - - * cal-util/cal-recur.c (generate_instances_for_chunk): Use the - proper types for exception dates. - - * gui/comp-util.h: - * gui/comp-util.c: New files with utilities for manipulating - calendar component objects. - (cal_comp_util_add_exdate): New function. - - * gui/Makefile.am (evolution_calendar_SOURCES): Added - comp-util.[ch] to the list of sources. - - * gui/e-day-view.c (add_exdate): New convenience function to add - an exception date to a calendar component. - (e_day_view_on_unrecur_appointment): Use cal_comp_util_add_exdate(). - (e_day_view_on_delete_occurrence): Likewise. - - * gui/e-week-view.c (e_week_view_on_delete_occurrence): Likewise. - (e_week_view_on_unrecur_appointment): Likewise. - - * gui/event-editor.c (nth_weekday): Be paranoid about valid - position values. - (fill_widgets): Use the proper types for exdates. - (dialog_to_comp_object): Likewise. - -2000-11-08 Federico Mena Quintero <federico@helixcode.com> - - * gui/event-editor.c (adjust_day_index_spin): Adjust the valid - range of the month index spin button depending on the selection of - the day/weekday menu. - -2000-11-07 Jesse Pavel <jpavel@helixcode.com> - - * gui/e-itip-control.c, gui/e-itip-control.glade: changed the GUI, - and added some extra feedback for the user. - -2000-11-07 Federico Mena Quintero <federico@helixcode.com> - - * gui/weekday-picker.h (WeekdayPickerClass): Added a "changed" - signal to notify of changes to the set of selected days. - - * gui/weekday-picker.c (weekday_picker_class_init): Create the - "changed" signal. - (weekday_picker_set_days): Emit the "changed" signal. - -2000-11-06 Jesse Pavel <jpavel@helixcode.com> - - * gui/e-itip-control.c, gui/e-itip-control.glade: changed to GUI to - accomodate dynamically generated buttons, which will be tailored to - the type of iTip message that is incoming. - - * gui/e-meeting-dialog.glade gui/e-meeting-edit.c: added a new button - to publish events, in addition to requesting meetings. - -2000-11-05 Federico Mena Quintero <federico@helixcode.com> - - * gui/event-editor-dialog.glade: Removed the old recurrence page. - Wheeeeeeeeee! - - * gui/event-editor.c (make_recurrence_special): Clear the monthly - widgets. - (make_recur_monthly_special): Create the monthly widgets. - (clear_widgets): Clear the monthly values. - (simple_recur_to_comp_object): Fill in the monthly values. - (fill_recurrence_widgets): Fill in the monthly and yearly source - values. - (dialog_to_comp_object): Take in a CalComponent instead of using - the event editor's directly. - (recur_to_comp_object): Likewise. - (simple_recur_to_comp_object): Likewise. - (EventEditorPrivate): Removed the widgets from the old recurrence - page. - (get_widgets): Likewise. - (clear_widgets): Likewise. - (dialog_to_comp_object): If the description or summary are empty, - just clear the description list or summary property, respectively, - instead of saving empty ones. - (simple_recur_to_comp_object): Set the week_start field. - - * gui/main.c: Fix includes, and add calendar-config.h. - - * gui/Makefile.am (evolution_calendar_SOURCES): The glade messages - file should not be in SOURCES. - -2000-11-05 Christopher James Lahey <clahey@helixcode.com> - - * doc/.cvsignore, doc/C/.cvsignore: Removed unnecessary .cvsignore - files. - -2000-11-03 Federico Mena Quintero <federico@helixcode.com> - - * gui/event-editor.c (check_all_day): Block signals from the - toggle button. - (date_changed_cb): Merged check_dates() and check_times() into - this function; provide better behavior as well. - (check_dates): Removed function. - (check_times): Removed function. - (init_widgets): Connect to the "changed" signal on the start_time - and end_time widgets. - (check_all_day): Use a better test. - - * gui/Makefile.am: Clean the idl-generated sources properly. - * cal-client/Makefile.am: Likewise. - -2000-11-03 Jesse Pavel <jpavel@helixcode.com> - - * gui/e-itip-control.c: added some checks for the type of an - incoming iCal component before passing it off to the CalComponent - routines. - -2000-11-02 Federico Mena Quintero <federico@helixcode.com> - - * gui/dialogs/task-editor.c (init_widgets): The date editor's - signal is now "changed". - (completed_changed): Renamed callback to reflect the name of the - signal. - -2000-11-01 Gediminas Paulauskas <menesis@delfi.lt> - - * gui/main.c: (main): added call to bindtextdomain and textdomain, so - all calendar gui shows up localized. - -2000-10-31 Federico Mena Quintero <federico@helixcode.com> - - * gui/event-editor.c (count_by_xxx): Hmmm. SHRT_MAX changed to - ICAL_RECURRENCE_ARRAY_MAX in libical. Deal with it. - (fill_recurrence_widgets): Likewise. - (simple_recur_to_comp_object): Fixed incorrect assertion. The - weekday picker is not the immediate child of the recurrence - special container. - (fill_recurrence_widgets): Call make_recurrence_special() after - setting the recurrence period type. - (fill_ending_date): Call make_recurrence_ending_special(). This - would be so much nicer if GTK+ were model/view all over. - -2000-10-31 JP Rosevear <jpr@helixcode.com> - - * conduits/todo/todo-conduit.h: Remove add/del/mod hashes and - add changed_hash. - - * conduits/calendar/calendar-conduit.h: ditto - - * conduits/todo/todo-conduit.c (next_changed_item): Utility function - to get the next "really" changed item (changed status can be cleared now) - (compute_status): Compute status based on changed_hash - (pre_sync): Fill changed_hash and counts adds/mods/dels - (set_status_cleared): New callback handler - avoid double syncing - (for_each_modified): Use next_changed_item to iterate - (add_archive_record): kill - (delete_archive_record): kill - (archive_record): New callback handler - mark/unmark archive status - (conduit_get_gpilot_conduit): Adjust signal connects - - * conduits/calendar/calendar-conduit.c: ditto - -2000-10-30 Federico Mena Quintero <federico@helixcode.com> - - * gui/event-editor.c (sensitize_recur_widgets): New function. We - split it from the radio callback so that we can call it explicitly - from fill_recurrence_widgets(). - (fill_recurrence_widgets): Call sensitize_recur_widgets() as - appropriate. - -2000-10-30 Federico Mena Quintero <federico@helixcode.com> - - * gui/calendar-commands.c (new_calendar): Removed the geometry and - hidden arguments. This code is ancient. - (all_calendars): Made static. This sucks; configuration should be - notification-based instead of "let's iterate through all open - calendars". - (active_calendars): Removed. Functions can check the length of - the all_calendars list if they are interested. - - * gui/event-editor.c (sync_entries): Do not take in an extra data - pointer. - (summary_changed_cb): Use a single call back to sync both entries. - (sync_date_edits): New function to sync two EDateEdit widgets. - (init_widgets): Connect the general and recurrence starting date - widgets. - -2000-10-27 Federico Mena Quintero <federico@helixcode.com> - - * gui/event-editor.c (sync_entries): New function. - (general_summary_changed_cb): Sync the general summary to the - recurrence summary widget. - (recurrence_summary_changed_cb): Vice-versa. - (init_widgets): Hook to the summaries. - - * event-editor-dialog.glade: Do not expand/fill the start and end - date so that the "all day event" button is not pushed all the way - to the right. - Decrease the spacing between the recurrence sentence widgets. - Remove a spurious empty label that was lurking around the - recurrence widgets. - Make the alarm widgets expand the right way. - Delete old recurrence widgets. - -2000-10-27 Federico Mena Quintero <federico@helixcode.com> - - * gui/event-editor.c (init_widgets): Connect to the recurrence - ending menu. - (recur_ending_selection_done_cb): Implemented. - (make_recurrence_ending_special): Implemented. - (make_recur_ending_until_special): Implemented. - (fill_ending_date): Implemented. - (make_recur_ending_count_special): Implemented. - (simple_recur_to_comp_object): Fill in the ending date. - (clear_widgets): Clear the recurrence ending widgets. - - * gui/event-editor-dialog.glade: Moved the recurrence type radio - buttons to a single hbox to save space. - Fixed the lower value of the recurrence interval spin button. - Removed the stale widgets from the recurrence ending date part. - -2000-10-27 Jesse Pavel <jpavel@helixcode.com> - - * gui/e-meeting-edit.c: fixed problems in which I allocated CORBA - strings of 0 length, but then didn't NULL terminate them. - -2000-10-27 <jpr@helixcode.com> - - * conduits/calendar/calendar-conduit.c (check_for_slow_setting): - Check boundary case of fast sync - - * conduits/todo/todo-conduit.c (check_for_slow_setting): ditto - -2000-10-27 <jpr@helixcode.com> - - * conduits/calendar/calendar-conduit.c (add_archive_record): Remove - invalid test. - (local_record_from_comp): If the event is all day, mark it as timeless - (comp_from_remote_record): Timeless events take up all day - - * conduits/todo/todo-conduit.c (add_archive_record): ditto - -2000-10-27 JP Rosevear <jpr@helixcode.com> - - * conduits/todo/todo-conduit.c (add_archive_record): Take proper - number of parameters - - * conduits/calendar/calendar-conduit.c (add_archive_record): ditto - -2000-10-26 Federico Mena Quintero <federico@helixcode.com> - - * gui/event-editor.c (EventEditorPrivate): Integrate Anna's new - recurrence page. Replace the old widget pointers with the new - ones. Modified the relevant functions accordingly and added - plenty of new ones. - (event_editor_get_cal_client): New function. - (fill_recurrence_widgets): This is *THE* tricky function for you. - It has to discriminate whether we get a recurrence we support for - editing or not. And this is not trivial. Sigh. - (event_editor_update_widgets): Added preconditions and API docs. - - * event-editor-dialog.glade: Fixed all the spacings/ - paddings/packing options so that the widgets will look right if - the dialog box is resized. Also fixes some misaligned widgets. - - * cal-util/cal-component.c (cal_component_set_rdate_list): Removed - incorrect assertion. - -2000-10-26 Michael Meeks <michael@helixcode.com> - - * pcs/cal-factory.c (str_tolower): unsigned chars to isalpha - - * cal-util/calobj.c (weekdaylist, weekdaynum): ditto. - -2000-10-25 Jesse Pavel <jpavel@helixcode.com> - - * gui/e-meeting-edit.c: brushed up some code to deal with - the organizer entry, and solidified the CORBA memory-freeing - issues. - -2000-10-25 Jesse Pavel <jpavel@helixcode.com> - - * removed the Evolution-Composer generated files, due - to a tip on how we do things. - -2000-10-25 Jesse Pavel <jpavel@helixcode.com> - - * gui/e-meeting-edit.c: I fixed a bunch of memory-deallocation - bugs, and finished the initial integration with the mailer. - - * gui/Makefile.am: made the build us the Evolution-Composer.idl - from the composer directory. - -2000-10-25 Jesse Pavel <jpavel@helixcode.com> - - * gui/Evolution-Composer.idl: added this from the composer IDL sources - - * gui/Makefile.am: changed to reflect the above IDL and the associated - orbit-idl generated files. - - * gui/Evolution-Composer.h, - gui/Evolution-Composer-common.c, - gui/Evolution-Composer-stubs.c, - gui/Evolution-Composer-skels.c: - the generated files, as per the above description. - - * gui/e-meeting-edit.c: more work towards mailer integration. - -2000-10-24 Jesse Pavel <jpavel@helixcode.com> - - * gui/e-meeting-edit.c: I've added code to interact with the mailer's - CORBA interfaces, though it's not yet working. - -2000-10-23 JP Rosevear <jpr@helixcode.com> - - * conduits/todo/todo-conduit.c (local_record_from_comp): Use - new e-pilot-map lookup function - (match): ditto - - * conduits/calendar/calendar-conduit.c (local_record_from_comp): Use - new e-pilot-map lookup function - (match): ditto - -2000-10-23 Dan Winship <danw@helixcode.com> - - * pcs/Makefile.am (INCLUDES): - * gui/dialogs/Makefile.am (INCLUDES): - * gui/Makefile.am (INCLUDES): - * cal-util/Makefile.am (INCLUDES): - * cal-client/Makefile.am (INCLUDES): Update GNOMELOCALEDIR. - -2000-10-23 JP Rosevear <jpr@helixcode.com> - - * conduits/todo/todo-conduit.h: Use new libeconduit calls and - abstraction - - * conduits/calendar/calendar-conduit.c: ditto - - * conduits/calendar/calendar-conduit.h: ditto - - * conduits/todo/todo-conduit.c: ditto - - * conduits/calendar/Makefile.am: Add libeconduit-static.la - - * conduits/calendar/calendar-conduit.c (post_sync): Use e_pilot_map_write - (pre_sync): Use e_pilot_map_read - -2000-10-23 JP Rosevear <jpr@helixcode.com> - - * conduits/todo/Makefile.am: Add libeconduit-static.la - - * conduits/todo/todo-conduit.c (post_sync): Use e_pilot_map_write - (pre_sync): Use e_pilot_map_read - -2000-10-21 Damon Chaplin <damon@helixcode.com> - - * gui/dialogs/cal-prefs-dialog.c - (cal_prefs_dialog_use_24_hour_toggled): removed debug message. - - * gui/e-calendar-table.c (e_calendar_table_save_state): new function - to save the state of the table to a given file. - - * gui/e-calendar-table.h (struct _ECalendarTable): added etable field - so we can access it to save the state. - - * gui/gnome-cal.c (gnome_calendar_destroy): call - e_calendar_table_save_state() to save the state of the TaskPad. - (setup_widgets): load the state of the TaskPad. - - * gui/calendar-config.c: added support for the default view. - - * gui/gnome-cal.c (gnome_calendar_construct): - (gnome_calendar_set_view_internal): use/set the default view setting. - -2000-10-20 Jesse Pavel <jpavel@helixcode.com> - - * gui/e-meeting-editor.c: added more (working) integration with the - meeting schedular. - -2000-10-20 Jesse Pavel <jpavel@helixcode.com> - - * cal-utils/cal-component.c: in set_datetime(), I put an #if 0'd portion - of the code back into operation, because the icalproperty_remove_parameter() - function is now implemented. - - * gui/e-meeting-editor.c: added more (unworking) integration with the - meeting schedular. - -2000-10-20 JP Rosevear <jpr@helixcode.com> - - * pcs/cal-backend.c (cal_backend_destroy): New destroy - handler to properly stop the timer, sync the log and unref - the URI. - (cal_backend_last_client_gone): Just emit the signal, - clean up work is done in cal_backend_destroy now. - - * pcs/cal-backend-file.c (cal_backend_file_load): Unref the - uri we are replacing NOT the new uri. - -2000-10-20 JP Rosevear <jpr@helixcode.com> - - * conduits/todo/Makefile.am: Fix build - - * conduits/calendar/Makefile.am: Fix build - -2000-10-20 JP Rosevear <jpr@helixcode.com> - - * conduits/calendar/calendar-conduit.c (delete_archive_record): - Don't throw an error - - * conduits/todo/todo-conduit.c (delete_archive_record): ditto - -2000-10-20 JP Rosevear <jpr@helixcode.com> - - * conduits/todo/todo-conduit-control-applet.c: Add defines - - * conduits/todo/todo-conduit-config.h: put #ifdefs around functions - can't make this a public interface in the usual way as then the - symbols would be exported - - * conduits/todo/todo-conduit.c: Kill warnings. clahey will be - happy! Add some defines to include only the necessary config functions. - (conduit_get_gpilot_conduit): Hook up archive signals - - * conduits/calendar/calendar-conduit.c: Same as above - - * conduits/calendar/calendar-conduit-control-applet.c: ditto - - * conduits/calendar/calendar-conduit-config.h: ditto - -2000-10-20 Michael Meeks <michael@helixcode.com> - - * gui/calendar-commands.h: s/BonoboUIHandler/BonoboUIComponent/ - - * gui/calendar-commands.c (properties_cmd): ditto. - -2000-10-20 Damon Chaplin <damon@helixcode.com> - - * gui/calendar-model.c (calendar_model_value_at): use - cal_component_has_alarms(). - -2000-10-20 Damon Chaplin <damon@helixcode.com> - - * gui/e-calendar-table.c (E_CALENDAR_TABLE_SPEC): added - _click-to-add-message, though I'm not sure if i18n will work. - - * cal-util/cal-recur.c (cal_obj_time_add_hours): - (cal_obj_time_add_minutes): - (cal_obj_time_add_seconds): updated to handle -ve args. - - * cal-util/timeutil.c (time_add_day): set tm_isdst to -1 before calling - mktime(). - - * cal-util/cal-recur.c (generate_instances_for_chunk): don't call the - callback if the event ends exactly on the interval start time. - - * gui/e-week-view.c (e_week_view_reshape_event_span): - * gui/e-week-view-event-item.c (e_week_view_event_item_draw_icons): - * gui/e-day-view-top-item.c (e_day_view_top_item_draw_long_event): - * gui/e-day-view-main-item.c (e_day_view_main_item_draw_day_event): - * gui/e-day-view.c (e_day_view_reshape_long_event): - (e_day_view_reshape_day_event): use cal_component_has_alarms(). - - * cal-util/cal-component.[hc]: added cal_component_has_alarms(). - -2000-10-16 Damon Chaplin <damon@helixcode.com> - - * gui/calendar-config.c (config_read): set default MonthVPanePosition - to 1 rather than 0, so if you move the hpane you'll see the date - navigator. - -2000-10-19 Jesse Pavel <jpavel@helixcode.com> - - * gui/event-editor.[ch]: added a public function which causes the - event editor to reload its widgets to the associated CalComponent. - - * gui/e-meeting-edit.c: added rudimentary support for the phat - e-meeting-time-selector widget, though it has no effect on the - component yet. - - * gui/Makefile.am: the meeting editor depends on the meeting widget - library, now. - - * gui/e-itip-control.glade: I added another toolbar button that summons - from the hoary deep the meeting time widget. - -2000-10-19 Ettore Perazzoli <ettore@helixcode.com> - - * gui/Makefile.am: Add `event-editor-dialog.glade.h'. - (EXTRA_DIST): Add `$(glade_messages)'. - -2000-10-19 Michael Meeks <michael@helixcode.com> - - * gui/calendar-commands.c (tb_print_cb): remove; redundant. - - * gui/event-editor.c (create_menu, create_toolbar): kill. - (event_editor_destroy): upd. - (event_editor_construct): update to new UI handler, cast - priv->general_summary to a widget not an object. - -2000-10-18 Michael Meeks <michael@helixcode.com> - - * gui/dialogs/task-editor.c (create_menu, create_toolbar): die. - (debug_xml_cb): add debugging hook. - - * gui/dialogs/Makefile.am: add EVOLUTION_DATADIR - - * gui/dialogs/task-editor.c (task_editor_construct): upd for new UI. - -2000-10-17 JP Rosevear <jpr@helixcode.com> - - * conduits/todo/todo-conduit-control-applet.c: Add defines - - * conduits/todo/todo-conduit-config.h: put #ifdefs around functions - can't make this a public interface in the usual way as then the - symbols would be exported - - * conduits/todo/todo-conduit.c: Kill warnings. clahey will be - happy! Add some defines to include only the necessary config functions. - (conduit_get_gpilot_conduit): Hook up archive signals - - * conduits/calendar/calendar-conduit.c: Same as above - - * conduits/calendar/calendar-conduit-control-applet.c: ditto - - * conduits/calendar/calendar-conduit-config.h: ditto - -2000-10-16 Jesse Pavel <jpavel@helixcode.com> - - * gui/e-itip-control.c: You can now add incoming iTip - messages to your calendar store. - - * gui/e-itip-control.glade: added a progress bar dialog - in case the calendar loading takes a long time. - -2000-10-16 JP Rosevear <jpr@helixcode.com> - - * cal-client/cal-client.h: Remove pilot cruft. All pilot stuff - is in the conduits now and uses the logging facility. - - * pcs/cal-backend-file.c: ditto - - * pcs/cal-backend.h: ditto - - * pcs/cal-backend.c: ditto - - * pcs/cal.c: ditto - - * pcs/cal.h: ditto - - * idl/evolution-calendar.idl: ditto - - * cal-util/cal-component.h: ditto - - * cal-util/cal-component.c: ditto - - * cal-client/cal-client.c: ditto - - * conduits/calendar/calendar-conduit.c (local_record_from_comp): - Take a stab at storing recurrence stuff on the pilot properly - - * pcs/cal-backend.c (cal_backend_update_object): Don't log the - event until after the update in case its a new item - -2000-10-16 Tuomas Kuosmanen <tigert@helixcode.com> - - * gui/dayview.xpm, gui/workweekview.xpm, gui/weekview.xpm - gui/monthview.xpm gui/yearview.xpm: Updated icons, let me know - if you like these or not, I might work on these some more but - I wanted to put these versions up anyway to get feedback.. - -2000-10-15 Dan Winship <danw@helixcode.com> - - * gui/Makefile.am: Remove CPPFLAGS def since the -D there was - already in INCLUDES - -2000-10-14 Ettore Perazzoli <ettore@helixcode.com> - - * gui/evolution-calendar.oafinfo: Added an - "evolution:shell-component-icon" attribute. - -2000-10-12 Jesse Pavel <jpavel@helixcode.com> - - * gui/e-itip-control.{c,glade}: Made the control much more - relavent to the function at hand. - -2000-10-12 Damon Chaplin <damon@helixcode.com> - - * gui/e-calendar-table.c (E_CALENDAR_TABLE_SPEC): set the 2 icon - columns to a min width of 18 and resizable to FALSE. - -2000-10-12 Damon Chaplin <damon@helixcode.com> - - * gui/calendar-commands.c (calendar_control_activate): - (update_pixmaps): - (set_pixmap): set the pixmaps of the toolbar buttons for the views, - and removed a lot of old unused stuff. We'll use plain buttons for - the view buttons for now, until Bonobo toolbars support radio buttons. - - * gui/gnome-cal.c (gnome_calendar_dayjump): check day_button is not - NULL before using it. - (gnome_calendar_update_view_buttons): check button is not NULL. - -2000-10-11 Damon Chaplin <damon@helixcode.com> - - * gui/e-day-view-time-item.c (e_day_view_time_item_draw): got 12/24 - hour format the wrong way round. - -2000-10-12 JP Rosevear <jpr@helixcode.com> - - * conduits/calendar/calendar-conduit.c (comp_from_remote_record): - Store recurrence stuff on the desktop properly - (get_ical_day): Utility function - -2000-10-12 Iain Holmes <iain@helixcode.com> - - * gui/component-factory.c: Disable the executive summary. - -2000-10-11 JP Rosevear <jpr@helixcode.com> - - * pcs/cal-backend.c (cal_backend_log_entry): Take CalObjType - as a param because its impossible to determine after a delete. - (cal_backend_remove_object): Calculate CalObjType and pass - it to cal_backend_log_entry - (cal_backend_update_object): ditto - - * conduits/todo/todo-conduit.c (local_record_from_comp): Kill - unused variables. - (add_archive_record): Don't kill the sync if this happens - (update_record): Kill old function - (replace_record): New function to handle replace_record signal - (conduit_get_gpilot_conduit): Listen for replace record signal - (add_record): Always add a new record, never replace - (replace_record): Always replace an existing record - - * conduits/calendar/calendar-conduit.c: Same as above - -2000-10-10 Jesse Pavel <jpavel@helixcode.com> - - * gui/e-itip-control.c: set a default size for the control. - -2000-10-10 Jesse Pavel <jpavel@helixcode.com> - - * gui/evolution-calendar.oafinfo: Added information about the - text/calendar MIME type, so that the evolution-calendar is called - to deal with iMIP attachments. - - * gui/e-itip-control.[ch]: These files implement a Bonobo - control that will eventually deal with iMIP/iTIP messages from - the mailer. Right now, it's not working. - - * gui/e-itip-control.glade: The Glade GUI for the above-mentioned - control. - - * gui/Makefile.am: added references to the files I created. - - * gui/main.c: called the initialization function of the Bonobo - control factory. - -2000-10-11 Tuomas Kuosmanen <tigert@helixcode.com> - - * gui/task-assigned-to.xpm gui/task-assigned.xpm - gui/recur.xpm gui/task-recurring.xpm gui/task.xpm: - New versions of the icons for the tasklist/pad. - -2000-10-11 Damon Chaplin <damon@helixcode.com> - - * gui/component-factory.c (owner_unset_cb): don't free evolution_dir - as we need it to save the config settings. - -2000-10-11 Damon Chaplin <damon@helixcode.com> - - * gui/main.c (main): call calendar_config_write_on_exit() to write - out some special config settings (as the mail component does). - - * gui/calendar-commands.c (properties_cmd): changed to use the new - preferences dialog. - (update_all_config_settings): new function to iterate over all the - calendars and update the config settings. - - * gui/dialogs/cal-prefs-dialog.glade: preferences dialog. - - * gui/dialogs/cal-prefs-dialog.[hc]: new files for the preferences - dialog. - - * gui/calendar-config.[hc]: new files to handle loading/saving config - settings. - - * cal-util/cal-recur.c: fixed bug in YEARLY when no filters were set, - plus minor changes. - - * cal-util/test-recur.c: updated. - - * gui/e-day-view-time-item.c: - * gui/popup-menu.c: update to #include <gal/widgets/e-gui-utils.h> - - * gui/component-factory.c (owner_set_cb): called calendar_config_init. - (owner_set_cb): - (owner_unset_cb): updated the prototypes. - - * gui/main.c (main): added call to calendar_config_write_on_exit(). - - * gui/component-factory.h: - * gui/component-factory.c (owner_set_cb): added global evolution_dir - just like the mail component, so we know we to store config stuff. - -2000-10-11 Christopher James Lahey <clahey@helixcode.com> - - * gui/e-calendar-table.c: Fixed the column elements here. - -2000-10-11 Christopher James Lahey <clahey@helixcode.com> - - * gui/e-calendar-table.c: Updated to use the new ETable - specification stuff. - -2000-10-11 JP Rosevear <jpr@helixcode.com> - - * conduits/todo/todo-conduit.c (map_sax_start_element): The - element is "pilot_id" not "pilotid". Update both maps - (compute_pid): Utility function to set a local records pid - (local_record_from_comp): Compute the pid and status here, - no longer use the old cal_component pilot interfaces - (free_match): Its a *local not a **local - - * conduits/calendar/calendar-conduit.c: same as above - - * conduits/todo/todo-conduit.h: Have both a uid and pid map - - * conduits/todo/calendar-conduit.h: same as above - -2000-10-09 JP Rosevear <jpr@helixcode.com> - - * conduits/*: Adjust to using gnome-pilot-sync-abs conduit which - is based on the latest pilot link changes. - -2000-10-09 Iain Holmes <iain@helixcode.com> - - * Makefile.am: Added the executive-summary library and cflags - - * gui/evolution-calendar.oafinfo: Added oaf servers for the - executive summary and executive summary factory. - - * gui/calendar-summary.[ch]: New files to create the summary. - - * gui/component-factory.c (summary_fn): Create the executive - summary component. - (component_factory_init): Start the summary factory as well. - -2000-10-06 Federico Mena Quintero <federico@helixcode.com> - - * gui/weekday-picker.[ch]: New widget to pick weekdays. - -2000-10-05 Michael Meeks <michael@helixcode.com> - - * gui/calendar-commands.c: upd. - (calendar_control_activate): upd. - (calendar_control_deactivate): upd. - -2000-10-05 Damon Chaplin <damon@helixcode.com> - - * gui/e-day-view.c: - * gui/e-week-view.c: when the user types in a new event, don't create - it until the user hits Return or switches focus. Removed the - editing_new_event flags. - - * cal-util/test-recur.c: rewritten to work on ics files. Now I can - start testing the recurrence code. - - * cal-util/cal-recur.c: a few fixes. - - * gui/e-day-view.c (e_day_view_check_if_new_event_fits): fixed to - return TRUE for long events, not FALSE. - -2000-10-04 Federico Mena Quintero <federico@helixcode.com> - - * gui/print.c (print_todo_details): As a temporary solution to the - to-do printing, just print the summaries. We'll use the ETable - printing stuff later. - - * gui/print.c (print_day_summary_cb): Use g_list_append() correctly. - (print_todo_details_cb): Likewise. - (print_day_summary): Initialize psi.events. This code was - obviously never tested. - (print_todo_details): Likewise. - (print_day_details): Initialize pdi.slots. - - * gui/print.c (range_selector_new): Fix strftime() %a versus %b - confusion. Fixes bugzilla #644. - (range_selector_new): Fix the whole localization mess by making - better use of strftime(). Now we generate whole date strings at a - time and compose them later. Fixes bugzilla #643. - -2000-10-02 Jesse Pavel <jpavel@helixcode.com> - - * gui/e-meeting-edit.c: added support for the ROLE and RSVP parameters - in both the GUI and underlying iCal. - -2000-09-29 Jesse Pavel <jpavel@helixcode.com> - - * gui/e-meeting-edit.c: added support for organizers in the meeting - scheduler. - -2000-09-29 Jesse Pavel <jpavel@helixcode.com> - - * gui/e-meeting-edit.c: added code that makes changes to the underlying - iCAL structure of an event, when the user changes meeting information. - - * gui/e-meeting-dialog.glade: this is the Glade UI for the meeting dialog - and accoutrements. - -2000-09-29 Damon Chaplin <damon@helixcode.com> - - * cal-util/cal-recur.c: updated to support RDATE end times or - durations. Note that if you have two RDATEs with the same start times, - but with different end dates/durations set, the results are - unpredictable. So the event editor dialog should check for this. - - * gui/e-week-view-main-item.c (e_week_view_main_item_draw_day): - make strftime() strings translatable, and changed the formats a bit. - - * NOTE: someone needs to check print.c to make sure strftime strings - are OK for i18n. - - * gui/e-day-view.h: Changed EDayViewDateFormat enum. We now try to - include the weekday if possible. Also changed EDayView struct so we - store the month & weekdays with the longest names rather than the - actual widths. This helps i18n. - - * gui/e-day-view.c (e_day_view_recalc_cell_sizes): used _() for - strftime strings, tried to see if weekday fits, and rearranged a - bit to make i18n easier. - - * gui/e-day-view-top-item.c (e_day_view_top_item_draw): used _() for - strftime strings, and updated to use new formats. - - * gui/calendar-model.c: added use_24_hour_format boolean to - CalendarModelPrivate so we can display dates in 12-hour format if - requested. This meant adding a CalendarModel argument to a few - functions. Also added get/set functions to set use_24_hour_format. - I suppose ideally we should have an ECellDate renderer and this option - should go there. - -2000-09-27 Jesse Pavel <jpavel@helixcode.com> - - * gui/event-editor.c: changed a menu entry so that it will invoke - my meeting editor. - - * gui/e-meeting-edit.[ch]: added these files to provide preliminary - support for iTIP meeting scheduling. Currently, only the GUI works; - there is not yet any backend support. - - * gui/Makefile.am: added entries for e-meeting-edit.[ch] - -2000-09-24 Damon Chaplin <damon@helixcode.com> - - * gui/dialogs/task-editor-dialog.glade: set the height of the scrolled - window for the description field, since the default window height - doesn't seem to be working. - - * cal-util/cal-component.h: added functions to get the actual - icalproperty lists for RRULE and EXRULE properties. - - * cal-util/cal-recur.[hc]: added support for COUNT, though I need to - test it a bit. Also fixed the call to generate_instances_for_year() so - it uses the chunk dates. - -2000-09-20 Damon Chaplin <damon@helixcode.com> - - * gui/event-editor.c: got rid of 1 '_' in '__Formatting'. - -2000-09-22 Michael Meeks <michael@helixcode.com> - - * gui/calendar-commands.c (calendar_control_activate): upd. - -2000-09-21 Federico Mena Quintero <federico@helixcode.com> - - * gui/calendar-commands.c (verbs): Removed the "about calendar" - command, since we don't want to have both "About Evolution" and - "About Calendar". - -2000-09-21 Michael Meeks <michael@helixcode.com> - - * gui/calendar-commands.c (calendar_control_activate): _UIHandler - update. - -2000-09-20 JP Rosevear <jpr@helixcode.com> - - * conduits/todo/todo-conduit.c (pre_sync): Don't fail if there - is no map file. - -2000-09-20 JP Rosevear <jpr@helixcode.com> - - * conduits/todo/todo-conduit.h: Add since field to context - - * conduits/todo/todo-conduit.c (map_set_node_timet): New utility - function - (map_sax_start_element): Look for the map timestamp as well - (map_write): Write the map timestamp - (pre_sync): Use the map time stamp when looking for changed entries - - * pcs/cal-backend.c (cal_backend_log_sax_start_element): Make sure - we are in a valid timestamp - -2000-09-20 JP Rosevear <jpr@helixcode.com> - - * pcs/cal-backend.c (cal_backend_log_name): Make the log file - name relevant to the actual calendar file, rather than just the - directory. - -2000-09-20 JP Rosevear <jpr@helixcode.com> - - * pcs/cal-backend.c (cal_backend_get_log_entries): Oops - -2000-09-20 JP Rosevear <jpr@helixcode.com> - - * pcs/cal-backend.c (cal_backend_get_log_entries): Use a local - sax handler. - - * conduits/todo/todo-conduit.c (pre_sync): Use xmlSAXParseFile - (map_sax_parse): Delete - -2000-09-20 JP Rosevear <jpr@helixcode.com> - - * pcs/cal-backend.c (cal_backend_log_sax_start_element): Properly - assign the CalObjChange type. - (cal_backend_log_sax_parse): Delete - (cal_backend_get_log_entries): Use xmlSAXUserParseFile - -2000-09-19 JP Rosevear <jpr@helixcode.com> - - * pcs/cal-backend.c (cal_backend_set_uri): New utility function - (cal_backend_load): use above - (cal_backend_create): use above - (cal_backend_log_name): Take a uri instead of a backend param - - * pcs/cal-backend-file.c: Get rid of useless hash functions - (cal_backend_file_load): Check to make sure path exists and is - local - (cal_backend_file_load): Unref the current uri if there is one - (cal_backend_file_create): ditto - - * pcs/cal-backend.c (cal_backend_last_client_gone): Sync before - shooting ourselves in the foot - - * pcs/cal-backend-file.c (save): Fully implement backing up the - calendar before writing out the new entry. - -2000-09-19 JP Rosevear <jpr@helixcode.com> - - * conduits/todo/todo-conduit.c (check_for_slow_setting): Add some - other cases where a slow sync is in order - (pre_sync): Pre load the uids, the map and the add/mod/del lists - (match_record): Use the map hash to match records - (iterate): Iterate using the pre-loaded uid list - (iterate_specific): Iterate using the add/mod/del lists - (purge): Delete all entries in the del list - (set_status): Set status by adding to an appropriate list - (set_pilot_id): Set pilot_id by updating map hash - - * conduits/todo/todo-conduit.h: Add lists for added, modified and - deleted objects - - * conduits/todo/todo-conduit.c (map_name): Get the pilot_id->uid map - file name - (map_sax_start_element): SAX handler to extract a pilot_id->uid - mapping - (map_sax_parse): Parse the given file and build a pilot_id->uid hash - (map_write_foreach): Write out individual mapping elements - (map_write): Write out the pilot_id->uid mapping - (start_calendar_server_cb): Rename from gnome_calendar_load_cb - - * conduits/todo/todo-conduit-config.h: Rename pilotID to pilot_id - - * conduits/todo/e-todo.conduit.in: A little renaming - - * conduits/todo/Makefile.am: Fix build slightly - - * pcs/cal.c (build_change_seq): Build a corba sequence out of a list - of CalObjChanges - (Cal_get_objects_in_range): Implement new corba function - - * pcs/cal-backend.c (cal_backend_init): Intiliaze to NULL - (cal_backend_load): Track the uri so we can write the log file - to the same place - (cal_backend_log_name): Figure out the log filename/path based on - the calendar uri - (cal_backend_set_node_timet): Set an xml node property value from - a time_t - (cal_backend_log_entry): Adds a log entry to list waiting to be written - out - (cal_backend_log_sync): Syncs the log entries to disk - (cal_backend_log_sax_start_element): SAX callback for reading in - log entries - (cal_backend_log_sax_end_element): ditto - (cal_backend_log_sax_parse): Main SAX parser call to parse the log - file looking for particular log entries and creating a CalObjChange - hash with the last change for each object - (cal_backend_get_log_entries): Returns a hash of objects of a given - type changed since the given time - (cal_backend_update_object): Add appropriate log entries - (cal_backend_remove_object): ditto - (cal_backend_get_changed_uids): Implement new idl interface call - (cal_backend_foreach_changed): Convert CalObjChange hash into a list - - * pcs/cal-backend-imc.[hc]: Remove crufty files - - * pcs/cal-backend-file.c (cal_backend_file_get_type_by_uid): New - function that returns the CalObjType for a uid. - - * cal-client/cal-client.h: Update prototypes. - - * cal-client/cal-client.c (build_change_list): Build a list - of CalObjChange items from a corba sequence. - (cal_client_get_changed_uids): New accessor method for the - similarly named addition to the idl file. - - * cal-util/cal-util.h: Update prototypes and add CalObjChangeType - enum. - - * cal-util/cal-util.c (cal_obj_change_list_free): New utility - method to free a list of CalObjChange objects. - - * idl/evolution-calendar.idl: Add get_changed_uids method - and associated types. - -2000-09-18 Christopher James Lahey <clahey@helixcode.com> - - * gui/Makefile.am: Added $(EXTRA_GNOME_CFLAGS) and - $(EXTRA_GNOME_LIBS). Removed unneeded libraries. - - * gui/calendar-model.h, gui/e-calendar-table.c, gui/e-day-view.c, - gui/e-week-view-event-item.c, gui/e-week-view.c, - gui/event-editor.c, gui/gncal-todo.c, gui/gnome-cal.c, gui/main.c, - gui/print.c, gui/dialogs/task-editor.c: Fixed the #include lines - to deal properly with gal. - - * gui/check-filled.xpm: New file since we can't include it from - e-table anymore. - -2000-09-16 Michael Meeks <michael@helixcode.com> - - * gui/Makefile.am (INCLUDES): add datadir - - * gui/calendar-commands.c (calendar_control_activate): use it. - -2000-09-14 JP Rosevear <jpr@helixcode.com> - - * conduits/todo/.cvsignore: Shush - -2000-09-14 JP Rosevear <jpr@helixcode.com> - - * Add headers with GPL notice and credit copyright to those appropriate - - * conduits/todo/todo-conduit-control-applet.c (doHelp): Update name, - authors, copyright for about dialog. - (activate_sync_type): Tidy - - * conduits/todo/Makefile.am: Rename binaries and libs to e-todo* - to avoid conflicts. - - * conduits/todo/e-todo.conduit.in: Reflect binary/lib name changes - - * conduits/todo/e-todo-conduit-control-applet.desktop: ditto - - * conduits/todo/todo.conduit.in: Removed - - * conduits/todo/todo-conduit-control-applet.desktop: Removed - - * conduits/todo/todo-conduit-config.h (todoconduit_load_configuration): - The config file will now be called e-todo-conduit - (todoconduit_save_configuration): ditto - - * conduits/todo/todo-conduit.c: Some renaming to keep consistent. - (pre_sync): Remove commented out function that does not exist. - - * conduits/todo/todo-conduit-control-applet.c: ditto - - * conduits/todo/todo-conduit-config.h: ditto - - * conduits/todo/todo-conduit.h: ditto - - -2000-09-07 Michael Meeks <michael@helixcode.com> - - * gui/calendar-commands.c: Re-write most UI handler code. - -2000-09-13 Federico Mena Quintero <federico@helixcode.com> - - * gui/calendar-model.c (obj_updated_cb): Removed an unused - variable. - - * gui/calendar-model.c (obj_updated_cb): See if the new object - matches the type of objects we were told to deal with. - (load_objects): Likewise. - -2000-09-13 JP Rosevear <jpr@helixcode.com> - - * pcs/cal-backend-file.c (remove_component): Only remove the pilot - item from the hash if it exists in the first place. - -2000-09-12 JP Rosevear <jpr@helixcode.com> - - * pcs/cal-backend-file.c (add_component): plug leakage - -2000-09-12 JP Rosevear <jpr@helixcode.com> - - * conduits/calendar/calendar-conduit.c: Hack to compile for distcheck. - - * conduits/calendar/calendar-conduit.h: Remove calobj.h dependency - -2000-09-12 JP Rosevear <jpr@helixcode.com> - - * pcs/cal-backend-file.c (cal_backend_file_load): Use g_int_* - for now - (cal_backend_file_create): ditto - - * conduits/todo/todo-conduit.c (local_record_from_compobject): Make - this actually fill in the todo record. - (find_record_in_repository): Add debug stuff - (iterate_specific): Use the already exisiting utility function - - * pcs/cal-backend-file.c (cal_backend_file_update_pilot_id): correct - the status and id types. g_strdup the uid since this is not a - constified return - (cal_backend_file_get_uid_by_pilot_id): correct the id type - -2000-09-12 Ettore Perazzoli <ettore@helixcode.com> - - * gui/Makefile.am: Remove `ui.xml' stuff. - - * pcs/cal-backend.c: Dont' #include calobj.h anymore as it's gone. - -2000-09-12 Federico Mena Quintero <federico@helixcode.com> - - * gui/gnome-cal.c (gnome_calendar_construct): Connect to the - "cal_loaded" signal of the client here. - (connect_load): Removed function. - (disconnect_load): Removed function. - (cal_loaded_cb): Store the URI we are loading in the GnomeCal - structure instead of in a weird closure. This gets rid of the - connect/disconnect mess as well. - (gnome_calendar_open): Store the URI in the GnomeCal. - -2000-09-11 Christopher James Lahey <clahey@helixcode.com> - - * gui/e-day-view.c: Fixed a warning (removed unused variable - gfloat width from e_day_view_get_event_position.) - -2000-09-11 JP Rosevear <jpr@helixcode.com> - - * conduits/todo/todo-conduit.c: Handle renaming, header cleanup - - * conduits/todo/todo-conduit.h: Rename GCalLocalRecord to - EToDoLocalRecord, header cleanup - -2000-09-11 JP Rosevear <jpr@helixcode.com> - - * conduits/todo/todo-conduit.c (comp_from_remote_record): Use - description list instead of comment list for pilot todo note - (transmit): Check for null cal component properties, set priority - correctly, use description list instead of comment list. Make - pilot record private when appropriate. - -2000-09-10 JP Rosevear <jpr@helixcode.com> - - * conduits/todo/todo-conduit.c (comp_from_remote_record): Only - set the due date only if it exists - -2000-09-10 JP Rosevear <jpr@helixcode.com> - - * gui/calendar-model.c (get_is_complete): Relying on the status - field is somewhat faulty since it is related to group scheduling - -2000-09-10 JP Rosevear <jpr@helixcode.com> - - * conduits/todo/todo-conduit.c (update_calendar_entry_in_repository): - Make log output a little more sensible - (comp_from_remote_record): Minor correction when making a CalComponent - from scratch. - (update_record): Use comp_from_remote_record for new items, rather - than repeating the code here. - -2000-09-10 JP Rosevear <jpr@helixcode.com> - - * conduits/todo/todo-conduit.c: Remove catch_ret_val function - since its no longer useful. Fix naming of various fields from - the header changes. Use GnomePilotRecord* stuff instead of - ICAL_PILOT_SYNC_* - (e_todo_context_new): Rename from gcalconduit_new_context. Now takes - a pilot id and loads the configuration here - (e_todo_context_destroy): Rename from gcalconduit_destroy_context. - Unref the client and destroy the configuration if they exist here - (start_calendar_server): Change the default calendar name - (local_record_from_comp_uid): Rename from local_record_from_ical_uid - (local_record_from_compobject): Rename from - local_record_from_icalobject. Properly do the pilot id and status. - (comp_from_remote_record): Rename from ical_from_remote_record. - Handle due, complete, classification and pilot stuff properly - (pre_sync): Remove some old stuff. We need to figure out how to - set some of the field values. - (set_status): Reflect pilot status changes from above - (conduit_destroy_gpilot_conduit): Remove cleanup stuff that is - now done by e_todo_context_destroy - (conduit_get_gpilot_conduit): Only set the context as object - data of the conduit. - - * conduits/todo/todo-conduit.h: Rename GCalConduitContext to - EToDoConduitContext. Remove some unused struct fields. - For GCalLocalRecord, rename ical to comp. - -2000-09-11 Damon Chaplin <damon@helixcode.com> - - * gui/dialogs/task-editor.c: changed to use EDateEdit. - - * gui/dialogs/task-editor-dialog.glade: added "None" option to - Classification option menu, and used custom widgets for the date - entries so we can use EDateEdit widgets. - - * gui/event-editor.c: changed to use EDateEdit. Note that this needs - to be fixed at some point to handle invalid dates, i.e. when - e_date_edit_get_time returns -1. - - * gui/calendar-model.c (ensure_task_complete): - (ensure_task_not_complete): new functions to set the related properties - to make sure a task is marked as complete on not, i.e. "Date Completed" - "Status" and "Percent" properties. - -2000-09-08 Damon Chaplin <damon@helixcode.com> - - * gui/calendar-model.c (get_is_complete): use the status field rather - than the completed date, as it is more reliable. - (get_is_overdue): use get_is_complete(). - (calendar_model_mark_task_complete): check if it is already complete, - and if so don't update it. - - * cal-util/cal-component.c (cal_component_get_status): - (cal_component_set_status): added functions to support the STATUS - property. Also added the property to CalComponentPrivate and set it - to NULL in free_icalcomponent(). Someone should check my code as I've - mainly done a Cut & Paste job. - -2000-09-10 JP Rosevear <jpr@helixcode.com> - * conduits/todo/todo-conduit.c: Convert "//" style comments - (local_record_from_ical_uid): Remove iCalObject cruft - (ical_from_remote_record): ditto - (free_match): Properly unref the CalComponent - -2000-09-10 JP Rosevear <jpr@helixcode.com> - - * conduits/todo/todo-conduit.c (local_record_from_icalobject): Use - cal component pilot stuff properly - (find_record_in_repository): Remove cruft - (ical_from_remote_record): Remove cruft - (update_record): Set the vtype immediately after creation. Remove cruft - - * conduits/todo/todo-conduit.h: Remove iCalObject stuff - - * conduits/todo/todo-conduit-config.h: Move all the config stuff - here, I need to kill the warnings at some point - - * conduits/todo/todo-conduit-control-applet.c (doRevertSettings): - Set all the state variables correctly on a revert - (doSaveSettings): Update original state - (doHelp): Rename from about_cb - (main): Destroy configurations when done - - * conduits/todo/Makefile.am: Tidy - - * pcs/cal-backend-file.c (cbf_pilot_hash): Function for hashing - pilot ids - (cbf_pilot_equal): For hash table of pilot ids - (cal_backend_file_destroy): Destroy pilot id hash - (add_component): Insert the uid into the pilot hash - (remove_component): Remove the uid from the pilot hash - (cal_backend_file_load): Create the pilot hash - (cal_backend_file_create): ditto - (cal_backend_file_get_uid_by_pilot_id): Implement using the pilot hash - (cal_backend_file_update_pilot_id): ditto - - * cal-util/cal-component.h: Update prototypes - - * cal-util/cal-component.c (cal_component_get_pilot_id): Implement - using ical X properties - (cal_component_set_pilot_id): ditto - (cal_component_get_pilot_status): ditto - (cal_component_set_pilot_status): ditto - (cal_component_free_pilot_id): Free a pilot id - (cal_component_free_pilot_status): Free a pilot status - -2000-09-09 Ettore Perazzoli <ettore@helixcode.com> - - * gui/dialogs/Makefile.am (INCLUDES): Add - `-I$(top_builddir)/libical/src/libical' so that we get - `icalversion.h' from the build directory instead of taking it from - the installation directory, which is of course Wrong (tm). - * gui/Makefile.am (INCLUDES): Likewise. - -2000-09-08 Federico Mena Quintero <federico@helixcode.com> - - * gui/gnome-cal.c (cal_loaded_cb): New function with the - loading/creation state machine. It is carefully modelled after - the state machine that started the Universe, so bow before it. - (gnome_calendar_construct): Do not connect to cal_loaded here. - (connect_load): The closure for the cal_loaded callback is a bit - tricky, so provide a function to create it and connect to the - signal. - (disconnect_load): Disconnect from the signal and free the - closure. - (gnome_calendar_load_cb): Removed obsolete buggy function. - (gnome_calendar_open): Use the new mechanism. - - * gui/control-factory.c (set_prop): The default filename is now - calendar.ics. - -2000-09-08 JP Rosevear <jpr@helixcode.com> - - * conduits/calendar/calendar-conduit.c (transmit): Use - icaltime_as_timet - -2000-09-08 Christopher James Lahey <clahey@helixcode.com> - - * cal-util/cal-recur.c, gui/e-day-view.c, gui/e-week-view.c, - gui/event-editor.c, gui/getdate.y, gui/gncal-todo.c, - gui/gnome-cal.c, gui/dialogs/task-editor.c: Fixed some warnings. - -2000-09-08 JP Rosevear <jpr@helixcode.com> - - * conduits/calendar/Makefile.am: Tidy - - * conduits/todo/Makefile.am: Tidy - -2000-09-08 Federico Mena Quintero <federico@helixcode.com> - - Fall equinox cleanup! - - OK, I know the equinox is not here yet, but weather has changed - enough to warrant it. - - Sigh. This place is definitely not the tropics. - - * gui/gnome-cal.c (obj_updated_cb): Renamed from - gnome_calendar_object_updated_cb(); fixed prototype. - (obj_removed_cb): Renamed from gnome_calendar_object_removed_cb(); - fixed prototype. - (GnomeCalendarPrivate): Moved all the GnomeCalendar fields to a - private structure so I don't have to rebuild the whole calendar - GUI directory every time something changes in the object. - (GnomeCalendarPrivate): Removed the property bag and the control - fields; they are local to the control-factory now. - (gnome_calendar_update_view_buttons): Remove the - ignore_view_button_clicks mess and just block the signal. - (gnome_calendar_set_view): Added a "focus" argument to indicate - whether we want the main widget in the specified view to grab the - focus. - (gnome_calendar_set_view_internal): Handle the focus argument here. - (gnome_calendar_set_view_buttons): Temporary hack to notify the - calendar about its buttons. - (gnome_calendar_get_selected_time_range): New function. - (gnome_calendar_get_cal_client): New function. - - * gui/control-factory.c (calendar_properties_init): Keep the - property bag local to here; it does not need to be in the calendar - object yet. - (control_factory_fn): Renamed from control_factory(). Just use - control_factory_new_control(). - (control_factory_new_control): Moved the stuff over from - create_control(), and keep the control local to here. Check the - return value of bonobo_control_new(). - - * gui/calendar-commands.c (show_day_view_clicked): Remove the - ignore_view_button_clicks mess. - (new_calendar): Removed the useless "page" argument. - (calendar_control_activate): Use gnome_calendar_set_view_buttons() - for now. - -2000-09-07 Lauris Kaplinski <lauris@helixcode.com> - - * cal-client/Makefile.am: Added -lunicode - - * gui/dialogs/task-editor.c: More UTF-8 wrappers - (priority_index_to_value): Kill warning, add assertion - -2000-09-06 JP Rosevear <jpr@helixcode.com> - - * gui/e-day-view-main-item.c (e_day_view_main_item_draw_day_event): - Use new cal_component_has_recurrences convenience function - - * gui/e-week-view.c (e_week_view_show_popup_menu): ditto - - * gui/e-week-view-event-item.c (e_week_view_event_item_draw_icons): - ditto - - * gui/calendar-model.c (calendar_model_value_at): ditto - (calendar_model_value_at): ditto - - * gui/e-day-view.c (e_day_view_on_event_click): ditto - (e_day_view_on_event_right_click): ditto - (e_day_view_on_top_canvas_motion): ditto - (e_day_view_on_top_canvas_motion): ditto - (e_day_view_on_main_canvas_motion): ditto - (e_day_view_on_main_canvas_motion): ditto - (e_day_view_reshape_day_event): ditto - - * gui/e-day-view-top-item.c (e_day_view_top_item_draw_long_event): - ditto - - * gui/e-day-view.c (e_day_view_on_long_event_click): ditto - -2000-09-06 JP Rosevear <jpr@helixcode.com> - - * cal-util/cal-recur.c (cal_recur_generate_instances): Use - new convenience functions and only get the recurrence - stuff if needed. Free the recurrence stuff if used. - -2000-09-05 JP Rosevear <jpr@helixcode.com> - - * cal-util/cal-component.h: Add new prototypes - - * cal-util/cal-component.c (cal_component_has_exrules): Utility - function to determine whether a cal component has any exrules - (cal_component_has_exdates): Ditto for exdates - (cal_component_has_exceptions): Utility function to determine - whether a cal component has any exception rules - (cal_component_has_recurrences):Utility function to determine - whether a cal component has any recurrence rules - -2000-09-05 JP Rosevear <jpr@helixcode.com> - - * gui/event-editor.c (dialog_to_comp_object): Kill all exdates if - there are no dates in the box - - * cal-util/cal-recur.c (generate_instances_for_year): Add a special - case for when there are exceptions but no rrules or rdates. - (cal_obj_remove_exceptions): Use date only compare func - (cal_obj_date_only_compare_func): New compare function that - compares the date only, not the time. - - * gui/event-editor.c (dialog_to_comp_object): Need a break for the - yearly recurrence type - (dialog_to_comp_object): We need to allocate icaltimetypes for the - exdate list - (fill_widgets): Handle a weekly recurrence with no particular day set - (dialog_to_comp_object): Kill all rrules if "None" is selected as - the recurrence type by the user - -2000-09-06 Damon Chaplin <damon@helixcode.com> - - * gui/e-calendar-table.c (e_calendar_table_open_task): uses the new - TaskEditor dialog. - - * gui/dialogs/task-editor.[hc]: - * gui/dialogs/task-editor-dialog.glade: updated. Still need to fix the - 'Status' property (CalComponent doesn't support it yet), and use a - replacement for GnomeDateEdit, since we need to support setting 'None' - as the date. - -2000-09-04 Damon Chaplin <damon@helixcode.com> - - * gui/event-editor.c (obj_updated_cb): - (obj_removed_cb): compare the updated object's uid with the one we - are editing, and just return if it doesn't match. - -2000-09-01 Damon Chaplin <damon@helixcode.com> - - * gui/gnome-cal.c (gnome_calendar_tag_calendar): added check to see - if the client has loaded successfully. Gets rid of a few warnings. - -2000-09-05 JP Rosevear <jpr@helixcode.com> - - * cal-util/cal-recur.c (generate_instances_for_year): The exdate - and rdate lists are a list of icaltimetypes, not CalComponentPeriods - - * gui/e-day-view.c (e_day_view_on_delete_occurrence): The exdate list - is a list of icaltimetypes, not CalComponentDateTimes - -2000-09-05 JP Rosevear <jpr@helixcode.com> - - * gui/e-day-view.c (e_day_view_on_delete_occurrence): Append - the exdate to the list AFTER we create the date value. - -2000-09-05 JP Rosevear <jpr@helixcode.com> - - * cal-util/cal-component.c (cal_component_free_recur_list): Free - the data, not the list element. - -2000-09-05 JP Rosevear <jpr@helixcode.com> - - * cal-util/cal-recur.c (cal_recur_generate_instances): Compute - the event duration using the event start/end times, not the - interval times. - -2000-09-05 JP Rosevear <jpr@helixcode.com> - - * cal-util/cal-recur.c (cal_recur_from_icalrecurrencetype): Check - to see if r->enddate is (time_t)-1 and set to 0 if so - -2000-09-02 Ettore Perazzoli <ettore@helixcode.com> - - * conduits/calendar/Makefile.am (INCLUDES): Add libical include - directories and `$(BONOBO_GNOME_CFLAGS)'. - * conduits/todo/Makefile.am (INCLUDES): Likewise. - -2000-09-02 Lauris Kaplinski <lauris@helixcode.com> - - * gui/event-editor.c: e_utf8 wrappers - - * gui/gncal-todo.c: e_utf8_wrappers - -2000-09-02 Christopher James Lahey <clahey@helixcode.com> - - * conduits/calendar/calendar-conduit.c, - conduits/todo/todo-conduit.c, gui/e-week-view.c, gui/gnome-cal.c: - Fixed some warnings. - -2000-09-01 Federico Mena Quintero <federico@helixcode.com> - - * gui/gnome-cal.c (gnome_calendar_new): Use - gnome_calendar_construct() so that we can check for proper - creation of the client. - (gnome_calendar_destroy): Check that the client exists before we - unref it. - (gnome_calendar_construct): Do the CalClient creation here. Bind - the views to it here as well instead of in setup_widgets(). - (gnome_calendar_init): Call setup_widgets() here. - - * gui/e-calendar-table.c (e_calendar_table_destroy): Unref the - model. - -2000-09-01 JP Rosevear <jpr@helixcode.com> - - * conduits/todo/todo-conduit.c: Update for new libical. - Conduits should atleast compile now. - - * conduits/calendar/calendar-conduit.c: ditto - - * Makefile.am: Build the conduits only when they've been - enabled. - -2000-09-01 JP Rosevear <jpr@helixcode.com> - - * gui/event-editor.c: Make toolbar save and close button. - We should put a similar menu option in sometime. - -2000-08-31 JP Rosevear <jpr@helixcode.com> - - * cal-util/cal-recur.c (array_to_list): Use - ICAL_RECURRENCE_ARRAY_MAX instead of MAX_SHORT - -2000-08-31 JP Rosevear <jpr@helixcode.com> - - * gui/event-editor.c (file_delete_cb): Implement delete option - (dialog_to_comp_object): Set the weekday start value and use - local not UTC time - -2000-08-31 Federico Mena Quintero <federico@helixcode.com> - - * gui/event-editor.c (file_delete_cb): No need to spit a warning - if removal fails. - (event_editor_destroy): Free the exception clist data. Unref the - calendar client here. - (close_dialog): Just call gtk_object_destroy() on the event - editor; the destroy handler will free everything else. - - * cal-client/cal-client.c (cal_client_object_exists): Removed - function; this is not useful because we operate asynchronously. - - * gui/e-day-view.c (e_day_view_on_delete_appointment): No need to - spit a warning if removal fails. - - * gui/e-week-view.c (e_week_view_on_delete_appointment): Likewise. - - * gui/calendar-model.c (calendar_model_delete_task): Likewise. - -2000-08-31 JP Rosevear <jpr@helixcode.com> - - * gui/event-editor.c (file_delete_cb): Implement delete option - (recurrence_toggled): Make an ugly hack to get the recurrence - pages showing properly since we don't yet implement all of the - recurrence rule stuff. - - * cal-client/cal-client.c (cal_client_object_exists): New function - to see if an object exists and is obtainable from the backend - - * cal-client/cal-client.h: Add prototype - -2000-08-31 JP Rosevear <jpr@helixcode.com> - - * gui/gnome-cal.c (editor_closed_cb): Event editor destroyed - callback to do hash cleanup - (gnome_calendar_edit_object): Set event editor calendar client. - - * gui/event-editor.h: Add new prototype - - * gui/event-editor.c: Trash signal stuff. We will manipulate - the client directly. Make the toolbar save and menu save items - work identically. Add icons to the toolbar. - (save_event_object): Call cal_client_update_object - (close_dialog): Unref the client and disconnect signals - Actually destroy the event editor object. - (obj_updated_cb): New function. Doesn't really do anything - yet but it will inform the user the event has changed elsewhere - in the future. - (obj_removed_cb): ditto - (event_editor_set_cal_client): New function to set the calendar - client - - * gui/gnome-cal.c (gnome_calendar_new_appointment): Commit - the sequence to the cal component and use non UTC times. - -2000-08-30 Lauris Kaplinski <lauris@helixcode.com> - - * gui/print.c: Countless small changes for gnome-print 0.21+ - -2000-08-30 Damon Chaplin <damon@helixcode.com> - - * gui/e-day-view.[hc]: - * gui/e-day-view-main-item.c: - * gui/e-week-view.[hc]: - * gui/e-week-view-main-item.c: - * gui/calendar-commands.c: - * gui/gnome-cal.[hc]: switched to using new ECalendar widget, - and a few other fixes. - -2000-08-30 Federico Mena Quintero <federico@helixcode.com> - - * gui/gnome-cal.h (GnomeCal): Removed unused field event_editor. - - * gui/e-day-view.c (e_day_view_key_press): Oops, set the - dtstart/dtend on the component before adding it. - (e_day_view_on_editing_stopped): No need to check for an UID. - Update the summary properly. - -2000-08-30 JP Rosevear <jpr@helixcode.com> - - * gui/e-week-view.c: Make sure the is_utc flag is always - FALSE for icaltime_from_timet - (e_week_view_on_unrecur_appointment): Use icaltimetype struct - from the stack and make sure tzid is always NULL - (e_week_view_key_press): ditto - -2000-08-30 JP Rosevear <jpr@helixcode.com> - - * gui/e-day-view.c: Make sure the is_utc flag is always - FALSE for icaltime_from_timet - (e_day_view_on_unrecur_appointment): Use icaltimetype struct - from the stack and make sure tzid is always NULL - (e_day_view_finish_long_event_resize): ditto - (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 - -2000-08-30 JP Rosevear <jpr@helixcode.com> - - * cal-client/cal-client.c (add_instance): Actually add the - comp_instance struct to the instances list. We now appear - to able to keep events and todos between sessions. Yay! - -2000-08-29 Federico Mena Quintero <federico@helixcode.com> - - Now the views monitor the client by themselves; it does not make - sense to proxy all notifications through the GnomeCal. The - GnomeCal should just be a meta-widget that holds all the views. - - At some later point we'll want to decouple the views from the - GnomeCal so that they can be embedded anywhere; they should emit - signals to request appropriate actions from the toplevel GUI - instead of calling the GnomeCal directly. - - * gui/e-day-view.c (e_day_view_set_cal_client): New function; now - the day view monitors the client by itself. - (cal_loaded_cb): New callback; moved over from - e_day_view_update_all_events(). - (obj_updated_cb): New callback; moved over from - e_day_view_update_event(). - (obj_removed_cb): New callback; moved over from - e_day_view_remove_event(). - (e_day_view_update_all_events): Removed function. - (e_day_view_update_event): Removed function. - (e_day_view_remove_event): Removed function. - (*): Use the day_view->client directly instead of fetching it from - the GnomeCal. - (e_day_view_destroy): Unref the client. - (e_day_view_reload_events): Check if the client is loaded. - (e_day_view_key_press): Set the vtype of the new component. - - * gui/e-week-view.c (e_week_view_set_cal_client): New function. - (cal_loaded_cb): New callback. - (obj_updated_cb): New callback. - (obj_removed_cb): New callback. - (e_week_view_update_all_events): Removed function. - (e_week_view_update_event): Removed function. - (e_week_view_remove_event): Removed function. - (*): Use the week_view->client directly. - (e_week_view_destroy): Unref the client. - (e_week_view_reload_events): Check if the client is loaded. - - * gui/gnome-cal.c (setup_widgets): Set the cal_client on all the - views. - (gnome_calendar_update_all): Do not update the views, since now - they do it themselves. - (gnome_calendar_object_updated_cb): Likewise. - (gnome_calendar_object_removed_cb): Likewise. - (setup_widgets): Remove all to-do list cruft. - (gnome_calendar_colors_changed): Likewise. - (gnome_calendar_todo_properties_changed): Likewise. - - * gui/calendar-commands.h (todo_style_changed): Removed variable. - - * gui/gncal-todo.c: Removed old clist cruft; just left in the - temporary dialog box for now. - -2000-08-29 Dan Winship <danw@helixcode.com> - - * cal-client/client-test.c: - * cal-client/cal-client.c: - * conduits/todo/todo-conduit.h: - * conduits/calendar/calendar-conduit.h: remove USING_OAF checks. - -2000-08-29 JP Rosevear <jpr@helixcode.com> - - * gui/gnome-cal.c (gnome_calendar_edit_object): Use - event_editor_set_event_object - - * gui/event-editor.c (event_editor_set_event_object): Rename - from event_editor_set_ical_object - - * gui/event-editor.h: Update prototype - - * gui/e-week-view.c (e_week_view_on_new_appointment): - Call cal_component_commit_sequence after event changes. Default - to these being all day events. - -2000-08-29 JP Rosevear <jpr@helixcode.com> - - * gui/event-editor.c (dialog_to_comp_object): These are not UTC - times - -2000-08-28 Federico Mena Quintero <federico@helixcode.com> - - * cal-client/cal-client.c (cal_client_is_loaded): New function. - We need this from code that dynamically updates from a client and - could not have connected to the "cal_loaded" signal right after - the client was created. - - * gui/calendar-model.c (load_objects): Do not try to load the - objects if the client has not been loaded yet. - (cal_loaded_cb): Check the status value. - - * gui/calendar-model.h (CalendarModel): Declare the private - structure here so that gdb will give me love. - - * pcs/cal-factory.h (CalFactory): Likewise. - - * pcs/cal.h (Cal): Likewise. - - * cal-client/cal-listener.h (CalListener): Likewise. - - * cal-client/cal-client.h (CalClient): Likewise. - - * pcs/cal-backend.h (CalBackend): This no longer has a private - structure, so remove it. - - * cal-util/Makefile.am (libcal_util_la_SOURCES): Removed the - vCalendar and old iCalendar cruft. - (libcal_utilinclude_HEADERS): Likewise. - Removed the obsolete iCalendar test program. - -2000-08-28 JP Rosevear <jpr@helixcode.com> - - * cal-util/timeutil.h: We no longer need time_from_icaltimetype - as libical has the API for this - - * cal-util/timeutil.c: ditto - - * cal-util/cal-recur.c: Replace time_from_icaltimetype with - icaltime_as_timet - - * gui/calendar-model.c: ditto - - * gui/event-editor.c: ditto - - * gui/gnome-cal.c: ditto - -2000-08-28 Federico Mena Quintero <federico@helixcode.com> - - * pcs/cal-backend-file.c (remove_component): Remove the - icalcomponent from the toplevel calendar here. - (cal_backend_file_update_object): Do not remove it here. - (cal_backend_file_remove_object): Do not remove it here. - (add_component): Add the icalcomponent to the toplevel calendar if - asked to. - (cal_backend_file_update_object): Do not add it here. - -2000-08-28 JP Rosevear <jpr@helixcode.com> - - * gui/event-editor.c (dialog_to_comp_object): Initiliaze tzid to - null, only set recurrence rules and exception dates if there - are any - -2000-08-27 JP Rosevear <jpr@helixcode.com> - - * pcs/cal-backend-file.c (save): Write out the calendar object - (cal_backend_file_update_object): Remove/add the icalcomponent - from our master icalcomponent (the calendar) - (cal_backend_file_remove_object): Remove the icalcomponent - from our master icalcomponent - -2000-08-26 JP Rosevear <jpr@helixcode.com> - - * gui/Makefile.am: Remove gnorba stuff - - * gui/main.c: ditto - - * gui/component-factory.c: ditto - - * gui/control-factory.c: ditto - - * gui/*.gnorba: ditto - -2000-08-25 JP Rosevear <jpr@helixcode.com> - - * gui/e-calendar-table.c (e_calendar_table_init): Uncomment - debug code. - - * gui/calendar-model.c (set_complete): Set the completed - date to the current date - (calendar_model_set_value_at): Handle complete field - -2000-08-25 JP Rosevear <jpr@helixcode.com> - - * gui/calendar-model.c (get_is_complete): Don't attempt to - free this if its null - (calendar_model_duplicate_value): Implement for summary field - value - (calendar_model_initialize_value): Remove debug code - - * gui/e-calendar-table.c: Correct etable init xml - (create_column): Pass the id to e_table_header_add_column - rather than a hard coded one - (e_calendar_table_init): Make sure summary column isn't - added twice. Add an alarms column, else etable won't - work with columns who have an ID higher than that - -2000-08-24 JP Rosevear <jpr@helixcode.com> - - * gui/gncal-todo.c (ok_button): Properly append to list - - * gui/event-editor.c (dialog_to_comp_object): ditto - - * gui/e-day-view.c (e_day_view_on_new_appointment): The base - times are not UTC - - * gui/e-week-view.c (e_week_view_on_new_appointment): ditto - -2000-08-24 JP Rosevear <jpr@helixcode.com> - - * Update for libical 0.19 - -2000-08-24 Christopher James Lahey <clahey@helixcode.com> - - * gui/calendar-commands.c, gui/e-day-view.c, gui/e-week-view.c, - gui/event-editor.c, gui/gncal-todo.c, gui/gnome-cal.c, gui/prop.c: - Fixed some warnings. - -2000-08-24 JP Rosevear <jpr@helixcode.com> - - * gui/e-week-view.c (e_week_view_on_new_appointment): Do not alloc - the struct icaltimetype but point to one on the stack. More - importantly, set the date.tzid to NULL. - -2000-08-24 JP Rosevear <jpr@helixcode.com> - - * gui/gnome-cal.c (save_event_object_cb): Make signal - names saner - (released_event_object_cb): ditto - (gnome_calendar_edit_object): ditto - - * gui/event-editor.h: Make signal names saner - - * gui/event-editor.c (event_editor_class_init): Make signal - names saner now that we don't use ical object - (save_event_object): ditto with callback names - (file_save_cb): ditto - (tb_save_and_close_cb): ditto - (event_editor_set_ical_object): ditto - - * gui/e-day-view.c (e_day_view_update_event): Umm, - != CAL_COMPONENT_EVENT (I hope that wasn't me!) - -2000-08-24 Federico Mena Quintero <federico@helixcode.com> - - * gui/e-day-view.c (e_day_view_on_new_appointment): Do not alloc - the struct icaltimetype but point to one on the stack. More - importantly, set the date.tzid to NULL. - -2000-08-24 JP Rosevear <jpr@helixcode.com> - - * gui/event-editor-dialog.glade: Remove owner field - - * gui/event-editor.c (clear_widgets): Forget about owner field - (get_widgets): ditto - (fill_widgets): ditto - -2000-08-24 JP Rosevear <jpr@helixcode.com> - - * gui/calendar-model.c (calendar_model_initialize_value): Handle - summary field - (calendar_model_value_is_empty): ditto - (calendar_model_free_value): ditto - -2000-08-23 JP Rosevear <jpr@helixcode.com> - - * gui/event-editor-dialog.glade: Remove status bar - - * cal-util/cal-component.c (cal_component_set_rrule_list): Allow - a null list - (cal_component_set_rdate_list): Allow a null list - - * gui/e-day-view.c (e_day_view_on_new_appointment): Commit - the CalComponent sequence - -2000-08-23 Federico Mena Quintero <federico@helixcode.com> - - * gui/main.c: #include <e-util/e-cursors.h> - - * gui/e-day-view-time-item.c (e_day_view_time_item_draw): - Initialize time_min_x1 and hour_r to keep gcc happy. - - * gui/e-day-view.c (e_day_view_update_event_label): Warning fix. - (e_day_view_update_main_canvas_drag): Initialize start_row. - - * gui/e-week-view-event-item.c (e_week_view_event_item_draw): - Initialize time_y_small_min, icon_x. - - * Makefile.am (SUBDIRS): Re-enable the gui directory. - - * gui/prop.c (prop_store_alarm_default_values): Temporarily #if 0 - out. - -2000-08-23 JP Rosevear <jpr@helixcode.com> - - * gui/e-week-view.c (e_week_view_key_press): Set vtype of new - CalComponent - (e_week_view_on_new_appointment): ditto - - * gui/e-day-view.c (e_day_view_on_new_appointment): ditto - -2000-08-23 JP Rosevear <jpr@helixcode.com> - - * gui/e-day-view-time-item.c: Include gnome.h for gettext purposes - - * gui/gnome-cal.c: ditto - - * gui/prop.c: #if out some alarm stuff - -2000-08-23 Federico Mena Quintero <federico@helixcode.com> - - * gui/e-calendar-table.c (e_calendar_table_init): Updated - function. - (e_calendar_table_open_task): Updated function. - -2000-08-21 Federico Mena Quintero <federico@helixcode.com> - - * gui/calendar-model.c (calendar_model_duplicate_value): Updated - function. - (calendar_model_free_value): Updated function. - (calendar_model_initialize_value): Updated function. - (calendar_model_value_is_empty): Updated function. - (remove_object): Updated function. - (obj_updated_cb): Updated function. - (calendar_model_get_cal_client): Added inline docs. - (calendar_model_delete_task): Updated. - (calendar_model_mark_task_complete): Updated. - (calendar_model_get_cal_object): Updated. - -2000-08-21 Federico Mena Quintero <federico@helixcode.com> - - * gui/calendar-model.c (set_categories): New function. - (parse_time): Moved over from the old set_time_t(). This just - parses the time and leaves the warning dialog for the caller. - (set_datetime): New function. - (set_geo): Updated old function. - (set_percent): Updated old function. - (set_priority): Updated old function. - (set_summary): New function. - (set_url): New function. - (calendar_model_set_value_at): Updated function. - (calendar_model_is_cell_editable): Updated function. - (calendar_model_append_row): Updated. Added an ugly hack to - accomodate ETable's lack of a real API for adding new items. - Also, don't try to set columns that are not editable. - -2000-08-21 JP Rosevear <jpr@helixcode.com> - - * gui/e-week-view.c (e_week_view_reload_events): - Use CalObjType - - * gui/e-day-view.c (e_day_view_reload_events): ditto - -2000-08-21 JP Rosevear <jpr@helixcode.com> - - * gui/e-day-view-main-item.c (e_day_view_main_item_draw_day_event): - Use CalComponent instead of iCalObject. #if some alarm stuff - -2000-08-21 JP Rosevear <jpr@helixcode.com> - - * gui/e-day-view-top-item.c (e_day_view_top_draw_long_event): - Use CalComponent instead of iCalObject. #if some alarm stuff - -2000-08-21 JP Rosevear <jpr@helixcode.com> - - * gui/e-day-view.h: Update prototypes - - * gui/e-day-view.c (e_day_view_on_unrecur_appointment): - Remove commented out portions. - - * gui/e-week-view.c (e_week_view_on_unrecur_appointment): - Tidy. - -2000-08-21 JP Rosevear <jpr@helixcode.com> - - * gui/e-day-view.c - (e_day_view_update_event): Use CalComponent - instead of iCalObject. Work around not having a compare - dates routine for two CalComponents. - (e_day_view_reshape_long_event): Use CalComponent instead - of iCalObject, #if some alarm stuff - (e_day_view_reshape_day_event): ditto - (e_day_view_reload_events): Use revamped CalClient - (e_day_view_update_event_cb): Use CalComponent - instead of iCalObject - (e_day_view_foreach_event_with_uid): ditto - (e_day_view_remove_event_cb): ditto - (e_day_view_update_event_label): ditto - (e_day_view_find_event_from_uid): ditto - (e_day_view_on_event_click): ditto - (e_day_view_on_event_right_click): ditto - (e_day_view_on_new_appointment): ditto - (e_day_view_on_edit_appointment): ditto - (e_day_view_on_delete_occurrence): ditto - (e_day_view_on_delete_appointment): ditto - (e_day_view_on_unrecur_appointment): ditto - (e_day_view_on_top_canvas_motion): ditto - (e_day_view_on_main_canvas_motion): ditto - (e_day_view_finish_long_event_resize): ditto - (e_day_view_finish_resize): ditto - (e_day_view_free_event_array): ditto - (e_day_view_add_event): ditto - (e_day_view_key_press): ditto - (e_day_view_on_editing_stopped): ditto - (e_day_view_update_top_canvas_drag): ditto - (e_day_view_update_main_canvas_drag): ditto - (e_day_view_on_drag_data_get): ditto - (e_day_view_on_top_canvas_drag_data_received): ditto - (e_day_view_on_main_canvas_drag_data_received): ditto - -2000-08-20 JP Rosevear <jpr@helixcode.com> - - * gui/e-week-view-event-item.c (e_week_view_event_item_draw_icons): - Use CalComponent instead of iCalObject. #if some alarm stuff - -2000-08-20 JP Rosevear <jpr@helixcode.com> - - * gui/e-week-view.c (e_week_view_update_event): Use CalComponent - instead of iCalObject. Work around not having a compare - dates routine for two CalComponents. - (e_week_view_reload_events): Use revamped CalClient - (e_week_view_reshape_event_span): Use CalComponent instead - of iCalObject, #if some alarm stuff - (e_week_view_update_event_cb): Use CalComponent instead of - iCalObject - (e_week_view_foreach_event_with_uid): ditto - (e_week_view_remove_event_cb): ditto - (e_week_view_free_events): ditto - (e_week_view_add_event): ditto - (e_week_view_on_editing_stopped): ditto - (e_week_view_find_event_from_uid): ditto - (e_week_view_key_press): ditto - (e_week_view_show_popup_menu): ditto - (e_week_view_on_new_appointment): ditto - (e_week_view_on_edit_appointment): ditto - (e_week_view_on_delete_occurrence): ditto - (e_week_view_on_delete_appointment): ditto - (e_week_view_on_unrecur_appointment): ditto - - * gui/e-week-view.h: Update prototypes. - -2000-08-18 JP Rosevear <jpr@helixcode.com> - - * gui/event-editor.h: Update prototypes. - - * gui/event-editor.c: Need to come back here later to fix the - alarm stuff. The gui also needs to be completely redone to - support the fancier CalComponent settings (exrules, rdates, etc) - There are some warnings that I put in to mark some of these - spots - (event_editor_destroy): Use Calcomponent instead - of iCalObject - (make_title_from_comp): ditto - (clear_widgets): ditto - (fill_widgets): ditto - (classification_get): ditto - (dialog_to_comp_object): ditto - (save_ical_object): ditto - (close_dialog): ditto - (event_editor_set_ical_object): ditto - -2000-08-17 JP Rosevear <jpr@helixcode.com> - - * gui/gncal-todo.c (ok_button): Use CalComponent instead of - iCalObject - (cancel_button): ditto - (gncal_todo_edit): ditto - (add_todo): ditto - (edit_todo): ditto - (delete_todo): ditto - (insert_in_clist): ditto - (gncal_todo_update): ditto - - * gui/gncal-todo.h: Update prototypes - -2000-08-16 JP Rosevear <jpr@helixcode.com> - - Rework gnome-cal.c - alarms are a tad broken ATM so this - will need more cleaning later. - - * gui/gnome-cal.c (snooze): Use CalComponent instead of - iCalObject - (edit): ditto - (audio_notification): ditto - (display_notification_cb): Use CalComponent member of - alarm_notify_closure rather than iCalObject - (display_notification): ditto - (trigger_alarm_cb): ditto. Use CalComponent alarm types - (gnome_calendar_tag_calendar_cb): New - cal_client_generate_instances callback to - mark_gtk_calendar_day's - (gnome_calendar_tag_calendar): Use above callback - (save_ical_object_cb): Use CalComponent instead of - iCalObject - (gnome_calendar_edit_object): ditto - (gnome_calendar_new_appointment): ditto - -2000-08-15 JP Rosevear <jpr@helixcode.com> - - * gui/mark.c (mark_month_item_cb): Callback used to mark every - event in a month. - (mark_month_item): Use cal_client_generate_instances with - above callback - -2000-08-15 JP Rosevear <jpr@helixcode.com> - - * gui/print.c (print_month_small): Use - cal_client_get_objects_in_range - (print_day_details_cb): Callback used to create columns and fill - events into a day view. Code should be shared with e-day-view - in reality. Maybe need to go back to layout.[hc] a bit later - (print_day_details): Use cal_client_generate_instances with - above callback. Iterate over results to expand events to fit. - (print_day_summary_cb): Callback to build list of event info - for a day - (print_day_summary): Use cal_client_generate_instances with - above callback to generate the required event info for printing - (print_todo_details_cb): Callback used create list of todo info - (print_todo_details): Use cal_client_generate_instances with - above callback to generate required todo info for printing. - - * gui/layout.[hc]: No longer used. - -2000-08-12 Federico Mena Quintero <federico@helixcode.com> - - * gui/calendar-model.c (get_is_overdue): Finished implementing. - (calendar_model_value_at): Handle the color field. - -2000-08-11 Seth Alves <alves@hungry.com> - - * cal-util/cal-component.c (cal_component_get_pilot_id): - (cal_component_set_pilot_id): stubs for pilot id accessors - (cal_component_get_pilot_status): - (cal_component_set_pilot_status): stubs for pilot status accessors - - * conduits/calendar/calendar-conduit.c (transmit): start to - convert to cal-component interface - - * conduits/todo/todo-conduit.c (transmit): same - -2000-08-11 Federico Mena Quintero <federico@helixcode.com> - - * gui/calendar-model.c (get_geo): Generate a prettier string for - the geographical position. - (get_classification): New function. - (get_categories): New function. - (get_completed): New function. - (get_dtend): New function. - (get_dtstart): New function. - (get_due): New function. - (get_percent): New function. - (get_priority): New function. - (get_summary): New function. - (get_transparency): New function. - (get_url): New function. - (get_has_alarms): New function. - (get_has_recurrences): New function. - (get_is_complete): New function. - (get_is_overdue): New function. - - * cal-util/cal-component.c (scan_property): Handle the GEO - property. - (free_icalcomponent): Likewise. - (cal_component_get_geo): Likewise. - (cal_component_set_geo): Likewise. - (cal_component_free_geo): Likewise. - (cal_component_set_exdate_list): Removed incorrect assertion. - (cal_component_set_exrule_list): Removed incorrect assertion. - (cal_component_get_next_alarm): Oops, this had not been - implemented at all. - (cal_component_has_rdates): New function. - (cal_component_has_rrules): New function. - - * cal-util/cal-component.h (CalComponentField): Added the GEO - property. - -2000-08-11 Federico Mena Quintero <federico@helixcode.com> - - * cal-util/cal-component.c (scan_property): Handle the - PERCENT-COMPLETE property. - (free_icalcomponent): Likewise. - (cal_component_get_percent): Likewise. - (cal_component_set_percent): Likewise. - (cal_component_free_percent): Likewise. - (scan_property): Handle the PRIORITY property. - (free_icalcomponent): Likewise. - (cal_component_get_priority): Likewise. - (cal_component_set_priority): Likewise. - (cal_component_free_priority): Likewise. - - * cal-util/cal-component.h (CalComponentField): New enumeration - with the list of fields we support for ETable. - -2000-08-10 Dan Winship <danw@helixcode.com> - - * gui/component-factory.c (owner_set_cb): Update prototype. - -2000-08-10 Federico Mena Quintero <federico@helixcode.com> - - * gui/gnome-cal.c (gnome_calendar_new_appointment): New function. - Mostly moved over from calendar-commands.c:display_objedit(). - - * gui/calendar-commands.c (calendar_iterate): Removed. Wheee! - (display_objedit): Removed. - (new_appointment_cb): New function. Just call - gnome_calendar_new_appointment(). - (display_objedit_today): Removed. - (calendar_control_activate): Removed the "New appointment for - today" option, since it is pretty useless. - -2000-08-10 Federico Mena Quintero <federico@helixcode.com> - - * cal-client/cal-client.c (cal_client_generate_instances): There. - A pretty function to generate recurrence instances atomically so - that clients don't have to jump through hoops. Now we can get rid - of the ugly calendar_iterate() function. - -2000-08-09 Cody Russell <bratsche@gnome.org> - - * gui/calendar-commands.c: Make the toolbar honor the user's - gnomecc settings for detachable toolbars. - -2000-08-09 Federico Mena Quintero <federico@helixcode.com> - - * gui/alarm.c (pop_alarm): Oops, subtract the new alarm's trigger - time from the current time. - -2000-08-09 Christopher James Lahey <clahey@helixcode.com> - - * cal-client/cal-client.c: Fixed a warning. - -2000-08-09 Christopher James Lahey <clahey@helixcode.com> - - * cal-client/cal-client.c, gui/e-calendar-table.c, pcs/cal.c: - Fixed some warnings. - -2000-08-08 Federico Mena Quintero <federico@helixcode.com> - - * idl/evolution-calendar.idl (Cal): Added a get_objects_in_range() - method. Takes in a time range and the type of component we are - interested in; returns a list of UIDs. The idea is that - ocurrences get computed in the client; we can have multiple - recurrences in iCalendar and we cannot identify them trivially - across the wire. - (Cal): Removed the get_events_in_range() method. - - * pcs/cal-backend.c (cal_backend_free_uid_list): New function. - (cal_backend_get_objects_in_range): New function. - (cal_backend_get_events_in_range): Removed. - - * pcs/cal-backend-file.c (cal_backend_file_get_objects_in_range): - Implemented new method. - (cal_backend_file_get_events_in_range): Removed. - - * pcs/cal.c (Cal_get_events_in_range): Removed. - (uncorba_obj_type): New function. - (Cal_get_uids): Use uncorba_obj_type(). - (Cal_get_n_objects): Likewise. - (Cal_get_objects_in_range): Implemented new method. - - * cal-client/cal-client.c (cal_client_get_events_in_range): Removed. - (cal_client_get_objects_in_range): Implemented. - (corba_obj_type): New function. - (cal_client_get_n_objects): Use corba_obj_type(). - (cal_client_get_uids): Likewise. - -2000-08-07 Federico Mena Quintero <federico@helixcode.com> - - * cal-util/cal-component.c (cal_component_clone): New function. - (cal_component_get_icalcomponent): Ensure that the SEQUENCE - property does not need incrementing. - - * gui/dialogs/alarm-notify-dialog.c (alarm_notify_dialog): Use - CalComponent. Deal with an empty summary property. - -2000-08-07 Federico Mena Quintero <federico@helixcode.com> - - * cal-util/cal-component.c (cal_component_get_as_string): Doh, - libical owns the string's memory, so do not free it. - - * cal-client/client-test.c (create_client): Connect to the destroy - signal of the client here. - - * cal-client/test.ics: New test file, modified from Eric Busboom's - test file from RFC 2445. - -2000-08-05 Federico Mena Quintero <federico@helixcode.com> - - * cal-client/client-test.c (dump_component): This was gone for - some reason. - (main): Load a new test file. - -2000-08-04 Federico Mena Quintero <federico@helixcode.com> - - * cal-util/cal-component.c (cal_component_commit_sequence): New - function to commit changes to the SEQUENCE property. - (cal_component_get_as_string): Ensure that the sequence has been - committed. - - * cal-client/cal-client.c (cal_client_get_object): Use - CalComponent instead of the old iCalObject. - (cal_client_update_object): Use iCalObject. Commit the SEQUENCE - property before stringifying the object and piping it over to the - Wombat. - -2000-08-04 Seth Alves <alves@hungry.com> - - * conduits/todo/todo-conduit.c (conduit_get_gpilot_conduit): if - oaf isn't initialized by the time the conduit starts, start it - up. we do this because we need to start wombat with oaf, and - gpilotd doesn't currently start oaf. - -2000-08-04 Michael Meeks <michael@helixcode.com> - - * gui/calendar-commands.c (calendar_control_activate): unref. - -2000-08-02 Federico Mena Quintero <federico@helixcode.com> - - * pcs/cal-backend-file.c (cal_backend_file_get_uid_by_pilot_id): - Added stub for now. - (cal_backend_file_update_pilot_id): Likewise. - - * pcs/Makefile.am (libpcs_a_SOURCES): Removed cal-backend-imc.[ch] - from the list of sources. The idea is to move vCalendar importing - to the GUI as a convenience function. - -2000-08-02 Seth Alves <alves@hungry.com> - - * pcs/cal-backend-imc.c (cal_backend_imc_update_pilot_id): call - save (cbimc) after setting the pilot id and status. - -2000-08-02 Joe Shaw <joe@helixcode.com> - - * pcs/cal-backend-file.c (cal_backend_file_update_pilot_id): - Fixed a g_return_if_fail that had two parameters and thus - wouldn't build. - -2000-08-03 Damon Chaplin <damon@helixcode.com> - - * gui/calendar-model.c (calendar_model_append_row): updated to match - the new ETableModel append_row. This meant we could also get rid of - the row_being_added and idle_id hack. - -2000-08-02 Christopher James Lahey <clahey@helixcode.com> - - * gui/calendar-model.c: Emit "model_pre_change" signals as - appropriate. - -2000-08-02 Federico Mena Quintero <federico@helixcode.com> - - * pcs/cal-backend-file.[ch]: New files for the iCalendar file - backend. - - * pcs/Makefile.am (libpcs_a_SOURCES): Added cal-backend-file.[ch]. - - * cal-util/cal-component.c (cal_component_set_icalcomponent): - Return an operation success code for if we are passed a component - of a type we don't support. - -2000-07-31 Federico Mena Quintero <federico@helixcode.com> - - * cal-util/cal-recur.c (*): Use CalComponent and the new property - types instead of the old iCalObject stuff. - (cal_recur_generate_instances): Renamed from - cal_object_generate_events(). Ensure that the component has the - DTSTART property. - (generate_instances_for_year): Renamed from - cal_object_generate_events_for_year(). - (cal_obj_expand_recurrence): Made static. - (cal_recur_from_icalrecurrencetype): New function. We should - really convert this whole file to use struct icalrecurrencetype - instead. - (cal_recur_free): New function. - - * cal-util/cal-recur.h (CalRecurType): Renamed from CalObjRecurType. - (CalRecurrence): Renamed from CalObjRecurrence. - - * cal-util/timeutil.c (time_from_icaltimetype): New function. - - * cal-util/Makefile.am: Commented out the test-recur program. - -2000-08-01 Damon Chaplin <damon@helixcode.com> - - * Removed doc directory, since it is the old gnome-pim docs which - aren't used any more. - - * Makefile.am (SUBDIRS): removed doc. - -2000-07-26 Peter Williams <peterw@helixcode.com> - - * gui/calendar-model.c: compile fix for Solaris - (works under Linux, too; don't know about others) - - * this is a test of whether CVS merge does what I - think it will do. - -2000-07-26 Federico Mena Quintero <federico@helixcode.com> - - OK, it seems that we have all the interesting properties for - single-user calendars now. RFC 2445 can bite me. - - * cal-util/cal-component.c (scan_property): Handle the RRULE - property. Yay!. - (scan_recur): Likewise, yow! - (get_recur_list): Likewise, yeehaw! - (get_recur_list): Likewise, honk honk! - (set_recur_list): Likewise, booooga booooga! - (cal_component_get_rrule_list): Likewise, squeek squeek! - (cal_component_set_rrule_list): That's it, I ran out of sounds. - (cal_component_free_recur_list): Likewise. - (scan_property): Handle the EXRULE property. - (free_icalcomponent): Likewise. - (cal_component_get_exrule_list): Likewise. - (cal_component_set_exrule_list): Likewise. - (set_period_list): Oops, free the old properties as well as - removing them. - (set_text_list): Ditto. - (cal_component_set_exdate_list): Ditto. - - * cal-util/cal-component.c: Put all the functions used to free - returned values all together. - (cal_component_set_rdate_list): Oops, mark SEQUENCE property to be - incremented since the RFC requires it. - (scan_property): Handle the EXDATE property. - (scan_exdate): Likewise. - (free_icalcomponent): Likewise. - (cal_component_get_exdate_list): Likewise. - (cal_component_set_exdate_list): Likewise. - (cal_component_free_exdate_list): Likewise. - -2000-07-26 Jeffrey Stedfast <fejj@helixcode.com> - - * gui/Makefile.am: Fixed a typo - -2000-07-26 Jeffrey Stedfast <fejj@helixcode.com> - - * gui/Makefile.am: Added a few xpm files to the EXTRA DIST section - -2000-07-25 Federico Mena Quintero <federico@helixcode.com> - - * cal-util/cal-component.c (cal_component_free_period_list): New function. - (scan_property): Handle the RDATE property. - (scan_period): Likewise. - (free_icalcomponent): Likewise. - (get_period_list): Likewise. - (set_period_list): Likewise. - (cal_component_get_rdate_list): Likewise. - (cal_component_set_rdate_list): Likewise. - (scan_text): Simplify a bit since we only handle the ALTREP - parameter; there is no need to iterate over all parameters. - (scan_datetime): Simplify; just handle the TZID parameter. - (scan_summary): Simplify; just handle the ALTREP parameter. - (cal_component_get_as_string): New function. - - * idl/evolution-calendar.idl (CalObjType): Removed the TYPE_OTHER; - now we only expose the types of objects we know about. - - * cal-util/cal-util.h (CalObjType): Likewise. - - * cal-client/cal-client.c (cal_client_get_n_objects): Likewise. - (cal_client_get_uids): Likewise. - - * conduits/calendar/calendar-conduit.c (get_calendar_objects): Likewise. - (check_for_slow_setting): Likewise. - - * pcs/cal-backend-imc.c (count_objects): Likewise. - (build_uids_list): Likewise. - - * pcs/cal.c (Cal_get_uids): Likewise. - (Cal_get_n_objects): Likewise. - -2000-07-25 Damon Chaplin <damon@helixcode.com> - - * gui/e-calendar-table.[hc]: new ECalendarTable to show an ETable view - for Todo/Event items. - - * gui/task-assigned-to.xpm: - * gui/task-recurring.xpm: - * gui/task-assigned.xpm: - * gui/task.xpm: new pixmaps (all the same at present) to go in the - icon column of the ETable. - - * gui/event-editor.c: hid the silly 'Calendar' labels on the - GnomeDateEdits and hid the times when you select 'All day event'. - Also adjusted the time_t's so that when an all day event finishes on - say midnight 13th May, we show 12th May in the dialog, since it - implicitly includes all of that day up to midnight. - - * gui/dialogs/task-editor-dialog.glade: - * gui/dialogs/task-editor.[hc]: unfinished dialog to edit tasks. - - * gui/gncal-todo.c: temporary hack so that we can use the simple dialog - with our new ETable. - -2000-07-23 Damon Chaplin <damon@helixcode.com> - - * cal-util/calobj.h: added a few more fields. - - * cal-util/calobj.c (ical_object_create_from_vobject): check for a - NULL return from vObjectUStringZValue for URL property to avoid SEGV. - For some reason an empty 'URL:' property appears and causes trouble. - -2000-07-20 Ettore Perazzoli <ettore@helixcode.com> - - * gui/component-factory.c (factory_fn): Update for the new - `evolution_shell_component_new()' arg. - -2000-07-19 Federico Mena Quintero <federico@helixcode.com> - - * cal-util/cal-component.c (cal_component_alarm_set_trigger): - Finish filling the trigger. What a pain, again. - (cal_component_alarm_free_trigger): Implemented. - -2000-07-19 Fatih Demir <kabalak@gmx.net> - - * conduits/calendar/calendar-conduit-control-applet.desktop: - - * conduits/todo/todo-conduit-control-applet.desktop: - Added the Turkish desktop entries. - -2000-07-18 Federico Mena Quintero <federico@helixcode.com> - - * cal-util/cal-component.c (cal_component_alarm_free): Free the - icalcomponent if this is an unattached alarm. - (scan_alarm_property): Handle the TRIGGER property. - (cal_component_alarm_get_trigger): Ditto. Royal pain. - (cal_component_alarm_set_trigger): Ditto. Less pain. - -2000-07-17 Federico Mena Quintero <federico@helixcode.com> - - * cal-client/cal-client.c (cal_client_get_object): Fixed inline - docs. - (cal_client_new): Ditto. - (cal_client_get_n_objects): Added inline docs. - -2000-07-14 Federico Mena Quintero <federico@helixcode.com> - - * cal-util/cal-component.c (CalComponentAlarm): New internal - represntation for alarm components. We really don't map them to a - CalComponent because it is more convenient to handle them as - "child" structures. - (make_alarm): New function to create a CalComponentAlarm from an - icalcomponent representing a VALARM. - (scan_alarm_property): New function to scan a property from an - alarm component. We support ACTION. - (cal_component_get_first_alarm): New function to start an iterator - over the alarms in a calendar component. - (cal_component_alarm_get_action): New function. - (cal_component_alarm_set_action): New function. - -2000-07-13 Seth Alves <alves@hungry.com> - - * conduits/todo/todo-conduit.c: conduit based on the calendar conduit. - this conduit syncs a pilot's ToDoDB database to wombat's list of "todo" - events. - - * gui/gncal-todo.c (simple_todo_editor): set todo's priority control - based on value from ical object during edit. - -2000-07-12 Federico Mena Quintero <federico@helixcode.com> - - * gui/print.c: Revert Michael's GnomeFont patch until the - gnome-print API stabilizes. - -2000-07-12 Michael Meeks <michael@helixcode.com> - - * gui/print.c (titled_box, print_text, print_month_small), - (bound_text): GnomeFont update. - -2000-07-12 Seth Alves <alves@hungry.com> - - * conduits/calendar/calendar-conduit.c: fixed various problems - - * cal-client/Makefile.am: build a static version of the library - to link with the conduits - - * cal-util/Makefile.am: same - -2000-07-11 Federico Mena Quintero <federico@helixcode.com> - - * cal-util/cal-component.c (scan_property): Handle the COMPLETED - property. - (free_icalcomponent): Ditto. - (cal_component_get_completed): Ditto. - (cal_component_set_completed): Ditto. - (scan_property): Handle the TRANSPARENCY property. - (free_icalcomponent): Ditto. - (cal_component_get_transparency): Ditto. - (cal_component_set_transparency): Ditto. - (scan_property): Handle the URL property. - (free_icalcomponent): Ditto. - (cal_component_get_url): Ditto. - (cal_component_set_url): Ditto. - - * pcs/cal-factory.c (queue_load_create_job): Removed unneeded - check for the URI. - (load_fn): Be more paranoid about the URI and notify the listener - if we got passed a bad URI. Simplify the termination code a bit. - (create_fn): Likewise. - (queue_load_create_job): Be more paranoid about the URI. - -2000-07-10 Ettore Perazzoli <ettore@helixcode.com> - - * gui/Makefile.am: Remove pilot stuff for now. - - * Makefile.am (SUBDIRS): Remove `conduits'. - -2000-07-10 Dan Winship <danw@helixcode.com> - - * gui/Makefile.am (EXTRA_DIST): remove gnomecal.conduit - - * conduits/calendar/Makefile.am (EXTRA_DIST): We want - calendar.conduit.in, not calendar.conduit. - -2000-07-10 Seth Alves <alves@hungry.com> - - * gui/Makefile.am (SUBDIRS): - * conduits/calendar/Makefile.am: moved calendar-conduit stuff from - the gui directory to here. - - * Makefile.am (SUBDIRS): added conduits to SIBDIRS - -2000-07-08 Ettore Perazzoli <ettore@helixcode.com> - - * gui/calendar-commands.c (calendar_control_activate): Remove - "close calendar" command. - -2000-07-08 Anders Carlsson <andersca@gnu.org> - - * gui/e-week-view.c (e_week_view_on_button_press): Handle mouse wheel scrolling. - - * gui/e-day-view.c (e_day_view_on_time_canvas_button_press): New function to handle - mouse wheel scrolling. - (e_day_view_on_main_canvas_button_press): Handle mouse wheel scrolling. - -2000-07-07 Federico Mena Quintero <federico@helixcode.com> - - * cal-util/cal-component.c (scan_property): Handle the SEQUENCE - property. - (free_icalcomponent): Ditto. - (cal_component_get_sequence): Ditto. - (cal_component_set_sequence): Ditto. - (cal_component_free_sequence): Ditto. - (cal_component_set_last_modified): Removed incorrect assertion. - (CalComponentPrivate): New need_sequence_inc flag. The sequence - number must be incremented when certain properties change, so we - store a flag that says if we need to bump it when piping the - object over the wire. - (free_icalcomponent): Reset need_sequence_inc. - (cal_component_set_dtstart): Set need_sequence_inc. - (cal_component_set_dtend): Ditto. - (cal_component_set_due): Ditto. - -2000-07-06 Federico Mena Quintero <federico@helixcode.com> - - * cal-util/cal-component.c (scan_property): Handle the - LAST-MODIFIED property. - (free_icalcomponent): Ditto. - (cal_component_get_last_modified): Ditto. - (cal_component_set_last_modified): Ditto. - (get_icaltimetype): New function to get struct icaltimetype - values. - (cal_component_get_created): Use get_icaltimetype(). - (set_icaltimetype): New function to set struct icaltimetype - values. - (cal_component_set_created): Use set_icaltimetype(). - - * cal-util/cal-component.c (scan_property): Handle the CREATED - property. - (free_icalcomponent): Ditto. - (cal_component_free_icaltimetype): Ditto. - (cal_component_get_created): Ditto. - (cal_component_set_created): Ditto. - (cal_component_init): Do not create an UID here. - (ensure_mandatory_properties): New function to ensure that the - mandatory RFC properties are indeed in the component. If they are - not, we create them on the fly. - (cal_component_set_new_vtype): Use ensure_mandatory_properties(). - (cal_component_set_icalcomponent): Ditto. - (cal_component_get_uid): Return the UID in a parameter, not as a - function return value, for consistency's sake. - (scan_property): Handle the DTSTAMP property. - (free_icalcomponent): Ditto. - (cal_component_get_dtstamp): Ditto. - (cal_component_set_dtstamp): Ditto. - -2000-07-04 Damon Chaplin <damon@helixcode.com> - - * gui/gncal-todo.c (gncal_todo_update): Use &obj instead of &ico in - the call to cal_client_get_object(). The ToDo list should work now. - - * gui/event-editor-dialog.glade: set the toplevel GnomeApp to invisible - so it doesn't appear and then resize. - -2000-07-03 Federico Mena Quintero <federico@helixcode.com> - - * cal-util/cal-component.c (cal_component_get_summary): Use - CalComponentText instead of CalComponentPropSummary. Removed the - latter typedef. - (cal_component_set_summary): Likewise. - (scan_property): Handle the CLASSIFICATION property. - (cal_component_get_classification): Ditto. - (cal_component_set_classification): Ditto. - - * cal-util/cal-component.c (cal_component_free_text_list): Renamed - from cal_component_free_description_list(). We can share this - function since both comments and descriptions have the same form. - (scan_text): Ditto. - (get_text_list): New function. - (set_text_list): New function. - (cal_component_get_description_list): Use get_text_list(). - (cal_component_set_description_list): Use set_text_list(). - (cal_component_set_uid): Add sanity check. - (cal_component_get_summary): Ditto. - (cal_component_get_description_list): Ditto. - (cal_component_get_dtstart): Ditto. - (cal_component_get_dtend): Ditto. - (cal_component_get_due): Ditto. - (scan_property): Handle the COMMENT property. - (cal_component_get_comment_list): Ditto. - (cal_component_set_comment_list): Ditto. - -2000-07-02 Federico Mena Quintero <federico@helixcode.com> - - * cal-util/cal-component.c (scan_categories): Handle CATEGORIES. - This can appear multiple times, so we maintain a list. We - compress them later to a single property with multiple values. - (cal_component_get_categories_list): Ditto. - (cal_component_set_categories_list): Ditto. - (cal_component_free_categories_list): Ditto. - (free_icalcomponent): Properly free the mappings. - -2000-07-02 Federico Mena Quintero <federico@helixcode.com> - - * cal-util/cal-component.c (scan_datetime): Handle date/time and - timezone pairs. - (scan_property): Handle DTSTART and DTEND. - (cal_component_free_datetime): Ditto. - (get_datetime): Ditto. - (cal_component_get_dtstart): Ditto. - (set_datetime): Ditto. - (cal_component_set_dtstart): Ditto. - (cal_component_get_dtend): Ditto. - (cal_component_set_dtend): Ditto. - (scan_property): Handle DUE date. - (cal_component_get_due): Ditto. - (cal_component_set_due): Ditto. - -2000-07-01 Federico Mena Quintero <federico@helixcode.com> - - * cal-util/cal-component.c (cal_component_get_description_list): - Handle the DESCRIPTION property. There can be multiple - descriptions with parameters each, so we deal with a list instead - of a single structure. - (cal_component_set_description_list): Ditto. - (cal_component_free_description_list): Ditto. - (scan_property): Ditto. - (scan_description): Ditto. - -2000-06-30 Federico Mena Quintero <federico@helixcode.com> - - * cal-util/cal-component.c (cal_component_get_summary): To avoid - passing a million parameters to setters/getters for properties - that support parameters, we now pass client-side structures - instead. Here we use CalComponentPropSummary. - (cal_component_set_summary): Ditto. - -2000-06-29 Christopher James Lahey <clahey@helixcode.com> - - * gui/component-factory.c: Make calendar die when evolution quits. - -2000-06-30 Federico Mena Quintero <federico@helixcode.com> - - * cal-util/cal-component.c: Change of plans. We use an - icalcomponent from libical as our core representation so that we - can preserve extension fields and fields that we don't (yet) - support. CalComponent is just a wrapper with a nice API that - provides non-iterative, random access to the ical's fields. - (cal_component_destroy): Free the thing correctly. - (cal_component_get_vtype): Re-implement in terms of icalcomponent. - (cal_component_set_icalcomponent): New function to set the - CalComponent's data from an existing icalcomponent. - (cal_component_get_icalcomponent): New function. - (cal_component_set_new_vtype): New convenience function to create - an empty component. - (scan_icalcomponent): Core scanning function. - (scan_property): Another core scanning function. - (cal_component_get_uid): Use the property directly. - (cal_component_get_summary): Ditto. Handle the altrep parameter - as well. - (cal_component_set_summary): Ditto. Feel the pain, motherfucker. - It is ridiculous how much code this involves. - (scan_summary): Ditto. - -2000-06-29 Ettore Perazzoli <ettore@helixcode.com> - - * gui/component-factory.c (owner_set_cb): Get an - EvolutionShellClient instead of an Evolution_Shell to match the - changes in libeshell. - -2000-06-29 Federico Mena Quintero <federico@helixcode.com> - - * gui/Makefile.am: Do not link and include the pilot stuff for the - calendar component, just for the Pilot conduit. Commented out the - Pilot part so that Evolution can build. Sigh, we'll have to - modify gnome-pilot to use OAF. - -2000-06-29 Peter Williams <peterw@helixcode.com> - - * gui/Makefile.am (LINK_FLAGS): Make the calendar-pilot-sync - program conditional on HAVE_GNOME_PILOT, and add - GNOME_PILOT_CFLAGS, GNOME_PILOT_LIBS, and PISOCK_LIBS in the - appropriate places. - -2000-06-29 Seth Alves <alves@hungry.com> - - * pcs/cal.c (Cal_get_uid_by_pilot_id): - (Cal_update_pilot_id): - * pcs/cal-backend-imc.c (cal_backend_imc_update_pilot_id): - (cal_backend_imc_get_uid_by_pilot_id): - * pcs/cal-backend.c (cal_backend_get_uid_by_pilot_id): - (cal_backend_update_pilot_id): server code to service these: - - * gui/calendar-pilot-sync.c: updated to make use of cal-client. - also uses dirty bits on both sides to aid in syncing. - - * cal-client/cal-client.c (cal_client_get_uid_by_pilot_id): new - function -- ask the cal server to return uid given an object's - pilot id. - (cal_client_update_pilot_id): new function -- inform the - cal server of an objects pilot id and pilot dirty-flag. - -2000-06-28 Federico Mena Quintero <federico@helixcode.com> - - * cal-util/cal-component.[ch]: New files for the new iCalendar - component object. Today's properties: basic component type, UID, - SUMMARY. - - * cal-util/Makefile.am: Added cal-component.[ch] to the list of - sources. - -2000-06-27 Michael Meeks <michael@helixcode.com> - - * pcs/Makefile.am (INCLUDES): use BONOBO_VFS_GNOME_CFLAGS. - -2000-06-26 Christopher James Lahey <clahey@helixcode.com> - - * gui/calendar-model.c: Added an #ifdefed value_to_string handler - assignment. - -2000-06-26 Federico Mena Quintero <federico@helixcode.com> - - * gui/calendar-model.c (calendar_model_duplicate_value): - Implement. - (calendar_model_initialize_value): Implement. - (calendar_model_value_is_empty): Implement. - -2000-06-21 Damon Chaplin <damon@helixcode.com> - - * gui/e-day-view.c (e_day_view_reshape_long_event): set event before - using it! - (e_day_view_init): used new colors from tigert. - -2000-06-21 Christopher James Lahey <clahey@helixcode.com> - - * gui/e-day-view.c, gui/e-week-view.c: Remove the usage of the "x" - and "y" arguments. - -2000-06-21 Damon Chaplin <damon@helixcode.com> - - * gui/gnome-cal.c (gnome_calendar_direction): changed so it keeps the - selection range. It just moves it on one day/week etc. This makes - it very handy for the keyboard shortcut code. - - * gui/calendar-commands.c (calendar_control_activate): fixed bug - setting the radio button active. - - * gui/e-day-view.[hc]: added support for keyboard navigation and - selection of the time range. - -2000-06-20 Federico Mena Quintero <federico@helixcode.com> - - * gui/calendar-model.c (calendar_model_set_value_at): Implemented. - (calendar_model_is_cell_editable): Implemented. - - * cal-client/cal-client.c (cal_client_update_object): Take in an - iCalObject instead of a stringified version. - - * gui/gnome-cal.c (gnome_calendar_update_object): Removed. - (gnome_calendar_remove_object): Removed. - (save_ical_object_cb): Use the CalClient function. - - * gui/e-day-view.c (e_day_view_on_delete_occurrence): Likewise. - (e_day_view_on_unrecur_appointment): Likewise. - (e_day_view_finish_long_event_resize): Likewise. - (e_day_view_finish_resize): Likewise. - (e_day_view_key_press): Likewise. - (e_day_view_on_editing_stopped): Likewise. - (e_day_view_on_top_canvas_drag_data_received): Likewise. - (e_day_view_on_main_canvas_drag_data_received): Likewise. - (e_day_view_on_delete_appointment): Likewise. - - * gui/e-week-view.c (e_week_view_on_editing_stopped): Likewise. - (e_week_view_key_press): Likewise. - (e_week_view_on_delete_occurrence): Likewise. - (e_week_view_on_unrecur_appointment): Likewise. - (e_week_view_on_delete_appointment): Likewise. - - * gui/gncal-todo.c (ok_button): Likewise. - (delete_todo): Likewise. - -2000-06-19 Damon Chaplin <damon@helixcode.com> - - * gui/event-editor-dialog.glade: tidied up dialog a bit, adding - space etc. - - * gui/e-week-view.c (e_week_view_reshape_events): removed debug msg. - -2000-06-18 Ettore Perazzoli <ettore@helixcode.com> - - * cal-util/Makefile.am (INCLUDES): Include from - `$(top_builddir)/libical/src/libical' too. [For the generated - libical `icalversion.h' header.] - * cal-client/Makefile.am (INCLUDES): Likewise. - -2000-06-18 Damon Chaplin <damon@helixcode.com> - - * gui/e-day-view.c (e_day_view_on_top_canvas_drag_data_received): - fixed a DnD bug. - -2000-06-17 Dan Winship <danw@helixcode.com> - - * cal-client/Makefile.am (INCLUDES): Fix to not depend on - installed ical.h - -2000-06-17 Damon Chaplin <damon@helixcode.com> - - * gui/e-week-view.c: added little buttons which are shown when there - are more events than will fit in a day. Clicking on the button takes - the user to the 1-Day view and shows the full day. - - * gui/e-day-view.c: - * gui/e-week-view.c: set the "use_ellipsis" arg to TRUE for the EText - items so we get tooltips automatically. Though we may want to use our - own code to show tooltips so we can show the tips when the mouse is - around the edges of the event box, and we may want to show the start - and end times of the event in full. - - * gui/calendar-commands.c (calendar_control_activate): - * gui/gnome-cal.h: added view_toolbar_buttons[] so we can access the - radio buttons in the code easily. We need this if we want to jump to - another view programmatically. - -2000-06-16 Damon Chaplin <damon@helixcode.com> - - * gui/jump.xpm: new icon for the EWeekView to jump to the day. - - * gui/Makefile.am (EXTRA_DIST): added jump.xpm - -2000-06-16 Damon Chaplin <damon@helixcode.com> - - * gui/calendar-model.c (calendar_model_class_init): #ifdef'ed out - references to functions which don't exist yet, so evolution still - compiles. - -2000-06-16 Damon Chaplin <damon@helixcode.com> - - * cal-util/test-recur.c: updated. - - * cal-util/cal-recur.[hc]: mostly finished, though it depends on the - iCalObject struct being updated to support more of iCalendar. - -2000-06-16 Damon Chaplin <damon@helixcode.com> - - * pcs/.cvsignore: added icalendar-test. - -2000-06-15 Damon Chaplin <damon@helixcode.com> - - * cal-util/Makefile.am (test_recur_LDADD): use libical.a - -2000-06-15 Dan Winship <danw@helixcode.com> - - * cal-util/Makefile.am (noinst_PROGRAMS): merge the two separate - noinst_PROGRAMS declarations into one so automake accepts it. - (INCLUDES): include libical src dir so we don't depend on having - ical.h already installed - -2000-06-14 Federico Mena Quintero <federico@helixcode.com> - - * gui/calendar-model.c: GPtrArray cannot insert stuff in the - middle of the array (!), so use plain GArray everywhere. Sigh. - -2000-06-13 Federico Mena Quintero <federico@helixcode.com> - - * cal-client/cal-client.c (cal_client_get_object): Use vCalendar - again. - - * cal-util/calobj.c (ical_object_find_in_string): From Seth, make - it use vCalendar again. - -2000-06-13 Federico Mena Quintero <federico@helixcode.com> - - * gui/calendar-model.c (obj_updated_cb): Juggle some eggs in - asynchronous fashion. Finished implementing. - (obj_removed_cb): Implemented. This one needs no juggling. - (calendar_model_set_cal_client): Only load the objects if we have - a client. - (calendar_model_destroy): Disconnect from the client's signals. - - * gui/Makefile.am (evolution_calendar_SOURCES): Added - calendar-model.[ch] to the list of sources. - - * pcs/cal-backend-imc.c (cal_backend_imc_get_n_objects): Doh, - return the computed value. - -2000-06-13 Federico Mena Quintero <federico@helixcode.com> - - * gui/calendar-model.c (CalendarModelPrivate): Added the array of - objects and the hash table of UID->array index. - (calendar_model_row_count): Return the length directly from the - array instead of asking the Wombat. - (calendar_model_value_at): Implemented. - (calendar_model_new): Create an empty model. We provide a new - setter function now. - (calendar_model_construct): Removed function. - (calendar_model_set_cal_client): New function to set the calendar - client and object type at any time. This lets us reuse a calendar - model object. - - * cal-util/calobj.h (iCalObjectField): Just report whether the - object has alarms; not every single alarm. - -2000-06-13 Ettore Perazzoli <ettore@helixcode.com> - - * gui/Makefile.am (SHELL_OBJS): Removed. - (evolution_calendar_LDADD): Link with - `$(top_builddir)/shell/libeshell.a'. - -2000-06-09 Ettore Perazzoli <ettore@helixcode.com> - - * gui/component-factory.c (factory_fn): Pass NULL for the new args - @create_folder_fn and @remove_folder_fn. - (create_view): Updated to match the new - `EvolutionShellComponentCreateViewFn'. Return - `EVOLUTION_SHELL_COMPONENT_UNSUPPORTEDTYPE' if type is not - "calendar". - -2000-06-09 Federico Mena Quintero <federico@helixcode.com> - - * idl/evolution-calendar.idl (Cal): Added a get_n_objects() - method. - - * pcs/cal-backend.c (cal_backend_get_n_objects): New function. - - * pcs/cal-backend-imc.c (cal_backend_imc_get_n_objects): - Implemented. - - * pcs/cal.c (Cal_get_n_objects): Implemented. - - * cal-client/cal-client.c (cal_client_get_uids): Free the ev. - (cal_client_get_n_objects): Implemented. - - * cal-util/calobj.h (iCalObjectField): New enumeration to identify - the fields in an iCalObject. - -2000-06-08 Federico Mena Quintero <federico@helixcode.com> - - * gui/event-editor.c (event_editor_destroy): Free the private - structure. - -2000-06-08 Federico Mena Quintero <federico@helixcode.com> - - * cal-util/calobj.c (ical_object_to_vobject): Allow for NULL - summaries. - -2000-06-07 Federico Mena Quintero <federico@helixcode.com> - - * gui/event-editor.c (toolbar): Added missing tooltips. We still - need icons, though. - -2000-06-07 Seth Alves <alves@hungry.com> - - * cal-util/calobj.c (ical_object_find_in_string): put this back in, - it's still used in cal-backend-imc.c:cal_backend_imc_update_object - - * cal-client/cal-client.c (cal_client_get_object): instead of - returning a text representation, decode the text and return an - iCalObject. Also added CalClientGetStatus which indicates - success or type of failure. - - * cal-util/calobj.c (ical_object_find_in_string): #ifed out - ical_object_find_in_string since it is unused now. - - * cal-client/client-test.c (list_uids): track get_object change - * gui/calendar-commands.c (calendar_iterate): same - * gui/e-day-view.c (e_day_view_update_event): same - * gui/e-week-view.c (e_week_view_update_event): same - * gui/print.c (print_day_details): same - (print_day_summary): same - (print_todo_details): same - * gui/gnome-cal.c (trigger_alarm_cb): same - * gui/gncal-todo.c (gncal_todo_update): same - -2000-06-06 Seth Alves <alves@hungry.com> - - * cal-util/icalendar.c, icalendar-save.c: fixed a bunch of problems - * cal-util/calobj.c (ical_object_find_in_string): use libical - instead of libversit - (ical_object_to_string): same - (dump_icalobject): prints the contents of an icalobject for debugging - - * gui/Makefile.am (LINK_FLAGS): link libical.a instead of libical.la - so we don't have to modify the build system of the released libical - * cal-client/Makefile.am (client_test_LDADD): same - * cal-util/Makefile.am (icalendar_test_LDADD): same - -2000-06-06 Federico Mena Quintero <federico@helixcode.com> - - * cal-util/calobj.c (ical_object_destroy): Removed from the public - header; made static. Now everyone should use refcounting. - - * pcs/cal-backend-imc.c (free_ical_object): Use - ical_object_unref(). - (remove_object): Likewise. - -2000-06-02 Federico Mena Quintero <federico@helixcode.com> - - * gui/calendar-commands.c (print): New function to call the print - engine. - (calendar_toolbar): Added the Print button. - (calendar_control_activate): Added the File/Print item. - - * gui/e-day-view.c (e_day_view_get_selected_time_range): Allow - start_time and end_time to be NULL. - - * gui/e-week-view.c (e_week_view_get_selected_time_range): - Likewise. - - * gui/print.c (range_selector_new): Show the range selector - widgets. Use the correct radio group for all of them! - (print_calendar): Do the dialog box here. We may want to split - this function later into smaller chunks. - -2000-06-05 Damon Chaplin <damon@helixcode.com> - - * gui/e-week-view-event-item.c (e_week_view_event_item_button_press): - allow the right button to popup the menu, even when the event is - being edited. - - * gui/e-week-view.c: - * gui/e-day-view.c: Set the keyboard focus to the EDayView/EWeekView - when the right button is clicked, so that any event being edited is - saved before any action (e.g. opening the Event Editor dialog) is - started. Note that this won't work if we switch to asynchronous - notification. - -2000-06-02 Federico Mena Quintero <federico@helixcode.com> - - * gui/event-editor.c (tb_save_and_close_cb): Implemented. - (toolbar): Added an icon for the Save and Close command. - (save_ical_object): Recompute the title of the window here. Maybe - it would be better to do it when we actually get the - "object_changed" signal from the CalClient. - (file_close_cb): Implemented. - -2000-06-02 Federico Mena Quintero <federico@helixcode.com> - - * gui/gnome-cal.c (save_ical_object_cb): Implemented. - (gnome_calendar_add_object): Removed function, since it was - identical to gnome_calendar_update_object(). Modified the rest - of the code to use only the latter. - (gnome_calendar_remove_object): Be more paranoid about the UID. - (gnome_calendar_update_object): Ditto. Also, renamed this - function from gnome_calendar_object_changed(), for consistency - with the lower-level CalClient interface. - - * gui/event-editor.c (event_editor_class_init): New - "save_ical_object" signal to ask that our parent store the - calendar object to the backend. - (save_ical_object): New function to save the calendar object, - actually if just emits the signal. - (file_save_cb): Implemented. - (dialog_to_ical_object): We want priv-> - alarm_program_run_program_entry (i.e. the entry inside the - GnomeFileEntry), not the file entry itself. - (dialog_to_ical_object): Only insert the recurrence ending date if - the event is recurrent! - -2000-06-02 Christopher James Lahey <clahey@helixcode.com> - - * gui/Makefile.am: Fixed EXTRA_DIST. - -2000-06-01 Federico Mena Quintero <federico@helixcode.com> - - * gui/gnome-cal.c (editor_closed_cb): Handler for the - "editor_closed" signal of the event editor; we just destroy it - then. - - * gui/event-editor.c (app_delete_event_cb): Callback used when the - dialog is closed. Release the iCalObject here instead of the - event editor's destroy handler, and emit the new "editor_closed" - signal. - -2000-06-01 Federico Mena Quintero <federico@helixcode.com> - - * gui/event-editor-dialog.glade: Change of plans. The toplevel - GnomeApp is now generated with Glade instead of being created in - the program code. Otherwise we can't migrate the accelerators to - the new toplevel and they won't work. - - * gui/event-editor.[ch]: EventEditor now derives from GtkObject. - This lets us use the GnomeApp created by libglade and still have - signals and stuff. - - * gui/event-editor.c (create_menu): Tell the UI handler that the - menubar is the GnomeApp's existing one, not to create a new one. - (create_toolbar): Tell the UI handler to use the GnomeApp's - existing toolbar. - (event_editor_focus): New function to raise/focus an event editor. - - * gui/gnome-cal.c (gnome_calendar_edit_object): Use - event_editor_focus(). - -2000-06-01 Ettore Perazzoli <ettore@helixcode.com> - - * gui/calendar-commands.c (calendar_control_activate): Put the - toolbar into a frame to make it look like standard GNOME toolbars. - Also, set `GNOME_DOCK_ITEM_BEH_NEVER_VERTICAL' so that it does not - do evil things when its moved to the left or the right of the - window. - -2000-05-31 Federico Mena Quintero <federico@helixcode.com> - - * gui/gnome-cal.h (GnomeCalendar): Added a hash table to map - calendar objects to their respective event editors. - - * gui/gnome-cal.c (gnome_calendar_init): Create the - object_editor_hash. - (gnome_calendar_destroy): Free the object_editor_hash. - (gnome_calendar_edit_object): New function to centralize the - launching of event editors; if one already exists for a particular - calendar object, we just raise its window. - (edit): Use gnome_calendar_edit_object(). - - * gui/calendar-commands.c (display_objedit): Use - gnome_calendar_edit_object(). - (display_objedit_today): Likewise. - - * gui/e-day-view.c (e_day_view_on_new_appointment): Likewise. - (e_day_view_on_edit_appointment): Likewise. - - * gui/e-week-view.c (e_week_view_on_new_appointment): Likewise. - (e_week_view_on_edit_appointment): Likewise. - - * gui/event-editor.c (event_editor_new): Do not take in an - iCalObject; rather provide an event_editor_set_ical_object() - function. We need this because a single editor may be switched - between different calendar objects. Also, do not show the event - editor; leave it up to the client code. - (event_editor_construct): Likewise. - (clear_widgets): New function to clear the widgets to default - values. - (fill_widgets): New function to fill in the widgets from the - iCalObject. We don't do this in init_widgets() anymore. - (free_exception_clist_data): New function to free the exceptions - clist data. We were leaking the row data. - (init_widgets): Hook to the destroy signal of the exceptions - clist. - (event_editor_set_ical_object): New function. Now it also makes a - copy of the calendar object for the event editor; clients do not - need to copy it anymore. - (event_editor_destroy): Unref the UI handler as well. - (event_editor_class_init): New "ical_object_released" signal to - notify the parent that we are no longer editing the calendar - object. - (make_title_from_ico): Handle NULL objects. - - * gui/event-editor.h (EventEditor): Removed fields that are no - longer used. - -2000-05-31 Damon Chaplin <damon@helixcode.com> - - * cal-util/Makefile.am: added test-recur test program. - - * cal-util/test-recur.c: new file to test the recurrence code. - - * cal-util/.cvsignore: added test-recur. - - * cal-util/cal-recur.c: updated. - -2000-05-30 Federico Mena Quintero <federico@helixcode.com> - - * gui/event-editor.c (event_editor_construct): Create the UI - handler after we have constructed the parent GnomeApp. - (main_menu): Menu template is now in place. - (toolbar): Tollbar template is now in place. - (create_toolbar): Turn off labels in the toolbar since it sucks; - it should support non-homogeneous buttons with horizontal icons - and text. - -2000-05-29 Federico Mena Quintero <federico@helixcode.com> - - * gui/gnome-cal.c (gnome_calendar_object_changed): Removed the - flags argument, since now we just proxy the calendar object to the - calendar client. - - * gui/event-editor.c (alarm_unit_get): Moved over from - event-editor-utils.c. - - * gui/event-editor-utils.[ch]: Removed files, since the two - functions that were left there (i.e. the ones not present in - e-dialog-widgets) can simply be moved to event-editor.c. - - * gui/Makefile.am (evolution_calendar_SOURCES): Removed - event-editor-utils.[ch] from the list of sources. - -2000-05-27 Federico Mena Quintero <federico@helixcode.com> - - * gui/event-editor-utils.c: Moved many functions to - e-util/e-dialog-widgets.c. - -2000-05-25 Federico Mena Quintero <federico@helixcode.com> - - * gui/event-editor-dialog.glade: Put the main notebook directly - under a simple GtkWindow. We are going to pull out the notebook - and slap it into our custom-built GnomeApp, anwyays. - - * gui/event-editor.c: Made the EventEditor derive from GnomeApp. - Added a BonoboUIHandler for its menu and toolbar. - (make_title_from_ico): Create a nice title for the window. - (get_widgets): Fetch the Glade widgets here instead of all over - the place. - (event_editor_new): Temporary hack to show the dialog here, just - so that I can test it. - - * gui/Makefile.am (EXTRA_DIST): Added the Glade messages file. - -2000-05-25 Federico Mena Quintero <federico@helixcode.com> - - * gui/main.c (init_bonobo): Do not initialize libglade twice. - - * gui/component-factory.c (create_view): Set the folder_uri - property, otherwise the calendar will not get loaded into the - view. - -2000-05-25 Christopher James Lahey <clahey@helixcode.com> - - * gui/main.c: Make it so that warnings don't crash calendar. - -2000-05-25 Ettore Perazzoli <ettore@helixcode.com> - - * gui/evolution-calendar-control.c: Removed. - - * gui/main.c: New. - - * gui/control-factory.c: New. - * gui/control-factory.h: New. - - * gui/calendar-component-factory.c: New. - * gui/calendar-component-factory.c: New. - - * gui/evolution-calendar-control.c (calendar_control_factory): - Renamed from `calendar_factory'. - (calendar_control_factory_init): Renamed from - `calendar_factory_init'. - - * gui/Makefile.am: Link with the files from `$(builddir)/shell'. - - * gui/evolution-calendar.gnorba: New. - * gui/evolution-calendar.oafinfo: New. - -2000-05-24 Federico Mena Quintero <federico@helixcode.com> - - * gui/print.c (range_selector_new): New function to create the - custom range selector. - (print_dialog): New function to show the print dialog. - (print_calendar): Use the print dialog. - -2000-05-24 Christopher James Lahey <clahey@helixcode.com> - - * gui/Makefile.am: Added libepaned.a. - - * gui/gnome-cal.c: Switched from GtkPaned to EPaned. - -2000-05-22 Federico Mena Quintero <federico@helixcode.com> - - * gui/calendar-commands.c (calendar_get_events_in_range): Removed - function. - - * gui/mark.c (mark_month_item): Use - cal_client_get_events_in_range(). - - * gui/calendar-commands.c (show_year_view_clicked): Comment out, - since we don't have a year view. - - * gui/gnome-cal.c (setup_widgets): Removed the year view stuff. - (gnome_calendar_get_current_view_name): Likewise. - (gnome_calendar_update_view_times): Likewise. - (gnome_calendar_direction): Likewise. - (gnome_calendar_set_view): Likewise. - (gnome_calendar_update_all): Likewise. - (gnome_calendar_object_updated_cb): Likewise. - (gnome_calendar_object_removed_cb): Likewise. - (gnome_calendar_time_format_changed): Likewise. - (gnome_calendar_get_current_time_range): Likewise. - - * gui/gnome-cal.h (GnomeCalendar): Removed the year view stuff. - - * gui/Makefile.am (evolution_calendar_SOURCES): Added layout.[ch], - print.[ch]. Removed quick-view.[ch], year-view.[ch] since they - are no longer used. Removed all the old Pilot crap. - -2000-05-20 Damon Chaplin <damon@helixcode.com> - - * cal-util/cal-recur.[hc]: new files to implement iCalendar recurrence - rules. These are only part finished, but people may like to check that - the architecture seems OK. - -2000-05-17 Damon Chaplin <damon@helixcode.com> - - * gui/e-day-view.c (e_day_view_on_delete_occurrence): - * gui/e-week-view.c (e_week_view_on_delete_occurrence): use a copy of - the iCalObject so we detect the change in the "update_event" callback. - Maybe we should just update the view ourselves and then we wouldn't - need to detect any change in the callback. - - * cal-util/calobj.c (ical_object_reset_recurrence): new function to - get rid of any recurrence rules. Used when we 'unrecur' an event. - - * gui/e-day-view.c (e_day_view_key_press): don't add a new event if it - won't fit, or we end up adding a new event for each key press. - (e_day_view_update_event_label): don't update it if it doesn't have - an EText item (i.e. it isn't visible). - - * gui/e-day-view-time-item.c: allow selection of times using this - column. - -2000-05-19 Federico Mena Quintero <federico@helixcode.com> - - * cal-util/timeutil.c (time_add_minutes): Fixed warning message. - (time_add_day): Likewise. - (time_add_month): Likewise. - (time_add_year): Likewise. - (time_from_day): Of all functions, *this* one had to have a bug. - Set the tm.tm_isdst to -1 to specify that we don't know whether - the time is in DST or not. This fixes *many* bugs upstream. - (time_week_begin): Likewise. We never noticed this since the week - functions are never used. - (time_week_end): Likewise. - -2000-05-17 Seth Alves <alves@hungry.com> - - * gui/event-editor.c: hooked up more widget signals to callbacks - to the gladified dialog acts more like the original one. - -2000-05-16 Seth Alves <alves@hungry.com> - - * gui/event-editor.c (recurrence_toggled): hook the radio buttons - to the pages of the notebook. - (append_exception): - (recurrence_exception_added): - (recurrence_exception_deleted): - (recurrence_exception_changed): code to deal with the recurrence - exception list. - -2000-05-15 Seth Alves <alves@hungry.com> - - * gui/event-editor.[ch]: gladeified replacement for eventedit.c - - * gui/event-editor-utils.[ch]: utilities used by event-editor.c - - * gui/event-editor-dialog.glade: glade file used by event-editor.c - -2000-05-14 Federico Mena Quintero <federico@helixcode.com> - - * gui/gnome-cal.c (display_notification): Use the alarm - notification dialog. - (display_notification_cb): New callback for the result of the - alarm notification dialog. - - * gui/dialogs/alarm-notify.glade: New file with the alarm - notification dialog. - - * gui/dialogs/alarm-notify-dialog.[ch]: New file. - - * gui/dialogs/Makefile.am: New file. - - * gui/Makefile.am (SUBDIRS): Added the dialogs directory. - -2000-05-13 Federico Mena Quintero <federico@helixcode.com> - - * gui/gnome-cal.c (trigger_alarm_cb): Better error checking, and - plug leaks of str_ico and ico. - - * gui/evolution-calendar-control.c (main): Initialize libglade. - -2000-05-13 Ettore Perazzoli <ettore@helixcode.com> - - * pcs/Makefile.am (INCLUDES): Add - `-I$(top_builddir)/libical/src/libical'. - -2000-05-12 Federico Mena Quintero <federico@helixcode.com> - - * cal-util/calobj.c (generate): Use a (dtend - dtstart) offset to - compute the ending time of the occurrence. This takes care of - recurring events that span multiple days. Also, removed the DST - condition since it did not look right at all: if you have a daily - appointment at 18:00, it still should happen at 18:00 even during - daylight savings. - - * gui/gnome-cal.c (gnome_calendar_tag_calendar): Use the timeutil - functions instead of calculating the month's times by hand. Use - cal_obj_instance_list_free() instead of freeing the list by hand. - Clip the range we pass to mark_gtk_calendar_day(). - (mark_gtk_calendar_day): Fixed off-by-one error at the end of the - month by adding real day offsets. - -2000-05-11 Federico Mena Quintero <federico@helixcode.com> - - * gui/gnome-cal.c (add_alarms_for_object): New function to add - today's alarms for a single object. - (gnome_calendar_object_updated_cb): Update the object's alarms. - - * idl/evolution-calendar.idl (Cal): Added a - get_alarms_for_object() method. - - * pcs/cal.c (Cal_get_alarms_for_object): Implemented method. - - * pcs/cal-backend.c (cal_backend_get_alarms_for_object): New - function. - - * pcs/cal-backend-imc.c (cal_backend_imc_get_alarms_for_object): - Implemented. - - * cal-client/cal-client.c (cal_client_get_alarms_for_object): New - function. - -2000-05-11 Dan Winship <danw@helixcode.com> - - * gui/calendar-commands.c (calendar_control_activate): Now that we - depend on current gnome-libs we can make the toolbar detachable - again. - - * pcs/icalendar-save.c (timet_to_icaltime): remove unused timezone - variable to make this compile on BSD systems (where timezone is - the name of a function) - -2000-05-11 Federico Mena Quintero <federico@helixcode.com> - - * gui/gnome-cal.c (gnome_calendar_update_all): Removed unused - arguments. Load the initial alarms here. - (load_alarms): New function to load a day's worth of alarms. - (gnome_calendar_class_init): Eeeek! This was taking in an - incorrect argument type. - (gnome_calendar_init): Now the calendar keeps a hash table of - UIDs->queued alarms. Create the hash table here. - (gnome_calendar_destroy): Destroy the alarms hash table. - (gnome_calendar_object_updated_cb): Remove the alarms for the - object and regenerate them. - (gnome_calendar_object_removed_cb): Remove the alarms for the - object. - - * gui/alarm.c (alarm_add): Do not take in a CalendarAlarm, just - the trigger time, the callback and the closure data. Return an - opaque identifier for the alarm so that it can be removed by the - client code if needed. Use the queue_alarm() helper function. - (queue_alarm): Helper function to actually queue the alarm and set - up the itimer. Deal with a nonzero return value from - setitimer(). - (alarm_remove): New function to remove an alarm based on its ID. - (pop_alarm): New helper function; pops the first alarm of the - queue and resets the timer as appropriate. - (alarm_ready): Simplified a lot by using pop_alarm(). - - * idl/evolution-calendar.idl (Cal): Added get_alarms_in_range(). - - * pcs/cal.c (build_instance_seq): New function to build a CORBA - sequence from the internal list of instances. - (Cal_get_events_in_range): Use build_instance_seq(). - (Cal_get_alarms_in_range): Implemented new method. - - * pcs/cal-backend.c (cal_backend_get_alarms_in_range): New - function with the get_alarms_in_range() engine. - - * pcs/cal-backend-imc.c (cal_backend_imc_get_alarms_in_range): - Implemented the get_alarms_in_range() method. - - * cal-client/cal-client.c (cal_client_get_alarms_in_range): New - client-side function for getting the alarms. - (build_instance_list): New helper function to build the - CalObjInstance list from the CORBA sequence. - (cal_client_get_events_in_range): Use build_instance_list(). - - * gui/calendar-commands.h: #include <cal-util/calobj.h>. #include - "gnome-cal.h". - - * gui/e-week-view.c: #include "calendar-commands.h" instead of - main.h; the latter is an obsolete file and will be killed. - - * gui/evolution-calendar-control.c (main): Call init_bonobo() - before anything else. We need the GTK+ object system initialized. - - * gui/Makefile.am (evolution_calendar_SOURCES): Do not use main.h. - - * cal-util/cal-util.c (cal_alarm_instance_list_free): New function. - -2000-05-10 Matt Loper <matt@helixcode.com> - - * gui/calendar-commands.c (calendar_control_activate): Move - "about" menuitem to the help menu. - -2000-05-10 Christopher James Lahey <clahey@helixcode.com> - - * gui/Makefile.am: Added main.h. Combined the two EXTRA_DIST - sections. - -2000-05-09 Christopher James Lahey <clahey@helixcode.com> - - * pcs/cal-backend-imc.c: Set the format when creating a new - calendar. - -2000-05-09 Christopher James Lahey <clahey@helixcode.com> - - * pcs/cal-factory.c: Removed double free of method_string in - uri->method_string. - -2000-05-08 Ettore Perazzoli <ettore@helixcode.com> - - * pcs/cal.h: Include "calendar/pcs/evolution-calendar.h" instead - of "evolution-calendar.h". - - * pcs/cal-backend.h: Include "calendar/pcs/evolution-calendar.h" - instead of "evolution-calendar.h". - -2000-05-08 Seth Alves <alves@hungry.com> - - * gui/e-day-view.c (e_day_view_on_delete_appointment): call - e_day_view_stop_editing_event here to avoid a divide by zero - a bit further on. i'm not sure if this is the best fix for this. - -2000-05-08 Federico Mena Quintero <federico@helixcode.com> - - * pcs/cal-backend.h (CalBackendClass): CalBackendClass now is just - an interface for calendar backends; this is an abstract class. - Put in the vtable for the backend methods. - - * pcs/cal-backend.c (cal_backend_new): Removed function, since - CalBackend is not just an abstract class. - Removed implementation-specific functions and made public - functions call the virtual methods instead. - - * pcs/cal-backend-imc.[ch]: New files with the CalBackendIMC - implementation; this implements a backend for iCalendar and - vCalendar files. Moved the implementation-specific stuff from - cal-backend.[ch] to here. - - * pcs/cal-backend-imc.c (CalendarFormat): Moved enumeration to - here. Added a CAL_UNKNOWN value for when the backend is not - loaded yet. - (cal_backend_imc_init): Initialize priv->format as CAL_UNKNOWN. - (save_to_vcal): Use the same VCProdIdProp value as in - cal-util/calobj.c. Use "1.0" as the VCVersionProp as per the - vCalendar spec. - (ensure_uid): Return nothing, since the result value need not be - used anymore. - (add_object): Since we mark the calendar as dirty anyways, we do - not need to check the result value of ensure_uid() anymore. - (remove_object): Asssert that we know how to handle the object's - type. We do this in add_object() anyways. - - * pcs/Makefile.am (libpcs_a_SOURCES): Added cal-backend-imc.[ch]. - - * gui/gnome-cal.c: Replaced debugging printf()s with g_message() - so that we can see the line number where they occur. - - * gui/gnome-cal.c (gnome_calendar_load_cb): Sort of handle the - LOAD_METHOD_NOT_SUPPORTED result code, and added a default for the - switch. - - * cal-client/cal-listener.h (CalListenerLoadStatus): Removed - enumeration; it is stupid to translate all values for the - CalClient when it is going to translate them again. - (CalListenerClass::cal_loaded): This signal now passes the - LoadStatus directly from the CORBA side. - - * cal-client/cal-listener.c (Listener_cal_loaded): Do not - translate the status value. - - * cal-client/cal-client.h (CalClientLoadStatus): Added the - CAL_CLIENT_LOAD_METHOD_NOT_SUPPORTED error code. - - * cal-client/cal-client.c (cal_loaded_cb): Translate the CORBA - version of the LoadStatus result code. - - * pcs/cal-factory.c (CalFactoryPrivate): New methods field for the - hash table from method strings to the GtkTypes for backend class - types. - (cal_factory_init): Create the priv->methods hash table. - (cal_factory_destroy): Free the priv->methods hash table. - (cal_factory_register_method): New function to register a backend - class for a particular URI method. - (launch_backend_for_uri): New function to launch a backend for a - particular URI's method. - (load_backend): Use launch_backend_for_uri(). Move the error - notification code from load_fn() to here. - (create_backend): Use launch_backend_for_uri(). Move the error - notification code form create_fn() to here; it is #ifdefed out - since currently cal_backend_create() does not have any error - reporting capabilities. - - * idl/evolution-calendar.idl (Listener::LoadStatus): Added a - PROTOCOL_NOT_SUPPORTED error code. - - * pcs/cal-factory.c (cal_factory_load cal_factory_create): Removed - functions, since they were supposed to be internal only. - (CalFactory_load): Call queue_load_create_job() directly. - (CalFactory_create): Likewise. - -2000-05-08 Damon Chaplin <damon@helixcode.com> - - * gui/e-week-view.c (e_week_view_remove_event_cb): - * gui/e-day-view.c (e_day_view_remove_event_cb): don't set the ico->uid - to NULL or we won't find any other occurrences of the event. Set the - editing_event_day/num to -1 instead. - - * gui/e-week-view-event-item.c (e_week_view_event_item_draw): fixed the - positioning of the icons for long events. - - * cal-util/calobj.c (ical_object_normalize_summary): forgot to - terminate the string. - -2000-05-07 Damon Chaplin <damon@helixcode.com> - - * gui/e-day-view.c (e_day_view_on_main_canvas_drag_data_received): - (e_day_view_on_top_canvas_drag_data_received): show the EText item, - just in case it hasn't moved, otherwise it won't appear. - - * gui/e-day-view.h (E_DAY_VIEW_BAR_WIDTH): increased from 6 to 8 to - make it easier to drag an event. Also increased E_DAY_VIEW_GAP_WIDTH - since it must be >= the BAR_WIDTH. - -2000-05-07 Matt Loper <matt@helixcode.com> - - * gui/evolution-calendar-control.c (PROPERTY_CALENDAR_URI): - Changed to "folder_uri" from "calendar_uri". - (set_prop): The uri given to us is a directory, so we append a - filename onto the end before we use it. - -2000-05-06 Damon Chaplin <damon@helixcode.com> - - * cal-util/timeutil.c (time_day_begin): - (time_day_end): changed these so they just do a simple localtime(), - update the struct tm, then do a mktime(). I don't know why it used to - look at the tm_isdst flags etc. From a little test program I wrote - which steps through testing every hour for a year it wasn't working - correctly, and the new code does. - (time_add_day): also got rid of the stuff that looked at tm_isdst here. - My test program now works better. - -2000-05-06 Chris Toshok <toshok@helixcode.com> - * gui/.cvsignore: ignore evolution-calendar.pure - - * gui/Makefile.am: add support for building evolution-calendar.pure - -2000-05-06 Damon Chaplin <damon@helixcode.com> - - * gui/e-day-view.c: - * gui/e-week-view.c: finish editing event when user hits Return key. - (e_week_view_on_text_item_event): stop event signals after doing any - other calls, since otherwise it will also stop any other resulting - event signals. - - * gui/e-week-view-event-item.c (e_week_view_event_item_draw): don't - draw the start/end times while editing. - - * gui/eventedit.c: changed the Summary field to a GtkEntry, since we - now only want a single line of text. - - * cal-util/calobj.c (ical_object_normalize_summary): new function to - convert the summary field to a single line of text, by converting any - sequence of CR & LF characters to a single space. - (ical_object_create_from_vobject): call the above function. I think - all functions that load iCalObjects go through this. - (ical_new): called it here as well just in case. - -2000-05-06 Damon Chaplin <damon@helixcode.com> - - * gui/week-view.[hc]: removed. - -2000-05-06 Damon Chaplin <damon@helixcode.com> - - * gui/gncal-day-panel.[hc]: - * gui/gncal-day-view.[hc]: - * gui/gncal-full-day.[hc]: - * gui/gncal-week-view.[hc]: - * gui/layout.[hc]: - * gui/view-utils.[hc]: removed old calendar view files. - -2000-05-06 Damon Chaplin <damon@helixcode.com> - - * cal-util/calobj.[hc]: added guint ref_count to iCalObject struct, - and ical_object_ref/unref() functions. I've updated all the gui/ - stuff to use ref_counts but I haven't touched the pcs/ stuff. Maybe - just using ical_object_destroy() is OK there. - - * gui/gncal-todo.c: - * gui/calendar-commands.c: - * gui/eventedit.c: - * gui/e-week-view.c: - * gui/e-day-view.c: use refcounting for iCalObjects. - - * gui/e-day-view-main-item.c: - * gui/e-day-view-top-item.c: - * gui/e-day-view.c: try not to ever draw outside the event, even when - the event is very small. - -2000-05-05 Damon Chaplin <damon@helixcode.com> - - * gui/e-day-view.c: don't allow recurring events to be resized or - dragged, and don't show the resize/drag cursors. Actually it may be - better to let the user do the resize/drag and then ask them what they - want to do - change the single occurrence or the entire series. - - * gui/e-day-view-time-item.c (e_day_view_time_item_show_popup_menu): - use e_auto_kill_popup_menu_on_hide() to destroy the popup menu. - - * gui/popup-menu.c: include e-gui-utils.h - -2000-05-04 Damon Chaplin <damon@helixcode.com> - - * gui/e-day-view.c (e_day_view_foreach_event_with_uid): for the long - events pass E_DAY_VIEW_LONG_EVENT as the day. Fixes SEGV. - - * gui/calendar-commands.c: when we switch views, grab the focus. - - * gui/gnome-cal.c (gnome_calendar_tag_calendar): - (gnome_calendar_mark_gtk_calendar_day): changed this so it uses - cal_client_get_events_in_range(), and doesn't load any objects. - Also just return if it isn't visible. - - * gui/calendar-commands.c (calendar_get_events_in_range): call - g_list_sort() to sort the list rather than g_list_insert_sorted() for - each element. It is much more efficient. - Also changed it so that the co->ev_start/end fields are copied from - the CalObjInstance rather than the parameters to the function - (that is right, isn't it?) - Also freed the list elements, and finally the list. - (calendar_iterate): changed this to use cal_client_get_events_in_range - since that is more efficient than getting all the uids and then loading - and parsing all the events. - - * pcs/cal-backend.c (save): output the '... saved' message before - freeing the string! - - * gui/gncal-todo.c (gncal_todo_update): - * gui/e-week-view.c (e_week_view_update_event): - * gui/e-day-view.c (e_day_view_update_event): - * gui/calendar-commands.c (calendar_get_events_in_range): - (calendar_iterate): free obj_string after it is parsed. - -2000-05-02 Damon Chaplin <damon@helixcode.com> - - * gui/calendar-commands.c (calendar_control_activate): set the active - radio button here. Oops - it wasn't a Bonobo problem after all. - - * gui/popup-menu.c (popup_menu): added call to - e_auto_kill_popup_menu_on_hide() to destroy the menu. - - * gui/e-week-view.c (e_week_view_show_popup_menu): - * gui/e-day-view.c (e_day_view_on_event_right_click): ico->user_data - isn't useful any more, since the event editor keeps its own iCalObject. - So for now we make the menu commands available even when the event is - being edited in the event editor. - Also corrected misspellings of 'occurance' -> 'occurrence'. - - * gui/eventedit.c (event_editor_destroy): destroy the iCalObject. - The event editor now uses its own independent iCalObject. - - * gui/e-week-view.c (e_week_view_on_unrecur_appointment): - * gui/e-day-view.c (e_day_view_on_unrecur_appointment): create a new - uid for the new single instance. I'm not sure what we should do about - the creation/last modification times of the objects. - - * gui/e-week-view.c (e_week_view_on_edit_appointment): - * gui/e-day-view.c (e_day_view_on_edit_appointment): duplicate the - iCalObject before passing it to the event editor, since it will change - the fields. If we don't duplicate it we won't know what has changed - when we get the "update_event" callback. - - * gui/e-week-view.c (e_week_view_key_press): - * gui/e-day-view.c (e_day_view_key_press): set the created and last_mod - times of the new iCalObject. We may want to set the default alarm as - well. - - * cal-util/calobj.c (ical_gen_uid): made this function public so we - can generate new uids if necessary. - -2000-05-01 Damon Chaplin <damon@helixcode.com> - - * gui/gnome-cal.[hc] (gnome_calendar_get_current_time_range): new - function to get the currently seleted time range form the current view. - - * gui/calendar-commands.c (display_objedit): use the above function - to get the time for the new appointment. - - * gui/e-week-view.c: - * gui/e-day-view.c: use a shallow copy of the ico when we update the - times (when resizing/dragging). Otherwise we won't detect that the - time has changed in the "update_event" callback. - - Also added functions to get the currently selected time range. - -2000-04-30 Seth Alves <alves@hungry.com> - - * pcs/icalendar-save.c (icalcomponent_create_from_ical_object): set - attendee and contact address correctly. - - * pcs/cal-backend.c (icalendar_calendar_load): init priv->object_hash - when loading. - (cal_get_type_from_filename): if file extension is .ical, consider - the file an ical file. - -2000-05-01 Damon Chaplin <damon@helixcode.com> - - * cal-util/calobj.c (ical_object_compare_dates): new function to see - if the event dates have changed (including any recurrence rules). - It is used for optimization when we get the "object_changed" signal. - We have to do far less work if the dates are unchanged. - - * gui/e-week-view.c: - * gui/e-day-view.c: only draw the selection when we have the keyboard - focus, since the user expects to be able to type in a new event when - the selection is shown. Also keep the selection when we lose focus, - but just don't show it. - - Also quite a few changes to cope with the new client/server - architecture. - - * gui/e-day-view-top-item.c (e_day_view_top_item_draw): - * gui/e-day-view-main-item.c (e_day_view_main_item_draw): - * gui/e-week-view-main-item.c (e_week_view_main_item_draw_day): - only draw the selection if the widget has the keyboard focus. - - * gui/gnome-cal.c (mark_gtk_calendar_day): fixed so it works with - events longer than one day. And changed the code for updating events - in the new views. - -2000-04-27 Ettore Perazzoli <ettore@helixcode.com> - - * gui/evolution-calendar-control.c - (init_bonobo): OAFized. - - * gui/main.c (main): Initialize with OAF if `USING_OAF'. - - * gui/evolution-calendar-control.c: New #define - `CONTROL_FACTORY_ID', varying according to whether we are - `USING_OAF'. - (calendar_factory_init): Use `CONTROL_FACTORY_ID'. - - * gui/Makefile.am: Updated for OAF. - - * pcs/cal-factory.h: Explicitly #include - "calendar/pcs/evolution-calendar.h" instead of just - "evolution-calendar.h". - - * cal-client/cal-client.c (cal_client_construct) [USING_OAF]: Use - OAF. - - * cal-client/client-test.c (init_corba): New function, implemented - differently depending on `USING_OAF'. - -2000-04-27 <alves@hungry.com> - - * pcs/cal-backend.c (cal_backend_load): fix memory leak - (save_to_vcal): same - (save): same - (cal_backend_load): same - -2000-04-26 Christopher James Lahey <clahey@helixcode.com> - - * cal-util/.cvsignore: Replaced libcal-util.la with *.la - - * pcs/.cvsignore: Added *.la and *.lo. - -2000-04-25 Federico Mena Quintero <federico@helixcode.com> - - * pcs/cal-factory.c (backend_last_client_gone_cb): Renamed from - backend_destroy_cb. Now we use it for the "last_client_gone" - signal from the backend. Also, unref the backend to destroy it. - (add_backend): Connect to the "last_client_gone" signal of the - backend. - (cal_factory_get_n_backends): New function to query the number of - running backends. - - * pcs/cal-backend.c (cal_backend_class_init): Register the new - "last_client_gone" signal. It is emitted when the last Cal client - goes away. It is used to notify the factory when a backend may be - safely destroyed. - (cal_destroy_cb): Emit the "last_client_gone" signal when the last - client disconnects from the backend. - -2000-04-25 Seth Alves <alves@hungry.com> - - * gui/e-day-view.c (e_day_view_find_event_from_ico): compare - iCalObjects by their UIDs instead of by their pointers. - - * pcs/cal-backend.c (cal_backend_destroy): don't save on destroy. - -2000-04-25 Ettore Perazzoli <ettore@helixcode.com> - - * cal-client/Makefile.am: Add `$(datadir)/idl'. - - * pcs/Makefile.am (idl_flags): Add `$(datadir)/idl'. - (INCLUDES): Use `$(BONOBO_GNOME_CFLAGS)'. - -2000-04-25 Seth Alves <alves@hungry.com> - - * gui/gnome-cal.c (gnome_calendar_destroy): hook for widget - destroy -- used to unref the CalClient so wombat knows we are gone. - (gnome_calendar_class_init): added a class init for this widget. - - * gui/e-day-view.c (e_day_view_update_event): allow for null ico - - * gui/e-week-view.c (e_week_view_update_event): allow for null ico - -2000-04-24 Federico Mena Quintero <federico@helixcode.com> - - * cal-client/client-test.c (main): The path to the test calendar - changed when we moved stuff around. Users will have to tweak this - for their CVS setup, anyways. - (create_client): Create or load the calendar as appropriate. - (client_destroy_cb): Exit the main loop if both clients are gone. - (main): Connect to the "destroy" signal of the clients so that we - can terminate the test program. - -2000-04-24 Seth Alves <alves@hungry.com> - - * pcs/icalendar.c (parse_person): allow for null CN - (parse_person): allow for null sent_by - - * pcs/Makefile.am: build icalendar-test - - * pcs/icalendar-test.c: a test which loads an ical file and - converts it to our internal format, and then saves it back out. - -2000-04-24 Damon Chaplin <damon@helixcode.com> - - * gui/Makefile.am: added new source files and pixmaps, and removed - old source files, which can be deleted. - - * gui/e-week-view-titles-item.[hc]: - * gui/e-week-view-main-item.[hc]: - * gui/e-week-view-event-item.[hc]: - * gui/e-week-view.[hc]: new files implementing the week/month views. - - * gui/yearview.xpm: - * gui/monthview.xpm: - * gui/weekview.xpm: - * gui/workweekview.xpm: - * gui/dayview.xpm: new pixmaps for the toolbar buttons. These aren't - intended to be the final pixmaps. - - * gui/calendar-commands.c: added radio buttons to the toolbar to - switch between the calendar views, and moved the am_pm_flag here so we - can get rid of view-utils.c. - - * gui/gnome-cal.[hc]: made it a subclass of GtkVBox, rearranged the - widgets into 2 notebooks, and added the selection_start_time and - selection_end_time fields. - - * gui/goto.c: updated to use new selection time range. - - * gui/quick-view.c: added '#include <gtk/gtkwindow.h>' so it compiles. - - * gui/e-day-view.[hc]: changed the interface to support the new - selection time range, got rid of a few debugging messages and changed - a few bits. - -2000-04-21 Seth Alves <alves@hungry.com> - - * pcs/icalendar-save.c: start on code to do the opposite of - icalendar.c (convert from iCalObjects to libical's icalcomponents). - - * gui/calendar-commands.c (calendar_control_activate): moved - "About Calendar" into the View menu so it shows up. - -2000-04-20 Seth Alves <alves@hungry.com> - - * gui/gnome-cal.c (gnome_calendar_changed_cb): new function: callback - for listener's object updated signal. - (gnome_calendar_object_removed_cb): new function: callback for - listener's object removed signal. - (gnome_calendar_new): hook up listener's "obj_updated" and - "obj_removed" signals so if evolution is running twice, - they will both see changes right away. - (gnome_calendar_object_changed): don't call update_all, since - it will be called by the listener. - (gnome_calendar_remove_object): don't call update_all - (gnome_calendar_add_object): don't call update_all - - * gui/gncal-full-day.c (child_realize): create fullday's gcs - even if pixmap_bell has already been created. this was - causing crashes if the calendar was run twice. - -2000-04-19 Seth Alves <alves@hungry.com> - - * gui/eventedit.c (ee_rp_init_rule): changed the order around - a bit to avoid a Gtk-CRITICAL crash - - * gui/gncal-todo.c (gncal_todo_update): fixed code to populate - the todo clist - - * cal-client/cal-client.c (cal_client_get_uids): don't check - type against CALOBJ_TYPE_ANY since it will always match. - (cal_client_get_uids): same (re: CALOBJ_TYPE_ANY) - - * pcs/cal-backend.c (build_uids_list): same (re: CALOBJ_TYPE_ANY) - - * pcs/cal.c (Cal_get_uids): same (re: CALOBJ_TYPE_ANY) - - * pcs/cal-backend.c (remove_object): don't call save from here - because in all cases the caller of remove_object calls save - - * gui/calendar-commands.c (calendar_set_uri): calls gnome_calendar_open - instead of checking on disk and calling load or create. - - * gui/gnome-cal.c (gnome_calendar_object_changed): fixed to use - cal_client_update_object -- editing and dragging events works again - (gnome_calendar_open): collapsed gnome_calendar_load and - gnome_calendar_create into this function. added new type - GnomeCalendarOpenMode which has the value CALENDAR_OPEN or - CALENDAR_OPEN_OR_CREATE. - - * gui/evolution-calendar-control.c (calendar_properties_init): create - a property bag for this control - (set_prop): callback for property sets - (get_prop): callback for proprety gets - - * gui/calendar-commands.c (calendar_set_uri): new function, - called when the "calendar_uri" property is set on the calendar- - control's property bag. - -2000-04-18 Federico Mena Quintero <federico@helixcode.com> - - * cal-util/Makefile.am (INCLUDES): Fix include path. - -2000-04-16 Federico Mena Quintero <federico@helixcode.com> - - * pcs/cal-factory.h (CalFactoryClass): We have a new - "last_calendar_gone" signal that Wombat can use to terminate - itself properly. - - * pcs/cal-factory.c (cal_factory_class_init): Register the - "last_calendar_gone" signal. - (backend_destroy_cb): Emit the "last_calendar_gone" signal instead - of killing the factory. - - * pcs/Makefile.am: Added $(CORBA_GENERATED) to BUILT_SOURCES. - (INCLUDES): Make the log domain be "wombat-pcs". - -2000-04-17 Seth Alves <alves@hungry.com> - - * pcs/cal-backend.c (add_object): removed implicit save, since - we don't want to save as we load from disk. - (cal_backend_update_object): added a call to save, since it - isn't done by add_object now. - -2000-04-16 Federico Mena Quintero <federico@helixcode.com> - - * cal-util/Makefile.am: Renamed library from libcalutil to - libcal-util, to be consistent with libcal-client. Install header - files in $(includedir)/evolution/cal-util. - (INCLUDES): Add "cal-util" log domain for glib. - (libcal_clientincludedir): The header files are now installed in - $(includedir)/evolution/cal-client. - - * cal-util/cal-util.h: Fix includes. - - * cal-client/client-test.c: Fix includes. - - * pcs/Makefile.am: Create libpcs.a, not a shared library, because - it is for internal use by Wombat only. The header files should - not be installed, either. Removed all the old Tlacuache stuff. - - * gui/Makefile.am (EXTRA_DIST): We no longer distribute - gncal.desktop. - (evolution_calendar_INCLUDES): Add "calendar-gui" for the glib log - domain. - - * gui/*.[ch]: Fix cal-util and cal-client includes. - - * pcs/Makefile.am (INCLUDES): Added "pcs" log domain for glib. - - * pcs/*.[ch]: Fix cal-util includes. - -2000-04-11 Chris Toshok <toshok@helixcode.com> - - * pcs/icalendar.c (icaltime_to_timet): use HAVE_TIMEZONE to switch - between linux's timezone variable and *bsd's method of getting the - gmt offset. - -2000-04-10 Seth Alves <alves@hungry.com> - - * pcs/cal-backend.c (save_to_vcal): create and save an actual - vcalendar instead of a list of vcal objects. - -2000-04-10 Damon Chaplin <damon@helixcode.com> - - * gui/Makefile.am (INCLUDES): moved srcdir directories to the top so - we search headers in the evolution tree before installed headers. - (Otherwise when you do 'make install' lots of files in gui/ get - rebuilt, since they depend on the installed cal-client.h which has just - been updated.) - -2000-04-09 Seth Alves <alves@hungry.com> - - * gui/gnome-cal.c (gnome_calendar_load): catch cal_loaded signal - on the cal client. - (gnome_calendar_load_cb): callback for cal_loaded signal. moved - gnome_calendar_update_all from gnome_calendar_load to here. - - * gui/calendar-commands.c: minor cleanups - - * pcs/cal-backend.c (save_to_vcal): copied code from gnome-pim - to write vcal to a file - (save): filled it with more gnome-pim code - (add_object): call save () after changing - (remove_object): same - (cal_backend_create): same - (cal_backend_remove_object): same - -2000-04-08 Christopher James Lahey <clahey@helixcode.com> - - * gui/Makefile.am: Removed linking with libetable and libeminicard - since they weren't being used. - -2000-04-08 Seth Alves <alves@hungry.com> - - * gui/gnome-cal.c (gnome_calendar_create): new function: - friendly wrapper for cal_client_create_calendar - - * gui/calendar-commands.c (new_calendar): call gnome_calendar_create - if no filename is provided - - * gui/prop.c (properties): calendar is a frame - - * gui/calendar-commands.c (calendar_control_activate): sort out the - menus a bit, more of them show up now. - - * gui/Makefile.am: don't build library or test, just the bonobo control - - * gui/gncal-todo.c (simple_todo_editor): calendar is a frame instead - of a window, now. - - * gui/gnome-cal.c (gnome_calendar_new): same - - * gui/goto.c (goto_dialog): same - -2000-04-06 Seth Alves <alves@hungry.com> - - * gui/calendar-commands.c (calendar_control_activate): removed - uih from the argument list, added cal. use cal as user_data - in callbacks rather than the control. - (calendar_control_deactivate): removed uih from argument list - -2000-04-05 Seth Alves <alves@hungry.com> - - * gui/calendar-commands.c (setup_menu): removed - (setup_appbar): removed - (calendar_control_activate): new function -- does the work - that setup_appbar and setup_menu used to do. - (calendar_control_deactivate): undoes what calendar_control_activate - does by removing the toolbar items and menu items. - - * gui/Makefile.am: build test-calendar-widget and evolution-calendar, - common stuff is in a library - - * gui/gnome-cal.c (gnome_calendar_get_type): made the calendar widget - based on a gtk_frame rather than a gnome_app - - * gui/calendar-commands.c: split out some of main.c - - * gui/evolution-calendar-control.c: bonobo bung so evolution - can use the calendar widget - -2000-04-01 Matt Loper <matt@helixcode.com> - - * pcs/.cvsignore: Added *.lo. - -2000-03-30 Seth Alves <alves@hungry.com> - - * gui/main.c (calendar_get_events_in_range): - cal_client_get_events_in_range returns a list of CalObjInstance *, not - a list of (char *) uid. - - * Makefile.am (SUBDIRS): readded the gui directory - - * gui/main.c: temporarily added alarm_defaults back in, - since the calendar doesn't link without it - -2000-03-29 Matt Loper <matt@helixcode.com> - - * Makefile.am: remove the gui directory, which doesn't compile. - -2000-03-28 Matt Loper <matt@helixcode.com> - - * pcs/Makefile.am: create a libpcs.la library, for use in the - wombat. - -2000-03-28 Seth Alves <alves@hungry.com> - - * gui/Makefile.am (LINK_FLAGS): added libeutil.la and libetext.a - - * gui/main.c (calendar_iterate): switch from string_to_ical_object to - ical_object_find_in_string - (calendar_get_events_in_range): same - (session_save_state): commented out references - to gcal->client->filename - -2000-03-27 Federico Mena Quintero <federico@helixcode.com> - - * pcs/cal-backend.c (cal_backend_get_object): Use - ical_object_to_string(). - - * cal-util/calobj.c (ical_object_to_string): Moved over from - pcs/cal-backend.c (was string_from_ical_object). - (get_calendar_base_vobject): Likewise, moved over from - pcs/cal-backend.c. - - * cal-util/cal-util.c: Removed string_to_ical_object(); the - correct function is in calobj.[ch], called - ical_object_find_in_string(). Removed ical_object_to_string, - since we now implement it in calobj.c. - - * cal-util/calobj.c: Removed ical_object_new_from_string(); see - above. - - * idl/evolution-calendar.idl (CalObjInstance): Calendar object - instances now contain only the UID for the object, not the whole - string representation of the object. This allows clients to - implement caching of objects if they wish. - - * pcs/cal.c (Cal_get_events_in_range): Likewise. - - * pcs/cal-backend.c (build_event_list): Likewise. - - * cal-client/cal-client.c (cal_client_get_events_in_range): - Likewise. - - * cal-util/cal-util.h (CalObjInstance): Likewise. - - * cal-util/cal-util.c (cal_obj_instance_list_free): Likewise. - (cal_obj_uid_list_free): Assert that the UIDs in the list are not - NULL. - - * pcs/tlacuache.gnorba (repo_id): The calendar factory also - supports the Unknown interface. - -2000-03-17 Federico Mena Quintero <federico@helixcode.com> - - * gui/e-day-view.c: Fix includes. - (e_day_view_on_delete_occurance): Do not call save_default_calendar(). - (e_day_view_on_delete_appointment): Likewise. - (e_day_view_on_unrecur_appointment): Likewise. - (e_day_view_finish_long_event_resize): Likewise. - (e_day_view_finish_resize): Likewise. - (e_day_view_key_press): Likewise. - (e_day_view_on_editing_stopped): Likewise. - (e_day_view_on_top_canvas_drag_data_received): Likewise. - (e_day_view_on_main_canvas_drag_data_received): Likewise. - -2000-03-13 Damon Chaplin <damon@helixcode.com> - - * gui/e-day-view*.[hc]: new files for the Day/Work-Week views. - -2000-03-12 Federico Mena Quintero <federico@helixcode.com> - - * gui/main.c (gnome_calendar_locate): Removed function now that it - is no CORBA server in the GUI. - (save_default_calendar): Removed function. Now the personal - calendar server will take care of saving modified calendars when - appropriate. - (close_cmd): Do not call unregister_calendar_services(). - - * gui/eventedit.c (ee_ok): Do not save the calendar. - - * gui/gncal-day-panel.c (day_view_range_activated): Likewise. - - * gui/gncal-todo.c (ok_button): Likewise. - (delete_todo): Likewise. - - * gui/gncal-full-day.c (delete_occurance): Likewise. - (delete_appointment): Likewise. - (unrecur_appointment): Likewise. - (child_focus_out): Likewise. - (update_from_drag_info): Likewise. - - * gui/gnome-cal.c (gnome_calendar_new): Removed obsolete call to - create the CORBA server. - - * gui/gnome-cal.h (GnomeCalendar): Renamed `calc' field to - `client'. - - * cal-client/cal-client.h (CalClient): Removed filename and - corba_server fields. - -2000-03-10 Federico Mena Quintero <federico@helixcode.com> - - * gui/main.c (main): Do not pass the INIT_SERVER flag to - gnome_CORBA_init_with_popt_table(). Check for exceptions - properly. - (main): Initialize Bonobo. - (main): Call process_dates() to parse the dates from the command - line before we dump the events or the TODOs. - (main): Use bonobo_main() instead of gtk_main(). - - * cal-util/calobj.c (ical_new): Initialize the alarm types here. - Do not call default_alarm() anymore, since that is a GUI issue. - (default_alarm): Removed function. - (alarm_defaults): Removed defaults data. - - * pcs/tlacuache.c (calendar_notify): Removed stubs for - alarm_defaults, calendar_notify(), debug_alarms. - -2000-03-09 Federico Mena Quintero <federico@helixcode.com> - - * gui/Makefile.am: Removed the corba-cal stuff. Commented out the - Pilot conduit stuff for now. - - * gui/calendar.c: Random #ifdefs to make it build, although this - file is going away. - - * gui/Makefile.am: Removed referenes to calobj.[ch] and timeutil.[ch]. - - * gui/calendar-conduit.c: Fixup includes. - - * gui/calendar-conduit.h: Fixup includes. - -2000-03-09 Seth Alves <alves@hungry.com> - - * gui/gnome-cal.h: replaced "Calendar *cal" with "CalClient *calc" - in the GnomeCalendar struct. - - * gui/*.c: tracked change from Calendar * to CalClient - - * gui/main.c: moved alarm_defaults from here to cal-util/calobj.c - (calendar_get_events_in_range): pulled this out of calendar.c and - fixed it up to use cal-client stuff. i'm not sure where to put it yet. - - * gui/main.c (calendar_iterate): pulled this one out of calendar.c also - -2000-03-07 Federico Mena Quintero <federico@helixcode.com> - - * cal-client/Makefile.am: Removed cal-client-alarm.[ch] from the - list of sources. This was a miscommunication on our part. - -2000-03-05 Seth Alves <alves@hungry.com> - - * cal-client/cal-client-alarm.c: stubs for client side - access to alarm structures. this will probably change, - since i don't know what i'm doing. - - * cal-util/alarm-enums.h: enums for alarms needed by - both the client and the server - - * remaining source files in calendar/... have been moved - to calendar/gui. - - * gui/alarm.c: start to decouple the view from the model - in the alarm editing code - -2000-03-03 Seth Alves <alves@hungry.com> - - * cal-util/Makefile.am: new file -- things shared between - the client and server go in this directory - - * calobj.c calobj.h icalendar.c icalendar.h - timeutil.c timeutil.h cal-util.c cal-util.h where moved - backend stuff went into pcs. shared stuff went into - cal-util. - -2000-03-02 Federico Mena Quintero <federico@helixcode.com> - - At this point the calendar client and personal calendar server - files were moved to the idl/, cal-client/, and pcs/ directories. - - * idl/Makefile.am: New file. - - * cal-client/Makefile.am: New file. Moved the libcal-client stuff - from calendar/Makefile.am to here. - - * pcs/Makefile.am: New file. Moved the tlacuache stuff from - calendar/Makefile.am to here. - - * Makefile.am (SUBDIRS): Added the idl and cal-client directories. - - * calendar.h: Removed the references to cal-backend.h and its - stuff. This file is going away soon! - - * icalendar.c: #include <config.h>. Also, we don't need to - include cal-backend.h or gnome.h. - - * icalendar.h: Protect from multiple inclusions. - -2000-03-01 Federico Mena Quintero <federico@helixcode.com> - - * Makefile.am: Use the gnome-config flags for orbit-idl. - Create a libcal-client library with the calendar client object. - -2000-02-29 Federico Mena Quintero <federico@helixcode.com> - - * Makefile.am: Removed stale rule for the conduit. - -2000-02-21 Matt Loper <matt@helixcode.com> - - * .cvsignore: Added *.lo. - -2000-02-19 Matt Loper <matt@helixcode.com> - - * .cvsignore: Added tlacuache and tl-test. - -2000-02-18 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * Makefile.am (INCLUDES): Use BONOBO_VFS_GNOME_CFLAGS instead of - GNOMEUI_INCLUDES, as we use Bonobo and VFS. - -2000-02-17 Seth Alves <alves@hungry.com> - - * cal-backend.h: moved CalendarFormat type def here - - * cal-backend.c (cal_backend_load): if extension suggests - an ical file, attempt to load an iCal file. - (cal_get_type_from_filename): returns CAL_ICAL if file - extension is 'ics' or 'ifb', else returns CAL_VCAL - (icalendar_calendar_load): moved this here from - icalendar.c because it needs to call the static function - add_object. - -2000-02-17 Federico Mena Quintero <federico@helixcode.com> - - * cal-client.c (cal_client_remove_object): Implemented. - - * cal.c (cal_notify_remove): Implemented. - (Cal_remove_object): Implemented. - (cal_get_epv): Fill in the remove_object field in the epv. - - * cal-backend.c (cal_backend_remove_object): Implemented. - (notify_remove): New function to notify clients that an object was - removed. - -2000-02-16 Russell Steinthal <rms39@columbia.edu> - - * calobj.[ch], eventedit.c, main.c: Change iCalObject.organizer - from char* to iCalPerson* - - * calobj.[ch]: Change iCalObject.related from list of char* to - list of iCalRelation*; assorted related fixes - - * icalendar.c: interface between libical and the gnomecal - internal representation - -2000-02-11 Federico Mena Quintero <federico@helixcode.com> - - * cal-client.c (cal_client_update_object): Implemented. - - * cal.c (cal_notify_update): New function to notify the listener - about an updated object. - (Cal_update_object): Implemented. - (Cal_get_uids): set_release() the sequence to TRUE. - (Cal_get_events_in_range): Likewise. - - * cal-backend.c (remove_object): New function to remove objects - from a calendar backend. - (cal_backend_update_object): New public function to update an - object and notify clients about it. - - * evolution-calendar.idl (Cal): Added update_object() and - delete_object() methods. - (Listener): Removed the obj_changed method and renamed obj_added - to obj_updated. We now only have updated and removed notifiers. - - * cal-listener.[ch]: Removed the "changed" notification code. - Changed the "added" notification code to the "updated" - notification. - - * cal-client.c: Likewise. - - * tlacuache.c (create_cal_factory): Connect to "destroy" on the - factory and exit the main loop when the factory is destroyed. - - * cal-factory.c (backend_destroy_cb): New callback used when a - backend is destroyed. Removes the backend from the factory's hash - table and unrefs the factory if all backends go away. - (add_calendar_client): Free the environment. - - * cal.c (cal_new): Use bonobo_object_unref() if we fail to - initialize. - - * cal-listener.c (cal_listener_new): Likewise. - - * layout.c (layout_events): Plug li.partition memory leak. - -2000-02-10 Federico Mena Quintero <federico@helixcode.com> - - * cal-backend.c (cal_backend_add_cal): Connect to the Cal's - destroy signal. - (cal_backend_remove_cal): Killed function now that removal of Cal - objects is done in their destroy callback. - (cal_destroy_cb): New callback to remove a Cal from the backend's - list of clients. Also, the backend destroys itself when there are - no more clients connected to it. - (save): New placeholder function to save a backend. - (destroy): New function to destroy a backend's data. - (cal_backend_destroy): Save the calendar and destroy it. - - * cal.c (cal_destroy): Reset the priv->backend to NULL. - - * cal-factory.c (add_calendar_client): There is no need to call - cal_backend_remove_cal(); we can now just destroy the Cal object. - (create_fn): Make sure we always unref the URI. - (load_fn): Move the URI unref to the end of the function for - safety. - - * cal-factory.c (add_calendar_client): Unref the Cal only if - notification of the listener was unsuccessful. Otherwise, the - calendar user agent (Listener side) keeps the reference. - - * tl-test.c (list_uids): Free the calobj. - - * cal-client.c (cal_loaded_cb): Use bonobo_object_unref() to get - rid of the listener. - (load_or_create): Likewise. - (destroy_factory): New function to get rid of the factory. - (destroy_listener): New function to get rid of the listener. - (destroy_cal): New function to get rid of the calendar client - interface object. - (cal_client_destroy): Free all resources. - (cal_client_get_object): CORBA_free() the calobj string. Boy, I - love memprof. - - * cal-listener.c (cal_listener_destroy): Reset the priv->cal to - CORBA_OBJECT_NIL. - - * cal-backend.c (cal_backend_remove_cal): Do not unref the Cal, - since the calendar user agent owns it. - (cal_backend_add_cal): Do not ref the Cal, since the calendar user - agent owns it. - - * cal-factory.c (add_calendar_client): Use bonobo_object_unref() - to get rid of the calendar client interface object. - - * calobj.c (ical_object_create_from_vobject): Duplicate the - default "PUBLIC" string. - -2000-02-09 Federico Mena Quintero <federico@helixcode.com> - - * cal-factory.c (cal_factory_load): Added documentation comment. - (load_fn): Do not print a message if the backend could not be - loaded due to a non-fatal error. - (queue_load_create_job): Moved the stuff from cal_factory_load() - to here. Now this function serves to queue load or create - requests. - (cal_factory_load): Use queue_load_create_job(). - (cal_factory_create): Implemented; use queue_load_create_job(). - (create_fn): New job handler for creating new calendars. - (create_backend): New function to create a new backend with a new - calendar. - (add_backend): New helper function to add backends to the - factory's hash table. - (load_backend): Use add_backend() instead of adding the backend by - ourselves. - - * cal-client.c (load_or_create): Moved the functionality from - cal_client_load_calendar() to here, and added an option to create - a new calendar instead of loading an existing one. - (cal_client_load_calendar): Use load_or_create(). - (cal_client_create_calendar): Implemented. - - * cal-backend.c (cal_backend_create): Implemented. - - * evolution-calendar.idl (LoadStatus): Added an IN_USE error for - create requests. - - * cal-listener.h (CalListenerLoadStatus): Added CAL_LISTENER_LOAD_IN_USE. - - * cal-listener.c (Listener_cal_loaded): Convert the IN_USE error. - - * cal-client.h (CalClientLoadStatus): Added CAL_CLIENT_LOAD_IN_USE. - - * cal-client.c (cal_loaded_cb): Handle CAL_LISTENER_LOAD_IN_USE. - - * tl-test.c: New test program for the calendar client side; it - also exercises the server side by sending commands to it. - - * Makefile.am: Added the tl-test program. - - * tlacuache.gnorba: Updated. - - * tlacuache.c (create_cal_factory): Use the right GOAD id. - - * cal-client.c (cal_client_construct): Use the right GOAD id. - -2000-02-08 Federico Mena Quintero <federico@helixcode.com> - - * evolution-calendar.idl (Cal): Added get_uids() method to get a - list of UIDs based on object types. - - * cal-backend.c (cal_backend_get_uids): Implemented get_uids() in - the backend. - - * cal.c (Cal_get_uids): Implemented get_uids() method. - - * cal-client.c (cal_client_get_uids): Implemented client-side - function. - - * cal-util.c (cal_obj_instance_list_free): Doh. Free the list, - not the last link. - (cal_obj_uid_list_free): New function to free a list of UIDs. - - * GnomeCal.idl (Repository): Removed unused method - get_object_by_id_list(). This is just for cleanup purposes and to - remind me exactly of what needs to be moved over to - evolution-calendar.idl. - (Repository): Removed unused get_objects() method. - - * corba-cal.c (init_calendar_repo_class): Removed the unused - get_objects method. - - * calobj.h (CalObjFindStatus): New status value enumeration for - the find function. - - * calobj.c (ical_object_find_in_string): New function to parse a - complete calendar and find a calendar object in it. This should - be used instead ical_object_new_from_string() in the future. - - * evolution-calendar.idl (CalObjInstance): Added an uid field. - Now the idea is that whenever calendar object strings are passed - around, their UIDs are passed along with them so that the actual - object can be pulled from the whole VCAL object using its UID to - identify it. - - * cal-util.h (CalObjInstance): Added uid field. - - * cal-util.c (cal_obj_instance_list_free): Free the UIDs. - - * cal-backend.c (build_event_list): Store the object's UID in the - instance structure. - - * cal.c (Cal_get_events_in_range): Copy the UID field to the CORBA - structure. - - * cal-client.c (cal_client_get_events_in_range): Copy the UID - field from the CORBA structure. - - * main.c (gnome_cal_file_menu): Removed unfinished html-month stuff. - - * Makefile.am (gnomecal_SOURCES): Removed html-month.c. - - * gnome-cal.c: #include "alarm.h" - (mail_notify): Made static. - - * alarm.h: #include "calobj.h" - - * corba-cal-factory.h (init_corba_server): Fixed prototype. - - * quick-view.c (create_items_for_event): Made static. - - * gncal-todo.c (column_resized): Made static. - - * layout.c (find_index): Made static. - -2000-02-08 Federico Mena Quintero <federico@helixcode.com> - - * evolution-calendar.idl (CalObjInstance): New struct to wrap - instances of calendar objects for recurrencies and alarms. - (Cal::get_events_in_range): New method to get ocurring and - recurring events by time range. - - * cal-backend.c (cal_backend_get_events_in_range): New function to - get a list of event instances in a time range. - (string_from_ical_object): New internal function. - (cal_backend_get_object): Use string_from_ical_object() instead of - doing everything ourselves. - (cal_backend_get_events_in_range): New function to get a list of - the events that occur or recur in a specified time range. - - * cal-client.c (cal_client_get_events_in_range): Implemented - client-side function. - - * cal-util.h: - * cal-util.c: New files with utilities and types common to the - client and server parts. - (CalObjInstance): New structure to hold an instance of an actual - occurrence, recurrence, or alarm trigger of a calendar object. - (cal_obj_instance_list_free): New function to free a list of - calendar object instances. - - * cal.c (Cal_get_events_in_range): Implemented new method. - - * corba-cal.c (cal_repo_get_updated_objects): Free `str' with - free(), not g_free(), since calendar_get_as_vcal_string() uses - writeMemVObject(), which uses realloc(). Fixed in gnome-pim as - well. - -2000-02-04 Federico Mena Quintero <federico@helixcode.com> - - * cal-backend.c (get_calendar_base_vobject): New function to - create the base VObject for a calendar. - (cal_backend_get_object): Create the base calendar and add the - sought object to it, then stringify it. - - * evolution-calendar.idl (Listener::obj_added - Listener::obj_changed): Now these pass in just the UIDs, not the - complete objects. - - * cal-listener.c (Listener_obj_added): Changed to pass in the uid, - not the object. - (Listener_obj_changed): Likewise. - - * cal-client.h (CalClientClass): Made the obj_added and - obj_changed signals take in the UIDs, not the full objects. - - * cal-client.c (obj_added_cb): Likewise. - (obj_changed_cb): Likewise. - -2000-02-04 Federico Mena Quintero <federico@helixcode.com> - - * cal-backend.c (CalBackendPrivate): Renamed the event_hash field - to object_hash. Now we hash all the calendar's objects here based - on their UIDs. - (ensure_uid): New function to create UIDs for calendar objects - that don't have them. - (add_object): Ensure the object has an UID before inserting it in - the calendar. - (cal_backend_get_object): New function. - -2000-02-03 Federico Mena Quintero <federico@helixcode.com> - - * evolution-calendar.idl (Cal): Added the get_object() method. - - * cal-client.c (cal_client_get_object): New function to get a - calendar object by its UID. - - * cal.c (Cal_get_object): Implemented. - - * cal-backend.c (cal_backend_get_object): New unfinished backend - function. We need some reorganizing of how the calendar objects - are stored. - -2000-02-02 Federico Mena Quintero <federico@helixcode.com> - - * Makefile.am (gnomecal_SOURCES): Added the CORBA generated - sources. - -2000-02-01 Federico Mena Quintero <federico@helixcode.com> - - * cal-client.c (cal_loaded): Handle the cal_loaded signal from the - listener. Store the calendar client interface object, and emit - our own cal_loaded signal. - (cal_client_load_calendar): Connect to the listener's signals. - (cal_client_class_init): Added the "obj_added", "obj_removed", - öbj_changed" signals. - (obj_added_cb): Handle the signal from the listener. - (obj_removed_cb): Likewise. - (obj_changed_cb): Likewise. - -2000-01-30 Federico Mena Quintero <federico@helixcode.com> - - * Makefile.am (gnomecal_SOURCES): Added cal-client.[ch] and - cal-listener.[ch]. - -2000-01-30 Federico Mena Quintero <federico@helixcode.com> - - * evolution-calendar.idl: Changed the namespace from - GNOME::Calendar to Evolution::Calendar. - (Listener::LoadStatus): Fixed SUCESSS -> SUCCESS typo. And I - never noticed it in the implementation. Ain't M-/ grand? - - * Makefile.am: Changed ocurrences of gnome-calendar.idl to - evolution-calendar.idl. - - * *.[ch]: Changed GNOME_Calendar_foo identifiers to - Evolution_Calendar_foo. - -2000-01-25 Federico Mena Quintero <federico@helixcode.com> - - * cal-client.c cal-client.h: New files with the calendar client - object. - -2000-01-25 Federico Mena Quintero <federico@helixcode.com> - - * cal-factory.c (CalFactory_load): Check that the listener is not - nil and emit and exception if it is. - - * gnome-calendar.idl (CalFactory::load CalFactory::create): Now - these raise the NilListener exception. - - * tlacuache.c (calendar_notify): Error stub for alarms. - (alarm_defaults): Stub array. - (debug_alarms): Stub variable. - (main): Initialize gnome-vfs. - -2000-01-24 Federico Mena Quintero <federico@helixcode.com> - - * tlacuache.c: New main module for the Tlacuache personal calendar - server. - - * tlacuache.gnorba: New gnorba file for Tlacuache, the GNOME - personal calendar server. - - * Makefile.am: Added the stuff necessary to build Tlacuache. - - * cal.c (Cal_get_uri): Convert the URI to a string before - returning it. - - * cal-factory.c (CalFactory_create): Doh, this function is void. - - * job.c (job_add): Use g_idle_add(), not gtk_idle_add(). - -2000-01-24 Federico Mena Quintero <federico@helixcode.com> - - * cal-backend.c (cal_backend_remove_cal): New function to remove a - calendar client interface object from a backend. - (cal_backend_load): Convert the URI to string and use - Parse_MIME_FromFileName(). The conversion is not very smart, - though. - - * cal-factory.c (load_backend): Moved most of the error handling - upstream to load_fn(). - (load_fn): Handle failure in case the backend could not be loaded. - (cal_factory_destroy): Free the backends and the backend hash - table. - (add_calendar_client): Implemented. We create a Cal client - interface object and attach it to the backend, and we notify the - listener. - -2000-01-22 Federico Mena Quintero <federico@helixcode.com> - - * cal-factory.c (lookup_backend): Renamed from lookup_calendar(). - Also, return a backend instead of a Cal client object. - - * cal-backend.c (cal_backend_load): Take in a GnomeVFSURI, not a - string. - - * cal-listener.c (Listener_cal_loaded): Pass the load status to - the signal. - (cal_listener_destroy): Better error checking. - (cal_listener_new): Better error checking. - - * cal-listener.h (CalListenerLoadStatus): New enum for the load - status of a calendar. - (CalListenerClass): Added the status argument to the cal_loaded - signal. - - * gnome-calendar.idl (cal_loaded): Added a load status code. - - * cal-backend.h (CalBackendLoadStatus): Renamed from - CalBackendLoadResult. - -2000-01-18 Federico Mena Quintero <federico@helixcode.com> - - * cal-backend.c cal-backend.h: Moved the calendar backend here. - This is the actual calendar-handling object. - (load_from_vobject): Moved over from calendar.c. Modified to use - a CalBackend instead of the old Calendar structure. - (add_object): Likewise. - - * cal.c: Now the Cal object is just a calendar client interface - object; we use it as a "viewport" onto a CalBackend. This also - lets us do correct resource management. - - * cal-common.h: New file with common forward declarations; we - can't have circular dependencies between headers. - -2000-01-18 Federico Mena Quintero <federico@helixcode.com> - - * cal-factory.c (cal_factory_load): Queue a load job. - (load_fn): Load job handler. Lookup the calendar by URI, load it - if it is not loaded, or just report it to the new listener if it is. - - * job.c job.h: New files with a simple job queue manager. - - * gnome-calendar.idl (Listener::cal_loaded): Do not return the - whole calendar object string. The client will be able to query - the calendar for the events it needs. - - * cal-listener.c (Listener_cal_loaded): Ref the calendar GNOME - object. We unref it when the listener is destroyed. - -2000-01-17 Federico Mena Quintero <federico@helixcode.com> - - The files from the gncal directory of the gnome-pim module on CVS - were moved here, to evolution/calendar, in preparation for the - Evolution work. The calendar is being split into a model/view - architecture. The model is a personal calendar server (PAS): it - provides storage, notification, and event generation; the - views/controllers are the calendar user agents and things like - Pilot synchronizers. - -2000-01-11 Federico Mena Quintero <federico@helixcode.com> - - * cal.c: Removed the CORBA listener methods, adjusted for the new - IDL. - - * cal-listener.c (cal_listener_init): Create the private - structure. In it we hold a reference to the calendar the listener - is watching. - (cal_listener_destroy): Destroy the private structure and unref - the calendar. - (Listener_cal_loaded): Stuff the calendar into our private data. - (Listener_obj_added): Adjusted for new IDL. - (Listener_obj_removed): Likewise. - - * gnome-calendar.idl: New IDL for the personal calendar server. - - * cal.h cal.c: New files with the calendar object. - - * cal-listener.h cal-listener.c: New files with the calendar - listener object. - - * cal-factory.h cal-factory.c: New files with the calendar factory - object. - -2000-01-09 Eskil Heyn Olsen <deity@eskil.dk> - - * Makefile.am: Changes to remove todo capplet stuff from distro. - -2000-01-08 Vadim Strizhevsky <vadim@optonline.net> - - * calendar-conduit-control-applet.c: Added pilotID argument to - gpilotd_conduit_mgmt_new. - - -2000-01-05 Eskil Heyn Olsen <deity@eskil.dk> - - * GnomeCal.idl: Added an argument to get_number_of_objects, so you - can choose which state the object should have - (any/new/modified/...). Will also add one to choose type - (event/journal etc). - - * corba-cal.c (cal_repo_get_number_of_objects): Implemented the - new version of get_number_of_objects. - - * calendar-conduit.c (pre_sync): Calls various - gnome_pilot_conduit_standard_abs_set_num_yadayda to get progress bars. - -2000-01-04 Eskil Heyn Olsen <deity@eskil.dk> - - * calendar-conduit.c (start_calendar_server): Let's not call - g_error, but g_warning instead. - (pre_sync): Get record numbers info, total, new, deleted etc, and - tell gpilotd. - -1999-12-31 Eskil Heyn Olsen <deity@eskil.dk> - - * eventedit.c (ee_store_recur_end_to_ical): Adds 86400 secs (1 - day) to the date chooses by the user. This ensures the recurrence - also occurs on that date. - (ee_rp_init_ending_date): And subtracts 86400 secs when about to - redisplay the box. - - * calendar.h: Added an argument to calendar_new, to enable certain - features, such as initing alarms or nor. - - * calendar.c (calendar_new): Implemented support for the - CALENDAR_INIT_ALARMS option to calendar_new. - - * corba-cal.c (cal_repo_get_updated_objects): Added - CALENDAR_INIT_ALARMS to calendar_new calls. - - * main.c: Added CALENDAR_INIT_ALARMS to calendar_new calls. This - should probably be CALENDAR_INIT_NIL, but I'm not sure, guess - steintr should check it. - - * gnome-cal.c: Added CALENDAR_INIT_ALARMS to calendar_new calls. - - * calendar-pilot-sync.c: Added CALENDAR_INIT_NIL to calendar_new calls. - -1999-12-10 Russell Steinthal <rms39@columbia.edu> - - * eventedit.c (ee_create_ae): Fix sensitivity bug when used to - create default alarm box (widgets in that box should always be - sensitive, even if the enabled checkbutton is not set) - -1999-12-08 Eskil Heyn Olsen <deity@eskil.dk> - - * calendar-conduit-control-applet.c (setSettings): Capplets now - sets first_sync on enable, this should make the conduit copy old - entries from the pilot to gnomecal. - -1999-12-07 Eskil Heyn Olsen <deity@eskil.dk> - - * calendar-conduit.c (pre_sync): Check if local store is - empty. If, force slow sync. - - * GnomeCal.idl (GNOME): Added get_number_of_objects. - - * corba-cal.c (cal_repo_get_number_of_objects): implemented the - get_number_of_objects. - - * calendar-conduit-control-applet.c (setStateCfg): Fixed bug that - caused the capplet to always set the sync action to Disable upon start. - -1999-12-05 Eskil Heyn Olsen <deity@eskil.dk> - - * Makefile.am (Conduits_second_DATA): Also install .desktop files - for conduit capplets in the gnome/apps menu dir. - -1999-12-04 Eskil Heyn Olsen <deity@eskil.dk> - - * Makefile.am (EXTRA_DIST): Added .desktop files to EXTRA_DIST. - -1999-10-12 Clifford R. Conover <rusty@zootweb.com> - - * gncal-todo.c Todo List improvements. - - Cleaned up todo item highlighting, added support for highlighting - events due today, and events not due yet. Colors are configurable - on the Colors Tab of the properties window. - - Renamed Frame in Properties window to Colors rather then Month - Colors since we are now asking for Todo item colors. - - Added ability to display time until todo item is due in list, it - automatically selects the best denomination of time (up to weeks) - and down to seconds to display. This should be made configurable - in a future version. - - Changed Todo dialog to ask for time that event is due. This - allows more accurate tracking of then the item is due, before the - dialog was only asking for the date of the todo item. - -1999-12-03 Eskil Heyn Olsen <deity@eskil.dk> - - * calendar-conduit.c: undef DEBUG_CALCONDUT, suppresses debug output. - -1999-12-02 Russell Steinthal <rms39@columbia.edu> - - * alarm.c: Enhanced debug support: can be toggled on and off by - SIGUSR1, reports alarms which could not be added - - * gnome-cal.c, main.[ch], prop.c: Add snooze capability for audio - and display alarms. Snooze interval can be configured in the - Properties box. - -1999-11-30 Eskil Heyn Olsen <deity@eskil.dk> - - * calendar-conduit.c (compare): Fixed compare bug. Also neated up - some of the if's in set_status. - -1999-11-22 Russell Steinthal <rms39@columbia.edu> - - * Merged todo list coloring patch from stable - * Added myself to AUTHORS, about box (per Miguel) - -1999-11-22 Eskil Heyn Olsen <deity@eskil.dk> - - * calendar-conduit.c (pre_sync): Writes some warning - messages when pre_sync fails. - -1999-11-14 Eskil Heyn Olsen <deity@eskil.dk> - - * Makefile.am: Stupid misplaced endif cause gncal to depend on an - install gnome-pilot... fixed... sorry. - -1999-11-12 Eskil Heyn Olsen <deity@eskil.dk> - - * Makefile.am (extra_pilot_bins): Fixed the if then else problem, - using solution suggested by James Henstridge, appears to be caused - by a (by now fixed) bug in my automake. - -1999-11-12 Russell Steinthal <rms39@columbia.edu> - - * prop.c: Config code for timeout, make Alarms property page use a - vbox instead of an hbox so that the propbox stays a reasonable width. - - * gnome-cal.c, main.[ch]: Add timeout for audio alarms, code to load - from config file - - * eventedit.c: Give some static functions external linkage so they - can be used elsewhere (make_spin_button); add some prototypes to - appease gcc. - -1999-11-11 Russell Steinthal <rms39@columbia.edu> - - * calendar.c (calendar_day_change): Add call to - calendar_init_alarms() to schedule another day change alarm. - -1999-11-09 Eskil Heyn Olsen <deity@eskil.dk> - - * calendar-conduit.c: Enabled debug output. Sets a g_log_domain, - now version 0.8.5. Consistent use of GSList/GList. Implemented - compare, default uses one that compares the contents of a struct - Appointment, but also has #ifdeffed code that does a field level - comparison, not complete, but perhaps educational. - - * Makefile.am (#todo_conduit_control_applet_SOURCES): Fixed an - unwanted conditional on libcalendar_conduit_la_LDFLAGS - -1999-11-05 Eskil Heyn Olsen <deity@eskil.dk> - - * calendar-conduit-control-applet.c (readStateCfg): Commented the - code out, thus the capplet works again. - -1999-11-04 Eskil Olsen <deity@eskil.dk> - - * Makefile.am: Uses the PISOCK_LIBDIR, for people with odd install - dirs for their pilot-link. Also install a pretty icon for the - calendar-conduit. - - * calendar-conduit-control-applet.c: Modfied the - try/revert/ok/cancel scheme to be more intuitive, also uses a - GtkOptionMenu for the possible sync methods. - - * calendar-conduit-control-applet.desktop: use the nice icon... - - * calendar-conduit.c: Ack, had to define debug_alarms and - alarm_default, otherwise they are undefined. Is gncal code messy - or is this considered a way of configuring the cal engine ? - Implemented delete_all syncabs methods. - - * calendar-pilot-sync.c: also had to declare debug_alarms and - alarm_defaults, just as ugly. - -1999-11-02 Russell Steinthal <rms39@columbia.edu> - - * prop.c: Add new alarm page to properties box - - * prop.c, calobj.c, main.[ch] eventedit.c: New support for default - alarms, configurable in the properties box. - - * gnome-cal.c, prop.c, main.[ch]: add option to beep on Display - alarms - -1999-10-23 Russell Steinthal <rms39@columbia.edu> - - * calendar.c (calendar_new): Correctly initialize calendar_day_end - and calendar_day_begin *before* installing day-change alarm. - -1999-10-21 Russell Steinthal <rms39@columbia.edu> - - * alarm.c, main.c: Added alarm debugging code - - * main.c (open_ok): Show an error box if the user tries to open a - non-existent file; fixes bug #1818 - -1999-10-19 Russell Steinthal <rms39@columbia.edu> - - * gnome-cal.c (calendar_notify): Fix typos which were causing - invalid times in audio notification dialogs; fixes Bug #2561 - -1999-10-18 Russell Steinthal <rms39@columbia.edu> - - * gncal-day-panel.c (gncal_day_panel_new): Placed the various - elements of the day view in paned windows so that the user can - adjust the relative sizes of the daily schedule, monthly calendar, - and to-do list. - -1999-10-18 Martin Norbäck <norpan@bigfoot.com> - - * gncal.desktop: Added swedish translation - -1999-10-13 Eskil Olsen <deity@eskil.dk> - - * Makefile.am: Hopefully the fixes the much-hated - gnome-pilot dependency. - -1999-10-07 Eskil Olsen <deity@eskil.dk> - - * calendar.c (calendar_object_changed): moved the pilot_status = - MOD up, so even a CHANGE_SUMMARY will set the modified flag. - - * calendar-conduit.c: more _free calls, vamped the noise on output. - -1999-10-06 Eskil Olsen <deity@eskil.dk> - - * *conduit*[ch]: checks return values from gpilotd_init/connect. - - * calender.c (vcalendar_create_from_calendar): removed a set - of cleanVObject cleanStrTbl, since the freed memory that the - function returned. - -1999-09-27 Timur Bakeyev <mc@bat.ru> - - * timeutil.c (time_from_isodate): Use tm.gmtoff or timezone to get - correct offset from UTC, according to HAVE_TM_GMTOFF or HAVE_TIMEZONE. - See also 1999-07-19 Matt Martin <matt@abacusnet.net> - -1999-09-27 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * month-view.c (add_event): ditto - (mark_current_day): ditto - (month_view_set): ditto - - * goto.c (goto_dialog): ditto. - - * gnome-month-item.c (gnome_month_item_init): ditto. - - * gncal-day-panel.c (gncal_day_panel_new): ditto. - - * getdate.c (RelativeDate): ditto. - - * eventedit.c (set_all_day): ditto. - (ee_rp_init_rule): ditto. - - * calendar.c (vcalendar_create_from_calendar): ditto. - - * calendar-conduit.c (update_record): ditto. - - * calobj.c (ical_object_generate_events): Get rid of pointers to - values returned from localtime, as it uses a static buffer. - -1999-09-26 Eskil Olsen <deity@eskil.dk> - - * corba-cal.c: the g_free that was commented out since glib said - was a duplicate free, was supposed to be a free. - - * GnomeCal.idl/corba-cal.c: added a get_object_id_list and a - get_objects_by_id_list. Latter is not done. - - * calendar-conduit.c: rewrote the way the conduit iterates over - records. It no longers fetches all entries (since that didn't work - with more then 285 entries. It now fetches the id list, and gets - each record. (will be using get_objects_by_id_list to get records - in amounts of 10 or so later, to reduce amount of corba calls). - - * calendar-conduit.c: now sets alarm parameters when transferring - from gnomecal to pilot. - -1999-09-23 Eskil Olsen <deity@eskil.dk> - - * calendar-conduit.c: better merge of summary/description - when doing ical_from_remote (update_record), also handles - import from gnomecal to pilot better, and on both ways, repeat - events are much better now. - -1999-09-22 Eskil Olsen <deity@eskil.dk> - - * corba-cal.c: commented out a g_free that glib reported - as being a duplicate free. - * calendar-conduit.c: got gnomecal->pilot up and runnning. - -1999-02-06 Lauris Kaplinski <lauris@ariman.ee> - - * gncal.desktop: Added Estonian translations. - -1999-09-14 Federico Mena Quintero <federico@redhat.com> - - * gncal-full-day.c (child_popup_menu): Set the data pointers for - all the items. - -1999-09-14 Kjartan Maraas <kmaraas@online.no> - - * doc/C/gnomecal.sgml: Merge from gnome-pim-1-0. Synced with newest - user-guide. - -1999-09-01 Miguel de Icaza <miguel@gnu.org> - - * eventedit.c (ee_create_buttons): Make the OK button the default - button per Russell's suggestion. - -1999-08-30 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * calendar.c (calendar_object_changed): Modify the - object->last_mod field. - (calendar_add_object): Ditto. - - Closes bug #676 - - * main.c (save_calendar_cmd): Fix problem in which we warned the - user about the calendar being modified the first time the calendar - was used. - -1999-08-22 Tomas Ogren <stric@ing.umu.se> - - * gnomecal.gnorba: "GenericFactoy" is wrong... - -1999-08-15 Miguel de Icaza <miguel@gnu.org> - - * calobj.c (ical_gen_uid): Fix the hostname part. - -1999-08-07 Peter Teichman <pat4@acpub.duke.edu> - - * calendar-pilot-sync.c (sync_pilot): sync correctly for objects - created on the pilot, but not dirty (because they have been synced - with some other program in the past) - -1999-07-30 Miguel de Icaza <miguel@gnu.org> - - * month-view.c (month_view_init): Release points here. - -1999-08-02 Peter Teichman <pat4@acpub.duke.edu> - - * Makefile.am (libcalendar_conduit_la_LDFLAGS): - libcalendar_conduit now installs - - * calendar-pilot-sync.c (sync_pilot): do deletion of appointments - correctly, when they are deleted on the pilot - (conduit_free_Appointment): protect against double-freeing parts - of the Appointment structure - (update_record): all-day events from the pilot are handled a bit - more reasonably - -1999-08-01 Peter Teichman <pat4@acpub.duke.edu> - - * calendar-pilot-sync.c (sync_object_to_pilot): The multi-day - appointment corruption bug is dead. Whoo! - -1999-07-31 Peter Teichman <pat4@acpub.duke.edu> - - * Makefile.am: fixed this up slightly with respect to pilot conduits - -1999-07-30 Jonathan Blandford <jrb@redhat.com> - - * Makefile.am (libcalendar_conduit_la_LIBADD): More autoconf-stuff - -1999-07-29 Jonathan Blandford <jrb@redhat.com> - - * gnome-cal.c (setup_widgets): Add scrolling to the yearview. - -1999-07-28 Miguel de Icaza <miguel@gnu.org> - - * calendar-pilot-sync.c: (sync_object_to_pilot): If the enddate is - not set, set the repeatForever to 1. This fixes all of the - birthdays problems I had. - - Make the code not take arguments - (sync_cal_to_pilot): Nice event update information - - * calendar.c (calendar_new): Add Event UID hash table. - (calendar_add_object): Add events to the hash table here. - (calendar_remove_object): Remove events here. - (calendar_object_find_event): Use the hash table here. - - * main.c (save_calendar_cmd): The object is already destroyed by - gnome_dialog_run. - - * calendar-pilot-sync.c (sync_object_to_pilot): Do not turn - archived bit on. - - * calobj.c (ical_gen_uid): Use the hostname, not the domain name. - (ical_gen_uid): Add a serial number. Isodates can be small. - - * corba-cal.c (cal_repo_update_pilot_id): New method to update the - pilot status. - (cal_repo_get_updated_objects): New method. Returns a list of - modified and not-sycned objects - - * calendar-pilot-sync.c (sync_cal_to_pilot): New function to sync - from the GnomeCalendar to the pilot. - (sync_object_to_pilot): Sync a single event to the pilot. - (try_alarm): Alarm syncing code. - -1999-07-27 Miguel de Icaza <miguel@gnu.org> - - * calendar-pilot-sync.c: New file. Implements PalmPilot - syncronization with the Gnome Calendar. - - * calobj.c (ical_object_new_from_string): New function. Creates - an iCalObject from a vCalendar string that is supposed to contain - only one vEvent. - - * calendar.c: - (calendar_save): Split this routine in two. - - * gnome-cal.c (gnome_calendar_new): Create the corba server here. - - * main.c: Include gnorba.h, and corba-cal-factory.h here - (close_cmd): Kill the calendar server on shutdown. - - * calobj.c (load_recur_yearly_day): Added a fixme comment. WE - need to handle intervals in the years. - - * calendar.c (calendar_object_find_in_list, calendar_object_find, - calendar_object_find_todo, calendar_object_find_event): New - functions for looking up information. - - * main.c (gnome_calendar_locate): New function. - - * corba-cal.c (calendar_create_object): New file. Implements the - corba server. - - * calendar.c (calendar_object_changed): Flag pilot-status as changed. - - * calobj.c (ical_object_to_vobject): Save pilot information for syncing. - (ical_object_create_from_vobject): Load syncing information for - pilot. Do it in a way compatible with KOrganizer. - -1999-07-26 Miguel de Icaza <miguel@gnu.org> - - * calobj.c (ical_object_create_from_vobject): Generate unique IDs - on Vevents we load that lack it. WE need this for the old - gnome calendar generated files (ie, before now :-). - - Required to sync with the Palm - -1999-07-26 Miguel de Icaza <miguel@gnu.org> - - * calobj.c (ical_object_create_from_vobject): Generate unique IDs - on Vevents we load that lack it. WE need this for the old - gnome calendar generated files (ie, before now :-). - - Required to sync with the Palm - -1999-07-19 Matt Martin <matt@abacusnet.net> - - * timeutil.c (time_from_isodate): Handle the 'Z' parameter to the - ISO date format to convert from GMT time. - -1999-07-17 Nat Friedman <nat@gnome-support.com> - - * calendar.c (calendar_add_object): Copy the new UID into the - iCalObject structure. - -1999-07-16 Miguel de Icaza <miguel@gnu.org> - - * gnome-month-item.c (gnome_month_item_set_arg): Merge fix from - gnome-pim-1-0: Fixed cut&paste bug for day fontsets. - -1999-07-14 Miguel de Icaza <miguel@gnu.org> - - * calobj.c (ical_gen_uid): Returns a UID. - (ical_object_new): Use a UID when creating an event. Should get - syncing done easier. - -1999-07-14 Nicholas J Kreucher <nick@poetic.com> - - * calobj.c (skip_numbers): Actually skip over the numbers. - (ical_object_to_vobject): Test the proper variable for storing the - proper information. - -1999-07-14 Jean-Noel Guiheneuf <jean-noel.guiheneuf@wanadoo.fr> - - * timeutil.c (time_add_month): Fixed the problem with next month - going from a 31-day to a 30-day by adjusting the date to the - closest day at the end of the month. - -1999-06-07 Mike McEwan <mike@lotusland.demon.co.uk> - - * timeutil.c (time_add_month): Tell ktime' that we don't know - about daylight saving time so that it does *not* make adjustments - when we traverse a DST boundary. - (time_year_begin): ditto. - (time_year_end): ditto. - (time_month_begin): ditto. - (time_month_end): ditto. - -1999-06-16 Anders Carlsson <anders.carlsson@tordata.se> - - * main.c (new_calendar): Realize the toplevel widget when - --hidden is passed to gnomecal. This fixes a segfault. - -1999-06-04 Robert Brady <rwb197@ecs.soton.ac.uk> - - * gnome-cal.h, gnome-cal.c: Fix abort() problem with the year view. - (Bug #1367). Thanks to Owen Cliffe <oc197@ecs.soton.ac.uk> for - helping track it down. - -1999-06-03 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * calobj.c (daynumberlist): One line bug fix from Sergey I Panov. - -1999-06-02 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * view-utils.c (nicetime): Use %H instead of %k, as %k is a GNU - extension, not available in other systems. - -1999-06-01 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * calobj.c (daynumberlist): Work around broken software that - writes a broken month-of-day as "zero". Use the dtstart date for - this on this event. - -1999-05-28 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * Makefile.am (install-data-local): help files be gone. They are - now installed from the Docbook stuff. - -1999-05-26 Russell Steinthal <steintr@condor.penguinpowered.com> - - * gncal-todo.c main.c main.h prop.c: Added support for priorities - for todo items. Doesn't do much, but you can set them and sort by - them. (Use the properties box to enable them; should they be on - by default?) - -1999-05-25 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * main.c (parse_an_arg): Added missing break here. It was causing - core dumps when invoked with --userfile. - - * gnome-cal.c (gnome_calendar_set_view): Add some assertions here, - to pin point the bug reported on gnome-list. - - * calobj.c (load_recurrence): Make intervals always exist. a 0 - interval is wrong. - -1999-05-25 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * year-view.c: Removed unused macro CALENDAR_HEIGHT. - -1999-05-25 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * year-view.c (idle_handler): Set the canvas scroll region here, - not in size_allocate(). Also, use the correct width and height - based on the allocation and the precomputed minimum width/height - values. - - * gnome-cal.c (setup_widgets): Set the scrollbar policy of the - scrolled window. - - * main.c (setup_appbar): Use the correct type for the appbar. - - * gncal-day-view.c: Removed unused function switch_to_day(). - - * gncal-day-panel.c (calendar_day_selected): Removed unused variable. - -1999-05-25 Nat Friedman <nat@nat.org> - - * doc/C/gnomecal.sgml: Fixed a typo. - - * gnome-cal.c (setup_widgets): Added a scrolled window widget into - which the year view is placed. - - * year-view.c (CALENDAR_HEIGHT): The height of the total year view - inside the scrolled window. - (idle_handler): Set the height of the year view to - CALENDAR_HEIGHT. - (year_view_size_allocate): Set the scroll region of the year view - canvas to allocation->width, CALENDAR_HEIGHT. - -1999-04-25 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * main.c (dump_todo): Add --todo flag to dump the todo contents. - -1999-04-19 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * gncal-todo.c (add_activated): Use same hack used in edit_activated - -1999-04-16 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * gncal-todo.c (edit_activated): Kill all grabs from the CList - before running the new dialog box. - - This fixes the problem of button-3/Edit on the todo item blocking - the GUI (actually, the main window responds, but not the todo - window). - -1999-04-08 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * gncal-todo.c (gncal_todo_init): Make sure we can get events for - button3. The code for the nice popup menu was there but was not - getting invoked. - -1999-04-01 Steve Murphy <murf@e-tools.com> - - * calobj.c (weekdaynum): Added this routine so Monthly recurrences - use the weekday field as a simple integer for a single weekday. - - * calobj.c (load_recur_monthly_pos): Call weekdaynum instead of - weekdaylist. The interface only lets the user input a single value - anyway. - - * calobj.c (ical_object_to_vobject): instead of code to output day - names from a bit array, use instead the value as an int and output - a single dayname. - - * calobj.c (ical_object_generate_events): first_week_day gets the - day int instead of the first entry in the bit field. I inserted a - fair chunk of code to avoid calling generate if the day is out of - range for a month. It may be unneccessary, because mktime will - turn the extra days into a valid date the next month. But not all - mktimes are equal, I fear. - - * eventedit.c (ee_store_recur_rule_to_ical): For case 3, - (Monthly), I added code to set the interval slot of the recur - struct; without this value, selecting a monthly recursing, by - date, would lead to an infinite loop broken only by a failure to - alloc more memory. Also, in the "by position" case, both - u.month_pos and u.month_day were being assigned values. This is a - mistake, as they are both part of an union, and the same - thing. The weekday field should get the recur_rr_month_weekday - value. - - * eventedit.c (ee_rp_init_rule): set default day from the weekday - field instead of the u.month_day field, which is really the - month_pos value. - - * gnome-cal.c (gnome_calendar_tag_calendar): Month days start with - 1, not 0; thus, setting tm.tm_mday = 0, and then calling mktime - will generate a time corresponding to the end of the previous - month, which may have a mday anywhere from 28 to 31. The end time - just adds 1 to the month, so your end time may not cover the last - few days of this month, depending on what the biggest mday of last - month was. I changed it so tm_mday is set to 1 instead. - -1999-03-30 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * gncal-todo.c (convert_time_t_to_char): Made static. Make it use - the full year format for strftime(). - -1999-03-27 Nuno Ferreira <nmrf@rnl.ist.utl.pt> - - * calobj.c: Include <config.h> So that strings get translated. - -1999-03-26 Tomas Ogren <stric@ing.umu.se> - - * prop.c (build_hours_menu): Made it respect 12/24h settings.. - Doesn't show until next time you open the dialog.. yet.. - -1999-03-24 Tomas Ogren <stric@ing.umu.se> - - * gncal-week-view.c (gncal_week_view_set): Did some i18n work - * eventedit.c (get_exception_string): Did some i18n work - -1999-03-24 Tomas Ogren <stric@ing.umu.se> - - * gncal-todo.c (gncal_todo_init): Made clist titles i18n:able - * main.c (poptOption): Added which views that are possible for - --view in the --help text (closes #367) - * main.c (dump_events): Added (short) month to the strftime and made - the strings i18n:able - -1999-03-23 Tomas Ogren <stric@ing.umu.se> - - * gncal/calobj.c: Added 2 paranthesis.. - "foobar = d / 60*60" is _NOT_ the same as "foobar = d / (60*60)" - which caused heavy alarm-corruption with alarms between 2 hrs and - 2 days. - -1999-03-23 Nat Friedman <nat@nat.org> - - * eventedit.c (ee_store_recur_rule_to_ical): Set the - recur->interval to the value of the recur_rr_month_period spin - button if the event is being set "by day." This closes bug #675 - as reported by bagfors@hpc2n.umu.se. Thanks for the report! - -1999-03-10 Clifford R. Conover <rconover@montana.edu> - - * gncal-todo.c (simple_todo_editor): Add support for Due Date when - adding a TODO item here. - (column_resized): New function - (init_column_sorting): New function. - (todo_click_column): New function. - (convert_time_t_to_char, make_overdue_todo_style): New functions. - - * gnome-cal.c (gnome_calendar_todo_properties_changed): New - function used to update the TODO when the properties have been - chagned for it. - - * prop.c (prop_apply_todo): Apply TODO properties. - - * gncal-day-panel.c (todo_list_properties_changed): Update the - TODO display here. - - * eventedit.c (date_edit_new): Made public - -1999-03-10 Craig A Soules (soules+@andrew.cmu.edu) - - * timeutil.c, calendar.c, calobj.c, gncal-day-panel.c: Add support - for daylight time savings. - -1999-02-28 Martin Baulig <martin@home-of-linux.org> - - * gncal-full-day.c (recompute_motion): For DRAG_MOVE, DRAG_SIZE_TOP - and DRAG_SIZE_BOTTOM: call child_focus_out () if the child currently - has the focus. - -1999-02-27 Changwoo Ryu <cwryu@adam.kaist.ac.kr> - - * quick-view.c (QUICK_VIEW_FONTSET): Added Korean font to the - fontset string. - * mark.h (*_FONTSET): Likewise. - -1999-02-23 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * calobj.c (ical_object_to_vobject): Save the owner/organizer of - the event. - (ical_object_create_from_vobject): Load the owner/organizer of the event. - - * gncal-full-day.c (delete_occurance): Assign child to data (fixes - crash on "delete this occurrance"). - -1999-02-22 Timur Bakeyev <mc@bat.ru> - - * calendar.c: According to configured values, use either tm.tm_zone - or tzname. In last case, also declare it extern. - - * prop.c: langinfo.h not available everywhere. Wrapped. BTW, works - fine without it. - -1999-02-20 Tomas Ogren <stric@ing.umu.se> - - * main.c (init_username): Made use of g_get_{user,real}_name() instead - of our own home-brew... - -1999-02-17 Sergey Panov <sipan@mit.edu> - - * gnome-month-item.c,gnome-month-item.h,goto.c,mark.h, - month-view.c,prop.c,quick-view.c,year-view.c: will define - fonts via fontset. Friendlier to locales that use iso8859-[^1] - and koi8-r encodings. Does not solve problem for Asian languiges - --- better solution is needed (e.g. standart GNOME fontstyles - defined in gtkrc). - -1999-02-16 Sergey Panov <sipan@mit.edu> - - * main.c: Use N_() macro for color settings labels in - color_props structure. - -1999-02-15 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * goto.c (goto_dialog): Indentation fixes. - -1999-02-15 Tomas Ogren <stric@ing.umu.se> - - * goto.c: Made a private copy of what localtime() returns, to be able - to keep the data after more calls to localtime(). - -1999-02-11 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * main.c (save_default_calendar): New function. Saves the - calendar if it is the user's default calendar - - * gncal-full-day.c (unrecur_appointment): - * gncal-day-panel.c (day_view_range_activated): - * eventedit.c (ee_ok): - * gncal-todo.c (ok_button): Added autosave for the default - calendar. - -1999-02-09 Tomas Ogren <stric@ing.umu.se> - - * main.c: Removed the gtk_widget_realize call. - -1999-02-06 Changwoo Ryu <cwryu@adam.kaist.ac.kr> - - * gncal.desktop: Added Korean translations. - -1999-02-04 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * eventedit.c (date_edit_new): New convenience function to create - a properly-configured date editor widget. - -1999-02-03 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * gncal-week-view.c (gncal_week_view_new): Make the calendar start - weeks on Monday if appropriate. - (gncal_week_view_time_format_changed): New function to notify the - week view that the time format has changed. - - * gncal-day-panel.c (gncal_day_panel_new): Make the calendar start - weeks on Monday if appropriate. - (gncal_day_panel_time_format_changed): New function to notify the - day panel that the time format has changed. - - * gnome-cal.c (gnome_calendar_time_format_changed): Tell the day - and week views that the time format has changed. - -1999-02-01 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * eventedit.c (event_editor_init): Set the title of the event - editor window. - -1999-01-31 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * gncal-day-view.c (gncal_day_view_expose): Do not remove the - clipping rectangle here. - - * view-utils.c (view_utils_draw_events): Remove the clipping - rectangle here, since the user of this function should not know - about it. - -1999-01-30 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * view-utils.c (view_utils_draw_events): Improve this draw - routine. Now it can split the text in lines and fit as many - events as possible. - (nicetime): Return strings without spaces at the beginning. - - * gncal-day-view.c (gncal_day_view_expose): Move clip-clear - operation here. - -1999-01-29 Jason Tackaberry <tack@dok.org> - - * gncal-full-day.c (child_popup_menu): if the user clicks on an - event that is an occurance, the menu will allow the user to delete - all occurances of this event, or just the selected occurance. - (delete_occurance): added. - - * eventedit.c (append_exception): force the clist to select the - new exception. (fixes segfault) - (delete_exception): if the last exception in the clist is deleted, - move the selection index up. (fixes segfault) - -1999-01-28 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * main.c (parse_an_arg): Add --hidden key to hide the calendar at - startup. Only works with GNOME window managers though :-( - - * calendar.c (calendar_day_change): Reschedule alarms for the new day. - - (calendar_init_alarms): Schedule an alarm for midnight to change - the calendar_day_begin/calendar_day_end. - - * alarm.c (alarm_ready): If we reschedule, there is no need to - activate any pending alarms. - -1999-01-28 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * gncal-full-day.c (child_new): Insert the summary text here. - (child_focus_in): No need to raise the window, since we have - Spiffo(tm) layout code. Boy, this is old code. - (gncal_full_day_focus_child): Now that GtkText works better, we - can avoid synthesizing a click which was causing grief, anyway. - (child_button_press): Grab the focus before popping up the menu. - - * layout.c (find_index): Added a sanity check. - - * gncal-full-day.c (child_destroy): Unmap and unrealize the child - before unparenting/destroying it. - (child_unrealize): Unrealize the widget. What was I thinking? - (child_new): Save the focus_out_event signal connection id in - Child structure (in a new field). - (child_destroy): Disconnect from the focus_out_event signal, since - we don't want to get such an event when the widget is destroyed. - (gncal_full_day_destroy): Destroy the children properly; it was - leaking memory. - -1999-01-27 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * main.c (save_calendar_cmd): Warn if the calendar file has - changed. - - * calendar.c (calendar_load, calendar_save): Keep track of the - modification time for the calendar file. - -1999-01-20 Nat Friedman <nat@nat.org> - - * gncal-full-day.c (gncal_full_day_key_press): Only trap printable - characters such that hotkeys work. - (UNSELECT_TIMEOUT): Changed to 0. Much saner behavior. - - * prop.c (properties): Connect gnome_help_pbox_display to the - GnomePropertyBox help button. - -1999-01-19 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * quick-view.c (quick_view_do_popup): Do not grab the mouse here - (it was being grabbed incorrectly, anyways). - (quick_view_map_event): Grab the mouse when the window is mapped. - This avoids the ugly "while (xGrabPointer () != Success)" hack. - (quick_view_button_release): Handle button releases here. - -1999-01-19 Tomas Ogren <stric@ing.umu.se> - - * main.c: do gtk_widget_realize on the toplevel window.. - -1999-01-13 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * gncal-day-panel.c (gncal_day_panel_new): Make the little - calendar start up with the correct date. - - * gncal-week-view.c (gncal_week_view_set): Add the month to the - date range display label. - -1999-01-08 Nat Friedman <nat@nat.org> - - * main.c: Converted some more stuff to use the standards. - -1999-01-08 Nat Friedman <nat@nat.org> - - * main.c (setup_appbar): New function to create the status bar. - (setup_menu): Install menu hints. - - Menu items updated to match the standards. New Settings menu - created. - -1998-12-30 Jeff Garzik <jgarzik@pobox.com> - - * gncal/calendar.c, gncal/gnome-cal.c, gncal/main.c, - gncal/quick-view.c: - s/g_copy_strings/g_strconcat/ - -1998-12-16 Miguel de Icaza <miguel@nuclecu.unam.mx> - - Rewrote the old and broken alarm system. It never actually - worked properly. Now it works properly, and I figured a nice way - to get the Audio alarm do something nicer (it is now like an alarm - clock :-). - - * gnome-cal.c (calendar_notify): Now we take a CalendarAlarm to - actually distinguish which alarm was triggered. - - * alarm.c (alarm_ready): The code was only activating the first - alarm. Reschedule the timer upon delivery of an alarm. - -1998-12-14 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * year-view.c (idle_handler): Use the allocation size instead of - the old fields in the canvas structure. - - * goto.c (create_days): Use gtk_widget_set_usize() instead of - gnome_canvas_set_size(). - * quick-view.c (setup_event_list): Likewise. - -1998-12-09 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * gncal-todo.c (simple_todo_editor): Use gnome_dialog_set_parent. - * goto.c (goto_dialog): ditto - * prop.c (properties): ditto. - -1998-11-23 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * eventedit.c (ee_rp_init_exceptions): Update GtkClist usage. - -1998-11-23 Andrew T. Veliath <andrewtv@usa.net> - - * gncal-day-panel.c (gncal_day_panel_new): Use - gtk_scrolled_window_add_with_viewport instead of - gtk_container_add (gtk changes). - -1998-11-23 Herbert V. Riedel <hvr@hvrlab.ml.org> - - * eventedit.c: use GPOINTER_TO_INT - - * gncal-todo.c: same. - -1998-11-22 Matthew Wilson <msw@redhat.com> - - * main.c: Fixed the popt event parsing callback to have the - correct number of arguments. This stops it from segfaulting. - -1998-11-16 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * eventedit.c (ee_classification_widgets): Doh. Fixed stupid bug - where the classification buttons were not being set correctly. - (ee_store_general_values_to_ical): Take into account the fact that - radio group lists are stored in reverse order of insertion. - - * gncal-todo.c (gncal_todo_init): Use a scrolled window to put the - clist into. - -1998-11-11 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * calendar.c (calendar_save): Backup the old file before saving - the caledar. - -1998-11-06 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * calobj.c: Add ctype.h - -1998-10-31 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * gnome-cal.c (gnome_calendar_direction): Add the offset from the - beginning of the current time unit (day/month/etc), otherwise it - does not work right, for example, you are on the 31st day of a - month and the next month is a 30-day one and you jump to the next - month. - -1998-10-16 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * month-view.c: Changed a lot of stuff not to use the layout code - -- the month view's days are too small to display layout - usefully. Now they display a little list of the events in each - day. We also have a popup menu for the days in the month view. - - * calendar.c (calendar_get_objects_in_range): Reverse the list so - that it is returned in increasing order. - - * eventedit.c (event_editor_new_whole_day): New public function to - create an event for the complete span of day_begin to day_end. - - * year-view.c (new_appointment): Use event_editor_new_whole_day(). - - * year-view.c (yv_popup_menu): Mark strings for i18n. - -1998-10-12 Ji Lee <g@ucsd.edu> - - * eventedit.c (ee_store_recur_rule_to_ical): The interval was - never being loaded from the spin button. - -1998-10-09 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * month-view.c (month_view_update): Create a list of children and - lay them out nicely. Lots of functions added for this purpose. - (adjust_segment): Main event segment adjustment routine. - (adjust_children): Adjusts all the children in the month view. - (child_create_segments): Creates the segments for a particular event. - (layout_children): Uses the generic layout engine to organize the children. - -1998-10-08 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * gncal-todo.c (clist_row_selected): Set the sensitivity of the - edit/delete buttons. - (gncal_todo_update): Likewise. Thanks to Dirk Luetjens for the - bug report. - - * layout.c: Do some cleanup; now we pass a struct with the layout - algorithm's state instead of passing a trillion parameters around. - - * gncal-full-day.c (layout_children): Use the new generic layout - engine. - (child_compare): Sort keys are start time then end time, not just - start time. This produces somewhat nicer results for the layout - algorithm. - - The new layout code uses a partition of the time range occupied by - the events, rather than using a fixed time granularity. This is - better since the different parts of the program that use the - layout module will have different semantics regarding snapping the - event bounds to a fixed "time grid". - -1998-10-07 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * layout.[ch]: New files that abstract the event layout code from - gncal-full-day.c into something useful for other parts of the - program. Now all event layout is done here. - - * Makefile.am (gnomecal_SOURCES): Added layout.[ch] to the list of - sources. - -1998-10-07 Carsten Schaar <nhadcasc@fs-maphy.uni-hannover.de> - - * main.c (main): Replaced the 'gnome_client_new_default' call with - 'gnome_master_client'. - -1998-10-02 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * timeutil.c (time_day_begin): Changed name from - time_start_of_day() to be consistent with the other begin/end functions. - (time_day_end): Likewise. - - * calobj.c (ical_object_get_first_weekday): New public function to - get the first toggled day in a weekday mask. Since we do not - support multiple weekdays in a monthly-by-pos rule, we just fetch - the first toggled one. - (ical_object_generate_events): Added a missing break statement. - - * timeutil.c (time_month_end): Made it consistent with the rest of - the time begin/end functions -- now it returns the first second of - the *next* month. - (time_week_end): Actually implemented this function. It will be - used when the week view is rewritten. - - * calobj.c (time_in_range): Fix off-by-one in the comparison of - the time against the end time. - - * gncal-full-day.c (expand_space): Fixed bug where the columns not - were being expanded due to a missing "slot + j". - -1998-10-01 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * month-view.c (month_view_init): Use the font #defines. - (month_view_new): Set the colors of the month view upon creation. - (mark_current_day): New function to mark the current day in the - month view. - (month_view_set): Mark the current day. - (month_view_colors_changed): Mark the current day and colorify the - month item appropriately. - - * month-view.h: Added year and month fields to the MonthView - structure. - - * main.c: Renamed the Appointments color property, since it will - be used by the month view as well. - - * goto.c (update): Set the current day's font and color. - - * year-view.c (year_view_init): Set the fonts of the month items - when creating them. - - * mark.h: Added new #defines for HEADING_FONT and TITLE_FONT. - - * year-view.c (year_view_init): Use the new font #defines. - - * prop.c (prop_apply_colors): Fixed to work with the - I-am-paranoid-and-I-need-to-size-my-ints changes to - GnomeColorPicker. - (color_spec_from_picker): Likewise. - -1998-09-30 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * goto.c (create_days): Colorify the month item and prepare it for - prelighting here. - - * main.c (color_props): Changed the default colors to something - not dull. - - * year-view.c (compute_min_size): New function to compute the - minimum size of the year view properly. - (year_view_size_request): Added two new fields to the year view - structure that contain the minimum size. Return this in the - size_request method. - (year_view_new): Call compute_min_size to save the minimum size - for later use. - (idle_handler): Make it resize the items correctly. - - * gnome-month-item.c (gnome_month_item_set_arg): Reshape when - necessary. This is needed becaues we now actually calculate a - minimum size for the month item based on the font sizes and paddings. - (check_heading_sizes): New function to calculate a minimum size - based on the headings' dimensions. - (check_day_sizes): New function to calculate a minimum size based - on the day number labels' dimensions. - (check_sizes): New function that computes a minimum size for the - month item. - (reshape): Now calls check_sizes() to ensure a minimum size for - the month item. - - * year-view.c (mark_current_day): New function to mark the current - day in the year view. - - * mark.c: Removed mark_current_day from here. - -1998-09-29 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * prop.c (fetch_color_spec): Changed name from fetch_prelight_spec - and made it conform to the new prelighting mechanism. - (fake_mark_days): Set the proper day attributes. - (reconfigure_month): Use colorify_month_item(). - (fake_mark_days): Use mark_month_item_index(). - - * mark.c (colorify_month_item): New public function to reset the - colors in a month item. - (get_attributes): New internal function that creates an array of - attributes for the days in a month item. This is the basis of all - the new optimizations to month item marking. - (unmark_month_item): Now it uses the attributes array to unmark - only the days that need unmarking. - (mark_event_in_month): Update the day attributes array. - (month_item_prepare_prelight): Changed the definition of the - prelight color query function. Use the new function. - (day_event): Do color changes based on the day attributes array. - (mark_month_item_index): New public function to mark a single day - by index. - (mark_event_in_month): Use mark_month_item_index(). - - * gnome-month-item.c (gnome_month_item_num2child): Now takes an - int, not a GnomeMonthItemChild. - (gnome_month_item_child2num): Now returns an int, not a - GnomeMonthItemChild. - (gnome_month_item_num2day): Now takes an int, not a - GnomeMonthItemChild. - - * goto.c (goto_dialog): Create the days before the year spin - button, because the year_changed callback expects the month item - to be created. The new semantics of the spin button cause it to - emit a value_changed signal on the adjustment upon creation -- is - this the behavior we want from it? - (goto_dialog): Use gtk_window_set_modal() instead of the - deprectaed gnome_dialog_set_modal(). - - * quick-view.c (quick_view_new): Make it look not as crappy by - putting the title inside the frame. - (quick_view_do_popup): Fixed the pointer grab and added a cursor. - (create_items_for_event): Query the text width/height from the - text item using the new object arguments, so that the size of the - popup window can be set properly. - - * year-view.c (do_quick_view_popup): Calculate a nice date string - for the popup window. - -1998-09-28 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * quick-view.[ch]: New file that presents a quick view of the - events in a particular day when the mouse is clicked on the year - view. Work in progress. - - * year-view.c (do_quick_view_popup): New function that creates a - quick view for the events in a day. - - * Makefile.am (gnomecal_SOURCES): Added quick-view.[ch] to the - list of sources. - -1998-09-27 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * main.c: Hotkey for File/Exit should be C-q, not C-x. - -1998-09-24 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * year-view.c (do_popup_menu): New function to execute the popup - menu in the year view. - (day_event): Invoke the popup menu with the context set to days. - (new_appointment): New function to create a new appointment from - the year view. - (do_jump): New function to do the appropriate view/date jumping - from the popup menu. - - * main.c: Fixed two icons in the File menu. - -1998-09-21 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * main.c: Added underlined shortcuts and accelerators to the main menu. - -1998-09-16 Raja R Harinath <harinath@cs.umn.edu> - - * gncal-week-view.c (<gtk/gtklabel.h>): Include. - * gncal-week-view.h (<gtk/gtkvbox.h>): Include. - -1998-09-06 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * gnome-cal.c (mail_notify): Fixed the bug reported about the mail - notification not beint sent until the program was terminated. - -1998-09-03 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * gncal-full-day.c (gncal_full_day_forall): Updated foreach -> - forall from Gtk changes, bleah. - - * year-view.c (day_event): New function to handle events from - days. Jumps to the day that is clicked. - - * main.c: Use a watch cursor while the previous/today/next - functions are doing their job. - - * mark.c (month_item_prepare_prelight): New public utility - function to prepare a month item for prelighting. It will store - the proper prelight information and attach the appropriate signals. - (mark_current_day): Make the current day bold as well (useful for - color-blind people, I guess). - - * prop.c (set_current_day): Reset the date in the sample calendar - and mark the current day. - (fake_mark_days): Mark fake events in the sample calendar. - - * year-view.c (year_view_set): Use the general prelighting engine. - - * goto.c (day_event): Just process button presses, as prelighting - is done behind the scenes now. - (update): Use the general prelighting engine. - - * prop.c (create_colors_page): We can now configure the colors of - the monthly calendars! Wheeeeee! There are still some nits to be - fixed, which are listed in the TODO file. - (build_color_spec): New function to build color specifications. - (parse_color_spec): New function to parse color specifications. - - * mark.c: Modified all functions to use the configured colors. - * goto.c: Likewise. - - * main.c (colors_changed): New function that notifies all - calendars that colors have changed. - - * gnome-cal.c (gnome_calendar_colors_changed): New function that - notifies all the views that the colors have changed. - - * month-view.c (month_view_colors_changed): New function that - notifies the month view that colors have changed. - - * year-view.c (year_view_colors_changed): New function that - notifies the year view that colors have changed. - - * gnome-month-item.h (struct _GnomeMonthItem): Added fields for - outline and day box colors. - - * gnome-month-item.c (gnome_month_item_set_arg): Added - outline_color, outline_color_gdk, day_box_color, and - day_box_color_gdk arguments to month items. These are convenient - to quickly set the colors of the month item. - (gnome_month_item_get_arg): Likewise. - - * main.[ch]: Added a global array of structures for color preferences. - -1998-08-31 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * goto.c: Small code cleanup. - (day_event): Upon receiving a LeaveNotify event, Reset the day's - background to the correct color. - -1998-08-29 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * mark.[ch]: New files with utility functions to mark calendars - with their events. - - * mark.c (mark_month_item): New public function to mark a month - item with events. - (unmark_month_item): New public function to unmark all the days in - a month item to their default appearance. - - * year-view.c (year_view_set): Use the new unmark_month_item() and - mark_month_item() to mark the months with events. - - * goto.c (update): New function that updates the calendar in the - Go-to dialog by marking the days. - - * timeutil.c (time_year_begin): Modified to take a time_t value. - (time_year_end): Likewise. - (time_month_begin): Actually implemented this function, which was - in the header file but not here. - (time_days_in_month): New public function that returns the number - of days in a month. - - * Makefile.am (gnomecal_SOURCES): Added mark.[ch] to the sources. - - * year-view.c (unmark_days): Use unmark_month_item(). - - * gncal-full-day.c (gncal_full_day_destroy): Fixed crash when - destroying the full day view. The full day's destroy method is - unusual in that it destroys the list of child widgets itself, as - it does not have a remove method, so it needs to reset the list to - NULL. - -1998-08-27 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * gnome-month-item.c (build_month): Now does the correct thing - when the user wants weeks to start on Monday. Now all the Monday - special casing, as far as day numbering is concerned, is only in - this function. - - * year-view.c (mark_days): This function marks the days that have - events in them. It also fixes a memory leak in the old - implementation (it was leaking the whole list). - (unmark_days): New function used to unmark all the days in the - year view. - (mark_event): New function that marks all the days that are - spanned by a time range. It also fixes the bug in the old - implementation where it could possibly mark days past the ends of - the year (if the event crosses year boundaries, for example). - - * timeutil.c (time_year_begin): Take the year parameter since year - 1, not 1900. - (time_year_end): Likewise. - - * year-view.c (year_view_size_allocate): Now changing the size of - the calendars is done in the idle loop. - (idle_handler): This function actually does the resizing of the items. - - * year-view.h (struct _YearView): Added idle_id and need_resize - fields. - -1998-08-26 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * year-view.c: Beginning of the new year view. Sizing and event - marking needs to be finished. - - * gnome-cal.c: Updated for year-view. - (gnome_calendar_time_format_changed): Use year_view_time_format_changed(). - - * year-view.[ch]: Renamed the gncal-year-view.[ch] files to - year-view.[ch]. - - * Makefile.am (gnomecal_SOURCES): Updated year-view.[ch] in the - list of source files. - -1998-08-25 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * goto.c (create_days): Set the heading color of the month item. - - * main.c: Use GNOME_STOCK_PIXMAP_JUMP_TO, now that it exists, - instead of goto.xpm. Also, removed goto.xpm from cvs. - - * gnome-month-item.h (struct _GnomeMonthItem): Added fields for - the heading and day number fonts. Added fields for heading and - day number label colors. - - * gnome-month-item.c (gnome_month_item_class_init): ARG_DAY_NAMES - should be write-only. Also, added arguments for heading and day - number fonts. Added arguments for heading and day number colors. - -1998-08-24 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * prop.c (build_two_radio_group): Doh. Set the state of the radio - buttons properly. - - * month-view.c (month_view_time_format_changed): New public - function that notifies the month view of a time format change. - - * gnome-cal.c (gnome_calendar_time_format_changed): New public - function that notifies the calendar of a time format change. - - * main.c (time_format_changed): Use gnome_calendar_time_format_changed(). - - * month-view.c (month_view_update): New public function to update - the month view when an event changes. This is still unfinished. - (month_view_set): New public function to set the month in the - month view. - - * gnome-cal.c (gnome_calendar_direction): Add case for month view. - (gnome_calendar_set_view): Likewise. - (gnome_calendar_update_all): Likewise. - - * timeutil.c (time_add_week): Implemented the time_add_week() - function, which was on the header file. - (time_add_month): Added public month-adding routine. - - * gnome-cal.c (gnome_calendar_get_current_view_name): Add case for - month view. - (gnome_calendar_goto): Likewise, and set the time on the month view. - - * month-view.c (month_view_new): Now it takes the calendar plus - the time_t representing the month. - - * gnome-month-item.h: Added documentation on the object arguments - for the month item. - - * month-view.c (month_view_init): Added a month/year heading to - the month view. - - * TODO: Updated the TODO list a bit. - - * main.c (gnome_cal_file_menu): The preferences menu option should - go in the File menu. - (gnome_cal_edit_menu): Added stock pixmaps to the menu items. - (gnome_cal_menu): Renamed the Calendar menu to Edit. - (gnome_cal_help_menu): Use "About Gnomecal", not just "About". - - * prop.c (hour_activated): Notify the property box that it has changed. - - * main.c: Changed the Properties menu item to Preferences. These - are global application preferences, not a single calendar's - properties. - - * prop.c (prop_apply): Save the week_starts_on_monday flag to the - configuration file. - (properties): Added a check button for weeks starting on Monday. - (properties): Beautified the Preferences dialog. - - * month-view.c (month_view_init): - * goto.c (create_days): Set the month item to start weeks on - Monday if appropriate. - - * main.c (init_calendar): A boolean is not an hour, so don't - range_check_hour() on it. - (init_calendar): Added a global week_starts_on_monday flag. - - * main.h: Added global week_starts_on_monday flag. - -1998-08-21 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * calobj.c (ical_object_create_from_vobject): If mail alarm or - program alarm are missing the action, then set an empty default. - -1998-08-18 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * gnome-month-item.c (gnome_month_item_day2index): New public - function to get the displayed day index of the specified date. - - * gnome-cal.c (gnome_calendar_goto_today): New public function to - jump to the current day. - - * goto.c (day_event): Jump to the selected day when the user - clicks the mouse, and prelight days as appropriate. - - * timeutil.c (time_from_day): New public function to build a - time_t from a year/month/day triplet. - - * gnome-month-item.c (gnome_month_item_num2child): - (gnome_month_item_child2num): New public functions to convert an - index into a child and vice-versa, respectively. - (gnome_month_item_num2day): New public function to convert a child - number into a displayed day number. - - * goto.c (goto_dialog): Doh, use gnome-dialog properly :-) - - * gnome-month-item.c (create_items): Use g_strdup()ed day names - from the start. - -1998-08-17 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * main.c (gnome_toolbar): Made it use goto.xpm. - - * Makefile.am (EXTRA_DIST): Added goto.xpm to the list of files. - -1998-08-13 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * gnome-month-item.c (gnome_month_item_set_arg): Doh. Actually - recalculate the days using the month and year. - - * main.c: Added "Go to" button to quickly jump to a specific date. - - * goto.c: New file that defines the quick go-to date dialog. - - * Makefile.am (gnomecal_SOURCES): Added goto.c to the sources. - -1998-08-11 Nuno Ferreira <nmrf@rnl.ist.utl.pt> - - * main.c (new_calendar): Made title i18n friendly. This was bug - #215. - - * eventedit.c (ee_store_recur_end_to_ical): Set recur->enddate to - recur->_enddate, not to itself, when adding recurring event and - supplying an end date. This fixes (at least part of) bug #99. - -1998-08-10 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * month-view.[ch]: Start of the month view widget. This will use - the generic month item and extend it to have the semantics desired - for the gnomecal month view. - - * gnome-month-item.[ch]: New generic canvas item for the month - view and the "small calendars". This is intended to be a - high-level display engine for monthly calendars. This is a work - in progress. - - * gnome-cal.h (GnomeCalendar): Added a month_view field. - - * gnome-cal.c (setup_widgets): Create the month view and insert it - into the notebook. - - * Makefile.am: Added month-view.[ch] and gnome-month-item.[ch] to - the sources. - -1998-08-03 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * main.c (about_calendar_cmd): Use an array of const strings to - keep gcc happy. - - * alarm.c (alarm_compare_by_time): Use gconstpointer to keep gcc happy. - * calendar.c (calendar_object_compare_by_start): Likewise. - * gncal-full-day.c (child_compare_by_start): Likewise. - -1998-07-07 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * main.c: Add support for --view flag. - (session_save_state): Save the view mode; - (new_calendar): Now takes a view mode flag. - - * gnome-cal.c (gnome_calendar_get_current_view_name): New - function for enhancing the session management support for - gnomecal. - (gnome_calendar_set_view): New function that makes a given page - active. - -1998-07-01 Nuno Ferreira <nmrf@rnl.ist.utl.pt> - - * gncal.desktop: Added Portuguese translation. - -Mon Jun 22 13:01:16 1998 Havoc Pennington <hp@pobox.com> - - * main.c (session_save_state): Use gnome_geometry_string to get - the geometry string. - -1998-06-04 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * eventedit.c (ee_rp_init_rule): Do not subtract 1 from - tm->tm_mday for the default_day. - - * gnome-cal.c (gnome_calendar_new): - (gnome_calendar_goto): Use the start of the day -- things expect - it to be that way. - -1998-05-27 Nuno Ferreira <nmrf@rnl.ist.utl.pt> - - * eventedit.c (ee_store_recur_rule_to_ical): Fill in - ical->recur->interval from value in spin_button. This ixed an - infinnite loop. - -1998-05-30 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * gncal-full-day.c (child_draw): Paint the decorations correctly. - (child_draw_decor): Paint the recurrence/bell icons correctly. - -1998-05-25 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * eventedit.c (ee_rp_init_rule): Use the contents of - ee->ical->dtstart for computing the predefined values of the recurrence. - - * gncal-full-day.c (gncal_full_day_unrealize): Fix the gc - destruction in the unrealization code and fix the pixmap unrefing. - - * main.c (close_cmd): Remove a bad hack that disabled calendar - widget destruction. - - * calobj.c (ical_object_generate_events): Fix for the weekly event - generation. Was reported on the bug tracking system. - -1998-05-18 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * gncal-full-day.c (layout_children): Implemented ultra-cool - layout for the events that share the same time range. Gals and - guys you can now drop Outlook on the recycle bin. - - Which reminds me. We do not have a recycle bin. How could that - happen in a project as cool as this one? Someone explain this to - me. - -1998-05-18 Federico Mena <federico@nuclecu.unam.mx> - - * gncal-full-day.c (paint_back): Eliminated unnecessary border repainting. - -Sun May 17 17:55:03 1998 Havoc Pennington <hp@pobox.com> - - * gncal-todo.c (simple_todo_editor): Close dialog when return is pressed. - -1998-05-15 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * gnome-cal.c (mark_gtk_calendar_day): Bug free version of the - range computation in place. - - * gncal-year-view.c (year_view_mark_day): Use the same new version - of the range computation here. - - * calobj.c (ical_object_generate_events): Fix the begin/end - condition. - -1998-05-14 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * timeutil.c (isodate_from_time_t): Do not add the spurious - padding. - - * calobj.c (store_date_list): Bug fix: I was using the wrong - pointer when saving the exception date list. - (set_date_list): Bug fix: load correctly the complete exception - date list. - (set_date_list): Use ',' for the exception date separator as the - versit people can not get their standard right. - - * gncal-full-day.c (unrecur_appointment): Support for making an - existing recurrent event `movable' for a day. - - * calobj.c (ical_object_add_exdate): New routine, used to add - exception dates. - (ical_object_duplicate): New routine: used to do the magic - recur->no-recur event. - -1998-05-08 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * gncal-full-day.c (new_appointment): Use gtk_calendar freeze/thaw - - * gncal-year-view.c (gncal_year_view_set_year): Use gtkcalendar freeze/thaw. - - * eventedit.c (event_editor_init): Use gnome_dialog_set_close to - avoid the ugly warning. - - * main.c (display_objedit): Default to the day the user is looking - at. - -1998-05-05 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * gncal-day-panel.c (full_day_size_allocated): Do not emit a value - changed signal if the value is the same. - -1998-05-04 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * prop.c (prop_apply): Only run the apply code once. - -1998-05-03 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * gncal-day-panel.c (update): Draw the day at startup. - (gncal_day_panel_set): Fix selected-day display. - (gncal_day_panel_new): Switch day on double clicks, not on single - clicks. - - * calobj.c (ical_object_compute_end): Removed debug messages. - -1998-04-30 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * prop.c (prop_apply): Do not call prop_cancel, ths is now using - GnomePropertyDialog. - -1998-04-29 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * gncal-week-view.c (sync_week): Use gnome_calendar_tag_calendar. - - * gnome-cal.c (gnome_calendar_tag_calendar): New routine used to - fill a gtk_calendar with the events on a GnomeCalendar object. - - * gncal-week-view.c (gncal_week_view_new): Set the week to the day - we double clicked. - -1998-04-28 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * gnome-cal.c (calendar_notify): Apply black magic to get mail - notifications to work. - - * gncal-full-day.c (child_focus_out): Temporary optimization, the - child_focus_out is constantly calling the - gnome_calendar_object_changed when the property editor has been - invoked. This happens every time the mouse moves crosses the main - window. - - * calendar.c (calendar_object_changed): Reschedule alarms when a - calendar object has changed its times. - -Sat Apr 25 22:20:45 1998 Havoc Pennington <hp@pobox.com> - - * eventedit.c, eventedit.h: Descend from GnomeDialog. Took vbox - out of class structure; use GnomeDialog vbox - instead. gnome_dialog_set_destroy instead of destroying in button - callbacks. Don't create buttons, separator, or vbox manually. - #include <libgnomeui/gnome-dialog.h>. - -1998-04-24 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * calobj.c (ical_object_create_from_vobject): Fixed alarm loading; - Load snooze time and snooze count - -1998-04-23 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * calendar.c (calendar_save): Actually save the to-do entries. - - * gncal-todo.c (simple_todo_editor): Now you can add and edit - to-do entries. - -1998-04-22 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * gncal-full-day.c: Made it use popup_menu(). - - * popup-menu.c: New file with utility functions for creating popup - menus. Maybe such a thing would be useful in libgnomeui, a la - gnome-app-helper? - - * Makefile.am (gnomecal_SOURCES): Added popup-menu.[ch] to the sources. - -1998-04-22 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * prop.c (properties): Added Calendar properties editor. - (properties): Make the code use a propery box. - - * main.c: Save/load properties (fix to old commit). - -1998-04-21 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * gncal-todo.c: New widget for editing TODO lists. This will be - worked on a lot. - - * Makefile.am (gnomecal_SOURCES): Added gncal-todo.[ch] to the sources. - - * gncal-day-panel.c: Make it use the new TODO widget. - -1998-04-21 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * timeutil.c (isodate_from_time_t): Do not save with the global - time flag (Z at the end of the isodate). When we figure out a way - to load times in GMT time, we will add this back - - * view-utils.c (popup_menu): Moved this routine here as there are - more users of this code. - - * gncal-day-view.c (gncal_day_view_class_init): Add button press - handler. - (new_appointment): New routine for creating appointments on a day. - - - - * main.c (save_ok): Added call to gtk_window_set_wmclass. - - * gncal-day-panel.c (calendar_day_selected): Fix, years for mktime - should substract 1900 and gtk_calendar stores years relative to - year 0. - - * gncal-week-view.c (gncal_week_view_new): Make the week view - descend from VBox so that we can add a label to it. - (gncal_week_view_set): Display the ending day of the week - correctly. - - Added a label that displays the week range. - -1998-04-21 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * gnome-cal.c: Made it use GncalDayPanel. - - * gncal-day-panel.c: New widget for the day view in the main - calendar toplevel. It basically takes care of everything - gnome-cal did by hand with respect to the day view. - - * Makefile.am (gnomecal_SOURCES): Added gncal-day-panel.[ch] to - the rules. - - * main.c: Added a separator between the About menu item and the - help topics. - -1998-04-20 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * eventedit.c (ee_ok): Mark the event as non-new after accepting changes. - -1998-04-20 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * gncal-full-day.c (gncal_full_day_get_day_start_yoffset): New - public function that returns the y offset for the row - corresponding to the "day begin" time. - - * gncal-full-day.c (gncal_full_day_key_press): Now any printable - keystroke (not just Return) will activate the selected range. - - * gncal-full-day.c (paint_back): Made it use the new paint_row - function instead of painting everything directly. We calculate - areas in a smarter way so there is even less flicker than before, - especially when selecting regions. - - * eventedit.c: Sensitize recurrence widgets properly. - - * calobj.c (duration_callback): Pass the correct pointer type to - is_date_in_list(). - -1998-04-20 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * calobj.c (duration_callback): Take exception dates into - account. - - * gncal-full-day.c (new_appointment): Setup the event editor dates - to those of the currently displayed day. - (gncal_full_day_selection_range): Use sensible values in the case - no range is selected. - (new_appointment): Events now use the current day for event creation. - - * view-utils.c: Pretty up the time display. - - * calobj.c (ical_object_compute_end): Initialize - ico->recur->enddate, otherwise we loop forever during final date computation. - - * eventedit.c: Now recurrence is toggled by a radio button in the - recurrence page, as the checkbox is confusing. - - * calobj.c (is_date_in_list): Add support for the exclussion - dates. - -1998-04-18 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * gncal-year-view.c (double_click): Fix this routine as well. - - * gncal-week-view.c (jump_to_day): Bind the gtkcalendar signals to - the week. - - * gncal-year-view.c (gncal_year_view_set_year): Put things in the - proper range. Now the year view actually matches this year. - - * gnome-cal.html: Added small documentation. - - * main.c: Add more icons to the menus; Rename some menubar - entries; Add `new' icon to the toolbar. - (dump_events): Added argument handling and dumping of events from - the command line. Extremely cool. - - * getdate.y: Taken from the CVS source code. Used for date - parsing in the command line. - - Internationalized getdate.y. Wee! It even works with spanish. - - * calobj.c (ical_object_to_vobject): Add Quoted printable property - to items containing new lines. - (duration): Use unsigned integers, to work around buggy calendar - files generated by korganizer. - - * main.c (save_calendar_cmd): Do not ask for file name if we are - saving. - (save_as_calendar_cmd): New command. - - -1998-04-17 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * alarm.c (alarm_kill, alarm_init, alarm_add): Implement the alarm - management framework. - -1998-04-17 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * calobj.c (ical_new): Added mandatory status property. - (ical_object_to_vobject): Only store "related" list if it exists. - (store_list): Add terminating null char and free the correct data. - - * main.c (save_calendar_cmd): Implemented calendar saving. - (open_calendar_cmd): Implemented calendar loading. - (new_calendar_cmd): Implemented calendar creation. - (new_calendar): Don't load our test calendar by default. - - * gncal-full-day.c (delete_appointment): Delete appointment implemented. - - * eventedit.c (ee_store_recur_values_to_ical): Free/create - ical's recurrence appropriately. - (ee_rp_init_rule): Initialize all missing parameters from ical. - (ee_rp_init_ending_date): Initialize missing fields from ical. - -1998-04-17 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * gnome-cal.c (gnome_calendar_remove_object): Add support for - removing objects. - -1998-04-17 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * eventedit.c (ee_init_recurrence_page): New function that creates - the recurrence page in the toplevel notebook. - (ee_store_recur_values_to_ical): Now we can also store the recurrences. - -1998-04-17 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * calobj.c (ical_object_generate_events): Implement - RECUR_MONTHLY_BY_POS implemented. - (ical_object_create_from_vobject): Fix the alarm - initialization code. - (save_alarm): Save alarms. - (ical_object_generate_events): Fixed the recurrent code to take - into account the recur->endate field (if at all specified). - - (ical_object_to_vobject): Implement recurrence rule saving. - -1998-04-16 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * eventedit.c (ee_store_alarm): Use menu_shell->children, not - menu->children. Why does GtkMenu have a children field in the - object structure? - (check_dates): New function that insures that start_date < end_date. - (check_times): In addition to checking whether the event spans the - whole day, now it insures that start_time < end_time. - - * gncal-full-day.c (child_set_size): Now children get bigger - temporarily while they are focused. This allows the handles not - to "overlap" the rows used by the child and thus allow editing of - very thin events. - (recompute_motion): Fix for new child coordinates. - (gncal_full_day_expose): Make it use find_child_by_window() - instead of looking for it by hand. - - * bell.xpm recur.xpm: XPM files for events with alarm and - recurrence, respectively. - -1998-04-15 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * gncal-full-day.c (button_1): Preserve the up/down cursor while dragging. - - * gncal-full-day.c (child_draw): Now children have a vertical - handle as well. This can be used to move the child anytime, not - only when it is focused. - (recompute_motion): Modified for new drag behavior. - - * eventedit.c (ee_init_general_page): The general_owner may be - null. Do the proper thing when creating the label. - (ee_ok): Update the gnome calendar appropriately. - - * timeutil.h: - * gncal-year-view.h: Add some missing prototypes. - - * gncal-full-day.c (child_popup_menu): Set the sensitivity of menu - items according to whether the ical object is being edited or not. - - * eventedit.c (event_editor_new): Set the "being edited" flag on - the ical object (stored as the ical object's user data). - (event_editor_destroy): Release the flag. - - * calobj.h: The iCalObject structure now has a generic user_data pointer. - * calobj.c (ical_object_set_user_data ical_object_get_user_data): - Functions to set this data. - - * gncal-full-day.c (child_button_press): Do child popup menu correctly. - - * main.c (about_calendar_cmd): Fixed my address and added Arturo - to the authors in the about box. - - * gncal-full-day.c (find_child_by_window): Compare child's widget - windows by user_data (which will be the parent widget, that is, - the text widget). We cannot assume that child->widget->window - will be *the* window we are interested on because there may be - child widgets with multiple windows. - -1998-04-15 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * calobj.c (ical_foreach): Define iterator routine. - -1998-04-15 Arturo Espinosa Aldama <arturo@nuclecu.unam.mx> - - * gncal-year-view.[hc]: Now using time_t for new and set. - Random fixes, as well. - -1998-04-15 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * gncal-full-day.c (button_3): New popup menus activated with - mouse button 3. - (create_appointment): Create a new appointment from the popup - menus. See the FIXME. - -1998-04-15 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * gncal-full-day.c (layout_kill_rows): Routine to destory rows - array properly. - - * gncal-year-view.c (gncal_year_view_new): Add missing year in - call to strftime. - - * calobj.c (ical_object_create_from_vobject): Fixed memory leaks - from the return values of versit's fakeCString. - -1998-04-14 Arturo Espinosa Aldama <arturo@nuclecu.unam.mx> - - * gncal-year-view.[hc]: New widget for the year view. - * Makefile.am: added required compilation of the new files. - -1998-04-14 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * eventedit.c (event_editor_setup_time_frame): Fixed some table - expansions to make the dialog look nicer when resized. - - * calobj.c (ignore_space): Fixed compiler warning about unused - computed value. - (ocurrencelist): Replace str by p confusion. Removed unused - variables value and q. - (daynumber): Fixed a couple of warnings about unused values. - (load_recurrence): Removed unused variable c. Added a default - clause to the switch(type). - - * eventedit.c (ee_rp_init_frequency): Removed unused variable content. - Fixed a compiler warning by adding a missing cast. - - * calobj.c (ical_object_create_from_vobject): Make the - load_recurrence() part work correctly. Eliminated use of - syntax_error variable. - -1998-04-13 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * gncal-full-day.c (child_key_press): Unfocus the child and focus - the parent fullday widget when the user presses Esc. - - * gncal-week-view.c (gncal_week_view_update): Now takes object and - flags parameters. - * gncal-day-view.c (gncal_day_view_update): Likewise. - * gncal-full-day.c (gncal_full_day_update): Likewise. - (child_focus_in): New function. In conjunction with - child_focus_out(), these only display the handles in the child - when it is focused. The result is that the user can see more of - the child's text when nothing is focused, and we can also display - fatter and nicer drag handles. - - * gnome-cal.c (gnome_calendar_object_changed): Now takes an - additional flags parameter - (gnome_calendar_update_all): Made function static. Now takes - changed object and flags parameters as well. - (gnome_calendar_object_changed): Now takes additional flags - parameter to indicate what changed in the specified object. - - * calobj.h (CalObjectChange): New enum with flags to describe what - has been changed in an object. - - * gncal-full-day.h: - * gncal-full-day.c (gncal_full_day_focus_child): New function to - let the outside world decide which child to focus. - (gncal_full_day_focus_child): Bleah. We have to synthesize a - click because GtkText will not set the cursor when you focus it. - - * gnome-cal.c (day_view_range_activated): Focus the new child in - the full day widget. - - * eventedit.c (event_editor_setup_time_frame): Re-aligned some - widgets to make it look prettier. - (ee_alarm_widgets): Likewise. - (ee_init_general_page): Likewise. - (ee_classification_widgets): Likewise. - (event_editor_init_widgets): Likewise. - - * gnome-cal.c (day_view_range_activated): Create new object and - add it to the calendar. You can now select a range in the - full-day view, hit Return, and a new event will be added at the - selected range. I still have to figure out how to focus this new child. - - * gncal-full-day.c (paint_back): Rewrote function to avoid - painting an area more than once -- eliminate flicker. - (paint_back_rows): New function that calls paint_back() only for - the area of the specified rows. - (gncal_full_day_button_press): - (gncal_full_day_button_release): - (gncal_full_day_motion): Made these functions use - paint_back_rows() instead of paint_back(), to eliminate flicker. Wheee! - -1998-04-12 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * gnome-cal.c (setup_day_view): We now connect to the - range_activated signal of the fullday widget instead of catching - key presses ourselves. - (day_view_range_activated): New function that creates a new - iCalObject and inserts it into the calendar, not finished yet. - -1998-04-11 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * gncal-full-day.c (get_time_from_rows): New function, calculates - a pair of time_t values from the specified start and number of rows. - - * gncal-full-day.h (GncalFullDayClass): New signal - "range_activated". It is emitted when a range is selected and the - user hits Return. - (gncal_full_day_selection_range): New function, returns the - selected range. - - * gncal-full-day.c (struct drag_info): Moved selection information - to their own fields instead of sharing the child's drag fields. - This allows us to keep the selection when a child is moved. - (recompute_motion): Made the case when (row < di->sel_click_row) - work correctly. - -1998-04-11 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * gnome-cal.c (gnome_calendar_goto): Add support for navigating - on the day view. - - * timeutil.c (time_start_of_day, time_end_of_day, time_day_hour): - New time manipulation functions. - - * eventedit.c (ee_rp_init_frequency): Add the different frequency - editors to a notebook. Make the notebook startup on the entry - selected recurrence type; - -1998-04-11 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * gncal-full-day.c (recompute_motion): Now we support selecting a - range in the main window (by clicking+dragging). It flickers - horribly and is not perfect, but it is a start. - -1998-04-09 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * gncal-full-day.c: #include <string.h> - - * gncal-full-day.c (child_map): Show instead of just map the child - widget (otherwise the text widget gets confused and will not focus). - - * calobj.c (ical_object_to_vobject): Quote chars as 'x', not "x". - - * calobj.h: Added prototype for ical_object_to_vobject(). - - * gnome-cal.c (gnome_calendar_object_changed): New function. This - should be called when a calendar object is changed. - - * gncal-full-day.c (update_from_drag_info): Call - gnome_calendar_object_changed() instead of updating manually. - - * calendar.c (calendar_add_object): - (calendar_remove_object): Set the modified flag to true. - - * gncal-full-day.c (gncal_full_day_draw): Finished implementing - this function. - -1998-04-08 Raja R Harinath <harinath@cs.umn.edu> - - * gncal.c (update_calendar): Say `#if 0', not `#ifdef 0'. - -1998-04-07 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * eventedit.c: Removed unused global variable parent_class. - - * eventedit.h: Renamed gtk_window field to window. - Made the parent_class field in the EventEditorClass structure be a - GtkWindowClass, not a gnome property box class. - Added prototype for event_editor_get_type(). - -1998-04-06 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * gncal-week-view.c (gncal_week_view_new): Use the new - gtk_table_set_homogeneous() instead of setting the variable directly. - -1998-04-03 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * eventedit.c (ee_create_ae): Make it return void. - (ee_alarm_widgets): Remove some unused variables. - (ee_store_alarm): Make it return void. - #include <string.h> - - * eventedit.h: #include "gnome-cal.h" - - * calobj.c (list_free): Don't use g_free in the g_list_foreach. - - * calendar.h: Add prototype for calendar_load(). - - * timeutil.h: Add prototypes for time_add_*(). - - * calendar.c: - * calobj.c: - * eventedit.c: - * gnome-cal.c: #include "timeutil.h" - - * gncal-day-view.c (gncal_day_view_size_request): Make the minimum - width equal or larger to the title width. - - * main.c: #include "eventedit.h" - (main): Add a return statement. - (new_calendar): Show stuff *after* the calendar has been loaded. - - * gnome-cal.c (gnome_calendar_load): Update the day view. - (setup_widgets): Hackish setup of a day view widget - will fix later. - (gnome_calendar_init): Initialize all fields. - - * gnome-cal.h: Added day_view field. Maybe this should be changed - when the a complete day view panel is complete. - - * gncal-day-view.c (gncal_day_view_update): Draw after update, not - before. - -1998-04-06 Carsten Schaar <nhadcasc@fs-maphy.uni-hannover.de> - - * versit/.cvsignore: New file. - -Fri Apr 3 22:31:54 1998 Tom Tromey <tromey@cygnus.com> - - * calendar.c: Include <config.h>. - -1998-04-03 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * timeutil.c (time_add_year, time_add_year, time_add_week): - Routines for time manipulation. - - * calobj.c (ical_object_destroy): Full destruction of the object. - - * eventedit.c: Finished the main event editor form; It still - lacks the details and the recurrence bits. It now adds events - and cancels. - -1998-04-03 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * view-utils.c (view_utils_draw_events): The "better" format - string for strftime() wasn't better, after all :-( - -1998-04-02 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * gncal-full-day.c: New full-day widget. It is still a work in - progress. It will be similar to M$ Schedule's nifty full day view - widget, but with Gtk's elegance :-) - - * Makefile.am (gnomecal_SOURCES): Added gncal-full-day.[ch] to the sources. - -1998-04-02 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * eventedit.c: Object editor widget. We dropped ObjEdit. - - * timeutil.c (time_from_isodate): Fix. - - * view-utils.c (view_utils_draw_events): Changed the display - formats. - -1998-04-02 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * view-utils.c (view_utils_draw_events): Use better format - specifier for strftime(). - (view_utils_draw_textured_frame): Ultra-nifty function to draw - textured "metal" frames, like Netscape's handles. - -1998-04-02 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * gncal-day-view.c (gncal_day_view_update): Day events are now - cached inside the widget. They get initialized at this time. - - * view-utils.c (view_utils_draw_events): Use the list of events. - -1998-04-02 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * gncal-day-view.c (gncal_day_view_set_shadow): New customization - function. We can't decide on a stupid border type :-) - (gncal_day_view_init): Made GTK_SHADOW_ETCHED_IN be the default - shadow type. Looks good. - -1998-04-02 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * main.c: New main program that uses our new datatypes and - objects. - - * calendar.c (calendar_load_from_vobject, calendar_load): - Implement loading of vCalendar objects and vCalendar files. - - * calobj.c (ical_object_create_from_vobject): Implement loading of - vCalendar event and todo objects. - - * timeutil.c (isodate_from_time_t): New function. - - * gnome-cal.c, gnome-cal.h: Implement a toplevel widget, derived - from GnomeApp. It holds all of the day views and arbitrates the - display. - -1998-04-02 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * gncal-week-view.[ch]: New week view composite widget. This - provides a full week view (7 day views plus busy time display -- - the latter is currently unimplemented). - -1998-04-01 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * gncal-day-view.c: New day view widget. It is intended to be a - child widget of the week view composite widget. - - * calendar.c (calendar_get_objects_in_range): - (calendar_get_events_in_range): - (calendar_get_journal_in_range): - (calendar_get_journal_in_range): These functions now take a - sort_func parameter, which is of type GCompareFunc. If the - specified value is non-NULL, it will return a sorted list. - Otherwise, it will return an unordered list. - (calendar_compare_by_dtstart): Provide a generic sorting routine - for calendar objects. - -1998-04-01 Miguel de Icaza <miguel@kernel.org> - - * Start from scratch - -Tue Mar 31 23:46:50 1998 Tom Tromey <tromey@cygnus.com> - - * timeutil.c (format_simple_hour): `buf' now static. - -1998-03-31 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * gncal.c: Removed #include "gtkcalendar.h", because it now comes - from libgnomeui. - - * Makefile.am (gncal_SOURCES): Added new source files to the rules. - - * timeutil.c (format_simple_hour): New function, formats an - hour/am_pm pair into a string of the form "3am", "12pm", "05h", - "19h", etc. It is used by the day view widget for its labels. - -1998-03-31 Craig Small <csmall@small.dropbear.id.au> - - * Now has (non working) session maangement - * Uses a clist for the dailylist like gtt - -Sat Mar 21 15:43:20 1998 Tom Tromey <tromey@cygnus.com> - - * gncal.c: Use gnome_message_box_*, not gnome_messagebox_*. - -1998-03-12 Craig Small <csmall@small.dropbear.id.au> - - * Now linked (in some horrible way) to the gtkcalendar widget. - -Sun Mar 8 16:38:10 1998 Tom Tromey <tromey@cygnus.com> - - * Makefile.am (INCLUDES): Added GNOME_INCLUDEDIR. - (gncal_LDADD): Don't include libsupport.a. - - * gncal.c (main): Use new gnome_init. - -1998-02-19 Federico Mena Quintero <federico@nuclecu.unam.mx> - - * gncal.c (main): Added app_id "gncal". - -1998-02-19 Carsten Schaar <nhadcasc@fs-maphy.uni-hannover.de> - - * Makefile.am (gncal_LDADD): Added '$(INTLLIBS)' - -1998-02-18 Raja R Harinath <harinath@cs.umn.edu> - - * Makefile.am (gncal_LDADD): Include `libsupport.a'. - - * calcs.c (month_atoi): Replace buggy explicit loop string compare - with strcasecmp. - (day_atoi): Likewise. - -Sun Jan 25 23:38:30 1998 Miguel de Icaza <miguel@nuclecu.unam.mx> - - * menus.c: Replace "Quit" with "Exit". diff --git a/calendar/Makefile.am b/calendar/Makefile.am deleted file mode 100644 index e17d581184..0000000000 --- a/calendar/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ -if ENABLE_PILOT_CONDUITS -CONDUIT_DIR = conduits -else -CONDUIT_DIR = -endif - -SUBDIRS = idl cal-util pcs cal-client gui $(CONDUIT_DIR) diff --git a/calendar/TODO b/calendar/TODO deleted file mode 100644 index 4a5dd6c6ff..0000000000 --- a/calendar/TODO +++ /dev/null @@ -1,88 +0,0 @@ -Cal-util: - -- calobj.h depends on libversit/vcc.h, because it uses a VObject for - ical_object_create_from_vobject(). This should be an internal - function in the PCS and nothing else (we do not install libversit, - so our public libraries should not depend on it). - -- Or maybe we *should* install libversit, since the addressbook code - uses it as well. - -- timeutil has a lot of crap and some namespace pollution. Clean it - up. - -PCS: - -- When loading a calendar, substitute duplicated UIDs by new ones, and - possibly print out a warning message. - ------ Old Gnomecal TODO starts here ----- - -Pilot: - -* Better support for untimed events (we have none now). - -* Hash objects based on their UIDs. - -* Add placeholders for deleted events, so that we can kill those - when syncing to the pilot. - -BUGS: - -- Recurrence end date is wrong. An event that repeats daily will not - be included in the ending date of the recurrence (off-by-one - error?). - -- X-fields (extensions) are stripped from a vCal file when it is - saved. They should be preserved. - -Features: - -- Add a calendar-week so that people know which week of the year it is - -Year view: - -- See why it is so fucking slow when opening its notebook page for the - first time. - -Month view: - -- Popup menu like in the year view. - -- Double click on a day takes you to the day view. - -- DnD of appointments to move them around. - -Week view: - -- Nice display as in the Palm Pilot. - -Day view: - -- Rewrite in terms of the canvas and make it pretty. - -Preferences: - -- BUG: 12/24 hours stuff is not consistent - I remember that on editing - new appointment you get the time-selectors always on 12-hr format - -Event editor dialog: - -- Make it figure out whether the alarm is in - minutes/hours/days/etc. (via a cascade of conditions) and set the - widgets appropriately. - -Gnome date selection widget: - -- Make the displayed date be localized properly -- use strftime(). - -General: - -- Write online help. Nice help. Lots of help. - -- If you leave the calendar running overnight, the "current day" - marker in the GnomeMonthItems does not get updated. - -- Add categories support. Color-coded categories. - -- Untimed events diff --git a/calendar/cal-client/.cvsignore b/calendar/cal-client/.cvsignore deleted file mode 100644 index 1537e6e01d..0000000000 --- a/calendar/cal-client/.cvsignore +++ /dev/null @@ -1,15 +0,0 @@ -Makefile.in -.deps -.libs -.pure -Makefile -evolution-calendar-stubs.c -evolution-calendar-skels.c -evolution-calendar-common.c -evolution-calendar.h -evolution-calendar-common.lo -evolution-calendar-skels.lo -evolution-calendar-stubs.lo -*.lo -*.la -client-test diff --git a/calendar/cal-client/Makefile.am b/calendar/cal-client/Makefile.am deleted file mode 100644 index f241bf6ce1..0000000000 --- a/calendar/cal-client/Makefile.am +++ /dev/null @@ -1,78 +0,0 @@ -# -# libcal-client -# - -CORBA_GENERATED = \ - evolution-calendar.h \ - evolution-calendar-common.c \ - evolution-calendar-skels.c \ - evolution-calendar-stubs.c - -idls = \ - $(srcdir)/../idl/evolution-calendar.idl - -idl_flags = `$(GNOME_CONFIG) --cflags idl` -I $(datadir)/idl - -$(CORBA_GENERATED): $(idls) - $(ORBIT_IDL) $(idl_flags) $(srcdir)/../idl/evolution-calendar.idl - -INCLUDES = \ - -DGNOMELOCALEDIR=\""$(localedir)"\" \ - -DG_LOG_DOMAIN=\"cal-client\" \ - -I$(top_srcdir)/calendar \ - -I$(srcdir) -I$(top_srcdir) \ - -I. \ - -I.. \ - -I$(top_builddir) \ - -I$(top_builddir)/libical/src/libical \ - -I$(top_srcdir)/libical/src/libical \ - $(BONOBO_GNOME_CFLAGS) - -lib_LTLIBRARIES = libcal-client.la - -libcal_clientincludedir = $(includedir)/evolution/cal-client - -libcal_client_la_SOURCES = \ - $(CORBA_GENERATED) \ - cal-client-types.c \ - cal-client.c \ - cal-listener.c \ - cal-listener.h - -libcal_clientinclude_HEADERS = \ - cal-client-types.h \ - cal-client.h - - -# -# make a static library for use by calendar conduit's shared library -# -noinst_LTLIBRARIES = libcal-client-static.la -libcal_client_static_la_SOURCES = $(libcal_client_la_SOURCES) -libcal_client_static_la_LDFLAGS = --all-static - - -# -# client-test program -# - -noinst_PROGRAMS = client-test - -client_test_SOURCES = \ - client-test.c - -client_test_INCLUDES = \ - $(INCLUDES) \ - -DG_LOG_DOMAIN=\"client-test\" - -client_test_LDADD = \ - $(BONOBO_VFS_GNOME_LIBS) \ - $(EXTRA_GNOME_LIBS) \ - -lunicode \ - $(top_builddir)/calendar/cal-util/libcal-util.la \ - $(top_builddir)/libversit/libversit.la \ - $(top_builddir)/libical/src/libical/libical.la \ - libcal-client.la - -BUILT_SOURCES = $(CORBA_GENERATED) -CLEANFILES += $(BUILT_SOURCES) diff --git a/calendar/cal-client/cal-client-types.c b/calendar/cal-client/cal-client-types.c deleted file mode 100644 index 23aa14475f..0000000000 --- a/calendar/cal-client/cal-client-types.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Evolution calendar utilities and types - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#include <config.h> -#include <stdlib.h> -#include "cal-client-types.h" - - - -/** - * cal_client_change_list_free: - * @list: List of #CalClientChange structures. - * - * Frees a list of #CalClientChange structures. - **/ -void -cal_client_change_list_free (GList *list) -{ - CalClientChange *c; - GList *l; - - for (l = list; l; l = l->next) { - c = l->data; - - g_assert (c != NULL); - g_assert (c->comp != NULL); - - gtk_object_unref (GTK_OBJECT (c->comp)); - g_free (c); - } - - g_list_free (list); -} diff --git a/calendar/cal-client/cal-client-types.h b/calendar/cal-client/cal-client-types.h deleted file mode 100644 index c356f2378e..0000000000 --- a/calendar/cal-client/cal-client-types.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Evolution calendar utilities and types - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef CAL_CLIENT_TYPES_H -#define CAL_CLIENT_TYPES_H - -#include <libgnome/gnome-defs.h> -#include <cal-util/cal-component.h> - -BEGIN_GNOME_DECLS - - - -typedef enum { - CAL_CLIENT_CHANGE_ADDED = 1 << 0, - CAL_CLIENT_CHANGE_MODIFIED = 1 << 1, - CAL_CLIENT_CHANGE_DELETED = 1 << 2 -} CalClientChangeType; - -typedef struct -{ - CalComponent *comp; - CalClientChangeType type; -} CalClientChange; - -void cal_client_change_list_free (GList *list); - -END_GNOME_DECLS - -#endif - diff --git a/calendar/cal-client/cal-client.c b/calendar/cal-client/cal-client.c deleted file mode 100644 index 0012ec3706..0000000000 --- a/calendar/cal-client/cal-client.c +++ /dev/null @@ -1,1515 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Evolution calendar client - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#include <config.h> -#include <gtk/gtksignal.h> -#include <liboaf/liboaf.h> - -#include "cal-client-types.h" -#include "cal-client.h" -#include "cal-listener.h" - - - -/* Private part of the CalClient structure */ -struct _CalClientPrivate { - /* Load state to avoid multiple loads */ - CalClientLoadState load_state; - - /* URI of the calendar that is being loaded or is already loaded, or - * NULL if we are not loaded. - */ - char *uri; - - /* The calendar factory we are contacting */ - GNOME_Evolution_Calendar_CalFactory factory; - - /* Our calendar listener */ - CalListener *listener; - - /* The calendar client interface object we are contacting */ - GNOME_Evolution_Calendar_Cal cal; -}; - - - -/* Signal IDs */ -enum { - CAL_OPENED, - OBJ_UPDATED, - OBJ_REMOVED, - LAST_SIGNAL -}; - -static void cal_client_class_init (CalClientClass *class); -static void cal_client_init (CalClient *client); -static void cal_client_destroy (GtkObject *object); - -static guint cal_client_signals[LAST_SIGNAL]; - -static GtkObjectClass *parent_class; - - - -/** - * cal_client_get_type: - * @void: - * - * Registers the #CalClient class if necessary, and returns the type ID assigned - * to it. - * - * Return value: The type ID of the #CalClient class. - **/ -GtkType -cal_client_get_type (void) -{ - static GtkType cal_client_type = 0; - - if (!cal_client_type) { - static const GtkTypeInfo cal_client_info = { - "CalClient", - sizeof (CalClient), - sizeof (CalClientClass), - (GtkClassInitFunc) cal_client_class_init, - (GtkObjectInitFunc) cal_client_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - cal_client_type = gtk_type_unique (GTK_TYPE_OBJECT, &cal_client_info); - } - - return cal_client_type; -} - -/* Class initialization function for the calendar client */ -static void -cal_client_class_init (CalClientClass *class) -{ - GtkObjectClass *object_class; - - object_class = (GtkObjectClass *) class; - - parent_class = gtk_type_class (GTK_TYPE_OBJECT); - - cal_client_signals[CAL_OPENED] = - gtk_signal_new ("cal_opened", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (CalClientClass, cal_opened), - gtk_marshal_NONE__ENUM, - GTK_TYPE_NONE, 1, - GTK_TYPE_ENUM); - cal_client_signals[OBJ_UPDATED] = - gtk_signal_new ("obj_updated", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (CalClientClass, obj_updated), - gtk_marshal_NONE__STRING, - GTK_TYPE_NONE, 1, - GTK_TYPE_STRING); - cal_client_signals[OBJ_REMOVED] = - gtk_signal_new ("obj_removed", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (CalClientClass, obj_removed), - gtk_marshal_NONE__STRING, - GTK_TYPE_NONE, 1, - GTK_TYPE_STRING); - - gtk_object_class_add_signals (object_class, cal_client_signals, LAST_SIGNAL); - - object_class->destroy = cal_client_destroy; -} - -/* Object initialization function for the calendar client */ -static void -cal_client_init (CalClient *client) -{ - CalClientPrivate *priv; - - priv = g_new0 (CalClientPrivate, 1); - client->priv = priv; - - priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED; - priv->uri = NULL; - priv->factory = CORBA_OBJECT_NIL; -} - -/* Gets rid of the factory that a client knows about */ -static void -destroy_factory (CalClient *client) -{ - CalClientPrivate *priv; - CORBA_Environment ev; - int result; - - priv = client->priv; - - CORBA_exception_init (&ev); - result = CORBA_Object_is_nil (priv->factory, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("destroy_factory(): could not see if the factory was nil"); - priv->factory = CORBA_OBJECT_NIL; - CORBA_exception_free (&ev); - return; - } - CORBA_exception_free (&ev); - - if (result) - return; - - CORBA_exception_init (&ev); - CORBA_Object_release (priv->factory, &ev); - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("destroy_factory(): could not release the factory"); - - CORBA_exception_free (&ev); - priv->factory = CORBA_OBJECT_NIL; -} - -/* Gets rid of the listener that a client knows about */ -static void -destroy_listener (CalClient *client) -{ - CalClientPrivate *priv; - - priv = client->priv; - - if (!priv->listener) - return; - - bonobo_object_unref (BONOBO_OBJECT (priv->listener)); - priv->listener = NULL; -} - -/* Gets rid of the calendar client interface object that a client knows about */ -static void -destroy_cal (CalClient *client) -{ - CalClientPrivate *priv; - CORBA_Environment ev; - int result; - - priv = client->priv; - - CORBA_exception_init (&ev); - result = CORBA_Object_is_nil (priv->cal, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("destroy_cal(): could not see if the " - "calendar client interface object was nil"); - priv->cal = CORBA_OBJECT_NIL; - CORBA_exception_free (&ev); - return; - } - CORBA_exception_free (&ev); - - if (result) - return; - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_Cal_unref (priv->cal, &ev); - if (ev._major != CORBA_NO_EXCEPTION) - 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 (ev._major != CORBA_NO_EXCEPTION) - g_message ("destroy_cal(): could not release the calendar client interface object"); - - CORBA_exception_free (&ev); - priv->cal = CORBA_OBJECT_NIL; - -} - -/* Destroy handler for the calendar client */ -static void -cal_client_destroy (GtkObject *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; - - destroy_factory (client); - destroy_listener (client); - destroy_cal (client); - - priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED; - - if (priv->uri) { - g_free (priv->uri); - priv->uri = NULL; - } - - g_free (priv); - client->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - - -/* 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) -{ - CalClient *client; - CalClientPrivate *priv; - CORBA_Environment ev; - GNOME_Evolution_Calendar_Cal cal_copy; - CalClientOpenStatus client_status; - - client = CAL_CLIENT (data); - priv = client->priv; - - g_assert (priv->load_state == CAL_CLIENT_LOAD_LOADING); - g_assert (priv->uri != NULL); - - client_status = CAL_CLIENT_OPEN_ERROR; - - switch (status) { - case GNOME_Evolution_Calendar_Listener_SUCCESS: - CORBA_exception_init (&ev); - cal_copy = CORBA_Object_duplicate (cal, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("cal_opened_cb(): could not duplicate the " - "calendar client interface"); - CORBA_exception_free (&ev); - goto error; - } - CORBA_exception_free (&ev); - - priv->cal = cal_copy; - priv->load_state = CAL_CLIENT_LOAD_LOADED; - - client_status = CAL_CLIENT_OPEN_SUCCESS; - goto out; - - case GNOME_Evolution_Calendar_Listener_ERROR: - client_status = CAL_CLIENT_OPEN_ERROR; - goto error; - - case GNOME_Evolution_Calendar_Listener_NOT_FOUND: - client_status = CAL_CLIENT_OPEN_NOT_FOUND; - goto error; - - case GNOME_Evolution_Calendar_Listener_METHOD_NOT_SUPPORTED: - client_status = CAL_CLIENT_OPEN_METHOD_NOT_SUPPORTED; - goto error; - - default: - g_assert_not_reached (); - } - - error: - - bonobo_object_unref (BONOBO_OBJECT (priv->listener)); - priv->listener = NULL; - - /* 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. - */ - - out: - - /* 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. - */ - - gtk_object_ref (GTK_OBJECT (client)); - - gtk_signal_emit (GTK_OBJECT (client), cal_client_signals[CAL_OPENED], - client_status); - - if (client_status != CAL_CLIENT_OPEN_SUCCESS) { - priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED; - g_free (priv->uri); - priv->uri = NULL; - } - - g_assert (priv->load_state != CAL_CLIENT_LOAD_LOADING); - - gtk_object_unref (GTK_OBJECT (client)); -} - -/* Handle the obj_updated signal from the listener */ -static void -obj_updated_cb (CalListener *listener, const GNOME_Evolution_Calendar_CalObjUID uid, gpointer data) -{ - CalClient *client; - - client = CAL_CLIENT (data); - gtk_signal_emit (GTK_OBJECT (client), cal_client_signals[OBJ_UPDATED], uid); -} - -/* Handle the obj_removed signal from the listener */ -static void -obj_removed_cb (CalListener *listener, const GNOME_Evolution_Calendar_CalObjUID uid, gpointer data) -{ - CalClient *client; - - client = CAL_CLIENT (data); - gtk_signal_emit (GTK_OBJECT (client), cal_client_signals[OBJ_REMOVED], uid); -} - - - -/** - * cal_client_construct: - * @client: A calendar client. - * - * Constructs a calendar client object by contacting the calendar factory of the - * calendar server. - * - * Return value: The same object as the @client argument, or NULL if the - * calendar factory could not be contacted. - **/ -CalClient * -cal_client_construct (CalClient *client) -{ - CalClientPrivate *priv; - GNOME_Evolution_Calendar_CalFactory factory, factory_copy; - CORBA_Environment ev; - int result; - - CORBA_exception_init (&ev); - g_return_val_if_fail (client != NULL, NULL); - g_return_val_if_fail (IS_CAL_CLIENT (client), NULL); - - priv = client->priv; - - factory = (GNOME_Evolution_Calendar_CalFactory) oaf_activate_from_id ( - "OAFIID:GNOME_Evolution_Wombat_CalendarFactory", - OAF_FLAG_NO_LOCAL, NULL, &ev); - - result = CORBA_Object_is_nil (factory, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("cal_client_construct(): could not see if the factory is NIL"); - CORBA_exception_free (&ev); - return NULL; - } - CORBA_exception_free (&ev); - - if (result) { - g_message ("cal_client_construct(): could not contact Wombat, " - "the personal calendar server"); - return NULL; - } - - CORBA_exception_init (&ev); - factory_copy = CORBA_Object_duplicate (factory, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("cal_client_construct(): could not duplicate the calendar factory"); - CORBA_exception_free (&ev); - return NULL; - } - CORBA_exception_free (&ev); - - priv->factory = factory_copy; - return client; -} - -/** - * cal_client_new: - * - * Creates a new calendar client. It should be initialized by calling - * cal_client_open_calendar(). - * - * 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) -{ - CalClient *client; - - client = gtk_type_new (CAL_CLIENT_TYPE); - - if (!cal_client_construct (client)) { - g_message ("cal_client_new(): could not construct the calendar client"); - gtk_object_unref (GTK_OBJECT (client)); - return NULL; - } - - return client; -} - -/** - * cal_client_open_calendar: - * @client: A calendar client. - * @str_uri: URI of calendar to open. - * @only_if_exists: FALSE if the calendar should be opened even if there - * was no storage for it, i.e. to create a new calendar or load an existing - * one if it already exists. TRUE if it should only try to load calendars - * that already exist. - * - * Makes a calendar client initiate a request to open a calendar. The calendar - * client will emit the "cal_opened" signal when the response from the server is - * received. - * - * 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) -{ - CalClientPrivate *priv; - GNOME_Evolution_Calendar_Listener corba_listener; - CORBA_Environment ev; - - 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_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, - obj_updated_cb, - obj_removed_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_object_corba_objref ( - BONOBO_OBJECT (priv->listener)); - - CORBA_exception_init (&ev); - - priv->load_state = CAL_CLIENT_LOAD_LOADING; - priv->uri = g_strdup (str_uri); - - GNOME_Evolution_Calendar_CalFactory_open (priv->factory, str_uri, only_if_exists, - corba_listener, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - CORBA_exception_free (&ev); - - g_message ("cal_client_open_calendar(): open request failed"); - 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; - } - CORBA_exception_free (&ev); - - return TRUE; -} - -/** - * cal_client_get_load_state: - * @client: A calendar client. - * - * Queries the state of loading of a calendar client. - * - * Return value: A #CalClientLoadState value indicating whether the client has - * not been loaded with cal_client_open_calendar() yet, whether it is being - * loaded, or whether it is already loaded. - **/ -CalClientLoadState -cal_client_get_load_state (CalClient *client) -{ - CalClientPrivate *priv; - - g_return_val_if_fail (client != NULL, FALSE); - g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE); - - priv = client->priv; - return priv->load_state; -} - -/** - * cal_client_get_uri: - * @client: A calendar client. - * - * Queries the URI that is open in a calendar client. - * - * Return value: The URI of the calendar that is already loaded or is being - * loaded, or NULL if the client has not started a load request yet. - **/ -const char * -cal_client_get_uri (CalClient *client) -{ - CalClientPrivate *priv; - - g_return_val_if_fail (client != NULL, NULL); - g_return_val_if_fail (IS_CAL_CLIENT (client), NULL); - - priv = client->priv; - return priv->uri; -} - -/* 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)); -} - -/** - * 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 (ev._major != CORBA_NO_EXCEPTION) { - 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; -} - -/** - * cal_client_get_object: - * @client: A calendar client. - * @uid: Unique identifier for a calendar component. - * @comp: Return value for the calendar component object. - * - * Queries a calendar for a calendar component object based on its unique - * identifier. - * - * Return value: Result code based on the status of the operation. - **/ -CalClientGetStatus -cal_client_get_object (CalClient *client, const char *uid, CalComponent **comp) -{ - CalClientPrivate *priv; - CORBA_Environment ev; - GNOME_Evolution_Calendar_CalObj comp_str; - CalClientGetStatus retval; - icalcomponent *icalcomp; - - 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 (uid != NULL, CAL_CLIENT_GET_NOT_FOUND); - g_return_val_if_fail (comp != NULL, CAL_CLIENT_GET_NOT_FOUND); - - retval = CAL_CLIENT_GET_NOT_FOUND; - *comp = NULL; - - CORBA_exception_init (&ev); - comp_str = GNOME_Evolution_Calendar_Cal_getObject (priv->cal, (char *) uid, &ev); - - if (ev._major == CORBA_USER_EXCEPTION - && strcmp (CORBA_exception_id (&ev), ex_GNOME_Evolution_Calendar_Cal_NotFound) == 0) - goto out; - else if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("cal_client_get_object(): 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; - } - - *comp = cal_component_new (); - if (!cal_component_set_icalcomponent (*comp, icalcomp)) { - icalcomponent_free (icalcomp); - gtk_object_unref (GTK_OBJECT (*comp)); - *comp = NULL; - - retval = CAL_CLIENT_GET_SYNTAX_ERROR; - goto out; - } - - retval = CAL_CLIENT_GET_SUCCESS; - - out: - - CORBA_exception_free (&ev); - return retval; -} - -/* 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) -{ - CalClientPrivate *priv; - CORBA_Environment ev; - GNOME_Evolution_Calendar_CalObjUIDSeq *seq; - int t; - GList *uids; - - g_return_val_if_fail (client != NULL, NULL); - g_return_val_if_fail (IS_CAL_CLIENT (client), NULL); - - priv = client->priv; - g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL); - - t = corba_obj_type (type); - - CORBA_exception_init (&ev); - - seq = GNOME_Evolution_Calendar_Cal_getUIds (priv->cal, t, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("cal_client_get_uids(): could not get the list of UIDs"); - CORBA_exception_free (&ev); - return NULL; - } - - CORBA_exception_free (&ev); - - uids = build_uid_list (seq); - CORBA_free (seq); - - return uids; -} - -/* 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; - - /* 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); - gtk_object_unref (GTK_OBJECT (ccc->comp)); - continue; - } - ccc->type = corba_coc->type; - - list = g_list_prepend (list, ccc); - } - - list = g_list_reverse (list); - - return list; -} - -GList * -cal_client_get_changes (CalClient *client, CalObjType type, const char *change_id) -{ - CalClientPrivate *priv; - CORBA_Environment ev; - GNOME_Evolution_Calendar_CalObjChangeSeq *seq; - int t; - GList *changes; - - g_return_val_if_fail (client != NULL, NULL); - g_return_val_if_fail (IS_CAL_CLIENT (client), NULL); - - priv = client->priv; - g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL); - - t = corba_obj_type (type); - CORBA_exception_init (&ev); - - seq = GNOME_Evolution_Calendar_Cal_getChanges (priv->cal, t, change_id, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("cal_client_get_changes(): could not get the list of changes"); - CORBA_exception_free (&ev); - return NULL; - } - - CORBA_exception_free (&ev); - - changes = build_change_list (seq); - CORBA_free (seq); - - return changes; -} - -/* 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; - - /* Create the list in reverse order */ - - list = NULL; - for (i = 0; i < seq->_length; i++) { - GNOME_Evolution_Calendar_CalObjInstance *corba_icoi; - CalObjInstance *icoi; - - corba_icoi = &seq->_buffer[i]; - icoi = g_new (CalObjInstance, 1); - - icoi->uid = g_strdup (corba_icoi->uid); - icoi->start = corba_icoi->start; - icoi->end = corba_icoi->end; - - list = g_list_prepend (list, icoi); - } - - 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); - - priv = client->priv; - g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL); - - g_return_val_if_fail (start != -1 && end != -1, NULL); - g_return_val_if_fail (start <= end, NULL); - - CORBA_exception_init (&ev); - - t = corba_obj_type (type); - - seq = GNOME_Evolution_Calendar_Cal_getObjectsInRange (priv->cal, t, start, end, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("cal_client_get_objects_in_range(): could not get the objects"); - CORBA_exception_free (&ev); - return NULL; - } - CORBA_exception_free (&ev); - - uids = build_uid_list (seq); - CORBA_free (seq); - - return uids; -} - -/* 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; - 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); - gtk_object_unref (GTK_OBJECT (comp)); - - status = cal_client_get_object (client, uid, &comp); - - switch (status) { - case CAL_CLIENT_GET_SUCCESS: - /* 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); - 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); - gtk_object_unref (GTK_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 = gtk_signal_connect (GTK_OBJECT (client), "obj_updated", - GTK_SIGNAL_FUNC (generate_instances_obj_updated_cb), - uid_comp_hash); - - obj_removed_id = gtk_signal_connect (GTK_OBJECT (client), "obj_removed", - GTK_SIGNAL_FUNC (generate_instances_obj_removed_cb), - uid_comp_hash); - - /* Get the objects */ - - for (l = uids; l; l = l->next) { - CalComponent *comp; - CalClientGetStatus status; - char *uid; - const char *comp_uid; - - uid = l->data; - - status = cal_client_get_object (client, uid, &comp); - - switch (status) { - case CAL_CLIENT_GET_SUCCESS: - /* 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); - 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. - */ - - gtk_signal_disconnect (GTK_OBJECT (client), obj_updated_id); - gtk_signal_disconnect (GTK_OBJECT (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; -} - -struct comp_instance { - CalComponent *comp; - time_t start; - time_t end; -}; - -/* Called from cal_recur_generate_instances(); adds an instance to the list */ -static gboolean -add_instance (CalComponent *comp, time_t start, time_t end, gpointer data) -{ - GList **list; - struct comp_instance *ci; - - list = data; - - ci = g_new (struct comp_instance, 1); - - ci->comp = comp; - gtk_object_ref (GTK_OBJECT (ci->comp)); - - ci->start = start; - ci->end = end; - - *list = g_list_prepend (*list, ci); - - return TRUE; -} - -/* Used from g_list_sort(); compares two struct comp_instance structures */ -static gint -compare_comp_instance (gconstpointer a, gconstpointer b) -{ - const struct comp_instance *cia, *cib; - time_t diff; - - cia = a; - cib = b; - - diff = cia->start - cib->start; - return (diff < 0) ? -1 : (diff > 0) ? 1 : 0; -} - -/** - * cal_client_generate_instances: - * @client: A calendar client. - * @type: Bitmask with types of objects to return. - * @start: Start time for query. - * @end: End time for query. - * @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. - * - * The callback function should do a gtk_object_ref() of the calendar component - * it gets passed if it intends to keep it around. - **/ -void -cal_client_generate_instances (CalClient *client, CalObjType type, - time_t start, time_t end, - CalRecurInstanceFn cb, gpointer cb_data) -{ - CalClientPrivate *priv; - GList *objects; - GList *instances; - GList *l; - - g_return_if_fail (client != NULL); - g_return_if_fail (IS_CAL_CLIENT (client)); - - priv = client->priv; - g_return_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED); - - g_return_if_fail (start != -1 && end != -1); - g_return_if_fail (start <= end); - g_return_if_fail (cb != NULL); - - /* Generate objects */ - - objects = get_objects_atomically (client, type, start, end); - instances = NULL; - - for (l = objects; l; l = l->next) { - CalComponent *comp; - - comp = l->data; - cal_recur_generate_instances (comp, start, end, add_instance, &instances); - gtk_object_unref (GTK_OBJECT (comp)); - } - - g_list_free (objects); - - /* Generate instances and spew them out */ - - instances = g_list_sort (instances, compare_comp_instance); - - for (l = instances; l; l = l->next) { - struct comp_instance *ci; - gboolean result; - - ci = l->data; - - result = (* cb) (ci->comp, ci->start, ci->end, cb_data); - - if (!result) - break; - } - - /* Clean up */ - - for (l = instances; l; l = l->next) { - struct comp_instance *ci; - - ci = l->data; - gtk_object_unref (GTK_OBJECT (ci->comp)); - g_free (ci); - } - - 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 = corba_instance->occur; - - 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) -{ - GSList *comp_alarms; - int i; - - comp_alarms = NULL; - - for (i = 0; i < seq->_length; i++) { - GNOME_Evolution_Calendar_CalComponentAlarms *corba_alarms; - CalComponent *comp; - CalComponentAlarms *alarms; - icalcomponent *icalcomp; - - corba_alarms = seq->_buffer + i; - - icalcomp = icalparser_parse_string (corba_alarms->calobj); - if (!icalcomp) - continue; - - comp = cal_component_new (); - if (!cal_component_set_icalcomponent (comp, icalcomp)) { - icalcomponent_free (icalcomp); - gtk_object_unref (GTK_OBJECT (comp)); - 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); - } - - return comp_alarms; -} - -/** - * cal_client_get_alarms_in_range: - * @client: A calendar client. - * @start: Start time for query. - * @end: End time for query. - * - * Queries a calendar for the alarms that trigger in the specified range of - * time. - * - * Return value: A list of #CalComponentAlarms structures. This should be freed - * using the cal_client_free_alarms() function, or by freeing each element - * separately with cal_component_alarms_free() and then freeing the list with - * g_slist_free(). - **/ -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; - - g_return_val_if_fail (client != NULL, NULL); - g_return_val_if_fail (IS_CAL_CLIENT (client), NULL); - - priv = client->priv; - g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL); - - g_return_val_if_fail (start != -1 && end != -1, NULL); - g_return_val_if_fail (start <= end, NULL); - - CORBA_exception_init (&ev); - - seq = GNOME_Evolution_Calendar_Cal_getAlarmsInRange (priv->cal, start, end, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("cal_client_get_alarms_in_range(): could not get the alarm range"); - CORBA_exception_free (&ev); - return NULL; - } - CORBA_exception_free (&ev); - - alarms = build_component_alarms_list (seq); - CORBA_free (seq); - - return alarms; -} - -/** - * cal_client_free_alarms: - * @comp_alarms: A list of #CalComponentAlarms structures. - * - * Frees a list of #CalComponentAlarms structures as returned by - * cal_client_get_alarms_in_range(). - **/ -void -cal_client_free_alarms (GSList *comp_alarms) -{ - GSList *l; - - for (l = comp_alarms; l; l = l->next) { - CalComponentAlarms *alarms; - - alarms = l->data; - g_assert (alarms != NULL); - - cal_component_alarms_free (alarms); - } - - g_slist_free (comp_alarms); -} - -/** - * cal_client_get_alarms_for_object: - * @client: A calendar client. - * @uid: Unique identifier for a calendar component. - * @start: Start time for query. - * @end: End time for query. - * @alarms: Return value for the component's alarm instances. Will return NULL - * if no instances occur within the specified time range. This should be freed - * using the cal_component_alarms_free() function. - * - * Queries a calendar for the alarms of a particular object that trigger in the - * specified range of time. - * - * Return value: TRUE on success, FALSE if the object was not found. - **/ -gboolean -cal_client_get_alarms_for_object (CalClient *client, const char *uid, - time_t start, time_t end, - CalComponentAlarms **alarms) -{ - CalClientPrivate *priv; - CORBA_Environment ev; - GNOME_Evolution_Calendar_CalComponentAlarms *corba_alarms; - gboolean retval; - icalcomponent *icalcomp; - CalComponent *comp; - - 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, FALSE); - - g_return_val_if_fail (uid != NULL, FALSE); - g_return_val_if_fail (start != -1 && end != -1, FALSE); - g_return_val_if_fail (start <= end, FALSE); - 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 (ev._major == CORBA_USER_EXCEPTION - && strcmp (CORBA_exception_id (&ev), ex_GNOME_Evolution_Calendar_Cal_NotFound) == 0) - goto out; - else if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("cal_client_get_alarms_for_object(): could not get the alarm range"); - goto out; - } - - icalcomp = icalparser_parse_string (corba_alarms->calobj); - if (!icalcomp) - goto out; - - comp = cal_component_new (); - if (!cal_component_set_icalcomponent (comp, icalcomp)) { - icalcomponent_free (icalcomp); - gtk_object_unref (GTK_OBJECT (comp)); - goto out; - } - - retval = TRUE; - - *alarms = g_new (CalComponentAlarms, 1); - (*alarms)->comp = comp; - (*alarms)->alarms = build_alarm_instance_list (comp, &corba_alarms->alarms); - CORBA_free (corba_alarms); - - out: - CORBA_exception_free (&ev); - return retval; -} - -/** - * 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: TRUE on success, FALSE on specifying an invalid component. - **/ -gboolean -cal_client_update_object (CalClient *client, CalComponent *comp) -{ - CalClientPrivate *priv; - CORBA_Environment ev; - gboolean retval; - char *obj_string; - const char *uid; - - 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, FALSE); - - g_return_val_if_fail (comp != NULL, FALSE); - - retval = FALSE; - - cal_component_commit_sequence (comp); - obj_string = cal_component_get_as_string (comp); - - cal_component_get_uid (comp, &uid); - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_Cal_updateObject (priv->cal, (char *) uid, obj_string, &ev); - g_free (obj_string); - - if (ev._major == CORBA_USER_EXCEPTION && - strcmp (CORBA_exception_id (&ev), ex_GNOME_Evolution_Calendar_Cal_InvalidObject) == 0) - goto out; - else if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("cal_client_update_object(): could not update the object"); - goto out; - } - - retval = TRUE; - - out: - CORBA_exception_free (&ev); - return retval; -} - -/** - * cal_client_remove_object: - * @client: A calendar client. - * @uid: Unique identifier of the calendar component to remove. - * - * Asks a calendar to remove a component. If the server is able to remove the - * component, all clients will be notified and they will emit the "obj_removed" - * signal. - * - * Return value: TRUE on success, FALSE on specifying a UID for a component that - * is not in the server. Returning FALSE is normal; the object may have - * disappeared from the server before the client has had a chance to receive the - * corresponding notification. - **/ -gboolean -cal_client_remove_object (CalClient *client, const char *uid) -{ - CalClientPrivate *priv; - CORBA_Environment ev; - gboolean retval; - - 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, FALSE); - - g_return_val_if_fail (uid != NULL, FALSE); - - retval = FALSE; - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_Cal_removeObject (priv->cal, (char *) uid, &ev); - - if (ev._major == CORBA_USER_EXCEPTION && - strcmp (CORBA_exception_id (&ev), ex_GNOME_Evolution_Calendar_Cal_NotFound) == 0) - goto out; - else if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("cal_client_remove_object(): could not remove the object"); - goto out; - } - - retval = TRUE; - - out: - CORBA_exception_free (&ev); - return retval; -} diff --git a/calendar/cal-client/cal-client.h b/calendar/cal-client/cal-client.h deleted file mode 100644 index 9e17b22b2b..0000000000 --- a/calendar/cal-client/cal-client.h +++ /dev/null @@ -1,131 +0,0 @@ -/* Evolution calendar client - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef CAL_CLIENT_H -#define CAL_CLIENT_H - -#include <libgnome/gnome-defs.h> -#include <gtk/gtkobject.h> -#include <cal-util/cal-recur.h> -#include <cal-util/cal-util.h> - -BEGIN_GNOME_DECLS - - - -#define CAL_CLIENT_TYPE (cal_client_get_type ()) -#define CAL_CLIENT(obj) (GTK_CHECK_CAST ((obj), CAL_CLIENT_TYPE, CalClient)) -#define CAL_CLIENT_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), CAL_CLIENT_TYPE, CalClientClass)) -#define IS_CAL_CLIENT(obj) (GTK_CHECK_TYPE ((obj), CAL_CLIENT_TYPE)) -#define IS_CAL_CLIENT_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), CAL_CLIENT_TYPE)) - -typedef struct _CalClient CalClient; -typedef struct _CalClientClass CalClientClass; - -typedef struct _CalClientPrivate CalClientPrivate; - -/* Open status for the cal_opened signal */ -typedef enum { - CAL_CLIENT_OPEN_SUCCESS, - CAL_CLIENT_OPEN_ERROR, - CAL_CLIENT_OPEN_NOT_FOUND, - CAL_CLIENT_OPEN_METHOD_NOT_SUPPORTED -} CalClientOpenStatus; - -/* Get status for the cal_client_get_object() function */ -typedef enum { - CAL_CLIENT_GET_SUCCESS, - CAL_CLIENT_GET_NOT_FOUND, - CAL_CLIENT_GET_SYNTAX_ERROR -} CalClientGetStatus; - -/* Whether the client is not loaded, is being loaded, or is already loaded */ -typedef enum { - CAL_CLIENT_LOAD_NOT_LOADED, - CAL_CLIENT_LOAD_LOADING, - CAL_CLIENT_LOAD_LOADED -} CalClientLoadState; - - -struct _CalClient { - GtkObject object; - - /* Private data */ - CalClientPrivate *priv; -}; - -struct _CalClientClass { - GtkObjectClass parent_class; - - /* Notification signals */ - - void (* cal_opened) (CalClient *client, CalClientOpenStatus status); - - void (* obj_updated) (CalClient *client, const char *uid); - void (* obj_removed) (CalClient *client, const char *uid); -}; - -GtkType cal_client_get_type (void); - -CalClient *cal_client_construct (CalClient *client); - -CalClient *cal_client_new (void); - -gboolean cal_client_open_calendar (CalClient *client, const char *str_uri, gboolean only_if_exists); - -CalClientLoadState cal_client_get_load_state (CalClient *client); - -const char *cal_client_get_uri (CalClient *client); - -int cal_client_get_n_objects (CalClient *client, CalObjType type); - -CalClientGetStatus cal_client_get_object (CalClient *client, - const char *uid, - CalComponent **comp); - -GList *cal_client_get_uids (CalClient *client, CalObjType type); -GList *cal_client_get_changes (CalClient *client, CalObjType type, const char *change_id); - -GList *cal_client_get_objects_in_range (CalClient *client, CalObjType type, - time_t start, time_t end); - -void cal_client_generate_instances (CalClient *client, CalObjType type, - time_t start, time_t end, - CalRecurInstanceFn cb, gpointer cb_data); - -GSList *cal_client_get_alarms_in_range (CalClient *client, time_t start, time_t end); - -void cal_client_free_alarms (GSList *comp_alarms); - -gboolean cal_client_get_alarms_for_object (CalClient *client, const char *uid, - time_t start, time_t end, - CalComponentAlarms **alarms); - -gboolean cal_client_update_object (CalClient *client, CalComponent *comp); - -gboolean cal_client_remove_object (CalClient *client, const char *uid); - - - -END_GNOME_DECLS - -#endif diff --git a/calendar/cal-client/cal-listener.c b/calendar/cal-client/cal-listener.c deleted file mode 100644 index b5c3bdbd6b..0000000000 --- a/calendar/cal-client/cal-listener.c +++ /dev/null @@ -1,388 +0,0 @@ -/* Evolution calendar listener - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#include <config.h> -#include <gtk/gtksignal.h> -#include "cal-listener.h" - - - -/* Private part of the CalListener structure */ -struct _CalListenerPrivate { - /* The calendar this listener refers to */ - GNOME_Evolution_Calendar_Cal cal; - - /* Notification functions and their closure data */ - CalListenerCalOpenedFn cal_opened_fn; - CalListenerObjUpdatedFn obj_updated_fn; - CalListenerObjRemovedFn obj_removed_fn; - gpointer fn_data; -}; - - - -static void cal_listener_class_init (CalListenerClass *class); -static void cal_listener_init (CalListener *listener); -static void cal_listener_destroy (GtkObject *object); - -static POA_GNOME_Evolution_Calendar_Listener__vepv cal_listener_vepv; - -static BonoboObjectClass *parent_class; - - - -/** - * cal_listener_get_type: - * @void: - * - * Registers the #CalListener class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the #CalListener class. - **/ -GtkType -cal_listener_get_type (void) -{ - static GtkType cal_listener_type = 0; - - if (!cal_listener_type) { - static const GtkTypeInfo cal_listener_info = { - "CalListener", - sizeof (CalListener), - sizeof (CalListenerClass), - (GtkClassInitFunc) cal_listener_class_init, - (GtkObjectInitFunc) cal_listener_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - cal_listener_type = gtk_type_unique (bonobo_object_get_type (), &cal_listener_info); - } - - return cal_listener_type; -} - -/* CORBA class initialization function for the calendar listener */ -static void -init_cal_listener_corba_class (void) -{ - cal_listener_vepv.Bonobo_Unknown_epv = bonobo_object_get_epv (); - cal_listener_vepv.GNOME_Evolution_Calendar_Listener_epv = cal_listener_get_epv (); -} - -/* Class initialization function for the calendar listener */ -static void -cal_listener_class_init (CalListenerClass *class) -{ - GtkObjectClass *object_class; - - object_class = (GtkObjectClass *) class; - - parent_class = gtk_type_class (bonobo_object_get_type ()); - - object_class->destroy = cal_listener_destroy; - - init_cal_listener_corba_class (); -} - -/* Object initialization function for the calendar listener */ -static void -cal_listener_init (CalListener *listener) -{ - CalListenerPrivate *priv; - - priv = g_new0 (CalListenerPrivate, 1); - listener->priv = priv; - - priv->cal = CORBA_OBJECT_NIL; - priv->cal_opened_fn = NULL; - priv->obj_updated_fn = NULL; - priv->obj_removed_fn = NULL; -} - -/* Destroy handler for the calendar listener */ -static void -cal_listener_destroy (GtkObject *object) -{ - CalListener *listener; - CalListenerPrivate *priv; - CORBA_Environment ev; - gboolean result; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_CAL_LISTENER (object)); - - listener = CAL_LISTENER (object); - priv = listener->priv; - - CORBA_exception_init (&ev); - result = CORBA_Object_is_nil (priv->cal, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("cal_listener_destroy(): could not see if the calendar was NIL"); - else if (!result) { - CORBA_exception_free (&ev); - - CORBA_exception_init (&ev); - CORBA_Object_release (priv->cal, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("cal_listener_destroy(): could not release the calendar"); - - priv->cal = CORBA_OBJECT_NIL; - } - CORBA_exception_free (&ev); - - g_free (priv); - listener->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - - -/* CORBA servant implementation */ - -/* Listener::notifyCalOpened method */ -static void -Listener_notifyCalOpened (PortableServer_Servant servant, - GNOME_Evolution_Calendar_Listener_OpenStatus status, - GNOME_Evolution_Calendar_Cal cal, - 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; - - if (priv->cal != CORBA_OBJECT_NIL) { - g_message ("Listener_notifyCalOpened(): calendar was already open!"); - return; - } - - CORBA_exception_init (&aev); - cal_copy = CORBA_Object_duplicate (cal, &aev); - - if (aev._major != CORBA_NO_EXCEPTION) { - g_message ("Listener_notifyCalOpened(): could not duplicate the calendar"); - CORBA_exception_free (&aev); - return; - } - CORBA_exception_free (&aev); - - priv->cal = cal_copy; - - g_assert (priv->cal_opened_fn != NULL); - (* priv->cal_opened_fn) (listener, status, cal, priv->fn_data); -} - -/* Listener::notifyObjUpdated method */ -static void -Listener_notifyObjUpdated (PortableServer_Servant servant, - GNOME_Evolution_Calendar_CalObjUID uid, - CORBA_Environment *ev) -{ - CalListener *listener; - CalListenerPrivate *priv; - - listener = CAL_LISTENER (bonobo_object_from_servant (servant)); - priv = listener->priv; - - g_assert (priv->obj_updated_fn != NULL); - (* priv->obj_updated_fn) (listener, uid, priv->fn_data); -} - -/* Listener::notifyObjRemoved method */ -static void -Listener_notifyObjRemoved (PortableServer_Servant servant, - GNOME_Evolution_Calendar_CalObjUID uid, - CORBA_Environment *ev) -{ - CalListener *listener; - CalListenerPrivate *priv; - - listener = CAL_LISTENER (bonobo_object_from_servant (servant)); - priv = listener->priv; - - g_assert (priv->obj_removed_fn != NULL); - (* priv->obj_removed_fn) (listener, uid, priv->fn_data); -} - -/** - * cal_listener_get_epv: - * @void: - * - * Creates an EPV for the Listener CORBA class. - * - * Return value: A newly-allocated EPV. - **/ -POA_GNOME_Evolution_Calendar_Listener__epv * -cal_listener_get_epv (void) -{ - POA_GNOME_Evolution_Calendar_Listener__epv *epv; - - epv = g_new0 (POA_GNOME_Evolution_Calendar_Listener__epv, 1); - epv->notifyCalOpened = Listener_notifyCalOpened; - epv->notifyObjUpdated = Listener_notifyObjUpdated; - epv->notifyObjRemoved = Listener_notifyObjRemoved; - return epv; -} - - - -/** - * cal_listener_construct: - * @listener: A calendar listener. - * @corba_listener: CORBA object for the 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. - * @fn_data: Closure data pointer that will be passed to the notification - * functions. - * - * Constructs a calendar listener by binding the corresponding CORBA object to - * it. - * - * Return value: the same object as the @listener argument. - **/ -CalListener * -cal_listener_construct (CalListener *listener, - GNOME_Evolution_Calendar_Listener corba_listener, - CalListenerCalOpenedFn cal_opened_fn, - CalListenerObjUpdatedFn obj_updated_fn, - CalListenerObjRemovedFn obj_removed_fn, - gpointer fn_data) -{ - CalListenerPrivate *priv; - - 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 (obj_updated_fn != NULL, NULL); - g_return_val_if_fail (obj_removed_fn != NULL, NULL); - - priv = listener->priv; - - priv->cal_opened_fn = cal_opened_fn; - priv->obj_updated_fn = obj_updated_fn; - priv->obj_removed_fn = obj_removed_fn; - priv->fn_data = fn_data; - - bonobo_object_construct (BONOBO_OBJECT (listener), corba_listener); - return listener; -} - -/** - * cal_listener_corba_object_create: - * @object: #BonoboObject that will wrap the CORBA object. - * - * Creates and activates the CORBA object that is wrapped by the specified - * calendar listener @object. - * - * Return value: An activated object reference or #CORBA_OBJECT_NIL in case of - * failure. - **/ -GNOME_Evolution_Calendar_Listener -cal_listener_corba_object_create (BonoboObject *object) -{ - POA_GNOME_Evolution_Calendar_Listener *servant; - CORBA_Environment ev; - - g_return_val_if_fail (object != NULL, CORBA_OBJECT_NIL); - g_return_val_if_fail (IS_CAL_LISTENER (object), CORBA_OBJECT_NIL); - - servant = (POA_GNOME_Evolution_Calendar_Listener *) g_new0 (BonoboObjectServant, 1); - servant->vepv = &cal_listener_vepv; - - CORBA_exception_init (&ev); - POA_GNOME_Evolution_Calendar_Listener__init ((PortableServer_Servant) servant, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_free (servant); - CORBA_exception_free (&ev); - return CORBA_OBJECT_NIL; - } - - CORBA_exception_free (&ev); - return (GNOME_Evolution_Calendar_Listener) bonobo_object_activate_servant (object, servant); -} - -/** - * 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. - * @fn_data: Closure data pointer that will be passed to the notification - * functions. - * - * Creates a new #CalListener object. - * - * Return value: A newly-created #CalListener, or NULL if its corresponding - * CORBA object could not be created. - **/ -CalListener * -cal_listener_new (CalListenerCalOpenedFn cal_opened_fn, - CalListenerObjUpdatedFn obj_updated_fn, - CalListenerObjRemovedFn obj_removed_fn, - gpointer fn_data) -{ - CalListener *listener; - CORBA_Environment ev; - GNOME_Evolution_Calendar_Listener corba_listener; - gboolean result; - - 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); - - listener = gtk_type_new (CAL_LISTENER_TYPE); - - corba_listener = cal_listener_corba_object_create (BONOBO_OBJECT (listener)); - - CORBA_exception_init (&ev); - result = CORBA_Object_is_nil (corba_listener, &ev); - - if (ev._major != CORBA_NO_EXCEPTION || result) { - g_message ("cal_listener_new(): could not create the CORBA listener"); - bonobo_object_unref (BONOBO_OBJECT (listener)); - CORBA_exception_free (&ev); - return NULL; - } - CORBA_exception_free (&ev); - - return cal_listener_construct (listener, - corba_listener, - cal_opened_fn, - obj_updated_fn, - obj_removed_fn, - fn_data); -} diff --git a/calendar/cal-client/cal-listener.h b/calendar/cal-client/cal-listener.h deleted file mode 100644 index 612d1d889f..0000000000 --- a/calendar/cal-client/cal-listener.h +++ /dev/null @@ -1,101 +0,0 @@ -/* Evolution calendar listener - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef CAL_LISTENER_H -#define CAL_LISTENER_H - -#include <libgnome/gnome-defs.h> -#include <bonobo/bonobo-object.h> -#include "evolution-calendar.h" - -BEGIN_GNOME_DECLS - - - -#define CAL_LISTENER_TYPE (cal_listener_get_type ()) -#define CAL_LISTENER(obj) (GTK_CHECK_CAST ((obj), CAL_LISTENER_TYPE, CalListener)) -#define CAL_LISTENER_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), CAL_LISTENER_TYPE, \ - CalListenerClass)) -#define IS_CAL_LISTENER(obj) (GTK_CHECK_TYPE ((obj), CAL_LISTENER_TYPE)) -#define IS_CAL_LISTENER_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), CAL_LISTENER_TYPE)) - -typedef struct _CalListener CalListener; -typedef struct _CalListenerClass CalListenerClass; - -typedef struct _CalListenerPrivate CalListenerPrivate; - -struct _CalListener { - BonoboObject object; - - /* Private data */ - CalListenerPrivate *priv; -}; - -struct _CalListenerClass { - BonoboObjectClass parent_class; - - /* Notification signals */ - - void (* cal_opened) (CalListener *listener, - GNOME_Evolution_Calendar_Listener_OpenStatus status, - GNOME_Evolution_Calendar_Cal cal); - void (* obj_updated) (CalListener *listener, const GNOME_Evolution_Calendar_CalObjUID uid); - void (* obj_removed) (CalListener *listener, const GNOME_Evolution_Calendar_CalObjUID uid); -}; - -/* Notification functions */ -typedef void (* CalListenerCalOpenedFn) (CalListener *listener, - GNOME_Evolution_Calendar_Listener_OpenStatus status, - GNOME_Evolution_Calendar_Cal cal, - gpointer data); - -typedef void (* CalListenerObjUpdatedFn) (CalListener *listener, - const GNOME_Evolution_Calendar_CalObjUID uid, - gpointer data); -typedef void (* CalListenerObjRemovedFn) (CalListener *listener, - const GNOME_Evolution_Calendar_CalObjUID uid, - gpointer data); - - -GtkType cal_listener_get_type (void); - -CalListener *cal_listener_construct (CalListener *listener, - GNOME_Evolution_Calendar_Listener corba_listener, - CalListenerCalOpenedFn cal_opened_fn, - CalListenerObjUpdatedFn obj_updated_fn, - CalListenerObjRemovedFn obj_removed_fn, - gpointer fn_data); - -GNOME_Evolution_Calendar_Listener cal_listener_corba_object_create (BonoboObject *object); - -CalListener *cal_listener_new (CalListenerCalOpenedFn cal_opened_fn, - CalListenerObjUpdatedFn obj_updated_fn, - CalListenerObjRemovedFn obj_removed_fn, - gpointer fn_data); - -POA_GNOME_Evolution_Calendar_Listener__epv *cal_listener_get_epv (void); - - - -END_GNOME_DECLS - -#endif diff --git a/calendar/cal-client/client-test.c b/calendar/cal-client/client-test.c deleted file mode 100644 index 7ff8aab8fc..0000000000 --- a/calendar/cal-client/client-test.c +++ /dev/null @@ -1,211 +0,0 @@ -/* Evolution calendar client - test program - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#include <config.h> -#include <bonobo.h> -#include <liboaf/liboaf.h> -#include <gnome.h> -#include <cal-client/cal-client.h> - -static CalClient *client1; -static CalClient *client2; - -/* Prints a message with a client identifier */ -static void -cl_printf (CalClient *client, const char *format, ...) -{ - va_list args; - - va_start (args, format); - printf ("Client %s: ", - client == client1 ? "1" : - client == client2 ? "2" : - "UNKNOWN"); - vprintf (format, args); - va_end (args); -} - -/* Dumps some interesting data from a component */ -static void -dump_component (CalComponent *comp) -{ - const char *uid; - CalComponentText summary; - - cal_component_get_uid (comp, &uid); - - printf ("UID %s\n", uid); - - 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"); -} - -/* Lists the UIDs of objects in a calendar, called as an idle handler */ -static gboolean -list_uids (gpointer data) -{ - CalClient *client; - GList *uids; - GList *l; - - client = CAL_CLIENT (data); - - uids = cal_client_get_uids (client, CALOBJ_TYPE_ANY); - - cl_printf (client, "UIDs: "); - - if (!uids) - printf ("none\n"); - else { - for (l = uids; l; l = l->next) { - char *uid; - - 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"); - gtk_object_unref (GTK_OBJECT (comp)); - } else { - printf ("FAILED: %d\n", status); - } - } - } - - cal_obj_uid_list_free (uids); - - gtk_object_unref (GTK_OBJECT (client)); - - return FALSE; -} - -/* Callback used when a calendar is opened */ -static void -cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data) -{ - cl_printf (client, "Load/create %s\n", - ((status == CAL_CLIENT_OPEN_SUCCESS) ? "success" : - (status == CAL_CLIENT_OPEN_ERROR) ? "error" : - (status == CAL_CLIENT_OPEN_NOT_FOUND) ? "not found" : - (status == CAL_CLIENT_OPEN_METHOD_NOT_SUPPORTED) ? "method not supported" : - "unknown status value")); - - if (status == CAL_CLIENT_OPEN_SUCCESS) - g_idle_add (list_uids, client); - else - gtk_object_unref (GTK_OBJECT (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 (GtkObject *object, gpointer data) -{ - if (CAL_CLIENT (object) == client1) - client1 = NULL; - else if (CAL_CLIENT (object) == client2) - client2 = NULL; - else - g_assert_not_reached (); - - if (!client1 && !client2) - gtk_main_quit (); -} - -/* 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) -{ - gboolean result; - - *client = cal_client_new (); - if (!*client) { - g_message ("create_client(): could not create the client"); - exit (1); - } - - gtk_signal_connect (GTK_OBJECT (*client), "destroy", - client_destroy_cb, - NULL); - - gtk_signal_connect (GTK_OBJECT (*client), "cal_opened", - GTK_SIGNAL_FUNC (cal_opened_cb), - NULL); - gtk_signal_connect (GTK_OBJECT (*client), "obj_updated", - GTK_SIGNAL_FUNC (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'", - uri); - exit (1); - } -} - -int -main (int argc, char **argv) -{ - bindtextdomain (PACKAGE, GNOMELOCALEDIR); - textdomain (PACKAGE); - - gnome_init ("tl-test", VERSION, argc, argv); - oaf_init (argc, argv); - - if (!bonobo_init (CORBA_OBJECT_NIL, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL)) { - g_message ("main(): could not initialize Bonobo"); - exit (1); - } - - create_client (&client1, "/cvs/evolution/calendar/cal-client/test.ics", FALSE); - create_client (&client2, "/cvs/evolution/calendar/cal-client/test.ics", TRUE); - - bonobo_main (); - return 0; -} diff --git a/calendar/cal-client/test.ics b/calendar/cal-client/test.ics deleted file mode 100644 index 128251ee11..0000000000 --- a/calendar/cal-client/test.ics +++ /dev/null @@ -1,318 +0,0 @@ -BEGIN:VCALENDAR -VERSION:2.0 -PRODID:-//hacksw/handcal//NONSGML v1.0//EN - -BEGIN:VEVENT -DTSTART:19970714T170000Z -DTEND:19970715T035959Z -SUMMARY:Bastille Day Party -END:VEVENT - -BEGIN:VEVENT -UID:19970901T130000Z-123401@host.com -DTSTAMP:19970901T1300Z -DTSTART:19970903T163000Z -DTEND:19970903T190000Z -SUMMARY:Annual Employee Review -CLASS:PRIVATE -CATEGORIES:BUSINESS,HUMAN RESOURCES -END:VEVENT - -BEGIN:VEVENT -UID:19970901T130000Z-123402@host.com -DTSTAMP:19970901T1300Z -DTSTART:19970401T163000Z -DTEND:19970402T010000Z -SUMMARY:Laurel is in sensitivity awareness class. -CLASS:PUBLIC -CATEGORIES:BUSINESS,HUMAN RESOURCES -TRANSP:TRANSPARENT -END:VEVENT - -BEGIN:VEVENT -UID:19970901T130000Z-123403@host.com -DTSTAMP:19970901T1300Z -DTSTART:19971102 -SUMMARY:Our Blissful Anniversary -CLASS:CONFIDENTIAL -CATEGORIES:ANNIVERSARY,PERSONAL,SPECIAL OCCASION -RRULE:FREQ=YEARLY -END:VEVENT - -BEGIN:VTODO -UID:19970901T130000Z-123404@host.com -DTSTAMP:19970901T1300Z -DTSTART:19970415T133000Z -DUE:19970416T045959Z -SUMMARY:1996 Income Tax Preparation -CLASS:CONFIDENTIAL -CATEGORIES:FAMILY,FINANCE -PRIORITY:1 -STATUS:NEEDS-ACTION -END:VTODO - -BEGIN:VJOURNAL -UID:19970901T130000Z-123405@host.com -DTSTAMP:19970901T1300Z -DTSTART;VALUE=DATE:19970317 -SUMMARY:Staff meeting minutes -DESCRIPTION:1. Staff meeting: Participants include Joe\, Lisa - and Bob. Aurora project plans were reviewed. There is currently - no budget reserves for this project. Lisa will escalate to - management. Next meeting on Tuesday.\n - 2. Telephone Conference: ABC Corp. sales representative called - to discuss new printer. Promised to get us a demo by Friday.\n - 3. Henry Miller (Handsoff Insurance): Car was totaled by tree. - Is looking into a loaner car. 654-2323 (tel). -END:VJOURNAL - -BEGIN:VFREEBUSY -ORGANIZER:MAILTO:jane_doe@host1.com -ATTENDEE:MAILTO:john_public@host2.com -DTSTART:19971015T050000Z -DTEND:19971016T050000Z -DTSTAMP:19970901T083000Z -END:VFREEBUSY - -BEGIN:VFREEBUSY -ORGANIZER:MAILTO:jane_doe@host1.com -ATTENDEE:MAILTO:john_public@host2.com -DTSTAMP:19970901T100000Z -FREEBUSY;VALUE=PERIOD:19971015T050000Z/PT8H30M, - 19971015T160000Z/PT5H30M,19971015T223000Z/PT6H30M -URL:http://host2.com/pub/busy/jpublic-01.ifb -COMMENT:This iCalendar file contains busy time information for - the next three months. -END:VFREEBUSY - -BEGIN:VFREEBUSY -ORGANIZER:jsmith@host.com -DTSTART:19980313T141711Z -DTEND:19980410T141711Z -FREEBUSY:19980314T233000Z/19980315T003000Z -FREEBUSY:19980316T153000Z/19980316T163000Z -FREEBUSY:19980318T030000Z/19980318T040000Z -URL:http://www.host.com/calendar/busytime/jsmith.ifb -END:VFREEBUSY - -BEGIN:VTIMEZONE -TZID:US-Eastern -LAST-MODIFIED:19870101T000000Z -BEGIN:STANDARD -DTSTART:19971026T020000 -RDATE:19971026T020000 -TZOFFSETFROM:-0400 -TZOFFSETTO:-0500 -TZNAME:EST -END:STANDARD -BEGIN:DAYLIGHT -DTSTART:19971026T020000 -RDATE:19970406T020000 -TZOFFSETFROM:-0500 -TZOFFSETTO:-0400 -TZNAME:EDT -END:DAYLIGHT -END:VTIMEZONE - -BEGIN:VTIMEZONE -TZID:US-Eastern -LAST-MODIFIED:19870101T000000Z -TZURL:http://zones.stds_r_us.net/tz/US-Eastern -BEGIN:STANDARD -DTSTART:19671029T020000 -RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10 -TZOFFSETFROM:-0400 -TZOFFSETTO:-0500 -TZNAME:EST -END:STANDARD -BEGIN:DAYLIGHT -DTSTART:19870405T020000 -RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4 -TZOFFSETFROM:-0500 -TZOFFSETTO:-0400 -TZNAME:EDT -END:DAYLIGHT -END:VTIMEZONE - -BEGIN:VTIMEZONE -TZID:US--Fictitious-Eastern -LAST-MODIFIED:19870101T000000Z -BEGIN:STANDARD -DTSTART:19671029T020000 -RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10 -TZOFFSETFROM:-0400 -TZOFFSETTO:-0500 -TZNAME:EST -END:STANDARD -BEGIN:DAYLIGHT -DTSTART:19870405T020000 -RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4;UNTIL=19980404T070000Z -TZOFFSETFROM:-0500 -TZOFFSETTO:-0400 -TZNAME:EDT -END:DAYLIGHT -END:VTIMEZONE - -BEGIN:VTIMEZONE -TZID:US--Fictitious-Eastern -LAST-MODIFIED:19870101T000000Z -BEGIN:STANDARD -DTSTART:19671029T020000 -RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10 -TZOFFSETFROM:-0400 -TZOFFSETTO:-0500 -TZNAME:EST -END:STANDARD -BEGIN:DAYLIGHT -DTSTART:19870405T020000 -RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4;UNTIL=19980404T070000Z -TZOFFSETFROM:-0500 -TZOFFSETTO:-0400 -TZNAME:EDT -END:DAYLIGHT -BEGIN:DAYLIGHT -DTSTART:19990424T020000 -RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=4 -TZOFFSETFROM:-0500 -TZOFFSETTO:-0400 -TZNAME:EDT -END:DAYLIGHT -END:VTIMEZONE - -BEGIN:VALARM -TRIGGER;VALUE=DATE-TIME:19970317T133000Z -REPEAT:4 -DURATION:PT15M -ACTION:AUDIO -ATTACH;FMTTYPE=audio/basic:ftp://host.com/pub/sounds/bell-01.aud -END:VALARM -BEGIN:VALARM -TRIGGER:-PT30M -REPEAT:2 -DURATION:PT15M -ACTION:DISPLAY -DESCRIPTION:Breakfast meeting with executive\n - team at 8:30 AM EST. -END:VALARM - -BEGIN:VALARM -TRIGGER:-P2D -ACTION:EMAIL -ATTENDEE:MAILTO:john_doe@host.com -SUMMARY:*** REMINDER: SEND AGENDA FOR WEEKLY STAFF MEETING *** -DESCRIPTION:A draft agenda needs to be sent out to the attendees - to the weekly managers meeting (MGR-LIST). Attached is a - pointer the document template for the agenda file. -ATTACH;FMTTYPE=application/binary:http://host.com/templates/agen - da.doc -END:VALARM - -BEGIN:VALARM -TRIGGER;VALUE=DATE-TIME:19980101T050000Z -REPEAT:23 -DURATION:PT1H -ACTION:PROCEDURE -ATTACH;FMTTYPE=application/binary:ftp://host.com/novo- - procs/felizano.exe -END:VALARM - -BEGIN:VTIMEZONE -TZID:US-Eastern -BEGIN:STANDARD -DTSTART:19981025T020000 -RDATE:19981025T020000 -TZOFFSETFROM:-0400 -TZOFFSETTO:-0500 -TZNAME:EST -END:STANDARD -BEGIN:DAYLIGHT -DTSTART:19990404T020000 -RDATE:19990404T020000 -TZOFFSETFROM:-0500 -TZOFFSETTO:-0400 -TZNAME:EDT -END:DAYLIGHT -END:VTIMEZONE - -BEGIN:VEVENT -DTSTAMP:19980309T231000Z -UID:guid-1.host1.com -ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com -ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP: - MAILTO:employee-A@host.com -DESCRIPTION:Project XYZ Review Meeting -CATEGORIES:MEETING -CLASS:PUBLIC -CREATED:19980309T130000Z -SUMMARY:XYZ Project Review -DTSTART;TZID=US-Eastern:19980312T083000 -DTEND;TZID=US-Eastern:19980312T093000 -LOCATION:1CP Conference Room 4350 -END:VEVENT - -BEGIN:VEVENT -DTSTAMP:19970324T1200Z -SEQUENCE:0 -UID:uid3@host1.com -ORGANIZER:MAILTO:jdoe@host1.com -DTSTART:19970324T123000Z -DTEND:19970324T210000Z -CATEGORIES:MEETING,PROJECT -CLASS:PUBLIC -SUMMARY:Calendaring Interoperability Planning Meeting -DESCRIPTION:Discuss how we can test c&s interoperability\n - using iCalendar and other IETF standards. -LOCATION:LDB Lobby -ATTACH;FMTTYPE=application/postscript:ftp://xyzCorp.com/pub/ - conf/bkgrnd.ps -END:VEVENT - -BEGIN:VTODO -DTSTAMP:19980130T134500Z -SEQUENCE:2 -UID:uid4@host1.com -ORGANIZER:MAILTO:unclesam@us.gov -ATTENDEE;PARTSTAT=ACCEPTED:MAILTO:jqpublic@host.com -DUE:19980415T235959 -STATUS:NEEDS-ACTION -SUMMARY:Submit Income Taxes -BEGIN:VALARM -ACTION:AUDIO -TRIGGER:19980403T120000 -ATTACH;FMTTYPE=audio/basic:http://host.com/pub/audio- - files/ssbanner.aud -REPEAT:4 -DURATION:PT1H -END:VALARM -END:VTODO - -BEGIN:VJOURNAL -DTSTAMP:19970324T120000Z -UID:uid5@host1.com -ORGANIZER:MAILTO:jsmith@host.com -STATUS:DRAFT -CLASS:PUBLIC -CATEGORIES:Project Report, XYZ, Weekly Meeting -DESCRIPTION:Project xyz Review Meeting Minutes\n - Agenda\n1. Review of project version 1.0 requirements.\n2. - Definition - of project processes.\n3. Review of project schedule.\n - Participants: John Smith\, Jane Doe\, Jim Dandy\n-It was - decided that the requirements need to be signed off by - product marketing.\n-Project processes were accepted.\n - -Project schedule needs to account for scheduled holidays - and employee vacation time. Check with HR for specific - dates.\n-New schedule will be distributed by Friday.\n- - Next weeks meeting is cancelled. No meeting until 3/23. -END:VJOURNAL - -BEGIN:VFREEBUSY -ORGANIZER:MAILTO:jsmith@host.com -DTSTART:19980313T141711Z -DTEND:19980410T141711Z -FREEBUSY:19980314T233000Z/19980315T003000Z -FREEBUSY:19980316T153000Z/19980316T163000Z -FREEBUSY:19980318T030000Z/19980318T040000Z -URL:http://www.host.com/calendar/busytime/jsmith.ifb -END:VFREEBUSY -END:VCALENDAR diff --git a/calendar/cal-util/.cvsignore b/calendar/cal-util/.cvsignore deleted file mode 100644 index 9f93120f8a..0000000000 --- a/calendar/cal-util/.cvsignore +++ /dev/null @@ -1,7 +0,0 @@ -.libs -Makefile.in -Makefile -.deps -*.lo -*.la -test-recur diff --git a/calendar/cal-util/Makefile.am b/calendar/cal-util/Makefile.am deleted file mode 100644 index 80c8da2662..0000000000 --- a/calendar/cal-util/Makefile.am +++ /dev/null @@ -1,49 +0,0 @@ -noinst_PROGRAMS = test-recur - -INCLUDES = \ - -DGNOMELOCALEDIR=\""$(localedir)"\" \ - -DG_LOG_DOMAIN=\"cal-util\" \ - -I$(top_srcdir) \ - -I$(top_srcdir)/calendar \ - -I. \ - -I.. \ - -I$(top_builddir) \ - -I$(top_srcdir)/libical/src/libical \ - -I$(top_builddir)/libical/src/libical \ - $(GNOME_INCLUDEDIR) - -# -# cal util library -# - -lib_LTLIBRARIES = libcal-util.la - -libcal_util_la_SOURCES = \ - cal-component.c \ - cal-recur.c \ - cal-util.c \ - timeutil.c - -libcal_utilincludedir = $(includedir)/evolution/cal-util - -libcal_utilinclude_HEADERS = \ - cal-component.h \ - cal-recur.h \ - cal-util.h \ - timeutil.h - -# -# static library for use in conduits' shared libraries -# -noinst_LTLIBRARIES = libcal-util-static.la -libcal_util_static_la_SOURCES = $(libcal_util_la_SOURCES) -libcal_util_static_la_LDFLAGS = --all-static - -test_recur_SOURCES = \ - test-recur.c - -test_recur_LDADD = \ - libcal-util.la \ - $(top_builddir)/libversit/libversit.la \ - $(top_builddir)/libical/src/libical/libical.la \ - $(EXTRA_GNOME_LIBS) diff --git a/calendar/cal-util/cal-component.c b/calendar/cal-util/cal-component.c deleted file mode 100644 index b0269ba262..0000000000 --- a/calendar/cal-util/cal-component.c +++ /dev/null @@ -1,4071 +0,0 @@ -/* Evolution calendar - iCalendar component object - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#include <config.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include "cal-component.h" -#include "timeutil.h" - - - -/* Extension property for alarm components so that we can reference them by UID */ -#define EVOLUTION_ALARM_UID_PROPERTY "X-EVOLUTION-ALARM-UID" - -/* Private part of the CalComponent structure */ -struct _CalComponentPrivate { - /* The icalcomponent we wrap */ - icalcomponent *icalcomp; - - /* Properties */ - - icalproperty *uid; - - icalproperty *status; - - icalproperty *categories; - - icalproperty *classification; - - struct text { - icalproperty *prop; - icalparameter *altrep_param; - }; - - GSList *comment_list; /* list of struct text */ - - icalproperty *completed; - icalproperty *created; - - GSList *description_list; /* list of struct text */ - - struct datetime { - icalproperty *prop; - icalparameter *tzid_param; - }; - - struct datetime dtstart; - struct datetime dtend; - - icalproperty *dtstamp; - - struct datetime due; - - GSList *exdate_list; /* list of struct datetime */ - GSList *exrule_list; /* list of icalproperty objects */ - - icalproperty *geo; - icalproperty *last_modified; - icalproperty *percent; - icalproperty *priority; - - struct period { - icalproperty *prop; - icalparameter *value_param; - }; - - GSList *rdate_list; /* list of struct period */ - - GSList *rrule_list; /* list of icalproperty objects */ - - icalproperty *sequence; - - struct { - icalproperty *prop; - icalparameter *altrep_param; - } summary; - - icalproperty *transparency; - icalproperty *url; - - /* Subcomponents */ - - GHashTable *alarm_uid_hash; - - /* Whether we should increment the sequence number when piping the - * object over the wire. - */ - guint need_sequence_inc : 1; -}; - -/* Private structure for alarms */ -struct _CalComponentAlarm { - /* Our parent component */ - CalComponent *parent; - - /* Alarm icalcomponent we wrap */ - icalcomponent *icalcomp; - - /* Our extension UID property */ - icalproperty *uid; - - /* Properties */ - - icalproperty *action; - icalproperty *trigger; -}; - - - -static void cal_component_class_init (CalComponentClass *class); -static void cal_component_init (CalComponent *comp); -static void cal_component_destroy (GtkObject *object); - -static GtkObjectClass *parent_class; - - - -/** - * cal_component_get_type: - * - * Registers the #CalComponent class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the #CalComponent class. - **/ -GtkType -cal_component_get_type (void) -{ - static GtkType cal_component_type = 0; - - if (!cal_component_type) { - static const GtkTypeInfo cal_component_info = { - "CalComponent", - sizeof (CalComponent), - sizeof (CalComponentClass), - (GtkClassInitFunc) cal_component_class_init, - (GtkObjectInitFunc) cal_component_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - cal_component_type = gtk_type_unique (GTK_TYPE_OBJECT, &cal_component_info); - } - - return cal_component_type; -} - -/* Class initialization function for the calendar component object */ -static void -cal_component_class_init (CalComponentClass *class) -{ - GtkObjectClass *object_class; - - object_class = (GtkObjectClass *) class; - - parent_class = gtk_type_class (GTK_TYPE_OBJECT); - - object_class->destroy = cal_component_destroy; -} - -/* Object initialization function for the calendar component object */ -static void -cal_component_init (CalComponent *comp) -{ - CalComponentPrivate *priv; - - priv = g_new0 (CalComponentPrivate, 1); - comp->priv = priv; - - priv->alarm_uid_hash = g_hash_table_new (g_str_hash, g_str_equal); -} - -/* Does a simple g_free() of the elements of a GSList and then frees the list - * itself. Returns NULL. - */ -static GSList * -free_slist (GSList *slist) -{ - GSList *l; - - for (l = slist; l; l = l->next) - g_free (l->data); - - g_slist_free (slist); - return NULL; -} - -/* Used from g_hash_table_foreach_remove() to free the alarm UIDs hash table. - * We do not need to do anything to individual elements since we were storing - * the UID pointers inside the icalproperties themselves. - */ -static gboolean -free_alarm_cb (gpointer key, gpointer value, gpointer data) -{ - return TRUE; -} - -/* Frees the internal icalcomponent only if it does not have a parent. If it - * does, it means we don't own it and we shouldn't free it. - */ -static void -free_icalcomponent (CalComponent *comp) -{ - CalComponentPrivate *priv; - - priv = comp->priv; - - if (!priv->icalcomp) - return; - - /* Free the icalcomponent */ - - if (icalcomponent_get_parent (priv->icalcomp) == NULL) - icalcomponent_free (priv->icalcomp); - - priv->icalcomp = NULL; - - /* Free the mappings */ - - priv->uid = NULL; - - priv->status = NULL; - - priv->categories = NULL; - - priv->classification = NULL; - priv->comment_list = NULL; - priv->completed = NULL; - priv->created = NULL; - - priv->description_list = free_slist (priv->description_list); - - priv->dtend.prop = NULL; - priv->dtend.tzid_param = NULL; - - priv->dtstamp = NULL; - - priv->dtstart.prop = NULL; - priv->dtstart.tzid_param = NULL; - - priv->due.prop = NULL; - priv->due.tzid_param = NULL; - - priv->exdate_list = free_slist (priv->exdate_list); - - g_slist_free (priv->exrule_list); - priv->exrule_list = NULL; - - priv->geo = NULL; - priv->last_modified = NULL; - priv->percent = NULL; - priv->priority = NULL; - - priv->rdate_list = free_slist (priv->rdate_list); - - g_slist_free (priv->rrule_list); - priv->rrule_list = NULL; - - priv->sequence = NULL; - - priv->summary.prop = NULL; - priv->summary.altrep_param = NULL; - - priv->transparency = NULL; - priv->url = NULL; - - /* Free the subcomponents */ - - g_hash_table_foreach_remove (priv->alarm_uid_hash, free_alarm_cb, NULL); - - /* Clean up */ - - priv->need_sequence_inc = FALSE; -} - -/* Destroy handler for the calendar component object */ -static void -cal_component_destroy (GtkObject *object) -{ - CalComponent *comp; - CalComponentPrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_CAL_COMPONENT (object)); - - comp = CAL_COMPONENT (object); - priv = comp->priv; - - free_icalcomponent (comp); - g_hash_table_destroy (priv->alarm_uid_hash); - priv->alarm_uid_hash = NULL; - - g_free (priv); - comp->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - - -/** - * cal_component_gen_uid: - * - * Generates a unique identifier suitable for calendar components. - * - * Return value: A unique identifier string. Every time this function is called - * a different string is returned. - **/ -char * -cal_component_gen_uid (void) -{ - static char *hostname; - time_t t = time (NULL); - static int serial; - - if (!hostname) { - static char buffer [512]; - - if ((gethostname (buffer, sizeof (buffer) - 1) == 0) && - (buffer [0] != 0)) - hostname = buffer; - else - hostname = "localhost"; - } - - return g_strdup_printf ( - "%s-%d-%d-%d-%d@%s", - isodate_from_time_t (t), - getpid (), - getgid (), - getppid (), - serial++, - hostname); -} - -/** - * cal_component_new: - * - * Creates a new empty calendar component object. You should set it from an - * #icalcomponent structure by using cal_component_set_icalcomponent() or with a - * new empty component type by using cal_component_set_new_vtype(). - * - * Return value: A newly-created calendar component object. - **/ -CalComponent * -cal_component_new (void) -{ - return CAL_COMPONENT (gtk_type_new (CAL_COMPONENT_TYPE)); -} - -/** - * cal_component_clone: - * @comp: A calendar component object. - * - * Creates a new calendar component object by copying the information from - * another one. - * - * Return value: A newly-created calendar component with the same values as the - * original one. - **/ -CalComponent * -cal_component_clone (CalComponent *comp) -{ - CalComponentPrivate *priv; - CalComponent *new_comp; - icalcomponent *new_icalcomp; - - g_return_val_if_fail (comp != NULL, NULL); - g_return_val_if_fail (IS_CAL_COMPONENT (comp), NULL); - - priv = comp->priv; - g_return_val_if_fail (priv->need_sequence_inc == FALSE, NULL); - - new_comp = cal_component_new (); - - if (priv->icalcomp) { - new_icalcomp = icalcomponent_new_clone (priv->icalcomp); - cal_component_set_icalcomponent (new_comp, new_icalcomp); - } - - return new_comp; -} - -/* Scans a date/time and timezone pair property */ -static void -scan_datetime (CalComponent *comp, struct datetime *datetime, icalproperty *prop) -{ - CalComponentPrivate *priv; - - priv = comp->priv; - - datetime->prop = prop; - datetime->tzid_param = icalproperty_get_first_parameter (prop, ICAL_TZID_PARAMETER); -} - -/* Scans an exception date property */ -static void -scan_exdate (CalComponent *comp, icalproperty *prop) -{ - CalComponentPrivate *priv; - struct datetime *dt; - - priv = comp->priv; - - dt = g_new (struct datetime, 1); - dt->prop = prop; - dt->tzid_param = icalproperty_get_first_parameter (prop, ICAL_TZID_PARAMETER); - - priv->exdate_list = g_slist_append (priv->exdate_list, dt); -} - -/* Scans an icalperiodtype property */ -static void -scan_period (CalComponent *comp, GSList **list, icalproperty *prop) -{ - struct period *period; - - period = g_new (struct period, 1); - period->prop = prop; - period->value_param = icalproperty_get_first_parameter (prop, ICAL_VALUE_PARAMETER); - - *list = g_slist_append (*list, period); -} - -/* Scans an icalrecurtype property */ -static void -scan_recur (CalComponent *comp, GSList **list, icalproperty *prop) -{ - *list = g_slist_append (*list, prop); -} - -/* Scans the summary property */ -static void -scan_summary (CalComponent *comp, icalproperty *prop) -{ - CalComponentPrivate *priv; - - priv = comp->priv; - - priv->summary.prop = prop; - priv->summary.altrep_param = icalproperty_get_first_parameter (prop, ICAL_ALTREP_PARAMETER); -} - -/* Scans a text (i.e. text + altrep) property */ -static void -scan_text (CalComponent *comp, GSList **text_list, icalproperty *prop) -{ - struct text *text; - - text = g_new (struct text, 1); - text->prop = prop; - text->altrep_param = icalproperty_get_first_parameter (prop, ICAL_ALTREP_PARAMETER); - - *text_list = g_slist_append (*text_list, text); -} - -/* Scans an icalproperty and adds its mapping to the component */ -static void -scan_property (CalComponent *comp, icalproperty *prop) -{ - CalComponentPrivate *priv; - icalproperty_kind kind; - - priv = comp->priv; - - kind = icalproperty_isa (prop); - - switch (kind) { - case ICAL_STATUS_PROPERTY: - priv->status = prop; - break; - - case ICAL_CATEGORIES_PROPERTY: - priv->categories = prop; - break; - - case ICAL_CLASS_PROPERTY: - priv->classification = prop; - break; - - case ICAL_COMMENT_PROPERTY: - scan_text (comp, &priv->comment_list, prop); - break; - - case ICAL_COMPLETED_PROPERTY: - priv->completed = prop; - break; - - case ICAL_CREATED_PROPERTY: - priv->created = prop; - break; - - case ICAL_DESCRIPTION_PROPERTY: - scan_text (comp, &priv->description_list, prop); - break; - - case ICAL_DTEND_PROPERTY: - scan_datetime (comp, &priv->dtend, prop); - break; - - case ICAL_DTSTAMP_PROPERTY: - priv->dtstamp = prop; - break; - - case ICAL_DTSTART_PROPERTY: - scan_datetime (comp, &priv->dtstart, prop); - break; - - case ICAL_DUE_PROPERTY: - scan_datetime (comp, &priv->due, prop); - break; - - case ICAL_EXDATE_PROPERTY: - scan_exdate (comp, prop); - break; - - case ICAL_EXRULE_PROPERTY: - scan_recur (comp, &priv->exrule_list, prop); - break; - - case ICAL_GEO_PROPERTY: - priv->geo = prop; - break; - - case ICAL_LASTMODIFIED_PROPERTY: - priv->last_modified = prop; - break; - - case ICAL_PERCENTCOMPLETE_PROPERTY: - priv->percent = prop; - break; - - case ICAL_PRIORITY_PROPERTY: - priv->priority = prop; - break; - - case ICAL_RDATE_PROPERTY: - scan_period (comp, &priv->rdate_list, prop); - break; - - case ICAL_RRULE_PROPERTY: - scan_recur (comp, &priv->rrule_list, prop); - break; - - case ICAL_SEQUENCE_PROPERTY: - priv->sequence = prop; - break; - - case ICAL_SUMMARY_PROPERTY: - scan_summary (comp, prop); - break; - - case ICAL_TRANSP_PROPERTY: - priv->transparency = prop; - break; - - case ICAL_UID_PROPERTY: - priv->uid = prop; - break; - - case ICAL_URL_PROPERTY: - priv->url = prop; - break; - - default: - break; - } -} - -/* Gets our alarm UID string from a property that is known to contain it */ -static const char * -alarm_uid_from_prop (icalproperty *prop) -{ - const char *xstr; - - g_assert (icalproperty_isa (prop) == ICAL_X_PROPERTY); - - xstr = icalproperty_get_x (prop); - g_assert (xstr != NULL); - - return xstr; -} - -/* Sets our alarm UID extension property on an alarm component. Returns a - * pointer to the UID string inside the property itself. - */ -static const char * -set_alarm_uid (icalcomponent *alarm, const char *auid) -{ - icalproperty *prop; - const char *inprop_auid; - - /* Create the new property */ - - prop = icalproperty_new_x ((char *) auid); - icalproperty_set_x_name (prop, EVOLUTION_ALARM_UID_PROPERTY); - - icalcomponent_add_property (alarm, prop); - - inprop_auid = alarm_uid_from_prop (prop); - return inprop_auid; -} - -/* Removes any alarm UID extension properties from an alarm subcomponent */ -static void -remove_alarm_uid (icalcomponent *alarm) -{ - icalproperty *prop; - GSList *list, *l; - - list = NULL; - - for (prop = icalcomponent_get_first_property (alarm, ICAL_X_PROPERTY); - prop; - prop = icalcomponent_get_next_property (alarm, ICAL_X_PROPERTY)) { - const char *xname; - - xname = icalproperty_get_x_name (prop); - g_assert (xname != NULL); - - if (strcmp (xname, EVOLUTION_ALARM_UID_PROPERTY) == 0) - list = g_slist_prepend (list, prop); - } - - for (l = list; l; l = l->next) { - prop = l->data; - icalcomponent_remove_property (alarm, prop); - icalproperty_free (prop); - } - - g_slist_free (list); -} - -/* Adds an alarm subcomponent to the calendar component's mapping table. The - * actual UID with which it gets added may not be the same as the specified one; - * this function will change it if the table already had an alarm subcomponent - * with the specified UID. Returns the actual UID used. - */ -static const char * -add_alarm (CalComponent *comp, icalcomponent *alarm, const char *auid) -{ - CalComponentPrivate *priv; - icalcomponent *old_alarm; - - priv = comp->priv; - - /* First we see if we already have an alarm with the requested UID. In - * that case, we need to change the new UID to something else. This - * should never happen, but who knows. - */ - - old_alarm = g_hash_table_lookup (priv->alarm_uid_hash, auid); - if (old_alarm != NULL) { - char *new_auid; - - g_message ("add_alarm(): Got alarm with duplicated UID `%s', changing it...", auid); - - remove_alarm_uid (alarm); - - new_auid = cal_component_gen_uid (); - auid = set_alarm_uid (alarm, new_auid); - g_free (new_auid); - } - - g_hash_table_insert (priv->alarm_uid_hash, (char *) auid, alarm); - return auid; -} - -static void -remove_alarm (CalComponent *comp, const char *auid) -{ - CalComponentPrivate *priv; - - priv = comp->priv; - - g_hash_table_remove (priv->alarm_uid_hash, auid); -} - - -/* Scans an alarm subcomponent, adds an UID extension property to it (so that we - * can reference alarms by unique IDs), and adds its mapping to the component. */ -static void -scan_alarm (CalComponent *comp, icalcomponent *alarm) -{ - CalComponentPrivate *priv; - icalproperty *prop; - const char *auid; - char *new_auid; - - priv = comp->priv; - - for (prop = icalcomponent_get_first_property (alarm, ICAL_X_PROPERTY); - prop; - prop = icalcomponent_get_next_property (alarm, ICAL_X_PROPERTY)) { - const char *xname; - - xname = icalproperty_get_x_name (prop); - g_assert (xname != NULL); - - if (strcmp (xname, EVOLUTION_ALARM_UID_PROPERTY) == 0) { - auid = alarm_uid_from_prop (prop); - add_alarm (comp, alarm, auid); - return; - } - } - - /* The component has no alarm UID property, so we create one. */ - - new_auid = cal_component_gen_uid (); - auid = set_alarm_uid (alarm, new_auid); - g_free (new_auid); - - add_alarm (comp, alarm, auid); -} - -/* Scans an icalcomponent for its properties so that we can provide - * random-access to them. It also builds a hash table of the component's alarm - * subcomponents. - */ -static void -scan_icalcomponent (CalComponent *comp) -{ - CalComponentPrivate *priv; - icalproperty *prop; - icalcompiter iter; - - priv = comp->priv; - - g_assert (priv->icalcomp != NULL); - - /* Scan properties */ - - for (prop = icalcomponent_get_first_property (priv->icalcomp, ICAL_ANY_PROPERTY); - prop; - prop = icalcomponent_get_next_property (priv->icalcomp, ICAL_ANY_PROPERTY)) - scan_property (comp, prop); - - /* Scan subcomponents */ - - for (iter = icalcomponent_begin_component (priv->icalcomp, ICAL_VALARM_COMPONENT); - icalcompiter_deref (&iter) != NULL; - icalcompiter_next (&iter)) { - icalcomponent *subcomp; - - subcomp = icalcompiter_deref (&iter); - scan_alarm (comp, subcomp); - } -} - -/* Ensures that the mandatory calendar component properties (uid, dtstamp) do - * exist. If they don't exist, it creates them automatically. - */ -static void -ensure_mandatory_properties (CalComponent *comp) -{ - CalComponentPrivate *priv; - - priv = comp->priv; - g_assert (priv->icalcomp != NULL); - - if (!priv->uid) { - char *uid; - - uid = cal_component_gen_uid (); - priv->uid = icalproperty_new_uid (uid); - g_free (uid); - - icalcomponent_add_property (priv->icalcomp, priv->uid); - } - - if (!priv->dtstamp) { - time_t tim; - struct icaltimetype t; - - tim = time (NULL); - t = icaltime_from_timet (tim, FALSE); - - priv->dtstamp = icalproperty_new_dtstamp (t); - icalcomponent_add_property (priv->icalcomp, priv->dtstamp); - } -} - -/** - * cal_component_set_new_vtype: - * @comp: A calendar component object. - * @type: Type of calendar component to create. - * - * Clears any existing component data from a calendar component object and - * creates a new #icalcomponent of the specified type for it. The only property - * that will be set in the new component will be its unique identifier. - **/ -void -cal_component_set_new_vtype (CalComponent *comp, CalComponentVType type) -{ - CalComponentPrivate *priv; - icalcomponent *icalcomp; - icalcomponent_kind kind; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - - priv = comp->priv; - - free_icalcomponent (comp); - - if (type == CAL_COMPONENT_NO_TYPE) - return; - - /* Figure out the kind and create the icalcomponent */ - - switch (type) { - case CAL_COMPONENT_EVENT: - kind = ICAL_VEVENT_COMPONENT; - break; - - case CAL_COMPONENT_TODO: - kind = ICAL_VTODO_COMPONENT; - break; - - case CAL_COMPONENT_JOURNAL: - kind = ICAL_VJOURNAL_COMPONENT; - break; - - case CAL_COMPONENT_FREEBUSY: - kind = ICAL_VFREEBUSY_COMPONENT; - break; - - case CAL_COMPONENT_TIMEZONE: - kind = ICAL_VTIMEZONE_COMPONENT; - break; - - default: - g_assert_not_reached (); - kind = ICAL_NO_COMPONENT; - } - - icalcomp = icalcomponent_new (kind); - if (!icalcomp) { - g_message ("cal_component_set_new_vtype(): Could not create the icalcomponent!"); - return; - } - - /* Scan the component to build our mapping table */ - - priv->icalcomp = icalcomp; - scan_icalcomponent (comp); - - /* Add missing stuff */ - - ensure_mandatory_properties (comp); -} - -/** - * cal_component_set_icalcomponent: - * @comp: A calendar component object. - * @icalcomp: An #icalcomponent. - * - * Sets the contents of a calendar component object from an #icalcomponent - * structure. If the @comp already had an #icalcomponent set into it, it will - * will be freed automatically if the #icalcomponent does not have a parent - * component itself. - * - * Supported component types are VEVENT, VTODO, VJOURNAL, VFREEBUSY, and VTIMEZONE. - * - * Return value: TRUE on success, FALSE if @icalcomp is an unsupported component - * type. - **/ -gboolean -cal_component_set_icalcomponent (CalComponent *comp, icalcomponent *icalcomp) -{ - CalComponentPrivate *priv; - icalcomponent_kind kind; - - g_return_val_if_fail (comp != NULL, FALSE); - g_return_val_if_fail (IS_CAL_COMPONENT (comp), FALSE); - - priv = comp->priv; - - if (priv->icalcomp == icalcomp) - return TRUE; - - free_icalcomponent (comp); - - if (!icalcomp) { - priv->icalcomp = NULL; - return TRUE; - } - - kind = icalcomponent_isa (icalcomp); - - if (!(kind == ICAL_VEVENT_COMPONENT - || kind == ICAL_VTODO_COMPONENT - || kind == ICAL_VJOURNAL_COMPONENT - || kind == ICAL_VFREEBUSY_COMPONENT - || kind == ICAL_VTIMEZONE_COMPONENT)) - return FALSE; - - priv->icalcomp = icalcomp; - - scan_icalcomponent (comp); - ensure_mandatory_properties (comp); - - return TRUE; -} - -/** - * cal_component_get_icalcomponent: - * @comp: A calendar component object. - * - * Queries the #icalcomponent structure that a calendar component object is - * wrapping. - * - * Return value: An #icalcomponent structure, or NULL if the @comp has no - * #icalcomponent set to it. - **/ -icalcomponent * -cal_component_get_icalcomponent (CalComponent *comp) -{ - CalComponentPrivate *priv; - - g_return_val_if_fail (comp != NULL, NULL); - g_return_val_if_fail (IS_CAL_COMPONENT (comp), NULL); - - priv = comp->priv; - g_return_val_if_fail (priv->need_sequence_inc == FALSE, NULL); - - return priv->icalcomp; -} - -/** - * cal_component_get_vtype: - * @comp: A calendar component object. - * - * Queries the type of a calendar component object. - * - * Return value: The type of the component, as defined by RFC 2445. - **/ -CalComponentVType -cal_component_get_vtype (CalComponent *comp) -{ - CalComponentPrivate *priv; - icalcomponent_kind kind; - - g_return_val_if_fail (comp != NULL, CAL_COMPONENT_NO_TYPE); - g_return_val_if_fail (IS_CAL_COMPONENT (comp), CAL_COMPONENT_NO_TYPE); - - priv = comp->priv; - g_return_val_if_fail (priv->icalcomp != NULL, CAL_COMPONENT_NO_TYPE); - - kind = icalcomponent_isa (priv->icalcomp); - switch (kind) { - case ICAL_VEVENT_COMPONENT: - return CAL_COMPONENT_EVENT; - - case ICAL_VTODO_COMPONENT: - return CAL_COMPONENT_TODO; - - case ICAL_VJOURNAL_COMPONENT: - return CAL_COMPONENT_JOURNAL; - - case ICAL_VFREEBUSY_COMPONENT: - return CAL_COMPONENT_FREEBUSY; - - case ICAL_VTIMEZONE_COMPONENT: - return CAL_COMPONENT_TIMEZONE; - - default: - /* We should have been loaded with a supported type! */ - g_assert_not_reached (); - return CAL_COMPONENT_NO_TYPE; - } -} - -/** - * cal_component_get_as_string: - * @comp: A calendar component. - * - * Gets the iCalendar string representation of a calendar component. You should - * call cal_component_commit_sequence() before this function to ensure that the - * component's sequence number is consistent with the state of the object. - * - * Return value: String representation of the calendar component according to - * RFC 2445. - **/ -char * -cal_component_get_as_string (CalComponent *comp) -{ - CalComponentPrivate *priv; - char *str, *buf; - - g_return_val_if_fail (comp != NULL, NULL); - g_return_val_if_fail (IS_CAL_COMPONENT (comp), NULL); - - priv = comp->priv; - g_return_val_if_fail (priv->icalcomp != NULL, NULL); - - /* Ensure that the user has committed the new SEQUENCE */ - g_return_val_if_fail (priv->need_sequence_inc == FALSE, NULL); - - /* We dup the string; libical owns that memory */ - - str = icalcomponent_as_ical_string (priv->icalcomp); - - if (str) - buf = g_strdup (str); - else - buf = NULL; - - return buf; -} - -/** - * cal_component_commit_sequence: - * @comp: - * - * Increments the sequence number property in a calendar component object if it - * needs it. This needs to be done when any of a number of properties listed in - * RFC 2445 change values, such as the start and end dates of a component. - * - * This function must be called before calling cal_component_get_as_string() to - * ensure that the component is fully consistent. - **/ -void -cal_component_commit_sequence (CalComponent *comp) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - if (!priv->need_sequence_inc) - return; - - if (priv->sequence) { - int seq; - - seq = icalproperty_get_sequence (priv->sequence); - icalproperty_set_sequence (priv->sequence, seq + 1); - } else { - /* The component had no SEQUENCE property, so assume that the - * default would have been zero. Since it needed incrementing - * anyways, we use a value of 1 here. - */ - priv->sequence = icalproperty_new_sequence (1); - icalcomponent_add_property (priv->icalcomp, priv->sequence); - } - - priv->need_sequence_inc = FALSE; -} - -/** - * cal_component_get_uid: - * @comp: A calendar component object. - * @uid: Return value for the UID string. - * - * Queries the unique identifier of a calendar component object. - **/ -void -cal_component_get_uid (CalComponent *comp, const char **uid) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (uid != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - /* This MUST exist, since we ensured that it did */ - g_assert (priv->uid != NULL); - - *uid = icalproperty_get_uid (priv->uid); -} - -/** - * cal_component_set_uid: - * @comp: A calendar component object. - * @uid: Unique identifier. - * - * Sets the unique identifier string of a calendar component object. - **/ -void -cal_component_set_uid (CalComponent *comp, const char *uid) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (uid != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - /* This MUST exist, since we ensured that it did */ - g_assert (priv->uid != NULL); - - icalproperty_set_uid (priv->uid, (char *) uid); -} - -/** - * cal_component_get_categories: - * @comp: A calendar component object. - * @categories: - * - * - **/ -void -cal_component_get_categories (CalComponent *comp, const char **categories) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (categories != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - if (priv->categories) - *categories = icalproperty_get_categories (priv->categories); - else - *categories = NULL; -} - -/** - * cal_component_set_categories: - * @comp: A calendar component object. - * @categories: - * - * - **/ -void -cal_component_set_categories (CalComponent *comp, const char *categories) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - if (!categories || !(*categories)) { - if (priv->categories) { - icalcomponent_remove_property (priv->icalcomp, priv->categories); - icalproperty_free (priv->categories); - priv->url = NULL; - } - - return; - } - - if (priv->categories) - icalproperty_set_categories (priv->categories, (char *) categories); - else { - priv->categories = icalproperty_new_categories ((char *) categories); - icalcomponent_add_property (priv->icalcomp, priv->categories); - } -} - - -/** - * cal_component_get_categories_list: - * @comp: A calendar component object. - * @categ_list: Return value for the list of strings, where each string is a - * category. This should be freed using cal_component_free_categories_list(). - * - * Queries the list of categories of a calendar component object. Each element - * in the returned categ_list is a string with the corresponding category. - **/ -void -cal_component_get_categories_list (CalComponent *comp, GSList **categ_list) -{ - CalComponentPrivate *priv; - const char *categories; - const char *p; - const char *cat_start; - char *str; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (categ_list != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - if (!priv->categories) { - *categ_list = NULL; - return; - } - - categories = icalproperty_get_categories (priv->categories); - g_assert (categories != NULL); - - cat_start = categories; - *categ_list = NULL; - - for (p = categories; *p; p++) - if (*p == ',') { - str = g_strndup (cat_start, p - cat_start); - *categ_list = g_slist_prepend (*categ_list, str); - - cat_start = p + 1; - } - - str = g_strndup (cat_start, p - cat_start); - *categ_list = g_slist_prepend (*categ_list, str); - - *categ_list = g_slist_reverse (*categ_list); -} - -/* Creates a comma-delimited string of categories */ -static char * -stringify_categories (GSList *categ_list) -{ - GString *s; - GSList *l; - char *str; - - s = g_string_new (NULL); - - for (l = categ_list; l; l = l->next) { - g_string_append (s, l->data); - - if (l->next != NULL) - g_string_append (s, ","); - } - - str = s->str; - g_string_free (s, FALSE); - - return str; -} - -/** - * cal_component_set_categories_list: - * @comp: A calendar component object. - * @categ_list: List of strings, one for each category. - * - * Sets the list of categories of a calendar component object. - **/ -void -cal_component_set_categories_list (CalComponent *comp, GSList *categ_list) -{ - CalComponentPrivate *priv; - char *categories_str; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - if (!categ_list) { - if (priv->categories) { - icalcomponent_remove_property (priv->icalcomp, priv->categories); - icalproperty_free (priv->categories); - } - - return; - } - - /* Create a single string of categories */ - categories_str = stringify_categories (categ_list); - - /* Set the categories */ - priv->categories = icalproperty_new_categories (categories_str); - g_free (categories_str); - - icalcomponent_add_property (priv->icalcomp, priv->categories); -} - -/** - * cal_component_get_classification: - * @comp: A calendar component object. - * @classif: Return value for the classification. - * - * Queries the classification of a calendar component object. If the - * classification property is not set on this component, this function returns - * #CAL_COMPONENT_CLASS_NONE. - **/ -void -cal_component_get_classification (CalComponent *comp, CalComponentClassification *classif) -{ - CalComponentPrivate *priv; - const char *class; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (classif != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - if (!priv->classification) { - *classif = CAL_COMPONENT_CLASS_NONE; - return; - } - - class = icalproperty_get_class (priv->classification); - - if (strcasecmp (class, "PUBLIC") == 0) - *classif = CAL_COMPONENT_CLASS_PUBLIC; - else if (strcasecmp (class, "PRIVATE") == 0) - *classif = CAL_COMPONENT_CLASS_PRIVATE; - else if (strcasecmp (class, "CONFIDENTIAL") == 0) - *classif = CAL_COMPONENT_CLASS_CONFIDENTIAL; - else - *classif = CAL_COMPONENT_CLASS_UNKNOWN; -} - -/** - * cal_component_set_classification: - * @comp: A calendar component object. - * @classif: Classification to use. - * - * Sets the classification property of a calendar component object. To unset - * the property, specify CAL_COMPONENT_CLASS_NONE for @classif. - **/ -void -cal_component_set_classification (CalComponent *comp, CalComponentClassification classif) -{ - CalComponentPrivate *priv; - char *str; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (classif != CAL_COMPONENT_CLASS_UNKNOWN); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - if (classif == CAL_COMPONENT_CLASS_NONE) { - if (priv->classification) { - icalcomponent_remove_property (priv->icalcomp, priv->classification); - icalproperty_free (priv->classification); - priv->classification = NULL; - } - - return; - } - - switch (classif) { - case CAL_COMPONENT_CLASS_PUBLIC: - str = "PUBLIC"; - break; - - case CAL_COMPONENT_CLASS_PRIVATE: - str = "PRIVATE"; - break; - - case CAL_COMPONENT_CLASS_CONFIDENTIAL: - str = "CONFIDENTIAL"; - break; - - default: - g_assert_not_reached (); - str = NULL; - } - - if (priv->classification) - icalproperty_set_class (priv->classification, str); - else { - priv->classification = icalproperty_new_class (str); - icalcomponent_add_property (priv->icalcomp, priv->classification); - } -} - -/* Gets a text list value */ -static void -get_text_list (GSList *text_list, - const char *(* get_prop_func) (icalproperty *prop), - GSList **tl) -{ - GSList *l; - - *tl = NULL; - - if (!text_list) - return; - - for (l = text_list; l; l = l->next) { - struct text *text; - CalComponentText *t; - - text = l->data; - g_assert (text->prop != NULL); - - t = g_new (CalComponentText, 1); - t->value = (* get_prop_func) (text->prop); - - if (text->altrep_param) - t->altrep = icalparameter_get_altrep (text->altrep_param); - else - t->altrep = NULL; - - *tl = g_slist_prepend (*tl, t); - } - - *tl = g_slist_reverse (*tl); -} - -/* Sets a text list value */ -static void -set_text_list (CalComponent *comp, - icalproperty *(* new_prop_func) (const char *value), - GSList **text_list, - GSList *tl) -{ - CalComponentPrivate *priv; - GSList *l; - - priv = comp->priv; - - /* Remove old texts */ - - for (l = *text_list; l; l = l->next) { - struct text *text; - - text = l->data; - g_assert (text->prop != NULL); - - icalcomponent_remove_property (priv->icalcomp, text->prop); - icalproperty_free (text->prop); - g_free (text); - } - - g_slist_free (*text_list); - *text_list = NULL; - - /* Add in new texts */ - - for (l = tl; l; l = l->next) { - CalComponentText *t; - struct text *text; - - t = l->data; - g_return_if_fail (t->value != NULL); - - text = g_new (struct text, 1); - - text->prop = (* new_prop_func) ((char *) t->value); - icalcomponent_add_property (priv->icalcomp, text->prop); - - if (t->altrep) { - text->altrep_param = icalparameter_new_altrep ((char *) t->altrep); - icalproperty_add_parameter (text->prop, text->altrep_param); - } else - text->altrep_param = NULL; - - *text_list = g_slist_prepend (*text_list, text); - } - - *text_list = g_slist_reverse (*text_list); -} - -/** - * cal_component_get_comment_list: - * @comp: A calendar component object. - * @text_list: Return value for the comment properties and their parameters, as - * a list of #CalComponentText structures. This should be freed using the - * cal_component_free_text_list() function. - * - * Queries the comment of a calendar component object. The comment property can - * appear several times inside a calendar component, and so a list of - * #CalComponentText is returned. - **/ -void -cal_component_get_comment_list (CalComponent *comp, GSList **text_list) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (text_list != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - get_text_list (priv->comment_list, icalproperty_get_comment, text_list); -} - -/** - * cal_component_set_comment_list: - * @comp: A calendar component object. - * @text_list: List of #CalComponentText structures. - * - * Sets the comment of a calendar component object. The comment property can - * appear several times inside a calendar component, and so a list of - * #CalComponentText structures is used. - **/ -void -cal_component_set_comment_list (CalComponent *comp, GSList *text_list) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - set_text_list (comp, icalproperty_new_comment, &priv->comment_list, text_list); -} - -/* Gets a struct icaltimetype value */ -static void -get_icaltimetype (icalproperty *prop, - struct icaltimetype (* get_prop_func) (icalproperty *prop), - struct icaltimetype **t) -{ - if (!prop) { - *t = NULL; - return; - } - - *t = g_new (struct icaltimetype, 1); - **t = (* get_prop_func) (prop); -} - -/* Sets a struct icaltimetype value */ -static void -set_icaltimetype (CalComponent *comp, icalproperty **prop, - icalproperty *(* prop_new_func) (struct icaltimetype v), - void (* prop_set_func) (icalproperty *prop, struct icaltimetype v), - struct icaltimetype *t) -{ - CalComponentPrivate *priv; - - priv = comp->priv; - - if (!t) { - if (*prop) { - icalcomponent_remove_property (priv->icalcomp, *prop); - icalproperty_free (*prop); - *prop = NULL; - } - - return; - } - - if (*prop) - (* prop_set_func) (*prop, *t); - else { - *prop = (* prop_new_func) (*t); - icalcomponent_add_property (priv->icalcomp, *prop); - } -} - -/** - * cal_component_get_completed: - * @comp: A calendar component object. - * @t: Return value for the completion date. This should be freed using the - * cal_component_free_icaltimetype() function. - * - * Queries the date at which a calendar compoment object was completed. - **/ -void -cal_component_get_completed (CalComponent *comp, struct icaltimetype **t) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (t != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - get_icaltimetype (priv->completed, icalproperty_get_completed, t); -} - -/** - * cal_component_set_completed: - * @comp: A calendar component object. - * @t: Value for the completion date. - * - * Sets the date at which a calendar component object was completed. - **/ -void -cal_component_set_completed (CalComponent *comp, struct icaltimetype *t) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - set_icaltimetype (comp, &priv->completed, - icalproperty_new_completed, - icalproperty_set_completed, - t); -} - - -/** - * cal_component_get_created: - * @comp: A calendar component object. - * @t: Return value for the creation date. This should be freed using the - * cal_component_free_icaltimetype() function. - * - * Queries the date in which a calendar component object was created in the - * calendar store. - **/ -void -cal_component_get_created (CalComponent *comp, struct icaltimetype **t) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (t != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - get_icaltimetype (priv->created, icalproperty_get_created, t); -} - -/** - * cal_component_set_created: - * @comp: A calendar component object. - * @t: Value for the creation date. - * - * Sets the date in which a calendar component object is created in the calendar - * store. This should only be used inside a calendar store application, i.e. - * not by calendar user agents. - **/ -void -cal_component_set_created (CalComponent *comp, struct icaltimetype *t) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - set_icaltimetype (comp, &priv->created, - icalproperty_new_created, - icalproperty_set_created, - t); -} - -/** - * cal_component_get_description_list: - * @comp: A calendar component object. - * @text_list: Return value for the description properties and their parameters, - * as a list of #CalComponentText structures. This should be freed using the - * cal_component_free_text_list() function. - * - * Queries the description of a calendar component object. Journal components - * may have more than one description, and as such this function returns a list - * of #CalComponentText structures. All other types of components can have at - * most one description. - **/ -void -cal_component_get_description_list (CalComponent *comp, GSList **text_list) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (text_list != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - get_text_list (priv->description_list, icalproperty_get_description, text_list); -} - -/** - * cal_component_set_description_list: - * @comp: A calendar component object. - * @text_list: List of #CalComponentSummary structures. - * - * Sets the description of a calendar component object. Journal components may - * have more than one description, and as such this function takes in a list of - * #CalComponentDescription structures. All other types of components can have - * at most one description. - **/ -void -cal_component_set_description_list (CalComponent *comp, GSList *text_list) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - set_text_list (comp, icalproperty_new_description, &priv->description_list, text_list); -} - -/* Gets a date/time and timezone pair */ -static void -get_datetime (struct datetime *datetime, - struct icaltimetype (* get_prop_func) (icalproperty *prop), - CalComponentDateTime *dt) -{ - if (datetime->prop) { - dt->value = g_new (struct icaltimetype, 1); - *dt->value = (* get_prop_func) (datetime->prop); - } else - dt->value = NULL; - - if (datetime->tzid_param) - dt->tzid = icalparameter_get_tzid (datetime->tzid_param); - else - dt->tzid = NULL; -} - -/* Sets a date/time and timezone pair */ -static void -set_datetime (CalComponent *comp, struct datetime *datetime, - icalproperty *(* prop_new_func) (struct icaltimetype v), - void (* prop_set_func) (icalproperty * prop, struct icaltimetype v), - CalComponentDateTime *dt) -{ - CalComponentPrivate *priv; - - priv = comp->priv; - - if (!dt) { - if (datetime->prop) { - icalcomponent_remove_property (priv->icalcomp, datetime->prop); - icalproperty_free (datetime->prop); - - datetime->prop = NULL; - datetime->tzid_param = NULL; - } - - return; - } - - g_return_if_fail (dt->value != NULL); - - if (datetime->prop) - (* prop_set_func) (datetime->prop, *dt->value); - else { - datetime->prop = (* prop_new_func) (*dt->value); - icalcomponent_add_property (priv->icalcomp, datetime->prop); - } - - if (dt->tzid) { - g_assert (datetime->prop != NULL); - - if (datetime->tzid_param) - icalparameter_set_tzid (datetime->tzid_param, (char *) dt->tzid); - else { - datetime->tzid_param = icalparameter_new_tzid ((char *) dt->tzid); - icalproperty_add_parameter (datetime->prop, datetime->tzid_param); - } - } else if (datetime->tzid_param) { - icalproperty_remove_parameter (datetime->prop, ICAL_TZID_PARAMETER); - icalparameter_free (datetime->tzid_param); - datetime->tzid_param = NULL; - } -} - -/** - * cal_component_get_dtend: - * @comp: A calendar component object. - * @dt: Return value for the date/time end. This should be freed with the - * cal_component_free_datetime() function. - * - * Queries the date/time end of a calendar component object. - **/ -void -cal_component_get_dtend (CalComponent *comp, CalComponentDateTime *dt) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (dt != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - get_datetime (&priv->dtend, icalproperty_get_dtend, dt); -} - -/** - * cal_component_set_dtend: - * @comp: A calendar component object. - * @dt: End date/time. - * - * Sets the date/time end property of a calendar component object. - **/ -void -cal_component_set_dtend (CalComponent *comp, CalComponentDateTime *dt) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - set_datetime (comp, &priv->dtend, - icalproperty_new_dtend, - icalproperty_set_dtend, - dt); - - priv->need_sequence_inc = TRUE; -} - -/** - * cal_component_get_dtstamp: - * @comp: A calendar component object. - * @t: Return value for the date/timestamp. - * - * Queries the date/timestamp property of a calendar component object, which is - * the last time at which the object was modified by a calendar user agent. - **/ -void -cal_component_get_dtstamp (CalComponent *comp, struct icaltimetype *t) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (t != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - /* This MUST exist, since we ensured that it did */ - g_assert (priv->dtstamp != NULL); - - *t = icalproperty_get_dtstamp (priv->dtstamp); -} - -/** - * cal_component_set_dtstamp: - * @comp: A calendar component object. - * @t: Date/timestamp value. - * - * Sets the date/timestamp of a calendar component object. This should be - * called whenever a calendar user agent makes a change to a component's - * properties. - **/ -void -cal_component_set_dtstamp (CalComponent *comp, struct icaltimetype *t) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (t != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - /* This MUST exist, since we ensured that it did */ - g_assert (priv->dtstamp != NULL); - - icalproperty_set_dtstamp (priv->dtstamp, *t); -} - -/** - * cal_component_get_dtstart: - * @comp: A calendar component object. - * @dt: Return value for the date/time start. This should be freed with the - * cal_component_free_datetime() function. - * - * Queries the date/time start of a calendar component object. - **/ -void -cal_component_get_dtstart (CalComponent *comp, CalComponentDateTime *dt) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (dt != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - get_datetime (&priv->dtstart, icalproperty_get_dtstart, dt); -} - -/** - * cal_component_set_dtstart: - * @comp: A calendar component object. - * @dt: Start date/time. - * - * Sets the date/time start property of a calendar component object. - **/ -void -cal_component_set_dtstart (CalComponent *comp, CalComponentDateTime *dt) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - set_datetime (comp, &priv->dtstart, - icalproperty_new_dtstart, - icalproperty_set_dtstart, - dt); - - priv->need_sequence_inc = TRUE; -} - -/** - * cal_component_get_due: - * @comp: A calendar component object. - * @dt: Return value for the due date/time. This should be freed with the - * cal_component_free_datetime() function. - * - * Queries the due date/time of a calendar component object. - **/ -void -cal_component_get_due (CalComponent *comp, CalComponentDateTime *dt) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (dt != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - get_datetime (&priv->due, icalproperty_get_due, dt); -} - -/** - * cal_component_set_due: - * @comp: A calendar component object. - * @dt: End date/time. - * - * Sets the due date/time property of a calendar component object. - **/ -void -cal_component_set_due (CalComponent *comp, CalComponentDateTime *dt) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - set_datetime (comp, &priv->due, - icalproperty_new_due, - icalproperty_set_due, - dt); - - priv->need_sequence_inc = TRUE; -} - -/* Builds a list of CalComponentPeriod structures based on a list of icalproperties */ -static void -get_period_list (GSList *period_list, - struct icaldatetimeperiodtype (* get_prop_func) (icalproperty *prop), - GSList **list) -{ - GSList *l; - - *list = NULL; - - if (!period_list) - return; - - for (l = period_list; l; l = l->next) { - struct period *period; - CalComponentPeriod *p; - struct icaldatetimeperiodtype ip; - - period = l->data; - g_assert (period->prop != NULL); - - p = g_new (CalComponentPeriod, 1); - - /* Get value parameter */ - - if (period->value_param) { - icalparameter_value value_type; - - value_type = icalparameter_get_value (period->value_param); - - if (value_type == ICAL_VALUE_DATE || value_type == ICAL_VALUE_DATETIME) - p->type = CAL_COMPONENT_PERIOD_DATETIME; - else if (value_type == ICAL_VALUE_DURATION) - p->type = CAL_COMPONENT_PERIOD_DURATION; - else { - g_message ("get_period_list(): Unknown value for period %d; " - "using DATETIME", value_type); - p->type = CAL_COMPONENT_PERIOD_DATETIME; - } - } else - p->type = CAL_COMPONENT_PERIOD_DATETIME; - - /* Get start and end/duration */ - - ip = (* get_prop_func) (period->prop); - - p->start = ip.period.start; - - if (p->type == CAL_COMPONENT_PERIOD_DATETIME) - p->u.end = ip.period.end; - else if (p->type == CAL_COMPONENT_PERIOD_DURATION) - p->u.duration = ip.period.duration; - else - g_assert_not_reached (); - - /* Put in list */ - - *list = g_slist_prepend (*list, p); - } - - *list = g_slist_reverse (*list); -} - -/* Sets a period list value */ -static void -set_period_list (CalComponent *comp, - icalproperty *(* new_prop_func) (struct icaldatetimeperiodtype period), - GSList **period_list, - GSList *pl) -{ - CalComponentPrivate *priv; - GSList *l; - - priv = comp->priv; - - /* Remove old periods */ - - for (l = *period_list; l; l = l->next) { - struct period *period; - - period = l->data; - g_assert (period->prop != NULL); - - icalcomponent_remove_property (priv->icalcomp, period->prop); - icalproperty_free (period->prop); - g_free (period); - } - - g_slist_free (*period_list); - *period_list = NULL; - - /* Add in new periods */ - - for (l = pl; l; l = l->next) { - CalComponentPeriod *p; - struct period *period; - struct icaldatetimeperiodtype ip; - icalparameter_value value_type; - - g_assert (l->data != NULL); - p = l->data; - - /* Create libical value */ - - ip.period.start = p->start; - - if (p->type == CAL_COMPONENT_PERIOD_DATETIME) { - value_type = ICAL_VALUE_DATETIME; - ip.period.end = p->u.end; - } else if (p->type == CAL_COMPONENT_PERIOD_DURATION) { - value_type = ICAL_VALUE_DURATION; - ip.period.duration = p->u.duration; - } else { - g_assert_not_reached (); - return; - } - - /* Create property */ - - period = g_new (struct period, 1); - - period->prop = (* new_prop_func) (ip); - period->value_param = icalparameter_new_value (value_type); - icalproperty_add_parameter (period->prop, period->value_param); - - /* Add to list */ - - *period_list = g_slist_prepend (*period_list, period); - } - - *period_list = g_slist_reverse (*period_list); -} - -/** - * cal_component_get_exdate_list: - * @comp: A calendar component object. - * @exdate_list: Return value for the list of exception dates, as a list of - * #CalComponentDateTime structures. This should be freed using the - * cal_component_free_exdate_list() function. - * - * Queries the list of exception date properties in a calendar component object. - **/ -void -cal_component_get_exdate_list (CalComponent *comp, GSList **exdate_list) -{ - CalComponentPrivate *priv; - GSList *l; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (exdate_list != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - *exdate_list = NULL; - - for (l = priv->exdate_list; l; l = l->next) { - struct datetime *dt; - CalComponentDateTime *cdt; - - dt = l->data; - - cdt = g_new (CalComponentDateTime, 1); - cdt->value = g_new (struct icaltimetype, 1); - - *cdt->value = icalproperty_get_exdate (dt->prop); - - if (dt->tzid_param) - cdt->tzid = icalparameter_get_tzid (dt->tzid_param); - else - cdt->tzid = NULL; - - *exdate_list = g_slist_prepend (*exdate_list, cdt); - } - - *exdate_list = g_slist_reverse (*exdate_list); -} - -/** - * cal_component_set_exdate_list: - * @comp: A calendar component object. - * @exdate_list: List of #CalComponentDateTime structures. - * - * Sets the list of exception dates in a calendar component object. - **/ -void -cal_component_set_exdate_list (CalComponent *comp, GSList *exdate_list) -{ - CalComponentPrivate *priv; - GSList *l; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - /* Remove old exception dates */ - - for (l = priv->exdate_list; l; l = l->next) { - struct datetime *dt; - - dt = l->data; - - icalcomponent_remove_property (priv->icalcomp, dt->prop); - icalproperty_free (dt->prop); - g_free (dt); - } - - g_slist_free (priv->exdate_list); - priv->exdate_list = NULL; - - /* Add in new exception dates */ - - for (l = exdate_list; l; l = l->next) { - CalComponentDateTime *cdt; - struct datetime *dt; - - g_assert (l->data != NULL); - cdt = l->data; - - g_assert (cdt->value != NULL); - - dt = g_new (struct datetime, 1); - dt->prop = icalproperty_new_exdate (*cdt->value); - - if (cdt->tzid) { - dt->tzid_param = icalparameter_new_tzid ((char *) cdt->tzid); - icalproperty_add_parameter (dt->prop, dt->tzid_param); - } else - dt->tzid_param = NULL; - - icalcomponent_add_property (priv->icalcomp, dt->prop); - priv->exdate_list = g_slist_prepend (priv->exdate_list, dt); - } - - priv->exdate_list = g_slist_reverse (priv->exdate_list); - - priv->need_sequence_inc = TRUE; -} - -/** - * cal_component_has_exdates: - * @comp: A calendar component object. - * - * Queries whether a calendar component object has any exception dates defined - * for it. - * - * Return value: TRUE if the component has exception dates, FALSE otherwise. - **/ -gboolean -cal_component_has_exdates (CalComponent *comp) -{ - CalComponentPrivate *priv; - - g_return_val_if_fail (comp != NULL, FALSE); - g_return_val_if_fail (IS_CAL_COMPONENT (comp), FALSE); - - priv = comp->priv; - g_return_val_if_fail (priv->icalcomp != NULL, FALSE); - - return (priv->exdate_list != NULL); -} - -/* Gets a list of recurrence rules */ -static void -get_recur_list (GSList *recur_list, - struct icalrecurrencetype (* get_prop_func) (icalproperty *prop), - GSList **list) -{ - GSList *l; - - *list = NULL; - - for (l = recur_list; l; l = l->next) { - icalproperty *prop; - struct icalrecurrencetype *r; - - prop = l->data; - - r = g_new (struct icalrecurrencetype, 1); - *r = (* get_prop_func) (prop); - - *list = g_slist_prepend (*list, r); - } - - *list = g_slist_reverse (*list); -} - -/* Sets a list of recurrence rules */ -static void -set_recur_list (CalComponent *comp, - icalproperty *(* new_prop_func) (struct icalrecurrencetype recur), - GSList **recur_list, - GSList *rl) -{ - CalComponentPrivate *priv; - GSList *l; - - priv = comp->priv; - - /* Remove old recurrences */ - - for (l = *recur_list; l; l = l->next) { - icalproperty *prop; - - prop = l->data; - icalcomponent_remove_property (priv->icalcomp, prop); - icalproperty_free (prop); - } - - g_slist_free (*recur_list); - *recur_list = NULL; - - /* Add in new recurrences */ - - for (l = rl; l; l = l->next) { - icalproperty *prop; - struct icalrecurrencetype *recur; - - g_assert (l->data != NULL); - recur = l->data; - - prop = (* new_prop_func) (*recur); - icalcomponent_add_property (priv->icalcomp, prop); - - *recur_list = g_slist_prepend (*recur_list, prop); - } - - *recur_list = g_slist_reverse (*recur_list); -} - -/** - * cal_component_get_exrule_list: - * @comp: A calendar component object. - * @recur_list: List of exception rules as struct #icalrecurrencetype - * structures. This should be freed using the cal_component_free_recur_list() - * function. - * - * Queries the list of exception rule properties of a calendar component - * object. - **/ -void -cal_component_get_exrule_list (CalComponent *comp, GSList **recur_list) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (recur_list != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - get_recur_list (priv->exrule_list, icalproperty_get_exrule, recur_list); -} - -/** - * cal_component_get_exrule_property_list: - * @comp: A calendar component object. - * @recur_list: Returns a list of exception rule properties. - * - * Queries the list of exception rule properties of a calendar component object. - **/ -void -cal_component_get_exrule_property_list (CalComponent *comp, GSList **recur_list) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (recur_list != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - *recur_list = priv->exrule_list; -} - -/** - * cal_component_set_exrule_list: - * @comp: A calendar component object. - * @recur_list: List of struct #icalrecurrencetype structures. - * - * Sets the list of exception rules in a calendar component object. - **/ -void -cal_component_set_exrule_list (CalComponent *comp, GSList *recur_list) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - set_recur_list (comp, icalproperty_new_exrule, &priv->exrule_list, recur_list); - - priv->need_sequence_inc = TRUE; -} - -/** - * cal_component_has_exrules: - * @comp: A calendar component object. - * - * Queries whether a calendar component object has any exception rules defined - * for it. - * - * Return value: TRUE if the component has exception rules, FALSE otherwise. - **/ -gboolean -cal_component_has_exrules (CalComponent *comp) -{ - CalComponentPrivate *priv; - - g_return_val_if_fail (comp != NULL, FALSE); - g_return_val_if_fail (IS_CAL_COMPONENT (comp), FALSE); - - priv = comp->priv; - g_return_val_if_fail (priv->icalcomp != NULL, FALSE); - - return (priv->exrule_list != NULL); -} - -/** - * cal_component_has_exceptions: - * @comp: A calendar component object - * - * Queries whether a calendar component object has any exception dates - * or exception rules. - * - * Return value: TRUE if the component has exceptions, FALSE otherwise. - **/ -gboolean -cal_component_has_exceptions (CalComponent *comp) -{ - return cal_component_has_exdates (comp) || cal_component_has_exrules (comp); -} - -/** - * cal_component_get_geo: - * @comp: A calendar component object. - * @geo: Return value for the geographic position property. This should be - * freed using the cal_component_free_geo() function. - * - * Sets the geographic position property of a calendar component object. - **/ -void -cal_component_get_geo (CalComponent *comp, struct icalgeotype **geo) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (geo != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - if (priv->geo) { - *geo = g_new (struct icalgeotype, 1); - **geo = icalproperty_get_geo (priv->geo); - } else - *geo = NULL; -} - -/** - * cal_component_set_geo: - * @comp: A calendar component object. - * @geo: Value for the geographic position property. - * - * Sets the geographic position property on a calendar component object. - **/ -void -cal_component_set_geo (CalComponent *comp, struct icalgeotype *geo) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - if (!geo) { - if (priv->geo) { - icalcomponent_remove_property (priv->icalcomp, priv->geo); - icalproperty_free (priv->geo); - priv->geo = NULL; - } - - return; - } - - if (priv->geo) - icalproperty_set_geo (priv->geo, *geo); - else { - priv->geo = icalproperty_new_geo (*geo); - icalcomponent_add_property (priv->icalcomp, priv->geo); - } -} - -/** - * cal_component_get_last_modified: - * @comp: A calendar component object. - * @t: Return value for the last modified time value. - * - * Queries the time at which a calendar component object was last modified in - * the calendar store. - **/ -void -cal_component_get_last_modified (CalComponent *comp, struct icaltimetype **t) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (t != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - get_icaltimetype (priv->last_modified, icalproperty_get_lastmodified, t); -} - -/** - * cal_component_set_last_modified: - * @comp: A calendar component object. - * @t: Value for the last time modified. - * - * Sets the time at which a calendar component object was last stored in the - * calendar store. This should not be called by plain calendar user agents. - **/ -void -cal_component_set_last_modified (CalComponent *comp, struct icaltimetype *t) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - set_icaltimetype (comp, &priv->last_modified, - icalproperty_new_lastmodified, - icalproperty_set_lastmodified, - t); -} - -/** - * cal_component_get_percent: - * @comp: A calendar component object. - * @percent: Return value for the percent-complete property. This should be - * freed using the cal_component_free_percent() function. - * - * Queries the percent-complete property of a calendar component object. - **/ -void -cal_component_get_percent (CalComponent *comp, int **percent) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (percent != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - if (priv->percent) { - *percent = g_new (int, 1); - **percent = icalproperty_get_percentcomplete (priv->percent); - } else - *percent = NULL; -} - -/** - * cal_component_set_percent: - * @comp: A calendar component object. - * @percent: Value for the percent-complete property. - * - * Sets the percent-complete property of a calendar component object. - **/ -void -cal_component_set_percent (CalComponent *comp, int *percent) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - if (!percent) { - if (priv->percent) { - icalcomponent_remove_property (priv->icalcomp, priv->percent); - icalproperty_free (priv->percent); - priv->percent = NULL; - } - - return; - } - - g_return_if_fail (*percent >= 0 && *percent <= 100); - - if (priv->percent) - icalproperty_set_percentcomplete (priv->percent, *percent); - else { - priv->percent = icalproperty_new_percentcomplete (*percent); - icalcomponent_add_property (priv->icalcomp, priv->percent); - } -} - -/** - * cal_component_get_priority: - * @comp: A calendar component object. - * @priority: Return value for the priority property. This should be freed using - * the cal_component_free_priority() function. - * - * Queries the priority property of a calendar component object. - **/ -void -cal_component_get_priority (CalComponent *comp, int **priority) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (priority != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - if (priv->priority) { - *priority = g_new (int, 1); - **priority = icalproperty_get_priority (priv->priority); - } else - *priority = NULL; -} - -/** - * cal_component_set_priority: - * @comp: A calendar component object. - * @priority: Value for the priority property. - * - * Sets the priority property of a calendar component object. - **/ -void -cal_component_set_priority (CalComponent *comp, int *priority) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - if (!priority) { - if (priv->priority) { - icalcomponent_remove_property (priv->icalcomp, priv->priority); - icalproperty_free (priv->priority); - priv->priority = NULL; - } - - return; - } - - g_return_if_fail (*priority >= 0 && *priority <= 9); - - if (priv->priority) - icalproperty_set_priority (priv->priority, *priority); - else { - priv->priority = icalproperty_new_priority (*priority); - icalcomponent_add_property (priv->icalcomp, priv->priority); - } -} - -/** - * cal_component_get_rdate_list: - * @comp: A calendar component object. - * @period_list: Return value for the list of recurrence dates, as a list of - * #CalComponentPeriod structures. This should be freed using the - * cal_component_free_period_list() function. - * - * Queries the list of recurrence date properties in a calendar component - * object. - **/ -void -cal_component_get_rdate_list (CalComponent *comp, GSList **period_list) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (period_list != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - get_period_list (priv->rdate_list, icalproperty_get_rdate, period_list); -} - -/** - * cal_component_set_rdate_list: - * @comp: A calendar component object. - * @period_list: List of #CalComponentPeriod structures. - * - * Sets the list of recurrence dates in a calendar component object. - **/ -void -cal_component_set_rdate_list (CalComponent *comp, GSList *period_list) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - set_period_list (comp, icalproperty_new_rdate, &priv->rdate_list, period_list); - - priv->need_sequence_inc = TRUE; -} - -/** - * cal_component_has_rdates: - * @comp: A calendar component object. - * - * Queries whether a calendar component object has any recurrence dates defined - * for it. - * - * Return value: TRUE if the component has recurrence dates, FALSE otherwise. - **/ -gboolean -cal_component_has_rdates (CalComponent *comp) -{ - CalComponentPrivate *priv; - - g_return_val_if_fail (comp != NULL, FALSE); - g_return_val_if_fail (IS_CAL_COMPONENT (comp), FALSE); - - priv = comp->priv; - g_return_val_if_fail (priv->icalcomp != NULL, FALSE); - - return (priv->rdate_list != NULL); -} - -/** - * cal_component_get_rrule_list: - * @comp: A calendar component object. - * @recur_list: List of recurrence rules as struct #icalrecurrencetype - * structures. This should be freed using the cal_component_free_recur_list() - * function. - * - * Queries the list of recurrence rule properties of a calendar component - * object. - **/ -void -cal_component_get_rrule_list (CalComponent *comp, GSList **recur_list) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (recur_list != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - get_recur_list (priv->rrule_list, icalproperty_get_rrule, recur_list); -} - -/** - * cal_component_get_rrule_property_list: - * @comp: A calendar component object. - * @recur_list: Returns a list of recurrence rule properties. - * - * Queries a list of recurrence rule properties of a calendar component object. - **/ -void -cal_component_get_rrule_property_list (CalComponent *comp, GSList **recur_list) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (recur_list != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - *recur_list = priv->rrule_list; -} - -/** - * cal_component_set_rrule_list: - * @comp: A calendar component object. - * @recur_list: List of struct #icalrecurrencetype structures. - * - * Sets the list of recurrence rules in a calendar component object. - **/ -void -cal_component_set_rrule_list (CalComponent *comp, GSList *recur_list) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - set_recur_list (comp, icalproperty_new_rrule, &priv->rrule_list, recur_list); - - priv->need_sequence_inc = TRUE; -} - -/** - * cal_component_has_rrules: - * @comp: A calendar component object. - * - * Queries whether a calendar component object has any recurrence rules defined - * for it. - * - * Return value: TRUE if the component has recurrence rules, FALSE otherwise. - **/ -gboolean -cal_component_has_rrules (CalComponent *comp) -{ - CalComponentPrivate *priv; - - g_return_val_if_fail (comp != NULL, FALSE); - g_return_val_if_fail (IS_CAL_COMPONENT (comp), FALSE); - - priv = comp->priv; - g_return_val_if_fail (priv->icalcomp != NULL, FALSE); - - return (priv->rrule_list != NULL); -} - -/** - * cal_component_has_recurrences: - * @comp: A calendar component object - * - * Queries whether a calendar component object has any recurrence dates or - * recurrence rules. - * - * Return value: TRUE if the component has recurrences, FALSE otherwise. - **/ -gboolean -cal_component_has_recurrences (CalComponent *comp) -{ - return cal_component_has_rdates (comp) || cal_component_has_rrules (comp); -} - -/** - * cal_component_get_sequence: - * @comp: A calendar component object. - * @sequence: Return value for the sequence number. This should be freed using - * cal_component_free_sequence(). - * - * Queries the sequence number of a calendar component object. - **/ -void -cal_component_get_sequence (CalComponent *comp, int **sequence) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (sequence != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - if (!priv->sequence) { - *sequence = NULL; - return; - } - - *sequence = g_new (int, 1); - **sequence = icalproperty_get_sequence (priv->sequence); -} - -/** - * cal_component_set_sequence: - * @comp: A calendar component object. - * @sequence: Sequence number value. - * - * Sets the sequence number of a calendar component object. Normally this - * function should not be called, since the sequence number is incremented - * automatically at the proper times. - **/ -void -cal_component_set_sequence (CalComponent *comp, int *sequence) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - priv->need_sequence_inc = FALSE; - - if (!sequence) { - if (priv->sequence) { - icalcomponent_remove_property (priv->icalcomp, priv->sequence); - icalproperty_free (priv->sequence); - priv->sequence = NULL; - } - - return; - } - - if (priv->sequence) - icalproperty_set_sequence (priv->sequence, *sequence); - else { - priv->sequence = icalproperty_new_sequence (*sequence); - icalcomponent_add_property (priv->icalcomp, priv->sequence); - } -} - -/** - * cal_component_get_status: - * @comp: A calendar component object. - * @status: Return value for the status value. It is set to #ICAL_STATUS_NONE - * if the component has no status property. - * - * Queries the status property of a calendar component object. - **/ -void -cal_component_get_status (CalComponent *comp, icalproperty_status *status) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (status != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - if (!priv->status) { - *status = ICAL_STATUS_NONE; - return; - } - - *status = icalproperty_get_status (priv->status); -} - -/** - * cal_component_set_status: - * @comp: A calendar component object. - * @status: Status value. You should use #ICAL_STATUS_NONE if you want to unset - * this property. - * - * Sets the status property of a calendar component object. - **/ -void -cal_component_set_status (CalComponent *comp, icalproperty_status status) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - priv->need_sequence_inc = TRUE; - - if (status == ICAL_STATUS_NONE) { - if (priv->status) { - icalcomponent_remove_property (priv->icalcomp, priv->status); - icalproperty_free (priv->status); - priv->status = NULL; - } - - return; - } - - if (priv->status) { - icalproperty_set_status (priv->status, status); - } else { - priv->status = icalproperty_new_status (status); - icalcomponent_add_property (priv->icalcomp, priv->status); - } -} - -/** - * cal_component_get_summary: - * @comp: A calendar component object. - * @summary: Return value for the summary property and its parameters. - * - * Queries the summary of a calendar component object. - **/ -void -cal_component_get_summary (CalComponent *comp, CalComponentText *summary) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (summary != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - if (priv->summary.prop) - summary->value = icalproperty_get_summary (priv->summary.prop); - else - summary->value = NULL; - - if (priv->summary.altrep_param) - summary->altrep = icalparameter_get_altrep (priv->summary.altrep_param); - else - summary->altrep = NULL; -} - -/** - * cal_component_set_summary: - * @comp: A calendar component object. - * @summary: Summary property and its parameters. - * - * Sets the summary of a calendar component object. - **/ -void -cal_component_set_summary (CalComponent *comp, CalComponentText *summary) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - if (!summary) { - if (priv->summary.prop) { - icalcomponent_remove_property (priv->icalcomp, priv->summary.prop); - icalproperty_free (priv->summary.prop); - - priv->summary.prop = NULL; - priv->summary.altrep_param = NULL; - } - - return; - } - - g_return_if_fail (summary->value != NULL); - - if (priv->summary.prop) - icalproperty_set_summary (priv->summary.prop, (char *) summary->value); - else { - priv->summary.prop = icalproperty_new_summary ((char *) summary->value); - icalcomponent_add_property (priv->icalcomp, priv->summary.prop); - } - - if (summary->altrep) { - g_assert (priv->summary.prop != NULL); - - if (priv->summary.altrep_param) - icalparameter_set_altrep (priv->summary.altrep_param, - (char *) summary->altrep); - else { - priv->summary.altrep_param = icalparameter_new_altrep ( - (char *) summary->altrep); - icalproperty_add_parameter (priv->summary.prop, - priv->summary.altrep_param); - } - } else if (priv->summary.altrep_param) { - icalproperty_remove_parameter (priv->summary.prop, ICAL_ALTREP_PARAMETER); - icalparameter_free (priv->summary.altrep_param); - priv->summary.altrep_param = NULL; - } -} - -/** - * cal_component_get_transparency: - * @comp: A calendar component object. - * @transp: Return value for the time transparency. - * - * Queries the time transparency of a calendar component object. - **/ -void -cal_component_get_transparency (CalComponent *comp, CalComponentTransparency *transp) -{ - CalComponentPrivate *priv; - const char *val; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (transp != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - if (!priv->transparency) { - *transp = CAL_COMPONENT_TRANSP_NONE; - return; - } - - val = icalproperty_get_transp (priv->transparency); - - if (strcasecmp (val, "TRANSPARENT")) - *transp = CAL_COMPONENT_TRANSP_TRANSPARENT; - else if (strcasecmp (val, "OPAQUE")) - *transp = CAL_COMPONENT_TRANSP_OPAQUE; - else - *transp = CAL_COMPONENT_TRANSP_UNKNOWN; -} - -/** - * cal_component_set_transparency: - * @comp: A calendar component object. - * @transp: Time transparency value. - * - * Sets the time transparency of a calendar component object. - **/ -void -cal_component_set_transparency (CalComponent *comp, CalComponentTransparency transp) -{ - CalComponentPrivate *priv; - char *str; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (transp != CAL_COMPONENT_TRANSP_UNKNOWN); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - - if (transp == CAL_COMPONENT_TRANSP_NONE) { - if (priv->transparency) { - icalcomponent_remove_property (priv->icalcomp, priv->transparency); - icalproperty_free (priv->transparency); - priv->transparency = NULL; - } - - return; - } - - switch (transp) { - case CAL_COMPONENT_TRANSP_TRANSPARENT: - str = "TRANSPARENT"; - break; - - case CAL_COMPONENT_TRANSP_OPAQUE: - str = "OPAQUE"; - break; - - default: - g_assert_not_reached (); - str = NULL; - } - - if (priv->transparency) - icalproperty_set_transp (priv->transparency, str); - else { - priv->transparency = icalproperty_new_transp (str); - icalcomponent_add_property (priv->icalcomp, priv->transparency); - } -} - -/** - * cal_component_get_url: - * @comp: A calendar component object. - * @url: Return value for the URL. - * - * Queries the uniform resource locator property of a calendar component object. - **/ -void -cal_component_get_url (CalComponent *comp, const char **url) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (url != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - if (priv->url) - *url = icalproperty_get_url (priv->url); - else - *url = NULL; -} - -/** - * cal_component_set_url: - * @comp: A calendar component object. - * @url: URL value. - * - * Sets the uniform resource locator property of a calendar component object. - **/ -void -cal_component_set_url (CalComponent *comp, const char *url) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - if (!url || !(*url)) { - if (priv->url) { - icalcomponent_remove_property (priv->icalcomp, priv->url); - icalproperty_free (priv->url); - priv->url = NULL; - } - - return; - } - - if (priv->url) - icalproperty_set_url (priv->url, (char *) url); - else { - priv->url = icalproperty_new_url ((char *) url); - icalcomponent_add_property (priv->icalcomp, priv->url); - } -} - - - -/** - * cal_component_free_categories_list: - * @categ_list: List of category strings. - * - * Frees a list of category strings. - **/ -void -cal_component_free_categories_list (GSList *categ_list) -{ - GSList *l; - - for (l = categ_list; l; l = l->next) - g_free (l->data); - - g_slist_free (categ_list); -} - -/** - * cal_component_free_datetime: - * @dt: A date/time structure. - * - * Frees a date/time structure. - **/ -void -cal_component_free_datetime (CalComponentDateTime *dt) -{ - g_return_if_fail (dt != NULL); - - if (dt->value) - g_free (dt->value); -} - -/** - * cal_component_free_exdate_list: - * @exdate_list: List of #CalComponentDateTime structures. - * - * Frees a list of #CalComponentDateTime structures as returned by the - * cal_component_get_exdate_list() function. - **/ -void -cal_component_free_exdate_list (GSList *exdate_list) -{ - GSList *l; - - for (l = exdate_list; l; l = l->next) { - CalComponentDateTime *cdt; - - g_assert (l->data != NULL); - cdt = l->data; - - g_assert (cdt->value != NULL); - g_free (cdt->value); - - g_free (cdt); - } - - g_slist_free (exdate_list); -} - -/** - * cal_component_free_geo: - * @geo: An #icalgeotype structure. - * - * Frees a struct #icalgeotype structure as returned by the calendar component - * functions. - **/ -void -cal_component_free_geo (struct icalgeotype *geo) -{ - g_return_if_fail (geo != NULL); - - g_free (geo); -} - -/** - * cal_component_free_icaltimetype: - * @t: An #icaltimetype structure. - * - * Frees a struct #icaltimetype value as returned by the calendar component - * functions. - **/ -void -cal_component_free_icaltimetype (struct icaltimetype *t) -{ - g_return_if_fail (t != NULL); - - g_free (t); -} - -/** - * cal_component_free_percent: - * @percent: Percent value. - * - * Frees a percent value as returned by the cal_component_get_percent() - * function. - **/ -void -cal_component_free_percent (int *percent) -{ - g_return_if_fail (percent != NULL); - - g_free (percent); -} - -/** - * cal_component_free_priority: - * @priority: Priority value. - * - * Frees a priority value as returned by the cal_component_get_priority() - * function. - **/ -void -cal_component_free_priority (int *priority) -{ - g_return_if_fail (priority != NULL); - - g_free (priority); -} - -/** - * cal_component_free_period_list: - * @period_list: List of #CalComponentPeriod structures. - * - * Frees a list of #CalComponentPeriod structures. - **/ -void -cal_component_free_period_list (GSList *period_list) -{ - GSList *l; - - for (l = period_list; l; l = l->next) { - CalComponentPeriod *period; - - g_assert (l->data != NULL); - - period = l->data; - g_free (period); - } - - g_slist_free (period_list); -} - -/** - * cal_component_free_recur_list: - * @recur_list: List of struct #icalrecurrencetype structures. - * - * Frees a list of struct #icalrecurrencetype structures. - **/ -void -cal_component_free_recur_list (GSList *recur_list) -{ - GSList *l; - - for (l = recur_list; l; l = l->next) { - struct icalrecurrencetype *r; - - g_assert (l->data != NULL); - r = l->data; - - g_free (r); - } - - g_slist_free (recur_list); -} - -/** - * cal_component_free_sequence: - * @sequence: Sequence number value. - * - * Frees a sequence number value. - **/ -void -cal_component_free_sequence (int *sequence) -{ - g_return_if_fail (sequence != NULL); - - g_free (sequence); -} - -/** - * cal_component_free_text_list: - * @text_list: List of #CalComponentText structures. - * - * Frees a list of #CalComponentText structures. This function should only be - * used to free lists of text values as returned by the other getter functions - * of #CalComponent. - **/ -void -cal_component_free_text_list (GSList *text_list) -{ - GSList *l; - - for (l = text_list; l; l = l->next) { - CalComponentText *text; - - g_assert (l->data != NULL); - - text = l->data; - g_return_if_fail (text != NULL); - g_free (text); - } - - g_slist_free (text_list); -} - - - -/** - * cal_component_has_alarms: - * @comp: A calendar component object. - * - * Checks whether the component has any alarms. - * - * Return value: TRUE if the component has any alarms. - **/ -gboolean -cal_component_has_alarms (CalComponent *comp) -{ - CalComponentPrivate *priv; - - g_return_val_if_fail (comp != NULL, FALSE); - g_return_val_if_fail (IS_CAL_COMPONENT (comp), FALSE); - - priv = comp->priv; - g_return_val_if_fail (priv->icalcomp != NULL, FALSE); - - return g_hash_table_size (priv->alarm_uid_hash) != 0; -} - -void -cal_component_add_alarm (CalComponent *comp, CalComponentAlarm *alarm) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (alarm != NULL); - - priv = comp->priv; - - alarm->parent = comp; - add_alarm (comp, alarm->icalcomp, icalproperty_get_x (alarm->uid)); - icalcomponent_add_component (priv->icalcomp, alarm->icalcomp); -} - -void -cal_component_remove_alarm (CalComponent *comp, const char *auid) -{ - CalComponentPrivate *priv; - icalcompiter iter; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (auid != NULL); - - priv = comp->priv; - - for (iter = icalcomponent_begin_component (priv->icalcomp, ICAL_VALARM_COMPONENT); - icalcompiter_deref (&iter) != NULL; - icalcompiter_next (&iter)) { - icalproperty *prop; - icalcomponent *subcomp; - - subcomp = icalcompiter_deref (&iter); - for (prop = icalcomponent_get_first_property (subcomp, ICAL_X_PROPERTY); - prop; - prop = icalcomponent_get_next_property (subcomp, ICAL_X_PROPERTY)) { - const char *xname; - const char *alarm_uid; - - xname = icalproperty_get_x_name (prop); - g_assert (xname != NULL); - - if (strcmp (xname, EVOLUTION_ALARM_UID_PROPERTY) == 0) { - alarm_uid = alarm_uid_from_prop (prop); - if (strcmp (alarm_uid, auid) == 0) { - remove_alarm (comp, auid); - icalcomponent_remove_component (priv->icalcomp, subcomp); - icalcomponent_free (subcomp); - break; - } - - return; - } - } - } -} - - -/* Scans an icalproperty from a calendar component and adds its mapping to our - * own alarm structure. - */ -static void -scan_alarm_property (CalComponentAlarm *alarm, icalproperty *prop) -{ - icalproperty_kind kind; - const char *xname; - - kind = icalproperty_isa (prop); - - switch (kind) { - case ICAL_ACTION_PROPERTY: - alarm->action = prop; - break; - - case ICAL_TRIGGER_PROPERTY: - alarm->trigger = prop; - break; - - case ICAL_X_PROPERTY: - xname = icalproperty_get_x_name (prop); - g_assert (xname != NULL); - - if (strcmp (xname, EVOLUTION_ALARM_UID_PROPERTY) == 0) - alarm->uid = prop; - - break; - - default: - break; - } -} - -/* Creates a CalComponentAlarm from a libical alarm subcomponent */ -static CalComponentAlarm * -make_alarm (CalComponent *comp, icalcomponent *subcomp) -{ - CalComponentAlarm *alarm; - icalproperty *prop; - - alarm = g_new (CalComponentAlarm, 1); - - alarm->parent = comp; - alarm->icalcomp = subcomp; - alarm->uid = NULL; - - for (prop = icalcomponent_get_first_property (subcomp, ICAL_ANY_PROPERTY); - prop; - prop = icalcomponent_get_next_property (subcomp, ICAL_ANY_PROPERTY)) - scan_alarm_property (alarm, prop); - - g_assert (alarm->uid != NULL); - - return alarm; -} - -/* Used from g_hash_table_foreach(); adds an alarm UID to a list */ -static void -add_alarm_uid (gpointer key, gpointer value, gpointer data) -{ - const char *auid; - GList **l; - - auid = key; - l = data; - - *l = g_list_prepend (*l, g_strdup (auid)); -} - -/** - * cal_component_get_alarm_uids: - * @comp: A calendar component. - * - * Builds a list of the unique identifiers of the alarm subcomponents inside a - * calendar component. - * - * Return value: List of unique identifiers for alarms. This should be freed - * using cal_obj_uid_list_free(). - **/ -GList * -cal_component_get_alarm_uids (CalComponent *comp) -{ - CalComponentPrivate *priv; - GList *l; - - g_return_val_if_fail (comp != NULL, NULL); - g_return_val_if_fail (IS_CAL_COMPONENT (comp), NULL); - - priv = comp->priv; - g_return_val_if_fail (priv->icalcomp != NULL, NULL); - - l = NULL; - g_hash_table_foreach (priv->alarm_uid_hash, add_alarm_uid, &l); - - return l; -} - -/** - * cal_component_get_alarm: - * @comp: A calendar component. - * @auid: Unique identifier for the sought alarm subcomponent. - * - * Queries a particular alarm subcomponent of a calendar component. - * - * Return value: The alarm subcomponent that corresponds to the specified @auid, - * or #NULL if no alarm exists with that UID. This should be freed using - * cal_component_alarm_free(). - **/ -CalComponentAlarm * -cal_component_get_alarm (CalComponent *comp, const char *auid) -{ - CalComponentPrivate *priv; - icalcomponent *alarm; - - g_return_val_if_fail (comp != NULL, NULL); - g_return_val_if_fail (IS_CAL_COMPONENT (comp), NULL); - - priv = comp->priv; - g_return_val_if_fail (priv->icalcomp != NULL, NULL); - - g_return_val_if_fail (auid != NULL, NULL); - - alarm = g_hash_table_lookup (priv->alarm_uid_hash, auid); - - if (alarm) - return make_alarm (comp, alarm); - else - return NULL; -} - -void -cal_component_free_alarm_uids (GList *alarm_uids) -{ - g_list_foreach (alarm_uids, (GFunc)g_free, NULL); -} - -/** - * cal_component_alarms_free: - * @alarms: Component alarms structure. - * - * Frees a #CalComponentAlarms structure. - **/ -void -cal_component_alarms_free (CalComponentAlarms *alarms) -{ - GSList *l; - - g_return_if_fail (alarms != NULL); - - g_assert (alarms->comp != NULL); - gtk_object_unref (GTK_OBJECT (alarms->comp)); - - for (l = alarms->alarms; l; l = l->next) { - CalAlarmInstance *instance; - - instance = l->data; - g_assert (instance != NULL); - g_free (instance); - } - - g_slist_free (alarms->alarms); - g_free (alarms); -} - -/** - * cal_component_alarm_new: - * - * - * - * Return value: a new alarm component - **/ -CalComponentAlarm * -cal_component_alarm_new (void) -{ - CalComponentAlarm *alarm = g_new0 (CalComponentAlarm, 1); - char *new_auid ; - - alarm->icalcomp = icalcomponent_new (ICAL_VALARM_COMPONENT); - - new_auid = cal_component_gen_uid (); - alarm->uid = icalproperty_new_x (new_auid); - icalproperty_set_x_name (alarm->uid, EVOLUTION_ALARM_UID_PROPERTY); - icalcomponent_add_property (alarm->icalcomp, alarm->uid); - g_free (new_auid); - - return alarm; -} - -/** - * cal_component_alarm_get_uid: - * @alarm: An alarm subcomponent. - * - * Queries the unique identifier of an alarm subcomponent. - * - * Return value: UID of the alarm. - **/ -const char * -cal_component_alarm_get_uid (CalComponentAlarm *alarm) -{ - g_return_val_if_fail (alarm != NULL, NULL); - - return alarm_uid_from_prop (alarm->uid); -} - -/** - * cal_component_alarm_get_action: - * @alarm: An alarm. - * @action: Return value for the alarm's action type. - * - * Queries the action type of an alarm. - **/ -void -cal_component_alarm_get_action (CalComponentAlarm *alarm, CalAlarmAction *action) -{ - const char *str; - - g_return_if_fail (alarm != NULL); - g_return_if_fail (action != NULL); - - g_assert (alarm->icalcomp != NULL); - - if (!alarm->action) { - *action = CAL_ALARM_NONE; - return; - } - - str = icalproperty_get_action (alarm->action); - - if (strcasecmp (str, "AUDIO") == 0) - *action = CAL_ALARM_AUDIO; - else if (strcasecmp (str, "DISPLAY") == 0) - *action = CAL_ALARM_DISPLAY; - else if (strcasecmp (str, "EMAIL") == 0) - *action = CAL_ALARM_EMAIL; - else if (strcasecmp (str, "PROCEDURE") == 0) - *action = CAL_ALARM_PROCEDURE; - else - *action = CAL_ALARM_UNKNOWN; -} - -/** - * cal_component_alarm_set_action: - * @alarm: An alarm. - * @action: Action type. - * - * Sets the action type for an alarm. - **/ -void -cal_component_alarm_set_action (CalComponentAlarm *alarm, CalAlarmAction action) -{ - char *str; - - g_return_if_fail (alarm != NULL); - g_return_if_fail (action != CAL_ALARM_NONE); - g_return_if_fail (action != CAL_ALARM_UNKNOWN); - - g_assert (alarm->icalcomp != NULL); - - switch (action) { - case CAL_ALARM_AUDIO: - str = "AUDIO"; - break; - - case CAL_ALARM_DISPLAY: - str = "DISPLAY"; - break; - - case CAL_ALARM_EMAIL: - str = "EMAIL"; - break; - - case CAL_ALARM_PROCEDURE: - str = "PROCEDURE"; - break; - - default: - g_assert_not_reached (); - str = NULL; - } - - if (alarm->action) - icalproperty_set_action (alarm->action, str); - else { - alarm->action = icalproperty_new_action (str); - icalcomponent_add_property (alarm->icalcomp, alarm->action); - } -} - -/** - * cal_component_alarm_get_trigger: - * @alarm: An alarm. - * @trigger: Return value for the trigger time. - * - * Queries the trigger time for an alarm. - **/ -void -cal_component_alarm_get_trigger (CalComponentAlarm *alarm, CalAlarmTrigger *trigger) -{ - icalparameter *param; - struct icaltriggertype t; - gboolean relative; - - g_return_if_fail (alarm != NULL); - g_return_if_fail (trigger != NULL); - - g_assert (alarm->icalcomp != NULL); - - if (!alarm->trigger) { - trigger->type = CAL_ALARM_TRIGGER_NONE; - return; - } - - /* Get trigger type */ - - param = icalproperty_get_first_parameter (alarm->trigger, ICAL_VALUE_PARAMETER); - if (param) { - icalparameter_value value; - - value = icalparameter_get_value (param); - - switch (value) { - case ICAL_VALUE_DURATION: - relative = TRUE; - break; - - case ICAL_VALUE_DATETIME: - relative = FALSE; - break; - - default: - g_message ("cal_component_alarm_get_trigger(): Unknown value for trigger " - "value %d; using RELATIVE", value); - - relative = TRUE; - break; - } - } else - relative = TRUE; - - /* Get trigger value and the RELATED parameter */ - - t = icalproperty_get_trigger (alarm->trigger); - - if (relative) { - trigger->u.rel_duration = t.duration; - - param = icalproperty_get_first_parameter (alarm->trigger, ICAL_RELATED_PARAMETER); - if (param) { - icalparameter_related rel; - - rel = icalparameter_get_related (param); - - switch (rel) { - case ICAL_RELATED_START: - trigger->type = CAL_ALARM_TRIGGER_RELATIVE_START; - break; - - case ICAL_RELATED_END: - trigger->type = CAL_ALARM_TRIGGER_RELATIVE_END; - break; - - default: - g_assert_not_reached (); - } - } else - trigger->type = CAL_ALARM_TRIGGER_RELATIVE_START; - } else { - trigger->u.abs_time = t.time; - trigger->type = CAL_ALARM_TRIGGER_ABSOLUTE; - } -} - -/** - * cal_component_alarm_set_trigger: - * @alarm: An alarm. - * @trigger: Trigger time structure. - * - * Sets the trigger time of an alarm. - **/ -void -cal_component_alarm_set_trigger (CalComponentAlarm *alarm, CalAlarmTrigger trigger) -{ - struct icaltriggertype t; - icalparameter *param; - icalparameter_value value_type; - icalparameter_related related; - - g_return_if_fail (alarm != NULL); - g_return_if_fail (trigger.type != CAL_ALARM_TRIGGER_NONE); - - g_assert (alarm->icalcomp != NULL); - - /* Delete old trigger */ - - if (alarm->trigger) { - icalcomponent_remove_property (alarm->icalcomp, alarm->trigger); - icalproperty_free (alarm->trigger); - alarm->trigger = NULL; - } - - /* Set the value */ - - related = ICAL_RELATED_START; /* Keep GCC happy */ - - t.time = icaltime_null_time (); - t.duration = icaldurationtype_null_duration (); - switch (trigger.type) { - case CAL_ALARM_TRIGGER_RELATIVE_START: - t.duration = trigger.u.rel_duration; - t.time.is_date = -1; - value_type = ICAL_DURATION_VALUE; - related = ICAL_RELATED_START; - break; - - case CAL_ALARM_TRIGGER_RELATIVE_END: - t.duration = trigger.u.rel_duration; - t.time.is_date = -1; - value_type = ICAL_DURATION_VALUE; - related = ICAL_RELATED_END; - break; - - case CAL_ALARM_TRIGGER_ABSOLUTE: - t.time = trigger.u.abs_time; - value_type = ICAL_DATETIME_VALUE; - break; - - default: - g_assert_not_reached (); - return; - } - - alarm->trigger = icalproperty_new_trigger (t); - icalcomponent_add_property (alarm->icalcomp, alarm->trigger); - - /* Value parameters */ - - param = icalproperty_get_first_parameter (alarm->trigger, ICAL_VALUE_PARAMETER); - if (param) - icalparameter_set_value (param, value_type); - else { - param = icalparameter_new_value (value_type); - icalproperty_add_parameter (alarm->trigger, param); - } - - /* Related parameter */ - - if (trigger.type != CAL_ALARM_TRIGGER_ABSOLUTE) { - param = icalproperty_get_first_parameter (alarm->trigger, ICAL_RELATED_PARAMETER); - - if (param) - icalparameter_set_related (param, related); - else { - param = icalparameter_new_related (related); - icalproperty_add_parameter (alarm->trigger, param); - } - } -} - -/** - * cal_component_alarm_free: - * @alarm: A calendar alarm. - * - * Frees an alarm structure. - **/ -void -cal_component_alarm_free (CalComponentAlarm *alarm) -{ - g_return_if_fail (alarm != NULL); - - g_assert (alarm->icalcomp != NULL); - - if (icalcomponent_get_parent (alarm->icalcomp) != NULL) - icalcomponent_free (alarm->icalcomp); - - alarm->icalcomp = NULL; - - alarm->parent = NULL; - alarm->action = NULL; - - g_free (alarm); -} - - -/* Returns TRUE if both strings match, i.e. they are both NULL or the - strings are equal. */ -static gboolean -cal_component_strings_match (const gchar *string1, - const gchar *string2) -{ - if (string1 == NULL || string2 == NULL) - return (string1 == string2) ? TRUE : FALSE; - - if (!strcmp (string1, string2)) - return TRUE; - - return FALSE; -} - - -/** - * cal_component_event_dates_match: - * @comp1: A calendar component object. - * @comp2: A calendar component object. - * - * Checks if the DTSTART and DTEND properties of the 2 components match. - * Note that the events may have different recurrence properties which are not - * taken into account here. - * - * Returns: TRUE if the DTSTART and DTEND properties of the 2 components match. - **/ -gboolean -cal_component_event_dates_match (CalComponent *comp1, - CalComponent *comp2) -{ - CalComponentDateTime comp1_dtstart, comp1_dtend; - CalComponentDateTime comp2_dtstart, comp2_dtend; - - cal_component_get_dtstart (comp1, &comp1_dtstart); - cal_component_get_dtend (comp1, &comp1_dtend); - cal_component_get_dtstart (comp2, &comp2_dtstart); - cal_component_get_dtend (comp2, &comp2_dtend); - - /* If either value is NULL they must both be NULL to match. */ - if (comp1_dtstart.value == NULL || comp2_dtstart.value == NULL) { - if (comp1_dtstart.value != comp2_dtstart.value) - return FALSE; - } else { - if (icaltime_compare (*comp1_dtstart.value, - *comp2_dtstart.value)) - return FALSE; - } - - if (comp1_dtend.value == NULL || comp2_dtend.value == NULL) { - if (comp1_dtend.value != comp2_dtend.value) - return FALSE; - } else { - if (icaltime_compare (*comp1_dtend.value, - *comp2_dtend.value)) - return FALSE; - } - - /* Now check the timezones. */ - if (!cal_component_strings_match (comp1_dtstart.tzid, - comp2_dtstart.tzid)) - return FALSE; - - if (!cal_component_strings_match (comp1_dtend.tzid, - comp2_dtend.tzid)) - return FALSE; - - return TRUE; -} - - - diff --git a/calendar/cal-util/cal-component.h b/calendar/cal-util/cal-component.h deleted file mode 100644 index b912c04e9e..0000000000 --- a/calendar/cal-util/cal-component.h +++ /dev/null @@ -1,357 +0,0 @@ -/* Evolution calendar - iCalendar component object - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef CAL_COMPONENT_H -#define CAL_COMPONENT_H - -#include <libgnome/gnome-defs.h> -#include <time.h> -#include <gtk/gtkobject.h> -#include <ical.h> - -BEGIN_GNOME_DECLS - - - -#define CAL_COMPONENT_TYPE (cal_component_get_type ()) -#define CAL_COMPONENT(obj) (GTK_CHECK_CAST ((obj), CAL_COMPONENT_TYPE, CalComponent)) -#define CAL_COMPONENT_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), CAL_COMPONENT_TYPE, \ - CalComponentClass)) -#define IS_CAL_COMPONENT(obj) (GTK_CHECK_TYPE ((obj), CAL_COMPONENT_TYPE)) -#define IS_CAL_COMPONENT_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), CAL_COMPONENT_TYPE)) - -/* Types of calendar components to be stored by a CalComponent, as per RFC 2445. - * We don't put the alarm component type here since we store alarms as separate - * structures inside the other "real" components. - */ -typedef enum { - CAL_COMPONENT_NO_TYPE, - CAL_COMPONENT_EVENT, - CAL_COMPONENT_TODO, - CAL_COMPONENT_JOURNAL, - CAL_COMPONENT_FREEBUSY, - CAL_COMPONENT_TIMEZONE -} CalComponentVType; - -/* Field identifiers for a calendar component; these are used by the data model - * for ETable. - */ -typedef enum { - CAL_COMPONENT_FIELD_CATEGORIES, /* concatenation of the categories list */ - CAL_COMPONENT_FIELD_CLASSIFICATION, - CAL_COMPONENT_FIELD_COMPLETED, - CAL_COMPONENT_FIELD_DTEND, - CAL_COMPONENT_FIELD_DTSTART, - CAL_COMPONENT_FIELD_DUE, - CAL_COMPONENT_FIELD_GEO, - CAL_COMPONENT_FIELD_PERCENT, - CAL_COMPONENT_FIELD_PRIORITY, - CAL_COMPONENT_FIELD_SUMMARY, - CAL_COMPONENT_FIELD_TRANSPARENCY, - CAL_COMPONENT_FIELD_URL, - CAL_COMPONENT_FIELD_HAS_ALARMS, /* not a real field */ - CAL_COMPONENT_FIELD_ICON, /* not a real field */ - CAL_COMPONENT_FIELD_COMPLETE, /* not a real field */ - CAL_COMPONENT_FIELD_RECURRING, /* not a real field */ - CAL_COMPONENT_FIELD_OVERDUE, /* not a real field */ - CAL_COMPONENT_FIELD_COLOR, /* not a real field */ - CAL_COMPONENT_FIELD_NUM_FIELDS -} CalComponentField; - -/* Structures and enumerations to return properties and their parameters */ - -/* CLASSIFICATION property */ -typedef enum { - CAL_COMPONENT_CLASS_NONE, - CAL_COMPONENT_CLASS_PUBLIC, - CAL_COMPONENT_CLASS_PRIVATE, - CAL_COMPONENT_CLASS_CONFIDENTIAL, - CAL_COMPONENT_CLASS_UNKNOWN -} CalComponentClassification; - -/* Properties that have time and timezone information */ -typedef struct { - /* Actual date/time value */ - struct icaltimetype *value; - - /* Timezone ID */ - const char *tzid; -} CalComponentDateTime; - -/* Way in which a period of time is specified */ -typedef enum { - CAL_COMPONENT_PERIOD_DATETIME, - CAL_COMPONENT_PERIOD_DURATION -} CalComponentPeriodType; - -/* Period of time, can have explicit start/end times or start/duration instead */ -typedef struct { - CalComponentPeriodType type; - - struct icaltimetype start; - - union { - struct icaltimetype end; - struct icaldurationtype duration; - } u; -} CalComponentPeriod; - -/* Text properties */ -typedef struct { - /* Description string */ - const char *value; - - /* Alternate representation URI */ - const char *altrep; -} CalComponentText; - -/* Time transparency */ -typedef enum { - CAL_COMPONENT_TRANSP_NONE, - CAL_COMPONENT_TRANSP_TRANSPARENT, - CAL_COMPONENT_TRANSP_OPAQUE, - CAL_COMPONENT_TRANSP_UNKNOWN -} CalComponentTransparency; - -/* Main calendar component object */ - -typedef struct _CalComponent CalComponent; -typedef struct _CalComponentClass CalComponentClass; - -typedef struct _CalComponentPrivate CalComponentPrivate; - -struct _CalComponent { - GtkObject object; - - /* Private data */ - CalComponentPrivate *priv; -}; - -struct _CalComponentClass { - GtkObjectClass parent_class; -}; - -/* Calendar component */ - -GtkType cal_component_get_type (void); - -char *cal_component_gen_uid (void); - -CalComponent *cal_component_new (void); - -CalComponent *cal_component_clone (CalComponent *comp); - -void cal_component_set_new_vtype (CalComponent *comp, CalComponentVType type); - -gboolean cal_component_set_icalcomponent (CalComponent *comp, icalcomponent *icalcomp); -icalcomponent *cal_component_get_icalcomponent (CalComponent *comp); - -CalComponentVType cal_component_get_vtype (CalComponent *comp); - -char *cal_component_get_as_string (CalComponent *comp); - -void cal_component_commit_sequence (CalComponent *comp); - -void cal_component_get_uid (CalComponent *comp, const char **uid); -void cal_component_set_uid (CalComponent *comp, const char *uid); - -void cal_component_get_categories (CalComponent *comp, const char **categories); -void cal_component_set_categories (CalComponent *comp, const char *categories); -void cal_component_get_categories_list (CalComponent *comp, GSList **categ_list); -void cal_component_set_categories_list (CalComponent *comp, GSList *categ_list); - -void cal_component_get_classification (CalComponent *comp, CalComponentClassification *classif); -void cal_component_set_classification (CalComponent *comp, CalComponentClassification classif); - -void cal_component_get_comment_list (CalComponent *comp, GSList **text_list); -void cal_component_set_comment_list (CalComponent *comp, GSList *text_list); - -void cal_component_get_completed (CalComponent *comp, struct icaltimetype **t); -void cal_component_set_completed (CalComponent *comp, struct icaltimetype *t); - -void cal_component_get_created (CalComponent *comp, struct icaltimetype **t); -void cal_component_set_created (CalComponent *comp, struct icaltimetype *t); - -void cal_component_get_description_list (CalComponent *comp, GSList **text_list); -void cal_component_set_description_list (CalComponent *comp, GSList *text_list); - -void cal_component_get_dtend (CalComponent *comp, CalComponentDateTime *dt); -void cal_component_set_dtend (CalComponent *comp, CalComponentDateTime *dt); - -void cal_component_get_dtstamp (CalComponent *comp, struct icaltimetype *t); -void cal_component_set_dtstamp (CalComponent *comp, struct icaltimetype *t); - -void cal_component_get_dtstart (CalComponent *comp, CalComponentDateTime *dt); -void cal_component_set_dtstart (CalComponent *comp, CalComponentDateTime *dt); - -void cal_component_get_due (CalComponent *comp, CalComponentDateTime *dt); -void cal_component_set_due (CalComponent *comp, CalComponentDateTime *dt); - -void cal_component_get_exdate_list (CalComponent *comp, GSList **exdate_list); -void cal_component_set_exdate_list (CalComponent *comp, GSList *exdate_list); -gboolean cal_component_has_exdates (CalComponent *comp); - -void cal_component_get_exrule_list (CalComponent *comp, GSList **recur_list); -void cal_component_get_exrule_property_list (CalComponent *comp, GSList **recur_list); -void cal_component_set_exrule_list (CalComponent *comp, GSList *recur_list); -gboolean cal_component_has_exrules (CalComponent *comp); - -gboolean cal_component_has_exceptions (CalComponent *comp); - -void cal_component_get_geo (CalComponent *comp, struct icalgeotype **geo); -void cal_component_set_geo (CalComponent *comp, struct icalgeotype *geo); - -void cal_component_get_last_modified (CalComponent *comp, struct icaltimetype **t); -void cal_component_set_last_modified (CalComponent *comp, struct icaltimetype *t); - -void cal_component_get_percent (CalComponent *comp, int **percent); -void cal_component_set_percent (CalComponent *comp, int *percent); - -void cal_component_get_priority (CalComponent *comp, int **priority); -void cal_component_set_priority (CalComponent *comp, int *priority); - -void cal_component_get_rdate_list (CalComponent *comp, GSList **period_list); -void cal_component_set_rdate_list (CalComponent *comp, GSList *period_list); -gboolean cal_component_has_rdates (CalComponent *comp); - -void cal_component_get_rrule_list (CalComponent *comp, GSList **recur_list); -void cal_component_get_rrule_property_list (CalComponent *comp, GSList **recur_list); -void cal_component_set_rrule_list (CalComponent *comp, GSList *recur_list); -gboolean cal_component_has_rrules (CalComponent *comp); - -gboolean cal_component_has_recurrences (CalComponent *comp); - -void cal_component_get_sequence (CalComponent *comp, int **sequence); -void cal_component_set_sequence (CalComponent *comp, int *sequence); - -void cal_component_get_status (CalComponent *comp, icalproperty_status *status); -void cal_component_set_status (CalComponent *comp, icalproperty_status status); - -void cal_component_get_summary (CalComponent *comp, CalComponentText *summary); -void cal_component_set_summary (CalComponent *comp, CalComponentText *summary); - -void cal_component_get_transparency (CalComponent *comp, CalComponentTransparency *transp); -void cal_component_set_transparency (CalComponent *comp, CalComponentTransparency transp); - -void cal_component_get_url (CalComponent *comp, const char **url); -void cal_component_set_url (CalComponent *comp, const char *url); - -gboolean cal_component_event_dates_match (CalComponent *comp1, CalComponent *comp2); - -/* Functions to free returned values */ - -void cal_component_free_categories_list (GSList *categ_list); -void cal_component_free_datetime (CalComponentDateTime *dt); -void cal_component_free_exdate_list (GSList *exdate_list); -void cal_component_free_geo (struct icalgeotype *geo); -void cal_component_free_icaltimetype (struct icaltimetype *t); -void cal_component_free_percent (int *percent); -void cal_component_free_priority (int *priority); -void cal_component_free_period_list (GSList *period_list); -void cal_component_free_recur_list (GSList *recur_list); -void cal_component_free_sequence (int *sequence); -void cal_component_free_text_list (GSList *text_list); - -/* Alarms */ - -/* Opaque structure used to represent alarm subcomponents */ -typedef struct _CalComponentAlarm CalComponentAlarm; - -/* An alarm occurrence, i.e. a trigger instance */ -typedef struct { - /* UID of the alarm that triggered */ - const char *auid; - - /* Trigger time, i.e. "5 minutes before the appointment" */ - time_t trigger; - - /* Actual event occurrence to which this trigger corresponds */ - time_t occur; -} CalAlarmInstance; - -/* Alarm trigger instances for a particular component */ -typedef struct { - /* The actual component */ - CalComponent *comp; - - /* List of CalAlarmInstance structures */ - GSList *alarms; -} CalComponentAlarms; - -/* Alarm types */ -typedef enum { - CAL_ALARM_NONE, - CAL_ALARM_AUDIO, - CAL_ALARM_DISPLAY, - CAL_ALARM_EMAIL, - CAL_ALARM_PROCEDURE, - CAL_ALARM_UNKNOWN -} CalAlarmAction; - -/* Whether a trigger is relative to the start or end of an event occurrence, or - * whether it is specified to occur at an absolute time. - */ -typedef enum { - CAL_ALARM_TRIGGER_NONE, - CAL_ALARM_TRIGGER_RELATIVE_START, - CAL_ALARM_TRIGGER_RELATIVE_END, - CAL_ALARM_TRIGGER_ABSOLUTE -} CalAlarmTriggerType; - -typedef struct { - CalAlarmTriggerType type; - - union { - struct icaldurationtype rel_duration; - struct icaltimetype abs_time; - } u; -} CalAlarmTrigger; - -gboolean cal_component_has_alarms (CalComponent *comp); -void cal_component_add_alarm (CalComponent *comp, CalComponentAlarm *alarm); -void cal_component_remove_alarm (CalComponent *comp, const char *auid); - -GList *cal_component_get_alarm_uids (CalComponent *comp); -CalComponentAlarm *cal_component_get_alarm (CalComponent *comp, const char *auid); -void cal_component_free_alarm_uids (GList *alarm_uids); - -void cal_component_alarms_free (CalComponentAlarms *alarms); - -/* CalComponentAlarms */ -CalComponentAlarm *cal_component_alarm_new (void); - -const char *cal_component_alarm_get_uid (CalComponentAlarm *alarm); - -void cal_component_alarm_get_action (CalComponentAlarm *alarm, CalAlarmAction *action); -void cal_component_alarm_set_action (CalComponentAlarm *alarm, CalAlarmAction action); - -void cal_component_alarm_get_trigger (CalComponentAlarm *alarm, CalAlarmTrigger *trigger); -void cal_component_alarm_set_trigger (CalComponentAlarm *alarm, CalAlarmTrigger trigger); - -void cal_component_alarm_free (CalComponentAlarm *alarm); - - - - -END_GNOME_DECLS - -#endif diff --git a/calendar/cal-util/cal-recur.c b/calendar/cal-util/cal-recur.c deleted file mode 100644 index 0b4f114484..0000000000 --- a/calendar/cal-util/cal-recur.c +++ /dev/null @@ -1,3758 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Evolution calendar recurrence rule functions - * - * Copyright (C) 2000 Helix Code, Inc. - * - * Author: Damon Chaplin <damon@helixcode.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#include <config.h> -#include <stdlib.h> -#include <string.h> -#include <cal-util/cal-recur.h> -#include <cal-util/timeutil.h> - - -/* - * Introduction to The Recurrence Generation Functions: - * - * Note: This is pretty complicated. See the iCalendar spec (RFC 2445) for - * the specification of the recurrence rules and lots of examples - * (sections 4.3.10 & 4.8.5). We also want to support the older - * vCalendar spec, though this should be easy since it is basically a - * subset of iCalendar. - * - * o An iCalendar event can have any number of recurrence rules specifying - * occurrences of the event, as well as dates & times of specific - * occurrences. It can also have any number of recurrence rules and - * specific dates & times specifying exceptions to the occurrences. - * So we first merge all the occurrences generated, eliminating any - * duplicates, then we generate all the exceptions and remove these to - * form the final set of occurrences. - * - * o There are 7 frequencies of occurrences: YEARLY, MONTHLY, WEEKLY, DAILY, - * HOURLY, MINUTELY & SECONDLY. The 'interval' property specifies the - * multiples of the frequency which we step by. We generate a 'set' of - * occurrences for each period defined by the frequency & interval. - * So for a YEARLY frequency with an interval of 3, we generate a set of - * occurrences for every 3rd year. We use complete years here - any - * generated occurrences that occur before the event's start (or after its - * end) are just discarded. - * - * o There are 8 frequency modifiers: BYMONTH, BYWEEKNO, BYYEARDAY, BYMONTHDAY, - * BYDAY, BYHOUR, BYMINUTE & BYSECOND. These can either add extra occurrences - * or filter out occurrences. For example 'FREQ=YEARLY;BYMONTH=1,2' produces - * 2 occurrences for each year rather than the default 1. And - * 'FREQ=DAILY;BYMONTH=1' filters out all occurrences except those in Jan. - * If the modifier works on periods which are less than the recurrence - * frequency, then extra occurrences are added, otherwise occurrences are - * filtered. So we have 2 functions for each modifier - one to expand events - * and the other to filter. We use a table of functions for each frequency - * which points to the appropriate function to use for each modifier. - * - * o Any number of frequency modifiers can be used in a recurrence rule. - * (Though the iCalendar spec says that BYWEEKNO can only be used in a YEARLY - * rule, and some modifiers aren't appropriate for some frequencies - e.g. - * BYMONTHDAY is not really useful in a WEEKLY frequency, and BYYEARDAY is - * not useful in a MONTHLY or WEEKLY frequency). - * The frequency modifiers are applied in the order given above. The first 5 - * modifier rules (BYMONTH, BYWEEKNO, BYYEARDAY, BYMONTHDAY & BYDAY) all - * produce the days on which the occurrences take place, and so we have to - * compute some of these in parallel rather than sequentially, or we may end - * up with too many days. - * - * o Note that some expansion functions may produce days which are invalid, - * e.g. 31st September, 30th Feb. These invalid days are removed before the - * BYHOUR, BYMINUTE & BYSECOND modifier functions are applied. - * - * o After the set of occurrences for the frequency interval are generated, - * the BYSETPOS property is used to select which of the occurrences are - * finally output. If BYSETPOS is not specified then all the occurrences are - * output. - */ - -/* Define this for some debugging output. */ -#if 0 -#define CAL_OBJ_DEBUG 1 -#endif - -/* We will use icalrecurrencetype instead of this eventually. */ -typedef struct { - icalrecurrencetype_frequency freq; - - int interval; - - /* Specifies the end of the recurrence. No occurrences are generated - after this date. If it is 0, the event recurs forever. */ - time_t enddate; - - /* WKST property - the week start day: 0 = Monday to 6 = Sunday. */ - gint week_start_day; - - - /* NOTE: I've used GList's here, but it doesn't matter if we use - other data structures like arrays. The code should be easy to - change. So long as it is easy to see if the modifier is set. */ - - /* For BYMONTH modifier. A list of GINT_TO_POINTERs, 0-11. */ - GList *bymonth; - - /* For BYWEEKNO modifier. A list of GINT_TO_POINTERs, [+-]1-53. */ - GList *byweekno; - - /* For BYYEARDAY modifier. A list of GINT_TO_POINTERs, [+-]1-366. */ - GList *byyearday; - - /* For BYMONTHDAY modifier. A list of GINT_TO_POINTERs, [+-]1-31. */ - GList *bymonthday; - - /* For BYDAY modifier. A list of GINT_TO_POINTERs, in pairs. - The first of each pair is the weekday, 0 = Monday to 6 = Sunday. - The second of each pair is the week number [+-]0-53. */ - GList *byday; - - /* For BYHOUR modifier. A list of GINT_TO_POINTERs, 0-23. */ - GList *byhour; - - /* For BYMINUTE modifier. A list of GINT_TO_POINTERs, 0-59. */ - GList *byminute; - - /* For BYSECOND modifier. A list of GINT_TO_POINTERs, 0-60. */ - GList *bysecond; - - /* For BYSETPOS modifier. A list of GINT_TO_POINTERs, +ve or -ve. */ - GList *bysetpos; -} CalRecurrence; - -/* This is what we use to pass to all the filter functions. */ -typedef struct _RecurData RecurData; -struct _RecurData { - CalRecurrence *recur; - - /* This is used for the WEEKLY frequency. It is the offset from the - week_start_day. */ - gint weekday_offset; - - /* This is used for fast lookup in BYMONTH filtering. */ - guint8 months[12]; - - /* This is used for fast lookup in BYYEARDAY filtering. */ - guint8 yeardays[367], neg_yeardays[367]; /* Days are 1 - 366. */ - - /* This is used for fast lookup in BYMONTHDAY filtering. */ - guint8 monthdays[32], neg_monthdays[32]; /* Days are 1 to 31. */ - - /* This is used for fast lookup in BYDAY filtering. */ - guint8 weekdays[7]; - - /* This is used for fast lookup in BYHOUR filtering. */ - guint8 hours[24]; - - /* This is used for fast lookup in BYMINUTE filtering. */ - guint8 minutes[60]; - - /* This is used for fast lookup in BYSECOND filtering. */ - guint8 seconds[62]; -}; - -/* This is what we use to represent a date & time. */ -typedef struct _CalObjTime CalObjTime; -struct _CalObjTime { - guint16 year; - guint8 month; /* 0 - 11 */ - guint8 day; /* 1 - 31 */ - guint8 hour; /* 0 - 23 */ - guint8 minute; /* 0 - 59 */ - guint8 second; /* 0 - 59 (maybe up to 61 for leap seconds) */ - guint8 is_rdate; /* TRUE if this is an RDATE, which may have an - end or duration set. */ -}; - -/* This is what we use to represent specific recurrence dates. - Note that we assume it starts with a CalObjTime when sorting. */ -typedef struct _CalObjRecurrenceDate CalObjRecurrenceDate; -struct _CalObjRecurrenceDate { - CalObjTime start; - CalComponentPeriod *period; -}; - -/* The paramter we use to store the enddate in RRULE and EXRULE properties. */ -#define EVOLUTION_END_DATE_PARAMETER "X-EVOLUTION-ENDDATE" - -typedef gboolean (*CalObjFindStartFn) (CalObjTime *event_start, - CalObjTime *event_end, - RecurData *recur_data, - CalObjTime *interval_start, - CalObjTime *interval_end, - CalObjTime *cotime); -typedef gboolean (*CalObjFindNextFn) (CalObjTime *cotime, - CalObjTime *event_end, - RecurData *recur_data, - CalObjTime *interval_end); -typedef GArray* (*CalObjFilterFn) (RecurData *recur_data, - GArray *occs); - -typedef struct _CalRecurVTable CalRecurVTable; -struct _CalRecurVTable { - CalObjFindStartFn find_start_position; - CalObjFindNextFn find_next_position; - - CalObjFilterFn bymonth_filter; - CalObjFilterFn byweekno_filter; - CalObjFilterFn byyearday_filter; - CalObjFilterFn bymonthday_filter; - CalObjFilterFn byday_filter; - CalObjFilterFn byhour_filter; - CalObjFilterFn byminute_filter; - CalObjFilterFn bysecond_filter; -}; - - -/* This is used to specify which parts of the CalObjTime to compare in - cal_obj_time_compare(). */ -typedef enum { - CALOBJ_YEAR, - CALOBJ_MONTH, - CALOBJ_DAY, - CALOBJ_HOUR, - CALOBJ_MINUTE, - CALOBJ_SECOND -} CalObjTimeComparison; - -static void cal_recur_generate_instances_of_rule (CalComponent *comp, - icalproperty *prop, - time_t start, - time_t end, - CalRecurInstanceFn cb, - gpointer cb_data); - -static CalRecurrence * cal_recur_from_icalproperty (icalproperty *prop, - gboolean exception); -static gint cal_recur_ical_weekday_to_weekday (enum icalrecurrencetype_weekday day); -static void cal_recur_free (CalRecurrence *r); - - -static gboolean cal_object_get_rdate_end (CalObjTime *occ, - GArray *rdate_periods); -static void cal_object_compute_duration (CalObjTime *start, - CalObjTime *end, - gint *days, - gint *seconds); - -static gboolean generate_instances_for_chunk (CalComponent *comp, - time_t comp_dtstart, - GSList *rrules, - GSList *rdates, - GSList *exrules, - GSList *exdates, - gboolean single_rule, - CalObjTime *event_start, - time_t interval_start, - CalObjTime *chunk_start, - CalObjTime *chunk_end, - gint duration_days, - gint duration_seconds, - CalRecurInstanceFn cb, - gpointer cb_data); - -static GArray* cal_obj_expand_recurrence (CalObjTime *event_start, - CalRecurrence *recur, - CalObjTime *interval_start, - CalObjTime *interval_end, - gboolean *finished); - -static GArray* cal_obj_generate_set_yearly (RecurData *recur_data, - CalRecurVTable *vtable, - CalObjTime *occ); -static GArray* cal_obj_generate_set_monthly (RecurData *recur_data, - CalRecurVTable *vtable, - CalObjTime *occ); -static GArray* cal_obj_generate_set_default (RecurData *recur_data, - CalRecurVTable *vtable, - CalObjTime *occ); - - -static CalRecurVTable* cal_obj_get_vtable (icalrecurrencetype_frequency recur_type); -static void cal_obj_initialize_recur_data (RecurData *recur_data, - CalRecurrence *recur, - CalObjTime *event_start); -static void cal_obj_sort_occurrences (GArray *occs); -static gint cal_obj_time_compare_func (const void *arg1, - const void *arg2); -static void cal_obj_remove_duplicates_and_invalid_dates (GArray *occs); -static void cal_obj_remove_exceptions (GArray *occs, - GArray *ex_occs); -static GArray* cal_obj_bysetpos_filter (CalRecurrence *recur, - GArray *occs); - - -static gboolean cal_obj_yearly_find_start_position (CalObjTime *event_start, - CalObjTime *event_end, - RecurData *recur_data, - CalObjTime *interval_start, - CalObjTime *interval_end, - CalObjTime *cotime); -static gboolean cal_obj_yearly_find_next_position (CalObjTime *cotime, - CalObjTime *event_end, - RecurData *recur_data, - CalObjTime *interval_end); - -static gboolean cal_obj_monthly_find_start_position (CalObjTime *event_start, - CalObjTime *event_end, - RecurData *recur_data, - CalObjTime *interval_start, - CalObjTime *interval_end, - CalObjTime *cotime); -static gboolean cal_obj_monthly_find_next_position (CalObjTime *cotime, - CalObjTime *event_end, - RecurData *recur_data, - CalObjTime *interval_end); - -static gboolean cal_obj_weekly_find_start_position (CalObjTime *event_start, - CalObjTime *event_end, - RecurData *recur_data, - CalObjTime *interval_start, - CalObjTime *interval_end, - CalObjTime *cotime); -static gboolean cal_obj_weekly_find_next_position (CalObjTime *cotime, - CalObjTime *event_end, - RecurData *recur_data, - CalObjTime *interval_end); - -static gboolean cal_obj_daily_find_start_position (CalObjTime *event_start, - CalObjTime *event_end, - RecurData *recur_data, - CalObjTime *interval_start, - CalObjTime *interval_end, - CalObjTime *cotime); -static gboolean cal_obj_daily_find_next_position (CalObjTime *cotime, - CalObjTime *event_end, - RecurData *recur_data, - CalObjTime *interval_end); - -static gboolean cal_obj_hourly_find_start_position (CalObjTime *event_start, - CalObjTime *event_end, - RecurData *recur_data, - CalObjTime *interval_start, - CalObjTime *interval_end, - CalObjTime *cotime); -static gboolean cal_obj_hourly_find_next_position (CalObjTime *cotime, - CalObjTime *event_end, - RecurData *recur_data, - CalObjTime *interval_end); - -static gboolean cal_obj_minutely_find_start_position (CalObjTime *event_start, - CalObjTime *event_end, - RecurData *recur_data, - CalObjTime *interval_start, - CalObjTime *interval_end, - CalObjTime *cotime); -static gboolean cal_obj_minutely_find_next_position (CalObjTime *cotime, - CalObjTime *event_end, - RecurData *recur_data, - CalObjTime *interval_end); - -static gboolean cal_obj_secondly_find_start_position (CalObjTime *event_start, - CalObjTime *event_end, - RecurData *recur_data, - CalObjTime *interval_start, - CalObjTime *interval_end, - CalObjTime *cotime); -static gboolean cal_obj_secondly_find_next_position (CalObjTime *cotime, - CalObjTime *event_end, - RecurData *recur_data, - CalObjTime *interval_end); - -static GArray* cal_obj_bymonth_expand (RecurData *recur_data, - GArray *occs); -static GArray* cal_obj_bymonth_filter (RecurData *recur_data, - GArray *occs); -static GArray* cal_obj_byweekno_expand (RecurData *recur_data, - GArray *occs); -#if 0 -/* This isn't used at present. */ -static GArray* cal_obj_byweekno_filter (RecurData *recur_data, - GArray *occs); -#endif -static GArray* cal_obj_byyearday_expand (RecurData *recur_data, - GArray *occs); -static GArray* cal_obj_byyearday_filter (RecurData *recur_data, - GArray *occs); -static GArray* cal_obj_bymonthday_expand (RecurData *recur_data, - GArray *occs); -static GArray* cal_obj_bymonthday_filter (RecurData *recur_data, - GArray *occs); -static GArray* cal_obj_byday_expand_yearly (RecurData *recur_data, - GArray *occs); -static GArray* cal_obj_byday_expand_monthly (RecurData *recur_data, - GArray *occs); -static GArray* cal_obj_byday_expand_weekly (RecurData *recur_data, - GArray *occs); -static GArray* cal_obj_byday_filter (RecurData *recur_data, - GArray *occs); -static GArray* cal_obj_byhour_expand (RecurData *recur_data, - GArray *occs); -static GArray* cal_obj_byhour_filter (RecurData *recur_data, - GArray *occs); -static GArray* cal_obj_byminute_expand (RecurData *recur_data, - GArray *occs); -static GArray* cal_obj_byminute_filter (RecurData *recur_data, - GArray *occs); -static GArray* cal_obj_bysecond_expand (RecurData *recur_data, - GArray *occs); -static GArray* cal_obj_bysecond_filter (RecurData *recur_data, - GArray *occs); - -static void cal_obj_time_add_months (CalObjTime *cotime, - gint months); -static void cal_obj_time_add_days (CalObjTime *cotime, - gint days); -static void cal_obj_time_add_hours (CalObjTime *cotime, - gint hours); -static void cal_obj_time_add_minutes (CalObjTime *cotime, - gint minutes); -static void cal_obj_time_add_seconds (CalObjTime *cotime, - gint seconds); -static gint cal_obj_time_compare (CalObjTime *cotime1, - CalObjTime *cotime2, - CalObjTimeComparison type); -static gint cal_obj_time_weekday (CalObjTime *cotime); -static gint cal_obj_time_weekday_offset (CalObjTime *cotime, - CalRecurrence *recur); -static gint cal_obj_time_day_of_year (CalObjTime *cotime); -static void cal_obj_time_find_first_week (CalObjTime *cotime, - RecurData *recur_data); -static void cal_object_time_from_time (CalObjTime *cotime, - time_t t); -#if 0 -static gint cal_obj_date_only_compare_func (const void *arg1, - const void *arg2); -#endif - - - -static gboolean cal_recur_ensure_end_dates (CalComponent *comp, - gboolean refresh); -static gboolean cal_recur_ensure_rule_end_date (CalComponent *comp, - icalproperty *prop, - gboolean exception, - gboolean refresh); -static gboolean cal_recur_ensure_rule_end_date_cb (CalComponent *comp, - time_t instance_start, - time_t instance_end, - gpointer data); -static time_t cal_recur_get_rule_end_date (icalproperty *prop); -static void cal_recur_set_rule_end_date (icalproperty *prop, - time_t end_date); - - -#ifdef CAL_OBJ_DEBUG -static char* cal_obj_time_to_string (CalObjTime *cotime); -#endif - - -CalRecurVTable cal_obj_yearly_vtable = { - cal_obj_yearly_find_start_position, - cal_obj_yearly_find_next_position, - - cal_obj_bymonth_expand, - cal_obj_byweekno_expand, - cal_obj_byyearday_expand, - cal_obj_bymonthday_expand, - cal_obj_byday_expand_yearly, - cal_obj_byhour_expand, - cal_obj_byminute_expand, - cal_obj_bysecond_expand -}; - -CalRecurVTable cal_obj_monthly_vtable = { - cal_obj_monthly_find_start_position, - cal_obj_monthly_find_next_position, - - cal_obj_bymonth_filter, - NULL, /* BYWEEKNO is only applicable to YEARLY frequency. */ - NULL, /* BYYEARDAY is not useful in a MONTHLY frequency. */ - cal_obj_bymonthday_expand, - cal_obj_byday_expand_monthly, - cal_obj_byhour_expand, - cal_obj_byminute_expand, - cal_obj_bysecond_expand -}; - -CalRecurVTable cal_obj_weekly_vtable = { - cal_obj_weekly_find_start_position, - cal_obj_weekly_find_next_position, - - cal_obj_bymonth_filter, - NULL, /* BYWEEKNO is only applicable to YEARLY frequency. */ - NULL, /* BYYEARDAY is not useful in a WEEKLY frequency. */ - NULL, /* BYMONTHDAY is not useful in a WEEKLY frequency. */ - cal_obj_byday_expand_weekly, - cal_obj_byhour_expand, - cal_obj_byminute_expand, - cal_obj_bysecond_expand -}; - -CalRecurVTable cal_obj_daily_vtable = { - cal_obj_daily_find_start_position, - cal_obj_daily_find_next_position, - - cal_obj_bymonth_filter, - NULL, /* BYWEEKNO is only applicable to YEARLY frequency. */ - cal_obj_byyearday_filter, - cal_obj_bymonthday_filter, - cal_obj_byday_filter, - cal_obj_byhour_expand, - cal_obj_byminute_expand, - cal_obj_bysecond_expand -}; - -CalRecurVTable cal_obj_hourly_vtable = { - cal_obj_hourly_find_start_position, - cal_obj_hourly_find_next_position, - - cal_obj_bymonth_filter, - NULL, /* BYWEEKNO is only applicable to YEARLY frequency. */ - cal_obj_byyearday_filter, - cal_obj_bymonthday_filter, - cal_obj_byday_filter, - cal_obj_byhour_filter, - cal_obj_byminute_expand, - cal_obj_bysecond_expand -}; - -CalRecurVTable cal_obj_minutely_vtable = { - cal_obj_minutely_find_start_position, - cal_obj_minutely_find_next_position, - - cal_obj_bymonth_filter, - NULL, /* BYWEEKNO is only applicable to YEARLY frequency. */ - cal_obj_byyearday_filter, - cal_obj_bymonthday_filter, - cal_obj_byday_filter, - cal_obj_byhour_filter, - cal_obj_byminute_filter, - cal_obj_bysecond_expand -}; - -CalRecurVTable cal_obj_secondly_vtable = { - cal_obj_secondly_find_start_position, - cal_obj_secondly_find_next_position, - - cal_obj_bymonth_filter, - NULL, /* BYWEEKNO is only applicable to YEARLY frequency. */ - cal_obj_byyearday_filter, - cal_obj_bymonthday_filter, - cal_obj_byday_filter, - cal_obj_byhour_filter, - cal_obj_byminute_filter, - cal_obj_bysecond_filter -}; - -/* - * Calls the given callback function for each occurrence of the event that - * intersects the range between the given start and end times (the end time is - * not included). Note that the occurrences may start before the given start - * time. - * - * If the callback routine returns FALSE the occurrence generation stops. - * - * Both start and end can be -1, in which case we start at the events first - * instance and continue until it ends, or forever if it has no enddate. - */ -void -cal_recur_generate_instances (CalComponent *comp, - time_t start, - time_t end, - CalRecurInstanceFn cb, - gpointer cb_data) -{ -#if 0 - g_print ("In cal_recur_generate_instances comp: %p\n", comp); - g_print (" start: %li - %s", start, ctime (&start)); - g_print (" end : %li - %s", end, ctime (&end)); -#endif - cal_recur_generate_instances_of_rule (comp, NULL, start, end, - cb, cb_data); -} - - -/* - * Calls the given callback function for each occurrence of the given - * recurrence rule between the given start and end times. If the rule is NULL - * it uses all the rules from the component. - * - * If the callback routine returns FALSE the occurrence generation stops. - * - * The use of the specific rule is for determining the end of a rule when - * COUNT is set. The callback will count instances and store the enddate - * when COUNT is reached. - * - * Both start and end can be -1, in which case we start at the events first - * instance and continue until it ends, or forever if it has no enddate. - */ -static void -cal_recur_generate_instances_of_rule (CalComponent *comp, - icalproperty *prop, - time_t start, - time_t end, - CalRecurInstanceFn cb, - gpointer cb_data) -{ - CalComponentDateTime dtstart, dtend; - time_t dtstart_time, dtend_time; - GSList *rrules = NULL, *rdates = NULL, elem; - GSList *exrules = NULL, *exdates = NULL; - CalObjTime interval_start, interval_end, event_start, event_end; - CalObjTime chunk_start, chunk_end; - gint days, seconds, year; - gboolean single_rule; - - g_return_if_fail (comp != NULL); - g_return_if_fail (cb != NULL); - g_return_if_fail (start >= -1); - g_return_if_fail (end >= -1); - - /* Get dtstart, dtend, recurrences, and exceptions */ - - cal_component_get_dtstart (comp, &dtstart); - cal_component_get_dtend (comp, &dtend); - - if (!dtstart.value) { - g_message ("cal_recur_generate_instances_of_rule(): bogus " - "component, does not have DTSTART. Skipping..."); - goto out; - } - - dtstart_time = icaltime_as_timet (*dtstart.value); - if (start == -1) - start = dtstart_time; - - /* FIXME: DURATION could be used instead, couldn't it? - Damon */ - if (dtend.value) - dtend_time = icaltime_as_timet (*dtend.value); - else - dtend_time = time_day_end (dtstart_time); - - /* If there is no recurrence, just call the callback if the event - intersects the given interval. */ - if (!(cal_component_has_recurrences (comp) - || cal_component_has_exceptions (comp))) { - if ((end == -1 || dtstart_time < end) && dtend_time > start) { - (* cb) (comp, dtstart_time, dtend_time, cb_data); - } - - goto out; - } - - /* If a specific recurrence rule is being used, set up a simple list, - else get the recurrence rules from the component. */ - if (prop) { - single_rule = TRUE; - - elem.data = prop; - elem.next = NULL; - rrules = &elem; - } else { - single_rule = FALSE; - - /* Make sure all the enddates for the rules are set. */ - cal_recur_ensure_end_dates (comp, FALSE); - - cal_component_get_rrule_property_list (comp, &rrules); - cal_component_get_rdate_list (comp, &rdates); - cal_component_get_exrule_property_list (comp, &exrules); - cal_component_get_exdate_list (comp, &exdates); - } - - /* Convert the interval start & end to CalObjTime. Note that if end - is -1 interval_end won't be set, so don't use it! - Also note that we use end - 1 since we want the interval to be - inclusive as it makes the code simpler. */ - cal_object_time_from_time (&interval_start, start); - if (end != -1) - cal_object_time_from_time (&interval_end, end - 1); - - cal_object_time_from_time (&event_start, dtstart_time); - cal_object_time_from_time (&event_end, dtend_time); - - /* Calculate the duration of the event, which we use for all - occurrences. We can't just subtract start from end since that may - be affected by daylight-saving time. So we want a value of days - + seconds. */ - cal_object_compute_duration (&event_start, &event_end, - &days, &seconds); - - /* Take off the duration from interval_start, so we get occurrences - that start just before the start time but overlap it. But only do - that if the interval is after the event's start time. */ - if (start > dtstart_time) { - cal_obj_time_add_days (&interval_start, -days); - cal_obj_time_add_seconds (&interval_start, -seconds); - } - - /* Expand the recurrence for each year between start & end, or until - the callback returns 0 if end is 0. We do a year at a time to - give the callback function a chance to break out of the loop, and - so we don't get into problems with infinite recurrences. Since we - have to work on complete sets of occurrences, if there is a yearly - frequency it wouldn't make sense to break it into smaller chunks, - since we would then be calculating the same sets several times. - Though this does mean that we sometimes do a lot more work than - is necessary, e.g. if COUNT is set to something quite low. */ - for (year = interval_start.year; - end == -1 || year <= interval_end.year; - year++) { - chunk_start = interval_start; - chunk_start.year = year; - if (end != -1) - chunk_end = interval_end; - chunk_end.year = year; - - if (year != interval_start.year) { - chunk_start.month = 0; - chunk_start.day = 1; - chunk_start.hour = 0; - chunk_start.minute = 0; - chunk_start.second = 0; - } - if (end == -1 || year != interval_end.year) { - chunk_end.month = 11; - chunk_end.day = 31; - chunk_end.hour = 23; - chunk_end.minute = 59; - chunk_end.second = 61; - chunk_end.is_rdate = FALSE; - } - - if (!generate_instances_for_chunk (comp, dtstart_time, - rrules, rdates, - exrules, exdates, - single_rule, - &event_start, - start, - &chunk_start, &chunk_end, - days, seconds, - cb, cb_data)) - break; - } - - if (!prop) { - cal_component_free_period_list (rdates); - cal_component_free_exdate_list (exdates); - } - - out: - cal_component_free_datetime (&dtstart); - cal_component_free_datetime (&dtend); -} - -/* Builds a list of GINT_TO_POINTER() elements out of a short array from a - * struct icalrecurrencetype. - */ -static GList * -array_to_list (short *array, int max_elements) -{ - GList *l; - int i; - - l = NULL; - - for (i = 0; i < max_elements && array[i] != ICAL_RECURRENCE_ARRAY_MAX; i++) - l = g_list_prepend (l, GINT_TO_POINTER ((int) (array[i]))); - return g_list_reverse (l); -} - -/** - * cal_recur_from_icalproperty: - * @ir: An RRULE or EXRULE #icalproperty. - * - * Converts an #icalproperty to a #CalRecurrence. This should be - * freed using the cal_recur_free() function. - * - * Return value: #CalRecurrence structure. - **/ -static CalRecurrence * -cal_recur_from_icalproperty (icalproperty *prop, gboolean exception) -{ - struct icalrecurrencetype ir; - CalRecurrence *r; - gint max_elements, i; - - g_return_val_if_fail (prop != NULL, NULL); - - r = g_new (CalRecurrence, 1); - - if (exception) - ir = icalproperty_get_exrule (prop); - else - ir = icalproperty_get_rrule (prop); - - r->freq = ir.freq; - r->interval = ir.interval; - - if (ir.count != 0) { - r->enddate = cal_recur_get_rule_end_date (prop); - } else { - /* FIXME: icaltime_as_timet() seems to return -1 if UNTIL isn't - set, but a simpler test would be better. */ - r->enddate = icaltime_as_timet (ir.until); - if (r->enddate == -1) - r->enddate = 0; - else if (ir.until.is_date) - /* FIXME: Decide what to do here. */ - r->enddate = time_add_day (r->enddate, 1) - 1; - } - - r->week_start_day = cal_recur_ical_weekday_to_weekday (ir.week_start); - - r->bymonth = array_to_list (ir.by_month, - sizeof (ir.by_month) / sizeof (ir.by_month[0])); - - r->byweekno = array_to_list (ir.by_week_no, - sizeof (ir.by_week_no) / sizeof (ir.by_week_no[0])); - - r->byyearday = array_to_list (ir.by_year_day, - sizeof (ir.by_year_day) / sizeof (ir.by_year_day[0])); - - r->bymonthday = array_to_list (ir.by_month_day, - sizeof (ir.by_month_day) / sizeof (ir.by_month_day[0])); - - /* FIXME: libical only supports 8 values, out of possible 107 * 7. */ - r->byday = NULL; - max_elements = sizeof (ir.by_day) / sizeof (ir.by_day[0]); - for (i = 0; i < max_elements && ir.by_day[i] != ICAL_RECURRENCE_ARRAY_MAX; i++) { - enum icalrecurrencetype_weekday day; - gint weeknum, weekday; - - day = icalrecurrencetype_day_day_of_week (ir.by_day[i]); - weeknum = icalrecurrencetype_day_position (ir.by_day[i]); - - weekday = cal_recur_ical_weekday_to_weekday (day); - - r->byday = g_list_prepend (r->byday, - GINT_TO_POINTER (weeknum)); - r->byday = g_list_prepend (r->byday, - GINT_TO_POINTER (weekday)); - } - - r->byhour = array_to_list (ir.by_hour, - sizeof (ir.by_hour) / sizeof (ir.by_hour[0])); - - r->byminute = array_to_list (ir.by_minute, - sizeof (ir.by_minute) / sizeof (ir.by_minute[0])); - - r->bysecond = array_to_list (ir.by_second, - sizeof (ir.by_second) / sizeof (ir.by_second[0])); - - r->bysetpos = array_to_list (ir.by_set_pos, - sizeof (ir.by_set_pos) / sizeof (ir.by_set_pos[0])); - - return r; -} - - -static gint -cal_recur_ical_weekday_to_weekday (enum icalrecurrencetype_weekday day) -{ - gint weekday; - - switch (day) { - case ICAL_NO_WEEKDAY: /* Monday is the default in RFC2445. */ - case ICAL_MONDAY_WEEKDAY: - weekday = 0; - break; - case ICAL_TUESDAY_WEEKDAY: - weekday = 1; - break; - case ICAL_WEDNESDAY_WEEKDAY: - weekday = 2; - break; - case ICAL_THURSDAY_WEEKDAY: - weekday = 3; - break; - case ICAL_FRIDAY_WEEKDAY: - weekday = 4; - break; - case ICAL_SATURDAY_WEEKDAY: - weekday = 5; - break; - case ICAL_SUNDAY_WEEKDAY: - weekday = 6; - break; - default: - g_warning ("cal_recur_ical_weekday_to_weekday(): Unknown week day %d", - day); - weekday = 0; - } - - return weekday; -} - - -/** - * cal_recur_free: - * @r: A #CalRecurrence structure. - * - * Frees a #CalRecurrence structure. - **/ -static void -cal_recur_free (CalRecurrence *r) -{ - g_return_if_fail (r != NULL); - - g_list_free (r->bymonth); - g_list_free (r->byweekno); - g_list_free (r->byyearday); - g_list_free (r->bymonthday); - g_list_free (r->byday); - g_list_free (r->byhour); - g_list_free (r->byminute); - g_list_free (r->bysecond); - g_list_free (r->bysetpos); - - g_free (r); -} - -/* Generates one year's worth of recurrence instances. Returns TRUE if all the - * callback invocations returned TRUE, or FALSE when any one of them returns - * FALSE, i.e. meaning that the instance generation should be stopped. - * - * This should only output instances whose start time is between chunk_start - * and chunk_end (inclusive), or we may generate duplicates when we do the next - * chunk. (This applies mainly to weekly recurrences, since weeks can span 2 - * years.) - * - * It should also only output instances that are on or after the event's - * DTSTART property and that intersect the required interval, between - * interval_start and interval_end. - */ -static gboolean -generate_instances_for_chunk (CalComponent *comp, - time_t comp_dtstart, - GSList *rrules, - GSList *rdates, - GSList *exrules, - GSList *exdates, - gboolean single_rule, - CalObjTime *event_start, - time_t interval_start, - CalObjTime *chunk_start, - CalObjTime *chunk_end, - gint duration_days, - gint duration_seconds, - CalRecurInstanceFn cb, - gpointer cb_data) -{ - GArray *occs, *ex_occs, *tmp_occs, *rdate_periods; - CalObjTime cotime, *occ; - GSList *elem; - gint i; - time_t start_time, end_time; - struct tm start_tm, end_tm; - gboolean cb_status = TRUE, rule_finished, finished = TRUE; - -#if 0 - g_print ("In generate_instances_for_chunk rrules: %p\n" - " %i/%i/%i %02i:%02i:%02i - %i/%i/%i %02i:%02i:%02i\n", - rrules, - chunk_start->day, chunk_start->month + 1, - chunk_start->year, chunk_start->hour, - chunk_start->minute, chunk_start->second, - chunk_end->day, chunk_end->month + 1, - chunk_end->year, chunk_end->hour, - chunk_end->minute, chunk_end->second); -#endif - - occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime)); - ex_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime)); - rdate_periods = g_array_new (FALSE, FALSE, - sizeof (CalObjRecurrenceDate)); - - /* The original DTSTART property is included in the occurrence set, - but not if we are just generating occurrences for a single rule. */ - if (!single_rule) { - /* We add it if it is in this chunk. If it is after this chunk - we set finished to FALSE, since we know we aren't finished - yet. */ - if (cal_obj_time_compare_func (event_start, chunk_end) >= 0) - finished = FALSE; - else if (cal_obj_time_compare_func (event_start, chunk_start) >= 0) - g_array_append_vals (occs, event_start, 1); - } - - /* Expand each of the recurrence rules. */ - for (elem = rrules; elem; elem = elem->next) { - icalproperty *prop; - CalRecurrence *r; - - prop = elem->data; - r = cal_recur_from_icalproperty (prop, FALSE); - - tmp_occs = cal_obj_expand_recurrence (event_start, r, - chunk_start, - chunk_end, - &rule_finished); - cal_recur_free (r); - - /* If any of the rules return FALSE for finished, we know we - have to carry on so we set finished to FALSE. */ - if (!rule_finished) - finished = FALSE; - - g_array_append_vals (occs, tmp_occs->data, tmp_occs->len); - g_array_free (tmp_occs, TRUE); - } - - /* Add on specific occurrence dates, flag them as RDATEs, and store - a pointer to the period in the rdate_periods array. */ - for (elem = rdates; elem; elem = elem->next) { - CalComponentPeriod *p; - CalObjRecurrenceDate rdate; - time_t t; - - p = elem->data; - t = icaltime_as_timet (p->start); - cal_object_time_from_time (&cotime, t); - - /* If the rdate is after the current chunk we set finished - to FALSE, and we skip it. */ - if (cal_obj_time_compare_func (&cotime, chunk_end) >= 0) { - finished = FALSE; - continue; - } - - /* Check if the end date or duration is set. If it is we need - to store it so we can get it later. (libical seems to set - second to -1 to denote an unset time. See icalvalue.c) */ - if (p->type != CAL_COMPONENT_PERIOD_DATETIME - || p->u.end.second != -1) { - cotime.is_rdate = TRUE; - - rdate.start = cotime; - rdate.period = p; - g_array_append_val (rdate_periods, rdate); - } - - g_array_append_val (occs, cotime); - } - - /* Expand each of the exception rules. */ - for (elem = exrules; elem; elem = elem->next) { - icalproperty *prop; - CalRecurrence *r; - - prop = elem->data; - r = cal_recur_from_icalproperty (prop, FALSE); - - tmp_occs = cal_obj_expand_recurrence (event_start, r, - chunk_start, - chunk_end, - &rule_finished); - cal_recur_free (r); - - g_array_append_vals (ex_occs, tmp_occs->data, tmp_occs->len); - g_array_free (tmp_occs, TRUE); - } - - /* Add on specific exception dates. */ - for (elem = exdates; elem; elem = elem->next) { - CalComponentDateTime *cdt; - time_t t; - - /* FIXME we should only be dealing with dates, not times too. - - No, I think it is supposed to be dates & times - Damon. - I'm not sure what the semantics of just a date would be, - since the event could recur several times each day. */ - cdt = elem->data; - t = icaltime_as_timet (*cdt->value); - cal_object_time_from_time (&cotime, t); - - g_array_append_val (ex_occs, cotime); - } - - - /* Sort all the arrays. */ - cal_obj_sort_occurrences (occs); - cal_obj_sort_occurrences (ex_occs); - - qsort (rdate_periods->data, rdate_periods->len, - sizeof (CalObjRecurrenceDate), cal_obj_time_compare_func); - - /* Create the final array, by removing the exceptions from the - occurrences, and removing any duplicates. */ - cal_obj_remove_exceptions (occs, ex_occs); - - /* Call the callback for each occurrence. If it returns 0 we break - out of the loop. */ - for (i = 0; i < occs->len; i++) { - /* Convert each CalObjTime into a start & end time_t, and - check it is within the bounds of the event & interval. */ - occ = &g_array_index (occs, CalObjTime, i); -#if 0 - g_print ("Checking occurrence: %s\n", - cal_obj_time_to_string (occ)); -#endif - start_tm.tm_year = occ->year - 1900; - start_tm.tm_mon = occ->month; - start_tm.tm_mday = occ->day; - start_tm.tm_hour = occ->hour; - start_tm.tm_min = occ->minute; - start_tm.tm_sec = occ->second; - start_tm.tm_isdst = -1; - start_time = mktime (&start_tm); - - if (start_time == -1) { - g_warning ("mktime failed - time_t out of range?"); - finished = TRUE; - break; - } - - /* Check to ensure that the start time is at or after the - event's DTSTART time, and that it is inside the chunk that - we are currently working on. (Note that the chunk_end time - is never after the interval end time, so this also tests - that we don't go past the end of the required interval). */ - if (start_time < comp_dtstart - || cal_obj_time_compare_func (occ, chunk_start) < 0 - || cal_obj_time_compare_func (occ, chunk_end) > 0) { -#if 0 - g_print (" start time invalid\n"); -#endif - continue; - } - - if (occ->is_rdate) { - if (!cal_object_get_rdate_end (occ, rdate_periods)) { - cal_obj_time_add_days (occ, duration_days); - cal_obj_time_add_seconds (occ, - duration_seconds); - } - } else { - cal_obj_time_add_days (occ, duration_days); - cal_obj_time_add_seconds (occ, duration_seconds); - } - - end_tm.tm_year = occ->year - 1900; - end_tm.tm_mon = occ->month; - end_tm.tm_mday = occ->day; - end_tm.tm_hour = occ->hour; - end_tm.tm_min = occ->minute; - end_tm.tm_sec = occ->second; - end_tm.tm_isdst = -1; - end_time = mktime (&end_tm); - - if (end_time == -1) { - g_warning ("mktime failed - time_t out of range?"); - finished = TRUE; - break; - } - - /* Check that the end time is after the interval start, so we - know that it intersects the required interval. */ - if (end_time <= interval_start) { -#if 0 - g_print (" end time invalid\n"); -#endif - continue; - } - - cb_status = (*cb) (comp, start_time, end_time, cb_data); - if (!cb_status) - break; - } - - g_array_free (occs, TRUE); - g_array_free (ex_occs, TRUE); - g_array_free (rdate_periods, TRUE); - - /* We return TRUE (i.e. carry on) only if the callback has always - returned TRUE and we know that we have more occurrences to generate - (i.e. finished is FALSE). */ - return cb_status && !finished; -} - - -/* This looks up the occurrence time in the sorted rdate_periods array, and - tries to compute the end time of the occurrence. If no end time or duration - is set it returns FALSE and the default duration will be used. */ -static gboolean -cal_object_get_rdate_end (CalObjTime *occ, - GArray *rdate_periods) -{ - CalObjRecurrenceDate *rdate = NULL; - CalComponentPeriod *p; - gint lower, upper, middle, cmp = 0; - time_t t; - - lower = 0; - upper = rdate_periods->len; - - while (lower < upper) { - middle = (lower + upper) >> 1; - - rdate = &g_array_index (rdate_periods, CalObjRecurrenceDate, - middle); - - cmp = cal_obj_time_compare_func (occ, &rdate->start); - - if (cmp == 0) - break; - else if (cmp < 0) - upper = middle; - else - lower = middle + 1; - } - - /* This should never happen. */ - if (cmp == 0) { - g_warning ("Recurrence date not found"); - return FALSE; - } - - p = rdate->period; - if (p->type == CAL_COMPONENT_PERIOD_DATETIME) { - t = icaltime_as_timet (p->u.end); - cal_object_time_from_time (occ, t); - } else { - cal_obj_time_add_days (occ, p->u.duration.weeks * 7 - + p->u.duration.days); - cal_obj_time_add_hours (occ, p->u.duration.hours); - cal_obj_time_add_minutes (occ, p->u.duration.minutes); - cal_obj_time_add_seconds (occ, p->u.duration.seconds); - } - - return TRUE; -} - - -static void -cal_object_compute_duration (CalObjTime *start, - CalObjTime *end, - gint *days, - gint *seconds) -{ - GDate start_date, end_date; - gint start_seconds, end_seconds; - - g_date_clear (&start_date, 1); - g_date_clear (&end_date, 1); - g_date_set_dmy (&start_date, start->day, start->month + 1, - start->year); - g_date_set_dmy (&end_date, end->day, end->month + 1, - end->year); - - *days = g_date_julian (&end_date) - g_date_julian (&start_date); - start_seconds = start->hour * 3600 + start->minute * 60 - + start->second; - end_seconds = end->hour * 3600 + end->minute * 60 + end->second; - - *seconds = end_seconds - start_seconds; - if (*seconds < 0) { - *days = *days - 1; - *seconds += 24 * 60 * 60; - } -} - - -/* Returns an unsorted GArray of CalObjTime's resulting from expanding the - given recurrence rule within the given interval. Note that it doesn't - clip the generated occurrences to the interval, i.e. if the interval - starts part way through the year this function still returns all the - occurrences for the year. Clipping is done later. - The finished flag is set to FALSE if there are more occurrences to generate - after the given interval.*/ -static GArray* -cal_obj_expand_recurrence (CalObjTime *event_start, - CalRecurrence *recur, - CalObjTime *interval_start, - CalObjTime *interval_end, - gboolean *finished) -{ - CalRecurVTable *vtable; - CalObjTime *event_end = NULL, event_end_cotime; - RecurData recur_data; - CalObjTime occ, *cotime; - GArray *all_occs, *occs; - gint len; - - /* This is the resulting array of CalObjTime elements. */ - all_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime)); - - *finished = TRUE; - - vtable = cal_obj_get_vtable (recur->freq); - if (!vtable) - return all_occs; - - /* Calculate some useful data such as some fast lookup tables. */ - cal_obj_initialize_recur_data (&recur_data, recur, event_start); - - /* Compute the event_end, if the recur's enddate is set. */ - if (recur->enddate > 0) { - cal_object_time_from_time (&event_end_cotime, - recur->enddate); - event_end = &event_end_cotime; - - /* If the enddate is before the requested interval return. */ - if (cal_obj_time_compare_func (event_end, interval_start) < 0) - return all_occs; - } - - /* Set finished to FALSE if we know there will be more occurrences to - do after this interval. */ - if (!interval_end || !event_end - || cal_obj_time_compare_func (event_end, interval_end) > 0) - *finished = FALSE; - - /* Get the first period based on the frequency and the interval that - intersects the interval between start and end. */ - if ((*vtable->find_start_position) (event_start, event_end, - &recur_data, - interval_start, interval_end, - &occ)) - return all_occs; - - /* Loop until the event ends or we go past the end of the required - interval. */ - for (;;) { - /* Generate the set of occurrences for this period. */ - switch (recur->freq) { - case ICAL_YEARLY_RECURRENCE: - occs = cal_obj_generate_set_yearly (&recur_data, - vtable, &occ); - break; - case ICAL_MONTHLY_RECURRENCE: - occs = cal_obj_generate_set_monthly (&recur_data, - vtable, &occ); - break; - default: - occs = cal_obj_generate_set_default (&recur_data, - vtable, &occ); - break; - } - - /* Sort the occurrences and remove duplicates. */ - cal_obj_sort_occurrences (occs); - cal_obj_remove_duplicates_and_invalid_dates (occs); - - /* Apply the BYSETPOS property. */ - occs = cal_obj_bysetpos_filter (recur, occs); - - /* Remove any occs after event_end. */ - len = occs->len - 1; - if (event_end) { - while (len >= 0) { - cotime = &g_array_index (occs, CalObjTime, - len); - if (cal_obj_time_compare_func (cotime, - event_end) <= 0) - break; - len--; - } - } - - /* Add the occurrences onto the main array. */ - if (len >= 0) - g_array_append_vals (all_occs, occs->data, len + 1); - - g_array_free (occs, TRUE); - - /* Skip to the next period, or exit the loop if finished. */ - if ((*vtable->find_next_position) (&occ, event_end, - &recur_data, interval_end)) - break; - } - - return all_occs; -} - - -static GArray* -cal_obj_generate_set_yearly (RecurData *recur_data, - CalRecurVTable *vtable, - CalObjTime *occ) -{ - CalRecurrence *recur = recur_data->recur; - GArray *occs_arrays[4], *occs, *occs2; - gint num_occs_arrays = 0, i; - - /* This is a bit complicated, since the iCalendar spec says that - several BYxxx modifiers can be used simultaneously. So we have to - be quite careful when determining the days of the occurrences. - The BYHOUR, BYMINUTE & BYSECOND modifiers are no problem at all. - - The modifiers we have to worry about are: BYMONTH, BYWEEKNO, - BYYEARDAY, BYMONTHDAY & BYDAY. We can't do these sequentially - since each filter will mess up the results of the previous one. - But they aren't all completely independant, e.g. BYMONTHDAY and - BYDAY are related to BYMONTH, and BYDAY is related to BYWEEKNO. - - BYDAY & BYMONTHDAY can also be applied independently, which makes - it worse. So we assume that if BYMONTH or BYWEEKNO is used, then - the BYDAY modifier applies to those, else it is applied - independantly. - - We expand the occurrences in parallel into the occs_arrays[] array, - and then merge them all into one GArray before expanding BYHOUR, - BYMINUTE & BYSECOND. */ - - if (recur->bymonth) { - occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime)); - g_array_append_vals (occs, occ, 1); - - occs = (*vtable->bymonth_filter) (recur_data, occs); - - /* If BYMONTHDAY & BYDAY are both set we need to expand them - in parallel and add the results. */ - if (recur->bymonthday && recur->byday) { - /* Copy the occs array. */ - occs2 = g_array_new (FALSE, FALSE, - sizeof (CalObjTime)); - g_array_append_vals (occs2, occs->data, occs->len); - - occs = (*vtable->bymonthday_filter) (recur_data, occs); - /* Note that we explicitly call the monthly version - of the BYDAY expansion filter. */ - occs2 = cal_obj_byday_expand_monthly (recur_data, - occs2); - - /* Add the 2 resulting arrays together. */ - g_array_append_vals (occs, occs2->data, occs2->len); - g_array_free (occs2, TRUE); - } else { - occs = (*vtable->bymonthday_filter) (recur_data, occs); - /* Note that we explicitly call the monthly version - of the BYDAY expansion filter. */ - occs = cal_obj_byday_expand_monthly (recur_data, occs); - } - - occs_arrays[num_occs_arrays++] = occs; - } - - if (recur->byweekno) { - occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime)); - g_array_append_vals (occs, occ, 1); - - occs = (*vtable->byweekno_filter) (recur_data, occs); - /* Note that we explicitly call the weekly version of the - BYDAY expansion filter. */ - occs = cal_obj_byday_expand_weekly (recur_data, occs); - - occs_arrays[num_occs_arrays++] = occs; - } - - if (recur->byyearday) { - occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime)); - g_array_append_vals (occs, occ, 1); - - occs = (*vtable->byyearday_filter) (recur_data, occs); - - occs_arrays[num_occs_arrays++] = occs; - } - - /* If BYMONTHDAY is set, and BYMONTH is not set, we need to - expand BYMONTHDAY independantly. */ - if (recur->bymonthday && !recur->bymonth) { - occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime)); - g_array_append_vals (occs, occ, 1); - - occs = (*vtable->bymonthday_filter) (recur_data, occs); - - occs_arrays[num_occs_arrays++] = occs; - } - - /* If BYDAY is set, and BYMONTH and BYWEEKNO are not set, we need to - expand BYDAY independantly. */ - if (recur->byday && !recur->bymonth && !recur->byweekno) { - occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime)); - g_array_append_vals (occs, occ, 1); - - occs = (*vtable->byday_filter) (recur_data, occs); - - occs_arrays[num_occs_arrays++] = occs; - } - - /* Add all the arrays together. If no filters were used we just - create an array with one element. */ - if (num_occs_arrays > 0) { - occs = occs_arrays[0]; - for (i = 1; i < num_occs_arrays; i++) { - occs2 = occs_arrays[i]; - g_array_append_vals (occs, occs2->data, occs2->len); - g_array_free (occs2, TRUE); - } - } else { - occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime)); - g_array_append_vals (occs, occ, 1); - } - - /* Now expand BYHOUR, BYMINUTE & BYSECOND. */ - occs = (*vtable->byhour_filter) (recur_data, occs); - occs = (*vtable->byminute_filter) (recur_data, occs); - occs = (*vtable->bysecond_filter) (recur_data, occs); - - return occs; -} - - -static GArray* -cal_obj_generate_set_monthly (RecurData *recur_data, - CalRecurVTable *vtable, - CalObjTime *occ) -{ - GArray *occs, *occs2; - - /* We start with just the one time in each set. */ - occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime)); - g_array_append_vals (occs, occ, 1); - - occs = (*vtable->bymonth_filter) (recur_data, occs); - - /* We need to combine the output of BYMONTHDAY & BYDAY, by doing them - in parallel rather than sequentially. If we did them sequentially - then we would lose the occurrences generated by BYMONTHDAY, and - instead have repetitions of the occurrences from BYDAY. */ - if (recur_data->recur->bymonthday && recur_data->recur->byday) { - occs2 = g_array_new (FALSE, FALSE, sizeof (CalObjTime)); - g_array_append_vals (occs2, occs->data, occs->len); - - occs = (*vtable->bymonthday_filter) (recur_data, occs); - occs2 = (*vtable->byday_filter) (recur_data, occs2); - - g_array_append_vals (occs, occs2->data, occs2->len); - g_array_free (occs2, TRUE); - } else { - occs = (*vtable->bymonthday_filter) (recur_data, occs); - occs = (*vtable->byday_filter) (recur_data, occs); - } - - occs = (*vtable->byhour_filter) (recur_data, occs); - occs = (*vtable->byminute_filter) (recur_data, occs); - occs = (*vtable->bysecond_filter) (recur_data, occs); - - return occs; -} - - -static GArray* -cal_obj_generate_set_default (RecurData *recur_data, - CalRecurVTable *vtable, - CalObjTime *occ) -{ - GArray *occs; - -#if 0 - g_print ("Generating set for %i/%i/%i %02i:%02i:%02i\n", - occ->day, occ->month + 1, occ->year, occ->hour, occ->minute, - occ->second); -#endif - - /* We start with just the one time in the set. */ - occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime)); - g_array_append_vals (occs, occ, 1); - - occs = (*vtable->bymonth_filter) (recur_data, occs); - if (vtable->byweekno_filter) - occs = (*vtable->byweekno_filter) (recur_data, occs); - if (vtable->byyearday_filter) - occs = (*vtable->byyearday_filter) (recur_data, occs); - if (vtable->bymonthday_filter) - occs = (*vtable->bymonthday_filter) (recur_data, occs); - occs = (*vtable->byday_filter) (recur_data, occs); - - occs = (*vtable->byhour_filter) (recur_data, occs); - occs = (*vtable->byminute_filter) (recur_data, occs); - occs = (*vtable->bysecond_filter) (recur_data, occs); - - return occs; -} - - - -/* Returns the function table corresponding to the recurrence frequency. */ -static CalRecurVTable* cal_obj_get_vtable (icalrecurrencetype_frequency recur_type) -{ - CalRecurVTable* vtable; - - switch (recur_type) { - case ICAL_YEARLY_RECURRENCE: - vtable = &cal_obj_yearly_vtable; - break; - case ICAL_MONTHLY_RECURRENCE: - vtable = &cal_obj_monthly_vtable; - break; - case ICAL_WEEKLY_RECURRENCE: - vtable = &cal_obj_weekly_vtable; - break; - case ICAL_DAILY_RECURRENCE: - vtable = &cal_obj_daily_vtable; - break; - case ICAL_HOURLY_RECURRENCE: - vtable = &cal_obj_hourly_vtable; - break; - case ICAL_MINUTELY_RECURRENCE: - vtable = &cal_obj_minutely_vtable; - break; - case ICAL_SECONDLY_RECURRENCE: - vtable = &cal_obj_secondly_vtable; - break; - default: - g_warning ("Unknown recurrence frequenct"); - vtable = NULL; - } - - return vtable; -} - - -/* This creates a number of fast lookup tables used when filtering with the - modifier properties BYMONTH, BYYEARDAY etc. */ -static void -cal_obj_initialize_recur_data (RecurData *recur_data, - CalRecurrence *recur, - CalObjTime *event_start) -{ - GList *elem; - gint month, yearday, monthday, weekday, week_num, hour, minute, second; - - /* Clear the entire RecurData. */ - memset (recur_data, 0, sizeof (RecurData)); - - recur_data->recur = recur; - - /* Set the weekday, used for the WEEKLY frequency and the BYWEEKNO - modifier. */ - recur_data->weekday_offset = cal_obj_time_weekday_offset (event_start, - recur); - - /* Create an array of months from bymonths for fast lookup. */ - elem = recur->bymonth; - while (elem) { - month = GPOINTER_TO_INT (elem->data); - recur_data->months[month] = 1; - elem = elem->next; - } - - /* Create an array of yeardays from byyearday for fast lookup. - We create a second array to handle the negative values. The first - element there corresponds to the last day of the year. */ - elem = recur->byyearday; - while (elem) { - yearday = GPOINTER_TO_INT (elem->data); - if (yearday >= 0) - recur_data->yeardays[yearday] = 1; - else - recur_data->neg_yeardays[-yearday] = 1; - elem = elem->next; - } - - /* Create an array of monthdays from bymonthday for fast lookup. - We create a second array to handle the negative values. The first - element there corresponds to the last day of the month. */ - elem = recur->bymonthday; - while (elem) { - monthday = GPOINTER_TO_INT (elem->data); - if (monthday >= 0) - recur_data->monthdays[monthday] = 1; - else - recur_data->neg_monthdays[-monthday] = 1; - elem = elem->next; - } - - /* Create an array of weekdays from byday for fast lookup. */ - elem = recur->byday; - while (elem) { - weekday = GPOINTER_TO_INT (elem->data); - elem = elem->next; - /* The week number is not used when filtering. */ - week_num = GPOINTER_TO_INT (elem->data); - elem = elem->next; - - recur_data->weekdays[weekday] = 1; - } - - /* Create an array of hours from byhour for fast lookup. */ - elem = recur->byhour; - while (elem) { - hour = GPOINTER_TO_INT (elem->data); - recur_data->hours[hour] = 1; - elem = elem->next; - } - - /* Create an array of minutes from byminutes for fast lookup. */ - elem = recur->byminute; - while (elem) { - minute = GPOINTER_TO_INT (elem->data); - recur_data->minutes[minute] = 1; - elem = elem->next; - } - - /* Create an array of seconds from byseconds for fast lookup. */ - elem = recur->bysecond; - while (elem) { - second = GPOINTER_TO_INT (elem->data); - recur_data->seconds[second] = 1; - elem = elem->next; - } -} - - -static void -cal_obj_sort_occurrences (GArray *occs) -{ - qsort (occs->data, occs->len, sizeof (CalObjTime), - cal_obj_time_compare_func); -} - - -static void -cal_obj_remove_duplicates_and_invalid_dates (GArray *occs) -{ - static const int days_in_month[12] = { - 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 - }; - - CalObjTime *occ, *prev_occ = NULL; - gint len, i, j = 0, year, month, days; - gboolean keep_occ; - - len = occs->len; - for (i = 0; i < len; i++) { - occ = &g_array_index (occs, CalObjTime, i); - keep_occ = TRUE; - - if (prev_occ && cal_obj_time_compare_func (occ, - prev_occ) == 0) - keep_occ = FALSE; - - year = occ->year; - month = occ->month; - days = days_in_month[occ->month]; - /* If it is february and a leap year, add a day. */ - if (month == 1 && (year % 4 == 0 - && (year % 100 != 0 - || year % 400 == 0))) - days++; - if (occ->day > days) - keep_occ = FALSE; - - if (keep_occ) { - if (i != j) - g_array_index (occs, CalObjTime, j) - = g_array_index (occs, CalObjTime, i); - j++; - } - - prev_occ = occ; - } - - g_array_set_size (occs, j); -} - - -/* Removes the exceptions from the ex_occs array from the occurrences in the - occs array, and removes any duplicates. Both arrays are sorted. */ -static void -cal_obj_remove_exceptions (GArray *occs, - GArray *ex_occs) -{ - CalObjTime *occ, *prev_occ = NULL, *ex_occ = NULL, *last_occ_kept; - gint i, j = 0, cmp, ex_index, occs_len, ex_occs_len; - gboolean keep_occ, current_time_is_exception = FALSE; - - if (occs->len == 0) - return; - - ex_index = 0; - occs_len = occs->len; - ex_occs_len = ex_occs->len; - - if (ex_occs_len > 0) - ex_occ = &g_array_index (ex_occs, CalObjTime, ex_index); - - for (i = 0; i < occs_len; i++) { - occ = &g_array_index (occs, CalObjTime, i); - keep_occ = TRUE; - - /* If the occurrence is a duplicate of the previous one, skip - it. */ - if (prev_occ - && cal_obj_time_compare_func (occ, prev_occ) == 0) { - keep_occ = FALSE; - - /* If this occurrence is an RDATE, and the previous - occurrence in the array was kept, set the RDATE flag - of the last one, so we still use the end date - or duration. */ - if (occ->is_rdate && !current_time_is_exception) { - last_occ_kept = &g_array_index (occs, - CalObjTime, - j - 1); - last_occ_kept->is_rdate = TRUE; - } - } else { - /* We've found a new occurrence time. Reset the flag - to indicate that it hasn't been found in the - exceptions array (yet). */ - current_time_is_exception = FALSE; - - if (ex_occ) { - /* Step through the exceptions until we come - to one that matches or follows this - occurrence. */ - while (ex_occ) { - cmp = cal_obj_time_compare_func (ex_occ, occ); - /* I'm pretty sure this is wrong. */ - /*cmp = cal_obj_date_only_compare_func (ex_occ, occ);*/ - if (cmp > 0) - break; - - /* Move to the next exception, or set - ex_occ to NULL when we reach the - end of array. */ - ex_index++; - if (ex_index < ex_occs_len) - ex_occ = &g_array_index (ex_occs, CalObjTime, ex_index); - else - ex_occ = NULL; - - /* If the exception did match this - occurrence we remove it, and set the - flag to indicate that the current - time is an exception. */ - if (cmp == 0) { - current_time_is_exception = TRUE; - keep_occ = FALSE; - break; - } - } - } - } - - if (keep_occ) { - if (i != j) - g_array_index (occs, CalObjTime, j) - = g_array_index (occs, CalObjTime, i); - j++; - } - - prev_occ = occ; - } - - g_array_set_size (occs, j); -} - - - -static GArray* -cal_obj_bysetpos_filter (CalRecurrence *recur, - GArray *occs) -{ - GArray *new_occs; - CalObjTime *occ; - GList *elem; - gint len, pos; - - /* If BYSETPOS has not been specified, or the array is empty, just - return the array. */ - elem = recur->bysetpos; - if (!elem || occs->len == 0) - return occs; - - new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime)); - - /* Iterate over the indices given in bysetpos, adding the corresponding - element from occs to new_occs. */ - len = occs->len; - while (elem) { - pos = GPOINTER_TO_INT (elem->data); - - /* Negative values count back from the end of the array. */ - if (pos < 0) - pos += len; - - if (pos >= 0 && pos < len) { - occ = &g_array_index (occs, CalObjTime, pos); - g_array_append_vals (new_occs, occ, 1); - } - elem = elem->next; - } - - g_array_free (occs, TRUE); - - return new_occs; -} - - - - -/* Finds the first year from the event_start, counting in multiples of the - recurrence interval, that intersects the given interval. It returns TRUE - if there is no intersection. */ -static gboolean -cal_obj_yearly_find_start_position (CalObjTime *event_start, - CalObjTime *event_end, - RecurData *recur_data, - CalObjTime *interval_start, - CalObjTime *interval_end, - CalObjTime *cotime) -{ - *cotime = *event_start; - - /* Move on to the next interval, if the event starts before the - given interval. */ - if (cotime->year < interval_start->year) { - gint years = interval_start->year - cotime->year - + recur_data->recur->interval - 1; - years -= years % recur_data->recur->interval; - /* NOTE: The day may now be invalid, e.g. 29th Feb. */ - cotime->year += years; - } - - if ((event_end && cotime->year > event_end->year) - || (interval_end && cotime->year > interval_end->year)) - return TRUE; - - return FALSE; -} - - -static gboolean -cal_obj_yearly_find_next_position (CalObjTime *cotime, - CalObjTime *event_end, - RecurData *recur_data, - CalObjTime *interval_end) -{ - /* NOTE: The day may now be invalid, e.g. 29th Feb. */ - cotime->year += recur_data->recur->interval; - - if ((event_end && cotime->year > event_end->year) - || (interval_end && cotime->year > interval_end->year)) - return TRUE; - - return FALSE; -} - - - -static gboolean -cal_obj_monthly_find_start_position (CalObjTime *event_start, - CalObjTime *event_end, - RecurData *recur_data, - CalObjTime *interval_start, - CalObjTime *interval_end, - CalObjTime *cotime) -{ - *cotime = *event_start; - - /* Move on to the next interval, if the event starts before the - given interval. */ - if (cal_obj_time_compare (cotime, interval_start, CALOBJ_MONTH) < 0) { - gint months = (interval_start->year - cotime->year) * 12 - + interval_start->month - cotime->month - + recur_data->recur->interval - 1; - months -= months % recur_data->recur->interval; - /* NOTE: The day may now be invalid, e.g. 31st Sep. */ - cal_obj_time_add_months (cotime, months); - } - - if (event_end && cal_obj_time_compare (cotime, event_end, - CALOBJ_MONTH) > 0) - return TRUE; - if (interval_end && cal_obj_time_compare (cotime, interval_end, - CALOBJ_MONTH) > 0) - return TRUE; - - return FALSE; -} - - -static gboolean -cal_obj_monthly_find_next_position (CalObjTime *cotime, - CalObjTime *event_end, - RecurData *recur_data, - CalObjTime *interval_end) -{ - /* NOTE: The day may now be invalid, e.g. 31st Sep. */ - cal_obj_time_add_months (cotime, recur_data->recur->interval); - - if (event_end && cal_obj_time_compare (cotime, event_end, - CALOBJ_MONTH) > 0) - return TRUE; - if (interval_end && cal_obj_time_compare (cotime, interval_end, - CALOBJ_MONTH) > 0) - return TRUE; - - return FALSE; -} - - - -static gboolean -cal_obj_weekly_find_start_position (CalObjTime *event_start, - CalObjTime *event_end, - RecurData *recur_data, - CalObjTime *interval_start, - CalObjTime *interval_end, - CalObjTime *cotime) -{ - GDate event_start_date, interval_start_date; - guint32 event_start_julian, interval_start_julian; - gint interval_start_weekday_offset; - CalObjTime week_start; - - if (event_end && cal_obj_time_compare (event_end, interval_start, - CALOBJ_DAY) < 0) - return TRUE; - if (interval_end && cal_obj_time_compare (event_start, interval_end, - CALOBJ_DAY) > 0) - return TRUE; - - *cotime = *event_start; - - /* Convert the event start and interval start to GDates, so we can - easily find the number of days between them. */ - g_date_clear (&event_start_date, 1); - g_date_set_dmy (&event_start_date, event_start->day, - event_start->month + 1, event_start->year); - g_date_clear (&interval_start_date, 1); - g_date_set_dmy (&interval_start_date, interval_start->day, - interval_start->month + 1, interval_start->year); - - /* Calculate the start of the weeks corresponding to the event start - and interval start. */ - event_start_julian = g_date_julian (&event_start_date); - event_start_julian -= recur_data->weekday_offset; - - interval_start_julian = g_date_julian (&interval_start_date); - interval_start_weekday_offset = cal_obj_time_weekday_offset (interval_start, recur_data->recur); - interval_start_julian -= interval_start_weekday_offset; - - /* We want to find the first full week using the recurrence interval - that intersects the given interval dates. */ - if (event_start_julian < interval_start_julian) { - gint weeks = (interval_start_julian - event_start_julian) / 7; - weeks += recur_data->recur->interval - 1; - weeks -= weeks % recur_data->recur->interval; - cal_obj_time_add_days (cotime, weeks * 7); - } - - week_start = *cotime; - cal_obj_time_add_days (&week_start, -recur_data->weekday_offset); - - if (event_end && cal_obj_time_compare (&week_start, event_end, - CALOBJ_DAY) > 0) - return TRUE; - if (interval_end && cal_obj_time_compare (&week_start, interval_end, - CALOBJ_DAY) > 0) - return TRUE; - - return FALSE; -} - - -static gboolean -cal_obj_weekly_find_next_position (CalObjTime *cotime, - CalObjTime *event_end, - RecurData *recur_data, - CalObjTime *interval_end) -{ - CalObjTime week_start; - - cal_obj_time_add_days (cotime, recur_data->recur->interval * 7); - - /* Return TRUE if the start of this week is after the event finishes - or is after the end of the required interval. */ - week_start = *cotime; - cal_obj_time_add_days (&week_start, -recur_data->weekday_offset); - -#ifdef CAL_OBJ_DEBUG - g_print ("Next day: %s\n", cal_obj_time_to_string (cotime)); - g_print ("Week Start: %s\n", cal_obj_time_to_string (&week_start)); -#endif - - if (event_end && cal_obj_time_compare (&week_start, event_end, - CALOBJ_DAY) > 0) - return TRUE; - if (interval_end && cal_obj_time_compare (&week_start, interval_end, - CALOBJ_DAY) > 0) { -#ifdef CAL_OBJ_DEBUG - g_print ("Interval end reached: %s\n", - cal_obj_time_to_string (interval_end)); -#endif - return TRUE; - } - - return FALSE; -} - - -static gboolean -cal_obj_daily_find_start_position (CalObjTime *event_start, - CalObjTime *event_end, - RecurData *recur_data, - CalObjTime *interval_start, - CalObjTime *interval_end, - CalObjTime *cotime) -{ - GDate event_start_date, interval_start_date; - guint32 event_start_julian, interval_start_julian, days; - - if (interval_end && cal_obj_time_compare (event_start, interval_end, - CALOBJ_DAY) > 0) - return TRUE; - if (event_end && cal_obj_time_compare (event_end, interval_start, - CALOBJ_DAY) < 0) - return TRUE; - - *cotime = *event_start; - - /* Convert the event start and interval start to GDates, so we can - easily find the number of days between them. */ - g_date_clear (&event_start_date, 1); - g_date_set_dmy (&event_start_date, event_start->day, - event_start->month + 1, event_start->year); - g_date_clear (&interval_start_date, 1); - g_date_set_dmy (&interval_start_date, interval_start->day, - interval_start->month + 1, interval_start->year); - - event_start_julian = g_date_julian (&event_start_date); - interval_start_julian = g_date_julian (&interval_start_date); - - if (event_start_julian < interval_start_julian) { - days = interval_start_julian - event_start_julian - + recur_data->recur->interval - 1; - days -= days % recur_data->recur->interval; - cal_obj_time_add_days (cotime, days); - } - - if (event_end && cal_obj_time_compare (cotime, event_end, - CALOBJ_DAY) > 0) - return TRUE; - if (interval_end && cal_obj_time_compare (cotime, interval_end, - CALOBJ_DAY) > 0) - return TRUE; - - return FALSE; -} - - -static gboolean -cal_obj_daily_find_next_position (CalObjTime *cotime, - CalObjTime *event_end, - RecurData *recur_data, - CalObjTime *interval_end) -{ - cal_obj_time_add_days (cotime, recur_data->recur->interval); - - if (event_end && cal_obj_time_compare (cotime, event_end, - CALOBJ_DAY) > 0) - return TRUE; - if (interval_end && cal_obj_time_compare (cotime, interval_end, - CALOBJ_DAY) > 0) - return TRUE; - - return FALSE; -} - - -static gboolean -cal_obj_hourly_find_start_position (CalObjTime *event_start, - CalObjTime *event_end, - RecurData *recur_data, - CalObjTime *interval_start, - CalObjTime *interval_end, - CalObjTime *cotime) -{ - GDate event_start_date, interval_start_date; - guint32 event_start_julian, interval_start_julian, hours; - - if (interval_end && cal_obj_time_compare (event_start, interval_end, - CALOBJ_HOUR) > 0) - return TRUE; - if (event_end && cal_obj_time_compare (event_end, interval_start, - CALOBJ_HOUR) < 0) - return TRUE; - - *cotime = *event_start; - - if (cal_obj_time_compare (event_start, interval_start, - CALOBJ_HOUR) < 0) { - /* Convert the event start and interval start to GDates, so we - can easily find the number of days between them. */ - g_date_clear (&event_start_date, 1); - g_date_set_dmy (&event_start_date, event_start->day, - event_start->month + 1, event_start->year); - g_date_clear (&interval_start_date, 1); - g_date_set_dmy (&interval_start_date, interval_start->day, - interval_start->month + 1, - interval_start->year); - - event_start_julian = g_date_julian (&event_start_date); - interval_start_julian = g_date_julian (&interval_start_date); - - hours = (interval_start_julian - event_start_julian) * 24; - hours += interval_start->hour - event_start->hour; - hours += recur_data->recur->interval - 1; - hours -= hours % recur_data->recur->interval; - cal_obj_time_add_hours (cotime, hours); - } - - if (event_end && cal_obj_time_compare (cotime, event_end, - CALOBJ_HOUR) > 0) - return TRUE; - if (interval_end && cal_obj_time_compare (cotime, interval_end, - CALOBJ_HOUR) > 0) - return TRUE; - - return FALSE; -} - - -static gboolean -cal_obj_hourly_find_next_position (CalObjTime *cotime, - CalObjTime *event_end, - RecurData *recur_data, - CalObjTime *interval_end) -{ - cal_obj_time_add_hours (cotime, recur_data->recur->interval); - - if (event_end && cal_obj_time_compare (cotime, event_end, - CALOBJ_HOUR) > 0) - return TRUE; - if (interval_end && cal_obj_time_compare (cotime, interval_end, - CALOBJ_HOUR) > 0) - return TRUE; - - return FALSE; -} - - -static gboolean -cal_obj_minutely_find_start_position (CalObjTime *event_start, - CalObjTime *event_end, - RecurData *recur_data, - CalObjTime *interval_start, - CalObjTime *interval_end, - CalObjTime *cotime) -{ - GDate event_start_date, interval_start_date; - guint32 event_start_julian, interval_start_julian, minutes; - - if (interval_end && cal_obj_time_compare (event_start, interval_end, - CALOBJ_MINUTE) > 0) - return TRUE; - if (event_end && cal_obj_time_compare (event_end, interval_start, - CALOBJ_MINUTE) < 0) - return TRUE; - - *cotime = *event_start; - - if (cal_obj_time_compare (event_start, interval_start, - CALOBJ_MINUTE) < 0) { - /* Convert the event start and interval start to GDates, so we - can easily find the number of days between them. */ - g_date_clear (&event_start_date, 1); - g_date_set_dmy (&event_start_date, event_start->day, - event_start->month + 1, event_start->year); - g_date_clear (&interval_start_date, 1); - g_date_set_dmy (&interval_start_date, interval_start->day, - interval_start->month + 1, - interval_start->year); - - event_start_julian = g_date_julian (&event_start_date); - interval_start_julian = g_date_julian (&interval_start_date); - - minutes = (interval_start_julian - event_start_julian) - * 24 * 60; - minutes += (interval_start->hour - event_start->hour) * 24; - minutes += interval_start->minute - event_start->minute; - minutes += recur_data->recur->interval - 1; - minutes -= minutes % recur_data->recur->interval; - cal_obj_time_add_minutes (cotime, minutes); - } - - if (event_end && cal_obj_time_compare (cotime, event_end, - CALOBJ_MINUTE) > 0) - return TRUE; - if (interval_end && cal_obj_time_compare (cotime, interval_end, - CALOBJ_MINUTE) > 0) - return TRUE; - - return FALSE; -} - - -static gboolean -cal_obj_minutely_find_next_position (CalObjTime *cotime, - CalObjTime *event_end, - RecurData *recur_data, - CalObjTime *interval_end) -{ - cal_obj_time_add_minutes (cotime, recur_data->recur->interval); - - if (event_end && cal_obj_time_compare (cotime, event_end, - CALOBJ_MINUTE) > 0) - return TRUE; - if (interval_end && cal_obj_time_compare (cotime, interval_end, - CALOBJ_MINUTE) > 0) - return TRUE; - - return FALSE; -} - - -static gboolean -cal_obj_secondly_find_start_position (CalObjTime *event_start, - CalObjTime *event_end, - RecurData *recur_data, - CalObjTime *interval_start, - CalObjTime *interval_end, - CalObjTime *cotime) -{ - GDate event_start_date, interval_start_date; - guint32 event_start_julian, interval_start_julian, seconds; - - if (interval_end && cal_obj_time_compare (event_start, interval_end, - CALOBJ_SECOND) > 0) - return TRUE; - if (event_end && cal_obj_time_compare (event_end, interval_start, - CALOBJ_SECOND) < 0) - return TRUE; - - *cotime = *event_start; - - if (cal_obj_time_compare (event_start, interval_start, - CALOBJ_SECOND) < 0) { - /* Convert the event start and interval start to GDates, so we - can easily find the number of days between them. */ - g_date_clear (&event_start_date, 1); - g_date_set_dmy (&event_start_date, event_start->day, - event_start->month + 1, event_start->year); - g_date_clear (&interval_start_date, 1); - g_date_set_dmy (&interval_start_date, interval_start->day, - interval_start->month + 1, - interval_start->year); - - event_start_julian = g_date_julian (&event_start_date); - interval_start_julian = g_date_julian (&interval_start_date); - - seconds = (interval_start_julian - event_start_julian) - * 24 * 60 * 60; - seconds += (interval_start->hour - event_start->hour) - * 24 * 60; - seconds += (interval_start->minute - event_start->minute) * 60; - seconds += interval_start->second - event_start->second; - seconds += recur_data->recur->interval - 1; - seconds -= seconds % recur_data->recur->interval; - cal_obj_time_add_seconds (cotime, seconds); - } - - if (event_end && cal_obj_time_compare (cotime, event_end, - CALOBJ_SECOND) >= 0) - return TRUE; - if (interval_end && cal_obj_time_compare (cotime, interval_end, - CALOBJ_SECOND) >= 0) - return TRUE; - - return FALSE; -} - - -static gboolean -cal_obj_secondly_find_next_position (CalObjTime *cotime, - CalObjTime *event_end, - RecurData *recur_data, - CalObjTime *interval_end) -{ - cal_obj_time_add_seconds (cotime, recur_data->recur->interval); - - if (event_end && cal_obj_time_compare (cotime, event_end, - CALOBJ_SECOND) >= 0) - return TRUE; - if (interval_end && cal_obj_time_compare (cotime, interval_end, - CALOBJ_SECOND) >= 0) - return TRUE; - - return FALSE; -} - - - - - -/* If the BYMONTH rule is specified it expands each occurrence in occs, by - using each of the months in the bymonth list. */ -static GArray* -cal_obj_bymonth_expand (RecurData *recur_data, - GArray *occs) -{ - GArray *new_occs; - CalObjTime *occ; - GList *elem; - gint len, i; - - /* If BYMONTH has not been specified, or the array is empty, just - return the array. */ - if (!recur_data->recur->bymonth || occs->len == 0) - return occs; - - new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime)); - - len = occs->len; - for (i = 0; i < len; i++) { - occ = &g_array_index (occs, CalObjTime, i); - - elem = recur_data->recur->bymonth; - while (elem) { - /* NOTE: The day may now be invalid, e.g. 31st Feb. */ - occ->month = GPOINTER_TO_INT (elem->data); - g_array_append_vals (new_occs, occ, 1); - elem = elem->next; - } - } - - g_array_free (occs, TRUE); - - return new_occs; -} - - -/* If the BYMONTH rule is specified it filters out all occurrences in occs - which do not match one of the months in the bymonth list. */ -static GArray* -cal_obj_bymonth_filter (RecurData *recur_data, - GArray *occs) -{ - GArray *new_occs; - CalObjTime *occ; - gint len, i; - - /* If BYMONTH has not been specified, or the array is empty, just - return the array. */ - if (!recur_data->recur->bymonth || occs->len == 0) - return occs; - - new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime)); - - len = occs->len; - for (i = 0; i < len; i++) { - occ = &g_array_index (occs, CalObjTime, i); - if (recur_data->months[occ->month]) - g_array_append_vals (new_occs, occ, 1); - } - - g_array_free (occs, TRUE); - - return new_occs; -} - - - -static GArray* -cal_obj_byweekno_expand (RecurData *recur_data, - GArray *occs) -{ - GArray *new_occs; - CalObjTime *occ, year_start_cotime, year_end_cotime, cotime; - GList *elem; - gint len, i, weekno; - - /* If BYWEEKNO has not been specified, or the array is empty, just - return the array. */ - if (!recur_data->recur->byweekno || occs->len == 0) - return occs; - - new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime)); - - len = occs->len; - for (i = 0; i < len; i++) { - occ = &g_array_index (occs, CalObjTime, i); - - /* Find the day that would correspond to week 1 (note that - week 1 is the first week starting from the specified week - start day that has 4 days in the new year). */ - year_start_cotime = *occ; - cal_obj_time_find_first_week (&year_start_cotime, - recur_data); - - /* Find the day that would correspond to week 1 of the next - year, which we use for -ve week numbers. */ - year_end_cotime = *occ; - year_end_cotime.year++; - cal_obj_time_find_first_week (&year_end_cotime, - recur_data); - - /* Now iterate over the week numbers in byweekno, generating a - new occurrence for each one. */ - elem = recur_data->recur->byweekno; - while (elem) { - weekno = GPOINTER_TO_INT (elem->data); - if (weekno > 0) { - cotime = year_start_cotime; - cal_obj_time_add_days (&cotime, - (weekno - 1) * 7); - } else { - cotime = year_end_cotime; - cal_obj_time_add_days (&cotime, weekno * 7); - } - - /* Skip occurrences if they fall outside the year. */ - if (cotime.year == occ->year) - g_array_append_val (new_occs, cotime); - elem = elem->next; - } - } - - g_array_free (occs, TRUE); - - return new_occs; -} - - -#if 0 -/* This isn't used at present. */ -static GArray* -cal_obj_byweekno_filter (RecurData *recur_data, - GArray *occs) -{ - - return occs; -} -#endif - - -static GArray* -cal_obj_byyearday_expand (RecurData *recur_data, - GArray *occs) -{ - GArray *new_occs; - CalObjTime *occ, year_start_cotime, year_end_cotime, cotime; - GList *elem; - gint len, i, dayno; - - /* If BYYEARDAY has not been specified, or the array is empty, just - return the array. */ - if (!recur_data->recur->byyearday || occs->len == 0) - return occs; - - new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime)); - - len = occs->len; - for (i = 0; i < len; i++) { - occ = &g_array_index (occs, CalObjTime, i); - - /* Find the day that would correspond to day 1. */ - year_start_cotime = *occ; - year_start_cotime.month = 0; - year_start_cotime.day = 1; - - /* Find the day that would correspond to day 1 of the next - year, which we use for -ve day numbers. */ - year_end_cotime = *occ; - year_end_cotime.year++; - year_end_cotime.month = 0; - year_end_cotime.day = 1; - - /* Now iterate over the day numbers in byyearday, generating a - new occurrence for each one. */ - elem = recur_data->recur->byyearday; - while (elem) { - dayno = GPOINTER_TO_INT (elem->data); - if (dayno > 0) { - cotime = year_start_cotime; - cal_obj_time_add_days (&cotime, dayno - 1); - } else { - cotime = year_end_cotime; - cal_obj_time_add_days (&cotime, dayno); - } - - /* Skip occurrences if they fall outside the year. */ - if (cotime.year == occ->year) - g_array_append_val (new_occs, cotime); - elem = elem->next; - } - } - - g_array_free (occs, TRUE); - - return new_occs; -} - - -/* Note: occs must not contain invalid dates, e.g. 31st September. */ -static GArray* -cal_obj_byyearday_filter (RecurData *recur_data, - GArray *occs) -{ - GArray *new_occs; - CalObjTime *occ; - gint yearday, len, i, days_in_year; - - /* If BYYEARDAY has not been specified, or the array is empty, just - return the array. */ - if (!recur_data->recur->byyearday || occs->len == 0) - return occs; - - new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime)); - - len = occs->len; - for (i = 0; i < len; i++) { - occ = &g_array_index (occs, CalObjTime, i); - yearday = cal_obj_time_day_of_year (occ); - if (recur_data->yeardays[yearday]) { - g_array_append_vals (new_occs, occ, 1); - } else { - days_in_year = g_date_is_leap_year (occ->year) - ? 366 : 365; - if (recur_data->neg_yeardays[days_in_year + 1 - - yearday]) - g_array_append_vals (new_occs, occ, 1); - } - } - - g_array_free (occs, TRUE); - - return new_occs; -} - - - -static GArray* -cal_obj_bymonthday_expand (RecurData *recur_data, - GArray *occs) -{ - GArray *new_occs; - CalObjTime *occ, month_start_cotime, month_end_cotime, cotime; - GList *elem; - gint len, i, dayno; - - /* If BYMONTHDAY has not been specified, or the array is empty, just - return the array. */ - if (!recur_data->recur->bymonthday || occs->len == 0) - return occs; - - new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime)); - - len = occs->len; - for (i = 0; i < len; i++) { - occ = &g_array_index (occs, CalObjTime, i); - - /* Find the day that would correspond to day 1. */ - month_start_cotime = *occ; - month_start_cotime.day = 1; - - /* Find the day that would correspond to day 1 of the next - month, which we use for -ve day numbers. */ - month_end_cotime = *occ; - month_end_cotime.month++; - month_end_cotime.day = 1; - - /* Now iterate over the day numbers in bymonthday, generating a - new occurrence for each one. */ - elem = recur_data->recur->bymonthday; - while (elem) { - dayno = GPOINTER_TO_INT (elem->data); - if (dayno > 0) { - cotime = month_start_cotime; - cal_obj_time_add_days (&cotime, dayno - 1); - } else { - cotime = month_end_cotime; - cal_obj_time_add_days (&cotime, dayno); - } - - /* Skip occurrences if they fall outside the month. */ - if (cotime.month == occ->month) - g_array_append_val (new_occs, cotime); - elem = elem->next; - } - } - - g_array_free (occs, TRUE); - - return new_occs; -} - - -static GArray* -cal_obj_bymonthday_filter (RecurData *recur_data, - GArray *occs) -{ - GArray *new_occs; - CalObjTime *occ; - gint len, i, days_in_month; - - /* If BYMONTHDAY has not been specified, or the array is empty, just - return the array. */ - if (!recur_data->recur->bymonthday || occs->len == 0) - return occs; - - new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime)); - - len = occs->len; - for (i = 0; i < len; i++) { - occ = &g_array_index (occs, CalObjTime, i); - if (recur_data->monthdays[occ->day]) { - g_array_append_vals (new_occs, occ, 1); - } else { - days_in_month = time_days_in_month (occ->year, - occ->month); - if (recur_data->neg_monthdays[days_in_month + 1 - - occ->day]) - g_array_append_vals (new_occs, occ, 1); - } - } - - g_array_free (occs, TRUE); - - return new_occs; -} - - - -static GArray* -cal_obj_byday_expand_yearly (RecurData *recur_data, - GArray *occs) -{ - GArray *new_occs; - CalObjTime *occ; - GList *elem; - gint len, i, weekday, week_num; - gint first_weekday, last_weekday, offset; - guint16 year; - - /* If BYDAY has not been specified, or the array is empty, just - return the array. */ - if (!recur_data->recur->byday || occs->len == 0) - return occs; - - new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime)); - - len = occs->len; - for (i = 0; i < len; i++) { - occ = &g_array_index (occs, CalObjTime, i); - - elem = recur_data->recur->byday; - while (elem) { - weekday = GPOINTER_TO_INT (elem->data); - elem = elem->next; - week_num = GPOINTER_TO_INT (elem->data); - elem = elem->next; - - year = occ->year; - if (week_num == 0) { - /* Expand to every Mon/Tue/etc. in the year. */ - occ->month = 0; - occ->day = 1; - first_weekday = cal_obj_time_weekday (occ); - offset = (weekday + 7 - first_weekday) % 7; - cal_obj_time_add_days (occ, offset); - - while (occ->year == year) { - g_array_append_vals (new_occs, occ, 1); - cal_obj_time_add_days (occ, 7); - } - - } else if (week_num > 0) { - /* Add the nth Mon/Tue/etc. in the year. */ - occ->month = 0; - occ->day = 1; - first_weekday = cal_obj_time_weekday (occ); - offset = (weekday + 7 - first_weekday) % 7; - offset += (week_num - 1) * 7; - cal_obj_time_add_days (occ, offset); - if (occ->year == year) - g_array_append_vals (new_occs, occ, 1); - - } else { - /* Add the -nth Mon/Tue/etc. in the year. */ - occ->month = 11; - occ->day = 31; - last_weekday = cal_obj_time_weekday (occ); - offset = (last_weekday + 7 - weekday) % 7; - offset += (week_num - 1) * 7; - cal_obj_time_add_days (occ, -offset); - if (occ->year == year) - g_array_append_vals (new_occs, occ, 1); - } - - /* Reset the year, as we may have gone past the end. */ - occ->year = year; - } - } - - g_array_free (occs, TRUE); - - return new_occs; -} - - -static GArray* -cal_obj_byday_expand_monthly (RecurData *recur_data, - GArray *occs) -{ - GArray *new_occs; - CalObjTime *occ; - GList *elem; - gint len, i, weekday, week_num; - gint first_weekday, last_weekday, offset; - guint16 year; - guint8 month; - - /* If BYDAY has not been specified, or the array is empty, just - return the array. */ - if (!recur_data->recur->byday || occs->len == 0) - return occs; - - new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime)); - - len = occs->len; - for (i = 0; i < len; i++) { - occ = &g_array_index (occs, CalObjTime, i); - - elem = recur_data->recur->byday; - while (elem) { - weekday = GPOINTER_TO_INT (elem->data); - elem = elem->next; - week_num = GPOINTER_TO_INT (elem->data); - elem = elem->next; - - year = occ->year; - month = occ->month; - if (week_num == 0) { - /* Expand to every Mon/Tue/etc. in the month.*/ - occ->day = 1; - first_weekday = cal_obj_time_weekday (occ); - offset = (weekday + 7 - first_weekday) % 7; - cal_obj_time_add_days (occ, offset); - - while (occ->year == year - && occ->month == month) { - g_array_append_vals (new_occs, occ, 1); - cal_obj_time_add_days (occ, 7); - } - - } else if (week_num > 0) { - /* Add the nth Mon/Tue/etc. in the month. */ - occ->day = 1; - first_weekday = cal_obj_time_weekday (occ); - offset = (weekday + 7 - first_weekday) % 7; - offset += (week_num - 1) * 7; - cal_obj_time_add_days (occ, offset); - if (occ->year == year && occ->month == month) - g_array_append_vals (new_occs, occ, 1); - - } else { - /* Add the -nth Mon/Tue/etc. in the month. */ - occ->day = time_days_in_month (occ->year, - occ->month); - last_weekday = cal_obj_time_weekday (occ); - offset = (last_weekday + 7 - weekday) % 7; - offset += (week_num - 1) * 7; - cal_obj_time_add_days (occ, -offset); - if (occ->year == year && occ->month == month) - g_array_append_vals (new_occs, occ, 1); - } - - /* Reset the year & month, as we may have gone past - the end. */ - occ->year = year; - occ->month = month; - } - } - - g_array_free (occs, TRUE); - - return new_occs; -} - - -/* Note: occs must not contain invalid dates, e.g. 31st September. */ -static GArray* -cal_obj_byday_expand_weekly (RecurData *recur_data, - GArray *occs) -{ - GArray *new_occs; - CalObjTime *occ; - GList *elem; - gint len, i, weekday, week_num; - gint weekday_offset, new_weekday_offset; - - /* If BYDAY has not been specified, or the array is empty, just - return the array. */ - if (!recur_data->recur->byday || occs->len == 0) - return occs; - - new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime)); - - len = occs->len; - for (i = 0; i < len; i++) { - occ = &g_array_index (occs, CalObjTime, i); - - elem = recur_data->recur->byday; - while (elem) { - weekday = GPOINTER_TO_INT (elem->data); - elem = elem->next; - - /* FIXME: Currently we just ignore this, but maybe we - should skip all elements where week_num != 0. - The spec isn't clear about this. */ - week_num = GPOINTER_TO_INT (elem->data); - elem = elem->next; - - weekday_offset = cal_obj_time_weekday_offset (occ, recur_data->recur); - new_weekday_offset = (weekday + 7 - recur_data->recur->week_start_day) % 7; - cal_obj_time_add_days (occ, new_weekday_offset - weekday_offset); - g_array_append_vals (new_occs, occ, 1); - } - } - - g_array_free (occs, TRUE); - - return new_occs; -} - - -/* Note: occs must not contain invalid dates, e.g. 31st September. */ -static GArray* -cal_obj_byday_filter (RecurData *recur_data, - GArray *occs) -{ - GArray *new_occs; - CalObjTime *occ; - gint len, i, weekday; - - /* If BYDAY has not been specified, or the array is empty, just - return the array. */ - if (!recur_data->recur->byday || occs->len == 0) - return occs; - - new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime)); - - len = occs->len; - for (i = 0; i < len; i++) { - occ = &g_array_index (occs, CalObjTime, i); - weekday = cal_obj_time_weekday (occ); - - /* See if the weekday on its own is set. */ - if (recur_data->weekdays[weekday]) - g_array_append_vals (new_occs, occ, 1); - } - - g_array_free (occs, TRUE); - - return new_occs; -} - - - -/* If the BYHOUR rule is specified it expands each occurrence in occs, by - using each of the hours in the byhour list. */ -static GArray* -cal_obj_byhour_expand (RecurData *recur_data, - GArray *occs) -{ - GArray *new_occs; - CalObjTime *occ; - GList *elem; - gint len, i; - - /* If BYHOUR has not been specified, or the array is empty, just - return the array. */ - if (!recur_data->recur->byhour || occs->len == 0) - return occs; - - new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime)); - - len = occs->len; - for (i = 0; i < len; i++) { - occ = &g_array_index (occs, CalObjTime, i); - - elem = recur_data->recur->byhour; - while (elem) { - occ->hour = GPOINTER_TO_INT (elem->data); - g_array_append_vals (new_occs, occ, 1); - elem = elem->next; - } - } - - g_array_free (occs, TRUE); - - return new_occs; -} - - -/* If the BYHOUR rule is specified it filters out all occurrences in occs - which do not match one of the hours in the byhour list. */ -static GArray* -cal_obj_byhour_filter (RecurData *recur_data, - GArray *occs) -{ - GArray *new_occs; - CalObjTime *occ; - gint len, i; - - /* If BYHOUR has not been specified, or the array is empty, just - return the array. */ - if (!recur_data->recur->byhour || occs->len == 0) - return occs; - - new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime)); - - len = occs->len; - for (i = 0; i < len; i++) { - occ = &g_array_index (occs, CalObjTime, i); - if (recur_data->hours[occ->hour]) - g_array_append_vals (new_occs, occ, 1); - } - - g_array_free (occs, TRUE); - - return new_occs; -} - - - -/* If the BYMINUTE rule is specified it expands each occurrence in occs, by - using each of the minutes in the byminute list. */ -static GArray* -cal_obj_byminute_expand (RecurData *recur_data, - GArray *occs) -{ - GArray *new_occs; - CalObjTime *occ; - GList *elem; - gint len, i; - - /* If BYMINUTE has not been specified, or the array is empty, just - return the array. */ - if (!recur_data->recur->byminute || occs->len == 0) - return occs; - - new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime)); - - len = occs->len; - for (i = 0; i < len; i++) { - occ = &g_array_index (occs, CalObjTime, i); - - elem = recur_data->recur->byminute; - while (elem) { - occ->minute = GPOINTER_TO_INT (elem->data); - g_array_append_vals (new_occs, occ, 1); - elem = elem->next; - } - } - - g_array_free (occs, TRUE); - - return new_occs; -} - - -/* If the BYMINUTE rule is specified it filters out all occurrences in occs - which do not match one of the minutes in the byminute list. */ -static GArray* -cal_obj_byminute_filter (RecurData *recur_data, - GArray *occs) -{ - GArray *new_occs; - CalObjTime *occ; - gint len, i; - - /* If BYMINUTE has not been specified, or the array is empty, just - return the array. */ - if (!recur_data->recur->byminute || occs->len == 0) - return occs; - - new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime)); - - len = occs->len; - for (i = 0; i < len; i++) { - occ = &g_array_index (occs, CalObjTime, i); - if (recur_data->minutes[occ->minute]) - g_array_append_vals (new_occs, occ, 1); - } - - g_array_free (occs, TRUE); - - return new_occs; -} - - - -/* If the BYSECOND rule is specified it expands each occurrence in occs, by - using each of the seconds in the bysecond list. */ -static GArray* -cal_obj_bysecond_expand (RecurData *recur_data, - GArray *occs) -{ - GArray *new_occs; - CalObjTime *occ; - GList *elem; - gint len, i; - - /* If BYSECOND has not been specified, or the array is empty, just - return the array. */ - if (!recur_data->recur->bysecond || occs->len == 0) - return occs; - - new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime)); - - len = occs->len; - for (i = 0; i < len; i++) { - occ = &g_array_index (occs, CalObjTime, i); - - elem = recur_data->recur->bysecond; - while (elem) { - occ->second = GPOINTER_TO_INT (elem->data); - g_array_append_vals (new_occs, occ, 1); - elem = elem->next; - } - } - - g_array_free (occs, TRUE); - - return new_occs; -} - - -/* If the BYSECOND rule is specified it filters out all occurrences in occs - which do not match one of the seconds in the bysecond list. */ -static GArray* -cal_obj_bysecond_filter (RecurData *recur_data, - GArray *occs) -{ - GArray *new_occs; - CalObjTime *occ; - gint len, i; - - /* If BYSECOND has not been specified, or the array is empty, just - return the array. */ - if (!recur_data->recur->bysecond || occs->len == 0) - return occs; - - new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime)); - - len = occs->len; - for (i = 0; i < len; i++) { - occ = &g_array_index (occs, CalObjTime, i); - if (recur_data->seconds[occ->second]) - g_array_append_vals (new_occs, occ, 1); - } - - g_array_free (occs, TRUE); - - return new_occs; -} - - - - - -/* Adds a positive or negative number of months to the given CalObjTime, - updating the year appropriately so we end up with a valid month. - Note that the day may be invalid, e.g. 30th Feb. */ -static void -cal_obj_time_add_months (CalObjTime *cotime, - gint months) -{ - guint month, years; - - /* We use a guint to avoid overflow on the guint8. */ - month = cotime->month + months; - cotime->month = month % 12; - if (month > 0) { - cotime->year += month / 12; - } else { - years = month / 12; - if (cotime->month != 0) { - cotime->month += 12; - years -= 1; - } - cotime->year += years; - } -} - - -/* Adds a positive or negative number of days to the given CalObjTime, - updating the month and year appropriately so we end up with a valid day. */ -static void -cal_obj_time_add_days (CalObjTime *cotime, - gint days) -{ - gint day, days_in_month; - - /* We use a guint to avoid overflow on the guint8. */ - day = cotime->day; - day += days; - - if (days >= 0) { - for (;;) { - days_in_month = time_days_in_month (cotime->year, - cotime->month); - if (day <= days_in_month) - break; - - cotime->month++; - if (cotime->month >= 12) { - cotime->year++; - cotime->month = 0; - } - - day -= days_in_month; - } - - cotime->day = (guint8) day; - } else { - while (day <= 0) { - if (cotime->month == 0) { - cotime->year--; - cotime->month = 11; - } else { - cotime->month--; - } - - days_in_month = time_days_in_month (cotime->year, - cotime->month); - day += days_in_month; - } - - cotime->day = (guint8) day; - } -} - - -/* Adds a positive or negative number of hours to the given CalObjTime, - updating the day, month & year appropriately so we end up with a valid - time. */ -static void -cal_obj_time_add_hours (CalObjTime *cotime, - gint hours) -{ - gint hour, days; - - /* We use a gint to avoid overflow on the guint8. */ - hour = cotime->hour + hours; - cotime->hour = hour % 24; - if (hour >= 0) { - if (hour >= 24) - cal_obj_time_add_days (cotime, hour / 24); - } else { - days = hour / 24; - if (cotime->hour != 0) { - cotime->hour += 24; - days -= 1; - } - cal_obj_time_add_days (cotime, days); - } -} - - -/* Adds a positive or negative number of minutes to the given CalObjTime, - updating the rest of the CalObjTime appropriately. */ -static void -cal_obj_time_add_minutes (CalObjTime *cotime, - gint minutes) -{ - gint minute, hours; - - /* We use a gint to avoid overflow on the guint8. */ - minute = cotime->minute + minutes; - cotime->minute = minute % 60; - if (minute >= 0) { - if (minute >= 60) - cal_obj_time_add_hours (cotime, minute / 60); - } else { - hours = minute / 60; - if (cotime->minute != 0) { - cotime->minute += 60; - hours -= 1; - } - cal_obj_time_add_hours (cotime, hours); - } -} - - -/* Adds a positive or negative number of seconds to the given CalObjTime, - updating the rest of the CalObjTime appropriately. */ -static void -cal_obj_time_add_seconds (CalObjTime *cotime, - gint seconds) -{ - gint second, minutes; - - /* We use a gint to avoid overflow on the guint8. */ - second = cotime->second + seconds; - cotime->second = second % 60; - if (second >= 0) { - if (second >= 60) - cal_obj_time_add_minutes (cotime, second / 60); - } else { - minutes = second / 60; - if (cotime->second != 0) { - cotime->second += 60; - minutes -= 1; - } - cal_obj_time_add_minutes (cotime, minutes); - } -} - - -/* Compares 2 CalObjTimes. Returns -1 if the cotime1 is before cotime2, 0 if - they are the same, or 1 if cotime1 is after cotime2. The comparison type - specifies which parts of the times we are interested in, e.g. if CALOBJ_DAY - is used we only want to know if the days are different. */ -static gint -cal_obj_time_compare (CalObjTime *cotime1, - CalObjTime *cotime2, - CalObjTimeComparison type) -{ - if (cotime1->year < cotime2->year) - return -1; - if (cotime1->year > cotime2->year) - return 1; - - if (type == CALOBJ_YEAR) - return 0; - - if (cotime1->month < cotime2->month) - return -1; - if (cotime1->month > cotime2->month) - return 1; - - if (type == CALOBJ_MONTH) - return 0; - - if (cotime1->day < cotime2->day) - return -1; - if (cotime1->day > cotime2->day) - return 1; - - if (type == CALOBJ_DAY) - return 0; - - if (cotime1->hour < cotime2->hour) - return -1; - if (cotime1->hour > cotime2->hour) - return 1; - - if (type == CALOBJ_HOUR) - return 0; - - if (cotime1->minute < cotime2->minute) - return -1; - if (cotime1->minute > cotime2->minute) - return 1; - - if (type == CALOBJ_MINUTE) - return 0; - - if (cotime1->second < cotime2->second) - return -1; - if (cotime1->second > cotime2->second) - return 1; - - return 0; -} - - -/* This is the same as the above function, but without the comparison type. - It is used for qsort(). */ -static gint -cal_obj_time_compare_func (const void *arg1, - const void *arg2) -{ - CalObjTime *cotime1, *cotime2; - gint retval; - - cotime1 = (CalObjTime*) arg1; - cotime2 = (CalObjTime*) arg2; - - if (cotime1->year < cotime2->year) - retval = -1; - else if (cotime1->year > cotime2->year) - retval = 1; - - else if (cotime1->month < cotime2->month) - retval = -1; - else if (cotime1->month > cotime2->month) - retval = 1; - - else if (cotime1->day < cotime2->day) - retval = -1; - else if (cotime1->day > cotime2->day) - retval = 1; - - else if (cotime1->hour < cotime2->hour) - retval = -1; - else if (cotime1->hour > cotime2->hour) - retval = 1; - - else if (cotime1->minute < cotime2->minute) - retval = -1; - else if (cotime1->minute > cotime2->minute) - retval = 1; - - else if (cotime1->second < cotime2->second) - retval = -1; - else if (cotime1->second > cotime2->second) - retval = 1; - - else - retval = 0; - -#if 0 - g_print ("%s - ", cal_obj_time_to_string (cotime1)); - g_print ("%s : %i\n", cal_obj_time_to_string (cotime2), retval); -#endif - - return retval; -} - -#if 0 -static gint -cal_obj_date_only_compare_func (const void *arg1, - const void *arg2) -{ - CalObjTime *cotime1, *cotime2; - - cotime1 = (CalObjTime*) arg1; - cotime2 = (CalObjTime*) arg2; - - if (cotime1->year < cotime2->year) - return -1; - if (cotime1->year > cotime2->year) - return 1; - - if (cotime1->month < cotime2->month) - return -1; - if (cotime1->month > cotime2->month) - return 1; - - if (cotime1->day < cotime2->day) - return -1; - if (cotime1->day > cotime2->day) - return 1; - - return 0; -} -#endif - -/* Returns the weekday of the given CalObjTime, from 0 (Mon) - 6 (Sun). */ -static gint -cal_obj_time_weekday (CalObjTime *cotime) -{ - GDate date; - gint weekday; - - g_date_clear (&date, 1); - g_date_set_dmy (&date, cotime->day, cotime->month + 1, cotime->year); - - /* This results in a value of 0 (Monday) - 6 (Sunday). */ - weekday = g_date_weekday (&date) - 1; - - return weekday; -} - - -/* Returns the weekday of the given CalObjTime, from 0 - 6. The week start - day is Monday by default, but can be set in the recurrence rule. */ -static gint -cal_obj_time_weekday_offset (CalObjTime *cotime, - CalRecurrence *recur) -{ - GDate date; - gint weekday, offset; - - g_date_clear (&date, 1); - g_date_set_dmy (&date, cotime->day, cotime->month + 1, cotime->year); - - /* This results in a value of 0 (Monday) - 6 (Sunday). */ - weekday = g_date_weekday (&date) - 1; - - /* This calculates the offset of our day from the start of the week. - We just add on a week (to avoid any possible negative values) and - then subtract the specified week start day, then convert it into a - value from 0-6. */ - offset = (weekday + 7 - recur->week_start_day) % 7; - - return offset; -} - - -/* Returns the day of the year of the given CalObjTime, from 1 - 366. */ -static gint -cal_obj_time_day_of_year (CalObjTime *cotime) -{ - GDate date; - - g_date_clear (&date, 1); - g_date_set_dmy (&date, cotime->day, cotime->month + 1, cotime->year); - - return g_date_day_of_year (&date); -} - - -/* Finds the first week in the given CalObjTime's year, using the same weekday - as the event start day (i.e. from the RecurData). - The first week of the year is the first week starting from the specified - week start day that has 4 days in the new year. It may be in the previous - year. */ -static void -cal_obj_time_find_first_week (CalObjTime *cotime, - RecurData *recur_data) -{ - GDate date; - gint weekday, week_start_day, first_full_week_start_offset, offset; - - /* Find out the weekday of the 1st of the year, 0 (Mon) - 6 (Sun). */ - g_date_clear (&date, 1); - g_date_set_dmy (&date, 1, 1, cotime->year); - weekday = g_date_weekday (&date) - 1; - - /* Calculate the first day of the year that starts a new week, i.e. the - first week_start_day after weekday, using 0 = 1st Jan. - e.g. if the 1st Jan is a Tuesday (1) and week_start_day is a - Monday (0), the result will be (0 + 7 - 1) % 7 = 6 (7th Jan). */ - week_start_day = recur_data->recur->week_start_day; - first_full_week_start_offset = (week_start_day + 7 - weekday) % 7; - - /* Now see if we have to move backwards 1 week, i.e. if the week - starts on or after Jan 5th (since the previous week has 4 days in - this year and so will be the first week of the year). */ - if (first_full_week_start_offset >= 4) - first_full_week_start_offset -= 7; - - /* Now add the days to get to the event's weekday. */ - offset = first_full_week_start_offset + recur_data->weekday_offset; - - /* Now move the cotime to the appropriate day. */ - cotime->month = 0; - cotime->day = 1; - cal_obj_time_add_days (cotime, offset); -} - - -static void -cal_object_time_from_time (CalObjTime *cotime, - time_t t) -{ - struct tm *tmp_tm; - time_t tmp_time_t; - - tmp_time_t = t; - tmp_tm = localtime (&tmp_time_t); - - cotime->year = tmp_tm->tm_year + 1900; - cotime->month = tmp_tm->tm_mon; - cotime->day = tmp_tm->tm_mday; - cotime->hour = tmp_tm->tm_hour; - cotime->minute = tmp_tm->tm_min; - cotime->second = tmp_tm->tm_sec; - cotime->is_rdate = FALSE; -} - - -/* Debugging function to convert a CalObjTime to a string. It uses a static - buffer so beware. */ -#ifdef CAL_OBJ_DEBUG -static char* -cal_obj_time_to_string (CalObjTime *cotime) -{ - static char buffer[20]; - char *weekdays[] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", - " " }; - gint weekday; - - weekday = cal_obj_time_weekday (cotime); - - sprintf (buffer, "%s %02i/%02i/%04i %02i:%02i:%02i", - weekdays[weekday], - cotime->day, cotime->month + 1, cotime->year, - cotime->hour, cotime->minute, cotime->second); - return buffer; -} -#endif - - -/* This recalculates the end dates for recurrence & exception rules which use - the COUNT property. If refresh is TRUE it will recalculate all enddates - for rules which use COUNT. If refresh is FALSE, it will only calculate - the enddate if it hasn't already been set. It returns TRUE if the component - was changed, i.e. if the component should be saved at some point. - We store the enddate in the "X-EVOLUTION-ENDDATE" parameter of the RRULE - or EXRULE. */ -static gboolean -cal_recur_ensure_end_dates (CalComponent *comp, - gboolean refresh) -{ - GSList *rrules, *exrules, *elem; - gboolean changed = FALSE; - - /* Do the RRULEs. */ - cal_component_get_rrule_property_list (comp, &rrules); - for (elem = rrules; elem; elem = elem->next) { - changed |= cal_recur_ensure_rule_end_date (comp, elem->data, - FALSE, refresh); - } - - /* Do the EXRULEs. */ - cal_component_get_exrule_property_list (comp, &exrules); - for (elem = exrules; elem; elem = elem->next) { - changed |= cal_recur_ensure_rule_end_date (comp, elem->data, - TRUE, refresh); - } - - return changed; -} - - -typedef struct _CalRecurEnsureEndDateData CalRecurEnsureEndDateData; -struct _CalRecurEnsureEndDateData { - gint count; - gint instances; - time_t end_date; -}; - - -static gboolean -cal_recur_ensure_rule_end_date (CalComponent *comp, - icalproperty *prop, - gboolean exception, - gboolean refresh) -{ - struct icalrecurrencetype rule; - CalRecurEnsureEndDateData cb_data; - - if (exception) - rule = icalproperty_get_exrule (prop); - else - rule = icalproperty_get_rrule (prop); - - /* If the rule doesn't use COUNT just return. */ - if (rule.count == 0) - return FALSE; - - /* If refresh is FALSE, we check if the enddate is already set, and - if it is we just return. */ - if (!refresh) { - if (cal_recur_get_rule_end_date (prop) != -1) - return FALSE; - } - - /* Calculate the end date. */ - cb_data.count = rule.count; - cb_data.instances = 0; - cal_recur_generate_instances_of_rule (comp, prop, -1, -1, - cal_recur_ensure_rule_end_date_cb, - &cb_data); - - /* Store the end date in the "X-EVOLUTION-ENDDATE" parameter of the - rule. */ - cal_recur_set_rule_end_date (prop, cb_data.end_date); - - return TRUE; -} - - -static gboolean -cal_recur_ensure_rule_end_date_cb (CalComponent *comp, - time_t instance_start, - time_t instance_end, - gpointer data) -{ - CalRecurEnsureEndDateData *cb_data; - - cb_data = (CalRecurEnsureEndDateData*) data; - - cb_data->instances++; - - if (cb_data->instances == cb_data->count) { - cb_data->end_date = instance_start; - return FALSE; - } - - return TRUE; -} - - -static time_t -cal_recur_get_rule_end_date (icalproperty *prop) -{ - icalparameter *param; - const char *xname, *xvalue; - icalvalue *value; - struct icaltimetype icaltime; - - param = icalproperty_get_first_parameter (prop, ICAL_X_PARAMETER); - while (param) { - xname = icalparameter_get_xname (param); - if (xname && !strcmp (xname, EVOLUTION_END_DATE_PARAMETER)) { - xvalue = icalparameter_get_x (param); - value = icalvalue_new_from_string (ICAL_DATETIME_VALUE, - xvalue); - if (value) { - icaltime = icalvalue_get_datetime (value); - icalvalue_free (value); - - return icaltime_as_timet (icaltime); - } - } - - param = icalproperty_get_next_parameter (prop, - ICAL_X_PARAMETER); - } - - return -1; -} - - -static void -cal_recur_set_rule_end_date (icalproperty *prop, - time_t end_date) -{ - icalparameter *param; - icalvalue *value; - struct icaltimetype icaltime; - const char *end_date_string, *xname; - - icaltime = icaltime_from_timet (end_date, FALSE); - value = icalvalue_new_datetime (icaltime); - end_date_string = icalvalue_as_ical_string (value); - icalvalue_free (value); - - /* If we already have an X-EVOLUTION-ENDDATE parameter, set the value - to the new date-time. */ - param = icalproperty_get_first_parameter (prop, ICAL_X_PARAMETER); - while (param) { - xname = icalparameter_get_xname (param); - if (xname && !strcmp (xname, EVOLUTION_END_DATE_PARAMETER)) { - icalparameter_set_x (param, end_date_string); - return; - } - param = icalproperty_get_next_parameter (prop, ICAL_X_PARAMETER); - } - - /* Create a new X-EVOLUTION-ENDDATE and add it to the property. */ - param = icalparameter_new_x (end_date_string); - icalparameter_set_xname (param, EVOLUTION_END_DATE_PARAMETER); - icalproperty_add_parameter (prop, param); -} - diff --git a/calendar/cal-util/cal-recur.h b/calendar/cal-util/cal-recur.h deleted file mode 100644 index de5a139f78..0000000000 --- a/calendar/cal-util/cal-recur.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Evolution calendar recurrence rule functions - * - * Copyright (C) 2000 Helix Code, Inc. - * - * Author: Damon Chaplin <damon@helixcode.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef CAL_RECUR_H -#define CAL_RECUR_H - -#include <libgnome/gnome-defs.h> -#include <glib.h> -#include <cal-util/cal-component.h> - -BEGIN_GNOME_DECLS - -typedef gboolean (* CalRecurInstanceFn) (CalComponent *comp, - time_t instance_start, - time_t instance_end, - gpointer data); - -/* - * Calls the given callback function for each occurrence of the event that - * intersects the range between the given start and end times (the end time is - * not included). Note that the occurrences may start before the given start - * time. - * - * If the callback routine returns FALSE the occurrence generation stops. - * - * Both start and end can be -1, in which case we start at the events first - * instance and continue until it ends, or forever if it has no enddate. - */ -void cal_recur_generate_instances (CalComponent *comp, - time_t start, - time_t end, - CalRecurInstanceFn cb, - gpointer cb_data); - -END_GNOME_DECLS - -#endif diff --git a/calendar/cal-util/cal-util.c b/calendar/cal-util/cal-util.c deleted file mode 100644 index 67da788b0f..0000000000 --- a/calendar/cal-util/cal-util.c +++ /dev/null @@ -1,75 +0,0 @@ -/* Evolution calendar utilities and types - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#include <config.h> -#include <stdlib.h> -#include "cal-util.h" - - - -/** - * cal_obj_instance_list_free: - * @list: List of #CalObjInstance structures. - * - * Frees a list of #CalObjInstance structures. - **/ -void -cal_obj_instance_list_free (GList *list) -{ - CalObjInstance *i; - GList *l; - - for (l = list; l; l = l->next) { - i = l->data; - - g_assert (i != NULL); - g_assert (i->uid != NULL); - - g_free (i->uid); - g_free (i); - } - - g_list_free (list); -} - -/** - * cal_obj_uid_list_free: - * @list: List of strings with unique identifiers. - * - * Frees a list of unique identifiers for calendar objects. - **/ -void -cal_obj_uid_list_free (GList *list) -{ - GList *l; - - for (l = list; l; l = l->next) { - char *uid; - - uid = l->data; - - g_assert (uid != NULL); - g_free (uid); - } - - g_list_free (list); -} diff --git a/calendar/cal-util/cal-util.h b/calendar/cal-util/cal-util.h deleted file mode 100644 index a0a111258d..0000000000 --- a/calendar/cal-util/cal-util.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Evolution calendar utilities and types - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef CAL_UTIL_H -#define CAL_UTIL_H - -#include <libgnome/gnome-defs.h> -#include <time.h> -#include <glib.h> - -BEGIN_GNOME_DECLS - - - -/* Instance of a calendar object. This can be an actual occurrence, a - * recurrence, or an alarm trigger of a `real' calendar object. - */ -typedef struct { - char *uid; /* UID of the object */ - time_t start; /* Start time of instance */ - time_t end; /* End time of instance */ -} CalObjInstance; - -void cal_obj_instance_list_free (GList *list); - -/* Used for multiple UID queries */ -typedef enum { - CALOBJ_TYPE_EVENT = 1 << 0, - CALOBJ_TYPE_TODO = 1 << 1, - CALOBJ_TYPE_JOURNAL = 1 << 2, - CALOBJ_TYPE_ANY = 0x07 -} CalObjType; - -void cal_obj_uid_list_free (GList *list); - -END_GNOME_DECLS - -#endif - diff --git a/calendar/cal-util/calobj.c b/calendar/cal-util/calobj.c deleted file mode 100644 index bcb1b9bb88..0000000000 --- a/calendar/cal-util/calobj.c +++ /dev/null @@ -1,2008 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Calendar objects implementations. - * Copyright (C) 1998 the Free Software Foundation - * - * Authors: - * Miguel de Icaza (miguel@gnu.org) - * Federico Mena (quartic@gimp.org) - */ -#include <config.h> -#include <string.h> -#include <glib.h> -#include <ctype.h> -#include <unistd.h> -#include <time.h> -#include "calobj.h" -#include "timeutil.h" -#include "libversit/vcc.h" -#include "icalendar-save.h" -#include "icalendar.h" - - - -/* VCalendar product ID */ -#define PRODID "-//Helix Code//NONSGML Evolution Calendar//EN" - -static gint compare_exdates (gconstpointer a, gconstpointer b); -static void ical_object_normalize_summary (iCalObject *ico); -static void list_free (GList *list); - - - -char * -ical_gen_uid (void) -{ - static char *hostname; - time_t t = time (NULL); - static int serial; - - if (!hostname){ - char buffer [128]; - - if ((gethostname (buffer, sizeof (buffer)-1) == 0) && - (buffer [0] != 0)) - hostname = g_strdup (buffer); - else - hostname = g_strdup ("localhost"); - } - - return g_strdup_printf ( - "%s-%d-%d-%d-%d@%s", - isodate_from_time_t (t), - getpid (), - getgid (), - getppid (), - serial++, - hostname); -} - -iCalObject * -ical_object_new (void) -{ - iCalObject *ico; - - ico = g_new0 (iCalObject, 1); - - ico->seq = -1; - ico->dtstamp = time (NULL); - ico->uid = ical_gen_uid (); - - ico->pilot_id = 0; - ico->pilot_status = ICAL_PILOT_SYNC_MOD; - - ico->ref_count = 1; - - return ico; -} - -iCalObject * -ical_new (char *comment, char *organizer, char *summary) -{ - iCalObject *ico; - - ico = ical_object_new (); - - ico->comment = g_strdup (comment); - ico->organizer = g_new0 (iCalPerson, 1); - ico->organizer->addr = g_strdup (organizer); - ico->summary = g_strdup (summary); - ico->class = g_strdup ("PUBLIC"); - ico->status = g_strdup ("NEEDS ACTION"); - - ico->dalarm.type = ALARM_DISPLAY; - ico->palarm.type = ALARM_PROGRAM; - ico->malarm.type = ALARM_MAIL; - ico->aalarm.type = ALARM_AUDIO; - - ical_object_normalize_summary (ico); - - return ico; -} - - -void -ical_object_ref (iCalObject *ico) -{ - ico->ref_count++; -} - - -#define free_if_defined(x) if (x){ g_free (x); x = 0; } -#define lfree_if_defined(x) if (x){ list_free (x); x = 0; } -static void -ical_object_destroy (iCalObject *ico) -{ - /* Regular strings */ - free_if_defined (ico->comment); - free_if_defined (ico->organizer); - free_if_defined (ico->summary); - free_if_defined (ico->uid); - free_if_defined (ico->status); - free_if_defined (ico->class); - free_if_defined (ico->url); - free_if_defined (ico->recur); - - /* Lists */ - lfree_if_defined (ico->exdate); - lfree_if_defined (ico->categories); - lfree_if_defined (ico->resources); - lfree_if_defined (ico->related); - lfree_if_defined (ico->attach); - - /* Alarms */ - g_free (ico->dalarm.data); - g_free (ico->palarm.data); - g_free (ico->malarm.data); - g_free (ico->aalarm.data); - - g_free (ico); -} - -void -ical_object_unref (iCalObject *ico) -{ - ico->ref_count--; - if (ico->ref_count == 0) - ical_object_destroy (ico); -} - - -static void -my_free (gpointer data, gpointer user_dat_ignored) -{ - g_free (data); -} - -static void -list_free (GList *list) -{ - g_list_foreach (list, my_free, 0); - g_list_free (list); -} - -/* This resets any recurrence rules of the iCalObject. */ -void -ical_object_reset_recurrence (iCalObject *ico) -{ - free_if_defined (ico->recur); - lfree_if_defined (ico->exdate); -} - -static GList * -set_list (char *str) -{ - GList *list = 0; - char *s; - - for (s = strtok (str, ";"); s; s = strtok (NULL, ";")) - list = g_list_prepend (list, g_strdup (s)); - - return list; -} - -static GList * -set_date_list (char *str) -{ - GList *list = 0; - char *s; - - for (s = strtok (str, ";,"); s; s = strtok (NULL, ";,")){ - time_t *t = g_new (time_t, 1); - - while (*s && isspace (*s)) - s++; - *t = time_from_isodate (s); - list = g_list_prepend (list, t); - } - return list; -} - -void -ical_object_add_exdate (iCalObject *o, time_t t) -{ - time_t *pt = g_new (time_t, 1); - - *pt = t; - o->exdate = g_list_prepend (o->exdate, pt); -} - -static void -ignore_space(char **str) -{ - while (**str && isspace (**str)) - (*str)++; -} - -static void -skip_numbers (char **str) -{ - while (**str){ - ignore_space (str); - if (!isdigit (**str)) - return; - while (**str && isdigit (**str)) - (*str)++; - } -} - -static void -weekdaylist (iCalObject *o, char **str) -{ - int i; - struct { - char first_letter, second_letter; - int index; - } days [] = { - { 'S', 'U', 0 }, - { 'M', 'O', 1 }, - { 'T', 'U', 2 }, - { 'W', 'E', 3 }, - { 'T', 'H', 4 }, - { 'F', 'R', 5 }, - { 'S', 'A', 6 } - }; - - ignore_space (str); - do { - for (i = 0; i < 7; i++){ - if (**str == days [i].first_letter && *(*str+1) == days [i].second_letter){ - o->recur->weekday |= 1 << i; - *str += 2; - if (**str == ' ') - (*str)++; - } - } - } while (isalpha ((unsigned char) **str)); - - if (o->recur->weekday == 0){ - struct tm tm = *localtime (&o->dtstart); - - o->recur->weekday = 1 << tm.tm_wday; - } -} - -static void -weekdaynum (iCalObject *o, char **str) -{ - int i; - struct { - char first_letter, second_letter; - int index; - } days [] = { - { 'S', 'U', 0 }, - { 'M', 'O', 1 }, - { 'T', 'U', 2 }, - { 'W', 'E', 3 }, - { 'T', 'H', 4 }, - { 'F', 'R', 5 }, - { 'S', 'A', 6 } - }; - - ignore_space (str); - do { - for (i = 0; i < 7; i++){ - if (**str == days [i].first_letter && *(*str+1) == days [i].second_letter){ - o->recur->weekday = i; - *str += 2; - if (**str == ' ') - (*str)++; - } - } - } while (isalpha ((unsigned char) **str)); -} - -static void -ocurrencelist (iCalObject *o, char **str) -{ - char *p; - - ignore_space (str); - p = *str; - if (!isdigit (*p)) - return; - - if (!(*p >= '1' && *p <= '5')) - return; - - if (!(*(p+1) == '+' || *(p+1) == '-')) - return; - - o->recur->u.month_pos = (*p-'0') * (*(p+1) == '+' ? 1 : -1); - *str += 2; -} - -#if 0 - -static void -daynumber (iCalObject *o, char **str) -{ - int val = 0; - char *p = *str; - - ignore_space (str); - if (strcmp (p, "LD")){ - o->recur->u.month_day = DAY_LASTDAY; - *str += 2; - return; - } - - if (!(isdigit (*p))) - return; - - while (**str && isdigit (**str)){ - val = val * 10 + (**str - '0'); - (*str)++; - } - - if (**str == '+') - (*str)++; - - if (**str == '-') - val *= -1; - o->recur->u.month_day = val; -} - -#endif - -static void -daynumberlist (iCalObject *o, char **str) -{ - int first = 0; - int val = 0; - - ignore_space (str); - - while (**str){ - if (!isdigit (**str)) - return; - while (**str && isdigit (**str)){ - val = 10 * val + (**str - '0'); - (*str)++; - } - if (!first){ - /* - * Some broken applications set this to zero - */ - if (val == 0){ - struct tm day = *localtime (&o->dtstart); - - val = day.tm_mday; - } - o->recur->u.month_day = val; - first = 1; - val = 0; - } - } -} - -static void -load_recur_weekly (iCalObject *o, char **str) -{ - weekdaylist (o, str); -} - -static void -load_recur_monthly_pos (iCalObject *o, char **str) -{ - ocurrencelist (o, str); - weekdaynum (o, str); -} - -static void -load_recur_monthly_day (iCalObject *o, char **str) -{ - daynumberlist (o, str); -} - -static void -load_recur_yearly_month (iCalObject *o, char **str) -{ - /* Skip as we do not support multiple months and we do expect - * the dtstart to agree with the value on this field - */ - skip_numbers (str); -} - -static void -load_recur_yearly_day (iCalObject *o, char **str) -{ - /* Skip as we do not support multiple days and we do expect - * the dtstart to agree with the value on this field - * - * FIXME: we should support every-n-years - */ - skip_numbers (str); -} - -static void -duration (iCalObject *o, char **str) -{ - unsigned int duration = 0; - - ignore_space (str); - if (**str != '#') - return; - (*str)++; - while (**str && isdigit (**str)){ - duration = duration * 10 + (**str - '0'); - (*str)++; - } - o->recur->duration = duration; -} - -static void -enddate (iCalObject *o, char **str) -{ - ignore_space (str); - if (isdigit (**str)){ - o->recur->_enddate = time_from_isodate (*str); - *str += 16; - } -} - -static int -load_recurrence (iCalObject *o, char *str) -{ - enum RecurType type; - int interval = 0; - - type = -1; - switch (*str++){ - case 'D': - type = RECUR_DAILY; - break; - - case 'W': - type = RECUR_WEEKLY; - break; - - case 'M': - if (*str == 'P') - type = RECUR_MONTHLY_BY_POS; - else if (*str == 'D') - type = RECUR_MONTHLY_BY_DAY; - str++; - break; - - case 'Y': - if (*str == 'M') - type = RECUR_YEARLY_BY_MONTH; - else if (*str == 'D') - type = RECUR_YEARLY_BY_DAY; - str++; - break; - } - if (type == -1) - return 0; - - o->recur = g_new0 (Recurrence, 1); - o->recur->type = type; - ignore_space (&str); - - /* Get the interval */ - for (;*str && isdigit (*str);str++) - interval = interval * 10 + (*str-'0'); - - if (interval == 0) - interval = 1; - - o->recur->interval = interval; - - /* this is the default per the spec */ - o->recur->duration = 2; - - ignore_space (&str); - - switch (type){ - case RECUR_DAILY: - break; - case RECUR_WEEKLY: - load_recur_weekly (o, &str); - break; - case RECUR_MONTHLY_BY_POS: - load_recur_monthly_pos (o, &str); - break; - case RECUR_MONTHLY_BY_DAY: - load_recur_monthly_day (o, &str); - break; - case RECUR_YEARLY_BY_MONTH: - load_recur_yearly_month (o, &str); - break; - case RECUR_YEARLY_BY_DAY: - load_recur_yearly_day (o, &str); - break; - default: - g_warning ("Unimplemented recurrence type %d", (int) type); - break; - } - duration (o, &str); - enddate (o, &str); - - /* Compute the enddate */ - if (o->recur->_enddate == 0){ - if (o->recur->duration != 0){ - ical_object_compute_end (o); - } else - o->recur->enddate = 0; - } else { - o->recur->enddate = o->recur->_enddate; - } - return 1; -} - -#define is_a_prop_of(obj,prop) isAPropertyOf (obj,prop) -#define str_val(obj) the_str = fakeCString (vObjectUStringZValue (obj)) -#define has(obj,prop) (vo = isAPropertyOf (obj, prop)) - -/* - * FIXME: This is loosing precission. Enhanec the thresholds - */ -#define HOURS(n) (n*(60*60)) - -static void -setup_alarm_at (iCalObject *ico, CalendarAlarm *alarm, char *iso_time, VObject *vo) -{ - time_t alarm_time = time_from_isodate (iso_time); - time_t base = ico->dtstart; - int d = difftime (base, alarm_time); - VObject *a; - char *the_str; - - alarm->enabled = 1; - if (d > HOURS (2)){ - if (d > HOURS (48)){ - alarm->count = d / HOURS (24); - alarm->units = ALARM_DAYS; - } else { - alarm->count = d / (60*60); - alarm->units = ALARM_HOURS; - } - } else { - alarm->count = d / 60; - alarm->units = ALARM_MINUTES; - } - - if ((a = is_a_prop_of (vo, VCSnoozeTimeProp))){ - alarm->snooze_secs = isodiff_to_secs (str_val (a)); - free (the_str); - } - - if ((a = is_a_prop_of (vo, VCRepeatCountProp))){ - alarm->snooze_repeat = atoi (str_val (a)); - free (the_str); - } -} - -/* - * Duplicates an iCalObject. Implementation is a grand hack. - * If you need the new ICalObject to have a new uid, free the current one, - * and call ical_gen_uid() to generate a new one. - */ -iCalObject * -ical_object_duplicate (iCalObject *o) -{ - VObject *vo; - iCalObject *new; - - vo = ical_object_to_vobject (o); - switch (o->type){ - case ICAL_EVENT: - new = ical_object_create_from_vobject (vo, VCEventProp); - break; - case ICAL_TODO: - new = ical_object_create_from_vobject (vo, VCTodoProp); - break; - default: - new = NULL; - } - - cleanVObject (vo); - return new; -} - -/* FIXME: we need to load the recurrence properties */ -iCalObject * -ical_object_create_from_vobject (VObject *o, const char *object_name) -{ - time_t now = time (NULL); - iCalObject *ical; - VObject *vo, *a; - VObjectIterator i; - char *the_str; - - ical = g_new0 (iCalObject, 1); - - if (strcmp (object_name, VCEventProp) == 0) - ical->type = ICAL_EVENT; - else if (strcmp (object_name, VCTodoProp) == 0) - ical->type = ICAL_TODO; - else { - g_free (ical); - return 0; - } - - ical->ref_count = 1; - - /* uid */ - if (has (o, VCUniqueStringProp)){ - ical->uid = g_strdup (str_val (vo)); - free (the_str); - } else { - ical->uid = ical_gen_uid (); - } - - /* seq */ - if (has (o, VCSequenceProp)){ - ical->seq = atoi (str_val (vo)); - free (the_str); - } else - ical->seq = 0; - - /* dtstart */ - if (has (o, VCDTstartProp)){ - ical->dtstart = time_from_isodate (str_val (vo)); - free (the_str); - } else - ical->dtstart = 0; - - /* dtend */ - ical->dtend = 0; /* default value */ - if (ical->type == ICAL_EVENT){ - if (has (o, VCDTendProp)){ - ical->dtend = time_from_isodate (str_val (vo)); - free (the_str); - } - } else if (ical->type == ICAL_TODO){ - if (has (o, VCDueProp)){ - ical->dtend = time_from_isodate (str_val (vo)); - free (the_str); - } - } - - /* dcreated */ - if (has (o, VCDCreatedProp)){ - ical->created = time_from_isodate (str_val (vo)); - free (the_str); - } - - /* completed */ - if (has (o, VCCompletedProp)){ - ical->completed = time_from_isodate (str_val (vo)); - free (the_str); - } - - /* last_mod */ - if (has (o, VCLastModifiedProp)){ - ical->last_mod = time_from_isodate (str_val (vo)); - free (the_str); - } else - ical->last_mod = now; - - /* exdate */ - if (has (o, VCExpDateProp)){ - ical->exdate = set_date_list (str_val (vo)); - free (the_str); - } - - /* description/comment */ - if (has (o, VCDescriptionProp)){ - ical->comment = g_strdup (str_val (vo)); - free (the_str); - } - - /* summary */ - if (has (o, VCSummaryProp)){ - ical->summary = g_strdup (str_val (vo)); - free (the_str); - - /* Convert any CR/LF/CRLF sequences in the summary field to - spaces so we just have a one-line field. */ - ical_object_normalize_summary (ical); - } else - ical->summary = g_strdup (""); - - /* status */ - if (has (o, VCStatusProp)){ - ical->status = g_strdup (str_val (vo)); - free (the_str); - } else - ical->status = g_strdup ("NEEDS ACTION"); - - if (has (o, VCClassProp)){ - ical->class = g_strdup (str_val (vo)); - free (the_str); - } else - ical->class = g_strdup ("PUBLIC"); - - /* categories */ - if (has (o, VCCategoriesProp)){ - ical->categories = set_list (str_val (vo)); - free (the_str); - } - - /* resources */ - if (has (o, VCResourcesProp)){ - ical->resources = set_list (str_val (vo)); - free (the_str); - } - - /* priority */ - if (has (o, VCPriorityProp)){ - ical->priority = atoi (str_val (vo)); - free (the_str); - } - - /* tranparency */ - if (has (o, VCTranspProp)){ - ical->transp = atoi (str_val (vo)) ? ICAL_TRANSPARENT : ICAL_OPAQUE; - free (the_str); - } - - /* Organizer */ - if (has (o, VCOrgNameProp)){ - ical->organizer = g_new0 (iCalPerson, 1); - ical->organizer->addr = g_strdup (str_val (vo)); - free (the_str); - } - - /* related */ - if (has (o, VCRelatedToProp)){ - char *str; - char *s; - iCalRelation *rel; - str = str_val (vo); - for (s = strtok (str, ";"); s; s = strtok (NULL, ";")) { - rel = g_new0 (iCalRelation, 1); - rel->uid = g_strdup (s); - rel->reltype = g_strdup ("PARENT"); - ical->related = g_list_prepend (ical->related, rel); - } - free (the_str); - } - - /* attach */ - initPropIterator (&i, o); - while (moreIteration (&i)){ - vo = nextVObject (&i); - if (strcmp (vObjectName (vo), VCAttachProp) == 0){ - ical->attach = g_list_prepend (ical->attach, g_strdup (str_val (vo))); - free (the_str); - } - } - - /* url */ - if (has (o, VCURLProp)){ - /* There seems to be a problem with the URL property. For some - reason an empty property gets saved, vObjectUStringZValue - returns NULL and fakeCString crashes. So we check for NULL. - */ - const wchar_t *zval; - - zval = vObjectUStringZValue (o); - if (zval) { - the_str = fakeCString (zval); - ical->url = g_strdup (the_str); - free (the_str); - } - } - - /* dalarm */ - ical->dalarm.type = ALARM_DISPLAY; - ical->dalarm.enabled = 0; - if (has (o, VCDAlarmProp)){ - if ((a = is_a_prop_of (vo, VCRunTimeProp))){ - setup_alarm_at (ical, &ical->dalarm, str_val (a), vo); - free (the_str); - } - } - - /* aalarm */ - ical->aalarm.type = ALARM_AUDIO; - ical->aalarm.enabled = 0; - if (has (o, VCAAlarmProp)){ - if ((a = is_a_prop_of (vo, VCRunTimeProp))){ - setup_alarm_at (ical, &ical->aalarm, str_val (a), vo); - free (the_str); - } - } - - /* palarm */ - ical->palarm.type = ALARM_PROGRAM; - ical->palarm.enabled = 0; - if (has (o, VCPAlarmProp)){ - ical->palarm.type = ALARM_PROGRAM; - if ((a = is_a_prop_of (vo, VCRunTimeProp))){ - setup_alarm_at (ical, &ical->palarm, str_val (a), vo); - free (the_str); - - if ((a = is_a_prop_of (vo, VCProcedureNameProp))){ - ical->palarm.data = g_strdup (str_val (a)); - free (the_str); - } else - ical->palarm.data = g_strdup (""); - } - } - - /* malarm */ - ical->malarm.type = ALARM_MAIL; - ical->malarm.enabled = 0; - if (has (o, VCMAlarmProp)){ - ical->malarm.type = ALARM_MAIL; - if ((a = is_a_prop_of (vo, VCRunTimeProp))){ - setup_alarm_at (ical, &ical->malarm, str_val (a), vo); - free (the_str); - - if ((a = is_a_prop_of (vo, VCEmailAddressProp))){ - ical->malarm.data = g_strdup (str_val (a)); - free (the_str); - } else - ical->malarm.data = g_strdup (""); - } - } - - /* rrule */ - if (has (o, VCRRuleProp)){ - if (!load_recurrence (ical, str_val (vo))) { - ical_object_unref (ical); - return NULL; - } - free (the_str); - } - - /* - * Pilot - */ - if (has (o, XPilotIdProp)){ - ical->pilot_id = atoi (str_val (vo)); - free (the_str); - } else - ical->pilot_id = 0; - - if (has (o, XPilotStatusProp)){ - ical->pilot_status = atoi (str_val (vo)); - free (the_str); - } else - ical->pilot_status = ICAL_PILOT_SYNC_MOD; - - return ical; -} - -static char * -to_str (int num) -{ - static char buf [40]; - - sprintf (buf, "%d", num); - return buf; -} - -/* - * stores a GList in the property. - */ -static void -store_list (VObject *o, char *prop, GList *values) -{ - GList *l; - int len; - char *result, *p; - - for (len = 0, l = values; l; l = l->next) - len += strlen (l->data) + 1; - - result = g_malloc (len); - - for (p = result, l = values; l; l = l->next) { - int len = strlen (l->data); - - strcpy (p, l->data); - - if (l->next) { - p [len] = ';'; - p += len+1; - } else - p += len; - } - - *p = 0; - - addPropValue (o, prop, result); - g_free (result); -} - -static void -store_rel_list (VObject *o, char *prop, GList *values) -{ - GList *l; - int len; - char *result, *p; - - for (len = 0, l = values; l; l = l->next) - len += strlen (((iCalRelation*)(l->data))->uid) + 1; - - result = g_malloc (len); - - for (p = result, l = values; l; l = l->next) { - int len = strlen (((iCalRelation*)(l->data))->uid); - - strcpy (p, ((iCalRelation*)(l->data))->uid); - - if (l->next) { - p [len] = ';'; - p += len+1; - } else - p += len; - } - - *p = 0; - - addPropValue (o, prop, result); - g_free (result); -} - -static void -store_date_list (VObject *o, char *prop, GList *values) -{ - GList *l; - int size, len; - char *s, *p; - - size = g_list_length (values); - s = p = g_malloc ((size * 17 + 1) * sizeof (char)); - - for (l = values; l; l = l->next){ - strcpy (s, isodate_from_time_t (*(time_t *)l->data)); - len = strlen (s); - s [len] = ','; - s += len + 1; - } - s--; - *s = 0; - addPropValue (o, prop, p); - g_free (p); -} - -static char *recur_type_name [] = { "D", "W", "MP", "MD", "YM", "YD" }; -static char *recur_day_list [] = { "SU", "MO", "TU","WE", "TH", "FR", "SA" }; -static char *alarm_names [] = { VCMAlarmProp, VCPAlarmProp, VCDAlarmProp, VCAAlarmProp }; - -static VObject * -save_alarm (VObject *o, CalendarAlarm *alarm, iCalObject *ical) -{ - VObject *alarm_object; - struct tm tm; - time_t alarm_time; - - if (!alarm->enabled) - return NULL; - tm = *localtime (&ical->dtstart); - switch (alarm->units){ - case ALARM_MINUTES: - tm.tm_min -= alarm->count; - break; - - case ALARM_HOURS: - tm.tm_hour -= alarm->count; - break; - - case ALARM_DAYS: - tm.tm_mday -= alarm->count; - break; - } - - alarm_time = mktime (&tm); - alarm_object = addProp (o, alarm_names [alarm->type]); - addPropValue (alarm_object, VCRunTimeProp, isodate_from_time_t (alarm_time)); - - if (alarm->snooze_secs) - addPropValue (alarm_object, VCSnoozeTimeProp, isodiff_from_secs (alarm->snooze_secs)); - else - addPropValue (alarm_object, VCSnoozeTimeProp, ""); - - if (alarm->snooze_repeat){ - char buf [20]; - - sprintf (buf, "%d", alarm->snooze_repeat); - addPropValue (alarm_object, VCRepeatCountProp, buf); - } else - addPropValue (alarm_object, VCRepeatCountProp, ""); - return alarm_object; -} - -VObject * -ical_object_to_vobject (iCalObject *ical) -{ - VObject *o, *alarm, *s; - GList *l; - - if (ical->type == ICAL_EVENT) - o = newVObject (VCEventProp); - else - o = newVObject (VCTodoProp); - - /* uid */ - if (ical->uid) - addPropValue (o, VCUniqueStringProp, ical->uid); - - /* seq */ - addPropValue (o, VCSequenceProp, to_str (ical->seq)); - - /* dtstart */ - addPropValue (o, VCDTstartProp, isodate_from_time_t (ical->dtstart)); - - /* dtend */ - if (ical->type == ICAL_EVENT){ - addPropValue (o, VCDTendProp, isodate_from_time_t (ical->dtend)); - } else if (ical->type == ICAL_TODO){ - addPropValue (o, VCDueProp, isodate_from_time_t (ical->dtend)); - } - - /* dcreated */ - addPropValue (o, VCDCreatedProp, isodate_from_time_t (ical->created)); - - /* completed */ - if (ical->completed) - addPropValue (o, VCDTendProp, isodate_from_time_t (ical->completed)); - - /* last_mod */ - addPropValue (o, VCLastModifiedProp, isodate_from_time_t (ical->last_mod)); - - /* exdate */ - if (ical->exdate) - store_date_list (o, VCExpDateProp, ical->exdate); - - /* description/comment */ - if (ical->comment && strlen (ical->comment)){ - s = addPropValue (o, VCDescriptionProp, ical->comment); - if (strchr (ical->comment, '\n')) - addProp (s, VCQuotedPrintableProp); - } - - /* summary */ - if (ical->summary && strlen (ical->summary)) { - s = addPropValue (o, VCSummaryProp, ical->summary); - if (strchr (ical->summary, '\n')) - addProp (s, VCQuotedPrintableProp); - } - - /* status */ - addPropValue (o, VCStatusProp, ical->status); - - /* class */ - addPropValue (o, VCClassProp, ical->class); - - /* categories */ - if (ical->categories) - store_list (o, VCCategoriesProp, ical->categories); - - /* resources */ - if (ical->resources) - store_list (o, VCCategoriesProp, ical->resources); - - /* priority */ - addPropValue (o, VCPriorityProp, to_str (ical->priority)); - - /* transparency */ - addPropValue (o, VCTranspProp, to_str (ical->transp)); - - /* Owner/organizer */ - if (ical->organizer && ical->organizer->addr) - addPropValue (o, VCOrgNameProp, ical->organizer->addr); - - /* related */ - if (ical->related) - store_rel_list (o, VCRelatedToProp, ical->related); - - /* attach */ - for (l = ical->attach; l; l = l->next) - addPropValue (o, VCAttachProp, l->data); - - /* url */ - if (ical->url) - addPropValue (o, VCURLProp, ical->url); - - if (ical->recur){ - char result [256]; - char buffer [80]; - int i; - - sprintf (result, "%s%d ", recur_type_name [ical->recur->type], ical->recur->interval); - switch (ical->recur->type){ - case RECUR_DAILY: - break; - - case RECUR_WEEKLY: - for (i = 0; i < 7; i++){ - if (ical->recur->weekday & (1 << i)){ - sprintf (buffer, "%s ", recur_day_list [i]); - strcat (result, buffer); - } - } - break; - - case RECUR_MONTHLY_BY_POS: { - int nega = ical->recur->u.month_pos < 0; - - sprintf (buffer, "%d%s ", nega ? -ical->recur->u.month_pos : ical->recur->u.month_pos, - nega ? "-" : "+"); - strcat (result, buffer); - /* the gui is set up for a single day, not a set here in this case */ - sprintf (buffer, "%s ", recur_day_list [ical->recur->weekday]); - strcat (result, buffer); - } - break; - - case RECUR_MONTHLY_BY_DAY: - sprintf (buffer, "%d ", ical->recur->u.month_pos); - strcat (result, buffer); - break; - - case RECUR_YEARLY_BY_MONTH: - break; - - case RECUR_YEARLY_BY_DAY: - break; - } - if (ical->recur->_enddate == 0) - sprintf (buffer, "#%d ",ical->recur->duration); - else - sprintf (buffer, "%s ", isodate_from_time_t (ical->recur->_enddate)); - strcat (result, buffer); - addPropValue (o, VCRRuleProp, result); - } - - save_alarm (o, &ical->aalarm, ical); - save_alarm (o, &ical->dalarm, ical); - - if ((alarm = save_alarm (o, &ical->palarm, ical))) - addPropValue (alarm, VCProcedureNameProp, ical->palarm.data); - if ((alarm = save_alarm (o, &ical->malarm, ical))) - addPropValue (alarm, VCEmailAddressProp, ical->malarm.data); - - /* Pilot */ - { - char buffer [20]; - - sprintf (buffer, "%d", ical->pilot_id); - addPropValue (o, XPilotIdProp, buffer); - sprintf (buffer, "%d", ical->pilot_status); - addPropValue (o, XPilotStatusProp, buffer); - } - - return o; -} - -void -ical_foreach (GList *events, calendarfn fn, void *closure) -{ - for (; events; events = events->next){ - iCalObject *ical = events->data; - - (*fn) (ical, ical->dtstart, ical->dtend, closure); - } -} - -static int -is_date_in_list (GList *list, struct tm *date) -{ - struct tm tm; - - for (; list; list = list->next){ - time_t *timep = list->data; - - tm = *localtime (timep); - if (date->tm_mday == tm.tm_mday && - date->tm_mon == tm.tm_mon && - date->tm_year == tm.tm_year){ - return 1; - } - } - return 0; -} - -/* Generates an event instance based on the reference time */ -static gboolean -generate (iCalObject *ico, time_t reference, calendarfn cb, void *closure) -{ - time_t offset; - struct tm tm_start, ref; - time_t start, end; - - offset = ico->dtend - ico->dtstart; - - tm_start = *localtime (&ico->dtstart); - ref = *localtime (&reference); - - tm_start.tm_mday = ref.tm_mday; - tm_start.tm_mon = ref.tm_mon; - tm_start.tm_year = ref.tm_year; - - start = mktime (&tm_start); - if (start == -1) { - g_message ("generate(): Produced invalid start date!"); - return FALSE; - } - - end = start + offset; - -#if 0 - /* FIXME: I think this is not needed, since we are offsetting by full day values, - * and the times should remain the same --- if you have a daily appointment - * at 18:00, it is always at 18:00 even during daylight savings. - * - * However, what should happen on the exact change-of-savings day with - * appointments in the early morning hours? - */ - - if (ref.tm_isdst > tm_start.tm_isdst) { - tm_start.tm_hour--; - tm_end.tm_hour--; - } else if (ref.tm_isdst < tm_start.tm_isdst) { - tm_start.tm_hour++; - tm_end.tm_hour++; - } -#endif - - if (ico->exdate && is_date_in_list (ico->exdate, &tm_start)) - return TRUE; - - return (*cb) (ico, start, end, closure); -} - -int -ical_object_get_first_weekday (int weekday_mask) -{ - int i; - - for (i = 0; i < 7; i++) - if (weekday_mask & (1 << i)) - return i; - - return -1; -} - -#define time_in_range(t, a, b) ((t >= a) && (b ? (t < b) : 1)) -#define recur_in_range(t, r) (r->enddate ? (t < r->enddate) : 1) - -/* - * Generate every possible event. Invokes the callback routine for - * every occurrence of the event in the [START, END] time interval. - * - * If END is zero, the event is generated forever. - * The callback routine is expected to return 0 when no further event - * generation is requested. - */ -void -ical_object_generate_events (iCalObject *ico, time_t start, time_t end, calendarfn cb, void *closure) -{ - time_t current; - int first_week_day; - - /* If there is no recurrence, just check ranges */ - - if (!ico->recur) { - if ((end && (ico->dtstart < end) && (ico->dtend > start)) - || ((end == 0) && (ico->dtend > start))) { - /* The new calendar views expect the times to not be - clipped, so they can show that it continues past - the end of the viewable area. */ -#if 0 - time_t ev_s, ev_e; - - /* Clip range */ - - ev_s = MAX (ico->dtstart, start); - ev_e = MIN (ico->dtend, end); - - (* cb) (ico, ev_s, ev_e, closure); -#else - (* cb) (ico, ico->dtstart, ico->dtend, closure); -#endif - } - return; - } - - /* The event has a recurrence rule -- check that we will generate at least one instance */ - - if (end != 0) { - if (ico->dtstart > end) - return; - - if (!IS_INFINITE (ico->recur) && (ico->recur->enddate < start)) - return; - } - - /* Generate the instances */ - - current = ico->dtstart; - - switch (ico->recur->type) { - case RECUR_DAILY: - do { - if (time_in_range (current, start, end) && recur_in_range (current, ico->recur)) - if (!generate (ico, current, cb, closure)) - return; - - /* Advance */ - - current = time_add_day (current, ico->recur->interval); - - if (current == -1) { - g_warning ("RECUR_DAILY: time_add_day() returned invalid time"); - return; - } - } while ((current < end) || (end == 0)); - - break; - - case RECUR_WEEKLY: - do { - struct tm tm; - - tm = *localtime (¤t); - - if (time_in_range (current, start, end) && recur_in_range (current, ico->recur)) { - /* Weekdays to recur on are specified as a bitmask */ - if (ico->recur->weekday & (1 << tm.tm_wday)) { - if (!generate (ico, current, cb, closure)) - return; - } - } - - /* Advance by day for scanning the week or by interval at week end */ - - if (tm.tm_wday == 6) - current = time_add_day (current, (ico->recur->interval - 1) * 7 + 1); - else - current = time_add_day (current, 1); - - if (current == -1) { - g_warning ("RECUR_WEEKLY: time_add_day() returned invalid time\n"); - return; - } - } while (current < end || (end == 0)); - - break; - - case RECUR_MONTHLY_BY_POS: - /* FIXME: We only deal with positives now */ - if (ico->recur->u.month_pos < 0) { - g_warning ("RECUR_MONTHLY_BY_POS does not support negative positions yet"); - return; - } - - if (ico->recur->u.month_pos == 0) - return; - - first_week_day = /* ical_object_get_first_weekday (ico->recur->weekday); */ - ico->recur->weekday; /* the i/f only lets you choose a single day of the week! */ - - /* This should not happen, but take it into account */ - if (first_week_day == -1) { - g_warning ("ical_object_get_first_weekday() returned -1"); - return; - } - - do { - struct tm tm; - time_t t; - int week_day_start; - - tm = *localtime (¤t); - tm.tm_mday = 1; - t = mktime (&tm); - tm = *localtime (&t); - week_day_start = tm.tm_wday; - - tm.tm_mday = (7 * (ico->recur->u.month_pos - ((week_day_start <= first_week_day ) ? 1 : 0)) - - (week_day_start - first_week_day) + 1); - if( tm.tm_mday > 31 ) - { - tm.tm_mday = 1; - tm.tm_mon += ico->recur->interval; - current = mktime (&tm); - continue; - } - - switch( tm.tm_mon ) - { - case 3: - case 5: - case 8: - case 10: - if( tm.tm_mday > 30 ) - { - tm.tm_mday = 1; - tm.tm_mon += ico->recur->interval; - current = mktime (&tm); - continue; - } - break; - case 1: - if( ((tm.tm_year+1900)%4) == 0 - && ((tm.tm_year+1900)%400) != 100 - && ((tm.tm_year+1900)%400) != 200 - && ((tm.tm_year+1900)%400) != 300 ) - { - - if( tm.tm_mday > 29 ) - { - tm.tm_mday = 1; - tm.tm_mon += ico->recur->interval; - current = mktime (&tm); - continue; - } - } - else - { - if( tm.tm_mday > 28 ) - { - tm.tm_mday = 1; - tm.tm_mon += ico->recur->interval; - current = mktime (&tm); - continue; - } - } - break; - } - - t = mktime (&tm); - - if (time_in_range (t, start, end) && recur_in_range (current, ico->recur)) - if (!generate (ico, t, cb, closure)) - return; - - /* Advance by the appropriate number of months */ - - current = mktime (&tm); - - tm.tm_mday = 1; - tm.tm_mon += ico->recur->interval; - current = mktime (&tm); - - if (current == -1) { - g_warning ("RECUR_MONTHLY_BY_DAY: mktime error\n"); - return; - } - } while ((current < end) || (end == 0)); - - break; - - case RECUR_MONTHLY_BY_DAY: - do { - struct tm tm; - time_t t; - int p; - - tm = *localtime (¤t); - - p = tm.tm_mday; - tm.tm_mday = ico->recur->u.month_day; - t = mktime (&tm); - if (time_in_range (t, start, end) && recur_in_range (current, ico->recur)) - if (!generate (ico, t, cb, closure)) - return; - - /* Advance by the appropriate number of months */ - - tm.tm_mday = p; - tm.tm_mon += ico->recur->interval; - current = mktime (&tm); - - if (current == -1) { - g_warning ("RECUR_MONTHLY_BY_DAY: mktime error\n"); - return; - } - } while (current < end || (end == 0)); - - break; - - case RECUR_YEARLY_BY_MONTH: - case RECUR_YEARLY_BY_DAY: - do { - if (time_in_range (current, start, end) && recur_in_range (current, ico->recur)) - if (!generate (ico, current, cb, closure)) - return; - - /* Advance */ - - current = time_add_year (current, ico->recur->interval); - } while (current < end || (end == 0)); - - break; - - default: - g_assert_not_reached (); - } -} - -static int -duration_callback (iCalObject *ico, time_t start, time_t end, void *closure) -{ - int *count = closure; - struct tm tm; - - tm = *localtime (&start); - - (*count)++; - if (ico->recur->duration == *count) { - ico->recur->enddate = time_day_end (end); - return 0; - } - return 1; -} - -/* Computes ico->recur->enddate from ico->recur->duration */ -void -ical_object_compute_end (iCalObject *ico) -{ - int count = 0; - - g_return_if_fail (ico->recur != NULL); - - ico->recur->_enddate = 0; - ico->recur->enddate = 0; - ical_object_generate_events (ico, ico->dtstart, 0, duration_callback, &count); -} - -int -alarm_compute_offset (CalendarAlarm *a) -{ - if (!a->enabled) - return -1; - switch (a->units){ - case ALARM_MINUTES: - a->offset = a->count * 60; - break; - case ALARM_HOURS: - a->offset = a->count * 3600; - break; - case ALARM_DAYS: - a->offset = a->count * 24 * 3600; - } - return a->offset; -} - - -/** - * ical_object_find_in_string: - * @uid: Unique identifier of the sought object. - * @vcalobj: String representation of a complete calendar object. - * @ico: The resulting #iCalObject is stored here. - * - * Parses a complete vCalendar object string and tries to find the calendar - * object that matches the specified @uid. If found, it stores the resulting - * #iCalObject in the @ico parameter. - * - * Return value: A result code depending on whether the parse and search were - * successful. - **/ -CalObjFindStatus -ical_object_find_in_string (const char *uid, const char *vcalobj, iCalObject **ico) -{ -#if 0 - icalcomponent* comp = NULL; - icalcomponent *subcomp; - iCalObject *ical; - - g_return_val_if_fail (vcalobj != NULL, CAL_OBJ_FIND_NOT_FOUND); - - comp = icalparser_parse_string (vcalobj); - - if (!comp) { - printf ("CAL_OBJ_FIND_SYNTAX_ERROR #1\n"); - return CAL_OBJ_FIND_SYNTAX_ERROR; - } - - subcomp = icalcomponent_get_first_component (comp, - ICAL_ANY_COMPONENT); - if (!subcomp) { - printf ("CAL_OBJ_FIND_SYNTAX_ERROR #2\n"); - return CAL_OBJ_FIND_SYNTAX_ERROR; - } - - while (subcomp) { - ical = ical_object_create_from_icalcomponent (subcomp); - if (ical->type != ICAL_EVENT && - ical->type != ICAL_TODO && - ical->type != ICAL_JOURNAL) { - g_warning ("Skipping unsupported iCalendar component"); - } else { - if (strcasecmp (ical->uid, uid) == 0) { - (*ico) = ical; - (*ico)->ref_count = 1; - printf ("CAL_OBJ_FIND_SUCCESS\n"); - - printf ("ical_object_find_in_string:\n"); - printf ("-----------------------------------------------------\n"); - dump_icalobject (*ico); - printf ("-----------------------------------------------------\n"); - - - return CAL_OBJ_FIND_SUCCESS; - } - } - subcomp = icalcomponent_get_next_component (comp, - ICAL_ANY_COMPONENT); - } - - printf ("CAL_OBJ_FIND_NOT_FOUND\n"); - return CAL_OBJ_FIND_NOT_FOUND; - -#else /* 1 */ - VObject *vcal; - VObjectIterator i; - CalObjFindStatus status; - - g_return_val_if_fail (uid != NULL, CAL_OBJ_FIND_SYNTAX_ERROR); - g_return_val_if_fail (vcalobj != NULL, CAL_OBJ_FIND_SYNTAX_ERROR); - g_return_val_if_fail (ico != NULL, CAL_OBJ_FIND_SYNTAX_ERROR); - - *ico = NULL; - status = CAL_OBJ_FIND_NOT_FOUND; - - vcal = Parse_MIME (vcalobj, strlen (vcalobj)); - - if (!vcal) - return CAL_OBJ_FIND_SYNTAX_ERROR; - - initPropIterator (&i, vcal); - - while (moreIteration (&i)) { - VObject *vobj; - VObject *uid_prop; - char *the_str; - - vobj = nextVObject (&i); - - uid_prop = isAPropertyOf (vobj, VCUniqueStringProp); - if (!uid_prop) - continue; - - /* str_val() sets the_str to the string representation of the - * property. - */ - str_val (uid_prop); - - if (strcmp (the_str, uid) == 0) { - const char *object_name; - - object_name = vObjectName (vobj); - *ico = ical_object_create_from_vobject (vobj, object_name); - - if (*ico) - status = CAL_OBJ_FIND_SUCCESS; - } - - free (the_str); - - if (status == CAL_OBJ_FIND_SUCCESS) - break; - } - - cleanVObject (vcal); - cleanStrTbl (); - - return status; -#endif /* 1 */ -} - - -#if 1 -/* Creates a VObject with the base information of a calendar */ -static VObject * -get_calendar_base_vobject (void) -{ - VObject *vobj; - time_t now; - struct tm tm; - - /* We call localtime for the side effect of setting tzname */ - - now = time (NULL); - tm = *localtime (&now); - - vobj = newVObject (VCCalProp); - - addPropValue (vobj, VCProdIdProp, PRODID); - -#if defined (HAVE_TM_ZONE) - addPropValue (vobj, VCTimeZoneProp, tm.tm_zone); -#elif defined (HAVE_TZNAME) - addPropValue (vobj, VCTimeZoneProp, tzname[0]); -#endif - - /* Per the vCalendar spec, this must be "1.0" */ - addPropValue (vobj, VCVersionProp, "1.0"); - - return vobj; -} -#endif /* 0 */ - -/** - * ical_object_to_string: - * @ico: A calendar object. - * - * Converts a vCalendar object to its string representation. It is wrapped - * inside a complete VCALENDAR object because other auxiliary information such - * as timezones may appear there. - * - * Return value: String representation of the object. - **/ -char * -ical_object_to_string (iCalObject *ico) -{ -#if 0 - icalcomponent *top = icalcomponent_new (ICAL_VCALENDAR_COMPONENT); - char *out_cal_string; - icalcomponent *comp; - - printf ("ical_object_to_string:\n"); - printf ("-----------------------------------------------------\n"); - dump_icalobject (ico); - printf ("-----------------------------------------------------\n"); - - comp = icalcomponent_create_from_ical_object (ico); - icalcomponent_add_component (top, comp); - out_cal_string = icalcomponent_as_ical_string (top); - return g_strdup (out_cal_string); - -#else /* 1 */ - VObject *vcalobj, *vobj; - char *buf, *gbuf; - - vcalobj = get_calendar_base_vobject (); - vobj = ical_object_to_vobject (ico); - addVObjectProp (vcalobj, vobj); - - buf = writeMemVObject (NULL, NULL, vcalobj); - - cleanVObject (vcalobj); - cleanStrTbl (); - - /* We have to g_strdup() it because libversit uses malloc()/realloc(), - * and we want clients to be able to use g_free(). Sigh. - */ - gbuf = g_strdup (buf); - free (buf); - - return gbuf; -#endif /* 1 */ -} - - -/** - * ical_object_compare_dates: - * @ico1: A calendar event. - * @ico2: A calendar event to compare with @ico1. - * - * Returns TRUE if the dates of both objects match, including any recurrence - * rules. Both calendar objects must have a type of ICAL_EVENT. - * - * Return value: TRUE if both calendar objects have the same dates. - **/ -gboolean -ical_object_compare_dates (iCalObject *ico1, - iCalObject *ico2) -{ - Recurrence *recur1, *recur2; - gint num_exdates; - GList *elem1, *elem2; - time_t *time1, *time2; - - g_return_val_if_fail (ico1 != NULL, FALSE); - g_return_val_if_fail (ico2 != NULL, FALSE); - g_return_val_if_fail (ico1->type == ICAL_EVENT, FALSE); - g_return_val_if_fail (ico2->type == ICAL_EVENT, FALSE); - - /* First check the base dates. */ - if (ico1->dtstart != ico2->dtstart - || ico1->dtend != ico2->dtend) - return FALSE; - - recur1 = ico1->recur; - recur2 = ico2->recur; - - /* If the event doesn't recur, we already know it matches. */ - if (!recur1 && !recur2) - return TRUE; - - /* Check that both recur. */ - if (!(recur1 && recur2)) - return FALSE; - - /* Now we need to see if the recurrence rules are the same. */ - if (recur1->type != recur2->type - || recur1->interval != recur2->interval - || recur1->enddate != recur2->enddate - || recur1->weekday != recur2->weekday - || recur1->duration != recur2->duration - || recur1->_enddate != recur2->_enddate - || recur1->__count != recur2->__count) - return FALSE; - - switch (recur1->type) { - case RECUR_MONTHLY_BY_POS: - if (recur1->u.month_pos != recur2->u.month_pos) - return FALSE; - break; - case RECUR_MONTHLY_BY_DAY: - if (recur1->u.month_day != recur2->u.month_day) - return FALSE; - break; - default: - break; - } - - /* Now check if the excluded dates match. */ - num_exdates = g_list_length (ico1->exdate); - if (g_list_length (ico2->exdate) != num_exdates) - return FALSE; - if (num_exdates == 0) - return TRUE; - - ico1->exdate = g_list_sort (ico1->exdate, compare_exdates); - ico2->exdate = g_list_sort (ico2->exdate, compare_exdates); - - elem1 = ico1->exdate; - elem2 = ico2->exdate; - while (elem1) { - time1 = (time_t*) elem1->data; - time2 = (time_t*) elem2->data; - - if (*time1 != *time2) - return FALSE; - - elem1 = elem1->next; - elem2 = elem2->next; - } - - return TRUE; -} - - -static gint -compare_exdates (gconstpointer a, gconstpointer b) -{ - const time_t *ca = a, *cb = b; - time_t diff = *ca - *cb; - return (diff < 0) ? -1 : (diff > 0) ? 1 : 0; -} - - -/* Converts any CR/LF sequences in the summary field to spaces so we just - have a one-line field. The iCalObjects summary field is changed. */ -static void -ical_object_normalize_summary (iCalObject *ico) -{ - gchar *src, *dest, ch; - gboolean just_output_space = FALSE; - - src = dest = ico->summary; - while ((ch = *src++)) { - if (ch == '\n' || ch == '\r') { - /* We only output 1 space for each sequence of CR & LF - characters. */ - if (!just_output_space) { - *dest++ = ' '; - just_output_space = TRUE; - } - } else { - *dest++ = ch; - just_output_space = FALSE; - } - } - *dest = '\0'; -} - - -void dump_icalobject (iCalObject *ico) -{ - if (!ico) { - printf ("<<NULL>>\n"); - return; - } - - printf ("type "); - switch (ico->type) { - case ICAL_EVENT: printf ("event"); break; - case ICAL_TODO: printf ("todo"); break; - case ICAL_JOURNAL: printf ("journal"); break; - case ICAL_FBREQUEST: printf ("fbrequest"); break; - case ICAL_FBREPLY: printf ("fbreply"); break; - case ICAL_BUSYTIME: printf ("busytime"); break; - case ICAL_TIMEZONE: printf ("timezone"); break; - } - printf ("\n"); - - printf ("attach-length %d\n", g_list_length (ico->attach)); - - printf ("attendee-length %d\n", g_list_length (ico->attendee)); - - printf ("catagories-length %d\n", g_list_length (ico->categories)); - - printf ("class '%s'\n", ico->class ? ico->class : "NULL"); - - printf ("comment '%s'\n", ico->comment ? ico->comment : "NULL"); - - printf ("completed %ld=%s", - ico->completed, ctime (&ico->completed)); - - printf ("created %ld=%s", ico->created, ctime (&ico->created)); - - printf ("contact-length %d\n", g_list_length (ico->contact)); - - printf ("desc '%s'\n", ico->desc ? ico->desc : "NULL"); - - printf ("dtstamp %ld=%s", ico->dtstamp, ctime (&ico->dtstamp)); - - printf ("dtstart %ld=%s", ico->dtstart, ctime (&ico->dtstart)); - - printf ("dtend %ld=%s", ico->dtend, ctime (&ico->dtend)); - - printf ("date_only %d\n", ico->date_only); - - printf ("exdate-length %d\n", g_list_length (ico->exdate)); - - printf ("exrule-length %d\n", g_list_length (ico->exrule)); - - printf ("iCalGeo %d %f %f\n", - ico->geo.valid, ico->geo.latitude, ico->geo.longitude); - - printf ("last_mod %ld=%s", ico->last_mod, ctime (&ico->last_mod)); - - printf ("location '%s'\n", ico->location ? ico->location : "NULL"); - - printf ("organizer %p\n", ico->organizer); - - printf ("percent %d\n", ico->percent); - - printf ("priority %d\n", ico->priority); - - printf ("rstatus '%s'\n", ico->rstatus ? ico->rstatus : "NULL"); - - printf ("related-length %d\n", g_list_length (ico->related)); - - printf ("resources-length %d\n", g_list_length (ico->resources)); - - printf ("rdate-length %d\n", g_list_length (ico->rdate)); - - printf ("rrule-length %d\n", g_list_length (ico->rrule)); - - printf ("seq %d\n", ico->seq); - - printf ("status '%s'\n", ico->status ? ico->status : "NULL"); - - printf ("summary '%s'\n", ico->summary ? ico->summary : "NULL"); - - printf ("transp "); - switch (ico->transp) { - case ICAL_OPAQUE: printf ("opaque"); break; - case ICAL_TRANSPARENT: printf ("transparent"); break; - } - printf ("\n"); - - printf ("uid '%s'\n", ico->uid ? ico->uid : "NULL"); - - printf ("url '%s'\n", ico->url ? ico->url : "NULL"); - - printf ("recurid %ld=%s", ico->recurid, ctime (&ico->recurid)); - - printf ("dalarm %d\n", ico->dalarm.enabled); - - printf ("aalarm %d\n", ico->aalarm.enabled); - - printf ("palarm %d\n", ico->palarm.enabled); - - printf ("malarm %d\n", ico->malarm.enabled); - - printf ("alarms-length %d\n", g_list_length (ico->alarms)); - - printf ("recur %p\n", ico->recur); - - printf ("new %d\n", ico->new); - - printf ("user_data %p\n", ico->user_data); - - printf ("ref_count %d\n", ico->ref_count); -} diff --git a/calendar/cal-util/calobj.h b/calendar/cal-util/calobj.h deleted file mode 100644 index 3caef945e2..0000000000 --- a/calendar/cal-util/calobj.h +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Internal representation of a Calendar object. This is modeled after the - * iCalendar/vCalendar specificiation - * - * Authors: Miguel de Icaza (miguel@gnu.org) - * Federico Mena (quartic@gimp.org). - */ -#ifndef CALOBJ_H -#define CALOBJ_H - -#include <libgnome/libgnome.h> -#include "libversit/vcc.h" - -BEGIN_GNOME_DECLS - -/* Alarm types */ -enum AlarmType { - ALARM_MAIL, - ALARM_PROGRAM, - ALARM_DISPLAY, - ALARM_AUDIO -}; - -/* Whether the alarm should trigger N mins/hours/days before its due time */ -enum AlarmUnit { - ALARM_MINUTES, - ALARM_HOURS, - ALARM_DAYS -}; - -/* Field identifiers for the iCalObject structure. These are also used to - identify columns in ECalendarTable, so be careful when reordering them. */ -typedef enum { - ICAL_OBJECT_FIELD_COMMENT, - ICAL_OBJECT_FIELD_COMPLETED, - ICAL_OBJECT_FIELD_CREATED, - ICAL_OBJECT_FIELD_DESCRIPTION, - ICAL_OBJECT_FIELD_DTSTAMP, - ICAL_OBJECT_FIELD_DTSTART, - ICAL_OBJECT_FIELD_DTEND, - ICAL_OBJECT_FIELD_GEO, - ICAL_OBJECT_FIELD_LAST_MOD, - ICAL_OBJECT_FIELD_LOCATION, - ICAL_OBJECT_FIELD_ORGANIZER, - ICAL_OBJECT_FIELD_PERCENT, - ICAL_OBJECT_FIELD_PRIORITY, - ICAL_OBJECT_FIELD_SUMMARY, - ICAL_OBJECT_FIELD_URL, - ICAL_OBJECT_FIELD_HAS_ALARMS, /* not a real field */ - ICAL_OBJECT_FIELD_ICON, /* not a real field */ - ICAL_OBJECT_FIELD_COMPLETE, /* not a real field */ - ICAL_OBJECT_FIELD_RECURRING, /* not a real field */ - ICAL_OBJECT_FIELD_OVERDUE, /* not a real field */ - ICAL_OBJECT_FIELD_COLOR, /* not a real field */ - ICAL_OBJECT_FIELD_NUM_FIELDS -} iCalObjectField; - -typedef struct { - enum AlarmType type; - int enabled; - int count; - enum AlarmUnit units; - char *data; /* not used for iCalendar alarms */ - - /* the following pointers are used for iCalendar alarms */ - - char *attach; /* AUDIO, EMAIL, PROC */ - char *desc; /* DISPLAY, EMAIL, PROC */ - char *summary; /* EMAIL */ - char *attendee; /* EMAIL */ - - /* Does not get saved, internally used */ - time_t offset; - time_t trigger; - - int snooze_secs; - int snooze_repeat; - - /* Widgets */ - void *w_count; /* A GtkEntry */ - void *w_enabled; /* A GtkChecButton */ - void *w_timesel; /* A GtkMenu */ - void *w_entry; /* A GnomeEntryFile/GtkEntry for PROGRAM/MAIL */ - void *w_label; -} CalendarAlarm; - -/* Calendar object type */ -typedef enum { - ICAL_EVENT, - ICAL_TODO, - ICAL_JOURNAL, - ICAL_FBREQUEST, - ICAL_FBREPLY, - ICAL_BUSYTIME, - ICAL_TIMEZONE -} iCalType; - -/* For keys that might contain binary or text/binary */ -typedef struct { - char *data; - int len; -} iCalValue; - -typedef enum { - ICAL_PILOT_SYNC_NONE = 0, - ICAL_PILOT_SYNC_MOD = 1, - ICAL_PILOT_SYNC_DEL = 3 -} iCalPilotState; - -typedef struct { - int valid; /* true if the Geography was specified */ - double latitude; - double longitude; -} iCalGeo; - -typedef enum { - ICAL_OPAQUE, - ICAL_TRANSPARENT -} iCalTransp; - -typedef struct { - char *uid; - char *reltype; -} iCalRelation; - -typedef char NotYet; - -enum RecurType { - RECUR_DAILY, - RECUR_WEEKLY, - RECUR_MONTHLY_BY_POS, - RECUR_MONTHLY_BY_DAY, - RECUR_YEARLY_BY_MONTH, - RECUR_YEARLY_BY_DAY, -}; - -#define DAY_LASTDAY 10000 - -typedef struct { - enum RecurType type; - - int interval; - - /* Used for recur computation */ - time_t enddate; /* If the value is zero, it is an infinite event - * otherwise, it is either the _enddate value (if - * this is what got specified) or it is our computed - * ending date (computed from the duration item). - */ - - int weekday; - - union { - int month_pos; - int month_day; - } u; - - int duration; - time_t _enddate; /* As found on the vCalendar file */ - int __count; -} Recurrence; - -/* - NOTE: iCalPerson is used for various property values which specify - people (e.g. ATTENDEE, ORGANIZER, etc. Not all fields are valid - under RFC 2445 for all property values, but iCalPerson can store - them anyway. Enforcing the RFC is a job for the parser. -*/ - -typedef struct { - char *addr; - char *name; - char *role; - char *partstat; - gboolean rsvp; - char *cutype; /* calendar user type */ - GList *member; /* group memberships */ - GList *deleg_to; - GList *deleg_from; - char *sent_by; - char *directory; - GList *altrep; /* list of char* URI's */ -} iCalPerson; - -#define IS_INFINITE(r) (r->duration == 0) - -/* Flags to indicate what has changed in an object */ -typedef enum { - CHANGE_NEW = 1 << 0, /* new object */ - CHANGE_SUMMARY = 1 << 1, /* summary */ - CHANGE_DATES = 1 << 2, /* dtstart / dtend */ - CHANGE_ALL = CHANGE_SUMMARY | CHANGE_DATES -} CalObjectChange; - -/* - * This describes an iCalendar object, note that we never store durations, instead we - * always compute the end time computed from the start + duration. - */ -typedef struct { - iCalType type; - - GList *attach; /* type: one or more URIs or binary data */ - GList *attendee; /* type: CAL-ADDRESS (list of iCalPerson) */ - GList *categories; /* type: one or more TEXT */ - char *class; - - char *comment; /* we collapse one or more TEXTs into one */ - time_t completed; - time_t created; - GList *contact; /* type: one or more TEXT */ - char *desc; - time_t dtstamp; - time_t dtstart; - time_t dtend; /* also duedate for todo's */ - gboolean date_only; /* set if the start/end times were - specified using dates, not times (internal use, not stored to disk) */ - GList *exdate; /* type: one or more time_t's */ - GList *exrule; /* type: one or more RECUR */ - iCalGeo geo; - time_t last_mod; - char *location; - iCalPerson *organizer; - int percent; - int priority; - char *rstatus; /* request status for freebusy */ - GList *related; /* type: one or more TEXT */ - GList *resources; /* type: one or more TEXT */ - GList *rdate; /* type: one or more recurrence date */ - GList *rrule; /* type: one or more recurrence rules */ - int seq; - char *status; - char *summary; - iCalTransp transp; - char *uid; - char *url; - time_t recurid; - - CalendarAlarm dalarm; - CalendarAlarm aalarm; - CalendarAlarm palarm; - CalendarAlarm malarm; - - GList *alarms; - - Recurrence *recur; - - int new; - void *user_data; /* Generic data pointer */ - - /* Pilot */ - iCalPilotState pilot_status; /* Status information */ - guint32 pilot_id; /* Pilot ID */ - - guint ref_count; -} iCalObject; - -/* The callback for the recurrence generator */ -typedef int (*calendarfn) (iCalObject *, time_t, time_t, void *); - -iCalObject *ical_new (char *comment, char *organizer, char *summary); -iCalObject *ical_object_new (void); - -void ical_object_ref (iCalObject *ico); -void ical_object_unref (iCalObject *ico); - -iCalObject *ical_object_create_from_vobject (VObject *obj, const char *object_name); -VObject *ical_object_to_vobject (iCalObject *ical); -iCalObject *ical_object_duplicate (iCalObject *o); -void ical_foreach (GList *events, calendarfn fn, void *closure); -void ical_object_generate_events (iCalObject *ico, time_t start, time_t end, calendarfn cb, void *closure); -void ical_object_add_exdate (iCalObject *o, time_t t); - -/* Computes the enddate field of the recurrence based on the duration */ -void ical_object_compute_end (iCalObject *ico); - -typedef enum { - CAL_OBJ_FIND_SUCCESS, - CAL_OBJ_FIND_SYNTAX_ERROR, - CAL_OBJ_FIND_NOT_FOUND -} CalObjFindStatus; - -CalObjFindStatus ical_object_find_in_string (const char *uid, const char *vcalobj, iCalObject **ico); - -char *ical_object_to_string (iCalObject *ico); - - -/* Returns the first toggled day in a weekday mask -- we do this because we do not support multiple - * days on a monthly-by-pos recurrence. If no days are toggled, it returns -1. - */ -int ical_object_get_first_weekday (int weekday_mask); - -/* Returns the number of seconds configured to trigger the alarm in advance to an event */ -int alarm_compute_offset (CalendarAlarm *a); - - -/* Returns TRUE if the dates of both objects match, including any recurrence - rules. */ -gboolean ical_object_compare_dates (iCalObject *ico1, iCalObject *ico2); - -/* Generates a new uid for a calendar object. Should be g_free'd eventually. */ -char *ical_gen_uid (void); - -/* This resets any recurrence rules of the iCalObject. */ -void ical_object_reset_recurrence (iCalObject *ico); - - -void dump_icalobject (iCalObject *ico); - -END_GNOME_DECLS - -#endif - diff --git a/calendar/cal-util/test-recur.c b/calendar/cal-util/test-recur.c deleted file mode 100644 index a049ea955b..0000000000 --- a/calendar/cal-util/test-recur.c +++ /dev/null @@ -1,194 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@helixcode.com> - * - * Copyright 2000, Helix Code, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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 - */ - -/* - * This tests the recurrence rule expansion functions. - * - * NOTE: currently it starts from the event start date and continues - * until all recurrence rules/dates end or we reach MAX_OCCURRENCES - * occurrences. So it does not test generating occurrences for a specific - * interval. A nice addition might be to do this automatically and compare - * the results from the complete set to ensure they match. - */ - -#include <config.h> -#include <stdio.h> -#include <gtk/gtk.h> -#include <cal-util/cal-recur.h> - - -/* Since events can recur infinitely, we set a limit to the number of - occurrences we output. */ -#define MAX_OCCURRENCES 1000 - -static void usage (void); -static icalcomponent* scan_ics_file (char *filename); -static char* get_line (char *s, - size_t size, - void *data); -static void generate_occurrences (icalcomponent *comp); -static gboolean occurrence_cb (CalComponent *comp, - time_t instance_start, - time_t instance_end, - gpointer data); - - -int -main (int argc, - char *argv[]) -{ - gchar *filename; - icalcomponent *icalcomp; - - gtk_init (&argc, &argv); - - if (argc != 2) - usage (); - - filename = argv[1]; - - icalcomp = scan_ics_file (filename); - if (icalcomp) - generate_occurrences (icalcomp); - - return 0; -} - - -static void -usage (void) -{ - g_print ("Usage: test-recur <filename>\n"); - exit (1); -} - - -static icalcomponent* -scan_ics_file (char *filename) -{ - FILE *fp; - icalcomponent *icalcomp; - icalparser *parser; - - g_print ("Opening file: %s\n", filename); - fp = fopen (filename, "r"); - - if (!fp) { - g_print ("Can't open file: %s\n", filename); - return NULL; - } - - parser = icalparser_new (); - icalparser_set_gen_data (parser, fp); - - icalcomp = icalparser_parse (parser, get_line); - icalparser_free (parser); - - return icalcomp; -} - - -/* Callback used from icalparser_parse() */ -static char * -get_line (char *s, - size_t size, - void *data) -{ - return fgets (s, size, (FILE*) data); -} - - -static void -generate_occurrences (icalcomponent *icalcomp) -{ - icalcompiter iter; - - for (iter = icalcomponent_begin_component (icalcomp, ICAL_ANY_COMPONENT); - icalcompiter_deref (&iter) != NULL; - icalcompiter_next (&iter)) { - icalcomponent *tmp_icalcomp; - CalComponent *comp; - icalcomponent_kind kind; - gint occurrences; - - tmp_icalcomp = icalcompiter_deref (&iter); - kind = icalcomponent_isa (tmp_icalcomp); - - if (!(kind == ICAL_VEVENT_COMPONENT - || kind == ICAL_VTODO_COMPONENT - || kind == ICAL_VJOURNAL_COMPONENT)) - continue; - - comp = cal_component_new (); - - if (!cal_component_set_icalcomponent (comp, tmp_icalcomp)) - continue; - - g_print ("#############################################################################\n"); - g_print ("%s\n\n", icalcomponent_as_ical_string (tmp_icalcomp)); - g_print ("Instances:\n"); - - occurrences = 0; - /* I use specific times when I am trying to pin down a bug seen - in one of the calendar views. */ -#if 0 - cal_recur_generate_instances (comp, 982022400, 982108800, - occurrence_cb, &occurrences); -#else - cal_recur_generate_instances (comp, -1, -1, - occurrence_cb, &occurrences); -#endif - - /* Print the component again so we can see the - X-EVOLUTION-ENDDATE parameter (only set if COUNT is used). - */ - g_print ("#############################################################################\n"); -#if 0 - g_print ("%s\n\n", icalcomponent_as_ical_string (tmp_icalcomp)); -#endif - } -} - - -static gboolean -occurrence_cb (CalComponent *comp, - time_t instance_start, - time_t instance_end, - gpointer data) -{ - char start[32], finish[32]; - gint *occurrences; - - occurrences = (gint*) data; - - strcpy (start, ctime (&instance_start)); - start[24] = '\0'; - strcpy (finish, ctime (&instance_end)); - finish[24] = '\0'; - - g_print ("%s - %s\n", start, finish); - - (*occurrences)++; - return (*occurrences == MAX_OCCURRENCES) ? FALSE : TRUE; -} diff --git a/calendar/cal-util/timeutil.c b/calendar/cal-util/timeutil.c deleted file mode 100644 index b48a02b5fa..0000000000 --- a/calendar/cal-util/timeutil.c +++ /dev/null @@ -1,314 +0,0 @@ -/* Miscellaneous time-related utilities - * - * Copyright (C) 1998 The Free Software Foundation - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Federico Mena <federico@ximian.com> - * Miguel de Icaza <miguel@ximian.com> - */ - -#include <string.h> -#include <glib.h> -#include "timeutil.h" - - - -void -print_time_t (time_t t) -{ - struct tm *tm = localtime (&t); - - printf ("%d/%02d/%02d %02d:%02d:%02d", - 1900 + tm->tm_year, tm->tm_mon+1, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec); -} - -char * -isodate_from_time_t (time_t t) -{ - struct tm *tm; - static char isotime [40]; - - tm = localtime (&t); - strftime (isotime, sizeof (isotime)-1, "%Y%m%dT%H%M%S", tm); - return isotime; -} - -time_t -time_add_minutes (time_t time, int minutes) -{ - struct tm *tm = localtime (&time); - time_t new_time; - - tm->tm_min += minutes; - if ((new_time = mktime (tm)) == -1) { - g_message ("time_add_minutes(): mktime() could not handle " - "adding %d minutes with\n", minutes); - print_time_t (time); - printf ("\n"); - return time; - } - return new_time; -} - -/* Adds a day onto the time, using local time. - Note that if clocks go forward due to daylight savings time, there are - some non-existent local times, so the hour may be changed to make it a - valid time. This also means that it may not be wise to keep calling - time_add_day() to step through a certain period - if the hour gets changed - to make it valid time, any further calls to time_add_day() will also return - this hour, which may not be what you want. */ -time_t -time_add_day (time_t time, int days) -{ - struct tm *tm = localtime (&time); - time_t new_time; -#if 0 - int dst_flag = tm->tm_isdst; -#endif - - tm->tm_mday += days; - tm->tm_isdst = -1; - - if ((new_time = mktime (tm)) == -1) { - g_message ("time_add_day(): mktime() could not handling adding %d days with\n", - days); - print_time_t (time); - printf ("\n"); - return time; - } - -#if 0 - /* I don't know what this is for. See also time_day_begin() and - time_day_end(). - Damon. */ - if (dst_flag > tm->tm_isdst) { - tm->tm_hour++; - new_time += 3600; - } else if (dst_flag < tm->tm_isdst) { - tm->tm_hour--; - new_time -= 3600; - } -#endif - - return new_time; -} - -time_t -time_add_week (time_t time, int weeks) -{ - return time_add_day (time, weeks * 7); -} - -time_t -time_add_month (time_t time, int months) -{ - struct tm *tm = localtime (&time); - time_t new_time; - int mday; - - mday = tm->tm_mday; - - tm->tm_mon += months; - tm->tm_isdst = -1; - if ((new_time = mktime (tm)) == -1) { - g_message ("time_add_month(): mktime() could not handling adding %d months with\n", - months); - print_time_t (time); - printf ("\n"); - return time; - } - tm = localtime (&new_time); - if (tm->tm_mday < mday) { - tm->tm_mon--; - tm->tm_mday = time_days_in_month (tm->tm_year+1900, tm->tm_mon); - return new_time = mktime (tm); - } - else - return new_time; -} - -time_t -time_add_year (time_t time, int years) -{ - struct tm *tm = localtime (&time); - time_t new_time; - - tm->tm_year += years; - if ((new_time = mktime (tm)) == -1) { - g_message ("time_add_year(): mktime() could not handling adding %d years with\n", - years); - print_time_t (time); - printf ("\n"); - return time; - } - return new_time; -} - -/* Number of days in a month, for normal and leap years */ -static const int days_in_month[2][12] = { - { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, - { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } -}; - -/* Returns whether the specified year is a leap year */ -static int -is_leap_year (int year) -{ - if (year <= 1752) - return !(year % 4); - else - return (!(year % 4) && (year % 100)) || !(year % 400); -} - -int -time_days_in_month (int year, int month) -{ - g_return_val_if_fail (year >= 1900, 0); - g_return_val_if_fail ((month >= 0) && (month < 12), 0); - - return days_in_month [is_leap_year (year)][month]; -} - -time_t -time_from_day (int year, int month, int day) -{ - struct tm tm; - - memset (&tm, 0, sizeof (tm)); - tm.tm_year = year - 1900; - tm.tm_mon = month; - tm.tm_mday = day; - tm.tm_isdst = -1; - - return mktime (&tm); -} - -time_t -time_year_begin (time_t t) -{ - struct tm tm; - - tm = *localtime (&t); - tm.tm_hour = 0; - tm.tm_min = 0; - tm.tm_sec = 0; - tm.tm_mon = 0; - tm.tm_mday = 1; - tm.tm_isdst = -1; - - return mktime (&tm); -} - -time_t -time_year_end (time_t t) -{ - struct tm tm; - - tm = *localtime (&t); - tm.tm_hour = 0; - tm.tm_min = 0; - tm.tm_sec = 0; - tm.tm_mon = 0; - tm.tm_mday = 1; - tm.tm_year++; - tm.tm_isdst = -1; - - return mktime (&tm); -} - -time_t -time_month_begin (time_t t) -{ - struct tm tm; - - tm = *localtime (&t); - tm.tm_hour = 0; - tm.tm_min = 0; - tm.tm_sec = 0; - tm.tm_mday = 1; - tm.tm_isdst = -1; - - return mktime (&tm); -} - -time_t -time_month_end (time_t t) -{ - struct tm tm; - - tm = *localtime (&t); - tm.tm_hour = 0; - tm.tm_min = 0; - tm.tm_sec = 0; - tm.tm_mday = 1; - tm.tm_mon++; - tm.tm_isdst = -1; - - return mktime (&tm); -} - -time_t -time_week_begin (time_t t) -{ - struct tm tm; - - /* FIXME: make it take week_starts_on_monday into account */ - - tm = *localtime (&t); - tm.tm_hour = 0; - tm.tm_min = 0; - tm.tm_sec = 0; - tm.tm_mday -= tm.tm_wday; - tm.tm_isdst = -1; - - return mktime (&tm); -} - -time_t -time_week_end (time_t t) -{ - struct tm tm; - - /* FIXME: make it take week_starts_on_monday into account */ - - tm = *localtime (&t); - tm.tm_hour = 0; - tm.tm_min = 0; - tm.tm_sec = 0; - tm.tm_mday += 7 - tm.tm_wday; - tm.tm_isdst = -1; - - return mktime (&tm); -} - -/* Returns the start of the day, according to the local time. */ -time_t -time_day_begin (time_t t) -{ - struct tm tm; - - tm = *localtime (&t); - tm.tm_hour = 0; - tm.tm_min = 0; - tm.tm_sec = 0; - tm.tm_isdst = -1; - - return mktime (&tm); -} - -/* Returns the end of the day, according to the local time. */ -time_t -time_day_end (time_t t) -{ - struct tm tm; - - tm = *localtime (&t); - tm.tm_mday++; - tm.tm_hour = 0; - tm.tm_min = 0; - tm.tm_sec = 0; - tm.tm_isdst = -1; - - return mktime (&tm); -} diff --git a/calendar/cal-util/timeutil.h b/calendar/cal-util/timeutil.h deleted file mode 100644 index 730c7dc089..0000000000 --- a/calendar/cal-util/timeutil.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Miscellaneous time-related utilities - * - * Copyright (C) 1998 The Free Software Foundation - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Federico Mena <federico@ximian.com> - * Miguel de Icaza <miguel@ximian.com> - */ - -#ifndef TIMEUTIL_H -#define TIMEUTIL_H - - -#include <time.h> -#include <ical.h> - - -char *isodate_from_time_t (time_t t); - -time_t time_add_minutes (time_t time, int minutes); -time_t time_add_day (time_t time, int days); -time_t time_add_week (time_t time, int weeks); -time_t time_add_month (time_t time, int months); -time_t time_add_year (time_t time, int years); - - -/* Returns the number of days in the specified month. Years are full years (starting from year 1). - * Months are in [0, 11]. - */ -int time_days_in_month (int year, int month); - -/* Converts the specified date to a time_t at the start of the specified day. Years are full years - * (starting from year 1). Months are in [0, 11]. Days are 1-based. - */ -time_t time_from_day (int year, int month, int day); - -/* For the functions below, time ranges are considered to contain the start time, but not the end - * time. - */ - -/* These two functions take a time value and return the beginning or end of the corresponding year, - * respectively. - */ -time_t time_year_begin (time_t t); -time_t time_year_end (time_t t); - -/* These two functions take a time value and return the beginning or end of the corresponding month, - * respectively. - */ -time_t time_month_begin (time_t t); -time_t time_month_end (time_t t); - -/* These functions take a time value and return the beginning or end of the corresponding week, - * respectively. This takes into account the global week_starts_on_monday flag. - */ -time_t time_week_begin (time_t t); -time_t time_week_end (time_t t); - -/* These two functions take a time value and return the beginning or end of the corresponding day, - * respectively. - */ -time_t time_day_begin (time_t t); -time_t time_day_end (time_t t); - -void print_time_t (time_t t); - - -#endif diff --git a/calendar/conduits/.cvsignore b/calendar/conduits/.cvsignore deleted file mode 100644 index b840c21800..0000000000 --- a/calendar/conduits/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile.in -Makefile
\ No newline at end of file diff --git a/calendar/conduits/Makefile.am b/calendar/conduits/Makefile.am deleted file mode 100644 index 906ea61971..0000000000 --- a/calendar/conduits/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -SUBDIRS = calendar todo diff --git a/calendar/conduits/calendar/.cvsignore b/calendar/conduits/calendar/.cvsignore deleted file mode 100644 index e8ba6ad844..0000000000 --- a/calendar/conduits/calendar/.cvsignore +++ /dev/null @@ -1,9 +0,0 @@ -Makefile.in -Makefile -.deps -e-calendar.conduit -*.lo -.libs -libecalendar_conduit.la -e-calendar-conduit-control-applet -e-calendar-conduit-control-applet.desktop diff --git a/calendar/conduits/calendar/Makefile.am b/calendar/conduits/calendar/Makefile.am deleted file mode 100644 index 9349cd518b..0000000000 --- a/calendar/conduits/calendar/Makefile.am +++ /dev/null @@ -1,71 +0,0 @@ -INCLUDES = \ - -I$(top_srcdir) \ - -I$(top_srcdir)/calendar \ - -I$(top_srcdir)/libical/src/libical \ - -I$(top_builddir)/libical/src/libical \ - -I$(top_builddir)/e-util \ - $(BONOBO_GNOME_CFLAGS) \ - $(PISOCK_INCLUDEDIR) \ - $(GNOME_PILOT_CFLAGS) - -# Calendar Capplet -bin_PROGRAMS = e-calendar-conduit-control-applet - -e_calendar_conduit_control_applet_SOURCES = calendar-conduit-control-applet.c - -e_calendar_conduit_control_applet_LDADD = \ - $(CAPPLET_LIBS) \ - $(GNOME_LIBDIR) \ - $(GNOME_PILOT_LIBS) \ - $(PISOCK_LIBS) \ - $(GNOME_CAPPLET_LIBS) \ - $(BONOBO_GNOME_LIBS) \ - $(GNOME_XML_LIB) \ - $(GNOMEUI_LIBS) \ - $(INTLLIBS) - -# Calendar Conduit -e_calendar_conduitsdir=$(libdir)/gnome-pilot/conduits -e_calendar_conduits_LTLIBRARIES = libecalendar_conduit.la - -libecalendar_conduit_la_SOURCES = \ - calendar-conduit.c \ - calendar-conduit.h \ - calendar-conduit-config.h - -libecalendar_conduit_la_LDFLAGS = -module -avoid-version -libecalendar_conduit_la_LIBADD = \ - $(top_builddir)/calendar/cal-client/libcal-client-static.la \ - $(top_builddir)/calendar/cal-util/libcal-util-static.la \ - $(top_builddir)/libversit/libversit.la \ - $(top_builddir)/libical/src/libical/libical-static.la \ - $(top_builddir)/e-util/libeconduit-static.la \ - $(BONOBO_GNOME_LIBS) \ - $(PISOCK_LIBS) \ - $(GNOME_LIBDIR) \ - $(GNOME_LIBS) - -e-calendar.conduit: e-calendar.conduit.in Makefile - sed -e 's^\@prefix\@^$(prefix)^g' < $(srcdir)/e-calendar.conduit.in > e-calendar.conduit.tmp \ - && mv e-calendar.conduit.tmp e-calendar.conduit - -ccenterdir = $(datadir)/control-center -ccenterPalmPilotdir = $(ccenterdir)/Peripherals -ccenterConduitsdir = $(ccenterPalmPilotdir)/Conduits -ccenterConduits_in_files = e-calendar-conduit-control-applet.desktop.in -ccenterConduits_DATA = $(ccenterConduits_in_files:.desktop.in=.desktop) -@XML_I18N_MERGE_DESKTOP_RULE@ - -panelConduitsdir = $(datadir)/gnome/apps/Settings/Peripherals/Conduits -panelConduits_DATA = $(ccenterConduits_DATA) - -Conduitdir = $(datadir)/gnome-pilot/conduits/ -Conduit_DATA = e-calendar.conduit - -EXTRA_DIST = \ - e-calendar.conduit.in \ - $(ccenterConduits_in_files) - -install-data-local: - $(mkinstalldirs) $(ccenterConduitsdir) - $(mkinstalldirs) $(Conduitdir) diff --git a/calendar/conduits/calendar/calendar-conduit-config.h b/calendar/conduits/calendar/calendar-conduit-config.h deleted file mode 100644 index d0ba28dbb1..0000000000 --- a/calendar/conduits/calendar/calendar-conduit-config.h +++ /dev/null @@ -1,120 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Evolution calendar - Calendar Conduit Configuration - * - * Copyright (C) 1998 Free Software Foundation - * Copyright (C) 2000 Helix Code, Inc. - * - * Authors: Eskil Heyn Olsen <deity@eskil.dk> - * JP Rosevear <jpr@helixcode.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef __CAL_CONDUIT_CONFIG_H__ -#define __CAL_CONDUIT_CONFIG_H__ - -#include <gnome.h> -#include <libgpilotdCM/gnome-pilot-conduit-management.h> -#include <libgpilotdCM/gnome-pilot-conduit-config.h> - -/* Configuration info */ -typedef struct _ECalConduitCfg ECalConduitCfg; -struct _ECalConduitCfg { - gboolean open_secret; - guint32 pilot_id; - GnomePilotConduitSyncType sync_type; /* only used by capplet */ -}; - -#ifdef CAL_CONFIG_LOAD -/* Loads the configuration data */ -static void -calconduit_load_configuration (ECalConduitCfg **c, guint32 pilot_id) -{ - gchar prefix[256]; - g_snprintf (prefix, 255, "/gnome-pilot.d/e-todo-conduit/Pilot_%u/", - pilot_id); - - *c = g_new0 (ECalConduitCfg,1); - g_assert (*c != NULL); - - gnome_config_push_prefix (prefix); - (*c)->open_secret = gnome_config_get_bool ("open_secret=FALSE"); - - /* set in capplets main */ - (*c)->sync_type = GnomePilotConduitSyncTypeCustom; - gnome_config_pop_prefix (); - - (*c)->pilot_id = pilot_id; -} -#endif - -#ifdef CAL_CONFIG_SAVE -/* Saves the configuration data. */ -static void -calconduit_save_configuration (ECalConduitCfg *c) -{ - gchar prefix[256]; - - g_snprintf (prefix, 255, "/gnome-pilot.d/e-todo-conduit/Pilot_%u/", - c->pilot_id); - - gnome_config_push_prefix (prefix); - gnome_config_set_bool ("open_secret", c->open_secret); - gnome_config_pop_prefix (); - - gnome_config_sync (); - gnome_config_drop_all (); -} -#endif - -#ifdef CAL_CONFIG_DUPE -/* Creates a duplicate of the configuration data */ -static ECalConduitCfg* -calconduit_dupe_configuration (ECalConduitCfg *c) -{ - ECalConduitCfg *retval; - - g_return_val_if_fail (c != NULL, NULL); - - retval = g_new0 (ECalConduitCfg, 1); - retval->sync_type = c->sync_type; - retval->open_secret = c->open_secret; - retval->pilot_id = c->pilot_id; - - return retval; -} -#endif - -#ifdef CAL_CONFIG_DESTROY -/* Destroy a configuration */ -static void -calconduit_destroy_configuration (ECalConduitCfg **c) -{ - g_return_if_fail (c != NULL); - g_return_if_fail (*c != NULL); - - g_free (*c); - *c = NULL; -} -#endif - -#endif __CAL_CONDUIT_CONFIG_H__ - - - - - - - diff --git a/calendar/conduits/calendar/calendar-conduit-control-applet.c b/calendar/conduits/calendar/calendar-conduit-control-applet.c deleted file mode 100644 index ecd8d84e65..0000000000 --- a/calendar/conduits/calendar/calendar-conduit-control-applet.c +++ /dev/null @@ -1,342 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Evolution calendar - Calendar Conduit Capplet - * - * Copyright (C) 1998 Free Software Foundation - * Copyright (C) 2000 Helix Code, Inc. - * - * Authors: Eskil Heyn Olsen <deity@eskil.dk> - * JP Rosevear <jpr@helixcode.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#include <pwd.h> -#include <sys/types.h> -#include <signal.h> -#include <gnome.h> - -#include <config.h> -#include <capplet-widget.h> - -#include <gpilotd/gnome-pilot-client.h> - -#define CAL_CONFIG_LOAD 1 -#define CAL_CONFIG_SAVE 1 -#define CAL_CONFIG_DUPE 1 -#define CAL_CONFIG_DESTROY 1 -#include <calendar-conduit-config.h> -#undef CAL_CONFIG_LOAD -#undef CAL_CONFIG_SAVE -#undef CAL_CONFIG_DUPE -#undef CAL_CONFIG_DESTROY - -/* tell changes callbacks to ignore changes or not */ -static gboolean ignore_changes=FALSE; - -/* capplet widget */ -static GtkWidget *capplet=NULL; - -/* host/device/pilot configuration windows */ -GtkWidget *cfgOptionsWindow=NULL; -GtkWidget *cfgStateWindow=NULL; -GtkWidget *dialogWindow=NULL; - -gboolean activated,org_activation_state; -GnomePilotConduitManagement *conduit; -GnomePilotConduitConfig *conduit_config; -ECalConduitCfg *origState = NULL; -ECalConduitCfg *curState = NULL; - -static void doTrySettings(GtkWidget *widget, ECalConduitCfg *c); -static void doRevertSettings(GtkWidget *widget, ECalConduitCfg *c); -static void doSaveSettings(GtkWidget *widget, ECalConduitCfg *c); - -static void setStateCfg (GtkWidget *w, ECalConduitCfg *c); - -gint pilotId; -static GnomePilotClient *gpc; - - - -/* This array must be in the same order as enumerations - in GnomePilotConduitSyncType as they are used as index. - Custom type implies Disabled state. -*/ -static gchar* sync_options[] ={ N_("Disabled"), - N_("Synchronize"), - N_("Copy From Pilot"), - N_("Copy To Pilot"), - N_("Merge From Pilot"), - N_("Merge To Pilot")}; -#define SYNC_OPTIONS_COUNT 6 - -static void -doTrySettings (GtkWidget *widget, ECalConduitCfg *c) -{ - if (c->sync_type != GnomePilotConduitSyncTypeCustom) - gnome_pilot_conduit_config_enable_with_first_sync (conduit_config, - c->sync_type, - c->sync_type, - TRUE); - else - gnome_pilot_conduit_config_disable (conduit_config); - - calconduit_save_configuration (c); -} - -static void -doRevertSettings (GtkWidget *widget, ECalConduitCfg *c) -{ - activated = org_activation_state; - *c = *origState; - setStateCfg (cfgStateWindow, c); - doTrySettings (widget, c); -} - -static void -doSaveSettings (GtkWidget *widget, ECalConduitCfg *c) -{ - *origState = *c; - doTrySettings (widget, c); -} - - -static void -doHelp (GtkWidget *widget, gpointer data) -{ - GtkWidget *about; - const gchar *authors[] = { - _("JP Rosevear <jpr@helixcode.com>"), - "", _("Original Author:"), - _("Eskil Heyn Olsen <deity@eskil.dk>"), - NULL}; - - about = gnome_about_new ( - _("Evolution Calendar Conduit"), VERSION, - _("(C) 1998-2000 the Free Software Foundation and Helix Code"), - authors, - _("Configuration utility for the evolution calendar conduit.\n"), - _("gnome-unknown.xpm")); - gtk_widget_show (about); - - return; -} - - -/* called by the sync_type GtkOptionMenu */ -static void -activate_sync_type (GtkMenuItem *widget, gpointer data) -{ - curState->sync_type = GPOINTER_TO_INT (data); - if (!ignore_changes) - capplet_widget_state_changed (CAPPLET_WIDGET (capplet), TRUE); -} - - -static GtkWidget * -createStateCfgWindow(void) -{ - GtkWidget *vbox, *table; - GtkWidget *label; - GtkWidget *optionMenu,*menuItem; - GtkMenu *menu; - gint i; - - vbox = gtk_vbox_new(FALSE, GNOME_PAD); - - table = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, GNOME_PAD); - - label = gtk_label_new(_("Synchronize Action")); - gtk_box_pack_start(GTK_BOX(table), label, FALSE, FALSE, GNOME_PAD); - - optionMenu=gtk_option_menu_new(); - gtk_object_set_data(GTK_OBJECT(vbox), "conduit_state", optionMenu); - menu = GTK_MENU(gtk_menu_new()); - - for (i=0; i<SYNC_OPTIONS_COUNT;i++) { - sync_options[i]=_(sync_options[i]); - menuItem = gtk_menu_item_new_with_label(sync_options[i]); - gtk_widget_show(menuItem); - gtk_signal_connect(GTK_OBJECT(menuItem),"activate", - GTK_SIGNAL_FUNC(activate_sync_type), - GINT_TO_POINTER(i)); - gtk_menu_append(menu,menuItem); - } - - gtk_option_menu_set_menu(GTK_OPTION_MENU(optionMenu),GTK_WIDGET(menu)); - gtk_box_pack_start(GTK_BOX(table), optionMenu, FALSE, FALSE, 0); - - return vbox; -} - - -static void -setStateCfg (GtkWidget *w, ECalConduitCfg *c) -{ - GtkOptionMenu *optionMenu; - GtkMenu *menu; - - optionMenu = gtk_object_get_data (GTK_OBJECT(w), "conduit_state"); - g_assert (optionMenu != NULL); - menu = GTK_MENU (gtk_option_menu_get_menu (optionMenu)); - - ignore_changes = TRUE; - /* Here were are relying on the items in menu being the same - order as in GnomePilotConduitSyncType. */ - gtk_option_menu_set_history (optionMenu, (int) c->sync_type); - ignore_changes = FALSE; -} - - -static void -pilot_capplet_setup(void) -{ - GtkWidget *frame, *table; - - capplet = capplet_widget_new(); - - table = gtk_table_new(1, 2, FALSE); - gtk_container_border_width(GTK_CONTAINER(table), GNOME_PAD); - gtk_container_add(GTK_CONTAINER(capplet), table); - - frame = gtk_frame_new(_("Conduit state")); - gtk_container_border_width(GTK_CONTAINER(frame), GNOME_PAD_SMALL); - gtk_table_attach_defaults(GTK_TABLE(table), frame, 0, 1, 0, 1); - cfgStateWindow = createStateCfgWindow(); - gtk_container_add(GTK_CONTAINER(frame), cfgStateWindow); - - gtk_signal_connect(GTK_OBJECT(capplet), "try", - GTK_SIGNAL_FUNC(doTrySettings), curState); - gtk_signal_connect(GTK_OBJECT(capplet), "revert", - GTK_SIGNAL_FUNC(doRevertSettings), curState); - gtk_signal_connect(GTK_OBJECT(capplet), "ok", - GTK_SIGNAL_FUNC(doSaveSettings), curState); - gtk_signal_connect(GTK_OBJECT(capplet), "help", - GTK_SIGNAL_FUNC(doHelp), NULL); - - - setStateCfg (cfgStateWindow, curState); - - gtk_widget_show_all (capplet); -} - - -static void -run_error_dialog(gchar *mesg,...) -{ - char tmp[80]; - va_list ap; - - va_start(ap,mesg); - vsnprintf(tmp,79,mesg,ap); - dialogWindow = gnome_message_box_new(mesg,GNOME_MESSAGE_BOX_ERROR,GNOME_STOCK_BUTTON_OK,NULL); - gnome_dialog_run_and_close(GNOME_DIALOG(dialogWindow)); - va_end(ap); -} - - -static gint -get_pilot_id_from_gpilotd() -{ - GList *pilots=NULL; - gint pilot; - int i,err; - - i=0; - /* we don't worry about leaking here, so pilots isn't freed */ - switch(err = gnome_pilot_client_get_pilots(gpc,&pilots)) { - case GPILOTD_OK: { - if(pilots) { - for(i=0;i<g_list_length(pilots);i++) { - g_message("pilot %d = \"%s\"",i,(gchar*)g_list_nth(pilots,i)->data); - } - if(i==0) { - run_error_dialog(_("No pilot configured, please choose the\n'Pilot Link Properties' capplet first.")); - return -1; - } else { - gnome_pilot_client_get_pilot_id_by_name(gpc, - pilots->data, /* this is the first pilot */ - &pilot); - if(i>1) { - g_message("too many pilots..."); - /* need a choose here */ - } - return pilot; - } - } else { - run_error_dialog(_("No pilot configured, please choose the\n'Pilot Link Properties' capplet first.")); - return -1; - } - break; - } - case GPILOTD_ERR_NOT_CONNECTED: - run_error_dialog(_("Not connected to the gnome-pilot daemon")); - return -1; - break; - default: - g_warning("gnome_pilot_client_get_pilot_ids(...) = %d",err); - run_error_dialog(_("An error occured when trying to fetch\npilot list from the gnome-pilot daemon")); - return -1; - break; - } -} - - -int -main (int argc, char *argv[]) -{ - g_log_set_always_fatal (G_LOG_LEVEL_ERROR | - G_LOG_LEVEL_CRITICAL | - G_LOG_LEVEL_WARNING); - - /* Init capplet */ - gnome_capplet_init ("Evolution Calendar conduit control applet", - NULL, argc, argv, - NULL, 0, NULL); - - /* Setup Client */ - gpc = gnome_pilot_client_new (); - gnome_pilot_client_connect_to_daemon (gpc); - pilotId = get_pilot_id_from_gpilotd (); - if (!pilotId) - return -1; - - - /* Put all code to set things up in here */ - conduit = gnome_pilot_conduit_management_new ("e_calendar_conduit", GNOME_PILOT_CONDUIT_MGMT_ID); - if (conduit == NULL) - return -1; - - calconduit_load_configuration (&origState, pilotId); - conduit_config = gnome_pilot_conduit_config_new (conduit, pilotId); - org_activation_state = activated = - gnome_pilot_conduit_config_is_enabled (conduit_config, - &origState->sync_type); - - curState = calconduit_dupe_configuration (origState); - - pilot_capplet_setup (); - - /* Done setting up, now run main loop */ - capplet_gtk_main(); - - /* Clean up */ - gnome_pilot_conduit_management_destroy (conduit); - calconduit_destroy_configuration (&origState); - calconduit_destroy_configuration (&curState); - - return 0; -} diff --git a/calendar/conduits/calendar/calendar-conduit.c b/calendar/conduits/calendar/calendar-conduit.c deleted file mode 100644 index 155813d65e..0000000000 --- a/calendar/conduits/calendar/calendar-conduit.c +++ /dev/null @@ -1,1198 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Evolution calendar - Calendar Conduit - * - * Copyright (C) 1998 Free Software Foundation - * Copyright (C) 2000 Helix Code, Inc. - * - * Authors: Eskil Heyn Olsen <deity@eskil.dk> - * JP Rosevear <jpr@helixcode.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#include <config.h> - -#include <liboaf/liboaf.h> -#include <bonobo.h> -#include <cal-client/cal-client-types.h> -#include <cal-client/cal-client.h> -#include <cal-util/timeutil.h> -#include <pi-source.h> -#include <pi-socket.h> -#include <pi-file.h> -#include <pi-dlp.h> -#include <libical/src/libical/icaltypes.h> -#include <e-pilot-util.h> - -#define CAL_CONFIG_LOAD 1 -#define CAL_CONFIG_DESTROY 1 -#include <calendar-conduit-config.h> -#undef CAL_CONFIG_LOAD -#undef CAL_CONFIG_DESTROY - -#include <calendar-conduit.h> - -GnomePilotConduit * conduit_get_gpilot_conduit (guint32); -void conduit_destroy_gpilot_conduit (GnomePilotConduit*); - -#define CONDUIT_VERSION "0.1.5" -#ifdef G_LOG_DOMAIN -#undef G_LOG_DOMAIN -#endif -#define G_LOG_DOMAIN "ecalconduit" - -#define DEBUG_CALCONDUIT 1 -/* #undef DEBUG_CALCONDUIT */ - -#ifdef DEBUG_CALCONDUIT -#define LOG(e...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, e) -#else -#define LOG(e...) -#endif - -#define WARN(e...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, e) -#define INFO(e...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, e) - -/* Debug routines */ -static char * -print_local (ECalLocalRecord *local) -{ - static char buff[ 4096 ]; - - if (local == NULL) { - sprintf (buff, "[NULL]"); - return buff; - } - - if (local->appt && local->appt->description) { - g_snprintf (buff, 4096, "[%ld %ld '%s' '%s']", - mktime (&local->appt->begin), - mktime (&local->appt->end), - local->appt->description ? - local->appt->description : "", - local->appt->note ? - local->appt->note : ""); - return buff; - } - - return ""; -} - -static char *print_remote (GnomePilotRecord *remote) -{ - static char buff[ 4096 ]; - struct Appointment appt; - - if (remote == NULL) { - sprintf (buff, "[NULL]"); - return buff; - } - - memset (&appt, 0, sizeof (struct Appointment)); - unpack_Appointment (&appt, remote->record, remote->length); - - g_snprintf (buff, 4096, "[%ld %ld '%s' '%s']", - mktime (&appt.begin), - mktime (&appt.end), - appt.description ? - appt.description : "", - appt.note ? - appt.note : ""); - - return buff; -} - -/* Context Routines */ -static ECalConduitContext * -e_calendar_context_new (guint32 pilot_id) -{ - ECalConduitContext *ctxt = g_new0 (ECalConduitContext, 1); - - calconduit_load_configuration (&ctxt->cfg, pilot_id); - - return ctxt; -} - -static void -e_calendar_context_foreach_change (gpointer key, gpointer value, gpointer data) -{ - g_free (key); -} - -static void -e_calendar_context_destroy (ECalConduitContext *ctxt) -{ - g_return_if_fail (ctxt != NULL); - - if (ctxt->cfg != NULL) - calconduit_destroy_configuration (&ctxt->cfg); - - if (ctxt->client != NULL) - gtk_object_unref (GTK_OBJECT (ctxt->client)); - - if (ctxt->calendar_file) - g_free (ctxt->calendar_file); - - if (ctxt->uids) - cal_obj_uid_list_free (ctxt->uids); - - if (ctxt->changed_hash) - g_hash_table_foreach (ctxt->changed_hash, e_calendar_context_foreach_change, NULL); - - if (ctxt->changed) - cal_client_change_list_free (ctxt->changed); - - if (ctxt->map) - e_pilot_map_destroy (ctxt->map); - - g_free (ctxt); -} - -/* Calendar Server routines */ -static void -start_calendar_server_cb (CalClient *cal_client, - CalClientOpenStatus status, - gpointer data) -{ - ECalConduitContext *ctxt; - - ctxt = data; - - LOG (" entering start_calendar_server_cb\n"); - - if (status == CAL_CLIENT_OPEN_SUCCESS) { - ctxt->calendar_open_success = TRUE; - LOG (" success\n"); - } else - LOG (" open of calendar failed\n"); - - gtk_main_quit (); /* end the sub event loop */ -} - -static int -start_calendar_server (ECalConduitContext *ctxt) -{ - - g_return_val_if_fail (ctxt != NULL, -2); - - ctxt->client = cal_client_new (); - - /* FIX ME */ - ctxt->calendar_file = g_concat_dir_and_file (g_get_home_dir (), - "evolution/local/Calendar/calendar.ics"); - - gtk_signal_connect (GTK_OBJECT (ctxt->client), "cal_opened", - start_calendar_server_cb, ctxt); - - LOG (" calling cal_client_open_calendar\n"); - if (!cal_client_open_calendar (ctxt->client, ctxt->calendar_file, FALSE)) - return -1; - - /* run a sub event loop to turn cal-client's async load - notification into a synchronous call */ - gtk_main (); - - if (ctxt->calendar_open_success) - return 0; - - return -1; -} - -/* Utility routines */ -static char * -map_name (ECalConduitContext *ctxt) -{ - char *filename; - - filename = g_strdup_printf ("%s/evolution/local/Calendar/pilot-map-calendar-%d.xml", g_get_home_dir (), ctxt->cfg->pilot_id); - - return filename; -} - -static icalrecurrencetype_weekday -get_ical_day (int day) -{ - switch (day) { - case 0: - return ICAL_SUNDAY_WEEKDAY; - case 1: - return ICAL_MONDAY_WEEKDAY; - case 2: - return ICAL_TUESDAY_WEEKDAY; - case 3: - return ICAL_WEDNESDAY_WEEKDAY; - case 4: - return ICAL_THURSDAY_WEEKDAY; - case 5: - return ICAL_FRIDAY_WEEKDAY; - case 6: - return ICAL_SATURDAY_WEEKDAY; - } - - return ICAL_NO_WEEKDAY; -} - -static int -get_pilot_day (icalrecurrencetype_weekday wd) -{ - switch (wd) { - case ICAL_SUNDAY_WEEKDAY: - return 0; - case ICAL_MONDAY_WEEKDAY: - return 1; - case ICAL_TUESDAY_WEEKDAY: - return 2; - case ICAL_WEDNESDAY_WEEKDAY: - return 3; - case ICAL_THURSDAY_WEEKDAY: - return 4; - case ICAL_FRIDAY_WEEKDAY: - return 5; - case ICAL_SATURDAY_WEEKDAY: - return 6; - default: - return -1; - } -} - -static gboolean -is_empty_time (struct tm time) -{ - if (time.tm_sec || time.tm_min || time.tm_hour - || time.tm_mday || time.tm_mon || time.tm_year) - return FALSE; - - return TRUE; -} - -static short -nth_weekday (int pos, icalrecurrencetype_weekday weekday) -{ - g_assert (pos > 0 && pos <= 5); - - return (pos << 3) | (int) weekday; -} - -static GList * -next_changed_item (ECalConduitContext *ctxt, GList *changes) -{ - CalClientChange *ccc; - GList *l; - - for (l = changes; l != NULL; l = l->next) { - const char *uid; - - ccc = l->data; - - cal_component_get_uid (ccc->comp, &uid); - if (g_hash_table_lookup (ctxt->changed_hash, uid)) - return l; - } - - return NULL; -} - -static void -compute_status (ECalConduitContext *ctxt, ECalLocalRecord *local, const char *uid) -{ - CalClientChange *ccc; - - local->local.archived = FALSE; - local->local.secret = FALSE; - - ccc = g_hash_table_lookup (ctxt->changed_hash, uid); - - if (ccc == NULL) { - local->local.attr = GnomePilotRecordNothing; - return; - } - - switch (ccc->type) { - case CAL_CLIENT_CHANGE_ADDED: - local->local.attr = GnomePilotRecordNew; - break; - - case CAL_CLIENT_CHANGE_MODIFIED: - local->local.attr = GnomePilotRecordModified; - break; - - case CAL_CLIENT_CHANGE_DELETED: - local->local.attr = GnomePilotRecordDeleted; - break; - } -} - -static GnomePilotRecord -local_record_to_pilot_record (ECalLocalRecord *local, - ECalConduitContext *ctxt) -{ - GnomePilotRecord p; - - g_assert (local->comp != NULL); - g_assert (local->appt != NULL ); - - p.ID = local->local.ID; - p.category = 0; - p.attr = local->local.attr; - p.archived = local->local.archived; - p.secret = local->local.secret; - - /* Generate pilot record structure */ - p.record = g_new0 (char, 0xffff); - p.length = pack_Appointment (local->appt, p.record, 0xffff); - - return p; -} - -/* - * converts a CalComponent object to a ECalLocalRecord - */ -static void -local_record_from_comp (ECalLocalRecord *local, CalComponent *comp, ECalConduitContext *ctxt) -{ - const char *uid; - CalComponentText summary; - GSList *d_list = NULL; - CalComponentText *description; - CalComponentDateTime dt; - time_t dt_time; - CalComponentClassification classif; - int i; - - g_return_if_fail (local != NULL); - g_return_if_fail (comp != NULL); - - local->comp = comp; - gtk_object_ref (GTK_OBJECT (comp)); - - cal_component_get_uid (local->comp, &uid); - local->local.ID = e_pilot_map_lookup_pid (ctxt->map, uid); - compute_status (ctxt, local, uid); - - local->appt = g_new0 (struct Appointment, 1); - - /* STOP: don't replace these with g_strdup, since free_Appointment - uses free to deallocate */ - cal_component_get_summary (comp, &summary); - if (summary.value) - local->appt->description = e_pilot_utf8_to_pchar (summary.value); - - cal_component_get_description_list (comp, &d_list); - if (d_list) { - description = (CalComponentText *) d_list->data; - if (description && description->value) - local->appt->note = e_pilot_utf8_to_pchar (description->value); - else - local->appt->note = NULL; - } else { - local->appt->note = NULL; - } - - cal_component_get_dtstart (comp, &dt); - if (dt.value) { - dt_time = icaltime_as_timet (*dt.value); - - local->appt->begin = *localtime (&dt_time); - } - - cal_component_get_dtend (comp, &dt); - if (dt.value && time_add_day (dt_time, 1) != icaltime_as_timet (*dt.value)) { - dt_time = icaltime_as_timet (*dt.value); - - local->appt->end = *localtime (&dt_time); - local->appt->event = 0; - } else { - local->appt->event = 1; - } - - /* Recurrence Rules */ - local->appt->repeatType = repeatNone; - - if (cal_component_has_rrules (comp)) { - GSList *list; - struct icalrecurrencetype *recur; - - cal_component_get_rrule_list (comp, &list); - recur = list->data; - - switch (recur->freq) { - case ICAL_DAILY_RECURRENCE: - local->appt->repeatType = repeatDaily; - break; - case ICAL_WEEKLY_RECURRENCE: - local->appt->repeatType = repeatWeekly; - for (i = 0; i <= 7 && recur->by_day[i] != ICAL_RECURRENCE_ARRAY_MAX; i++) { - icalrecurrencetype_weekday wd; - - wd = icalrecurrencetype_day_day_of_week (recur->by_day[i]); - local->appt->repeatDays[get_pilot_day (wd)] = 1; - } - - break; - case ICAL_MONTHLY_RECURRENCE: - if (recur->by_month_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { - local->appt->repeatType = repeatMonthlyByDate; - break; - } - - /* FIX ME Not going to work with -ve by_day */ - local->appt->repeatType = repeatMonthlyByDay; - switch (icalrecurrencetype_day_position (recur->by_day[0])) { - case 1: - local->appt->repeatDay = dom1stSun; - break; - case 2: - local->appt->repeatDay = dom2ndSun; - break; - case 3: - local->appt->repeatDay = dom3rdSun; - break; - case 4: - local->appt->repeatDay = dom4thSun; - break; - case 5: - local->appt->repeatDay = domLastSun; - break; - } - local->appt->repeatDay += get_pilot_day (icalrecurrencetype_day_day_of_week (recur->by_day[0])); - break; - case ICAL_YEARLY_RECURRENCE: - local->appt->repeatType = repeatYearly; - break; - default: - break; - } - - if (local->appt->repeatType != repeatNone) { - local->appt->repeatFrequency = recur->interval; - } - - if (icaltime_is_null_time (recur->until)) { - local->appt->repeatForever = 1; - } else { - local->appt->repeatForever = 0; - dt_time = icaltime_as_timet (recur->until); - local->appt->repeatEnd = *localtime (&dt_time); - } - - cal_component_free_recur_list (list); - } - - cal_component_get_classification (comp, &classif); - - if (classif == CAL_COMPONENT_CLASS_PRIVATE) - local->local.secret = 1; - else - local->local.secret = 0; - - local->local.archived = 0; -} - -static void -local_record_from_uid (ECalLocalRecord *local, - const char *uid, - ECalConduitContext *ctxt) -{ - CalComponent *comp; - CalClientGetStatus status; - - g_assert(local!=NULL); - - status = cal_client_get_object (ctxt->client, uid, &comp); - - if (status == CAL_CLIENT_GET_SUCCESS) { - local_record_from_comp (local, comp, ctxt); - } else if (status == CAL_CLIENT_GET_NOT_FOUND) { - comp = cal_component_new (); - cal_component_set_new_vtype (comp, CAL_COMPONENT_EVENT); - cal_component_set_uid (comp, uid); - local_record_from_comp (local, comp, ctxt); - } else { - INFO ("Object did not exist"); - } -} - -static CalComponent * -comp_from_remote_record (GnomePilotConduitSyncAbs *conduit, - GnomePilotRecord *remote, - CalComponent *in_comp) -{ - CalComponent *comp; - struct Appointment appt; - struct icaltimetype now = icaltime_from_timet (time (NULL), FALSE), it; - struct icalrecurrencetype recur; - int pos, i; - CalComponentText summary = {NULL, NULL}; - CalComponentDateTime dt = {NULL, NULL}; - GList *alist, *l; - char *txt; - - g_return_val_if_fail (remote != NULL, NULL); - - memset (&appt, 0, sizeof (struct Appointment)); - unpack_Appointment (&appt, remote->record, remote->length); - - if (in_comp == NULL) { - comp = cal_component_new (); - cal_component_set_new_vtype (comp, CAL_COMPONENT_EVENT); - cal_component_set_created (comp, &now); - } else { - comp = cal_component_clone (in_comp); - } - - cal_component_set_last_modified (comp, &now); - - summary.value = txt = e_pilot_utf8_from_pchar (appt.description); - cal_component_set_summary (comp, &summary); - free (txt); - - /* The iCal description field */ - if (!appt.note) { - cal_component_set_comment_list (comp, NULL); - } else { - GSList l; - CalComponentText text; - - text.value = txt = e_pilot_utf8_from_pchar (appt.note); - text.altrep = NULL; - l.data = &text; - l.next = NULL; - - cal_component_set_description_list (comp, &l); - free (txt); - } - - if (!is_empty_time (appt.begin)) { - it = icaltime_from_timet (mktime (&appt.begin), FALSE); - dt.value = ⁢ - cal_component_set_dtstart (comp, &dt); - } - - if (appt.event) { - time_t t = mktime (&appt.begin); - - t = time_day_end (t); - it = icaltime_from_timet (t, FALSE); - dt.value = ⁢ - cal_component_set_dtend (comp, &dt); - } else if (!is_empty_time (appt.end)) { - it = icaltime_from_timet (mktime (&appt.end), FALSE); - dt.value = ⁢ - cal_component_set_dtend (comp, &dt); - } - - /* Recurrence information */ - icalrecurrencetype_clear (&recur); - - switch (appt.repeatType) { - case repeatNone: - recur.freq = ICAL_NO_RECURRENCE; - break; - - case repeatDaily: - recur.freq = ICAL_DAILY_RECURRENCE; - recur.interval = appt.repeatFrequency; - break; - - case repeatWeekly: - recur.freq = ICAL_WEEKLY_RECURRENCE; - recur.interval = appt.repeatFrequency; - - pos = 0; - for (i = 0; i < 7; i++) { - if (appt.repeatDays[i]) - recur.by_day[pos++] = get_ical_day (i); - } - - break; - - case repeatMonthlyByDay: - recur.freq = ICAL_MONTHLY_RECURRENCE; - recur.interval = appt.repeatFrequency; - recur.by_day[0] = nth_weekday (appt.repeatDay / 5, get_ical_day (appt.repeatDay % 5 - 1)); - break; - - case repeatMonthlyByDate: - recur.freq = ICAL_MONTHLY_RECURRENCE; - recur.interval = appt.repeatFrequency; - recur.by_month_day[0] = appt.begin.tm_mday; - break; - - case repeatYearly: - recur.freq = ICAL_YEARLY_RECURRENCE; - recur.interval = appt.repeatFrequency; - break; - - default: - g_assert_not_reached (); - } - - if (recur.freq != ICAL_NO_RECURRENCE) { - GSList *list = NULL; - - /* recurrence start of week */ - recur.week_start = get_ical_day (appt.repeatWeekstart); - - if (!appt.repeatForever) { - time_t t = mktime (&appt.repeatEnd); - t = time_add_day (t, 1); - recur.until = icaltime_from_timet (t, FALSE); - } - - list = g_slist_append (list, &recur); - cal_component_set_rrule_list (comp, list); - g_slist_free (list); - } else { - cal_component_set_rrule_list (comp, NULL); - } - - cal_component_set_transparency (comp, CAL_COMPONENT_TRANSP_NONE); - - if (remote->attr & dlpRecAttrSecret) - cal_component_set_classification (comp, CAL_COMPONENT_CLASS_PRIVATE); - else - cal_component_set_classification (comp, CAL_COMPONENT_CLASS_PUBLIC); - - cal_component_commit_sequence (comp); - - free_Appointment (&appt); - - return comp; -} - -static void -update_comp (GnomePilotConduitSyncAbs *conduit, CalComponent *comp, - ECalConduitContext *ctxt) -{ - gboolean success; - - g_return_if_fail (conduit != NULL); - g_return_if_fail (comp != NULL); - - success = cal_client_update_object (ctxt->client, comp); - - if (!success) - WARN (_("Error while communicating with calendar server")); -} - -static void -check_for_slow_setting (GnomePilotConduit *c, ECalConduitContext *ctxt) -{ - int count, map_count; - - count = g_list_length (ctxt->uids); - map_count = g_hash_table_size (ctxt->map->pid_map); - - /* If there are no objects or objects but no log */ - if (map_count == 0) { - GnomePilotConduitStandard *conduit; - LOG (" doing slow sync\n"); - conduit = GNOME_PILOT_CONDUIT_STANDARD (c); - gnome_pilot_conduit_standard_set_slow (conduit); - } else { - LOG (" doing fast sync\n"); - } -} - -/* Pilot syncing callbacks */ -static gint -pre_sync (GnomePilotConduit *conduit, - GnomePilotDBInfo *dbi, - ECalConduitContext *ctxt) -{ - GnomePilotConduitSyncAbs *abs_conduit; - GList *l; - int len; - unsigned char *buf; - char *filename, *change_id; - gint num_records, add_records = 0, mod_records = 0, del_records = 0; - - abs_conduit = GNOME_PILOT_CONDUIT_SYNC_ABS (conduit); - - LOG ("---------------------------------------------------------\n"); - LOG ("pre_sync: Calendar Conduit v.%s", CONDUIT_VERSION); - g_message ("Calendar Conduit v.%s", CONDUIT_VERSION); - - ctxt->client = NULL; - - if (start_calendar_server (ctxt) != 0) { - WARN(_("Could not start wombat server")); - gnome_pilot_conduit_error (conduit, _("Could not start wombat")); - 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); - - /* 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); - ctxt->changed_hash = g_hash_table_new (g_str_hash, g_str_equal); - - for (l = ctxt->changed; l != NULL; l = l->next) { - CalClientChange *ccc = l->data; - const char *uid; - - cal_component_get_uid (ccc->comp, &uid); - if (!e_pilot_map_uid_is_archived (ctxt->map, uid)) { - - g_hash_table_insert (ctxt->changed_hash, g_strdup (uid), ccc); - - switch (ccc->type) { - case CAL_CLIENT_CHANGE_ADDED: - add_records++; - break; - case CAL_CLIENT_CHANGE_MODIFIED: - mod_records++; - break; - case CAL_CLIENT_CHANGE_DELETED: - del_records++; - break; - } - } - } - - /* Set the count information */ - num_records = cal_client_get_n_objects (ctxt->client, CALOBJ_TYPE_TODO); - 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); - gnome_pilot_conduit_sync_abs_set_num_deleted_local_records(abs_conduit, del_records); - - gtk_object_set_data (GTK_OBJECT (conduit), "dbinfo", dbi); - - buf = (unsigned char*)g_malloc (0xffff); - len = dlp_ReadAppBlock (dbi->pilot_socket, dbi->db_handle, 0, - (unsigned char *)buf, 0xffff); - - if (len < 0) { - WARN (_("Could not read pilot's Calendar application block")); - WARN ("dlp_ReadAppBlock(...) = %d", len); - gnome_pilot_conduit_error (conduit, - _("Could not read pilot's Calendar application block")); - return -1; - } - unpack_AppointmentAppInfo (&(ctxt->ai), buf, len); - g_free (buf); - - check_for_slow_setting (conduit, ctxt); - - return 0; -} - -static gint -post_sync (GnomePilotConduit *conduit, - GnomePilotDBInfo *dbi, - ECalConduitContext *ctxt) -{ - GList *changed; - gchar *filename, *change_id; - - LOG ("post_sync: Calendar Conduit v.%s", CONDUIT_VERSION); - LOG ("---------------------------------------------------------\n"); - - filename = map_name (ctxt); - e_pilot_map_write (filename, ctxt->map); - g_free (filename); - - /* FIX ME ugly hack - our changes musn't count, this does introduce - * 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); - - return 0; -} - -static gint -set_pilot_id (GnomePilotConduitSyncAbs *conduit, - ECalLocalRecord *local, - guint32 ID, - ECalConduitContext *ctxt) -{ - const char *uid; - - LOG ("set_pilot_id: setting to %d\n", ID); - - cal_component_get_uid (local->comp, &uid); - e_pilot_map_insert (ctxt->map, ID, uid, FALSE); - - return 0; -} - -static gint -set_status_cleared (GnomePilotConduitSyncAbs *conduit, - ECalLocalRecord *local, - ECalConduitContext *ctxt) -{ - const char *uid; - - LOG ("set_status_cleared: clearing status\n"); - - cal_component_get_uid (local->comp, &uid); - g_hash_table_remove (ctxt->changed_hash, uid); - - return 0; -} - -static gint -for_each (GnomePilotConduitSyncAbs *conduit, - ECalLocalRecord **local, - ECalConduitContext *ctxt) -{ - static GList *uids, *iterator; - static int count; - - g_return_val_if_fail (local != NULL, -1); - - if (*local == NULL) { - LOG ("beginning for_each"); - - uids = ctxt->uids; - count = 0; - - if (uids != NULL) { - LOG ("iterating over %d records", g_list_length (uids)); - - *local = g_new0 (ECalLocalRecord, 1); - local_record_from_uid (*local, uids->data, ctxt); - - iterator = uids; - } else { - LOG ("no events"); - (*local) = NULL; - return 0; - } - } else { - count++; - if (g_list_next (iterator)) { - iterator = g_list_next (iterator); - - *local = g_new0 (ECalLocalRecord, 1); - local_record_from_uid (*local, iterator->data, ctxt); - } else { - LOG ("for_each ending"); - - /* Tell the pilot the iteration is over */ - *local = NULL; - - return 0; - } - } - - return 0; -} - -static gint -for_each_modified (GnomePilotConduitSyncAbs *conduit, - ECalLocalRecord **local, - ECalConduitContext *ctxt) -{ - static GList *iterator; - static int count; - - g_return_val_if_fail (local != NULL, 0); - - if (*local == NULL) { - LOG ("beginning for_each_modified: beginning\n"); - - iterator = ctxt->changed; - - count = 0; - - LOG ("iterating over %d records", g_hash_table_size (ctxt->changed_hash)); - - iterator = next_changed_item (ctxt, iterator); - if (iterator != NULL) { - CalClientChange *ccc = iterator->data; - - *local = g_new0 (ECalLocalRecord, 1); - local_record_from_comp (*local, ccc->comp, ctxt); - } else { - LOG ("no events"); - - *local = NULL; - } - } else { - count++; - iterator = g_list_next (iterator); - if (iterator && (iterator = next_changed_item (ctxt, iterator))) { - CalClientChange *ccc = iterator->data; - - *local = g_new0 (ECalLocalRecord, 1); - local_record_from_comp (*local, ccc->comp, ctxt); - } else { - LOG ("for_each_modified ending"); - - /* Signal the iteration is over */ - *local = NULL; - } - } - - return 0; -} - -static gint -compare (GnomePilotConduitSyncAbs *conduit, - ECalLocalRecord *local, - GnomePilotRecord *remote, - ECalConduitContext *ctxt) -{ - /* used by the quick compare */ - GnomePilotRecord local_pilot; - int retval = 0; - - LOG ("compare: local=%s remote=%s...\n", - print_local (local), print_remote (remote)); - - g_return_val_if_fail (local!=NULL,-1); - g_return_val_if_fail (remote!=NULL,-1); - - local_pilot = local_record_to_pilot_record (local, ctxt); - - if (remote->length != local_pilot.length - || memcmp (local_pilot.record, remote->record, remote->length)) - retval = 1; - - if (retval == 0) - LOG (" equal"); - else - LOG (" not equal"); - - return retval; -} - -static gint -add_record (GnomePilotConduitSyncAbs *conduit, - GnomePilotRecord *remote, - ECalConduitContext *ctxt) -{ - CalComponent *comp; - const char *uid; - int retval = 0; - - g_return_val_if_fail (remote != NULL, -1); - - LOG ("add_record: adding %s to desktop\n", print_remote (remote)); - - comp = comp_from_remote_record (conduit, remote, NULL); - update_comp (conduit, comp, ctxt); - - cal_component_get_uid (comp, &uid); - - e_pilot_map_insert (ctxt->map, remote->ID, uid, FALSE); - - return retval; -} - -static gint -replace_record (GnomePilotConduitSyncAbs *conduit, - ECalLocalRecord *local, - GnomePilotRecord *remote, - ECalConduitContext *ctxt) -{ - CalComponent *new_comp; - int retval = 0; - - g_return_val_if_fail (remote != NULL, -1); - - LOG ("replace_record: replace %s with %s\n", - print_local (local), print_remote (remote)); - - new_comp = comp_from_remote_record (conduit, remote, local->comp); - gtk_object_unref (GTK_OBJECT (local->comp)); - local->comp = new_comp; - update_comp (conduit, local->comp, ctxt); - - return retval; -} - -static gint -delete_record (GnomePilotConduitSyncAbs *conduit, - ECalLocalRecord *local, - ECalConduitContext *ctxt) -{ - const char *uid; - - g_return_val_if_fail (local != NULL, -1); - g_assert (local->comp != NULL); - - cal_component_get_uid (local->comp, &uid); - - LOG ("delete_record: deleting %s\n", uid); - - e_pilot_map_remove_by_uid (ctxt->map, uid); - cal_client_remove_object (ctxt->client, uid); - - return 0; -} - -static gint -archive_record (GnomePilotConduitSyncAbs *conduit, - ECalLocalRecord *local, - gboolean archive, - ECalConduitContext *ctxt) -{ - const char *uid; - int retval = 0; - - g_return_val_if_fail (local != NULL, -1); - - LOG ("archive_record: %s\n", archive ? "yes" : "no"); - - cal_component_get_uid (local->comp, &uid); - e_pilot_map_insert (ctxt->map, local->local.ID, uid, archive); - - return retval; -} - -static gint -match (GnomePilotConduitSyncAbs *conduit, - GnomePilotRecord *remote, - ECalLocalRecord **local, - ECalConduitContext *ctxt) -{ - const char *uid; - - LOG ("match: looking for local copy of %s\n", - print_remote (remote)); - - g_return_val_if_fail (local != NULL, -1); - g_return_val_if_fail (remote != NULL, -1); - - *local = NULL; - uid = e_pilot_map_lookup_uid (ctxt->map, remote->ID); - - if (!uid) - return 0; - - LOG (" matched\n"); - - *local = g_new0 (ECalLocalRecord, 1); - local_record_from_uid (*local, uid, ctxt); - - return 0; -} - -static gint -free_match (GnomePilotConduitSyncAbs *conduit, - ECalLocalRecord *local, - ECalConduitContext *ctxt) -{ - LOG ("free_match: freeing\n"); - - g_return_val_if_fail (local != NULL, -1); - - gtk_object_unref (GTK_OBJECT (local->comp)); - g_free (local); - - return 0; -} - -static gint -prepare (GnomePilotConduitSyncAbs *conduit, - ECalLocalRecord *local, - GnomePilotRecord *remote, - ECalConduitContext *ctxt) -{ - LOG ("prepare: encoding local %s\n", print_local (local)); - - *remote = local_record_to_pilot_record (local, ctxt); - - return 0; -} - -static ORBit_MessageValidationResult -accept_all_cookies (CORBA_unsigned_long request_id, - CORBA_Principal *principal, - CORBA_char *operation) -{ - /* allow ALL cookies */ - return ORBIT_MESSAGE_ALLOW_ALL; -} - - -GnomePilotConduit * -conduit_get_gpilot_conduit (guint32 pilot_id) -{ - GtkObject *retval; - ECalConduitContext *ctxt; - - LOG ("in calendar's conduit_get_gpilot_conduit\n"); - - /* we need to find wombat with oaf, so make sure oaf - is initialized here. once the desktop is converted - to oaf and gpilotd is built with oaf, this can go away */ - if (!oaf_is_initialized ()) { - char *argv[ 1 ] = {"hi"}; - oaf_init (1, argv); - - if (bonobo_init (CORBA_OBJECT_NIL, - CORBA_OBJECT_NIL, - CORBA_OBJECT_NIL) == FALSE) - g_error (_("Could not initialize Bonobo")); - - ORBit_set_request_validation_handler (accept_all_cookies); - } - - retval = gnome_pilot_conduit_sync_abs_new ("DatebookDB", 0x64617465); - g_assert (retval != NULL); - - gnome_pilot_conduit_construct (GNOME_PILOT_CONDUIT (retval), - "e_calendar_conduit"); - - ctxt = e_calendar_context_new (pilot_id); - gtk_object_set_data (GTK_OBJECT (retval), "calconduit_context", ctxt); - - gtk_signal_connect (retval, "pre_sync", (GtkSignalFunc) pre_sync, ctxt); - gtk_signal_connect (retval, "post_sync", (GtkSignalFunc) post_sync, ctxt); - - gtk_signal_connect (retval, "set_pilot_id", (GtkSignalFunc) set_pilot_id, ctxt); - gtk_signal_connect (retval, "set_status_cleared", (GtkSignalFunc) set_status_cleared, ctxt); - - gtk_signal_connect (retval, "for_each", (GtkSignalFunc) for_each, ctxt); - gtk_signal_connect (retval, "for_each_modified", (GtkSignalFunc) for_each_modified, ctxt); - gtk_signal_connect (retval, "compare", (GtkSignalFunc) compare, ctxt); - - gtk_signal_connect (retval, "add_record", (GtkSignalFunc) add_record, ctxt); - gtk_signal_connect (retval, "replace_record", (GtkSignalFunc) replace_record, ctxt); - gtk_signal_connect (retval, "delete_record", (GtkSignalFunc) delete_record, ctxt); - gtk_signal_connect (retval, "archive_record", (GtkSignalFunc) archive_record, ctxt); - - gtk_signal_connect (retval, "match", (GtkSignalFunc) match, ctxt); - gtk_signal_connect (retval, "free_match", (GtkSignalFunc) free_match, ctxt); - - gtk_signal_connect (retval, "prepare", (GtkSignalFunc) prepare, ctxt); - - return GNOME_PILOT_CONDUIT (retval); -} - -void -conduit_destroy_gpilot_conduit (GnomePilotConduit *conduit) -{ - GtkObject *obj = GTK_OBJECT (conduit); - ECalConduitContext *ctxt; - - ctxt = gtk_object_get_data (obj, "calconduit_context"); - e_calendar_context_destroy (ctxt); - - gtk_object_destroy (obj); -} diff --git a/calendar/conduits/calendar/calendar-conduit.h b/calendar/conduits/calendar/calendar-conduit.h deleted file mode 100644 index 03308e77d9..0000000000 --- a/calendar/conduits/calendar/calendar-conduit.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Evolution calendar - Calendar Conduit - * - * Copyright (C) 1998 Free Software Foundation - * Copyright (C) 2000 Helix Code, Inc. - * - * Authors: Eskil Heyn Olsen <deity@eskil.dk> - * JP Rosevear <jpr@helixcode.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef __CALENDAR_CONDUIT_H__ -#define __CALENDAR_CONDUIT_H__ - -#include <sys/types.h> -#include <fcntl.h> -#include <unistd.h> -#include <gnome.h> -#include <pi-datebook.h> -#include <gpilotd/gnome-pilot-conduit.h> -#include <gpilotd/gnome-pilot-conduit-sync-abs.h> -#include <cal-client/cal-client.h> -#include <e-pilot-map.h> - -/* This is the local record structure for the Evolution Calendar conduit. */ -typedef struct _ECalLocalRecord ECalLocalRecord; -struct _ECalLocalRecord { - /* The stuff from gnome-pilot-conduit-standard-abs.h - Must be first in the structure, or instances of this - structure cannot be used by gnome-pilot-conduit-standard-abs. - */ - GnomePilotDesktopRecord local; - - /* The corresponding Comp object */ - CalComponent *comp; - - /* pilot-link todo structure */ - struct Appointment *appt; -}; - -/* This is the context for all the Evolution Calendar conduit methods. */ -typedef struct _ECalConduitContext ECalConduitContext; -struct _ECalConduitContext { - ECalConduitCfg *cfg; - - struct AppointmentAppInfo ai; - - CalClient *client; - char *calendar_file; - gboolean calendar_open_success; - - time_t since; - GList *uids; - GList *changed; - GHashTable *changed_hash; - - EPilotMap *map; -}; - -#endif __CALENDAR_CONDUIT_H__ - - - - - - diff --git a/calendar/conduits/calendar/e-calendar-conduit-control-applet.desktop.in b/calendar/conduits/calendar/e-calendar-conduit-control-applet.desktop.in deleted file mode 100644 index 322e63c802..0000000000 --- a/calendar/conduits/calendar/e-calendar-conduit-control-applet.desktop.in +++ /dev/null @@ -1,7 +0,0 @@ -[Desktop Entry] -_Name=Evolution Calendar conduit -_Comment=Configure the GnomeCal conduit -Exec=e-calendar-conduit-control-applet --cap-id=1 -Terminal=0 -Type=Application -Icon=gnome-calendar-conduit.png diff --git a/calendar/conduits/calendar/e-calendar.conduit.in b/calendar/conduits/calendar/e-calendar.conduit.in deleted file mode 100644 index 6143978e8b..0000000000 --- a/calendar/conduits/calendar/e-calendar.conduit.in +++ /dev/null @@ -1,8 +0,0 @@ -<gnome-pilot-conduit version="1.0"> -<conduit id="e_calendar_conduit" type="shlib" location="@prefix@/lib/gnome-pilot/conduits/libecalendar_conduit.so"/> -<name value="ECalendar"/> -<conduit-attribute name="description" value="Synchronizes Calendar with Evolution"/> -<conduit-attribute name="default-synctype" value="synchronize"/> -<conduit-attribute name="icon" value="@prefix@/share/pixmaps/gnome-calendar-conduit.png"/> -<conduit-attribute name="settings" value="TRUE"/> -</gnome-pilot-conduit> diff --git a/calendar/conduits/todo/.cvsignore b/calendar/conduits/todo/.cvsignore deleted file mode 100644 index 3ee063c770..0000000000 --- a/calendar/conduits/todo/.cvsignore +++ /dev/null @@ -1,9 +0,0 @@ -Makefile.in -Makefile -.deps -.libs -*.lo -*.la -e-todo-conduit-control-applet -e-todo-conduit-control-applet.desktop -e-todo.conduit diff --git a/calendar/conduits/todo/Makefile.am b/calendar/conduits/todo/Makefile.am deleted file mode 100644 index ea7b628b15..0000000000 --- a/calendar/conduits/todo/Makefile.am +++ /dev/null @@ -1,73 +0,0 @@ -INCLUDES = \ - -I$(top_srcdir) \ - -I$(top_srcdir)/calendar \ - -I$(top_srcdir)/libical/src/libical \ - -I$(top_builddir)/libical/src/libical \ - -I$(top_builddir)/e-util \ - $(BONOBO_GNOME_CFLAGS) \ - $(PISOCK_INCLUDEDIR) \ - $(GNOME_PILOT_CFLAGS) - -# ToDo Capplet -bin_PROGRAMS = e-todo-conduit-control-applet - -e_todo_conduit_control_applet_SOURCES = todo-conduit-control-applet.c - -e_todo_conduit_control_applet_LDADD = \ - $(CAPPLET_LIBS) \ - $(GNOME_LIBDIR) \ - $(GNOME_PILOT_LIBS) \ - $(PISOCK_LIBS) \ - $(GNOME_CAPPLET_LIBS) \ - $(BONOBO_GNOME_LIBS) \ - $(GNOME_XML_LIB) \ - $(GNOMEUI_LIBS) \ - $(INTLLIBS) - -# ToDo Conduit -e_todo_conduitsdir=$(libdir)/gnome-pilot/conduits -e_todo_conduits_LTLIBRARIES = libetodo_conduit.la - -libetodo_conduit_la_SOURCES = \ - todo-conduit.c \ - todo-conduit.h \ - todo-conduit-config.h - -libetodo_conduit_la_LDFLAGS = -module -avoid-version -libetodo_conduit_la_LIBADD = \ - $(top_builddir)/calendar/cal-client/libcal-client-static.la \ - $(top_builddir)/calendar/cal-util/libcal-util-static.la \ - $(top_builddir)/libversit/libversit.la \ - $(top_builddir)/libical/src/libical/libical-static.la \ - $(top_builddir)/e-util/libeconduit-static.la \ - $(BONOBO_GNOME_LIBS) \ - $(PISOCK_LIBS) \ - $(UNICODE_LIBS) \ - $(GNOME_LIBDIR) \ - $(GNOME_LIBS) - -e-todo.conduit: e-todo.conduit.in Makefile - sed -e 's^\@prefix\@^$(prefix)^g' < $(srcdir)/e-todo.conduit.in > e-todo.conduit.tmp \ - && mv e-todo.conduit.tmp e-todo.conduit - - -ccenterdir = $(datadir)/control-center -ccenterPalmPilotdir = $(ccenterdir)/Peripherals -ccenterConduitsdir = $(ccenterPalmPilotdir)/Conduits -ccenterConduits_in_files = e-todo-conduit-control-applet.desktop.in -ccenterConduits_DATA = $(ccenterConduits_in_files:.desktop.in=.desktop) -@XML_I18N_MERGE_DESKTOP_RULE@ - -panelConduitsdir = $(datadir)/gnome/apps/Settings/Peripherals/Conduits -panelConduits_DATA = $(ccenterConduits_DATA) - -Conduitdir = $(datadir)/gnome-pilot/conduits/ -Conduit_DATA = e-todo.conduit - -EXTRA_DIST = \ - e-todo.conduit.in \ - $(ccenterConduits_in_files) - -install-data-local: - $(mkinstalldirs) $(ccenterConduitsdir) - $(mkinstalldirs) $(Conduitdir) diff --git a/calendar/conduits/todo/e-todo-conduit-control-applet.desktop.in b/calendar/conduits/todo/e-todo-conduit-control-applet.desktop.in deleted file mode 100644 index 216c07afd5..0000000000 --- a/calendar/conduits/todo/e-todo-conduit-control-applet.desktop.in +++ /dev/null @@ -1,6 +0,0 @@ -[Desktop Entry] -_Name=Evolution ToDo conduit -_Comment=Configure the todo conduit -Exec=e-todo-conduit-control-applet --cap-id=1 -Terminal=0 -Type=Application diff --git a/calendar/conduits/todo/e-todo.conduit.in b/calendar/conduits/todo/e-todo.conduit.in deleted file mode 100644 index 40e6fd620c..0000000000 --- a/calendar/conduits/todo/e-todo.conduit.in +++ /dev/null @@ -1,8 +0,0 @@ -<gnome-pilot-conduit version="1.0"> -<conduit id="e_todo_conduit" type="shlib" location="@prefix@/lib/gnome-pilot/conduits/libetodo_conduit.so"/> -<name value="EToDo"/> -<conduit-attribute name="description" value="Synchronizes ToDo List with Evolution"/> -<conduit-attribute name="default-synctype" value="synchronize"/> -<conduit-attribute name="icon" value="@prefix@/share/pixmaps/gnome-calendar-conduit.png"/> -<conduit-attribute name="settings" value="TRUE"/> -</gnome-pilot-conduit> diff --git a/calendar/conduits/todo/todo-conduit-config.h b/calendar/conduits/todo/todo-conduit-config.h deleted file mode 100644 index fe7b1dbafa..0000000000 --- a/calendar/conduits/todo/todo-conduit-config.h +++ /dev/null @@ -1,120 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Evolution calendar - ToDo Conduit Configuration - * - * Copyright (C) 1998 Free Software Foundation - * Copyright (C) 2000 Helix Code, Inc. - * - * Authors: Eskil Heyn Olsen <deity@eskil.dk> - * JP Rosevear <jpr@helixcode.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef __TODO_CONDUIT_CONFIG_H__ -#define __TODO_CONDUIT_CONFIG_H__ - -#include <gnome.h> -#include <libgpilotdCM/gnome-pilot-conduit-management.h> -#include <libgpilotdCM/gnome-pilot-conduit-config.h> - -/* Configuration info */ -typedef struct _EToDoConduitCfg EToDoConduitCfg; -struct _EToDoConduitCfg { - gboolean open_secret; - guint32 pilot_id; - GnomePilotConduitSyncType sync_type; /* only used by capplet */ -}; - -#ifdef TODO_CONFIG_LOAD -/* Load the configuration data */ -static void -todoconduit_load_configuration (EToDoConduitCfg **c, guint32 pilot_id) -{ - gchar prefix[256]; - g_snprintf (prefix, 255, "/gnome-pilot.d/e-todo-conduit/Pilot_%u/", - pilot_id); - - *c = g_new0 (EToDoConduitCfg,1); - g_assert (*c != NULL); - - gnome_config_push_prefix (prefix); - (*c)->open_secret = gnome_config_get_bool ("open_secret=FALSE"); - - /* set in capplets main */ - (*c)->sync_type = GnomePilotConduitSyncTypeCustom; - gnome_config_pop_prefix (); - - (*c)->pilot_id = pilot_id; -} -#endif - -#ifdef TODO_CONFIG_SAVE -/* Saves the configuration data. */ -static void -todoconduit_save_configuration (EToDoConduitCfg *c) -{ - gchar prefix[256]; - - g_snprintf (prefix, 255, "/gnome-pilot.d/e-todo-conduit/Pilot_%u/", - c->pilot_id); - - gnome_config_push_prefix (prefix); - gnome_config_set_bool ("open_secret", c->open_secret); - gnome_config_pop_prefix (); - - gnome_config_sync (); - gnome_config_drop_all (); -} -#endif - -#ifdef TODO_CONFIG_DUPE -/* Creates a duplicate of the configuration data */ -static EToDoConduitCfg* -todoconduit_dupe_configuration (EToDoConduitCfg *c) -{ - EToDoConduitCfg *retval; - - g_return_val_if_fail (c != NULL, NULL); - - retval = g_new0 (EToDoConduitCfg, 1); - retval->sync_type = c->sync_type; - retval->open_secret = c->open_secret; - retval->pilot_id = c->pilot_id; - - return retval; -} -#endif - -#ifdef TODO_CONFIG_DESTROY -/* Destroy a configuration */ -static void -todoconduit_destroy_configuration (EToDoConduitCfg **c) -{ - g_return_if_fail (c != NULL); - g_return_if_fail (*c != NULL); - - g_free (*c); - *c = NULL; -} -#endif - -#endif __TODO_CONDUIT_CONFIG_H__ - - - - - - - diff --git a/calendar/conduits/todo/todo-conduit-control-applet.c b/calendar/conduits/todo/todo-conduit-control-applet.c deleted file mode 100644 index 7140522b55..0000000000 --- a/calendar/conduits/todo/todo-conduit-control-applet.c +++ /dev/null @@ -1,341 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Evolution calendar - ToDo Conduit Capplet - * - * Copyright (C) 1998 Free Software Foundation - * Copyright (C) 2000 Helix Code, Inc. - * - * Authors: Eskil Heyn Olsen <deity@eskil.dk> - * JP Rosevear <jpr@helixcode.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#include <pwd.h> -#include <sys/types.h> -#include <signal.h> -#include <gnome.h> - -#include <config.h> -#include <capplet-widget.h> - -#include <gpilotd/gnome-pilot-client.h> - -#define TODO_CONFIG_LOAD 1 -#define TODO_CONFIG_SAVE 1 -#define TODO_CONFIG_DUPE 1 -#define TODO_CONFIG_DESTROY 1 -#include <todo-conduit-config.h> -#undef TODO_CONFIG_LOAD -#undef TODO_CONFIG_SAVE -#undef TODO_CONFIG_DUPE -#undef TODO_CONFIG_DESTROY - -/* tell changes callbacks to ignore changes or not */ -static gboolean ignore_changes=FALSE; - -/* capplet widget */ -static GtkWidget *capplet=NULL; - -/* host/device/pilot configuration windows */ -GtkWidget *cfgOptionsWindow=NULL; -GtkWidget *cfgStateWindow=NULL; -GtkWidget *dialogWindow=NULL; - -gboolean activated,org_activation_state; -GnomePilotConduitManagement *conduit; -GnomePilotConduitConfig *conduit_config; -EToDoConduitCfg *origState = NULL; -EToDoConduitCfg *curState = NULL; - -static void doTrySettings(GtkWidget *widget, EToDoConduitCfg *c); -static void doRevertSettings(GtkWidget *widget, EToDoConduitCfg *c); -static void doSaveSettings(GtkWidget *widget, EToDoConduitCfg *c); - -static void setStateCfg (GtkWidget *w, EToDoConduitCfg *c); - -gint pilotId; -static GnomePilotClient *gpc; - - - -/* This array must be in the same order as enumerations - in GnomePilotConduitSyncType as they are used as index. - Custom type implies Disabled state. -*/ -static gchar* sync_options[] ={ N_("Disabled"), - N_("Synchronize"), - N_("Copy From Pilot"), - N_("Copy To Pilot"), - N_("Merge From Pilot"), - N_("Merge To Pilot")}; -#define SYNC_OPTIONS_COUNT 6 - -static void -doTrySettings (GtkWidget *widget, EToDoConduitCfg *c) -{ - if (c->sync_type != GnomePilotConduitSyncTypeCustom) - gnome_pilot_conduit_config_enable_with_first_sync (conduit_config, - c->sync_type, - c->sync_type, - TRUE); - else - gnome_pilot_conduit_config_disable (conduit_config); - - todoconduit_save_configuration (c); -} - -static void -doRevertSettings (GtkWidget *widget, EToDoConduitCfg *c) -{ - activated = org_activation_state; - *c = *origState; - setStateCfg (cfgStateWindow, c); - doTrySettings (widget, c); -} - -static void -doSaveSettings (GtkWidget *widget, EToDoConduitCfg *c) -{ - *origState = *c; - doTrySettings (widget, c); -} - - -static void -doHelp (GtkWidget *widget, gpointer data) -{ - GtkWidget *about; - const gchar *authors[] = { - _("JP Rosevear <jpr@helixcode.com>"), - "", _("Original Author:"), - _("Eskil Heyn Olsen <deity@eskil.dk>"), - NULL}; - - about = gnome_about_new ( - _("Evolution ToDo Conduit"), VERSION, - _("(C) 1998-2000 the Free Software Foundation and Helix Code"), - authors, - _("Configuration utility for the evolution todo conduit.\n"), - _("gnome-unknown.xpm")); - gtk_widget_show (about); - - return; -} - - -/* called by the sync_type GtkOptionMenu */ -static void -activate_sync_type (GtkMenuItem *widget, gpointer data) -{ - curState->sync_type = GPOINTER_TO_INT (data); - if (!ignore_changes) - capplet_widget_state_changed (CAPPLET_WIDGET (capplet), TRUE); -} - - -static GtkWidget * -createStateCfgWindow(void) -{ - GtkWidget *vbox, *table; - GtkWidget *label; - GtkWidget *optionMenu,*menuItem; - GtkMenu *menu; - gint i; - - vbox = gtk_vbox_new(FALSE, GNOME_PAD); - - table = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, GNOME_PAD); - - label = gtk_label_new(_("Synchronize Action")); - gtk_box_pack_start(GTK_BOX(table), label, FALSE, FALSE, GNOME_PAD); - - optionMenu=gtk_option_menu_new(); - gtk_object_set_data(GTK_OBJECT(vbox), "conduit_state", optionMenu); - menu = GTK_MENU(gtk_menu_new()); - - for (i=0; i<SYNC_OPTIONS_COUNT;i++) { - sync_options[i]=_(sync_options[i]); - menuItem = gtk_menu_item_new_with_label(sync_options[i]); - gtk_widget_show(menuItem); - gtk_signal_connect(GTK_OBJECT(menuItem),"activate", - GTK_SIGNAL_FUNC(activate_sync_type), - GINT_TO_POINTER(i)); - gtk_menu_append(menu,menuItem); - } - - gtk_option_menu_set_menu(GTK_OPTION_MENU(optionMenu),GTK_WIDGET(menu)); - gtk_box_pack_start(GTK_BOX(table), optionMenu, FALSE, FALSE, 0); - - return vbox; -} - - -static void -setStateCfg (GtkWidget *w, EToDoConduitCfg *c) -{ - GtkOptionMenu *optionMenu; - GtkMenu *menu; - - optionMenu = gtk_object_get_data (GTK_OBJECT(w), "conduit_state"); - g_assert (optionMenu != NULL); - menu = GTK_MENU (gtk_option_menu_get_menu (optionMenu)); - - ignore_changes = TRUE; - /* Here were are relying on the items in menu being the same - order as in GnomePilotConduitSyncType. */ - gtk_option_menu_set_history (optionMenu, (int) c->sync_type); - ignore_changes = FALSE; -} - -static void -pilot_capplet_setup(void) -{ - GtkWidget *frame, *table; - - capplet = capplet_widget_new(); - - table = gtk_table_new(1, 2, FALSE); - gtk_container_border_width(GTK_CONTAINER(table), GNOME_PAD); - gtk_container_add(GTK_CONTAINER(capplet), table); - - frame = gtk_frame_new(_("Conduit state")); - gtk_container_border_width(GTK_CONTAINER(frame), GNOME_PAD_SMALL); - gtk_table_attach_defaults(GTK_TABLE(table), frame, 0, 1, 0, 1); - cfgStateWindow = createStateCfgWindow(); - gtk_container_add(GTK_CONTAINER(frame), cfgStateWindow); - - gtk_signal_connect(GTK_OBJECT(capplet), "try", - GTK_SIGNAL_FUNC(doTrySettings), curState); - gtk_signal_connect(GTK_OBJECT(capplet), "revert", - GTK_SIGNAL_FUNC(doRevertSettings), curState); - gtk_signal_connect(GTK_OBJECT(capplet), "ok", - GTK_SIGNAL_FUNC(doSaveSettings), curState); - gtk_signal_connect(GTK_OBJECT(capplet), "help", - GTK_SIGNAL_FUNC(doHelp), NULL); - - - setStateCfg (cfgStateWindow, curState); - - gtk_widget_show_all (capplet); -} - - -static void -run_error_dialog(gchar *mesg,...) -{ - char tmp[80]; - va_list ap; - - va_start(ap,mesg); - vsnprintf(tmp,79,mesg,ap); - dialogWindow = gnome_message_box_new(mesg,GNOME_MESSAGE_BOX_ERROR,GNOME_STOCK_BUTTON_OK,NULL); - gnome_dialog_run_and_close(GNOME_DIALOG(dialogWindow)); - va_end(ap); -} - - -static gint -get_pilot_id_from_gpilotd() -{ - GList *pilots=NULL; - gint pilot; - int i,err; - - i=0; - /* we don't worry about leaking here, so pilots isn't freed */ - switch(err = gnome_pilot_client_get_pilots(gpc,&pilots)) { - case GPILOTD_OK: { - if(pilots) { - for(i=0;i<g_list_length(pilots);i++) { - g_message("pilot %d = \"%s\"",i,(gchar*)g_list_nth(pilots,i)->data); - } - if(i==0) { - run_error_dialog(_("No pilot configured, please choose the\n'Pilot Link Properties' capplet first.")); - return -1; - } else { - gnome_pilot_client_get_pilot_id_by_name(gpc, - pilots->data, /* this is the first pilot */ - &pilot); - if(i>1) { - g_message("too many pilots..."); - /* need a choose here */ - } - return pilot; - } - } else { - run_error_dialog(_("No pilot configured, please choose the\n'Pilot Link Properties' capplet first.")); - return -1; - } - break; - } - case GPILOTD_ERR_NOT_CONNECTED: - run_error_dialog(_("Not connected to the gnome-pilot daemon")); - return -1; - break; - default: - g_warning("gnome_pilot_client_get_pilot_ids(...) = %d",err); - run_error_dialog(_("An error occured when trying to fetch\npilot list from the gnome-pilot daemon")); - return -1; - break; - } -} - - -int -main (int argc, char *argv[]) -{ - g_log_set_always_fatal (G_LOG_LEVEL_ERROR | - G_LOG_LEVEL_CRITICAL | - G_LOG_LEVEL_WARNING); - - /* Init capplet */ - gnome_capplet_init ("Evolution ToDo conduit control applet", - NULL, argc, argv, - NULL, 0, NULL); - - /* Setup Client */ - gpc = gnome_pilot_client_new (); - gnome_pilot_client_connect_to_daemon (gpc); - pilotId = get_pilot_id_from_gpilotd (); - if (!pilotId) - return -1; - - - /* Put all code to set things up in here */ - conduit = gnome_pilot_conduit_management_new ("e_todo_conduit", GNOME_PILOT_CONDUIT_MGMT_ID); - if (conduit == NULL) - return -1; - - todoconduit_load_configuration (&origState, pilotId); - conduit_config = gnome_pilot_conduit_config_new (conduit, pilotId); - org_activation_state = activated = - gnome_pilot_conduit_config_is_enabled (conduit_config, - &origState->sync_type); - - curState = todoconduit_dupe_configuration (origState); - - pilot_capplet_setup (); - - /* Done setting up, now run main loop */ - capplet_gtk_main(); - - /* Clean up */ - gnome_pilot_conduit_management_destroy (conduit); - todoconduit_destroy_configuration (&origState); - todoconduit_destroy_configuration (&curState); - - return 0; -} diff --git a/calendar/conduits/todo/todo-conduit.c b/calendar/conduits/todo/todo-conduit.c deleted file mode 100644 index f812532616..0000000000 --- a/calendar/conduits/todo/todo-conduit.c +++ /dev/null @@ -1,1012 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Evolution calendar - ToDo Conduit - * - * Copyright (C) 1998 Free Software Foundation - * Copyright (C) 2000 Helix Code, Inc. - * - * Authors: Eskil Heyn Olsen <deity@eskil.dk> - * JP Rosevear <jpr@helixcode.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#include <config.h> - -#include <liboaf/liboaf.h> -#include <bonobo.h> -#include <cal-client/cal-client-types.h> -#include <cal-client/cal-client.h> -#include <cal-util/timeutil.h> -#include <pi-source.h> -#include <pi-socket.h> -#include <pi-file.h> -#include <pi-dlp.h> -#include <libical/src/libical/icaltypes.h> -#include <e-pilot-util.h> - -#define TODO_CONFIG_LOAD 1 -#define TODO_CONFIG_DESTROY 1 -#include <todo-conduit-config.h> -#undef TODO_CONFIG_LOAD -#undef TODO_CONFIG_DESTROY - -#include <todo-conduit.h> - -GnomePilotConduit * conduit_get_gpilot_conduit (guint32); -void conduit_destroy_gpilot_conduit (GnomePilotConduit*); - -#define CONDUIT_VERSION "0.1.4" -#ifdef G_LOG_DOMAIN -#undef G_LOG_DOMAIN -#endif -#define G_LOG_DOMAIN "etodoconduit" - -#define DEBUG_CALCONDUIT 1 -/* #undef DEBUG_CALCONDUIT */ - -#ifdef DEBUG_CALCONDUIT -#define LOG(e...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, e) -#else -#define LOG(e...) -#endif - -#define WARN(e...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, e) -#define INFO(e...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, e) - -/* Debug routines */ -static char * -print_local (EToDoLocalRecord *local) -{ - static char buff[ 4096 ]; - - if (local == NULL) { - sprintf (buff, "[NULL]"); - return buff; - } - - if (local->todo && local->todo->description) { - g_snprintf (buff, 4096, "[%d %ld %d %d '%s' '%s']", - local->todo->indefinite, - mktime (& local->todo->due), - local->todo->priority, - local->todo->complete, - local->todo->description ? - local->todo->description : "", - local->todo->note ? - local->todo->note : ""); - return buff; - } - - return ""; -} - -static char *print_remote (GnomePilotRecord *remote) -{ - static char buff[ 4096 ]; - struct ToDo todo; - - if (remote == NULL) { - sprintf (buff, "[NULL]"); - return buff; - } - - memset (&todo, 0, sizeof (struct ToDo)); - unpack_ToDo (&todo, remote->record, remote->length); - - g_snprintf (buff, 4096, "[%d %ld %d %d '%s' '%s']", - todo.indefinite, - mktime (&todo.due), - todo.priority, - todo.complete, - todo.description ? - todo.description : "", - todo.note ? - todo.note : ""); - - return buff; -} - -/* Context Routines */ -static EToDoConduitContext * -e_todo_context_new (guint32 pilot_id) -{ - EToDoConduitContext *ctxt = g_new0 (EToDoConduitContext, 1); - - todoconduit_load_configuration (&ctxt->cfg, pilot_id); - - return ctxt; -} - -static void -e_todo_context_foreach_change (gpointer key, gpointer value, gpointer data) -{ - g_free (key); -} - -static void -e_todo_context_destroy (EToDoConduitContext *ctxt) -{ - g_return_if_fail (ctxt != NULL); - - if (ctxt->cfg != NULL) - todoconduit_destroy_configuration (&ctxt->cfg); - - if (ctxt->client != NULL) - gtk_object_unref (GTK_OBJECT (ctxt->client)); - - if (ctxt->calendar_file) - g_free (ctxt->calendar_file); - - if (ctxt->uids) - cal_obj_uid_list_free (ctxt->uids); - - if (ctxt->changed_hash) - g_hash_table_foreach (ctxt->changed_hash, e_todo_context_foreach_change, NULL); - - if (ctxt->changed) - cal_client_change_list_free (ctxt->changed); - - if (ctxt->map) - e_pilot_map_destroy (ctxt->map); - - g_free (ctxt); -} - -/* Calendar Server routines */ -static void -start_calendar_server_cb (CalClient *cal_client, - CalClientOpenStatus status, - gpointer data) -{ - EToDoConduitContext *ctxt; - - ctxt = data; - - LOG (" entering start_calendar_server_cb\n"); - - if (status == CAL_CLIENT_OPEN_SUCCESS) { - ctxt->calendar_open_success = TRUE; - LOG (" success\n"); - } else - LOG (" open of calendar failed\n"); - - gtk_main_quit (); /* end the sub event loop */ -} - -static int -start_calendar_server (EToDoConduitContext *ctxt) -{ - - g_return_val_if_fail (ctxt != NULL, -2); - - ctxt->client = cal_client_new (); - - /* FIX ME */ - ctxt->calendar_file = g_concat_dir_and_file (g_get_home_dir (), - "evolution/local/Tasks/tasks.ics"); - - gtk_signal_connect (GTK_OBJECT (ctxt->client), "cal_opened", - start_calendar_server_cb, ctxt); - - LOG (" calling cal_client_open_calendar\n"); - if (!cal_client_open_calendar (ctxt->client, ctxt->calendar_file, FALSE)) - return -1; - - /* run a sub event loop to turn cal-client's async load - notification into a synchronous call */ - gtk_main (); - - if (ctxt->calendar_open_success) - return 0; - - return -1; -} - -/* Utility routines */ -static char * -map_name (EToDoConduitContext *ctxt) -{ - char *filename; - - filename = g_strdup_printf ("%s/evolution/local/Tasks/pilot-map-todo-%d.xml", g_get_home_dir (), ctxt->cfg->pilot_id); - - return filename; -} - -static gboolean -is_empty_time (struct tm time) -{ - if (time.tm_sec || time.tm_min || time.tm_hour - || time.tm_mday || time.tm_mon || time.tm_year) - return FALSE; - - return TRUE; -} - -static GList * -next_changed_item (EToDoConduitContext *ctxt, GList *changes) -{ - CalClientChange *ccc; - GList *l; - - for (l = changes; l != NULL; l = l->next) { - const char *uid; - - ccc = l->data; - - cal_component_get_uid (ccc->comp, &uid); - if (g_hash_table_lookup (ctxt->changed_hash, uid)) - return l; - } - - return NULL; -} - -static void -compute_status (EToDoConduitContext *ctxt, EToDoLocalRecord *local, const char *uid) -{ - CalClientChange *ccc; - - local->local.archived = FALSE; - local->local.secret = FALSE; - - ccc = g_hash_table_lookup (ctxt->changed_hash, uid); - - if (ccc == NULL) { - local->local.attr = GnomePilotRecordNothing; - return; - } - - switch (ccc->type) { - case CAL_CLIENT_CHANGE_ADDED: - local->local.attr = GnomePilotRecordNew; - break; - case CAL_CLIENT_CHANGE_MODIFIED: - local->local.attr = GnomePilotRecordModified; - break; - case CAL_CLIENT_CHANGE_DELETED: - local->local.attr = GnomePilotRecordDeleted; - break; - } -} - -static GnomePilotRecord -local_record_to_pilot_record (EToDoLocalRecord *local, - EToDoConduitContext *ctxt) -{ - GnomePilotRecord p; - - g_assert (local->comp != NULL); - g_assert (local->todo != NULL ); - - LOG ("local_record_to_pilot_record\n"); - - p.ID = local->local.ID; - p.category = 0; - p.attr = local->local.attr; - p.archived = local->local.archived; - p.secret = local->local.secret; - - /* Generate pilot record structure */ - p.record = g_new0 (char, 0xffff); - p.length = pack_ToDo (local->todo, p.record, 0xffff); - - return p; -} - -/* - * converts a CalComponent object to a EToDoLocalRecord - */ -static void -local_record_from_comp (EToDoLocalRecord *local, CalComponent *comp, EToDoConduitContext *ctxt) -{ - const char *uid; - int *priority; - struct icaltimetype *completed; - CalComponentText summary; - GSList *d_list = NULL; - CalComponentText *description; - CalComponentDateTime due; - time_t due_time; - CalComponentClassification classif; - - LOG ("local_record_from_comp\n"); - - g_return_if_fail (local != NULL); - g_return_if_fail (comp != NULL); - - local->comp = comp; - gtk_object_ref (GTK_OBJECT (comp)); - - cal_component_get_uid (local->comp, &uid); - local->local.ID = e_pilot_map_lookup_pid (ctxt->map, uid); - - compute_status (ctxt, local, uid); - - local->todo = g_new0 (struct ToDo,1); - - /* STOP: don't replace these with g_strdup, since free_ToDo - uses free to deallocate */ - cal_component_get_summary (comp, &summary); - if (summary.value) - local->todo->description = e_pilot_utf8_to_pchar (summary.value); - - cal_component_get_description_list (comp, &d_list); - if (d_list) { - description = (CalComponentText *) d_list->data; - if (description && description->value) - local->todo->note = e_pilot_utf8_to_pchar (description->value); - else - local->todo->note = NULL; - } else { - local->todo->note = NULL; - } - - cal_component_get_due (comp, &due); - if (due.value) { - due_time = icaltime_as_timet (*due.value); - - local->todo->due = *localtime (&due_time); - local->todo->indefinite = 0; - } else { - local->todo->indefinite = 1; - } - - cal_component_get_completed (comp, &completed); - if (completed) { - local->todo->complete = 1; - cal_component_free_icaltimetype (completed); - } - - cal_component_get_priority (comp, &priority); - if (priority) { - local->todo->priority = *priority; - cal_component_free_priority (priority); - } - - cal_component_get_classification (comp, &classif); - - if (classif == CAL_COMPONENT_CLASS_PRIVATE) - local->local.secret = 1; - else - local->local.secret = 0; - - local->local.archived = 0; -} - -static void -local_record_from_uid (EToDoLocalRecord *local, - const char *uid, - EToDoConduitContext *ctxt) -{ - CalComponent *comp; - CalClientGetStatus status; - - g_assert(local!=NULL); - - status = cal_client_get_object (ctxt->client, uid, &comp); - - if (status == CAL_CLIENT_GET_SUCCESS) { - local_record_from_comp (local, comp, ctxt); - } else if (status == CAL_CLIENT_GET_NOT_FOUND) { - comp = cal_component_new (); - cal_component_set_new_vtype (comp, CAL_COMPONENT_TODO); - cal_component_set_uid (comp, uid); - local_record_from_comp (local, comp, ctxt); - } else { - INFO ("Object did not exist"); - } -} - - -static CalComponent * -comp_from_remote_record (GnomePilotConduitSyncAbs *conduit, - GnomePilotRecord *remote, - CalComponent *in_comp) -{ - CalComponent *comp; - struct ToDo todo; - struct icaltimetype now = icaltime_from_timet (time (NULL), FALSE); - CalComponentText summary = {NULL, NULL}; - CalComponentDateTime dt = {NULL, NULL}; - struct icaltimetype due; - char *txt; - - g_return_val_if_fail (remote != NULL, NULL); - - memset (&todo, 0, sizeof (struct ToDo)); - unpack_ToDo (&todo, remote->record, remote->length); - - if (in_comp == NULL) { - comp = cal_component_new (); - cal_component_set_new_vtype (comp, CAL_COMPONENT_TODO); - cal_component_set_created (comp, &now); - } else { - comp = cal_component_clone (in_comp); - } - - cal_component_set_last_modified (comp, &now); - - summary.value = txt = e_pilot_utf8_from_pchar (todo.description); - cal_component_set_summary (comp, &summary); - free (txt); - - /* The iCal description field */ - if (!todo.note) { - cal_component_set_comment_list (comp, NULL); - } else { - GSList l; - CalComponentText text; - - text.value = txt = e_pilot_utf8_from_pchar (todo.note); - text.altrep = NULL; - l.data = &text; - l.next = NULL; - - cal_component_set_description_list (comp, &l); - free (txt); - } - - if (todo.complete) { - int percent = 100; - cal_component_set_completed (comp, &now); - cal_component_set_percent (comp, &percent); - } - - if (!is_empty_time (todo.due)) { - due = icaltime_from_timet (mktime (&todo.due), FALSE); - dt.value = &due; - cal_component_set_due (comp, &dt); - } - - cal_component_set_priority (comp, &todo.priority); - cal_component_set_transparency (comp, CAL_COMPONENT_TRANSP_NONE); - - if (remote->attr & dlpRecAttrSecret) - cal_component_set_classification (comp, CAL_COMPONENT_CLASS_PRIVATE); - else - cal_component_set_classification (comp, CAL_COMPONENT_CLASS_PUBLIC); - - cal_component_commit_sequence (comp); - - free_ToDo(&todo); - - return comp; -} - -static void -update_comp (GnomePilotConduitSyncAbs *conduit, CalComponent *comp, - EToDoConduitContext *ctxt) -{ - gboolean success; - - g_return_if_fail (conduit != NULL); - g_return_if_fail (comp != NULL); - - success = cal_client_update_object (ctxt->client, comp); - - if (!success) - WARN (_("Error while communicating with calendar server")); -} - -static void -check_for_slow_setting (GnomePilotConduit *c, EToDoConduitContext *ctxt) -{ - int count, map_count; - - count = g_list_length (ctxt->uids); - map_count = g_hash_table_size (ctxt->map->pid_map); - - /* If there are no objects or objects but no log */ - if (map_count == 0) { - GnomePilotConduitStandard *conduit; - LOG (" doing slow sync\n"); - conduit = GNOME_PILOT_CONDUIT_STANDARD (c); - gnome_pilot_conduit_standard_set_slow (conduit); - } else { - LOG (" doing fast sync\n"); - } -} - -/* Pilot syncing callbacks */ -static gint -pre_sync (GnomePilotConduit *conduit, - GnomePilotDBInfo *dbi, - EToDoConduitContext *ctxt) -{ - GnomePilotConduitSyncAbs *abs_conduit; - GList *l; - int len; - unsigned char *buf; - char *filename, *change_id; - gint num_records, add_records = 0, mod_records = 0, del_records = 0; - - abs_conduit = GNOME_PILOT_CONDUIT_SYNC_ABS (conduit); - - LOG ("---------------------------------------------------------\n"); - LOG ("pre_sync: ToDo Conduit v.%s", CONDUIT_VERSION); - g_message ("ToDo Conduit v.%s", CONDUIT_VERSION); - - ctxt->client = NULL; - - if (start_calendar_server (ctxt) != 0) { - WARN(_("Could not start wombat server")); - gnome_pilot_conduit_error (conduit, _("Could not start wombat")); - 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); - - /* 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); - ctxt->changed_hash = g_hash_table_new (g_str_hash, g_str_equal); - - for (l = ctxt->changed; l != NULL; l = l->next) { - CalClientChange *ccc = l->data; - const char *uid; - - cal_component_get_uid (ccc->comp, &uid); - if (!e_pilot_map_uid_is_archived (ctxt->map, uid)) { - - g_hash_table_insert (ctxt->changed_hash, g_strdup (uid), ccc); - - switch (ccc->type) { - case CAL_CLIENT_CHANGE_ADDED: - add_records++; - break; - case CAL_CLIENT_CHANGE_MODIFIED: - mod_records++; - break; - case CAL_CLIENT_CHANGE_DELETED: - del_records++; - break; - } - } - } - - /* Set the count information */ - num_records = cal_client_get_n_objects (ctxt->client, CALOBJ_TYPE_TODO); - 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); - gnome_pilot_conduit_sync_abs_set_num_deleted_local_records(abs_conduit, del_records); - - gtk_object_set_data (GTK_OBJECT (conduit), "dbinfo", dbi); - - buf = (unsigned char*)g_malloc (0xffff); - len = dlp_ReadAppBlock (dbi->pilot_socket, dbi->db_handle, 0, - (unsigned char *)buf, 0xffff); - - if (len < 0) { - WARN (_("Could not read pilot's ToDo application block")); - WARN ("dlp_ReadAppBlock(...) = %d", len); - gnome_pilot_conduit_error (conduit, - _("Could not read pilot's ToDo application block")); - return -1; - } - unpack_ToDoAppInfo (&(ctxt->ai), buf, len); - g_free (buf); - - check_for_slow_setting (conduit, ctxt); - - return 0; -} - -static gint -post_sync (GnomePilotConduit *conduit, - GnomePilotDBInfo *dbi, - EToDoConduitContext *ctxt) -{ - GList *changed; - gchar *filename, *change_id; - - LOG ("post_sync: ToDo Conduit v.%s", CONDUIT_VERSION); - LOG ("---------------------------------------------------------\n"); - - filename = map_name (ctxt); - e_pilot_map_write (filename, ctxt->map); - g_free (filename); - - /* FIX ME ugly hack - our changes musn't count, this does introduce - * 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); - - return 0; -} - -static gint -set_pilot_id (GnomePilotConduitSyncAbs *conduit, - EToDoLocalRecord *local, - guint32 ID, - EToDoConduitContext *ctxt) -{ - const char *uid; - - LOG ("set_pilot_id: setting to %d\n", ID); - - cal_component_get_uid (local->comp, &uid); - e_pilot_map_insert (ctxt->map, ID, uid, FALSE); - - return 0; -} - -static gint -set_status_cleared (GnomePilotConduitSyncAbs *conduit, - EToDoLocalRecord *local, - EToDoConduitContext *ctxt) -{ - const char *uid; - - LOG ("set_status_cleared: clearing status\n"); - - cal_component_get_uid (local->comp, &uid); - g_hash_table_remove (ctxt->changed_hash, uid); - - return 0; -} - -static gint -for_each (GnomePilotConduitSyncAbs *conduit, - EToDoLocalRecord **local, - EToDoConduitContext *ctxt) -{ - static GList *uids, *iterator; - static int count; - - g_return_val_if_fail (local != NULL, -1); - - if (*local == NULL) { - LOG ("beginning for_each"); - - uids = ctxt->uids; - count = 0; - - if (uids != NULL) { - LOG ("iterating over %d records", g_list_length (uids)); - - *local = g_new0 (EToDoLocalRecord, 1); - local_record_from_uid (*local, uids->data, ctxt); - - iterator = uids; - } else { - LOG ("no events"); - (*local) = NULL; - return 0; - } - } else { - count++; - if (g_list_next (iterator)) { - iterator = g_list_next (iterator); - - *local = g_new0 (EToDoLocalRecord, 1); - local_record_from_uid (*local, iterator->data, ctxt); - } else { - LOG ("for_each ending"); - - /* Tell the pilot the iteration is over */ - *local = NULL; - - return 0; - } - } - - return 0; -} - -static gint -for_each_modified (GnomePilotConduitSyncAbs *conduit, - EToDoLocalRecord **local, - EToDoConduitContext *ctxt) -{ - static GList *iterator; - static int count; - - g_return_val_if_fail (local != NULL, 0); - - if (*local == NULL) { - LOG ("beginning for_each_modified: beginning\n"); - - iterator = ctxt->changed; - - count = 0; - - LOG ("iterating over %d records", g_hash_table_size (ctxt->changed_hash)); - - iterator = next_changed_item (ctxt, iterator); - if (iterator != NULL) { - CalClientChange *ccc = iterator->data; - - *local = g_new0 (EToDoLocalRecord, 1); - local_record_from_comp (*local, ccc->comp, ctxt); - } else { - LOG ("no events"); - - *local = NULL; - } - } else { - count++; - iterator = g_list_next (iterator); - if (iterator && (iterator = next_changed_item (ctxt, iterator))) { - CalClientChange *ccc = iterator->data; - - *local = g_new0 (EToDoLocalRecord, 1); - local_record_from_comp (*local, ccc->comp, ctxt); - } else { - LOG ("for_each_modified ending"); - - /* Signal the iteration is over */ - *local = NULL; - } - } - - return 0; -} - -static gint -compare (GnomePilotConduitSyncAbs *conduit, - EToDoLocalRecord *local, - GnomePilotRecord *remote, - EToDoConduitContext *ctxt) -{ - /* used by the quick compare */ - GnomePilotRecord local_pilot; - int retval = 0; - - LOG ("compare: local=%s remote=%s...\n", - print_local (local), print_remote (remote)); - - g_return_val_if_fail (local!=NULL,-1); - g_return_val_if_fail (remote!=NULL,-1); - - local_pilot = local_record_to_pilot_record (local, ctxt); - - if (remote->length != local_pilot.length - || memcmp (local_pilot.record, remote->record, remote->length)) - retval = 1; - - if (retval == 0) - LOG (" equal"); - else - LOG (" not equal"); - - return retval; -} - -static gint -add_record (GnomePilotConduitSyncAbs *conduit, - GnomePilotRecord *remote, - EToDoConduitContext *ctxt) -{ - CalComponent *comp; - const char *uid; - int retval = 0; - - g_return_val_if_fail (remote != NULL, -1); - - LOG ("add_record: adding %s to desktop\n", print_remote (remote)); - - comp = comp_from_remote_record (conduit, remote, NULL); - update_comp (conduit, comp, ctxt); - - cal_component_get_uid (comp, &uid); - - e_pilot_map_insert (ctxt->map, remote->ID, uid, FALSE); - - return retval; -} - -static gint -replace_record (GnomePilotConduitSyncAbs *conduit, - EToDoLocalRecord *local, - GnomePilotRecord *remote, - EToDoConduitContext *ctxt) -{ - CalComponent *new_comp; - int retval = 0; - - g_return_val_if_fail (remote != NULL, -1); - - LOG ("replace_record: replace %s with %s\n", - print_local (local), print_remote (remote)); - - new_comp = comp_from_remote_record (conduit, remote, local->comp); - gtk_object_unref (GTK_OBJECT (local->comp)); - local->comp = new_comp; - update_comp (conduit, local->comp, ctxt); - - return retval; -} - -static gint -delete_record (GnomePilotConduitSyncAbs *conduit, - EToDoLocalRecord *local, - EToDoConduitContext *ctxt) -{ - const char *uid; - - g_return_val_if_fail (local != NULL, -1); - g_return_val_if_fail (local->comp != NULL, -1); - - cal_component_get_uid (local->comp, &uid); - - LOG ("delete_record: deleting %s\n", uid); - - e_pilot_map_remove_by_uid (ctxt->map, uid); - cal_client_remove_object (ctxt->client, uid); - - return 0; -} - -static gint -archive_record (GnomePilotConduitSyncAbs *conduit, - EToDoLocalRecord *local, - gboolean archive, - EToDoConduitContext *ctxt) -{ - const char *uid; - int retval = 0; - - g_return_val_if_fail (local != NULL, -1); - - LOG ("archive_record: %s\n", archive ? "yes" : "no"); - - cal_component_get_uid (local->comp, &uid); - e_pilot_map_insert (ctxt->map, local->local.ID, uid, archive); - - return retval; -} - -static gint -match (GnomePilotConduitSyncAbs *conduit, - GnomePilotRecord *remote, - EToDoLocalRecord **local, - EToDoConduitContext *ctxt) -{ - const char *uid; - - LOG ("match: looking for local copy of %s\n", - print_remote (remote)); - - g_return_val_if_fail (local != NULL, -1); - g_return_val_if_fail (remote != NULL, -1); - - *local = NULL; - uid = e_pilot_map_lookup_uid (ctxt->map, remote->ID); - - if (!uid) - return 0; - - LOG (" matched\n"); - - *local = g_new0 (EToDoLocalRecord, 1); - local_record_from_uid (*local, uid, ctxt); - - return 0; -} - -static gint -free_match (GnomePilotConduitSyncAbs *conduit, - EToDoLocalRecord *local, - EToDoConduitContext *ctxt) -{ - LOG ("free_match: freeing\n"); - - g_return_val_if_fail (local != NULL, -1); - - gtk_object_unref (GTK_OBJECT (local->comp)); - g_free (local); - - return 0; -} - -static gint -prepare (GnomePilotConduitSyncAbs *conduit, - EToDoLocalRecord *local, - GnomePilotRecord *remote, - EToDoConduitContext *ctxt) -{ - LOG ("prepare: encoding local %s\n", print_local (local)); - - *remote = local_record_to_pilot_record (local, ctxt); - - return 0; -} - -static ORBit_MessageValidationResult -accept_all_cookies (CORBA_unsigned_long request_id, - CORBA_Principal *principal, - CORBA_char *operation) -{ - /* allow ALL cookies */ - return ORBIT_MESSAGE_ALLOW_ALL; -} - - -GnomePilotConduit * -conduit_get_gpilot_conduit (guint32 pilot_id) -{ - GtkObject *retval; - EToDoConduitContext *ctxt; - - LOG ("in todo's conduit_get_gpilot_conduit\n"); - - /* we need to find wombat with oaf, so make sure oaf - is initialized here. once the desktop is converted - to oaf and gpilotd is built with oaf, this can go away */ - if (!oaf_is_initialized ()) { - char *argv[ 1 ] = {"hi"}; - oaf_init (1, argv); - - if (bonobo_init (CORBA_OBJECT_NIL, - CORBA_OBJECT_NIL, - CORBA_OBJECT_NIL) == FALSE) - g_error (_("Could not initialize Bonobo")); - - ORBit_set_request_validation_handler (accept_all_cookies); - } - - retval = gnome_pilot_conduit_sync_abs_new ("ToDoDB", 0x746F646F); - g_assert (retval != NULL); - - gnome_pilot_conduit_construct (GNOME_PILOT_CONDUIT (retval), - "e_todo_conduit"); - - ctxt = e_todo_context_new (pilot_id); - gtk_object_set_data (GTK_OBJECT (retval), "todoconduit_context", ctxt); - - gtk_signal_connect (retval, "pre_sync", (GtkSignalFunc) pre_sync, ctxt); - gtk_signal_connect (retval, "post_sync", (GtkSignalFunc) post_sync, ctxt); - - gtk_signal_connect (retval, "set_pilot_id", (GtkSignalFunc) set_pilot_id, ctxt); - gtk_signal_connect (retval, "set_status_cleared", (GtkSignalFunc) set_status_cleared, ctxt); - - gtk_signal_connect (retval, "for_each", (GtkSignalFunc) for_each, ctxt); - gtk_signal_connect (retval, "for_each_modified", (GtkSignalFunc) for_each_modified, ctxt); - gtk_signal_connect (retval, "compare", (GtkSignalFunc) compare, ctxt); - - gtk_signal_connect (retval, "add_record", (GtkSignalFunc) add_record, ctxt); - gtk_signal_connect (retval, "replace_record", (GtkSignalFunc) replace_record, ctxt); - gtk_signal_connect (retval, "delete_record", (GtkSignalFunc) delete_record, ctxt); - gtk_signal_connect (retval, "archive_record", (GtkSignalFunc) archive_record, ctxt); - - gtk_signal_connect (retval, "match", (GtkSignalFunc) match, ctxt); - gtk_signal_connect (retval, "free_match", (GtkSignalFunc) free_match, ctxt); - - gtk_signal_connect (retval, "prepare", (GtkSignalFunc) prepare, ctxt); - - return GNOME_PILOT_CONDUIT (retval); -} - -void -conduit_destroy_gpilot_conduit (GnomePilotConduit *conduit) -{ - GtkObject *obj = GTK_OBJECT (conduit); - EToDoConduitContext *ctxt; - - ctxt = gtk_object_get_data (obj, "todoconduit_context"); - e_todo_context_destroy (ctxt); - - gtk_object_destroy (obj); -} diff --git a/calendar/conduits/todo/todo-conduit.h b/calendar/conduits/todo/todo-conduit.h deleted file mode 100644 index 46f89fc1a0..0000000000 --- a/calendar/conduits/todo/todo-conduit.h +++ /dev/null @@ -1,78 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Evolution calendar - ToDo Conduit Capplet - * - * Copyright (C) 1998 Free Software Foundation - * Copyright (C) 2000 Helix Code, Inc. - * - * Authors: Eskil Heyn Olsen <deity@eskil.dk> - * JP Rosevear <jpr@helixcode.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef __TODO_CONDUIT_H__ -#define __TODO_CONDUIT_H__ - -#include <sys/types.h> -#include <fcntl.h> -#include <unistd.h> -#include <gnome.h> -#include <pi-todo.h> -#include <gpilotd/gnome-pilot-conduit.h> -#include <gpilotd/gnome-pilot-conduit-sync-abs.h> -#include <cal-client/cal-client.h> -#include <e-pilot-map.h> - -/* This is the local record structure for the Evolution ToDo conduit. */ -typedef struct _EToDoLocalRecord EToDoLocalRecord; -struct _EToDoLocalRecord { - /* The stuff from gnome-pilot-conduit-standard-abs.h - Must be first in the structure, or instances of this - structure cannot be used by gnome-pilot-conduit-standard-abs. - */ - GnomePilotDesktopRecord local; - - /* The corresponding Comp object */ - CalComponent *comp; - - /* pilot-link todo structure */ - struct ToDo *todo; -}; - -/* This is the context for all the Evolution ToDo conduit methods. */ -typedef struct _EToDoConduitContext EToDoConduitContext; -struct _EToDoConduitContext { - EToDoConduitCfg *cfg; - - struct ToDoAppInfo ai; - - CalClient *client; - char *calendar_file; - gboolean calendar_open_success; - - GList *uids; - GList *changed; - GHashTable *changed_hash; - - EPilotMap *map; -}; - -#endif __TODO_CONDUIT_H__ - - - - - - diff --git a/calendar/gui/.cvsignore b/calendar/gui/.cvsignore deleted file mode 100644 index f7f6b10b34..0000000000 --- a/calendar/gui/.cvsignore +++ /dev/null @@ -1,17 +0,0 @@ -Makefile.in -Makefile -.deps -_libs -.libs -.pure -evolution-calendar -evolution-calendar.pure -getdate.c -*.lo -Evolution-Composer-common.c -Evolution-Composer-skels.c -Evolution-Composer-stubs.c -Evolution-Composer.h -GNOME_Evolution_Calendar_Control.oaf -GNOME_Evolution_Calendar.oaf -GNOME_Evolution_Calendar_gnomecal.oaf diff --git a/calendar/gui/Evolution-Composer.h b/calendar/gui/Evolution-Composer.h deleted file mode 100644 index bd61419d04..0000000000 --- a/calendar/gui/Evolution-Composer.h +++ /dev/null @@ -1,352 +0,0 @@ -/* - * This file was generated by orbit-idl - DO NOT EDIT! - */ - -#include <glib.h> -#define ORBIT_IDL_SERIAL 9 -#include <orb/orbit.h> - -#ifndef Evolution_Composer_H -#define Evolution_Composer_H 1 -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -/** typedefs **/ -#include <bonobo/Bonobo.h> -#if !defined(ORBIT_DECL_GNOME_Evolution_Composer) && !defined(_GNOME_Evolution_Composer_defined) -#define ORBIT_DECL_GNOME_Evolution_Composer 1 -#define _GNOME_Evolution_Composer_defined 1 -#define GNOME_Evolution_Composer__free CORBA_Object__free - typedef CORBA_Object GNOME_Evolution_Composer; - extern CORBA_unsigned_long GNOME_Evolution_Composer__classid; -#if !defined(TC_IMPL_TC_GNOME_Evolution_Composer_0) -#define TC_IMPL_TC_GNOME_Evolution_Composer_0 'E' -#define TC_IMPL_TC_GNOME_Evolution_Composer_1 'v' -#define TC_IMPL_TC_GNOME_Evolution_Composer_2 'o' -#define TC_IMPL_TC_GNOME_Evolution_Composer_3 'l' -#define TC_IMPL_TC_GNOME_Evolution_Composer_4 'u' -#define TC_IMPL_TC_GNOME_Evolution_Composer_5 't' -#define TC_IMPL_TC_GNOME_Evolution_Composer_6 'i' -#define TC_IMPL_TC_GNOME_Evolution_Composer_7 'o' -#define TC_IMPL_TC_GNOME_Evolution_Composer_8 'n' -#define TC_IMPL_TC_GNOME_Evolution_Composer_9 '_' -#define TC_IMPL_TC_GNOME_Evolution_Composer_10 'C' -#define TC_IMPL_TC_GNOME_Evolution_Composer_11 'o' -#define TC_IMPL_TC_GNOME_Evolution_Composer_12 'm' -#define TC_IMPL_TC_GNOME_Evolution_Composer_13 'p' -#define TC_IMPL_TC_GNOME_Evolution_Composer_14 'o' -#define TC_IMPL_TC_GNOME_Evolution_Composer_15 's' -#define TC_IMPL_TC_GNOME_Evolution_Composer_16 'e' -#define TC_IMPL_TC_GNOME_Evolution_Composer_17 'r' - extern const struct CORBA_TypeCode_struct - TC_GNOME_Evolution_Composer_struct; -#define TC_GNOME_Evolution_Composer ((CORBA_TypeCode)&TC_GNOME_Evolution_Composer_struct) -#endif -#endif -#if !defined(_GNOME_Evolution_Composer_Recipient_defined) -#define _GNOME_Evolution_Composer_Recipient_defined 1 - typedef struct - { - CORBA_char *name; - CORBA_char *address; - } - GNOME_Evolution_Composer_Recipient; - -#if !defined(TC_IMPL_TC_GNOME_Evolution_Composer_Recipient_0) -#define TC_IMPL_TC_GNOME_Evolution_Composer_Recipient_0 'E' -#define TC_IMPL_TC_GNOME_Evolution_Composer_Recipient_1 'v' -#define TC_IMPL_TC_GNOME_Evolution_Composer_Recipient_2 'o' -#define TC_IMPL_TC_GNOME_Evolution_Composer_Recipient_3 'l' -#define TC_IMPL_TC_GNOME_Evolution_Composer_Recipient_4 'u' -#define TC_IMPL_TC_GNOME_Evolution_Composer_Recipient_5 't' -#define TC_IMPL_TC_GNOME_Evolution_Composer_Recipient_6 'i' -#define TC_IMPL_TC_GNOME_Evolution_Composer_Recipient_7 'o' -#define TC_IMPL_TC_GNOME_Evolution_Composer_Recipient_8 'n' -#define TC_IMPL_TC_GNOME_Evolution_Composer_Recipient_9 '_' -#define TC_IMPL_TC_GNOME_Evolution_Composer_Recipient_10 'C' -#define TC_IMPL_TC_GNOME_Evolution_Composer_Recipient_11 'o' -#define TC_IMPL_TC_GNOME_Evolution_Composer_Recipient_12 'm' -#define TC_IMPL_TC_GNOME_Evolution_Composer_Recipient_13 'p' -#define TC_IMPL_TC_GNOME_Evolution_Composer_Recipient_14 'o' -#define TC_IMPL_TC_GNOME_Evolution_Composer_Recipient_15 's' -#define TC_IMPL_TC_GNOME_Evolution_Composer_Recipient_16 'e' -#define TC_IMPL_TC_GNOME_Evolution_Composer_Recipient_17 'r' - extern const struct CORBA_TypeCode_struct - TC_GNOME_Evolution_Composer_Recipient_struct; -#define TC_GNOME_Evolution_Composer_Recipient ((CORBA_TypeCode)&TC_GNOME_Evolution_Composer_Recipient_struct) -#endif - extern GNOME_Evolution_Composer_Recipient - *GNOME_Evolution_Composer_Recipient__alloc(void); - extern gpointer GNOME_Evolution_Composer_Recipient__free(gpointer mem, - gpointer dat, - CORBA_boolean free_strings); /* ORBit internal use */ -#endif -#if !defined(ORBIT_DECL_CORBA_sequence_GNOME_Evolution_Composer_Recipient) && !defined(_CORBA_sequence_GNOME_Evolution_Composer_Recipient_defined) -#define ORBIT_DECL_CORBA_sequence_GNOME_Evolution_Composer_Recipient 1 -#define _CORBA_sequence_GNOME_Evolution_Composer_Recipient_defined 1 -#define ORBIT_IMPL_CORBA_sequence_GNOME_Evolution_Composer_Recipient_0 'E' -#define ORBIT_IMPL_CORBA_sequence_GNOME_Evolution_Composer_Recipient_1 'v' -#define ORBIT_IMPL_CORBA_sequence_GNOME_Evolution_Composer_Recipient_2 'o' -#define ORBIT_IMPL_CORBA_sequence_GNOME_Evolution_Composer_Recipient_3 'l' -#define ORBIT_IMPL_CORBA_sequence_GNOME_Evolution_Composer_Recipient_4 'u' -#define ORBIT_IMPL_CORBA_sequence_GNOME_Evolution_Composer_Recipient_5 't' -#define ORBIT_IMPL_CORBA_sequence_GNOME_Evolution_Composer_Recipient_6 'i' -#define ORBIT_IMPL_CORBA_sequence_GNOME_Evolution_Composer_Recipient_7 'o' -#define ORBIT_IMPL_CORBA_sequence_GNOME_Evolution_Composer_Recipient_8 'n' -#define ORBIT_IMPL_CORBA_sequence_GNOME_Evolution_Composer_Recipient_9 '_' -#define ORBIT_IMPL_CORBA_sequence_GNOME_Evolution_Composer_Recipient_10 'C' -#define ORBIT_IMPL_CORBA_sequence_GNOME_Evolution_Composer_Recipient_11 'o' -#define ORBIT_IMPL_CORBA_sequence_GNOME_Evolution_Composer_Recipient_12 'm' -#define ORBIT_IMPL_CORBA_sequence_GNOME_Evolution_Composer_Recipient_13 'p' -#define ORBIT_IMPL_CORBA_sequence_GNOME_Evolution_Composer_Recipient_14 'o' -#define ORBIT_IMPL_CORBA_sequence_GNOME_Evolution_Composer_Recipient_15 's' -#define ORBIT_IMPL_CORBA_sequence_GNOME_Evolution_Composer_Recipient_16 'e' -#define ORBIT_IMPL_CORBA_sequence_GNOME_Evolution_Composer_Recipient_17 'r' - typedef struct - { - CORBA_unsigned_long _maximum, - _length; - GNOME_Evolution_Composer_Recipient *_buffer; - CORBA_boolean _release; - } - CORBA_sequence_GNOME_Evolution_Composer_Recipient; -#if !defined(TC_IMPL_TC_CORBA_sequence_GNOME_Evolution_Composer_Recipient_0) -#define TC_IMPL_TC_CORBA_sequence_GNOME_Evolution_Composer_Recipient_0 'E' -#define TC_IMPL_TC_CORBA_sequence_GNOME_Evolution_Composer_Recipient_1 'v' -#define TC_IMPL_TC_CORBA_sequence_GNOME_Evolution_Composer_Recipient_2 'o' -#define TC_IMPL_TC_CORBA_sequence_GNOME_Evolution_Composer_Recipient_3 'l' -#define TC_IMPL_TC_CORBA_sequence_GNOME_Evolution_Composer_Recipient_4 'u' -#define TC_IMPL_TC_CORBA_sequence_GNOME_Evolution_Composer_Recipient_5 't' -#define TC_IMPL_TC_CORBA_sequence_GNOME_Evolution_Composer_Recipient_6 'i' -#define TC_IMPL_TC_CORBA_sequence_GNOME_Evolution_Composer_Recipient_7 'o' -#define TC_IMPL_TC_CORBA_sequence_GNOME_Evolution_Composer_Recipient_8 'n' -#define TC_IMPL_TC_CORBA_sequence_GNOME_Evolution_Composer_Recipient_9 '_' -#define TC_IMPL_TC_CORBA_sequence_GNOME_Evolution_Composer_Recipient_10 'C' -#define TC_IMPL_TC_CORBA_sequence_GNOME_Evolution_Composer_Recipient_11 'o' -#define TC_IMPL_TC_CORBA_sequence_GNOME_Evolution_Composer_Recipient_12 'm' -#define TC_IMPL_TC_CORBA_sequence_GNOME_Evolution_Composer_Recipient_13 'p' -#define TC_IMPL_TC_CORBA_sequence_GNOME_Evolution_Composer_Recipient_14 'o' -#define TC_IMPL_TC_CORBA_sequence_GNOME_Evolution_Composer_Recipient_15 's' -#define TC_IMPL_TC_CORBA_sequence_GNOME_Evolution_Composer_Recipient_16 'e' -#define TC_IMPL_TC_CORBA_sequence_GNOME_Evolution_Composer_Recipient_17 'r' - extern const struct CORBA_TypeCode_struct - TC_CORBA_sequence_GNOME_Evolution_Composer_Recipient_struct; -#define TC_CORBA_sequence_GNOME_Evolution_Composer_Recipient ((CORBA_TypeCode)&TC_CORBA_sequence_GNOME_Evolution_Composer_Recipient_struct) -#endif - extern CORBA_sequence_GNOME_Evolution_Composer_Recipient - *CORBA_sequence_GNOME_Evolution_Composer_Recipient__alloc(void); - extern gpointer - CORBA_sequence_GNOME_Evolution_Composer_Recipient__free(gpointer mem, - gpointer dat, - CORBA_boolean free_strings); /* ORBit internal use */ - GNOME_Evolution_Composer_Recipient - *CORBA_sequence_GNOME_Evolution_Composer_Recipient_allocbuf - (CORBA_unsigned_long len); -#endif -#if !defined(_GNOME_Evolution_Composer_RecipientList_defined) -#define _GNOME_Evolution_Composer_RecipientList_defined 1 - typedef CORBA_sequence_GNOME_Evolution_Composer_Recipient - GNOME_Evolution_Composer_RecipientList; -#if !defined(TC_IMPL_TC_GNOME_Evolution_Composer_RecipientList_0) -#define TC_IMPL_TC_GNOME_Evolution_Composer_RecipientList_0 'E' -#define TC_IMPL_TC_GNOME_Evolution_Composer_RecipientList_1 'v' -#define TC_IMPL_TC_GNOME_Evolution_Composer_RecipientList_2 'o' -#define TC_IMPL_TC_GNOME_Evolution_Composer_RecipientList_3 'l' -#define TC_IMPL_TC_GNOME_Evolution_Composer_RecipientList_4 'u' -#define TC_IMPL_TC_GNOME_Evolution_Composer_RecipientList_5 't' -#define TC_IMPL_TC_GNOME_Evolution_Composer_RecipientList_6 'i' -#define TC_IMPL_TC_GNOME_Evolution_Composer_RecipientList_7 'o' -#define TC_IMPL_TC_GNOME_Evolution_Composer_RecipientList_8 'n' -#define TC_IMPL_TC_GNOME_Evolution_Composer_RecipientList_9 '_' -#define TC_IMPL_TC_GNOME_Evolution_Composer_RecipientList_10 'C' -#define TC_IMPL_TC_GNOME_Evolution_Composer_RecipientList_11 'o' -#define TC_IMPL_TC_GNOME_Evolution_Composer_RecipientList_12 'm' -#define TC_IMPL_TC_GNOME_Evolution_Composer_RecipientList_13 'p' -#define TC_IMPL_TC_GNOME_Evolution_Composer_RecipientList_14 'o' -#define TC_IMPL_TC_GNOME_Evolution_Composer_RecipientList_15 's' -#define TC_IMPL_TC_GNOME_Evolution_Composer_RecipientList_16 'e' -#define TC_IMPL_TC_GNOME_Evolution_Composer_RecipientList_17 'r' - extern const struct CORBA_TypeCode_struct - TC_GNOME_Evolution_Composer_RecipientList_struct; -#define TC_GNOME_Evolution_Composer_RecipientList ((CORBA_TypeCode)&TC_GNOME_Evolution_Composer_RecipientList_struct) -#endif - extern GNOME_Evolution_Composer_RecipientList - *GNOME_Evolution_Composer_RecipientList__alloc(void); - extern gpointer GNOME_Evolution_Composer_RecipientList__free(gpointer mem, - gpointer dat, - CORBA_boolean free_strings); /* ORBit internal use */ -#endif -#define ex_GNOME_Evolution_Composer_CouldNotParse "IDL:GNOME/Evolution/Composer/CouldNotParse:1.0" - void _ORBIT_GNOME_Evolution_Composer_CouldNotParse_demarshal(GIOPRecvBuffer - * - _ORBIT_recv_buffer, - CORBA_Environment - * ev); - void _ORBIT_GNOME_Evolution_Composer_CouldNotParse_marshal(GIOPSendBuffer * - _ORBIT_send_buffer, - CORBA_Environment - * ev); -#if !defined(_GNOME_Evolution_Composer_CouldNotParse_defined) -#define _GNOME_Evolution_Composer_CouldNotParse_defined 1 - typedef struct - { - int dummy; - } - GNOME_Evolution_Composer_CouldNotParse; - -#if !defined(TC_IMPL_TC_GNOME_Evolution_Composer_CouldNotParse_0) -#define TC_IMPL_TC_GNOME_Evolution_Composer_CouldNotParse_0 'E' -#define TC_IMPL_TC_GNOME_Evolution_Composer_CouldNotParse_1 'v' -#define TC_IMPL_TC_GNOME_Evolution_Composer_CouldNotParse_2 'o' -#define TC_IMPL_TC_GNOME_Evolution_Composer_CouldNotParse_3 'l' -#define TC_IMPL_TC_GNOME_Evolution_Composer_CouldNotParse_4 'u' -#define TC_IMPL_TC_GNOME_Evolution_Composer_CouldNotParse_5 't' -#define TC_IMPL_TC_GNOME_Evolution_Composer_CouldNotParse_6 'i' -#define TC_IMPL_TC_GNOME_Evolution_Composer_CouldNotParse_7 'o' -#define TC_IMPL_TC_GNOME_Evolution_Composer_CouldNotParse_8 'n' -#define TC_IMPL_TC_GNOME_Evolution_Composer_CouldNotParse_9 '_' -#define TC_IMPL_TC_GNOME_Evolution_Composer_CouldNotParse_10 'C' -#define TC_IMPL_TC_GNOME_Evolution_Composer_CouldNotParse_11 'o' -#define TC_IMPL_TC_GNOME_Evolution_Composer_CouldNotParse_12 'm' -#define TC_IMPL_TC_GNOME_Evolution_Composer_CouldNotParse_13 'p' -#define TC_IMPL_TC_GNOME_Evolution_Composer_CouldNotParse_14 'o' -#define TC_IMPL_TC_GNOME_Evolution_Composer_CouldNotParse_15 's' -#define TC_IMPL_TC_GNOME_Evolution_Composer_CouldNotParse_16 'e' -#define TC_IMPL_TC_GNOME_Evolution_Composer_CouldNotParse_17 'r' - extern const struct CORBA_TypeCode_struct - TC_GNOME_Evolution_Composer_CouldNotParse_struct; -#define TC_GNOME_Evolution_Composer_CouldNotParse ((CORBA_TypeCode)&TC_GNOME_Evolution_Composer_CouldNotParse_struct) -#endif -#define GNOME_Evolution_Composer_CouldNotParse__alloc() NULL - extern gpointer GNOME_Evolution_Composer_CouldNotParse__free(gpointer mem, - gpointer dat, - CORBA_boolean free_strings); /* ORBit internal use */ -#endif - -/** POA structures **/ - typedef struct - { - void *_private; - void (*setHeaders) (PortableServer_Servant _servant, - const GNOME_Evolution_Composer_RecipientList * to, - const GNOME_Evolution_Composer_RecipientList * cc, - const GNOME_Evolution_Composer_RecipientList * bcc, - const CORBA_char * subject, CORBA_Environment * ev); - void (*setBodyText) (PortableServer_Servant _servant, - const CORBA_char * body, CORBA_Environment * ev); - void (*attachMIME) (PortableServer_Servant _servant, - const CORBA_char * data, CORBA_Environment * ev); - void (*attachData) (PortableServer_Servant _servant, - const CORBA_char * content_type, - const CORBA_char * filename, - const CORBA_char * description, - const CORBA_boolean show_inline, - const CORBA_char * data, CORBA_Environment * ev); - void (*show) (PortableServer_Servant _servant, CORBA_Environment * ev); - } - POA_GNOME_Evolution_Composer__epv; - typedef struct - { - PortableServer_ServantBase__epv *_base_epv; - POA_Bonobo_Unknown__epv *Bonobo_Unknown_epv; - POA_GNOME_Evolution_Composer__epv *GNOME_Evolution_Composer_epv; - } - POA_GNOME_Evolution_Composer__vepv; - typedef struct - { - void *_private; - POA_GNOME_Evolution_Composer__vepv *vepv; - } - POA_GNOME_Evolution_Composer; - extern void POA_GNOME_Evolution_Composer__init(PortableServer_Servant - servant, - CORBA_Environment * ev); - extern void POA_GNOME_Evolution_Composer__fini(PortableServer_Servant - servant, - CORBA_Environment * ev); - -/** prototypes **/ -#define GNOME_Evolution_Composer_ref Bonobo_Unknown_ref -#define GNOME_Evolution_Composer_unref Bonobo_Unknown_unref -#define GNOME_Evolution_Composer_queryInterface Bonobo_Unknown_queryInterface - void GNOME_Evolution_Composer_setHeaders(GNOME_Evolution_Composer _obj, - const - GNOME_Evolution_Composer_RecipientList - * to, - const - GNOME_Evolution_Composer_RecipientList - * cc, - const - GNOME_Evolution_Composer_RecipientList - * bcc, const CORBA_char * subject, - CORBA_Environment * ev); - void GNOME_Evolution_Composer_setBodyText(GNOME_Evolution_Composer _obj, - const CORBA_char * body, - CORBA_Environment * ev); - void GNOME_Evolution_Composer_attachMIME(GNOME_Evolution_Composer _obj, - const CORBA_char * data, - CORBA_Environment * ev); - void GNOME_Evolution_Composer_attachData(GNOME_Evolution_Composer _obj, - const CORBA_char * content_type, - const CORBA_char * filename, - const CORBA_char * description, - const CORBA_boolean show_inline, - const CORBA_char * data, - CORBA_Environment * ev); - void GNOME_Evolution_Composer_show(GNOME_Evolution_Composer _obj, - CORBA_Environment * ev); - - void - _ORBIT_skel_GNOME_Evolution_Composer_setHeaders - (POA_GNOME_Evolution_Composer * _ORBIT_servant, - GIOPRecvBuffer * _ORBIT_recv_buffer, CORBA_Environment * ev, - void (*_impl_setHeaders) (PortableServer_Servant _servant, - const GNOME_Evolution_Composer_RecipientList - * to, - const GNOME_Evolution_Composer_RecipientList - * cc, - const GNOME_Evolution_Composer_RecipientList - * bcc, const CORBA_char * subject, - CORBA_Environment * ev)); - void - _ORBIT_skel_GNOME_Evolution_Composer_setBodyText - (POA_GNOME_Evolution_Composer * _ORBIT_servant, - GIOPRecvBuffer * _ORBIT_recv_buffer, CORBA_Environment * ev, - void (*_impl_setBodyText) (PortableServer_Servant _servant, - const CORBA_char * body, - CORBA_Environment * ev)); - void - _ORBIT_skel_GNOME_Evolution_Composer_attachMIME - (POA_GNOME_Evolution_Composer * _ORBIT_servant, - GIOPRecvBuffer * _ORBIT_recv_buffer, CORBA_Environment * ev, - void (*_impl_attachMIME) (PortableServer_Servant _servant, - const CORBA_char * data, - CORBA_Environment * ev)); - void - _ORBIT_skel_GNOME_Evolution_Composer_attachData - (POA_GNOME_Evolution_Composer * _ORBIT_servant, - GIOPRecvBuffer * _ORBIT_recv_buffer, CORBA_Environment * ev, - void (*_impl_attachData) (PortableServer_Servant _servant, - const CORBA_char * content_type, - const CORBA_char * filename, - const CORBA_char * description, - const CORBA_boolean show_inline, - const CORBA_char * data, - CORBA_Environment * ev)); - void _ORBIT_skel_GNOME_Evolution_Composer_show(POA_GNOME_Evolution_Composer - * _ORBIT_servant, - GIOPRecvBuffer * - _ORBIT_recv_buffer, - CORBA_Environment * ev, - void (*_impl_show) - (PortableServer_Servant - _servant, - CORBA_Environment * ev)); -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif -#undef ORBIT_IDL_SERIAL diff --git a/calendar/gui/GNOME_Evolution_Calendar.oaf.in b/calendar/gui/GNOME_Evolution_Calendar.oaf.in deleted file mode 100644 index e96e4b7c8a..0000000000 --- a/calendar/gui/GNOME_Evolution_Calendar.oaf.in +++ /dev/null @@ -1,89 +0,0 @@ -<oaf_info> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_iTip_ControlFactory" - type="exe" - location="evolution-calendar"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/ObjectFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - _value="Factory for the calendar iTip view control"/> - -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_iTip_Control" - type="factory" - location="OAFIID:GNOME_Evolution_Calendar_iTip_ControlFactory"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:Bonobo/Control:1.0"/> - <item value="IDL:Bonobo/PersistStream:1.0"/> - </oaf_attribute> - - <oaf_attribute name="bonobo:supported_mime_types" type="stringv"> - <item value="text/calendar"/> - <item value="text/x-calendar"/> - </oaf_attribute> - - <oaf_attribute name="name" type="string" - _value="Evolution calendar iTip/iMip viewer"/> - <oaf_attribute name="description" type="string" - _value="Factory for the calendar iTip view control"/> - -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_ShellComponentFactory" - type="exe" - location="evolution-calendar"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/ObjectFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - _value="Factory for the Evolution calendar component."/> - -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_ShellComponent" - type="factory" - location="OAFIID:GNOME_Evolution_Calendar_ShellComponentFactory"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution/ShellComponent:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - _value="Evolution component for handling the calendar."/> - - <oaf_attribute name="evolution:shell-component-icon" type="string" - value="evolution-calendar.png"/> -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_Summary_ComponentFactory" - type="exe" - location="evolution-calendar"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME:GenericFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - _value="Factory for the Calendar Summary component."/> -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_Summary_Component" - type="factory" - location="OAFIID:GNOME_Evolution_Calendar_Summary_ComponentFactory"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution:Summary:ComponentFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - _value="Evolution calendar executive summary component."/> -</oaf_server> - -</oaf_info> diff --git a/calendar/gui/GNOME_Evolution_Calendar.oafinfo b/calendar/gui/GNOME_Evolution_Calendar.oafinfo deleted file mode 100644 index 75aa4a6b0f..0000000000 --- a/calendar/gui/GNOME_Evolution_Calendar.oafinfo +++ /dev/null @@ -1,89 +0,0 @@ -<oaf_info> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_iTip_ControlFactory" - type="exe" - location="evolution-calendar"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/ObjectFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Factory for the calendar iTip view control"/> - -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_iTip_Control" - type="factory" - location="OAFIID:GNOME_Evolution_Calendar_iTip_ControlFactory"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:Bonobo/Control:1.0"/> - <item value="IDL:Bonobo/PersistStream:1.0"/> - </oaf_attribute> - - <oaf_attribute name="bonobo:supported_mime_types" type="stringv"> - <item value="text/calendar"/> - <item value="text/x-calendar"/> - </oaf_attribute> - - <oaf_attribute name="name" type="string" - value="Evolution calendar iTip/iMip viewer"/> - <oaf_attribute name="description" type="string" - value="Factory for the calendar iTip view control"/> - -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_ShellComponentFactory" - type="exe" - location="evolution-calendar"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/ObjectFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Factory for the Evolution calendar component."/> - -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_ShellComponent" - type="factory" - location="OAFIID:GNOME_Evolution_Calendar_ShellComponentFactory"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution/ShellComponent:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Evolution component for handling the calendar."/> - - <oaf_attribute name="evolution:shell-component-icon" type="string" - value="evolution-calendar.png"/> -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_Summary_ComponentFactory" - type="exe" - location="evolution-calendar"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME:GenericFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Factory for the Calendar Summary component."/> -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_Summary_Component" - type="factory" - location="OAFIID:GNOME_Evolution_Calendar_Summary_ComponentFactory"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution:Summary:ComponentFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Evolution calendar executive summary component."/> -</oaf_server> - -</oaf_info> diff --git a/calendar/gui/GNOME_Evolution_Calendar_Control.oaf.in b/calendar/gui/GNOME_Evolution_Calendar_Control.oaf.in deleted file mode 100644 index d241806784..0000000000 --- a/calendar/gui/GNOME_Evolution_Calendar_Control.oaf.in +++ /dev/null @@ -1,28 +0,0 @@ -<oaf_info> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_ControlFactory" - type="exe" - location="evolution-calendar"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/ObjectFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - _value="Factory for the sample Calendar control"/> -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_Control" - type="factory" - location="OAFIID:GNOME_Evolution_Calendar_ControlFactory"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:BonoboControl/calendar-control:1.0"/> - <item value="IDL:Bonobo/Control:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - _value="A sample Bonobo control which displays an calendar."/> -</oaf_server> - -</oaf_info> diff --git a/calendar/gui/GNOME_Evolution_Calendar_Control.oafinfo b/calendar/gui/GNOME_Evolution_Calendar_Control.oafinfo deleted file mode 100644 index 48cbfa7cbb..0000000000 --- a/calendar/gui/GNOME_Evolution_Calendar_Control.oafinfo +++ /dev/null @@ -1,28 +0,0 @@ -<oaf_info> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_ControlFactory" - type="exe" - location="evolution-calendar"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/ObjectFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Factory for the sample Calendar control"/> -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_Control" - type="factory" - location="OAFIID:GNOME_Evolution_Calendar_ControlFactory"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:BonoboControl/calendar-control:1.0"/> - <item value="IDL:Bonobo/Control:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="A sample Bonobo control which displays an calendar."/> -</oaf_server> - -</oaf_info> diff --git a/calendar/gui/GNOME_Evolution_Calendar_gnomecal.oaf.in b/calendar/gui/GNOME_Evolution_Calendar_gnomecal.oaf.in deleted file mode 100644 index 3719ba618b..0000000000 --- a/calendar/gui/GNOME_Evolution_Calendar_gnomecal.oaf.in +++ /dev/null @@ -1,27 +0,0 @@ -<oaf_info> - -<oaf_server iid="OAFIID:IDL:GNOME:Calendar:Repository:1.0:56989bb6-65a1-430c-86a8-81bbe64bf7ab" - type="factory" - location="OAFIID:IDL:GNOME:Calendar:RepositoryLocator:1.0:83b25bb0-b68b-4c6b-86e7-c303e9897c21"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:Gnome/Calendar/Repository:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - _value="Calendar Repository"/> -</oaf_server> - -<oaf_server iid="OAFIID:IDL:GNOME:Calendar:RepositoryLocator:1.0:83b25bb0-b68b-4c6b-86e7-c303e9897c21" - type="exe" - location="gnomecal"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/GenericFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - _value="Calendar Server"/> -</oaf_server> - -</oaf_info> diff --git a/calendar/gui/GNOME_Evolution_Calendar_gnomecal.oafinfo b/calendar/gui/GNOME_Evolution_Calendar_gnomecal.oafinfo deleted file mode 100644 index c4b91b9dd8..0000000000 --- a/calendar/gui/GNOME_Evolution_Calendar_gnomecal.oafinfo +++ /dev/null @@ -1,27 +0,0 @@ -<oaf_info> - -<oaf_server iid="OAFIID:IDL:GNOME:Calendar:Repository:1.0:56989bb6-65a1-430c-86a8-81bbe64bf7ab" - type="factory" - location="OAFIID:IDL:GNOME:Calendar:RepositoryLocator:1.0:83b25bb0-b68b-4c6b-86e7-c303e9897c21"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:Gnome/Calendar/Repository:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Calendar Repository"/> -</oaf_server> - -<oaf_server iid="OAFIID:IDL:GNOME:Calendar:RepositoryLocator:1.0:83b25bb0-b68b-4c6b-86e7-c303e9897c21" - type="exe" - location="gnomecal"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/GenericFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - value="Calendar Server"/> -</oaf_server> - -</oaf_info> diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am deleted file mode 100644 index 432acf0676..0000000000 --- a/calendar/gui/Makefile.am +++ /dev/null @@ -1,178 +0,0 @@ -## CORBA stuff - -IDLS = \ - $(srcdir)/../../composer/Evolution-Composer.idl - -IDL_GENERATED = \ - Evolution-Composer.h \ - Evolution-Composer-common.c \ - Evolution-Composer-skels.c \ - Evolution-Composer-stubs.c - -$(IDL_GENERATED): $(IDLS) - $(ORBIT_IDL) -I $(srcdir) -I $(datadir)/idl `$(GNOME_CONFIG) --cflags idl` \ - $(srcdir)/../../composer/Evolution-Composer.idl - -#SUBDIRS = alarm-notify dialogs -SUBDIRS = dialogs - -help_base = $(datadir)/gnome/help/cal - -bin_PROGRAMS = evolution-calendar - -INCLUDES = \ - -DG_LOG_DOMAIN=\"calendar-gui\" \ - -I$(top_builddir)/shell \ - -I$(top_srcdir)/shell \ - -I$(top_srcdir) \ - -I$(top_srcdir)/calendar \ - -I$(top_srcdir)/libical/src/libical \ - -I$(top_builddir)/libical/src/libical \ - -I$(top_srcdir)/widgets \ - -I$(top_srcdir)/executive-summary \ - -I$(includedir) \ - $(BONOBO_VFS_GNOME_CFLAGS) \ - $(EXTRA_GNOME_CFLAGS) \ - -DEVOLUTION_DATADIR=\""$(datadir)"\" \ - -DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \ - -DEVOLUTION_LOCALEDIR=\""$(localedir)"\" - -gladedir = $(datadir)/evolution/glade - -glade_DATA = \ - event-editor-dialog.glade \ - e-meeting-dialog.glade \ - e-itip-control.glade \ - goto-dialog.glade - -evolution_calendar_SOURCES = \ - $(IDL_GENERATED) \ - alarm.c \ - alarm.h \ - calendar-config.c \ - calendar-config.h \ - calendar-commands.c \ - calendar-commands.h \ - calendar-model.c \ - calendar-model.h \ - calendar-summary.c \ - calendar-summary.h \ - comp-util.c \ - comp-util.h \ - control-factory.c \ - control-factory.h \ - component-factory.c \ - component-factory.h \ - e-calendar-table.h \ - e-calendar-table.c \ - e-day-view-main-item.c \ - e-day-view-main-item.h \ - e-day-view-time-item.c \ - e-day-view-time-item.h \ - e-day-view-top-item.c \ - e-day-view-top-item.h \ - e-day-view.c \ - e-day-view.h \ - e-itip-control.h \ - e-itip-control.c \ - e-meeting-edit.h \ - e-meeting-edit.c \ - e-week-view-event-item.c \ - e-week-view-event-item.h \ - e-week-view-main-item.c \ - e-week-view-main-item.h \ - e-week-view-titles-item.c \ - e-week-view-titles-item.h \ - e-week-view.c \ - e-week-view.h \ - e-tasks.c \ - e-tasks.h \ - event-editor.c \ - event-editor.h \ - gnome-cal.c \ - gnome-cal.h \ - goto.c \ - goto.h \ - itip-utils.c \ - itip-utils.h \ - main.c \ - popup-menu.c \ - popup-menu.h \ - print.c \ - print.h \ - tag-calendar.c \ - tag-calendar.h \ - tasks-control-factory.c \ - tasks-control-factory.h \ - tasks-control.c \ - tasks-control.h \ - tasks-migrate.c \ - tasks-migrate.h \ - weekday-picker.c \ - weekday-picker.h \ - widget-util.c \ - widget-util.h - -evolution_calendar_LDADD = \ - $(top_builddir)/shell/libeshell.a \ - $(top_builddir)/calendar/cal-client/libcal-client.la \ - $(top_builddir)/calendar/cal-util/libcal-util.la \ - $(top_builddir)/e-util/libeutil.la \ - $(top_builddir)/executive-summary/evolution-services/libevolution-services.la \ - $(top_builddir)/libversit/libversit.la \ - $(top_builddir)/libical/src/libical/libical.la \ - $(top_builddir)/widgets/meeting-time-sel/libevolutionmtsel.a \ - $(top_builddir)/widgets/misc/libemiscwidgets.a \ - $(top_builddir)/widgets/menus/libmenus.la \ - dialogs/libcal-dialogs.a \ - $(BONOBO_HTML_GNOME_LIBS) \ - $(BONOBO_VFS_GNOME_LIBS) \ - $(EXTRA_GNOME_LIBS) \ - $(INTLLIBS) - -#evolution_calendar_LDFLAGS = `gnome-config --libs gdk_pixbuf` - -oafdir = $(datadir)/oaf -oaf_in_files = \ - GNOME_Evolution_Calendar_Control.oaf.in \ - GNOME_Evolution_Calendar.oaf.in \ - GNOME_Evolution_Calendar_gnomecal.oaf.in - -oaf_DATA = $(oaf_in_files:.oaf.in=.oaf) - -@XML_I18N_MERGE_OAF_RULE@ - -EXTRA_DIST = \ - $(glade_DATA) \ - bell.xpm \ - check-filled.xpm \ - dayview.xpm \ - jump.xpm \ - monthview.xpm \ - recur.xpm \ - task-assigned-to.xpm \ - task-assigned.xpm \ - task-recurring.xpm \ - task.xpm \ - weekview.xpm \ - workweekview.xpm \ - yearview.xpm \ - $(oaf_in_files) $(oaf_DATA) - -install-data-local: - $(mkinstalldirs) $(DESTDIR)$(help_base)/C - $(mkinstalldirs) $(Conduitsdir) - -if ENABLE_PURIFY -PLINK = $(LIBTOOL) --mode=link $(PURIFY) $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ - -all-local: evolution-calendar.pure - -evolution-calendar.pure: evolution-calendar - @rm -f evolution-calendar.pure - $(PLINK) $(evolution_calendar_LDFLAGS) $(evolution_calendar_OBJECTS) $(evolution_calendar_LDADD) $(LIBS) - -endif - -BUILT_SOURCES = $(IDL_GENERATED) -CLEANFILES += $(BUILT_SOURCES) diff --git a/calendar/gui/alarm-notify.c b/calendar/gui/alarm-notify.c deleted file mode 100644 index d824b2a189..0000000000 --- a/calendar/gui/alarm-notify.c +++ /dev/null @@ -1,963 +0,0 @@ -/* Evolution calendar - Alarm notification engine - * - * Copyright (C) 2000 Helix Code, Inc. - * - * Authors: Federico Mena-Quintero <federico@helixcode.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtksignal.h> -#include <cal-util/timeutil.h> -#include "alarm.h" -#include "alarm-notify.h" - - - -/* Whether the notification system has been initialized */ -static gboolean alarm_notify_inited; - -/* Clients we are monitoring for alarms */ -static GHashTable *client_alarms_hash = NULL; - -/* Structure that stores a client we are monitoring */ -typedef struct { - /* Monitored client */ - CalClient *client; - - /* Number of times this client has been registered */ - int refcount; - - /* Hash table of component UID -> CompQueuedAlarms. If an element is - * present here, then it means its cqa->queued_alarms contains at least - * one queued alarm. When all the alarms for a component have been - * dequeued, the CompQueuedAlarms structure is removed from the hash - * table. Thus a CQA exists <=> it has queued alarms. - */ - GHashTable *uid_alarms_hash; -} ClientAlarms; - -/* Pair of a CalComponentAlarms and the mapping from queued alarm IDs to the - * actual alarm instance structures. - */ -typedef struct { - /* The parent client alarms structure */ - ClientAlarms *parent_client; - - /* The actual component and its alarm instances */ - CalComponentAlarms *alarms; - - /* List of QueuedAlarm structures */ - GSList *queued_alarms; -} CompQueuedAlarms; - -/* Pair of a queued alarm ID and the alarm trigger instance it refers to */ -typedef struct { - /* Alarm ID from alarm.h */ - gpointer alarm_id; - - /* Instance from our parent CompAlarms->alarms list */ - CalAlarmInstance *instance; -} QueuedAlarm; - -/* Alarm ID for the midnight refresh function */ -static gpointer midnight_refresh_id = NULL; - - - -static void load_alarms (ClientAlarms *ca); -static void midnight_refresh_cb (gpointer alarm_id, time_t trigger, gpointer data); - -/* Queues an alarm trigger for midnight so that we can load the next day's worth - * of alarms. - */ -static void -queue_midnight_refresh (void) -{ - time_t midnight; - - g_assert (midnight_refresh_id == NULL); - - midnight = time_day_end (time (NULL)); - - midnight_refresh_id = alarm_add (midnight, midnight_refresh_cb, NULL, NULL); - if (!midnight_refresh_id) { - g_message ("alarm_notify_init(): Could not set up the midnight refresh alarm!"); - /* FIXME: what to do? */ - } -} - -/* Loads a client's alarms; called from g_hash_table_foreach() */ -static void -add_client_alarms_cb (gpointer key, gpointer value, gpointer data) -{ - ClientAlarms *ca; - - ca = value; - load_alarms (ca); -} - -/* Loads the alarms for the new day every midnight */ -static void -midnight_refresh_cb (gpointer alarm_id, time_t trigger, gpointer data) -{ - /* Re-load the alarms for all clients */ - - g_hash_table_foreach (client_alarms_hash, add_client_alarms_cb, NULL); - - /* Re-schedule the midnight update */ - - midnight_refresh_id = NULL; - queue_midnight_refresh (); -} - -/* Looks up a client in the client alarms hash table */ -static ClientAlarms * -lookup_client (CalClient *client) -{ - return g_hash_table_lookup (client_alarms_hash, client); -} - -/* Callback used when an alarm triggers */ -static void -alarm_trigger_cb (gpointer alarm_id, time_t trigger, gpointer data) -{ - CompQueuedAlarms *cqa; - - cqa = data; - - /* FIXME */ - - g_message ("alarm_trigger_cb(): Triggered!"); -} - -/* Callback used when an alarm must be destroyed */ -static void -alarm_destroy_cb (gpointer alarm_id, gpointer data) -{ - CompQueuedAlarms *cqa; - GSList *l; - QueuedAlarm *qa; - const char *uid; - - cqa = data; - - qa = NULL; /* Keep GCC happy */ - - /* Find the alarm in the queued alarms */ - - for (l = cqa->queued_alarms; l; l = l->next) { - qa = l->data; - if (qa->alarm_id == alarm_id) - break; - } - - g_assert (l != NULL); - - /* Remove it and free it */ - - cqa->queued_alarms = g_slist_remove_link (cqa->queued_alarms, l); - g_slist_free_1 (l); - - g_free (qa); - - /* If this was the last queued alarm for this component, remove the - * component itself. - */ - - if (cqa->queued_alarms != NULL) - return; - - cal_component_get_uid (cqa->alarms->comp, &uid); - g_hash_table_remove (cqa->parent_client->uid_alarms_hash, uid); - cqa->parent_client = NULL; - - cal_component_alarms_free (cqa->alarms); - cqa->alarms = NULL; - - g_free (cqa); -} - -/* Adds the alarms in a CalComponentAlarms structure to the alarms queued for a - * particular client. Also puts the triggers in the alarm timer queue. - */ -static void -add_component_alarms (ClientAlarms *ca, CalComponentAlarms *alarms) -{ - const char *uid; - CompQueuedAlarms *cqa; - GSList *l; - - /* No alarms? */ - if (alarms->alarms == NULL) { - cal_component_alarms_free (alarms); - return; - } - - cqa = g_new (CompQueuedAlarms, 1); - cqa->parent_client = ca; - cqa->alarms = alarms; - - cqa->queued_alarms = NULL; - - for (l = alarms->alarms; l; l = l->next) { - CalAlarmInstance *instance; - gpointer alarm_id; - QueuedAlarm *qa; - - instance = l->data; - - alarm_id = alarm_add (instance->trigger, alarm_trigger_cb, cqa, alarm_destroy_cb); - if (!alarm_id) { - g_message ("add_component_alarms(): Could not schedule a trigger for " - "%ld, discarding...", (long) instance->trigger); - continue; - } - - qa = g_new (QueuedAlarm, 1); - qa->alarm_id = alarm_id; - qa->instance = instance; - - cqa->queued_alarms = g_slist_prepend (cqa->queued_alarms, qa); - } - - cal_component_get_uid (alarms->comp, &uid); - - /* If we failed to add all the alarms, then we should get rid of the cqa */ - if (cqa->queued_alarms == NULL) { - g_message ("add_component_alarms(): Could not add any of the alarms " - "for the component `%s'; discarding it...", uid); - - cal_component_alarms_free (cqa->alarms); - cqa->alarms = NULL; - - g_free (cqa); - return; - } - - cqa->queued_alarms = g_slist_reverse (cqa->queued_alarms); - g_hash_table_insert (ca->uid_alarms_hash, (char *) uid, cqa); -} - -/* Loads today's remaining alarms for a client */ -static void -load_alarms (ClientAlarms *ca) -{ - time_t now, day_end; - GSList *comp_alarms; - GSList *l; - - now = time (NULL); - day_end = time_day_end (now); - - comp_alarms = cal_client_get_alarms_in_range (ca->client, now, day_end); - - /* All of the last day's alarms should have already triggered and should - * have been removed, so we should have no pending components. - */ - g_assert (g_hash_table_size (ca->uid_alarms_hash) == 0); - - for (l = comp_alarms; l; l = l->next) { - CalComponentAlarms *alarms; - - alarms = l->data; - add_component_alarms (ca, alarms); - } - - g_slist_free (comp_alarms); -} - -/* Called when a calendar client finished loading; we load its alarms */ -static void -cal_loaded_cb (CalClient *client, CalClientLoadStatus status, gpointer data) -{ - ClientAlarms *ca; - - ca = data; - - if (status != CAL_CLIENT_LOAD_SUCCESS) - return; - - load_alarms (ca); -} - -/* Looks up a component's queued alarm structure in a client alarms structure */ -static CompQueuedAlarms * -lookup_comp_queued_alarms (ClientAlarms *ca, const char *uid) -{ - return g_hash_table_lookup (ca->uid_alarms_hash, uid); -} - -/* Removes a component an its alarms */ -static void -remove_comp (ClientAlarms *ca, const char *uid) -{ - CompQueuedAlarms *cqa; - GSList *l; - - cqa = lookup_comp_queued_alarms (ca, uid); - if (!cqa) - return; - - /* If a component is present, then it means we must have alarms queued - * for it. - */ - g_assert (cqa->queued_alarms != NULL); - - for (l = cqa->queued_alarms; l;) { - QueuedAlarm *qa; - - qa = l->data; - - /* Get the next element here because the list element will go - * away. Also, we do not free the qa here because it will be - * freed by the destroy notification function. - */ - l = l->next; - - alarm_remove (qa->alarm_id); - } - - /* The list should be empty now, and thus the queued component alarms - * structure should have been freed and removed from the hash table. - */ - g_assert (lookup_comp_queued_alarms (ca, uid) == NULL); -} - -/* Called when a calendar component changes; we must reload its corresponding - * alarms. - */ -static void -obj_updated_cb (CalClient *client, const char *uid, gpointer data) -{ - ClientAlarms *ca; - time_t now, day_end; - CalComponentAlarms *alarms; - gboolean found; - - ca = data; - - remove_comp (ca, uid); - - now = time (NULL); - day_end = time_day_end (now); - - found = cal_client_get_alarms_for_object (ca->client, uid, now, day_end, &alarms); - - if (!found) - return; - - add_component_alarms (ca, alarms); -} - -/* Called when a calendar component is removed; we must delete its corresponding - * alarms. - */ -static void -obj_removed_cb (CalClient *client, const char *uid, gpointer data) -{ - ClientAlarms *ca; - - ca = data; - - remove_comp (ca, uid); -} - - - -/** - * alarm_notify_init: - * - * Initializes the alarm notification system. This should be called near the - * beginning of the program, after calling alarm_init(). - **/ -void -alarm_notify_init (void) -{ - g_return_if_fail (alarm_notify_inited == FALSE); - - client_alarms_hash = g_hash_table_new (g_direct_hash, g_direct_equal); - queue_midnight_refresh (); - - alarm_notify_inited = TRUE; -} - -/** - * alarm_notify_done: - * - * Shuts down the alarm notification system. This should be called near the end - * of the program. All the monitored calendar clients should already have been - * unregistered with alarm_notify_remove_client(). - **/ -void -alarm_notify_done (void) -{ - g_return_if_fail (alarm_notify_inited); - - /* All clients must be unregistered by now */ - g_return_if_fail (g_hash_table_size (client_alarms_hash) == 0); - - g_hash_table_destroy (client_alarms_hash); - client_alarms_hash = NULL; - - g_assert (midnight_refresh_id != NULL); - alarm_remove (midnight_refresh_id); - midnight_refresh_id = NULL; - - alarm_notify_inited = FALSE; -} - -/** - * alarm_notify_add_client: - * @client: A calendar client. - * - * Adds a calendar client to the alarm notification system. Alarm trigger - * notifications will be presented at the appropriate times. The client should - * be removed with alarm_notify_remove_client() when receiving notifications - * from it is no longer desired. - * - * A client can be added any number of times to the alarm notification system, - * but any single alarm trigger will only be presented once for a particular - * client. The client must still be removed the same number of times from the - * notification system when it is no longer wanted. - **/ -void -alarm_notify_add_client (CalClient *client) -{ - ClientAlarms *ca; - - g_return_if_fail (alarm_notify_inited); - g_return_if_fail (client != NULL); - g_return_if_fail (IS_CAL_CLIENT (client)); - - ca = lookup_client (client); - if (ca) { - ca->refcount++; - return; - } - - ca = g_new (ClientAlarms, 1); - - ca->client = client; - gtk_object_ref (GTK_OBJECT (ca->client)); - - ca->refcount = 1; - g_hash_table_insert (client_alarms_hash, client, ca); - - ca->uid_alarms_hash = g_hash_table_new (g_str_hash, g_str_equal); - - if (!cal_client_is_loaded (client)) - gtk_signal_connect (GTK_OBJECT (client), "cal_loaded", - GTK_SIGNAL_FUNC (cal_loaded_cb), ca); - - gtk_signal_connect (GTK_OBJECT (client), "obj_updated", - GTK_SIGNAL_FUNC (obj_updated_cb), ca); - gtk_signal_connect (GTK_OBJECT (client), "obj_removed", - GTK_SIGNAL_FUNC (obj_removed_cb), ca); - - if (cal_client_is_loaded (client)) - load_alarms (ca); -} - -/* Called from g_hash_table_foreach(); adds a component UID to a list */ -static void -add_uid_cb (gpointer key, gpointer value, gpointer data) -{ - GSList **uids; - const char *uid; - - uids = data; - uid = key; - - *uids = g_slist_prepend (*uids, (char *) uid); -} - -/* Removes all the alarms queued for a particular calendar client */ -static void -remove_client_alarms (ClientAlarms *ca) -{ - GSList *uids; - GSList *l; - - /* First we build a list of UIDs so that we can remove them one by one */ - - uids = NULL; - g_hash_table_foreach (ca->uid_alarms_hash, add_uid_cb, &uids); - - for (l = uids; l; l = l->next) { - const char *uid; - - uid = l->data; - - remove_comp (ca, uid); - } - - g_slist_free (uids); - - /* The hash table should be empty now */ - - g_assert (g_hash_table_size (ca->uid_alarms_hash) == 0); -} - -/** - * alarm_notify_remove_client: - * @client: A calendar client. - * - * Removes a calendar client from the alarm notification system. - **/ -void -alarm_notify_remove_client (CalClient *client) -{ - ClientAlarms *ca; - - g_return_if_fail (alarm_notify_inited); - g_return_if_fail (client != NULL); - g_return_if_fail (IS_CAL_CLIENT (client)); - - ca = lookup_client (client); - g_return_if_fail (ca != NULL); - - g_assert (ca->refcount > 0); - ca->refcount--; - - if (ca->refcount > 0) - return; - - remove_client_alarms (ca); - - /* Clean up */ - - gtk_signal_disconnect_by_data (GTK_OBJECT (ca->client), ca); - - gtk_object_unref (GTK_OBJECT (ca->client)); - ca->client = NULL; - - g_hash_table_destroy (ca->uid_alarms_hash); - ca->uid_alarms_hash = NULL; - - g_free (ca); - - g_hash_table_remove (client_alarms_hash, client); -} - - - -#if 0 - -/* Sends a mail notification of an alarm trigger */ -static void -mail_notification (char *mail_address, char *text, time_t app_time) -{ - pid_t pid; - int p [2]; - char *command; - - pipe (p); - pid = fork (); - if (pid == 0){ - int dev_null; - - dev_null = open ("/dev/null", O_RDWR); - dup2 (p [0], 0); - dup2 (dev_null, 1); - dup2 (dev_null, 2); - execl ("/usr/lib/sendmail", "/usr/lib/sendmail", - mail_address, NULL); - _exit (127); - } - command = g_strconcat ("To: ", mail_address, "\n", - "Subject: ", _("Reminder of your appointment at "), - ctime (&app_time), "\n\n", text, "\n", NULL); - write (p [1], command, strlen (command)); - close (p [1]); - close (p [0]); - g_free (command); -} - -static int -max_open_files (void) -{ - static int files; - - if (files) - return files; - - files = sysconf (_SC_OPEN_MAX); - if (files != -1) - return files; -#ifdef OPEN_MAX - return files = OPEN_MAX; -#else - return files = 256; -#endif -} - -/* Executes a program as a notification of an alarm trigger */ -static void -program_notification (char *command, int close_standard) -{ - struct sigaction ignore, save_intr, save_quit; - int status = 0, i; - pid_t pid; - - ignore.sa_handler = SIG_IGN; - sigemptyset (&ignore.sa_mask); - ignore.sa_flags = 0; - - sigaction (SIGINT, &ignore, &save_intr); - sigaction (SIGQUIT, &ignore, &save_quit); - - if ((pid = fork ()) < 0){ - fprintf (stderr, "\n\nfork () = -1\n"); - return; - } - if (pid == 0){ - pid = fork (); - if (pid == 0){ - const int top = max_open_files (); - sigaction (SIGINT, &save_intr, NULL); - sigaction (SIGQUIT, &save_quit, NULL); - - for (i = (close_standard ? 0 : 3); i < top; i++) - close (i); - - /* FIXME: As an excercise to the reader, copy the - * code from mc to setup shell properly instead of - * /bin/sh. Yes, this comment is larger than a cut and paste. - */ - execl ("/bin/sh", "/bin/sh", "-c", command, (char *) 0); - - _exit (127); - } else { - _exit (127); - } - } - wait (&status); - sigaction (SIGINT, &save_intr, NULL); - sigaction (SIGQUIT, &save_quit, NULL); -} - -/* Queues a snooze alarm */ -static void -snooze (GnomeCalendar *gcal, CalComponent *comp, time_t occur, int snooze_mins, gboolean audio) -{ - time_t now, trigger; - struct tm tm; - CalAlarmInstance ai; - - now = time (NULL); - tm = *localtime (&now); - tm.tm_min += snooze_mins; - - trigger = mktime (&tm); - if (trigger == -1) { - g_message ("snooze(): produced invalid time_t; not queueing alarm!"); - return; - } - -#if 0 - cal_component_get_uid (comp, &ai.uid); - ai.type = audio ? ALARM_AUDIO : ALARM_DISPLAY; -#endif - ai.trigger = trigger; - ai.occur = occur; - - setup_alarm (gcal, &ai); -} - -struct alarm_notify_closure { - GnomeCalendar *gcal; - CalComponent *comp; - time_t occur; -}; - -/* Callback used for the result of the alarm notification dialog */ -static void -display_notification_cb (AlarmNotifyResult result, int snooze_mins, gpointer data) -{ - struct alarm_notify_closure *c; - - c = data; - - switch (result) { - case ALARM_NOTIFY_CLOSE: - break; - - case ALARM_NOTIFY_SNOOZE: - snooze (c->gcal, c->comp, c->occur, snooze_mins, FALSE); - break; - - case ALARM_NOTIFY_EDIT: - gnome_calendar_edit_object (c->gcal, c->comp); - break; - - default: - g_assert_not_reached (); - } - - gtk_object_unref (GTK_OBJECT (c->comp)); - g_free (c); -} - -/* Present a display notification of an alarm trigger */ -static void -display_notification (time_t trigger, time_t occur, CalComponent *comp, GnomeCalendar *gcal) -{ - gboolean result; - struct alarm_notify_closure *c; - - gtk_object_ref (GTK_OBJECT (comp)); - - c = g_new (struct alarm_notify_closure, 1); - c->gcal = gcal; - c->comp = comp; - c->occur = occur; - - result = alarm_notify_dialog (trigger, occur, comp, display_notification_cb, c); - if (!result) { - g_message ("display_notification(): could not display the alarm notification dialog"); - g_free (c); - gtk_object_unref (GTK_OBJECT (comp)); - } -} - -/* Present an audible notification of an alarm trigger */ -static void -audio_notification (time_t trigger, time_t occur, CalComponent *comp, GnomeCalendar *gcal) -{ - g_message ("AUDIO NOTIFICATION!"); - /* FIXME */ -} - -/* Callback function used when an alarm is triggered */ -static void -trigger_alarm_cb (gpointer alarm_id, time_t trigger, gpointer data) -{ - struct trigger_alarm_closure *c; - GnomeCalendarPrivate *priv; - CalComponent *comp; - CalClientGetStatus status; - const char *uid; - ObjectAlarms *oa; - GList *l; - - c = data; - priv = c->gcal->priv; - - /* Fetch the object */ - - status = cal_client_get_object (priv->client, c->uid, &comp); - - switch (status) { - case CAL_CLIENT_GET_SUCCESS: - /* Go on */ - break; - case CAL_CLIENT_GET_SYNTAX_ERROR: - case CAL_CLIENT_GET_NOT_FOUND: - g_message ("trigger_alarm_cb(): syntax error in fetched object"); - return; - } - - g_assert (comp != NULL); - - /* Present notification */ - - switch (c->type) { - case CAL_COMPONENT_ALARM_EMAIL: -#if 0 - g_assert (ico->malarm.enabled); - mail_notification (ico->malarm.data, ico->summary, c->occur); -#endif - break; - - case CAL_COMPONENT_ALARM_PROCEDURE: -#if 0 - g_assert (ico->palarm.enabled); - program_notification (ico->palarm.data, FALSE); -#endif - break; - - case CAL_COMPONENT_ALARM_DISPLAY: -#if 0 - g_assert (ico->dalarm.enabled); -#endif - display_notification (trigger, c->occur, comp, c->gcal); - break; - - case CAL_COMPONENT_ALARM_AUDIO: -#if 0 - g_assert (ico->aalarm.enabled); -#endif - audio_notification (trigger, c->occur, comp, c->gcal); - break; - - default: - break; - } - - /* Remove the alarm from the hash table */ - cal_component_get_uid (comp, &uid); - oa = g_hash_table_lookup (priv->alarms, uid); - g_assert (oa != NULL); - - l = g_list_find (oa->alarm_ids, alarm_id); - g_assert (l != NULL); - - oa->alarm_ids = g_list_remove_link (oa->alarm_ids, l); - g_list_free_1 (l); - - if (!oa->alarm_ids) { - g_hash_table_remove (priv->alarms, uid); - g_free (oa->uid); - g_free (oa); - } - - gtk_object_unref (GTK_OBJECT (comp)); -} - -#endif - -#if 0 - -static void -stop_beeping (GtkObject* object, gpointer data) -{ - guint timer_tag, beep_tag; - timer_tag = GPOINTER_TO_INT (gtk_object_get_data (object, "timer_tag")); - beep_tag = GPOINTER_TO_INT (gtk_object_get_data (object, "beep_tag")); - - if (beep_tag > 0) { - gtk_timeout_remove (beep_tag); - gtk_object_set_data (object, "beep_tag", GINT_TO_POINTER (0)); - } - if (timer_tag > 0) { - gtk_timeout_remove (timer_tag); - gtk_object_set_data (object, "timer_tag", GINT_TO_POINTER (0)); - } -} - -static gint -start_beeping (gpointer data) -{ - gdk_beep (); - - return TRUE; -} - -static gint -timeout_beep (gpointer data) -{ - stop_beeping (data, NULL); - return FALSE; -} - -void -calendar_notify (time_t activation_time, CalendarAlarm *which, void *data) -{ - iCalObject *ico = data; - guint beep_tag, timer_tag; - int ret; - gchar* snooze_button = (enable_snooze ? _("Snooze") : NULL); - time_t now, diff; - - if (&ico->aalarm == which){ - time_t app = ico->aalarm.trigger + ico->aalarm.offset; - GtkWidget *w; - char *msg; - - msg = g_strconcat (_("Reminder of your appointment at "), - ctime (&app), "`", - ico->summary, "'", NULL); - - /* Idea: we need Snooze option :-) */ - w = gnome_message_box_new (msg, GNOME_MESSAGE_BOX_INFO, _("Ok"), snooze_button, NULL); - beep_tag = gtk_timeout_add (1000, start_beeping, NULL); - if (enable_aalarm_timeout) - timer_tag = gtk_timeout_add (audio_alarm_timeout*1000, - timeout_beep, w); - else - timer_tag = 0; - gtk_object_set_data (GTK_OBJECT (w), "timer_tag", - GINT_TO_POINTER (timer_tag)); - gtk_object_set_data (GTK_OBJECT (w), "beep_tag", - GINT_TO_POINTER (beep_tag)); - gtk_widget_ref (w); - gtk_window_set_modal (GTK_WINDOW (w), FALSE); - ret = gnome_dialog_run (GNOME_DIALOG (w)); - switch (ret) { - case 1: - stop_beeping (GTK_OBJECT (w), NULL); - now = time (NULL); - diff = now - which->trigger; - which->trigger = which->trigger + diff + snooze_secs; - which->offset = which->offset - diff - snooze_secs; - alarm_add (which, &calendar_notify, data); - break; - default: - stop_beeping (GTK_OBJECT (w), NULL); - break; - } - - gtk_widget_unref (w); - return; - } - - if (&ico->palarm == which){ - execute (ico->palarm.data, 0); - return; - } - - if (&ico->malarm == which){ - time_t app = ico->malarm.trigger + ico->malarm.offset; - - mail_notify (ico->malarm.data, ico->summary, app); - return; - } - - if (&ico->dalarm == which){ - time_t app = ico->dalarm.trigger + ico->dalarm.offset; - GtkWidget *w; - char *msg; - - if (beep_on_display) - gdk_beep (); - msg = g_strconcat (_("Reminder of your appointment at "), - ctime (&app), "`", - ico->summary, "'", NULL); - w = gnome_message_box_new (msg, GNOME_MESSAGE_BOX_INFO, - _("Ok"), snooze_button, NULL); - gtk_window_set_modal (GTK_WINDOW (w), FALSE); - ret = gnome_dialog_run (GNOME_DIALOG (w)); - switch (ret) { - case 1: - now = time (NULL); - diff = now - which->trigger; - which->trigger = which->trigger + diff + snooze_secs; - which->offset = which->offset - diff - snooze_secs; - alarm_add (which, &calendar_notify, data); - break; - default: - break; - } - - return; - } -} - -#endif diff --git a/calendar/gui/alarm-notify.h b/calendar/gui/alarm-notify.h deleted file mode 100644 index f386a56ae4..0000000000 --- a/calendar/gui/alarm-notify.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Evolution calendar - Alarm notification engine - * - * Copyright (C) 2000 Helix Code, Inc. - * - * Authors: Federico Mena-Quintero <federico@helixcode.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef ALARM_NOTIFY_H -#define ALARM_NOTIFY_H - -#include <cal-client/cal-client.h> - - -void alarm_notify_init (void); -void alarm_notify_done (void); - -void alarm_notify_add_client (CalClient *client); -void alarm_notify_remove_client (CalClient *client); - - -#endif diff --git a/calendar/gui/alarm-notify/.cvsignore b/calendar/gui/alarm-notify/.cvsignore deleted file mode 100644 index fa1c1f7c87..0000000000 --- a/calendar/gui/alarm-notify/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -.deps -.libs -Makefile -Makefile.in -evolution-calendar-stubs.c -evolution-calendar-skels.c -evolution-calendar-common.c -evolution-calendar.h diff --git a/calendar/gui/alarm-notify/Makefile.am b/calendar/gui/alarm-notify/Makefile.am deleted file mode 100644 index 5df0b3c234..0000000000 --- a/calendar/gui/alarm-notify/Makefile.am +++ /dev/null @@ -1,56 +0,0 @@ -CORBA_GENERATED = \ - evolution-calendar.h \ - evolution-calendar-common.c \ - evolution-calendar-skels.c \ - evolution-calendar-stubs.c - -idls = $(top_srcdir)/calendar/idl/evolution-calendar.idl - -idl_flags = `$(GNOME_CONFIG) --cflags idl` -I $(datadir)/idl - -$(CORBA_GENERATED): $(idls) - $(ORBIT_IDL) $(idl_flags) $(top_srcdir)/calendar/idl/evolution-calendar.idl - -bin_PROGRAMS = evolution-alarm-notify - -INCLUDES = \ - -DG_LOG_DOMAIN=\"evolution-alarm-notify\" \ - -I$(top_srcdir) \ - -I$(top_srcdir)/calendar \ - -I$(top_srcdir)/libical/src/libical \ - -I$(top_builddir)/libical/src/libical \ - -I$(top_srcdir)/widgets \ - -I$(includedir) \ - $(BONOBO_VFS_GNOME_CFLAGS) \ - $(EXTRA_GNOME_CFLAGS) \ - -DEVOLUTION_DATADIR=\""$(datadir)"\" \ - -DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \ - -DEVOLUTION_LOCALEDIR=\""$(localedir)"\" - -gladedir = $(datadir)/evolution/glade - -evolution_alarm_notify_SOURCES = \ - alarm.c \ - alarm.h \ - alarm-notify.c \ - alarm-notify.h \ - alarm-queue.c \ - alarm-queue.h \ - notify-main.c - -evolution_alarm_notify_LDADD = \ - $(top_builddir)/calendar/cal-client/libcal-client.la \ - $(top_builddir)/calendar/cal-util/libcal-util.la \ - $(top_builddir)/libical/src/libical/libical.la \ - $(BONOBO_VFS_GNOME_LIBS) \ - $(EXTRA_GNOME_LIBS) \ - $(INTLLIBS) - -oafdir = $(datadir)/oaf -oaf_DATA = GNOME_Evolution_Calendar_AlarmNotify.oafinfo - -EXTRA_DIST = \ - $(oaf_DATA) - -BUILT_SOURCES = $(CORBA_GENERATED) -CLEANFILES += $(BUILT_SOURCES) diff --git a/calendar/gui/alarm-notify/alarm-notify-dialog.c b/calendar/gui/alarm-notify/alarm-notify-dialog.c deleted file mode 100644 index fbd8c1f097..0000000000 --- a/calendar/gui/alarm-notify/alarm-notify-dialog.c +++ /dev/null @@ -1,226 +0,0 @@ -/* Evolution calendar - alarm notification dialog - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#include <config.h> -#include <gnome.h> -#include <glade/glade.h> -#include "alarm-notify-dialog.h" - - - -/* The useful contents of the alarm notify dialog */ -typedef struct { - GladeXML *xml; - - GtkWidget *dialog; - GtkWidget *close; - GtkWidget *snooze; - GtkWidget *edit; - GtkWidget *heading; - GtkWidget *summary; - GtkWidget *snooze_time; - - AlarmNotifyFunc func; - gpointer func_data; -} AlarmNotify; - - - -/* Callback used when the notify dialog is destroyed */ -static void -dialog_destroy_cb (GtkObject *object, gpointer data) -{ - AlarmNotify *an; - - an = data; - gtk_object_unref (GTK_OBJECT (an->xml)); - g_free (an); -} - -/* Delete_event handler for the alarm notify dialog */ -static gint -delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data) -{ - AlarmNotify *an; - - an = data; - g_assert (an->func != NULL); - - (* an->func) (ALARM_NOTIFY_CLOSE, -1, an->func_data); - - gtk_widget_destroy (widget); - return TRUE; -} - -/* Callback for the close button */ -static void -close_clicked_cb (GtkWidget *widget, gpointer data) -{ - AlarmNotify *an; - - an = data; - g_assert (an->func != NULL); - - (* an->func) (ALARM_NOTIFY_CLOSE, -1, an->func_data); - - gtk_widget_destroy (an->dialog); -} - -/* Callback for the snooze button */ -static void -snooze_clicked_cb (GtkWidget *widget, gpointer data) -{ - AlarmNotify *an; - int snooze_time; - - an = data; - g_assert (an->func != NULL); - - snooze_time = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (an->snooze_time)); - (* an->func) (ALARM_NOTIFY_SNOOZE, snooze_time, an->func_data); - - gtk_widget_destroy (an->dialog); -} - -/* Callback for the edit button */ -static void -edit_clicked_cb (GtkWidget *widget, gpointer data) -{ - AlarmNotify *an; - - an = data; - g_assert (an->func != NULL); - - (* an->func) (ALARM_NOTIFY_EDIT, -1, an->func_data); - - gtk_widget_destroy (an->dialog); -} - -/** - * alarm_notify_dialog: - * @trigger: Trigger time for the alarm. - * @occur: Occurrence time for the event. - * @comp: Calendar component object which corresponds to the alarm. - * @func: Function to be called when a dialog action is invoked. - * @func_data: Closure data for @func. - * - * Runs the alarm notification dialog. The specified @func will be used to - * notify the client about result of the actions in the dialog. - * - * Return value: TRUE on success, FALSE if the dialog could not be created. - **/ -gboolean -alarm_notify_dialog (time_t trigger, time_t occur, CalComponent *comp, - AlarmNotifyFunc func, gpointer func_data) -{ - AlarmNotify *an; - char buf[256]; - struct tm tm_trigger; - struct tm tm_occur; - CalComponentText summary; - - g_return_val_if_fail (trigger != -1, FALSE); - g_return_val_if_fail (occur != -1, FALSE); - g_return_val_if_fail (comp != NULL, FALSE); - g_return_val_if_fail (IS_CAL_COMPONENT (comp), FALSE); - g_return_val_if_fail (func != NULL, FALSE); - - an = g_new0 (AlarmNotify, 1); - - an->func = func; - an->func_data = func_data; - - an->xml = glade_xml_new (EVOLUTION_GLADEDIR "/alarm-notify.glade", NULL); - if (!an->xml) { - g_message ("alarm_notify_dialog(): Could not load the Glade XML file!"); - g_free (an); - return FALSE; - } - - an->dialog = glade_xml_get_widget (an->xml, "alarm-notify"); - an->close = glade_xml_get_widget (an->xml, "close"); - an->snooze = glade_xml_get_widget (an->xml, "snooze"); - an->edit = glade_xml_get_widget (an->xml, "edit"); - an->heading = glade_xml_get_widget (an->xml, "heading"); - an->summary = glade_xml_get_widget (an->xml, "summary"); - an->snooze_time = glade_xml_get_widget (an->xml, "snooze-time"); - - if (!(an->dialog && an->close && an->snooze && an->edit && an->heading && an->summary - && an->snooze_time)) { - g_message ("alarm_notify_dialog(): Could not find all widgets in Glade file!"); - gtk_object_unref (GTK_OBJECT (an->xml)); - g_free (an); - return FALSE; - } - - gtk_object_set_data (GTK_OBJECT (an->dialog), "alarm-notify", an); - gtk_signal_connect (GTK_OBJECT (an->dialog), "destroy", - GTK_SIGNAL_FUNC (dialog_destroy_cb), an); - - /* Title */ - - /* FIXME: use am_pm_flag or 24-hour time */ - - tm_trigger = *localtime (&trigger); - strftime (buf, sizeof (buf), _("Alarm on %A %b %d %Y %H:%M"), &tm_trigger); - gtk_window_set_title (GTK_WINDOW (an->dialog), buf); - - /* Heading */ - - tm_occur = *localtime (&occur); - strftime (buf, sizeof (buf), - _("Notification about your appointment on %A %b %d %Y %H:%M"), - &tm_occur); - gtk_label_set_text (GTK_LABEL (an->heading), buf); - - /* Summary */ - - cal_component_get_summary (comp, &summary); - - if (summary.value) - gtk_label_set_text (GTK_LABEL (an->summary), summary.value); - else - gtk_label_set_text (GTK_LABEL (an->summary), _("No summary available.")); - - /* Connect actions */ - - gtk_signal_connect (GTK_OBJECT (an->dialog), "delete_event", - GTK_SIGNAL_FUNC (delete_event_cb), - an); - - gtk_signal_connect (GTK_OBJECT (an->close), "clicked", - GTK_SIGNAL_FUNC (close_clicked_cb), - an); - - gtk_signal_connect (GTK_OBJECT (an->snooze), "clicked", - GTK_SIGNAL_FUNC (snooze_clicked_cb), - an); - - gtk_signal_connect (GTK_OBJECT (an->edit), "clicked", - GTK_SIGNAL_FUNC (edit_clicked_cb), - an); - - /* Run! */ - - gtk_widget_show (an->dialog); - return TRUE; -} diff --git a/calendar/gui/alarm-notify/alarm-notify-dialog.h b/calendar/gui/alarm-notify/alarm-notify-dialog.h deleted file mode 100644 index f2c938c495..0000000000 --- a/calendar/gui/alarm-notify/alarm-notify-dialog.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Evolution calendar - alarm notification dialog - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef ALARM_NOTIFY_DIALOG_H -#define ALARM_NOTIFY_DIALOG_H - -#include <time.h> -#include <glib.h> -#include <cal-util/cal-component.h> - - - -typedef enum { - ALARM_NOTIFY_CLOSE, - ALARM_NOTIFY_SNOOZE, - ALARM_NOTIFY_EDIT -} AlarmNotifyResult; - -typedef void (* AlarmNotifyFunc) (AlarmNotifyResult result, int snooze_mins, gpointer data); - -gboolean alarm_notify_dialog (time_t trigger, time_t occur, CalComponent *comp, - AlarmNotifyFunc func, gpointer func_data); - - - -#endif diff --git a/calendar/gui/alarm-notify/alarm-notify.c b/calendar/gui/alarm-notify/alarm-notify.c deleted file mode 100644 index 9d64bfd4a8..0000000000 --- a/calendar/gui/alarm-notify/alarm-notify.c +++ /dev/null @@ -1,333 +0,0 @@ -/* Evolution calendar - Alarm notification service object - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <libgnomevfs/gnome-vfs.h> -#include <cal-client/cal-client.h> -#include "alarm-notify.h" - - - -/* Private part of the AlarmNotify structure */ -struct _AlarmNotifyPrivate { - /* Mapping from GnomeVFSURIs to loaded clients */ - GHashTable *uri_client_hash; -}; - - - -static void alarm_notify_class_init (AlarmNotifyClass *class); -static void alarm_notify_init (AlarmNotify *an); -static void alarm_notify_destroy (GtkObject *object); - -static POA_GNOME_Evolution_Calendar_AlarmNotify__vepv alarm_notify_vepv; - -static BonoboObjectClass *parent_class; - - - -/** - * alarm_notify_get_type: - * - * Registers the #AlarmNotify class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the #AlarmNotify class. - **/ -GtkType -alarm_notify_get_type (void) -{ - static GtkType alarm_notify_type = 0; - - if (!alarm_notify_type) { - static const GtkTypeInfo alarm_notify_info = { - "AlarmNotify", - sizeof (AlarmNotify), - sizeof (AlarmNotifyClass), - (GtkClassInitFunc) alarm_notify_class_init, - (GtkObjectInitFunc) alarm_notify_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - alarm_notify_type = gtk_type_unique (BONOBO_OBJECT_TYPE, &alarm_notify_info); - } - - return alarm_notify_type; -} - -/* CORBA class initialization function for the alarm notify service */ -static void -init_alarm_notify_corba_class (void) -{ - alarm_notify_vepv.Bonobo_Unknown_epv = bonobo_object_get_epv (); - alarm_notify_vepv.GNOME_Evolution_Calendar_AlarmNotify_epv = alarm_notify_get_epv (); -} - -/* Class initialization function for the alarm notify service */ -static void -alarm_notify_class_init (AlarmNotifyClass *class) -{ - GtkObjectClass *object_class; - - object_class = (GtkObjectClass *) class; - - parent_class = gtk_type_class (BONOBO_OBJECT_TYPE); - - object_class->destroy = alarm_notify_destroy; - - init_alarm_notify_corba_class (); -} - -/* Object initialization function for the alarm notify system */ -static void -alarm_notify_init (AlarmNotify *an) -{ - AlarmNotifyPrivate *priv; - - priv = g_new0 (AlarmNotifyPrivate, 1); - an->priv = priv; - - priv->uri_client_hash = g_hash_table_new (gnome_vfs_uri_hash, gnome_vfs_uri_hequal); -} - -/* Destroy handler for the alarm notify system */ -static void -alarm_notify_destroy (GtkObject *object) -{ - AlarmNotify *an; - AlarmNotifyPrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_ALARM_NOTIFY (object)); - - an = ALARM_NOTIFY (object); - priv = an->priv; - - /* FIXME */ - - g_hash_table_destroy (priv->uri_client_hash); - priv->uri_client_hash = NULL; - - g_free (priv); - an->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - - -/* CORBA servant implementation */ - -/* AlarmNotify::addCalendar method */ -static void -AlarmNotify_addCalendar (PortableServer_Servant servant, - const CORBA_char *str_uri, - CORBA_Environment *ev) -{ - AlarmNotify *an; - AlarmNotifyPrivate *priv; - GnomeVFSURI *uri; - CalClient *client; - - an = ALARM_NOTIFY (bonobo_object_from_servant (servant)); - priv = an->priv; - - uri = gnome_vfs_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, uri); - - if (client) { - gnome_vfs_uri_unref (uri); - - gtk_object_ref (GTK_OBJECT (client)); - return; - } - - client = cal_client_new (); - - if (client) { - g_hash_table_insert (priv->uri_client_hash, uri); - alarm_queue_add_client (client); - - if (!cal_client_open_calendar (client, str_uri, FALSE)) { - gtk_object_unref (GTK_OBJECT (client)); - client = NULL; - } - } else { - gnome_vfs_uri_unref (uri); - - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_GNOME_Evolution_Calendar_AlarmNotify_BackendContactError, - NULL); - return; - } -} - -/* AlarmNotify::removeCalendar method */ -static void -AlarmNotify_removeCalendar (PortableServer_Servant servant, - const CORBA_char *uri, - CORBA_Environment *ev) -{ - AlarmNotify *an; - AlarmNotifyPrivate *priv; - CalClient *client; - char *orig_uri; - - an = ALARM_NOTIFY (bonobo_object_from_servant (servant)); - priv = an->priv; - - if (!g_hash_table_lookup_extended (priv->uri_client_hash, uri, &orig_uri, &client)) { - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_GNOME_Evolution_Calendar_AlarmNotify_NotFound); - return; - } - - gtk_object_unref (client); - - /* FIXME: do we need to do anything else? */ -} - -/** - * alarm_notify_get_epv: - * - * Creates an EPV for the AlarmNotify CORBA class. - * - * Return value: A newly-allocated EPV. - **/ -POA_GNOME_Evolution_Calendar_AlarmNotify__epv * -alarm_notify_get_epv (void) -{ - POA_GNOME_Evolution_Calendar_AlarmNotify__epv *epv; - - epv = g_new0 (POA_GNOME_Evolution_Calendar_AlarmNotify__epv, 1); - epv->addCalendar = AlarmNotify_addCalendar; - epv->removeCalendar = AlarmNotify_removeCalendar; - epv->die = AlarmNotify_die; - return epv; -} - - - -/** - * alarm_notify_construct: - * @an: An alarm notification service object. - * @corba_an: CORBA object for the alarm notification service. - * - * Constructs an alarm notification service object by binding the corresponding - * CORBA object to it. - * - * Return value: the same object as the @an argument. - **/ -AlarmNotify * -alarm_notify_construct (AlarmNotify *an, - GNOME_Evolution_Calendar_AlarmNotify corba_an) -{ - g_return_val_if_fail (an != NULL, NULL); - g_return_val_if_fail (IS_ALARM_NOTIFY (an), NULL); - - /* FIXME: add_interface the property bag here */ - - bonobo_object_construct (BONOBO_OBJECT (an), corba_an); - return an; -} - -/** - * alarm_notify_corba_object_create: - * @object: #BonoboObject that will wrap the CORBA object. - * - * Creates and activates the CORBA object that is wrapped by the specified alarm - * notification service @object. - * - * Return value: An activated object reference or #CORBA_OBJECT_NIL in case of - * failure. - **/ -GNOME_Evolution_Calendar_AlarmNotify -alarm_notify_corba_object_create (BonoboObject *object) -{ - POA_GNOME_Evolution_Calendar_AlarmNotify *servant; - CORBA_Environment ev; - - g_return_val_if_fail (object != NULL, CORBA_OBJECT_NIL); - g_return_val_if_fail (IS_ALARM_NOTIFY (object), CORBA_OBJECT_NIL); - - servant = (POA_GNOME_Evolution_Calendar_AlarmNotify *) g_new (BonoboObjectServant, 1); - servant->vepv = &alarm_notify_vepv; - - CORBA_exception_init (&ev); - POA_GNOME_Evolution_Calendar_AlarmNotify__init ((PortableServer_Servant) servant, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_free (servant); - CORBA_exception_free (&ev); - return CORBA_OBJECT_NIL; - } - - CORBA_exception_free (&ev); - return (GNOME_Evolution_Calendar_AlarmNotify) bonobo_object_activate_servant ( - object, servant); -} - -/** - * alarm_notify_new: - * - * Creates a new #AlarmNotify object. - * - * Return value: A newly-created #AlarmNotify, or NULL if its corresponding - * CORBA object could not be created. - **/ -AlarmNotify * -alarm_notify_new (void) -{ - AlarmNotify *an; - GNOME_Evolution_Calendar_AlarmNotify corba_an; - CORBA_Environment ev; - gboolean result; - - an = gtk_type_new (TYPE_ALARM_NOTIFY); - - corba_an = alarm_notify_corba_object_create (BONOBO_OBJECT (an)); - - CORBA_exception_init (&ev); - result = CORBA_Object_is_nil (corba_an, &ev); - - if (ev._major != CORBA_NO_EXCEPTION || result) { - g_message ("alarm_notify_new(): could not create the CORBA alarm notify service"); - bonobo_object_unref (BONOBO_OBJECT (an)); - CORBA_exception_free (&ev); - return NULL; - } - CORBA_exception_free (&ev); - - return alarm_notify_construct (an, corba_an); -} diff --git a/calendar/gui/alarm-notify/alarm-notify.glade b/calendar/gui/alarm-notify/alarm-notify.glade deleted file mode 100644 index 41718d0572..0000000000 --- a/calendar/gui/alarm-notify/alarm-notify.glade +++ /dev/null @@ -1,228 +0,0 @@ -<?xml version="1.0"?> -<GTK-Interface> - -<project> - <name>Evolution Calendar</name> - <program_name>evolution-calendar</program_name> - <directory></directory> - <source_directory>src</source_directory> - <pixmaps_directory>pixmaps</pixmaps_directory> - <language>C</language> - <gnome_support>True</gnome_support> - <gettext_support>True</gettext_support> - <use_widget_names>False</use_widget_names> - <output_main_file>True</output_main_file> - <output_support_files>True</output_support_files> - <output_build_files>True</output_build_files> - <backup_source_files>True</backup_source_files> - <main_source_file>interface.c</main_source_file> - <main_header_file>interface.h</main_header_file> - <handler_source_file>callbacks.c</handler_source_file> - <handler_header_file>callbacks.h</handler_header_file> - <support_source_file>support.c</support_source_file> - <support_header_file>support.h</support_header_file> -</project> - -<widget> - <class>GtkWindow</class> - <name>alarm-notify</name> - <cxx_use_heap>True</cxx_use_heap> - <title></title> - <type>GTK_WINDOW_DIALOG</type> - <position>GTK_WIN_POS_CENTER</position> - <modal>False</modal> - <allow_shrink>False</allow_shrink> - <allow_grow>False</allow_grow> - <auto_shrink>False</auto_shrink> - - <widget> - <class>GtkVBox</class> - <name>vbox2</name> - <border_width>4</border_width> - <cxx_use_heap>True</cxx_use_heap> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - - <widget> - <class>GtkHBox</class> - <name>hbox3</name> - <cxx_use_heap>True</cxx_use_heap> - <homogeneous>False</homogeneous> - <spacing>8</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkVBox</class> - <name>vbox5</name> - <cxx_use_heap>True</cxx_use_heap> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>heading</name> - <cxx_use_heap>True</cxx_use_heap> - <label></label> - <justify>GTK_JUSTIFY_LEFT</justify> - <wrap>True</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>summary</name> - <cxx_use_heap>True</cxx_use_heap> - <label></label> - <justify>GTK_JUSTIFY_LEFT</justify> - <wrap>True</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> - - <widget> - <class>GtkVBox</class> - <name>vbox4</name> - <cxx_use_heap>True</cxx_use_heap> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkButton</class> - <name>close</name> - <cxx_use_heap>True</cxx_use_heap> - <can_focus>True</can_focus> - <label>Close</label> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkButton</class> - <name>snooze</name> - <cxx_use_heap>True</cxx_use_heap> - <can_focus>True</can_focus> - <label>Snooze</label> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkButton</class> - <name>edit</name> - <cxx_use_heap>True</cxx_use_heap> - <can_focus>True</can_focus> - <label>Edit appointment</label> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> - </widget> - - <widget> - <class>GtkHSeparator</class> - <name>hseparator1</name> - <cxx_use_heap>True</cxx_use_heap> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - </widget> - - <widget> - <class>GtkHBox</class> - <name>hbox4</name> - <cxx_use_heap>True</cxx_use_heap> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label4</name> - <cxx_use_heap>True</cxx_use_heap> - <label>Snooze time (minutes)</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkSpinButton</class> - <name>snooze-time</name> - <cxx_use_heap>True</cxx_use_heap> - <can_focus>True</can_focus> - <climb_rate>1</climb_rate> - <digits>0</digits> - <numeric>False</numeric> - <update_policy>GTK_UPDATE_ALWAYS</update_policy> - <snap>False</snap> - <wrap>False</wrap> - <value>5</value> - <lower>1</lower> - <upper>1440</upper> - <step>1</step> - <page>5</page> - <page_size>5</page_size> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> - </widget> -</widget> - -</GTK-Interface> diff --git a/calendar/gui/alarm-notify/alarm-notify.h b/calendar/gui/alarm-notify/alarm-notify.h deleted file mode 100644 index e7a907485d..0000000000 --- a/calendar/gui/alarm-notify/alarm-notify.h +++ /dev/null @@ -1,67 +0,0 @@ -/* Evolution calendar - Alarm notification service object - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef ALARM_NOTIFY_H -#define ALARM_NOTIFY_H - -#include <bonobo/bonobo-object.h> -#include "evolution-calendar.h" - - - -#define TYPE_ALARM_NOTIFY (alarm_notify_get_type ()) -#define ALARM_NOTIFY(obj) (GTK_CHECK_CAST ((obj), TYPE_ALARM_NOTIFY, AlarmNotify)) -#define ALARM_NOTIFY_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_ALARM_NOTIFY, \ - AlarmNotifyClass)) -#define IS_ALARM_NOTIFY(obj) (GTK_CHECK_TYPE ((obj), TYPE_ALARM_NOTIFY)) -#define IS_ALARM_NOTIFY_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), TYPE_ALARM_NOTIFY)) - -typedef struct _AlarmNotify AlarmNotify; -typedef struct _AlarmNotifyClass AlarmNotifyClass; - -typedef struct _AlarmNotifyPrivate AlarmNotifyPrivate; - -struct _AlarmNotify { - BonoboObject object; - - /* Private data */ - AlarmNotifyPrivate *priv; -}; - -struct _AlarmNotifyClass { - BonoboObjectClass parent_class; -}; - -GtkType alarm_notify_get_type (void); - -AlarmNotify *alarm_notify_construct (AlarmNotify *an, - GNOME_Evolution_Calendar_AlarmNotify corba_an); - -GNOME_Evolution_Calendar_AlarmNotify alarm_notify_corba_object_create (BonoboObject *object); -POA_GNOME_Evolution_Calendar_AlarmNotify__epv *alarm_notify_get_epv (void); - -AlarmNotify *alarm_notify_new (void); - - - - -#endif diff --git a/calendar/gui/alarm-notify/alarm-queue.c b/calendar/gui/alarm-notify/alarm-queue.c deleted file mode 100644 index e2f2ae88db..0000000000 --- a/calendar/gui/alarm-notify/alarm-queue.c +++ /dev/null @@ -1,964 +0,0 @@ -/* Evolution calendar - Alarm queueing engine - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtksignal.h> -#include <cal-util/timeutil.h> -#include "alarm.h" -#include "alarm-queue.h" - - - -/* Whether the queueing system has been initialized */ -static gboolean alarm_queue_inited; - -/* Clients we are monitoring for alarms */ -static GHashTable *client_alarms_hash = NULL; - -/* Structure that stores a client we are monitoring */ -typedef struct { - /* Monitored client */ - CalClient *client; - - /* Number of times this client has been registered */ - int refcount; - - /* Hash table of component UID -> CompQueuedAlarms. If an element is - * present here, then it means its cqa->queued_alarms contains at least - * one queued alarm. When all the alarms for a component have been - * dequeued, the CompQueuedAlarms structure is removed from the hash - * table. Thus a CQA exists <=> it has queued alarms. - */ - GHashTable *uid_alarms_hash; -} ClientAlarms; - -/* Pair of a CalComponentAlarms and the mapping from queued alarm IDs to the - * actual alarm instance structures. - */ -typedef struct { - /* The parent client alarms structure */ - ClientAlarms *parent_client; - - /* The actual component and its alarm instances */ - CalComponentAlarms *alarms; - - /* List of QueuedAlarm structures */ - GSList *queued_alarms; -} CompQueuedAlarms; - -/* Pair of a queued alarm ID and the alarm trigger instance it refers to */ -typedef struct { - /* Alarm ID from alarm.h */ - gpointer alarm_id; - - /* Instance from our parent CompAlarms->alarms list */ - CalAlarmInstance *instance; -} QueuedAlarm; - -/* Alarm ID for the midnight refresh function */ -static gpointer midnight_refresh_id = NULL; - - - -static void load_alarms (ClientAlarms *ca); -static void midnight_refresh_cb (gpointer alarm_id, time_t trigger, gpointer data); - -/* Queues an alarm trigger for midnight so that we can load the next day's worth - * of alarms. - */ -static void -queue_midnight_refresh (void) -{ - time_t midnight; - - g_assert (midnight_refresh_id == NULL); - - midnight = time_day_end (time (NULL)); - - midnight_refresh_id = alarm_add (midnight, midnight_refresh_cb, NULL, NULL); - if (!midnight_refresh_id) { - g_message ("queue_midnight_refresh(): Could not set up the midnight refresh alarm!"); - /* FIXME: what to do? */ - } -} - -/* Loads a client's alarms; called from g_hash_table_foreach() */ -static void -add_client_alarms_cb (gpointer key, gpointer value, gpointer data) -{ - ClientAlarms *ca; - - ca = value; - load_alarms (ca); -} - -/* Loads the alarms for the new day every midnight */ -static void -midnight_refresh_cb (gpointer alarm_id, time_t trigger, gpointer data) -{ - /* Re-load the alarms for all clients */ - - g_hash_table_foreach (client_alarms_hash, add_client_alarms_cb, NULL); - - /* Re-schedule the midnight update */ - - midnight_refresh_id = NULL; - queue_midnight_refresh (); -} - -/* Looks up a client in the client alarms hash table */ -static ClientAlarms * -lookup_client (CalClient *client) -{ - return g_hash_table_lookup (client_alarms_hash, client); -} - -/* Callback used when an alarm triggers */ -static void -alarm_trigger_cb (gpointer alarm_id, time_t trigger, gpointer data) -{ - CompQueuedAlarms *cqa; - - cqa = data; - - /* FIXME */ - - g_message ("alarm_trigger_cb(): Triggered!"); -} - -/* Callback used when an alarm must be destroyed */ -static void -alarm_destroy_cb (gpointer alarm_id, gpointer data) -{ - CompQueuedAlarms *cqa; - GSList *l; - QueuedAlarm *qa; - const char *uid; - - cqa = data; - - qa = NULL; /* Keep GCC happy */ - - /* Find the alarm in the queued alarms */ - - for (l = cqa->queued_alarms; l; l = l->next) { - qa = l->data; - if (qa->alarm_id == alarm_id) - break; - } - - g_assert (l != NULL); - - /* Remove it and free it */ - - cqa->queued_alarms = g_slist_remove_link (cqa->queued_alarms, l); - g_slist_free_1 (l); - - g_free (qa); - - /* If this was the last queued alarm for this component, remove the - * component itself. - */ - - if (cqa->queued_alarms != NULL) - return; - - cal_component_get_uid (cqa->alarms->comp, &uid); - g_hash_table_remove (cqa->parent_client->uid_alarms_hash, uid); - cqa->parent_client = NULL; - - cal_component_alarms_free (cqa->alarms); - cqa->alarms = NULL; - - g_free (cqa); -} - -/* Adds the alarms in a CalComponentAlarms structure to the alarms queued for a - * particular client. Also puts the triggers in the alarm timer queue. - */ -static void -add_component_alarms (ClientAlarms *ca, CalComponentAlarms *alarms) -{ - const char *uid; - CompQueuedAlarms *cqa; - GSList *l; - - /* No alarms? */ - if (alarms->alarms == NULL) { - cal_component_alarms_free (alarms); - return; - } - - cqa = g_new (CompQueuedAlarms, 1); - cqa->parent_client = ca; - cqa->alarms = alarms; - - cqa->queued_alarms = NULL; - - for (l = alarms->alarms; l; l = l->next) { - CalAlarmInstance *instance; - gpointer alarm_id; - QueuedAlarm *qa; - - instance = l->data; - - alarm_id = alarm_add (instance->trigger, alarm_trigger_cb, cqa, alarm_destroy_cb); - if (!alarm_id) { - g_message ("add_component_alarms(): Could not schedule a trigger for " - "%ld, discarding...", (long) instance->trigger); - continue; - } - - qa = g_new (QueuedAlarm, 1); - qa->alarm_id = alarm_id; - qa->instance = instance; - - cqa->queued_alarms = g_slist_prepend (cqa->queued_alarms, qa); - } - - cal_component_get_uid (alarms->comp, &uid); - - /* If we failed to add all the alarms, then we should get rid of the cqa */ - if (cqa->queued_alarms == NULL) { - g_message ("add_component_alarms(): Could not add any of the alarms " - "for the component `%s'; discarding it...", uid); - - cal_component_alarms_free (cqa->alarms); - cqa->alarms = NULL; - - g_free (cqa); - return; - } - - cqa->queued_alarms = g_slist_reverse (cqa->queued_alarms); - g_hash_table_insert (ca->uid_alarms_hash, (char *) uid, cqa); -} - -/* Loads today's remaining alarms for a client */ -static void -load_alarms (ClientAlarms *ca) -{ - time_t now, day_end; - GSList *comp_alarms; - GSList *l; - - now = time (NULL); - day_end = time_day_end (now); - - comp_alarms = cal_client_get_alarms_in_range (ca->client, now, day_end); - - /* All of the last day's alarms should have already triggered and should - * have been removed, so we should have no pending components. - */ - g_assert (g_hash_table_size (ca->uid_alarms_hash) == 0); - - for (l = comp_alarms; l; l = l->next) { - CalComponentAlarms *alarms; - - alarms = l->data; - add_component_alarms (ca, alarms); - } - - g_slist_free (comp_alarms); -} - -/* Called when a calendar client finished loading; we load its alarms */ -static void -cal_loaded_cb (CalClient *client, CalClientLoadStatus status, gpointer data) -{ - ClientAlarms *ca; - - ca = data; - - if (status != CAL_CLIENT_LOAD_SUCCESS) - return; - - load_alarms (ca); -} - -/* Looks up a component's queued alarm structure in a client alarms structure */ -static CompQueuedAlarms * -lookup_comp_queued_alarms (ClientAlarms *ca, const char *uid) -{ - return g_hash_table_lookup (ca->uid_alarms_hash, uid); -} - -/* Removes a component an its alarms */ -static void -remove_comp (ClientAlarms *ca, const char *uid) -{ - CompQueuedAlarms *cqa; - GSList *l; - - cqa = lookup_comp_queued_alarms (ca, uid); - if (!cqa) - return; - - /* If a component is present, then it means we must have alarms queued - * for it. - */ - g_assert (cqa->queued_alarms != NULL); - - for (l = cqa->queued_alarms; l;) { - QueuedAlarm *qa; - - qa = l->data; - - /* Get the next element here because the list element will go - * away. Also, we do not free the qa here because it will be - * freed by the destroy notification function. - */ - l = l->next; - - alarm_remove (qa->alarm_id); - } - - /* The list should be empty now, and thus the queued component alarms - * structure should have been freed and removed from the hash table. - */ - g_assert (lookup_comp_queued_alarms (ca, uid) == NULL); -} - -/* Called when a calendar component changes; we must reload its corresponding - * alarms. - */ -static void -obj_updated_cb (CalClient *client, const char *uid, gpointer data) -{ - ClientAlarms *ca; - time_t now, day_end; - CalComponentAlarms *alarms; - gboolean found; - - ca = data; - - remove_comp (ca, uid); - - now = time (NULL); - day_end = time_day_end (now); - - found = cal_client_get_alarms_for_object (ca->client, uid, now, day_end, &alarms); - - if (!found) - return; - - add_component_alarms (ca, alarms); -} - -/* Called when a calendar component is removed; we must delete its corresponding - * alarms. - */ -static void -obj_removed_cb (CalClient *client, const char *uid, gpointer data) -{ - ClientAlarms *ca; - - ca = data; - - remove_comp (ca, uid); -} - - - -/** - * alarm_queue_init: - * - * Initializes the alarm queueing system. This should be called near the - * beginning of the program, after calling alarm_init(). - **/ -void -alarm_queue_init (void) -{ - g_return_if_fail (alarm_queue_inited == FALSE); - - client_alarms_hash = g_hash_table_new (g_direct_hash, g_direct_equal); - queue_midnight_refresh (); - - alarm_queue_inited = TRUE; -} - -/** - * alarm_queue_done: - * - * Shuts down the alarm queueing system. This should be called near the end - * of the program. All the monitored calendar clients should already have been - * unregistered with alarm_queue_remove_client(). - **/ -void -alarm_queue_done (void) -{ - g_return_if_fail (alarm_queue_inited); - - /* All clients must be unregistered by now */ - g_return_if_fail (g_hash_table_size (client_alarms_hash) == 0); - - g_hash_table_destroy (client_alarms_hash); - client_alarms_hash = NULL; - - g_assert (midnight_refresh_id != NULL); - alarm_remove (midnight_refresh_id); - midnight_refresh_id = NULL; - - alarm_queue_inited = FALSE; -} - -/** - * alarm_queue_add_client: - * @client: A calendar client. - * - * Adds a calendar client to the alarm queueing system. Alarm trigger - * notifications will be presented at the appropriate times. The client should - * be removed with alarm_queue_remove_client() when receiving notifications - * from it is no longer desired. - * - * A client can be added any number of times to the alarm queueing system, - * but any single alarm trigger will only be presented once for a particular - * client. The client must still be removed the same number of times from the - * queueing system when it is no longer wanted. - **/ -void -alarm_queue_add_client (CalClient *client) -{ - ClientAlarms *ca; - - g_return_if_fail (alarm_queue_inited); - g_return_if_fail (client != NULL); - g_return_if_fail (IS_CAL_CLIENT (client)); - - ca = lookup_client (client); - if (ca) { - ca->refcount++; - return; - } - - ca = g_new (ClientAlarms, 1); - - ca->client = client; - gtk_object_ref (GTK_OBJECT (ca->client)); - - ca->refcount = 1; - g_hash_table_insert (client_alarms_hash, client, ca); - - ca->uid_alarms_hash = g_hash_table_new (g_str_hash, g_str_equal); - - if (!cal_client_is_loaded (client)) - gtk_signal_connect (GTK_OBJECT (client), "cal_loaded", - GTK_SIGNAL_FUNC (cal_loaded_cb), ca); - - gtk_signal_connect (GTK_OBJECT (client), "obj_updated", - GTK_SIGNAL_FUNC (obj_updated_cb), ca); - gtk_signal_connect (GTK_OBJECT (client), "obj_removed", - GTK_SIGNAL_FUNC (obj_removed_cb), ca); - - if (cal_client_is_loaded (client)) - load_alarms (ca); -} - -/* Called from g_hash_table_foreach(); adds a component UID to a list */ -static void -add_uid_cb (gpointer key, gpointer value, gpointer data) -{ - GSList **uids; - const char *uid; - - uids = data; - uid = key; - - *uids = g_slist_prepend (*uids, (char *) uid); -} - -/* Removes all the alarms queued for a particular calendar client */ -static void -remove_client_alarms (ClientAlarms *ca) -{ - GSList *uids; - GSList *l; - - /* First we build a list of UIDs so that we can remove them one by one */ - - uids = NULL; - g_hash_table_foreach (ca->uid_alarms_hash, add_uid_cb, &uids); - - for (l = uids; l; l = l->next) { - const char *uid; - - uid = l->data; - - remove_comp (ca, uid); - } - - g_slist_free (uids); - - /* The hash table should be empty now */ - - g_assert (g_hash_table_size (ca->uid_alarms_hash) == 0); -} - -/** - * alarm_queue_remove_client: - * @client: A calendar client. - * - * Removes a calendar client from the alarm queueing system. - **/ -void -alarm_queue_remove_client (CalClient *client) -{ - ClientAlarms *ca; - - g_return_if_fail (alarm_queue_inited); - g_return_if_fail (client != NULL); - g_return_if_fail (IS_CAL_CLIENT (client)); - - ca = lookup_client (client); - g_return_if_fail (ca != NULL); - - g_assert (ca->refcount > 0); - ca->refcount--; - - if (ca->refcount > 0) - return; - - remove_client_alarms (ca); - - /* Clean up */ - - gtk_signal_disconnect_by_data (GTK_OBJECT (ca->client), ca); - - gtk_object_unref (GTK_OBJECT (ca->client)); - ca->client = NULL; - - g_hash_table_destroy (ca->uid_alarms_hash); - ca->uid_alarms_hash = NULL; - - g_free (ca); - - g_hash_table_remove (client_alarms_hash, client); -} - - - -#if 0 - -/* Sends a mail notification of an alarm trigger */ -static void -mail_notification (char *mail_address, char *text, time_t app_time) -{ - pid_t pid; - int p [2]; - char *command; - - pipe (p); - pid = fork (); - if (pid == 0){ - int dev_null; - - dev_null = open ("/dev/null", O_RDWR); - dup2 (p [0], 0); - dup2 (dev_null, 1); - dup2 (dev_null, 2); - execl ("/usr/lib/sendmail", "/usr/lib/sendmail", - mail_address, NULL); - _exit (127); - } - command = g_strconcat ("To: ", mail_address, "\n", - "Subject: ", _("Reminder of your appointment at "), - ctime (&app_time), "\n\n", text, "\n", NULL); - write (p [1], command, strlen (command)); - close (p [1]); - close (p [0]); - g_free (command); -} - -static int -max_open_files (void) -{ - static int files; - - if (files) - return files; - - files = sysconf (_SC_OPEN_MAX); - if (files != -1) - return files; -#ifdef OPEN_MAX - return files = OPEN_MAX; -#else - return files = 256; -#endif -} - -/* Executes a program as a notification of an alarm trigger */ -static void -program_notification (char *command, int close_standard) -{ - struct sigaction ignore, save_intr, save_quit; - int status = 0, i; - pid_t pid; - - ignore.sa_handler = SIG_IGN; - sigemptyset (&ignore.sa_mask); - ignore.sa_flags = 0; - - sigaction (SIGINT, &ignore, &save_intr); - sigaction (SIGQUIT, &ignore, &save_quit); - - if ((pid = fork ()) < 0){ - fprintf (stderr, "\n\nfork () = -1\n"); - return; - } - if (pid == 0){ - pid = fork (); - if (pid == 0){ - const int top = max_open_files (); - sigaction (SIGINT, &save_intr, NULL); - sigaction (SIGQUIT, &save_quit, NULL); - - for (i = (close_standard ? 0 : 3); i < top; i++) - close (i); - - /* FIXME: As an excercise to the reader, copy the - * code from mc to setup shell properly instead of - * /bin/sh. Yes, this comment is larger than a cut and paste. - */ - execl ("/bin/sh", "/bin/sh", "-c", command, (char *) 0); - - _exit (127); - } else { - _exit (127); - } - } - wait (&status); - sigaction (SIGINT, &save_intr, NULL); - sigaction (SIGQUIT, &save_quit, NULL); -} - -/* Queues a snooze alarm */ -static void -snooze (GnomeCalendar *gcal, CalComponent *comp, time_t occur, int snooze_mins, gboolean audio) -{ - time_t now, trigger; - struct tm tm; - CalAlarmInstance ai; - - now = time (NULL); - tm = *localtime (&now); - tm.tm_min += snooze_mins; - - trigger = mktime (&tm); - if (trigger == -1) { - g_message ("snooze(): produced invalid time_t; not queueing alarm!"); - return; - } - -#if 0 - cal_component_get_uid (comp, &ai.uid); - ai.type = audio ? ALARM_AUDIO : ALARM_DISPLAY; -#endif - ai.trigger = trigger; - ai.occur = occur; - - setup_alarm (gcal, &ai); -} - -struct alarm_notify_closure { - GnomeCalendar *gcal; - CalComponent *comp; - time_t occur; -}; - -/* Callback used for the result of the alarm notification dialog */ -static void -display_notification_cb (AlarmNotifyResult result, int snooze_mins, gpointer data) -{ - struct alarm_notify_closure *c; - - c = data; - - switch (result) { - case ALARM_NOTIFY_CLOSE: - break; - - case ALARM_NOTIFY_SNOOZE: - snooze (c->gcal, c->comp, c->occur, snooze_mins, FALSE); - break; - - case ALARM_NOTIFY_EDIT: - gnome_calendar_edit_object (c->gcal, c->comp); - break; - - default: - g_assert_not_reached (); - } - - gtk_object_unref (GTK_OBJECT (c->comp)); - g_free (c); -} - -/* Present a display notification of an alarm trigger */ -static void -display_notification (time_t trigger, time_t occur, CalComponent *comp, GnomeCalendar *gcal) -{ - gboolean result; - struct alarm_notify_closure *c; - - gtk_object_ref (GTK_OBJECT (comp)); - - c = g_new (struct alarm_notify_closure, 1); - c->gcal = gcal; - c->comp = comp; - c->occur = occur; - - result = alarm_notify_dialog (trigger, occur, comp, display_notification_cb, c); - if (!result) { - g_message ("display_notification(): could not display the alarm notification dialog"); - g_free (c); - gtk_object_unref (GTK_OBJECT (comp)); - } -} - -/* Present an audible notification of an alarm trigger */ -static void -audio_notification (time_t trigger, time_t occur, CalComponent *comp, GnomeCalendar *gcal) -{ - g_message ("AUDIO NOTIFICATION!"); - /* FIXME */ -} - -/* Callback function used when an alarm is triggered */ -static void -trigger_alarm_cb (gpointer alarm_id, time_t trigger, gpointer data) -{ - struct trigger_alarm_closure *c; - GnomeCalendarPrivate *priv; - CalComponent *comp; - CalClientGetStatus status; - const char *uid; - ObjectAlarms *oa; - GList *l; - - c = data; - priv = c->gcal->priv; - - /* Fetch the object */ - - status = cal_client_get_object (priv->client, c->uid, &comp); - - switch (status) { - case CAL_CLIENT_GET_SUCCESS: - /* Go on */ - break; - case CAL_CLIENT_GET_SYNTAX_ERROR: - case CAL_CLIENT_GET_NOT_FOUND: - g_message ("trigger_alarm_cb(): syntax error in fetched object"); - return; - } - - g_assert (comp != NULL); - - /* Present notification */ - - switch (c->type) { - case CAL_COMPONENT_ALARM_EMAIL: -#if 0 - g_assert (ico->malarm.enabled); - mail_notification (ico->malarm.data, ico->summary, c->occur); -#endif - break; - - case CAL_COMPONENT_ALARM_PROCEDURE: -#if 0 - g_assert (ico->palarm.enabled); - program_notification (ico->palarm.data, FALSE); -#endif - break; - - case CAL_COMPONENT_ALARM_DISPLAY: -#if 0 - g_assert (ico->dalarm.enabled); -#endif - display_notification (trigger, c->occur, comp, c->gcal); - break; - - case CAL_COMPONENT_ALARM_AUDIO: -#if 0 - g_assert (ico->aalarm.enabled); -#endif - audio_notification (trigger, c->occur, comp, c->gcal); - break; - - default: - break; - } - - /* Remove the alarm from the hash table */ - cal_component_get_uid (comp, &uid); - oa = g_hash_table_lookup (priv->alarms, uid); - g_assert (oa != NULL); - - l = g_list_find (oa->alarm_ids, alarm_id); - g_assert (l != NULL); - - oa->alarm_ids = g_list_remove_link (oa->alarm_ids, l); - g_list_free_1 (l); - - if (!oa->alarm_ids) { - g_hash_table_remove (priv->alarms, uid); - g_free (oa->uid); - g_free (oa); - } - - gtk_object_unref (GTK_OBJECT (comp)); -} - -#endif - -#if 0 - -static void -stop_beeping (GtkObject* object, gpointer data) -{ - guint timer_tag, beep_tag; - timer_tag = GPOINTER_TO_INT (gtk_object_get_data (object, "timer_tag")); - beep_tag = GPOINTER_TO_INT (gtk_object_get_data (object, "beep_tag")); - - if (beep_tag > 0) { - gtk_timeout_remove (beep_tag); - gtk_object_set_data (object, "beep_tag", GINT_TO_POINTER (0)); - } - if (timer_tag > 0) { - gtk_timeout_remove (timer_tag); - gtk_object_set_data (object, "timer_tag", GINT_TO_POINTER (0)); - } -} - -static gint -start_beeping (gpointer data) -{ - gdk_beep (); - - return TRUE; -} - -static gint -timeout_beep (gpointer data) -{ - stop_beeping (data, NULL); - return FALSE; -} - -void -calendar_notify (time_t activation_time, CalendarAlarm *which, void *data) -{ - iCalObject *ico = data; - guint beep_tag, timer_tag; - int ret; - gchar* snooze_button = (enable_snooze ? _("Snooze") : NULL); - time_t now, diff; - - if (&ico->aalarm == which){ - time_t app = ico->aalarm.trigger + ico->aalarm.offset; - GtkWidget *w; - char *msg; - - msg = g_strconcat (_("Reminder of your appointment at "), - ctime (&app), "`", - ico->summary, "'", NULL); - - /* Idea: we need Snooze option :-) */ - w = gnome_message_box_new (msg, GNOME_MESSAGE_BOX_INFO, _("Ok"), snooze_button, NULL); - beep_tag = gtk_timeout_add (1000, start_beeping, NULL); - if (enable_aalarm_timeout) - timer_tag = gtk_timeout_add (audio_alarm_timeout*1000, - timeout_beep, w); - else - timer_tag = 0; - gtk_object_set_data (GTK_OBJECT (w), "timer_tag", - GINT_TO_POINTER (timer_tag)); - gtk_object_set_data (GTK_OBJECT (w), "beep_tag", - GINT_TO_POINTER (beep_tag)); - gtk_widget_ref (w); - gtk_window_set_modal (GTK_WINDOW (w), FALSE); - ret = gnome_dialog_run (GNOME_DIALOG (w)); - switch (ret) { - case 1: - stop_beeping (GTK_OBJECT (w), NULL); - now = time (NULL); - diff = now - which->trigger; - which->trigger = which->trigger + diff + snooze_secs; - which->offset = which->offset - diff - snooze_secs; - alarm_add (which, &calendar_notify, data); - break; - default: - stop_beeping (GTK_OBJECT (w), NULL); - break; - } - - gtk_widget_unref (w); - return; - } - - if (&ico->palarm == which){ - execute (ico->palarm.data, 0); - return; - } - - if (&ico->malarm == which){ - time_t app = ico->malarm.trigger + ico->malarm.offset; - - mail_notify (ico->malarm.data, ico->summary, app); - return; - } - - if (&ico->dalarm == which){ - time_t app = ico->dalarm.trigger + ico->dalarm.offset; - GtkWidget *w; - char *msg; - - if (beep_on_display) - gdk_beep (); - msg = g_strconcat (_("Reminder of your appointment at "), - ctime (&app), "`", - ico->summary, "'", NULL); - w = gnome_message_box_new (msg, GNOME_MESSAGE_BOX_INFO, - _("Ok"), snooze_button, NULL); - gtk_window_set_modal (GTK_WINDOW (w), FALSE); - ret = gnome_dialog_run (GNOME_DIALOG (w)); - switch (ret) { - case 1: - now = time (NULL); - diff = now - which->trigger; - which->trigger = which->trigger + diff + snooze_secs; - which->offset = which->offset - diff - snooze_secs; - alarm_add (which, &calendar_notify, data); - break; - default: - break; - } - - return; - } -} - -#endif diff --git a/calendar/gui/alarm-notify/alarm-queue.h b/calendar/gui/alarm-notify/alarm-queue.h deleted file mode 100644 index 1f8871fb96..0000000000 --- a/calendar/gui/alarm-notify/alarm-queue.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Evolution calendar - Alarm queueing engine - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef ALARM_QUEUE_H -#define ALARM_QUEUE_H - -#include <cal-client/cal-client.h> - - -void alarm_queue_init (void); -void alarm_queue_done (void); - -void alarm_queue_add_client (CalClient *client); -void alarm_queue_remove_client (CalClient *client); - - -#endif diff --git a/calendar/gui/alarm-notify/alarm.c b/calendar/gui/alarm-notify/alarm.c deleted file mode 100644 index d32d8f1af9..0000000000 --- a/calendar/gui/alarm-notify/alarm.c +++ /dev/null @@ -1,357 +0,0 @@ -/* Evolution calendar - Low-level alarm timer mechanism - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Miguel de Icaza <miguel@ximian.com> - * Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#include <config.h> -#include <unistd.h> -#include <time.h> -#include <fcntl.h> -#include <signal.h> -#include <sys/time.h> -#include <gdk/gdk.h> -#include "alarm.h" - - - -/* Whether the timer system has been initialized */ -static gboolean alarm_inited; - -/* The pipes used to notify about an alarm */ -static int alarm_pipes [2]; - -/* The list of pending alarms */ -static GList *alarms; - -/* A queued alarm structure */ -typedef struct { - time_t trigger; - AlarmFunction alarm_fn; - gpointer data; - AlarmDestroyNotify destroy_notify_fn; -} AlarmRecord; - - - -/* SIGALRM handler. Notifies the callback about the alarm. */ -static void -alarm_signal (int arg) -{ - char c = 0; - - write (alarm_pipes [1], &c, 1); -} - -/* Sets up an itimer and returns a success code */ -static gboolean -setup_itimer (time_t diff) -{ - struct itimerval itimer; - int v; - - itimer.it_interval.tv_sec = 0; - itimer.it_interval.tv_usec = 0; - itimer.it_value.tv_sec = diff; - itimer.it_value.tv_usec = 0; - - v = setitimer (ITIMER_REAL, &itimer, NULL); - - return (v == 0) ? TRUE : FALSE; -} - -/* Clears the itimer we have pending */ -static gboolean -clear_itimer (void) -{ - return setup_itimer (0); -} - -/* Removes the head alarm, returns it, and schedules the next alarm in the - * queue. - */ -static AlarmRecord * -pop_alarm (void) -{ - AlarmRecord *ar; - GList *l; - - if (!alarms) - return NULL; - - ar = alarms->data; - - l = alarms; - alarms = g_list_remove_link (alarms, l); - g_list_free_1 (l); - - if (alarms) { - time_t now; - AlarmRecord *new_ar; - - now = time (NULL); - new_ar = alarms->data; - - if (!setup_itimer (new_ar->trigger - now)) { - g_message ("pop_alarm(): Could not reset the timer! " - "Weird things will happen."); - - /* FIXME: should we free the alarm list? What - * about further alarm removal requests that - * will fail? - */ - } - } else - if (!clear_itimer ()) - g_message ("pop_alarm(): Could not clear the timer! " - "Weird things may happen."); - - return ar; -} - -/* Input handler for our own alarm notification pipe */ -static void -alarm_ready (gpointer data, gint fd, GdkInputCondition cond) -{ - AlarmRecord *ar; - char c; - - if (read (alarm_pipes [0], &c, 1) != 1) { - g_message ("alarm_ready(): Uh? Could not read from notification pipe."); - return; - } - - g_assert (alarms != NULL); - ar = pop_alarm (); - - g_print ("alarm_ready(): Notifying about alarm on %s\n", ctime (&ar->trigger)); - - (* ar->alarm_fn) (ar, ar->trigger, ar->data); - - if (ar->destroy_notify_fn) - (* ar->destroy_notify_fn) (ar, ar->data); - - g_free (ar); -} - -static int -compare_alarm_by_time (gconstpointer a, gconstpointer b) -{ - const AlarmRecord *ara = a; - const AlarmRecord *arb = b; - time_t diff; - - diff = ara->trigger - arb->trigger; - return (diff < 0) ? -1 : (diff > 0) ? 1 : 0; -} - -/* Adds an alarm to the queue and sets up the timer */ -static gboolean -queue_alarm (time_t now, AlarmRecord *ar) -{ - time_t diff; - AlarmRecord *old_head; - - if (alarms) - old_head = alarms->data; - else - old_head = NULL; - - alarms = g_list_insert_sorted (alarms, ar, compare_alarm_by_time); - - if (old_head == alarms->data) - return TRUE; - - /* Set the timer for removal upon activation */ - - diff = ar->trigger - now; - if (!setup_itimer (diff)) { - GList *l; - - g_message ("queue_alarm(): Could not set up timer! Not queueing alarm."); - - l = g_list_find (alarms, ar); - g_assert (l != NULL); - - alarms = g_list_remove_link (alarms, l); - g_list_free_1 (l); - return FALSE; - } - - return TRUE; -} - -/** - * alarm_add: - * @trigger: Time at which alarm will trigger. - * @alarm_fn: Callback for trigger. - * @data: Closure data for callback. - * - * Adds an alarm to trigger at the specified time. The @alarm_fn will be called - * with the provided data and the alarm will be removed from the trigger list. - * - * Return value: An identifier for this alarm; it can be used to remove the - * alarm later with alarm_remove(). If the trigger time occurs in the past, then - * the alarm will not be queued and the function will return NULL. - **/ -gpointer -alarm_add (time_t trigger, AlarmFunction alarm_fn, gpointer data, - AlarmDestroyNotify destroy_notify_fn) -{ - time_t now; - AlarmRecord *ar; - - g_return_val_if_fail (alarm_inited, NULL); - g_return_val_if_fail (trigger != -1, NULL); - g_return_val_if_fail (alarm_fn != NULL, NULL); - - now = time (NULL); - if (trigger < now) - return NULL; - - ar = g_new (AlarmRecord, 1); - ar->trigger = trigger; - ar->alarm_fn = alarm_fn; - ar->data = data; - ar->destroy_notify_fn = destroy_notify_fn; - - g_print ("alarm_add(): Adding alarm for %s\n", ctime (&trigger)); - - if (!queue_alarm (now, ar)) { - g_free (ar); - ar = NULL; - } - - return ar; -} - -/** - * alarm_remove: - * @alarm: A queued alarm identifier. - * - * Removes an alarm from the alarm queue. - **/ -void -alarm_remove (gpointer alarm) -{ - AlarmRecord *ar; - AlarmRecord *old_head; - GList *l; - - g_return_if_fail (alarm_inited); - g_return_if_fail (alarm != NULL); - - ar = alarm; - - l = g_list_find (alarms, ar); - if (!l) { - g_message ("alarm_remove(): Requested removal of nonexistent alarm!"); - return; - } - - old_head = alarms->data; - - if (old_head == ar) - pop_alarm (); - else { - alarms = g_list_remove_link (alarms, l); - g_list_free_1 (l); - } - - if (ar->destroy_notify_fn) - (* ar->destroy_notify_fn) (ar, ar->data); - - g_free (ar); -} - -/** - * alarm_init: - * - * Initializes the alarm timer mechanism. This must be called near the - * beginning of the program. - **/ -void -alarm_init (void) -{ - struct sigaction sa; - int flags; - - g_return_if_fail (alarm_inited == FALSE); - - pipe (alarm_pipes); - - /* set non blocking mode */ - flags = 0; - fcntl (alarm_pipes [0], F_GETFL, &flags); - fcntl (alarm_pipes [0], F_SETFL, flags | O_NONBLOCK); - gdk_input_add (alarm_pipes [0], GDK_INPUT_READ, alarm_ready, NULL); - - /* Setup the signal handler */ - sa.sa_handler = alarm_signal; - sigemptyset (&sa.sa_mask); - sa.sa_flags = SA_RESTART; - sigaction (SIGALRM, &sa, NULL); - - alarm_inited = TRUE; -} - -/** - * alarm_done: - * - * Terminates the alarm timer mechanism. This should be called at the end of - * the program. - **/ -void -alarm_done (void) -{ - GList *l; - - g_return_if_fail (alarm_inited); - - if (!clear_itimer ()) - g_message ("alarm_done(): Could not clear the timer! " - "Weird things may happen."); - - for (l = alarms; l; l = l->next) { - AlarmRecord *ar; - - ar = l->data; - - if (ar->destroy_notify_fn) - (* ar->destroy_notify_fn) (ar, ar->data); - - g_free (ar); - } - - g_list_free (alarms); - alarms = NULL; - - if (close (alarm_pipes[0]) != 0) - g_message ("alarm_done(): Could not close the input pipe for notification"); - - alarm_pipes[0] = -1; - - if (close (alarm_pipes[1]) != 0) - g_message ("alarm_done(): Could not close the output pipe for notification"); - - alarm_pipes[1] = -1; - - alarm_inited = FALSE; -} diff --git a/calendar/gui/alarm-notify/alarm.h b/calendar/gui/alarm-notify/alarm.h deleted file mode 100644 index fc81908ef2..0000000000 --- a/calendar/gui/alarm-notify/alarm.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Evolution calendar - Low-level alarm timer mechanism - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Miguel de Icaza <miguel@ximian.com> - * Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef ALARM_H -#define ALARM_H - -#include <time.h> -#include <glib.h> - - - -typedef void (* AlarmFunction) (gpointer alarm_id, time_t trigger, gpointer data); -typedef void (* AlarmDestroyNotify) (gpointer alarm_id, gpointer data); - -void alarm_init (void); -void alarm_done (void); - -gpointer alarm_add (time_t trigger, AlarmFunction alarm_fn, gpointer data, - AlarmDestroyNotify destroy_notify_fn); -void alarm_remove (gpointer alarm); - - - -#endif diff --git a/calendar/gui/alarm-notify/notify-main.c b/calendar/gui/alarm-notify/notify-main.c deleted file mode 100644 index 6712865725..0000000000 --- a/calendar/gui/alarm-notify/notify-main.c +++ /dev/null @@ -1,82 +0,0 @@ -/* Evolution calendar - Alarm notification service main file - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <gnome.h> -#include <bonobo.h> -#include <liboaf/liboaf.h> -#include "alarm-notify.h" - - - -static BonoboGenericFactory *factory; - -static AlarmNotify *alarm_notify_service; - - -/* Factory function for the alarm notify service; just creates and references a - * singleton service object. - */ -static BonoboObject * -alarm_notify_factory_fn (BonoboGenericFactory *factory, void *data) -{ - if (!alarm_notify_service) { - alarm_notify_service = alarm_notify_new (); - if (!alarm_notify_service) - return NULL; - } - - bonobo_object_ref (BONOBO_OBJECT (alarm_notify_service)); - return BONOBO_OBJECT (alarm_notify_service); -} - -int -main (int argc, char **argv) -{ - - bindtextdomain (PACKAGE, EVOLUTION_LOCALEDIR); - textdomain (PACKAGE); - - if (gnome_init_with_popt_table ("evolution-alarm-notify", VERSION, argc, argv, - oaf_popt_options, 0, NULL) != 0) - g_error (_("Could not initialize GNOME")); - - oaf_init (argc, argv); - - if (bonobo_init (CORBA_OBJECT_NIL, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL) == FALSE) - g_error (_("Could not initialize Bonobo")); - - factory = bonobo_generic_factory_new ("OAFID:GNOME_Evolution_Calendar_AlarmNotify_Factory", - alarm_notify_factory_fn, NULL); - if (!factory) - g_error (_("Could not create the alarm notify service factory")); - - bonobo_main (); - - bonobo_object_unref (BONOBO_OBJECT (factory)); - factory = NULL; - - return 0; -} diff --git a/calendar/gui/alarm.c b/calendar/gui/alarm.c deleted file mode 100644 index a0fe90f337..0000000000 --- a/calendar/gui/alarm.c +++ /dev/null @@ -1,356 +0,0 @@ -/* Evolution calendar - Low-level alarm timer mechanism - * - * Copyright (C) 2000 Helix Code, Inc. - * - * Authors: Miguel de Icaza <miguel@helixcode.com> - * Federico Mena-Quintero <federico@helixcode.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#include <config.h> -#include <unistd.h> -#include <time.h> -#include <fcntl.h> -#include <signal.h> -#include <sys/time.h> -#include <gdk/gdk.h> -#include "alarm.h" - - - -/* Whether the timer system has been initialized */ -static gboolean alarm_inited; - -/* The pipes used to notify about an alarm */ -static int alarm_pipes [2]; - -/* The list of pending alarms */ -static GList *alarms; - -/* A queued alarm structure */ -typedef struct { - time_t trigger; - AlarmFunction alarm_fn; - gpointer data; - AlarmDestroyNotify destroy_notify_fn; -} AlarmRecord; - - - -/* SIGALRM handler. Notifies the callback about the alarm. */ -static void -alarm_signal (int arg) -{ - char c = 0; - - write (alarm_pipes [1], &c, 1); -} - -/* Sets up an itimer and returns a success code */ -static gboolean -setup_itimer (time_t diff) -{ - struct itimerval itimer; - int v; - - itimer.it_interval.tv_sec = 0; - itimer.it_interval.tv_usec = 0; - itimer.it_value.tv_sec = diff; - itimer.it_value.tv_usec = 0; - - v = setitimer (ITIMER_REAL, &itimer, NULL); - - return (v == 0) ? TRUE : FALSE; -} - -/* Clears the itimer we have pending */ -static gboolean -clear_itimer (void) -{ - return setup_itimer (0); -} - -/* Removes the head alarm, returns it, and schedules the next alarm in the - * queue. - */ -static AlarmRecord * -pop_alarm (void) -{ - AlarmRecord *ar; - GList *l; - - if (!alarms) - return NULL; - - ar = alarms->data; - - l = alarms; - alarms = g_list_remove_link (alarms, l); - g_list_free_1 (l); - - if (alarms) { - time_t now; - AlarmRecord *new_ar; - - now = time (NULL); - new_ar = alarms->data; - - if (!setup_itimer (new_ar->trigger - now)) { - g_message ("pop_alarm(): Could not reset the timer! " - "Weird things will happen."); - - /* FIXME: should we free the alarm list? What - * about further alarm removal requests that - * will fail? - */ - } - } else - if (!clear_itimer ()) - g_message ("pop_alarm(): Could not clear the timer! " - "Weird things may happen."); - - return ar; -} - -/* Input handler for our own alarm notification pipe */ -static void -alarm_ready (gpointer data, gint fd, GdkInputCondition cond) -{ - AlarmRecord *ar; - char c; - - if (read (alarm_pipes [0], &c, 1) != 1) { - g_message ("alarm_ready(): Uh? Could not read from notification pipe."); - return; - } - - g_assert (alarms != NULL); - ar = pop_alarm (); - - g_print ("alarm_ready(): Notifying about alarm on %s\n", ctime (&ar->trigger)); - - (* ar->alarm_fn) (ar, ar->trigger, ar->data); - - if (ar->destroy_notify_fn) - (* ar->destroy_notify_fn) (ar, ar->data); - - g_free (ar); -} - -static int -compare_alarm_by_time (gconstpointer a, gconstpointer b) -{ - const AlarmRecord *ara = a; - const AlarmRecord *arb = b; - time_t diff; - - diff = ara->trigger - arb->trigger; - return (diff < 0) ? -1 : (diff > 0) ? 1 : 0; -} - -/* Adds an alarm to the queue and sets up the timer */ -static gboolean -queue_alarm (time_t now, AlarmRecord *ar) -{ - time_t diff; - AlarmRecord *old_head; - - if (alarms) - old_head = alarms->data; - else - old_head = NULL; - - alarms = g_list_insert_sorted (alarms, ar, compare_alarm_by_time); - - if (old_head == alarms->data) - return TRUE; - - /* Set the timer for removal upon activation */ - - diff = ar->trigger - now; - if (!setup_itimer (diff)) { - GList *l; - - g_message ("queue_alarm(): Could not set up timer! Not queueing alarm."); - - l = g_list_find (alarms, ar); - g_assert (l != NULL); - - alarms = g_list_remove_link (alarms, l); - g_list_free_1 (l); - return FALSE; - } - - return TRUE; -} - -/** - * alarm_add: - * @trigger: Time at which alarm will trigger. - * @alarm_fn: Callback for trigger. - * @data: Closure data for callback. - * - * Adds an alarm to trigger at the specified time. The @alarm_fn will be called - * with the provided data and the alarm will be removed from the trigger list. - * - * Return value: An identifier for this alarm; it can be used to remove the - * alarm later with alarm_remove(). If the trigger time occurs in the past, then - * the alarm will not be queued and the function will return NULL. - **/ -gpointer -alarm_add (time_t trigger, AlarmFunction alarm_fn, gpointer data, - AlarmDestroyNotify destroy_notify_fn) -{ - time_t now; - AlarmRecord *ar; - - g_return_val_if_fail (alarm_inited, NULL); - g_return_val_if_fail (trigger != -1, NULL); - g_return_val_if_fail (alarm_fn != NULL, NULL); - - now = time (NULL); - if (trigger < now) - return NULL; - - ar = g_new (AlarmRecord, 1); - ar->trigger = trigger; - ar->alarm_fn = alarm_fn; - ar->data = data; - ar->destroy_notify_fn = destroy_notify_fn; - - g_print ("alarm_add(): Adding alarm for %s\n", ctime (&trigger)); - - if (!queue_alarm (now, ar)) { - g_free (ar); - ar = NULL; - } - - return ar; -} - -/** - * alarm_remove: - * @alarm: A queued alarm identifier. - * - * Removes an alarm from the alarm queue. - **/ -void -alarm_remove (gpointer alarm) -{ - AlarmRecord *ar; - AlarmRecord *old_head; - GList *l; - - g_return_if_fail (alarm_inited); - g_return_if_fail (alarm != NULL); - - ar = alarm; - - l = g_list_find (alarms, ar); - if (!l) { - g_message ("alarm_remove(): Requested removal of nonexistent alarm!"); - return; - } - - old_head = alarms->data; - - if (old_head == ar) - pop_alarm (); - else { - alarms = g_list_remove_link (alarms, l); - g_list_free_1 (l); - } - - if (ar->destroy_notify_fn) - (* ar->destroy_notify_fn) (ar, ar->data); - - g_free (ar); -} - -/** - * alarm_init: - * - * Initializes the alarm timer mechanism. This must be called near the - * beginning of the program. - **/ -void -alarm_init (void) -{ - struct sigaction sa; - int flags; - - g_return_if_fail (alarm_inited == FALSE); - - pipe (alarm_pipes); - - /* set non blocking mode */ - flags = 0; - fcntl (alarm_pipes [0], F_GETFL, &flags); - fcntl (alarm_pipes [0], F_SETFL, flags | O_NONBLOCK); - gdk_input_add (alarm_pipes [0], GDK_INPUT_READ, alarm_ready, NULL); - - /* Setup the signal handler */ - sa.sa_handler = alarm_signal; - sigemptyset (&sa.sa_mask); - sa.sa_flags = SA_RESTART; - sigaction (SIGALRM, &sa, NULL); - - alarm_inited = TRUE; -} - -/** - * alarm_done: - * - * Terminates the alarm timer mechanism. This should be called at the end of - * the program. - **/ -void -alarm_done (void) -{ - GList *l; - - g_return_if_fail (alarm_inited); - - if (!clear_itimer ()) - g_message ("alarm_done(): Could not clear the timer! " - "Weird things may happen."); - - for (l = alarms; l; l = l->next) { - AlarmRecord *ar; - - ar = l->data; - - if (ar->destroy_notify_fn) - (* ar->destroy_notify_fn) (ar, ar->data); - - g_free (ar); - } - - g_list_free (alarms); - alarms = NULL; - - if (close (alarm_pipes[0]) != 0) - g_message ("alarm_done(): Could not close the input pipe for notification"); - - alarm_pipes[0] = -1; - - if (close (alarm_pipes[1]) != 0) - g_message ("alarm_done(): Could not close the output pipe for notification"); - - alarm_pipes[1] = -1; - - alarm_inited = FALSE; -} diff --git a/calendar/gui/alarm.h b/calendar/gui/alarm.h deleted file mode 100644 index afa79edfd8..0000000000 --- a/calendar/gui/alarm.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Evolution calendar - Low-level alarm timer mechanism - * - * Copyright (C) 2000 Helix Code, Inc. - * - * Authors: Miguel de Icaza <miguel@helixcode.com> - * Federico Mena-Quintero <federico@helixcode.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef ALARM_H -#define ALARM_H - -#include <time.h> -#include <glib.h> - - - -typedef void (* AlarmFunction) (gpointer alarm_id, time_t trigger, gpointer data); -typedef void (* AlarmDestroyNotify) (gpointer alarm_id, gpointer data); - -void alarm_init (void); -void alarm_done (void); - -gpointer alarm_add (time_t trigger, AlarmFunction alarm_fn, gpointer data, - AlarmDestroyNotify destroy_notify_fn); -void alarm_remove (gpointer alarm); - - - -#endif diff --git a/calendar/gui/bell.xpm b/calendar/gui/bell.xpm deleted file mode 100644 index b1ab537a17..0000000000 --- a/calendar/gui/bell.xpm +++ /dev/null @@ -1,83 +0,0 @@ -/* XPM */ -static char * bell_xpm[] = { -"16 16 64 1", -" c None", -". c #000000", -"+ c #E3BB43", -"@ c #E6C049", -"# c #EED275", -"$ c #F4E193", -"% c #F4DF8C", -"& c #EAC95C", -"* c #EFD57A", -"= c #FAEFBB", -"- c #FDF6D3", -"; c #FDF5C6", -"> c #F4E18F", -", c #E4BD43", -"' c #F6E295", -") c #FEF9D8", -"! c #FFFFFF", -"~ c #FFFADA", -"{ c #FCEEAA", -"] c #EBCA5A", -"^ c #E9C550", -"/ c #FAEA9C", -"( c #FEF7CB", -"_ c #FFF8CC", -": c #FDF1A8", -"< c #EED060", -"[ c #D39D12", -"} c #F2D55D", -"| c #FCEC91", -"1 c #FFF4AE", -"2 c #FFF5B6", -"3 c #FEEF97", -"4 c #F3D65E", -"5 c #D5A216", -"6 c #FAE05C", -"7 c #FFED7C", -"8 c #FFEF8C", -"9 c #FFF092", -"0 c #FDEB7A", -"a c #F4D750", -"b c #D8A717", -"c c #EAC01D", -"d c #F6D83E", -"e c #FAE255", -"f c #FAE362", -"g c #F9E161", -"h c #F6DE5B", -"i c #F1D145", -"j c #E6BE28", -"k c #D09B09", -"l c #B67E00", -"m c #CE9100", -"n c #D69F04", -"o c #E0B011", -"p c #E6BA1D", -"q c #E3B721", -"r c #E0B21E", -"s c #DCAB16", -"t c #D7A20D", -"u c #CC9303", -"v c #BE8400", -"w c #AC7500", -"x c #A06B00", -"y c #FFDD00", -" ", -" .. ", -" .+@. ", -" .#$%&. ", -" .*=-;>,. ", -" .')!~{]. ", -" .^/(~_:<[. ", -" .}|121345. ", -" .678980ab. ", -" .cdefghijkl. ", -" .mnopqrstuvwx. ", -" .............. ", -" .8y. ", -" .. ", -" ", -" "}; diff --git a/calendar/gui/calendar-commands.c b/calendar/gui/calendar-commands.c deleted file mode 100644 index 29557e2d68..0000000000 --- a/calendar/gui/calendar-commands.c +++ /dev/null @@ -1,462 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Evolution calendar - Commands for the calendar GUI control - * - * Copyright (C) 1998 The Free Software Foundation - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Miguel de Icaza <miguel@ximian.com> - * Federico Mena-Quintero <federico@ximian.com> - * Seth Alves <alves@hungry.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#include <config.h> -#include <pwd.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <string.h> -#include <ctype.h> -#include <errno.h> -#include <glib.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <libgnomeui/gnome-messagebox.h> -#include <libgnorba/gnorba.h> -#include <bonobo.h> -#include <cal-util/timeutil.h> -#include "calendar-commands.h" -#include "gnome-cal.h" -#include "goto.h" -#include "print.h" -#include "dialogs/cal-prefs-dialog.h" - - -/* A list of all of the calendars started */ -static GList *all_calendars = NULL; - -/* We have one global preferences dialog. */ -static CalPrefsDialog *preferences_dialog = NULL; - -/* Callback for the new appointment command */ -static void -new_appointment_cb (BonoboUIComponent *uic, gpointer data, const char *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - gnome_calendar_new_appointment (gcal); -} - -/* Prints the calendar at its current view and time range */ -static void -print (GnomeCalendar *gcal, gboolean preview) -{ - time_t start; - const char *view; - PrintView print_view; - - gnome_calendar_get_current_time_range (gcal, &start, NULL); - view = gnome_calendar_get_current_view_name (gcal); - - if (strcmp (view, "dayview") == 0) - print_view = PRINT_VIEW_DAY; - else if (strcmp (view, "workweekview") == 0 || strcmp (view, "weekview") == 0) - print_view = PRINT_VIEW_WEEK; - else if (strcmp (view, "monthview") == 0) - print_view = PRINT_VIEW_MONTH; - else { - g_assert_not_reached (); - print_view = PRINT_VIEW_DAY; - } - - print_calendar (gcal, preview, start, print_view); -} - -/* File/Print callback */ -static void -file_print_cb (BonoboUIComponent *uic, gpointer data, const char *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - print (gcal, FALSE); -} - - -/* This iterates over each calendar telling them to update their config - settings. */ -void -update_all_config_settings (void) -{ - GList *l; - - for (l = all_calendars; l; l = l->next) - gnome_calendar_update_config_settings (GNOME_CALENDAR (l->data), FALSE); -} - - -/* Sets a clock cursor for the specified calendar window */ -static void -set_clock_cursor (GnomeCalendar *gcal) -{ - GdkCursor *cursor; - - cursor = gdk_cursor_new (GDK_WATCH); - gdk_window_set_cursor (GTK_WIDGET (gcal)->window, cursor); - gdk_cursor_destroy (cursor); - gdk_flush (); -} - -/* Resets the normal cursor for the specified calendar window */ -static void -set_normal_cursor (GnomeCalendar *gcal) -{ - gdk_window_set_cursor (GTK_WIDGET (gcal)->window, NULL); - gdk_flush (); -} - -static void -previous_clicked (BonoboUIComponent *uic, gpointer data, const char *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - set_clock_cursor (gcal); - gnome_calendar_previous (gcal); - set_normal_cursor (gcal); -} - -static void -next_clicked (BonoboUIComponent *uic, gpointer data, const char *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - set_clock_cursor (gcal); - gnome_calendar_next (gcal); - set_normal_cursor (gcal); -} - -static void -today_clicked (BonoboUIComponent *uic, gpointer data, const char *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - set_clock_cursor (gcal); - gnome_calendar_goto_today (gcal); - set_normal_cursor (gcal); -} - -static void -goto_clicked (BonoboUIComponent *uic, gpointer data, const char *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - goto_dialog (gcal); -} - -static void -show_day_view_clicked (BonoboUIComponent *uic, gpointer data, const char *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - gnome_calendar_set_view (gcal, "dayview", FALSE, TRUE); -} - -static void -show_work_week_view_clicked (BonoboUIComponent *uic, gpointer data, const char *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - gnome_calendar_set_view (gcal, "workweekview", FALSE, TRUE); -} - -static void -show_week_view_clicked (BonoboUIComponent *uic, gpointer data, const char *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - gnome_calendar_set_view (gcal, "weekview", FALSE, TRUE); -} - -static void -show_month_view_clicked (BonoboUIComponent *uic, gpointer data, const char *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - gnome_calendar_set_view (gcal, "monthview", FALSE, TRUE); -} - - -static void -new_calendar_cmd (BonoboUIComponent *uic, gpointer data, const char *path) -{ - new_calendar (); -} - -static void -open_ok (GtkWidget *widget, GtkFileSelection *fs) -{ - GtkWidget *error_dialog; - int ret; - if(!g_file_exists (gtk_file_selection_get_filename (fs))) { - error_dialog = gnome_message_box_new ( - _("File not found"), - GNOME_MESSAGE_BOX_ERROR, - GNOME_STOCK_BUTTON_OK, - NULL); - - gnome_dialog_set_parent (GNOME_DIALOG (error_dialog), GTK_WINDOW (fs)); - ret = gnome_dialog_run (GNOME_DIALOG (error_dialog)); - } else { - /* FIXME: find out who owns this calendar and use that name */ -#ifndef NO_WARNINGS -#warning "FIXME: find out who owns this calendar and use that name" -#endif - /* - new_calendar ("Somebody", gtk_file_selection_get_filename (fs)); - */ - gtk_widget_destroy (GTK_WIDGET (fs)); - } -} - -static void -open_calendar_cmd (BonoboUIComponent *uic, gpointer data, const char *path) -{ - GtkFileSelection *fs; - - fs = GTK_FILE_SELECTION (gtk_file_selection_new (_("Open calendar"))); - - gtk_signal_connect (GTK_OBJECT (fs->ok_button), "clicked", - (GtkSignalFunc) open_ok, - fs); - gtk_signal_connect_object (GTK_OBJECT (fs->cancel_button), "clicked", - (GtkSignalFunc) gtk_widget_destroy, - GTK_OBJECT (fs)); - - gtk_widget_show (GTK_WIDGET (fs)); - gtk_grab_add (GTK_WIDGET (fs)); /* Yes, it is modal, so sue me */ -} - -static void -save_ok (GtkWidget *widget, GtkFileSelection *fs) -{ - GnomeCalendar *gcal; - gchar *fname; - - gcal = GNOME_CALENDAR (gtk_object_get_user_data (GTK_OBJECT (fs))); - gtk_window_set_wmclass (GTK_WINDOW (gcal), "gnomecal", "gnomecal"); - - fname = g_strdup (gtk_file_selection_get_filename (fs)); - g_free(fname); - gtk_main_quit (); -} - -static gint -close_save (GtkWidget *w) -{ - gtk_main_quit (); - return TRUE; -} - -static void -save_as_calendar_cmd (BonoboUIComponent *uic, gpointer data, const char *path) -{ - GnomeCalendar *gcal; - GtkFileSelection *fs; - - gcal = GNOME_CALENDAR (data); - - fs = GTK_FILE_SELECTION (gtk_file_selection_new (_("Save calendar"))); - gtk_object_set_user_data (GTK_OBJECT (fs), gcal); - - gtk_signal_connect (GTK_OBJECT (fs->ok_button), "clicked", - (GtkSignalFunc) save_ok, - fs); - gtk_signal_connect_object (GTK_OBJECT (fs->cancel_button), "clicked", - (GtkSignalFunc) close_save, - GTK_OBJECT (fs)); - gtk_signal_connect_object (GTK_OBJECT (fs), "delete_event", - GTK_SIGNAL_FUNC (close_save), - GTK_OBJECT (fs)); - gtk_widget_show (GTK_WIDGET (fs)); - gtk_grab_add (GTK_WIDGET (fs)); /* Yes, it is modal, so sue me even more */ - gtk_main (); - gtk_widget_destroy (GTK_WIDGET (fs)); -} - -static void -properties_cmd (BonoboUIComponent *uic, gpointer data, const char *path) -{ - if (!preferences_dialog) - preferences_dialog = cal_prefs_dialog_new (); - else - cal_prefs_dialog_show (preferences_dialog); -} - - -static BonoboUIVerb verbs [] = { - BONOBO_UI_VERB ("CalendarNew", new_calendar_cmd), - BONOBO_UI_VERB ("CalendarOpen", open_calendar_cmd), - BONOBO_UI_VERB ("CalendarSaveAs", save_as_calendar_cmd), - BONOBO_UI_VERB ("CalendarPrint", file_print_cb), - BONOBO_UI_VERB ("EditNewAppointment", new_appointment_cb), - BONOBO_UI_VERB ("CalendarPreferences", properties_cmd), - - BONOBO_UI_VERB ("CalendarPrev", previous_clicked), - BONOBO_UI_VERB ("CalendarToday", today_clicked), - BONOBO_UI_VERB ("CalendarNext", next_clicked), - BONOBO_UI_VERB ("CalendarGoto", goto_clicked), - - BONOBO_UI_VERB ("ShowDayView", show_day_view_clicked), - BONOBO_UI_VERB ("ShowWorkWeekView", show_work_week_view_clicked), - BONOBO_UI_VERB ("ShowWeekView", show_week_view_clicked), - BONOBO_UI_VERB ("ShowMonthView", show_month_view_clicked), - - BONOBO_UI_VERB_END -}; - -static void -set_pixmap (BonoboUIComponent *uic, - const char *xml_path, - const char *icon) -{ - char *path; - GdkPixbuf *pixbuf; - - path = g_concat_dir_and_file (EVOLUTION_DATADIR "/images/evolution", icon); - - pixbuf = gdk_pixbuf_new_from_file (path); - if (pixbuf == NULL) { - g_warning ("Cannot load image -- %s", path); - g_free (path); - return; - } - - bonobo_ui_util_set_pixbuf (uic, xml_path, pixbuf); - - gdk_pixbuf_unref (pixbuf); - - g_free (path); -} - -static void -update_pixmaps (BonoboUIComponent *uic) -{ - set_pixmap (uic, "/Toolbar/New", "buttons/new_appointment.png"); - - set_pixmap (uic, "/Toolbar/DayView", "buttons/dayview.xpm"); - set_pixmap (uic, "/Toolbar/WorkWeekView", "buttons/workweekview.xpm"); - set_pixmap (uic, "/Toolbar/WeekView", "buttons/weekview.xpm"); - set_pixmap (uic, "/Toolbar/MonthView", "buttons/monthview.xpm"); -} - -void -calendar_control_activate (BonoboControl *control, - GnomeCalendar *cal) -{ - Bonobo_UIContainer remote_uih; - BonoboUIComponent *uic; - - uic = bonobo_control_get_ui_component (control); - g_assert (uic != NULL); - - remote_uih = bonobo_control_get_remote_ui_container (control); - bonobo_ui_component_set_container (uic, remote_uih); - bonobo_object_release_unref (remote_uih, NULL); - -#if 0 - /* FIXME: Need to update this to use new Bonobo ui stuff somehow. - Also need radio buttons really. */ - - /* Note that these indices should correspond with the button indices - in the gnome_toolbar_view_buttons UIINFO struct. */ - gnome_calendar_set_view_buttons (cal, - gnome_toolbar_view_buttons[0].widget, - gnome_toolbar_view_buttons[1].widget, - gnome_toolbar_view_buttons[2].widget, - gnome_toolbar_view_buttons[3].widget); - - /* This makes the appropriate radio button in the toolbar active. */ - gnome_calendar_update_view_buttons (cal); -#endif - - bonobo_ui_component_add_verb_list_with_data ( - uic, verbs, cal); - - bonobo_ui_component_freeze (uic, NULL); - - bonobo_ui_util_set_ui (uic, EVOLUTION_DATADIR, - "evolution-calendar.xml", - "evolution-calendar"); - - update_pixmaps (uic); - - bonobo_ui_component_thaw (uic, NULL); -} - -void -calendar_control_deactivate (BonoboControl *control) -{ - BonoboUIComponent *uic = bonobo_control_get_ui_component (control); - g_assert (uic != NULL); - - bonobo_ui_component_rm (uic, "/", NULL); - bonobo_ui_component_unset_container (uic); -} - -GnomeCalendar * -new_calendar (void) -{ - GtkWidget *gcal; - - gcal = gnome_calendar_new (); - if (!gcal) { - gnome_warning_dialog (_("Could not create the calendar view. Please check your " - "ORBit and OAF setup.")); - return NULL; - } - - all_calendars = g_list_prepend (all_calendars, gcal); - - return GNOME_CALENDAR (gcal); -} - - -void -calendar_set_uri (GnomeCalendar *gcal, char *calendar_file) -{ - g_return_if_fail (gcal); - g_return_if_fail (calendar_file); - - gnome_calendar_open (gcal, calendar_file); -} diff --git a/calendar/gui/calendar-commands.h b/calendar/gui/calendar-commands.h deleted file mode 100644 index 364051e3a3..0000000000 --- a/calendar/gui/calendar-commands.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Evolution calendar - Commands for the calendar GUI control - * - * Copyright (C) 1998 The Free Software Foundation - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Miguel de Icaza <miguel@ximian.com> - * Federico Mena-Quintero <federico@ximian.com> - * Seth Alves <alves@hungry.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef CALENDAR_COMMANDS_H -#define CALENDAR_COMMANDS_H - -#include <bonobo/bonobo-control.h> -#include "gnome-cal.h" - -/* This tells all the calendars to reload the config settings. */ -void update_all_config_settings (void); - -GnomeCalendar *new_calendar (void); - -void calendar_set_uri (GnomeCalendar *gcal, char *calendar_file); - -void calendar_control_activate (BonoboControl *control, - GnomeCalendar *cal); -void calendar_control_deactivate (BonoboControl *control); - -#endif /* CALENDAR_COMMANDS_H */ diff --git a/calendar/gui/calendar-component.c b/calendar/gui/calendar-component.c deleted file mode 100644 index 5226c2480d..0000000000 --- a/calendar/gui/calendar-component.c +++ /dev/null @@ -1,175 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* component-factory.c - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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: Ettore Perazzoli <ettore@ximian.com> - */ - -#include <config.h> -#include <bonobo.h> -#include "evolution-shell-component.h" -#include <executive-summary/evolution-services/executive-summary-component.h> -#include "component-factory.h" -#include "tasks-control-factory.h" -#include "control-factory.h" -#include "calendar-config.h" -#include "calendar-summary.h" -#include "tasks-control.h" -#include "tasks-migrate.h" - - - -#define COMPONENT_FACTORY_ID "OAFIID:GNOME_Evolution_Calendar_ShellComponentFactory" - -static BonoboGenericFactory *factory = NULL; -static BonoboGenericFactory *summary_factory = NULL; -char *evolution_dir; - -static const EvolutionShellComponentFolderType folder_types[] = { - { "calendar", "evolution-calendar.png" }, - { "tasks", "evolution-tasks.png" }, - { NULL, NULL } -}; - - -/* EvolutionShellComponent methods and signals. */ - -static EvolutionShellComponentResult -create_view (EvolutionShellComponent *shell_component, - const char *physical_uri, - const char *type, - BonoboControl **control_return, - void *closure) -{ - BonoboControl *control; - - if (!g_strcasecmp (type, "calendar")) { - control = control_factory_new_control (); - if (!control) - return EVOLUTION_SHELL_COMPONENT_CORBAERROR; - } else if (!g_strcasecmp (type, "tasks")) { - control = tasks_control_new (); - if (!control) - return EVOLUTION_SHELL_COMPONENT_CORBAERROR; - } else { - return EVOLUTION_SHELL_COMPONENT_UNSUPPORTEDTYPE; - } - - bonobo_control_set_property (control, "folder_uri", physical_uri, NULL); - - *control_return = control; - - return EVOLUTION_SHELL_COMPONENT_OK; -} - -static void -create_folder (EvolutionShellComponent *shell_component, - const char *physical_uri, - const char *type, - const GNOME_Evolution_ShellComponentListener listener, - void *closure) -{ - CORBA_Environment ev; - - CORBA_exception_init(&ev); - /* FIXME: I don't think we have to do anything to create a calendar - or tasks folder - the '.ics' files are created automatically when - needed. But I'm not sure - Damon. */ - if (!strcmp(type, "calendar") || !strcmp(type, "tasks")) { - GNOME_Evolution_ShellComponentListener_notifyResult(listener, GNOME_Evolution_ShellComponentListener_OK, &ev); - } else { - GNOME_Evolution_ShellComponentListener_notifyResult(listener, GNOME_Evolution_ShellComponentListener_UNSUPPORTED_TYPE, &ev); - } - CORBA_exception_free(&ev); -} - -static gint owner_count = 0; - -static void -owner_set_cb (EvolutionShellComponent *shell_component, - EvolutionShellClient *shell_client, - const char *evolution_homedir, - gpointer user_data) -{ - static gboolean migrated = FALSE; - - owner_count ++; - evolution_dir = g_strdup (evolution_homedir); - - calendar_config_init (); - - if (!migrated) { - tasks_migrate (); - migrated = TRUE; - } -} - -static void -owner_unset_cb (EvolutionShellComponent *shell_component, - gpointer user_data) -{ - owner_count --; - if (owner_count <= 0) - gtk_main_quit(); -} - - -/* The factory function. */ - -static BonoboObject * -factory_fn (BonoboGenericFactory *factory, - void *closure) -{ - EvolutionShellComponent *shell_component; - - shell_component = evolution_shell_component_new (folder_types, - create_view, - create_folder, - NULL, /* remove_folder_fn */ - NULL, /* copy_folder_fn */ - NULL, /* populate_folder_context_menu_fn */ - NULL /* closure */); - - gtk_signal_connect (GTK_OBJECT (shell_component), "owner_set", - GTK_SIGNAL_FUNC (owner_set_cb), NULL); - gtk_signal_connect (GTK_OBJECT (shell_component), "owner_unset", - GTK_SIGNAL_FUNC (owner_unset_cb), NULL); - - return BONOBO_OBJECT (shell_component); -} - - - -void -component_factory_init (void) -{ - if (factory != NULL && factory != NULL) - return; - - factory = bonobo_generic_factory_new (COMPONENT_FACTORY_ID, factory_fn, NULL); - - summary_factory = calendar_summary_factory_init (); - - if (factory == NULL) - g_error ("Cannot initialize Evolution's calendar component."); - - if (summary_factory == NULL) - g_error ("Cannot initialize Evolution's calendar summary component."); -} diff --git a/calendar/gui/calendar-component.h b/calendar/gui/calendar-component.h deleted file mode 100644 index d2d570e340..0000000000 --- a/calendar/gui/calendar-component.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* component-factory.h - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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: Ettore Perazzoli <ettore@ximian.com> - */ - -#ifndef _COMPONENT_FACTORY_H_ -#define _COMPONENT_FACTORY_H_ - -extern char *evolution_dir; - -void component_factory_init (void); - -#endif /* _COMPONENT_FACTORY_H_ */ diff --git a/calendar/gui/calendar-config.c b/calendar/gui/calendar-config.c deleted file mode 100644 index 08579182fe..0000000000 --- a/calendar/gui/calendar-config.c +++ /dev/null @@ -1,478 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 2000, Helix Code, Inc. - * Copyright 2000, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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 - */ - -/* - * calendar-config.c - functions to load/save/get/set user settings. - */ - -#include <config.h> -#include "component-factory.h" -#include "calendar-config.h" - - -typedef struct -{ - CalWeekdays working_days; - gboolean use_24_hour_format; - gint week_start_day; - gint day_start_hour; - gint day_start_minute; - gint day_end_hour; - gint day_end_minute; - gint time_divisions; - gboolean dnav_show_week_no; - gint view; - gfloat hpane_pos; - gfloat vpane_pos; - gfloat month_hpane_pos; - gfloat month_vpane_pos; - gboolean compress_weekend; - gboolean show_event_end; -} CalendarConfig; - - -static CalendarConfig *config = NULL; - -static void config_read (void); - - -void -calendar_config_init (void) -{ - if (config) - return; - - config = g_new0 (CalendarConfig, 1); - - config_read (); -} - - -static void -config_read (void) -{ - gchar *prefix; - gboolean is_default; - - /* 'Display' settings. */ - prefix = g_strdup_printf ("=%s/config/Calendar=/Display/", - evolution_dir); - gnome_config_push_prefix (prefix); - g_free (prefix); - - config->working_days = gnome_config_get_int_with_default ("WorkingDays", &is_default); - if (is_default) { - config->working_days = CAL_MONDAY | CAL_TUESDAY - | CAL_WEDNESDAY | CAL_THURSDAY | CAL_FRIDAY; - } - config->use_24_hour_format = gnome_config_get_bool ("Use24HourFormat=0"); - config->week_start_day = gnome_config_get_int ("WeekStartDay=1"); - config->day_start_hour = gnome_config_get_int ("DayStartHour=9"); - config->day_start_minute = gnome_config_get_int ("DayStartMinute=0"); - config->day_end_hour = gnome_config_get_int ("DayEndHour=17"); - config->day_end_minute = gnome_config_get_int ("DayEndMinute=0"); - config->time_divisions = gnome_config_get_int ("TimeDivisions=30"); - config->view = gnome_config_get_int ("View=0"); - config->hpane_pos = gnome_config_get_float ("HPanePosition=1"); - config->vpane_pos = gnome_config_get_float ("VPanePosition=1"); - config->month_hpane_pos = gnome_config_get_float ("MonthHPanePosition=0"); - config->month_vpane_pos = gnome_config_get_float ("MonthVPanePosition=1"); - config->compress_weekend = gnome_config_get_bool ("CompressWeekend=1"); - config->show_event_end = gnome_config_get_bool ("ShowEventEndTime=1"); - - gnome_config_pop_prefix (); - - - /* 'DateNavigator' settings. */ - prefix = g_strdup_printf ("=%s/config/Calendar=/DateNavigator/", - evolution_dir); - gnome_config_push_prefix (prefix); - g_free (prefix); - - config->dnav_show_week_no = gnome_config_get_bool ("ShowWeekNumbers=0"); - - gnome_config_pop_prefix (); - - - gnome_config_sync (); -} - - -void -calendar_config_write (void) -{ - gchar *prefix; - - /* 'Display' settings. */ - prefix = g_strdup_printf ("=%s/config/Calendar=/Display/", - evolution_dir); - gnome_config_push_prefix (prefix); - g_free (prefix); - - gnome_config_set_int ("WorkingDays", config->working_days); - gnome_config_set_bool ("Use24HourFormat", config->use_24_hour_format); - gnome_config_set_int ("WeekStartDay", config->week_start_day); - gnome_config_set_int ("DayStartHour", config->day_start_hour); - gnome_config_set_int ("DayStartMinute", config->day_start_minute); - gnome_config_set_int ("DayEndHour", config->day_end_hour); - gnome_config_set_int ("DayEndMinute", config->day_end_minute); - gnome_config_set_bool ("CompressWeekend", config->compress_weekend); - gnome_config_set_bool ("ShowEventEndTime", config->show_event_end); - - gnome_config_pop_prefix (); - - - /* 'DateNavigator' settings. */ - prefix = g_strdup_printf ("=%s/config/Calendar=/DateNavigator/", - evolution_dir); - gnome_config_push_prefix (prefix); - g_free (prefix); - - gnome_config_set_bool ("ShowWeekNumbers", config->dnav_show_week_no); - - gnome_config_pop_prefix (); - - - gnome_config_sync (); -} - - -void -calendar_config_write_on_exit (void) -{ - gchar *prefix; - - /* 'Display' settings. */ - prefix = g_strdup_printf ("=%s/config/Calendar=/Display/", - evolution_dir); - gnome_config_push_prefix (prefix); - g_free (prefix); - - gnome_config_set_int ("View", config->view); - gnome_config_set_int ("TimeDivisions", config->time_divisions); - gnome_config_set_float ("HPanePosition", config->hpane_pos); - gnome_config_set_float ("VPanePosition", config->vpane_pos); - gnome_config_set_float ("MonthHPanePosition", config->month_hpane_pos); - gnome_config_set_float ("MonthVPanePosition", config->month_vpane_pos); - - gnome_config_pop_prefix (); - - - gnome_config_sync (); -} - - -/* - * Calendar Settings. - */ - -/* Whether we use 24-hour format or 12-hour format (AM/PM). */ -gboolean -calendar_config_get_24_hour_format (void) -{ - return config->use_24_hour_format; -} - - -void -calendar_config_set_24_hour_format (gboolean use_24_hour) -{ - config->use_24_hour_format = use_24_hour; -} - - -/* The start day of the week (0 = Sun to 6 = Mon). */ -gint -calendar_config_get_week_start_day (void) -{ - return config->week_start_day; -} - - -void -calendar_config_set_week_start_day (gint week_start_day) -{ - config->week_start_day = week_start_day; -} - - -/* The start and end times of the work-day. */ -gint -calendar_config_get_day_start_hour (void) -{ - return config->day_start_hour; -} - - -void -calendar_config_set_day_start_hour (gint day_start_hour) -{ - config->day_start_hour = day_start_hour; -} - - -gint -calendar_config_get_day_start_minute (void) -{ - return config->day_start_minute; -} - - -void -calendar_config_set_day_start_minute (gint day_start_min) -{ - config->day_start_minute = day_start_min; -} - - -gint -calendar_config_get_day_end_hour (void) -{ - return config->day_end_hour; -} - - -void -calendar_config_set_day_end_hour (gint day_end_hour) -{ - config->day_end_hour = day_end_hour; -} - - -gint -calendar_config_get_day_end_minute (void) -{ - return config->day_end_minute; -} - - -void -calendar_config_set_day_end_minute (gint day_end_min) -{ - config->day_end_minute = day_end_min; -} - - -/* The time divisions in the Day/Work-Week view in minutes (5/10/15/30/60). */ -gint -calendar_config_get_time_divisions (void) -{ - return config->time_divisions; -} - - -void -calendar_config_set_time_divisions (gint divisions) -{ - config->time_divisions = divisions; -} - - -/* Whether we show week numbers in the Date Navigator. */ -gboolean -calendar_config_get_dnav_show_week_no (void) -{ - return config->dnav_show_week_no; -} - - -void -calendar_config_set_dnav_show_week_no (gboolean show_week_no) -{ - config->dnav_show_week_no = show_week_no; -} - - -/* The view to show on start-up, 0 = Day, 1 = WorkWeek, 2 = Week, 3 = Month. */ -gint -calendar_config_get_default_view (void) -{ - return config->view; -} - - -void -calendar_config_set_default_view (gint view) -{ - config->view = view; -} - - -/* The positions of the panes in the normal and month views. */ -gfloat -calendar_config_get_hpane_pos (void) -{ - return config->hpane_pos; -} - - -void -calendar_config_set_hpane_pos (gfloat hpane_pos) -{ - config->hpane_pos = hpane_pos; -} - - -gfloat -calendar_config_get_vpane_pos (void) -{ - return config->vpane_pos; -} - - -void -calendar_config_set_vpane_pos (gfloat vpane_pos) -{ - config->vpane_pos = vpane_pos; -} - - -gfloat -calendar_config_get_month_hpane_pos (void) -{ - return config->month_hpane_pos; -} - - -void -calendar_config_set_month_hpane_pos (gfloat hpane_pos) -{ - config->month_hpane_pos = hpane_pos; -} - - -gfloat -calendar_config_get_month_vpane_pos (void) -{ - return config->month_vpane_pos; -} - - -void -calendar_config_set_month_vpane_pos (gfloat vpane_pos) -{ - config->month_vpane_pos = vpane_pos; -} - - -/* Whether we compress the weekend in the week/month views. */ -gboolean -calendar_config_get_compress_weekend (void) -{ - return config->compress_weekend; -} - - -void -calendar_config_set_compress_weekend (gboolean compress) -{ - config->compress_weekend = compress; -} - - -/* Whether we show event end times. */ -gboolean -calendar_config_get_show_event_end (void) -{ - return config->show_event_end; -} - - -void -calendar_config_set_show_event_end (gboolean show_end) -{ - config->show_event_end = show_end; -} - - -/* The working days of the week, a bit-wise combination of flags. */ -CalWeekdays -calendar_config_get_working_days (void) -{ - return config->working_days; -} - - -void -calendar_config_set_working_days (CalWeekdays days) -{ - config->working_days = days; -} - - -/* This sets all the common config settings for an ECalendar widget. - These are the week start day, and whether we show week numbers. */ -void -calendar_config_configure_e_calendar (ECalendar *cal) -{ - gboolean dnav_show_week_no; - gint week_start_day; - - dnav_show_week_no = calendar_config_get_dnav_show_week_no (); - - /* Note that this is 0 (Sun) to 6 (Sat). */ - week_start_day = calendar_config_get_week_start_day (); - - /* Convert it to 0 (Mon) to 6 (Sun), which is what we use. */ - week_start_day = (week_start_day + 6) % 7; - - gnome_canvas_item_set (GNOME_CANVAS_ITEM (cal->calitem), - "show_week_numbers", dnav_show_week_no, - "week_start_day", week_start_day, - NULL); -} - - -/* This sets all the common config settings for an EDateEdit widget. - These are the week start day, whether we show week numbers, whether we - use 24 hour format, and the hours of the working day to use in the time - popup. */ -void -calendar_config_configure_e_date_edit (EDateEdit *dedit) -{ - gboolean dnav_show_week_no, use_24_hour; - gint week_start_day, start_hour, end_hour; - - dnav_show_week_no = calendar_config_get_dnav_show_week_no (); - - /* Note that this is 0 (Sun) to 6 (Sat). */ - week_start_day = calendar_config_get_week_start_day (); - - /* Convert it to 0 (Mon) to 6 (Sun), which is what we use. */ - week_start_day = (week_start_day + 6) % 7; - - use_24_hour = calendar_config_get_24_hour_format (); - - start_hour = calendar_config_get_day_start_hour (); - end_hour = calendar_config_get_day_end_hour (); - /* Round up the end hour. */ - if (calendar_config_get_day_end_minute () != 0) - end_hour = end_hour + 1 % 24; - - e_date_edit_set_week_start_day (dedit, week_start_day); - e_date_edit_set_show_week_numbers (dedit, dnav_show_week_no); - e_date_edit_set_use_24_hour_format (dedit, use_24_hour); - e_date_edit_set_time_popup_range (dedit, start_hour, end_hour); -} diff --git a/calendar/gui/calendar-config.h b/calendar/gui/calendar-config.h deleted file mode 100644 index 8b11570f12..0000000000 --- a/calendar/gui/calendar-config.h +++ /dev/null @@ -1,126 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 2000, Helix Code, Inc. - * Copyright 2000, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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 - */ - -/* - * calendar-config.h - functions to load/save/get/set user settings. - */ - -#ifndef _CALENDAR_CONFIG_H_ -#define _CALENDAR_CONFIG_H_ - -#include <widgets/misc/e-calendar.h> -#include <widgets/misc/e-dateedit.h> - - -/* These are used to get/set the working days in the week. The bit-flags are - combined together. The bits must be from 0 (Sun) to 6 (Sat) to match the - day values used by localtime etc. */ -typedef enum -{ - CAL_SUNDAY = 1 << 0, - CAL_MONDAY = 1 << 1, - CAL_TUESDAY = 1 << 2, - CAL_WEDNESDAY = 1 << 3, - CAL_THURSDAY = 1 << 4, - CAL_FRIDAY = 1 << 5, - CAL_SATURDAY = 1 << 6 -} CalWeekdays; - - - -void calendar_config_init (void); -void calendar_config_write (void); -void calendar_config_write_on_exit (void); - - -/* - * Calendar Settings. - */ - -/* The working days of the week, a bit-wise combination of flags. */ -CalWeekdays calendar_config_get_working_days (void); -void calendar_config_set_working_days (CalWeekdays days); - -/* The start day of the week (0 = Sun to 6 = Sat). */ -gint calendar_config_get_week_start_day (void); -void calendar_config_set_week_start_day (gint week_start_day); - -/* The start and end times of the work-day. */ -gint calendar_config_get_day_start_hour (void); -void calendar_config_set_day_start_hour (gint day_start_hour); - -gint calendar_config_get_day_start_minute (void); -void calendar_config_set_day_start_minute (gint day_start_min); - -gint calendar_config_get_day_end_hour (void); -void calendar_config_set_day_end_hour (gint day_end_hour); - -gint calendar_config_get_day_end_minute (void); -void calendar_config_set_day_end_minute (gint day_end_min); - -/* Whether we use 24-hour format or 12-hour format (AM/PM). */ -gboolean calendar_config_get_24_hour_format (void); -void calendar_config_set_24_hour_format (gboolean use_24_hour); - -/* The time divisions in the Day/Work-Week view in minutes (5/10/15/30/60). */ -gint calendar_config_get_time_divisions (void); -void calendar_config_set_time_divisions (gint divisions); - -/* Whether we show event end times. */ -gboolean calendar_config_get_show_event_end (void); -void calendar_config_set_show_event_end (gboolean show_end); - -/* Whether we compress the weekend in the week/month views. */ -gboolean calendar_config_get_compress_weekend (void); -void calendar_config_set_compress_weekend (gboolean compress); - -/* Whether we show week numbers in the Date Navigator. */ -gboolean calendar_config_get_dnav_show_week_no (void); -void calendar_config_set_dnav_show_week_no (gboolean show_week_no); - -/* The view to show on start-up, 0 = Day, 1 = WorkWeek, 2 = Week, 3 = Month. */ -gint calendar_config_get_default_view (void); -void calendar_config_set_default_view (gint view); - -/* The positions of the panes in the normal and month views. */ -gfloat calendar_config_get_hpane_pos (void); -void calendar_config_set_hpane_pos (gfloat hpane_pos); - -gfloat calendar_config_get_vpane_pos (void); -void calendar_config_set_vpane_pos (gfloat vpane_pos); - -gfloat calendar_config_get_month_hpane_pos (void); -void calendar_config_set_month_hpane_pos (gfloat hpane_pos); - -gfloat calendar_config_get_month_vpane_pos (void); -void calendar_config_set_month_vpane_pos (gfloat vpane_pos); - - -/* Convenience functions to configure common properties of ECalendar and - EDateEdit widgets. */ -void calendar_config_configure_e_calendar (ECalendar *cal); -void calendar_config_configure_e_date_edit (EDateEdit *dedit); - -#endif /* _CALENDAR_CONFIG_H_ */ diff --git a/calendar/gui/calendar-model.c b/calendar/gui/calendar-model.c deleted file mode 100644 index 3e8f3359ab..0000000000 --- a/calendar/gui/calendar-model.c +++ /dev/null @@ -1,2204 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* Evolution calendar - Data model for ETable - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - - -#include <config.h> - -#include <math.h> -#include <sys/types.h> - -/* We need this for strptime. */ -#define _XOPEN_SOURCE 500 -#define __USE_XOPEN -#include <time.h> -#include <sys/time.h> -#undef _XOPEN_SOURCE -#undef __USE_XOPEN - -#include <ctype.h> -#include <glib.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <libgnomeui/gnome-messagebox.h> -#include <gal/widgets/e-unicode.h> -#include <cal-util/timeutil.h> -#include "calendar-model.h" -#include "calendar-commands.h" - - - - -/* Private part of the ECalendarModel structure */ -struct _CalendarModelPrivate { - /* Calendar client we are using */ - CalClient *client; - - /* Types of objects we are dealing with */ - CalObjType type; - - /* Array of pointers to calendar objects */ - GArray *objects; - - /* UID -> array index hash */ - GHashTable *uid_index_hash; - - /* Type of components to create when using click-to-add in the table */ - CalComponentVType new_comp_vtype; - - /* Whether we display dates in 24-hour format. */ - gboolean use_24_hour_format; - - /* HACK: so that ETable can do its stupid append_row() thing */ - guint appending_row : 1; - - /* The default category to use when creating new tasks, e.g. when the - filter is set to a certain category we use that category when - creating a new task. */ - gchar *default_category; - - /* A balanced tree of the categories used by all the tasks/events. */ - GTree *categories; -}; - -enum { - CATEGORIES_CHANGED, - LAST_SIGNAL -}; - -static gint calendar_model_signals [LAST_SIGNAL] = { 0 }; - - - -static void calendar_model_class_init (CalendarModelClass *class); -static void calendar_model_init (CalendarModel *model); -static void calendar_model_destroy (GtkObject *object); - -static int calendar_model_column_count (ETableModel *etm); -static int calendar_model_row_count (ETableModel *etm); -static void *calendar_model_value_at (ETableModel *etm, int col, int row); -static void calendar_model_set_value_at (ETableModel *etm, int col, int row, const void *value); -static gboolean calendar_model_is_cell_editable (ETableModel *etm, int col, int row); -static void calendar_model_append_row (ETableModel *etm, ETableModel *source, gint row); -static void *calendar_model_duplicate_value (ETableModel *etm, int col, const void *value); -static void calendar_model_free_value (ETableModel *etm, int col, void *value); -static void *calendar_model_initialize_value (ETableModel *etm, int col); -static gboolean calendar_model_value_is_empty (ETableModel *etm, int col, const void *value); -static char * calendar_model_value_to_string (ETableModel *etm, int col, const void *value); -static void load_objects (CalendarModel *model); -static int remove_object (CalendarModel *model, const char *uid); -static void ensure_task_complete (CalComponent *comp, - time_t completed_date); -static void ensure_task_not_complete (CalComponent *comp); -static void calendar_model_collect_all_categories (CalendarModel *model); -static gboolean calendar_model_collect_categories (CalendarModel *model, - CalComponent *comp); - -static ETableModelClass *parent_class; - - - -/** - * calendar_model_get_type: - * @void: - * - * Registers the #CalendarModel class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the #CalendarModel class. - **/ -GtkType -calendar_model_get_type (void) -{ - static GtkType calendar_model_type = 0; - - if (!calendar_model_type) { - static GtkTypeInfo calendar_model_info = { - "CalendarModel", - sizeof (CalendarModel), - sizeof (CalendarModelClass), - (GtkClassInitFunc) calendar_model_class_init, - (GtkObjectInitFunc) calendar_model_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - calendar_model_type = gtk_type_unique (E_TABLE_MODEL_TYPE, &calendar_model_info); - } - - return calendar_model_type; -} - -/* Class initialization function for the calendar table model */ -static void -calendar_model_class_init (CalendarModelClass *class) -{ - GtkObjectClass *object_class; - ETableModelClass *etm_class; - - object_class = (GtkObjectClass *) class; - etm_class = (ETableModelClass *) class; - - parent_class = gtk_type_class (E_TABLE_MODEL_TYPE); - - calendar_model_signals [CATEGORIES_CHANGED] = - gtk_signal_new ("categories-changed", - GTK_RUN_LAST, object_class->type, - GTK_SIGNAL_OFFSET (CalendarModelClass, - categories_changed), - gtk_signal_default_marshaller, - GTK_TYPE_NONE, 0); - - gtk_object_class_add_signals (object_class, calendar_model_signals, - LAST_SIGNAL); - - object_class->destroy = calendar_model_destroy; - - etm_class->column_count = calendar_model_column_count; - etm_class->row_count = calendar_model_row_count; - etm_class->value_at = calendar_model_value_at; - etm_class->set_value_at = calendar_model_set_value_at; - etm_class->is_cell_editable = calendar_model_is_cell_editable; - etm_class->append_row = calendar_model_append_row; - etm_class->duplicate_value = calendar_model_duplicate_value; - etm_class->free_value = calendar_model_free_value; - etm_class->initialize_value = calendar_model_initialize_value; - etm_class->value_is_empty = calendar_model_value_is_empty; - etm_class->value_to_string = calendar_model_value_to_string; - - class->categories_changed = NULL; -} - -/* Object initialization function for the calendar table model */ -static void -calendar_model_init (CalendarModel *model) -{ - CalendarModelPrivate *priv; - - priv = g_new0 (CalendarModelPrivate, 1); - model->priv = priv; - - priv->objects = g_array_new (FALSE, TRUE, sizeof (CalComponent *)); - priv->uid_index_hash = g_hash_table_new (g_str_hash, g_str_equal); - priv->new_comp_vtype = CAL_COMPONENT_EVENT; - priv->use_24_hour_format = TRUE; - - priv->categories = g_tree_new ((GCompareFunc)strcmp); -} - -/* Called from g_hash_table_foreach_remove(), frees a stored UID->index - * mapping. - */ -static gboolean -free_uid_index (gpointer key, gpointer value, gpointer data) -{ - int *idx; - - idx = value; - g_free (idx); - - return TRUE; -} - -/* Frees the objects stored in the calendar model */ -static void -free_objects (CalendarModel *model) -{ - CalendarModelPrivate *priv; - int i; - - priv = model->priv; - - g_hash_table_foreach_remove (priv->uid_index_hash, free_uid_index, NULL); - - for (i = 0; i < priv->objects->len; i++) { - CalComponent *comp; - - comp = g_array_index (priv->objects, CalComponent *, i); - g_assert (comp != NULL); - gtk_object_unref (GTK_OBJECT (comp)); - } - - g_array_set_size (priv->objects, 0); -} - -/* Destroy handler for the calendar table model */ -static void -calendar_model_destroy (GtkObject *object) -{ - CalendarModel *model; - CalendarModelPrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_CALENDAR_MODEL (object)); - - model = CALENDAR_MODEL (object); - priv = model->priv; - - /* Free the calendar client interface object */ - - if (priv->client) { - gtk_signal_disconnect_by_data (GTK_OBJECT (priv->client), model); - gtk_object_unref (GTK_OBJECT (priv->client)); - priv->client = NULL; - } - - /* Free the uid->index hash data and the array of UIDs */ - - free_objects (model); - - g_hash_table_destroy (priv->uid_index_hash); - priv->uid_index_hash = NULL; - - g_array_free (priv->objects, TRUE); - priv->objects = NULL; - - g_free (priv->default_category); - - /* We only need to free the first argument, the key, so g_free will do. - */ - g_tree_traverse (priv->categories, (GTraverseFunc) g_free, - G_PRE_ORDER, NULL); - g_tree_destroy (priv->categories); - - /* Free the private structure */ - - g_free (priv); - model->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - - -/* ETableModel methods */ - -/* column_count handler for the calendar table model */ -static int -calendar_model_column_count (ETableModel *etm) -{ - return CAL_COMPONENT_FIELD_NUM_FIELDS; -} - -/* row_count handler for the calendar table model */ -static int -calendar_model_row_count (ETableModel *etm) -{ - CalendarModel *model; - CalendarModelPrivate *priv; - - model = CALENDAR_MODEL (etm); - priv = model->priv; - - return priv->objects->len; -} - -/* Creates a nice string representation of a time value */ -static char* -get_time_t (CalendarModel *model, time_t *t, gboolean skip_midnight) -{ - static char buffer[64]; - struct tm *tmp_tm; - char *format; - - if (*t <= 0) { - buffer[0] = '\0'; - } else { - tmp_tm = localtime (t); - - if (skip_midnight && tmp_tm->tm_hour == 0 - && tmp_tm->tm_min == 0 && tmp_tm->tm_sec == 0) - /* strftime format of a weekday and a date. */ - format = _("%a %m/%d/%Y"); - else if (model->priv->use_24_hour_format) - /* strftime format of a weekday, a date and a time, - in 24-hour format. */ - format = _("%a %m/%d/%Y %H:%M:%S"); - else - /* strftime format of a weekday, a date and a time, - in 12-hour format. */ - format = _("%a %m/%d/%Y %I:%M:%S %p"); - - strftime (buffer, sizeof (buffer), format, tmp_tm); - } - - return buffer; -} - -/* Builds a string based on the list of CATEGORIES properties of a calendar - * component. - */ -static char * -get_categories (CalComponent *comp) -{ - const char *categories; - - cal_component_get_categories (comp, &categories); - - return categories ? (char*) categories : ""; -} - -/* Returns a string based on the CLASSIFICATION property of a calendar component */ -static char * -get_classification (CalComponent *comp) -{ - CalComponentClassification classif; - - cal_component_get_classification (comp, &classif); - - switch (classif) { - case CAL_COMPONENT_CLASS_NONE: - return ""; - - case CAL_COMPONENT_CLASS_PUBLIC: - return _("Public"); - - case CAL_COMPONENT_CLASS_PRIVATE: - return _("Private"); - - case CAL_COMPONENT_CLASS_CONFIDENTIAL: - return _("Confidential"); - - case CAL_COMPONENT_CLASS_UNKNOWN: - return _("Unknown"); - - default: - g_assert_not_reached (); - return ""; - } -} - -/* Builds a string for the COMPLETED property of a calendar component */ -static char * -get_completed (CalendarModel *model, - CalComponent *comp) -{ - struct icaltimetype *completed; - time_t t; - - cal_component_get_completed (comp, &completed); - - if (!completed) - t = 0; - else { - t = icaltime_as_timet (*completed); - cal_component_free_icaltimetype (completed); - } - - return get_time_t (model, &t, FALSE); -} - -/* Builds a string for and frees a date/time value */ -static char * -get_and_free_datetime (CalendarModel *model, CalComponentDateTime dt) -{ - time_t t; - - if (!dt.value) - t = 0; - else - t = icaltime_as_timet (*dt.value); - - cal_component_free_datetime (&dt); - - return get_time_t (model, &t, FALSE); -} - -/* Builds a string for the DTEND property of a calendar component */ -static char * -get_dtend (CalendarModel *model, CalComponent *comp) -{ - CalComponentDateTime dt; - - cal_component_get_dtend (comp, &dt); - return get_and_free_datetime (model, dt); -} - -/* Builds a string for the DTSTART property of a calendar component */ -static char * -get_dtstart (CalendarModel *model, CalComponent *comp) -{ - CalComponentDateTime dt; - - cal_component_get_dtstart (comp, &dt); - return get_and_free_datetime (model, dt); -} - -/* Builds a string for the DUE property of a calendar component */ -static char * -get_due (CalendarModel *model, CalComponent *comp) -{ - CalComponentDateTime dt; - - cal_component_get_due (comp, &dt); - return get_and_free_datetime (model, dt); -} - -/* Builds a string for the GEO property of a calendar component */ -static char* -get_geo (CalComponent *comp) -{ - struct icalgeotype *geo; - static gchar buf[32]; - - cal_component_get_geo (comp, &geo); - - if (!geo) - buf[0] = '\0'; - else { - g_snprintf (buf, sizeof (buf), "%g %s, %g %s", - fabs (geo->lat), - geo->lat >= 0.0 ? _("N") : _("S"), - fabs (geo->lon), - geo->lon >= 0.0 ? _("E") : _("W")); - cal_component_free_geo (geo); - } - - return buf; -} - -/* Builds a string for the PERCENT property of a calendar component */ -static char * -get_percent (CalComponent *comp) -{ - int *percent; - static char buf[32]; - - cal_component_get_percent (comp, &percent); - - if (!percent) - buf[0] = '\0'; - else { - g_snprintf (buf, sizeof (buf), "%d%%", *percent); - cal_component_free_percent (percent); - } - - return buf; -} - -/* Builds a string for the PRIORITY property of a calendar component */ -static char * -get_priority (CalComponent *comp) -{ - int *priority; - static char buf[32]; - - cal_component_get_priority (comp, &priority); - - if (!priority) - buf[0] = '\0'; - else { - g_snprintf (buf, sizeof (buf), "%d", *priority); - cal_component_free_priority (priority); - } - - return buf; -} - -/* Builds a string for the SUMMARY property of a calendar component */ -static char * -get_summary (CalComponent *comp) -{ - CalComponentText summary; - - cal_component_get_summary (comp, &summary); - - if (summary.value) - return (char *) summary.value; - else - return ""; -} - -/* Builds a string for the TRANSPARENCY property of a calendar component */ -static char * -get_transparency (CalComponent *comp) -{ - CalComponentTransparency transp; - - cal_component_get_transparency (comp, &transp); - - switch (transp) { - case CAL_COMPONENT_TRANSP_NONE: - return ""; - - case CAL_COMPONENT_TRANSP_TRANSPARENT: - return _("Transparent"); - - case CAL_COMPONENT_TRANSP_OPAQUE: - return _("Opaque"); - - case CAL_COMPONENT_TRANSP_UNKNOWN: - return _("Unknown"); - - default: - g_assert_not_reached (); - return NULL; - } -} - -/* Builds a string for the URL property of a calendar component */ -static char * -get_url (CalComponent *comp) -{ - const char *url; - - cal_component_get_url (comp, &url); - - if (url) - return (char *) url; - else - return ""; -} - -/* Returns whether the completion date has been set on a component */ -static gboolean -get_is_complete (CalComponent *comp) -{ - struct icaltimetype *t; - gboolean retval; - - cal_component_get_completed (comp, &t); - retval = (t != NULL); - - if (retval) - cal_component_free_icaltimetype (t); - - return retval; -} - -/* Returns whether a calendar component is overdue. - * - * FIXME: This will only get called when the component is scrolled into the - * ETable. There should be some sort of dynamic update thingy for if a component - * becomes overdue while it is being viewed. - */ -static gboolean -get_is_overdue (CalComponent *comp) -{ - CalComponentDateTime dt; - gboolean retval; - - cal_component_get_due (comp, &dt); - - /* First, do we have a due date? */ - - if (!dt.value) - retval = FALSE; - else { - time_t t; - - /* Second, is it already completed? */ - - if (get_is_complete (comp)) { - retval = FALSE; - goto out; - } - - /* Third, are we overdue as of right now? */ - - t = icaltime_as_timet (*dt.value); - - if (t < time (NULL)) - retval = TRUE; - else - retval = FALSE; - } - - out: - - cal_component_free_datetime (&dt); - - return retval; -} - -/* value_at handler for the calendar table model */ -static void * -calendar_model_value_at (ETableModel *etm, int col, int row) -{ - CalendarModel *model; - CalendarModelPrivate *priv; - CalComponent *comp; - - model = CALENDAR_MODEL (etm); - priv = model->priv; - - g_return_val_if_fail (col >= 0 && col < CAL_COMPONENT_FIELD_NUM_FIELDS, NULL); - g_return_val_if_fail (row >= 0 && row < priv->objects->len, NULL); - - comp = g_array_index (priv->objects, CalComponent *, row); - g_assert (comp != NULL); - - switch (col) { - case CAL_COMPONENT_FIELD_CATEGORIES: - return get_categories (comp); - - case CAL_COMPONENT_FIELD_CLASSIFICATION: - return get_classification (comp); - - case CAL_COMPONENT_FIELD_COMPLETED: - return get_completed (model, comp); - - case CAL_COMPONENT_FIELD_DTEND: - return get_dtend (model, comp); - - case CAL_COMPONENT_FIELD_DTSTART: - return get_dtstart (model, comp); - - case CAL_COMPONENT_FIELD_DUE: - return get_due (model, comp); - - case CAL_COMPONENT_FIELD_GEO: - return get_geo (comp); - - case CAL_COMPONENT_FIELD_PERCENT: - return get_percent (comp); - - case CAL_COMPONENT_FIELD_PRIORITY: - return get_priority (comp); - - case CAL_COMPONENT_FIELD_SUMMARY: - return get_summary (comp); - - case CAL_COMPONENT_FIELD_TRANSPARENCY: - return get_transparency (comp); - - case CAL_COMPONENT_FIELD_URL: - return get_url (comp); - - case CAL_COMPONENT_FIELD_HAS_ALARMS: - return GINT_TO_POINTER (cal_component_has_alarms (comp)); - - case CAL_COMPONENT_FIELD_ICON: - /* FIXME: Also support 'Assigned to me' & 'Assigned to someone - else'. */ - if (cal_component_has_recurrences (comp)) - return GINT_TO_POINTER (1); - else { - icalcomponent *ical_comp; - - ical_comp = cal_component_get_icalcomponent (comp); - if (icalcomponent_get_first_property (ical_comp, - ICAL_ATTENDEE_PROPERTY) != NULL) - { - return GINT_TO_POINTER (2); /* Task-assigned */ - } - else { - return GINT_TO_POINTER (0); - } - } - case CAL_COMPONENT_FIELD_COMPLETE: - return GINT_TO_POINTER (get_is_complete (comp)); - - case CAL_COMPONENT_FIELD_RECURRING: - return GINT_TO_POINTER (cal_component_has_recurrences (comp)); - - case CAL_COMPONENT_FIELD_OVERDUE: - return GINT_TO_POINTER (get_is_overdue (comp)); - - case CAL_COMPONENT_FIELD_COLOR: - if (get_is_overdue (comp)) - return "red"; - else - return NULL; - - default: - g_message ("calendar_model_value_at(): Requested invalid column %d", col); - return NULL; - } -} - -/* Returns whether a string is NULL, empty, or full of whitespace */ -static gboolean -string_is_empty (const char *value) -{ - const char *p; - gboolean empty = TRUE; - - if (value) { - p = value; - while (*p) { - if (!isspace (*p)) { - empty = FALSE; - break; - } - p++; - } - } - return empty; -} - - -/* FIXME: We need to set the "transient_for" property for the dialog, but - the model doesn't know anything about the windows. */ -static void -show_date_warning (CalendarModel *model) -{ - GtkWidget *dialog; - char buffer[64], message[256], *format; - time_t t; - struct tm *tmp_tm; - - t = time (NULL); - tmp_tm = localtime (&t); - - if (model->priv->use_24_hour_format) - /* strftime format of a weekday, a date and a time, 24-hour. */ - format = _("%a %m/%d/%Y %H:%M:%S"); - else - /* strftime format of a weekday, a date and a time, 12-hour. */ - format = _("%a %m/%d/%Y %I:%M:%S %p"); - - strftime (buffer, sizeof (buffer), format, tmp_tm); - - g_snprintf (message, 256, - _("The date must be entered in the format: \n\n%s"), - buffer); - - dialog = gnome_message_box_new (message, - GNOME_MESSAGE_BOX_ERROR, - GNOME_STOCK_BUTTON_OK, NULL); - gtk_widget_show (dialog); -} - -/* Builds a list of categories from a comma-delimited string */ -static GSList * -categories_from_string (const char *value) -{ - GSList *list; - const char *categ_start; - const char *categ_end; - const char *p; - - if (!value) - return NULL; - - list = NULL; - - categ_start = categ_end = NULL; - - for (p = value; *p; p++) { - if (categ_start) { - if (*p == ',') { - char *c; - - c = g_strndup (categ_start, categ_end - categ_start + 1); - list = g_slist_prepend (list, c); - - categ_start = categ_end = NULL; - } else if (!isspace (*p)) - categ_end = p; - } else if (!isspace (*p) && *p != ',') - categ_start = categ_end = p; - } - - if (categ_start) { - char *c; - - c = g_strndup (categ_start, categ_end - categ_start + 1); - list = g_slist_prepend (list, c); - } - - return g_slist_reverse (list); -} - -/* Sets the list of categories from a comma-delimited string */ -static void -set_categories (CalComponent *comp, const char *value) -{ - GSList *list; - GSList *l; - - list = categories_from_string (value); - - cal_component_set_categories_list (comp, list); - - for (l = list; l; l = l->next) { - char *s; - - s = l->data; - g_free (s); - } - - g_slist_free (list); -} - -/* Parses a time value entered by the user; returns -1 if it could not be - * parsed. Returns 0 for an empty time. - */ -static time_t -parse_time (const char *value) -{ - struct tm discard_tm, date_tm, time_tm; - struct tm *today_tm; - time_t t; - const char *pos, *parse_end; - char *format[4]; - gboolean parsed_date = FALSE, parsed_time = FALSE; - gint i; - - if (string_is_empty (value)) - return 0; - - pos = value; - - /* Skip any whitespace. */ - while (isspace (*pos)) - pos++; - - /* Skip any weekday name, full or abbreviated. */ - parse_end = strptime (pos, "%a ", &discard_tm); - if (parse_end) - pos = parse_end; - - memset (&date_tm, 0, sizeof (date_tm)); - /* strptime format for a date. */ - parse_end = strptime (pos, _("%m/%d/%Y"), &date_tm); - if (parse_end) { - pos = parse_end; - parsed_date = TRUE; - } - - /* Skip any whitespace. */ - while (isspace (*pos)) - pos++; - - /* Skip any weekday name, full or abbreviated, again. */ - parse_end = strptime (pos, "%a ", &discard_tm); - if (parse_end) - pos = parse_end; - - - /* strptime format for a time of day, in 12-hour format. - If it is is not appropriate in the locale set to an empty string. */ - format[0] = _("%I:%M:%S %p%n"); - - /* strptime format for a time of day, in 24-hour format. */ - format[1] = _("%H:%M:%S%n"); - - /* strptime format for time of day, without seconds, 12-hour format. - If it is is not appropriate in the locale set to an empty string. */ - format[2] = _("%I:%M %p%n"); - - /* strptime format for time of day, without seconds 24-hour format. */ - format[3] = _("%H:%M%n"); - - for (i = 0; i < sizeof (format) / sizeof (format[0]); i++) { - memset (&time_tm, 0, sizeof (time_tm)); - parse_end = strptime (pos, format[i], &time_tm); - if (parse_end) { - pos = parse_end; - parsed_time = TRUE; - break; - } - } - - /* Skip any whitespace. */ - while (isspace (*pos)) - pos++; - - /* If we haven't already parsed a date, try again. */ - if (!parsed_date) { - memset (&date_tm, 0, sizeof (date_tm)); - /* strptime format for a date. */ - parse_end = strptime (pos, _("%m/%d/%Y"), &date_tm); - if (parse_end) { - pos = parse_end; - parsed_date = TRUE; - } - } - - /* If we don't have a date or a time it must be invalid. */ - if (!parsed_date && !parsed_time) - return -1; - - - if (parsed_date) { - /* If a 2-digit year was used we use the current century. */ - if (date_tm.tm_year < 0) { - t = time (NULL); - today_tm = localtime (&t); - - /* This should convert it into a value from 0 to 99. */ - date_tm.tm_year += 1900; - - /* Now add on the century. */ - date_tm.tm_year += today_tm->tm_year - - (today_tm->tm_year % 100); - } - } else { - /* If we didn't get a date we use the current day. */ - t = time (NULL); - today_tm = localtime (&t); - date_tm.tm_mday = today_tm->tm_mday; - date_tm.tm_mon = today_tm->tm_mon; - date_tm.tm_year = today_tm->tm_year; - } - - if (parsed_time) { - date_tm.tm_hour = time_tm.tm_hour; - date_tm.tm_min = time_tm.tm_min; - date_tm.tm_sec = time_tm.tm_sec; - } else { - date_tm.tm_hour = 0; - date_tm.tm_min = 0; - date_tm.tm_sec = 0; - } - - - date_tm.tm_isdst = -1; - return mktime (&date_tm); -} - -/* Called to set the "Date Completed" field. We also need to update the - Status and Percent fields to make sure they match. */ -static void -set_completed (CalendarModel *model, CalComponent *comp, const char *value) -{ - time_t t; - - t = parse_time (value); - if (t == -1) { - show_date_warning (model); - } else if (t == 0) { - ensure_task_not_complete (comp); - } else { - ensure_task_complete (comp, t); - } -} - -/* Sets a CalComponentDateTime value */ -static void -set_datetime (CalendarModel *model, CalComponent *comp, const char *value, - void (* set_func) (CalComponent *comp, CalComponentDateTime *dt)) -{ - time_t t; - - t = parse_time (value); - if (t == -1) { - show_date_warning (model); - return; - } else if (t == 0) { - (* set_func) (comp, NULL); - return; - } else { - CalComponentDateTime dt; - struct icaltimetype itt; - - itt = icaltime_from_timet (t, FALSE); - dt.value = &itt; - dt.tzid = NULL; - - (* set_func) (comp, &dt); - } -} - -/* FIXME: We need to set the "transient_for" property for the dialog, but the - * model doesn't know anything about the windows. - */ -static void -show_geo_warning (void) -{ - GtkWidget *dialog; - - dialog = gnome_message_box_new (_("The geographical position must be entered " - "in the format: \n\n45.436845,125.862501"), - GNOME_MESSAGE_BOX_ERROR, - GNOME_STOCK_BUTTON_OK, NULL); - gtk_widget_show (dialog); -} - -/* Sets the geographical position value of a component */ -static void -set_geo (CalComponent *comp, const char *value) -{ - double latitude, longitude; - int matched; - struct icalgeotype geo; - - if (string_is_empty (value)) { - cal_component_set_geo (comp, NULL); - return; - } - - matched = sscanf (value, "%lg , %lg", &latitude, &longitude); - - if (matched != 2) { - show_geo_warning (); - return; - } - - geo.lat = latitude; - geo.lon = longitude; - cal_component_set_geo (comp, &geo); -} - -/* FIXME: We need to set the "transient_for" property for the dialog, but the - * model doesn't know anything about the windows. - */ -static void -show_percent_warning (void) -{ - GtkWidget *dialog; - - dialog = gnome_message_box_new (_("The percent value must be between 0 and 100, inclusive"), - GNOME_MESSAGE_BOX_ERROR, - GNOME_STOCK_BUTTON_OK, NULL); - gtk_widget_show (dialog); -} - -/* Sets the percent value of a calendar component */ -static void -set_percent (CalComponent *comp, const char *value) -{ - int matched, percent; - - if (string_is_empty (value)) { - cal_component_set_percent (comp, NULL); - ensure_task_not_complete (comp); - return; - } - - matched = sscanf (value, "%i", &percent); - - if (matched != 1 || percent < 0 || percent > 100) { - show_percent_warning (); - return; - } - - cal_component_set_percent (comp, &percent); - - if (percent == 100) - ensure_task_complete (comp, -1); - else - ensure_task_not_complete (comp); -} - -/* FIXME: We need to set the "transient_for" property for the dialog, but the - * model doesn't know anything about the windows. */ -static void -show_priority_warning (void) -{ - GtkWidget *dialog; - - dialog = gnome_message_box_new (_("The priority must be between 1 and 9, inclusive"), - GNOME_MESSAGE_BOX_ERROR, - GNOME_STOCK_BUTTON_OK, NULL); - gtk_widget_show (dialog); -} - -/* Sets the priority of a calendar component */ -static void -set_priority (CalComponent *comp, const char *value) -{ - int matched, priority; - - if (string_is_empty (value)) { - cal_component_set_priority (comp, NULL); - return; - } - - matched = sscanf (value, "%i", &priority); - - if (matched != 1 || priority < 1 || priority > 9) { - show_priority_warning (); - return; - } - - cal_component_set_priority (comp, &priority); -} - -/* Sets the summary of a calendar component */ -static void -set_summary (CalComponent *comp, const char *value) -{ - CalComponentText text; - - if (string_is_empty (value)) { - cal_component_set_summary (comp, NULL); - return; - } - - text.value = value; - text.altrep = NULL; /* FIXME: should we preserve the old ALTREP? */ - - cal_component_set_summary (comp, &text); -} - -/* Sets the URI of a calendar component */ -static void -set_url (CalComponent *comp, const char *value) -{ - if (string_is_empty (value)) { - cal_component_set_url (comp, NULL); - return; - } - - cal_component_set_url (comp, value); -} - -/* Called to set the checkbutton field which indicates whether a task is - complete. */ -static void -set_complete (CalComponent *comp, const void *value) -{ - gint state = GPOINTER_TO_INT (value); - - if (state) { - ensure_task_complete (comp, -1); - } else { - ensure_task_not_complete (comp); - } -} - -/* set_value_at handler for the calendar table model */ -static void -calendar_model_set_value_at (ETableModel *etm, int col, int row, const void *value) -{ - CalendarModel *model; - CalendarModelPrivate *priv; - CalComponent *comp; - - model = CALENDAR_MODEL (etm); - priv = model->priv; - - g_return_if_fail (col >= 0 && col < CAL_COMPONENT_FIELD_NUM_FIELDS); - g_return_if_fail (row >= 0 && row < priv->objects->len); - - comp = g_array_index (priv->objects, CalComponent *, row); - g_assert (comp != NULL); - - switch (col) { - case CAL_COMPONENT_FIELD_CATEGORIES: - set_categories (comp, value); - if (calendar_model_collect_categories (model, comp)) { - gtk_signal_emit (GTK_OBJECT (model), - calendar_model_signals [CATEGORIES_CHANGED]); - } - break; - - /* FIXME: CLASSIFICATION requires an option menu cell renderer */ - - case CAL_COMPONENT_FIELD_COMPLETED: - set_completed (model, comp, value); - break; - - case CAL_COMPONENT_FIELD_DTEND: - /* FIXME: Need to reset dtstart if dtend happens before it */ - set_datetime (model, comp, value, cal_component_set_dtend); - break; - - case CAL_COMPONENT_FIELD_DTSTART: - /* FIXME: Need to reset dtend if dtstart happens after it */ - set_datetime (model, comp, value, cal_component_set_dtstart); - break; - - case CAL_COMPONENT_FIELD_DUE: - set_datetime (model, comp, value, cal_component_set_due); - break; - - case CAL_COMPONENT_FIELD_GEO: - set_geo (comp, value); - break; - - case CAL_COMPONENT_FIELD_PERCENT: - set_percent (comp, value); - break; - - case CAL_COMPONENT_FIELD_PRIORITY: - set_priority (comp, value); - break; - - case CAL_COMPONENT_FIELD_SUMMARY: - set_summary (comp, value); - break; - - /* FIXME: TRANSPARENCY requires an option menu cell renderer */ - - case CAL_COMPONENT_FIELD_URL: - set_url (comp, value); - break; - - case CAL_COMPONENT_FIELD_COMPLETE: - set_complete (comp, value); - break; - - default: - g_message ("calendar_model_set_value_at(): Requested invalid column %d", col); - break; - } - - /* FIXME: this is an ugly HACK. ETable needs a better API for the - * "click here to add an element" thingy. - */ - if (priv->appending_row) - return; - - if (!cal_client_update_object (priv->client, comp)) - g_message ("calendar_model_set_value_at(): Could not update the object!"); -} - -/* is_cell_editable handler for the calendar table model */ -static gboolean -calendar_model_is_cell_editable (ETableModel *etm, int col, int row) -{ - CalendarModel *model; - CalendarModelPrivate *priv; - - model = CALENDAR_MODEL (etm); - priv = model->priv; - - g_return_val_if_fail (col >= 0 && col < CAL_COMPONENT_FIELD_NUM_FIELDS, FALSE); - - /* FIXME: We can't check this as 'click-to-add' passes row 0. */ - /*g_return_val_if_fail (row >= 0 && row < priv->objects->len, FALSE);*/ - - switch (col) { - case CAL_COMPONENT_FIELD_CATEGORIES: - case CAL_COMPONENT_FIELD_COMPLETED: - case CAL_COMPONENT_FIELD_DTEND: - case CAL_COMPONENT_FIELD_DTSTART: - case CAL_COMPONENT_FIELD_DUE: - case CAL_COMPONENT_FIELD_GEO: - case CAL_COMPONENT_FIELD_PERCENT: - case CAL_COMPONENT_FIELD_PRIORITY: - case CAL_COMPONENT_FIELD_SUMMARY: - case CAL_COMPONENT_FIELD_URL: - case CAL_COMPONENT_FIELD_COMPLETE: - return TRUE; - - default: - return FALSE; - } -} - -/* append_row handler for the calendar model */ -static void -calendar_model_append_row (ETableModel *etm, ETableModel *source, gint row) -{ - CalendarModel *model; - CalendarModelPrivate *priv; - CalComponent *comp; - int *new_idx, col; - const char *uid; - - model = CALENDAR_MODEL (etm); - priv = model->priv; - - /* This is a HACK */ - priv->appending_row = TRUE; - - /* FIXME: This should support other types of components, but for now it - * is only used for the task list. - */ - comp = cal_component_new (); - cal_component_set_new_vtype (comp, priv->new_comp_vtype); - - cal_component_get_uid (comp, &uid); - - g_array_append_val (priv->objects, comp); - new_idx = g_new (int, 1); - *new_idx = priv->objects->len - 1; - g_hash_table_insert (priv->uid_index_hash, (char *) uid, new_idx); - - /* Notify the views about the new row. I think we have to do that here, - or the views may become confused when they start getting - "row_changed" or "cell_changed" signals for this new row. */ - e_table_model_row_inserted (etm, *new_idx); - - for (col = 0; col < CAL_COMPONENT_FIELD_NUM_FIELDS; col++) { - const void *val; - - if (!e_table_model_is_cell_editable (etm, col, *new_idx)) - continue; - - val = e_table_model_value_at(source, col, row); - e_table_model_set_value_at (etm, col, *new_idx, val); - } - - /* This is the end of the HACK */ - priv->appending_row = FALSE; - - if (!cal_client_update_object (priv->client, comp)) { - /* FIXME: Show error dialog. */ - g_message ("calendar_model_append_row(): Could not add new object!"); - remove_object (model, uid); - e_table_model_row_deleted (etm, *new_idx); - } -} - -/* Duplicates a string value */ -static char * -dup_string (const char *value) -{ - return g_strdup (value); -} - -/* duplicate_value handler for the calendar table model */ -static void * -calendar_model_duplicate_value (ETableModel *etm, int col, const void *value) -{ - g_return_val_if_fail (col >= 0 && col < CAL_COMPONENT_FIELD_NUM_FIELDS, NULL); - - /* They are almost all dup_string()s for now, but we'll have real fields - * later. - */ - - switch (col) { - case CAL_COMPONENT_FIELD_CATEGORIES: - case CAL_COMPONENT_FIELD_CLASSIFICATION: - case CAL_COMPONENT_FIELD_COMPLETED: - case CAL_COMPONENT_FIELD_DTEND: - case CAL_COMPONENT_FIELD_DTSTART: - case CAL_COMPONENT_FIELD_DUE: - case CAL_COMPONENT_FIELD_GEO: - case CAL_COMPONENT_FIELD_PERCENT: - case CAL_COMPONENT_FIELD_PRIORITY: - case CAL_COMPONENT_FIELD_SUMMARY: - case CAL_COMPONENT_FIELD_TRANSPARENCY: - case CAL_COMPONENT_FIELD_URL: - return dup_string (value); - - case CAL_COMPONENT_FIELD_HAS_ALARMS: - case CAL_COMPONENT_FIELD_ICON: - case CAL_COMPONENT_FIELD_COMPLETE: - case CAL_COMPONENT_FIELD_RECURRING: - case CAL_COMPONENT_FIELD_OVERDUE: - case CAL_COMPONENT_FIELD_COLOR: - return (void *) value; - - default: - g_message ("calendar_model_duplicate_value(): Requested invalid column %d", col); - return NULL; - } -} - -/* free_value handler for the calendar table model */ -static void -calendar_model_free_value (ETableModel *etm, int col, void *value) -{ - g_return_if_fail (col >= 0 && col < CAL_COMPONENT_FIELD_NUM_FIELDS); - - switch (col) { - case CAL_COMPONENT_FIELD_CATEGORIES: - g_free (value); - - case CAL_COMPONENT_FIELD_CLASSIFICATION: - return; - - case CAL_COMPONENT_FIELD_COMPLETED: - case CAL_COMPONENT_FIELD_DTEND: - case CAL_COMPONENT_FIELD_DTSTART: - case CAL_COMPONENT_FIELD_DUE: - case CAL_COMPONENT_FIELD_GEO: - case CAL_COMPONENT_FIELD_PERCENT: - case CAL_COMPONENT_FIELD_PRIORITY: - case CAL_COMPONENT_FIELD_SUMMARY: - g_free (value); - - case CAL_COMPONENT_FIELD_TRANSPARENCY: - return; - - case CAL_COMPONENT_FIELD_URL: - g_free (value); - - case CAL_COMPONENT_FIELD_HAS_ALARMS: - case CAL_COMPONENT_FIELD_ICON: - case CAL_COMPONENT_FIELD_COMPLETE: - case CAL_COMPONENT_FIELD_RECURRING: - case CAL_COMPONENT_FIELD_OVERDUE: - case CAL_COMPONENT_FIELD_COLOR: - return; - - default: - g_message ("calendar_model_free_value(): Requested invalid column %d", col); - return; - } -} - -/* Initializes a string value */ -static char * -init_string (void) -{ - return g_strdup (""); -} - -/* initialize_value handler for the calendar table model */ -static void * -calendar_model_initialize_value (ETableModel *etm, int col) -{ - CalendarModel *model; - - g_return_val_if_fail (col >= 0 && col < CAL_COMPONENT_FIELD_NUM_FIELDS, NULL); - - model = CALENDAR_MODEL (etm); - - switch (col) { - case CAL_COMPONENT_FIELD_CATEGORIES: - return g_strdup (model->priv->default_category ? model->priv->default_category : ""); - - case CAL_COMPONENT_FIELD_CLASSIFICATION: - case CAL_COMPONENT_FIELD_COMPLETED: - case CAL_COMPONENT_FIELD_DTEND: - case CAL_COMPONENT_FIELD_DTSTART: - case CAL_COMPONENT_FIELD_DUE: - case CAL_COMPONENT_FIELD_GEO: - case CAL_COMPONENT_FIELD_PERCENT: - case CAL_COMPONENT_FIELD_PRIORITY: - case CAL_COMPONENT_FIELD_SUMMARY: - case CAL_COMPONENT_FIELD_TRANSPARENCY: - case CAL_COMPONENT_FIELD_URL: - return init_string (); - - case CAL_COMPONENT_FIELD_HAS_ALARMS: - case CAL_COMPONENT_FIELD_ICON: - case CAL_COMPONENT_FIELD_COMPLETE: - case CAL_COMPONENT_FIELD_RECURRING: - case CAL_COMPONENT_FIELD_OVERDUE: - case CAL_COMPONENT_FIELD_COLOR: - return NULL; - - default: - g_message ("calendar_model_initialize_value(): Requested invalid column %d", col); - return NULL; - } -} - -/* value_is_empty handler for the calendar model. This should return TRUE - unless a significant value has been set. The 'click-to-add' feature - checks all fields to see if any are not empty and if so it adds a new - row, so we only want to return FALSE if we have a useful object. */ -static gboolean -calendar_model_value_is_empty (ETableModel *etm, int col, const void *value) -{ - g_return_val_if_fail (col >= 0 && col < CAL_COMPONENT_FIELD_NUM_FIELDS, TRUE); - - switch (col) { - case CAL_COMPONENT_FIELD_CATEGORIES: - case CAL_COMPONENT_FIELD_CLASSIFICATION: /* actually goes here, not by itself */ - case CAL_COMPONENT_FIELD_COMPLETED: - case CAL_COMPONENT_FIELD_DTEND: - case CAL_COMPONENT_FIELD_DTSTART: - case CAL_COMPONENT_FIELD_DUE: - case CAL_COMPONENT_FIELD_GEO: - case CAL_COMPONENT_FIELD_PERCENT: - case CAL_COMPONENT_FIELD_PRIORITY: - case CAL_COMPONENT_FIELD_SUMMARY: - case CAL_COMPONENT_FIELD_TRANSPARENCY: - case CAL_COMPONENT_FIELD_URL: - return string_is_empty (value); - - case CAL_COMPONENT_FIELD_HAS_ALARMS: - case CAL_COMPONENT_FIELD_ICON: - case CAL_COMPONENT_FIELD_COMPLETE: - case CAL_COMPONENT_FIELD_RECURRING: - case CAL_COMPONENT_FIELD_OVERDUE: - case CAL_COMPONENT_FIELD_COLOR: - return TRUE; - - default: - g_message ("calendar_model_value_is_empty(): Requested invalid column %d", col); - return TRUE; - } -} - -static char * -calendar_model_value_to_string (ETableModel *etm, int col, const void *value) -{ - g_return_val_if_fail (col >= 0 && col < CAL_COMPONENT_FIELD_NUM_FIELDS, NULL); - - switch (col) { - case CAL_COMPONENT_FIELD_CATEGORIES: - case CAL_COMPONENT_FIELD_CLASSIFICATION: - case CAL_COMPONENT_FIELD_COMPLETED: - case CAL_COMPONENT_FIELD_DTEND: - case CAL_COMPONENT_FIELD_DTSTART: - case CAL_COMPONENT_FIELD_DUE: - case CAL_COMPONENT_FIELD_GEO: - case CAL_COMPONENT_FIELD_PERCENT: - case CAL_COMPONENT_FIELD_PRIORITY: - case CAL_COMPONENT_FIELD_SUMMARY: - case CAL_COMPONENT_FIELD_TRANSPARENCY: - case CAL_COMPONENT_FIELD_URL: - return e_utf8_from_locale_string (value); - - case CAL_COMPONENT_FIELD_ICON: - if ((int)value == 0) - return e_utf8_from_locale_string (_("Normal")); - else if ((int)value == 1) - return e_utf8_from_locale_string (_("Recurring")); - else - return e_utf8_from_locale_string (_("Assigned")); - - case CAL_COMPONENT_FIELD_HAS_ALARMS: - case CAL_COMPONENT_FIELD_COMPLETE: - case CAL_COMPONENT_FIELD_RECURRING: - case CAL_COMPONENT_FIELD_OVERDUE: - return e_utf8_from_locale_string (value ? _("Yes") : _("No")); - - case CAL_COMPONENT_FIELD_COLOR: - return NULL; - - default: - g_message ("calendar_model_value_as_string(): Requested invalid column %d", col); - return NULL; - } -} - - - -/** - * calendar_model_new: - * - * Creates a new calendar model. It must be told about the calendar client - * interface object it will monitor with calendar_model_set_cal_client(). - * - * Return value: A newly-created calendar model. - **/ -CalendarModel * -calendar_model_new (void) -{ - return CALENDAR_MODEL (gtk_type_new (TYPE_CALENDAR_MODEL)); -} - - -/* Callback used when a calendar is opened into the server */ -static void -cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data) -{ - CalendarModel *model; - - model = CALENDAR_MODEL (data); - - e_table_model_pre_change (E_TABLE_MODEL (model)); - - if (status == CAL_CLIENT_OPEN_SUCCESS) { - load_objects (model); - calendar_model_collect_all_categories (model); - } - - e_table_model_changed (E_TABLE_MODEL (model)); -} - - -/* Removes an object from the model and updates all the indices that follow. - * Returns the index of the object that was removed, or -1 if no object with - * such UID was found. - */ -static int -remove_object (CalendarModel *model, const char *uid) -{ - CalendarModelPrivate *priv; - int *idx; - CalComponent *orig_comp; - int i; - int n; - - priv = model->priv; - - /* Find the index of the object to be removed */ - - idx = g_hash_table_lookup (priv->uid_index_hash, uid); - if (!idx) - return -1; - - orig_comp = g_array_index (priv->objects, CalComponent *, *idx); - g_assert (orig_comp != NULL); - - /* Decrease the indices of all the objects that follow in the array */ - - for (i = *idx + 1; i < priv->objects->len; i++) { - CalComponent *comp; - int *comp_idx; - const char *comp_uid; - - comp = g_array_index (priv->objects, CalComponent *, i); - g_assert (comp != NULL); - - cal_component_get_uid (comp, &comp_uid); - - comp_idx = g_hash_table_lookup (priv->uid_index_hash, comp_uid); - g_assert (comp_idx != NULL); - - (*comp_idx)--; - g_assert (*comp_idx >= 0); - } - - /* Remove this object from the array and hash */ - - g_hash_table_remove (priv->uid_index_hash, uid); - g_array_remove_index (priv->objects, *idx); - - gtk_object_unref (GTK_OBJECT (orig_comp)); - - n = *idx; - g_free (idx); - - return n; -} - -/* Returns whether a component's type matches the types we support */ -static gboolean -matches_type (CalObjType type, CalComponentVType vtype) -{ - return ((vtype == CAL_COMPONENT_EVENT && (type & CALOBJ_TYPE_EVENT)) - || (vtype == CAL_COMPONENT_TODO && (type & CALOBJ_TYPE_TODO)) - || (vtype == CAL_COMPONENT_JOURNAL && (type & CALOBJ_TYPE_JOURNAL))); -} - -/* Callback used when an object is updated in the server */ -static void -obj_updated_cb (CalClient *client, const char *uid, gpointer data) -{ - CalendarModel *model; - CalendarModelPrivate *priv; - int orig_idx; - CalComponent *new_comp; - CalComponentVType new_comp_vtype; - const char *new_comp_uid; - int *new_idx; - CalClientGetStatus status; - - model = CALENDAR_MODEL (data); - priv = model->priv; - - orig_idx = remove_object (model, uid); - - status = cal_client_get_object (priv->client, uid, &new_comp); - - switch (status) { - case CAL_CLIENT_GET_SUCCESS: - /* Check if we are interested in this type of object */ - - new_comp_vtype = cal_component_get_vtype (new_comp); - if (!matches_type (priv->type, new_comp_vtype)) { - gtk_object_unref (GTK_OBJECT (new_comp)); - break; - } - - /* Insert the object into the model */ - - cal_component_get_uid (new_comp, &new_comp_uid); - - if (orig_idx == -1) { - /* The object not in the model originally, so we just append it */ - - g_array_append_val (priv->objects, new_comp); - - new_idx = g_new (int, 1); - *new_idx = priv->objects->len - 1; - - g_hash_table_insert (priv->uid_index_hash, (char *) new_comp_uid, new_idx); - e_table_model_row_inserted (E_TABLE_MODEL (model), *new_idx); - } else { - int i; - - /* Insert the new version of the object in its old position */ - - g_array_insert_val (priv->objects, orig_idx, new_comp); - - new_idx = g_new (int, 1); - *new_idx = orig_idx; - g_hash_table_insert (priv->uid_index_hash, (char *) new_comp_uid, new_idx); - - /* Increase the indices of all subsequent objects */ - - for (i = orig_idx + 1; i < priv->objects->len; i++) { - CalComponent *comp; - int *comp_idx; - const char *comp_uid; - - comp = g_array_index (priv->objects, CalComponent *, i); - g_assert (comp != NULL); - - cal_component_get_uid (comp, &comp_uid); - - comp_idx = g_hash_table_lookup (priv->uid_index_hash, comp_uid); - g_assert (comp_idx != NULL); - - (*comp_idx)++; - } - - e_table_model_row_changed (E_TABLE_MODEL (model), *new_idx); - } - - /* See if we need to add any categories. Note that old - categories won't be removed, but I don't think that matters - too much here. */ - if (calendar_model_collect_categories (model, new_comp)) { - gtk_signal_emit (GTK_OBJECT (model), - calendar_model_signals [CATEGORIES_CHANGED]); - } - - break; - - case CAL_CLIENT_GET_NOT_FOUND: - /* Nothing; the object may have been removed from the server. We just - * notify that the old object was deleted. - */ - if (orig_idx != -1) - e_table_model_row_deleted (E_TABLE_MODEL (model), orig_idx); - - break; - - case CAL_CLIENT_GET_SYNTAX_ERROR: - g_message ("obj_updated_cb(): Syntax error when getting object `%s'", uid); - - /* Same notification as above */ - if (orig_idx != -1) - e_table_model_row_deleted (E_TABLE_MODEL (model), orig_idx); - - break; - - default: - g_assert_not_reached (); - } -} - -/* Callback used when an object is removed in the server */ -static void -obj_removed_cb (CalClient *client, const char *uid, gpointer data) -{ - CalendarModel *model; - int idx; - - model = CALENDAR_MODEL (data); - - idx = remove_object (model, uid); - - if (idx != -1) - e_table_model_row_deleted (E_TABLE_MODEL (model), idx); -} - -/* Loads the required objects from the calendar client */ -static void -load_objects (CalendarModel *model) -{ - CalendarModelPrivate *priv; - GList *uids; - GList *l; - - priv = model->priv; - - g_assert (cal_client_get_load_state (priv->client) == CAL_CLIENT_LOAD_LOADED); - - uids = cal_client_get_uids (priv->client, priv->type); - - for (l = uids; l; l = l->next) { - char *uid; - CalComponent *comp; - const char *comp_uid; - CalClientGetStatus status; - CalComponentVType comp_vtype; - int *idx; - - uid = l->data; - status = cal_client_get_object (priv->client, uid, &comp); - - switch (status) { - case CAL_CLIENT_GET_SUCCESS: - break; - - case CAL_CLIENT_GET_NOT_FOUND: - /* Nothing; the object may have been removed from the server */ - continue; - - case CAL_CLIENT_GET_SYNTAX_ERROR: - g_message ("load_objects(): Syntax error when getting object `%s'", uid); - continue; - - default: - g_assert_not_reached (); - } - - /* Check if we are interested in this type of object */ - - comp_vtype = cal_component_get_vtype (comp); - if (!matches_type (priv->type, comp_vtype)) { - gtk_object_unref (GTK_OBJECT (comp)); - continue; - } - - /* Insert the object into the model */ - - idx = g_new (int, 1); - - g_array_append_val (priv->objects, comp); - *idx = priv->objects->len - 1; - - cal_component_get_uid (comp, &comp_uid); - g_hash_table_insert (priv->uid_index_hash, (char *) comp_uid, idx); - } - - cal_obj_uid_list_free (uids); -} - -/** - * calendar_model_get_cal_client: - * @model: A calendar model. - * - * Queries the calendar client interface object that a calendar model is using. - * - * Return value: A calendar client interface object. - **/ -CalClient * -calendar_model_get_cal_client (CalendarModel *model) -{ - CalendarModelPrivate *priv; - - g_return_val_if_fail (model != NULL, NULL); - g_return_val_if_fail (IS_CALENDAR_MODEL (model), NULL); - - priv = model->priv; - - return priv->client; -} - - -/** - * calendar_model_set_cal_client: - * @model: A calendar model. - * @client: A calendar client interface object. - * @type: Type of objects to present. - * - * Sets the calendar client interface object that a calendar model will monitor. - * It also sets the types of objects this model will present to an #ETable. - **/ -void -calendar_model_set_cal_client (CalendarModel *model, CalClient *client, CalObjType type) -{ - CalendarModelPrivate *priv; - - g_return_if_fail (model != NULL); - g_return_if_fail (IS_CALENDAR_MODEL (model)); - - if (client) - g_return_if_fail (IS_CAL_CLIENT (client)); - - priv = model->priv; - - if (priv->client == client && priv->type == type) - return; - - e_table_model_pre_change (E_TABLE_MODEL(model)); - - if (client) - gtk_object_ref (GTK_OBJECT (client)); - - if (priv->client) { - gtk_signal_disconnect_by_data (GTK_OBJECT (priv->client), model); - gtk_object_unref (GTK_OBJECT (priv->client)); - } - - free_objects (model); - - priv->client = client; - priv->type = type; - - if (priv->client) { - gtk_signal_connect (GTK_OBJECT (priv->client), "obj_updated", - GTK_SIGNAL_FUNC (obj_updated_cb), model); - gtk_signal_connect (GTK_OBJECT (priv->client), "obj_removed", - GTK_SIGNAL_FUNC (obj_removed_cb), model); - - if (cal_client_get_load_state (priv->client) != CAL_CLIENT_LOAD_LOADED) - gtk_signal_connect (GTK_OBJECT (priv->client), "cal_opened", - GTK_SIGNAL_FUNC (cal_opened_cb), model); - else - load_objects (model); - } - - e_table_model_changed (E_TABLE_MODEL (model)); -} - - -/** - * calendar_model_set_new_comp_vtype: - * @model: A calendar model. - * @vtype: Type of calendar components to create. - * - * Sets the type of calendar components that will be created by a calendar table - * model when the click-to-add functionality of the table is used. - **/ -void -calendar_model_set_new_comp_vtype (CalendarModel *model, CalComponentVType vtype) -{ - CalendarModelPrivate *priv; - - g_return_if_fail (model != NULL); - g_return_if_fail (IS_CALENDAR_MODEL (model)); - g_return_if_fail (vtype != CAL_COMPONENT_NO_TYPE); - - priv = model->priv; - priv->new_comp_vtype = vtype; -} - -/** - * calendar_model_get_new_comp_vtype: - * @model: A calendar model. - * - * Queries the type of calendar components that are created by a calendar table - * model when using the click-to-add functionality in a table. - * - * Return value: Type of components that are created. - **/ -CalComponentVType -calendar_model_get_new_comp_vtype (CalendarModel *model) -{ - CalendarModelPrivate *priv; - - g_return_val_if_fail (model != NULL, CAL_COMPONENT_NO_TYPE); - g_return_val_if_fail (IS_CALENDAR_MODEL (model), CAL_COMPONENT_NO_TYPE); - - priv = model->priv; - return priv->new_comp_vtype; -} - - -void -calendar_model_mark_task_complete (CalendarModel *model, - gint row) -{ - CalendarModelPrivate *priv; - CalComponent *comp; - - g_return_if_fail (model != NULL); - g_return_if_fail (IS_CALENDAR_MODEL (model)); - - priv = model->priv; - - g_return_if_fail (row >= 0 && row < priv->objects->len); - - comp = g_array_index (priv->objects, CalComponent *, row); - g_assert (comp != NULL); - - ensure_task_complete (comp, -1); - - if (!cal_client_update_object (priv->client, comp)) - g_message ("calendar_model_mark_task_complete(): Could not update the object!"); -} - - -/** - * calendar_model_get_component: - * @model: A calendar model. - * @row: Row number of sought calendar component. - * - * Queries a calendar component from a calendar model based on its row number. - * - * Return value: The sought calendar component. - **/ -CalComponent * -calendar_model_get_component (CalendarModel *model, - gint row) -{ - CalendarModelPrivate *priv; - - g_return_val_if_fail (model != NULL, NULL); - g_return_val_if_fail (IS_CALENDAR_MODEL (model), NULL); - - priv = model->priv; - - g_return_val_if_fail (row >= 0 && row < priv->objects->len, NULL); - - return g_array_index (priv->objects, CalComponent *, row); -} - - -/* This makes sure a task is marked as complete. - It makes sure the "Date Completed" property is set. If the completed_date - is not -1, then that is used, otherwise if the "Date Completed" property - is not already set it is set to the current time. - It makes sure the percent is set to 100, and that the status is "Completed". - Note that this doesn't update the component on the client. */ -static void -ensure_task_complete (CalComponent *comp, - time_t completed_date) -{ - struct icaltimetype *old_completed = NULL; - struct icaltimetype new_completed; - int *old_percent, new_percent; - icalproperty_status status; - gboolean set_completed = TRUE; - - /* Date Completed. */ - if (completed_date == -1) { - cal_component_get_completed (comp, &old_completed); - - if (old_completed) { - cal_component_free_icaltimetype (old_completed); - set_completed = FALSE; - } else { - completed_date = time (NULL); - } - } - - if (set_completed) { - new_completed = icaltime_from_timet (completed_date, FALSE); - cal_component_set_completed (comp, &new_completed); - } - - /* Percent. */ - cal_component_get_percent (comp, &old_percent); - if (!old_percent || *old_percent != 100) { - new_percent = 100; - cal_component_set_percent (comp, &new_percent); - } - if (old_percent) - cal_component_free_percent (old_percent); - - /* Status. */ - cal_component_get_status (comp, &status); - if (status != ICAL_STATUS_COMPLETED) { - cal_component_set_status (comp, ICAL_STATUS_COMPLETED); - } -} - - -/* This makes sure a task is marked as incomplete. It clears the - "Date Completed" property. If the percent is set to 100 it removes it, - and if the status is "Completed" it sets it to "Needs Action". - Note that this doesn't update the component on the client. */ -static void -ensure_task_not_complete (CalComponent *comp) -{ - icalproperty_status old_status; - int *old_percent; - - /* Date Completed. */ - cal_component_set_completed (comp, NULL); - - /* Percent. */ - cal_component_get_percent (comp, &old_percent); - if (old_percent && *old_percent == 100) - cal_component_set_percent (comp, NULL); - if (old_percent) - cal_component_free_percent (old_percent); - - /* Status. */ - cal_component_get_status (comp, &old_status); - if (old_status == ICAL_STATUS_COMPLETED) - cal_component_set_status (comp, ICAL_STATUS_NEEDSACTION); -} - - -/* Whether we use 24 hour format to display the times. */ -gboolean -calendar_model_get_use_24_hour_format (CalendarModel *model) -{ - g_return_val_if_fail (IS_CALENDAR_MODEL (model), TRUE); - - return model->priv->use_24_hour_format; -} - - -void -calendar_model_set_use_24_hour_format (CalendarModel *model, - gboolean use_24_hour_format) -{ - g_return_if_fail (IS_CALENDAR_MODEL (model)); - - if (model->priv->use_24_hour_format != use_24_hour_format) { - model->priv->use_24_hour_format = use_24_hour_format; - /* Get the views to redraw themselves. */ - e_table_model_changed (E_TABLE_MODEL (model)); - } -} - - -void -calendar_model_set_default_category (CalendarModel *model, - gchar *default_category) -{ - g_return_if_fail (IS_CALENDAR_MODEL (model)); - - g_free (model->priv->default_category); - model->priv->default_category = g_strdup (default_category); -} - - -static void -calendar_model_collect_all_categories (CalendarModel *model) -{ - CalendarModelPrivate *priv; - CalComponent *comp; - int i; - - priv = model->priv; - - /* Destroy the current tree and start from scratch. */ - g_tree_traverse (priv->categories, (GTraverseFunc) g_free, - G_PRE_ORDER, NULL); - g_tree_destroy (priv->categories); - - priv->categories = g_tree_new ((GCompareFunc)strcmp); - - for (i = 0; i < priv->objects->len; i++) { - comp = g_array_index (priv->objects, CalComponent *, i); - calendar_model_collect_categories (model, comp); - } - - gtk_signal_emit (GTK_OBJECT (model), - calendar_model_signals [CATEGORIES_CHANGED]); -} - - -static gboolean -calendar_model_collect_categories (CalendarModel *model, - CalComponent *comp) -{ - CalendarModelPrivate *priv; - GSList *categories_list, *elem; - gboolean changed = FALSE; - - priv = model->priv; - - cal_component_get_categories_list (comp, &categories_list); - - for (elem = categories_list; elem; elem = elem->next) { - if (!g_tree_lookup (priv->categories, elem->data)) { - /* We store a '1' as the data, just so we can use - g_tree_lookup() on it. Note that we don't free - the string since it is now part of the tree. */ - g_tree_insert (priv->categories, elem->data, - GINT_TO_POINTER (1)); - changed = TRUE; - } else { - g_free (elem->data); - } - } - - g_slist_free (categories_list); - - return changed; -} - - -GTree* -calendar_model_get_categories (CalendarModel *model) -{ - g_return_val_if_fail (IS_CALENDAR_MODEL (model), NULL); - - return model->priv->categories; -} diff --git a/calendar/gui/calendar-model.h b/calendar/gui/calendar-model.h deleted file mode 100644 index 5ff2f41c38..0000000000 --- a/calendar/gui/calendar-model.h +++ /dev/null @@ -1,93 +0,0 @@ -/* Evolution calendar - Data model for ETable - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef CALENDAR_MODEL_H -#define CALENDAR_MODEL_H - -#include <libgnome/gnome-defs.h> -#include <gal/e-table/e-table-model.h> -#include <cal-client/cal-client.h> - -BEGIN_GNOME_DECLS - - - -#define TYPE_CALENDAR_MODEL (calendar_model_get_type ()) -#define CALENDAR_MODEL(obj) (GTK_CHECK_CAST ((obj), TYPE_CALENDAR_MODEL, CalendarModel)) -#define CALENDAR_MODEL_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_CALENDAR_MODEL, \ - CalendarModelClass)) -#define IS_CALENDAR_MODEL(obj) (GTK_CHECK_TYPE ((obj), TYPE_CALENDAR_MODEL)) -#define IS_CALENDAR_MODEL_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), TYPE_CALENDAR_MODEL)) - -typedef struct _CalendarModel CalendarModel; -typedef struct _CalendarModelClass CalendarModelClass; - -typedef struct _CalendarModelPrivate CalendarModelPrivate; - -struct _CalendarModel { - ETableModel model; - - /* Private data */ - CalendarModelPrivate *priv; -}; - -struct _CalendarModelClass { - ETableModelClass parent_class; - - void (* categories_changed) (CalendarModel *model); -}; - -GtkType calendar_model_get_type (void); - -CalendarModel* calendar_model_new (void); - -CalClient* calendar_model_get_cal_client (CalendarModel *model); -void calendar_model_set_cal_client (CalendarModel *model, - CalClient *client, - CalObjType type); - -void calendar_model_set_new_comp_vtype (CalendarModel *model, - CalComponentVType vtype); -CalComponentVType calendar_model_get_new_comp_vtype (CalendarModel *model); - -void calendar_model_mark_task_complete (CalendarModel *model, - gint row); - -CalComponent* calendar_model_get_component (CalendarModel *model, - gint row); - -/* Whether we use 24 hour format to display the times. */ -gboolean calendar_model_get_use_24_hour_format (CalendarModel *model); -void calendar_model_set_use_24_hour_format (CalendarModel *model, - gboolean use_24_hour_format); - -GTree* calendar_model_get_categories (CalendarModel *model); - -void calendar_model_set_default_category (CalendarModel *model, - gchar *default_category); - - - - -END_GNOME_DECLS - -#endif diff --git a/calendar/gui/calendar-summary.c b/calendar/gui/calendar-summary.c deleted file mode 100644 index 0d0c404769..0000000000 --- a/calendar/gui/calendar-summary.c +++ /dev/null @@ -1,776 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* calendar-summary.c - * - * Authors: Iain Holmes <iain@ximian.com> - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <time.h> - -#include <gnome.h> -#include <bonobo.h> - -#include <liboaf/liboaf.h> - -#include <evolution-services/executive-summary-component.h> -#include <evolution-services/executive-summary-html-view.h> - -#include <gnome-xml/parser.h> -#include <gnome-xml/xmlmemory.h> - -#include "cal-util/cal-component.h" -#include "cal-util/timeutil.h" -#include "alarm.h" -#include "calendar-model.h" - -#include "calendar-summary.h" - -typedef struct { - ExecutiveSummaryComponent *component; - ExecutiveSummaryHtmlView *view; - BonoboPropertyControl *property_control; - CalClient *client; - - GtkWidget *show_appointments; - GtkWidget *show_tasks; - - gboolean appointments; - gboolean tasks; - - char *title; - char *icon; - - guint32 idle; - - gpointer alarm; -} CalSummary; - -enum { - PROPERTY_TITLE, - PROPERTY_ICON -}; - -extern gchar *evolution_dir; - -static int running_views = 0; -static BonoboGenericFactory *factory; -#define CALENDAR_SUMMARY_ID "OAFIID:GNOME_Evolution_Calendar_Summary_ComponentFactory" - -/* list_sort_merge, and list_sort are copied from GNOME-VFS. - Author: Sven Oliver <sven.over@ob.kamp.net> - Modified by Ettore Perazzoli <ettore@comm2000.it> to let the compare - functions get an additional gpointer parameter. - - Included here as using gnome-vfs for 1 20 line function - seems a bit of overkill. -*/ - -typedef gint (* CalSummaryListCompareFunc) (gconstpointer a, - gconstpointer b, - gpointer data); -static GList * -cal_list_sort_merge (GList *l1, - GList *l2, - CalSummaryListCompareFunc compare_func, - gpointer data) -{ - GList list, *l, *lprev; - - l = &list; - lprev = NULL; - - while (l1 && l2) { - if (compare_func (l1->data, l2->data, data) < 0) { - l->next = l1; - l = l->next; - l->prev = lprev; - lprev = l; - l1 = l1->next; - } else { - l->next = l2; - l = l->next; - l->prev = lprev; - lprev = l; - l2 = l2->next; - } - } - - l->next = l1 ? l1 : l2; - l->next->prev = l; - - return list.next; -} - -static GList * -cal_list_sort (GList *list, - CalSummaryListCompareFunc compare_func, - gpointer data) -{ - GList *l1, *l2; - - if (!list) - return NULL; - if (!list->next) - return list; - - l1 = list; - l2 = list->next; - - while ((l2 = l2->next) != NULL) { - if ((l2 = l2->next) == NULL) - break; - l1 = l1->next; - } - - l2 = l1->next; - l1->next = NULL; - - return cal_list_sort_merge (cal_list_sort (list, compare_func, data), - cal_list_sort (l2, compare_func, data), - compare_func, data); -} - -static int -sort_uids (gconstpointer a, - gconstpointer b, - gpointer user_data) -{ - CalComponent *comp_a, *comp_b; - CalSummary *summary = user_data; - CalClientGetStatus status; - CalComponentDateTime start_a, start_b; - - /* a after b then return > 0 */ - - status = cal_client_get_object (summary->client, a, &comp_a); - if (status != CAL_CLIENT_GET_SUCCESS) - return -1; - - status = cal_client_get_object (summary->client, b, &comp_b); - if (status != CAL_CLIENT_GET_SUCCESS) - return 1; - - cal_component_get_dtstart (comp_a, &start_a); - cal_component_get_dtstart (comp_b, &start_b); - - return icaltime_compare (*start_a.value, *start_b.value); -} - -static gboolean -generate_html_summary (gpointer data) -{ - CalSummary *summary; - time_t t, day_begin, day_end; - struct tm *timeptr; - GList *uids, *l; - char *ret_html, *tmp, *datestr; - - summary = data; - - t = time (NULL); - day_begin = time_day_begin (t); - day_end = time_day_end (t); - - datestr = g_new (char, 256); - timeptr = localtime (&t); - strftime (datestr, 255, _("%A, %e %B %Y"), timeptr); - ret_html = g_strdup_printf ("<b>%s</b>", datestr); - g_free (datestr); - - if (summary->appointments) { - tmp = ret_html; - ret_html = g_strdup_printf ("%s<p align=\"center\">Appointments</p><hr><ul>", - tmp); - g_free (tmp); - - uids = cal_client_get_objects_in_range (summary->client, - CALOBJ_TYPE_EVENT, day_begin, - day_end); - uids = cal_list_sort (uids, sort_uids, summary); - - for (l = uids; l; l = l->next){ - CalComponent *comp; - CalComponentText text; - CalClientGetStatus status; - CalComponentDateTime start, end; - struct icaltimetype *end_time; - time_t start_t, end_t; - struct tm *start_tm, *end_tm; - char *start_str, *end_str; - char *uid; - char *tmp2; - - uid = l->data; - status = cal_client_get_object (summary->client, uid, &comp); - if (status != CAL_CLIENT_GET_SUCCESS) - continue; - - cal_component_get_summary (comp, &text); - cal_component_get_dtstart (comp, &start); - cal_component_get_dtend (comp, &end); - - g_print ("text.value: %s\n", text.value); - end_time = end.value; - - start_t = icaltime_as_timet (*start.value); - - start_str = g_new (char, 20); - start_tm = localtime (&start_t); - strftime (start_str, 19, _("%I:%M%p"), start_tm); - - if (end_time) { - end_str = g_new (char, 20); - end_t = icaltime_as_timet (*end_time); - end_tm = localtime (&end_t); - strftime (end_str, 19, _("%I:%M%p"), end_tm); - } else { - end_str = g_strdup ("..."); - } - - tmp2 = g_strdup_printf ("<li>%s:%s -> %s</li>", text.value, start_str, end_str); - g_free (start_str); - g_free (end_str); - - tmp = ret_html; - ret_html = g_strconcat (ret_html, tmp2, NULL); - g_free (tmp); - g_free (tmp2); - } - - cal_obj_uid_list_free (uids); - - tmp = ret_html; - ret_html = g_strconcat (ret_html, "</ul>", NULL); - g_free (tmp); - } - - if (summary->tasks) { - tmp = ret_html; - ret_html = g_strconcat (ret_html, - "<p align=\"center\">Tasks</p><hr><ul>", - NULL); - g_free (tmp); - - /* Generate a list of tasks */ - uids = cal_client_get_uids (summary->client, CALOBJ_TYPE_TODO); - for (l = uids; l; l = l->next){ - CalComponent *comp; - CalComponentText text; - CalClientGetStatus status; - struct icaltimetype *completed; - char *uid; - char *tmp2; - - uid = l->data; - status = cal_client_get_object (summary->client, uid, &comp); - if (status != CAL_CLIENT_GET_SUCCESS) - continue; - - cal_component_get_summary (comp, &text); - cal_component_get_completed (comp, &completed); - - if (completed == NULL) { - tmp2 = g_strdup_printf ("<li>%s</li>", text.value); - } else { - tmp2 = g_strdup_printf ("<li><strike>%s</strike></li>", - text.value); - cal_component_free_icaltimetype (completed); - } - - tmp = ret_html; - ret_html = g_strconcat (ret_html, tmp2, NULL); - g_free (tmp); - g_free (tmp2); - } - - cal_obj_uid_list_free (uids); - - tmp = ret_html; - ret_html = g_strconcat (ret_html, "</ul>", NULL); - g_free (tmp); - } - - executive_summary_html_view_set_html (summary->view, ret_html); - g_free (ret_html); - - summary->idle = 0; - return FALSE; -} - -static void -get_property (BonoboPropertyBag *bag, - BonoboArg *arg, - guint arg_id, - CORBA_Environment *ev, - gpointer data) -{ - CalSummary *summary = (CalSummary *) data; - - switch (arg_id) { - case PROPERTY_TITLE: - g_warning ("Get property: %s", summary->title); - BONOBO_ARG_SET_STRING (arg, summary->title); - break; - - case PROPERTY_ICON: - BONOBO_ARG_SET_STRING (arg, summary->icon); - break; - - default: - break; - } -} - -static void -set_property (BonoboPropertyBag *bag, - const BonoboArg *arg, - guint arg_id, - CORBA_Environment *ev, - gpointer user_data) -{ - CalSummary *summary = (CalSummary *) user_data; - - switch (arg_id) { - case PROPERTY_TITLE: - if (summary->title) - g_free (summary->title); - - summary->title = g_strdup (BONOBO_ARG_GET_STRING (arg)); - bonobo_property_bag_notify_listeners (bag, "window_title", - arg, NULL); - break; - - case PROPERTY_ICON: - if (summary->icon) - g_free (summary->icon); - - summary->icon = g_strdup (BONOBO_ARG_GET_STRING (arg)); - bonobo_property_bag_notify_listeners (bag, "window_icon", - arg, NULL); - break; - - default: - break; - } -} - -static void -component_destroyed (GtkObject *object, - gpointer data) -{ - CalSummary *summary = (CalSummary *) data; - - g_free (summary->title); - g_free (summary->icon); - gtk_object_destroy (GTK_OBJECT (summary->client)); - - g_free (summary); - - running_views--; - - if (running_views <= 0) { - bonobo_object_unref (BONOBO_OBJECT (factory)); - } -} - -static void -obj_updated_cb (CalClient *client, - const char *uid, - CalSummary *summary) -{ - /* FIXME: Maybe cache the uid's in the summary and only call this if - uid is in this cache??? */ - - if (summary->idle != 0) - return; - - summary->idle = g_idle_add (generate_html_summary, summary); -} - -static void -obj_removed_cb (CalClient *client, - const char *uid, - CalSummary *summary) -{ - /* See FIXME: above */ - if (summary->idle != 0) - return; - - summary->idle = g_idle_add (generate_html_summary, summary); -} - -static void -cal_opened_cb (CalClient *client, - CalClientOpenStatus status, - CalSummary *summary) -{ - switch (status) { - case CAL_CLIENT_OPEN_SUCCESS: - if (summary->idle != 0) - return; - - summary->idle = g_idle_add (generate_html_summary, summary); - break; - - case CAL_CLIENT_OPEN_ERROR: - executive_summary_html_view_set_html (summary->view, - _("<b>Error loading calendar</b>")); - break; - - case CAL_CLIENT_OPEN_NOT_FOUND: - /* We did not use only_if_exists when opening the calendar, so - * this should not happen. - */ - g_assert_not_reached (); - break; - - case CAL_CLIENT_OPEN_METHOD_NOT_SUPPORTED: - executive_summary_html_view_set_html (summary->view, - _("<b>Error loading calendar:<br>Method not supported")); - break; - - default: - break; - } -} - -static void -alarm_fn (gpointer alarm_id, - time_t old_t, - gpointer data) -{ - CalSummary *summary; - time_t t, day_end; - - summary = data; - - /* Remove the old alarm, and start a new one for the next midnight */ - alarm_remove (alarm_id); - - t = time (NULL); - day_end = time_day_end (t); - summary->alarm = alarm_add (day_end, alarm_fn, summary, NULL); - - /* Now redraw the summary */ - generate_html_summary (summary); -} - -/* PersistStream callbacks */ -static void -load_from_stream (BonoboPersistStream *ps, - Bonobo_Stream stream, - Bonobo_Persist_ContentType type, - gpointer data, - CORBA_Environment *ev) -{ - CalSummary *summary = (CalSummary *) data; - char *str; - xmlChar *xml_str; - xmlDocPtr doc; - xmlNodePtr root, children; - - if (*type && g_strcasecmp (type, "application/x-evolution-calendar-summary") != 0) { - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_Bonobo_Persist_WrongDataType, NULL); - return; - } - - bonobo_stream_client_read_string (stream, &str, ev); - if (ev->_major != CORBA_NO_EXCEPTION || str == NULL) { - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_Bonobo_Persist_WrongDataType, NULL); - return; - } - - doc = xmlParseDoc ((xmlChar *) str); - - if (doc == NULL) { - g_warning ("Bad data: %s!", str); - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_Bonobo_Persist_WrongDataType, NULL); - g_free (str); - return; - } - - g_free (str); - root = doc->root; - children = root->childs; - while (children) { - if (strcasecmp (children->name, "showappointments") == 0) { - xml_str = xmlNodeListGetString (doc, children->childs, 1); - if (strcmp (xml_str, "TRUE") == 0) - summary->appointments = TRUE; - else - summary->appointments = FALSE; - xmlFree (xml_str); - - children = children->next; - continue; - } - - if (strcasecmp (children->name, "showtasks") == 0) { - xml_str = xmlNodeListGetString (doc, children->childs, 1); - if (strcmp (xml_str, "TRUE") == 0) - summary->tasks = TRUE; - else - summary->tasks = FALSE; - xmlFree (xml_str); - - children = children->next; - continue; - } - - g_print ("Unknown name: %s\n", children->name); - children = children->next; - } - xmlFreeDoc (doc); - - summary->idle = g_idle_add (generate_html_summary, summary); -} - -static char * -summary_to_string (CalSummary *summary) -{ - xmlChar *out_str; - int out_len = 0; - xmlDocPtr doc; - xmlNsPtr ns; - - doc = xmlNewDoc ("1.0"); - ns = xmlNewGlobalNs (doc, "http://www.helixcode.com", "calendar-summary"); - doc->root = xmlNewDocNode (doc, ns, "calendar-summary", NULL); - - xmlNewChild (doc->root, ns, "showappointments", - summary->appointments ? "TRUE" : "FALSE"); - xmlNewChild (doc->root, ns, "showtasks", summary->tasks ? "TRUE" : "FALSE"); - - xmlDocDumpMemory (doc, &out_str, &out_len); - return out_str; -} - -static void -save_to_stream (BonoboPersistStream *ps, - const Bonobo_Stream stream, - Bonobo_Persist_ContentType type, - gpointer data, - CORBA_Environment *ev) -{ - CalSummary *summary = (CalSummary *) data; - char *str; - - if (*type && g_strcasecmp (type, "application/x-evolution-calendar-summary") != 0) { - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_Bonobo_Persist_WrongDataType, NULL); - return; - } - - str = summary_to_string (summary); - if (str) - bonobo_stream_client_printf (stream, TRUE, ev, str); - xmlFree (str); - - return; -} - -static Bonobo_Persist_ContentTypeList * -content_types (BonoboPersistStream *ps, - void *closure, - CORBA_Environment *ev) -{ - return bonobo_persist_generate_content_types (1, "application/x-evolution-calendar-summary"); -} - -static void -property_dialog_changed (GtkWidget *widget, - CalSummary *summary) -{ - bonobo_property_control_changed (summary->property_control, NULL); -} - -static BonoboControl * -property_dialog (BonoboPropertyControl *property_control, - int page_num, - void *user_data) -{ - BonoboControl *control; - CalSummary *summary = (CalSummary *) user_data; - GtkWidget *container, *vbox; - - container = gtk_frame_new (_("Display")); - gtk_container_set_border_width (GTK_CONTAINER (container), 2); - vbox = gtk_vbox_new (FALSE, 2); - gtk_container_add (GTK_CONTAINER (container), vbox); - - summary->show_appointments = gtk_check_button_new_with_label (_("Show appointments")); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (summary->show_appointments), - summary->appointments); - gtk_signal_connect (GTK_OBJECT (summary->show_appointments), "toggled", - GTK_SIGNAL_FUNC (property_dialog_changed), summary); - gtk_box_pack_start (GTK_BOX (vbox), summary->show_appointments, - TRUE, TRUE, 0); - - summary->show_tasks = gtk_check_button_new_with_label (_("Show tasks")); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (summary->show_tasks), - summary->tasks); - gtk_signal_connect (GTK_OBJECT (summary->show_tasks), "toggled", - GTK_SIGNAL_FUNC (property_dialog_changed), summary); - gtk_box_pack_start (GTK_BOX (vbox), summary->show_tasks, TRUE, TRUE, 0); - gtk_widget_show_all (container); - - control = bonobo_control_new (container); - return control; -} - -static void -property_action (GtkObject *property_control, - int page_num, - Bonobo_PropertyControl_Action action, - CalSummary *summary) -{ - switch (action) { - case Bonobo_PropertyControl_APPLY: - summary->appointments = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (summary->show_appointments)); - summary->tasks = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (summary->show_tasks)); - summary->idle = g_idle_add (generate_html_summary, summary); - break; - - case Bonobo_PropertyControl_HELP: - g_print ("HELP\n"); - break; - - default: - break; - } -} - -BonoboObject * -create_summary_view (ExecutiveSummaryComponentFactory *_factory, - void *closure) -{ - BonoboObject *component, *view; - BonoboPersistStream *stream; - BonoboPropertyBag *bag; - BonoboPropertyControl *property_control; - BonoboEventSource *event_source; - CalSummary *summary; - char *file; - time_t t, day_end; - - file = g_concat_dir_and_file (evolution_dir, "local/Calendar/calendar.ics"); - - /* Create the component object */ - component = executive_summary_component_new (); - - summary = g_new (CalSummary, 1); - summary->component = EXECUTIVE_SUMMARY_COMPONENT (component); - summary->icon = g_strdup ("evolution-calendar.png"); - summary->title = g_strdup ("Things to do"); - summary->client = cal_client_new (); - summary->idle = 0; - summary->appointments = TRUE; - summary->tasks = TRUE; - - t = time (NULL); - day_end = time_day_end (t); - summary->alarm = alarm_add (day_end, alarm_fn, summary, NULL); - - /* Load calendar */ - cal_client_open_calendar (summary->client, file, FALSE); - g_free (file); - - gtk_signal_connect (GTK_OBJECT (summary->client), "cal-opened", - GTK_SIGNAL_FUNC (cal_opened_cb), summary); - gtk_signal_connect (GTK_OBJECT (summary->client), "obj-updated", - GTK_SIGNAL_FUNC (obj_updated_cb), summary); - gtk_signal_connect (GTK_OBJECT (summary->client), "obj-removed", - GTK_SIGNAL_FUNC (obj_removed_cb), summary); - - gtk_signal_connect (GTK_OBJECT (component), "destroy", - GTK_SIGNAL_FUNC (component_destroyed), summary); - - event_source = bonobo_event_source_new (); - - /* HTML view */ - view = executive_summary_html_view_new_full (event_source); - summary->view = EXECUTIVE_SUMMARY_HTML_VIEW (view); - - executive_summary_html_view_set_html (EXECUTIVE_SUMMARY_HTML_VIEW (view), - _("Loading Calendar")); - bonobo_object_add_interface (component, view); - - /* BonoboPropertyBag */ - bag = bonobo_property_bag_new_full (get_property, set_property, - event_source, summary); - bonobo_property_bag_add (bag, "window_title", PROPERTY_TITLE, - BONOBO_ARG_STRING, NULL, - "The title of this component's window", 0); - bonobo_property_bag_add (bag, "window_icon", PROPERTY_ICON, - BONOBO_ARG_STRING, NULL, - "The icon for this component's window", 0); - bonobo_object_add_interface (component, BONOBO_OBJECT (bag)); - - property_control = bonobo_property_control_new_full (property_dialog, - 1, event_source, - summary); - summary->property_control = property_control; - gtk_signal_connect (GTK_OBJECT (property_control), "action", - GTK_SIGNAL_FUNC (property_action), summary); - bonobo_object_add_interface (component, BONOBO_OBJECT (property_control)); - - stream = bonobo_persist_stream_new (load_from_stream, save_to_stream, - NULL, content_types, summary); - bonobo_object_add_interface (component, BONOBO_OBJECT (stream)); - - running_views++; - - return component; -} - -static BonoboObject * -factory_fn (BonoboGenericFactory *generic_factory, - void *closure) -{ - BonoboObject *_factory; - - _factory = executive_summary_component_factory_new (create_summary_view, - NULL); - return _factory; -} - -BonoboGenericFactory * -calendar_summary_factory_init (void) -{ - if (factory != NULL) - return factory; - - factory = bonobo_generic_factory_new (CALENDAR_SUMMARY_ID, factory_fn, - NULL); - - if (factory == NULL) { - g_warning ("Cannot initialise calendar summary factory"); - return NULL; - } - - return factory; -} diff --git a/calendar/gui/calendar-summary.h b/calendar/gui/calendar-summary.h deleted file mode 100644 index cfb92c0697..0000000000 --- a/calendar/gui/calendar-summary.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* calendar-summary.c - * - * Authors: Iain Holmes <iain@ximian.com> - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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. - */ - -#ifndef CALENDAR_SUMMARY_H -#define CALENDAR_SUMMARY_H - -#include <evolution-services/executive-summary-component.h> - -BonoboGenericFactory *calendar_summary_factory_init (void); - -BonoboObject *create_summary_view (ExecutiveSummaryComponentFactory *_factory, - void *closure); - -#endif diff --git a/calendar/gui/check-filled.xpm b/calendar/gui/check-filled.xpm deleted file mode 100644 index c0468fc25b..0000000000 --- a/calendar/gui/check-filled.xpm +++ /dev/null @@ -1,21 +0,0 @@ -/* XPM */ -static const char * check_filled_xpm[] = { -"16 16 2 1", -" c None", -". c #000000", -" ", -" ", -" ............ ", -" . . ", -" . . . ", -" . .. . ", -" . ... . ", -" . . ... . ", -" . .. ... . ", -" . ..... . ", -" . ... . ", -" . . . ", -" . . ", -" ............ ", -" ", -" "}; diff --git a/calendar/gui/comp-util.c b/calendar/gui/comp-util.c deleted file mode 100644 index f1898e914e..0000000000 --- a/calendar/gui/comp-util.c +++ /dev/null @@ -1,58 +0,0 @@ -/* Evolution calendar - Utilities for manipulating CalComponent objects - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "comp-util.h" - - - -/** - * cal_comp_util_add_exdate: - * @comp: A calendar component object. - * @itt: Time for the exception. - * - * Adds an exception date to the current list of EXDATE properties in a calendar - * component object. - **/ -void -cal_comp_util_add_exdate (CalComponent *comp, struct icaltimetype itt) -{ - GSList *list; - CalComponentDateTime *cdt; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - - cal_component_get_exdate_list (comp, &list); - - cdt = g_new (CalComponentDateTime, 1); - cdt->value = g_new (struct icaltimetype, 1); - *cdt->value = itt; - cdt->tzid = NULL; - - list = g_slist_append (list, cdt); - cal_component_set_exdate_list (comp, list); - cal_component_free_exdate_list (list); -} diff --git a/calendar/gui/comp-util.h b/calendar/gui/comp-util.h deleted file mode 100644 index 9c70172aee..0000000000 --- a/calendar/gui/comp-util.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Evolution calendar - Utilities for manipulating CalComponent objects - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef COMP_UTIL_H -#define COMP_UTIL_H - -#include <cal-util/cal-component.h> - -void cal_comp_util_add_exdate (CalComponent *comp, struct icaltimetype itt); - -#endif diff --git a/calendar/gui/component-factory.c b/calendar/gui/component-factory.c deleted file mode 100644 index 5226c2480d..0000000000 --- a/calendar/gui/component-factory.c +++ /dev/null @@ -1,175 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* component-factory.c - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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: Ettore Perazzoli <ettore@ximian.com> - */ - -#include <config.h> -#include <bonobo.h> -#include "evolution-shell-component.h" -#include <executive-summary/evolution-services/executive-summary-component.h> -#include "component-factory.h" -#include "tasks-control-factory.h" -#include "control-factory.h" -#include "calendar-config.h" -#include "calendar-summary.h" -#include "tasks-control.h" -#include "tasks-migrate.h" - - - -#define COMPONENT_FACTORY_ID "OAFIID:GNOME_Evolution_Calendar_ShellComponentFactory" - -static BonoboGenericFactory *factory = NULL; -static BonoboGenericFactory *summary_factory = NULL; -char *evolution_dir; - -static const EvolutionShellComponentFolderType folder_types[] = { - { "calendar", "evolution-calendar.png" }, - { "tasks", "evolution-tasks.png" }, - { NULL, NULL } -}; - - -/* EvolutionShellComponent methods and signals. */ - -static EvolutionShellComponentResult -create_view (EvolutionShellComponent *shell_component, - const char *physical_uri, - const char *type, - BonoboControl **control_return, - void *closure) -{ - BonoboControl *control; - - if (!g_strcasecmp (type, "calendar")) { - control = control_factory_new_control (); - if (!control) - return EVOLUTION_SHELL_COMPONENT_CORBAERROR; - } else if (!g_strcasecmp (type, "tasks")) { - control = tasks_control_new (); - if (!control) - return EVOLUTION_SHELL_COMPONENT_CORBAERROR; - } else { - return EVOLUTION_SHELL_COMPONENT_UNSUPPORTEDTYPE; - } - - bonobo_control_set_property (control, "folder_uri", physical_uri, NULL); - - *control_return = control; - - return EVOLUTION_SHELL_COMPONENT_OK; -} - -static void -create_folder (EvolutionShellComponent *shell_component, - const char *physical_uri, - const char *type, - const GNOME_Evolution_ShellComponentListener listener, - void *closure) -{ - CORBA_Environment ev; - - CORBA_exception_init(&ev); - /* FIXME: I don't think we have to do anything to create a calendar - or tasks folder - the '.ics' files are created automatically when - needed. But I'm not sure - Damon. */ - if (!strcmp(type, "calendar") || !strcmp(type, "tasks")) { - GNOME_Evolution_ShellComponentListener_notifyResult(listener, GNOME_Evolution_ShellComponentListener_OK, &ev); - } else { - GNOME_Evolution_ShellComponentListener_notifyResult(listener, GNOME_Evolution_ShellComponentListener_UNSUPPORTED_TYPE, &ev); - } - CORBA_exception_free(&ev); -} - -static gint owner_count = 0; - -static void -owner_set_cb (EvolutionShellComponent *shell_component, - EvolutionShellClient *shell_client, - const char *evolution_homedir, - gpointer user_data) -{ - static gboolean migrated = FALSE; - - owner_count ++; - evolution_dir = g_strdup (evolution_homedir); - - calendar_config_init (); - - if (!migrated) { - tasks_migrate (); - migrated = TRUE; - } -} - -static void -owner_unset_cb (EvolutionShellComponent *shell_component, - gpointer user_data) -{ - owner_count --; - if (owner_count <= 0) - gtk_main_quit(); -} - - -/* The factory function. */ - -static BonoboObject * -factory_fn (BonoboGenericFactory *factory, - void *closure) -{ - EvolutionShellComponent *shell_component; - - shell_component = evolution_shell_component_new (folder_types, - create_view, - create_folder, - NULL, /* remove_folder_fn */ - NULL, /* copy_folder_fn */ - NULL, /* populate_folder_context_menu_fn */ - NULL /* closure */); - - gtk_signal_connect (GTK_OBJECT (shell_component), "owner_set", - GTK_SIGNAL_FUNC (owner_set_cb), NULL); - gtk_signal_connect (GTK_OBJECT (shell_component), "owner_unset", - GTK_SIGNAL_FUNC (owner_unset_cb), NULL); - - return BONOBO_OBJECT (shell_component); -} - - - -void -component_factory_init (void) -{ - if (factory != NULL && factory != NULL) - return; - - factory = bonobo_generic_factory_new (COMPONENT_FACTORY_ID, factory_fn, NULL); - - summary_factory = calendar_summary_factory_init (); - - if (factory == NULL) - g_error ("Cannot initialize Evolution's calendar component."); - - if (summary_factory == NULL) - g_error ("Cannot initialize Evolution's calendar summary component."); -} diff --git a/calendar/gui/component-factory.h b/calendar/gui/component-factory.h deleted file mode 100644 index d2d570e340..0000000000 --- a/calendar/gui/component-factory.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* component-factory.h - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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: Ettore Perazzoli <ettore@ximian.com> - */ - -#ifndef _COMPONENT_FACTORY_H_ -#define _COMPONENT_FACTORY_H_ - -extern char *evolution_dir; - -void component_factory_init (void); - -#endif /* _COMPONENT_FACTORY_H_ */ diff --git a/calendar/gui/control-factory.c b/calendar/gui/control-factory.c deleted file mode 100644 index 678870da91..0000000000 --- a/calendar/gui/control-factory.c +++ /dev/null @@ -1,186 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* control-factory.c - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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: Ettore Perazzoli <ettore@ximian.com> - */ - -#include <config.h> -#include <glade/glade.h> -#include <bonobo.h> -#include <bonobo/bonobo-control.h> -#include <glade/glade.h> - -#include <liboaf/liboaf.h> - -#include <cal-util/timeutil.h> -#include <gui/gnome-cal.h> -#include <gui/calendar-commands.h> - -#include "control-factory.h" - -#define PROPERTY_CALENDAR_URI "folder_uri" - -#define PROPERTY_CALENDAR_URI_IDX 1 - -#define CONTROL_FACTORY_ID "OAFIID:GNOME_Evolution_Calendar_ControlFactory" - - -CORBA_Environment ev; -CORBA_ORB orb; - - -static void -control_activate_cb (BonoboControl *control, - gboolean activate, - gpointer user_data) -{ - if (activate) - calendar_control_activate (control, user_data); - else - calendar_control_deactivate (control); -} - - -static void -get_prop (BonoboPropertyBag *bag, - BonoboArg *arg, - guint arg_id, - CORBA_Environment *ev, - gpointer user_data) -{ - /*GnomeCalendar *gcal = user_data;*/ - - switch (arg_id) { - - case PROPERTY_CALENDAR_URI_IDX: - /* - if (fb && fb->uri) - BONOBO_ARG_SET_STRING (arg, fb->uri); - else - BONOBO_ARG_SET_STRING (arg, ""); - */ - break; - - default: - g_warning ("Unhandled arg %d\n", arg_id); - } -} - - -static void -set_prop (BonoboPropertyBag *bag, - const BonoboArg *arg, - guint arg_id, - CORBA_Environment *ev, - gpointer user_data) -{ - GnomeCalendar *gcal = user_data; - char *filename; - - switch (arg_id) { - - case PROPERTY_CALENDAR_URI_IDX: - filename = g_strdup_printf ("%s/calendar.ics", - BONOBO_ARG_GET_STRING (arg)); - calendar_set_uri (gcal, filename); - g_free (filename); - break; - - default: - g_warning ("Unhandled arg %d\n", arg_id); - break; - } -} - - -static void -calendar_properties_init (GnomeCalendar *gcal, BonoboControl *control) -{ - BonoboPropertyBag *pbag; - - pbag = bonobo_property_bag_new (get_prop, set_prop, gcal); - - bonobo_property_bag_add (pbag, - PROPERTY_CALENDAR_URI, - PROPERTY_CALENDAR_URI_IDX, - BONOBO_ARG_STRING, - NULL, - _("The URI that the calendar will display"), - 0); - - bonobo_control_set_properties (control, pbag); -} - -/* Callback factory function for calendar controls */ -static BonoboObject * -control_factory_fn (BonoboGenericFactory *Factory, void *data) -{ - BonoboControl *control; - - control = control_factory_new_control (); - - if (control) - return BONOBO_OBJECT (control); - else - return NULL; -} - - -void -control_factory_init (void) -{ - static BonoboGenericFactory *factory = NULL; - - if (factory != NULL) - return; - - factory = bonobo_generic_factory_new (CONTROL_FACTORY_ID, control_factory_fn, NULL); - - if (factory == NULL) - g_error ("I could not register a Calendar control factory."); -} - - -BonoboControl * -control_factory_new_control (void) -{ - BonoboControl *control; - GnomeCalendar *gcal; - - gcal = new_calendar (); - if (!gcal) - return NULL; - - gtk_widget_show (GTK_WIDGET (gcal)); - - control = bonobo_control_new (GTK_WIDGET (gcal)); - if (!control) { - g_message ("control_factory_fn(): could not create the control!"); - return NULL; - } - - calendar_properties_init (gcal, control); - - gtk_signal_connect (GTK_OBJECT (control), "activate", - GTK_SIGNAL_FUNC (control_activate_cb), gcal); - - return control; -} diff --git a/calendar/gui/control-factory.h b/calendar/gui/control-factory.h deleted file mode 100644 index 7170404cda..0000000000 --- a/calendar/gui/control-factory.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* control-factory.c - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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: Ettore Perazzoli <ettore@ximian.com> - */ - -#ifndef _CONTROL_FACTORY_H_ -#define _CONTROL_FACTORY_H_ - -void control_factory_init (void); -BonoboControl *control_factory_new_control (void); - -#endif /* _CONTROL_FACTORY_H_ */ diff --git a/calendar/gui/dialogs/.cvsignore b/calendar/gui/dialogs/.cvsignore deleted file mode 100644 index e995588475..0000000000 --- a/calendar/gui/dialogs/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -.deps -Makefile -Makefile.in diff --git a/calendar/gui/dialogs/Makefile.am b/calendar/gui/dialogs/Makefile.am deleted file mode 100644 index dd9a2b2540..0000000000 --- a/calendar/gui/dialogs/Makefile.am +++ /dev/null @@ -1,35 +0,0 @@ -gladedir = $(datadir)/evolution/glade - -INCLUDES = \ - -DG_LOG_DOMAIN=\"calendar-gui\" \ - -I$(top_srcdir) \ - -I$(top_srcdir)/calendar \ - -I$(top_srcdir)/libical/src/libical \ - -I$(top_builddir)/libical/src/libical \ - -I$(includedir) \ - -DEVOLUTION_DATADIR=\""$(datadir)"\" \ - -DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \ - $(BONOBO_VFS_GNOME_CFLAGS) \ - -DGNOMELOCALEDIR=\""$(localedir)"\" - -noinst_LIBRARIES = libcal-dialogs.a - -libcal_dialogs_a_SOURCES = \ - alarm-notify-dialog.c \ - alarm-notify-dialog.h \ - cal-prefs-dialog.c \ - cal-prefs-dialog.h \ - delete-comp.c \ - delete-comp.h \ - save-comp.c \ - save-comp.h \ - task-editor.c \ - task-editor.h - -glade_DATA = \ - alarm-notify.glade \ - cal-prefs-dialog.glade \ - task-editor-dialog.glade - -EXTRA_DIST = \ - $(glade_DATA) diff --git a/calendar/gui/dialogs/alarm-notify-dialog.c b/calendar/gui/dialogs/alarm-notify-dialog.c deleted file mode 100644 index fbd8c1f097..0000000000 --- a/calendar/gui/dialogs/alarm-notify-dialog.c +++ /dev/null @@ -1,226 +0,0 @@ -/* Evolution calendar - alarm notification dialog - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#include <config.h> -#include <gnome.h> -#include <glade/glade.h> -#include "alarm-notify-dialog.h" - - - -/* The useful contents of the alarm notify dialog */ -typedef struct { - GladeXML *xml; - - GtkWidget *dialog; - GtkWidget *close; - GtkWidget *snooze; - GtkWidget *edit; - GtkWidget *heading; - GtkWidget *summary; - GtkWidget *snooze_time; - - AlarmNotifyFunc func; - gpointer func_data; -} AlarmNotify; - - - -/* Callback used when the notify dialog is destroyed */ -static void -dialog_destroy_cb (GtkObject *object, gpointer data) -{ - AlarmNotify *an; - - an = data; - gtk_object_unref (GTK_OBJECT (an->xml)); - g_free (an); -} - -/* Delete_event handler for the alarm notify dialog */ -static gint -delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data) -{ - AlarmNotify *an; - - an = data; - g_assert (an->func != NULL); - - (* an->func) (ALARM_NOTIFY_CLOSE, -1, an->func_data); - - gtk_widget_destroy (widget); - return TRUE; -} - -/* Callback for the close button */ -static void -close_clicked_cb (GtkWidget *widget, gpointer data) -{ - AlarmNotify *an; - - an = data; - g_assert (an->func != NULL); - - (* an->func) (ALARM_NOTIFY_CLOSE, -1, an->func_data); - - gtk_widget_destroy (an->dialog); -} - -/* Callback for the snooze button */ -static void -snooze_clicked_cb (GtkWidget *widget, gpointer data) -{ - AlarmNotify *an; - int snooze_time; - - an = data; - g_assert (an->func != NULL); - - snooze_time = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (an->snooze_time)); - (* an->func) (ALARM_NOTIFY_SNOOZE, snooze_time, an->func_data); - - gtk_widget_destroy (an->dialog); -} - -/* Callback for the edit button */ -static void -edit_clicked_cb (GtkWidget *widget, gpointer data) -{ - AlarmNotify *an; - - an = data; - g_assert (an->func != NULL); - - (* an->func) (ALARM_NOTIFY_EDIT, -1, an->func_data); - - gtk_widget_destroy (an->dialog); -} - -/** - * alarm_notify_dialog: - * @trigger: Trigger time for the alarm. - * @occur: Occurrence time for the event. - * @comp: Calendar component object which corresponds to the alarm. - * @func: Function to be called when a dialog action is invoked. - * @func_data: Closure data for @func. - * - * Runs the alarm notification dialog. The specified @func will be used to - * notify the client about result of the actions in the dialog. - * - * Return value: TRUE on success, FALSE if the dialog could not be created. - **/ -gboolean -alarm_notify_dialog (time_t trigger, time_t occur, CalComponent *comp, - AlarmNotifyFunc func, gpointer func_data) -{ - AlarmNotify *an; - char buf[256]; - struct tm tm_trigger; - struct tm tm_occur; - CalComponentText summary; - - g_return_val_if_fail (trigger != -1, FALSE); - g_return_val_if_fail (occur != -1, FALSE); - g_return_val_if_fail (comp != NULL, FALSE); - g_return_val_if_fail (IS_CAL_COMPONENT (comp), FALSE); - g_return_val_if_fail (func != NULL, FALSE); - - an = g_new0 (AlarmNotify, 1); - - an->func = func; - an->func_data = func_data; - - an->xml = glade_xml_new (EVOLUTION_GLADEDIR "/alarm-notify.glade", NULL); - if (!an->xml) { - g_message ("alarm_notify_dialog(): Could not load the Glade XML file!"); - g_free (an); - return FALSE; - } - - an->dialog = glade_xml_get_widget (an->xml, "alarm-notify"); - an->close = glade_xml_get_widget (an->xml, "close"); - an->snooze = glade_xml_get_widget (an->xml, "snooze"); - an->edit = glade_xml_get_widget (an->xml, "edit"); - an->heading = glade_xml_get_widget (an->xml, "heading"); - an->summary = glade_xml_get_widget (an->xml, "summary"); - an->snooze_time = glade_xml_get_widget (an->xml, "snooze-time"); - - if (!(an->dialog && an->close && an->snooze && an->edit && an->heading && an->summary - && an->snooze_time)) { - g_message ("alarm_notify_dialog(): Could not find all widgets in Glade file!"); - gtk_object_unref (GTK_OBJECT (an->xml)); - g_free (an); - return FALSE; - } - - gtk_object_set_data (GTK_OBJECT (an->dialog), "alarm-notify", an); - gtk_signal_connect (GTK_OBJECT (an->dialog), "destroy", - GTK_SIGNAL_FUNC (dialog_destroy_cb), an); - - /* Title */ - - /* FIXME: use am_pm_flag or 24-hour time */ - - tm_trigger = *localtime (&trigger); - strftime (buf, sizeof (buf), _("Alarm on %A %b %d %Y %H:%M"), &tm_trigger); - gtk_window_set_title (GTK_WINDOW (an->dialog), buf); - - /* Heading */ - - tm_occur = *localtime (&occur); - strftime (buf, sizeof (buf), - _("Notification about your appointment on %A %b %d %Y %H:%M"), - &tm_occur); - gtk_label_set_text (GTK_LABEL (an->heading), buf); - - /* Summary */ - - cal_component_get_summary (comp, &summary); - - if (summary.value) - gtk_label_set_text (GTK_LABEL (an->summary), summary.value); - else - gtk_label_set_text (GTK_LABEL (an->summary), _("No summary available.")); - - /* Connect actions */ - - gtk_signal_connect (GTK_OBJECT (an->dialog), "delete_event", - GTK_SIGNAL_FUNC (delete_event_cb), - an); - - gtk_signal_connect (GTK_OBJECT (an->close), "clicked", - GTK_SIGNAL_FUNC (close_clicked_cb), - an); - - gtk_signal_connect (GTK_OBJECT (an->snooze), "clicked", - GTK_SIGNAL_FUNC (snooze_clicked_cb), - an); - - gtk_signal_connect (GTK_OBJECT (an->edit), "clicked", - GTK_SIGNAL_FUNC (edit_clicked_cb), - an); - - /* Run! */ - - gtk_widget_show (an->dialog); - return TRUE; -} diff --git a/calendar/gui/dialogs/alarm-notify-dialog.h b/calendar/gui/dialogs/alarm-notify-dialog.h deleted file mode 100644 index f2c938c495..0000000000 --- a/calendar/gui/dialogs/alarm-notify-dialog.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Evolution calendar - alarm notification dialog - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef ALARM_NOTIFY_DIALOG_H -#define ALARM_NOTIFY_DIALOG_H - -#include <time.h> -#include <glib.h> -#include <cal-util/cal-component.h> - - - -typedef enum { - ALARM_NOTIFY_CLOSE, - ALARM_NOTIFY_SNOOZE, - ALARM_NOTIFY_EDIT -} AlarmNotifyResult; - -typedef void (* AlarmNotifyFunc) (AlarmNotifyResult result, int snooze_mins, gpointer data); - -gboolean alarm_notify_dialog (time_t trigger, time_t occur, CalComponent *comp, - AlarmNotifyFunc func, gpointer func_data); - - - -#endif diff --git a/calendar/gui/dialogs/alarm-notify.glade b/calendar/gui/dialogs/alarm-notify.glade deleted file mode 100644 index 41718d0572..0000000000 --- a/calendar/gui/dialogs/alarm-notify.glade +++ /dev/null @@ -1,228 +0,0 @@ -<?xml version="1.0"?> -<GTK-Interface> - -<project> - <name>Evolution Calendar</name> - <program_name>evolution-calendar</program_name> - <directory></directory> - <source_directory>src</source_directory> - <pixmaps_directory>pixmaps</pixmaps_directory> - <language>C</language> - <gnome_support>True</gnome_support> - <gettext_support>True</gettext_support> - <use_widget_names>False</use_widget_names> - <output_main_file>True</output_main_file> - <output_support_files>True</output_support_files> - <output_build_files>True</output_build_files> - <backup_source_files>True</backup_source_files> - <main_source_file>interface.c</main_source_file> - <main_header_file>interface.h</main_header_file> - <handler_source_file>callbacks.c</handler_source_file> - <handler_header_file>callbacks.h</handler_header_file> - <support_source_file>support.c</support_source_file> - <support_header_file>support.h</support_header_file> -</project> - -<widget> - <class>GtkWindow</class> - <name>alarm-notify</name> - <cxx_use_heap>True</cxx_use_heap> - <title></title> - <type>GTK_WINDOW_DIALOG</type> - <position>GTK_WIN_POS_CENTER</position> - <modal>False</modal> - <allow_shrink>False</allow_shrink> - <allow_grow>False</allow_grow> - <auto_shrink>False</auto_shrink> - - <widget> - <class>GtkVBox</class> - <name>vbox2</name> - <border_width>4</border_width> - <cxx_use_heap>True</cxx_use_heap> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - - <widget> - <class>GtkHBox</class> - <name>hbox3</name> - <cxx_use_heap>True</cxx_use_heap> - <homogeneous>False</homogeneous> - <spacing>8</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkVBox</class> - <name>vbox5</name> - <cxx_use_heap>True</cxx_use_heap> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>heading</name> - <cxx_use_heap>True</cxx_use_heap> - <label></label> - <justify>GTK_JUSTIFY_LEFT</justify> - <wrap>True</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>summary</name> - <cxx_use_heap>True</cxx_use_heap> - <label></label> - <justify>GTK_JUSTIFY_LEFT</justify> - <wrap>True</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> - - <widget> - <class>GtkVBox</class> - <name>vbox4</name> - <cxx_use_heap>True</cxx_use_heap> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkButton</class> - <name>close</name> - <cxx_use_heap>True</cxx_use_heap> - <can_focus>True</can_focus> - <label>Close</label> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkButton</class> - <name>snooze</name> - <cxx_use_heap>True</cxx_use_heap> - <can_focus>True</can_focus> - <label>Snooze</label> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkButton</class> - <name>edit</name> - <cxx_use_heap>True</cxx_use_heap> - <can_focus>True</can_focus> - <label>Edit appointment</label> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> - </widget> - - <widget> - <class>GtkHSeparator</class> - <name>hseparator1</name> - <cxx_use_heap>True</cxx_use_heap> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - </widget> - - <widget> - <class>GtkHBox</class> - <name>hbox4</name> - <cxx_use_heap>True</cxx_use_heap> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label4</name> - <cxx_use_heap>True</cxx_use_heap> - <label>Snooze time (minutes)</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkSpinButton</class> - <name>snooze-time</name> - <cxx_use_heap>True</cxx_use_heap> - <can_focus>True</can_focus> - <climb_rate>1</climb_rate> - <digits>0</digits> - <numeric>False</numeric> - <update_policy>GTK_UPDATE_ALWAYS</update_policy> - <snap>False</snap> - <wrap>False</wrap> - <value>5</value> - <lower>1</lower> - <upper>1440</upper> - <step>1</step> - <page>5</page> - <page_size>5</page_size> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> - </widget> -</widget> - -</GTK-Interface> diff --git a/calendar/gui/dialogs/cal-prefs-dialog.c b/calendar/gui/dialogs/cal-prefs-dialog.c deleted file mode 100644 index 11577ffc05..0000000000 --- a/calendar/gui/dialogs/cal-prefs-dialog.c +++ /dev/null @@ -1,454 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 2000, Helix Code, Inc. - * Copyright 2000, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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 - */ - -/* - * CalPrefsDialog - a GtkObject which handles a libglade-loaded dialog - * to edit the calendar preference settings. - */ - -#include <config.h> -#include <glade/glade.h> -#include <gal/util/e-util.h> -#include <e-util/e-dialog-widgets.h> -#include <widgets/misc/e-dateedit.h> -#include "cal-prefs-dialog.h" -#include "../calendar-config.h" -#include "../calendar-commands.h" - - -typedef struct { - /* Glade XML data */ - GladeXML *xml; - - GtkWidget *dialog; - - GtkWidget *working_days[7]; - GtkWidget *week_start_day; - GtkWidget *start_of_day; - GtkWidget *end_of_day; - GtkWidget *use_12_hour; - GtkWidget *use_24_hour; - GtkWidget *time_divisions; - GtkWidget *show_end_times; - GtkWidget *compress_weekend; - GtkWidget *dnav_show_week_no; -} CalPrefsDialogPrivate; - -static const int week_start_day_map[] = { - 1, 2, 3, 4, 5, 6, 0, -1 -}; - -static const int time_division_map[] = { - 60, 30, 15, 10, 5, -1 -}; - -static void cal_prefs_dialog_class_init (CalPrefsDialogClass *class); -static void cal_prefs_dialog_init (CalPrefsDialog *prefs); -static gboolean get_widgets (CalPrefsDialog *prefs); -static void cal_prefs_dialog_destroy (GtkObject *object); -static void cal_prefs_dialog_init_widgets (CalPrefsDialog *prefs); -static void cal_prefs_dialog_button_clicked (GtkWidget *dialog, - gint button, - CalPrefsDialog *prefs); -static void cal_prefs_dialog_use_24_hour_toggled(GtkWidget *button, - CalPrefsDialog *prefs); -static void cal_prefs_dialog_show_config (CalPrefsDialog *prefs); -static void cal_prefs_dialog_update_config (CalPrefsDialog *prefs); - -GtkWidget* cal_prefs_dialog_create_time_edit (void); - -static GtkObjectClass *parent_class; - -E_MAKE_TYPE (cal_prefs_dialog, "CalPrefsDialog", CalPrefsDialog, - cal_prefs_dialog_class_init, cal_prefs_dialog_init, - GTK_TYPE_OBJECT) - - -static void -cal_prefs_dialog_class_init (CalPrefsDialogClass *class) -{ - GtkObjectClass *object_class; - - object_class = (GtkObjectClass *) class; - - parent_class = gtk_type_class (GTK_TYPE_OBJECT); - - object_class->destroy = cal_prefs_dialog_destroy; -} - - -static void -cal_prefs_dialog_init (CalPrefsDialog *prefs) -{ - CalPrefsDialogPrivate *priv; - - priv = g_new0 (CalPrefsDialogPrivate, 1); - prefs->priv = priv; - -} - - -/** - * cal_prefs_dialog_new: - * @Returns: a new #CalPrefsDialog. - * - * Creates a new #CalPrefsDialog. - **/ -CalPrefsDialog * -cal_prefs_dialog_new (void) -{ - CalPrefsDialog *prefs; - - prefs = CAL_PREFS_DIALOG (gtk_type_new (cal_prefs_dialog_get_type ())); - return cal_prefs_dialog_construct (prefs); -} - - -/** - * cal_prefs_dialog_construct: - * @prefs: A #CalPrefsDialog. - * - * Constructs a task editor by loading its Glade XML file. - * - * Return value: The same object as @prefs, or NULL if the widgets could not be - * created. In the latter case, the task editor will automatically be - * destroyed. - **/ -CalPrefsDialog * -cal_prefs_dialog_construct (CalPrefsDialog *prefs) -{ - CalPrefsDialogPrivate *priv; - - g_return_val_if_fail (IS_CAL_PREFS_DIALOG (prefs), NULL); - - priv = prefs->priv; - - /* Load the content widgets */ - - priv->xml = glade_xml_new (EVOLUTION_GLADEDIR "/cal-prefs-dialog.glade", NULL); - if (!priv->xml) { - g_message ("cal_prefs_dialog_construct(): Could not load the Glade XML file!"); - goto error; - } - - if (!get_widgets (prefs)) { - g_message ("cal_prefs_dialog_construct(): Could not find all widgets in the XML file!"); - goto error; - } - - cal_prefs_dialog_init_widgets (prefs); - - cal_prefs_dialog_show_config (prefs); - - gtk_widget_show (priv->dialog); - - return prefs; - - error: - - gtk_object_unref (GTK_OBJECT (prefs)); - return NULL; -} - - -/* Gets the widgets from the XML file and returns if they are all available. - */ -static gboolean -get_widgets (CalPrefsDialog *prefs) -{ - CalPrefsDialogPrivate *priv; - - priv = prefs->priv; - -#define GW(name) glade_xml_get_widget (priv->xml, name) - - priv->dialog = GW ("cal-prefs-dialog"); - - /* The indices must match the mktime() values. */ - priv->working_days[0] = GW ("sun_button"); - priv->working_days[1] = GW ("mon_button"); - priv->working_days[2] = GW ("tue_button"); - priv->working_days[3] = GW ("wed_button"); - priv->working_days[4] = GW ("thu_button"); - priv->working_days[5] = GW ("fri_button"); - priv->working_days[6] = GW ("sat_button"); - - priv->week_start_day = GW ("first_day_of_week"); - priv->start_of_day = GW ("start_of_day"); - priv->end_of_day = GW ("end_of_day"); - priv->use_12_hour = GW ("use_12_hour"); - priv->use_24_hour = GW ("use_24_hour"); - priv->time_divisions = GW ("time_divisions"); - priv->show_end_times = GW ("show_end_times"); - priv->compress_weekend = GW ("compress_weekend"); - priv->dnav_show_week_no = GW ("dnav_show_week_no"); - -#undef GW - - return (priv->dialog - && priv->working_days[0] - && priv->working_days[1] - && priv->working_days[2] - && priv->working_days[3] - && priv->working_days[4] - && priv->working_days[5] - && priv->working_days[6] - && priv->week_start_day - && priv->start_of_day - && priv->end_of_day - && priv->use_12_hour - && priv->use_24_hour - && priv->time_divisions - && priv->show_end_times - && priv->compress_weekend - && priv->dnav_show_week_no); -} - - -static void -cal_prefs_dialog_destroy (GtkObject *object) -{ - CalPrefsDialog *prefs; - CalPrefsDialogPrivate *priv; - - g_return_if_fail (IS_CAL_PREFS_DIALOG (object)); - - prefs = CAL_PREFS_DIALOG (object); - priv = prefs->priv; - - - g_free (priv); - prefs->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - -/* Called by libglade to create our custom EDateEdit widgets. */ -GtkWidget * -cal_prefs_dialog_create_time_edit (void) -{ - GtkWidget *dedit; - - dedit = e_date_edit_new (); - - e_date_edit_set_time_popup_range (E_DATE_EDIT (dedit), 0, 24); - e_date_edit_set_show_date (E_DATE_EDIT (dedit), FALSE); - - return dedit; -} - - -void -cal_prefs_dialog_show (CalPrefsDialog *prefs) -{ - CalPrefsDialogPrivate *priv; - - g_return_if_fail (IS_CAL_PREFS_DIALOG (prefs)); - - priv = prefs->priv; - - /* If the dialog is already show just raise it, otherwise refresh the - config settings and show it. */ - if (GTK_WIDGET_MAPPED (priv->dialog)) { - gdk_window_raise (priv->dialog->window); - } else { - cal_prefs_dialog_show_config (prefs); - gtk_widget_show (priv->dialog); - } -} - - -/* Connects any necessary signal handlers. */ -static void -cal_prefs_dialog_init_widgets (CalPrefsDialog *prefs) -{ - CalPrefsDialogPrivate *priv; - - priv = prefs->priv; - - gtk_signal_connect (GTK_OBJECT (priv->dialog), "clicked", - GTK_SIGNAL_FUNC (cal_prefs_dialog_button_clicked), - prefs); - - gtk_signal_connect (GTK_OBJECT (priv->use_24_hour), "toggled", - GTK_SIGNAL_FUNC (cal_prefs_dialog_use_24_hour_toggled), - prefs); -} - - -static void -cal_prefs_dialog_button_clicked (GtkWidget *dialog, - gint button, - CalPrefsDialog *prefs) -{ - CalPrefsDialogPrivate *priv; - - g_return_if_fail (IS_CAL_PREFS_DIALOG (prefs)); - - priv = prefs->priv; - - /* OK & Apply buttons update the config settings. */ - if (button == 0 || button == 1) - cal_prefs_dialog_update_config (prefs); - - /* OK & Close buttons close the dialog. */ - if (button == 0 || button == 2) - gtk_widget_hide (priv->dialog); -} - - -static void -cal_prefs_dialog_use_24_hour_toggled (GtkWidget *button, - CalPrefsDialog *prefs) -{ - CalPrefsDialogPrivate *priv; - gboolean use_24_hour; - - priv = prefs->priv; - - use_24_hour = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->use_24_hour)); - - e_date_edit_set_use_24_hour_format (E_DATE_EDIT (priv->start_of_day), - use_24_hour); - e_date_edit_set_use_24_hour_format (E_DATE_EDIT (priv->end_of_day), - use_24_hour); -} - - -/* Shows the current config settings in the dialog. */ -static void -cal_prefs_dialog_show_config (CalPrefsDialog *prefs) -{ - CalPrefsDialogPrivate *priv; - CalWeekdays working_days; - gint mask, day, week_start_day, time_divisions; - - priv = prefs->priv; - - /* Working Days. */ - working_days = calendar_config_get_working_days (); - mask = 1 << 0; - for (day = 0; day < 7; day++) { - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->working_days[day]), (working_days & mask) ? TRUE : FALSE); - mask <<= 1; - } - - /* Week Start Day. */ - week_start_day = calendar_config_get_week_start_day (); - e_dialog_option_menu_set (priv->week_start_day, week_start_day, - week_start_day_map); - - /* Start of Day. */ - e_date_edit_set_time_of_day (E_DATE_EDIT (priv->start_of_day), - calendar_config_get_day_start_hour (), - calendar_config_get_day_start_minute ()); - - /* End of Day. */ - e_date_edit_set_time_of_day (E_DATE_EDIT (priv->end_of_day), - calendar_config_get_day_end_hour (), - calendar_config_get_day_end_minute ()); - - /* 12/24 Hour Format. */ - if (calendar_config_get_24_hour_format ()) - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->use_24_hour), TRUE); - else - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->use_12_hour), TRUE); - - /* Time Divisions. */ - time_divisions = calendar_config_get_time_divisions (); - e_dialog_option_menu_set (priv->time_divisions, time_divisions, - time_division_map); - - /* Show Appointment End Times. */ - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->show_end_times), - calendar_config_get_show_event_end ()); - - /* Compress Weekend. */ - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->compress_weekend), calendar_config_get_compress_weekend ()); - - /* Date Navigator - Show Week Numbers. */ - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->dnav_show_week_no), calendar_config_get_dnav_show_week_no ()); -} - - -/* Updates the config values based on the settings in the dialog. */ -static void -cal_prefs_dialog_update_config (CalPrefsDialog *prefs) -{ - CalPrefsDialogPrivate *priv; - CalWeekdays working_days; - gint mask, day, week_start_day, time_divisions, hour, minute; - - priv = prefs->priv; - - /* Working Days. */ - working_days = 0; - mask = 1 << 0; - for (day = 0; day < 7; day++) { - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->working_days[day]))) - working_days |= mask; - mask <<= 1; - } - calendar_config_set_working_days (working_days); - - /* Week Start Day. */ - week_start_day = e_dialog_option_menu_get (priv->week_start_day, - week_start_day_map); - calendar_config_set_week_start_day (week_start_day); - - /* Start of Day. */ - e_date_edit_get_time_of_day (E_DATE_EDIT (priv->start_of_day), - &hour, &minute); - calendar_config_set_day_start_hour (hour); - calendar_config_set_day_start_minute (minute); - - /* End of Day. */ - e_date_edit_get_time_of_day (E_DATE_EDIT (priv->end_of_day), - &hour, &minute); - calendar_config_set_day_end_hour (hour); - calendar_config_set_day_end_minute (minute); - - /* 12/24 Hour Format. */ - calendar_config_set_24_hour_format (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->use_24_hour))); - - /* Time Divisions. */ - time_divisions = e_dialog_option_menu_get (priv->time_divisions, - time_division_map); - calendar_config_set_time_divisions (time_divisions); - - /* Show Appointment End Times. */ - calendar_config_set_show_event_end (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->show_end_times))); - - /* Compress Weekend. */ - calendar_config_set_compress_weekend (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->compress_weekend))); - - /* Date Navigator - Show Week Numbers. */ - calendar_config_set_dnav_show_week_no (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->dnav_show_week_no))); - - calendar_config_write (); - update_all_config_settings (); -} diff --git a/calendar/gui/dialogs/cal-prefs-dialog.glade b/calendar/gui/dialogs/cal-prefs-dialog.glade deleted file mode 100644 index f6eccb163d..0000000000 --- a/calendar/gui/dialogs/cal-prefs-dialog.glade +++ /dev/null @@ -1,1241 +0,0 @@ -<?xml version="1.0"?> -<GTK-Interface> - -<project> - <name>preferences</name> - <program_name>preferences</program_name> - <directory></directory> - <source_directory>src</source_directory> - <pixmaps_directory>pixmaps</pixmaps_directory> - <language>C</language> - <gnome_support>True</gnome_support> - <gettext_support>True</gettext_support> -</project> - -<widget> - <class>GnomeDialog</class> - <name>cal-prefs-dialog</name> - <title>Calendar Preferences</title> - <type>GTK_WINDOW_TOPLEVEL</type> - <position>GTK_WIN_POS_NONE</position> - <modal>False</modal> - <allow_shrink>False</allow_shrink> - <allow_grow>False</allow_grow> - <auto_shrink>False</auto_shrink> - <auto_close>False</auto_close> - <hide_on_close>True</hide_on_close> - - <widget> - <class>GtkVBox</class> - <child_name>GnomeDialog:vbox</child_name> - <name>vbox1</name> - <homogeneous>False</homogeneous> - <spacing>8</spacing> - <child> - <padding>4</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkHButtonBox</class> - <child_name>GnomeDialog:action_area</child_name> - <name>hbuttonbox1</name> - <layout_style>GTK_BUTTONBOX_END</layout_style> - <spacing>8</spacing> - <child_min_width>85</child_min_width> - <child_min_height>27</child_min_height> - <child_ipad_x>7</child_ipad_x> - <child_ipad_y>0</child_ipad_y> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - <pack>GTK_PACK_END</pack> - </child> - - <widget> - <class>GtkButton</class> - <name>button1</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <stock_button>GNOME_STOCK_BUTTON_OK</stock_button> - </widget> - - <widget> - <class>GtkButton</class> - <name>button2</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <stock_button>GNOME_STOCK_BUTTON_APPLY</stock_button> - </widget> - - <widget> - <class>GtkButton</class> - <name>button3</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <stock_button>GNOME_STOCK_BUTTON_CLOSE</stock_button> - </widget> - </widget> - - <widget> - <class>GtkNotebook</class> - <name>notebook1</name> - <can_focus>True</can_focus> - <show_tabs>True</show_tabs> - <show_border>True</show_border> - <tab_pos>GTK_POS_TOP</tab_pos> - <scrollable>False</scrollable> - <tab_hborder>2</tab_hborder> - <tab_vborder>2</tab_vborder> - <popup_enable>False</popup_enable> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkVBox</class> - <name>vbox8</name> - <border_width>4</border_width> - <homogeneous>False</homogeneous> - <spacing>6</spacing> - - <widget> - <class>GtkFrame</class> - <name>frame9</name> - <label>Work week</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkVBox</class> - <name>vbox9</name> - <border_width>4</border_width> - <homogeneous>False</homogeneous> - <spacing>3</spacing> - - <widget> - <class>GtkHBox</class> - <name>hbox8</name> - <homogeneous>True</homogeneous> - <spacing>0</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkCheckButton</class> - <name>mon_button</name> - <can_focus>True</can_focus> - <label>Mon</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - </widget> - - <widget> - <class>GtkCheckButton</class> - <name>tue_button</name> - <can_focus>True</can_focus> - <label>Tue</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - </widget> - - <widget> - <class>GtkCheckButton</class> - <name>wed_button</name> - <can_focus>True</can_focus> - <label>Wed</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - </widget> - - <widget> - <class>GtkCheckButton</class> - <name>thu_button</name> - <can_focus>True</can_focus> - <label>Thu</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - </widget> - - <widget> - <class>GtkCheckButton</class> - <name>fri_button</name> - <can_focus>True</can_focus> - <label>Fri</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - </widget> - - <widget> - <class>GtkCheckButton</class> - <name>sat_button</name> - <can_focus>True</can_focus> - <label>Sat</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - </widget> - - <widget> - <class>GtkCheckButton</class> - <name>sun_button</name> - <can_focus>True</can_focus> - <label>Sun</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - </widget> - </widget> - - <widget> - <class>GtkHBox</class> - <name>hbox9</name> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label16</name> - <label>First day of week:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkOptionMenu</class> - <name>first_day_of_week</name> - <can_focus>True</can_focus> - <items>Monday -Tuesday -Wednesday -Thursday -Friday -Saturday -Sunday -</items> - <initial_choice>0</initial_choice> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> - - <widget> - <class>GtkHBox</class> - <name>hbox11</name> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label17</name> - <label>Start of day:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>Custom</class> - <name>start_of_day</name> - <creation_function>cal_prefs_dialog_create_time_edit</creation_function> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Tue, 10 Oct 2000 15:12:12 GMT</last_modification_time> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label18</name> - <label>End of day:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>Custom</class> - <name>end_of_day</name> - <creation_function>cal_prefs_dialog_create_time_edit</creation_function> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Tue, 10 Oct 2000 15:12:21 GMT</last_modification_time> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - </widget> - </widget> - </widget> - </widget> - - <widget> - <class>GtkFrame</class> - <name>frame10</name> - <label>Display options</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkTable</class> - <name>table4</name> - <border_width>4</border_width> - <rows>4</rows> - <columns>3</columns> - <homogeneous>False</homogeneous> - <row_spacing>0</row_spacing> - <column_spacing>4</column_spacing> - - <widget> - <class>GtkLabel</class> - <name>label19</name> - <label>Time divisions:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>7.45058e-09</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label20</name> - <label>Time format:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkCheckButton</class> - <name>show_end_times</name> - <can_focus>True</can_focus> - <label>Show appointment end times</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <child> - <left_attach>0</left_attach> - <right_attach>3</right_attach> - <top_attach>2</top_attach> - <bottom_attach>3</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkCheckButton</class> - <name>compress_weekend</name> - <can_focus>True</can_focus> - <label>Compress weekends</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <child> - <left_attach>0</left_attach> - <right_attach>3</right_attach> - <top_attach>3</top_attach> - <bottom_attach>4</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkHBox</class> - <name>hbox10</name> - <homogeneous>True</homogeneous> - <spacing>4</spacing> - <child> - <left_attach>1</left_attach> - <right_attach>3</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkRadioButton</class> - <name>use_12_hour</name> - <can_focus>True</can_focus> - <label>12 hour (am/pm)</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <group>time_format_group</group> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - </widget> - - <widget> - <class>GtkRadioButton</class> - <name>use_24_hour</name> - <can_focus>True</can_focus> - <label>24 hour</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <group>time_format_group</group> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - </widget> - </widget> - - <widget> - <class>GtkAlignment</class> - <name>alignment4</name> - <xalign>7.45058e-09</xalign> - <yalign>0.5</yalign> - <xscale>0</xscale> - <yscale>1</yscale> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - - <widget> - <class>GtkOptionMenu</class> - <name>time_divisions</name> - <can_focus>True</can_focus> - <items>60 minutes -30 minutes -15 minutes -10 minutes -05 minutes -</items> - <initial_choice>0</initial_choice> - </widget> - </widget> - </widget> - </widget> - - <widget> - <class>GtkFrame</class> - <name>frame11</name> - <label>Date navigator options</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkCheckButton</class> - <name>dnav_show_week_no</name> - <border_width>4</border_width> - <can_focus>True</can_focus> - <label>Show week numbers</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - </widget> - </widget> - </widget> - - <widget> - <class>GtkLabel</class> - <child_name>Notebook:tab</child_name> - <name>label7</name> - <label>Calendar</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - - <widget> - <class>GtkVBox</class> - <name>vbox3</name> - <border_width>4</border_width> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - - <widget> - <class>GtkHBox</class> - <name>hbox4</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkFrame</class> - <name>frame3</name> - <label>Show</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkVBox</class> - <name>vbox4</name> - <border_width>4</border_width> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - - <widget> - <class>GtkCheckButton</class> - <name>checkbutton1</name> - <can_focus>True</can_focus> - <label>Due Date</label> - <active>True</active> - <draw_indicator>True</draw_indicator> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkCheckButton</class> - <name>checkbutton2</name> - <can_focus>True</can_focus> - <label>Time Until Due</label> - <active>True</active> - <draw_indicator>True</draw_indicator> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkCheckButton</class> - <name>checkbutton3</name> - <can_focus>True</can_focus> - <label>Priority</label> - <active>True</active> - <draw_indicator>True</draw_indicator> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> - </widget> - - <widget> - <class>GtkFrame</class> - <name>frame4</name> - <label>Highlight</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkVBox</class> - <name>vbox5</name> - <border_width>4</border_width> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - - <widget> - <class>GtkCheckButton</class> - <name>checkbutton4</name> - <can_focus>True</can_focus> - <label>Overdue Items</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkCheckButton</class> - <name>checkbutton5</name> - <can_focus>True</can_focus> - <label>Items Due Today</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkCheckButton</class> - <name>checkbutton6</name> - <can_focus>True</can_focus> - <label>Items Not Yet Due</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> - </widget> - </widget> - - <widget> - <class>GtkFrame</class> - <name>frame5</name> - <label>Colors</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkTable</class> - <name>table3</name> - <border_width>4</border_width> - <rows>3</rows> - <columns>2</columns> - <homogeneous>False</homogeneous> - <row_spacing>4</row_spacing> - <column_spacing>4</column_spacing> - - <widget> - <class>GnomeColorPicker</class> - <name>colorpicker1</name> - <can_focus>True</can_focus> - <dither>True</dither> - <use_alpha>False</use_alpha> - <title>Pick a color</title> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>False</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GnomeColorPicker</class> - <name>colorpicker2</name> - <can_focus>True</can_focus> - <dither>True</dither> - <use_alpha>False</use_alpha> - <title>Pick a color</title> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>False</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GnomeColorPicker</class> - <name>colorpicker3</name> - <can_focus>True</can_focus> - <dither>True</dither> - <use_alpha>False</use_alpha> - <title>Pick a color</title> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>2</top_attach> - <bottom_attach>3</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>False</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkAlignment</class> - <name>alignment1</name> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xscale>1</xscale> - <yscale>1</yscale> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label8</name> - <label>Items Not Yet Due:</label> - <justify>GTK_JUSTIFY_RIGHT</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - </widget> - - <widget> - <class>GtkAlignment</class> - <name>alignment2</name> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xscale>1</xscale> - <yscale>1</yscale> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label9</name> - <label>Items Due Today:</label> - <justify>GTK_JUSTIFY_RIGHT</justify> - <wrap>True</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - </widget> - - <widget> - <class>GtkAlignment</class> - <name>alignment3</name> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xscale>1</xscale> - <yscale>1</yscale> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>2</top_attach> - <bottom_attach>3</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label10</name> - <label>Overdue Items:</label> - <justify>GTK_JUSTIFY_RIGHT</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - </widget> - </widget> - </widget> - </widget> - - <widget> - <class>GtkLabel</class> - <child_name>Notebook:tab</child_name> - <name>label11</name> - <label>TaskPad</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - - <widget> - <class>GtkVBox</class> - <name>vbox6</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - - <widget> - <class>GtkFrame</class> - <name>frame6</name> - <border_width>4</border_width> - <label>Defaults</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>4</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkHBox</class> - <name>hbox5</name> - <border_width>4</border_width> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - - <widget> - <class>GtkCheckButton</class> - <name>checkbutton7</name> - <border_width>2</border_width> - <can_focus>True</can_focus> - <label>Remind me of all appointments</label> - <active>True</active> - <draw_indicator>True</draw_indicator> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkSpinButton</class> - <name>spinbutton1</name> - <can_focus>True</can_focus> - <climb_rate>1</climb_rate> - <digits>0</digits> - <numeric>False</numeric> - <update_policy>GTK_UPDATE_ALWAYS</update_policy> - <snap>False</snap> - <wrap>False</wrap> - <value>1</value> - <lower>0</lower> - <upper>100</upper> - <step>1</step> - <page>10</page> - <page_size>10</page_size> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label12</name> - <label>minutes before they occur.</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>3</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> - </widget> - - <widget> - <class>GtkFrame</class> - <name>frame7</name> - <border_width>4</border_width> - <label>Visual Alarms</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>4</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkCheckButton</class> - <name>checkbutton8</name> - <border_width>4</border_width> - <can_focus>True</can_focus> - <label>Beep when alarm windows appear.</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - </widget> - </widget> - - <widget> - <class>GtkFrame</class> - <name>frame8</name> - <border_width>4</border_width> - <label>Audio Alarms</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>4</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkVBox</class> - <name>vbox7</name> - <border_width>4</border_width> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - - <widget> - <class>GtkHBox</class> - <name>hbox6</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkCheckButton</class> - <name>checkbutton9</name> - <can_focus>True</can_focus> - <label>Alarms timeout after</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkSpinButton</class> - <name>spinbutton2</name> - <can_focus>True</can_focus> - <climb_rate>1</climb_rate> - <digits>0</digits> - <numeric>False</numeric> - <update_policy>GTK_UPDATE_ALWAYS</update_policy> - <snap>False</snap> - <wrap>False</wrap> - <value>5</value> - <lower>0</lower> - <upper>100</upper> - <step>1</step> - <page>10</page> - <page_size>10</page_size> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label13</name> - <label>seconds.</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> - - <widget> - <class>GtkHBox</class> - <name>hbox7</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkCheckButton</class> - <name>checkbutton10</name> - <can_focus>True</can_focus> - <label>Enable snoozing for</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkSpinButton</class> - <name>spinbutton3</name> - <can_focus>True</can_focus> - <climb_rate>1</climb_rate> - <digits>0</digits> - <numeric>False</numeric> - <update_policy>GTK_UPDATE_ALWAYS</update_policy> - <snap>False</snap> - <wrap>False</wrap> - <value>600</value> - <lower>0</lower> - <upper>1000</upper> - <step>1</step> - <page>10</page> - <page_size>10</page_size> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label14</name> - <label>seconds.</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> - </widget> - </widget> - </widget> - - <widget> - <class>GtkLabel</class> - <child_name>Notebook:tab</child_name> - <name>label15</name> - <label>Reminders</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - </widget> - </widget> -</widget> - -</GTK-Interface> diff --git a/calendar/gui/dialogs/cal-prefs-dialog.h b/calendar/gui/dialogs/cal-prefs-dialog.h deleted file mode 100644 index 9d744f806d..0000000000 --- a/calendar/gui/dialogs/cal-prefs-dialog.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 2000, Helix Code, Inc. - * Copyright 2000, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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 - */ - -/* - * CalPrefsDialog - a GtkObject which handles a libglade-loaded dialog - * to edit the calendar preference settings. - */ - -#ifndef _CAL_PREFS_DIALOG_H_ -#define _CAL_PREFS_DIALOG_H_ - -#include <gtk/gtkobject.h> -#include <libgnome/gnome-defs.h> - -BEGIN_GNOME_DECLS - - -#define CAL_PREFS_DIALOG(obj) GTK_CHECK_CAST (obj, cal_prefs_dialog_get_type (), CalPrefsDialog) -#define CAL_PREFS_DIALOG_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, cal_prefs_dialog_get_type (), CalPrefsDialogClass) -#define IS_CAL_PREFS_DIALOG(obj) GTK_CHECK_TYPE (obj, cal_prefs_dialog_get_type ()) - - -typedef struct _CalPrefsDialog CalPrefsDialog; -typedef struct _CalPrefsDialogClass CalPrefsDialogClass; - -struct _CalPrefsDialog -{ - GtkObject object; - - /* Private data */ - gpointer priv; -}; - -struct _CalPrefsDialogClass -{ - GtkObjectClass parent_class; -}; - - -GtkType cal_prefs_dialog_get_type (void); -CalPrefsDialog* cal_prefs_dialog_construct (CalPrefsDialog *prefs); -CalPrefsDialog* cal_prefs_dialog_new (void); - -void cal_prefs_dialog_show (CalPrefsDialog *prefs); - -END_GNOME_DECLS - -#endif /* _CAL_PREFS_DIALOG_H_ */ diff --git a/calendar/gui/dialogs/delete-comp.c b/calendar/gui/dialogs/delete-comp.c deleted file mode 100644 index bd70f6b261..0000000000 --- a/calendar/gui/dialogs/delete-comp.c +++ /dev/null @@ -1,113 +0,0 @@ -/* Evolution calendar - Delete calendar component dialog - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <glib.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <libgnomeui/gnome-dialog.h> -#include <libgnomeui/gnome-dialog-util.h> -#include <libgnomeui/gnome-uidefs.h> -#include <gal/widgets/e-unicode.h> -#include "delete-comp.h" - - - -/** - * delete_component_dialog: - * @comp: A calendar component. - * @widget: A widget to use as a basis for conversion from UTF8 into font - * encoding. - * - * Pops up a dialog box asking the user whether he wants to delete a particular - * calendar component. - * - * Return value: TRUE if the user clicked Yes, FALSE otherwise. - **/ -gboolean -delete_component_dialog (CalComponent *comp, GtkWidget *widget) -{ - CalComponentText summary; - CalComponentVType vtype; - char *str, *tmp; - GtkWidget *dialog; - - g_return_val_if_fail (comp != NULL, FALSE); - g_return_val_if_fail (IS_CAL_COMPONENT (comp), FALSE); - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); - - vtype = cal_component_get_vtype (comp); - cal_component_get_summary (comp, &summary); - - switch (vtype) { - case CAL_COMPONENT_EVENT: - if (summary.value) - str = g_strdup_printf (_("Are you sure you want to delete the appointment " - "`%s'?"), summary.value); - else - str = g_strdup (_("Are you sure you want to delete this " - "untitled appointment?")); - break; - - case CAL_COMPONENT_TODO: - if (summary.value) - str = g_strdup_printf (_("Are you sure you want to delete the task " - "`%s'?"), summary.value); - else - str = g_strdup (_("Are you sure you want to delete this " - "untitled task?")); - break; - - case CAL_COMPONENT_JOURNAL: - if (summary.value) - str = g_strdup_printf (_("Are you sure you want to delete the journal entry " - "`%s'?"), summary.value); - else - str = g_strdup (_("Are you sure want to delete this " - "untitled journal entry?")); - break; - - default: - g_message ("delete_component_dialog(): Cannot handle object of type %d", vtype); - return FALSE; - } - - tmp = e_utf8_to_gtk_string (widget, str); - g_free (str); - - if (tmp) { - dialog = gnome_question_dialog_modal (tmp, NULL, NULL); - g_free (tmp); - - if (gnome_dialog_run (GNOME_DIALOG (dialog)) == GNOME_YES) - return TRUE; - else - return FALSE; - } else { - g_message ("delete_component_dialog(): Could not convert the string from UTF8"); - return FALSE; - } -} diff --git a/calendar/gui/dialogs/delete-comp.h b/calendar/gui/dialogs/delete-comp.h deleted file mode 100644 index d7243e75c4..0000000000 --- a/calendar/gui/dialogs/delete-comp.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Evolution calendar - Delete calendar component dialog - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef DELETE_COMP_H -#define DELETE_COMP_H - -#include <gtk/gtkwidget.h> -#include <cal-util/cal-component.h> - -gboolean delete_component_dialog (CalComponent *comp, GtkWidget *widget); - -#endif diff --git a/calendar/gui/dialogs/save-comp.c b/calendar/gui/dialogs/save-comp.c deleted file mode 100644 index c36e98cb5a..0000000000 --- a/calendar/gui/dialogs/save-comp.c +++ /dev/null @@ -1,63 +0,0 @@ -/* Evolution calendar - Delete calendar component dialog - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <glib.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <libgnomeui/gnome-messagebox.h> -#include <libgnomeui/gnome-stock.h> -#include <gal/widgets/e-unicode.h> -#include "save-comp.h" - - - -/** - * save_component_dialog: - * @parent: Window to use as the transient dialog's parent. - * - * Pops up a dialog box asking the user whether he wants to save changes for - * a calendar component. - * - * Return value: TRUE if changes shold be saved, FALSE otherwise. - **/ -gint -save_component_dialog (GtkWindow *parent) -{ - GtkWidget *dialog; - - dialog = gnome_message_box_new (_("Do you want to save changes?"), - GNOME_MESSAGE_BOX_QUESTION, - GNOME_STOCK_BUTTON_YES, - GNOME_STOCK_BUTTON_NO, - GNOME_STOCK_BUTTON_CANCEL, - NULL); - - gnome_dialog_set_default (GNOME_DIALOG (dialog), 0); - gnome_dialog_grab_focus (GNOME_DIALOG (dialog), 0); - gnome_dialog_set_parent (GNOME_DIALOG (dialog), parent); - - return gnome_dialog_run_and_close (GNOME_DIALOG (dialog)); -} diff --git a/calendar/gui/dialogs/save-comp.h b/calendar/gui/dialogs/save-comp.h deleted file mode 100644 index 2fb8e2c2a8..0000000000 --- a/calendar/gui/dialogs/save-comp.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Evolution calendar - Delete calendar component dialog - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef SAVE_COMP_H -#define SAVE_COMP_H - -gint save_component_dialog (GtkWindow *parent); - -#endif diff --git a/calendar/gui/dialogs/task-editor-dialog.glade b/calendar/gui/dialogs/task-editor-dialog.glade deleted file mode 100644 index ae7ea9681a..0000000000 --- a/calendar/gui/dialogs/task-editor-dialog.glade +++ /dev/null @@ -1,695 +0,0 @@ -<?xml version="1.0"?> -<GTK-Interface> - -<project> - <name>task-editor-dialog</name> - <program_name>task-editor-dialog</program_name> - <directory></directory> - <source_directory>src</source_directory> - <pixmaps_directory>pixmaps</pixmaps_directory> - <language>C</language> - <gnome_support>True</gnome_support> - <gettext_support>True</gettext_support> -</project> - -<widget> - <class>GnomePropertyBox</class> - <name>task-editor-dialog</name> - <visible>False</visible> - <position>GTK_WIN_POS_NONE</position> - <modal>False</modal> - <allow_shrink>False</allow_shrink> - <allow_grow>False</allow_grow> - <auto_shrink>False</auto_shrink> - - <widget> - <class>GtkNotebook</class> - <child_name>GnomeDock:contents</child_name> - <name>notebook1</name> - <border_width>2</border_width> - <can_focus>True</can_focus> - <show_tabs>True</show_tabs> - <show_border>True</show_border> - <tab_pos>GTK_POS_TOP</tab_pos> - <scrollable>False</scrollable> - <tab_hborder>2</tab_hborder> - <tab_vborder>2</tab_vborder> - <popup_enable>False</popup_enable> - - <widget> - <class>GtkVBox</class> - <name>vbox1</name> - <border_width>4</border_width> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - - <widget> - <class>GtkTable</class> - <name>table3</name> - <rows>1</rows> - <columns>2</columns> - <homogeneous>False</homogeneous> - <row_spacing>4</row_spacing> - <column_spacing>4</column_spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label3</name> - <label>Su_mmary:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <default_focus_target>summary</default_focus_target> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>False</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>summary</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - </widget> - - <widget> - <class>GtkFrame</class> - <name>frame2</name> - <label>Date & Time</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkHBox</class> - <name>hbox4</name> - <border_width>4</border_width> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - - <widget> - <class>GtkTable</class> - <name>table1</name> - <rows>2</rows> - <columns>2</columns> - <homogeneous>False</homogeneous> - <row_spacing>2</row_spacing> - <column_spacing>4</column_spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label6</name> - <label>Sta_rt Date:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label5</name> - <label>_Due Date:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>Custom</class> - <name>due-date</name> - <creation_function>task_editor_create_date_edit</creation_function> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Sun, 10 Sep 2000 17:32:18 GMT</last_modification_time> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>Custom</class> - <name>start-date</name> - <creation_function>task_editor_create_date_edit</creation_function> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Sun, 10 Sep 2000 17:33:31 GMT</last_modification_time> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - </widget> - </widget> - </widget> - - <widget> - <class>GtkScrolledWindow</class> - <name>scrolledwindow1</name> - <hscrollbar_policy>GTK_POLICY_NEVER</hscrollbar_policy> - <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy> - <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy> - <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkText</class> - <name>description</name> - <height>80</height> - <can_focus>True</can_focus> - <editable>True</editable> - <text></text> - </widget> - </widget> - - <widget> - <class>GtkFrame</class> - <name>frame23</name> - <label>Progress</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkHBox</class> - <name>hbox3</name> - <border_width>4</border_width> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - - <widget> - <class>GtkLabel</class> - <name>label7</name> - <label>_Status:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <default_focus_target>status</default_focus_target> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkOptionMenu</class> - <name>status</name> - <can_focus>True</can_focus> - <items>Not Started -In Progress -Completed -Cancelled -</items> - <initial_choice>0</initial_choice> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label8</name> - <label>_Priority:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <default_focus_target>priority</default_focus_target> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkOptionMenu</class> - <name>priority</name> - <can_focus>True</can_focus> - <items>High -Normal -Low -Undefined -</items> - <initial_choice>0</initial_choice> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label9</name> - <label>% Comp_lete:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <default_focus_target>percent-complete</default_focus_target> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkSpinButton</class> - <name>percent-complete</name> - <width>60</width> - <can_focus>True</can_focus> - <climb_rate>1</climb_rate> - <digits>0</digits> - <numeric>False</numeric> - <update_policy>GTK_UPDATE_ALWAYS</update_policy> - <snap>False</snap> - <wrap>False</wrap> - <value>0</value> - <lower>0</lower> - <upper>100</upper> - <step>10</step> - <page>10</page> - <page_size>10</page_size> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> - </widget> - - <widget> - <class>GtkFrame</class> - <name>frame24</name> - <label>Classification</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkHBox</class> - <name>hbox6</name> - <border_width>2</border_width> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - - <widget> - <class>GtkRadioButton</class> - <name>classification-public</name> - <can_focus>True</can_focus> - <label>Pu_blic</label> - <active>True</active> - <draw_indicator>True</draw_indicator> - <group>classification_radio_group</group> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkRadioButton</class> - <name>classification-private</name> - <can_focus>True</can_focus> - <label>Pri_vate</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <group>classification_radio_group</group> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkRadioButton</class> - <name>classification-confidential</name> - <can_focus>True</can_focus> - <label>_Confidential</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <group>classification_radio_group</group> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> - </widget> - - <widget> - <class>GtkHBox</class> - <name>hbox2</name> - <homogeneous>False</homogeneous> - <spacing>2</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkButton</class> - <name>contacts-button</name> - <can_focus>True</can_focus> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label16</name> - <label>_Contacts...</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>4</xpad> - <ypad>0</ypad> - </widget> - </widget> - - <widget> - <class>GtkEntry</class> - <name>contacts</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - </widget> - - <widget> - <class>GtkButton</class> - <name>categories-button</name> - <can_focus>True</can_focus> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label17</name> - <label>Ca_tegories...</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>4</xpad> - <ypad>0</ypad> - </widget> - </widget> - - <widget> - <class>GtkEntry</class> - <name>categories</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - </widget> - </widget> - </widget> - - <widget> - <class>GtkLabel</class> - <child_name>Notebook:tab</child_name> - <name>label1</name> - <label>Task</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - - <widget> - <class>GtkTable</class> - <name>table4</name> - <border_width>4</border_width> - <rows>2</rows> - <columns>2</columns> - <homogeneous>False</homogeneous> - <row_spacing>2</row_spacing> - <column_spacing>4</column_spacing> - - <widget> - <class>GtkLabel</class> - <name>label12</name> - <label>Date Completed:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label14</name> - <label>URL:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>url</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>Custom</class> - <name>completed-date</name> - <creation_function>task_editor_create_date_edit</creation_function> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Sun, 10 Sep 2000 17:34:07 GMT</last_modification_time> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - </widget> - - <widget> - <class>GtkLabel</class> - <child_name>Notebook:tab</child_name> - <name>label2</name> - <label>Details</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - </widget> -</widget> - -</GTK-Interface> diff --git a/calendar/gui/dialogs/task-editor.c b/calendar/gui/dialogs/task-editor.c deleted file mode 100644 index 64e73e30f5..0000000000 --- a/calendar/gui/dialogs/task-editor.c +++ /dev/null @@ -1,1280 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 2000, Helix Code, Inc. - * Copyright 2000, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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 - */ - -/* - * TaskEditor - a GtkObject which handles a libglade-loaded dialog to edit - * tasks. - */ - -#include <config.h> -#include <glade/glade.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <gal/util/e-util.h> -#include <gal/widgets/e-unicode.h> -#include <gal/widgets/e-categories.h> -#include <e-util/e-dialog-widgets.h> -#include <widgets/misc/e-dateedit.h> -#include <cal-util/timeutil.h> -#include "delete-comp.h" -#include "save-comp.h" -#include "task-editor.h" -#include "../calendar-config.h" -#include "../widget-util.h" - - -typedef struct { - /* Glade XML data */ - GladeXML *xml; - - /* Client to use */ - CalClient *client; - - /* Calendar component we are editing; this is an internal copy and is - * not one of the read-only objects from the parent calendar. - */ - CalComponent *comp; - - - /* This is TRUE while we are setting the widget values. We just return - from any signal handlers. */ - gboolean ignore_callbacks; - - /* Widgets from the Glade file */ - - GtkWidget *app; - - GtkWidget *summary; - - GtkWidget *due_date; - GtkWidget *start_date; - - GtkWidget *percent_complete; - - GtkWidget *status; - GtkWidget *priority; - - GtkWidget *description; - - GtkWidget *classification_public; - GtkWidget *classification_private; - GtkWidget *classification_confidential; - - GtkWidget *contacts; - GtkWidget *categories_btn; - GtkWidget *categories; - - GtkWidget *completed_date; - GtkWidget *url; - - /* Call task_editor_set_changed() to set this to TRUE when any field - in the dialog is changed. When the user closes the dialog we will - prompt to save changes. */ - gboolean changed; -} TaskEditorPrivate; - - -/* Note that these two arrays must match. */ -static const int status_map[] = { - ICAL_STATUS_NEEDSACTION, - ICAL_STATUS_INPROCESS, - ICAL_STATUS_COMPLETED, - ICAL_STATUS_CANCELLED, - -1 -}; - -typedef enum { - PRIORITY_HIGH, - PRIORITY_NORMAL, - PRIORITY_LOW, - PRIORITY_UNDEFINED, -} TaskEditorPriority; - -static const int priority_map[] = { - PRIORITY_HIGH, - PRIORITY_NORMAL, - PRIORITY_LOW, - PRIORITY_UNDEFINED, - -1 -}; - -static const int classification_map[] = { - CAL_COMPONENT_CLASS_PUBLIC, - CAL_COMPONENT_CLASS_PRIVATE, - CAL_COMPONENT_CLASS_CONFIDENTIAL, - -1 -}; - -static void task_editor_class_init (TaskEditorClass *class); -static void task_editor_init (TaskEditor *tedit); -static void tedit_apply_event_cb (GtkWidget *widget, gint page_num, gpointer data); -static gint tedit_close_event_cb (GtkWidget *widget, gpointer data); -static gint tedit_delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data); -static void close_dialog (TaskEditor *tedit); -static gboolean get_widgets (TaskEditor *tedit); -static void init_widgets (TaskEditor *tedit); -static void task_editor_destroy (GtkObject *object); -static char * make_title_from_comp (CalComponent *comp); -static void set_title_from_comp (TaskEditor *tedit, CalComponent *comp); -static void clear_widgets (TaskEditor *tedit); -static void fill_widgets (TaskEditor *tedit); - -static void save_todo_object (TaskEditor *tedit); -static void dialog_to_comp_object (TaskEditor *tedit); - -static void obj_updated_cb (CalClient *client, const char *uid, gpointer data); -static void obj_removed_cb (CalClient *client, const char *uid, gpointer data); -static void raise_and_focus (GtkWidget *widget); - -static TaskEditorPriority priority_value_to_index (int priority_value); -static int priority_index_to_value (TaskEditorPriority priority); - -static void completed_changed (EDateEdit *dedit, - TaskEditor *tedit); -static void status_changed (GtkMenu *menu, - TaskEditor *tedit); -static void percent_complete_changed (GtkAdjustment *adj, - TaskEditor *tedit); -static void field_changed (GtkWidget *widget, - TaskEditor *tedit); -static void task_editor_set_changed (TaskEditor *tedit, - gboolean changed); -static gboolean prompt_to_save_changes (TaskEditor *tedit); -static CalComponentClassification classification_get (GtkWidget *widget); -static void categories_clicked (GtkWidget *button, - TaskEditor *editor); - -/* The function libglade calls to create the EDateEdit widgets in the GUI. */ -GtkWidget * task_editor_create_date_edit (void); - -static GtkObjectClass *parent_class; - -E_MAKE_TYPE(task_editor, "TaskEditor", TaskEditor, - task_editor_class_init, task_editor_init, GTK_TYPE_OBJECT) - - -static void -task_editor_class_init (TaskEditorClass *class) -{ - GtkObjectClass *object_class; - - object_class = (GtkObjectClass *) class; - - parent_class = gtk_type_class (GTK_TYPE_OBJECT); - - object_class->destroy = task_editor_destroy; -} - - -static void -task_editor_init (TaskEditor *tedit) -{ - TaskEditorPrivate *priv; - - priv = g_new0 (TaskEditorPrivate, 1); - tedit->priv = priv; - - priv->ignore_callbacks = FALSE; - - task_editor_set_changed (tedit, FALSE); -} - - -/** - * task_editor_new: - * @Returns: a new #TaskEditor. - * - * Creates a new #TaskEditor. - **/ -TaskEditor * -task_editor_new (void) -{ - TaskEditor *tedit; - - tedit = TASK_EDITOR (gtk_type_new (task_editor_get_type ())); - return task_editor_construct (tedit); -} - -/** - * task_editor_construct: - * @tedit: A #TaskEditor. - * - * Constructs a task editor by loading its Glade XML file. - * - * Return value: The same object as @tedit, or NULL if the widgets could not be - * created. In the latter case, the task editor will automatically be - * destroyed. - **/ -TaskEditor * -task_editor_construct (TaskEditor *tedit) -{ - TaskEditorPrivate *priv; - - g_return_val_if_fail (tedit != NULL, NULL); - g_return_val_if_fail (IS_TASK_EDITOR (tedit), NULL); - - priv = tedit->priv; - - /* Load the content widgets */ - - priv->xml = glade_xml_new (EVOLUTION_GLADEDIR "/task-editor-dialog.glade", NULL); - if (!priv->xml) { - g_message ("task_editor_construct(): Could not load the Glade XML file!"); - goto error; - } - - if (!get_widgets (tedit)) { - g_message ("task_editor_construct(): Could not find all widgets in the XML file!"); - goto error; - } - - init_widgets (tedit); - - /* Hook to destruction of the dialog */ - gtk_signal_connect (GTK_OBJECT (priv->app), "apply", - GTK_SIGNAL_FUNC (tedit_apply_event_cb), tedit); - gtk_signal_connect (GTK_OBJECT (priv->app), "close", - GTK_SIGNAL_FUNC (tedit_close_event_cb), tedit); - gtk_signal_connect (GTK_OBJECT (priv->app), "delete_event", - GTK_SIGNAL_FUNC (tedit_delete_event_cb), tedit); - - /* Add focus to the summary entry */ - gtk_widget_grab_focus (GTK_WIDGET (priv->summary)); - - - return tedit; - - error: - - gtk_object_unref (GTK_OBJECT (tedit)); - return NULL; -} - - -/* Called by libglade to create our custom EDateEdit widgets. */ -GtkWidget * -task_editor_create_date_edit (void) -{ - GtkWidget *dedit; - - dedit = date_edit_new (TRUE, TRUE); - e_date_edit_set_allow_no_date_set (E_DATE_EDIT (dedit), TRUE); - - return dedit; -} - -/* Callback used when the dialog box is destroyed */ -static void -tedit_apply_event_cb (GtkWidget *widget, gint page_num, gpointer data) -{ - TaskEditor *tedit; - - g_return_if_fail (IS_TASK_EDITOR (data)); - - tedit = TASK_EDITOR (data); - - if (page_num != -1) - return; - - save_todo_object (tedit); -} - -/* Callback used when the dialog box is destroyed */ -static gint -tedit_close_event_cb (GtkWidget *widget, gpointer data) -{ - TaskEditor *tedit; - - g_return_val_if_fail (IS_TASK_EDITOR (data), TRUE); - - tedit = TASK_EDITOR (data); - - if (prompt_to_save_changes (tedit)) - close_dialog (tedit); - - return TRUE; -} - -/* Callback used when the dialog box is destroyed */ -static gint -tedit_delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data) -{ - TaskEditor *tedit; - - g_return_val_if_fail (IS_TASK_EDITOR (data), TRUE); - - tedit = TASK_EDITOR (data); - - if (prompt_to_save_changes (tedit)) - close_dialog (tedit); - - return TRUE; -} - - -/* Closes the dialog box and emits the appropriate signals */ -static void -close_dialog (TaskEditor *tedit) -{ - TaskEditorPrivate *priv; - - priv = tedit->priv; - - g_assert (priv->app != NULL); - - gtk_object_destroy (GTK_OBJECT (tedit)); -} - - -/* Gets the widgets from the XML file and returns if they are all available. - * For the widgets whose values can be simply set with e-dialog-utils, it does - * that as well. - */ -static gboolean -get_widgets (TaskEditor *tedit) -{ - TaskEditorPrivate *priv; - - priv = tedit->priv; - -#define GW(name) glade_xml_get_widget (priv->xml, name) - - priv->app = GW ("task-editor-dialog"); - - priv->summary = GW ("summary"); - - priv->due_date = GW ("due-date"); - priv->start_date = GW ("start-date"); - - priv->percent_complete = GW ("percent-complete"); - - priv->status = GW ("status"); - priv->priority = GW ("priority"); - - priv->description = GW ("description"); - - priv->classification_public = GW ("classification-public"); - priv->classification_private = GW ("classification-private"); - priv->classification_confidential = GW ("classification-confidential"); - - priv->contacts = GW ("contacts"); - priv->categories_btn = GW ("categories-button"); - priv->categories = GW ("categories"); - - priv->completed_date = GW ("completed-date"); - priv->url = GW ("url"); - -#undef GW - - return (priv->app - && priv->summary - && priv->due_date - && priv->start_date - && priv->percent_complete - && priv->status - && priv->priority - && priv->classification_public - && priv->classification_private - && priv->classification_confidential - && priv->description - && priv->contacts - && priv->categories_btn - && priv->categories - && priv->completed_date - && priv->url); -} - - -/* Hooks the widget signals */ -static void -init_widgets (TaskEditor *tedit) -{ - TaskEditorPrivate *priv; - - priv = tedit->priv; - - /* Connect signals. The Status, Percent Complete & Date Completed - properties are closely related so whenever one changes we may need - to update the other 2. */ - gtk_signal_connect (GTK_OBJECT (priv->completed_date), "changed", - GTK_SIGNAL_FUNC (completed_changed), tedit); - - gtk_signal_connect (GTK_OBJECT (GTK_OPTION_MENU (priv->status)->menu), - "deactivate", - GTK_SIGNAL_FUNC (status_changed), tedit); - - gtk_signal_connect (GTK_OBJECT (GTK_SPIN_BUTTON (priv->percent_complete)->adjustment), - "value_changed", - GTK_SIGNAL_FUNC (percent_complete_changed), tedit); - - /* Classification */ - gtk_signal_connect (GTK_OBJECT (priv->description), "changed", - GTK_SIGNAL_FUNC (field_changed), tedit); - gtk_signal_connect (GTK_OBJECT (priv->classification_public), - "toggled", - GTK_SIGNAL_FUNC (field_changed), tedit); - gtk_signal_connect (GTK_OBJECT (priv->classification_private), - "toggled", - GTK_SIGNAL_FUNC (field_changed), tedit); - gtk_signal_connect (GTK_OBJECT (priv->classification_confidential), - "toggled", - GTK_SIGNAL_FUNC (field_changed), tedit); - - /* Connect the default signal handler to use to make sure the "changed" - field gets set whenever a field is changed. */ - gtk_signal_connect (GTK_OBJECT (priv->summary), "changed", - GTK_SIGNAL_FUNC (field_changed), tedit); - gtk_signal_connect (GTK_OBJECT (priv->due_date), "changed", - GTK_SIGNAL_FUNC (field_changed), tedit); - gtk_signal_connect (GTK_OBJECT (priv->start_date), "changed", - GTK_SIGNAL_FUNC (field_changed), tedit); - gtk_signal_connect (GTK_OBJECT (GTK_OPTION_MENU (priv->priority)->menu), - "deactivate", - GTK_SIGNAL_FUNC (field_changed), tedit); - gtk_signal_connect (GTK_OBJECT (priv->description), "changed", - GTK_SIGNAL_FUNC (field_changed), tedit); - gtk_signal_connect (GTK_OBJECT (priv->contacts), "changed", - GTK_SIGNAL_FUNC (field_changed), tedit); - gtk_signal_connect (GTK_OBJECT (priv->categories), "changed", - GTK_SIGNAL_FUNC (field_changed), tedit); - gtk_signal_connect (GTK_OBJECT (priv->url), "changed", - GTK_SIGNAL_FUNC (field_changed), tedit); - - /* Button clicks */ - gtk_signal_connect (GTK_OBJECT (priv->categories_btn), "clicked", - GTK_SIGNAL_FUNC (categories_clicked), tedit); -} - -static void -task_editor_destroy (GtkObject *object) -{ - TaskEditor *tedit; - TaskEditorPrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_TASK_EDITOR (object)); - - tedit = TASK_EDITOR (object); - priv = tedit->priv; - - if (priv->app) { - gtk_widget_destroy (priv->app); - priv->app = NULL; - } - - if (priv->comp) { - gtk_object_unref (GTK_OBJECT (priv->comp)); - priv->comp = NULL; - } - - if (priv->client) { - gtk_signal_disconnect_by_data (GTK_OBJECT (priv->client), - tedit); - gtk_object_unref (GTK_OBJECT (priv->client)); - priv->client = NULL; - } - - if (priv->xml) { - gtk_object_unref (GTK_OBJECT (priv->xml)); - priv->xml = NULL; - } - - g_free (priv); - tedit->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - -void -task_editor_set_cal_client (TaskEditor *tedit, - CalClient *client) -{ - TaskEditorPrivate *priv; - - g_return_if_fail (tedit != NULL); - g_return_if_fail (IS_TASK_EDITOR (tedit)); - - priv = tedit->priv; - - if (client == priv->client) - return; - - if (client) - g_return_if_fail (IS_CAL_CLIENT (client)); - - if (client) - g_return_if_fail (cal_client_get_load_state (client) == CAL_CLIENT_LOAD_LOADED); - - if (client) - gtk_object_ref (GTK_OBJECT (client)); - - if (priv->client) { - gtk_signal_disconnect_by_data (GTK_OBJECT (priv->client), - tedit); - gtk_object_unref (GTK_OBJECT (priv->client)); - } - - priv->client = client; - - if (priv->client) { - gtk_signal_connect (GTK_OBJECT (priv->client), "obj_updated", - GTK_SIGNAL_FUNC (obj_updated_cb), tedit); - gtk_signal_connect (GTK_OBJECT (priv->client), "obj_removed", - GTK_SIGNAL_FUNC (obj_removed_cb), tedit); - } -} - - -/* Callback used when the calendar client tells us that an object changed */ -static void -obj_updated_cb (CalClient *client, const char *uid, gpointer data) -{ - TaskEditor *tedit; - TaskEditorPrivate *priv; - CalComponent *comp; - CalClientGetStatus status; - const gchar *editing_uid; - - tedit = TASK_EDITOR (data); - - g_return_if_fail (IS_TASK_EDITOR (tedit)); - - priv = tedit->priv; - - /* If we aren't showing the object which has been updated, return. */ - if (!priv->comp) - return; - cal_component_get_uid (priv->comp, &editing_uid); - if (strcmp (uid, editing_uid)) - return; - - - /* Get the task from the server. */ - status = cal_client_get_object (priv->client, uid, &comp); - - switch (status) { - case CAL_CLIENT_GET_SUCCESS: - /* Everything is fine */ - break; - - case CAL_CLIENT_GET_SYNTAX_ERROR: - g_message ("obj_updated_cb(): Syntax error when 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; - } - - raise_and_focus (priv->app); -} - -/* Callback used when the calendar client tells us that an object was removed */ -static void -obj_removed_cb (CalClient *client, const char *uid, gpointer data) -{ - TaskEditor *tedit; - TaskEditorPrivate *priv; - const gchar *editing_uid; - - tedit = TASK_EDITOR (data); - - g_return_if_fail (tedit != NULL); - g_return_if_fail (IS_TASK_EDITOR (tedit)); - - priv = tedit->priv; - - /* If we aren't showing the object which has been updated, return. */ - if (!priv->comp) - return; - cal_component_get_uid (priv->comp, &editing_uid); - if (strcmp (uid, editing_uid)) - return; - - - raise_and_focus (priv->app); -} - - -/* Brings attention to a window by raising it and giving it focus */ -static void -raise_and_focus (GtkWidget *widget) -{ - g_assert (GTK_WIDGET_REALIZED (widget)); - gdk_window_show (widget->window); - gtk_widget_grab_focus (widget); -} - - -/** - * task_editor_set_todo_object: - * @tedit: A #TaskEditor. - * @comp: A todo object. - * - * Sets the todo object that a task editor dialog will manipulate. - **/ -void -task_editor_set_todo_object (TaskEditor *tedit, - CalComponent *comp) -{ - TaskEditorPrivate *priv; - - g_return_if_fail (tedit != NULL); - g_return_if_fail (IS_TASK_EDITOR (tedit)); - - priv = tedit->priv; - - if (priv->comp) { - gtk_object_unref (GTK_OBJECT (priv->comp)); - priv->comp = NULL; - } - - if (comp) - priv->comp = cal_component_clone (comp); - - set_title_from_comp (tedit, priv->comp); - fill_widgets (tedit); -} - -void -task_editor_focus (TaskEditor *tedit) -{ - TaskEditorPrivate *priv; - - g_return_if_fail (tedit != NULL); - g_return_if_fail (IS_TASK_EDITOR (tedit)); - - priv = tedit->priv; - gtk_widget_show_now (priv->app); - raise_and_focus (priv->app); -} - -/* Creates an appropriate title for the task editor dialog */ -static char * -make_title_from_comp (CalComponent *comp) -{ - const char *summary; - CalComponentVType type; - CalComponentText text; - - if (!comp) - return g_strdup (_("Edit Task")); - - cal_component_get_summary (comp, &text); - if (text.value) - summary = text.value; - else - summary = _("No summary"); - - - type = cal_component_get_vtype (comp); - switch (type) { - case CAL_COMPONENT_EVENT: - return g_strdup_printf (_("Appointment - %s"), summary); - - case CAL_COMPONENT_TODO: - return g_strdup_printf (_("Task - %s"), summary); - - case CAL_COMPONENT_JOURNAL: - return g_strdup_printf (_("Journal entry - %s"), summary); - - default: - g_message ("make_title_from_comp(): Cannot handle object of type %d", type); - return NULL; - } -} - -/* Sets the event editor's window title from a calendar component */ -static void -set_title_from_comp (TaskEditor *tedit, CalComponent *comp) -{ - TaskEditorPrivate *priv; - char *title, *tmp; - - priv = tedit->priv; - - title = make_title_from_comp (comp); - tmp = e_utf8_to_gtk_string (priv->app, title); - g_free (title); - - if (tmp) { - gtk_window_set_title (GTK_WINDOW (priv->app), tmp); - g_free (tmp); - } else { - g_message ("set_title_from_comp(): Could not convert the title from UTF8"); - gtk_window_set_title (GTK_WINDOW (priv->app), ""); - } -} - -/* Fills the widgets with default values */ -static void -clear_widgets (TaskEditor *tedit) -{ - TaskEditorPrivate *priv; - - priv = tedit->priv; - - -} - -/* Fills in the widgets with the proper values */ -static void -fill_widgets (TaskEditor *tedit) -{ - TaskEditorPrivate *priv; - CalComponentText text; - CalComponentDateTime d; - CalComponentClassification cl; - struct icaltimetype *completed; - GSList *l; - time_t t; - int *priority_value, *percent; - icalproperty_status status; - TaskEditorPriority priority; - const char *url; - const char *categories; - - priv = tedit->priv; - - task_editor_set_changed (tedit, FALSE); - - clear_widgets (tedit); - - if (!priv->comp) - return; - - /* We want to ignore any signals emitted while changing fields. */ - priv->ignore_callbacks = TRUE; - - - cal_component_get_summary (priv->comp, &text); - e_dialog_editable_set (priv->summary, text.value); - - cal_component_get_description_list (priv->comp, &l); - if (l) { - text = *(CalComponentText *)l->data; - e_dialog_editable_set (priv->description, text.value); - } else { - e_dialog_editable_set (priv->description, NULL); - } - cal_component_free_text_list (l); - - /* Due Date. */ - cal_component_get_due (priv->comp, &d); - if (d.value) { - t = icaltime_as_timet (*d.value); - } else { - t = -1; - } - e_date_edit_set_time (E_DATE_EDIT (priv->due_date), t); - - /* Start Date. */ - cal_component_get_dtstart (priv->comp, &d); - if (d.value) { - t = icaltime_as_timet (*d.value); - } else { - t = -1; - } - e_date_edit_set_time (E_DATE_EDIT (priv->start_date), t); - - /* Completed Date. */ - cal_component_get_completed (priv->comp, &completed); - if (completed) { - t = icaltime_as_timet (*completed); - cal_component_free_icaltimetype (completed); - } else { - t = -1; - } - e_date_edit_set_time (E_DATE_EDIT (priv->completed_date), t); - - /* Percent Complete. */ - cal_component_get_percent (priv->comp, &percent); - if (percent) { - e_dialog_spin_set (priv->percent_complete, *percent); - cal_component_free_percent (percent); - } else { - /* FIXME: Could check if task is completed and set 100%. */ - e_dialog_spin_set (priv->percent_complete, 0); - } - - /* Status. */ - cal_component_get_status (priv->comp, &status); - if (status == ICAL_STATUS_NONE) { - /* Try to user the percent value. */ - if (percent) { - if (*percent == 0) - status = ICAL_STATUS_NEEDSACTION; - else if (*percent == 100) - status = ICAL_STATUS_COMPLETED; - else - status = ICAL_STATUS_INPROCESS; - } else - status = ICAL_STATUS_NEEDSACTION; - } - e_dialog_option_menu_set (priv->status, status, status_map); - - /* Priority. */ - cal_component_get_priority (priv->comp, &priority_value); - if (priority_value) { - priority = priority_value_to_index (*priority_value); - cal_component_free_priority (priority_value); - } else { - priority = PRIORITY_UNDEFINED; - } - e_dialog_option_menu_set (priv->priority, priority, priority_map); - - - /* Classification. */ - cal_component_get_classification (priv->comp, &cl); - - switch (cl) { - case CAL_COMPONENT_CLASS_PUBLIC: - e_dialog_radio_set (priv->classification_public, CAL_COMPONENT_CLASS_PUBLIC, - classification_map); - case CAL_COMPONENT_CLASS_PRIVATE: - e_dialog_radio_set (priv->classification_public, CAL_COMPONENT_CLASS_PRIVATE, - classification_map); - case CAL_COMPONENT_CLASS_CONFIDENTIAL: - e_dialog_radio_set (priv->classification_public, CAL_COMPONENT_CLASS_CONFIDENTIAL, - classification_map); - default: - /* What do do? We can't g_assert_not_reached() since it is a - * value from an external file. - */ - } - - /* Categories */ - cal_component_get_categories (priv->comp, &categories); - e_dialog_editable_set (priv->categories, categories); - - /* URL. */ - cal_component_get_url (priv->comp, &url); - e_dialog_editable_set (priv->url, url); - - priv->ignore_callbacks = FALSE; -} - - -static void -save_todo_object (TaskEditor *tedit) -{ - TaskEditorPrivate *priv; - - priv = tedit->priv; - - g_return_if_fail (priv->client != NULL); - - if (!priv->comp) - return; - - dialog_to_comp_object (tedit); - set_title_from_comp (tedit, priv->comp); - - if (!cal_client_update_object (priv->client, priv->comp)) - g_message ("save_todo_object(): Could not update the object!"); - else - task_editor_set_changed (tedit, FALSE); -} - - -/* Get the values of the widgets in the event editor and put them in the iCalObject */ -static void -dialog_to_comp_object (TaskEditor *tedit) -{ - TaskEditorPrivate *priv; - CalComponent *comp; - CalComponentDateTime date; - time_t t; - icalproperty_status status; - TaskEditorPriority priority; - int priority_value, percent; - char *url, *cat; - char *str; - - priv = tedit->priv; - comp = priv->comp; - - /* Summary. */ - - str = e_dialog_editable_get (priv->summary); - if (!str || strlen (str) == 0) - cal_component_set_summary (comp, NULL); - else { - CalComponentText text; - - text.value = str; - text.altrep = NULL; - - cal_component_set_summary (comp, &text); - } - - if (str) - g_free (str); - - /* Description */ - - str = e_dialog_editable_get (priv->description); - if (!str || strlen (str) == 0) - cal_component_set_description_list (comp, NULL); - else { - GSList l; - CalComponentText text; - - text.value = str; - text.altrep = NULL; - l.data = &text; - l.next = NULL; - - cal_component_set_description_list (comp, &l); - } - - if (!str) - g_free (str); - - /* Dates */ - - date.value = g_new (struct icaltimetype, 1); - date.tzid = NULL; - - /* Due Date. */ - t = e_date_edit_get_time (E_DATE_EDIT (priv->due_date)); - if (t != -1) { - *date.value = icaltime_from_timet (t, FALSE); - cal_component_set_due (comp, &date); - } else { - cal_component_set_due (comp, NULL); - } - - /* Start Date. */ - t = e_date_edit_get_time (E_DATE_EDIT (priv->start_date)); - if (t != -1) { - *date.value = icaltime_from_timet (t, FALSE); - cal_component_set_dtstart (comp, &date); - } else { - cal_component_set_dtstart (comp, NULL); - } - - /* Completed Date. */ - t = e_date_edit_get_time (E_DATE_EDIT (priv->completed_date)); - if (t != -1) { - *date.value = icaltime_from_timet (t, FALSE); - cal_component_set_completed (comp, date.value); - } else { - cal_component_set_completed (comp, NULL); - } - - g_free (date.value); - - /* Percent Complete. */ - percent = e_dialog_spin_get_int (priv->percent_complete); - cal_component_set_percent (comp, &percent); - - /* Status. */ - status = e_dialog_option_menu_get (priv->status, status_map); - cal_component_set_status (comp, status); - - /* Priority. */ - priority = e_dialog_option_menu_get (priv->priority, priority_map); - priority_value = priority_index_to_value (priority); - cal_component_set_priority (comp, &priority_value); - - /* Classification. */ - cal_component_set_classification (comp, classification_get (priv->classification_public)); - - /* Categories */ - cat = e_dialog_editable_get (priv->categories); - cal_component_set_categories (comp, cat); - - if (cat) - g_free (cat); - - /* URL. */ - url = e_dialog_editable_get (priv->url); - cal_component_set_url (comp, url); - - if (url) - g_free (url); - - cal_component_commit_sequence (comp); -} - -static TaskEditorPriority -priority_value_to_index (int priority_value) -{ - TaskEditorPriority retval; - - if (priority_value == 0) - retval = PRIORITY_UNDEFINED; - else if (priority_value <= 4) - retval = PRIORITY_HIGH; - else if (priority_value == 5) - retval = PRIORITY_NORMAL; - else - retval = PRIORITY_LOW; - - return retval; -} - - -static int -priority_index_to_value (TaskEditorPriority priority) -{ - int retval; - - switch (priority) { - case PRIORITY_UNDEFINED: - retval = 0; - break; - case PRIORITY_HIGH: - retval = 3; - break; - case PRIORITY_NORMAL: - retval = 5; - break; - case PRIORITY_LOW: - retval = 7; - break; - default: - retval = -1; - g_assert_not_reached (); - break; - } - - return retval; -} - - -static void -completed_changed (EDateEdit *dedit, - TaskEditor *tedit) -{ - TaskEditorPrivate *priv; - time_t t; - - g_return_if_fail (IS_TASK_EDITOR (tedit)); - - priv = tedit->priv; - - if (priv->ignore_callbacks) - return; - - task_editor_set_changed (tedit, TRUE); - - priv->ignore_callbacks = TRUE; - t = e_date_edit_get_time (E_DATE_EDIT (priv->completed_date)); - if (t == -1) { - /* If the 'Completed Date' is set to 'None', we set the - status to 'Not Started' and the percent-complete to 0. - The task may actually be partially-complete, but we leave - it to the user to set those fields. */ - e_dialog_option_menu_set (priv->status, ICAL_STATUS_NEEDSACTION, - status_map); - e_dialog_spin_set (priv->percent_complete, 0); - } else { - e_dialog_option_menu_set (priv->status, ICAL_STATUS_COMPLETED, - status_map); - e_dialog_spin_set (priv->percent_complete, 100); - } - priv->ignore_callbacks = FALSE; -} - - -static void -status_changed (GtkMenu *menu, - TaskEditor *tedit) -{ - TaskEditorPrivate *priv; - icalproperty_status status; - - g_return_if_fail (IS_TASK_EDITOR (tedit)); - - priv = tedit->priv; - - if (priv->ignore_callbacks) - return; - - task_editor_set_changed (tedit, TRUE); - - status = e_dialog_option_menu_get (priv->status, status_map); - priv->ignore_callbacks = TRUE; - if (status == ICAL_STATUS_NEEDSACTION) { - e_dialog_spin_set (priv->percent_complete, 0); - e_date_edit_set_time (E_DATE_EDIT (priv->completed_date), -1); - } else if (status == ICAL_STATUS_COMPLETED) { - e_dialog_spin_set (priv->percent_complete, 100); - e_date_edit_set_time (E_DATE_EDIT (priv->completed_date), - time (NULL)); - } - priv->ignore_callbacks = FALSE; -} - - -static void -percent_complete_changed (GtkAdjustment *adj, - TaskEditor *tedit) -{ - TaskEditorPrivate *priv; - gint percent; - icalproperty_status status; - time_t date_completed; - - g_return_if_fail (IS_TASK_EDITOR (tedit)); - - priv = tedit->priv; - - if (priv->ignore_callbacks) - return; - - task_editor_set_changed (tedit, TRUE); - - percent = e_dialog_spin_get_int (priv->percent_complete); - priv->ignore_callbacks = TRUE; - - if (percent == 100) { - date_completed = time (NULL); - status = ICAL_STATUS_COMPLETED; - } else { - /* FIXME: Set to 'None'. */ - date_completed = time (NULL); - - if (percent == 0) - status = ICAL_STATUS_NEEDSACTION; - else - status = ICAL_STATUS_INPROCESS; - } - - e_date_edit_set_time (E_DATE_EDIT (priv->completed_date), - date_completed); - e_dialog_option_menu_set (priv->status, status, status_map); - - priv->ignore_callbacks = FALSE; -} - -/* Decode the radio button group for classifications */ -static CalComponentClassification -classification_get (GtkWidget *widget) -{ - return e_dialog_radio_get (widget, classification_map); -} - - -/* This is called when all fields except those handled above (status, percent - complete & completed date) are changed. It just sets the "changed" flag. */ -static void -field_changed (GtkWidget *widget, - TaskEditor *tedit) -{ - TaskEditorPrivate *priv; - - g_return_if_fail (IS_TASK_EDITOR (tedit)); - - priv = tedit->priv; - - if (priv->ignore_callbacks) - return; - - task_editor_set_changed (tedit, TRUE); -} - - -static void -task_editor_set_changed (TaskEditor *tedit, - gboolean changed) -{ - TaskEditorPrivate *priv; - - priv = tedit->priv; - -#if 0 - g_print ("In task_editor_set_changed: %s\n", - changed ? "TRUE" : "FALSE"); -#endif - - priv->changed = changed; - - if (priv->app) - gnome_property_box_set_state (GNOME_PROPERTY_BOX (priv->app), changed); -} - - -/* This checks if the "changed" field is set, and if so it prompts to save - the changes using a "Save/Discard/Cancel" modal dialog. It then saves the - changes if requested. It returns TRUE if the dialog should now be closed. */ -static gboolean -prompt_to_save_changes (TaskEditor *tedit) -{ - TaskEditorPrivate *priv; - - priv = tedit->priv; - - if (!priv->changed) - return TRUE; - - switch (save_component_dialog (GTK_WINDOW (priv->app))) { - case 0: /* Save */ - /* FIXME: If an error occurs here, we should popup a dialog - and then return FALSE. */ - save_todo_object (tedit); - return TRUE; - case 1: /* Discard */ - return TRUE; - case 2: /* Cancel */ - default: - return FALSE; - break; - } - -} - -static void -categories_clicked(GtkWidget *button, TaskEditor *tedit) -{ - char *categories; - GnomeDialog *dialog; - int result; - GtkWidget *entry; - - entry = ((TaskEditorPrivate *)tedit->priv)->categories; - categories = e_utf8_gtk_entry_get_text (GTK_ENTRY (entry)); - - dialog = GNOME_DIALOG (e_categories_new (categories)); - result = gnome_dialog_run (dialog); - g_free (categories); - - if (result == 0) { - gtk_object_get (GTK_OBJECT (dialog), - "categories", &categories, - NULL); - e_utf8_gtk_entry_set_text (GTK_ENTRY (entry), categories); - g_free (categories); - } - gtk_object_destroy (GTK_OBJECT (dialog)); -} diff --git a/calendar/gui/dialogs/task-editor.h b/calendar/gui/dialogs/task-editor.h deleted file mode 100644 index 7327803a72..0000000000 --- a/calendar/gui/dialogs/task-editor.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 2000, Helix Code, Inc. - * Copyright 2000, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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 - */ -#ifndef _TASK_EDITOR_H_ -#define _TASK_EDITOR_H_ - -#include <gtk/gtkobject.h> -#include <libgnome/gnome-defs.h> -#include <bonobo.h> -#include <cal-client/cal-client.h> - -BEGIN_GNOME_DECLS - - -#define TASK_EDITOR(obj) GTK_CHECK_CAST (obj, task_editor_get_type (), TaskEditor) -#define TASK_EDITOR_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, task_editor_get_type (), TaskEditorClass) -#define IS_TASK_EDITOR(obj) GTK_CHECK_TYPE (obj, task_editor_get_type ()) - - -typedef struct _TaskEditor TaskEditor; -typedef struct _TaskEditorClass TaskEditorClass; - -struct _TaskEditor -{ - GtkObject object; - - /* Private data */ - gpointer priv; -}; - -struct _TaskEditorClass -{ - GtkObjectClass parent_class; -}; - -GtkType task_editor_get_type (void); -TaskEditor* task_editor_construct (TaskEditor *tedit); -TaskEditor* task_editor_new (void); -void task_editor_set_cal_client (TaskEditor *tedit, - CalClient *client); -void task_editor_set_todo_object (TaskEditor *tedit, - CalComponent *comp); -void task_editor_focus (TaskEditor *tedit); - - - -END_GNOME_DECLS - -#endif /* _TASK_EDITOR_H_ */ diff --git a/calendar/gui/dialogs/task-page.glade b/calendar/gui/dialogs/task-page.glade deleted file mode 100644 index ae7ea9681a..0000000000 --- a/calendar/gui/dialogs/task-page.glade +++ /dev/null @@ -1,695 +0,0 @@ -<?xml version="1.0"?> -<GTK-Interface> - -<project> - <name>task-editor-dialog</name> - <program_name>task-editor-dialog</program_name> - <directory></directory> - <source_directory>src</source_directory> - <pixmaps_directory>pixmaps</pixmaps_directory> - <language>C</language> - <gnome_support>True</gnome_support> - <gettext_support>True</gettext_support> -</project> - -<widget> - <class>GnomePropertyBox</class> - <name>task-editor-dialog</name> - <visible>False</visible> - <position>GTK_WIN_POS_NONE</position> - <modal>False</modal> - <allow_shrink>False</allow_shrink> - <allow_grow>False</allow_grow> - <auto_shrink>False</auto_shrink> - - <widget> - <class>GtkNotebook</class> - <child_name>GnomeDock:contents</child_name> - <name>notebook1</name> - <border_width>2</border_width> - <can_focus>True</can_focus> - <show_tabs>True</show_tabs> - <show_border>True</show_border> - <tab_pos>GTK_POS_TOP</tab_pos> - <scrollable>False</scrollable> - <tab_hborder>2</tab_hborder> - <tab_vborder>2</tab_vborder> - <popup_enable>False</popup_enable> - - <widget> - <class>GtkVBox</class> - <name>vbox1</name> - <border_width>4</border_width> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - - <widget> - <class>GtkTable</class> - <name>table3</name> - <rows>1</rows> - <columns>2</columns> - <homogeneous>False</homogeneous> - <row_spacing>4</row_spacing> - <column_spacing>4</column_spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label3</name> - <label>Su_mmary:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <default_focus_target>summary</default_focus_target> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>False</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>summary</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - </widget> - - <widget> - <class>GtkFrame</class> - <name>frame2</name> - <label>Date & Time</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkHBox</class> - <name>hbox4</name> - <border_width>4</border_width> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - - <widget> - <class>GtkTable</class> - <name>table1</name> - <rows>2</rows> - <columns>2</columns> - <homogeneous>False</homogeneous> - <row_spacing>2</row_spacing> - <column_spacing>4</column_spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label6</name> - <label>Sta_rt Date:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label5</name> - <label>_Due Date:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>Custom</class> - <name>due-date</name> - <creation_function>task_editor_create_date_edit</creation_function> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Sun, 10 Sep 2000 17:32:18 GMT</last_modification_time> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>Custom</class> - <name>start-date</name> - <creation_function>task_editor_create_date_edit</creation_function> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Sun, 10 Sep 2000 17:33:31 GMT</last_modification_time> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - </widget> - </widget> - </widget> - - <widget> - <class>GtkScrolledWindow</class> - <name>scrolledwindow1</name> - <hscrollbar_policy>GTK_POLICY_NEVER</hscrollbar_policy> - <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy> - <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy> - <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkText</class> - <name>description</name> - <height>80</height> - <can_focus>True</can_focus> - <editable>True</editable> - <text></text> - </widget> - </widget> - - <widget> - <class>GtkFrame</class> - <name>frame23</name> - <label>Progress</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkHBox</class> - <name>hbox3</name> - <border_width>4</border_width> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - - <widget> - <class>GtkLabel</class> - <name>label7</name> - <label>_Status:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <default_focus_target>status</default_focus_target> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkOptionMenu</class> - <name>status</name> - <can_focus>True</can_focus> - <items>Not Started -In Progress -Completed -Cancelled -</items> - <initial_choice>0</initial_choice> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label8</name> - <label>_Priority:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <default_focus_target>priority</default_focus_target> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkOptionMenu</class> - <name>priority</name> - <can_focus>True</can_focus> - <items>High -Normal -Low -Undefined -</items> - <initial_choice>0</initial_choice> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label9</name> - <label>% Comp_lete:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <default_focus_target>percent-complete</default_focus_target> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkSpinButton</class> - <name>percent-complete</name> - <width>60</width> - <can_focus>True</can_focus> - <climb_rate>1</climb_rate> - <digits>0</digits> - <numeric>False</numeric> - <update_policy>GTK_UPDATE_ALWAYS</update_policy> - <snap>False</snap> - <wrap>False</wrap> - <value>0</value> - <lower>0</lower> - <upper>100</upper> - <step>10</step> - <page>10</page> - <page_size>10</page_size> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> - </widget> - - <widget> - <class>GtkFrame</class> - <name>frame24</name> - <label>Classification</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkHBox</class> - <name>hbox6</name> - <border_width>2</border_width> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - - <widget> - <class>GtkRadioButton</class> - <name>classification-public</name> - <can_focus>True</can_focus> - <label>Pu_blic</label> - <active>True</active> - <draw_indicator>True</draw_indicator> - <group>classification_radio_group</group> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkRadioButton</class> - <name>classification-private</name> - <can_focus>True</can_focus> - <label>Pri_vate</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <group>classification_radio_group</group> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkRadioButton</class> - <name>classification-confidential</name> - <can_focus>True</can_focus> - <label>_Confidential</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <group>classification_radio_group</group> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> - </widget> - - <widget> - <class>GtkHBox</class> - <name>hbox2</name> - <homogeneous>False</homogeneous> - <spacing>2</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkButton</class> - <name>contacts-button</name> - <can_focus>True</can_focus> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label16</name> - <label>_Contacts...</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>4</xpad> - <ypad>0</ypad> - </widget> - </widget> - - <widget> - <class>GtkEntry</class> - <name>contacts</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - </widget> - - <widget> - <class>GtkButton</class> - <name>categories-button</name> - <can_focus>True</can_focus> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label17</name> - <label>Ca_tegories...</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>4</xpad> - <ypad>0</ypad> - </widget> - </widget> - - <widget> - <class>GtkEntry</class> - <name>categories</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - </widget> - </widget> - </widget> - - <widget> - <class>GtkLabel</class> - <child_name>Notebook:tab</child_name> - <name>label1</name> - <label>Task</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - - <widget> - <class>GtkTable</class> - <name>table4</name> - <border_width>4</border_width> - <rows>2</rows> - <columns>2</columns> - <homogeneous>False</homogeneous> - <row_spacing>2</row_spacing> - <column_spacing>4</column_spacing> - - <widget> - <class>GtkLabel</class> - <name>label12</name> - <label>Date Completed:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label14</name> - <label>URL:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>url</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>Custom</class> - <name>completed-date</name> - <creation_function>task_editor_create_date_edit</creation_function> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Sun, 10 Sep 2000 17:34:07 GMT</last_modification_time> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - </widget> - - <widget> - <class>GtkLabel</class> - <child_name>Notebook:tab</child_name> - <name>label2</name> - <label>Details</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - </widget> -</widget> - -</GTK-Interface> diff --git a/calendar/gui/e-calendar-table.c b/calendar/gui/e-calendar-table.c deleted file mode 100644 index ba3d1dedb3..0000000000 --- a/calendar/gui/e-calendar-table.c +++ /dev/null @@ -1,690 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 2000, Helix Code, Inc. - * Copyright 2000, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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 - */ - -/* - * ECalendarTable - displays the CalComponent objects in a table (an ETable). - * Used for calendar events and tasks. - */ - -#include <config.h> -#include <sys/stat.h> -#include <unistd.h> -#include <gnome.h> -#include <gal/e-table/e-table-scrolled.h> -#include <gal/e-table/e-cell-checkbox.h> -#include <gal/e-table/e-cell-toggle.h> -#include <gal/e-table/e-cell-text.h> -#include "e-calendar-table.h" -#include "calendar-model.h" -#include "dialogs/delete-comp.h" -#include "dialogs/task-editor.h" - -/* Pixmaps. */ -#include "task.xpm" -#include "task-recurring.xpm" -#include "task-assigned.xpm" -#include "task-assigned-to.xpm" - -#include "check-filled.xpm" - - -static void e_calendar_table_class_init (ECalendarTableClass *class); -static void e_calendar_table_init (ECalendarTable *cal_table); -static void e_calendar_table_destroy (GtkObject *object); - -static void e_calendar_table_on_double_click (ETable *table, - gint row, - gint col, - GdkEvent *event, - ECalendarTable *cal_table); -static gint e_calendar_table_on_right_click (ETable *table, - gint row, - gint col, - GdkEventButton *event, - ECalendarTable *cal_table); -static void e_calendar_table_on_open_task (GtkWidget *menuitem, - gpointer data); -static void e_calendar_table_on_mark_task_complete (GtkWidget *menuitem, - gpointer data); -static void e_calendar_table_on_delete_task (GtkWidget *menuitem, - gpointer data); -static gint e_calendar_table_on_key_press (ETable *table, - gint row, - gint col, - GdkEventKey *event, - ECalendarTable *cal_table); - -static void e_calendar_table_open_task (ECalendarTable *cal_table, - gint row); - -static void e_calendar_table_apply_filter (ECalendarTable *cal_table); -static void e_calendar_table_on_model_changed (ETableModel *model, - ECalendarTable *cal_table); -static void e_calendar_table_on_row_inserted (ETableModel *model, - gint row, - ECalendarTable *cal_table); -static void e_calendar_table_on_row_deleted (ETableModel *model, - gint row, - ECalendarTable *cal_table); - - -/* The icons to represent the task. */ -#define E_CALENDAR_MODEL_NUM_ICONS 4 -static char** icon_xpm_data[E_CALENDAR_MODEL_NUM_ICONS] = { - task_xpm, task_recurring_xpm, task_assigned_xpm, task_assigned_to_xpm -}; -static GdkPixbuf* icon_pixbufs[E_CALENDAR_MODEL_NUM_ICONS] = { 0 }; - -static GtkTableClass *parent_class; - - -GtkType -e_calendar_table_get_type (void) -{ - static GtkType e_calendar_table_type = 0; - - if (!e_calendar_table_type){ - GtkTypeInfo e_calendar_table_info = { - "ECalendarTable", - sizeof (ECalendarTable), - sizeof (ECalendarTableClass), - (GtkClassInitFunc) e_calendar_table_class_init, - (GtkObjectInitFunc) e_calendar_table_init, - NULL, /* reserved 1 */ - NULL, /* reserved 2 */ - (GtkClassInitFunc) NULL - }; - - parent_class = gtk_type_class (GTK_TYPE_TABLE); - e_calendar_table_type = gtk_type_unique (GTK_TYPE_TABLE, - &e_calendar_table_info); - } - - return e_calendar_table_type; -} - - -static void -e_calendar_table_class_init (ECalendarTableClass *class) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - - object_class = (GtkObjectClass *) class; - widget_class = (GtkWidgetClass *) class; - - /* Method override */ - object_class->destroy = e_calendar_table_destroy; - -#if 0 - widget_class->realize = e_calendar_table_realize; - widget_class->unrealize = e_calendar_table_unrealize; - widget_class->style_set = e_calendar_table_style_set; - widget_class->size_allocate = e_calendar_table_size_allocate; - widget_class->focus_in_event = e_calendar_table_focus_in; - widget_class->focus_out_event = e_calendar_table_focus_out; - widget_class->key_press_event = e_calendar_table_key_press; -#endif -} - -#ifdef JUST_FOR_TRANSLATORS -static char *list [] = { - N_("Categories"), - N_("Classification"), - N_("Completion Date"), - N_("End Date"), - N_("Start Date"), - N_("Due Date"), - N_("Geographical Position"), - N_("Precent complete"), - N_("Priority"), - N_("Summary"), - N_("Transparency"), - N_("URL"), - N_("Alarms"), - N_("Click here to add a task") -}; -#endif - -#define E_CALENDAR_TABLE_SPEC \ - "<ETableSpecification click-to-add=\"true\" " \ - " _click-to-add-message=\"Click here to add a task\" " \ - " draw-grid=\"true\">" \ - " <ETableColumn model_col= \"0\" _title=\"Categories\" " \ - " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \ - " cell=\"calstring\" compare=\"string\"/>" \ - " <ETableColumn model_col= \"1\" _title=\"Classification\" " \ - " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \ - " cell=\"calstring\" compare=\"string\"/>" \ - " <ETableColumn model_col= \"2\" _title=\"Completion Date\" " \ - " expansion=\"2.0\" minimum_width=\"10\" resizable=\"true\" " \ - " cell=\"calstring\" compare=\"string\"/>" \ - " <ETableColumn model_col= \"3\" _title=\"End Date\" " \ - " expansion=\"2.0\" minimum_width=\"10\" resizable=\"true\" " \ - " cell=\"calstring\" compare=\"string\"/>" \ - " <ETableColumn model_col= \"4\" _title=\"Start Date\" " \ - " expansion=\"2.0\" minimum_width=\"10\" resizable=\"true\" " \ - " cell=\"calstring\" compare=\"string\"/>" \ - " <ETableColumn model_col= \"5\" _title=\"Due Date\" " \ - " expansion=\"2.0\" minimum_width=\"10\" resizable=\"true\" " \ - " cell=\"calstring\" compare=\"string\"/>" \ - " <ETableColumn model_col= \"6\" _title=\"Geographical Position\" " \ - " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \ - " cell=\"calstring\" compare=\"string\"/>" \ - " <ETableColumn model_col= \"7\" _title=\"% Complete\" " \ - " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \ - " cell=\"calstring\" compare=\"string\"/>" \ - " <ETableColumn model_col= \"8\" _title=\"Priority\" " \ - " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \ - " cell=\"calstring\" compare=\"string\"/>" \ - " <ETableColumn model_col= \"9\" _title=\"Summary\" " \ - " expansion=\"3.0\" minimum_width=\"10\" resizable=\"true\" " \ - " cell=\"calstring\" compare=\"string\"/>" \ - " <ETableColumn model_col=\"10\" _title=\"Transparency\" " \ - " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \ - " cell=\"calstring\" compare=\"string\"/>" \ - " <ETableColumn model_col=\"11\" _title=\"URL\" " \ - " expansion=\"2.0\" minimum_width=\"10\" resizable=\"true\" " \ - " cell=\"calstring\" compare=\"string\"/>" \ - " <ETableColumn model_col=\"12\" _title=\"Alarms\" " \ - " expansion=\"1.0\" minimum_width=\"10\" resizable=\"true\" " \ - " cell=\"calstring\" compare=\"string\"/>" \ - " <ETableColumn model_col=\"13\" pixbuf=\"icon\" _title=\"Type\" "\ - " expansion=\"1.0\" minimum_width=\"16\" resizable=\"false\" "\ - " cell=\"icon\" compare=\"integer\"/>" \ - " <ETableColumn model_col=\"14\" pixbuf=\"complete\" _title=\"Compelete\" " \ - " expansion=\"1.0\" minimum_width=\"16\" resizable=\"false\" "\ - " cell=\"checkbox\" compare=\"integer\"/>" \ - " <ETableState>" \ - " <column source=\"13\"/>" \ - " <column source=\"14\"/>" \ - " <column source= \"9\"/>" \ - " <grouping></grouping>" \ - " </ETableState>" \ - "</ETableSpecification>" - -static void -e_calendar_table_init (ECalendarTable *cal_table) -{ - GtkWidget *table; - ETable *e_table; - ECell *cell; - ETableExtras *extras; - gint i; - GdkPixbuf *pixbuf; - GdkColormap *colormap; - gboolean success[E_CALENDAR_TABLE_COLOR_LAST]; - gint nfailed; - - /* Allocate the colors we need. */ - - colormap = gtk_widget_get_colormap (GTK_WIDGET (cal_table)); - - cal_table->colors[E_CALENDAR_TABLE_COLOR_OVERDUE].red = 65535; - cal_table->colors[E_CALENDAR_TABLE_COLOR_OVERDUE].green = 0; - cal_table->colors[E_CALENDAR_TABLE_COLOR_OVERDUE].blue = 0; - - nfailed = gdk_colormap_alloc_colors (colormap, cal_table->colors, - E_CALENDAR_TABLE_COLOR_LAST, - FALSE, TRUE, success); - if (nfailed) - g_warning ("Failed to allocate all colors"); - - /* Create the model */ - - cal_table->model = calendar_model_new (); - cal_table->subset_model = e_table_subset_variable_new (E_TABLE_MODEL (cal_table->model)); - - gtk_signal_connect (GTK_OBJECT (cal_table->model), "model_changed", - GTK_SIGNAL_FUNC (e_calendar_table_on_model_changed), - cal_table); - gtk_signal_connect (GTK_OBJECT (cal_table->model), "model_row_inserted", - GTK_SIGNAL_FUNC (e_calendar_table_on_row_inserted), - cal_table); - gtk_signal_connect (GTK_OBJECT (cal_table->model), "model_row_deleted", - GTK_SIGNAL_FUNC (e_calendar_table_on_row_deleted), - cal_table); - - /* Create the header columns */ - - extras = e_table_extras_new(); - - cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT); - gtk_object_set (GTK_OBJECT (cell), - "strikeout_column", CAL_COMPONENT_FIELD_COMPLETE, - "bold_column", CAL_COMPONENT_FIELD_OVERDUE, - "color_column", CAL_COMPONENT_FIELD_COLOR, - NULL); - e_table_extras_add_cell (extras, "calstring", cell); - - /* Create pixmaps */ - - if (!icon_pixbufs[0]) - for (i = 0; i < E_CALENDAR_MODEL_NUM_ICONS; i++) { - icon_pixbufs[i] = gdk_pixbuf_new_from_xpm_data ( - (const char **) icon_xpm_data[i]); - } - - cell = e_cell_toggle_new (0, E_CALENDAR_MODEL_NUM_ICONS, icon_pixbufs); - e_table_extras_add_cell(extras, "icon", cell); - e_table_extras_add_pixbuf(extras, "icon", icon_pixbufs[0]); - - pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) check_filled_xpm); - e_table_extras_add_pixbuf(extras, "complete", pixbuf); - gdk_pixbuf_unref(pixbuf); - - /* Create the table */ - - table = e_table_scrolled_new (cal_table->subset_model, extras, - E_CALENDAR_TABLE_SPEC, NULL); - gtk_object_unref (GTK_OBJECT (extras)); - - cal_table->etable = table; - gtk_table_attach (GTK_TABLE (cal_table), table, 0, 1, 0, 1, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - gtk_widget_show (table); - - - e_table = e_table_scrolled_get_table (E_TABLE_SCROLLED (table)); - gtk_signal_connect (GTK_OBJECT (e_table), "double_click", - GTK_SIGNAL_FUNC (e_calendar_table_on_double_click), - cal_table); - gtk_signal_connect (GTK_OBJECT (e_table), "right_click", - GTK_SIGNAL_FUNC (e_calendar_table_on_right_click), - cal_table); - gtk_signal_connect (GTK_OBJECT (e_table), "key_press", - GTK_SIGNAL_FUNC (e_calendar_table_on_key_press), - cal_table); -} - - -/** - * e_calendar_table_new: - * @Returns: a new #ECalendarTable. - * - * Creates a new #ECalendarTable. - **/ -GtkWidget * -e_calendar_table_new (void) -{ - GtkWidget *cal_table; - - cal_table = GTK_WIDGET (gtk_type_new (e_calendar_table_get_type ())); - - return cal_table; -} - - -/** - * e_calendar_table_get_model: - * @cal_table: A calendar table. - * - * Queries the calendar data model that a calendar table is using. - * - * Return value: A calendar model. - **/ -CalendarModel * -e_calendar_table_get_model (ECalendarTable *cal_table) -{ - g_return_val_if_fail (cal_table != NULL, NULL); - g_return_val_if_fail (E_IS_CALENDAR_TABLE (cal_table), NULL); - - return cal_table->model; -} - - -static void -e_calendar_table_destroy (GtkObject *object) -{ - ECalendarTable *cal_table; - - cal_table = E_CALENDAR_TABLE (object); - - gtk_object_unref (GTK_OBJECT (cal_table->model)); - cal_table->model = NULL; - - gtk_object_unref (GTK_OBJECT (cal_table->subset_model)); - cal_table->subset_model = NULL; - - GTK_OBJECT_CLASS (parent_class)->destroy (object); -} - - -void -e_calendar_table_set_cal_client (ECalendarTable *cal_table, - CalClient *client) -{ - calendar_model_set_cal_client (cal_table->model, client, - CALOBJ_TYPE_TODO); -} - - -static void -e_calendar_table_on_double_click (ETable *table, - gint row, - gint col, - GdkEvent *event, - ECalendarTable *cal_table) -{ - g_print ("In e_calendar_table_on_double_click\n"); - - e_calendar_table_open_task (cal_table, row); -} - - -static GnomeUIInfo e_calendar_table_popup_uiinfo[] = { - { GNOME_APP_UI_ITEM, N_("Mark Complete"), - N_("Mark the task complete"), e_calendar_table_on_mark_task_complete, - NULL, NULL, 0, 0, 0, 0 }, - - GNOMEUIINFO_SEPARATOR, - - { GNOME_APP_UI_ITEM, N_("Edit this task..."), - N_("Edit the task"), e_calendar_table_on_open_task, - NULL, NULL, 0, 0, 0, 0 }, - { GNOME_APP_UI_ITEM, N_("Delete this task"), - N_("Delete the task"), e_calendar_table_on_delete_task, - NULL, NULL, 0, 0, 0, 0 }, - - GNOMEUIINFO_END -}; - - -typedef struct _ECalendarMenuData ECalendarMenuData; -struct _ECalendarMenuData { - ECalendarTable *cal_table; - gint row; -}; - -static gint -e_calendar_table_on_right_click (ETable *table, - gint row, - gint col, - GdkEventButton *event, - ECalendarTable *cal_table) -{ - ECalendarMenuData menu_data; - GtkWidget *popup_menu; - - menu_data.cal_table = cal_table; - menu_data.row = row; - - popup_menu = gnome_popup_menu_new (e_calendar_table_popup_uiinfo); - gnome_popup_menu_do_popup_modal (popup_menu, NULL, NULL, event, - &menu_data); - - gtk_widget_destroy (popup_menu); - - return TRUE; -} - - -static void -e_calendar_table_on_open_task (GtkWidget *menuitem, - gpointer data) -{ - ECalendarMenuData *menu_data = (ECalendarMenuData*) data; - - e_calendar_table_open_task (menu_data->cal_table, - menu_data->row); -} - - -static void -e_calendar_table_on_mark_task_complete (GtkWidget *menuitem, - gpointer data) -{ - ECalendarMenuData *menu_data = (ECalendarMenuData*) data; - - calendar_model_mark_task_complete (menu_data->cal_table->model, - menu_data->row); -} - - -/* Deletes a component from the table */ -static void -delete_component (CalendarModel *model, int row, GtkWidget *widget) -{ - CalComponent *comp; - - comp = calendar_model_get_component (model, row); - - if (delete_component_dialog (comp, widget)) { - CalClient *client; - const char *uid; - - client = calendar_model_get_cal_client (model); - cal_component_get_uid (comp, &uid); - - /* We don't check the return value; FALSE can mean the object - * was not in the server anyways. - */ - cal_client_remove_object (client, uid); - } -} - -static void -e_calendar_table_on_delete_task (GtkWidget *menuitem, - gpointer data) -{ - ECalendarMenuData *menu_data = (ECalendarMenuData*) data; - - delete_component (menu_data->cal_table->model, menu_data->row, menuitem); -} - - - -static gint -e_calendar_table_on_key_press (ETable *table, - gint row, - gint col, - GdkEventKey *event, - ECalendarTable *cal_table) -{ - if (event->keyval == GDK_Delete) { - delete_component (cal_table->model, row, GTK_WIDGET (table)); - return TRUE; - } - - return FALSE; -} - - -static void -e_calendar_table_open_task (ECalendarTable *cal_table, - gint row) -{ - TaskEditor *tedit; - CalComponent *comp; - - tedit = task_editor_new (); - task_editor_set_cal_client (tedit, calendar_model_get_cal_client (cal_table->model)); - - comp = calendar_model_get_component (cal_table->model, row); - task_editor_set_todo_object (tedit, comp); - - task_editor_focus (tedit); -} - - -/* Loads the state of the table (headers shown etc.) from the given file. */ -void -e_calendar_table_load_state (ECalendarTable *cal_table, - gchar *filename) -{ - struct stat st; - - g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table)); - - if (stat (filename, &st) == 0 && st.st_size > 0 - && S_ISREG (st.st_mode)) { - e_table_load_state (e_table_scrolled_get_table(E_TABLE_SCROLLED (cal_table->etable)), filename); - } -} - - -/* Saves the state of the table (headers shown etc.) to the given file. */ -void -e_calendar_table_save_state (ECalendarTable *cal_table, - gchar *filename) -{ - g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table)); - - e_table_save_state (e_table_scrolled_get_table(E_TABLE_SCROLLED (cal_table->etable)), - filename); -} - - -void -e_calendar_table_set_filter_func (ECalendarTable *cal_table, - ECalendarTableFilterFunc filter_func, - gpointer filter_data, - GDestroyNotify filter_data_destroy) -{ - g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table)); - - if (cal_table->filter_func == filter_func - && cal_table->filter_data == filter_data - && cal_table->filter_data_destroy == filter_data_destroy) - return; - - if (cal_table->filter_data_destroy) - (*cal_table->filter_data_destroy) (cal_table->filter_data); - - cal_table->filter_func = filter_func; - cal_table->filter_data = filter_data; - cal_table->filter_data_destroy = filter_data_destroy; - - e_calendar_table_apply_filter (cal_table); -} - - -static void -e_calendar_table_apply_filter (ECalendarTable *cal_table) -{ - ETableSubsetVariable *etssv; - CalComponent *comp; - gint rows, row; - - etssv = E_TABLE_SUBSET_VARIABLE (cal_table->subset_model); - - /* Make sure that any edits get saved first. */ - e_table_model_pre_change (cal_table->subset_model); - - /* FIXME: A hack to remove all the existing rows quickly. */ - E_TABLE_SUBSET (cal_table->subset_model)->n_map = 0; - - if (cal_table->filter_func == NULL) { - e_table_subset_variable_add_all (etssv); - } else { - rows = e_table_model_row_count (E_TABLE_MODEL (cal_table->model)); - for (row = 0; row < rows; row++) { - comp = calendar_model_get_component (cal_table->model, - row); - - if ((*cal_table->filter_func) (cal_table, comp, - cal_table->filter_data)) - e_table_subset_variable_add (etssv, row); - } - } - - e_table_model_changed (cal_table->subset_model); -} - - -gboolean -e_calendar_table_filter_by_category (ECalendarTable *cal_table, - CalComponent *comp, - gpointer filter_data) -{ - GSList *categories_list, *elem; - gboolean retval = FALSE; - - cal_component_get_categories_list (comp, &categories_list); - - for (elem = categories_list; elem; elem = elem->next) { - if (retval == FALSE - && !strcmp ((char*) elem->data, (char*) filter_data)) - retval = TRUE; - g_free (elem->data); - } - - g_slist_free (categories_list); - - return retval; -} - - -static void -e_calendar_table_on_model_changed (ETableModel *model, - ECalendarTable *cal_table) -{ - e_calendar_table_apply_filter (cal_table); -} - - -static void -e_calendar_table_on_row_inserted (ETableModel *model, - gint row, - ECalendarTable *cal_table) -{ - ETableSubsetVariable *etssv; - CalComponent *comp; - gboolean add_row = FALSE; - - etssv = E_TABLE_SUBSET_VARIABLE (cal_table->subset_model); - - if (cal_table->filter_func == NULL) { - add_row = TRUE; - } else { - comp = calendar_model_get_component (cal_table->model, row); - - if ((*cal_table->filter_func) (cal_table, comp, - cal_table->filter_data)) - add_row = TRUE; - } - - if (add_row) { - e_table_subset_variable_increment (etssv, row, 1); - e_table_subset_variable_add (etssv, row); - } -} - - -static void -e_calendar_table_on_row_deleted (ETableModel *model, - gint row, - ECalendarTable *cal_table) -{ - /* We just reapply the filter since we aren't too bothered about - being efficient. It doesn't happen often. */ - e_calendar_table_apply_filter (cal_table); -} - -const gchar * -e_calendar_table_get_spec (void) -{ - return E_CALENDAR_TABLE_SPEC; -} diff --git a/calendar/gui/e-calendar-table.h b/calendar/gui/e-calendar-table.h deleted file mode 100644 index 89a57552b3..0000000000 --- a/calendar/gui/e-calendar-table.h +++ /dev/null @@ -1,119 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 2000, Helix Code, Inc. - * Copyright 2000, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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 - */ -#ifndef _E_CALENDAR_TABLE_H_ -#define _E_CALENDAR_TABLE_H_ - -#include <gtk/gtktable.h> -#include "calendar-model.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - * ECalendarTable - displays the iCalendar objects in a table (an ETable). - * Used for calendar events and tasks. - */ - -/* These index our colors array. */ -typedef enum -{ - E_CALENDAR_TABLE_COLOR_OVERDUE, - - E_CALENDAR_TABLE_COLOR_LAST -} ECalendarTableColors; - - -#define E_CALENDAR_TABLE(obj) GTK_CHECK_CAST (obj, e_calendar_table_get_type (), ECalendarTable) -#define E_CALENDAR_TABLE_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, e_calendar_table_get_type (), ECalendarTableClass) -#define E_IS_CALENDAR_TABLE(obj) GTK_CHECK_TYPE (obj, e_calendar_table_get_type ()) - - -typedef struct _ECalendarTable ECalendarTable; -typedef struct _ECalendarTableClass ECalendarTableClass; - - -typedef gboolean (*ECalendarTableFilterFunc) (ECalendarTable *cal_table, - CalComponent *comp, - gpointer data); - -struct _ECalendarTable -{ - GtkTable table; - - /* This is the underlying model which contains all the tasks/events. */ - CalendarModel *model; - - /* This is the model that we use when filtering the tasks/events. */ - ETableModel *subset_model; - - GtkWidget *etable; - - /* Colors for drawing. */ - GdkColor colors[E_CALENDAR_TABLE_COLOR_LAST]; - - /* Data for filtering the Tasks. */ - ECalendarTableFilterFunc filter_func; - gpointer filter_data; - GDestroyNotify filter_data_destroy; -}; - -struct _ECalendarTableClass -{ - GtkTableClass parent_class; -}; - - -GtkType e_calendar_table_get_type (void); -GtkWidget* e_calendar_table_new (void); - -CalendarModel *e_calendar_table_get_model (ECalendarTable *cal_table); - -void e_calendar_table_set_cal_client (ECalendarTable *cal_table, - CalClient *client); - -/* These load and save the state of the table (headers shown etc.) to/from - the given file. */ -void e_calendar_table_load_state (ECalendarTable *cal_table, - gchar *filename); -void e_calendar_table_save_state (ECalendarTable *cal_table, - gchar *filename); - -void e_calendar_table_set_filter_func (ECalendarTable *cal_table, - ECalendarTableFilterFunc filter_func, - gpointer filter_data, - GDestroyNotify filter_data_destroy); -gboolean e_calendar_table_filter_by_category (ECalendarTable *cal_table, - CalComponent *comp, - gpointer filter_data); - -const gchar *e_calendar_table_get_spec (void); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_CALENDAR_TABLE_H_ */ diff --git a/calendar/gui/e-day-view-main-item.c b/calendar/gui/e-day-view-main-item.c deleted file mode 100644 index 3cab1f1a05..0000000000 --- a/calendar/gui/e-day-view-main-item.c +++ /dev/null @@ -1,660 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 1999, Helix Code, Inc. - * Copyright 1999, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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 - */ - -/* - * EDayViewMainItem - canvas item which displays most of the appointment - * data in the main Day/Work Week display. - */ - -#include <config.h> -#include "e-day-view-main-item.h" - -static void e_day_view_main_item_class_init (EDayViewMainItemClass *class); -static void e_day_view_main_item_init (EDayViewMainItem *dvtitem); - -static void e_day_view_main_item_set_arg (GtkObject *o, GtkArg *arg, - guint arg_id); -static void e_day_view_main_item_update (GnomeCanvasItem *item, - double *affine, - ArtSVP *clip_path, int flags); -static void e_day_view_main_item_draw (GnomeCanvasItem *item, - GdkDrawable *drawable, - int x, int y, - int width, int height); -static double e_day_view_main_item_point (GnomeCanvasItem *item, - double x, double y, - int cx, int cy, - GnomeCanvasItem **actual_item); -static gint e_day_view_main_item_event (GnomeCanvasItem *item, - GdkEvent *event); - -static void e_day_view_main_item_draw_long_events_in_vbars (EDayViewMainItem *dvmitem, - GdkDrawable *drawable, - int x, - int y, - int width, - int height); -static void e_day_view_main_item_draw_events_in_vbars (EDayViewMainItem *dvmitem, - GdkDrawable *drawable, - int x, int y, - int width, int height, - gint day); -static void e_day_view_main_item_draw_day_events (EDayViewMainItem *dvmitem, - GdkDrawable *drawable, - int x, int y, - int width, int height, - gint day); -static void e_day_view_main_item_draw_day_event (EDayViewMainItem *dvmitem, - GdkDrawable *drawable, - int x, int y, - int width, int height, - gint day, gint event_num); - -static GnomeCanvasItemClass *parent_class; - -/* The arguments we take */ -enum { - ARG_0, - ARG_DAY_VIEW -}; - - -GtkType -e_day_view_main_item_get_type (void) -{ - static GtkType e_day_view_main_item_type = 0; - - if (!e_day_view_main_item_type) { - GtkTypeInfo e_day_view_main_item_info = { - "EDayViewMainItem", - sizeof (EDayViewMainItem), - sizeof (EDayViewMainItemClass), - (GtkClassInitFunc) e_day_view_main_item_class_init, - (GtkObjectInitFunc) e_day_view_main_item_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - e_day_view_main_item_type = gtk_type_unique (gnome_canvas_item_get_type (), &e_day_view_main_item_info); - } - - return e_day_view_main_item_type; -} - - -static void -e_day_view_main_item_class_init (EDayViewMainItemClass *class) -{ - GtkObjectClass *object_class; - GnomeCanvasItemClass *item_class; - - parent_class = gtk_type_class (gnome_canvas_item_get_type()); - - object_class = (GtkObjectClass *) class; - item_class = (GnomeCanvasItemClass *) class; - - gtk_object_add_arg_type ("EDayViewMainItem::day_view", - GTK_TYPE_POINTER, GTK_ARG_WRITABLE, - ARG_DAY_VIEW); - - object_class->set_arg = e_day_view_main_item_set_arg; - - /* GnomeCanvasItem method overrides */ - item_class->update = e_day_view_main_item_update; - item_class->draw = e_day_view_main_item_draw; - item_class->point = e_day_view_main_item_point; - item_class->event = e_day_view_main_item_event; -} - - -static void -e_day_view_main_item_init (EDayViewMainItem *dvtitem) -{ - dvtitem->day_view = NULL; -} - - -static void -e_day_view_main_item_set_arg (GtkObject *o, GtkArg *arg, guint arg_id) -{ - GnomeCanvasItem *item; - EDayViewMainItem *dvmitem; - - item = GNOME_CANVAS_ITEM (o); - dvmitem = E_DAY_VIEW_MAIN_ITEM (o); - - switch (arg_id){ - case ARG_DAY_VIEW: - dvmitem->day_view = GTK_VALUE_POINTER (*arg); - break; - } -} - - -static void -e_day_view_main_item_update (GnomeCanvasItem *item, - double *affine, - ArtSVP *clip_path, - int flags) -{ - if (GNOME_CANVAS_ITEM_CLASS (parent_class)->update) - (* GNOME_CANVAS_ITEM_CLASS (parent_class)->update) (item, affine, clip_path, flags); - - /* The item covers the entire canvas area. */ - item->x1 = 0; - item->y1 = 0; - item->x2 = INT_MAX; - item->y2 = INT_MAX; -} - - -/* - * DRAWING ROUTINES - functions to paint the canvas item. - */ - -static void -e_day_view_main_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable, - int x, int y, int width, int height) -{ - EDayViewMainItem *dvmitem; - EDayView *day_view; - GtkStyle *style; - GdkGC *gc; - GdkFont *font; - gint row, row_y, grid_x1, grid_x2; - gint day, grid_y1, grid_y2; - gint work_day_start_row, work_day_end_row; - gint work_day_start_y, work_day_end_y; - gint day_x, day_w, work_day; - gint start_row, end_row, rect_x, rect_y, rect_width, rect_height; - struct tm *day_start; - -#if 0 - g_print ("In e_day_view_main_item_draw %i,%i %ix%i\n", - x, y, width, height); -#endif - dvmitem = E_DAY_VIEW_MAIN_ITEM (canvas_item); - day_view = dvmitem->day_view; - g_return_if_fail (day_view != NULL); - - style = GTK_WIDGET (day_view)->style; - font = style->font; - - /* Paint the background colors. */ - gc = day_view->main_gc; - work_day_start_row = e_day_view_convert_time_to_row (day_view, day_view->work_day_start_hour, day_view->work_day_start_minute); - work_day_start_y = work_day_start_row * day_view->row_height - y; - work_day_end_row = e_day_view_convert_time_to_row (day_view, day_view->work_day_end_hour, day_view->work_day_end_minute); - work_day_end_y = work_day_end_row * day_view->row_height - y; - - for (day = 0; day < day_view->days_shown; day++) { - day_start = localtime (&day_view->day_starts[day]); - - work_day = day_view->working_days & (1 << day_start->tm_wday); - - day_x = day_view->day_offsets[day] - x; - day_w = day_view->day_widths[day]; - - if (work_day) { - gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING]); - gdk_draw_rectangle (drawable, gc, TRUE, - day_x, 0 - y, - day_w, work_day_start_y - (0 - y)); - gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_BG_WORKING]); - gdk_draw_rectangle (drawable, gc, TRUE, - day_x, work_day_start_y, - day_w, work_day_end_y - work_day_start_y); - gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING]); - gdk_draw_rectangle (drawable, gc, TRUE, - day_x, work_day_end_y, - day_w, height - work_day_end_y); - } else { - gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING]); - gdk_draw_rectangle (drawable, gc, TRUE, - day_x, 0, - day_w, height); - } - } - - /* Paint the selection background. */ - if (GTK_WIDGET_HAS_FOCUS (day_view) - && day_view->selection_start_day != -1 - && !day_view->selection_in_top_canvas) { - for (day = day_view->selection_start_day; - day <= day_view->selection_end_day; - day++) { - if (day == day_view->selection_start_day - && day_view->selection_start_row != -1) - start_row = day_view->selection_start_row; - else - start_row = 0; - if (day == day_view->selection_end_day - && day_view->selection_end_row != -1) - end_row = day_view->selection_end_row; - else - end_row = day_view->rows - 1; - - rect_x = day_view->day_offsets[day] - x; - rect_width = day_view->day_widths[day]; - rect_y = start_row * day_view->row_height - y; - rect_height = (end_row - start_row + 1) * day_view->row_height; - - gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_BG_SELECTED]); - gdk_draw_rectangle (drawable, gc, TRUE, - rect_x, rect_y, - rect_width, rect_height); - } - } - - /* Drawing the horizontal grid lines. */ - grid_x1 = day_view->day_offsets[0] - x; - grid_x2 = day_view->day_offsets[day_view->days_shown] - x; - - gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_BG_GRID]); - for (row = 0, row_y = 0 - y; - row < day_view->rows && row_y < height; - row++, row_y += day_view->row_height) { - if (row_y >= 0 && row_y < height) - gdk_draw_line (drawable, gc, - grid_x1, row_y, grid_x2, row_y); - } - - /* Draw the vertical bars down the left of each column. */ - grid_y1 = 0; - grid_y2 = height; - for (day = 0; day < day_view->days_shown; day++) { - grid_x1 = day_view->day_offsets[day] - x; - - /* Skip if it isn't visible. */ - if (grid_x1 >= width || grid_x1 + E_DAY_VIEW_BAR_WIDTH <= 0) - continue; - - gdk_draw_line (drawable, style->black_gc, - grid_x1, grid_y1, - grid_x1, grid_y2); - gdk_draw_line (drawable, style->black_gc, - grid_x1 + E_DAY_VIEW_BAR_WIDTH - 1, grid_y1, - grid_x1 + E_DAY_VIEW_BAR_WIDTH - 1, grid_y2); - gdk_draw_rectangle (drawable, style->white_gc, TRUE, - grid_x1 + 1, grid_y1, - E_DAY_VIEW_BAR_WIDTH - 2, grid_y2 - grid_y1); - - /* Fill in the bars when the user is busy. */ - e_day_view_main_item_draw_events_in_vbars (dvmitem, drawable, - x, y, - width, height, - day); - } - - /* Fill in the vertical bars corresponding to the busy times from the - long events. */ - e_day_view_main_item_draw_long_events_in_vbars (dvmitem, drawable, - x, y, width, height); - - /* Draw the event borders and backgrounds, and the vertical bars - down the left edges. */ - for (day = 0; day < day_view->days_shown; day++) { - e_day_view_main_item_draw_day_events (dvmitem, drawable, - x, y, width, height, - day); - } -} - - -static void -e_day_view_main_item_draw_events_in_vbars (EDayViewMainItem *dvmitem, - GdkDrawable *drawable, - int x, int y, - int width, int height, - gint day) -{ - EDayView *day_view; - EDayViewEvent *event; - GdkGC *gc; - gint grid_x, event_num, bar_y, bar_h; - - day_view = dvmitem->day_view; - - gc = day_view->main_gc; - gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR]); - - grid_x = day_view->day_offsets[day] + 1 - x; - - /* Draw the busy times corresponding to the events in the day. */ - for (event_num = 0; event_num < day_view->events[day]->len; - event_num++) { - event = &g_array_index (day_view->events[day], EDayViewEvent, - event_num); - - /* We can skip the events in the first column since they will - draw over this anyway. */ - if (event->num_columns > 0 && event->start_row_or_col == 0) - continue; - - bar_y = event->start_minute * day_view->row_height / day_view->mins_per_row; - bar_h = event->end_minute * day_view->row_height / day_view->mins_per_row - bar_y; - bar_y -= y; - - /* Skip it if it isn't visible. */ - if (bar_y >= height || bar_y + bar_h <= 0) - continue; - - gdk_draw_rectangle (drawable, gc, TRUE, - grid_x, bar_y, - E_DAY_VIEW_BAR_WIDTH - 2, bar_h); - } -} - - -static void -e_day_view_main_item_draw_long_events_in_vbars (EDayViewMainItem *dvmitem, - GdkDrawable *drawable, - int x, int y, - int width, int height) -{ - EDayView *day_view; - EDayViewEvent *event; - gint event_num, start_day, end_day, day, bar_y1, bar_y2, grid_x; - GdkGC *gc; - - day_view = dvmitem->day_view; - - gc = day_view->main_gc; - gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR]); - - for (event_num = 0; event_num < day_view->long_events->len; - event_num++) { - event = &g_array_index (day_view->long_events, EDayViewEvent, - event_num); - - if (!e_day_view_find_long_event_days (day_view, event, - &start_day, &end_day)) - continue; - - for (day = start_day; day <= end_day; day++) { - grid_x = day_view->day_offsets[day] + 1 - x; - - /* Skip if it isn't visible. */ - if (grid_x >= width - || grid_x + E_DAY_VIEW_BAR_WIDTH <= 0) - continue; - - if (event->start <= day_view->day_starts[day]) { - bar_y1 = 0; - } else { - bar_y1 = event->start_minute * day_view->row_height / day_view->mins_per_row - y; - } - - if (event->end >= day_view->day_starts[day + 1]) { - bar_y2 = height; - } else { - bar_y2 = event->end_minute * day_view->row_height / day_view->mins_per_row - y; - } - - if (bar_y1 < height && bar_y2 > 0 && bar_y2 > bar_y1) { - gdk_draw_rectangle (drawable, gc, TRUE, - grid_x, bar_y1, - E_DAY_VIEW_BAR_WIDTH - 2, - bar_y2 - bar_y1); - } - } - - - } -} - - -static void -e_day_view_main_item_draw_day_events (EDayViewMainItem *dvmitem, - GdkDrawable *drawable, - int x, int y, int width, int height, - gint day) -{ - EDayView *day_view; - gint event_num; - - day_view = dvmitem->day_view; - - for (event_num = 0; event_num < day_view->events[day]->len; - event_num++) { - e_day_view_main_item_draw_day_event (dvmitem, drawable, - x, y, width, height, - day, event_num); - } -} - - -static void -e_day_view_main_item_draw_day_event (EDayViewMainItem *dvmitem, - GdkDrawable *drawable, - int x, int y, int width, int height, - gint day, gint event_num) -{ - EDayView *day_view; - EDayViewEvent *event; - gint item_x, item_y, item_w, item_h, bar_y1, bar_y2; - GtkStyle *style; - GdkGC *gc; - CalComponent *comp; - gint num_icons, icon_x, icon_y, icon_x_inc, icon_y_inc; - gint max_icon_w, max_icon_h; - gboolean draw_reminder_icon, draw_recurrence_icon; - - day_view = dvmitem->day_view; - - /* If the event is currently being dragged, don't draw it. It will - be drawn in the special drag items. */ - if (day_view->drag_event_day == day - && day_view->drag_event_num == event_num) - return; - - style = GTK_WIDGET (day_view)->style; - - gc = day_view->main_gc; - gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR]); - - /* Get the position of the event. If it is not shown skip it.*/ - if (!e_day_view_get_event_position (day_view, day, event_num, - &item_x, &item_y, - &item_w, &item_h)) - return; - - item_x -= x; - item_y -= y; - - event = &g_array_index (day_view->events[day], EDayViewEvent, - event_num); - - /* Fill in the white background. Note that for events in the first - column of the day, we might not want to paint over the vertical bar, - since that is used for multiple events. But then you can't see - where the event in the first column finishes. */ -#if 0 - if (event->start_row_or_col == 0) - gdk_draw_rectangle (drawable, style->white_gc, TRUE, - item_x + E_DAY_VIEW_BAR_WIDTH, item_y + 1, - MAX (item_w - E_DAY_VIEW_BAR_WIDTH - 1, 0), - item_h - 2); - else -#endif - gdk_draw_rectangle (drawable, style->white_gc, TRUE, - item_x + 1, item_y + 1, - MAX (item_w - 2, 0), item_h - 2); - - /* Draw the right edge of the vertical bar. */ - gdk_draw_line (drawable, style->black_gc, - item_x + E_DAY_VIEW_BAR_WIDTH - 1, - item_y + 1, - item_x + E_DAY_VIEW_BAR_WIDTH - 1, - item_y + item_h - 2); - - /* Draw the vertical colored bar showing when the appointment - begins & ends. */ - bar_y1 = event->start_minute * day_view->row_height / day_view->mins_per_row - y; - bar_y2 = event->end_minute * day_view->row_height / day_view->mins_per_row - y; - - /* When an item is being resized, we fill the bar up to the new row. */ - if (day_view->resize_drag_pos != E_DAY_VIEW_POS_NONE - && day_view->resize_event_day == day - && day_view->resize_event_num == event_num) { - if (day_view->resize_drag_pos == E_DAY_VIEW_POS_TOP_EDGE) - bar_y1 = item_y + 1; - else if (day_view->resize_drag_pos == E_DAY_VIEW_POS_BOTTOM_EDGE) - bar_y2 = item_y + item_h - 1; - } - - gdk_draw_rectangle (drawable, gc, TRUE, - item_x + 1, bar_y1, - E_DAY_VIEW_BAR_WIDTH - 2, bar_y2 - bar_y1); - - /* Draw the box around the entire event. Do this after drawing - the colored bar so we don't have to worry about being 1 - pixel out. */ - gdk_draw_rectangle (drawable, style->black_gc, FALSE, - item_x, item_y, MAX (item_w - 1, 0), item_h - 1); - -#if 0 - /* Draw the horizontal bars above and beneath the event if it - is currently being edited. */ - if (day_view->editing_event_day == day - && day_view->editing_event_num == event_num) { - gdk_draw_rectangle (drawable, gc, TRUE, - item_x, - item_y - E_DAY_VIEW_BAR_HEIGHT, - item_w, - E_DAY_VIEW_BAR_HEIGHT); - gdk_draw_rectangle (drawable, gc, TRUE, - item_x, item_y + item_h, - item_w, E_DAY_VIEW_BAR_HEIGHT); - } -#endif - - /* Draw the reminder & recurrence icons, if needed. */ - num_icons = 0; - draw_reminder_icon = FALSE; - draw_recurrence_icon = FALSE; - icon_x = item_x + E_DAY_VIEW_BAR_WIDTH + E_DAY_VIEW_ICON_X_PAD; - icon_y = item_y + E_DAY_VIEW_EVENT_BORDER_HEIGHT - + E_DAY_VIEW_ICON_Y_PAD; - comp = event->comp; - - if (cal_component_has_alarms (comp)) { - draw_reminder_icon = TRUE; - num_icons++; - } - - if (cal_component_has_recurrences (comp)) { - draw_recurrence_icon = TRUE; - num_icons++; - } - - if (num_icons != 0) { - if (item_h >= (E_DAY_VIEW_ICON_HEIGHT + E_DAY_VIEW_ICON_Y_PAD) - * num_icons) { - icon_x_inc = 0; - icon_y_inc = E_DAY_VIEW_ICON_HEIGHT - + E_DAY_VIEW_ICON_Y_PAD; - } else { - icon_x_inc = E_DAY_VIEW_ICON_WIDTH - + E_DAY_VIEW_ICON_X_PAD; - icon_y_inc = 0; - } - - if (draw_reminder_icon) { - max_icon_w = item_x + item_w - icon_x - - E_DAY_VIEW_EVENT_BORDER_WIDTH; - max_icon_h = item_y + item_h - icon_y - - E_DAY_VIEW_EVENT_BORDER_HEIGHT; - - gdk_gc_set_clip_origin (gc, icon_x, icon_y); - gdk_gc_set_clip_mask (gc, day_view->reminder_mask); - gdk_draw_pixmap (drawable, gc, - day_view->reminder_icon, - 0, 0, icon_x, icon_y, - MIN (E_DAY_VIEW_ICON_WIDTH, - max_icon_w), - MIN (E_DAY_VIEW_ICON_HEIGHT, - max_icon_h)); - icon_x += icon_x_inc; - icon_y += icon_y_inc; - } - - if (draw_recurrence_icon) { - max_icon_w = item_x + item_w - icon_x - - E_DAY_VIEW_EVENT_BORDER_WIDTH; - max_icon_h = item_y + item_h - icon_y - - E_DAY_VIEW_EVENT_BORDER_HEIGHT; - - gdk_gc_set_clip_origin (gc, icon_x, icon_y); - gdk_gc_set_clip_mask (gc, day_view->recurrence_mask); - gdk_draw_pixmap (drawable, gc, - day_view->recurrence_icon, - 0, 0, icon_x, icon_y, - MIN (E_DAY_VIEW_ICON_WIDTH, - max_icon_w), - MIN (E_DAY_VIEW_ICON_HEIGHT, - max_icon_h)); - } - gdk_gc_set_clip_mask (gc, NULL); - } -} - - -/* This is supposed to return the nearest item to the point and the distance. - Since we are the only item we just return ourself and 0 for the distance. - This is needed so that we get button/motion events. */ -static double -e_day_view_main_item_point (GnomeCanvasItem *item, double x, double y, - int cx, int cy, - GnomeCanvasItem **actual_item) -{ - *actual_item = item; - return 0.0; -} - - -static gint -e_day_view_main_item_event (GnomeCanvasItem *item, GdkEvent *event) -{ - EDayViewMainItem *dvtitem; - - dvtitem = E_DAY_VIEW_MAIN_ITEM (item); - - switch (event->type) { - case GDK_BUTTON_PRESS: - - case GDK_BUTTON_RELEASE: - - case GDK_MOTION_NOTIFY: - - default: - break; - } - - return FALSE; -} - - diff --git a/calendar/gui/e-day-view-main-item.h b/calendar/gui/e-day-view-main-item.h deleted file mode 100644 index cb9e2589d8..0000000000 --- a/calendar/gui/e-day-view-main-item.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 1999, Helix Code, Inc. - * Copyright 1999, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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 - */ -#ifndef _E_DAY_VIEW_MAIN_ITEM_H_ -#define _E_DAY_VIEW_MAIN_ITEM_H_ - -#include "e-day-view.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - * EDayViewMainItem - canvas item which displays most of the appointment - * data in the main Day/Work Week display. - */ - -#define E_DAY_VIEW_MAIN_ITEM(obj) (GTK_CHECK_CAST((obj), \ - e_day_view_main_item_get_type (), EDayViewMainItem)) -#define E_DAY_VIEW_MAIN_ITEM_CLASS(k) (GTK_CHECK_CLASS_CAST ((k),\ - e_day_view_main_item_get_type ())) -#define E_IS_DAY_VIEW_MAIN_ITEM(o) (GTK_CHECK_TYPE((o), \ - e_day_view_main_item_get_type ())) - -typedef struct { - GnomeCanvasItem canvas_item; - - /* The parent EDayView widget. */ - EDayView *day_view; -} EDayViewMainItem; - -typedef struct { - GnomeCanvasItemClass parent_class; - -} EDayViewMainItemClass; - - -GtkType e_day_view_main_item_get_type (void); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_DAY_VIEW_MAIN_ITEM_H_ */ diff --git a/calendar/gui/e-day-view-time-item.c b/calendar/gui/e-day-view-time-item.c deleted file mode 100644 index 854d3cb34f..0000000000 --- a/calendar/gui/e-day-view-time-item.c +++ /dev/null @@ -1,657 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 1999, Helix Code, Inc. - * Copyright 1999, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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 - */ - -/* - * EDayViewTimeItem - canvas item which displays the times down the left of - * the EDayView. - */ - -#include <config.h> -#include <gal/widgets/e-gui-utils.h> -#include "e-day-view-time-item.h" -#include "calendar-config.h" - - -/* The spacing between items in the time column. GRID_X_PAD is the space down - either side of the column, i.e. outside the main horizontal grid lines. - HOUR_L_PAD & HOUR_R_PAD are the spaces on the left & right side of the - big hour number (this is inside the horizontal grid lines). - MIN_X_PAD is the spacing either side of the minute number. The smaller - horizontal grid lines match with this. - 60_MIN_X_PAD is the space either side of the HH:MM display used when - we are displaying 60 mins per row (inside the main grid lines). - LARGE_HOUR_Y_PAD is the offset of the large hour string from the top of the - row. - SMALL_FONT_Y_PAD is the offset of the small time/minute string from the top - of the row. */ -#define E_DVTMI_TIME_GRID_X_PAD 4 -#define E_DVTMI_HOUR_L_PAD 4 -#define E_DVTMI_HOUR_R_PAD 2 -#define E_DVTMI_MIN_X_PAD 2 -#define E_DVTMI_60_MIN_X_PAD 4 -#define E_DVTMI_LARGE_HOUR_Y_PAD 1 -#define E_DVTMI_SMALL_FONT_Y_PAD 1 - -static void e_day_view_time_item_class_init (EDayViewTimeItemClass *class); -static void e_day_view_time_item_init (EDayViewTimeItem *dvtmitem); -static void e_day_view_time_item_set_arg (GtkObject *o, - GtkArg *arg, - guint arg_id); - -static void e_day_view_time_item_update (GnomeCanvasItem *item, - double *affine, - ArtSVP *clip_path, int flags); -static void e_day_view_time_item_draw (GnomeCanvasItem *item, - GdkDrawable *drawable, - int x, int y, - int width, int height); -static double e_day_view_time_item_point (GnomeCanvasItem *item, - double x, double y, - int cx, int cy, - GnomeCanvasItem **actual_item); -static gint e_day_view_time_item_event (GnomeCanvasItem *item, - GdkEvent *event); -static void e_day_view_time_item_increment_time (gint *hour, - gint *minute, - gint mins_per_row); -static void e_day_view_time_item_show_popup_menu (EDayViewTimeItem *dvtmitem, - GdkEvent *event); -static void e_day_view_time_item_on_set_divisions (GtkWidget *item, - EDayViewTimeItem *dvtmitem); -static void e_day_view_time_item_on_button_press (EDayViewTimeItem *dvtmitem, - GdkEvent *event); -static void e_day_view_time_item_on_button_release (EDayViewTimeItem *dvtmitem, - GdkEvent *event); -static void e_day_view_time_item_on_motion_notify (EDayViewTimeItem *dvtmitem, - GdkEvent *event); -static gint e_day_view_time_item_convert_position_to_row (EDayViewTimeItem *dvtmitem, - gint y); - - -static GnomeCanvasItemClass *parent_class; - - -/* The arguments we take */ -enum { - ARG_0, - ARG_DAY_VIEW -}; - - -GtkType -e_day_view_time_item_get_type (void) -{ - static GtkType e_day_view_time_item_type = 0; - - if (!e_day_view_time_item_type) { - GtkTypeInfo e_day_view_time_item_info = { - "EDayViewTimeItem", - sizeof (EDayViewTimeItem), - sizeof (EDayViewTimeItemClass), - (GtkClassInitFunc) e_day_view_time_item_class_init, - (GtkObjectInitFunc) e_day_view_time_item_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - e_day_view_time_item_type = gtk_type_unique (gnome_canvas_item_get_type (), &e_day_view_time_item_info); - } - - return e_day_view_time_item_type; -} - - -static void -e_day_view_time_item_class_init (EDayViewTimeItemClass *class) -{ - GtkObjectClass *object_class; - GnomeCanvasItemClass *item_class; - - parent_class = gtk_type_class (gnome_canvas_item_get_type()); - - object_class = (GtkObjectClass *) class; - item_class = (GnomeCanvasItemClass *) class; - - gtk_object_add_arg_type ("EDayViewTimeItem::day_view", - GTK_TYPE_POINTER, GTK_ARG_WRITABLE, - ARG_DAY_VIEW); - - object_class->set_arg = e_day_view_time_item_set_arg; - - /* GnomeCanvasItem method overrides */ - item_class->update = e_day_view_time_item_update; - item_class->draw = e_day_view_time_item_draw; - item_class->point = e_day_view_time_item_point; - item_class->event = e_day_view_time_item_event; -} - - -static void -e_day_view_time_item_init (EDayViewTimeItem *dvtmitem) -{ - dvtmitem->dragging_selection = FALSE; -} - - -static void -e_day_view_time_item_set_arg (GtkObject *o, GtkArg *arg, guint arg_id) -{ - GnomeCanvasItem *item; - EDayViewTimeItem *dvtmitem; - - item = GNOME_CANVAS_ITEM (o); - dvtmitem = E_DAY_VIEW_TIME_ITEM (o); - - switch (arg_id){ - case ARG_DAY_VIEW: - dvtmitem->day_view = GTK_VALUE_POINTER (*arg); - break; - } -} - - -static void -e_day_view_time_item_update (GnomeCanvasItem *item, - double *affine, - ArtSVP *clip_path, - int flags) -{ - if (GNOME_CANVAS_ITEM_CLASS (parent_class)->update) - (* GNOME_CANVAS_ITEM_CLASS (parent_class)->update) (item, affine, clip_path, flags); - - /* The item covers the entire canvas area. */ - item->x1 = 0; - item->y1 = 0; - item->x2 = INT_MAX; - item->y2 = INT_MAX; -} - - -/* Returns the minimum width needed for the column, by adding up all the - maximum widths of the strings. The string widths are all calculated in - the style_set handlers of EDayView and EDayViewTimeCanvas. */ -gint -e_day_view_time_item_get_column_width (EDayViewTimeItem *dvtmitem) -{ - EDayView *day_view; - GtkStyle *style; - GdkFont *small_font, *large_font; - gint digit, large_digit_width, max_large_digit_width = 0; - gint max_suffix_width, max_minute_or_suffix_width; - gint column_width_default, column_width_60_min_rows; - - day_view = dvtmitem->day_view; - g_return_val_if_fail (day_view != NULL, 0); - - style = GTK_WIDGET (day_view)->style; - g_return_val_if_fail (style != NULL, 0); - small_font = style->font; - g_return_val_if_fail (small_font != NULL, 0); - large_font = day_view->large_font; - g_return_val_if_fail (large_font != NULL, 0); - - for (digit = '0'; digit <= '9'; digit++) { - large_digit_width = gdk_char_width (large_font, digit); - max_large_digit_width = MAX (max_large_digit_width, - large_digit_width); - } - - /* Calculate the width of each time column, using the maximum of the - default format with large hour numbers, and the 60-min divisions - format which uses small text. */ - max_suffix_width = MAX (day_view->am_string_width, - day_view->pm_string_width); - - max_minute_or_suffix_width = MAX (max_suffix_width, - day_view->max_minute_width); - - column_width_default = max_large_digit_width * 2 - + max_minute_or_suffix_width - + E_DVTMI_MIN_X_PAD * 2 - + E_DVTMI_HOUR_L_PAD - + E_DVTMI_HOUR_R_PAD - + E_DVTMI_TIME_GRID_X_PAD * 2; - - column_width_60_min_rows = day_view->max_small_hour_width - + day_view->colon_width - + max_minute_or_suffix_width - + E_DVTMI_60_MIN_X_PAD * 2 - + E_DVTMI_TIME_GRID_X_PAD * 2; - - dvtmitem->column_width = MAX (column_width_default, - column_width_60_min_rows); - - return dvtmitem->column_width; -} - - -/* - * DRAWING ROUTINES - functions to paint the canvas item. - */ - -static void -e_day_view_time_item_draw (GnomeCanvasItem *canvas_item, - GdkDrawable *drawable, - int x, - int y, - int width, - int height) -{ - EDayView *day_view; - EDayViewTimeItem *dvtmitem; - GtkStyle *style; - GdkFont *small_font, *large_font; - GdkGC *fg_gc, *dark_gc; - gchar buffer[64], *suffix; - gint hour, display_hour, minute, row; - gint row_y, start_y, large_hour_y_offset, small_font_y_offset; - gint long_line_x1, long_line_x2, short_line_x1; - gint large_hour_x2, minute_x2; - gint hour_width, minute_width, suffix_width; - gint max_suffix_width, max_minute_or_suffix_width; - - dvtmitem = E_DAY_VIEW_TIME_ITEM (canvas_item); - day_view = dvtmitem->day_view; - g_return_if_fail (day_view != NULL); - - style = GTK_WIDGET (day_view)->style; - small_font = style->font; - large_font = day_view->large_font; - fg_gc = style->fg_gc[GTK_STATE_NORMAL]; - dark_gc = style->dark_gc[GTK_STATE_NORMAL]; - - /* The start and end of the long horizontal line between hours. */ - long_line_x1 = E_DVTMI_TIME_GRID_X_PAD - x; - long_line_x2 = dvtmitem->column_width - E_DVTMI_TIME_GRID_X_PAD - x; - - if (day_view->mins_per_row == 60) { - /* The right edge of the complete time string in 60-min - divisions, e.g. "14:00" or "2 pm". */ - minute_x2 = long_line_x2 - E_DVTMI_60_MIN_X_PAD; - - /* These aren't used for 60-minute divisions, but we initialize - them to keep gcc happy. */ - short_line_x1 = 0; - large_hour_x2 = 0; - } else { - max_suffix_width = MAX (day_view->am_string_width, - day_view->pm_string_width); - - max_minute_or_suffix_width = MAX (max_suffix_width, - day_view->max_minute_width); - - /* The start of the short horizontal line between the periods - within each hour. */ - short_line_x1 = long_line_x2 - E_DVTMI_MIN_X_PAD * 2 - - max_minute_or_suffix_width; - - /* The right edge of the large hour string. */ - large_hour_x2 = short_line_x1 - E_DVTMI_HOUR_R_PAD; - - /* The right edge of the minute part of the time. */ - minute_x2 = long_line_x2 - E_DVTMI_MIN_X_PAD; - } - - /* Start with the first hour & minute shown in the EDayView. */ - hour = day_view->first_hour_shown; - minute = day_view->first_minute_shown; - - /* The offset of the large hour string from the top of the row. */ - large_hour_y_offset = large_font->ascent + E_DVTMI_LARGE_HOUR_Y_PAD; - - /* The offset of the small time/minute string from top of row. */ - small_font_y_offset = small_font->ascent + E_DVTMI_SMALL_FONT_Y_PAD; - - /* Calculate the minimum y position of the first row we need to draw. - This is normally one row height above the 0 position, but if we - are using the large font we may have to go back a bit further. */ - start_y = 0 - MAX (day_view->row_height, - large_hour_y_offset + large_font->descent); - - /* Step through each row, drawing the times and the horizontal lines - between them. */ - for (row = 0, row_y = 0 - y; - row < day_view->rows && row_y < height; - row++, row_y += day_view->row_height) { - - /* If the row is above the first row we want to draw just - increment the time and skip to the next row. */ - if (row_y < start_y) { - e_day_view_time_item_increment_time (&hour, &minute, - day_view->mins_per_row); - continue; - } - - /* Calculate the actual hour number to display. For 12-hour - format we convert 0-23 to 12-11am/12-11pm. */ - e_day_view_convert_time_to_display (day_view, hour, - &display_hour, - &suffix, &suffix_width); - - if (day_view->mins_per_row == 60) { - /* 60 minute intervals - draw a long horizontal line - between hours and display as one long string, - e.g. "14:00" or "2 pm". */ - gdk_draw_line (drawable, dark_gc, - long_line_x1, row_y, - long_line_x2, row_y); - - if (day_view->use_24_hour_format) { - g_snprintf (buffer, sizeof (buffer), "%i:%02i", - display_hour, minute); - } else { - g_snprintf (buffer, sizeof (buffer), "%i %s", - display_hour, suffix); - } - minute_width = gdk_string_width (small_font, buffer); - gdk_draw_string (drawable, small_font, fg_gc, - minute_x2 - minute_width, - row_y + small_font_y_offset, - buffer); - } else { - /* 5/10/15/30 minute intervals. */ - - if (minute == 0) { - /* On the hour - draw a long horizontal line - before the hour and display the hour in the - large font. */ - gdk_draw_line (drawable, dark_gc, - long_line_x1, row_y, - long_line_x2, row_y); - - g_snprintf (buffer, sizeof (buffer), "%i", - display_hour); - hour_width = gdk_string_width (large_font, - buffer); - gdk_draw_string (drawable, large_font, fg_gc, - large_hour_x2 - hour_width, - row_y + large_hour_y_offset, - buffer); - } else { - /* Within the hour - draw a short line before - the time. */ - gdk_draw_line (drawable, dark_gc, - short_line_x1, row_y, - long_line_x2, row_y); - } - - /* Normally we display the minute in each - interval, but when using 30-minute intervals - we don't display the '30'. */ - if (day_view->mins_per_row != 30 || minute != 30) { - /* In 12-hour format we display 'am' or 'pm' - instead of '00'. */ - if (minute == 0 - && !day_view->use_24_hour_format) { - strcpy (buffer, suffix); - } else { - g_snprintf (buffer, sizeof (buffer), - "%02i", minute); - } - minute_width = gdk_string_width (small_font, - buffer); - gdk_draw_string (drawable, small_font, fg_gc, - minute_x2 - minute_width, - row_y + small_font_y_offset, - buffer); - } - } - - e_day_view_time_item_increment_time (&hour, &minute, - day_view->mins_per_row); - } -} - - -/* Increment the time by the 5/10/15/30/60 minute interval. - Note that mins_per_row is never > 60, so we never have to - worry about adding more than 60 minutes. */ -static void -e_day_view_time_item_increment_time (gint *hour, - gint *minute, - gint mins_per_row) -{ - *minute += mins_per_row; - if (*minute >= 60) { - *minute -= 60; - /* Currently we never wrap around to the next day, but - we may do if we display extra timezones. */ - *hour = (*hour + 1) % 24; - } -} - - -static double -e_day_view_time_item_point (GnomeCanvasItem *item, double x, double y, - int cx, int cy, - GnomeCanvasItem **actual_item) -{ - *actual_item = item; - return 0.0; -} - - -static gint -e_day_view_time_item_event (GnomeCanvasItem *item, - GdkEvent *event) -{ - EDayViewTimeItem *dvtmitem; - - dvtmitem = E_DAY_VIEW_TIME_ITEM (item); - - switch (event->type) { - case GDK_BUTTON_PRESS: - if (event->button.button == 1) { - e_day_view_time_item_on_button_press (dvtmitem, event); - } else if (event->button.button == 3) { - e_day_view_time_item_show_popup_menu (dvtmitem, event); - return TRUE; - } - break; - case GDK_BUTTON_RELEASE: - if (event->button.button == 1) - e_day_view_time_item_on_button_release (dvtmitem, - event); - break; - - case GDK_MOTION_NOTIFY: - e_day_view_time_item_on_motion_notify (dvtmitem, event); - break; - - default: - break; - } - - return FALSE; -} - - -static void -e_day_view_time_item_show_popup_menu (EDayViewTimeItem *dvtmitem, - GdkEvent *event) -{ - static gint divisions[] = { 60, 30, 15, 10, 5 }; - EDayView *day_view; - gint num_divisions = sizeof (divisions) / sizeof (divisions[0]); - GtkWidget *menu, *item; - gchar buffer[256]; - GSList *group = NULL; - gint current_divisions, i; - - day_view = dvtmitem->day_view; - g_return_if_fail (day_view != NULL); - - current_divisions = e_day_view_get_mins_per_row (day_view); - - menu = gtk_menu_new (); - - /* Make sure the menu is destroyed when it disappears. */ - e_auto_kill_popup_menu_on_hide (GTK_MENU (menu)); - - for (i = 0; i < num_divisions; i++) { - g_snprintf (buffer, sizeof (buffer), - _("%02i minute divisions"), divisions[i]); - item = gtk_radio_menu_item_new_with_label (group, buffer); - group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (item)); - gtk_widget_show (item); - gtk_menu_append (GTK_MENU (menu), item); - - if (current_divisions == divisions[i]) - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE); - - gtk_object_set_data (GTK_OBJECT (item), "divisions", - GINT_TO_POINTER (divisions[i])); - - gtk_signal_connect (GTK_OBJECT (item), "toggled", - e_day_view_time_item_on_set_divisions, - dvtmitem); - } - - gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, - event->button.button, event->button.time); -} - - -static void -e_day_view_time_item_on_set_divisions (GtkWidget *item, - EDayViewTimeItem *dvtmitem) -{ - EDayView *day_view; - gint divisions; - - day_view = dvtmitem->day_view; - g_return_if_fail (day_view != NULL); - - if (!GTK_CHECK_MENU_ITEM (item)->active) - return; - - divisions = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (item), - "divisions")); - e_day_view_set_mins_per_row (day_view, divisions); - calendar_config_set_time_divisions (divisions); -} - - -static void -e_day_view_time_item_on_button_press (EDayViewTimeItem *dvtmitem, - GdkEvent *event) -{ - EDayView *day_view; - GnomeCanvas *canvas; - gint row; - - day_view = dvtmitem->day_view; - g_return_if_fail (day_view != NULL); - - canvas = GNOME_CANVAS_ITEM (dvtmitem)->canvas; - - row = e_day_view_time_item_convert_position_to_row (dvtmitem, - event->button.y); - - if (row == -1) - return; - - if (!GTK_WIDGET_HAS_FOCUS (day_view)) - gtk_widget_grab_focus (GTK_WIDGET (day_view)); - - if (gdk_pointer_grab (GTK_LAYOUT (canvas)->bin_window, FALSE, - GDK_POINTER_MOTION_MASK - | GDK_BUTTON_RELEASE_MASK, - FALSE, NULL, event->button.time) == 0) { - e_day_view_start_selection (day_view, -1, row); - dvtmitem->dragging_selection = TRUE; - } -} - - -static void -e_day_view_time_item_on_button_release (EDayViewTimeItem *dvtmitem, - GdkEvent *event) -{ - EDayView *day_view; - - day_view = dvtmitem->day_view; - g_return_if_fail (day_view != NULL); - - if (dvtmitem->dragging_selection) { - gdk_pointer_ungrab (event->button.time); - e_day_view_finish_selection (day_view); - e_day_view_stop_auto_scroll (day_view); - } - - dvtmitem->dragging_selection = FALSE; -} - - -static void -e_day_view_time_item_on_motion_notify (EDayViewTimeItem *dvtmitem, - GdkEvent *event) -{ - EDayView *day_view; - GnomeCanvas *canvas; - gdouble window_y; - gint y, row; - - if (!dvtmitem->dragging_selection) - return; - - day_view = dvtmitem->day_view; - g_return_if_fail (day_view != NULL); - - canvas = GNOME_CANVAS_ITEM (dvtmitem)->canvas; - - y = event->motion.y; - row = e_day_view_time_item_convert_position_to_row (dvtmitem, y); - - if (row != -1) { - gnome_canvas_world_to_window (canvas, 0, event->motion.y, - NULL, &window_y); - e_day_view_update_selection (day_view, -1, row); - e_day_view_check_auto_scroll (day_view, -1, (gint) window_y); - } -} - - -/* Returns the row corresponding to the y position, or -1. */ -static gint -e_day_view_time_item_convert_position_to_row (EDayViewTimeItem *dvtmitem, - gint y) -{ - EDayView *day_view; - gint row; - - day_view = dvtmitem->day_view; - g_return_val_if_fail (day_view != NULL, -1); - - if (y < 0) - return -1; - - row = y / day_view->row_height; - if (row >= day_view->rows) - return -1; - - return row; -} diff --git a/calendar/gui/e-day-view-time-item.h b/calendar/gui/e-day-view-time-item.h deleted file mode 100644 index 972f01e1b5..0000000000 --- a/calendar/gui/e-day-view-time-item.h +++ /dev/null @@ -1,75 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 1999, Helix Code, Inc. - * Copyright 1999, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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 - */ -#ifndef _E_DAY_VIEW_TIME_ITEM_H_ -#define _E_DAY_VIEW_TIME_ITEM_H_ - -#include "e-day-view.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - * EDayViewTimeItem - canvas item which displays the times down the left of - * the EDayView. - */ - -#define E_DAY_VIEW_TIME_ITEM(obj) (GTK_CHECK_CAST((obj), \ - e_day_view_time_item_get_type (), EDayViewTimeItem)) -#define E_DAY_VIEW_TIME_ITEM_CLASS(k) (GTK_CHECK_CLASS_CAST ((k),\ - e_day_view_time_item_get_type ())) -#define E_IS_DAY_VIEW_TIME_ITEM(o) (GTK_CHECK_TYPE((o), \ - e_day_view_time_item_get_type ())) - -typedef struct { - GnomeCanvasItem canvas_item; - - /* The parent EDayView widget. */ - EDayView *day_view; - - /* The width of the time column. */ - gint column_width; - - /* TRUE if we are currently dragging the selection times. */ - gboolean dragging_selection; -} EDayViewTimeItem; - -typedef struct { - GnomeCanvasItemClass parent_class; - -} EDayViewTimeItemClass; - - -GtkType e_day_view_time_item_get_type (void); - - -gint e_day_view_time_item_get_column_width (EDayViewTimeItem *dvtmitem); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_DAY_VIEW_TIME_ITEM_H_ */ diff --git a/calendar/gui/e-day-view-top-item.c b/calendar/gui/e-day-view-top-item.c deleted file mode 100644 index 8995832399..0000000000 --- a/calendar/gui/e-day-view-top-item.c +++ /dev/null @@ -1,648 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@helixcode.com> - * - * Copyright 1999, Helix Code, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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 - */ - -/* - * EDayViewTopItem - displays the top part of the Day/Work Week calendar view. - */ - -#include <config.h> -#include "e-day-view-top-item.h" - -static void e_day_view_top_item_class_init (EDayViewTopItemClass *class); -static void e_day_view_top_item_init (EDayViewTopItem *dvtitem); - -static void e_day_view_top_item_set_arg (GtkObject *o, - GtkArg *arg, - guint arg_id); -static void e_day_view_top_item_update (GnomeCanvasItem *item, - double *affine, - ArtSVP *clip_path, - int flags); -static void e_day_view_top_item_draw (GnomeCanvasItem *item, - GdkDrawable *drawable, - int x, - int y, - int width, - int height); -static void e_day_view_top_item_draw_long_event (EDayViewTopItem *dvtitem, - gint event_num, - GdkDrawable *drawable, - int x, - int y, - int width, - int height); -static void e_day_view_top_item_draw_triangle (EDayViewTopItem *dvtitem, - GdkDrawable *drawable, - gint x, - gint y, - gint w, - gint h); -static double e_day_view_top_item_point (GnomeCanvasItem *item, - double x, - double y, - int cx, - int cy, - GnomeCanvasItem **actual_item); -static gint e_day_view_top_item_event (GnomeCanvasItem *item, - GdkEvent *event); - - -static GnomeCanvasItemClass *parent_class; - -/* The arguments we take */ -enum { - ARG_0, - ARG_DAY_VIEW -}; - - -GtkType -e_day_view_top_item_get_type (void) -{ - static GtkType e_day_view_top_item_type = 0; - - if (!e_day_view_top_item_type) { - GtkTypeInfo e_day_view_top_item_info = { - "EDayViewTopItem", - sizeof (EDayViewTopItem), - sizeof (EDayViewTopItemClass), - (GtkClassInitFunc) e_day_view_top_item_class_init, - (GtkObjectInitFunc) e_day_view_top_item_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - e_day_view_top_item_type = gtk_type_unique (gnome_canvas_item_get_type (), &e_day_view_top_item_info); - } - - return e_day_view_top_item_type; -} - - -static void -e_day_view_top_item_class_init (EDayViewTopItemClass *class) -{ - GtkObjectClass *object_class; - GnomeCanvasItemClass *item_class; - - parent_class = gtk_type_class (gnome_canvas_item_get_type()); - - object_class = (GtkObjectClass *) class; - item_class = (GnomeCanvasItemClass *) class; - - gtk_object_add_arg_type ("EDayViewTopItem::day_view", - GTK_TYPE_POINTER, GTK_ARG_WRITABLE, - ARG_DAY_VIEW); - - object_class->set_arg = e_day_view_top_item_set_arg; - - /* GnomeCanvasItem method overrides */ - item_class->update = e_day_view_top_item_update; - item_class->draw = e_day_view_top_item_draw; - item_class->point = e_day_view_top_item_point; - item_class->event = e_day_view_top_item_event; -} - - -static void -e_day_view_top_item_init (EDayViewTopItem *dvtitem) -{ - dvtitem->day_view = NULL; -} - - -static void -e_day_view_top_item_set_arg (GtkObject *o, GtkArg *arg, guint arg_id) -{ - GnomeCanvasItem *item; - EDayViewTopItem *dvtitem; - - item = GNOME_CANVAS_ITEM (o); - dvtitem = E_DAY_VIEW_TOP_ITEM (o); - - switch (arg_id){ - case ARG_DAY_VIEW: - dvtitem->day_view = GTK_VALUE_POINTER (*arg); - break; - } -} - - -static void -e_day_view_top_item_update (GnomeCanvasItem *item, - double *affine, - ArtSVP *clip_path, - int flags) -{ - if (GNOME_CANVAS_ITEM_CLASS (parent_class)->update) - (* GNOME_CANVAS_ITEM_CLASS (parent_class)->update) (item, affine, clip_path, flags); - - /* The item covers the entire canvas area. */ - item->x1 = 0; - item->y1 = 0; - item->x2 = INT_MAX; - item->y2 = INT_MAX; -} - - -/* - * DRAWING ROUTINES - functions to paint the canvas item. - */ - -static void -e_day_view_top_item_draw (GnomeCanvasItem *canvas_item, - GdkDrawable *drawable, - int x, - int y, - int width, - int height) -{ - EDayViewTopItem *dvtitem; - EDayView *day_view; - GtkStyle *style; - GdkGC *gc, *fg_gc, *bg_gc, *light_gc, *dark_gc; - gchar buffer[128], *format; - GdkRectangle clip_rect; - GdkFont *font; - gint canvas_width, canvas_height, left_edge, day, date_width, date_x; - gint item_height, event_num; - struct tm *day_start; - -#if 0 - g_print ("In e_day_view_top_item_draw %i,%i %ix%i\n", - x, y, width, height); -#endif - dvtitem = E_DAY_VIEW_TOP_ITEM (canvas_item); - day_view = dvtitem->day_view; - g_return_if_fail (day_view != NULL); - - style = GTK_WIDGET (day_view)->style; - font = style->font; - gc = day_view->main_gc; - fg_gc = style->fg_gc[GTK_STATE_NORMAL]; - bg_gc = style->bg_gc[GTK_STATE_NORMAL]; - light_gc = style->light_gc[GTK_STATE_NORMAL]; - dark_gc = style->dark_gc[GTK_STATE_NORMAL]; - canvas_width = GTK_WIDGET (canvas_item->canvas)->allocation.width; - canvas_height = GTK_WIDGET (canvas_item->canvas)->allocation.height; - left_edge = 0; - item_height = day_view->top_row_height - E_DAY_VIEW_TOP_CANVAS_Y_GAP; - - /* Draw the shadow around the dates. */ - gdk_draw_line (drawable, light_gc, - left_edge + 1 - x, 1 - y, - canvas_width - 2 - x, 1 - y); - gdk_draw_line (drawable, light_gc, - left_edge + 1 - x, 2 - y, - left_edge + 1 - x, item_height - 1 - y); - gdk_draw_line (drawable, dark_gc, - left_edge + 2 - x, item_height - 1 - y, - canvas_width - 1 - x, item_height - 1 - y); - gdk_draw_line (drawable, dark_gc, - canvas_width - 1 - x, 1 - y, - canvas_width - 1 - x, item_height - 1 - y); - - /* Draw the background for the dates. */ - gdk_draw_rectangle (drawable, bg_gc, TRUE, - left_edge + 2 - x, 2 - y, - canvas_width - left_edge - 3, - item_height - 3); - - /* Clear the main area background. */ - gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_BG_TOP_CANVAS]); - gdk_draw_rectangle (drawable, gc, TRUE, - left_edge - x, item_height - y, - canvas_width - left_edge, - canvas_height - item_height); - - /* Draw the selection background. */ - if (GTK_WIDGET_HAS_FOCUS (day_view) - && day_view->selection_start_day != -1) { - gint start_col, end_col, rect_x, rect_y, rect_w, rect_h; - - start_col = day_view->selection_start_day; - end_col = day_view->selection_end_day; - - if (end_col > start_col - || day_view->selection_start_row == -1 - || day_view->selection_end_row == -1) { - rect_x = day_view->day_offsets[start_col]; - rect_y = item_height; - rect_w = day_view->day_offsets[end_col + 1] - rect_x; - rect_h = canvas_height - 1 - rect_y; - - gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_BG_TOP_CANVAS_SELECTED]); - gdk_draw_rectangle (drawable, gc, TRUE, - rect_x - x, rect_y - y, - rect_w, rect_h); - } - } - - /* Draw the date. Set a clipping rectangle so we don't draw over the - next day. */ - for (day = 0; day < day_view->days_shown; day++) { - day_start = localtime (&day_view->day_starts[day]); - - if (day_view->date_format == E_DAY_VIEW_DATE_FULL) - /* strftime format %A = full weekday name, %d = day of month, - %B = full month name. Don't use any other specifiers. */ - format = _("%A %d %B"); - else if (day_view->date_format == E_DAY_VIEW_DATE_ABBREVIATED) - /* strftime format %a = abbreviated weekday name, %d = day of month, - %b = abbreviated month name. Don't use any other specifiers. */ - format = _("%a %d %b"); - else if (day_view->date_format == E_DAY_VIEW_DATE_NO_WEEKDAY) - /* strftime format %d = day of month, %b = abbreviated month name. - Don't use any other specifiers. */ - format = _("%d %b"); - else - format = "%d"; - - strftime (buffer, sizeof (buffer), format, day_start); - - clip_rect.x = day_view->day_offsets[day] - x; - clip_rect.y = 2 - y; - clip_rect.width = day_view->day_widths[day]; - clip_rect.height = item_height - 2; - gdk_gc_set_clip_rectangle (fg_gc, &clip_rect); - - date_width = gdk_string_width (font, buffer); - date_x = day_view->day_offsets[day] + (day_view->day_widths[day] - date_width) / 2; - gdk_draw_string (drawable, font, fg_gc, - date_x - x, 3 + font->ascent - y, buffer); - - gdk_gc_set_clip_rectangle (fg_gc, NULL); - - /* Draw the lines down the left and right of the date cols. */ - if (day != 0) { - gdk_draw_line (drawable, light_gc, - day_view->day_offsets[day] - x, - 4 - y, - day_view->day_offsets[day] - x, - item_height - 4 - y); - - gdk_draw_line (drawable, dark_gc, - day_view->day_offsets[day] - 1 - x, - 4 - y, - day_view->day_offsets[day] - 1 - x, - item_height - 4 - y); - } - - /* Draw the lines between each column. */ - if (day != 0) { - gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_BG_TOP_CANVAS_GRID]); - gdk_draw_line (drawable, gc, - day_view->day_offsets[day] - x, - item_height - y, - day_view->day_offsets[day] - x, - canvas_height - y); - } - } - - /* Draw the long events. */ - for (event_num = 0; event_num < day_view->long_events->len; - event_num++) { - e_day_view_top_item_draw_long_event (dvtitem, event_num, - drawable, - x, y, width, height); - } -} - - -/* This draws one event in the top canvas. */ -static void -e_day_view_top_item_draw_long_event (EDayViewTopItem *dvtitem, - gint event_num, - GdkDrawable *drawable, - int x, - int y, - int width, - int height) -{ - EDayView *day_view; - EDayViewEvent *event; - GtkStyle *style; - GdkGC *gc, *fg_gc, *bg_gc; - GdkFont *font; - gint start_day, end_day; - gint item_x, item_y, item_w, item_h; - gint text_x, icon_x, icon_y, icon_x_inc; - CalComponent *comp; - gchar buffer[16]; - gint hour, display_hour, minute, offset, time_width, time_x; - gint min_end_time_x, suffix_width, max_icon_x; - gchar *suffix; - gboolean draw_start_triangle, draw_end_triangle; - GdkRectangle clip_rect; - - day_view = dvtitem->day_view; - - /* If the event is currently being dragged, don't draw it. It will - be drawn in the special drag items. */ - if (day_view->drag_event_day == E_DAY_VIEW_LONG_EVENT - && day_view->drag_event_num == event_num) - return; - - if (!e_day_view_get_long_event_position (day_view, event_num, - &start_day, &end_day, - &item_x, &item_y, - &item_w, &item_h)) - return; - - event = &g_array_index (day_view->long_events, EDayViewEvent, - event_num); - - style = GTK_WIDGET (day_view)->style; - font = style->font; - gc = day_view->main_gc; - fg_gc = style->fg_gc[GTK_STATE_NORMAL]; - bg_gc = style->bg_gc[GTK_STATE_NORMAL]; - comp = event->comp; - - /* Draw the lines across the top & bottom of the entire event. */ - gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_LONG_EVENT_BORDER]); - gdk_draw_line (drawable, gc, - item_x - x, item_y - y, - item_x + item_w - 1 - x, item_y - y); - gdk_draw_line (drawable, gc, - item_x - x, item_y + item_h - 1 - y, - item_x + item_w - 1 - x, item_y + item_h - 1 - y); - - /* Fill it in. */ - gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_LONG_EVENT_BACKGROUND]); - gdk_draw_rectangle (drawable, gc, TRUE, - item_x - x, item_y + 1 - y, - item_w, item_h - 2); - - /* When resizing we don't draw the triangles.*/ - draw_start_triangle = TRUE; - draw_end_triangle = TRUE; - if (day_view->resize_drag_pos != E_DAY_VIEW_POS_NONE - && day_view->resize_event_day == E_DAY_VIEW_LONG_EVENT - && day_view->resize_event_num == event_num) { - if (day_view->resize_drag_pos == E_DAY_VIEW_POS_LEFT_EDGE) - draw_start_triangle = FALSE; - - if (day_view->resize_drag_pos == E_DAY_VIEW_POS_RIGHT_EDGE) - draw_end_triangle = FALSE; - } - - /* If the event starts before the first day shown, draw a triangle, - else just draw a vertical line down the left. */ - if (draw_start_triangle - && event->start < day_view->day_starts[start_day]) { - e_day_view_top_item_draw_triangle (dvtitem, drawable, - item_x - x, item_y - y, - -E_DAY_VIEW_BAR_WIDTH, - item_h); - } else { - gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_LONG_EVENT_BORDER]); - gdk_draw_line (drawable, gc, - item_x - x, item_y - y, - item_x - x, item_y + item_h - 1 - y); - } - - /* Similar for the event end. */ - if (draw_end_triangle - && event->end > day_view->day_starts[end_day + 1]) { - e_day_view_top_item_draw_triangle (dvtitem, drawable, - item_x + item_w - 1 - x, - item_y - y, - E_DAY_VIEW_BAR_WIDTH, - item_h); - } else { - gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_LONG_EVENT_BORDER]); - gdk_draw_line (drawable, gc, - item_x + item_w - 1 - x, - item_y - y, - item_x + item_w - 1 - x, - item_y + item_h - 1 - y); - } - - /* If we are editing the event we don't show the icons or the start - & end times. */ - if (day_view->editing_event_day == E_DAY_VIEW_LONG_EVENT - && day_view->editing_event_num == event_num) - return; - - /* Determine the position of the label, so we know where to place the - icons. Note that since the top canvas never scrolls we don't need - to take the scroll offset into account. It will always be 0. */ - text_x = event->canvas_item->x1; - - /* Draw the start & end times, if necessary. */ - min_end_time_x = item_x + E_DAY_VIEW_LONG_EVENT_X_PAD - x; - - time_width = e_day_view_get_time_string_width (day_view); - - if (event->start > day_view->day_starts[start_day]) { - offset = day_view->first_hour_shown * 60 - + day_view->first_minute_shown + event->start_minute; - hour = offset / 60; - minute = offset % 60; - /* Calculate the actual hour number to display. For 12-hour - format we convert 0-23 to 12-11am/12-11pm. */ - e_day_view_convert_time_to_display (day_view, hour, - &display_hour, - &suffix, &suffix_width); - if (day_view->use_24_hour_format) { - g_snprintf (buffer, sizeof (buffer), "%i:%02i", - display_hour, minute); - } else { - g_snprintf (buffer, sizeof (buffer), "%i:%02i%s", - display_hour, minute, suffix); - } - - clip_rect.x = item_x - x; - clip_rect.y = item_y - y; - clip_rect.width = item_w - E_DAY_VIEW_LONG_EVENT_BORDER_WIDTH; - clip_rect.height = item_h; - gdk_gc_set_clip_rectangle (fg_gc, &clip_rect); - - time_x = item_x + E_DAY_VIEW_LONG_EVENT_X_PAD - x; - if (display_hour < 10) - time_x += day_view->digit_width; - - gdk_draw_string (drawable, font, fg_gc, - time_x, - item_y + E_DAY_VIEW_LONG_EVENT_BORDER_HEIGHT - + E_DAY_VIEW_LONG_EVENT_Y_PAD - + font->ascent - y, - buffer); - - gdk_gc_set_clip_rectangle (fg_gc, NULL); - - min_end_time_x += time_width - + E_DAY_VIEW_LONG_EVENT_TIME_X_PAD; - } - - max_icon_x = item_x + item_w - E_DAY_VIEW_LONG_EVENT_X_PAD - - E_DAY_VIEW_ICON_WIDTH; - - if (event->end < day_view->day_starts[end_day + 1]) { - offset = day_view->first_hour_shown * 60 - + day_view->first_minute_shown - + event->end_minute; - hour = offset / 60; - minute = offset % 60; - time_x = item_x + item_w - E_DAY_VIEW_LONG_EVENT_X_PAD - time_width - E_DAY_VIEW_LONG_EVENT_TIME_X_PAD - x; - - if (time_x >= min_end_time_x) { - /* Calculate the actual hour number to display. */ - e_day_view_convert_time_to_display (day_view, hour, - &display_hour, - &suffix, - &suffix_width); - if (day_view->use_24_hour_format) { - g_snprintf (buffer, sizeof (buffer), - "%i:%02i", display_hour, minute); - } else { - g_snprintf (buffer, sizeof (buffer), - "%i:%02i%s", display_hour, minute, - suffix); - } - - if (display_hour < 10) - time_x += day_view->digit_width; - - gdk_draw_string (drawable, font, fg_gc, - time_x, - item_y + E_DAY_VIEW_LONG_EVENT_Y_PAD - + font->ascent + 1 - y, - buffer); - - max_icon_x -= time_width + E_DAY_VIEW_LONG_EVENT_TIME_X_PAD; - } - } - - /* Draw the icons. */ - icon_x_inc = E_DAY_VIEW_ICON_WIDTH + E_DAY_VIEW_ICON_X_PAD; - icon_x = text_x - icon_x_inc - x; - icon_y = item_y + E_DAY_VIEW_LONG_EVENT_BORDER_HEIGHT - + E_DAY_VIEW_ICON_Y_PAD - y; - - if (icon_x <= max_icon_x && cal_component_has_recurrences (comp)) { - gdk_gc_set_clip_origin (gc, icon_x, icon_y); - gdk_gc_set_clip_mask (gc, day_view->recurrence_mask); - gdk_draw_pixmap (drawable, gc, - day_view->recurrence_icon, - 0, 0, icon_x, icon_y, - E_DAY_VIEW_ICON_WIDTH, - E_DAY_VIEW_ICON_HEIGHT); - icon_x -= icon_x_inc; - } - - if (icon_x <= max_icon_x && cal_component_has_alarms (comp)) { - gdk_gc_set_clip_origin (gc, icon_x, icon_y); - gdk_gc_set_clip_mask (gc, day_view->reminder_mask); - gdk_draw_pixmap (drawable, gc, - day_view->reminder_icon, - 0, 0, icon_x, icon_y, - E_DAY_VIEW_ICON_WIDTH, - E_DAY_VIEW_ICON_HEIGHT); - icon_x -= icon_x_inc; - } - gdk_gc_set_clip_mask (gc, NULL); -} - - -/* This draws a little triangle to indicate that an event extends past - the days visible on screen. */ -static void -e_day_view_top_item_draw_triangle (EDayViewTopItem *dvtitem, - GdkDrawable *drawable, - gint x, - gint y, - gint w, - gint h) -{ - EDayView *day_view; - GtkStyle *style; - GdkGC *gc; - GdkPoint points[3]; - gint c1, c2; - - day_view = dvtitem->day_view; - - style = GTK_WIDGET (day_view)->style; - gc = day_view->main_gc; - - points[0].x = x; - points[0].y = y; - points[1].x = x + w; - points[1].y = y + (h / 2) - 1; - points[2].x = x; - points[2].y = y + h - 1; - - /* If the height is odd we can use the same central point for both - lines. If it is even we use different end-points. */ - c1 = c2 = y + (h / 2); - if (h % 2 == 0) - c1--; - - gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_LONG_EVENT_BACKGROUND]); - gdk_draw_polygon (drawable, gc, TRUE, points, 3); - - gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_LONG_EVENT_BORDER]); - gdk_draw_line (drawable, gc, x, y, x + w, c1); - gdk_draw_line (drawable, gc, x, y + h - 1, x + w, c2); -} - - -/* This is supposed to return the nearest item the the point and the distance. - Since we are the only item we just return ourself and 0 for the distance. - This is needed so that we get button/motion events. */ -static double -e_day_view_top_item_point (GnomeCanvasItem *item, double x, double y, - int cx, int cy, - GnomeCanvasItem **actual_item) -{ - *actual_item = item; - return 0.0; -} - - -static gint -e_day_view_top_item_event (GnomeCanvasItem *item, GdkEvent *event) -{ - EDayViewTopItem *dvtitem; - - dvtitem = E_DAY_VIEW_TOP_ITEM (item); - - switch (event->type) { - case GDK_BUTTON_PRESS: - - case GDK_BUTTON_RELEASE: - - case GDK_MOTION_NOTIFY: - - default: - break; - } - - return FALSE; -} - - diff --git a/calendar/gui/e-day-view-top-item.h b/calendar/gui/e-day-view-top-item.h deleted file mode 100644 index 53db4eda79..0000000000 --- a/calendar/gui/e-day-view-top-item.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 1999, Helix Code, Inc. - * Copyright 1999, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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 - */ -#ifndef _E_DAY_VIEW_TOP_ITEM_H_ -#define _E_DAY_VIEW_TOP_ITEM_H_ - -#include "e-day-view.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - * EDayViewTopItem - displays the top part of the Day/Work Week calendar view. - */ - -#define E_DAY_VIEW_TOP_ITEM(obj) (GTK_CHECK_CAST((obj), \ - e_day_view_top_item_get_type (), EDayViewTopItem)) -#define E_DAY_VIEW_TOP_ITEM_CLASS(k) (GTK_CHECK_CLASS_CAST ((k),\ - e_day_view_top_item_get_type ())) -#define E_IS_DAY_VIEW_TOP_ITEM(o) (GTK_CHECK_TYPE((o), \ - e_day_view_top_item_get_type ())) - -typedef struct { - GnomeCanvasItem canvas_item; - - /* The parent EDayView widget. */ - EDayView *day_view; -} EDayViewTopItem; - -typedef struct { - GnomeCanvasItemClass parent_class; - -} EDayViewTopItemClass; - - -GtkType e_day_view_top_item_get_type (void); - - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_DAY_VIEW_TOP_ITEM_H_ */ diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c deleted file mode 100644 index bbf0732122..0000000000 --- a/calendar/gui/e-day-view.c +++ /dev/null @@ -1,6582 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@helixcode.com> - * - * Copyright 1999, Helix Code, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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 - */ - -/* - * EDayView - displays the Day & Work-Week views of the calendar. - */ - -#include <config.h> -#include <math.h> -#include <time.h> -#include <gdk/gdkx.h> -#include <cal-util/timeutil.h> -#include "dialogs/delete-comp.h" -#include "comp-util.h" -#include "e-day-view.h" -#include "e-day-view-time-item.h" -#include "e-day-view-top-item.h" -#include "e-day-view-main-item.h" -#include "calendar-commands.h" -#include "popup-menu.h" -#include <gal/widgets/e-canvas.h> -#include <gal/e-text/e-text.h> -#include <gal/widgets/e-canvas-utils.h> -#include "e-meeting-edit.h" - -/* Images */ -#include "bell.xpm" -#include "recur.xpm" - -/* The minimum amount of space wanted on each side of the date string. */ -#define E_DAY_VIEW_DATE_X_PAD 4 - -#define E_DAY_VIEW_LARGE_FONT \ - "-adobe-utopia-regular-r-normal-*-*-240-*-*-p-*-iso8859-*" -#define E_DAY_VIEW_LARGE_FONT_FALLBACK \ - "-adobe-helvetica-bold-r-normal-*-*-240-*-*-p-*-iso8859-*" - -/* The offset from the top/bottom of the canvas before auto-scrolling starts.*/ -#define E_DAY_VIEW_AUTO_SCROLL_OFFSET 16 - -/* The time between each auto-scroll, in milliseconds. */ -#define E_DAY_VIEW_AUTO_SCROLL_TIMEOUT 50 - -/* The number of timeouts we skip before we start scrolling. */ -#define E_DAY_VIEW_AUTO_SCROLL_DELAY 5 - -/* The number of pixels the mouse has to be moved with the button down before - we start a drag. */ -#define E_DAY_VIEW_DRAG_START_OFFSET 4 - -/* The amount we scroll the main canvas when the Page Up/Down keys are pressed, - as a fraction of the page size. */ -#define E_DAY_VIEW_PAGE_STEP 0.5 - -/* The amount we scroll the main canvas when the mouse wheel buttons are - pressed, as a fraction of the page size. */ -#define E_DAY_VIEW_WHEEL_MOUSE_STEP_SIZE 0.25 - - -/* Drag and Drop stuff. */ -enum { - TARGET_CALENDAR_EVENT -}; -static GtkTargetEntry target_table[] = { - { "application/x-e-calendar-event", 0, TARGET_CALENDAR_EVENT } -}; -static guint n_targets = sizeof(target_table) / sizeof(target_table[0]); - -static void e_day_view_class_init (EDayViewClass *class); -static void e_day_view_init (EDayView *day_view); -static void e_day_view_destroy (GtkObject *object); -static void e_day_view_realize (GtkWidget *widget); -static void e_day_view_unrealize (GtkWidget *widget); -static void e_day_view_style_set (GtkWidget *widget, - GtkStyle *previous_style); -static void e_day_view_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); -static gboolean e_day_view_update_scroll_regions (EDayView *day_view); -static gint e_day_view_focus_in (GtkWidget *widget, - GdkEventFocus *event); -static gint e_day_view_focus_out (GtkWidget *widget, - GdkEventFocus *event); -static gint e_day_view_key_press (GtkWidget *widget, - GdkEventKey *event); -static void e_day_view_cursor_key_up_shifted (EDayView *day_view, - GdkEventKey *event); -static void e_day_view_cursor_key_down_shifted (EDayView *day_view, - GdkEventKey *event); -static void e_day_view_cursor_key_left_shifted (EDayView *day_view, - GdkEventKey *event); -static void e_day_view_cursor_key_right_shifted (EDayView *day_view, - GdkEventKey *event); -static void e_day_view_cursor_key_up (EDayView *day_view, - GdkEventKey *event); -static void e_day_view_cursor_key_down (EDayView *day_view, - GdkEventKey *event); -static void e_day_view_cursor_key_left (EDayView *day_view, - GdkEventKey *event); -static void e_day_view_cursor_key_right (EDayView *day_view, - GdkEventKey *event); -static void e_day_view_ensure_rows_visible (EDayView *day_view, - gint start_row, - gint end_row); -static void e_day_view_scroll (EDayView *day_view, - gfloat pages_to_scroll); - -static gboolean e_day_view_check_if_new_event_fits (EDayView *day_view); - -static void e_day_view_on_canvas_realized (GtkWidget *widget, - EDayView *day_view); - -static gboolean e_day_view_on_top_canvas_button_press (GtkWidget *widget, - GdkEventButton *event, - EDayView *day_view); -static gboolean e_day_view_on_top_canvas_button_release (GtkWidget *widget, - GdkEventButton *event, - EDayView *day_view); -static gboolean e_day_view_on_top_canvas_motion (GtkWidget *widget, - GdkEventMotion *event, - EDayView *day_view); - -static gboolean e_day_view_on_main_canvas_button_press (GtkWidget *widget, - GdkEventButton *event, - EDayView *day_view); -static gboolean e_day_view_on_main_canvas_button_release (GtkWidget *widget, - GdkEventButton *event, - EDayView *day_view); - -static gboolean e_day_view_on_time_canvas_button_press (GtkWidget *widget, - GdkEventButton *event, - EDayView *day_view); - -static void e_day_view_update_calendar_selection_time (EDayView *day_view); -static gboolean e_day_view_on_main_canvas_motion (GtkWidget *widget, - GdkEventMotion *event, - EDayView *day_view); -static gboolean e_day_view_convert_event_coords (EDayView *day_view, - GdkEvent *event, - GdkWindow *window, - gint *x_return, - gint *y_return); -static void e_day_view_update_long_event_resize (EDayView *day_view, - gint day); -static void e_day_view_update_resize (EDayView *day_view, - gint row); -static void e_day_view_finish_long_event_resize (EDayView *day_view); -static void e_day_view_finish_resize (EDayView *day_view); -static void e_day_view_abort_resize (EDayView *day_view, - guint32 time); - - -static gboolean e_day_view_on_long_event_button_press (EDayView *day_view, - gint event_num, - GdkEventButton *event, - EDayViewPosition pos, - gint event_x, - gint event_y); -static gboolean e_day_view_on_event_button_press (EDayView *day_view, - gint day, - gint event_num, - GdkEventButton *event, - EDayViewPosition pos, - gint event_x, - gint event_y); -static void e_day_view_on_long_event_click (EDayView *day_view, - gint event_num, - GdkEventButton *bevent, - EDayViewPosition pos, - gint event_x, - gint event_y); -static void e_day_view_on_event_click (EDayView *day_view, - gint day, - gint event_num, - GdkEventButton *event, - EDayViewPosition pos, - gint event_x, - gint event_y); -static void e_day_view_on_event_double_click (EDayView *day_view, - gint day, - gint event_num); -static void e_day_view_on_event_right_click (EDayView *day_view, - GdkEventButton *bevent, - gint day, - gint event_num); - -static void e_day_view_recalc_day_starts (EDayView *day_view, - time_t start_time); -static void e_day_view_recalc_num_rows (EDayView *day_view); -static void e_day_view_recalc_cell_sizes (EDayView *day_view); - -static EDayViewPosition e_day_view_convert_position_in_top_canvas (EDayView *day_view, - gint x, - gint y, - gint *day_return, - gint *event_num_return); -static EDayViewPosition e_day_view_convert_position_in_main_canvas (EDayView *day_view, - gint x, - gint y, - gint *day_return, - gint *row_return, - gint *event_num_return); -static gboolean e_day_view_find_event_from_item (EDayView *day_view, - GnomeCanvasItem *item, - gint *day_return, - gint *event_num_return); -static gboolean e_day_view_find_event_from_uid (EDayView *day_view, - const gchar *uid, - gint *day_return, - gint *event_num_return); - -typedef gboolean (* EDayViewForeachEventCallback) (EDayView *day_view, - gint day, - gint event_num, - gpointer data); - -static void e_day_view_foreach_event (EDayView *day_view, - EDayViewForeachEventCallback callback, - gpointer data); -static void e_day_view_foreach_event_with_uid (EDayView *day_view, - const gchar *uid, - EDayViewForeachEventCallback callback, - gpointer data); - -static void e_day_view_queue_reload_events (EDayView *day_view); -static gboolean e_day_view_reload_events_idle_cb (gpointer data); -static void e_day_view_reload_events (EDayView *day_view); -static void e_day_view_free_events (EDayView *day_view); -static void e_day_view_free_event_array (EDayView *day_view, - GArray *array); -static int e_day_view_add_event (CalComponent *comp, - time_t start, - time_t end, - gpointer data); -static void e_day_view_update_event_label (EDayView *day_view, - gint day, - gint event_num); -static void e_day_view_update_long_event_label (EDayView *day_view, - gint event_num); - -static void e_day_view_layout_long_events (EDayView *day_view); -static void e_day_view_layout_long_event (EDayView *day_view, - EDayViewEvent *event, - guint8 *grid); -static void e_day_view_reshape_long_events (EDayView *day_view); -static void e_day_view_reshape_long_event (EDayView *day_view, - gint event_num); -static void e_day_view_layout_day_events (EDayView *day_view, - gint day); -static void e_day_view_layout_day_event (EDayView *day_view, - gint day, - EDayViewEvent *event, - guint8 *grid, - guint16 *group_starts); -static void e_day_view_expand_day_event (EDayView *day_view, - gint day, - EDayViewEvent *event, - guint8 *grid); -static void e_day_view_recalc_cols_per_row (EDayView *day_view, - gint day, - guint16 *group_starts); -static void e_day_view_reshape_day_events (EDayView *day_view, - gint day); -static void e_day_view_reshape_day_event (EDayView *day_view, - gint day, - gint event_num); -static void e_day_view_reshape_main_canvas_resize_bars (EDayView *day_view); -static void e_day_view_reshape_resize_long_event_rect_item (EDayView *day_view); -static void e_day_view_reshape_resize_rect_item (EDayView *day_view); - -static void e_day_view_ensure_events_sorted (EDayView *day_view); -static gint e_day_view_event_sort_func (const void *arg1, - const void *arg2); - -static void e_day_view_start_editing_event (EDayView *day_view, - gint day, - gint event_num, - gchar *initial_text); -static void e_day_view_stop_editing_event (EDayView *day_view); -static gboolean e_day_view_on_text_item_event (GnomeCanvasItem *item, - GdkEvent *event, - EDayView *day_view); -static void e_day_view_on_editing_started (EDayView *day_view, - GnomeCanvasItem *item); -static void e_day_view_on_editing_stopped (EDayView *day_view, - GnomeCanvasItem *item); - -static time_t e_day_view_convert_grid_position_to_time (EDayView *day_view, - gint col, - gint row); -static gboolean e_day_view_convert_time_to_grid_position (EDayView *day_view, - time_t time, - gint *col, - gint *row); - -static void e_day_view_start_auto_scroll (EDayView *day_view, - gboolean scroll_up); -static gboolean e_day_view_auto_scroll_handler (gpointer data); - -static void e_day_view_on_new_appointment (GtkWidget *widget, - gpointer data); -static void e_day_view_on_edit_appointment (GtkWidget *widget, - gpointer data); -static void e_day_view_on_delete_occurrence (GtkWidget *widget, - gpointer data); -static void e_day_view_on_delete_appointment (GtkWidget *widget, - gpointer data); -static void e_day_view_on_schedule_meet (GtkWidget *widget, - gpointer data); -static void e_day_view_on_unrecur_appointment (GtkWidget *widget, - gpointer data); -static EDayViewEvent* e_day_view_get_popup_menu_event (EDayView *day_view); - -static gint e_day_view_on_top_canvas_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time, - EDayView *day_view); -static void e_day_view_update_top_canvas_drag (EDayView *day_view, - gint day); -static void e_day_view_reshape_top_canvas_drag_item (EDayView *day_view); -static gint e_day_view_on_main_canvas_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time, - EDayView *day_view); -static void e_day_view_reshape_main_canvas_drag_item (EDayView *day_view); -static void e_day_view_update_main_canvas_drag (EDayView *day_view, - gint row, - gint day); -static void e_day_view_on_top_canvas_drag_leave (GtkWidget *widget, - GdkDragContext *context, - guint time, - EDayView *day_view); -static void e_day_view_on_main_canvas_drag_leave (GtkWidget *widget, - GdkDragContext *context, - guint time, - EDayView *day_view); -static void e_day_view_on_drag_begin (GtkWidget *widget, - GdkDragContext *context, - EDayView *day_view); -static void e_day_view_on_drag_end (GtkWidget *widget, - GdkDragContext *context, - EDayView *day_view); -static void e_day_view_on_drag_data_get (GtkWidget *widget, - GdkDragContext *context, - GtkSelectionData *selection_data, - guint info, - guint time, - EDayView *day_view); -static void e_day_view_on_top_canvas_drag_data_received (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *data, - guint info, - guint time, - EDayView *day_view); -static void e_day_view_on_main_canvas_drag_data_received (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *data, - guint info, - guint time, - EDayView *day_view); - -static gboolean e_day_view_update_event_cb (EDayView *day_view, - gint day, - gint event_num, - gpointer data); -static gboolean e_day_view_remove_event_cb (EDayView *day_view, - gint day, - gint event_num, - gpointer data); -static void e_day_view_normalize_selection (EDayView *day_view); -static gboolean e_day_view_set_show_times_cb (EDayView *day_view, - gint day, - gint event_num, - gpointer data); -static time_t e_day_view_find_work_week_start (EDayView *day_view, - time_t start_time); -static void e_day_view_recalc_work_week (EDayView *day_view); -static void e_day_view_recalc_work_week_days_shown (EDayView *day_view); -static gboolean e_day_view_set_event_font_cb (EDayView *day_view, - gint day, - gint event_num, - gpointer data); - - -static GtkTableClass *parent_class; - - -GtkType -e_day_view_get_type (void) -{ - static GtkType e_day_view_type = 0; - - if (!e_day_view_type){ - GtkTypeInfo e_day_view_info = { - "EDayView", - sizeof (EDayView), - sizeof (EDayViewClass), - (GtkClassInitFunc) e_day_view_class_init, - (GtkObjectInitFunc) e_day_view_init, - NULL, /* reserved 1 */ - NULL, /* reserved 2 */ - (GtkClassInitFunc) NULL - }; - - parent_class = gtk_type_class (GTK_TYPE_TABLE); - e_day_view_type = gtk_type_unique (GTK_TYPE_TABLE, - &e_day_view_info); - } - - return e_day_view_type; -} - - -static void -e_day_view_class_init (EDayViewClass *class) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - - object_class = (GtkObjectClass *) class; - widget_class = (GtkWidgetClass *) class; - - /* Method override */ - object_class->destroy = e_day_view_destroy; - - widget_class->realize = e_day_view_realize; - widget_class->unrealize = e_day_view_unrealize; - widget_class->style_set = e_day_view_style_set; - widget_class->size_allocate = e_day_view_size_allocate; - widget_class->focus_in_event = e_day_view_focus_in; - widget_class->focus_out_event = e_day_view_focus_out; - widget_class->key_press_event = e_day_view_key_press; -} - - -static void -e_day_view_init (EDayView *day_view) -{ - gint day; - GnomeCanvasGroup *canvas_group; - - GTK_WIDGET_SET_FLAGS (day_view, GTK_CAN_FOCUS); - - day_view->calendar = NULL; - day_view->client = NULL; - - day_view->long_events = g_array_new (FALSE, FALSE, - sizeof (EDayViewEvent)); - day_view->long_events_sorted = TRUE; - day_view->long_events_need_layout = FALSE; - day_view->long_events_need_reshape = FALSE; - day_view->reload_events_idle_id = 0; - - for (day = 0; day < E_DAY_VIEW_MAX_DAYS; day++) { - day_view->events[day] = g_array_new (FALSE, FALSE, - sizeof (EDayViewEvent)); - day_view->events_sorted[day] = TRUE; - day_view->need_layout[day] = FALSE; - day_view->need_reshape[day] = FALSE; - } - - /* These indicate that the times haven't been set. */ - day_view->lower = 0; - day_view->upper = 0; - - day_view->work_week_view = FALSE; - day_view->days_shown = 1; - - day_view->mins_per_row = 30; - day_view->date_format = E_DAY_VIEW_DATE_FULL; - day_view->rows_in_top_display = 0; - - /* Note that these don't work yet. It would need a few fixes to the - way event->start_minute and event->end_minute are used, and there - may be problems with events that go outside the visible times. */ - day_view->first_hour_shown = 0; - day_view->first_minute_shown = 0; - day_view->last_hour_shown = 24; - day_view->last_minute_shown = 0; - - day_view->main_gc = NULL; - e_day_view_recalc_num_rows (day_view); - - day_view->working_days = E_DAY_VIEW_MONDAY | E_DAY_VIEW_TUESDAY - | E_DAY_VIEW_WEDNESDAY | E_DAY_VIEW_THURSDAY - | E_DAY_VIEW_FRIDAY; - - day_view->work_day_start_hour = 9; - day_view->work_day_start_minute = 0; - day_view->work_day_end_hour = 17; - day_view->work_day_end_minute = 0; - day_view->show_event_end_times = TRUE; - day_view->week_start_day = 0; - day_view->scroll_to_work_day = TRUE; - - day_view->editing_event_day = -1; - day_view->editing_event_num = -1; - - day_view->resize_bars_event_day = -1; - day_view->resize_bars_event_num = -1; - - day_view->selection_start_row = -1; - day_view->selection_start_day = -1; - day_view->selection_end_row = -1; - day_view->selection_end_day = -1; - day_view->selection_is_being_dragged = FALSE; - day_view->selection_drag_pos = E_DAY_VIEW_DRAG_END; - day_view->selection_in_top_canvas = FALSE; - - day_view->resize_drag_pos = E_DAY_VIEW_POS_NONE; - - day_view->pressed_event_day = -1; - - day_view->drag_event_day = -1; - day_view->drag_last_day = -1; - - day_view->auto_scroll_timeout_id = 0; - - /* Create the large font. */ - day_view->large_font = gdk_font_load (E_DAY_VIEW_LARGE_FONT); - if (!day_view->large_font) - day_view->large_font = gdk_font_load (E_DAY_VIEW_LARGE_FONT_FALLBACK); - if (!day_view->large_font) - g_warning ("Couldn't load font"); - - /* String to use in 12-hour time format for times in the morning. */ - day_view->am_string = _("am"); - - /* String to use in 12-hour time format for times in the afternoon. */ - day_view->pm_string = _("pm"); - - - /* - * Top Canvas - */ - day_view->top_canvas = e_canvas_new (); - gtk_table_attach (GTK_TABLE (day_view), day_view->top_canvas, - 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); - gtk_widget_show (day_view->top_canvas); - gtk_signal_connect_after (GTK_OBJECT (day_view->top_canvas), "button_press_event", - GTK_SIGNAL_FUNC (e_day_view_on_top_canvas_button_press), - day_view); - gtk_signal_connect_after (GTK_OBJECT (day_view->top_canvas), "button_release_event", - GTK_SIGNAL_FUNC (e_day_view_on_top_canvas_button_release), - day_view); - gtk_signal_connect_after (GTK_OBJECT (day_view->top_canvas), "motion_notify_event", - GTK_SIGNAL_FUNC (e_day_view_on_top_canvas_motion), - day_view); - gtk_signal_connect_after (GTK_OBJECT (day_view->top_canvas), - "drag_motion", - GTK_SIGNAL_FUNC (e_day_view_on_top_canvas_drag_motion), - day_view); - gtk_signal_connect_after (GTK_OBJECT (day_view->top_canvas), - "drag_leave", - GTK_SIGNAL_FUNC (e_day_view_on_top_canvas_drag_leave), - day_view); - gtk_signal_connect (GTK_OBJECT (day_view->top_canvas), - "drag_begin", - GTK_SIGNAL_FUNC (e_day_view_on_drag_begin), - day_view); - gtk_signal_connect (GTK_OBJECT (day_view->top_canvas), - "drag_end", - GTK_SIGNAL_FUNC (e_day_view_on_drag_end), - day_view); - gtk_signal_connect (GTK_OBJECT (day_view->top_canvas), - "drag_data_get", - GTK_SIGNAL_FUNC (e_day_view_on_drag_data_get), - day_view); - gtk_signal_connect (GTK_OBJECT (day_view->top_canvas), - "drag_data_received", - GTK_SIGNAL_FUNC (e_day_view_on_top_canvas_drag_data_received), - day_view); - - canvas_group = GNOME_CANVAS_GROUP (GNOME_CANVAS (day_view->top_canvas)->root); - - day_view->top_canvas_item = - gnome_canvas_item_new (canvas_group, - e_day_view_top_item_get_type (), - "EDayViewTopItem::day_view", day_view, - NULL); - - day_view->resize_long_event_rect_item = - gnome_canvas_item_new (canvas_group, - gnome_canvas_rect_get_type(), - NULL); - gnome_canvas_item_hide (day_view->resize_long_event_rect_item); - - day_view->drag_long_event_rect_item = - gnome_canvas_item_new (canvas_group, - gnome_canvas_rect_get_type (), - "width_pixels", 1, - NULL); - gnome_canvas_item_hide (day_view->drag_long_event_rect_item); - - day_view->drag_long_event_item = - gnome_canvas_item_new (canvas_group, - e_text_get_type (), - "anchor", GTK_ANCHOR_NW, - "line_wrap", TRUE, - "clip", TRUE, - "max_lines", 1, - "editable", TRUE, - "draw_background", FALSE, - "fill_color_rgba", GNOME_CANVAS_COLOR(0, 0, 0), - NULL); - gnome_canvas_item_hide (day_view->drag_long_event_item); - - /* - * Main Canvas - */ - day_view->main_canvas = e_canvas_new (); - gtk_table_attach (GTK_TABLE (day_view), day_view->main_canvas, - 1, 2, 1, 2, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - gtk_widget_show (day_view->main_canvas); - gtk_signal_connect (GTK_OBJECT (day_view->main_canvas), "realize", - GTK_SIGNAL_FUNC (e_day_view_on_canvas_realized), - day_view); - gtk_signal_connect_after (GTK_OBJECT (day_view->main_canvas), - "button_press_event", - GTK_SIGNAL_FUNC (e_day_view_on_main_canvas_button_press), - day_view); - gtk_signal_connect_after (GTK_OBJECT (day_view->main_canvas), - "button_release_event", - GTK_SIGNAL_FUNC (e_day_view_on_main_canvas_button_release), - day_view); - gtk_signal_connect_after (GTK_OBJECT (day_view->main_canvas), - "motion_notify_event", - GTK_SIGNAL_FUNC (e_day_view_on_main_canvas_motion), - day_view); - gtk_signal_connect_after (GTK_OBJECT (day_view->main_canvas), - "drag_motion", - GTK_SIGNAL_FUNC (e_day_view_on_main_canvas_drag_motion), - day_view); - gtk_signal_connect_after (GTK_OBJECT (day_view->main_canvas), - "drag_leave", - GTK_SIGNAL_FUNC (e_day_view_on_main_canvas_drag_leave), - day_view); - gtk_signal_connect (GTK_OBJECT (day_view->main_canvas), - "drag_begin", - GTK_SIGNAL_FUNC (e_day_view_on_drag_begin), - day_view); - gtk_signal_connect (GTK_OBJECT (day_view->main_canvas), - "drag_end", - GTK_SIGNAL_FUNC (e_day_view_on_drag_end), - day_view); - gtk_signal_connect (GTK_OBJECT (day_view->main_canvas), - "drag_data_get", - GTK_SIGNAL_FUNC (e_day_view_on_drag_data_get), - day_view); - gtk_signal_connect (GTK_OBJECT (day_view->main_canvas), - "drag_data_received", - GTK_SIGNAL_FUNC (e_day_view_on_main_canvas_drag_data_received), - day_view); - - canvas_group = GNOME_CANVAS_GROUP (GNOME_CANVAS (day_view->main_canvas)->root); - - day_view->main_canvas_item = - gnome_canvas_item_new (canvas_group, - e_day_view_main_item_get_type (), - "EDayViewMainItem::day_view", day_view, - NULL); - - day_view->resize_rect_item = - gnome_canvas_item_new (canvas_group, - gnome_canvas_rect_get_type(), - NULL); - gnome_canvas_item_hide (day_view->resize_rect_item); - - day_view->resize_bar_item = - gnome_canvas_item_new (canvas_group, - gnome_canvas_rect_get_type(), - NULL); - gnome_canvas_item_hide (day_view->resize_bar_item); - - day_view->main_canvas_top_resize_bar_item = - gnome_canvas_item_new (canvas_group, - gnome_canvas_rect_get_type (), - "width_pixels", 1, - NULL); - gnome_canvas_item_hide (day_view->main_canvas_top_resize_bar_item); - - day_view->main_canvas_bottom_resize_bar_item = - gnome_canvas_item_new (canvas_group, - gnome_canvas_rect_get_type (), - "width_pixels", 1, - NULL); - gnome_canvas_item_hide (day_view->main_canvas_bottom_resize_bar_item); - - - day_view->drag_rect_item = - gnome_canvas_item_new (canvas_group, - gnome_canvas_rect_get_type (), - "width_pixels", 1, - NULL); - gnome_canvas_item_hide (day_view->drag_rect_item); - - day_view->drag_bar_item = - gnome_canvas_item_new (canvas_group, - gnome_canvas_rect_get_type (), - "width_pixels", 1, - NULL); - gnome_canvas_item_hide (day_view->drag_bar_item); - - day_view->drag_item = - gnome_canvas_item_new (canvas_group, - e_text_get_type (), - "anchor", GTK_ANCHOR_NW, - "line_wrap", TRUE, - "clip", TRUE, - "editable", TRUE, - "draw_background", FALSE, - "fill_color_rgba", GNOME_CANVAS_COLOR(0, 0, 0), - NULL); - gnome_canvas_item_hide (day_view->drag_item); - - - /* - * Times Canvas - */ - day_view->time_canvas = e_canvas_new (); - gtk_layout_set_vadjustment (GTK_LAYOUT (day_view->time_canvas), - GTK_LAYOUT (day_view->main_canvas)->vadjustment); - gtk_table_attach (GTK_TABLE (day_view), day_view->time_canvas, - 0, 1, 1, 2, - GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - gtk_widget_show (day_view->time_canvas); - gtk_signal_connect_after (GTK_OBJECT (day_view->time_canvas), - "button_press_event", - GTK_SIGNAL_FUNC (e_day_view_on_time_canvas_button_press), - day_view); - - canvas_group = GNOME_CANVAS_GROUP (GNOME_CANVAS (day_view->time_canvas)->root); - - day_view->time_canvas_item = - gnome_canvas_item_new (canvas_group, - e_day_view_time_item_get_type (), - "EDayViewTimeItem::day_view", day_view, - NULL); - - - /* - * Scrollbar. - */ - day_view->vscrollbar = gtk_vscrollbar_new (GTK_LAYOUT (day_view->main_canvas)->vadjustment); - gtk_table_attach (GTK_TABLE (day_view), day_view->vscrollbar, - 2, 3, 1, 2, 0, GTK_EXPAND | GTK_FILL, 0, 0); - gtk_widget_show (day_view->vscrollbar); - - - /* Create the cursors. */ - day_view->normal_cursor = gdk_cursor_new (GDK_TOP_LEFT_ARROW); - day_view->move_cursor = gdk_cursor_new (GDK_FLEUR); - day_view->resize_width_cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW); - day_view->resize_height_cursor = gdk_cursor_new (GDK_SB_V_DOUBLE_ARROW); - day_view->last_cursor_set_in_top_canvas = NULL; - day_view->last_cursor_set_in_main_canvas = NULL; - - /* Set up the drop sites. */ - gtk_drag_dest_set (day_view->top_canvas, - GTK_DEST_DEFAULT_ALL, - target_table, n_targets, - GDK_ACTION_COPY | GDK_ACTION_MOVE); - gtk_drag_dest_set (day_view->main_canvas, - GTK_DEST_DEFAULT_ALL, - target_table, n_targets, - GDK_ACTION_COPY | GDK_ACTION_MOVE); -} - - -/* Turn off the background of the canvas windows. This reduces flicker - considerably when scrolling. (Why isn't it in GnomeCanvas?). */ -static void -e_day_view_on_canvas_realized (GtkWidget *widget, - EDayView *day_view) -{ - gdk_window_set_back_pixmap (GTK_LAYOUT (widget)->bin_window, - NULL, FALSE); -} - - -/** - * e_day_view_new: - * @Returns: a new #EDayView. - * - * Creates a new #EDayView. - **/ -GtkWidget * -e_day_view_new (void) -{ - GtkWidget *day_view; - - day_view = GTK_WIDGET (gtk_type_new (e_day_view_get_type ())); - - return day_view; -} - - -static void -e_day_view_destroy (GtkObject *object) -{ - EDayView *day_view; - gint day; - - day_view = E_DAY_VIEW (object); - - e_day_view_stop_auto_scroll (day_view); - - if (day_view->reload_events_idle_id != 0) { - g_source_remove (day_view->reload_events_idle_id); - day_view->reload_events_idle_id = 0; - } - - if (day_view->client) { - gtk_signal_disconnect_by_data (GTK_OBJECT (day_view->client), day_view); - gtk_object_unref (GTK_OBJECT (day_view->client)); - day_view->client = NULL; - } - - if (day_view->large_font) - gdk_font_unref (day_view->large_font); - - gdk_cursor_destroy (day_view->normal_cursor); - gdk_cursor_destroy (day_view->move_cursor); - gdk_cursor_destroy (day_view->resize_width_cursor); - gdk_cursor_destroy (day_view->resize_height_cursor); - - e_day_view_free_events (day_view); - g_array_free (day_view->long_events, TRUE); - for (day = 0; day < E_DAY_VIEW_MAX_DAYS; day++) - g_array_free (day_view->events[day], TRUE); - - GTK_OBJECT_CLASS (parent_class)->destroy (object); -} - - -static void -e_day_view_realize (GtkWidget *widget) -{ - EDayView *day_view; - GdkColormap *colormap; - gboolean success[E_DAY_VIEW_COLOR_LAST]; - gint nfailed; - - if (GTK_WIDGET_CLASS (parent_class)->realize) - (*GTK_WIDGET_CLASS (parent_class)->realize)(widget); - - day_view = E_DAY_VIEW (widget); - day_view->main_gc = gdk_gc_new (widget->window); - - colormap = gtk_widget_get_colormap (widget); - - /* Allocate the colors. */ - day_view->colors[E_DAY_VIEW_COLOR_BG_WORKING].red = 247 * 257; - day_view->colors[E_DAY_VIEW_COLOR_BG_WORKING].green = 247 * 257; - day_view->colors[E_DAY_VIEW_COLOR_BG_WORKING].blue = 244 * 257; - - day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING].red = 216 * 257; - day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING].green = 216 * 257; - day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING].blue = 214 * 257; - - day_view->colors[E_DAY_VIEW_COLOR_BG_SELECTED].red = 0 * 257; - day_view->colors[E_DAY_VIEW_COLOR_BG_SELECTED].green = 0 * 257; - day_view->colors[E_DAY_VIEW_COLOR_BG_SELECTED].blue = 156 * 257; - - day_view->colors[E_DAY_VIEW_COLOR_BG_GRID].red = 148 * 257; - day_view->colors[E_DAY_VIEW_COLOR_BG_GRID].green = 149 * 257; - day_view->colors[E_DAY_VIEW_COLOR_BG_GRID].blue = 148 * 257; - - day_view->colors[E_DAY_VIEW_COLOR_BG_TOP_CANVAS].red = 148 * 257; - day_view->colors[E_DAY_VIEW_COLOR_BG_TOP_CANVAS].green = 149 * 257; - day_view->colors[E_DAY_VIEW_COLOR_BG_TOP_CANVAS].blue = 148 * 257; - - day_view->colors[E_DAY_VIEW_COLOR_BG_TOP_CANVAS_SELECTED].red = 65535; - day_view->colors[E_DAY_VIEW_COLOR_BG_TOP_CANVAS_SELECTED].green = 65535; - day_view->colors[E_DAY_VIEW_COLOR_BG_TOP_CANVAS_SELECTED].blue = 65535; - - day_view->colors[E_DAY_VIEW_COLOR_BG_TOP_CANVAS_GRID].red = 0; - day_view->colors[E_DAY_VIEW_COLOR_BG_TOP_CANVAS_GRID].green = 0; - day_view->colors[E_DAY_VIEW_COLOR_BG_TOP_CANVAS_GRID].blue = 0; - - day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR].red = 0; - day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR].green = 0; - day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR].blue = 65535; - - day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND].red = 65535; - day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND].green = 65535; - day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND].blue = 65535; - - day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER].red = 0; - day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER].green = 0; - day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER].blue = 0; - - day_view->colors[E_DAY_VIEW_COLOR_LONG_EVENT_BACKGROUND].red = 213 * 257; - day_view->colors[E_DAY_VIEW_COLOR_LONG_EVENT_BACKGROUND].green = 213 * 257; - day_view->colors[E_DAY_VIEW_COLOR_LONG_EVENT_BACKGROUND].blue = 213 * 257; - - day_view->colors[E_DAY_VIEW_COLOR_LONG_EVENT_BORDER].red = 0; - day_view->colors[E_DAY_VIEW_COLOR_LONG_EVENT_BORDER].green = 0; - day_view->colors[E_DAY_VIEW_COLOR_LONG_EVENT_BORDER].blue = 0; - - nfailed = gdk_colormap_alloc_colors (colormap, day_view->colors, - E_DAY_VIEW_COLOR_LAST, FALSE, - TRUE, success); - if (nfailed) - g_warning ("Failed to allocate all colors"); - - - /* Create the pixmaps. */ - day_view->reminder_icon = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &day_view->reminder_mask, NULL, bell_xpm); - day_view->recurrence_icon = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &day_view->recurrence_mask, NULL, recur_xpm); - - - - /* Set the canvas item colors. */ - gnome_canvas_item_set (day_view->resize_long_event_rect_item, - "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND], - "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER], - NULL); - - gnome_canvas_item_set (day_view->drag_long_event_rect_item, - "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND], - "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER], - NULL); - - - gnome_canvas_item_set (day_view->resize_rect_item, - "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND], - "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER], - NULL); - - gnome_canvas_item_set (day_view->resize_bar_item, - "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR], - "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER], - NULL); - - gnome_canvas_item_set (day_view->main_canvas_top_resize_bar_item, - "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR], - "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER], - NULL); - - gnome_canvas_item_set (day_view->main_canvas_bottom_resize_bar_item, - "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR], - "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER], - NULL); - - - gnome_canvas_item_set (day_view->drag_rect_item, - "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND], - "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER], - NULL); - - gnome_canvas_item_set (day_view->drag_bar_item, - "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR], - "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER], - NULL); -} - - -static void -e_day_view_unrealize (GtkWidget *widget) -{ - EDayView *day_view; - GdkColormap *colormap; - gint i; - - day_view = E_DAY_VIEW (widget); - - gdk_gc_unref (day_view->main_gc); - day_view->main_gc = NULL; - - colormap = gtk_widget_get_colormap (widget); - for (i = 0; i < E_DAY_VIEW_COLOR_LAST; i++) - gdk_colors_free (colormap, &day_view->colors[i].pixel, 1, 0); - - gdk_pixmap_unref (day_view->reminder_icon); - day_view->reminder_icon = NULL; - gdk_pixmap_unref (day_view->recurrence_icon); - day_view->recurrence_icon = NULL; - - if (GTK_WIDGET_CLASS (parent_class)->unrealize) - (*GTK_WIDGET_CLASS (parent_class)->unrealize)(widget); -} - - -static void -e_day_view_style_set (GtkWidget *widget, - GtkStyle *previous_style) -{ - EDayView *day_view; - GdkFont *font; - gint top_rows, top_canvas_height; - gint hour, max_large_hour_width; - gint minute, max_minute_width, i; - gint month, day, width; - gint longest_month_width, longest_abbreviated_month_width; - gint longest_weekday_width, longest_abbreviated_weekday_width; - struct tm date_tm; - gchar buffer[128]; - gint times_width; - - if (GTK_WIDGET_CLASS (parent_class)->style_set) - (*GTK_WIDGET_CLASS (parent_class)->style_set)(widget, previous_style); - - day_view = E_DAY_VIEW (widget); - font = widget->style->font; - - /* Recalculate the height of each row based on the font size. */ - day_view->row_height = font->ascent + font->descent + E_DAY_VIEW_EVENT_BORDER_HEIGHT + E_DAY_VIEW_EVENT_Y_PAD * 2 + 2 /* FIXME */; - day_view->row_height = MAX (day_view->row_height, E_DAY_VIEW_ICON_HEIGHT + E_DAY_VIEW_ICON_Y_PAD + 2); - GTK_LAYOUT (day_view->main_canvas)->vadjustment->step_increment = day_view->row_height; - - day_view->top_row_height = font->ascent + font->descent + E_DAY_VIEW_LONG_EVENT_BORDER_HEIGHT * 2 + E_DAY_VIEW_LONG_EVENT_Y_PAD * 2 + E_DAY_VIEW_TOP_CANVAS_Y_GAP; - day_view->top_row_height = MAX (day_view->top_row_height, E_DAY_VIEW_ICON_HEIGHT + E_DAY_VIEW_ICON_Y_PAD + 2 + E_DAY_VIEW_TOP_CANVAS_Y_GAP); - - /* Set the height of the top canvas based on the row height and the - number of rows needed (min 1 + 1 for the dates + 1 space for DnD).*/ - top_rows = MAX (1, day_view->rows_in_top_display); - top_canvas_height = (top_rows + 2) * day_view->top_row_height; - gtk_widget_set_usize (day_view->top_canvas, -1, top_canvas_height); - - /* Find the longest full & abbreviated month names. */ - memset (&date_tm, 0, sizeof (date_tm)); - date_tm.tm_year = 100; - date_tm.tm_mday = 1; - date_tm.tm_isdst = -1; - - longest_month_width = 0; - longest_abbreviated_month_width = 0; - for (month = 0; month < 12; month++) { - date_tm.tm_mon = month; - - strftime (buffer, sizeof (buffer), "%B", &date_tm); - width = gdk_string_width (font, buffer); - if (width > longest_month_width) { - longest_month_width = width; - day_view->longest_month_name = month; - } - - strftime (buffer, sizeof (buffer), "%b", &date_tm); - width = gdk_string_width (font, buffer); - if (width > longest_abbreviated_month_width) { - longest_abbreviated_month_width = width; - day_view->longest_abbreviated_month_name = month; - } - } - - /* Find the longest full & abbreviated weekday names. */ - memset (&date_tm, 0, sizeof (date_tm)); - date_tm.tm_year = 100; - date_tm.tm_mon = 0; - date_tm.tm_isdst = -1; - - longest_weekday_width = 0; - longest_abbreviated_weekday_width = 0; - for (day = 0; day < 7; day++) { - date_tm.tm_mday = 2 + day; - date_tm.tm_wday = day; - - strftime (buffer, sizeof (buffer), "%A", &date_tm); - width = gdk_string_width (font, buffer); - if (width > longest_weekday_width) { - longest_weekday_width = width; - day_view->longest_weekday_name = day; - } - - strftime (buffer, sizeof (buffer), "%a", &date_tm); - width = gdk_string_width (font, buffer); - if (width > longest_abbreviated_weekday_width) { - longest_abbreviated_weekday_width = width; - day_view->longest_abbreviated_weekday_name = day; - } - } - - - /* Calculate the widths of all the time strings necessary. */ - day_view->max_small_hour_width = 0; - max_large_hour_width = 0; - for (hour = 0; hour < 24; hour++) { - g_snprintf (buffer, sizeof (buffer), "%02i", hour); - day_view->small_hour_widths[hour] = gdk_string_width (font, buffer); - day_view->max_small_hour_width = MAX (day_view->max_small_hour_width, day_view->small_hour_widths[hour]); - } - - max_minute_width = 0; - for (minute = 0, i = 0; minute < 60; minute += 5, i++) { - gint minute_width; - - g_snprintf (buffer, sizeof (buffer), "%02i", minute); - minute_width = gdk_string_width (font, buffer); - max_minute_width = MAX (max_minute_width, minute_width); - } - day_view->max_minute_width = max_minute_width; - day_view->colon_width = gdk_string_width (font, ":"); - day_view->digit_width = gdk_string_width (font, "0"); - - day_view->am_string_width = gdk_string_width (font, - day_view->am_string); - day_view->pm_string_width = gdk_string_width (font, - day_view->pm_string); - - /* Calculate the width of the time column. */ - times_width = e_day_view_time_item_get_column_width (E_DAY_VIEW_TIME_ITEM (day_view->time_canvas_item)); - gtk_widget_set_usize (day_view->time_canvas, times_width, -1); - - /* Set the font of all the EText items. */ - e_day_view_foreach_event (day_view, e_day_view_set_event_font_cb, - font); - - /* Set the fonts for the text items used when dragging. */ - gnome_canvas_item_set (day_view->drag_long_event_item, - "font_gdk", GTK_WIDGET (day_view)->style->font, - NULL); - - gnome_canvas_item_set (day_view->drag_item, - "font_gdk", GTK_WIDGET (day_view)->style->font, - NULL); -} - - -static gboolean -e_day_view_set_event_font_cb (EDayView *day_view, - gint day, - gint event_num, - gpointer data) -{ - EDayViewEvent *event; - GdkFont *font = data; - - if (day == E_DAY_VIEW_LONG_EVENT) - event = &g_array_index (day_view->long_events, - EDayViewEvent, event_num); - else - event = &g_array_index (day_view->events[day], - EDayViewEvent, event_num); - - if (event->canvas_item) - gnome_canvas_item_set (event->canvas_item, - "font_gdk", font, - NULL); - - return TRUE; -} - - -/* This recalculates the sizes of each column. */ -static void -e_day_view_size_allocate (GtkWidget *widget, GtkAllocation *allocation) -{ - EDayView *day_view; - gint day, scroll_y; - gboolean need_reshape; - gdouble old_x2, old_y2, new_x2, new_y2; - -#if 0 - g_print ("In e_day_view_size_allocate\n"); -#endif - day_view = E_DAY_VIEW (widget); - - (*GTK_WIDGET_CLASS (parent_class)->size_allocate) (widget, allocation); - - e_day_view_recalc_cell_sizes (day_view); - - /* Set the scroll region of the top canvas to its allocated size. */ - gnome_canvas_get_scroll_region (GNOME_CANVAS (day_view->top_canvas), - NULL, NULL, &old_x2, &old_y2); - new_x2 = day_view->top_canvas->allocation.width - 1; - new_y2 = day_view->top_canvas->allocation.height - 1; - if (old_x2 != new_x2 || old_y2 != new_y2) - gnome_canvas_set_scroll_region (GNOME_CANVAS (day_view->top_canvas), - 0, 0, new_x2, new_y2); - - need_reshape = e_day_view_update_scroll_regions (day_view); - - /* Scroll to the start of the working day, if this is the initial - allocation. */ - if (day_view->scroll_to_work_day) { - scroll_y = e_day_view_convert_time_to_position (day_view, day_view->work_day_start_hour, day_view->work_day_start_minute); - gnome_canvas_scroll_to (GNOME_CANVAS (day_view->main_canvas), - 0, scroll_y); - day_view->scroll_to_work_day = FALSE; - } - - /* Flag that we need to reshape the events. Note that changes in height - don't matter, since the rows are always the same height. */ - if (need_reshape) { - day_view->long_events_need_reshape = TRUE; - for (day = 0; day < E_DAY_VIEW_MAX_DAYS; day++) - day_view->need_reshape[day] = TRUE; - - e_day_view_check_layout (day_view); - } -} - - -static void -e_day_view_recalc_cell_sizes (EDayView *day_view) -{ - /* An array of dates, one for each month in the year 2000. They must - all be Sundays. */ - static const int days[12] = { 23, 20, 19, 23, 21, 18, - 23, 20, 17, 22, 19, 24 }; - gfloat width, offset; - gint day, max_width; - struct tm date_tm; - GdkFont *font; - char buffer[128]; - - g_return_if_fail (((GtkWidget*)day_view)->style != NULL); - font = GTK_WIDGET (day_view)->style->font; - - /* Calculate the column sizes, using floating point so that pixels - get divided evenly. Note that we use one more element than the - number of columns, to make it easy to get the column widths. */ - width = day_view->main_canvas->allocation.width; - width /= day_view->days_shown; - offset = 0; - for (day = 0; day <= day_view->days_shown; day++) { - day_view->day_offsets[day] = floor (offset + 0.5); - offset += width; - } - - /* Calculate the days widths based on the offsets. */ - for (day = 0; day < day_view->days_shown; day++) { - day_view->day_widths[day] = day_view->day_offsets[day + 1] - day_view->day_offsets[day]; - } - - /* Determine which date format to use, based on the column widths. - We want to check the widths using the longest full or abbreviated - month name and the longest full or abbreviated weekday name, as - appropriate. */ - max_width = day_view->day_widths[0]; - - memset (&date_tm, 0, sizeof (date_tm)); - date_tm.tm_year = 100; - - /* Try "Thursday 21 January". */ - date_tm.tm_mon = day_view->longest_month_name; - date_tm.tm_mday = days[date_tm.tm_mon] - + day_view->longest_weekday_name; - date_tm.tm_wday = day_view->longest_weekday_name; - date_tm.tm_isdst = -1; - /* strftime format %A = full weekday name, %d = day of month, - %B = full month name. Don't use any other specifiers. */ - strftime (buffer, sizeof (buffer), _("%A %d %B"), &date_tm); - if (gdk_string_width (font, buffer) < max_width) { - day_view->date_format = E_DAY_VIEW_DATE_FULL; - return; - } - - /* Try "Thu 21 Jan". */ - date_tm.tm_mon = day_view->longest_abbreviated_month_name; - date_tm.tm_mday = days[date_tm.tm_mon] - + day_view->longest_abbreviated_weekday_name; - date_tm.tm_wday = day_view->longest_abbreviated_weekday_name; - date_tm.tm_isdst = -1; - /* strftime format %a = abbreviated weekday name, %d = day of month, - %b = abbreviated month name. Don't use any other specifiers. */ - strftime (buffer, sizeof (buffer), _("%a %d %b"), &date_tm); - if (gdk_string_width (font, buffer) < max_width) { - day_view->date_format = E_DAY_VIEW_DATE_ABBREVIATED; - return; - } - - /* Try "23 Jan". */ - date_tm.tm_mon = day_view->longest_abbreviated_month_name; - date_tm.tm_mday = 23; - date_tm.tm_wday = 0; - date_tm.tm_isdst = -1; - /* strftime format %d = day of month, %b = abbreviated month name. - Don't use any other specifiers. */ - strftime (buffer, sizeof (buffer), _("%d %b"), &date_tm); - if (gdk_string_width (font, buffer) < max_width) - day_view->date_format = E_DAY_VIEW_DATE_NO_WEEKDAY; - else - day_view->date_format = E_DAY_VIEW_DATE_SHORT; -} - - -static gint -e_day_view_focus_in (GtkWidget *widget, GdkEventFocus *event) -{ - EDayView *day_view; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (E_IS_DAY_VIEW (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - day_view = E_DAY_VIEW (widget); - - GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS); - - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); - - return FALSE; -} - - -static gint -e_day_view_focus_out (GtkWidget *widget, GdkEventFocus *event) -{ - EDayView *day_view; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (E_IS_DAY_VIEW (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - day_view = E_DAY_VIEW (widget); - - GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS); - - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); - - return FALSE; -} - - -void -e_day_view_set_calendar (EDayView *day_view, - GnomeCalendar *calendar) -{ - g_return_if_fail (E_IS_DAY_VIEW (day_view)); - - day_view->calendar = calendar; -} - - -/* Callback used when the calendar client finishes opening */ -static void -cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data) -{ - EDayView *day_view; - - day_view = E_DAY_VIEW (data); - - if (status != CAL_CLIENT_OPEN_SUCCESS) - return; - - e_day_view_queue_reload_events (day_view); -} - -/* Callback used when the calendar client tells us that an object changed */ -static void -obj_updated_cb (CalClient *client, const char *uid, gpointer data) -{ - EDayView *day_view; - EDayViewEvent *event; - CalComponent *comp; - CalClientGetStatus status; - gint day, event_num; - - g_return_if_fail (E_IS_DAY_VIEW (data)); - - day_view = E_DAY_VIEW (data); - - /* Sanity check. */ - g_return_if_fail (client == day_view->client); - - /* If our time hasn't been set yet, just return. */ - if (day_view->lower == 0 && day_view->upper == 0) - return; - - /* Get the event from the server. */ - status = cal_client_get_object (day_view->client, uid, &comp); - - switch (status) { - case CAL_CLIENT_GET_SUCCESS: - /* Everything is fine */ - break; - - case CAL_CLIENT_GET_SYNTAX_ERROR: - g_message ("obj_updated_cb(): Syntax error when 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; - } - - /* We only care about events. */ - if (cal_component_get_vtype (comp) != CAL_COMPONENT_EVENT) { - gtk_object_unref (GTK_OBJECT (comp)); - return; - } - - /* If the event already exists and the dates didn't change, we can - update the event fairly easily without changing the events arrays - or computing a new layout. */ - if (e_day_view_find_event_from_uid (day_view, uid, &day, &event_num)) { - if (day == E_DAY_VIEW_LONG_EVENT) - event = &g_array_index (day_view->long_events, - EDayViewEvent, event_num); - else - event = &g_array_index (day_view->events[day], - EDayViewEvent, event_num); - - if (!cal_component_has_recurrences (comp) - && !cal_component_has_recurrences (event->comp) - && cal_component_event_dates_match (comp, event->comp)) { -#if 0 - g_print ("updated object's dates unchanged\n"); -#endif - e_day_view_foreach_event_with_uid (day_view, uid, e_day_view_update_event_cb, comp); - gtk_object_unref (GTK_OBJECT (comp)); - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); - return; - } - - /* The dates have changed, so we need to remove the - old occurrrences before adding the new ones. */ -#if 0 - g_print ("dates changed - removing occurrences\n"); -#endif - e_day_view_foreach_event_with_uid (day_view, uid, - e_day_view_remove_event_cb, - NULL); - } - - /* Add the occurrences of the event. */ - cal_recur_generate_instances (comp, day_view->lower, - day_view->upper, - e_day_view_add_event, - day_view); - gtk_object_unref (GTK_OBJECT (comp)); - - e_day_view_check_layout (day_view); - - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); -} - - -/* Callback used when the calendar client tells us that an object was removed */ -static void -obj_removed_cb (CalClient *client, const char *uid, gpointer data) -{ - EDayView *day_view; - - day_view = E_DAY_VIEW (data); - - e_day_view_foreach_event_with_uid (day_view, uid, - e_day_view_remove_event_cb, NULL); - - e_day_view_check_layout (day_view); - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); -} - - -/** - * e_day_view_set_cal_client: - * @day_view: A day view. - * @client: A calendar client interface object. - * - * Sets the calendar client interface object that a day view will monitor. - **/ -void -e_day_view_set_cal_client (EDayView *day_view, - CalClient *client) -{ - g_return_if_fail (day_view != NULL); - g_return_if_fail (E_IS_DAY_VIEW (day_view)); - - if (client == day_view->client) - return; - - if (client) - g_return_if_fail (IS_CAL_CLIENT (client)); - - if (client) - gtk_object_ref (GTK_OBJECT (client)); - - if (day_view->client) { - gtk_signal_disconnect_by_data (GTK_OBJECT (day_view->client), day_view); - gtk_object_unref (GTK_OBJECT (day_view->client)); - } - - day_view->client = client; - - if (day_view->client) { - if (cal_client_get_load_state (day_view->client) != CAL_CLIENT_LOAD_LOADED) - gtk_signal_connect (GTK_OBJECT (day_view->client), "cal_opened", - GTK_SIGNAL_FUNC (cal_opened_cb), day_view); - - gtk_signal_connect (GTK_OBJECT (day_view->client), "obj_updated", - GTK_SIGNAL_FUNC (obj_updated_cb), day_view); - gtk_signal_connect (GTK_OBJECT (day_view->client), "obj_removed", - GTK_SIGNAL_FUNC (obj_removed_cb), day_view); - } - - e_day_view_queue_reload_events (day_view); -} - - -static gboolean -e_day_view_update_event_cb (EDayView *day_view, - gint day, - gint event_num, - gpointer data) -{ - EDayViewEvent *event; - CalComponent *comp; - - comp = data; -#if 0 - g_print ("In e_day_view_update_event_cb day:%i event_num:%i\n", - day, event_num); -#endif - if (day == E_DAY_VIEW_LONG_EVENT) { - event = &g_array_index (day_view->long_events, EDayViewEvent, - event_num); - } else { - event = &g_array_index (day_view->events[day], EDayViewEvent, - event_num); - } - - gtk_object_unref (GTK_OBJECT (event->comp)); - event->comp = comp; - gtk_object_ref (GTK_OBJECT (comp)); - - if (day == E_DAY_VIEW_LONG_EVENT) { - e_day_view_update_long_event_label (day_view, event_num); - e_day_view_reshape_long_event (day_view, event_num); - } else { - e_day_view_update_event_label (day_view, day, event_num); - e_day_view_reshape_day_event (day_view, day, event_num); - } - return TRUE; -} - - -/* This calls a given function for each event instance (in both views). - If the callback returns FALSE the iteration is stopped. - Note that it is safe for the callback to remove the event (since we - step backwards through the arrays). */ -static void -e_day_view_foreach_event (EDayView *day_view, - EDayViewForeachEventCallback callback, - gpointer data) -{ - EDayViewEvent *event; - gint day, event_num; - - for (day = 0; day < day_view->days_shown; day++) { - for (event_num = day_view->events[day]->len - 1; - event_num >= 0; - event_num--) { - event = &g_array_index (day_view->events[day], - EDayViewEvent, event_num); - - if (!(*callback) (day_view, day, event_num, data)) - return; - } - } - - for (event_num = day_view->long_events->len - 1; - event_num >= 0; - event_num--) { - event = &g_array_index (day_view->long_events, - EDayViewEvent, event_num); - - if (!(*callback) (day_view, E_DAY_VIEW_LONG_EVENT, event_num, - data)) - return; - } -} - - -/* This calls a given function for each event instance that matches the given - uid. If the callback returns FALSE the iteration is stopped. - Note that it is safe for the callback to remove the event (since we - step backwards through the arrays). */ -static void -e_day_view_foreach_event_with_uid (EDayView *day_view, - const gchar *uid, - EDayViewForeachEventCallback callback, - gpointer data) -{ - EDayViewEvent *event; - gint day, event_num; - const char *u; - - for (day = 0; day < day_view->days_shown; day++) { - for (event_num = day_view->events[day]->len - 1; - event_num >= 0; - event_num--) { - event = &g_array_index (day_view->events[day], - EDayViewEvent, event_num); - - cal_component_get_uid (event->comp, &u); - if (uid && !strcmp (uid, u)) { - if (!(*callback) (day_view, day, event_num, - data)) - return; - } - } - } - - for (event_num = day_view->long_events->len - 1; - event_num >= 0; - event_num--) { - event = &g_array_index (day_view->long_events, - EDayViewEvent, event_num); - - cal_component_get_uid (event->comp, &u); - if (u && !strcmp (uid, u)) { - if (!(*callback) (day_view, E_DAY_VIEW_LONG_EVENT, - event_num, data)) - return; - } - } -} - - -static gboolean -e_day_view_remove_event_cb (EDayView *day_view, - gint day, - gint event_num, - gpointer data) -{ - EDayViewEvent *event; - -#if 0 - g_print ("In e_day_view_remove_event_cb day:%i event_num:%i\n", - day, event_num); -#endif - - if (day == E_DAY_VIEW_LONG_EVENT) - event = &g_array_index (day_view->long_events, - EDayViewEvent, event_num); - else - event = &g_array_index (day_view->events[day], - EDayViewEvent, event_num); - - /* If we were editing this event, set editing_event_num to -1 so - on_editing_stopped doesn't try to update the event. */ - if (day_view->editing_event_day == day - && day_view->editing_event_num == event_num) - day_view->editing_event_day = -1; - - if (event->canvas_item) - gtk_object_destroy (GTK_OBJECT (event->canvas_item)); - gtk_object_unref (GTK_OBJECT (event->comp)); - - if (day == E_DAY_VIEW_LONG_EVENT) { - g_array_remove_index (day_view->long_events, event_num); - day_view->long_events_need_layout = TRUE; - } else { - g_array_remove_index (day_view->events[day], event_num); - day_view->need_layout[day] = TRUE; - } - return TRUE; -} - - -/* This updates the text shown for an event. If the event start or end do not - lie on a row boundary, the time is displayed before the summary. */ -static void -e_day_view_update_event_label (EDayView *day_view, - gint day, - gint event_num) -{ - EDayViewEvent *event; - char *text, *start_suffix, *end_suffix; - gboolean free_text = FALSE, editing_event = FALSE; - gint offset; - gint start_hour, start_display_hour, start_minute, start_suffix_width; - gint end_hour, end_display_hour, end_minute, end_suffix_width; - CalComponentText summary; - - event = &g_array_index (day_view->events[day], EDayViewEvent, - event_num); - - /* If the event isn't visible just return. */ - if (!event->canvas_item) - return; - - cal_component_get_summary (event->comp, &summary); - text = summary.value ? (char*) summary.value : ""; - - if (day_view->editing_event_day == day - && day_view->editing_event_num == event_num) - editing_event = TRUE; - - if (!editing_event - && (event->start_minute % day_view->mins_per_row != 0 - || (day_view->show_event_end_times - && event->end_minute % day_view->mins_per_row != 0))) { - offset = day_view->first_hour_shown * 60 - + day_view->first_minute_shown; - start_minute = offset + event->start_minute; - end_minute = offset + event->end_minute; - - start_hour = start_minute / 60; - start_minute = start_minute % 60; - - end_hour = end_minute / 60; - end_minute = end_minute % 60; - - e_day_view_convert_time_to_display (day_view, start_hour, - &start_display_hour, - &start_suffix, - &start_suffix_width); - e_day_view_convert_time_to_display (day_view, end_hour, - &end_display_hour, - &end_suffix, - &end_suffix_width); - - if (day_view->use_24_hour_format) { - if (day_view->show_event_end_times) { - /* 24 hour format with end time. */ - text = g_strdup_printf - ("%2i:%02i-%2i:%02i %s", - start_display_hour, start_minute, - end_display_hour, end_minute, - text); - } else { - /* 24 hour format without end time. */ - text = g_strdup_printf - ("%2i:%02i %s", - start_display_hour, start_minute, - text); - } - } else { - if (day_view->show_event_end_times) { - /* 12 hour format with end time. */ - text = g_strdup_printf - ("%2i:%02i%s-%2i:%02i%s %s", - start_display_hour, start_minute, - start_suffix, - end_display_hour, end_minute, - end_suffix, - text); - } else { - /* 12 hour format without end time. */ - text = g_strdup_printf - ("%2i:%02i%s %s", - start_display_hour, start_minute, - start_suffix, - text); - } - } - - free_text = TRUE; - } - - gnome_canvas_item_set (event->canvas_item, - "text", text, - NULL); - - if (free_text) - g_free (text); -} - - -static void -e_day_view_update_long_event_label (EDayView *day_view, - gint event_num) -{ - EDayViewEvent *event; - CalComponentText summary; - - event = &g_array_index (day_view->long_events, EDayViewEvent, - event_num); - - /* If the event isn't visible just return. */ - if (!event->canvas_item) - return; - - cal_component_get_summary (event->comp, &summary); - gnome_canvas_item_set (event->canvas_item, - "text", summary.value ? summary.value : "", - NULL); -} - - -/* Finds the day and index of the event with the given canvas item. - If is is a long event, -1 is returned as the day. - Returns TRUE if the event was found. */ -static gboolean -e_day_view_find_event_from_item (EDayView *day_view, - GnomeCanvasItem *item, - gint *day_return, - gint *event_num_return) -{ - EDayViewEvent *event; - gint day, event_num; - - for (day = 0; day < day_view->days_shown; day++) { - for (event_num = 0; event_num < day_view->events[day]->len; - event_num++) { - event = &g_array_index (day_view->events[day], - EDayViewEvent, event_num); - if (event->canvas_item == item) { - *day_return = day; - *event_num_return = event_num; - return TRUE; - } - } - } - - for (event_num = 0; event_num < day_view->long_events->len; - event_num++) { - event = &g_array_index (day_view->long_events, - EDayViewEvent, event_num); - if (event->canvas_item == item) { - *day_return = E_DAY_VIEW_LONG_EVENT; - *event_num_return = event_num; - return TRUE; - } - } - - return FALSE; -} - - -/* Finds the day and index of the event with the given uid. - If is is a long event, E_DAY_VIEW_LONG_EVENT is returned as the day. - Returns TRUE if an event with the uid was found. - Note that for recurring events there may be several EDayViewEvents, one - for each instance, all with the same iCalObject and uid. So only use this - function if you know the event doesn't recur or you are just checking to - see if any events with the uid exist. */ -static gboolean -e_day_view_find_event_from_uid (EDayView *day_view, - const gchar *uid, - gint *day_return, - gint *event_num_return) -{ - EDayViewEvent *event; - gint day, event_num; - const char *u; - - for (day = 0; day < day_view->days_shown; day++) { - for (event_num = 0; event_num < day_view->events[day]->len; - event_num++) { - event = &g_array_index (day_view->events[day], - EDayViewEvent, event_num); - - cal_component_get_uid (event->comp, &u); - if (u && !strcmp (uid, u)) { - *day_return = day; - *event_num_return = event_num; - return TRUE; - } - } - } - - for (event_num = 0; event_num < day_view->long_events->len; - event_num++) { - event = &g_array_index (day_view->long_events, - EDayViewEvent, event_num); - - cal_component_get_uid (event->comp, &u); - if (u && !strcmp (uid, u)) { - *day_return = E_DAY_VIEW_LONG_EVENT; - *event_num_return = event_num; - return TRUE; - } - } - - return FALSE; -} - - -/* This sets the selected time range. The EDayView will show the day or week - corresponding to the start time. If the start_time & end_time are not equal - and are both visible in the view, then the selection is set to those times, - otherwise it is set to 1 hour from the start of the working day. */ -void -e_day_view_set_selected_time_range (EDayView *day_view, - time_t start_time, - time_t end_time) -{ - time_t lower; - gint start_row, start_col, end_row, end_col; - gboolean need_redraw = FALSE, start_in_grid, end_in_grid; - - g_return_if_fail (E_IS_DAY_VIEW (day_view)); - - /* Calculate the first day that should be shown, based on start_time - and the days_shown setting. If we are showing 1 day it is just the - start of the day given by start_time, otherwise it is the previous - work-week start day. */ - if (!day_view->work_week_view) { - lower = time_day_begin (start_time); - } else { - lower = e_day_view_find_work_week_start (day_view, start_time); - } - - /* See if we need to change the days shown. */ - if (lower != day_view->lower) { - e_day_view_recalc_day_starts (day_view, lower); - e_day_view_queue_reload_events (day_view); - } - - /* Set the selection. */ - start_in_grid = e_day_view_convert_time_to_grid_position (day_view, - start_time, - &start_col, - &start_row); - end_in_grid = e_day_view_convert_time_to_grid_position (day_view, - end_time - 60, - &end_col, - &end_row); - - /* If either of the times isn't in the grid, or the selection covers - an entire day, we set the selection to 1 row from the start of the - working day, in the day corresponding to the start time. */ - if (!start_in_grid || !end_in_grid - || (start_row == 0 && end_row == day_view->rows - 1)) { - end_col = start_col; - - start_row = e_day_view_convert_time_to_row (day_view, day_view->work_day_start_hour, day_view->work_day_start_minute); - start_row = CLAMP (start_row, 0, day_view->rows - 1); - end_row = start_row; - } - - if (start_row != day_view->selection_start_row - || start_col != day_view->selection_start_day) { - need_redraw = TRUE; - day_view->selection_in_top_canvas = FALSE; - day_view->selection_start_row = start_row; - day_view->selection_start_day = start_col; - } - - if (end_row != day_view->selection_end_row - || end_col != day_view->selection_end_day) { - need_redraw = TRUE; - day_view->selection_in_top_canvas = FALSE; - day_view->selection_end_row = end_row; - day_view->selection_end_day = end_col; - } - - if (need_redraw) { - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); - } -} - - -/* Finds the start of the working week which includes the given time. */ -static time_t -e_day_view_find_work_week_start (EDayView *day_view, - time_t start_time) -{ - GDate date; - gint weekday, day, i, offset; - - g_date_clear (&date, 1); - g_date_set_time (&date, start_time); - - /* The start of the work-week is the first working day after the - week start day. */ - - /* Get the weekday corresponding to start_time, 0 (Sun) to 6 (Sat). */ - weekday = g_date_weekday (&date) % 7; - - /* Calculate the first working day of the week, 0 (Sun) to 6 (Sat). - It will automatically default to the week start day if no days - are set as working days. */ - day = (day_view->week_start_day + 1) % 7; - for (i = 0; i < 7; i++) { - if (day_view->working_days & (1 << day)) - break; - day = (day + 1) % 7; - } - - /* Calculate how many days we need to go back to the first workday. */ - offset = (weekday + 7 - day) % 7; - - g_date_subtract_days (&date, offset); - - return time_from_day (g_date_year (&date), - g_date_month (&date) - 1, - g_date_day (&date)); -} - - -/* Returns the selected time range. */ -void -e_day_view_get_selected_time_range (EDayView *day_view, - time_t *start_time, - time_t *end_time) -{ - gint start_col, start_row, end_col, end_row; - time_t start, end; - - start_col = day_view->selection_start_day; - start_row = day_view->selection_start_row; - end_col = day_view->selection_end_day; - end_row = day_view->selection_end_row; - - if (start_col == -1) { - start_col = 0; - start_row = 0; - end_col = 0; - end_row = 0; - } - - /* Check if the selection is only in the top canvas, in which case - we can simply use the day_starts array. */ - if (day_view->selection_in_top_canvas) { - start = day_view->day_starts[start_col]; - end = day_view->day_starts[end_col + 1]; - } else { - /* Convert the start col + row into a time. */ - start = e_day_view_convert_grid_position_to_time (day_view, start_col, start_row); - end = e_day_view_convert_grid_position_to_time (day_view, end_col, end_row + 1); - } - - if (start_time) - *start_time = start; - - if (end_time) - *end_time = end; -} - - -static void -e_day_view_recalc_day_starts (EDayView *day_view, - time_t start_time) -{ - gint day; - - day_view->day_starts[0] = start_time; - for (day = 1; day <= day_view->days_shown; day++) { - day_view->day_starts[day] = time_add_day (day_view->day_starts[day - 1], 1); - } - - day_view->lower = start_time; - day_view->upper = day_view->day_starts[day_view->days_shown]; -} - - -/* 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) -{ - g_return_val_if_fail (E_IS_DAY_VIEW (day_view), FALSE); - - return day_view->work_week_view; -} - - -void -e_day_view_set_work_week_view (EDayView *day_view, - gboolean work_week_view) -{ - g_return_if_fail (E_IS_DAY_VIEW (day_view)); - - if (day_view->work_week_view == work_week_view) - return; - - day_view->work_week_view = work_week_view; - - if (day_view->work_week_view) - e_day_view_recalc_work_week (day_view); -} - - -gint -e_day_view_get_days_shown (EDayView *day_view) -{ - g_return_val_if_fail (E_IS_DAY_VIEW (day_view), -1); - - return day_view->days_shown; -} - - -void -e_day_view_set_days_shown (EDayView *day_view, - gint days_shown) -{ - g_return_if_fail (E_IS_DAY_VIEW (day_view)); - g_return_if_fail (days_shown >= 1); - g_return_if_fail (days_shown <= E_DAY_VIEW_MAX_DAYS); - - if (day_view->days_shown == days_shown) - return; - - day_view->days_shown = days_shown; - - /* If the date isn't set, just return. */ - if (day_view->lower == 0 && day_view->upper == 0) - return; - - e_day_view_recalc_day_starts (day_view, day_view->lower); - e_day_view_recalc_cell_sizes (day_view); - e_day_view_queue_reload_events (day_view); -} - - -gint -e_day_view_get_mins_per_row (EDayView *day_view) -{ - g_return_val_if_fail (E_IS_DAY_VIEW (day_view), -1); - - return day_view->mins_per_row; -} - - -void -e_day_view_set_mins_per_row (EDayView *day_view, - gint mins_per_row) -{ - gint day; - - g_return_if_fail (E_IS_DAY_VIEW (day_view)); - - if (mins_per_row != 5 && mins_per_row != 10 && mins_per_row != 15 - && mins_per_row != 30 && mins_per_row != 60) { - g_warning ("Invalid minutes per row setting"); - return; - } - - if (day_view->mins_per_row == mins_per_row) - return; - - day_view->mins_per_row = mins_per_row; - e_day_view_recalc_num_rows (day_view); - - /* If we aren't visible, we'll sort it out later. */ - if (!GTK_WIDGET_VISIBLE (day_view)) - return; - - for (day = 0; day < E_DAY_VIEW_MAX_DAYS; day++) - day_view->need_layout[day] = TRUE; - - /* We need to update all the day event labels since the start & end - times may or may not be on row boundaries any more. */ - e_day_view_foreach_event (day_view, - e_day_view_set_show_times_cb, NULL); - - /* We must layout the events before updating the scroll region, since - that will result in a redraw which would crash otherwise. */ - e_day_view_check_layout (day_view); - gtk_widget_queue_draw (day_view->time_canvas); - gtk_widget_queue_draw (day_view->main_canvas); - - e_day_view_update_scroll_regions (day_view); -} - - -/* This specifies the working days in the week. The value is a bitwise - combination of day flags. Defaults to Mon-Fri. */ -EDayViewDays -e_day_view_get_working_days (EDayView *day_view) -{ - g_return_val_if_fail (E_IS_DAY_VIEW (day_view), 0); - - return day_view->working_days; -} - - -void -e_day_view_set_working_days (EDayView *day_view, - EDayViewDays days) -{ - g_return_if_fail (E_IS_DAY_VIEW (day_view)); - - if (day_view->working_days == days) - return; - - day_view->working_days = days; - - if (day_view->work_week_view) - e_day_view_recalc_work_week (day_view); - - /* We have to do this, as the new working days may have no effect on - the days shown, but we still want the background color to change. */ - gtk_widget_queue_draw (day_view->main_canvas); -} - - -static void -e_day_view_recalc_work_week_days_shown (EDayView *day_view) -{ - gint first_day, last_day, i, days_shown; - gboolean has_working_days = FALSE; - - /* Find the first working day in the week, 0 (Sun) to 6 (Sat). */ - first_day = (day_view->week_start_day + 1) % 7; - for (i = 0; i < 7; i++) { - if (day_view->working_days & (1 << first_day)) { - has_working_days = TRUE; - break; - } - first_day = (first_day + 1) % 7; - } - - if (has_working_days) { - /* Now find the last working day of the week, backwards. */ - last_day = day_view->week_start_day % 7; - for (i = 0; i < 7; i++) { - if (day_view->working_days & (1 << last_day)) - break; - last_day = (last_day + 6) % 7; - } - /* Now calculate the days we need to show to include all the - working days in the week. Add 1 to make it inclusive. */ - days_shown = (last_day + 7 - first_day) % 7 + 1; - } else { - /* If no working days are set, just use 7. */ - days_shown = 7; - } - - e_day_view_set_days_shown (day_view, days_shown); -} - - -/* The start and end time of the working day. This only affects the background - colors. */ -void -e_day_view_get_working_day (EDayView *day_view, - gint *start_hour, - gint *start_minute, - gint *end_hour, - gint *end_minute) -{ - g_return_if_fail (E_IS_DAY_VIEW (day_view)); - - *start_hour = day_view->work_day_start_hour; - *start_minute = day_view->work_day_start_minute; - *end_hour = day_view->work_day_end_hour; - *end_minute = day_view->work_day_end_minute; -} - - -void -e_day_view_set_working_day (EDayView *day_view, - gint start_hour, - gint start_minute, - gint end_hour, - gint end_minute) -{ - g_return_if_fail (E_IS_DAY_VIEW (day_view)); - - day_view->work_day_start_hour = start_hour; - day_view->work_day_start_minute = start_minute; - day_view->work_day_end_hour = end_hour; - day_view->work_day_end_minute = end_minute; - - gtk_widget_queue_draw (day_view->main_canvas); -} - - -/* Whether we use 12-hour of 24-hour format. */ -gboolean -e_day_view_get_24_hour_format (EDayView *day_view) -{ - g_return_val_if_fail (E_IS_DAY_VIEW (day_view), FALSE); - - return day_view->use_24_hour_format; -} - - -void -e_day_view_set_24_hour_format (EDayView *day_view, - gboolean use_24_hour) -{ - g_return_if_fail (E_IS_DAY_VIEW (day_view)); - - if (day_view->use_24_hour_format == use_24_hour) - return; - - day_view->use_24_hour_format = use_24_hour; - - /* We need to update all the text in the events since they may contain - the time in the old format. */ - e_day_view_foreach_event (day_view, e_day_view_set_show_times_cb, - NULL); - - /* FIXME: We need to re-layout the top canvas since the time - format affects the sizes. */ - gtk_widget_queue_draw (day_view->time_canvas); - gtk_widget_queue_draw (day_view->top_canvas); -} - - -/* Whether we display event end times in the main canvas. */ -gboolean -e_day_view_get_show_event_end_times (EDayView *day_view) -{ - g_return_val_if_fail (E_IS_DAY_VIEW (day_view), TRUE); - - return day_view->show_event_end_times; -} - - -void -e_day_view_set_show_event_end_times (EDayView *day_view, - gboolean show) -{ - g_return_if_fail (E_IS_DAY_VIEW (day_view)); - - if (day_view->show_event_end_times != show) { - day_view->show_event_end_times = show; - e_day_view_foreach_event (day_view, - e_day_view_set_show_times_cb, NULL); - } -} - - -/* This is a callback used to update all day event labels. */ -static gboolean -e_day_view_set_show_times_cb (EDayView *day_view, - gint day, - gint event_num, - gpointer data) -{ - if (day != E_DAY_VIEW_LONG_EVENT) { - e_day_view_update_event_label (day_view, day, event_num); - } - - return TRUE; -} - - -/* The first day of the week, 0 (Monday) to 6 (Sunday). */ -gint -e_day_view_get_week_start_day (EDayView *day_view) -{ - g_return_val_if_fail (E_IS_DAY_VIEW (day_view), 0); - - return day_view->week_start_day; -} - - -void -e_day_view_set_week_start_day (EDayView *day_view, - gint week_start_day) -{ - g_return_if_fail (E_IS_DAY_VIEW (day_view)); - g_return_if_fail (week_start_day >= 0); - g_return_if_fail (week_start_day < 7); - - if (day_view->week_start_day == week_start_day) - return; - - day_view->week_start_day = week_start_day; - - if (day_view->work_week_view) - e_day_view_recalc_work_week (day_view); -} - - -static void -e_day_view_recalc_work_week (EDayView *day_view) -{ - time_t lower; - - /* If we aren't showing the work week, just return. */ - if (!day_view->work_week_view) - return; - - e_day_view_recalc_work_week_days_shown (day_view); - - /* If the date isn't set, just return. */ - if (day_view->lower == 0 && day_view->upper == 0) - return; - - lower = e_day_view_find_work_week_start (day_view, day_view->lower); - if (lower != day_view->lower) { - /* Reset the selection, as it may disappear. */ - day_view->selection_start_day = -1; - - e_day_view_recalc_day_starts (day_view, lower); - e_day_view_queue_reload_events (day_view); - - /* This updates the date navigator. */ - e_day_view_update_calendar_selection_time (day_view); - } -} - - -static gboolean -e_day_view_update_scroll_regions (EDayView *day_view) -{ - gdouble old_x2, old_y2, new_x2, new_y2; - gboolean need_reshape = FALSE; - - /* Set the scroll region of the time canvas to its allocated width, - but with the height the same as the main canvas. */ - gnome_canvas_get_scroll_region (GNOME_CANVAS (day_view->time_canvas), - NULL, NULL, &old_x2, &old_y2); - new_x2 = day_view->time_canvas->allocation.width - 1; - new_y2 = MAX (day_view->rows * day_view->row_height, - day_view->main_canvas->allocation.height) - 1; - if (old_x2 != new_x2 || old_y2 != new_y2) - gnome_canvas_set_scroll_region (GNOME_CANVAS (day_view->time_canvas), - 0, 0, new_x2, new_y2); - - /* Set the scroll region of the main canvas to its allocated width, - but with the height depending on the number of rows needed. */ - gnome_canvas_get_scroll_region (GNOME_CANVAS (day_view->main_canvas), - NULL, NULL, &old_x2, &old_y2); - new_x2 = day_view->main_canvas->allocation.width - 1; - if (old_x2 != new_x2 || old_y2 != new_y2) { - need_reshape = TRUE; - gnome_canvas_set_scroll_region (GNOME_CANVAS (day_view->main_canvas), - 0, 0, new_x2, new_y2); - } - - return need_reshape; -} - - -/* This recalculates the number of rows to display, based on the time range - shown and the minutes per row. */ -static void -e_day_view_recalc_num_rows (EDayView *day_view) -{ - gint hours, minutes, total_minutes; - - hours = day_view->last_hour_shown - day_view->first_hour_shown; - /* This could be negative but it works out OK. */ - minutes = day_view->last_minute_shown - day_view->first_minute_shown; - total_minutes = hours * 60 + minutes; - day_view->rows = total_minutes / day_view->mins_per_row; -} - - -/* Converts an hour and minute to a row in the canvas. Note that if we aren't - showing all 24 hours of the day, the returned row may be negative or - greater than day_view->rows. */ -gint -e_day_view_convert_time_to_row (EDayView *day_view, - gint hour, - gint minute) -{ - gint total_minutes, start_minute, offset; - - total_minutes = hour * 60 + minute; - start_minute = day_view->first_hour_shown * 60 - + day_view->first_minute_shown; - offset = total_minutes - start_minute; - if (offset < 0) - return -1; - else - return offset / day_view->mins_per_row; -} - - -/* Converts an hour and minute to a y coordinate in the canvas. */ -gint -e_day_view_convert_time_to_position (EDayView *day_view, - gint hour, - gint minute) -{ - gint total_minutes, start_minute, offset; - - total_minutes = hour * 60 + minute; - start_minute = day_view->first_hour_shown * 60 - + day_view->first_minute_shown; - offset = total_minutes - start_minute; - - return offset * day_view->row_height / day_view->mins_per_row; -} - - -static gboolean -e_day_view_on_top_canvas_button_press (GtkWidget *widget, - GdkEventButton *event, - EDayView *day_view) -{ - gint event_x, event_y, scroll_x, scroll_y, day, event_num; - EDayViewPosition pos; - - /* Convert the coords to the main canvas window, or return if the - window is not found. */ - if (!e_day_view_convert_event_coords (day_view, (GdkEvent*) event, - GTK_LAYOUT (widget)->bin_window, - &event_x, &event_y)) - return FALSE; - - /* The top canvas doesn't scroll, but just in case. */ - gnome_canvas_get_scroll_offsets (GNOME_CANVAS (widget), - &scroll_x, &scroll_y); - event_x += scroll_x; - event_y += scroll_y; - - pos = e_day_view_convert_position_in_top_canvas (day_view, - event_x, event_y, - &day, &event_num); - - if (pos == E_DAY_VIEW_POS_OUTSIDE) - return FALSE; - - if (pos != E_DAY_VIEW_POS_NONE) - return e_day_view_on_long_event_button_press (day_view, - event_num, - event, pos, - event_x, - event_y); - - e_day_view_stop_editing_event (day_view); - - if (event->button == 1) { - if (!GTK_WIDGET_HAS_FOCUS (day_view)) - gtk_widget_grab_focus (GTK_WIDGET (day_view)); - - if (gdk_pointer_grab (GTK_LAYOUT (widget)->bin_window, FALSE, - GDK_POINTER_MOTION_MASK - | GDK_BUTTON_RELEASE_MASK, - FALSE, NULL, event->time) == 0) { - e_day_view_start_selection (day_view, day, -1); - } - } else if (event->button == 3) { - if (!GTK_WIDGET_HAS_FOCUS (day_view)) - gtk_widget_grab_focus (GTK_WIDGET (day_view)); - - e_day_view_on_event_right_click (day_view, event, -1, -1); - } - - return TRUE; -} - - -static gboolean -e_day_view_convert_event_coords (EDayView *day_view, - GdkEvent *event, - GdkWindow *window, - gint *x_return, - gint *y_return) -{ - gint event_x, event_y, win_x, win_y; - GdkWindow *event_window;; - - /* Get the event window, x & y from the appropriate event struct. */ - switch (event->type) { - case GDK_BUTTON_PRESS: - case GDK_2BUTTON_PRESS: - case GDK_3BUTTON_PRESS: - case GDK_BUTTON_RELEASE: - event_x = event->button.x; - event_y = event->button.y; - event_window = event->button.window; - break; - case GDK_MOTION_NOTIFY: - event_x = event->motion.x; - event_y = event->motion.y; - event_window = event->motion.window; - break; - default: - /* Shouldn't get here. */ - g_assert_not_reached (); - return FALSE; - } - - while (event_window && event_window != window - && event_window != GDK_ROOT_PARENT()) { - gdk_window_get_position (event_window, &win_x, &win_y); - event_x += win_x; - event_y += win_y; - event_window = gdk_window_get_parent (event_window); - } - - *x_return = event_x; - *y_return = event_y; - - if (event_window != window) - g_warning ("Couldn't find event window\n"); - - return (event_window == window) ? TRUE : FALSE; -} - - -static gboolean -e_day_view_on_main_canvas_button_press (GtkWidget *widget, - GdkEventButton *event, - EDayView *day_view) -{ - gint event_x, event_y, scroll_x, scroll_y, row, day, event_num; - EDayViewPosition pos; - - /* Handle scroll wheel events */ - if (event->button == 4) { - /* The wheel has been moved up, so scroll the canvas down. */ - e_day_view_scroll (day_view, E_DAY_VIEW_WHEEL_MOUSE_STEP_SIZE); - return TRUE; - } - if (event->button == 5) { - /* The wheel has been moved down, so scroll the canvas up. */ - e_day_view_scroll (day_view, -E_DAY_VIEW_WHEEL_MOUSE_STEP_SIZE); - return TRUE; - } - - /* Convert the coords to the main canvas window, or return if the - window is not found. */ - if (!e_day_view_convert_event_coords (day_view, (GdkEvent*) event, - GTK_LAYOUT (widget)->bin_window, - &event_x, &event_y)) - return FALSE; - - gnome_canvas_get_scroll_offsets (GNOME_CANVAS (widget), - &scroll_x, &scroll_y); - event_x += scroll_x; - event_y += scroll_y; - - /* Find out where the mouse is. */ - pos = e_day_view_convert_position_in_main_canvas (day_view, - event_x, event_y, - &day, &row, - &event_num); - - if (pos == E_DAY_VIEW_POS_OUTSIDE) - return FALSE; - - if (pos != E_DAY_VIEW_POS_NONE) - return e_day_view_on_event_button_press (day_view, day, - event_num, event, pos, - event_x, event_y); - - e_day_view_stop_editing_event (day_view); - - /* Start the selection drag. */ - if (event->button == 1) { - if (!GTK_WIDGET_HAS_FOCUS (day_view)) - gtk_widget_grab_focus (GTK_WIDGET (day_view)); - - if (gdk_pointer_grab (GTK_LAYOUT (widget)->bin_window, FALSE, - GDK_POINTER_MOTION_MASK - | GDK_BUTTON_RELEASE_MASK, - FALSE, NULL, event->time) == 0) { - e_day_view_start_selection (day_view, day, row); - } - } else if (event->button == 3) { - if (!GTK_WIDGET_HAS_FOCUS (day_view)) - gtk_widget_grab_focus (GTK_WIDGET (day_view)); - - e_day_view_on_event_right_click (day_view, event, -1, -1); - } - - return TRUE; -} - - -static gboolean -e_day_view_on_time_canvas_button_press (GtkWidget *widget, - GdkEventButton *event, - EDayView *day_view) -{ - /* Handle scroll wheel events */ - if (event->button == 4 || event->button == 5) { - GtkAdjustment *adj = GTK_LAYOUT (day_view->main_canvas)->vadjustment; - gfloat new_value; - - new_value = adj->value + ((event->button == 4) ? - -adj->page_increment / 2: - adj->page_increment / 2); - new_value = CLAMP (new_value, adj->lower, adj->upper - adj->page_size); - gtk_adjustment_set_value (adj, new_value); - - return TRUE; - } - - return FALSE; -} - - -static gboolean -e_day_view_on_long_event_button_press (EDayView *day_view, - gint event_num, - GdkEventButton *event, - EDayViewPosition pos, - gint event_x, - gint event_y) -{ - if (event->button == 1) { - if (event->type == GDK_BUTTON_PRESS) { - e_day_view_on_long_event_click (day_view, event_num, - event, pos, - event_x, event_y); - return TRUE; - } else if (event->type == GDK_2BUTTON_PRESS) { - e_day_view_on_event_double_click (day_view, -1, - event_num); - return TRUE; - } - } else if (event->button == 3) { - if (!GTK_WIDGET_HAS_FOCUS (day_view)) - gtk_widget_grab_focus (GTK_WIDGET (day_view)); - - e_day_view_on_event_right_click (day_view, event, - E_DAY_VIEW_LONG_EVENT, - event_num); - return TRUE; - } - return FALSE; -} - - -static gboolean -e_day_view_on_event_button_press (EDayView *day_view, - gint day, - gint event_num, - GdkEventButton *event, - EDayViewPosition pos, - gint event_x, - gint event_y) -{ - if (event->button == 1) { - if (event->type == GDK_BUTTON_PRESS) { - e_day_view_on_event_click (day_view, day, event_num, - event, pos, - event_x, event_y); - return TRUE; - } else if (event->type == GDK_2BUTTON_PRESS) { - e_day_view_on_event_double_click (day_view, day, - event_num); - return TRUE; - } - } else if (event->button == 3) { - if (!GTK_WIDGET_HAS_FOCUS (day_view)) - gtk_widget_grab_focus (GTK_WIDGET (day_view)); - - e_day_view_on_event_right_click (day_view, event, - day, event_num); - return TRUE; - } - return FALSE; -} - - -static void -e_day_view_on_long_event_click (EDayView *day_view, - gint event_num, - GdkEventButton *bevent, - EDayViewPosition pos, - gint event_x, - gint event_y) -{ - EDayViewEvent *event; - gint start_day, end_day, day; - gint item_x, item_y, item_w, item_h; - - event = &g_array_index (day_view->long_events, EDayViewEvent, - event_num); - - /* Ignore clicks on the EText while editing. */ - if (pos == E_DAY_VIEW_POS_EVENT - && E_TEXT (event->canvas_item)->editing) - return; - - if (!(cal_component_has_recurrences (event->comp)) - && (pos == E_DAY_VIEW_POS_LEFT_EDGE - || pos == E_DAY_VIEW_POS_RIGHT_EDGE)) { - if (!e_day_view_find_long_event_days (day_view, event, - &start_day, &end_day)) - return; - - /* Grab the keyboard focus, so the event being edited is saved - and we can use the Escape key to abort the resize. */ - if (!GTK_WIDGET_HAS_FOCUS (day_view)) - gtk_widget_grab_focus (GTK_WIDGET (day_view)); - - if (gdk_pointer_grab (GTK_LAYOUT (day_view->top_canvas)->bin_window, FALSE, - GDK_POINTER_MOTION_MASK - | GDK_BUTTON_RELEASE_MASK, - FALSE, NULL, bevent->time) == 0) { - - day_view->resize_event_day = E_DAY_VIEW_LONG_EVENT; - day_view->resize_event_num = event_num; - day_view->resize_drag_pos = pos; - day_view->resize_start_row = start_day; - day_view->resize_end_row = end_day; - - /* Create the edit rect if necessary. */ - e_day_view_reshape_resize_long_event_rect_item (day_view); - - /* Make sure the text item is on top. */ - gnome_canvas_item_raise_to_top (day_view->resize_long_event_rect_item); - - /* Raise the event's item, above the rect as well. */ - gnome_canvas_item_raise_to_top (event->canvas_item); - } - } else if (e_day_view_get_long_event_position (day_view, event_num, - &start_day, &end_day, - &item_x, &item_y, - &item_w, &item_h)) { - /* Remember the item clicked and the mouse position, - so we can start a drag if the mouse moves. */ - day_view->pressed_event_day = E_DAY_VIEW_LONG_EVENT; - day_view->pressed_event_num = event_num; - - day_view->drag_event_x = event_x; - day_view->drag_event_y = event_y; - - e_day_view_convert_position_in_top_canvas (day_view, - event_x, event_y, - &day, NULL); - day_view->drag_event_offset = day - start_day; - } -} - - -static void -e_day_view_on_event_click (EDayView *day_view, - gint day, - gint event_num, - GdkEventButton *bevent, - EDayViewPosition pos, - gint event_x, - gint event_y) -{ - EDayViewEvent *event; - gint tmp_day, row, start_row; - - event = &g_array_index (day_view->events[day], EDayViewEvent, - event_num); - - /* Ignore clicks on the EText while editing. */ - if (pos == E_DAY_VIEW_POS_EVENT - && E_TEXT (event->canvas_item)->editing) - return; - - if (!(cal_component_has_recurrences (event->comp)) - && (pos == E_DAY_VIEW_POS_TOP_EDGE - || pos == E_DAY_VIEW_POS_BOTTOM_EDGE)) { - /* Grab the keyboard focus, so the event being edited is saved - and we can use the Escape key to abort the resize. */ - if (!GTK_WIDGET_HAS_FOCUS (day_view)) - gtk_widget_grab_focus (GTK_WIDGET (day_view)); - - if (gdk_pointer_grab (GTK_LAYOUT (day_view->main_canvas)->bin_window, FALSE, - GDK_POINTER_MOTION_MASK - | GDK_BUTTON_RELEASE_MASK, - FALSE, NULL, bevent->time) == 0) { - - day_view->resize_event_day = day; - day_view->resize_event_num = event_num; - day_view->resize_drag_pos = pos; - day_view->resize_start_row = event->start_minute / day_view->mins_per_row; - day_view->resize_end_row = (event->end_minute - 1) / day_view->mins_per_row; - - day_view->resize_bars_event_day = day; - day_view->resize_bars_event_num = event_num; - - /* Create the edit rect if necessary. */ - e_day_view_reshape_resize_rect_item (day_view); - - e_day_view_reshape_main_canvas_resize_bars (day_view); - - /* Make sure the text item is on top. */ - gnome_canvas_item_raise_to_top (day_view->resize_rect_item); - gnome_canvas_item_raise_to_top (day_view->resize_bar_item); - - /* Raise the event's item, above the rect as well. */ - gnome_canvas_item_raise_to_top (event->canvas_item); - } - - } else { - /* Remember the item clicked and the mouse position, - so we can start a drag if the mouse moves. */ - day_view->pressed_event_day = day; - day_view->pressed_event_num = event_num; - - day_view->drag_event_x = event_x; - day_view->drag_event_y = event_y; - - e_day_view_convert_position_in_main_canvas (day_view, - event_x, event_y, - &tmp_day, &row, - NULL); - start_row = event->start_minute / day_view->mins_per_row; - day_view->drag_event_offset = row - start_row; - } -} - - -static void -e_day_view_reshape_resize_long_event_rect_item (EDayView *day_view) -{ - gint day, event_num, start_day, end_day; - gint item_x, item_y, item_w, item_h; - gdouble x1, y1, x2, y2; - - day = day_view->resize_event_day; - event_num = day_view->resize_event_num; - - /* If we're not resizing an event, or the event is not shown, - hide the resize bars. */ - if (day_view->resize_drag_pos == E_DAY_VIEW_POS_NONE - || !e_day_view_get_long_event_position (day_view, event_num, - &start_day, &end_day, - &item_x, &item_y, - &item_w, &item_h)) { - gnome_canvas_item_hide (day_view->resize_long_event_rect_item); - return; - } - - x1 = item_x; - y1 = item_y; - x2 = item_x + item_w - 1; - y2 = item_y + item_h - 1; - - gnome_canvas_item_set (day_view->resize_long_event_rect_item, - "x1", x1, - "y1", y1, - "x2", x2, - "y2", y2, - NULL); - gnome_canvas_item_show (day_view->resize_long_event_rect_item); -} - - -static void -e_day_view_reshape_resize_rect_item (EDayView *day_view) -{ - gint day, event_num; - gint item_x, item_y, item_w, item_h; - gdouble x1, y1, x2, y2; - - day = day_view->resize_event_day; - event_num = day_view->resize_event_num; - - /* If we're not resizing an event, or the event is not shown, - hide the resize bars. */ - if (day_view->resize_drag_pos == E_DAY_VIEW_POS_NONE - || !e_day_view_get_event_position (day_view, day, event_num, - &item_x, &item_y, - &item_w, &item_h)) { - gnome_canvas_item_hide (day_view->resize_rect_item); - return; - } - - x1 = item_x; - y1 = item_y; - x2 = item_x + item_w - 1; - y2 = item_y + item_h - 1; - - gnome_canvas_item_set (day_view->resize_rect_item, - "x1", x1 + E_DAY_VIEW_BAR_WIDTH - 1, - "y1", y1, - "x2", x2, - "y2", y2, - NULL); - gnome_canvas_item_show (day_view->resize_rect_item); - - gnome_canvas_item_set (day_view->resize_bar_item, - "x1", x1, - "y1", y1, - "x2", x1 + E_DAY_VIEW_BAR_WIDTH - 1, - "y2", y2, - NULL); - gnome_canvas_item_show (day_view->resize_bar_item); -} - - -static void -e_day_view_on_event_double_click (EDayView *day_view, - gint day, - gint event_num) -{ -#if 0 - g_print ("In e_day_view_on_event_double_click\n"); -#endif - -} - - -static void -e_day_view_on_event_right_click (EDayView *day_view, - GdkEventButton *bevent, - gint day, - gint event_num) -{ - EDayViewEvent *event; - int have_selection, not_being_edited, items, i; - struct menu_item *context_menu; - - static struct menu_item main_items[] = { - { N_("New appointment..."), (GtkSignalFunc) e_day_view_on_new_appointment, NULL, TRUE } - }; - - static struct menu_item child_items[] = { - { N_("Schedule meeting"), (GtkSignalFunc) e_day_view_on_schedule_meet, NULL, TRUE }, - - { NULL, NULL, NULL, TRUE}, - - { N_("Edit this appointment..."), (GtkSignalFunc) e_day_view_on_edit_appointment, NULL, TRUE }, - { N_("Delete this appointment"), (GtkSignalFunc) e_day_view_on_delete_appointment, NULL, TRUE }, - - { NULL, NULL, NULL, TRUE}, - - { N_("New appointment..."), (GtkSignalFunc) e_day_view_on_new_appointment, NULL, TRUE } - }; - - static struct menu_item recur_child_items[] = { - { N_("Make this appointment movable"), (GtkSignalFunc) e_day_view_on_unrecur_appointment, NULL, TRUE }, - { N_("Schedule meeting"), (GtkSignalFunc) e_day_view_on_schedule_meet, NULL, TRUE }, - - { NULL, NULL, NULL, TRUE}, - - { N_("Edit this appointment..."), (GtkSignalFunc) e_day_view_on_edit_appointment, NULL, TRUE }, - { N_("Delete this occurrence"), (GtkSignalFunc) e_day_view_on_delete_occurrence, NULL, TRUE }, - { N_("Delete all occurrences"), (GtkSignalFunc) e_day_view_on_delete_appointment, NULL, TRUE }, - - { NULL, NULL, NULL, TRUE}, - - { N_("New appointment..."), (GtkSignalFunc) e_day_view_on_new_appointment, NULL, TRUE }, - }; - - have_selection = GTK_WIDGET_HAS_FOCUS (day_view) - && day_view->selection_start_day != -1; - - if (event_num == -1) { - items = 1; - context_menu = &main_items[0]; - context_menu[0].sensitive = have_selection; - } else { - if (day == E_DAY_VIEW_LONG_EVENT) - event = &g_array_index (day_view->long_events, - EDayViewEvent, event_num); - else - event = &g_array_index (day_view->events[day], - EDayViewEvent, event_num); - - /* This used to be set only if the event wasn't being edited - in the event editor, but we can't check that at present. - We could possibly set up another method of checking it. */ - not_being_edited = TRUE; - - if (cal_component_has_recurrences (event->comp)) { - items = 8; - context_menu = &recur_child_items[0]; - context_menu[0].sensitive = not_being_edited; - context_menu[1].sensitive = not_being_edited; - context_menu[3].sensitive = not_being_edited; - context_menu[4].sensitive = not_being_edited; - context_menu[5].sensitive = not_being_edited; - context_menu[7].sensitive = have_selection; - } else { - items = 6; - context_menu = &child_items[0]; - context_menu[0].sensitive = not_being_edited; - context_menu[2].sensitive = not_being_edited; - context_menu[3].sensitive = not_being_edited; - context_menu[5].sensitive = have_selection; - } - } - - for (i = 0; i < items; i++) - context_menu[i].data = day_view; - - day_view->popup_event_day = day; - day_view->popup_event_num = event_num; - popup_menu (context_menu, items, bevent); -} - - -static void -e_day_view_on_new_appointment (GtkWidget *widget, gpointer data) -{ - EDayView *day_view; - CalComponent *comp; - CalComponentDateTime date; - time_t dtstart, dtend; - struct icaltimetype itt; - - day_view = E_DAY_VIEW (data); - - comp = cal_component_new (); - cal_component_set_new_vtype (comp, CAL_COMPONENT_EVENT); - e_day_view_get_selected_time_range (day_view, &dtstart, &dtend); - - date.value = &itt; - date.tzid = NULL; - - *date.value = icaltime_from_timet (dtstart, FALSE); - cal_component_set_dtstart (comp, &date); - - *date.value = icaltime_from_timet (dtend, FALSE); - cal_component_set_dtend (comp, &date); - - cal_component_commit_sequence (comp); - - if (day_view->calendar) - gnome_calendar_edit_object (day_view->calendar, comp); - else - g_warning ("Calendar not set"); - - gtk_object_unref (GTK_OBJECT (comp)); -} - - -static void -e_day_view_on_edit_appointment (GtkWidget *widget, gpointer data) -{ - EDayView *day_view; - EDayViewEvent *event; - - day_view = E_DAY_VIEW (data); - - event = e_day_view_get_popup_menu_event (day_view); - if (event == NULL) - return; - - if (day_view->calendar) - gnome_calendar_edit_object (day_view->calendar, event->comp); - else - g_warning ("Calendar not set"); -} - - -static void -e_day_view_on_delete_occurrence (GtkWidget *widget, gpointer data) -{ - EDayView *day_view; - EDayViewEvent *event; - CalComponent *comp; - - day_view = E_DAY_VIEW (data); - - event = e_day_view_get_popup_menu_event (day_view); - if (event == NULL) - return; - - /* We must duplicate the CalComponent, or we won't know it has changed - when we get the "update_event" callback. */ - comp = cal_component_clone (event->comp); - cal_comp_util_add_exdate (comp, icaltime_from_timet (event->start, FALSE)); - - if (!cal_client_update_object (day_view->client, comp)) - g_message ("e_day_view_on_delete_occurrence(): Could not update the object!"); - - gtk_object_unref (GTK_OBJECT (comp)); -} - - -static void -e_day_view_on_delete_appointment (GtkWidget *widget, gpointer data) -{ - EDayView *day_view; - EDayViewEvent *event; - - day_view = E_DAY_VIEW (data); - - event = e_day_view_get_popup_menu_event (day_view); - if (event == NULL) - return; - - if (day_view->editing_event_day >= 0) - e_day_view_stop_editing_event (day_view); - - if (delete_component_dialog (event->comp, widget)) { - const char *uid; - - cal_component_get_uid (event->comp, &uid); - - /* We don't check the return value; FALSE can mean the object - * was not in the server anyways. - */ - cal_client_remove_object (day_view->client, uid); - } -} - - -static void -e_day_view_on_schedule_meet (GtkWidget *widget, gpointer data) -{ - EDayView *day_view; - EDayViewEvent *event; - EMeetingEditor *editor; - - day_view = E_DAY_VIEW (data); - - event = e_day_view_get_popup_menu_event (day_view); - if (event == NULL) - return; - - editor = e_meeting_editor_new (event->comp, day_view->client); - - e_meeting_edit (editor); - e_meeting_editor_free (editor); -} - -static void -e_day_view_on_unrecur_appointment (GtkWidget *widget, gpointer data) -{ - EDayView *day_view; - EDayViewEvent *event; - CalComponent *comp, *new_comp; - CalComponentDateTime date; - struct icaltimetype itt; - - day_view = E_DAY_VIEW (data); - - 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_clone (event->comp); - cal_comp_util_add_exdate (comp, icaltime_from_timet (event->start, FALSE)); - - /* 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_clone (event->comp); - 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 = NULL; - - *date.value = icaltime_from_timet (event->start, FALSE); - cal_component_set_dtstart (new_comp, &date); - *date.value = icaltime_from_timet (event->end, FALSE); - 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 (day_view->client, comp)) - g_message ("e_day_view_on_unrecur_appointment(): Could not update the object!"); - - gtk_object_unref (GTK_OBJECT (comp)); - - if (!cal_client_update_object (day_view->client, new_comp)) - g_message ("e_day_view_on_unrecur_appointment(): Could not update the object!"); - - gtk_object_unref (GTK_OBJECT (new_comp)); -} - - -static EDayViewEvent* -e_day_view_get_popup_menu_event (EDayView *day_view) -{ - if (day_view->popup_event_num == -1) - return NULL; - - if (day_view->popup_event_day == E_DAY_VIEW_LONG_EVENT) - return &g_array_index (day_view->long_events, - EDayViewEvent, - day_view->popup_event_num); - else - return &g_array_index (day_view->events[day_view->popup_event_day], - EDayViewEvent, - day_view->popup_event_num); -} - - -static gboolean -e_day_view_on_top_canvas_button_release (GtkWidget *widget, - GdkEventButton *event, - EDayView *day_view) -{ - if (day_view->selection_is_being_dragged) { - gdk_pointer_ungrab (event->time); - e_day_view_finish_selection (day_view); - } else if (day_view->resize_drag_pos != E_DAY_VIEW_POS_NONE) { - e_day_view_finish_long_event_resize (day_view); - gdk_pointer_ungrab (event->time); - } else if (day_view->pressed_event_day != -1) { - e_day_view_start_editing_event (day_view, - day_view->pressed_event_day, - day_view->pressed_event_num, - NULL); - } - - day_view->pressed_event_day = -1; - - return FALSE; -} - - -static gboolean -e_day_view_on_main_canvas_button_release (GtkWidget *widget, - GdkEventButton *event, - EDayView *day_view) -{ - if (day_view->selection_is_being_dragged) { - gdk_pointer_ungrab (event->time); - e_day_view_finish_selection (day_view); - e_day_view_stop_auto_scroll (day_view); - } else if (day_view->resize_drag_pos != E_DAY_VIEW_POS_NONE) { - e_day_view_finish_resize (day_view); - gdk_pointer_ungrab (event->time); - e_day_view_stop_auto_scroll (day_view); - } else if (day_view->pressed_event_day != -1) { - e_day_view_start_editing_event (day_view, - day_view->pressed_event_day, - day_view->pressed_event_num, - NULL); - } - - day_view->pressed_event_day = -1; - - return FALSE; -} - - -static void -e_day_view_update_calendar_selection_time (EDayView *day_view) -{ - time_t start, end; - - e_day_view_get_selected_time_range (day_view, &start, &end); - -#if 0 - g_print ("Start: %s", ctime (&start)); - g_print ("End : %s", ctime (&end)); -#endif - - if (day_view->calendar) - gnome_calendar_set_selected_time_range (day_view->calendar, - start, end); -} - - -static gboolean -e_day_view_on_top_canvas_motion (GtkWidget *widget, - GdkEventMotion *mevent, - EDayView *day_view) -{ - EDayViewEvent *event = NULL; - EDayViewPosition pos; - gint event_x, event_y, scroll_x, scroll_y, canvas_x, canvas_y; - gint day, event_num; - GdkCursor *cursor; - -#if 0 - g_print ("In e_day_view_on_top_canvas_motion\n"); -#endif - - /* Convert the coords to the main canvas window, or return if the - window is not found. */ - if (!e_day_view_convert_event_coords (day_view, (GdkEvent*) mevent, - GTK_LAYOUT (widget)->bin_window, - &event_x, &event_y)) - return FALSE; - - /* The top canvas doesn't scroll, but just in case. */ - gnome_canvas_get_scroll_offsets (GNOME_CANVAS (widget), - &scroll_x, &scroll_y); - canvas_x = event_x + scroll_x; - canvas_y = event_y + scroll_y; - - pos = e_day_view_convert_position_in_top_canvas (day_view, - canvas_x, canvas_y, - &day, &event_num); - if (event_num != -1) - event = &g_array_index (day_view->long_events, EDayViewEvent, - event_num); - - if (day_view->selection_is_being_dragged) { - e_day_view_update_selection (day_view, day, -1); - return TRUE; - } else if (day_view->resize_drag_pos != E_DAY_VIEW_POS_NONE) { - if (pos != E_DAY_VIEW_POS_OUTSIDE) { - e_day_view_update_long_event_resize (day_view, day); - return TRUE; - } - } else if (day_view->pressed_event_day == E_DAY_VIEW_LONG_EVENT) { - GtkTargetList *target_list; - - event = &g_array_index (day_view->long_events, EDayViewEvent, - day_view->pressed_event_num); - - if (!(cal_component_has_recurrences (event->comp)) - && (abs (canvas_x - day_view->drag_event_x) - > E_DAY_VIEW_DRAG_START_OFFSET - || abs (canvas_y - day_view->drag_event_y) - > E_DAY_VIEW_DRAG_START_OFFSET)) { - day_view->drag_event_day = day_view->pressed_event_day; - day_view->drag_event_num = day_view->pressed_event_num; - day_view->pressed_event_day = -1; - - /* Hide the horizontal bars. */ - if (day_view->resize_bars_event_day != -1) { - day_view->resize_bars_event_day = -1; - day_view->resize_bars_event_num = -1; - gnome_canvas_item_hide (day_view->main_canvas_top_resize_bar_item); - gnome_canvas_item_hide (day_view->main_canvas_bottom_resize_bar_item); - } - - target_list = gtk_target_list_new (target_table, - n_targets); - gtk_drag_begin (widget, target_list, - GDK_ACTION_COPY | GDK_ACTION_MOVE, - 1, (GdkEvent*)mevent); - gtk_target_list_unref (target_list); - } - } else { - cursor = day_view->normal_cursor; - - /* Recurring events can't be resized. */ - if (event && !cal_component_has_recurrences (event->comp)) { - switch (pos) { - case E_DAY_VIEW_POS_LEFT_EDGE: - case E_DAY_VIEW_POS_RIGHT_EDGE: - cursor = day_view->resize_width_cursor; - break; - default: - break; - } - } - - /* Only set the cursor if it is different to last one set. */ - if (day_view->last_cursor_set_in_top_canvas != cursor) { - day_view->last_cursor_set_in_top_canvas = cursor; - gdk_window_set_cursor (widget->window, cursor); - } - - } - - return FALSE; -} - - -static gboolean -e_day_view_on_main_canvas_motion (GtkWidget *widget, - GdkEventMotion *mevent, - EDayView *day_view) -{ - EDayViewEvent *event = NULL; - EDayViewPosition pos; - gint event_x, event_y, scroll_x, scroll_y, canvas_x, canvas_y; - gint row, day, event_num; - GdkCursor *cursor; - -#if 0 - g_print ("In e_day_view_on_main_canvas_motion\n"); -#endif - - /* Convert the coords to the main canvas window, or return if the - window is not found. */ - if (!e_day_view_convert_event_coords (day_view, (GdkEvent*) mevent, - GTK_LAYOUT (widget)->bin_window, - &event_x, &event_y)) - return FALSE; - - gnome_canvas_get_scroll_offsets (GNOME_CANVAS (widget), - &scroll_x, &scroll_y); - canvas_x = event_x + scroll_x; - canvas_y = event_y + scroll_y; - - pos = e_day_view_convert_position_in_main_canvas (day_view, - canvas_x, canvas_y, - &day, &row, - &event_num); - if (event_num != -1) - event = &g_array_index (day_view->events[day], EDayViewEvent, - event_num); - - if (day_view->selection_is_being_dragged) { - if (pos != E_DAY_VIEW_POS_OUTSIDE) { - e_day_view_update_selection (day_view, day, row); - e_day_view_check_auto_scroll (day_view, - event_x, event_y); - return TRUE; - } - } else if (day_view->resize_drag_pos != E_DAY_VIEW_POS_NONE) { - if (pos != E_DAY_VIEW_POS_OUTSIDE) { - e_day_view_update_resize (day_view, row); - e_day_view_check_auto_scroll (day_view, - event_x, event_y); - return TRUE; - } - } else if (day_view->pressed_event_day != -1 - && day_view->pressed_event_day != E_DAY_VIEW_LONG_EVENT) { - GtkTargetList *target_list; - - event = &g_array_index (day_view->events[day_view->pressed_event_day], EDayViewEvent, day_view->pressed_event_num); - - if (!cal_component_has_recurrences (event->comp) - && (abs (canvas_x - day_view->drag_event_x) - > E_DAY_VIEW_DRAG_START_OFFSET - || abs (canvas_y - day_view->drag_event_y) - > E_DAY_VIEW_DRAG_START_OFFSET)) { - day_view->drag_event_day = day_view->pressed_event_day; - day_view->drag_event_num = day_view->pressed_event_num; - day_view->pressed_event_day = -1; - - /* Hide the horizontal bars. */ - if (day_view->resize_bars_event_day != -1) { - day_view->resize_bars_event_day = -1; - day_view->resize_bars_event_num = -1; - gnome_canvas_item_hide (day_view->main_canvas_top_resize_bar_item); - gnome_canvas_item_hide (day_view->main_canvas_bottom_resize_bar_item); - } - - target_list = gtk_target_list_new (target_table, - n_targets); - gtk_drag_begin (widget, target_list, - GDK_ACTION_COPY | GDK_ACTION_MOVE, - 1, (GdkEvent*)mevent); - gtk_target_list_unref (target_list); - } - } else { - cursor = day_view->normal_cursor; - - /* Recurring events can't be resized. */ - if (event && !cal_component_has_recurrences (event->comp)) { - switch (pos) { - case E_DAY_VIEW_POS_LEFT_EDGE: - cursor = day_view->move_cursor; - break; - case E_DAY_VIEW_POS_TOP_EDGE: - case E_DAY_VIEW_POS_BOTTOM_EDGE: - cursor = day_view->resize_height_cursor; - break; - default: - break; - } - } - - /* Only set the cursor if it is different to last one set. */ - if (day_view->last_cursor_set_in_main_canvas != cursor) { - day_view->last_cursor_set_in_main_canvas = cursor; - gdk_window_set_cursor (widget->window, cursor); - } - } - - return FALSE; -} - - -/* This sets the selection to a single cell. If day is -1 then the current - start day is reused. If row is -1 then the selection is in the top canvas. -*/ -void -e_day_view_start_selection (EDayView *day_view, - gint day, - gint row) -{ - if (day == -1) { - day = day_view->selection_start_day; - if (day == -1) - day = 0; - } - - day_view->selection_start_day = day; - day_view->selection_end_day = day; - - day_view->selection_start_row = row; - day_view->selection_end_row = row; - - day_view->selection_is_being_dragged = TRUE; - day_view->selection_drag_pos = E_DAY_VIEW_DRAG_END; - day_view->selection_in_top_canvas = (row == -1) ? TRUE : FALSE; - - /* FIXME: Optimise? */ - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); -} - - -/* Updates the selection during a drag. If day is -1 the selection day is - unchanged. */ -void -e_day_view_update_selection (EDayView *day_view, - gint day, - gint row) -{ - gboolean need_redraw = FALSE; - -#if 0 - g_print ("Updating selection %i,%i\n", day, row); -#endif - - day_view->selection_in_top_canvas = (row == -1) ? TRUE : FALSE; - - if (day == -1) - day = (day_view->selection_drag_pos == E_DAY_VIEW_DRAG_START) - ? day_view->selection_start_day - : day_view->selection_end_day; - - if (day_view->selection_drag_pos == E_DAY_VIEW_DRAG_START) { - if (row != day_view->selection_start_row - || day != day_view->selection_start_day) { - need_redraw = TRUE; - day_view->selection_start_row = row; - day_view->selection_start_day = day; - } - } else { - if (row != day_view->selection_end_row - || day != day_view->selection_end_day) { - need_redraw = TRUE; - day_view->selection_end_row = row; - day_view->selection_end_day = day; - } - } - - e_day_view_normalize_selection (day_view); - - /* FIXME: Optimise? */ - if (need_redraw) { - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); - } -} - - -static void -e_day_view_normalize_selection (EDayView *day_view) -{ - gint tmp_row, tmp_day; - - /* Switch the drag position if necessary. */ - if (day_view->selection_start_day > day_view->selection_end_day - || (day_view->selection_start_day == day_view->selection_end_day - && day_view->selection_start_row > day_view->selection_end_row)) { - tmp_row = day_view->selection_start_row; - tmp_day = day_view->selection_start_day; - day_view->selection_start_day = day_view->selection_end_day; - day_view->selection_start_row = day_view->selection_end_row; - day_view->selection_end_day = tmp_day; - day_view->selection_end_row = tmp_row; - if (day_view->selection_drag_pos == E_DAY_VIEW_DRAG_START) - day_view->selection_drag_pos = E_DAY_VIEW_DRAG_END; - else - day_view->selection_drag_pos = E_DAY_VIEW_DRAG_START; - } -} - - -void -e_day_view_finish_selection (EDayView *day_view) -{ - day_view->selection_is_being_dragged = FALSE; - e_day_view_update_calendar_selection_time (day_view); -} - - -static void -e_day_view_update_long_event_resize (EDayView *day_view, - gint day) -{ - EDayViewEvent *event; - gint event_num; - gboolean need_reshape = FALSE; - -#if 0 - g_print ("Updating resize Day:%i\n", day); -#endif - - event_num = day_view->resize_event_num; - event = &g_array_index (day_view->long_events, EDayViewEvent, - event_num); - - if (day_view->resize_drag_pos == E_DAY_VIEW_POS_LEFT_EDGE) { - day = MIN (day, day_view->resize_end_row); - if (day != day_view->resize_start_row) { - need_reshape = TRUE; - day_view->resize_start_row = day; - - } - } else { - day = MAX (day, day_view->resize_start_row); - if (day != day_view->resize_end_row) { - need_reshape = TRUE; - day_view->resize_end_row = day; - } - } - - /* FIXME: Optimise? */ - if (need_reshape) { - e_day_view_reshape_long_event (day_view, event_num); - e_day_view_reshape_resize_long_event_rect_item (day_view); - gtk_widget_queue_draw (day_view->top_canvas); - } -} - - -static void -e_day_view_update_resize (EDayView *day_view, - gint row) -{ - EDayViewEvent *event; - gint day, event_num; - gboolean need_reshape = FALSE; - -#if 0 - g_print ("Updating resize Row:%i\n", row); -#endif - - day = day_view->resize_event_day; - event_num = day_view->resize_event_num; - event = &g_array_index (day_view->events[day], EDayViewEvent, - event_num); - - if (day_view->resize_drag_pos == E_DAY_VIEW_POS_TOP_EDGE) { - row = MIN (row, day_view->resize_end_row); - if (row != day_view->resize_start_row) { - need_reshape = TRUE; - day_view->resize_start_row = row; - - } - } else { - row = MAX (row, day_view->resize_start_row); - if (row != day_view->resize_end_row) { - need_reshape = TRUE; - day_view->resize_end_row = row; - } - } - - /* FIXME: Optimise? */ - if (need_reshape) { - e_day_view_reshape_day_event (day_view, day, event_num); - e_day_view_reshape_resize_rect_item (day_view); - e_day_view_reshape_main_canvas_resize_bars (day_view); - gtk_widget_queue_draw (day_view->main_canvas); - } -} - - -/* This converts the resize start or end row back to a time and updates the - event. */ -static void -e_day_view_finish_long_event_resize (EDayView *day_view) -{ - EDayViewEvent *event; - gint event_num; - CalComponent *comp; - CalComponentDateTime date; - struct icaltimetype itt; - time_t dt; - - event_num = day_view->resize_event_num; - event = &g_array_index (day_view->long_events, EDayViewEvent, - event_num); - - /* We use a temporary copy of the comp since we don't want to - change the original comp here. Otherwise we would not detect that - the event's time had changed in the "update_event" callback. */ - comp = cal_component_clone (event->comp); - - date.value = &itt; - date.tzid = NULL; - - if (day_view->resize_drag_pos == E_DAY_VIEW_POS_LEFT_EDGE) { - dt = day_view->day_starts[day_view->resize_start_row]; - *date.value = icaltime_from_timet (dt, FALSE); - cal_component_set_dtstart (comp, &date); - } else { - dt = day_view->day_starts[day_view->resize_end_row + 1]; - *date.value = icaltime_from_timet (dt, FALSE); - cal_component_set_dtend (comp, &date); - } - - gnome_canvas_item_hide (day_view->resize_long_event_rect_item); - - day_view->resize_drag_pos = E_DAY_VIEW_POS_NONE; - - if (!cal_client_update_object (day_view->client, comp)) - g_message ("e_day_view_finish_long_event_resize(): Could not update the object!"); - - gtk_object_unref (GTK_OBJECT (comp)); -} - - -/* This converts the resize start or end row back to a time and updates the - event. */ -static void -e_day_view_finish_resize (EDayView *day_view) -{ - EDayViewEvent *event; - gint day, event_num; - CalComponent *comp; - CalComponentDateTime date; - struct icaltimetype itt; - time_t dt; - - day = day_view->resize_event_day; - event_num = day_view->resize_event_num; - event = &g_array_index (day_view->events[day], EDayViewEvent, - event_num); - - /* We use a temporary shallow copy of the ico since we don't want to - change the original ico here. Otherwise we would not detect that - the event's time had changed in the "update_event" callback. */ - comp = cal_component_clone (event->comp); - - date.value = &itt; - date.tzid = NULL; - - if (day_view->resize_drag_pos == E_DAY_VIEW_POS_TOP_EDGE) { - dt = e_day_view_convert_grid_position_to_time (day_view, day, day_view->resize_start_row); - *date.value = icaltime_from_timet (dt, FALSE); - cal_component_set_dtstart (comp, &date); - } else { - dt = e_day_view_convert_grid_position_to_time (day_view, day, day_view->resize_end_row + 1); - *date.value = icaltime_from_timet (dt, FALSE); - cal_component_set_dtend (comp, &date); - } - - gnome_canvas_item_hide (day_view->resize_rect_item); - gnome_canvas_item_hide (day_view->resize_bar_item); - - /* Hide the horizontal bars. */ - day_view->resize_bars_event_day = -1; - day_view->resize_bars_event_num = -1; - gnome_canvas_item_hide (day_view->main_canvas_top_resize_bar_item); - gnome_canvas_item_hide (day_view->main_canvas_bottom_resize_bar_item); - - day_view->resize_drag_pos = E_DAY_VIEW_POS_NONE; - - if (!cal_client_update_object (day_view->client, comp)) - g_message ("e_day_view_finish_resize(): Could not update the object!"); - - gtk_object_unref (GTK_OBJECT (comp)); -} - - -static void -e_day_view_abort_resize (EDayView *day_view, - guint32 time) -{ - gint day, event_num; - - if (day_view->resize_drag_pos == E_DAY_VIEW_POS_NONE) - return; - - day_view->resize_drag_pos = E_DAY_VIEW_POS_NONE; - gdk_pointer_ungrab (time); - - day = day_view->resize_event_day; - event_num = day_view->resize_event_num; - - if (day == E_DAY_VIEW_LONG_EVENT) { - e_day_view_reshape_long_event (day_view, event_num); - gtk_widget_queue_draw (day_view->top_canvas); - - day_view->last_cursor_set_in_top_canvas = day_view->normal_cursor; - gdk_window_set_cursor (day_view->top_canvas->window, - day_view->normal_cursor); - gnome_canvas_item_hide (day_view->resize_long_event_rect_item); - } else { - e_day_view_reshape_day_event (day_view, day, event_num); - e_day_view_reshape_main_canvas_resize_bars (day_view); - gtk_widget_queue_draw (day_view->main_canvas); - - day_view->last_cursor_set_in_main_canvas = day_view->normal_cursor; - gdk_window_set_cursor (day_view->main_canvas->window, - day_view->normal_cursor); - gnome_canvas_item_hide (day_view->resize_rect_item); - gnome_canvas_item_hide (day_view->resize_bar_item); - } -} - - -/* This frees any events currently loaded, and queues a reload. */ -static void -e_day_view_queue_reload_events (EDayView *day_view) -{ - e_day_view_free_events (day_view); - - if (day_view->reload_events_idle_id == 0) { - /* We'll use a high idle priority here, so the events are - reloaded before the canvas is updated. */ - day_view->reload_events_idle_id = g_idle_add_full - (G_PRIORITY_HIGH_IDLE, - e_day_view_reload_events_idle_cb, day_view, NULL); - } -} - - -static gboolean -e_day_view_reload_events_idle_cb (gpointer data) -{ - EDayView *day_view; - - g_return_val_if_fail (E_IS_DAY_VIEW (data), FALSE); - - GDK_THREADS_ENTER (); - - day_view = E_DAY_VIEW (data); - - day_view->reload_events_idle_id = 0; - - e_day_view_reload_events (day_view); - - GDK_THREADS_LEAVE (); - return FALSE; -} - - -static void -e_day_view_reload_events (EDayView *day_view) -{ - e_day_view_free_events (day_view); - - if (!(day_view->client - && cal_client_get_load_state (day_view->client) == CAL_CLIENT_LOAD_LOADED)) - return; - - /* If both lower & upper are 0, then the time range hasn't been set, - so we don't try to load any events. */ - if (day_view->lower != 0 || day_view->upper != 0) { -#if 0 - g_print ("EDayView (%s) generating instances\n", - day_view->work_week_view ? "Work Week" : "1 Day View"); -#endif - cal_client_generate_instances (day_view->client, - CALOBJ_TYPE_EVENT, - day_view->lower, - day_view->upper, - e_day_view_add_event, - day_view); - } - - /* We need to do this to make sure the top canvas is resized. */ - day_view->long_events_need_layout = TRUE; - - e_day_view_check_layout (day_view); - e_day_view_reshape_main_canvas_resize_bars (day_view); - - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); -} - - -static void -e_day_view_free_events (EDayView *day_view) -{ - gint day; - - /* Reset all our indices. */ - day_view->editing_event_day = -1; - day_view->popup_event_day = -1; - day_view->resize_bars_event_day = -1; - day_view->resize_event_day = -1; - day_view->pressed_event_day = -1; - day_view->drag_event_day = -1; - - e_day_view_free_event_array (day_view, day_view->long_events); - - for (day = 0; day < E_DAY_VIEW_MAX_DAYS; day++) - e_day_view_free_event_array (day_view, day_view->events[day]); -} - - -static void -e_day_view_free_event_array (EDayView *day_view, - GArray *array) -{ - EDayViewEvent *event; - gint event_num; - - for (event_num = 0; event_num < array->len; event_num++) { - event = &g_array_index (array, EDayViewEvent, event_num); - if (event->canvas_item) - gtk_object_destroy (GTK_OBJECT (event->canvas_item)); - gtk_object_unref (GTK_OBJECT (event->comp)); - } - - g_array_set_size (array, 0); -} - - -/* This adds one event to the view, adding it to the appropriate array. */ -static gboolean -e_day_view_add_event (CalComponent *comp, - time_t start, - time_t end, - gpointer data) - -{ - EDayView *day_view; - EDayViewEvent event; - gint day, offset; - struct tm start_tm, end_tm; - - day_view = E_DAY_VIEW (data); - -#if 0 - g_print ("Day view lower: %s", ctime (&day_view->lower)); - g_print ("Day view upper: %s", ctime (&day_view->upper)); - g_print ("Event start: %s", ctime (&start)); - g_print ("Event end : %s\n", ctime (&end)); -#endif - - /* Check that the event times are valid. */ - g_return_val_if_fail (start <= end, TRUE); - g_return_val_if_fail (start < day_view->upper, TRUE); - g_return_val_if_fail (end > day_view->lower, TRUE); - - start_tm = *(localtime (&start)); - end_tm = *(localtime (&end)); - - event.comp = comp; - gtk_object_ref (GTK_OBJECT (comp)); - event.start = start; - event.end = end; - event.canvas_item = NULL; - - /* Calculate the start & end minute, relative to the top of the - display. */ - offset = day_view->first_hour_shown * 60 - + day_view->first_minute_shown; - event.start_minute = start_tm.tm_hour * 60 + start_tm.tm_min - offset; - event.end_minute = end_tm.tm_hour * 60 + end_tm.tm_min - offset; - - event.start_row_or_col = -1; - event.num_columns = -1; - - /* Find out which array to add the event to. */ - for (day = 0; day < day_view->days_shown; day++) { - if (start >= day_view->day_starts[day] - && end <= day_view->day_starts[day + 1]) { - - /* Special case for when the appointment ends at - midnight, i.e. the start of the next day. */ - if (end == day_view->day_starts[day + 1]) { - - /* If the event last the entire day, then we - skip it here so it gets added to the top - canvas. */ - if (start == day_view->day_starts[day]) - break; - - event.end_minute = 24 * 60; - } - - g_array_append_val (day_view->events[day], event); - day_view->events_sorted[day] = FALSE; - day_view->need_layout[day] = TRUE; - return TRUE; - } - } - - /* The event wasn't within one day so it must be a long event, - i.e. shown in the top canvas. */ - g_array_append_val (day_view->long_events, event); - day_view->long_events_sorted = FALSE; - day_view->long_events_need_layout = TRUE; - return TRUE; -} - - -/* This lays out the short (less than 1 day) events in the columns. - Any long events are simply skipped. */ -void -e_day_view_check_layout (EDayView *day_view) -{ - gint day; - - /* Don't bother if we aren't visible. */ - if (!GTK_WIDGET_VISIBLE (day_view)) - return; - - /* Make sure the events are sorted (by start and size). */ - e_day_view_ensure_events_sorted (day_view); - - for (day = 0; day < day_view->days_shown; day++) { - if (day_view->need_layout[day]) - e_day_view_layout_day_events (day_view, day); - - if (day_view->need_layout[day] - || day_view->need_reshape[day]) { - e_day_view_reshape_day_events (day_view, day); - - if (day_view->resize_bars_event_day == day) - e_day_view_reshape_main_canvas_resize_bars (day_view); - } - - day_view->need_layout[day] = FALSE; - day_view->need_reshape[day] = FALSE; - } - - if (day_view->long_events_need_layout) - e_day_view_layout_long_events (day_view); - - if (day_view->long_events_need_layout - || day_view->long_events_need_reshape) - e_day_view_reshape_long_events (day_view); - - day_view->long_events_need_layout = FALSE; - day_view->long_events_need_reshape = FALSE; -} - - -static void -e_day_view_layout_long_events (EDayView *day_view) -{ - EDayViewEvent *event; - gint event_num, old_rows_in_top_display, top_canvas_height, top_rows; - guint8 *grid; - - /* This is a temporary 2-d grid which is used to place events. - Each element is 0 if the position is empty, or 1 if occupied. - We allocate the maximum size possible here, assuming that each - event will need its own row. */ - grid = g_new0 (guint8, - day_view->long_events->len * E_DAY_VIEW_MAX_DAYS); - - /* Reset the number of rows in the top display to 0. It will be - updated as events are layed out below. */ - old_rows_in_top_display = day_view->rows_in_top_display; - day_view->rows_in_top_display = 0; - - /* Iterate over the events, finding which days they cover, and putting - them in the first free row available. */ - for (event_num = 0; event_num < day_view->long_events->len; - event_num++) { - event = &g_array_index (day_view->long_events, - EDayViewEvent, event_num); - e_day_view_layout_long_event (day_view, event, grid); - } - - /* Free the grid. */ - g_free (grid); - - /* Set the height of the top canvas based on the row height and the - number of rows needed (min 1 + 1 for the dates + 1 space for DnD).*/ - if (day_view->rows_in_top_display != old_rows_in_top_display) { - top_rows = MAX (1, day_view->rows_in_top_display); - top_canvas_height = (top_rows + 2) * day_view->top_row_height; - gtk_widget_set_usize (day_view->top_canvas, -1, - top_canvas_height); - } -} - - -static void -e_day_view_layout_long_event (EDayView *day_view, - EDayViewEvent *event, - guint8 *grid) -{ - gint start_day, end_day, free_row, day, row; - - event->num_columns = 0; - - if (!e_day_view_find_long_event_days (day_view, event, - &start_day, &end_day)) - return; - - /* Try each row until we find a free one. */ - row = 0; - do { - free_row = row; - for (day = start_day; day <= end_day; day++) { - if (grid[row * E_DAY_VIEW_MAX_DAYS + day]) { - free_row = -1; - break; - } - } - row++; - } while (free_row == -1); - - event->start_row_or_col = free_row; - event->num_columns = 1; - - /* Mark the cells as full. */ - for (day = start_day; day <= end_day; day++) { - grid[free_row * E_DAY_VIEW_MAX_DAYS + day] = 1; - } - - /* Update the number of rows in the top canvas if necessary. */ - day_view->rows_in_top_display = MAX (day_view->rows_in_top_display, - free_row + 1); -} - - -static void -e_day_view_reshape_long_events (EDayView *day_view) -{ - EDayViewEvent *event; - gint event_num; - - for (event_num = 0; event_num < day_view->long_events->len; - event_num++) { - event = &g_array_index (day_view->long_events, EDayViewEvent, - event_num); - - if (event->num_columns == 0) { - if (event->canvas_item) { - gtk_object_destroy (GTK_OBJECT (event->canvas_item)); - event->canvas_item = NULL; - } - } else { - e_day_view_reshape_long_event (day_view, event_num); - } - } -} - - -static void -e_day_view_reshape_long_event (EDayView *day_view, - gint event_num) -{ - EDayViewEvent *event; - GdkFont *font; - gint start_day, end_day, item_x, item_y, item_w, item_h; - gint text_x, text_w, num_icons, icons_width, width, time_width; - CalComponent *comp; - gint min_text_x, max_text_w, text_width, line_len; - gchar *text, *end_of_line; - gboolean show_icons = TRUE, use_max_width = FALSE; - - event = &g_array_index (day_view->long_events, EDayViewEvent, - event_num); - - if (!e_day_view_get_long_event_position (day_view, event_num, - &start_day, &end_day, - &item_x, &item_y, - &item_w, &item_h)) { - if (event->canvas_item) { - gtk_object_destroy (GTK_OBJECT (event->canvas_item)); - event->canvas_item = NULL; - } - return; - } - - /* Take off the border and padding. */ - item_x += E_DAY_VIEW_LONG_EVENT_BORDER_WIDTH + E_DAY_VIEW_LONG_EVENT_X_PAD; - item_w -= (E_DAY_VIEW_LONG_EVENT_BORDER_WIDTH + E_DAY_VIEW_LONG_EVENT_X_PAD) * 2; - item_y += E_DAY_VIEW_LONG_EVENT_BORDER_HEIGHT + E_DAY_VIEW_LONG_EVENT_Y_PAD; - item_h -= (E_DAY_VIEW_LONG_EVENT_BORDER_HEIGHT + E_DAY_VIEW_LONG_EVENT_Y_PAD) * 2; - - /* We don't show the icons while resizing, since we'd have to - draw them on top of the resize rect. Nor when editing. */ - num_icons = 0; - comp = event->comp; - font = GTK_WIDGET (day_view)->style->font; - - if (day_view->resize_drag_pos != E_DAY_VIEW_POS_NONE - && day_view->resize_event_day == E_DAY_VIEW_LONG_EVENT - && day_view->resize_event_num == event_num) - show_icons = FALSE; - - if (day_view->editing_event_day == E_DAY_VIEW_LONG_EVENT - && day_view->editing_event_num == event_num) { - show_icons = FALSE; - use_max_width = TRUE; - } - - if (show_icons) { - if (cal_component_has_alarms (comp)) - num_icons++; - if (cal_component_has_recurrences (comp)) - num_icons++; - } - - if (!event->canvas_item) { - event->canvas_item = - gnome_canvas_item_new (GNOME_CANVAS_GROUP (GNOME_CANVAS (day_view->top_canvas)->root), - e_text_get_type (), - "font_gdk", GTK_WIDGET (day_view)->style->font, - "anchor", GTK_ANCHOR_NW, - "clip", TRUE, - "max_lines", 1, - "editable", TRUE, - "use_ellipsis", TRUE, - "draw_background", FALSE, - "fill_color_rgba", GNOME_CANVAS_COLOR(0, 0, 0), - NULL); - gtk_signal_connect (GTK_OBJECT (event->canvas_item), "event", - GTK_SIGNAL_FUNC (e_day_view_on_text_item_event), - day_view); - e_day_view_update_long_event_label (day_view, event_num); - } - - /* Calculate its position. We first calculate the ideal position which - is centered with the icons. We then make sure we haven't gone off - the left edge of the available space. Finally we make sure we don't - go off the right edge. */ - icons_width = (E_DAY_VIEW_ICON_WIDTH + E_DAY_VIEW_ICON_X_PAD) - * num_icons; - time_width = e_day_view_get_time_string_width (day_view); - - if (use_max_width) { - text_x = item_x; - text_w = item_w; - } else { - /* Get the requested size of the label. */ - gtk_object_get (GTK_OBJECT (event->canvas_item), - "text", &text, - NULL); - text_width = 0; - if (text) { - end_of_line = strchr (text, '\n'); - if (end_of_line) - line_len = end_of_line - text; - else - line_len = strlen (text); - text_width = gdk_text_width (font, text, line_len); - g_free (text); - } - - width = text_width + icons_width; - text_x = item_x + (item_w - width) / 2; - - min_text_x = item_x; - if (event->start > day_view->day_starts[start_day]) - min_text_x += time_width + E_DAY_VIEW_LONG_EVENT_TIME_X_PAD; - - text_x = MAX (text_x, min_text_x); - - max_text_w = item_x + item_w - text_x; - if (event->end < day_view->day_starts[end_day + 1]) - max_text_w -= time_width + E_DAY_VIEW_LONG_EVENT_TIME_X_PAD; - - text_w = MIN (width, max_text_w); - - /* Now take out the space for the icons. */ - text_x += icons_width; - text_w -= icons_width; - } - - text_w = MAX (text_w, 0); - gnome_canvas_item_set (event->canvas_item, - "clip_width", (gdouble) text_w, - "clip_height", (gdouble) item_h, - NULL); - e_canvas_item_move_absolute(event->canvas_item, - text_x, item_y); -} - - -/* Find the start and end days for the event. */ -gboolean -e_day_view_find_long_event_days (EDayView *day_view, - EDayViewEvent *event, - gint *start_day_return, - gint *end_day_return) -{ - gint day, start_day, end_day; - - start_day = -1; - end_day = -1; - - for (day = 0; day < day_view->days_shown; day++) { - if (start_day == -1 - && event->start < day_view->day_starts[day + 1]) - start_day = day; - if (event->end > day_view->day_starts[day]) - end_day = day; - } - - /* Sanity check. */ - if (start_day < 0 || start_day >= day_view->days_shown - || end_day < 0 || end_day >= day_view->days_shown - || end_day < start_day) { - g_warning ("Invalid date range for event"); - return FALSE; - } - - *start_day_return = start_day; - *end_day_return = end_day; - - return TRUE; -} - - -static void -e_day_view_layout_day_events (EDayView *day_view, - gint day) -{ - EDayViewEvent *event; - gint row, event_num; - guint8 *grid; - - /* This is a temporary array which keeps track of rows which are - connected. When an appointment spans multiple rows then the number - of columns in each of these rows must be the same (i.e. the maximum - of all of them). Each element in the array corresponds to one row - and contains the index of the first row in the group of connected - rows. */ - guint16 group_starts[12 * 24]; - - /* Reset the cols_per_row array, and initialize the connected rows so - that all rows are not connected - each row is the start of a new - group. */ - for (row = 0; row < day_view->rows; row++) { - day_view->cols_per_row[day][row] = 0; - group_starts[row] = row; - } - - /* This is a temporary 2-d grid which is used to place events. - Each element is 0 if the position is empty, or 1 if occupied. */ - grid = g_new0 (guint8, day_view->rows * E_DAY_VIEW_MAX_COLUMNS); - - - /* Iterate over the events, finding which rows they cover, and putting - them in the first free column available. Increment the number of - events in each of the rows it covers, and make sure they are all - in one group. */ - for (event_num = 0; event_num < day_view->events[day]->len; - event_num++) { - event = &g_array_index (day_view->events[day], EDayViewEvent, - event_num); - - e_day_view_layout_day_event (day_view, day, event, - grid, group_starts); - } - - /* Recalculate the number of columns needed in each row. */ - e_day_view_recalc_cols_per_row (day_view, day, group_starts); - - /* Iterate over the events again, trying to expand events horizontally - if there is enough space. */ - for (event_num = 0; event_num < day_view->events[day]->len; - event_num++) { - event = &g_array_index (day_view->events[day], EDayViewEvent, - event_num); - e_day_view_expand_day_event (day_view, day, event, grid); - } - - /* Free the grid. */ - g_free (grid); -} - - -/* Finds the first free position to place the event in. - Increments the number of events in each of the rows it covers, and makes - sure they are all in one group. */ -static void -e_day_view_layout_day_event (EDayView *day_view, - gint day, - EDayViewEvent *event, - guint8 *grid, - guint16 *group_starts) -{ - gint start_row, end_row, free_col, col, row, group_start; - - start_row = event->start_minute / day_view->mins_per_row; - end_row = (event->end_minute - 1) / day_view->mins_per_row; - - event->num_columns = 0; - - /* If the event can't currently be seen, just return. */ - if (start_row >= day_view->rows || end_row < 0) - return; - - /* Make sure we don't go outside the visible times. */ - start_row = CLAMP (start_row, 0, day_view->rows - 1); - end_row = CLAMP (end_row, 0, day_view->rows - 1); - - /* Try each column until we find a free one. */ - for (col = 0; col < E_DAY_VIEW_MAX_COLUMNS; col++) { - free_col = col; - for (row = start_row; row <= end_row; row++) { - if (grid[row * E_DAY_VIEW_MAX_COLUMNS + col]) { - free_col = -1; - break; - } - } - - if (free_col != -1) - break; - } - - /* If we can't find space for the event, just return. */ - if (free_col == -1) - return; - - /* The event is assigned 1 col initially, but may be expanded later. */ - event->start_row_or_col = free_col; - event->num_columns = 1; - - /* Determine the start index of the group. */ - group_start = group_starts[start_row]; - - /* Increment number of events in each of the rows the event covers. - We use the cols_per_row array for this. It will be sorted out after - all the events have been layed out. Also make sure all the rows that - the event covers are in one group. */ - for (row = start_row; row <= end_row; row++) { - grid[row * E_DAY_VIEW_MAX_COLUMNS + free_col] = 1; - day_view->cols_per_row[day][row]++; - group_starts[row] = group_start; - } - - /* If any following rows should be in the same group, add them. */ - for (row = end_row + 1; row < day_view->rows; row++) { - if (group_starts[row] > end_row) - break; - group_starts[row] = group_start; - } -} - - -/* For each group of rows, find the max number of events in all the - rows, and set the number of cols in each of the rows to that. */ -static void -e_day_view_recalc_cols_per_row (EDayView *day_view, - gint day, - guint16 *group_starts) -{ - gint start_row = 0, row, next_start_row, max_events; - - while (start_row < day_view->rows) { - - max_events = 0; - for (row = start_row; row < day_view->rows && group_starts[row] == start_row; row++) - max_events = MAX (max_events, day_view->cols_per_row[day][row]); - - next_start_row = row; - - for (row = start_row; row < next_start_row; row++) - day_view->cols_per_row[day][row] = max_events; - - start_row = next_start_row; - } -} - - -/* Expands the event horizontally to fill any free space. */ -static void -e_day_view_expand_day_event (EDayView *day_view, - gint day, - EDayViewEvent *event, - guint8 *grid) -{ - gint start_row, end_row, col, row; - gboolean clashed; - - start_row = event->start_minute / day_view->mins_per_row; - end_row = (event->end_minute - 1) / day_view->mins_per_row; - - /* Try each column until we find a free one. */ - clashed = FALSE; - for (col = event->start_row_or_col + 1; col < day_view->cols_per_row[day][start_row]; col++) { - for (row = start_row; row <= end_row; row++) { - if (grid[row * E_DAY_VIEW_MAX_COLUMNS + col]) { - clashed = TRUE; - break; - } - } - - if (clashed) - break; - - event->num_columns++; - } -} - - -/* This creates or updates the sizes of the canvas items for one day of the - main canvas. */ -static void -e_day_view_reshape_day_events (EDayView *day_view, - gint day) -{ - gint event_num; - - for (event_num = 0; event_num < day_view->events[day]->len; - event_num++) { - e_day_view_reshape_day_event (day_view, day, event_num); - } -} - - -static void -e_day_view_reshape_day_event (EDayView *day_view, - gint day, - gint event_num) -{ - EDayViewEvent *event; - gint item_x, item_y, item_w, item_h; - gint num_icons, icons_offset; - CalComponent *comp; - - event = &g_array_index (day_view->events[day], EDayViewEvent, - event_num); - comp = event->comp; - - if (!e_day_view_get_event_position (day_view, day, event_num, - &item_x, &item_y, - &item_w, &item_h)) { - if (event->canvas_item) { - gtk_object_destroy (GTK_OBJECT (event->canvas_item)); - event->canvas_item = NULL; - } - } else { - /* Skip the border and padding. */ - item_x += E_DAY_VIEW_BAR_WIDTH + E_DAY_VIEW_EVENT_X_PAD; - item_w -= E_DAY_VIEW_BAR_WIDTH + E_DAY_VIEW_EVENT_X_PAD * 2; - item_y += E_DAY_VIEW_EVENT_BORDER_HEIGHT + E_DAY_VIEW_EVENT_Y_PAD; - item_h -= (E_DAY_VIEW_EVENT_BORDER_HEIGHT + E_DAY_VIEW_EVENT_Y_PAD) * 2; - - /* We don't show the icons while resizing, since we'd have to - draw them on top of the resize rect. */ - num_icons = 0; - if (day_view->resize_drag_pos == E_DAY_VIEW_POS_NONE - || day_view->resize_event_day != day - || day_view->resize_event_num != event_num) { - if (cal_component_has_alarms (comp)) - num_icons++; - if (cal_component_has_recurrences (comp)) - num_icons++; - } - - if (num_icons > 0) { - if (item_h >= (E_DAY_VIEW_ICON_HEIGHT + E_DAY_VIEW_ICON_Y_PAD) * num_icons) - icons_offset = E_DAY_VIEW_ICON_WIDTH + E_DAY_VIEW_ICON_X_PAD * 2; - else - icons_offset = (E_DAY_VIEW_ICON_WIDTH + E_DAY_VIEW_ICON_X_PAD) * num_icons + E_DAY_VIEW_ICON_X_PAD; - item_x += icons_offset; - item_w -= icons_offset; - } - - if (!event->canvas_item) { - event->canvas_item = - gnome_canvas_item_new (GNOME_CANVAS_GROUP (GNOME_CANVAS (day_view->main_canvas)->root), - e_text_get_type (), - "font_gdk", GTK_WIDGET (day_view)->style->font, - "anchor", GTK_ANCHOR_NW, - "line_wrap", TRUE, - "editable", TRUE, - "clip", TRUE, - "use_ellipsis", TRUE, - "draw_background", FALSE, - "fill_color_rgba", GNOME_CANVAS_COLOR(0, 0, 0), - NULL); - gtk_signal_connect (GTK_OBJECT (event->canvas_item), - "event", - GTK_SIGNAL_FUNC (e_day_view_on_text_item_event), - day_view); - e_day_view_update_event_label (day_view, day, - event_num); - } - - item_w = MAX (item_w, 0); - gnome_canvas_item_set (event->canvas_item, - "clip_width", (gdouble) item_w, - "clip_height", (gdouble) item_h, - NULL); - e_canvas_item_move_absolute(event->canvas_item, - item_x, item_y); - } -} - - -/* This creates or resizes the horizontal bars used to resize events in the - main canvas. */ -static void -e_day_view_reshape_main_canvas_resize_bars (EDayView *day_view) -{ - gint day, event_num; - gint item_x, item_y, item_w, item_h; - gdouble x, y, w, h; - - day = day_view->resize_bars_event_day; - event_num = day_view->resize_bars_event_num; - - /* If we're not editing an event, or the event is not shown, - hide the resize bars. */ - if (day != -1 && day == day_view->drag_event_day - && event_num == day_view->drag_event_num) { - gtk_object_get (GTK_OBJECT (day_view->drag_rect_item), - "x1", &x, - "y1", &y, - "x2", &w, - "y2", &h, - NULL); - w -= x; - x++; - h -= y; - } else if (day != -1 - && e_day_view_get_event_position (day_view, day, event_num, - &item_x, &item_y, - &item_w, &item_h)) { - x = item_x + E_DAY_VIEW_BAR_WIDTH; - y = item_y; - w = item_w - E_DAY_VIEW_BAR_WIDTH; - h = item_h; - } else { - gnome_canvas_item_hide (day_view->main_canvas_top_resize_bar_item); - gnome_canvas_item_hide (day_view->main_canvas_bottom_resize_bar_item); - return; - } - - gnome_canvas_item_set (day_view->main_canvas_top_resize_bar_item, - "x1", x - E_DAY_VIEW_BAR_WIDTH, - "y1", y - E_DAY_VIEW_BAR_HEIGHT, - "x2", x + w - 1, - "y2", y - 1, - NULL); - gnome_canvas_item_show (day_view->main_canvas_top_resize_bar_item); - - gnome_canvas_item_set (day_view->main_canvas_bottom_resize_bar_item, - "x1", x - E_DAY_VIEW_BAR_WIDTH, - "y1", y + h, - "x2", x + w - 1, - "y2", y + h + E_DAY_VIEW_BAR_HEIGHT - 1, - NULL); - gnome_canvas_item_show (day_view->main_canvas_bottom_resize_bar_item); -} - - -static void -e_day_view_ensure_events_sorted (EDayView *day_view) -{ - gint day; - - /* Sort the long events. */ - if (!day_view->long_events_sorted) { - qsort (day_view->long_events->data, - day_view->long_events->len, - sizeof (EDayViewEvent), - e_day_view_event_sort_func); - day_view->long_events_sorted = TRUE; - } - - /* Sort the events for each day. */ - for (day = 0; day < day_view->days_shown; day++) { - if (!day_view->events_sorted[day]) { - qsort (day_view->events[day]->data, - day_view->events[day]->len, - sizeof (EDayViewEvent), - e_day_view_event_sort_func); - day_view->events_sorted[day] = TRUE; - } - } -} - - -static gint -e_day_view_event_sort_func (const void *arg1, - const void *arg2) -{ - EDayViewEvent *event1, *event2; - - event1 = (EDayViewEvent*) arg1; - event2 = (EDayViewEvent*) arg2; - - if (event1->start < event2->start) - return -1; - if (event1->start > event2->start) - return 1; - - if (event1->end > event2->end) - return -1; - if (event1->end < event2->end) - return 1; - - return 0; -} - - -static gint -e_day_view_key_press (GtkWidget *widget, GdkEventKey *event) -{ - EDayView *day_view; - CalComponent *comp; - gint day, event_num; - gchar *initial_text; - guint keyval; - gboolean stop_emission; - time_t dtstart, dtend; - CalComponentDateTime dt; - struct icaltimetype itt; - const char *uid; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (E_IS_DAY_VIEW (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - day_view = E_DAY_VIEW (widget); - keyval = event->keyval; - - /* The Escape key aborts a resize operation. */ - if (day_view->resize_drag_pos != E_DAY_VIEW_POS_NONE) { - if (keyval == GDK_Escape) { - e_day_view_abort_resize (day_view, event->time); - } - return FALSE; - } - - /* Handle the cursor keys for moving & extending the selection. */ - stop_emission = TRUE; - if (event->state & GDK_SHIFT_MASK) { - switch (keyval) { - case GDK_Up: - e_day_view_cursor_key_up_shifted (day_view, event); - break; - case GDK_Down: - e_day_view_cursor_key_down_shifted (day_view, event); - break; - case GDK_Left: - e_day_view_cursor_key_left_shifted (day_view, event); - break; - case GDK_Right: - e_day_view_cursor_key_right_shifted (day_view, event); - break; - default: - stop_emission = FALSE; - break; - } - } else { - switch (keyval) { - case GDK_Up: - e_day_view_cursor_key_up (day_view, event); - break; - case GDK_Down: - e_day_view_cursor_key_down (day_view, event); - break; - case GDK_Left: - e_day_view_cursor_key_left (day_view, event); - break; - case GDK_Right: - e_day_view_cursor_key_right (day_view, event); - break; - case GDK_Page_Up: - e_day_view_scroll (day_view, E_DAY_VIEW_PAGE_STEP); - break; - case GDK_Page_Down: - e_day_view_scroll (day_view, -E_DAY_VIEW_PAGE_STEP); - break; - default: - stop_emission = FALSE; - break; - } - } - if (stop_emission) - return TRUE; - - if (day_view->selection_start_day == -1) - return FALSE; - - /* Check if there is room for a new event to be typed in. If there - isn't we don't want to add an event as we will then add a new - event for every key press. */ - if (!e_day_view_check_if_new_event_fits (day_view)) { - return FALSE; - } - - /* We only want to start an edit with a return key or a simple - character. */ - if (keyval == GDK_Return) { - initial_text = NULL; - } else if ((keyval < 0x20) - || (keyval > 0xFF) - || (event->length == 0) - || (event->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK))) { - return FALSE; - } else { - initial_text = event->string; - } - - /* Add a new event covering the selected range */ - - comp = cal_component_new (); - cal_component_set_new_vtype (comp, CAL_COMPONENT_EVENT); - - e_day_view_get_selected_time_range (day_view, &dtstart, &dtend); - - dt.value = &itt; - dt.tzid = NULL; - - *dt.value = icaltime_from_timet (dtstart, FALSE); - cal_component_set_dtstart (comp, &dt); - - *dt.value = icaltime_from_timet (dtend, FALSE); - cal_component_set_dtend (comp, &dt); - - /* We add the event locally and start editing it. When we get the - "update_event" callback from the server, we basically ignore it. - If we were to wait for the "update_event" callback it wouldn't be - as responsive and we may lose a few keystrokes. */ - e_day_view_add_event (comp, dtstart, dtend, day_view); - e_day_view_check_layout (day_view); - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); - - cal_component_get_uid (comp, &uid); - if (e_day_view_find_event_from_uid (day_view, uid, &day, &event_num)) { - e_day_view_start_editing_event (day_view, day, event_num, - initial_text); - } else { - g_warning ("Couldn't find event to start editing.\n"); - } - - gtk_object_unref (GTK_OBJECT (comp)); - - return TRUE; -} - - -static void -e_day_view_cursor_key_up_shifted (EDayView *day_view, GdkEventKey *event) -{ - gint *row; - - if (day_view->selection_in_top_canvas) - return; - - if (day_view->selection_drag_pos == E_DAY_VIEW_DRAG_START) - row = &day_view->selection_start_row; - else - row = &day_view->selection_end_row; - - if (*row == 0) - return; - - *row = *row - 1; - - e_day_view_ensure_rows_visible (day_view, *row, *row); - - e_day_view_normalize_selection (day_view); - - e_day_view_update_calendar_selection_time (day_view); - - /* FIXME: Optimise? */ - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); -} - - -static void -e_day_view_cursor_key_down_shifted (EDayView *day_view, GdkEventKey *event) -{ - gint *row; - - if (day_view->selection_in_top_canvas) - return; - - if (day_view->selection_drag_pos == E_DAY_VIEW_DRAG_START) - row = &day_view->selection_start_row; - else - row = &day_view->selection_end_row; - - if (*row >= day_view->rows - 1) - return; - - *row = *row + 1; - - e_day_view_ensure_rows_visible (day_view, *row, *row); - - e_day_view_normalize_selection (day_view); - - e_day_view_update_calendar_selection_time (day_view); - - /* FIXME: Optimise? */ - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); -} - - -static void -e_day_view_cursor_key_left_shifted (EDayView *day_view, GdkEventKey *event) -{ - gint *day; - - if (day_view->selection_drag_pos == E_DAY_VIEW_DRAG_START) - day = &day_view->selection_start_day; - else - day = &day_view->selection_end_day; - - if (*day == 0) - return; - - *day = *day - 1; - - e_day_view_normalize_selection (day_view); - - e_day_view_update_calendar_selection_time (day_view); - - /* FIXME: Optimise? */ - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); -} - - -static void -e_day_view_cursor_key_right_shifted (EDayView *day_view, GdkEventKey *event) -{ - gint *day; - - if (day_view->selection_drag_pos == E_DAY_VIEW_DRAG_START) - day = &day_view->selection_start_day; - else - day = &day_view->selection_end_day; - - if (*day >= day_view->days_shown - 1) - return; - - *day = *day + 1; - - e_day_view_normalize_selection (day_view); - - e_day_view_update_calendar_selection_time (day_view); - - /* FIXME: Optimise? */ - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); -} - - -static void -e_day_view_cursor_key_up (EDayView *day_view, GdkEventKey *event) -{ - if (day_view->selection_start_day == -1) { - day_view->selection_start_day = 0; - day_view->selection_start_row = 0; - } - day_view->selection_end_day = day_view->selection_start_day; - - if (day_view->selection_in_top_canvas) { - return; - } else if (day_view->selection_start_row == 0) { - day_view->selection_in_top_canvas = TRUE; - day_view->selection_start_row = -1; - } else { - day_view->selection_start_row--; - } - day_view->selection_end_row = day_view->selection_start_row; - - if (!day_view->selection_in_top_canvas) - e_day_view_ensure_rows_visible (day_view, - day_view->selection_start_row, - day_view->selection_end_row); - - e_day_view_update_calendar_selection_time (day_view); - - /* FIXME: Optimise? */ - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); -} - - -static void -e_day_view_cursor_key_down (EDayView *day_view, GdkEventKey *event) -{ - if (day_view->selection_start_day == -1) { - day_view->selection_start_day = 0; - day_view->selection_start_row = 0; - } - day_view->selection_end_day = day_view->selection_start_day; - - if (day_view->selection_in_top_canvas) { - day_view->selection_in_top_canvas = FALSE; - day_view->selection_start_row = 0; - } else if (day_view->selection_start_row >= day_view->rows - 1) { - return; - } else { - day_view->selection_start_row++; - } - day_view->selection_end_row = day_view->selection_start_row; - - if (!day_view->selection_in_top_canvas) - e_day_view_ensure_rows_visible (day_view, - day_view->selection_start_row, - day_view->selection_end_row); - - e_day_view_update_calendar_selection_time (day_view); - - /* FIXME: Optimise? */ - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); -} - - -static void -e_day_view_cursor_key_left (EDayView *day_view, GdkEventKey *event) -{ - if (day_view->selection_start_day == 0) { - if (day_view->calendar) - gnome_calendar_previous (day_view->calendar); - } else { - day_view->selection_start_day--; - day_view->selection_end_day--; - - e_day_view_update_calendar_selection_time (day_view); - - /* FIXME: Optimise? */ - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); - } -} - - -static void -e_day_view_cursor_key_right (EDayView *day_view, GdkEventKey *event) -{ - if (day_view->selection_end_day == day_view->days_shown - 1) { - if (day_view->calendar) - gnome_calendar_next (day_view->calendar); - } else { - day_view->selection_start_day++; - day_view->selection_end_day++; - - e_day_view_update_calendar_selection_time (day_view); - - /* FIXME: Optimise? */ - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); - } -} - - -/* Scrolls the main canvas up or down. The pages_to_scroll argument - is multiplied with the adjustment's page size and added to the adjustment's - value, while ensuring we stay within the bounds. A positive value will - scroll the canvas down and a negative value will scroll it up. */ -static void -e_day_view_scroll (EDayView *day_view, - gfloat pages_to_scroll) -{ - GtkAdjustment *adj = GTK_LAYOUT (day_view->main_canvas)->vadjustment; - gfloat new_value; - - new_value = adj->value - adj->page_size * pages_to_scroll; - new_value = CLAMP (new_value, adj->lower, adj->upper - adj->page_size); - gtk_adjustment_set_value (adj, new_value); -} - - -static gboolean -e_day_view_check_if_new_event_fits (EDayView *day_view) -{ - gint day, start_row, end_row, row; - - day = day_view->selection_start_day; - start_row = day_view->selection_start_row; - end_row = day_view->selection_end_row; - - /* Long events always fit, since we keep adding rows to the top - canvas. */ - if (day != day_view->selection_end_day) - return TRUE; - if (start_row == 0 && end_row == day_view->rows) - return TRUE; - - /* If any of the rows already have E_DAY_VIEW_MAX_COLUMNS columns, - return FALSE. */ - for (row = start_row; row <= end_row; row++) { - if (day_view->cols_per_row[day][row] >= E_DAY_VIEW_MAX_COLUMNS) - return FALSE; - } - - return TRUE; -} - - -static void -e_day_view_ensure_rows_visible (EDayView *day_view, - gint start_row, - gint end_row) -{ - GtkAdjustment *adj; - gfloat value, min_value, max_value; - - adj = GTK_LAYOUT (day_view->main_canvas)->vadjustment; - - value = adj->value; - - min_value = (end_row + 1) * day_view->row_height - adj->page_size; - if (value < min_value) - value = min_value; - - max_value = start_row * day_view->row_height; - if (value > max_value) - value = max_value; - - if (value != adj->value) { - adj->value = value; - gtk_adjustment_value_changed (adj); - } -} - - -static void -e_day_view_start_editing_event (EDayView *day_view, - gint day, - gint event_num, - gchar *initial_text) -{ - EDayViewEvent *event; - ETextEventProcessor *event_processor = NULL; - ETextEventProcessorCommand command; - -#if 0 - g_print ("In e_day_view_start_editing_event\n"); -#endif - - /* If we are already editing the event, just return. */ - if (day == day_view->editing_event_day - && event_num == day_view->editing_event_num) - return; - - if (day == E_DAY_VIEW_LONG_EVENT) { - event = &g_array_index (day_view->long_events, EDayViewEvent, - event_num); - } else { - event = &g_array_index (day_view->events[day], EDayViewEvent, - event_num); - } - - /* If the event is not shown, don't try to edit it. */ - if (!event->canvas_item) - return; - - /* We must grab the focus before setting the initial text, since - grabbing the focus will result in a call to - e_day_view_on_editing_started(), which will reset the text to get - rid of the start and end times. */ - e_canvas_item_grab_focus (event->canvas_item); - - if (initial_text) { - gnome_canvas_item_set (event->canvas_item, - "text", initial_text, - NULL); - } - - /* Try to move the cursor to the end of the text. */ - gtk_object_get (GTK_OBJECT (event->canvas_item), - "event_processor", &event_processor, - NULL); - if (event_processor) { - command.action = E_TEP_MOVE; - command.position = E_TEP_END_OF_BUFFER; - gtk_signal_emit_by_name (GTK_OBJECT (event_processor), - "command", &command); - } -} - - -/* This stops the current edit. If accept is TRUE the event summary is update, - else the edit is cancelled. */ -static void -e_day_view_stop_editing_event (EDayView *day_view) -{ - GtkWidget *toplevel; - - /* Check we are editing an event. */ - if (day_view->editing_event_day == -1) - return; - - /* Set focus to the toplevel so the item loses focus. */ - toplevel = gtk_widget_get_toplevel (GTK_WIDGET (day_view)); - if (toplevel && GTK_IS_WINDOW (toplevel)) - gtk_window_set_focus (GTK_WINDOW (toplevel), NULL); -} - - -static gboolean -e_day_view_on_text_item_event (GnomeCanvasItem *item, - GdkEvent *event, - EDayView *day_view) -{ - switch (event->type) { - case GDK_KEY_PRESS: - if (event && event->key.keyval == GDK_Return) { - /* We set the keyboard focus to the EDayView, so the - EText item loses it and stops the edit. */ - gtk_widget_grab_focus (GTK_WIDGET (day_view)); - - /* Stop the signal last or we will also stop any - other events getting to the EText item. */ - gtk_signal_emit_stop_by_name (GTK_OBJECT (item), - "event"); - return TRUE; - } - break; - case GDK_BUTTON_PRESS: - case GDK_BUTTON_RELEASE: - /* Only let the EText handle the event while editing. */ - if (!E_TEXT (item)->editing) - gtk_signal_emit_stop_by_name (GTK_OBJECT (item), - "event"); - break; - case GDK_FOCUS_CHANGE: - if (event->focus_change.in) - e_day_view_on_editing_started (day_view, item); - else - e_day_view_on_editing_stopped (day_view, item); - - return FALSE; - default: - break; - } - - return FALSE; -} - - -static void -e_day_view_on_editing_started (EDayView *day_view, - GnomeCanvasItem *item) -{ - gint day, event_num; - - if (!e_day_view_find_event_from_item (day_view, item, - &day, &event_num)) - return; - -#if 0 - g_print ("In e_day_view_on_editing_started Day:%i Event:%i\n", - day, event_num); -#endif - - /* FIXME: This is a temporary workaround for a bug which seems to stop - us getting focus_out signals. It is not a complete fix since if we - don't get focus_out signals we don't save the appointment text so - this may be lost. */ - if (day_view->editing_event_day == day - && day_view->editing_event_num == event_num) - return; - - day_view->editing_event_day = day; - day_view->editing_event_num = event_num; - - if (day == E_DAY_VIEW_LONG_EVENT) { - e_day_view_reshape_long_event (day_view, event_num); - } else { - day_view->resize_bars_event_day = day; - day_view->resize_bars_event_num = event_num; - e_day_view_update_event_label (day_view, day, event_num); - e_day_view_reshape_main_canvas_resize_bars (day_view); - } -} - - -static void -e_day_view_on_editing_stopped (EDayView *day_view, - GnomeCanvasItem *item) -{ - gint day, event_num; - gboolean editing_long_event = FALSE; - EDayViewEvent *event; - gchar *text = NULL; - CalComponentText summary; - - /* 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. */ - day = day_view->editing_event_day; - event_num = day_view->editing_event_num; - -#if 0 - g_print ("In e_day_view_on_editing_stopped Day:%i Event:%i\n", - day, event_num); -#endif - - /* If no item is being edited, just return. */ - if (day == -1) - return; - - if (day == E_DAY_VIEW_LONG_EVENT) { - editing_long_event = TRUE; - event = &g_array_index (day_view->long_events, EDayViewEvent, - event_num); - } else { - event = &g_array_index (day_view->events[day], EDayViewEvent, - event_num); - - /* Hide the horizontal bars. */ - gnome_canvas_item_hide (day_view->main_canvas_top_resize_bar_item); - gnome_canvas_item_hide (day_view->main_canvas_bottom_resize_bar_item); - } - - /* Reset the edit fields. */ - day_view->editing_event_day = -1; - day_view->editing_event_num = -1; - - day_view->resize_bars_event_day = -1; - day_view->resize_bars_event_num = -1; - - gtk_object_get (GTK_OBJECT (event->canvas_item), - "text", &text, - NULL); - - /* Only update the summary if necessary. */ - cal_component_get_summary (event->comp, &summary); - if (text && summary.value && !strcmp (text, summary.value)) { - g_free (text); - - if (day == E_DAY_VIEW_LONG_EVENT) - e_day_view_reshape_long_event (day_view, event_num); - return; - } - - if (text) { - summary.value = text; - summary.altrep = NULL; - cal_component_set_summary (event->comp, &summary); - - g_free (text); - } else - cal_component_set_summary (event->comp, NULL); - - if (!cal_client_update_object (day_view->client, event->comp)) - g_message ("e_day_view_on_editing_stopped(): Could not update the object!"); -} - - -/* FIXME: It is possible that we may produce an invalid time due to daylight - saving times (i.e. when clocks go forward there is a range of time which - is not valid). I don't know the best way to handle daylight saving time. */ -static time_t -e_day_view_convert_grid_position_to_time (EDayView *day_view, - gint col, - gint row) -{ - struct tm *tmp_tm; - time_t val; - gint minutes; - - /* Calulate the number of minutes since the start of the day. */ - minutes = day_view->first_hour_shown * 60 - + day_view->first_minute_shown - + row * day_view->mins_per_row; - - /* A special case for midnight, where we can use the start of the - next day. */ - if (minutes == 60 * 24) - return day_view->day_starts[col + 1]; - - /* We convert the start of the day to a struct tm, then set the - hour and minute, then convert it back to a time_t. */ - tmp_tm = localtime (&day_view->day_starts[col]); - - tmp_tm->tm_hour = minutes / 60; - tmp_tm->tm_min = minutes % 60; - tmp_tm->tm_isdst = -1; - - val = mktime (tmp_tm); - return val; -} - - -static gboolean -e_day_view_convert_time_to_grid_position (EDayView *day_view, - time_t time, - gint *col, - gint *row) -{ - struct tm *tmp_tm; - gint day, minutes; - - *col = *row = 0; - - if (time < day_view->lower || time >= day_view->upper) - return FALSE; - - /* We can find the column easily using the day_starts array. */ - for (day = 1; day <= day_view->days_shown; day++) { - if (time < day_view->day_starts[day]) { - *col = day - 1; - break; - } - } - - /* To find the row we need to convert the time to a struct tm, - calculate the offset in minutes from the top of the display and - divide it by the mins per row setting. */ - tmp_tm = localtime (&time); - minutes = tmp_tm->tm_hour * 60 + tmp_tm->tm_min; - minutes -= day_view->first_hour_shown * 60 - + day_view->first_minute_shown; - - *row = minutes / day_view->mins_per_row; - - if (*row < 0 || *row >= day_view->rows) - return FALSE; - - return TRUE; -} - - -/* This starts or stops auto-scrolling when dragging a selection or resizing - an event. */ -void -e_day_view_check_auto_scroll (EDayView *day_view, - gint event_x, - gint event_y) -{ - day_view->last_mouse_x = event_x; - day_view->last_mouse_y = event_y; - - if (event_y < E_DAY_VIEW_AUTO_SCROLL_OFFSET) - e_day_view_start_auto_scroll (day_view, TRUE); - else if (event_y >= day_view->main_canvas->allocation.height - - E_DAY_VIEW_AUTO_SCROLL_OFFSET) - e_day_view_start_auto_scroll (day_view, FALSE); - else - e_day_view_stop_auto_scroll (day_view); -} - - -static void -e_day_view_start_auto_scroll (EDayView *day_view, - gboolean scroll_up) -{ - if (day_view->auto_scroll_timeout_id == 0) { - day_view->auto_scroll_timeout_id = g_timeout_add (E_DAY_VIEW_AUTO_SCROLL_TIMEOUT, e_day_view_auto_scroll_handler, day_view); - day_view->auto_scroll_delay = E_DAY_VIEW_AUTO_SCROLL_DELAY; - } - day_view->auto_scroll_up = scroll_up; -} - - -void -e_day_view_stop_auto_scroll (EDayView *day_view) -{ - if (day_view->auto_scroll_timeout_id != 0) { - gtk_timeout_remove (day_view->auto_scroll_timeout_id); - day_view->auto_scroll_timeout_id = 0; - } -} - - -static gboolean -e_day_view_auto_scroll_handler (gpointer data) -{ - EDayView *day_view; - EDayViewPosition pos; - gint scroll_x, scroll_y, new_scroll_y, canvas_x, canvas_y, row, day; - GtkAdjustment *adj; - - g_return_val_if_fail (E_IS_DAY_VIEW (data), FALSE); - - day_view = E_DAY_VIEW (data); - - GDK_THREADS_ENTER (); - - if (day_view->auto_scroll_delay > 0) { - day_view->auto_scroll_delay--; - GDK_THREADS_LEAVE (); - return TRUE; - } - - gnome_canvas_get_scroll_offsets (GNOME_CANVAS (day_view->main_canvas), - &scroll_x, &scroll_y); - - adj = GTK_LAYOUT (day_view->main_canvas)->vadjustment; - - if (day_view->auto_scroll_up) - new_scroll_y = MAX (scroll_y - adj->step_increment, 0); - else - new_scroll_y = MIN (scroll_y + adj->step_increment, - adj->upper - adj->page_size); - - if (new_scroll_y != scroll_y) { - /* NOTE: This reduces flicker, but only works if we don't use - canvas items which have X windows. */ - gtk_layout_freeze (GTK_LAYOUT (day_view->main_canvas)); - - gnome_canvas_scroll_to (GNOME_CANVAS (day_view->main_canvas), - scroll_x, new_scroll_y); - - gtk_layout_thaw (GTK_LAYOUT (day_view->main_canvas)); - } - - canvas_x = day_view->last_mouse_x + scroll_x; - canvas_y = day_view->last_mouse_y + new_scroll_y; - - /* The last_mouse_x position is set to -1 when we are selecting using - the time column. In this case we set canvas_x to 0 and we ignore - the resulting day. */ - if (day_view->last_mouse_x == -1) - canvas_x = 0; - - /* Update the selection/resize/drag if necessary. */ - pos = e_day_view_convert_position_in_main_canvas (day_view, - canvas_x, canvas_y, - &day, &row, NULL); - - if (day_view->last_mouse_x == -1) - day = -1; - - if (pos != E_DAY_VIEW_POS_OUTSIDE) { - if (day_view->selection_is_being_dragged) { - e_day_view_update_selection (day_view, day, row); - } else if (day_view->resize_drag_pos != E_DAY_VIEW_POS_NONE) { - e_day_view_update_resize (day_view, row); - } else if (day_view->drag_item->object.flags - & GNOME_CANVAS_ITEM_VISIBLE) { - e_day_view_update_main_canvas_drag (day_view, row, - day); - } - } - - GDK_THREADS_LEAVE (); - return TRUE; -} - - -gboolean -e_day_view_get_event_position (EDayView *day_view, - gint day, - gint event_num, - gint *item_x, - gint *item_y, - gint *item_w, - gint *item_h) -{ - EDayViewEvent *event; - gint start_row, end_row, cols_in_row, start_col, num_columns; - - event = &g_array_index (day_view->events[day], EDayViewEvent, - event_num); - - /* If the event is flagged as not displayed, return FALSE. */ - if (event->num_columns == 0) - return FALSE; - - start_row = event->start_minute / day_view->mins_per_row; - end_row = (event->end_minute - 1) / day_view->mins_per_row; - cols_in_row = day_view->cols_per_row[day][start_row]; - start_col = event->start_row_or_col; - num_columns = event->num_columns; - - if (cols_in_row == 0) - return FALSE; - - /* If the event is being resize, use the resize position. */ - if (day_view->resize_drag_pos != E_DAY_VIEW_POS_NONE - && day_view->resize_event_day == day - && day_view->resize_event_num == event_num) { - if (day_view->resize_drag_pos == E_DAY_VIEW_POS_TOP_EDGE) - start_row = day_view->resize_start_row; - else if (day_view->resize_drag_pos == E_DAY_VIEW_POS_BOTTOM_EDGE) - end_row = day_view->resize_end_row; - } - - - *item_x = day_view->day_offsets[day] - + day_view->day_widths[day] * start_col / cols_in_row; - *item_w = day_view->day_widths[day] * num_columns / cols_in_row - - E_DAY_VIEW_GAP_WIDTH; - *item_w = MAX (*item_w, 0); - *item_y = start_row * day_view->row_height; -#if 0 - *item_h = (end_row - start_row + 1) * day_view->row_height; -#else - /* This makes the event end on the grid line of the next row, - which maybe looks nicer if you have 2 events on consecutive rows. */ - *item_h = (end_row - start_row + 1) * day_view->row_height + 1; -#endif - return TRUE; -} - - -gboolean -e_day_view_get_long_event_position (EDayView *day_view, - gint event_num, - gint *start_day, - gint *end_day, - gint *item_x, - gint *item_y, - gint *item_w, - gint *item_h) -{ - EDayViewEvent *event; - - event = &g_array_index (day_view->long_events, EDayViewEvent, - event_num); - - /* If the event is flagged as not displayed, return FALSE. */ - if (event->num_columns == 0) - return FALSE; - - if (!e_day_view_find_long_event_days (day_view, event, - start_day, end_day)) - return FALSE; - - /* If the event is being resize, use the resize position. */ - if (day_view->resize_drag_pos != E_DAY_VIEW_POS_NONE - && day_view->resize_event_day == E_DAY_VIEW_LONG_EVENT - && day_view->resize_event_num == event_num) { - if (day_view->resize_drag_pos == E_DAY_VIEW_POS_LEFT_EDGE) - *start_day = day_view->resize_start_row; - else if (day_view->resize_drag_pos == E_DAY_VIEW_POS_RIGHT_EDGE) - *end_day = day_view->resize_end_row; - } - - *item_x = day_view->day_offsets[*start_day] + E_DAY_VIEW_BAR_WIDTH; - *item_w = day_view->day_offsets[*end_day + 1] - *item_x - - E_DAY_VIEW_GAP_WIDTH; - *item_w = MAX (*item_w, 0); - *item_y = (event->start_row_or_col + 1) * day_view->top_row_height; - *item_h = day_view->top_row_height - E_DAY_VIEW_TOP_CANVAS_Y_GAP; - return TRUE; -} - - -/* Converts a position within the entire top canvas to a day & event and - a place within the event if appropriate. If event_num_return is NULL, it - simply returns the grid position without trying to find the event. */ -static EDayViewPosition -e_day_view_convert_position_in_top_canvas (EDayView *day_view, - gint x, - gint y, - gint *day_return, - gint *event_num_return) -{ - EDayViewEvent *event; - gint day, row, col; - gint event_num, start_day, end_day, item_x, item_y, item_w, item_h; - - *day_return = -1; - if (event_num_return) - *event_num_return = -1; - - if (x < 0 || y < 0) - return E_DAY_VIEW_POS_OUTSIDE; - - row = y / day_view->top_row_height - 1; - - day = -1; - for (col = 1; col <= day_view->days_shown; col++) { - if (x < day_view->day_offsets[col]) { - day = col - 1; - break; - } - } - if (day == -1) - return E_DAY_VIEW_POS_OUTSIDE; - - *day_return = day; - - /* If only the grid position is wanted, return. */ - if (event_num_return == NULL) - return E_DAY_VIEW_POS_NONE; - - for (event_num = 0; event_num < day_view->long_events->len; - event_num++) { - event = &g_array_index (day_view->long_events, EDayViewEvent, - event_num); - - if (event->start_row_or_col != row) - continue; - - if (!e_day_view_get_long_event_position (day_view, event_num, - &start_day, &end_day, - &item_x, &item_y, - &item_w, &item_h)) - continue; - - if (x < item_x) - continue; - - if (x >= item_x + item_w) - continue; - - *event_num_return = event_num; - - if (x < item_x + E_DAY_VIEW_LONG_EVENT_BORDER_WIDTH - + E_DAY_VIEW_LONG_EVENT_X_PAD) - return E_DAY_VIEW_POS_LEFT_EDGE; - - if (x >= item_x + item_w - E_DAY_VIEW_LONG_EVENT_BORDER_WIDTH - - E_DAY_VIEW_LONG_EVENT_X_PAD) - return E_DAY_VIEW_POS_RIGHT_EDGE; - - return E_DAY_VIEW_POS_EVENT; - } - - return E_DAY_VIEW_POS_NONE; -} - - -/* Converts a position within the entire main canvas to a day, row, event and - a place within the event if appropriate. If event_num_return is NULL, it - simply returns the grid position without trying to find the event. */ -static EDayViewPosition -e_day_view_convert_position_in_main_canvas (EDayView *day_view, - gint x, - gint y, - gint *day_return, - gint *row_return, - gint *event_num_return) -{ - gint day, row, col, event_num; - gint item_x, item_y, item_w, item_h; - - *day_return = -1; - *row_return = -1; - if (event_num_return) - *event_num_return = -1; - - /* Check the position is inside the canvas, and determine the day - and row. */ - if (x < 0 || y < 0) - return E_DAY_VIEW_POS_OUTSIDE; - - row = y / day_view->row_height; - if (row >= day_view->rows) - return E_DAY_VIEW_POS_OUTSIDE; - - day = -1; - for (col = 1; col <= day_view->days_shown; col++) { - if (x < day_view->day_offsets[col]) { - day = col - 1; - break; - } - } - if (day == -1) - return E_DAY_VIEW_POS_OUTSIDE; - - *day_return = day; - *row_return = row; - - /* If only the grid position is wanted, return. */ - if (event_num_return == NULL) - return E_DAY_VIEW_POS_NONE; - - /* Check the selected item first, since the horizontal resizing bars - may be above other events. */ - if (day_view->resize_bars_event_day == day) { - if (e_day_view_get_event_position (day_view, day, - day_view->resize_bars_event_num, - &item_x, &item_y, - &item_w, &item_h)) { - if (x >= item_x && x < item_x + item_w) { - *event_num_return = day_view->resize_bars_event_num; - if (y >= item_y - E_DAY_VIEW_BAR_HEIGHT - && y < item_y + E_DAY_VIEW_EVENT_BORDER_HEIGHT) - return E_DAY_VIEW_POS_TOP_EDGE; - if (y >= item_y + item_h - E_DAY_VIEW_EVENT_BORDER_HEIGHT - && y < item_y + item_h + E_DAY_VIEW_BAR_HEIGHT) - return E_DAY_VIEW_POS_BOTTOM_EDGE; - } - } - } - - /* Try to find the event at the found position. */ - *event_num_return = -1; - for (event_num = 0; event_num < day_view->events[day]->len; - event_num++) { - if (!e_day_view_get_event_position (day_view, day, event_num, - &item_x, &item_y, - &item_w, &item_h)) - continue; - - if (x < item_x || x >= item_x + item_w - || y < item_y || y >= item_y + item_h) - continue; - - *event_num_return = event_num; - - if (x < item_x + E_DAY_VIEW_BAR_WIDTH) - return E_DAY_VIEW_POS_LEFT_EDGE; - - if (y < item_y + E_DAY_VIEW_EVENT_BORDER_HEIGHT - + E_DAY_VIEW_EVENT_Y_PAD) - return E_DAY_VIEW_POS_TOP_EDGE; - - if (y >= item_y + item_h - E_DAY_VIEW_EVENT_BORDER_HEIGHT - - E_DAY_VIEW_EVENT_Y_PAD) - return E_DAY_VIEW_POS_BOTTOM_EDGE; - - return E_DAY_VIEW_POS_EVENT; - } - - return E_DAY_VIEW_POS_NONE; -} - - -static gint -e_day_view_on_top_canvas_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time, - EDayView *day_view) -{ - gint scroll_x, scroll_y; - - gnome_canvas_get_scroll_offsets (GNOME_CANVAS (widget), - &scroll_x, &scroll_y); - day_view->drag_event_x = x + scroll_x; - day_view->drag_event_y = y + scroll_y; - - e_day_view_reshape_top_canvas_drag_item (day_view); - - return TRUE; -} - - -static void -e_day_view_reshape_top_canvas_drag_item (EDayView *day_view) -{ - EDayViewPosition pos; - gint x, y, day; - - /* Calculate the day & start row of the event being dragged, using - the current mouse position. */ - x = day_view->drag_event_x; - y = day_view->drag_event_y; - pos = e_day_view_convert_position_in_top_canvas (day_view, x, y, - &day, NULL); - /* This shouldn't really happen in a drag. */ - if (pos == E_DAY_VIEW_POS_OUTSIDE) - return; - - if (day_view->drag_event_day == E_DAY_VIEW_LONG_EVENT) - day -= day_view->drag_event_offset; - day = MAX (day, 0); - - e_day_view_update_top_canvas_drag (day_view, day); -} - - -static void -e_day_view_update_top_canvas_drag (EDayView *day_view, - gint day) -{ - EDayViewEvent *event = NULL; - gint row, num_days, start_day, end_day; - gdouble item_x, item_y, item_w, item_h; - GdkFont *font; - gchar *text; - - - /* Calculate the event's position. If the event is in the same - position we started in, we use the same columns. */ - row = day_view->rows_in_top_display + 1; - num_days = 1; - - if (day_view->drag_event_day == E_DAY_VIEW_LONG_EVENT) { - event = &g_array_index (day_view->long_events, EDayViewEvent, - day_view->drag_event_num); - row = event->start_row_or_col + 1; - - if (!e_day_view_find_long_event_days (day_view, event, - &start_day, &end_day)) - return; - - num_days = end_day - start_day + 1; - - /* Make sure we don't go off the screen. */ - day = MIN (day, day_view->days_shown - num_days); - - } else if (day_view->drag_event_day != -1) { - event = &g_array_index (day_view->events[day_view->drag_event_day], - EDayViewEvent, - day_view->drag_event_num); - } - - /* If the position hasn't changed, just return. */ - if (day_view->drag_last_day == day - && (day_view->drag_long_event_item->object.flags - & GNOME_CANVAS_ITEM_VISIBLE)) - return; - - day_view->drag_last_day = day; - - - item_x = day_view->day_offsets[day] + E_DAY_VIEW_BAR_WIDTH; - item_w = day_view->day_offsets[day + num_days] - item_x - - E_DAY_VIEW_GAP_WIDTH; - item_y = row * day_view->top_row_height; - item_h = day_view->top_row_height - E_DAY_VIEW_TOP_CANVAS_Y_GAP; - - - /* Set the positions of the event & associated items. */ - gnome_canvas_item_set (day_view->drag_long_event_rect_item, - "x1", item_x, - "y1", item_y, - "x2", item_x + item_w - 1, - "y2", item_y + item_h - 1, - NULL); - - font = GTK_WIDGET (day_view)->style->font; - gnome_canvas_item_set (day_view->drag_long_event_item, - "font_gdk", font, - "clip_width", item_w - (E_DAY_VIEW_LONG_EVENT_BORDER_WIDTH + E_DAY_VIEW_LONG_EVENT_X_PAD) * 2, - "clip_height", item_h - (E_DAY_VIEW_LONG_EVENT_BORDER_HEIGHT + E_DAY_VIEW_LONG_EVENT_Y_PAD) * 2, - NULL); - e_canvas_item_move_absolute (day_view->drag_long_event_item, - item_x + E_DAY_VIEW_LONG_EVENT_BORDER_WIDTH + E_DAY_VIEW_LONG_EVENT_X_PAD, - item_y + E_DAY_VIEW_LONG_EVENT_BORDER_HEIGHT + E_DAY_VIEW_LONG_EVENT_Y_PAD); - - if (!(day_view->drag_long_event_rect_item->object.flags & GNOME_CANVAS_ITEM_VISIBLE)) { - gnome_canvas_item_raise_to_top (day_view->drag_long_event_rect_item); - gnome_canvas_item_show (day_view->drag_long_event_rect_item); - } - - /* Set the text, if necessary. We don't want to set the text every - time it moves, so we check if it is currently invisible and only - set the text then. */ - if (!(day_view->drag_long_event_item->object.flags - & GNOME_CANVAS_ITEM_VISIBLE)) { - CalComponentText summary; - - cal_component_get_summary (event->comp, &summary); - if (event) { - cal_component_get_summary (event->comp, &summary); - text = g_strdup (summary.value); - } else { - text = NULL; - } - - gnome_canvas_item_set (day_view->drag_long_event_item, - "text", text ? text : "", - NULL); - gnome_canvas_item_raise_to_top (day_view->drag_long_event_item); - gnome_canvas_item_show (day_view->drag_long_event_item); - - g_free (text); - } -} - - -static gint -e_day_view_on_main_canvas_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time, - EDayView *day_view) -{ - gint scroll_x, scroll_y; - - gnome_canvas_get_scroll_offsets (GNOME_CANVAS (widget), - &scroll_x, &scroll_y); - day_view->drag_event_x = x + scroll_x; - day_view->drag_event_y = y + scroll_y; - - e_day_view_reshape_main_canvas_drag_item (day_view); - e_day_view_reshape_main_canvas_resize_bars (day_view); - - e_day_view_check_auto_scroll (day_view, x, y); - - return TRUE; -} - - -static void -e_day_view_reshape_main_canvas_drag_item (EDayView *day_view) -{ - EDayViewPosition pos; - gint x, y, day, row; - - /* Calculate the day & start row of the event being dragged, using - the current mouse position. */ - x = day_view->drag_event_x; - y = day_view->drag_event_y; - pos = e_day_view_convert_position_in_main_canvas (day_view, x, y, - &day, &row, NULL); - /* This shouldn't really happen in a drag. */ - if (pos == E_DAY_VIEW_POS_OUTSIDE) - return; - - if (day_view->drag_event_day != -1 - && day_view->drag_event_day != E_DAY_VIEW_LONG_EVENT) - row -= day_view->drag_event_offset; - row = MAX (row, 0); - - e_day_view_update_main_canvas_drag (day_view, row, day); -} - - -static void -e_day_view_update_main_canvas_drag (EDayView *day_view, - gint row, - gint day) -{ - EDayViewEvent *event = NULL; - gint cols_in_row, start_col, num_columns, num_rows, start_row, end_row; - gdouble item_x, item_y, item_w, item_h; - GdkFont *font; - gchar *text; - - /* If the position hasn't changed, just return. */ - if (day_view->drag_last_day == day - && day_view->drag_last_row == row - && (day_view->drag_item->object.flags & GNOME_CANVAS_ITEM_VISIBLE)) - return; - - day_view->drag_last_day = day; - day_view->drag_last_row = row; - - /* Calculate the event's position. If the event is in the same - position we started in, we use the same columns. */ - cols_in_row = 1; - start_row = 0; - start_col = 0; - num_columns = 1; - num_rows = 1; - - if (day_view->drag_event_day == E_DAY_VIEW_LONG_EVENT) { - event = &g_array_index (day_view->long_events, EDayViewEvent, - day_view->drag_event_num); - } else if (day_view->drag_event_day != -1) { - event = &g_array_index (day_view->events[day_view->drag_event_day], - EDayViewEvent, - day_view->drag_event_num); - start_row = event->start_minute / day_view->mins_per_row; - end_row = (event->end_minute - 1) / day_view->mins_per_row; - num_rows = end_row - start_row + 1; - } - - if (day_view->drag_event_day == day && start_row == row) { - cols_in_row = day_view->cols_per_row[day][row]; - start_col = event->start_row_or_col; - num_columns = event->num_columns; - } - - item_x = day_view->day_offsets[day] - + day_view->day_widths[day] * start_col / cols_in_row; - item_w = day_view->day_widths[day] * num_columns / cols_in_row - - E_DAY_VIEW_GAP_WIDTH; - item_y = row * day_view->row_height; - item_h = num_rows * day_view->row_height; - - /* Set the positions of the event & associated items. */ - gnome_canvas_item_set (day_view->drag_rect_item, - "x1", item_x + E_DAY_VIEW_BAR_WIDTH - 1, - "y1", item_y, - "x2", item_x + item_w - 1, - "y2", item_y + item_h - 1, - NULL); - - gnome_canvas_item_set (day_view->drag_bar_item, - "x1", item_x, - "y1", item_y, - "x2", item_x + E_DAY_VIEW_BAR_WIDTH - 1, - "y2", item_y + item_h - 1, - NULL); - - font = GTK_WIDGET (day_view)->style->font; - gnome_canvas_item_set (day_view->drag_item, - "font_gdk", font, - "clip_width", item_w - E_DAY_VIEW_BAR_WIDTH - E_DAY_VIEW_EVENT_X_PAD * 2, - "clip_height", item_h - (E_DAY_VIEW_EVENT_BORDER_HEIGHT + E_DAY_VIEW_EVENT_Y_PAD) * 2, - NULL); - e_canvas_item_move_absolute (day_view->drag_item, - item_x + E_DAY_VIEW_BAR_WIDTH + E_DAY_VIEW_EVENT_X_PAD, - item_y + E_DAY_VIEW_EVENT_BORDER_HEIGHT + E_DAY_VIEW_EVENT_Y_PAD); - - if (!(day_view->drag_bar_item->object.flags & GNOME_CANVAS_ITEM_VISIBLE)) { - gnome_canvas_item_raise_to_top (day_view->drag_bar_item); - gnome_canvas_item_show (day_view->drag_bar_item); - } - - if (!(day_view->drag_rect_item->object.flags & GNOME_CANVAS_ITEM_VISIBLE)) { - gnome_canvas_item_raise_to_top (day_view->drag_rect_item); - gnome_canvas_item_show (day_view->drag_rect_item); - } - - /* Set the text, if necessary. We don't want to set the text every - time it moves, so we check if it is currently invisible and only - set the text then. */ - if (!(day_view->drag_item->object.flags & GNOME_CANVAS_ITEM_VISIBLE)) { - CalComponentText summary; - - if (event) { - cal_component_get_summary (event->comp, &summary); - text = g_strdup (summary.value); - } else { - text = NULL; - } - - gnome_canvas_item_set (day_view->drag_item, - "text", text ? text : "", - NULL); - gnome_canvas_item_raise_to_top (day_view->drag_item); - gnome_canvas_item_show (day_view->drag_item); - - g_free (text); - } -} - - -static void -e_day_view_on_top_canvas_drag_leave (GtkWidget *widget, - GdkDragContext *context, - guint time, - EDayView *day_view) -{ - day_view->drag_last_day = -1; - - gnome_canvas_item_hide (day_view->drag_long_event_rect_item); - gnome_canvas_item_hide (day_view->drag_long_event_item); -} - - -static void -e_day_view_on_main_canvas_drag_leave (GtkWidget *widget, - GdkDragContext *context, - guint time, - EDayView *day_view) -{ - day_view->drag_last_day = -1; - - e_day_view_stop_auto_scroll (day_view); - - gnome_canvas_item_hide (day_view->drag_rect_item); - gnome_canvas_item_hide (day_view->drag_bar_item); - gnome_canvas_item_hide (day_view->drag_item); - - /* Hide the resize bars if they are being used in the drag. */ - if (day_view->drag_event_day == day_view->resize_bars_event_day - && day_view->drag_event_num == day_view->resize_bars_event_num) { - gnome_canvas_item_hide (day_view->main_canvas_top_resize_bar_item); - gnome_canvas_item_hide (day_view->main_canvas_bottom_resize_bar_item); - } -} - - -static void -e_day_view_on_drag_begin (GtkWidget *widget, - GdkDragContext *context, - EDayView *day_view) -{ - EDayViewEvent *event; - gint day, event_num; - - day = day_view->drag_event_day; - event_num = day_view->drag_event_num; - - /* These should both be set. */ - g_return_if_fail (day != -1); - g_return_if_fail (event_num != -1); - - if (day == E_DAY_VIEW_LONG_EVENT) - event = &g_array_index (day_view->long_events, EDayViewEvent, - event_num); - else - event = &g_array_index (day_view->events[day], EDayViewEvent, - event_num); - - /* Hide the text item, since it will be shown in the special drag - items. */ - gnome_canvas_item_hide (event->canvas_item); -} - - -static void -e_day_view_on_drag_end (GtkWidget *widget, - GdkDragContext *context, - EDayView *day_view) -{ - EDayViewEvent *event; - gint day, event_num; - - day = day_view->drag_event_day; - event_num = day_view->drag_event_num; - - /* If the calendar has already been updated in drag_data_received() - we just return. */ - if (day == -1 || event_num == -1) - return; - - if (day == E_DAY_VIEW_LONG_EVENT) { - event = &g_array_index (day_view->long_events, EDayViewEvent, - event_num); - gtk_widget_queue_draw (day_view->top_canvas); - } else { - event = &g_array_index (day_view->events[day], EDayViewEvent, - event_num); - gtk_widget_queue_draw (day_view->main_canvas); - } - - /* Show the text item again. */ - gnome_canvas_item_show (event->canvas_item); - - day_view->drag_event_day = -1; - day_view->drag_event_num = -1; -} - - -static void -e_day_view_on_drag_data_get (GtkWidget *widget, - GdkDragContext *context, - GtkSelectionData *selection_data, - guint info, - guint time, - EDayView *day_view) -{ - EDayViewEvent *event; - gint day, event_num; - const char *event_uid; - - day = day_view->drag_event_day; - event_num = day_view->drag_event_num; - - /* These should both be set. */ - g_return_if_fail (day != -1); - g_return_if_fail (event_num != -1); - - if (day == E_DAY_VIEW_LONG_EVENT) - event = &g_array_index (day_view->long_events, - EDayViewEvent, event_num); - else - event = &g_array_index (day_view->events[day], - EDayViewEvent, event_num); - - - cal_component_get_uid (event->comp, &event_uid); - - g_return_if_fail (event_uid != NULL); - - if (info == TARGET_CALENDAR_EVENT) { - gtk_selection_data_set (selection_data, selection_data->target, - 8, event_uid, strlen (event_uid)); - } -} - - -static void -e_day_view_on_top_canvas_drag_data_received (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *data, - guint info, - guint time, - EDayView *day_view) -{ - EDayViewEvent *event=NULL; - EDayViewPosition pos; - gint day, start_day, end_day, num_days; - gint start_offset, end_offset; - gchar *event_uid; - CalComponent *comp; - CalComponentDateTime date; - struct icaltimetype itt; - time_t dt; - - if ((data->length >= 0) && (data->format == 8)) { - pos = e_day_view_convert_position_in_top_canvas (day_view, - x, y, &day, - NULL); - if (pos != E_DAY_VIEW_POS_OUTSIDE) { - const char *uid; - num_days = 1; - start_offset = 0; - end_offset = -1; - - if (day_view->drag_event_day == E_DAY_VIEW_LONG_EVENT) { - event = &g_array_index (day_view->long_events, EDayViewEvent, - day_view->drag_event_num); - day -= day_view->drag_event_offset; - day = MAX (day, 0); - - e_day_view_find_long_event_days (day_view, - event, - &start_day, - &end_day); - num_days = end_day - start_day + 1; - /* Make sure we don't go off the screen. */ - day = MIN (day, day_view->days_shown - num_days); - - start_offset = event->start_minute; - end_offset = event->end_minute; - } else if (day_view->drag_event_day != -1) { - event = &g_array_index (day_view->events[day_view->drag_event_day], - EDayViewEvent, - day_view->drag_event_num); - } - - event_uid = data->data; - - cal_component_get_uid (event->comp, &uid); - - if (!event_uid || !uid || strcmp (event_uid, uid)) - g_warning ("Unexpected event UID"); - - /* We use a temporary shallow of the comp since we - don't want to change the original comp here. - Otherwise we would not detect that the event's time - had changed in the "update_event" callback. */ - - comp = cal_component_clone (event->comp); - - date.value = &itt; - date.tzid = NULL; - - dt = day_view->day_starts[day] + start_offset * 60; - *date.value = icaltime_from_timet (dt, FALSE); - cal_component_set_dtstart (comp, &date); - if (end_offset == -1 || end_offset == 0) - dt = day_view->day_starts[day + num_days]; - else - dt = day_view->day_starts[day + num_days - 1] + end_offset * 60; - *date.value = icaltime_from_timet (dt, FALSE); - cal_component_set_dtend (comp, &date); - - gtk_drag_finish (context, TRUE, TRUE, time); - - /* Reset this since it will be invalid. */ - day_view->drag_event_day = -1; - - /* Show the text item again, just in case it hasn't - moved. If we don't do this it may not appear. */ - if (event->canvas_item) - gnome_canvas_item_show (event->canvas_item); - - if (!cal_client_update_object (day_view->client, comp)) - g_message ("e_day_view_on_top_canvas_drag_data_received(): Could " - "not update the object!"); - - gtk_object_unref (GTK_OBJECT (comp)); - - return; - } - } - - gtk_drag_finish (context, FALSE, FALSE, time); -} - - -static void -e_day_view_on_main_canvas_drag_data_received (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *data, - guint info, - guint time, - EDayView *day_view) -{ - EDayViewEvent *event = NULL; - EDayViewPosition pos; - gint day, row, start_row, end_row, num_rows, scroll_x, scroll_y; - gint start_offset, end_offset; - gchar *event_uid; - CalComponent *comp; - CalComponentDateTime date; - struct icaltimetype itt; - time_t dt; - - gnome_canvas_get_scroll_offsets (GNOME_CANVAS (widget), - &scroll_x, &scroll_y); - x += scroll_x; - y += scroll_y; - - if ((data->length >= 0) && (data->format == 8)) { - pos = e_day_view_convert_position_in_main_canvas (day_view, - x, y, &day, - &row, NULL); - if (pos != E_DAY_VIEW_POS_OUTSIDE) { - const char *uid; - num_rows = 1; - start_offset = 0; - end_offset = 0; - - if (day_view->drag_event_day == E_DAY_VIEW_LONG_EVENT) { - event = &g_array_index (day_view->long_events, EDayViewEvent, - day_view->drag_event_num); - } else if (day_view->drag_event_day != -1) { - event = &g_array_index (day_view->events[day_view->drag_event_day], - EDayViewEvent, - day_view->drag_event_num); - row -= day_view->drag_event_offset; - - /* Calculate time offset from start row. */ - start_row = event->start_minute / day_view->mins_per_row; - end_row = (event->end_minute - 1) / day_view->mins_per_row; - num_rows = end_row - start_row + 1; - - start_offset = event->start_minute % day_view->mins_per_row; - end_offset = event->end_minute % day_view->mins_per_row; - if (end_offset != 0) - end_offset = day_view->mins_per_row - end_offset; - } - - event_uid = data->data; - - cal_component_get_uid (event->comp, &uid); - if (!event_uid || !uid || strcmp (event_uid, uid)) - g_warning ("Unexpected event UID"); - - /* We use a temporary shallow copy of comp since we - don't want to change the original comp here. - Otherwise we would not detect that the event's time - had changed in the "update_event" callback. */ - comp = cal_component_clone (event->comp); - - date.value = &itt; - date.tzid = NULL; - - dt = e_day_view_convert_grid_position_to_time (day_view, day, row) + start_offset * 60; - *date.value = icaltime_from_timet (dt, FALSE); - cal_component_set_dtstart (comp, &date); - dt = e_day_view_convert_grid_position_to_time (day_view, day, row + num_rows) - end_offset * 60; - *date.value = icaltime_from_timet (dt, FALSE); - cal_component_set_dtend (comp, &date); - - gtk_drag_finish (context, TRUE, TRUE, time); - - /* Reset this since it will be invalid. */ - day_view->drag_event_day = -1; - - /* Show the text item again, just in case it hasn't - moved. If we don't do this it may not appear. */ - if (event->canvas_item) - gnome_canvas_item_show (event->canvas_item); - - if (!cal_client_update_object (day_view->client, comp)) - g_message ("e_day_view_on_main_canvas_drag_data_received(): " - "Could not update the object!"); - - gtk_object_unref (GTK_OBJECT (comp)); - - return; - } - } - - gtk_drag_finish (context, FALSE, FALSE, time); -} - - -/* Converts an hour from 0-23 to the preferred time format, and returns the - suffix to add and the width of it in the normal font. */ -void -e_day_view_convert_time_to_display (EDayView *day_view, - gint hour, - gint *display_hour, - gchar **suffix, - gint *suffix_width) -{ - /* Calculate the actual hour number to display. For 12-hour - format we convert 0-23 to 12-11am/12-11pm. */ - *display_hour = hour; - if (day_view->use_24_hour_format) { - *suffix = ""; - *suffix_width = 0; - } else { - if (hour < 12) { - *suffix = day_view->am_string; - *suffix_width = day_view->am_string_width; - } else { - *display_hour -= 12; - *suffix = day_view->pm_string; - *suffix_width = day_view->pm_string_width; - } - - /* 12-hour uses 12:00 rather than 0:00. */ - if (*display_hour == 0) - *display_hour = 12; - } -} - - -gint -e_day_view_get_time_string_width (EDayView *day_view) -{ - gint time_width; - - time_width = day_view->digit_width * 4 + day_view->colon_width; - - if (!day_view->use_24_hour_format) - time_width += MAX (day_view->am_string_width, - day_view->pm_string_width); - - return time_width; -} diff --git a/calendar/gui/e-day-view.h b/calendar/gui/e-day-view.h deleted file mode 100644 index 2379a76b87..0000000000 --- a/calendar/gui/e-day-view.h +++ /dev/null @@ -1,621 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 1999, Helix Code, Inc. - * Copyright 1999, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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 - */ -#ifndef _E_DAY_VIEW_H_ -#define _E_DAY_VIEW_H_ - -#include <time.h> -#include <gtk/gtktable.h> -#include <libgnomeui/gnome-canvas.h> - -#include "gnome-cal.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - * EDayView - displays the Day & Work-Week views of the calendar. - */ - -/* The maximum number of days shown. We use the week view for anything more - than about 9 days. */ -#define E_DAY_VIEW_MAX_DAYS 10 - -/* This is used as a special code to signify a long event instead of the day - of a normal event. */ -#define E_DAY_VIEW_LONG_EVENT E_DAY_VIEW_MAX_DAYS - -/* The maximum number of columns of appointments within a day. */ -#define E_DAY_VIEW_MAX_COLUMNS 6 - -/* The width of the gap between appointments. This should be at least - E_DAY_VIEW_BAR_WIDTH, since in the top canvas we use this space to draw - the triangle to represent continuing events. */ -#define E_DAY_VIEW_GAP_WIDTH 7 - -/* The width of the bars down the left of each column and appointment. - This includes the borders on each side of it. */ -#define E_DAY_VIEW_BAR_WIDTH 7 - -/* The height of the horizontal bar above & beneath the selected event. - This includes the borders on the top and bottom. */ -#define E_DAY_VIEW_BAR_HEIGHT 6 - -/* The size of the reminder & recurrence icons, and padding around them. */ -#define E_DAY_VIEW_ICON_WIDTH 16 -#define E_DAY_VIEW_ICON_HEIGHT 16 -#define E_DAY_VIEW_ICON_X_PAD 0 -#define E_DAY_VIEW_ICON_Y_PAD 0 - -/* The size of the border around the event. */ -#define E_DAY_VIEW_EVENT_BORDER_WIDTH 1 -#define E_DAY_VIEW_EVENT_BORDER_HEIGHT 1 - -/* The padding on each side of the event text. */ -#define E_DAY_VIEW_EVENT_X_PAD 2 -#define E_DAY_VIEW_EVENT_Y_PAD 1 - -/* The padding on each side of the event text for events in the top canvas. */ -#define E_DAY_VIEW_LONG_EVENT_X_PAD 2 -#define E_DAY_VIEW_LONG_EVENT_Y_PAD 2 - -/* The size of the border around the long events in the top canvas. */ -#define E_DAY_VIEW_LONG_EVENT_BORDER_WIDTH 1 -#define E_DAY_VIEW_LONG_EVENT_BORDER_HEIGHT 1 - -/* The space between the time and the icon/text in the top canvas. */ -#define E_DAY_VIEW_LONG_EVENT_TIME_X_PAD 2 - -/* The gap between rows in the top canvas. */ -#define E_DAY_VIEW_TOP_CANVAS_Y_GAP 2 - - -/* These are used to get/set the working days in the week. The bit-flags are - combined together. The bits must be from 0 (Sun) to 6 (Sat) to match the - day values used by localtime etc. */ -typedef enum -{ - E_DAY_VIEW_SUNDAY = 1 << 0, - E_DAY_VIEW_MONDAY = 1 << 1, - E_DAY_VIEW_TUESDAY = 1 << 2, - E_DAY_VIEW_WEDNESDAY = 1 << 3, - E_DAY_VIEW_THURSDAY = 1 << 4, - E_DAY_VIEW_FRIDAY = 1 << 5, - E_DAY_VIEW_SATURDAY = 1 << 6 -} EDayViewDays; - - -/* These are used to specify the type of an appointment. They match those - used in EMeetingTimeSelector. */ -typedef enum -{ - E_DAY_VIEW_BUSY_TENTATIVE = 0, - E_DAY_VIEW_BUSY_OUT_OF_OFFICE = 1, - E_DAY_VIEW_BUSY_BUSY = 2, - - E_DAY_VIEW_BUSY_LAST = 3 -} EDayViewBusyType; - -/* This is used to specify the format used when displaying the dates. - The full format is like 'Thursday 12 September'. The abbreviated format is - like 'Thu 12 Sep'. The no weekday format is like '12 Sep'. The short format - is like '12'. The actual format used is determined in - e_day_view_recalc_cell_sizes(), once we know the font being used. */ -typedef enum -{ - E_DAY_VIEW_DATE_FULL, - E_DAY_VIEW_DATE_ABBREVIATED, - E_DAY_VIEW_DATE_NO_WEEKDAY, - E_DAY_VIEW_DATE_SHORT -} EDayViewDateFormat; - -/* These index our colors array. */ -typedef enum -{ - E_DAY_VIEW_COLOR_BG_WORKING, - E_DAY_VIEW_COLOR_BG_NOT_WORKING, - E_DAY_VIEW_COLOR_BG_SELECTED, - E_DAY_VIEW_COLOR_BG_GRID, - - E_DAY_VIEW_COLOR_BG_TOP_CANVAS, - E_DAY_VIEW_COLOR_BG_TOP_CANVAS_SELECTED, - E_DAY_VIEW_COLOR_BG_TOP_CANVAS_GRID, - - E_DAY_VIEW_COLOR_EVENT_VBAR, - E_DAY_VIEW_COLOR_EVENT_BACKGROUND, - E_DAY_VIEW_COLOR_EVENT_BORDER, - - E_DAY_VIEW_COLOR_LONG_EVENT_BACKGROUND, - E_DAY_VIEW_COLOR_LONG_EVENT_BORDER, - - E_DAY_VIEW_COLOR_LAST -} EDayViewColors; - -/* These specify which part of the selection we are dragging, if any. */ -typedef enum -{ - E_DAY_VIEW_DRAG_START, - E_DAY_VIEW_DRAG_END -} EDayViewDragPosition; - -/* Specifies the position of the mouse. */ -typedef enum -{ - E_DAY_VIEW_POS_OUTSIDE, - E_DAY_VIEW_POS_NONE, - E_DAY_VIEW_POS_EVENT, - E_DAY_VIEW_POS_LEFT_EDGE, - E_DAY_VIEW_POS_RIGHT_EDGE, - E_DAY_VIEW_POS_TOP_EDGE, - E_DAY_VIEW_POS_BOTTOM_EDGE -} EDayViewPosition; - -typedef struct _EDayViewEvent EDayViewEvent; -struct _EDayViewEvent { - CalComponent *comp; - - /* These are the times of this specific occurrence of the event. */ - time_t start; - time_t end; - - /* For events in the main canvas, this contains the start column. - For long events in the top canvas, this is its row. */ - guint8 start_row_or_col; - - /* For events in the main canvas, this is the number of columns that - it covers. For long events this is set to 1 if the event is shown. - For both types of events this is set to 0 if the event is not shown, - i.e. it couldn't fit into the display. Currently long events are - always shown as we just increase the height of the top canvas. */ - guint8 num_columns; - - /* These are minute offsets from the first time shown in the view. - They range from 0 to 24 * 60. Currently the main canvas always - starts at 12am and the code to handle starting at other times - isn't finished. */ - guint16 start_minute; - guint16 end_minute; - - /* This is the EText item containing the event summary. */ - GnomeCanvasItem *canvas_item; -}; - - -#define E_DAY_VIEW(obj) GTK_CHECK_CAST (obj, e_day_view_get_type (), EDayView) -#define E_DAY_VIEW_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, e_day_view_get_type (), EDayViewClass) -#define E_IS_DAY_VIEW(obj) GTK_CHECK_TYPE (obj, e_day_view_get_type ()) - - -typedef struct _EDayView EDayView; -typedef struct _EDayViewClass EDayViewClass; - -struct _EDayView -{ - GtkTable table; - - /* The top canvas where the dates and long appointments are shown. */ - GtkWidget *top_canvas; - GnomeCanvasItem *top_canvas_item; - - /* The main canvas where the rest of the appointments are shown. */ - GtkWidget *main_canvas; - GnomeCanvasItem *main_canvas_item; - - /* The canvas displaying the times of the day. */ - GtkWidget *time_canvas; - GnomeCanvasItem *time_canvas_item; - - GtkWidget *vscrollbar; - - /* The calendar we are associated with. */ - GnomeCalendar *calendar; - - /* Calendar client object we are monitoring */ - CalClient *client; - - /* The start and end of the days shown. */ - time_t lower; - time_t upper; - - /* Whether we are showing the work-week view. */ - gboolean work_week_view; - - /* The number of days we are showing. Usually 1 or 5, but can be up - to E_DAY_VIEW_MAX_DAYS, e.g. when the user selects a range of - days in the date navigator. */ - gint days_shown; - - /* The start of each day & an extra element to hold the last time. */ - time_t day_starts[E_DAY_VIEW_MAX_DAYS + 1]; - - - /* An array of EDayViewEvent elements for the top view and each day. */ - GArray *long_events; - GArray *events[E_DAY_VIEW_MAX_DAYS]; - - /* These are set to FALSE whenever an event in the corresponding array - is changed. Any function that needs the events sorted calls - e_day_view_ensure_events_sorted(). */ - gboolean long_events_sorted; - gboolean events_sorted[E_DAY_VIEW_MAX_DAYS]; - - /* This is TRUE if we need to relayout the events before drawing. */ - gboolean long_events_need_layout; - gboolean need_layout[E_DAY_VIEW_MAX_DAYS]; - - /* This is TRUE if we need to reshape the canvas items, but a full - layout is not necessary. */ - gboolean long_events_need_reshape; - gboolean need_reshape[E_DAY_VIEW_MAX_DAYS]; - - /* The id of our idle function to reload all events. */ - gint reload_events_idle_id; - - /* The number of minutes per row. 5, 10, 15, 30 or 60. */ - gint mins_per_row; - - /* The number of rows needed, depending on the times shown and the - minutes per row. */ - gint rows; - - /* The height of each row. */ - gint row_height; - - /* The number of rows in the top display. */ - gint rows_in_top_display; - - /* The height of each row in the top canvas. */ - gint top_row_height; - - /* The first and last times shown in the display. The last time isn't - included in the range. Default is 0:00-24:00 */ - gint first_hour_shown; - gint first_minute_shown; - gint last_hour_shown; - gint last_minute_shown; - - /* Bitwise combination of working days. Defaults to Mon-Fri. */ - EDayViewDays working_days; - - /* The start and end of the work day, rounded to the nearest row. */ - gint work_day_start_hour; - gint work_day_start_minute; - gint work_day_end_hour; - gint work_day_end_minute; - - /* Whether we use 12-hour of 24-hour format. */ - gboolean use_24_hour_format; - - /* Whether we use show event end times in the main canvas. */ - gboolean show_event_end_times; - - /* The first day of the week, 0 (Monday) to 6 (Sunday). */ - gint week_start_day; - - /* This is set to TRUE when the widget is created, so it scrolls to - the start of the working day when first shown. */ - gboolean scroll_to_work_day; - - /* This is the width & offset of each of the day columns in the - display. */ - gint day_widths[E_DAY_VIEW_MAX_DAYS]; - gint day_offsets[E_DAY_VIEW_MAX_DAYS + 1]; - - /* An array holding the number of columns in each row, in each day. - Note that there are a maximum of 12 * 24 rows (when a row is 5 mins) - but we don't always have that many rows. */ - guint8 cols_per_row[E_DAY_VIEW_MAX_DAYS][12 * 24]; - - /* Sizes of the various time strings. */ - gint small_hour_widths[24]; - gint max_small_hour_width; - gint max_minute_width; - gint colon_width; - gint digit_width; /* Size of '0' character. */ - - /* This specifies how we are displaying the dates at the top. */ - EDayViewDateFormat date_format; - - /* These are the longest month & weekday names in the current font. - Months are 0 to 11. Weekdays are 0 (Sun) to 6 (Sat). */ - gint longest_month_name; - gint longest_abbreviated_month_name; - gint longest_weekday_name; - gint longest_abbreviated_weekday_name; - - /* The large font used to display the hours. I don't think we need a - fontset since we only display numbers. */ - GdkFont *large_font; - - /* The GC used for painting in different colors. */ - GdkGC *main_gc; - - /* The icons. */ - GdkPixmap *reminder_icon; - GdkBitmap *reminder_mask; - GdkPixmap *recurrence_icon; - GdkBitmap *recurrence_mask; - - /* Colors for drawing. */ - GdkColor colors[E_DAY_VIEW_COLOR_LAST]; - - /* The normal & resizing cursors. */ - GdkCursor *normal_cursor; - GdkCursor *move_cursor; - GdkCursor *resize_width_cursor; - GdkCursor *resize_height_cursor; - - /* This remembers the last cursor set on the window. */ - GdkCursor *last_cursor_set_in_top_canvas; - GdkCursor *last_cursor_set_in_main_canvas; - - /* - * Editing, Selection & Dragging data - */ - - /* The horizontal bars to resize events in the main canvas. */ - GnomeCanvasItem *main_canvas_top_resize_bar_item; - GnomeCanvasItem *main_canvas_bottom_resize_bar_item; - - /* The event currently being edited. The day is -1 if no event is - being edited, or E_DAY_VIEW_LONG_EVENT if a long event is edited. */ - gint editing_event_day; - gint editing_event_num; - - /* This is a GnomeCanvasRect which is placed around an item while it - is being resized, so we can raise it above all other EText items. */ - GnomeCanvasItem *resize_long_event_rect_item; - GnomeCanvasItem *resize_rect_item; - GnomeCanvasItem *resize_bar_item; - - /* The event for which a popup menu is being displayed, as above. */ - gint popup_event_day; - gint popup_event_num; - - /* The currently selected region. If selection_start_day is -1 there is - no current selection. If start_row or end_row is -1 then the - selection is in the top canvas. */ - gint selection_start_day; - gint selection_end_day; - gint selection_start_row; - gint selection_end_row; - - /* This is TRUE if the selection is currently being dragged using the - mouse. */ - gboolean selection_is_being_dragged; - - /* This specifies which end of the selection is being dragged. */ - EDayViewDragPosition selection_drag_pos; - - /* This is TRUE if the selection is in the top canvas only (i.e. if the - last motion event was in the top canvas). */ - gboolean selection_in_top_canvas; - - /* The last mouse position, relative to the main canvas window. - Used when auto-scrolling to update the selection. */ - gint last_mouse_x; - gint last_mouse_y; - - /* Auto-scroll info for when selecting an area or dragging an item. */ - gint auto_scroll_timeout_id; - gint auto_scroll_delay; - gboolean auto_scroll_up; - - /* These are used for the resize bars. */ - gint resize_bars_event_day; - gint resize_bars_event_num; - - /* These are used when resizing events. */ - gint resize_event_day; - gint resize_event_num; - EDayViewPosition resize_drag_pos; - gint resize_start_row; - gint resize_end_row; - - /* This is the event the mouse button was pressed on. If the button - is released we start editing it, but if the mouse is dragged we set - this to -1. */ - gint pressed_event_day; - gint pressed_event_num; - - /* These are used when dragging events. If drag_event_day is not -1 we - know that we are dragging one of the EDayView events around. */ - gint drag_event_day; - gint drag_event_num; - - /* The last mouse position when dragging, in the entire canvas. */ - gint drag_event_x; - gint drag_event_y; - - /* The offset of the mouse from the top of the event, in rows. - In the top canvas this is the offset from the left, in days. */ - gint drag_event_offset; - - /* The last day & row dragged to, so we know when we need to update - the dragged event's position. */ - gint drag_last_day; - gint drag_last_row; - - /* This is a GnomeCanvasRect which is placed around an item while it - is being resized, so we can raise it above all other EText items. */ - GnomeCanvasItem *drag_long_event_rect_item; - GnomeCanvasItem *drag_long_event_item; - GnomeCanvasItem *drag_rect_item; - GnomeCanvasItem *drag_bar_item; - GnomeCanvasItem *drag_item; - - /* "am" and "pm" in the current locale, and their widths. */ - gchar *am_string; - gchar *pm_string; - gint am_string_width; - gint pm_string_width; -}; - -struct _EDayViewClass -{ - GtkTableClass parent_class; -}; - - -GtkType e_day_view_get_type (void); -GtkWidget* e_day_view_new (void); - -void e_day_view_set_calendar (EDayView *day_view, - GnomeCalendar *calendar); - -void e_day_view_set_cal_client (EDayView *day_view, - CalClient *client); - -/* This sets the selected time range. The EDayView will show the day or week - corresponding to the start time. If the start_time & end_time are not equal - and are both visible in the view, then the selection is set to those times, - otherwise it is set to 1 hour from the start of the working day. */ -void e_day_view_set_selected_time_range (EDayView *day_view, - time_t start_time, - time_t end_time); - -/* Returns the selected time range. */ -void e_day_view_get_selected_time_range (EDayView *day_view, - time_t *start_time, - time_t *end_time); - -/* This is called when one event has been added or updated. */ -void e_day_view_update_event (EDayView *day_view, - const gchar *uid); - -/* This removes all the events associated with the given uid. Note that for - recurring events there may be more than one. If any events are found and - removed we need to layout the events again. */ -void e_day_view_remove_event (EDayView *day_view, - const gchar *uid); - -/* 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); -void e_day_view_set_work_week_view (EDayView *day_view, - gboolean work_week_view); - -/* The number of days shown in the EDayView, from 1 to 7. This is normally - either 1 or 5 (for the Work-Week view). */ -gint e_day_view_get_days_shown (EDayView *day_view); -void e_day_view_set_days_shown (EDayView *day_view, - gint days_shown); - -/* This specifies how many minutes are represented by one row in the display. - It can be 60, 30, 15, 10 or 5. The default is 30. */ -gint e_day_view_get_mins_per_row (EDayView *day_view); -void e_day_view_set_mins_per_row (EDayView *day_view, - gint mins_per_row); - -/* This specifies the working days in the week. The value is a bitwise - combination of day flags. Defaults to Mon-Fri. */ -EDayViewDays e_day_view_get_working_days (EDayView *day_view); -void e_day_view_set_working_days (EDayView *day_view, - EDayViewDays days); - -/* The start and end time of the working day. This only affects the background - colors. */ -void e_day_view_get_working_day (EDayView *day_view, - gint *start_hour, - gint *start_minute, - gint *end_hour, - gint *end_minute); -void e_day_view_set_working_day (EDayView *day_view, - gint start_hour, - gint start_minute, - gint end_hour, - gint end_minute); - -/* Whether we use 12-hour or 24-hour format. */ -gboolean e_day_view_get_24_hour_format (EDayView *day_view); -void e_day_view_set_24_hour_format (EDayView *day_view, - gboolean use_24_hour); - -/* Whether we display event end times in the main canvas. */ -gboolean e_day_view_get_show_event_end_times (EDayView *day_view); -void e_day_view_set_show_event_end_times (EDayView *day_view, - gboolean show); - -/* The first day of the week, 0 (Monday) to 6 (Sunday). */ -gint e_day_view_get_week_start_day (EDayView *day_view); -void e_day_view_set_week_start_day (EDayView *day_view, - gint week_start_day); - -/* - * Internal functions called by the associated canvas items. - */ -void e_day_view_check_layout (EDayView *day_view); -gint e_day_view_convert_time_to_row (EDayView *day_view, - gint hour, - gint minute); -gint e_day_view_convert_time_to_position (EDayView *day_view, - gint hour, - gint minute); -gboolean e_day_view_get_event_position (EDayView *day_view, - gint day, - gint event_num, - gint *item_x, - gint *item_y, - gint *item_w, - gint *item_h); -gboolean e_day_view_get_long_event_position (EDayView *day_view, - gint event_num, - gint *start_day, - gint *end_day, - gint *item_x, - gint *item_y, - gint *item_w, - gint *item_h); -gboolean e_day_view_find_long_event_days (EDayView *day_view, - EDayViewEvent *event, - gint *start_day, - gint *end_day); - -void e_day_view_start_selection (EDayView *day_view, - gint day, - gint row); -void e_day_view_update_selection (EDayView *day_view, - gint day, - gint row); -void e_day_view_finish_selection (EDayView *day_view); - -void e_day_view_check_auto_scroll (EDayView *day_view, - gint event_x, - gint event_y); -void e_day_view_stop_auto_scroll (EDayView *day_view); - -void e_day_view_convert_time_to_display (EDayView *day_view, - gint hour, - gint *display_hour, - gchar **suffix, - gint *suffix_width); -gint e_day_view_get_time_string_width (EDayView *day_view); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_DAY_VIEW_H_ */ diff --git a/calendar/gui/e-itip-control.c b/calendar/gui/e-itip-control.c deleted file mode 100644 index 65905b7efb..0000000000 --- a/calendar/gui/e-itip-control.c +++ /dev/null @@ -1,1073 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Evolution calendar - Control for displaying iTIP mail messages - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Jesse Pavel <jpavel@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#include <config.h> -#include <time.h> -#include <gnome.h> -#include <bonobo.h> -#include <glade/glade.h> -#include <ical.h> -#include <Evolution-Composer.h> - -#include "e-itip-control.h" -#include <cal-util/cal-component.h> -#include <cal-client/cal-client.h> -#include "itip-utils.h" - -#define MAIL_COMPOSER_OAF_IID "OAFIID:GNOME_Evolution_Mail_Composer" - -#define DEFAULT_WIDTH 400 -#define DEFAULT_HEIGHT 300 - -extern gchar *evolution_dir; - -typedef struct _EItipControlPrivate EItipControlPrivate; - -struct _EItipControlPrivate { - GladeXML *xml, *xml2; - GtkWidget *main_frame; - GtkWidget *organizer_entry, *dtstart_label, *dtend_label; - GtkWidget *summary_entry, *description_box, *message_text; - GtkWidget *button_box; - GtkWidget *address_entry; - GtkWidget *add_button; - GtkWidget *loading_window; - GtkWidget *loading_progress; - - icalcomponent *main_comp, *comp; - CalComponent *cal_comp; - char *vcalendar; - gchar *from_address, *my_address, *organizer; - icalparameter_partstat new_partstat; -}; - -enum E_ITIP_BONOBO_ARGS { - FROM_ADDRESS_ARG_ID, - MY_ADDRESS_ARG_ID -}; - - -/******** - * find_attendee() searches through the attendee properties of `comp' - * and returns the one the value of which is the same as `address' if such - * a property exists. Otherwise, it will return NULL. - ********/ -static icalproperty * -find_attendee (icalcomponent *comp, char *address) -{ - icalproperty *prop; - const char *attendee, *text; - icalvalue *value; - - for (prop = icalcomponent_get_first_property (comp, ICAL_ATTENDEE_PROPERTY); - prop != NULL; - prop = icalcomponent_get_next_property (comp, ICAL_ATTENDEE_PROPERTY)) - { - value = icalproperty_get_value (prop); - if (!value) - continue; - - attendee = icalvalue_get_string (value); - - /* Here I strip off the "MAILTO:" if it is present. */ - text = strchr (attendee, ':'); - if (text != NULL) - text++; - else - text = attendee; - - if (strcmp (text, address) == 0) { - /* We have found the correct property. */ - break; - } - } - - return prop; -} - -static void -itip_control_destroy_cb (GtkObject *object, - gpointer data) -{ - EItipControlPrivate *priv = data; - - gtk_object_unref (GTK_OBJECT (priv->xml)); - gtk_object_unref (GTK_OBJECT (priv->xml2)); - - if (priv->main_comp != NULL) { - if (priv->comp != NULL) - icalcomponent_remove_component (priv->main_comp, priv->comp); - - icalcomponent_free (priv->main_comp); - } - - - if (priv->cal_comp != NULL) { - gtk_object_unref (GTK_OBJECT (priv->cal_comp)); - } - - if (priv->from_address != NULL) - g_free (priv->from_address); - - if (priv->organizer != NULL) - g_free (priv->organizer); - - if (priv->vcalendar != NULL) - g_free (priv->vcalendar); - - g_free (priv); -} - - -static void -cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data) -{ - EItipControlPrivate *priv = data; - - gtk_widget_hide (priv->loading_progress); - - if (status == CAL_CLIENT_OPEN_SUCCESS) { - if (cal_client_update_object (client, priv->cal_comp) == FALSE) { - GtkWidget *dialog; - - dialog = gnome_warning_dialog(_("I couldn't update your calendar file!\n")); - gnome_dialog_run (GNOME_DIALOG(dialog)); - } else { - /* We have success. */ - GtkWidget *dialog; - - dialog = gnome_ok_dialog(_("Component successfully updated.")); - gnome_dialog_run (GNOME_DIALOG(dialog)); - } - } else { - GtkWidget *dialog; - - dialog = gnome_ok_dialog(_("There was an error loading the calendar file.")); - gnome_dialog_run (GNOME_DIALOG(dialog)); - } - - gtk_object_unref (GTK_OBJECT (client)); - return; -} - -static void -update_calendar (EItipControlPrivate *priv) -{ - gchar cal_uri[255]; - CalClient *client; - - snprintf (cal_uri, 250, "%s/local/Calendar/calendar.ics", evolution_dir); - - client = cal_client_new (); - - gtk_signal_connect (GTK_OBJECT (client), "cal_opened", - GTK_SIGNAL_FUNC (cal_opened_cb), priv); - - if (cal_client_open_calendar (client, cal_uri, FALSE) == FALSE) { - GtkWidget *dialog; - - dialog = gnome_warning_dialog(_("I couldn't open your calendar file!\n")); - gnome_dialog_run (GNOME_DIALOG(dialog)); - gtk_object_unref (GTK_OBJECT (client)); - - return; - } - - gtk_progress_bar_update (GTK_PROGRESS_BAR (priv->loading_progress), 0.5); - gtk_widget_show (priv->loading_progress); - - return; -} - -static void -add_button_clicked_cb (GtkWidget *widget, gpointer data) -{ - EItipControlPrivate *priv = data; - - update_calendar (priv); - - return; -} - -static void -change_my_status (icalparameter_partstat status, EItipControlPrivate *priv) -{ - icalproperty *prop; - - prop = find_attendee (priv->comp, priv->my_address); - if (prop) { - icalparameter *param; - - icalproperty_remove_parameter (prop, ICAL_PARTSTAT_PARAMETER); - param = icalparameter_new_partstat (status); - icalproperty_add_parameter (prop, param); - } -} - -static void -send_itip_reply (EItipControlPrivate *priv) -{ - BonoboObjectClient *bonobo_server; - GNOME_Evolution_Composer composer_server; - CORBA_Environment ev; - GNOME_Evolution_Composer_RecipientList *to_list, *cc_list, *bcc_list; - GNOME_Evolution_Composer_Recipient *recipient; - CORBA_char *subject; - CalComponentText caltext; - CORBA_char *content_type, *filename, *description, *attach_data; - CORBA_boolean show_inline; - CORBA_char tempstr[200]; - - CORBA_exception_init (&ev); - - /* First, I obtain an object reference that represents the Composer. */ - bonobo_server = bonobo_object_activate (MAIL_COMPOSER_OAF_IID, 0); - - g_return_if_fail (bonobo_server != NULL); - - composer_server = bonobo_object_corba_objref (BONOBO_OBJECT (bonobo_server)); - - /* Now I have to make a CORBA sequence that represents a recipient list with - one item, for the organizer. */ - to_list = GNOME_Evolution_Composer_RecipientList__alloc (); - to_list->_maximum = 1; - to_list->_length = 1; - to_list->_buffer = CORBA_sequence_GNOME_Evolution_Composer_Recipient_allocbuf (1); - - recipient = &(to_list->_buffer[0]); - recipient->name = CORBA_string_alloc (0); /* FIXME: we may want an actual name here. */ - recipient->name[0] = '\0'; - recipient->address = CORBA_string_alloc (strlen (priv->organizer)); - strcpy (recipient->address, priv->organizer); - - cc_list = GNOME_Evolution_Composer_RecipientList__alloc (); - cc_list->_maximum = cc_list->_length = 0; - bcc_list = GNOME_Evolution_Composer_RecipientList__alloc (); - bcc_list->_maximum = bcc_list->_length = 0; - - cal_component_get_summary (priv->cal_comp, &caltext); - subject = CORBA_string_alloc (strlen (caltext.value)); - strcpy (subject, caltext.value); - - GNOME_Evolution_Composer_setHeaders (composer_server, to_list, cc_list, bcc_list, subject, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_printerr ("gui/e-meeting-edit.c: I couldn't set the composer headers via CORBA! Aagh.\n"); - CORBA_exception_free (&ev); - return; - } - - sprintf (tempstr, "text/calendar;METHOD=REPLY"); - content_type = CORBA_string_alloc (strlen (tempstr)); - strcpy (content_type, tempstr); - filename = CORBA_string_alloc (0); - filename[0] = '\0'; - sprintf (tempstr, "Calendar attachment"); - description = CORBA_string_alloc (strlen (tempstr)); - strcpy (description, tempstr); - show_inline = FALSE; - - /* I need to create an encapsulating iCalendar component, and stuff our reply event - into it. */ - { - icalcomponent *comp; - icalproperty *prop; - icalvalue *value; - gchar *ical_string; - - comp = icalcomponent_new (ICAL_VCALENDAR_COMPONENT); - - prop = icalproperty_new (ICAL_PRODID_PROPERTY); - value = icalvalue_new_text ("-//HelixCode/Evolution//EN"); - icalproperty_set_value (prop, value); - icalcomponent_add_property (comp, prop); - - prop = icalproperty_new (ICAL_VERSION_PROPERTY); - value = icalvalue_new_text ("2.0"); - icalproperty_set_value (prop, value); - icalcomponent_add_property (comp, prop); - - prop = icalproperty_new (ICAL_METHOD_PROPERTY); - value = icalvalue_new_text ("REPLY"); - icalproperty_set_value (prop, value); - icalcomponent_add_property (comp, prop); - - icalcomponent_remove_component (priv->main_comp, priv->comp); - icalcomponent_add_component (comp, priv->comp); - - ical_string = icalcomponent_as_ical_string (comp); - attach_data = CORBA_string_alloc (strlen (ical_string)); - strcpy (attach_data, ical_string); - - icalcomponent_remove_component (comp, priv->comp); - icalcomponent_add_component (priv->main_comp, priv->comp); - icalcomponent_free (comp); - - } - - GNOME_Evolution_Composer_attachData (composer_server, - content_type, filename, description, - show_inline, attach_data, - &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_printerr ("gui/e-meeting-edit.c: I couldn't attach data to the composer via CORBA! Aagh.\n"); - CORBA_exception_free (&ev); - return; - } - - GNOME_Evolution_Composer_show (composer_server, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_printerr ("gui/e-meeting-edit.c: I couldn't show the composer via CORBA! Aagh.\n"); - CORBA_exception_free (&ev); - return; - } - - CORBA_exception_free (&ev); - - /* Here is where we free our graciously-allocated memory. */ - if (CORBA_sequence_get_release (to_list) != FALSE) - CORBA_free (to_list->_buffer); - - CORBA_free (to_list); - CORBA_free (cc_list); - CORBA_free (bcc_list); - - CORBA_free (subject); - CORBA_free (content_type); - CORBA_free (filename); - CORBA_free (description); - CORBA_free (attach_data); - -} - -static void -accept_button_clicked_cb (GtkWidget *widget, gpointer data) -{ - EItipControlPrivate *priv = data; - - change_my_status (ICAL_PARTSTAT_ACCEPTED, priv); - send_itip_reply (priv); - update_calendar (priv); - - return; -} - -static void -tentative_button_clicked_cb (GtkWidget *widget, gpointer data) -{ - EItipControlPrivate *priv = data; - - change_my_status (ICAL_PARTSTAT_TENTATIVE, priv); - send_itip_reply (priv); - update_calendar (priv); - - return; -} - -static void -decline_button_clicked_cb (GtkWidget *widget, gpointer data) -{ - EItipControlPrivate *priv = data; - - change_my_status (ICAL_PARTSTAT_DECLINED, priv); - send_itip_reply (priv); - - return; -} - - -/******** - * load_calendar_store() opens and loads the calendar referred to by cal_uri - * and sets cal_client as a client for that store. If cal_uri is NULL, - * we load the default calendar URI. If all goes well, it returns TRUE; - * otherwise, it returns FALSE. - ********/ -static gboolean -load_calendar_store (char *cal_uri, CalClient **cal_client) -{ - char uri_buf[255]; - char *uri; - - if (cal_uri == NULL) { - snprintf (uri_buf, 250, "%s/local/Calendar/calendar.ics", evolution_dir); - uri = uri_buf; - } - else { - uri = cal_uri; - } - - *cal_client = cal_client_new (); - if (cal_client_open_calendar (*cal_client, uri, FALSE) == FALSE) { - return FALSE; - } - - /* FIXME!!!!!! This is fucking ugly. */ - - while (!cal_client_get_load_state (*cal_client) != CAL_CLIENT_LOAD_LOADED) { - gtk_main_iteration_do (FALSE); /* Do a non-blocking iteration. */ - usleep (200000L); /* Pause for 1/5th of a second before checking again.*/ - } - - return TRUE; -} - - -static void -update_reply_cb (GtkWidget *widget, gpointer data) -{ - EItipControlPrivate *priv = data; - CalClient *cal_client; - CalComponent *cal_comp; - icalcomponent *comp; - icalproperty *prop; - icalparameter *param; - const char *uid; - - if (load_calendar_store (NULL, &cal_client) == FALSE) { - GtkWidget *dialog; - - dialog = gnome_warning_dialog(_("I couldn't load your calendar file!\n")); - gnome_dialog_run (GNOME_DIALOG(dialog)); - gtk_object_unref (GTK_OBJECT (cal_client)); - - return; - } - - - cal_component_get_uid (priv->cal_comp, &uid); - if (cal_client_get_object (cal_client, uid, &cal_comp) != CAL_CLIENT_GET_SUCCESS) { - GtkWidget *dialog; - - dialog = gnome_warning_dialog(_("I couldn't read your calendar file!\n")); - gnome_dialog_run (GNOME_DIALOG(dialog)); - gtk_object_unref (GTK_OBJECT (cal_client)); - - return; - } - - comp = cal_component_get_icalcomponent (cal_comp); - - prop = find_attendee (comp, priv->from_address); - if (!prop) { - GtkWidget *dialog; - - dialog = gnome_warning_dialog(_("This is a reply from someone who was uninvited!")); - gnome_dialog_run (GNOME_DIALOG(dialog)); - gtk_object_unref (GTK_OBJECT (cal_client)); - gtk_object_unref (GTK_OBJECT (cal_comp)); - - return; - } - - icalproperty_remove_parameter (prop, ICAL_PARTSTAT_PARAMETER); - param = icalparameter_new_partstat (priv->new_partstat); - icalproperty_add_parameter (prop, param); - - /* Now we need to update the object in the calendar store. */ - if (!cal_client_update_object (cal_client, cal_comp)) { - GtkWidget *dialog; - - dialog = gnome_warning_dialog(_("I couldn't update your calendar store.")); - gnome_dialog_run (GNOME_DIALOG(dialog)); - gtk_object_unref (GTK_OBJECT (cal_client)); - gtk_object_unref (GTK_OBJECT (cal_comp)); - - return; - } - else { - /* We have success. */ - GtkWidget *dialog; - - dialog = gnome_ok_dialog(_("Component successfully updated.")); - gnome_dialog_run (GNOME_DIALOG(dialog)); - } - - - gtk_object_unref (GTK_OBJECT (cal_client)); - gtk_object_unref (GTK_OBJECT (cal_comp)); -} - -static void -cancel_meeting_cb (GtkWidget *widget, gpointer data) -{ - EItipControlPrivate *priv = data; - CalClient *cal_client; - const char *uid; - - if (load_calendar_store (NULL, &cal_client) == FALSE) { - GtkWidget *dialog; - - dialog = gnome_warning_dialog(_("I couldn't load your calendar file!\n")); - gnome_dialog_run (GNOME_DIALOG(dialog)); - gtk_object_unref (GTK_OBJECT (cal_client)); - - return; - } - - cal_component_get_uid (priv->cal_comp, &uid); - if (cal_client_remove_object (cal_client, uid) == FALSE) { - GtkWidget *dialog; - - dialog = gnome_warning_dialog(_("I couldn't delete the calendar component!\n")); - gnome_dialog_run (GNOME_DIALOG(dialog)); - gtk_object_unref (GTK_OBJECT (cal_client)); - - return; - } - else { - /* We have success! */ - GtkWidget *dialog; - - dialog = gnome_ok_dialog(_("Component successfully deleted.")); - gnome_dialog_run (GNOME_DIALOG(dialog)); - } - -} - - - -/* - * Bonobo::PersistStream - * - * These two functions implement the Bonobo::PersistStream load and - * save methods which allow data to be loaded into and out of the - * BonoboObject. - */ - -static char * -stream_read (Bonobo_Stream stream) -{ - Bonobo_Stream_iobuf *buffer; - CORBA_Environment ev; - gchar *data = NULL; - gint length = 0; - - CORBA_exception_init (&ev); - do { -#define READ_CHUNK_SIZE 65536 - Bonobo_Stream_read (stream, READ_CHUNK_SIZE, - &buffer, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - CORBA_exception_free (&ev); - return NULL; - } - - if (buffer->_length <= 0) - break; - - data = g_realloc (data, - length + buffer->_length); - - memcpy (data + length, - buffer->_buffer, buffer->_length); - - length += buffer->_length; - - CORBA_free (buffer); - } while (1); - - CORBA_free (buffer); - CORBA_exception_free (&ev); - - if (data == NULL) - data = g_strdup(""); - - return data; -} /* stream_read */ - -/* - * This function implements the Bonobo::PersistStream:load method. - */ -static void -pstream_load (BonoboPersistStream *ps, const Bonobo_Stream stream, - Bonobo_Persist_ContentType type, void *data, - CORBA_Environment *ev) -{ - EItipControlPrivate *priv = data; - gint pos, length, length2; - icalcompiter iter; - icalcomponent_kind comp_kind; - char message[256]; - - - if (type && g_strcasecmp (type, "text/calendar") != 0 && - g_strcasecmp (type, "text/x-calendar") != 0) { - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_Bonobo_Persist_WrongDataType, NULL); - return; - } - - if ((priv->vcalendar = stream_read (stream)) == NULL) { - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_Bonobo_Persist_FileNotFound, NULL); - return; - } - - /* Do something with the data, here. */ - - priv->main_comp = icalparser_parse_string (priv->vcalendar); - if (priv->main_comp == NULL) { - g_printerr ("e-itip-control.c: the iCalendar data was invalid!\n"); - return; - } - - iter = icalcomponent_begin_component (priv->main_comp, ICAL_ANY_COMPONENT); - priv->comp = icalcompiter_deref (&iter); - -#if 0 - { - FILE *fp; - - fp = fopen ("evo.debug", "w"); - - fputs ("The raw vCalendar data:\n\n", fp); - fputs (priv->vcalendar, fp); - - fputs ("The main component:\n\n", fp); - fputs (icalcomponent_as_ical_string (priv->main_comp), fp); - - fputs ("The child component:\n\n", fp); - fputs (icalcomponent_as_ical_string (priv->comp), fp); - - fclose (fp); - } -#endif - - if (priv->comp == NULL) { - g_printerr ("e-itip-control.c: I could not extract a proper component from\n" - " the vCalendar data.\n"); - icalcomponent_free (priv->main_comp); - return; - } - - comp_kind = icalcomponent_isa (priv->comp); - - switch (comp_kind) { - case ICAL_VEVENT_COMPONENT: - case ICAL_VTODO_COMPONENT: - case ICAL_VJOURNAL_COMPONENT: - priv->cal_comp = cal_component_new (); - if (cal_component_set_icalcomponent (priv->cal_comp, priv->comp) == FALSE) { - g_printerr ("e-itip-control.c: I couldn't create a CalComponent from the iTip data.\n"); - gtk_object_unref (GTK_OBJECT (priv->cal_comp)); - } - break; - case ICAL_VFREEBUSY_COMPONENT: - /* Take care of busy time information. */ - return; - break; - default: - /* We don't know what this is, so bail. */ - { - GtkWidget *dialog; - - dialog = gnome_warning_dialog(_("I don't recognize this type of calendar component.")); - gnome_dialog_run (GNOME_DIALOG(dialog)); - - g_free (priv->vcalendar); - priv->vcalendar = NULL; - - return; - } - break; - } /* End switch. */ - - - /* Okay, good then; now I will pick apart the component to get - all the things I'll show in my control. */ - { - icalproperty *prop; - const char *description, *summary; - const char *new_text; - const char *organizer; - struct icaltimetype dtstart, dtend; - time_t tstart, tend; - - prop = icalcomponent_get_first_property (priv->comp, ICAL_ORGANIZER_PROPERTY); - if (prop) { - organizer = icalproperty_get_organizer (prop); - - /* Here I strip off the "MAILTO:" if it is present. */ - new_text = strchr (organizer, ':'); - if (new_text != NULL) - new_text++; - else - new_text = organizer; - - priv->organizer = g_strdup (new_text); - gtk_entry_set_text (GTK_ENTRY (priv->organizer_entry), new_text); - } - - prop = icalcomponent_get_first_property (priv->comp, ICAL_SUMMARY_PROPERTY); - if (prop) { - summary = icalproperty_get_summary (prop); - gtk_entry_set_text (GTK_ENTRY (priv->summary_entry), summary); - } - - prop = icalcomponent_get_first_property (priv->comp, ICAL_DESCRIPTION_PROPERTY); - if (prop) { - description = icalproperty_get_summary (prop); - - pos = 0; - length = strlen (description); - length2 = strlen (gtk_editable_get_chars - (GTK_EDITABLE (priv->description_box), 0, -1)); - - if (length2 > 0) - gtk_editable_delete_text (GTK_EDITABLE (priv->description_box), 0, length2); - - gtk_editable_insert_text (GTK_EDITABLE (priv->description_box), - description, - length, - &pos); - } - - prop = icalcomponent_get_first_property (priv->comp, ICAL_DTSTART_PROPERTY); - dtstart = icalproperty_get_dtstart (prop); - prop = icalcomponent_get_first_property (priv->comp, ICAL_DTEND_PROPERTY); - dtend = icalproperty_get_dtend (prop); - - tstart = icaltime_as_timet (dtstart); - tend = icaltime_as_timet (dtend); - - gtk_label_set_text (GTK_LABEL (priv->dtstart_label), ctime (&tstart)); - gtk_label_set_text (GTK_LABEL (priv->dtend_label), ctime (&tend)); - - /* Clear out any old-assed text that's been lying around in my message box. */ - gtk_editable_delete_text (GTK_EDITABLE (priv->message_text), 0, -1); - - prop = icalcomponent_get_first_property (priv->main_comp, ICAL_METHOD_PROPERTY); - switch (icalproperty_get_method (prop)) { - case ICAL_METHOD_PUBLISH: - { - GtkWidget *button; - - snprintf (message, 250, "%s has published calendar information, " - "which you can add to your own calendar. " - "No reply is necessary.", - priv->from_address); - - button = gtk_button_new_with_label (_("Add to Calendar")); - gtk_box_pack_start (GTK_BOX (priv->button_box), button, FALSE, FALSE, 3); - gtk_widget_show (button); - - gtk_signal_connect (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (add_button_clicked_cb), priv); - - break; - } - case ICAL_METHOD_REQUEST: - { - /* I'll check if I have to rsvp. */ - icalproperty *prop; - icalparameter *param; - int rsvp = FALSE; - - prop = find_attendee (priv->comp, priv->my_address); - if (prop) { - param = get_icalparam_by_type (prop, ICAL_RSVP_PARAMETER); - - if (param) { - if (icalparameter_get_rsvp (param)) - rsvp = TRUE; - } - } - - snprintf (message, 250, "This is a meeting organized by %s, " - "who indicated that you %s RSVP.", - (priv->organizer ? priv->organizer : "an unknown person"), - (rsvp ? "should" : "don't have to") ); - - if (rsvp) { - GtkWidget *accept_button, *decline_button, *tentative_button; - - accept_button = gtk_button_new_with_label (_("Accept")); - decline_button = gtk_button_new_with_label (_("Decline")); - tentative_button = gtk_button_new_with_label (_("Tentative")); - - gtk_box_pack_start (GTK_BOX (priv->button_box), accept_button, FALSE, FALSE, 3); - gtk_box_pack_start (GTK_BOX (priv->button_box), decline_button, FALSE, FALSE, 3); - gtk_box_pack_start (GTK_BOX (priv->button_box), tentative_button, FALSE, FALSE, 3); - - gtk_signal_connect (GTK_OBJECT (accept_button), "clicked", - GTK_SIGNAL_FUNC (accept_button_clicked_cb), priv); - gtk_signal_connect (GTK_OBJECT (tentative_button), "clicked", - GTK_SIGNAL_FUNC (tentative_button_clicked_cb), priv); - gtk_signal_connect (GTK_OBJECT (decline_button), "clicked", - GTK_SIGNAL_FUNC (decline_button_clicked_cb), priv); - - gtk_widget_show (accept_button); - gtk_widget_show (decline_button); - gtk_widget_show (tentative_button); - } - - } - break; - case ICAL_METHOD_REPLY: - { - icalproperty *prop; - icalparameter *param; - gboolean success = FALSE; - - prop = find_attendee (priv->comp, priv->from_address); - if (prop) { - param = get_icalparam_by_type (prop, ICAL_PARTSTAT_PARAMETER); - if (param) { - success = TRUE; - - priv->new_partstat = icalparameter_get_partstat (param); - } - } - - if (!success) { - snprintf (message, 250, "%s sent a reply to a meeting request, but " - "the reply is not properly formed.", - priv->from_address); - } - else { - GtkWidget *button; - - button = gtk_button_new_with_label (_("Update Calendar")); - gtk_box_pack_start (GTK_BOX (priv->button_box), button, FALSE, FALSE, 3); - gtk_widget_show (button); - - gtk_signal_connect (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (update_reply_cb), priv); - - snprintf (message, 250, "%s responded to your request, replying with: %s", - priv->from_address, partstat_values[priv->new_partstat]); - } - - } - break; - case ICAL_METHOD_CANCEL: - { - if (strcmp (priv->organizer, priv->from_address) != 0) { - snprintf (message, 250, "%s sent a cancellation request, but is not " - "the organizer of the meeting.", - priv->from_address); - } - else { - GtkWidget *button; - - button = gtk_button_new_with_label (_("Cancel Meeting")); - gtk_box_pack_start (GTK_BOX (priv->button_box), button, FALSE, FALSE, 3); - gtk_widget_show (button); - - gtk_signal_connect (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (cancel_meeting_cb), priv); - - snprintf (message, 250, "%s sent a cancellation request. You can" - " delete this event from your calendar, if you wish.", - priv->organizer); - } - - } - break; - default: - snprintf (message, 250, "I haven't the slightest notion what this calendar " - "object represents. Sorry."); - } - - { - int pos = 0; - - gtk_editable_insert_text (GTK_EDITABLE (priv->message_text), message, - strlen (message), &pos); - } - } - -} /* pstream_load */ - -/* - * This function implements the Bonobo::PersistStream:save method. - */ -static void -pstream_save (BonoboPersistStream *ps, const Bonobo_Stream stream, - Bonobo_Persist_ContentType type, void *data, - CORBA_Environment *ev) -{ - EItipControlPrivate *priv = data; - int length; - - if (type && g_strcasecmp (type, "text/calendar") != 0 && - g_strcasecmp (type, "text/x-calendar") != 0) { - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_Bonobo_Persist_WrongDataType, NULL); - return; - } - - /* Put something into vcalendar here. */ - length = strlen (priv->vcalendar); - - bonobo_stream_client_write (stream, priv->vcalendar, length, ev); -} /* pstream_save */ - -static CORBA_long -pstream_get_max_size (BonoboPersistStream *ps, void *data, - CORBA_Environment *ev) -{ - EItipControlPrivate *priv = data; - - if (priv->vcalendar) - return strlen (priv->vcalendar); - else - return 0L; -} - -static Bonobo_Persist_ContentTypeList * -pstream_get_content_types (BonoboPersistStream *ps, void *closure, - CORBA_Environment *ev) -{ - return bonobo_persist_generate_content_types (2, "text/calendar", "text/x-calendar"); -} - -static void -get_prop ( BonoboPropertyBag *bag, - BonoboArg *arg, - guint arg_id, - CORBA_Environment *ev, - gpointer user_data) -{ - EItipControlPrivate *priv = user_data; - - if (arg_id == FROM_ADDRESS_ARG_ID) { - BONOBO_ARG_SET_STRING (arg, priv->from_address); - } - else if (arg_id == MY_ADDRESS_ARG_ID) { - BONOBO_ARG_SET_STRING (arg, priv->my_address); - } -} - -static void -set_prop ( BonoboPropertyBag *bag, - const BonoboArg *arg, - guint arg_id, - CORBA_Environment *ev, - gpointer user_data) -{ - EItipControlPrivate *priv = user_data; - - if (arg_id == FROM_ADDRESS_ARG_ID) { - if (priv->from_address) - g_free (priv->from_address); - - - priv->from_address = g_strdup (BONOBO_ARG_GET_STRING (arg)); - - /* Let's set the widget here, though I'm not sure if - it will work. */ - gtk_entry_set_text (GTK_ENTRY (priv->address_entry), priv->from_address); - - } - else if (arg_id == MY_ADDRESS_ARG_ID) { - if (priv->my_address) - g_free (priv->my_address); - - priv->my_address = g_strdup (BONOBO_ARG_GET_STRING (arg)); - } -} - - -static BonoboObject * -e_itip_control_factory (BonoboGenericFactory *Factory, void *closure) -{ - BonoboControl *control; - BonoboPropertyBag *prop_bag; - BonoboPersistStream *stream; - EItipControlPrivate *priv; - - priv = g_new0 (EItipControlPrivate, 1); - - priv->xml = glade_xml_new (EVOLUTION_GLADEDIR "/" "e-itip-control.glade", "main_frame"); - - /* Create the control. */ - priv->main_frame = glade_xml_get_widget (priv->xml, "main_frame"); - priv->organizer_entry = glade_xml_get_widget (priv->xml, "organizer_entry"); - priv->dtstart_label = glade_xml_get_widget (priv->xml, "dtstart_label"); - priv->dtend_label = glade_xml_get_widget (priv->xml, "dtend_label"); - priv->summary_entry = glade_xml_get_widget (priv->xml, "summary_entry"); - priv->description_box = glade_xml_get_widget (priv->xml, "description_box"); - /* priv->add_button = glade_xml_get_widget (priv->xml, "add_button"); */ - priv->button_box = glade_xml_get_widget (priv->xml, "button_box"); - priv->address_entry = glade_xml_get_widget (priv->xml, "address_entry"); - priv->message_text = glade_xml_get_widget (priv->xml, "message_text"); - - gtk_text_set_word_wrap (GTK_TEXT (priv->message_text), TRUE); - - priv->xml2 = glade_xml_new (EVOLUTION_GLADEDIR "/" "e-itip-control.glade", "loading_window"); - priv->loading_progress = glade_xml_get_widget (priv->xml2, "loading_progress"); - priv->loading_window = glade_xml_get_widget (priv->xml2, "loading_window"); - - gtk_signal_connect (GTK_OBJECT (priv->main_frame), "destroy", - GTK_SIGNAL_FUNC (itip_control_destroy_cb), priv); - - gtk_widget_show (priv->main_frame); - - control = bonobo_control_new (priv->main_frame); - - /* create a property bag */ - prop_bag = bonobo_property_bag_new ( get_prop, set_prop, priv ); - bonobo_control_set_properties (control, prop_bag); - - bonobo_property_bag_add (prop_bag, "from_address", FROM_ADDRESS_ARG_ID, BONOBO_ARG_STRING, NULL, - "from_address", 0 ); - bonobo_property_bag_add (prop_bag, "my_address", MY_ADDRESS_ARG_ID, BONOBO_ARG_STRING, NULL, - "my_address", 0 ); - - bonobo_control_set_automerge (control, TRUE); - - stream = bonobo_persist_stream_new (pstream_load, pstream_save, - pstream_get_max_size, - pstream_get_content_types, - priv); - - if (stream == NULL) { - bonobo_object_unref (BONOBO_OBJECT (control)); - return NULL; - } - - bonobo_object_add_interface (BONOBO_OBJECT (control), - BONOBO_OBJECT (stream)); - - return BONOBO_OBJECT (control); -} - -void -e_itip_control_factory_init (void) -{ - static BonoboGenericFactory *factory = NULL; - - if (factory != NULL) - return; - - factory = bonobo_generic_factory_new ( - "OAFIID:GNOME_Evolution_Calendar_iTip_ControlFactory", - e_itip_control_factory, NULL); - - if (factory == NULL) - g_error ("I could not register an iTip control factory."); -} - diff --git a/calendar/gui/e-itip-control.glade b/calendar/gui/e-itip-control.glade deleted file mode 100644 index eb950139a1..0000000000 --- a/calendar/gui/e-itip-control.glade +++ /dev/null @@ -1,510 +0,0 @@ -<?xml version="1.0"?> -<GTK-Interface> - -<project> - <name>e-itip-control</name> - <program_name>e-itip-control</program_name> - <directory></directory> - <source_directory>src</source_directory> - <pixmaps_directory>pixmaps</pixmaps_directory> - <language>C</language> - <gnome_support>True</gnome_support> - <gettext_support>True</gettext_support> -</project> - -<widget> - <class>GtkWindow</class> - <name>window1</name> - <visible>False</visible> - <title>window1</title> - <type>GTK_WINDOW_TOPLEVEL</type> - <position>GTK_WIN_POS_NONE</position> - <modal>False</modal> - <allow_shrink>False</allow_shrink> - <allow_grow>True</allow_grow> - <auto_shrink>False</auto_shrink> - - <widget> - <class>GtkFrame</class> - <name>main_frame</name> - <border_width>4</border_width> - <label>Calendar Message</label> - <label_xalign>0.11</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - - <widget> - <class>GtkScrolledWindow</class> - <name>scrolledwindow1</name> - <hscrollbar_policy>GTK_POLICY_NEVER</hscrollbar_policy> - <vscrollbar_policy>GTK_POLICY_NEVER</vscrollbar_policy> - <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy> - <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy> - - <widget> - <class>GtkViewport</class> - <name>viewport1</name> - <shadow_type>GTK_SHADOW_IN</shadow_type> - - <widget> - <class>GtkVBox</class> - <name>vbox1</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - - <widget> - <class>GtkTable</class> - <name>table1</name> - <rows>5</rows> - <columns>2</columns> - <homogeneous>False</homogeneous> - <row_spacing>0</row_spacing> - <column_spacing>9</column_spacing> - <child> - <padding>6</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkEntry</class> - <name>organizer_entry</name> - <can_focus>True</can_focus> - <editable>False</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>summary_entry</name> - <can_focus>True</can_focus> - <editable>False</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>2</top_attach> - <bottom_attach>3</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkScrolledWindow</class> - <name>scrolledwindow2</name> - <hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy> - <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy> - <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy> - <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>3</top_attach> - <bottom_attach>4</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkText</class> - <name>description_box</name> - <can_focus>True</can_focus> - <editable>False</editable> - <text></text> - </widget> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label7</name> - <label>Date:</label> - <justify>GTK_JUSTIFY_RIGHT</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label6</name> - <label>Organizer:</label> - <justify>GTK_JUSTIFY_RIGHT</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label8</name> - <label>Summary:</label> - <justify>GTK_JUSTIFY_RIGHT</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>2</top_attach> - <bottom_attach>3</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label9</name> - <label>Description:</label> - <justify>GTK_JUSTIFY_RIGHT</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>3</top_attach> - <bottom_attach>4</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkAlignment</class> - <name>alignment1</name> - <xalign>0</xalign> - <yalign>0</yalign> - <xscale>1</xscale> - <yscale>1</yscale> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkHBox</class> - <name>hbox1</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - - <widget> - <class>GtkLabel</class> - <name>dtstart_label</name> - <label>date-start</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label3</name> - <label>--to--</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0</yalign> - <xpad>19</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>dtend_label</name> - <label>date-end</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label11</name> - <label>Sender</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>4</top_attach> - <bottom_attach>5</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>address_entry</name> - <can_focus>True</can_focus> - <editable>False</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>4</top_attach> - <bottom_attach>5</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - </widget> - - <widget> - <class>GtkScrolledWindow</class> - <name>scrolledwindow3</name> - <border_width>3</border_width> - <width>365</width> - <hscrollbar_policy>GTK_POLICY_NEVER</hscrollbar_policy> - <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy> - <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy> - <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkText</class> - <name>message_text</name> - <can_focus>True</can_focus> - <editable>False</editable> - <text></text> - </widget> - </widget> - - <widget> - <class>GtkHBox</class> - <name>button_box</name> - <border_width>3</border_width> - <height>30</height> - <homogeneous>False</homogeneous> - <spacing>8</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>Placeholder</class> - </widget> - </widget> - </widget> - </widget> - </widget> - </widget> -</widget> - -<widget> - <class>GtkWindow</class> - <name>loading_window</name> - <visible>False</visible> - <title>Loading Calendar</title> - <type>GTK_WINDOW_DIALOG</type> - <position>GTK_WIN_POS_CENTER</position> - <modal>False</modal> - <allow_shrink>False</allow_shrink> - <allow_grow>True</allow_grow> - <auto_shrink>False</auto_shrink> - - <widget> - <class>GtkFrame</class> - <name>frame1</name> - <border_width>4</border_width> - <label></label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_OUT</shadow_type> - - <widget> - <class>GtkVBox</class> - <name>vbox2</name> - <border_width>7</border_width> - <homogeneous>False</homogeneous> - <spacing>1</spacing> - - <widget> - <class>GtkHBox</class> - <name>hbox2</name> - <border_width>6</border_width> - <homogeneous>False</homogeneous> - <spacing>9</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label10</name> - <label>Loading calendar...</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkProgressBar</class> - <name>loading_progress</name> - <value>0</value> - <lower>0</lower> - <upper>100</upper> - <bar_style>GTK_PROGRESS_CONTINUOUS</bar_style> - <orientation>GTK_PROGRESS_LEFT_TO_RIGHT</orientation> - <activity_mode>False</activity_mode> - <show_text>False</show_text> - <format>%P %%</format> - <text_xalign>0.5</text_xalign> - <text_yalign>0.5</text_yalign> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> - </widget> - </widget> -</widget> - -</GTK-Interface> diff --git a/calendar/gui/e-itip-control.h b/calendar/gui/e-itip-control.h deleted file mode 100644 index 6c2df626ce..0000000000 --- a/calendar/gui/e-itip-control.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Evolution calendar - Control for displaying iTIP mail messages - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Jesse Pavel <jpavel@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef __E_ITIP_CONTROL_H__ -#define __E_ITIP_CONTROL_H__ - -#include <bonobo/bonobo-control.h> - -void e_itip_control_factory_init (void); - -#endif /* __E_ITIP_CONTROL_H__ */ diff --git a/calendar/gui/e-meeting-dialog.glade b/calendar/gui/e-meeting-dialog.glade deleted file mode 100644 index 5b9a057f46..0000000000 --- a/calendar/gui/e-meeting-dialog.glade +++ /dev/null @@ -1,489 +0,0 @@ -<?xml version="1.0"?> -<GTK-Interface> - -<project> - <name>e-meeting-dialog</name> - <program_name>e-meeting-dialog</program_name> - <directory></directory> - <source_directory>src</source_directory> - <pixmaps_directory>pixmaps</pixmaps_directory> - <language>C</language> - <gnome_support>True</gnome_support> - <gettext_support>True</gettext_support> -</project> - -<widget> - <class>GtkWindow</class> - <name>meeting_window</name> - <width>486</width> - <height>330</height> - <visible>False</visible> - <title>Meeting Invitations</title> - <type>GTK_WINDOW_DIALOG</type> - <position>GTK_WIN_POS_NONE</position> - <modal>True</modal> - <allow_shrink>False</allow_shrink> - <allow_grow>True</allow_grow> - <auto_shrink>False</auto_shrink> - - <widget> - <class>GtkVBox</class> - <name>vbox1</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - - <widget> - <class>GtkToolbar</class> - <name>toolbar1</name> - <orientation>GTK_ORIENTATION_HORIZONTAL</orientation> - <type>GTK_TOOLBAR_BOTH</type> - <space_size>5</space_size> - <space_style>GTK_TOOLBAR_SPACE_LINE</space_style> - <relief>GTK_RELIEF_NORMAL</relief> - <tooltips>True</tooltips> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkButton</class> - <child_name>Toolbar:button</child_name> - <name>publish_button</name> - <label>Publish -Event</label> - <stock_pixmap>GNOME_STOCK_PIXMAP_MAIL_SND</stock_pixmap> - </widget> - - <widget> - <class>GtkVSeparator</class> - <name>vseparator1</name> - <width>13</width> - <height>58</height> - </widget> - - <widget> - <class>GtkButton</class> - <child_name>Toolbar:button</child_name> - <name>request_button</name> - <label>Request -Meeting</label> - <stock_pixmap>GNOME_STOCK_PIXMAP_REFRESH</stock_pixmap> - </widget> - - <widget> - <class>GtkVSeparator</class> - <name>vseparator3</name> - <width>13</width> - <height>58</height> - </widget> - - <widget> - <class>GtkButton</class> - <child_name>Toolbar:button</child_name> - <name>cancel_button</name> - <label>Cancel -Meeting</label> - <stock_pixmap>GNOME_STOCK_PIXMAP_CLOSE</stock_pixmap> - </widget> - - <widget> - <class>GtkVSeparator</class> - <name>vseparator2</name> - <width>12</width> - <height>58</height> - </widget> - - <widget> - <class>GtkButton</class> - <child_name>Toolbar:button</child_name> - <name>schedule_button</name> - <label>Schedule -Time</label> - <stock_pixmap>GNOME_STOCK_PIXMAP_MULTIPLE</stock_pixmap> - </widget> - </widget> - - <widget> - <class>GtkHBox</class> - <name>hbox3</name> - <border_width>3</border_width> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - <child> - <padding>4</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label3</name> - <label>Organizer: </label> - <justify>GTK_JUSTIFY_RIGHT</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>3</xpad> - <ypad>0</ypad> - <child> - <padding>1</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>organizer_entry</name> - <width>252</width> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - </widget> - </widget> - - <widget> - <class>GtkHBox</class> - <name>hbox1</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - <pack>GTK_PACK_END</pack> - </child> - - <widget> - <class>GtkLabel</class> - <name>label1</name> - <label>Attendees: </label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <padding>4</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkHButtonBox</class> - <name>hbuttonbox3</name> - <layout_style>GTK_BUTTONBOX_START</layout_style> - <spacing>0</spacing> - <child_min_width>83</child_min_width> - <child_min_height>29</child_min_height> - <child_ipad_x>8</child_ipad_x> - <child_ipad_y>1</child_ipad_y> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkButton</class> - <name>add_button</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <label>Add</label> - </widget> - - <widget> - <class>GtkButton</class> - <name>delete_button</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <label>Delete</label> - </widget> - - <widget> - <class>GtkButton</class> - <name>edit_button</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <label>Edit</label> - </widget> - </widget> - </widget> - - <widget> - <class>GtkScrolledWindow</class> - <name>scrolledwindow1</name> - <hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy> - <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy> - <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy> - <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkCList</class> - <name>attendee_list</name> - <can_focus>True</can_focus> - <columns>4</columns> - <column_widths>145,141,60,80</column_widths> - <selection_mode>GTK_SELECTION_SINGLE</selection_mode> - <show_titles>True</show_titles> - <shadow_type>GTK_SHADOW_IN</shadow_type> - - <widget> - <class>GtkLabel</class> - <child_name>CList:title</child_name> - <name>label8</name> - <label>Attendee</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - - <widget> - <class>GtkLabel</class> - <child_name>CList:title</child_name> - <name>label5</name> - <label>Role</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - - <widget> - <class>GtkLabel</class> - <child_name>CList:title</child_name> - <name>label6</name> - <label>RSVP</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - - <widget> - <class>GtkLabel</class> - <child_name>CList:title</child_name> - <name>label7</name> - <label>Status</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - </widget> - </widget> - </widget> -</widget> - -<widget> - <class>GnomeDialog</class> - <name>edit_dialog</name> - <width>344</width> - <height>152</height> - <visible>False</visible> - <title>Attendee</title> - <type>GTK_WINDOW_DIALOG</type> - <position>GTK_WIN_POS_MOUSE</position> - <modal>True</modal> - <allow_shrink>False</allow_shrink> - <allow_grow>False</allow_grow> - <auto_shrink>False</auto_shrink> - <auto_close>False</auto_close> - <hide_on_close>False</hide_on_close> - - <widget> - <class>GtkVBox</class> - <child_name>GnomeDialog:vbox</child_name> - <name>dialog-vbox1</name> - <homogeneous>False</homogeneous> - <spacing>8</spacing> - <child> - <padding>4</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkHButtonBox</class> - <child_name>GnomeDialog:action_area</child_name> - <name>dialog-action_area1</name> - <layout_style>GTK_BUTTONBOX_SPREAD</layout_style> - <spacing>8</spacing> - <child_min_width>85</child_min_width> - <child_min_height>27</child_min_height> - <child_ipad_x>7</child_ipad_x> - <child_ipad_y>0</child_ipad_y> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - <pack>GTK_PACK_END</pack> - </child> - - <widget> - <class>GtkButton</class> - <name>button1</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <stock_button>GNOME_STOCK_BUTTON_OK</stock_button> - </widget> - - <widget> - <class>GtkButton</class> - <name>button3</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button> - </widget> - </widget> - - <widget> - <class>GtkHBox</class> - <name>hbox2</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label2</name> - <label>Attendee address</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>6</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>address_entry</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - </widget> - </widget> - - <widget> - <class>GtkHBox</class> - <name>hbox4</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label9</name> - <label>Role</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>5</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkCombo</class> - <name>role_combo</name> - <width>160</width> - <value_in_list>False</value_in_list> - <ok_if_empty>True</ok_if_empty> - <case_sensitive>False</case_sensitive> - <use_arrows>True</use_arrows> - <use_arrows_always>False</use_arrows_always> - <items>Chair -Required Participant -Optional Participant -Non-Participant -Other - - -</items> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkEntry</class> - <child_name>GtkCombo:entry</child_name> - <name>role_entry</name> - <can_focus>True</can_focus> - <editable>False</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text>Required Participant</text> - </widget> - </widget> - - <widget> - <class>GtkCheckButton</class> - <name>rsvp_check</name> - <can_focus>True</can_focus> - <label>RSVP</label> - <active>True</active> - <draw_indicator>True</draw_indicator> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>False</fill> - </child> - </widget> - </widget> - </widget> -</widget> - -</GTK-Interface> diff --git a/calendar/gui/e-meeting-edit.c b/calendar/gui/e-meeting-edit.c deleted file mode 100644 index 934c284ae7..0000000000 --- a/calendar/gui/e-meeting-edit.c +++ /dev/null @@ -1,992 +0,0 @@ -/* Evolution calendar - Meeting editor dialog - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Jesse Pavel <jpavel@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#include <config.h> -#include <bonobo.h> -#include <glade/glade.h> -#include <ical.h> -#include <widgets/meeting-time-sel/e-meeting-time-sel.h> -#include <Evolution-Composer.h> -#include <string.h> -#include "e-meeting-edit.h" -#include "itip-utils.h" - -#define E_MEETING_GLADE_XML "e-meeting-dialog.glade" - - -typedef struct _EMeetingEditorPrivate EMeetingEditorPrivate; - -struct _EMeetingEditorPrivate { - /* These are the widgets to be used in the GUI. */ - GladeXML *xml; - GtkWidget *meeting_window; - GtkWidget *attendee_list; - GtkWidget *address_entry; - GtkWidget *edit_dialog; - GtkWidget *organizer_entry; - GtkWidget *role_entry; - GtkWidget *rsvp_check; - GtkWidget *publish_button, *request_button, *cancel_button, - *schedule_button; - - gint changed_signal_id; - - /* Various pieces of information. */ - gint selected_row; - CalComponent *comp; - CalClient *client; - icalcomponent *icalcomp, *vevent; - - gint numentries; /* How many attendees are there? */ - gboolean dirty; /* Has anything changed? */ -}; - -#define NUM_COLUMNS 4 /* The number of columns in our attendee list. */ - -enum column_names {ADDRESS_COL, ROLE_COL, RSVP_COL, STATUS_COL}; - - -static void -save_organizer (EMeetingEditorPrivate *priv) -{ - icalproperty *prop; - icalvalue *value; - gchar *text; - - /* Save the organizer into the iCAL object. */ - - text = gtk_entry_get_text (GTK_ENTRY (priv->organizer_entry)); - if (strlen (text) > 0) { - gchar buffer[200]; - g_snprintf (buffer, 190, "MAILTO:%s", text); - - prop = icalcomponent_get_first_property (priv->vevent, ICAL_ORGANIZER_PROPERTY); - if (prop == NULL) { - /* We need to add an ORGANIZER property. */ - prop = icalproperty_new (ICAL_ORGANIZER_PROPERTY); - icalcomponent_add_property (priv->vevent, prop); - } - value = icalvalue_new_text (buffer); - icalproperty_set_value (prop, value); - } -} - - - -static gboolean -window_delete_cb (GtkWidget *widget, - GdkEvent *event, - gpointer data) -{ - EMeetingEditorPrivate *priv; - - priv = (EMeetingEditorPrivate *) ((EMeetingEditor *)data)->priv; - - save_organizer (priv); - - if (priv->dirty == TRUE) { - /* FIXME: notify the event editor that our data has changed. - For now, I'll just display a dialog box. */ - { - if (!cal_client_update_object (priv->client, priv->comp)) { - GtkWidget *dialog; - - dialog = gnome_warning_dialog_parented ("I couldn't automatically save this meeting,\n" - "so try to save this event manually.", - GTK_WINDOW (priv->meeting_window)); - gnome_dialog_run (GNOME_DIALOG(dialog)); - } - } - } - - gtk_entry_set_text (GTK_ENTRY (priv->organizer_entry), ""); - - return (FALSE); -} - -static void -window_destroy_cb (GtkWidget *widget, - gpointer data) -{ - EMeetingEditorPrivate *priv; - - priv = (EMeetingEditorPrivate *) ((EMeetingEditor *)data)->priv; - - gtk_main_quit (); - return; -} - -/* put_property_in_list() synchronizes the display of row `rownum' - in our attendee list to the values of `prop'. If rownum < 0, - then put_property_in_list() will append a new row. - If the property doesn't contain certain parameters that we deem - necessary, it will add them. */ -static void -put_property_in_list (icalproperty *prop, gint rownum, gpointer data) -{ - gchar *row_text[NUM_COLUMNS]; - gchar *text, *new_text; - icalparameter *param; - icalvalue *value; - gint enumval; - gint cntr; - - EMeetingEditorPrivate *priv; - - priv = (EMeetingEditorPrivate *) ((EMeetingEditor *)data)->priv; - - value = icalproperty_get_value (prop); - - if (value != NULL) { - text = strdup (icalvalue_as_ical_string (value)); - - /* Here I strip off the "MAILTO:" if it is present. */ - new_text = strchr (text, ':'); - if (new_text != NULL) - new_text++; - else - new_text = text; - - row_text[ADDRESS_COL] = g_strdup (new_text); - g_free (text); - } - - param = get_icalparam_by_type (prop, ICAL_ROLE_PARAMETER); - if (param == NULL) { - param = icalparameter_new_role (ICAL_ROLE_REQPARTICIPANT); - icalproperty_add_parameter (prop, param); - } - - enumval = icalparameter_get_role (param); - if (enumval < 0 || enumval > 4) - enumval = 4; - - row_text[ROLE_COL] = role_values [enumval]; - - param = get_icalparam_by_type (prop, ICAL_RSVP_PARAMETER); - if (param == NULL) { - param = icalparameter_new_rsvp (TRUE); - icalproperty_add_parameter (prop, param); - } - - if (icalparameter_get_rsvp (param)) - row_text[RSVP_COL] = "Y"; - else - row_text[RSVP_COL] = "N"; - - param = get_icalparam_by_type (prop, ICAL_PARTSTAT_PARAMETER); - if (param == NULL) { - param = icalparameter_new_partstat (ICAL_PARTSTAT_NEEDSACTION); - icalproperty_add_parameter (prop, param); - } - - enumval = icalparameter_get_partstat (param); - if (enumval < 0 || enumval > 7) { - enumval = 7; - } - - row_text[STATUS_COL] = partstat_values [enumval]; - - if (rownum < 0) { - gtk_clist_append (GTK_CLIST (priv->attendee_list), row_text); - gtk_clist_set_row_data (GTK_CLIST (priv->attendee_list), priv->numentries, prop); - priv->numentries++; - } - else { - for (cntr = 0; cntr < NUM_COLUMNS; cntr++) { - gtk_clist_set_text (GTK_CLIST (priv->attendee_list), - rownum, - cntr, - row_text[cntr]); - } - } - - g_free (row_text[ADDRESS_COL]); -} - - - -/******** - * edit_attendee() performs the GUI manipulation and interaction for - * editing `prop' and returns TRUE if the user indicated that he wants - * to save the new property information. - * - * Note that it is necessary that the property have parameters of the types - * RSVP, PARTSTAT, and ROLE already when passed into this function. - ********/ -static gboolean -edit_attendee (icalproperty *prop, gpointer data) -{ - EMeetingEditorPrivate *priv; - gint button_num; - gchar *new_text, *text; - icalparameter *param; - icalvalue *value; - gchar buffer[200]; - gint cntr; - gint enumval; - gboolean retval; - - priv = (EMeetingEditorPrivate *) ((EMeetingEditor *)data)->priv; - - g_return_val_if_fail (prop != NULL, FALSE); - - if (priv->edit_dialog == NULL || priv->address_entry == NULL) { - priv->edit_dialog = glade_xml_get_widget (priv->xml, "edit_dialog"); - priv->address_entry = glade_xml_get_widget (priv->xml, "address_entry"); - - gnome_dialog_set_close (GNOME_DIALOG (priv->edit_dialog), TRUE); - gnome_dialog_editable_enters (GNOME_DIALOG (priv->edit_dialog), - GTK_EDITABLE (priv->address_entry)); - gnome_dialog_close_hides (GNOME_DIALOG (priv->edit_dialog), TRUE); - gnome_dialog_set_default (GNOME_DIALOG (priv->edit_dialog), 0); - } - - g_return_val_if_fail (priv->edit_dialog != NULL, FALSE); - g_return_val_if_fail (priv->address_entry != NULL, FALSE); - - gtk_widget_realize (priv->edit_dialog); - - value = icalproperty_get_value (prop); - - if (value != NULL) { - text = strdup (icalvalue_as_ical_string (value)); - - /* Here I strip off the "MAILTO:" if it is present. */ - new_text = strchr (text, ':'); - if (new_text != NULL) - new_text++; - else - new_text = text; - - gtk_entry_set_text (GTK_ENTRY (priv->address_entry), new_text); - g_free (text); - } - else { - gtk_entry_set_text (GTK_ENTRY (priv->address_entry), ""); - } - - - param = get_icalparam_by_type (prop, ICAL_ROLE_PARAMETER); - enumval = icalparameter_get_role (param); - if (enumval < 0 || enumval > 4) - enumval = 4; - - text = role_values [enumval]; - gtk_entry_set_text (GTK_ENTRY (priv->role_entry), text); - - param = get_icalparam_by_type (prop, ICAL_RSVP_PARAMETER); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->rsvp_check), - icalparameter_get_rsvp (param)); - - gtk_widget_show (priv->edit_dialog); - - button_num = gnome_dialog_run (GNOME_DIALOG (priv->edit_dialog)); - - if (button_num == 0) { - /* The user pressed the OK button. */ - new_text = gtk_entry_get_text (GTK_ENTRY (priv->address_entry)); - - g_snprintf (buffer, 190, "MAILTO:%s", new_text); - value = icalvalue_new_text (buffer); - icalproperty_set_value (prop, value); - - /* Take care of the ROLE. */ - icalproperty_remove_parameter (prop, ICAL_ROLE_PARAMETER); - - param = NULL; - text = gtk_entry_get_text (GTK_ENTRY(priv->role_entry)); - - for (cntr = 0; cntr < 5; cntr++) { - if (strncmp (text, role_values[cntr], 3) == 0) { - param = icalparameter_new_role (cntr); - break; - } - } - - if (param == NULL) { - g_print ("e-meeting-edit.c: edit_attendee() the ROLE param was null.\n"); - /* Use this as a default case, if none of the others match. */ - param = icalparameter_new_role (ICAL_ROLE_REQPARTICIPANT); - } - - icalproperty_add_parameter (prop, param); - - /* Now the RSVP. */ - icalproperty_remove_parameter (prop, ICAL_RSVP_PARAMETER); - - param = icalparameter_new_rsvp - (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->rsvp_check))); - icalproperty_add_parameter (prop, param); - - retval = TRUE; - } - else /* The user didn't say OK. */ - retval = FALSE; - - return retval; -} - -static void -schedule_button_clicked_cb (GtkWidget *widget, gpointer data) -{ - EMeetingEditorPrivate *priv; - - EMeetingTimeSelector *mts; - EMeetingTimeSelectorAttendeeType type; - GtkWidget *dialog; - gchar *attendee; - gint cntr, row; - icalproperty *prop; - icalparameter *param; - gint button_num; - - priv = (EMeetingEditorPrivate *) ((EMeetingEditor *)data)->priv; - - - gtk_widget_push_visual (gdk_imlib_get_visual ()); - gtk_widget_push_colormap (gdk_imlib_get_colormap ()); - - dialog = gnome_dialog_new ("Schedule Meeting", "Set Time", "Cancel", NULL); - - gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 400); - gtk_window_set_policy (GTK_WINDOW (dialog), FALSE, TRUE, FALSE); - - mts = (EMeetingTimeSelector *)e_meeting_time_selector_new (); - gtk_container_add (GTK_CONTAINER (GNOME_DIALOG (dialog)->vbox), GTK_WIDGET (mts)); - gtk_window_add_accel_group (GTK_WINDOW (dialog), - E_MEETING_TIME_SELECTOR (mts)->accel_group); - gtk_widget_show (GTK_WIDGET (mts)); - - gtk_widget_pop_visual (); - gtk_widget_pop_colormap (); - - - /* Let's stick all the attendees that we have in our clist, into the - meeting time widget. */ - for (cntr = 0; cntr < priv->numentries; cntr++ ) { - gtk_clist_get_text (GTK_CLIST (priv->attendee_list), cntr, - ADDRESS_COL, &attendee); - row = e_meeting_time_selector_attendee_add (mts, attendee, NULL); - - prop = (icalproperty *)gtk_clist_get_row_data (GTK_CLIST (priv->attendee_list), cntr); - param = get_icalparam_by_type (prop, ICAL_ROLE_PARAMETER); - - switch (icalparameter_get_role (param)) { - case ICAL_ROLE_CHAIR: - case ICAL_ROLE_REQPARTICIPANT: - type = E_MEETING_TIME_SELECTOR_REQUIRED_PERSON; - break; - default: - type = E_MEETING_TIME_SELECTOR_OPTIONAL_PERSON; - } - - e_meeting_time_selector_attendee_set_type (mts, row, type); - } - - /* I don't want the meeting widget to be destroyed before I can - extract information from it; so now the dialog window will just - be hidden when the user clicks a button or closes it. */ - gnome_dialog_close_hides (GNOME_DIALOG (dialog), TRUE); - - gnome_dialog_set_close (GNOME_DIALOG (dialog), TRUE); - - button_num = gnome_dialog_run (GNOME_DIALOG (dialog)); - - if (button_num == 0) { - /* The user clicked "Set Time". */ - gint start_year, start_month, start_day, start_hour, start_minute, - end_year, end_month, end_day, end_hour, end_minute; - CalComponentDateTime cal_dtstart, cal_dtend; - - - e_meeting_time_selector_get_meeting_time (mts, - &start_year, - &start_month, - &start_day, - &start_hour, - &start_minute, - &end_year, - &end_month, - &end_day, - &end_hour, - &end_minute); - - cal_component_get_dtstart (priv->comp, &cal_dtstart); - cal_component_get_dtend (priv->comp, &cal_dtend); - - cal_dtstart.value->second = 0; - cal_dtstart.value->minute = start_minute; - cal_dtstart.value->hour = start_hour; - cal_dtstart.value->day = start_day; - cal_dtstart.value->month = start_month; - cal_dtstart.value->year = start_year; - - cal_dtend.value->second = 0; - cal_dtend.value->minute = end_minute; - cal_dtend.value->hour = end_hour; - cal_dtend.value->day = end_day; - cal_dtend.value->month = end_month; - cal_dtend.value->year = end_year; - - cal_component_set_dtstart (priv->comp, &cal_dtstart); - cal_component_set_dtend (priv->comp, &cal_dtend); - - cal_component_free_datetime (&cal_dtstart); - cal_component_free_datetime (&cal_dtend); - - priv->dirty = TRUE; - } - - gtk_widget_destroy (GTK_WIDGET (dialog)); - - return; -} - -#define GNOME_EVOLUTION_COMPOSER_OAFIID "OAFIID:GNOME_Evolution_Mail_Composer" - -static gchar *itip_methods[] = { - "REQUEST", - "PUBLISH", - "CANCEL" -}; - -enum itip_method_enum { - METHOD_REQUEST, - METHOD_PUBLISH, - METHOD_CANCEL -}; - -typedef enum itip_method_enum itip_method_enum; - -static void -send_calendar_info (itip_method_enum method, EMeetingEditorPrivate *priv) -{ - BonoboObjectClient *bonobo_server; - GNOME_Evolution_Composer composer_server; - CORBA_Environment ev; - GNOME_Evolution_Composer_RecipientList *to_list, *cc_list, *bcc_list; - GNOME_Evolution_Composer_Recipient *recipient; - gchar *cell_text; - CORBA_char *subject; - gint cntr; - gint len; - CalComponentText caltext; - CORBA_char *content_type, *filename, *description, *attach_data; - CORBA_boolean show_inline; - CORBA_char tempstr[200]; - - - CORBA_exception_init (&ev); - - /* First, I obtain an object reference that represents the Composer. */ - bonobo_server = bonobo_object_activate (GNOME_EVOLUTION_COMPOSER_OAFIID, 0); - - g_return_if_fail (bonobo_server != NULL); - - composer_server = bonobo_object_corba_objref (BONOBO_OBJECT (bonobo_server)); - - /* All right, now I have to convert my list of recipients into one of those - CORBA sequences. */ - to_list = GNOME_Evolution_Composer_RecipientList__alloc (); - to_list->_maximum = priv->numentries; - to_list->_length = priv->numentries; - to_list->_buffer = CORBA_sequence_GNOME_Evolution_Composer_Recipient_allocbuf (priv->numentries); - - for (cntr = 0; cntr < priv->numentries; cntr++) { - gtk_clist_get_text (GTK_CLIST (priv->attendee_list), - cntr, ADDRESS_COL, - &cell_text); - len = strlen (cell_text); - - recipient = &(to_list->_buffer[cntr]); - recipient->name = CORBA_string_alloc (0); /* FIXME: we may want an actual name here. */ - recipient->name[0] = '\0'; - recipient->address = CORBA_string_alloc (len); - strcpy (recipient->address, cell_text); - } - - cc_list = GNOME_Evolution_Composer_RecipientList__alloc (); - cc_list->_maximum = cc_list->_length = 0; - bcc_list = GNOME_Evolution_Composer_RecipientList__alloc (); - bcc_list->_maximum = bcc_list->_length = 0; - - cal_component_get_summary (priv->comp, &caltext); - subject = CORBA_string_alloc (strlen (caltext.value)); - strcpy (subject, caltext.value); - - GNOME_Evolution_Composer_setHeaders (composer_server, to_list, cc_list, bcc_list, subject, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_printerr ("gui/e-meeting-edit.c: I couldn't set the composer headers via CORBA! Aagh.\n"); - CORBA_exception_free (&ev); - return; - } - - sprintf (tempstr, "text/calendar;METHOD=%s", itip_methods[method]); - content_type = CORBA_string_alloc (strlen (tempstr)); - strcpy (content_type, tempstr); - filename = CORBA_string_alloc (0); - filename[0] = '\0'; - sprintf (tempstr, "Calendar attachment"); - description = CORBA_string_alloc (strlen (tempstr)); - strcpy (description, tempstr); - show_inline = FALSE; - - /* I need to create an encapsulating iCalendar component, and stuff our vEvent - into it. */ - { - icalcomponent *comp; - icalproperty *prop; - icalvalue *value; - gchar *ical_string; - - save_organizer (priv); - - comp = icalcomponent_new (ICAL_VCALENDAR_COMPONENT); - - prop = icalproperty_new (ICAL_PRODID_PROPERTY); - value = icalvalue_new_text ("-//HelixCode/Evolution//EN"); - icalproperty_set_value (prop, value); - icalcomponent_add_property (comp, prop); - - prop = icalproperty_new (ICAL_VERSION_PROPERTY); - value = icalvalue_new_text ("2.0"); - icalproperty_set_value (prop, value); - icalcomponent_add_property (comp, prop); - - prop = icalproperty_new (ICAL_METHOD_PROPERTY); - value = icalvalue_new_text (itip_methods[method]); - icalproperty_set_value (prop, value); - icalcomponent_add_property (comp, prop); - - icalcomponent_add_component (comp, priv->vevent); - - ical_string = icalcomponent_as_ical_string (comp); - attach_data = CORBA_string_alloc (strlen (ical_string)); - strcpy (attach_data, ical_string); - - icalcomponent_remove_component (comp, priv->vevent); - icalcomponent_free (comp); - } - - GNOME_Evolution_Composer_attachData (composer_server, - content_type, filename, description, - show_inline, attach_data, - &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_printerr ("gui/e-meeting-edit.c: I couldn't attach data to the composer via CORBA! Aagh.\n"); - CORBA_exception_free (&ev); - return; - } - - GNOME_Evolution_Composer_show (composer_server, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_printerr ("gui/e-meeting-edit.c: I couldn't show the composer via CORBA! Aagh.\n"); - CORBA_exception_free (&ev); - return; - } - - CORBA_exception_free (&ev); - - /* Let's free shit up. */ - - /* Beware--depending on whether CORBA_free is recursive, which I - think is is, we might have memory leaks, in which case the code - below is necessary. */ -#if 0 - for (cntr = 0; cntr < priv->numentries; cntr++) { - recipient = &(to_list->_buffer[cntr]); - CORBA_free (recipient->name); - CORBA_free (recipient->address); - recipient->name = recipient->address = NULL; - } -#endif - - if (CORBA_sequence_get_release (to_list) != FALSE) - CORBA_free (to_list->_buffer); - - CORBA_free (to_list); - CORBA_free (cc_list); - CORBA_free (bcc_list); - - CORBA_free (subject); - CORBA_free (content_type); - CORBA_free (filename); - CORBA_free (description); - CORBA_free (attach_data); - - /* bonobo_object_unref (BONOBO_OBJECT (bonobo_server)); */ -} - -/******** - * This routine is called when the publish button is clicked. Duh. - * Actually, I'm just testing my commenting macros. - ********/ -static void -publish_button_clicked_cb (GtkWidget *widget, gpointer data) -{ - EMeetingEditorPrivate *priv; - - - priv = (EMeetingEditorPrivate *) ((EMeetingEditor *)data)->priv; - - send_calendar_info (METHOD_PUBLISH, priv); - -} - -static void -request_button_clicked_cb (GtkWidget *widget, gpointer data) -{ - EMeetingEditorPrivate *priv; - - priv = (EMeetingEditorPrivate *) ((EMeetingEditor *)data)->priv; - - send_calendar_info (METHOD_REQUEST, priv); - -} - -static void -cancel_button_clicked_cb (GtkWidget *widget, gpointer data) -{ - EMeetingEditorPrivate *priv; - - priv = (EMeetingEditorPrivate *) ((EMeetingEditor *)data)->priv; - - send_calendar_info (METHOD_CANCEL, priv); -} - - - -static void -add_button_clicked_cb (GtkWidget *widget, gpointer data) -{ - EMeetingEditorPrivate *priv; - icalproperty *prop; - icalparameter *param; - - priv = (EMeetingEditorPrivate *) ((EMeetingEditor *)data)->priv; - - prop = icalproperty_new (ICAL_ATTENDEE_PROPERTY); - param = icalparameter_new_role (ICAL_ROLE_REQPARTICIPANT); - icalproperty_add_parameter (prop, param); - param = icalparameter_new_rsvp (TRUE); - icalproperty_add_parameter (prop, param); - param = icalparameter_new_partstat (ICAL_PARTSTAT_NEEDSACTION); - icalproperty_add_parameter (prop, param); - - if (edit_attendee (prop, data) == TRUE) { - /* Let's add this property to our component and to the CList. */ - icalcomponent_add_property (priv->vevent, prop); - - /* The -1 indicates that we should add a new row. */ - put_property_in_list (prop, -1, data); - - priv->dirty = TRUE; - } - else { - icalproperty_free (prop); - } -} - -static void -delete_button_clicked_cb (GtkWidget *widget, gpointer data) -{ - EMeetingEditorPrivate *priv; - - priv = (EMeetingEditorPrivate *) ((EMeetingEditor *)data)->priv; - - if (priv->selected_row < 0) { - GtkWidget *dialog; - - dialog = gnome_warning_dialog_parented ("You must select an entry to delete.", - GTK_WINDOW (priv->meeting_window)); - gnome_dialog_run (GNOME_DIALOG(dialog)); - } - else { - /* Delete the associated property from the iCAL object. */ - icalproperty *prop; - - prop = (icalproperty *)gtk_clist_get_row_data (GTK_CLIST (priv->attendee_list), - priv->selected_row); - icalcomponent_remove_property (priv->vevent, prop); - icalproperty_free (prop); - - gtk_clist_remove (GTK_CLIST (priv->attendee_list), priv->selected_row); - priv->selected_row = -1; - priv->numentries--; - priv->dirty = TRUE; - } -} - -static void -edit_button_clicked_cb (GtkWidget *widget, gpointer data) -{ - EMeetingEditorPrivate *priv; - - priv = (EMeetingEditorPrivate *) ((EMeetingEditor *)data)->priv; - - - if (priv->selected_row < 0) { - GtkWidget *dialog; - - dialog = gnome_warning_dialog_parented ("You must select an entry to edit.", - GTK_WINDOW (priv->meeting_window)); - gnome_dialog_run (GNOME_DIALOG(dialog)); - return; - } - else { - icalproperty *prop, *new_prop; - icalparameter *param; - icalvalue *value; - - prop = (icalproperty *)gtk_clist_get_row_data (GTK_CLIST (priv->attendee_list), - priv->selected_row); - - g_assert (prop != NULL); - - new_prop = icalproperty_new_clone (prop); - - if (edit_attendee (new_prop, data)) { - /* The user hit Okay. */ - /*We need to synchronize the old property with the newly edited one.*/ - value = icalvalue_new_clone (icalproperty_get_value (new_prop)); - icalproperty_set_value (prop, value); - - icalproperty_remove_parameter (prop, ICAL_ROLE_PARAMETER); - icalproperty_remove_parameter (prop, ICAL_RSVP_PARAMETER); - icalproperty_remove_parameter (prop, ICAL_PARTSTAT_PARAMETER); - - param = icalparameter_new_clone (get_icalparam_by_type (new_prop, ICAL_ROLE_PARAMETER)); - g_assert (param != NULL); - icalproperty_add_parameter (prop, param); - param = icalparameter_new_clone (get_icalparam_by_type (new_prop, ICAL_RSVP_PARAMETER)); - g_assert (param != NULL); - icalproperty_add_parameter (prop, param); - param = icalparameter_new_clone (get_icalparam_by_type (new_prop, ICAL_PARTSTAT_PARAMETER)); - g_assert (param != NULL); - icalproperty_add_parameter (prop, param); - - put_property_in_list (prop, priv->selected_row, data); - priv->dirty = TRUE; - - } - icalproperty_free (new_prop); - } -} - - - -static void -list_row_select_cb (GtkWidget *widget, - gint row, - gint column, - GdkEventButton *event, - gpointer data) -{ - EMeetingEditorPrivate *priv; - - priv = (EMeetingEditorPrivate *) ((EMeetingEditor *)data)->priv; - - priv->selected_row = row; -} - -static void -organizer_changed_cb (GtkWidget *widget, gpointer data) -{ - EMeetingEditorPrivate *priv; - - priv = (EMeetingEditorPrivate *) ((EMeetingEditor *)data)->priv; - - gtk_signal_disconnect (GTK_OBJECT (priv->organizer_entry), priv->changed_signal_id); - - priv->dirty = TRUE; -} - - -/* ------------------------------------------------------------ */ -/* --------------------- Exported Functions ------------------- */ -/* ------------------------------------------------------------ */ - -EMeetingEditor * -e_meeting_editor_new (CalComponent *comp, CalClient *client) -{ - EMeetingEditor *object; - EMeetingEditorPrivate *priv; - - object = (EMeetingEditor *)g_new(EMeetingEditor, 1); - - priv = (EMeetingEditorPrivate *) g_new0(EMeetingEditorPrivate, 1); - priv->selected_row = -1; - priv->comp = comp; - priv->client = client; - priv->icalcomp = cal_component_get_icalcomponent (comp); - - object->priv = priv; - - return object; -} - -void -e_meeting_editor_free (EMeetingEditor *editor) -{ - if (editor == NULL) - return; - - if (editor->priv != NULL) - g_free (editor->priv); - - g_free (editor); -} - - - -void -e_meeting_edit (EMeetingEditor *editor) -{ - EMeetingEditorPrivate *priv; - GtkWidget *add_button, *delete_button, *edit_button; - icalproperty *prop; - icalvalue *value; - gchar *text; - - - g_return_if_fail (editor != NULL); - - priv = (EMeetingEditorPrivate *)editor->priv; - - g_return_if_fail (priv != NULL); - - - priv->xml = glade_xml_new (EVOLUTION_GLADEDIR "/" E_MEETING_GLADE_XML, NULL); - - priv->meeting_window = glade_xml_get_widget (priv->xml, "meeting_window"); - priv->attendee_list = glade_xml_get_widget (priv->xml, "attendee_list"); - priv->role_entry = glade_xml_get_widget (priv->xml, "role_entry"); - priv->rsvp_check = glade_xml_get_widget (priv->xml, "rsvp_check"); - priv->schedule_button = glade_xml_get_widget (priv->xml, "schedule_button"); - priv->publish_button = glade_xml_get_widget (priv->xml, "publish_button"); - priv->request_button = glade_xml_get_widget (priv->xml, "request_button"); - priv->cancel_button = glade_xml_get_widget (priv->xml, "cancel_button"); - - gtk_clist_set_column_justification (GTK_CLIST (priv->attendee_list), ROLE_COL, GTK_JUSTIFY_CENTER); - gtk_clist_set_column_justification (GTK_CLIST (priv->attendee_list), RSVP_COL, GTK_JUSTIFY_CENTER); - gtk_clist_set_column_justification (GTK_CLIST (priv->attendee_list), STATUS_COL, GTK_JUSTIFY_CENTER); - - gtk_signal_connect (GTK_OBJECT (priv->meeting_window), "delete_event", - GTK_SIGNAL_FUNC (window_delete_cb), editor); - - gtk_signal_connect_after (GTK_OBJECT (priv->meeting_window), "delete_event", - GTK_SIGNAL_FUNC (window_destroy_cb), editor); - - gtk_signal_connect (GTK_OBJECT (priv->meeting_window), "destroy_event", - GTK_SIGNAL_FUNC (window_destroy_cb), editor); - - gtk_signal_connect (GTK_OBJECT (priv->attendee_list), "select_row", - GTK_SIGNAL_FUNC (list_row_select_cb), editor); - - gtk_signal_connect (GTK_OBJECT (priv->schedule_button), "clicked", - GTK_SIGNAL_FUNC (schedule_button_clicked_cb), editor); - - gtk_signal_connect (GTK_OBJECT (priv->publish_button), "clicked", - GTK_SIGNAL_FUNC (publish_button_clicked_cb), editor); - - gtk_signal_connect (GTK_OBJECT (priv->request_button), "clicked", - GTK_SIGNAL_FUNC (request_button_clicked_cb), editor); - - gtk_signal_connect (GTK_OBJECT (priv->cancel_button), "clicked", - GTK_SIGNAL_FUNC (cancel_button_clicked_cb), editor); - - add_button = glade_xml_get_widget (priv->xml, "add_button"); - delete_button = glade_xml_get_widget (priv->xml, "delete_button"); - edit_button = glade_xml_get_widget (priv->xml, "edit_button"); - - gtk_signal_connect (GTK_OBJECT (add_button), "clicked", - GTK_SIGNAL_FUNC (add_button_clicked_cb), editor); - - gtk_signal_connect (GTK_OBJECT (delete_button), "clicked", - GTK_SIGNAL_FUNC (delete_button_clicked_cb), editor); - - gtk_signal_connect (GTK_OBJECT (edit_button), "clicked", - GTK_SIGNAL_FUNC (edit_button_clicked_cb), editor); - - priv->organizer_entry = glade_xml_get_widget (priv->xml, "organizer_entry"); - - if (icalcomponent_isa (priv->icalcomp) != ICAL_VEVENT_COMPONENT) { - icalcompiter iter; - - iter = icalcomponent_begin_component (priv->icalcomp, ICAL_VEVENT_COMPONENT); - priv->vevent = icalcompiter_deref (&iter); - } else - priv->vevent = priv->icalcomp; - - g_assert (priv->vevent != NULL); - - /* Let's extract the organizer, if there is one. */ - prop = icalcomponent_get_first_property (priv->vevent, ICAL_ORGANIZER_PROPERTY); - - if (prop != NULL) { - gchar *buffer; - - value = icalproperty_get_value (prop); - buffer = g_strdup (icalvalue_as_ical_string (value)); - if (buffer != NULL) { - /* Strip off the MAILTO:, if it is present. */ - text = strchr (buffer, ':'); - if (text == NULL) - text = buffer; - else - text++; - - gtk_entry_set_text (GTK_ENTRY (priv->organizer_entry), text); - g_free (buffer); - } - - } - - priv->changed_signal_id = gtk_signal_connect (GTK_OBJECT (priv->organizer_entry), "changed", - GTK_SIGNAL_FUNC (organizer_changed_cb), editor); - - - /* Let's go through the iCAL object, and create a list entry - for each ATTENDEE property. */ - for (prop = icalcomponent_get_first_property (priv->vevent, ICAL_ATTENDEE_PROPERTY); - prop != NULL; - prop = icalcomponent_get_next_property (priv->vevent, ICAL_ATTENDEE_PROPERTY)) - { - put_property_in_list (prop, -1, editor); - } - - - gtk_widget_show (priv->meeting_window); - - gtk_main (); - - if (priv->meeting_window != NULL) - gtk_widget_destroy (priv->meeting_window); - - if (priv->edit_dialog != NULL) - gtk_widget_destroy (priv->edit_dialog); - - gtk_object_unref (GTK_OBJECT (priv->xml)); -} diff --git a/calendar/gui/e-meeting-edit.h b/calendar/gui/e-meeting-edit.h deleted file mode 100644 index e29453ecba..0000000000 --- a/calendar/gui/e-meeting-edit.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Evolution calendar - Meeting editor dialog - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Jesse Pavel <jpavel@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef __E_MEETING_EDIT_H__ -#define __E_MEETING_EDIT_H__ - -#include <config.h> -#include <glade/glade.h> -#include <cal-util/cal-component.h> -#include <cal-client/cal-client.h> - -typedef struct _EMeetingEditor EMeetingEditor; - -struct _EMeetingEditor { - gpointer priv; -}; - - -EMeetingEditor * e_meeting_editor_new (CalComponent *comp, CalClient *client); - -void e_meeting_edit (EMeetingEditor *editor); -void e_meeting_editor_free (EMeetingEditor *editor); - - -#endif /* __E_MEETING_EDIT_H__ */ - diff --git a/calendar/gui/e-tasks.c b/calendar/gui/e-tasks.c deleted file mode 100644 index 92917d6d55..0000000000 --- a/calendar/gui/e-tasks.c +++ /dev/null @@ -1,567 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-tasks.c - * - * Copyright (C) 2001 Helix Code, Inc. - * Copyright (C) 2001 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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. - * - * Authors: Federico Mena Quintero <federico@ximian.com> - * Damon Chaplin <damon@ximian.com> - */ - -#include <config.h> -#include <gnome.h> -#include <gal/util/e-util.h> -#include <gal/e-table/e-table-scrolled.h> -#include <gal/menus/gal-view-collection.h> -#include <gal/menus/gal-view-factory-etable.h> -#include <gal/menus/gal-view-etable.h> -#include "widgets/menus/gal-view-menus.h" -#include "dialogs/task-editor.h" -#include "e-calendar-table.h" -#include "component-factory.h" - -#include "e-tasks.h" - - -/* Private part of the GnomeCalendar structure */ -struct _ETasksPrivate { - /* The calendar client object we monitor */ - CalClient *client; - - /* The ECalendarTable showing the tasks. */ - GtkWidget *tasks_view; - - /* The option menu showing the categories, and the popup menu. */ - GtkWidget *categories_option_menu; - GtkWidget *categories_menu; -}; - - -static void e_tasks_class_init (ETasksClass *class); -static void e_tasks_init (ETasks *tasks); -static void setup_widgets (ETasks *tasks); -static void e_tasks_destroy (GtkObject *object); - -static void cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data); -static void obj_updated_cb (CalClient *client, const char *uid, gpointer data); -static void obj_removed_cb (CalClient *client, const char *uid, gpointer data); - -static char* e_tasks_get_config_filename (ETasks *tasks); - -static void e_tasks_on_filter_selected (GtkMenuShell *menu_shell, - ETasks *tasks); -static void e_tasks_on_categories_changed (CalendarModel *model, - ETasks *tasks); -static void e_tasks_rebuild_categories_menu (ETasks *tasks); -static gint e_tasks_add_menu_item (gpointer key, - gpointer value, - gpointer data); - - -static GtkTableClass *parent_class; - - -E_MAKE_TYPE (e_tasks, "ETasks", ETasks, - e_tasks_class_init, e_tasks_init, - GTK_TYPE_TABLE) - - -/* Class initialization function for the gnome calendar */ -static void -e_tasks_class_init (ETasksClass *class) -{ - GtkObjectClass *object_class; - - object_class = (GtkObjectClass *) class; - - parent_class = gtk_type_class (GTK_TYPE_TABLE); - - object_class->destroy = e_tasks_destroy; -} - - -/* Object initialization function for the gnome calendar */ -static void -e_tasks_init (ETasks *tasks) -{ - ETasksPrivate *priv; - - priv = g_new0 (ETasksPrivate, 1); - tasks->priv = priv; - - setup_widgets (tasks); -} - - -#define E_TASKS_TABLE_DEFAULT_STATE \ - "<?xml version=\"1.0\"?>" \ - "<ETableState>" \ - "<column source=\"13\"/>" \ - "<column source=\"14\"/>" \ - "<column source=\"9\"/>" \ - "<column source=\"5\"/>" \ - "<grouping/>" \ - "</ETableState>" - - -static void -setup_widgets (ETasks *tasks) -{ - ETasksPrivate *priv; - ETable *etable; - GtkWidget *hbox, *menuitem, *categories_label; - CalendarModel *model; - - priv = tasks->priv; - - hbox = gtk_hbox_new (FALSE, 0); - gtk_widget_show (hbox); - gtk_table_attach (GTK_TABLE (tasks), hbox, 0, 1, 0, 1, - GTK_EXPAND | GTK_FILL, 0, 0, 0); - - priv->categories_option_menu = gtk_option_menu_new (); - gtk_widget_show (priv->categories_option_menu); - gtk_box_pack_end (GTK_BOX (hbox), priv->categories_option_menu, - FALSE, FALSE, 0); - - priv->categories_menu = gtk_menu_new (); - - menuitem = gtk_menu_item_new_with_label (_("All")); - gtk_widget_show (menuitem); - gtk_menu_append (GTK_MENU (priv->categories_menu), menuitem); - - gtk_option_menu_set_menu (GTK_OPTION_MENU (priv->categories_option_menu), priv->categories_menu); - - categories_label = gtk_label_new (_("Category:")); - gtk_widget_show (categories_label); - gtk_box_pack_end (GTK_BOX (hbox), categories_label, FALSE, FALSE, 4); - - - priv->tasks_view = e_calendar_table_new (); - model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view)); - calendar_model_set_new_comp_vtype (model, CAL_COMPONENT_TODO); - etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (E_CALENDAR_TABLE (priv->tasks_view)->etable)); - e_table_set_state (etable, E_TASKS_TABLE_DEFAULT_STATE); - gtk_table_attach (GTK_TABLE (tasks), priv->tasks_view, 0, 1, 1, 2, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - gtk_widget_show (priv->tasks_view); - - gtk_signal_connect (GTK_OBJECT (E_CALENDAR_TABLE (priv->tasks_view)->model), - "categories-changed", - GTK_SIGNAL_FUNC (e_tasks_on_categories_changed), tasks); -} - - -GtkWidget * -e_tasks_construct (ETasks *tasks) -{ - ETasksPrivate *priv; - - g_return_val_if_fail (tasks != NULL, NULL); - g_return_val_if_fail (E_IS_TASKS (tasks), NULL); - - priv = tasks->priv; - - priv->client = cal_client_new (); - if (!priv->client) - return NULL; - - gtk_signal_connect (GTK_OBJECT (priv->client), "cal_opened", - GTK_SIGNAL_FUNC (cal_opened_cb), tasks); - gtk_signal_connect (GTK_OBJECT (priv->client), "obj_updated", - GTK_SIGNAL_FUNC (obj_updated_cb), tasks); - gtk_signal_connect (GTK_OBJECT (priv->client), "obj_removed", - GTK_SIGNAL_FUNC (obj_removed_cb), tasks); - -#if 0 - alarm_notify_add_client (priv->client); -#endif - - e_calendar_table_set_cal_client (E_CALENDAR_TABLE (priv->tasks_view), - priv->client); - - return GTK_WIDGET (tasks); -} - - -GtkWidget * -e_tasks_new (void) -{ - ETasks *tasks; - - tasks = gtk_type_new (e_tasks_get_type ()); - - if (!e_tasks_construct (tasks)) { - g_message ("e_tasks_new(): Could not construct the tasks GUI"); - gtk_object_unref (GTK_OBJECT (tasks)); - return NULL; - } - - return GTK_WIDGET (tasks); -} - - -static void -e_tasks_destroy (GtkObject *object) -{ - ETasks *tasks; - ETasksPrivate *priv; - char *config_filename; - - g_return_if_fail (object != NULL); - g_return_if_fail (E_IS_TASKS (object)); - - tasks = E_TASKS (object); - priv = tasks->priv; - - /* Save the ETable layout. */ - config_filename = e_tasks_get_config_filename (tasks); - e_calendar_table_save_state (E_CALENDAR_TABLE (priv->tasks_view), - config_filename); - g_free (config_filename); - - if (priv->client) { -#if 0 - alarm_notify_remove_client (priv->client); -#endif - gtk_object_unref (GTK_OBJECT (priv->client)); - priv->client = NULL; - } - - g_free (priv); - tasks->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - -gboolean -e_tasks_open (ETasks *tasks, - char *file) -{ - ETasksPrivate *priv; - char *config_filename; - - g_return_val_if_fail (tasks != NULL, FALSE); - g_return_val_if_fail (E_IS_TASKS (tasks), FALSE); - g_return_val_if_fail (file != NULL, FALSE); - - priv = tasks->priv; - - if (!cal_client_open_calendar (priv->client, file, FALSE)) { - g_message ("e_tasks_open(): Could not issue the request"); - return FALSE; - } - - config_filename = e_tasks_get_config_filename (tasks); - e_calendar_table_load_state (E_CALENDAR_TABLE (priv->tasks_view), - config_filename); - g_free (config_filename); - - return TRUE; -} - - -/* Displays an error to indicate that loading a calendar failed */ -static void -load_error (ETasks *tasks, - const char *uri) -{ - char *msg; - - msg = g_strdup_printf (_("Could not load the tasks in `%s'"), uri); - gnome_error_dialog_parented (msg, GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tasks)))); - g_free (msg); -} - -/* Displays an error to indicate that the specified URI method is not supported */ -static void -method_error (ETasks *tasks, - const char *uri) -{ - char *msg; - - msg = g_strdup_printf (_("The method required to load `%s' is not supported"), uri); - gnome_error_dialog_parented (msg, GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tasks)))); - g_free (msg); -} - -/* Callback from the calendar client when a calendar is opened */ -static void -cal_opened_cb (CalClient *client, - CalClientOpenStatus status, - gpointer data) -{ - ETasks *tasks; - ETasksPrivate *priv; - - tasks = E_TASKS (data); - priv = tasks->priv; - - switch (status) { - case CAL_CLIENT_OPEN_SUCCESS: - /* Everything is OK */ - return; - - case CAL_CLIENT_OPEN_ERROR: - load_error (tasks, cal_client_get_uri (client)); - break; - - case CAL_CLIENT_OPEN_NOT_FOUND: - /* bullshit; we did not specify only_if_exists */ - g_assert_not_reached (); - return; - - case CAL_CLIENT_OPEN_METHOD_NOT_SUPPORTED: - method_error (tasks, cal_client_get_uri (client)); - break; - - default: - g_assert_not_reached (); - } -} - - -/* Callback from the calendar client when an object is updated */ -static void -obj_updated_cb (CalClient *client, - const char *uid, - gpointer data) -{ - ETasks *tasks; - ETasksPrivate *priv; - - tasks = E_TASKS (data); - priv = tasks->priv; - - /* FIXME: Do we need to do anything? */ -} - - -/* Callback from the calendar client when an object is removed */ -static void -obj_removed_cb (CalClient *client, - const char *uid, - gpointer data) -{ - ETasks *tasks; - ETasksPrivate *priv; - - tasks = E_TASKS (data); - priv = tasks->priv; - - /* FIXME: Do we need to do anything? */ -} - - -static char* -e_tasks_get_config_filename (ETasks *tasks) -{ - ETasksPrivate *priv; - char *url, *filename; - - priv = tasks->priv; - - url = g_strdup (cal_client_get_uri (priv->client)); - - /* This turns all funny characters into '_', in the string itself. */ - e_filename_make_safe (url); - - filename = g_strdup_printf ("%s/config/et-header-%s", evolution_dir, - url); - g_free (url); - - return filename; -} - - -/** - * e_tasks_get_cal_client: - * @tasks: An #ETasks. - * - * Queries the calendar client interface object that a tasks view is using. - * - * Return value: A calendar client interface object. - **/ -CalClient * -e_tasks_get_cal_client (ETasks *tasks) -{ - ETasksPrivate *priv; - - g_return_val_if_fail (E_IS_TASKS (tasks), NULL); - - priv = tasks->priv; - - return priv->client; -} - - -void -e_tasks_new_task (ETasks *tasks) -{ - ETasksPrivate *priv; - TaskEditor *tedit; - CalComponent *comp; - - g_return_if_fail (E_IS_TASKS (tasks)); - - priv = tasks->priv; - - tedit = task_editor_new (); - task_editor_set_cal_client (tedit, priv->client); - - comp = cal_component_new (); - cal_component_set_new_vtype (comp, CAL_COMPONENT_TODO); - - task_editor_set_todo_object (tedit, comp); - gtk_object_unref (GTK_OBJECT (comp)); - - task_editor_focus (tedit); -} - - -static void -e_tasks_on_filter_selected (GtkMenuShell *menu_shell, - ETasks *tasks) -{ - ETasksPrivate *priv; - ECalendarTable *cal_table; - CalendarModel *model; - GtkWidget *label; - char *category; - - g_return_if_fail (E_IS_TASKS (tasks)); - - priv = tasks->priv; - - label = GTK_BIN (priv->categories_option_menu)->child; - gtk_label_get (GTK_LABEL (label), &category); - - cal_table = E_CALENDAR_TABLE (priv->tasks_view); - model = cal_table->model; - - if (!strcmp (category, _("All"))) { - calendar_model_set_default_category (model, NULL); - e_calendar_table_set_filter_func (cal_table, NULL, NULL, - NULL); - } else { - calendar_model_set_default_category (model, category); - e_calendar_table_set_filter_func (cal_table, - e_calendar_table_filter_by_category, - g_strdup (category), g_free); - } -} - - -static void -e_tasks_on_categories_changed (CalendarModel *model, - ETasks *tasks) -{ - e_tasks_rebuild_categories_menu (tasks); -} - - -static void -e_tasks_rebuild_categories_menu (ETasks *tasks) -{ - ETasksPrivate *priv; - CalendarModel *model; - GTree *categories; - GtkWidget *menuitem; - - priv = tasks->priv; - - priv->categories_menu = gtk_menu_new (); - - menuitem = gtk_menu_item_new_with_label (_("All")); - gtk_widget_show (menuitem); - gtk_menu_append (GTK_MENU (priv->categories_menu), menuitem); - - model = E_CALENDAR_TABLE (priv->tasks_view)->model; - categories = calendar_model_get_categories (model); - g_return_if_fail (categories != NULL); - - g_tree_traverse (categories, e_tasks_add_menu_item, G_IN_ORDER, - priv->categories_menu); - - gtk_option_menu_set_menu (GTK_OPTION_MENU (priv->categories_option_menu), priv->categories_menu); - - gtk_signal_connect (GTK_OBJECT (priv->categories_menu), "deactivate", - GTK_SIGNAL_FUNC (e_tasks_on_filter_selected), - tasks); -} - - -static gint -e_tasks_add_menu_item (gpointer key, - gpointer value, - gpointer data) -{ - GtkWidget *menuitem; - - menuitem = gtk_menu_item_new_with_label ((char*) key); - gtk_widget_show (menuitem); - gtk_menu_append (GTK_MENU (data), menuitem); - - return FALSE; -} - -static void -display_view(GalViewCollection *collection, - GalView *view, - gpointer data) -{ - ETasks *tasks = data; - if (GAL_IS_VIEW_ETABLE(view)) { - e_table_set_state_object (e_table_scrolled_get_table (E_TABLE_SCROLLED (E_CALENDAR_TABLE (tasks->priv->tasks_view)->etable)), GAL_VIEW_ETABLE (view)->state); - } -} - -void -e_tasks_setup_menus (ETasks *tasks, - BonoboUIComponent *uic) -{ - GalViewCollection *collection; - GalViewMenus *views; - GalViewFactory *factory; - ETableSpecification *spec; - - collection = gal_view_collection_new(); - /* FIXME: Memory leak. */ - gal_view_collection_set_storage_directories (collection, - EVOLUTION_DATADIR "/evolution/views/tasks/", - gnome_util_prepend_user_home ("/evolution/views/tasks/")); - - spec = e_table_specification_new (); - e_table_specification_load_from_string (spec, e_calendar_table_get_spec()); - - factory = gal_view_factory_etable_new (spec); - gal_view_collection_add_factory (collection, factory); - gtk_object_sink (GTK_OBJECT (factory)); - - gal_view_collection_load (collection); - - views = gal_view_menus_new (collection); - gal_view_menus_apply (views, uic, NULL); /* This function probably needs to sink the views object. */ - gtk_signal_connect (GTK_OBJECT (collection), "display_view", - display_view, tasks); - /* gtk_object_sink(GTK_OBJECT(views)); */ - - gtk_object_sink (GTK_OBJECT (collection)); -} diff --git a/calendar/gui/e-tasks.h b/calendar/gui/e-tasks.h deleted file mode 100644 index 94dc8607f6..0000000000 --- a/calendar/gui/e-tasks.h +++ /dev/null @@ -1,71 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-tasks.h - * - * Copyright (C) 2001 Helix Code, Inc. - * Copyright (C) 2001 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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. - * - * Authors: Federico Mena Quintero <federico@ximian.com> - * Damon Chaplin <damon@ximian.com> - */ - -#ifndef _E_TASKS_H_ -#define _E_TASKS_H_ - -#include <cal-client/cal-client.h> -#include <bonobo.h> - -#define E_TYPE_TASKS (e_tasks_get_type ()) -#define E_TASKS(obj) (GTK_CHECK_CAST ((obj), E_TYPE_TASKS, ETasks)) -#define E_TASKS_CLASS(klass) (GTK_CHECK_CAST_CLASS ((klass), E_TYPE_TASKS, \ - ETasksClass)) -#define E_IS_TASKS(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_TASKS)) -#define E_IS_TASKS_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), E_TYPE_TASKS)) - -typedef struct _ETasks ETasks; -typedef struct _ETasksClass ETasksClass; -typedef struct _ETasksPrivate ETasksPrivate; - -struct _ETasks { - GtkTable table; - - /* Private data */ - ETasksPrivate *priv; -}; - -struct _ETasksClass { - GtkTableClass parent_class; -}; - - -GtkType e_tasks_get_type (void); -GtkWidget *e_tasks_construct (ETasks *tasks); - -GtkWidget *e_tasks_new (void); - -gboolean e_tasks_open (ETasks *tasks, - char *file); - -CalClient *e_tasks_get_cal_client (ETasks *tasks); - -void e_tasks_new_task (ETasks *tasks); - -void e_tasks_setup_menus (ETasks *tasks, - BonoboUIComponent *uic); - - -#endif /* _E_TASKS_H_ */ diff --git a/calendar/gui/e-week-view-event-item.c b/calendar/gui/e-week-view-event-item.c deleted file mode 100644 index 8adfdd96ff..0000000000 --- a/calendar/gui/e-week-view-event-item.c +++ /dev/null @@ -1,813 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 1999, Helix Code, Inc. - * Copyright 2001, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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 - */ - -/* - * EWeekViewEventItem - displays the background, times and icons for an event - * in the week/month views. A separate EText canvas item is used to display & - * edit the text. - */ - -#include <config.h> -#include <gal/e-text/e-text.h> -#include "e-week-view-event-item.h" - -static void e_week_view_event_item_class_init (EWeekViewEventItemClass *class); -static void e_week_view_event_item_init (EWeekViewEventItem *wveitem); - -static void e_week_view_event_item_set_arg (GtkObject *o, - GtkArg *arg, - guint arg_id); -static void e_week_view_event_item_update (GnomeCanvasItem *item, - double *affine, - ArtSVP *clip_path, - int flags); -static void e_week_view_event_item_draw (GnomeCanvasItem *item, - GdkDrawable *drawable, - int x, - int y, - int width, - int height); -static void e_week_view_draw_time (EWeekView *week_view, - GdkDrawable *drawable, - gint time_x, - gint time_y, - gint hour, - gint minute); -static void e_week_view_event_item_draw_icons (EWeekViewEventItem *wveitem, - GdkDrawable *drawable, - gint icon_x, - gint icon_y, - gint x2, - gboolean right_align); -static void e_week_view_event_item_draw_triangle (EWeekViewEventItem *wveitem, - GdkDrawable *drawable, - gint x, - gint y, - gint w, - gint h); -static double e_week_view_event_item_point (GnomeCanvasItem *item, - double x, - double y, - int cx, - int cy, - GnomeCanvasItem **actual_item); -static gint e_week_view_event_item_event (GnomeCanvasItem *item, - GdkEvent *event); -static gboolean e_week_view_event_item_button_press (EWeekViewEventItem *wveitem, - GdkEvent *event); -static gboolean e_week_view_event_item_button_release (EWeekViewEventItem *wveitem, - GdkEvent *event); -static EWeekViewPosition e_week_view_event_item_get_position (EWeekViewEventItem *wveitem, - gdouble x, - gdouble y); - - -static GnomeCanvasItemClass *parent_class; - -/* The arguments we take */ -enum { - ARG_0, - ARG_EVENT_NUM, - ARG_SPAN_NUM -}; - - -GtkType -e_week_view_event_item_get_type (void) -{ - static GtkType e_week_view_event_item_type = 0; - - if (!e_week_view_event_item_type) { - GtkTypeInfo e_week_view_event_item_info = { - "EWeekViewEventItem", - sizeof (EWeekViewEventItem), - sizeof (EWeekViewEventItemClass), - (GtkClassInitFunc) e_week_view_event_item_class_init, - (GtkObjectInitFunc) e_week_view_event_item_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - e_week_view_event_item_type = gtk_type_unique (gnome_canvas_item_get_type (), &e_week_view_event_item_info); - } - - return e_week_view_event_item_type; -} - - -static void -e_week_view_event_item_class_init (EWeekViewEventItemClass *class) -{ - GtkObjectClass *object_class; - GnomeCanvasItemClass *item_class; - - parent_class = gtk_type_class (gnome_canvas_item_get_type()); - - object_class = (GtkObjectClass *) class; - item_class = (GnomeCanvasItemClass *) class; - - gtk_object_add_arg_type ("EWeekViewEventItem::event_num", - GTK_TYPE_INT, GTK_ARG_WRITABLE, - ARG_EVENT_NUM); - gtk_object_add_arg_type ("EWeekViewEventItem::span_num", - GTK_TYPE_INT, GTK_ARG_WRITABLE, - ARG_SPAN_NUM); - - object_class->set_arg = e_week_view_event_item_set_arg; - - /* GnomeCanvasItem method overrides */ - item_class->update = e_week_view_event_item_update; - item_class->draw = e_week_view_event_item_draw; - item_class->point = e_week_view_event_item_point; - item_class->event = e_week_view_event_item_event; -} - - -static void -e_week_view_event_item_init (EWeekViewEventItem *wveitem) -{ - wveitem->event_num = -1; - wveitem->span_num = -1; -} - - -static void -e_week_view_event_item_set_arg (GtkObject *o, GtkArg *arg, guint arg_id) -{ - GnomeCanvasItem *item; - EWeekViewEventItem *wveitem; - gboolean needs_update = FALSE; - - item = GNOME_CANVAS_ITEM (o); - wveitem = E_WEEK_VIEW_EVENT_ITEM (o); - - switch (arg_id){ - case ARG_EVENT_NUM: - wveitem->event_num = GTK_VALUE_INT (*arg); - needs_update = TRUE; - break; - case ARG_SPAN_NUM: - wveitem->span_num = GTK_VALUE_INT (*arg); - needs_update = TRUE; - break; - } - - if (needs_update) - gnome_canvas_item_request_update (item); -} - - -static void -e_week_view_event_item_update (GnomeCanvasItem *item, - double *affine, - ArtSVP *clip_path, - int flags) -{ - EWeekViewEventItem *wveitem; - EWeekView *week_view; - gint span_x, span_y, span_w; - -#if 0 - g_print ("In e_week_view_event_item_update\n"); -#endif - - wveitem = E_WEEK_VIEW_EVENT_ITEM (item); - week_view = E_WEEK_VIEW (GTK_WIDGET (item->canvas)->parent); - g_return_if_fail (E_IS_WEEK_VIEW (week_view)); - - if (GNOME_CANVAS_ITEM_CLASS (parent_class)->update) - (* GNOME_CANVAS_ITEM_CLASS (parent_class)->update) (item, affine, clip_path, flags); - - item->x1 = 0; - item->y1 = 0; - item->x2 = 0; - item->y2 = 0; - - if (wveitem->event_num != -1 && wveitem->span_num != -1) { - if (e_week_view_get_span_position (week_view, - wveitem->event_num, - wveitem->span_num, - &span_x, &span_y, - &span_w)) { -#if 0 - g_print (" Event:%i Span:%i %i,%i W:%i\n", - wveitem->event_num, wveitem->span_num, - span_x, span_y, span_w); -#endif - item->x1 = span_x; - item->y1 = span_y; - item->x2 = span_x + span_w - 1; - item->y2 = span_y + week_view->row_height - 1; - } - } -} - - -/* - * DRAWING ROUTINES - functions to paint the canvas item. - */ - -static void -e_week_view_event_item_draw (GnomeCanvasItem *canvas_item, - GdkDrawable *drawable, - int x, - int y, - int width, - int height) -{ - EWeekViewEventItem *wveitem; - EWeekView *week_view; - EWeekViewEvent *event; - EWeekViewEventSpan *span; - GtkStyle *style; - GdkGC *fg_gc, *gc; - gint x1, y1, x2, y2, time_x, time_y; - gint icon_x, icon_y, time_width, min_end_time_x, max_icon_x; - gint rect_x, rect_w, rect_x2; - gboolean one_day_event, editing_span = FALSE; - gint start_hour, start_minute, end_hour, end_minute; - gboolean draw_start, draw_end; - gboolean draw_start_triangle = FALSE, draw_end_triangle = FALSE; - GdkRectangle clip_rect; - -#if 0 - g_print ("In e_week_view_event_item_draw %i,%i %ix%i\n", - x, y, width, height); -#endif - - wveitem = E_WEEK_VIEW_EVENT_ITEM (canvas_item); - week_view = E_WEEK_VIEW (GTK_WIDGET (canvas_item->canvas)->parent); - g_return_if_fail (E_IS_WEEK_VIEW (week_view)); - - if (wveitem->event_num == -1 || wveitem->span_num == -1) - return; - - event = &g_array_index (week_view->events, EWeekViewEvent, - wveitem->event_num); - span = &g_array_index (week_view->spans, EWeekViewEventSpan, - event->spans_index + wveitem->span_num); - - style = GTK_WIDGET (week_view)->style; - fg_gc = style->fg_gc[GTK_STATE_NORMAL]; - gc = week_view->main_gc; - - x1 = canvas_item->x1 - x; - y1 = canvas_item->y1 - y; - x2 = canvas_item->x2 - x; - y2 = canvas_item->y2 - y; - - if (x1 == x2 || y1 == y2) - return; - - icon_x = 0; - icon_y = y1 + E_WEEK_VIEW_EVENT_BORDER_HEIGHT + E_WEEK_VIEW_ICON_Y_PAD; - - /* Get the start & end times in 24-hour format. */ - start_hour = event->start_minute / 60; - start_minute = event->start_minute % 60; - end_hour = event->end_minute / 60; - end_minute = event->end_minute % 60; - - time_y = y1 + E_WEEK_VIEW_EVENT_BORDER_HEIGHT - + E_WEEK_VIEW_EVENT_TEXT_Y_PAD; - - time_width = e_week_view_get_time_string_width (week_view); - - one_day_event = e_week_view_is_one_day_event (week_view, - wveitem->event_num); - if (one_day_event) { - time_x = x1 + E_WEEK_VIEW_EVENT_L_PAD; - - /* Draw the start and end times, as required. */ - switch (week_view->time_format) { - case E_WEEK_VIEW_TIME_BOTH_SMALL_MIN: - case E_WEEK_VIEW_TIME_BOTH: - draw_start = TRUE; - draw_end = TRUE; - break; - - case E_WEEK_VIEW_TIME_START_SMALL_MIN: - case E_WEEK_VIEW_TIME_START: - draw_start = TRUE; - draw_end = FALSE; - break; - - case E_WEEK_VIEW_TIME_NONE: - draw_start = FALSE; - draw_end = FALSE; - break; - default: - g_assert_not_reached(); - draw_start = FALSE; - draw_end = FALSE; - break; - } - - if (draw_start) { - e_week_view_draw_time (week_view, drawable, - time_x, time_y, - start_hour, start_minute); - time_x += time_width; - } - - if (draw_end) { - time_x += E_WEEK_VIEW_EVENT_TIME_SPACING; - e_week_view_draw_time (week_view, drawable, - time_x, time_y, - end_hour, end_minute); - time_x += time_width; - } - - icon_x = time_x; - if (draw_start) - icon_x += E_WEEK_VIEW_EVENT_TIME_X_PAD; - - /* Draw the icons. */ - e_week_view_event_item_draw_icons (wveitem, drawable, - icon_x, icon_y, - x2, FALSE); - - } else { - rect_x = x1 + E_WEEK_VIEW_EVENT_L_PAD; - rect_w = x2 - x1 - E_WEEK_VIEW_EVENT_L_PAD - - E_WEEK_VIEW_EVENT_R_PAD + 1; - - /* Draw the triangles at the start & end, if needed. - They also use the first few pixels at the edge of the - event so we update rect_x & rect_w so we don't draw over - them. */ - if (event->start < week_view->day_starts[span->start_day]) { - draw_start_triangle = TRUE; - rect_x += 2; - rect_w -= 2; - } - - if (event->end > week_view->day_starts[span->start_day - + span->num_days]) { - draw_end_triangle = TRUE; - rect_w -= 2; - } - - gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND]); - gdk_draw_rectangle (drawable, gc, TRUE, - rect_x, y1 + 1, rect_w, y2 - y1 - 1); - - gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BORDER]); - rect_x2 = rect_x + rect_w - 1; - gdk_draw_line (drawable, gc, rect_x, y1, rect_x2, y1); - gdk_draw_line (drawable, gc, rect_x, y2, rect_x2, y2); - - if (draw_start_triangle) { - e_week_view_event_item_draw_triangle (wveitem, drawable, x1 + E_WEEK_VIEW_EVENT_L_PAD + 2, y1, -3, y2 - y1 + 1); - } else { - gdk_draw_line (drawable, gc, rect_x, y1, rect_x, y2); - } - - if (draw_end_triangle) { - e_week_view_event_item_draw_triangle (wveitem, drawable, x2 - E_WEEK_VIEW_EVENT_R_PAD - 2, y1, 3, y2 - y1 + 1); - } else { - gdk_draw_line (drawable, gc, rect_x2, y1, rect_x2, y2); - } - - if (span->text_item && E_TEXT (span->text_item)->editing) - editing_span = TRUE; - - /* Draw the start & end times, if they are not on day - boundaries. The start time would always be shown if it was - needed, though it may be clipped as the window shrinks. - The end time is only displayed if there is enough room. - We calculate the minimum position for the end time, which - depends on whether the start time is displayed. If the end - time doesn't fit, then we don't draw it. */ - min_end_time_x = x1 + E_WEEK_VIEW_EVENT_L_PAD - + E_WEEK_VIEW_EVENT_BORDER_WIDTH - + E_WEEK_VIEW_EVENT_EDGE_X_PAD; - if (!editing_span - && event->start > week_view->day_starts[span->start_day]) { - time_x = x1 + E_WEEK_VIEW_EVENT_L_PAD - + E_WEEK_VIEW_EVENT_BORDER_WIDTH - + E_WEEK_VIEW_EVENT_EDGE_X_PAD; - - clip_rect.x = x1; - clip_rect.y = y1; - clip_rect.width = x2 - x1 - E_WEEK_VIEW_EVENT_R_PAD - - E_WEEK_VIEW_EVENT_BORDER_WIDTH + 1; - clip_rect.height = y2 - y1 + 1; - gdk_gc_set_clip_rectangle (gc, &clip_rect); - - gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_EVENT_TEXT]); - - e_week_view_draw_time (week_view, drawable, - time_x, time_y, - start_hour, start_minute); - - gdk_gc_set_clip_rectangle (gc, NULL); - - /* We don't want the end time to be drawn over the - start time, so we increase the minimum position. */ - min_end_time_x += time_width - + E_WEEK_VIEW_EVENT_TIME_X_PAD; - } - - max_icon_x = x2 + 1 - E_WEEK_VIEW_EVENT_R_PAD - - E_WEEK_VIEW_EVENT_BORDER_WIDTH - - E_WEEK_VIEW_EVENT_EDGE_X_PAD; - - if (!editing_span - && event->end < week_view->day_starts[span->start_day - + span->num_days]) { - /* Calculate where the end time should be displayed. */ - time_x = x2 + 1 - E_WEEK_VIEW_EVENT_R_PAD - - E_WEEK_VIEW_EVENT_BORDER_WIDTH - - E_WEEK_VIEW_EVENT_EDGE_X_PAD - - time_width; - - /* Draw the end time, if the position is greater than - the minimum calculated above. */ - if (time_x >= min_end_time_x) { - e_week_view_draw_time (week_view, drawable, - time_x, time_y, - end_hour, end_minute); - max_icon_x -= time_width - + E_WEEK_VIEW_EVENT_TIME_X_PAD; - } - } - - /* Draw the icons. */ - if (span->text_item && - week_view->editing_event_num != wveitem->event_num - && week_view->editing_span_num != wveitem->span_num) { - icon_x = span->text_item->x1 - x; - e_week_view_event_item_draw_icons (wveitem, drawable, - icon_x, icon_y, - max_icon_x, TRUE); - } - } -} - - -static void -e_week_view_draw_time (EWeekView *week_view, - GdkDrawable *drawable, - gint time_x, - gint time_y, - gint hour, - gint minute) -{ - GtkStyle *style; - GdkGC *gc; - GdkFont *font, *small_font; - gint hour_to_display, suffix_width; - gint time_y_normal_font, time_y_small_font; - gchar buffer[128], *suffix; - - style = GTK_WIDGET (week_view)->style; - font = style->font; - small_font = week_view->small_font; - gc = week_view->main_gc; - - - time_y_normal_font = time_y_small_font = time_y + font->ascent; - if (small_font) - time_y_small_font = time_y + small_font->ascent; - - e_week_view_convert_time_to_display (week_view, hour, &hour_to_display, - &suffix, &suffix_width); - - if (week_view->use_small_font && week_view->small_font) { - g_snprintf (buffer, sizeof (buffer), "%2i:%02i", - hour_to_display, minute); - - /* Draw the hour. */ - if (hour_to_display < 10) - gdk_draw_text (drawable, font, gc, - time_x + week_view->digit_width, - time_y_normal_font, buffer + 1, 1); - else - gdk_draw_text (drawable, font, gc, - time_x, time_y_normal_font, buffer, 2); - - time_x += week_view->digit_width * 2; - - /* Draw the start minute, in the small font. */ - gdk_draw_text (drawable, week_view->small_font, gc, - time_x, time_y_small_font, buffer + 3, 2); - - time_x += week_view->small_digit_width * 2; - - /* Draw the 'am'/'pm' suffix, if 12-hour format. */ - if (!week_view->use_24_hour_format) { - gdk_draw_string (drawable, font, gc, - time_x, time_y_normal_font, suffix); - } - } else { - /* Draw the start time in one go. */ - g_snprintf (buffer, sizeof (buffer), "%2i:%02i%s", - hour_to_display, minute, suffix); - if (hour_to_display < 10) - gdk_draw_string (drawable, font, gc, - time_x + week_view->digit_width, - time_y_normal_font, buffer + 1); - else - gdk_draw_string (drawable, font, gc, - time_x, time_y_normal_font, - buffer); - - } -} - - -static void -e_week_view_event_item_draw_icons (EWeekViewEventItem *wveitem, - GdkDrawable *drawable, - gint icon_x, - gint icon_y, - gint x2, - gboolean right_align) -{ - EWeekView *week_view; - EWeekViewEvent *event; - EWeekViewEventSpan *span; - CalComponent *comp; - GdkGC *gc; - gint num_icons = 0, icon_x_inc; - gboolean draw_reminder_icon = FALSE, draw_recurrence_icon = FALSE; - - week_view = E_WEEK_VIEW (GTK_WIDGET (GNOME_CANVAS_ITEM (wveitem)->canvas)->parent); - - event = &g_array_index (week_view->events, EWeekViewEvent, - wveitem->event_num); - span = &g_array_index (week_view->spans, EWeekViewEventSpan, - event->spans_index + wveitem->span_num); - comp = event->comp; - - gc = week_view->main_gc; - - if (cal_component_has_alarms (comp)) { - draw_reminder_icon = TRUE; - num_icons++; - } - - if (cal_component_has_recurrences (comp)) { - draw_recurrence_icon = TRUE; - num_icons++; - } - - icon_x_inc = E_WEEK_VIEW_ICON_WIDTH + E_WEEK_VIEW_ICON_X_PAD; - - if (right_align) - icon_x -= icon_x_inc * num_icons; - - if (draw_reminder_icon && icon_x + E_WEEK_VIEW_ICON_WIDTH <= x2) { - gdk_gc_set_clip_origin (gc, icon_x, icon_y); - gdk_gc_set_clip_mask (gc, week_view->reminder_mask); - gdk_draw_pixmap (drawable, gc, - week_view->reminder_icon, - 0, 0, icon_x, icon_y, - E_WEEK_VIEW_ICON_WIDTH, - E_WEEK_VIEW_ICON_HEIGHT); - icon_x += icon_x_inc; - } - - if (draw_recurrence_icon && icon_x + E_WEEK_VIEW_ICON_WIDTH <= x2) { - gdk_gc_set_clip_origin (gc, icon_x, icon_y); - gdk_gc_set_clip_mask (gc, week_view->recurrence_mask); - gdk_draw_pixmap (drawable, gc, - week_view->recurrence_icon, - 0, 0, icon_x, icon_y, - E_WEEK_VIEW_ICON_WIDTH, - E_WEEK_VIEW_ICON_HEIGHT); - icon_x += icon_x_inc; - } - - gdk_gc_set_clip_mask (gc, NULL); -} - - -/* This draws a little triangle to indicate that an event extends past - the days visible on screen. */ -static void -e_week_view_event_item_draw_triangle (EWeekViewEventItem *wveitem, - GdkDrawable *drawable, - gint x, - gint y, - gint w, - gint h) -{ - EWeekView *week_view; - GdkGC *gc; - GdkPoint points[3]; - gint c1, c2; - - week_view = E_WEEK_VIEW (GTK_WIDGET (GNOME_CANVAS_ITEM (wveitem)->canvas)->parent); - - gc = week_view->main_gc; - - points[0].x = x; - points[0].y = y; - points[1].x = x + w; - points[1].y = y + (h / 2) - 1; - points[2].x = x; - points[2].y = y + h - 1; - - gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND]); - gdk_draw_polygon (drawable, gc, TRUE, points, 3); - - gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BORDER]); - - /* If the height is odd we can use the same central point for both - lines. If it is even we use different end-points. */ - c1 = c2 = y + (h / 2); - if (h % 2 == 0) - c1--; - - gdk_draw_line (drawable, gc, x, y, x + w, c1); - gdk_draw_line (drawable, gc, x, y + h - 1, x + w, c2); -} - - -/* This is supposed to return the nearest item the the point and the distance. - Since we are the only item we just return ourself and 0 for the distance. - This is needed so that we get button/motion events. */ -static double -e_week_view_event_item_point (GnomeCanvasItem *item, double x, double y, - int cx, int cy, - GnomeCanvasItem **actual_item) -{ - *actual_item = item; - return 0.0; -} - - -static gint -e_week_view_event_item_event (GnomeCanvasItem *item, GdkEvent *event) -{ - EWeekViewEventItem *wveitem; - - wveitem = E_WEEK_VIEW_EVENT_ITEM (item); - - switch (event->type) { - case GDK_BUTTON_PRESS: - return e_week_view_event_item_button_press (wveitem, event); - case GDK_BUTTON_RELEASE: - return e_week_view_event_item_button_release (wveitem, event); - case GDK_MOTION_NOTIFY: - break; - default: - break; - } - - return FALSE; -} - - -static gboolean -e_week_view_event_item_button_press (EWeekViewEventItem *wveitem, - GdkEvent *bevent) -{ - EWeekView *week_view; - EWeekViewPosition pos; - EWeekViewEvent *event; - EWeekViewEventSpan *span; - GnomeCanvasItem *item; - - item = GNOME_CANVAS_ITEM (wveitem); - - week_view = E_WEEK_VIEW (GTK_WIDGET (item->canvas)->parent); - g_return_val_if_fail (E_IS_WEEK_VIEW (week_view), FALSE); - - event = &g_array_index (week_view->events, EWeekViewEvent, - wveitem->event_num); - span = &g_array_index (week_view->spans, EWeekViewEventSpan, - event->spans_index + wveitem->span_num); - -#if 0 - g_print ("In e_week_view_event_item_button_press\n"); -#endif - - pos = e_week_view_event_item_get_position (wveitem, bevent->button.x, - bevent->button.y); - if (pos == E_WEEK_VIEW_POS_NONE) - return FALSE; - - week_view->pressed_event_num = wveitem->event_num; - week_view->pressed_span_num = wveitem->span_num; - - if (bevent->button.button == 1) { - /* Ignore clicks on the event while editing. */ - if (E_TEXT (span->text_item)->editing) - return FALSE; - - /* Remember the item clicked and the mouse position, - so we can start a drag if the mouse moves. */ - week_view->drag_event_x = bevent->button.x; - week_view->drag_event_y = bevent->button.y; - - /* FIXME: Remember the day offset from the start of the event. - */ - } else if (bevent->button.button == 3) { - if (!GTK_WIDGET_HAS_FOCUS (week_view)) - gtk_widget_grab_focus (GTK_WIDGET (week_view)); - e_week_view_show_popup_menu (week_view, - (GdkEventButton*) bevent, - wveitem->event_num); - gtk_signal_emit_stop_by_name (GTK_OBJECT (item->canvas), - "button_press_event"); - } - - return TRUE; -} - - -static gboolean -e_week_view_event_item_button_release (EWeekViewEventItem *wveitem, - GdkEvent *event) -{ - EWeekView *week_view; - GnomeCanvasItem *item; - - item = GNOME_CANVAS_ITEM (wveitem); - - week_view = E_WEEK_VIEW (GTK_WIDGET (item->canvas)->parent); - g_return_val_if_fail (E_IS_WEEK_VIEW (week_view), FALSE); - -#if 0 - g_print ("In e_week_view_event_item_button_release\n"); -#endif - - if (week_view->pressed_event_num != -1 - && week_view->pressed_event_num == wveitem->event_num - && week_view->pressed_span_num == wveitem->span_num) { - e_week_view_start_editing_event (week_view, - wveitem->event_num, - wveitem->span_num, - NULL); - week_view->pressed_event_num = -1; - return TRUE; - } - - week_view->pressed_event_num = -1; - - return FALSE; -} - - -static EWeekViewPosition -e_week_view_event_item_get_position (EWeekViewEventItem *wveitem, - gdouble x, - gdouble y) -{ - EWeekView *week_view; - GnomeCanvasItem *item; - - item = GNOME_CANVAS_ITEM (wveitem); - - week_view = E_WEEK_VIEW (GTK_WIDGET (item->canvas)->parent); - g_return_val_if_fail (E_IS_WEEK_VIEW (week_view), E_WEEK_VIEW_POS_NONE); - -#if 0 - g_print ("In e_week_view_event_item_get_position item: %g,%g %g,%g point: %g,%g\n", item->x1, item->y1, item->x2, item->y2, x, y); -#endif - - if (x < item->x1 + E_WEEK_VIEW_EVENT_L_PAD - || x >= item->x2 - E_WEEK_VIEW_EVENT_R_PAD) - return E_WEEK_VIEW_POS_NONE; - - /* Support left/right edge for long events only. */ - if (!e_week_view_is_one_day_event (week_view, wveitem->event_num)) { - if (x < item->x1 + E_WEEK_VIEW_EVENT_L_PAD - + E_WEEK_VIEW_EVENT_BORDER_WIDTH - + E_WEEK_VIEW_EVENT_EDGE_X_PAD) - return E_WEEK_VIEW_POS_LEFT_EDGE; - - if (x >= item->x2 + 1 - E_WEEK_VIEW_EVENT_R_PAD - - E_WEEK_VIEW_EVENT_BORDER_WIDTH - - E_WEEK_VIEW_EVENT_EDGE_X_PAD) - return E_WEEK_VIEW_POS_RIGHT_EDGE; - } - - return E_WEEK_VIEW_POS_EVENT; -} diff --git a/calendar/gui/e-week-view-event-item.h b/calendar/gui/e-week-view-event-item.h deleted file mode 100644 index ff2b9b2c9f..0000000000 --- a/calendar/gui/e-week-view-event-item.h +++ /dev/null @@ -1,71 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 1999, Helix Code, Inc. - * Copyright 2001, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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 - */ -#ifndef _E_WEEK_VIEW_EVENT_ITEM_H_ -#define _E_WEEK_VIEW_EVENT_ITEM_H_ - -#include "e-week-view.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - * EWeekViewEventItem - displays the background, times and icons for an event - * in the week/month views. A separate EText canvas item is used to display & - * edit the text. - */ - -#define E_WEEK_VIEW_EVENT_ITEM(obj) (GTK_CHECK_CAST((obj), \ - e_week_view_event_item_get_type (), EWeekViewEventItem)) -#define E_WEEK_VIEW_EVENT_ITEM_CLASS(k) (GTK_CHECK_CLASS_CAST ((k),\ - e_week_view_event_item_get_type ())) -#define E_IS_WEEK_VIEW_EVENT_ITEM(o) (GTK_CHECK_TYPE((o), \ - e_week_view_event_item_get_type ())) - -typedef struct { - GnomeCanvasItem canvas_item; - - /* The event index in the EWeekView events array. */ - gint event_num; - - /* The span index within the event. */ - gint span_num; -} EWeekViewEventItem; - -typedef struct { - GnomeCanvasItemClass parent_class; - -} EWeekViewEventItemClass; - - -GtkType e_week_view_event_item_get_type (void); - - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_WEEK_VIEW_EVENT_ITEM_H_ */ diff --git a/calendar/gui/e-week-view-main-item.c b/calendar/gui/e-week-view-main-item.c deleted file mode 100644 index e1959489b1..0000000000 --- a/calendar/gui/e-week-view-main-item.c +++ /dev/null @@ -1,385 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@helixcode.com> - * - * Copyright 1999, Helix Code, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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 - */ - -/* - * EWeekViewMainItem - displays the background grid and dates for the Week and - * Month calendar views. - */ - -#include <config.h> -#include "e-week-view-main-item.h" - -static void e_week_view_main_item_class_init (EWeekViewMainItemClass *class); -static void e_week_view_main_item_init (EWeekViewMainItem *wvmitem); - -static void e_week_view_main_item_set_arg (GtkObject *o, - GtkArg *arg, - guint arg_id); -static void e_week_view_main_item_update (GnomeCanvasItem *item, - double *affine, - ArtSVP *clip_path, - int flags); -static void e_week_view_main_item_draw (GnomeCanvasItem *item, - GdkDrawable *drawable, - int x, - int y, - int width, - int height); -static void e_week_view_main_item_draw_day (EWeekViewMainItem *wvmitem, - gint day, - GDate *date, - GdkDrawable *drawable, - gint x, - gint y, - gint width, - gint height); -static double e_week_view_main_item_point (GnomeCanvasItem *item, - double x, - double y, - int cx, - int cy, - GnomeCanvasItem **actual_item); - - -static GnomeCanvasItemClass *parent_class; - -/* The arguments we take */ -enum { - ARG_0, - ARG_WEEK_VIEW -}; - - -GtkType -e_week_view_main_item_get_type (void) -{ - static GtkType e_week_view_main_item_type = 0; - - if (!e_week_view_main_item_type) { - GtkTypeInfo e_week_view_main_item_info = { - "EWeekViewMainItem", - sizeof (EWeekViewMainItem), - sizeof (EWeekViewMainItemClass), - (GtkClassInitFunc) e_week_view_main_item_class_init, - (GtkObjectInitFunc) e_week_view_main_item_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - e_week_view_main_item_type = gtk_type_unique (gnome_canvas_item_get_type (), &e_week_view_main_item_info); - } - - return e_week_view_main_item_type; -} - - -static void -e_week_view_main_item_class_init (EWeekViewMainItemClass *class) -{ - GtkObjectClass *object_class; - GnomeCanvasItemClass *item_class; - - parent_class = gtk_type_class (gnome_canvas_item_get_type()); - - object_class = (GtkObjectClass *) class; - item_class = (GnomeCanvasItemClass *) class; - - gtk_object_add_arg_type ("EWeekViewMainItem::week_view", - GTK_TYPE_POINTER, GTK_ARG_WRITABLE, - ARG_WEEK_VIEW); - - object_class->set_arg = e_week_view_main_item_set_arg; - - /* GnomeCanvasItem method overrides */ - item_class->update = e_week_view_main_item_update; - item_class->draw = e_week_view_main_item_draw; - item_class->point = e_week_view_main_item_point; -} - - -static void -e_week_view_main_item_init (EWeekViewMainItem *wvmitem) -{ - wvmitem->week_view = NULL; -} - - -static void -e_week_view_main_item_set_arg (GtkObject *o, GtkArg *arg, guint arg_id) -{ - GnomeCanvasItem *item; - EWeekViewMainItem *wvmitem; - - item = GNOME_CANVAS_ITEM (o); - wvmitem = E_WEEK_VIEW_MAIN_ITEM (o); - - switch (arg_id){ - case ARG_WEEK_VIEW: - wvmitem->week_view = GTK_VALUE_POINTER (*arg); - break; - } -} - - -static void -e_week_view_main_item_update (GnomeCanvasItem *item, - double *affine, - ArtSVP *clip_path, - int flags) -{ - if (GNOME_CANVAS_ITEM_CLASS (parent_class)->update) - (* GNOME_CANVAS_ITEM_CLASS (parent_class)->update) (item, affine, clip_path, flags); - - /* The item covers the entire canvas area. */ - item->x1 = 0; - item->y1 = 0; - item->x2 = INT_MAX; - item->y2 = INT_MAX; -} - - -/* - * DRAWING ROUTINES - functions to paint the canvas item. - */ - -static void -e_week_view_main_item_draw (GnomeCanvasItem *canvas_item, - GdkDrawable *drawable, - int x, - int y, - int width, - int height) -{ - EWeekViewMainItem *wvmitem; - EWeekView *week_view; - GDate date; - gint num_days, day, day_x, day_y, day_w, day_h; - -#if 0 - g_print ("In e_week_view_main_item_draw %i,%i %ix%i\n", - x, y, width, height); -#endif - - wvmitem = E_WEEK_VIEW_MAIN_ITEM (canvas_item); - week_view = wvmitem->week_view; - g_return_if_fail (week_view != NULL); - - /* Step through each of the days. */ - date = week_view->first_day_shown; - - /* If no date has been set, we just use Dec 1999/January 2000. */ - if (!g_date_valid (&date)) - g_date_set_dmy (&date, 27, 12, 1999); - - num_days = week_view->multi_week_view ? week_view->weeks_shown * 7 : 7; - for (day = 0; day < num_days; day++) { - e_week_view_get_day_position (week_view, day, - &day_x, &day_y, - &day_w, &day_h); - /* Skip any days which are outside the area. */ - if (day_x < x + width && day_x + day_w >= x - && day_y < y + height && day_y + day_h >= y) { - e_week_view_main_item_draw_day (wvmitem, day, &date, - drawable, - day_x - x, day_y - y, - day_w, day_h); - } - g_date_add_days (&date, 1); - } -} - - -static void -e_week_view_main_item_draw_day (EWeekViewMainItem *wvmitem, - gint day, - GDate *date, - GdkDrawable *drawable, - gint x, - gint y, - gint width, - gint height) -{ - EWeekView *week_view; - GtkStyle *style; - GdkGC *gc; - GdkFont *font; - gint right_edge, bottom_edge, date_width, date_x, line_y; - gboolean show_day_name, show_month_name, selected; - gchar buffer[128], *format_string; - gint month, day_of_month, max_width; - GdkColor *bg_color; - -#if 0 - g_print ("Drawing Day:%i at %i,%i\n", day, x, y); -#endif - week_view = wvmitem->week_view; - style = GTK_WIDGET (week_view)->style; - font = style->font; - gc = week_view->main_gc; - - g_return_if_fail (gc != NULL); - - month = g_date_month (date); - day_of_month = g_date_day (date); - line_y = y + E_WEEK_VIEW_DATE_T_PAD + font->ascent - + font->descent + E_WEEK_VIEW_DATE_LINE_T_PAD; - - /* Draw the background of the day. In the month view odd months are - one color and even months another, so you can easily see when each - month starts (defaults are white for odd - January, March, ... and - light gray for even). In the week view the background is always the - same color, the color used for the odd months in the month view. */ - if (week_view->multi_week_view && (month % 2 == 0)) - bg_color = &week_view->colors[E_WEEK_VIEW_COLOR_EVEN_MONTHS]; - else - bg_color = &week_view->colors[E_WEEK_VIEW_COLOR_ODD_MONTHS]; - - gdk_gc_set_foreground (gc, bg_color); - gdk_draw_rectangle (drawable, gc, TRUE, x, y, width, height); - - /* Draw the lines on the right and bottom of the cell. The canvas is - sized so that the lines on the right & bottom edges will be off the - edge of the canvas, so we don't have to worry about them. */ - right_edge = x + width - 1; - bottom_edge = y + height - 1; - - gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_GRID]); - gdk_draw_line (drawable, gc, - right_edge, y, right_edge, bottom_edge); - gdk_draw_line (drawable, gc, - x, bottom_edge, right_edge, bottom_edge); - - /* If the day is selected, draw the blue background. */ - selected = TRUE; - if (!GTK_WIDGET_HAS_FOCUS (week_view) - || week_view->selection_start_day == -1 - || week_view->selection_start_day > day - || week_view->selection_end_day < day) - selected = FALSE; - if (selected) { - gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_SELECTED]); - if (week_view->multi_week_view) { - gdk_draw_rectangle (drawable, gc, TRUE, - x + 2, y + 1, - width - 5, - E_WEEK_VIEW_DATE_T_PAD - 1 - + font->ascent + font->descent); - } else { - gdk_draw_rectangle (drawable, gc, TRUE, - x + 2, y + 1, - width - 5, line_y - y); - } - } - - /* Display the date in the top of the cell. - In the week view, display the long format "10 January" in all cells, - or abbreviate it to "10 Jan" or "10" if that doesn't fit. - In the month view, only use the long format for the first cell and - the 1st of each month, otherwise use "10". */ - show_day_name = FALSE; - show_month_name = FALSE; - if (!week_view->multi_week_view) { - show_day_name = TRUE; - show_month_name = TRUE; - } else if (day == 0 || day_of_month == 1) { - show_month_name = TRUE; - } - - /* Now find the longest form of the date that will fit. */ - max_width = width - 4; - format_string = NULL; - if (show_day_name) { - if (week_view->max_day_width + week_view->digit_width * 2 - + week_view->space_width * 2 - + week_view->month_widths[month - 1] < max_width) - /* strftime format %A = full weekday name, %d = day of - month, %B = full month name. You can change the - order but don't change the specifiers or add - anything. */ - format_string = _("%A %d %B"); - else if (week_view->max_abbr_day_width - + week_view->digit_width * 2 - + week_view->space_width * 2 - + week_view->abbr_month_widths[month - 1] < max_width) - /* strftime format %a = abbreviated weekday name, - %d = day of month, %b = abbreviated month name. - You can change the order but don't change the - specifiers or add anything. */ - format_string = _("%a %d %b"); - } - if (!format_string && show_month_name) { - if (week_view->digit_width * 2 + week_view->space_width - + week_view->month_widths[month - 1] < max_width) - /* strftime format %d = day of month, %B = full - month name. You can change the order but don't - change the specifiers or add anything. */ - format_string = _("%d %B"); - else if (week_view->digit_width * 2 + week_view->space_width - + week_view->abbr_month_widths[month - 1] < max_width) - /* strftime format %d = day of month, %b = abbreviated - month name. You can change the order but don't - change the specifiers or add anything. */ - format_string = _("%d %b"); - } - - g_date_strftime (buffer, sizeof (buffer), - format_string ? format_string : "%d", date); - date_width = gdk_string_width (font, buffer); - date_x = x + width - date_width - E_WEEK_VIEW_DATE_R_PAD; - date_x = MAX (date_x, x + 1); - - if (selected) - gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_DATES_SELECTED]); - else - gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_DATES]); - gdk_draw_string (drawable, font, gc, - date_x, y + E_WEEK_VIEW_DATE_T_PAD + font->ascent, - buffer); - - /* Draw the line under the date. */ - if (!week_view->multi_week_view) { - gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_GRID]); - gdk_draw_line (drawable, gc, - x + E_WEEK_VIEW_DATE_LINE_L_PAD, line_y, - right_edge, line_y); - } -} - - - - -/* This is supposed to return the nearest item the the point and the distance. - Since we are the only item we just return ourself and 0 for the distance. - This is needed so that we get button/motion events. */ -static double -e_week_view_main_item_point (GnomeCanvasItem *item, double x, double y, - int cx, int cy, - GnomeCanvasItem **actual_item) -{ - *actual_item = item; - return 0.0; -} - - diff --git a/calendar/gui/e-week-view-main-item.h b/calendar/gui/e-week-view-main-item.h deleted file mode 100644 index 71ebe423dc..0000000000 --- a/calendar/gui/e-week-view-main-item.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 1999, Helix Code, Inc. - * Copyright 2001, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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 - */ -#ifndef _E_WEEK_VIEW_MAIN_ITEM_H_ -#define _E_WEEK_VIEW_MAIN_ITEM_H_ - -#include "e-week-view.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - * EWeekViewMainItem - displays the background grid and dates for the Week and - * Month calendar views. - */ - -#define E_WEEK_VIEW_MAIN_ITEM(obj) (GTK_CHECK_CAST((obj), \ - e_week_view_main_item_get_type (), EWeekViewMainItem)) -#define E_WEEK_VIEW_MAIN_ITEM_CLASS(k) (GTK_CHECK_CLASS_CAST ((k),\ - e_week_view_main_item_get_type ())) -#define E_IS_WEEK_VIEW_MAIN_ITEM(o) (GTK_CHECK_TYPE((o), \ - e_week_view_main_item_get_type ())) - -typedef struct { - GnomeCanvasItem canvas_item; - - /* The parent EWeekView widget. */ - EWeekView *week_view; -} EWeekViewMainItem; - -typedef struct { - GnomeCanvasItemClass parent_class; - -} EWeekViewMainItemClass; - - -GtkType e_week_view_main_item_get_type (void); - - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_WEEK_VIEW_MAIN_ITEM_H_ */ diff --git a/calendar/gui/e-week-view-titles-item.c b/calendar/gui/e-week-view-titles-item.c deleted file mode 100644 index 5a2b9c164a..0000000000 --- a/calendar/gui/e-week-view-titles-item.c +++ /dev/null @@ -1,311 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@helixcode.com> - * - * Copyright 1999, Helix Code, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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 - */ - -/* - * EWeekViewTitlesItem - displays the 'Monday', 'Tuesday' etc. at the top of - * the Month calendar view. - */ - -#include <config.h> -#include "e-week-view-titles-item.h" - -static void e_week_view_titles_item_class_init (EWeekViewTitlesItemClass *class); -static void e_week_view_titles_item_init (EWeekViewTitlesItem *wvtitem); - -static void e_week_view_titles_item_set_arg (GtkObject *o, - GtkArg *arg, - guint arg_id); -static void e_week_view_titles_item_update (GnomeCanvasItem *item, - double *affine, - ArtSVP *clip_path, - int flags); -static void e_week_view_titles_item_draw (GnomeCanvasItem *item, - GdkDrawable *drawable, - int x, - int y, - int width, - int height); -static double e_week_view_titles_item_point (GnomeCanvasItem *item, - double x, - double y, - int cx, - int cy, - GnomeCanvasItem **actual_item); - - -static GnomeCanvasItemClass *parent_class; - -/* The arguments we take */ -enum { - ARG_0, - ARG_WEEK_VIEW -}; - - -GtkType -e_week_view_titles_item_get_type (void) -{ - static GtkType e_week_view_titles_item_type = 0; - - if (!e_week_view_titles_item_type) { - GtkTypeInfo e_week_view_titles_item_info = { - "EWeekViewTitlesItem", - sizeof (EWeekViewTitlesItem), - sizeof (EWeekViewTitlesItemClass), - (GtkClassInitFunc) e_week_view_titles_item_class_init, - (GtkObjectInitFunc) e_week_view_titles_item_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - e_week_view_titles_item_type = gtk_type_unique (gnome_canvas_item_get_type (), &e_week_view_titles_item_info); - } - - return e_week_view_titles_item_type; -} - - -static void -e_week_view_titles_item_class_init (EWeekViewTitlesItemClass *class) -{ - GtkObjectClass *object_class; - GnomeCanvasItemClass *item_class; - - parent_class = gtk_type_class (gnome_canvas_item_get_type()); - - object_class = (GtkObjectClass *) class; - item_class = (GnomeCanvasItemClass *) class; - - gtk_object_add_arg_type ("EWeekViewTitlesItem::week_view", - GTK_TYPE_POINTER, GTK_ARG_WRITABLE, - ARG_WEEK_VIEW); - - object_class->set_arg = e_week_view_titles_item_set_arg; - - /* GnomeCanvasItem method overrides */ - item_class->update = e_week_view_titles_item_update; - item_class->draw = e_week_view_titles_item_draw; - item_class->point = e_week_view_titles_item_point; -} - - -static void -e_week_view_titles_item_init (EWeekViewTitlesItem *wvtitem) -{ - wvtitem->week_view = NULL; -} - - -static void -e_week_view_titles_item_set_arg (GtkObject *o, GtkArg *arg, guint arg_id) -{ - GnomeCanvasItem *item; - EWeekViewTitlesItem *wvtitem; - - item = GNOME_CANVAS_ITEM (o); - wvtitem = E_WEEK_VIEW_TITLES_ITEM (o); - - switch (arg_id){ - case ARG_WEEK_VIEW: - wvtitem->week_view = GTK_VALUE_POINTER (*arg); - break; - } -} - - -static void -e_week_view_titles_item_update (GnomeCanvasItem *item, - double *affine, - ArtSVP *clip_path, - int flags) -{ - if (GNOME_CANVAS_ITEM_CLASS (parent_class)->update) - (* GNOME_CANVAS_ITEM_CLASS (parent_class)->update) (item, affine, clip_path, flags); - - /* The item covers the entire canvas area. */ - item->x1 = 0; - item->y1 = 0; - item->x2 = INT_MAX; - item->y2 = INT_MAX; -} - - -/* - * DRAWING ROUTINES - functions to paint the canvas item. - */ - -static void -e_week_view_titles_item_draw (GnomeCanvasItem *canvas_item, - GdkDrawable *drawable, - int x, - int y, - int width, - int height) -{ - EWeekViewTitlesItem *wvtitem; - EWeekView *week_view; - GtkStyle *style; - GdkGC *fg_gc, *bg_gc, *light_gc, *dark_gc; - GdkFont *font; - gint canvas_width, canvas_height, col_width, col, date_width, date_x; - gchar buffer[128], *date_format; - GDate date; - GdkRectangle clip_rect; - gboolean long_format; - gint weekday; - -#if 0 - g_print ("In e_week_view_titles_item_draw %i,%i %ix%i\n", - x, y, width, height); -#endif - - wvtitem = E_WEEK_VIEW_TITLES_ITEM (canvas_item); - week_view = wvtitem->week_view; - g_return_if_fail (week_view != NULL); - - style = GTK_WIDGET (week_view)->style; - font = style->font; - fg_gc = style->fg_gc[GTK_STATE_NORMAL]; - bg_gc = style->bg_gc[GTK_STATE_NORMAL]; - light_gc = style->light_gc[GTK_STATE_NORMAL]; - dark_gc = style->dark_gc[GTK_STATE_NORMAL]; - canvas_width = GTK_WIDGET (canvas_item->canvas)->allocation.width; - canvas_height = GTK_WIDGET (canvas_item->canvas)->allocation.height; - - /* Draw the shadow around the dates. */ - gdk_draw_line (drawable, light_gc, - 1 - x, 1 - y, - canvas_width - 2 - x, 1 - y); - gdk_draw_line (drawable, light_gc, - 1 - x, 2 - y, - 1 - x, canvas_height - 1 - y); - - gdk_draw_rectangle (drawable, dark_gc, FALSE, - 0 - x, 0 - y, - canvas_width - 1, canvas_height); - - /* Determine the format to use. */ - col_width = canvas_width / week_view->columns; - if (col_width > week_view->max_day_width + 2) { - date_format = "%A"; - long_format = TRUE; - } else { - date_format = "%a"; - long_format = FALSE; - } - - /* Shift right one pixel to account for the shadow around the main - canvas. */ - x--; - - /* Draw the date. Set a clipping rectangle so we don't draw over the - next day. */ - g_date_clear (&date, 1); - /* Note that 20th March 2000 is a Monday. We only care about the - weekday. */ - weekday = week_view->display_start_day; - g_date_set_dmy (&date, 20 + weekday, 3, 2000); - for (col = 0; col < week_view->columns; col++) { - if (weekday == 5 && week_view->compress_weekend) { - g_date_strftime (buffer, 128, "%a/", &date); - g_date_add_days (&date, 1); - g_date_strftime (buffer + strlen (buffer), 100, - "%a", &date); - } else { - g_date_strftime (buffer, 128, date_format, &date); - } - - clip_rect.x = week_view->col_offsets[col] - x; - clip_rect.y = 2 - y; - clip_rect.width = week_view->col_widths[col]; - clip_rect.height = canvas_height - 2; - gdk_gc_set_clip_rectangle (fg_gc, &clip_rect); - - if (weekday == 5 && week_view->compress_weekend) - date_width = week_view->abbr_day_widths[5] - + week_view->slash_width - + week_view->abbr_day_widths[6]; - else if (long_format) - date_width = week_view->day_widths[weekday]; - else - date_width = week_view->abbr_day_widths[weekday]; - - date_x = week_view->col_offsets[col] - + (week_view->col_widths[col] - date_width) / 2; - date_x = MAX (date_x, week_view->col_offsets[col]); - gdk_draw_string (drawable, font, fg_gc, - date_x - x, 3 + font->ascent - y, buffer); - - gdk_gc_set_clip_rectangle (fg_gc, NULL); - - /* Draw the lines down the left and right of the date cols. */ - if (col != 0) { - gdk_draw_line (drawable, light_gc, - week_view->col_offsets[col] - x, - 4 - y, - week_view->col_offsets[col] - x, - canvas_height - 4 - y); - - gdk_draw_line (drawable, dark_gc, - week_view->col_offsets[col] - 1 - x, - 4 - y, - week_view->col_offsets[col] - 1 - x, - canvas_height - 4 - y); - } - - /* Draw the lines between each column. */ - if (col != 0) { - gdk_draw_line (drawable, style->black_gc, - week_view->col_offsets[col] - x, - canvas_height - y, - week_view->col_offsets[col] - x, - canvas_height - y); - } - - if (weekday == 5 && week_view->compress_weekend) - weekday += 2; - else - weekday++; - - weekday = weekday % 7; - - g_date_add_days (&date, 1); - } -} - - -/* This is supposed to return the nearest item the the point and the distance. - Since we are the only item we just return ourself and 0 for the distance. - This is needed so that we get button/motion events. */ -static double -e_week_view_titles_item_point (GnomeCanvasItem *item, double x, double y, - int cx, int cy, - GnomeCanvasItem **actual_item) -{ - *actual_item = item; - return 0.0; -} - - diff --git a/calendar/gui/e-week-view-titles-item.h b/calendar/gui/e-week-view-titles-item.h deleted file mode 100644 index fc4d45107d..0000000000 --- a/calendar/gui/e-week-view-titles-item.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 1999, Helix Code, Inc. - * Copyright 2001, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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 - */ -#ifndef _E_WEEK_VIEW_TITLES_ITEM_H_ -#define _E_WEEK_VIEW_TITLES_ITEM_H_ - -#include "e-week-view.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - * EWeekViewTitlesItem - displays the 'Monday', 'Tuesday' etc. at the top of - * the Month calendar view. - */ - -#define E_WEEK_VIEW_TITLES_ITEM(obj) (GTK_CHECK_CAST((obj), \ - e_week_view_titles_item_get_type (), EWeekViewTitlesItem)) -#define E_WEEK_VIEW_TITLES_ITEM_CLASS(k) (GTK_CHECK_CLASS_CAST ((k),\ - e_week_view_titles_item_get_type ())) -#define E_IS_WEEK_VIEW_TITLES_ITEM(o) (GTK_CHECK_TYPE((o), \ - e_week_view_titles_item_get_type ())) - -typedef struct { - GnomeCanvasItem canvas_item; - - /* The parent EWeekView widget. */ - EWeekView *week_view; -} EWeekViewTitlesItem; - -typedef struct { - GnomeCanvasItemClass parent_class; - -} EWeekViewTitlesItemClass; - - -GtkType e_week_view_titles_item_get_type (void); - - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_WEEK_VIEW_TITLES_ITEM_H_ */ diff --git a/calendar/gui/e-week-view.c b/calendar/gui/e-week-view.c deleted file mode 100644 index 74c0df4f9c..0000000000 --- a/calendar/gui/e-week-view.c +++ /dev/null @@ -1,3547 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 1999, Helix Code, Inc. - * Copyright 2001, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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 - */ - -/* - * EWeekView - displays the Week & Month views of the calendar. - */ - -#include <config.h> -#include <math.h> -#include <gdk-pixbuf/gdk-pixbuf.h> -#include <gdk-pixbuf/gnome-canvas-pixbuf.h> -#include "dialogs/delete-comp.h" -#include "calendar-commands.h" -#include "comp-util.h" -#include "e-week-view.h" -#include "e-week-view-event-item.h" -#include "e-week-view-main-item.h" -#include "e-week-view-titles-item.h" -#include <cal-util/timeutil.h> -#include "popup-menu.h" -#include <gal/widgets/e-canvas.h> -#include <gal/e-text/e-text.h> -#include <gal/widgets/e-canvas-utils.h> -#include "e-meeting-edit.h" - -/* Images */ -#include "bell.xpm" -#include "recur.xpm" - -#include "jump.xpm" - -#define E_WEEK_VIEW_SMALL_FONT \ - "-adobe-utopia-regular-r-normal-*-*-100-*-*-p-*-iso8859-*" -#define E_WEEK_VIEW_SMALL_FONT_FALLBACK \ - "-adobe-helvetica-medium-r-normal-*-*-80-*-*-p-*-iso8859-*" - -/* We use a 7-bit field to store row numbers in EWeekViewEventSpan, so the - maximum number or rows we can allow is 127. It is very unlikely to be - reached anyway. */ -#define E_WEEK_VIEW_MAX_ROWS_PER_CELL 127 - -#define E_WEEK_VIEW_JUMP_BUTTON_WIDTH 16 -#define E_WEEK_VIEW_JUMP_BUTTON_HEIGHT 8 - -#define E_WEEK_VIEW_JUMP_BUTTON_X_PAD 3 -#define E_WEEK_VIEW_JUMP_BUTTON_Y_PAD 3 - -static void e_week_view_class_init (EWeekViewClass *class); -static void e_week_view_init (EWeekView *week_view); -static void e_week_view_destroy (GtkObject *object); -static void e_week_view_realize (GtkWidget *widget); -static void e_week_view_unrealize (GtkWidget *widget); -static void e_week_view_style_set (GtkWidget *widget, - GtkStyle *previous_style); -static void e_week_view_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); -static void e_week_view_recalc_cell_sizes (EWeekView *week_view); -static gint e_week_view_focus_in (GtkWidget *widget, - GdkEventFocus *event); -static gint e_week_view_focus_out (GtkWidget *widget, - GdkEventFocus *event); -static gint e_week_view_expose_event (GtkWidget *widget, - GdkEventExpose *event); -static void e_week_view_draw (GtkWidget *widget, - GdkRectangle *area); -static void e_week_view_draw_shadow (EWeekView *week_view); - -static gboolean e_week_view_on_button_press (GtkWidget *widget, - GdkEventButton *event, - EWeekView *week_view); -static gboolean e_week_view_on_button_release (GtkWidget *widget, - GdkEventButton *event, - EWeekView *week_view); -static gboolean e_week_view_on_motion (GtkWidget *widget, - GdkEventMotion *event, - EWeekView *week_view); -static gint e_week_view_convert_position_to_day (EWeekView *week_view, - gint x, - gint y); -static void e_week_view_update_selection (EWeekView *week_view, - gint day); - -static void e_week_view_queue_reload_events (EWeekView *week_view); -static gboolean e_week_view_reload_events_idle_cb (gpointer data); -static void e_week_view_reload_events (EWeekView *week_view); -static void e_week_view_free_events (EWeekView *week_view); -static gboolean e_week_view_add_event (CalComponent *comp, - time_t start, - time_t end, - gpointer data); -static void e_week_view_check_layout (EWeekView *week_view); -static void e_week_view_layout_events (EWeekView *week_view); -static void e_week_view_layout_event (EWeekView *week_view, - EWeekViewEvent *event, - guint8 *grid, - GArray *spans); -static void e_week_view_ensure_events_sorted (EWeekView *week_view); -static gint e_week_view_event_sort_func (const void *arg1, - const void *arg2); -static void e_week_view_reshape_events (EWeekView *week_view); -static void e_week_view_reshape_event_span (EWeekView *week_view, - gint event_num, - gint span_num); -static gint e_week_view_find_day (EWeekView *week_view, - time_t time_to_find, - gboolean include_midnight_in_prev_day); -static gint e_week_view_find_span_end (EWeekView *week_view, - gint day); -static void e_week_view_recalc_day_starts (EWeekView *week_view, - time_t lower); -static void e_week_view_on_adjustment_changed (GtkAdjustment *adjustment, - EWeekView *week_view); -static void e_week_view_on_editing_started (EWeekView *week_view, - GnomeCanvasItem *item); -static void e_week_view_on_editing_stopped (EWeekView *week_view, - GnomeCanvasItem *item); -static gboolean e_week_view_find_event_from_item (EWeekView *week_view, - GnomeCanvasItem *item, - gint *event_num, - gint *span_num); -static gboolean e_week_view_find_event_from_uid (EWeekView *week_view, - const gchar *uid, - gint *event_num_return); -typedef gboolean (* EWeekViewForeachEventCallback) (EWeekView *week_view, - gint event_num, - gpointer data); - -static void e_week_view_foreach_event_with_uid (EWeekView *week_view, - const gchar *uid, - EWeekViewForeachEventCallback callback, - gpointer data); -static gboolean e_week_view_on_text_item_event (GnomeCanvasItem *item, - GdkEvent *event, - EWeekView *week_view); -static gboolean e_week_view_on_jump_button_event (GnomeCanvasItem *item, - GdkEvent *event, - EWeekView *week_view); -static gint e_week_view_key_press (GtkWidget *widget, GdkEventKey *event); -static void e_week_view_on_new_appointment (GtkWidget *widget, - gpointer data); -static void e_week_view_on_edit_appointment (GtkWidget *widget, - gpointer data); -static void e_week_view_on_delete_occurrence (GtkWidget *widget, - gpointer data); -static void e_week_view_on_delete_appointment (GtkWidget *widget, - gpointer data); -static void e_week_view_on_schedule_meet (GtkWidget *widget, - gpointer data); -static void e_week_view_on_unrecur_appointment (GtkWidget *widget, - gpointer data); - -static gboolean e_week_view_update_event_cb (EWeekView *week_view, - gint event_num, - gpointer data); -static gboolean e_week_view_remove_event_cb (EWeekView *week_view, - gint event_num, - gpointer data); -static gboolean e_week_view_recalc_display_start_day (EWeekView *week_view); - -static GtkTableClass *parent_class; - - -GtkType -e_week_view_get_type (void) -{ - static GtkType e_week_view_type = 0; - - if (!e_week_view_type){ - GtkTypeInfo e_week_view_info = { - "EWeekView", - sizeof (EWeekView), - sizeof (EWeekViewClass), - (GtkClassInitFunc) e_week_view_class_init, - (GtkObjectInitFunc) e_week_view_init, - NULL, /* reserved 1 */ - NULL, /* reserved 2 */ - (GtkClassInitFunc) NULL - }; - - parent_class = gtk_type_class (GTK_TYPE_TABLE); - e_week_view_type = gtk_type_unique (GTK_TYPE_TABLE, - &e_week_view_info); - } - - return e_week_view_type; -} - - -static void -e_week_view_class_init (EWeekViewClass *class) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - - object_class = (GtkObjectClass *) class; - widget_class = (GtkWidgetClass *) class; - - /* Method override */ - object_class->destroy = e_week_view_destroy; - - widget_class->realize = e_week_view_realize; - widget_class->unrealize = e_week_view_unrealize; - widget_class->style_set = e_week_view_style_set; - widget_class->size_allocate = e_week_view_size_allocate; - widget_class->focus_in_event = e_week_view_focus_in; - widget_class->focus_out_event = e_week_view_focus_out; - widget_class->key_press_event = e_week_view_key_press; - widget_class->expose_event = e_week_view_expose_event; - widget_class->draw = e_week_view_draw; -} - - -static void -e_week_view_init (EWeekView *week_view) -{ - GnomeCanvasGroup *canvas_group; - GtkObject *adjustment; - GdkPixbuf *pixbuf; - gint i; - - GTK_WIDGET_SET_FLAGS (week_view, GTK_CAN_FOCUS); - - week_view->calendar = NULL; - week_view->client = NULL; - - week_view->events = g_array_new (FALSE, FALSE, - sizeof (EWeekViewEvent)); - week_view->events_sorted = TRUE; - week_view->events_need_layout = FALSE; - week_view->events_need_reshape = FALSE; - week_view->reload_events_idle_id = 0; - - week_view->spans = NULL; - - week_view->multi_week_view = FALSE; - week_view->weeks_shown = 6; - week_view->rows = 6; - week_view->columns = 2; - week_view->compress_weekend = TRUE; - week_view->show_event_end_times = TRUE; - week_view->week_start_day = 0; /* Monday. */ - week_view->display_start_day = 0; /* Monday. */ - - g_date_clear (&week_view->base_date, 1); - g_date_clear (&week_view->first_day_shown, 1); - - week_view->row_height = 10; - week_view->rows_per_cell = 1; - - week_view->selection_start_day = -1; - week_view->selection_drag_pos = E_WEEK_VIEW_DRAG_NONE; - - week_view->pressed_event_num = -1; - week_view->editing_event_num = -1; - - week_view->main_gc = NULL; - - /* Create the small font. */ - week_view->use_small_font = TRUE; - week_view->small_font = gdk_font_load (E_WEEK_VIEW_SMALL_FONT); - if (!week_view->small_font) - week_view->small_font = gdk_font_load (E_WEEK_VIEW_SMALL_FONT_FALLBACK); - if (!week_view->small_font) - g_warning ("Couldn't load font"); - - /* String to use in 12-hour time format for times in the morning. */ - week_view->am_string = _("am"); - - /* String to use in 12-hour time format for times in the afternoon. */ - week_view->pm_string = _("pm"); - - - /* - * Titles Canvas. Note that we don't show it is only shown in the - * Month view. - */ - week_view->titles_canvas = e_canvas_new (); - gtk_table_attach (GTK_TABLE (week_view), week_view->titles_canvas, - 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); - - canvas_group = GNOME_CANVAS_GROUP (GNOME_CANVAS (week_view->titles_canvas)->root); - - week_view->titles_canvas_item = - gnome_canvas_item_new (canvas_group, - e_week_view_titles_item_get_type (), - "EWeekViewTitlesItem::week_view", week_view, - NULL); - - /* - * Main Canvas - */ - week_view->main_canvas = e_canvas_new (); - gtk_table_attach (GTK_TABLE (week_view), week_view->main_canvas, - 1, 2, 1, 2, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 1, 1); - gtk_widget_show (week_view->main_canvas); - - canvas_group = GNOME_CANVAS_GROUP (GNOME_CANVAS (week_view->main_canvas)->root); - - week_view->main_canvas_item = - gnome_canvas_item_new (canvas_group, - e_week_view_main_item_get_type (), - "EWeekViewMainItem::week_view", week_view, - NULL); - - gtk_signal_connect_after (GTK_OBJECT (week_view->main_canvas), - "button_press_event", - GTK_SIGNAL_FUNC (e_week_view_on_button_press), - week_view); - gtk_signal_connect_after (GTK_OBJECT (week_view->main_canvas), - "button_release_event", - GTK_SIGNAL_FUNC (e_week_view_on_button_release), - week_view); - gtk_signal_connect_after (GTK_OBJECT (week_view->main_canvas), - "motion_notify_event", - GTK_SIGNAL_FUNC (e_week_view_on_motion), - week_view); - - /* Create the buttons to jump to each days. */ - pixbuf = gdk_pixbuf_new_from_xpm_data ((const char**) jump_xpm); - - for (i = 0; i < E_WEEK_VIEW_MAX_WEEKS * 7; i++) { - week_view->jump_buttons[i] = gnome_canvas_item_new - (canvas_group, - gnome_canvas_pixbuf_get_type (), - "GnomeCanvasPixbuf::pixbuf", pixbuf, - NULL); - - gtk_signal_connect (GTK_OBJECT (week_view->jump_buttons[i]), - "event", - GTK_SIGNAL_FUNC (e_week_view_on_jump_button_event), - week_view); - } - gdk_pixbuf_unref (pixbuf); - - /* - * Scrollbar. - */ - adjustment = gtk_adjustment_new (0, -52, 52, 1, 1, 1); - gtk_signal_connect (adjustment, "value_changed", - GTK_SIGNAL_FUNC (e_week_view_on_adjustment_changed), - week_view); - - week_view->vscrollbar = gtk_vscrollbar_new (GTK_ADJUSTMENT (adjustment)); - gtk_table_attach (GTK_TABLE (week_view), week_view->vscrollbar, - 2, 3, 1, 2, 0, GTK_EXPAND | GTK_FILL, 0, 0); - gtk_widget_show (week_view->vscrollbar); - - - /* Create the cursors. */ - week_view->normal_cursor = gdk_cursor_new (GDK_TOP_LEFT_ARROW); - week_view->move_cursor = gdk_cursor_new (GDK_FLEUR); - week_view->resize_width_cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW); - week_view->last_cursor_set = NULL; -} - - -/** - * e_week_view_new: - * @Returns: a new #EWeekView. - * - * Creates a new #EWeekView. - **/ -GtkWidget * -e_week_view_new (void) -{ - GtkWidget *week_view; - - week_view = GTK_WIDGET (gtk_type_new (e_week_view_get_type ())); - - return week_view; -} - - -static void -e_week_view_destroy (GtkObject *object) -{ - EWeekView *week_view; - - week_view = E_WEEK_VIEW (object); - - e_week_view_free_events (week_view); - - if (week_view->reload_events_idle_id != 0) { - g_source_remove (week_view->reload_events_idle_id); - week_view->reload_events_idle_id = 0; - } - - if (week_view->client) { - gtk_signal_disconnect_by_data (GTK_OBJECT (week_view->client), week_view); - gtk_object_unref (GTK_OBJECT (week_view->client)); - week_view->client = NULL; - } - - if (week_view->small_font) - gdk_font_unref (week_view->small_font); - - gdk_cursor_destroy (week_view->normal_cursor); - gdk_cursor_destroy (week_view->move_cursor); - gdk_cursor_destroy (week_view->resize_width_cursor); - - GTK_OBJECT_CLASS (parent_class)->destroy (object); -} - - -static void -e_week_view_realize (GtkWidget *widget) -{ - EWeekView *week_view; - GdkColormap *colormap; - gboolean success[E_WEEK_VIEW_COLOR_LAST]; - gint nfailed; - - if (GTK_WIDGET_CLASS (parent_class)->realize) - (*GTK_WIDGET_CLASS (parent_class)->realize)(widget); - - week_view = E_WEEK_VIEW (widget); - week_view->main_gc = gdk_gc_new (widget->window); - - colormap = gtk_widget_get_colormap (widget); - - /* Allocate the colors. */ - week_view->colors[E_WEEK_VIEW_COLOR_EVEN_MONTHS].red = 0xeded; - week_view->colors[E_WEEK_VIEW_COLOR_EVEN_MONTHS].green = 0xeded; - week_view->colors[E_WEEK_VIEW_COLOR_EVEN_MONTHS].blue = 0xeded; - - week_view->colors[E_WEEK_VIEW_COLOR_ODD_MONTHS].red = 65535; - week_view->colors[E_WEEK_VIEW_COLOR_ODD_MONTHS].green = 65535; - week_view->colors[E_WEEK_VIEW_COLOR_ODD_MONTHS].blue = 65535; - - week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND].red = 0xd6d6; - week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND].green = 0xd6d6; - week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND].blue = 0xd6d6; - - week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BORDER].red = 0; - week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BORDER].green = 0; - week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BORDER].blue = 0; - - week_view->colors[E_WEEK_VIEW_COLOR_EVENT_TEXT].red = 0; - week_view->colors[E_WEEK_VIEW_COLOR_EVENT_TEXT].green = 0; - week_view->colors[E_WEEK_VIEW_COLOR_EVENT_TEXT].blue = 0; - - week_view->colors[E_WEEK_VIEW_COLOR_GRID].red = 0 * 257; - week_view->colors[E_WEEK_VIEW_COLOR_GRID].green = 0 * 257; - week_view->colors[E_WEEK_VIEW_COLOR_GRID].blue = 0 * 257; - - week_view->colors[E_WEEK_VIEW_COLOR_SELECTED].red = 0 * 257; - week_view->colors[E_WEEK_VIEW_COLOR_SELECTED].green = 0 * 257; - week_view->colors[E_WEEK_VIEW_COLOR_SELECTED].blue = 156 * 257; - - week_view->colors[E_WEEK_VIEW_COLOR_DATES].red = 0 * 257; - week_view->colors[E_WEEK_VIEW_COLOR_DATES].green = 0 * 257; - week_view->colors[E_WEEK_VIEW_COLOR_DATES].blue = 0 * 257; - - week_view->colors[E_WEEK_VIEW_COLOR_DATES_SELECTED].red = 65535; - week_view->colors[E_WEEK_VIEW_COLOR_DATES_SELECTED].green = 65535; - week_view->colors[E_WEEK_VIEW_COLOR_DATES_SELECTED].blue = 65535; - - nfailed = gdk_colormap_alloc_colors (colormap, week_view->colors, - E_WEEK_VIEW_COLOR_LAST, FALSE, - TRUE, success); - if (nfailed) - g_warning ("Failed to allocate all colors"); - - - /* Create the pixmaps. */ - week_view->reminder_icon = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &week_view->reminder_mask, NULL, bell_xpm); - week_view->recurrence_icon = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &week_view->recurrence_mask, NULL, recur_xpm); -} - - -static void -e_week_view_unrealize (GtkWidget *widget) -{ - EWeekView *week_view; - GdkColormap *colormap; - gint i; - - week_view = E_WEEK_VIEW (widget); - - gdk_gc_unref (week_view->main_gc); - week_view->main_gc = NULL; - - colormap = gtk_widget_get_colormap (widget); - for (i = 0; i < E_WEEK_VIEW_COLOR_LAST; i++) - gdk_colors_free (colormap, &week_view->colors[i].pixel, 1, 0); - - gdk_pixmap_unref (week_view->reminder_icon); - week_view->reminder_icon = NULL; - gdk_pixmap_unref (week_view->recurrence_icon); - week_view->recurrence_icon = NULL; - - if (GTK_WIDGET_CLASS (parent_class)->unrealize) - (*GTK_WIDGET_CLASS (parent_class)->unrealize)(widget); -} - - -static void -e_week_view_style_set (GtkWidget *widget, - GtkStyle *previous_style) -{ - EWeekView *week_view; - EWeekViewEventSpan *span; - GdkFont *font; - gint day, day_width, max_day_width, max_abbr_day_width; - gint month, month_width, max_month_width, max_abbr_month_width; - gint span_num; - GDate date; - gchar buffer[128]; - - if (GTK_WIDGET_CLASS (parent_class)->style_set) - (*GTK_WIDGET_CLASS (parent_class)->style_set)(widget, previous_style); - - week_view = E_WEEK_VIEW (widget); - font = widget->style->font; - - /* Recalculate the height of each row based on the font size. */ - week_view->row_height = font->ascent + font->descent + E_WEEK_VIEW_EVENT_BORDER_HEIGHT * 2 + E_WEEK_VIEW_EVENT_TEXT_Y_PAD * 2; - week_view->row_height = MAX (week_view->row_height, E_WEEK_VIEW_ICON_HEIGHT + E_WEEK_VIEW_ICON_Y_PAD + E_WEEK_VIEW_EVENT_BORDER_HEIGHT * 2); - - /* Set the height of the top canvas. */ - gtk_widget_set_usize (week_view->titles_canvas, -1, - font->ascent + font->descent + 5); - - /* Save the sizes of various strings in the font, so we can quickly - decide which date formats to use. */ - g_date_clear (&date, 1); - g_date_set_dmy (&date, 27, 3, 2000); /* Must be a Monday. */ - - max_day_width = 0; - max_abbr_day_width = 0; - for (day = 0; day < 7; day++) { - g_date_strftime (buffer, 128, "%A", &date); - day_width = gdk_string_width (font, buffer); - week_view->day_widths[day] = day_width; - max_day_width = MAX (max_day_width, day_width); - - g_date_strftime (buffer, 128, "%a", &date); - day_width = gdk_string_width (font, buffer); - week_view->abbr_day_widths[day] = day_width; - max_abbr_day_width = MAX (max_abbr_day_width, day_width); - - g_date_add_days (&date, 1); - } - - max_month_width = 0; - max_abbr_month_width = 0; - for (month = 0; month < 12; month++) { - g_date_set_month (&date, month + 1); - - g_date_strftime (buffer, 128, "%B", &date); - month_width = gdk_string_width (font, buffer); - week_view->month_widths[month] = month_width; - max_month_width = MAX (max_month_width, month_width); - - g_date_strftime (buffer, 128, "%b", &date); - month_width = gdk_string_width (font, buffer); - week_view->abbr_month_widths[month] = month_width; - max_abbr_month_width = MAX (max_abbr_month_width, month_width); - } - - week_view->space_width = gdk_string_width (font, " "); - week_view->colon_width = gdk_string_width (font, ":"); - week_view->slash_width = gdk_string_width (font, "/"); - week_view->digit_width = gdk_string_width (font, "5"); - if (week_view->small_font) - week_view->small_digit_width = gdk_string_width (week_view->small_font, "5"); - week_view->max_day_width = max_day_width; - week_view->max_abbr_day_width = max_abbr_day_width; - week_view->max_month_width = max_month_width; - week_view->max_abbr_month_width = max_abbr_month_width; - - week_view->am_string_width = gdk_string_width (font, - week_view->am_string); - week_view->pm_string_width = gdk_string_width (font, - week_view->pm_string); - - /* Set the font of all the EText items. */ - if (week_view->spans) { - for (span_num = 0; span_num < week_view->spans->len; - span_num++) { - span = &g_array_index (week_view->spans, - EWeekViewEventSpan, span_num); - if (span->text_item) - gnome_canvas_item_set (span->text_item, - "font_gdk", font, - NULL); - } - } -} - - -/* This recalculates the sizes of each column. */ -static void -e_week_view_size_allocate (GtkWidget *widget, GtkAllocation *allocation) -{ - EWeekView *week_view; - gdouble old_x2, old_y2, new_x2, new_y2; - - week_view = E_WEEK_VIEW (widget); - - (*GTK_WIDGET_CLASS (parent_class)->size_allocate) (widget, allocation); - - e_week_view_recalc_cell_sizes (week_view); - - /* Set the scroll region of the top canvas to its allocated size. */ - gnome_canvas_get_scroll_region (GNOME_CANVAS (week_view->titles_canvas), - NULL, NULL, &old_x2, &old_y2); - new_x2 = week_view->titles_canvas->allocation.width - 1; - new_y2 = week_view->titles_canvas->allocation.height - 1; - if (old_x2 != new_x2 || old_y2 != new_y2) - gnome_canvas_set_scroll_region (GNOME_CANVAS (week_view->titles_canvas), - 0, 0, new_x2, new_y2); - - - /* Set the scroll region of the main canvas to its allocated width, - but with the height depending on the number of rows needed. */ - gnome_canvas_get_scroll_region (GNOME_CANVAS (week_view->main_canvas), - NULL, NULL, &old_x2, &old_y2); - new_x2 = week_view->main_canvas->allocation.width - 1; - new_y2 = week_view->main_canvas->allocation.height - 1; - if (old_x2 != new_x2 || old_y2 != new_y2) - gnome_canvas_set_scroll_region (GNOME_CANVAS (week_view->main_canvas), - 0, 0, new_x2, new_y2); - - /* Flag that we need to reshape the events. */ - if (old_x2 != new_x2 || old_y2 != new_y2) { - week_view->events_need_reshape = TRUE; - e_week_view_check_layout (week_view); - } -} - - -static void -e_week_view_recalc_cell_sizes (EWeekView *week_view) -{ - gfloat canvas_width, canvas_height, offset; - gint row, col; - GtkWidget *widget; - GdkFont *font; - gint width, height, time_width; - - if (week_view->multi_week_view) { - week_view->rows = week_view->weeks_shown * 2; - week_view->columns = week_view->compress_weekend ? 6 : 7; - } else { - week_view->rows = 6; - week_view->columns = 2; - } - - /* Calculate the column sizes, using floating point so that pixels - get divided evenly. Note that we use one more element than the - number of columns, to make it easy to get the column widths. - We also add one to the width so that the right border of the last - column is off the edge of the displayed area. */ - canvas_width = week_view->main_canvas->allocation.width + 1; - canvas_width /= week_view->columns; - offset = 0; - for (col = 0; col <= week_view->columns; col++) { - week_view->col_offsets[col] = floor (offset + 0.5); - offset += canvas_width; - } - - /* Calculate the cell widths based on the offsets. */ - for (col = 0; col < week_view->columns; col++) { - week_view->col_widths[col] = week_view->col_offsets[col + 1] - - week_view->col_offsets[col]; - } - - /* Now do the same for the row heights. */ - canvas_height = week_view->main_canvas->allocation.height + 1; - canvas_height /= week_view->rows; - offset = 0; - for (row = 0; row <= week_view->rows; row++) { - week_view->row_offsets[row] = floor (offset + 0.5); - offset += canvas_height; - } - - /* Calculate the cell heights based on the offsets. */ - for (row = 0; row < week_view->rows; row++) { - week_view->row_heights[row] = week_view->row_offsets[row + 1] - - week_view->row_offsets[row]; - } - - - /* If the font hasn't been set yet just return. */ - widget = GTK_WIDGET (week_view); - if (!widget->style || ! widget->style->font) - return; - - font = widget->style->font; - - /* Calculate the number of rows of events in each cell, for the large - cells and the compressed weekend cells. */ - if (week_view->multi_week_view) { - week_view->events_y_offset = E_WEEK_VIEW_DATE_T_PAD - + font->ascent + font->descent - + E_WEEK_VIEW_DATE_B_PAD; - } else { - week_view->events_y_offset = E_WEEK_VIEW_DATE_T_PAD - + font->ascent + font->descent - + E_WEEK_VIEW_DATE_LINE_T_PAD + 1 - + E_WEEK_VIEW_DATE_LINE_B_PAD; - } - - height = week_view->row_heights[0]; - week_view->rows_per_cell = (height * 2 - week_view->events_y_offset) - / (week_view->row_height + E_WEEK_VIEW_EVENT_Y_SPACING); - week_view->rows_per_cell = MIN (week_view->rows_per_cell, - E_WEEK_VIEW_MAX_ROWS_PER_CELL); - - week_view->rows_per_compressed_cell = - (height - week_view->events_y_offset) - / (week_view->row_height + E_WEEK_VIEW_EVENT_Y_SPACING); - week_view->rows_per_compressed_cell = MIN (week_view->rows_per_compressed_cell, - E_WEEK_VIEW_MAX_ROWS_PER_CELL); - - /* Determine which time format to use, based on the width of the cells. - We only allow the time to take up about half of the width. */ - width = week_view->col_widths[0]; - - time_width = e_week_view_get_time_string_width (week_view); - - week_view->time_format = E_WEEK_VIEW_TIME_NONE; - if (week_view->use_small_font && week_view->small_font) { - if (week_view->show_event_end_times - && width / 2 > time_width * 2 + E_WEEK_VIEW_EVENT_TIME_SPACING) - week_view->time_format = E_WEEK_VIEW_TIME_BOTH_SMALL_MIN; - else if (width / 2 > time_width) - week_view->time_format = E_WEEK_VIEW_TIME_START_SMALL_MIN; - } else { - if (week_view->show_event_end_times - && width / 2 > time_width * 2 + E_WEEK_VIEW_EVENT_TIME_SPACING) - week_view->time_format = E_WEEK_VIEW_TIME_BOTH; - else if (width / 2 > time_width) - week_view->time_format = E_WEEK_VIEW_TIME_START; - } -} - - -static gint -e_week_view_focus_in (GtkWidget *widget, GdkEventFocus *event) -{ - EWeekView *week_view; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (E_IS_WEEK_VIEW (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - week_view = E_WEEK_VIEW (widget); - - GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS); - - gtk_widget_queue_draw (week_view->main_canvas); - - return FALSE; -} - - -static gint -e_week_view_focus_out (GtkWidget *widget, GdkEventFocus *event) -{ - EWeekView *week_view; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (E_IS_WEEK_VIEW (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - week_view = E_WEEK_VIEW (widget); - - GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS); - - gtk_widget_queue_draw (week_view->main_canvas); - - return FALSE; -} - - -/* This draws a shadow around the top display and main display. */ -static gint -e_week_view_expose_event (GtkWidget *widget, - GdkEventExpose *event) -{ - EWeekView *week_view; - - week_view = E_WEEK_VIEW (widget); - - e_week_view_draw_shadow (week_view); - - if (GTK_WIDGET_CLASS (parent_class)->expose_event) - (*GTK_WIDGET_CLASS (parent_class)->expose_event)(widget, event); - - return FALSE; -} - - -static void -e_week_view_draw (GtkWidget *widget, - GdkRectangle *area) -{ - EWeekView *week_view; - - week_view = E_WEEK_VIEW (widget); - - e_week_view_draw_shadow (week_view); - - if (GTK_WIDGET_CLASS (parent_class)->draw) - (*GTK_WIDGET_CLASS (parent_class)->draw)(widget, area); -} - - -static void -e_week_view_draw_shadow (EWeekView *week_view) -{ - gint x1, y1, x2, y2; - GtkStyle *style; - GdkGC *light_gc, *dark_gc; - GdkWindow *window; - - /* Draw the shadow around the graphical displays. */ - x1 = week_view->main_canvas->allocation.x - 1; - y1 = week_view->main_canvas->allocation.y - 1; - x2 = x1 + week_view->main_canvas->allocation.width + 2; - y2 = y1 + week_view->main_canvas->allocation.height + 2; - - style = GTK_WIDGET (week_view)->style; - dark_gc = style->dark_gc[GTK_STATE_NORMAL]; - light_gc = style->light_gc[GTK_STATE_NORMAL]; - - window = GTK_WIDGET (week_view)->window; - gdk_draw_line (window, dark_gc, x1, y1, x1, y2); - gdk_draw_line (window, dark_gc, x1, y1, x2, y1); - gdk_draw_line (window, light_gc, x2, y1, x2, y2); - gdk_draw_line (window, light_gc, x1, y2, x2, y2); -} - - -void -e_week_view_set_calendar (EWeekView *week_view, - GnomeCalendar *calendar) -{ - g_return_if_fail (E_IS_WEEK_VIEW (week_view)); - - week_view->calendar = calendar; -} - - -/* Callback used when the calendar client finishes opening */ -static void -cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data) -{ - EWeekView *week_view; - - week_view = E_WEEK_VIEW (data); - - if (status != CAL_CLIENT_OPEN_SUCCESS) - return; - - e_week_view_queue_reload_events (week_view); -} - -/* Callback used when the calendar client tells us that an object changed */ -static void -obj_updated_cb (CalClient *client, const char *uid, gpointer data) -{ - EWeekView *week_view; - EWeekViewEvent *event; - gint event_num, num_days; - CalComponent *comp; - CalClientGetStatus status; - - week_view = E_WEEK_VIEW (data); - - /* Sanity check. */ - g_return_if_fail (client == week_view->client); - - /* If we don't have a valid date set yet, just return. */ - if (!g_date_valid (&week_view->first_day_shown)) - return; - - /* Get the event from the server. */ - status = cal_client_get_object (week_view->client, uid, &comp); - - switch (status) { - case CAL_CLIENT_GET_SUCCESS: - /* Everything is fine */ - break; - - case CAL_CLIENT_GET_SYNTAX_ERROR: - g_message ("obj_updated_cb(): Syntax error when getting object `%s'", uid); - return; - - case CAL_CLIENT_GET_NOT_FOUND: - /* The object is no longer in the server, so do nothing */ - return; - } - - /* We only care about events. */ - if (cal_component_get_vtype (comp) != CAL_COMPONENT_EVENT) { - gtk_object_unref (GTK_OBJECT (comp)); - return; - } - - /* If the event already exists and the dates didn't change, we can - update the event fairly easily without changing the events arrays - or computing a new layout. */ - if (e_week_view_find_event_from_uid (week_view, uid, &event_num)) { - event = &g_array_index (week_view->events, EWeekViewEvent, - event_num); - - if (!cal_component_has_recurrences (comp) - && !cal_component_has_recurrences (event->comp) - && cal_component_event_dates_match (comp, event->comp)) { -#if 0 - g_print ("updated object's dates unchanged\n"); -#endif - e_week_view_foreach_event_with_uid (week_view, uid, e_week_view_update_event_cb, comp); - gtk_object_unref (GTK_OBJECT (comp)); - gtk_widget_queue_draw (week_view->main_canvas); - return; - } - - /* The dates have changed, so we need to remove the - old occurrrences before adding the new ones. */ -#if 0 - g_print ("dates changed - removing occurrences\n"); -#endif - e_week_view_foreach_event_with_uid (week_view, uid, - e_week_view_remove_event_cb, - NULL); - } - - /* Add the occurrences of the event. */ - num_days = week_view->multi_week_view ? week_view->weeks_shown * 7 : 7; - - cal_recur_generate_instances (comp, - week_view->day_starts[0], - week_view->day_starts[num_days], - e_week_view_add_event, - week_view); - - gtk_object_unref (GTK_OBJECT (comp)); - - e_week_view_check_layout (week_view); - - gtk_widget_queue_draw (week_view->main_canvas); -} - -/* Callback used when the calendar client tells us that an object was removed */ -static void -obj_removed_cb (CalClient *client, const char *uid, gpointer data) -{ - EWeekView *week_view; - - week_view = E_WEEK_VIEW (data); - - e_week_view_foreach_event_with_uid (week_view, uid, - e_week_view_remove_event_cb, NULL); - - e_week_view_check_layout (week_view); - gtk_widget_queue_draw (week_view->main_canvas); -} - - -/** - * e_week_view_set_cal_client: - * @week_view: A week view. - * @client: A calendar client interface object. - * - * Sets the calendar client interface object that a week view will monitor. - **/ -void -e_week_view_set_cal_client (EWeekView *week_view, - CalClient *client) -{ - g_return_if_fail (week_view != NULL); - g_return_if_fail (E_IS_WEEK_VIEW (week_view)); - - if (client == week_view->client) - return; - - if (client) - g_return_if_fail (IS_CAL_CLIENT (client)); - - if (client) - gtk_object_ref (GTK_OBJECT (client)); - - if (week_view->client) { - gtk_signal_disconnect_by_data (GTK_OBJECT (week_view->client), week_view); - gtk_object_unref (GTK_OBJECT (week_view->client)); - } - - week_view->client = client; - - if (week_view->client) { - if (cal_client_get_load_state (week_view->client) != CAL_CLIENT_LOAD_LOADED) - gtk_signal_connect (GTK_OBJECT (week_view->client), "cal_opened", - GTK_SIGNAL_FUNC (cal_opened_cb), week_view); - - gtk_signal_connect (GTK_OBJECT (week_view->client), "obj_updated", - GTK_SIGNAL_FUNC (obj_updated_cb), week_view); - gtk_signal_connect (GTK_OBJECT (week_view->client), "obj_removed", - GTK_SIGNAL_FUNC (obj_removed_cb), week_view); - } - - e_week_view_queue_reload_events (week_view); -} - - -/* 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. */ -void -e_week_view_set_selected_time_range (EWeekView *week_view, - time_t start_time, - time_t end_time) -{ - GDate date, base_date, end_date; - gint day_offset, weekday, week_start_offset, num_days; - gboolean update_adjustment_value = FALSE; - - g_return_if_fail (E_IS_WEEK_VIEW (week_view)); - - g_date_clear (&date, 1); - g_date_set_time (&date, start_time); - - if (week_view->multi_week_view) { - /* Find the number of days since the start of the month. */ - day_offset = g_date_day (&date) - 1; - - /* Find the 1st week which starts at or before the start of - the month. */ - base_date = date; - g_date_set_day (&base_date, 1); - - /* Calculate the weekday of the 1st of the month, 0 = Mon. */ - weekday = g_date_weekday (&base_date) - 1; - - /* Convert it to an offset from the start of the display. */ - week_start_offset = (weekday + 7 - week_view->display_start_day) % 7; - - /* Add it to the day offset so we go back to the 1st week at - or before the start of the month. */ - day_offset += week_start_offset; - } else { - /* Calculate the weekday of the given date, 0 = Mon. */ - weekday = g_date_weekday (&date) - 1; - - /* Convert it to an offset from the start of the display. */ - week_start_offset = (weekday + 7 - week_view->display_start_day) % 7; - - /* Set the day_offset to the result, so we move back to the - start of the week. */ - day_offset = week_start_offset; - } - - /* Calculate the base date, i.e. the first day shown when the - scrollbar adjustment value is 0. */ - base_date = date; - g_date_subtract_days (&base_date, day_offset); - - /* See if we need to update the base date. */ - if (!g_date_valid (&week_view->base_date) - || g_date_compare (&week_view->base_date, &base_date)) { - week_view->base_date = base_date; - update_adjustment_value = TRUE; - } - - /* See if we need to update the first day shown. */ - if (!g_date_valid (&week_view->first_day_shown) - || g_date_compare (&week_view->first_day_shown, &base_date)) { - week_view->first_day_shown = base_date; - start_time = time_add_day (start_time, -day_offset); - start_time = time_day_begin (start_time); - e_week_view_recalc_day_starts (week_view, start_time); - e_week_view_queue_reload_events (week_view); - } - - /* Set the selection to the given days. */ - week_view->selection_start_day = g_date_julian (&date) - - g_date_julian (&base_date); - if (end_time == start_time - || end_time <= time_add_day (start_time, 1)) - week_view->selection_end_day = week_view->selection_start_day; - else { - g_date_clear (&end_date, 1); - g_date_set_time (&end_date, end_time - 60); - week_view->selection_end_day = g_date_julian (&end_date) - - g_date_julian (&base_date); - } - - /* Make sure the selection is valid. */ - num_days = week_view->multi_week_view ? week_view->weeks_shown * 7 : 7; - num_days--; - week_view->selection_start_day = CLAMP (week_view->selection_start_day, - 0, num_days); - week_view->selection_end_day = CLAMP (week_view->selection_end_day, - week_view->selection_start_day, - num_days); - - /* Reset the adjustment value to 0 if the base address has changed. - Note that we do this after updating first_day_shown so that our - signal handler will not try to reload the events. */ - if (update_adjustment_value) - gtk_adjustment_set_value (GTK_RANGE (week_view->vscrollbar)->adjustment, 0); - - - gtk_widget_queue_draw (week_view->main_canvas); -} - - -/* Returns the selected time range. */ -void -e_week_view_get_selected_time_range (EWeekView *week_view, - time_t *start_time, - time_t *end_time) -{ - gint start_day, end_day; - - start_day = week_view->selection_start_day; - end_day = week_view->selection_end_day; - - if (start_day == -1) { - start_day = 0; - end_day = 0; - } - - if (start_time) - *start_time = week_view->day_starts[start_day]; - - if (end_time) - *end_time = week_view->day_starts[end_day + 1]; -} - - -/* Note that the returned date may be invalid if no date has been set yet. */ -void -e_week_view_get_first_day_shown (EWeekView *week_view, - GDate *date) -{ - *date = week_view->first_day_shown; -} - - -/* This sets the first day shown in the view. It will be rounded down to the - nearest week. */ -void -e_week_view_set_first_day_shown (EWeekView *week_view, - GDate *date) -{ - GDate base_date; - gint weekday, day_offset, num_days; - gboolean update_adjustment_value = FALSE; - guint32 old_selection_start_julian = 0, old_selection_end_julian = 0; - struct tm start_tm; - time_t start_time; - - g_return_if_fail (E_IS_WEEK_VIEW (week_view)); - - /* Calculate the old selection range. */ - if (week_view->selection_start_day != -1) { - old_selection_start_julian = - g_date_julian (&week_view->base_date) - + week_view->selection_start_day; - old_selection_end_julian = - g_date_julian (&week_view->base_date) - + week_view->selection_end_day; - } - - /* Calculate the weekday of the given date, 0 = Mon. */ - weekday = g_date_weekday (date) - 1; - - /* Convert it to an offset from the start of the display. */ - day_offset = (weekday + 7 - week_view->display_start_day) % 7; - - /* Calculate the base date, i.e. the first day shown when the - scrollbar adjustment value is 0. */ - base_date = *date; - g_date_subtract_days (&base_date, day_offset); - - /* See if we need to update the base date. */ - if (!g_date_valid (&week_view->base_date) - || g_date_compare (&week_view->base_date, &base_date)) { - week_view->base_date = base_date; - update_adjustment_value = TRUE; - } - - /* See if we need to update the first day shown. */ - if (!g_date_valid (&week_view->first_day_shown) - || g_date_compare (&week_view->first_day_shown, &base_date)) { - week_view->first_day_shown = base_date; - g_date_to_struct_tm (&base_date, &start_tm); - start_time = mktime (&start_tm); - e_week_view_recalc_day_starts (week_view, start_time); - e_week_view_queue_reload_events (week_view); - } - - /* Try to keep the previous selection, but if it is no longer shown - just select the first day. */ - if (week_view->selection_start_day != -1) { - week_view->selection_start_day = old_selection_start_julian - - g_date_julian (&base_date); - week_view->selection_end_day = old_selection_end_julian - - g_date_julian (&base_date); - - /* Make sure the selection is valid. */ - num_days = week_view->multi_week_view - ? week_view->weeks_shown * 7 : 7; - num_days--; - week_view->selection_start_day = - CLAMP (week_view->selection_start_day, 0, num_days); - week_view->selection_end_day = - CLAMP (week_view->selection_end_day, - week_view->selection_start_day, - num_days); - } - - /* Reset the adjustment value to 0 if the base address has changed. - Note that we do this after updating first_day_shown so that our - signal handler will not try to reload the events. */ - if (update_adjustment_value) - gtk_adjustment_set_value (GTK_RANGE (week_view->vscrollbar)->adjustment, 0); - - - gtk_widget_queue_draw (week_view->main_canvas); -} - - -/* Recalculates the time_t corresponding to the start of each day. */ -static void -e_week_view_recalc_day_starts (EWeekView *week_view, - time_t lower) -{ - gint num_days, day; - time_t tmp_time; - - num_days = week_view->multi_week_view ? week_view->weeks_shown * 7 : 7; - - tmp_time = lower; - week_view->day_starts[0] = tmp_time; - for (day = 1; day <= num_days; day++) { - tmp_time = time_add_day (tmp_time, 1); - week_view->day_starts[day] = tmp_time; - } -} - - -gboolean -e_week_view_get_multi_week_view (EWeekView *week_view) -{ - g_return_val_if_fail (E_IS_WEEK_VIEW (week_view), FALSE); - - return week_view->multi_week_view; -} - - -void -e_week_view_set_multi_week_view (EWeekView *week_view, - gboolean multi_week_view) -{ - GtkAdjustment *adjustment; - gint page_increment, page_size; - - g_return_if_fail (E_IS_WEEK_VIEW (week_view)); - - if (week_view->multi_week_view == multi_week_view) - return; - - week_view->multi_week_view = multi_week_view; - - if (multi_week_view) { - gtk_widget_show (week_view->titles_canvas); - page_increment = 4; - page_size = 5; - } else { - gtk_widget_hide (week_view->titles_canvas); - page_increment = page_size = 1; - } - - adjustment = GTK_RANGE (week_view->vscrollbar)->adjustment; - adjustment->page_increment = page_increment; - adjustment->page_size = page_size; - gtk_adjustment_changed (adjustment); - - e_week_view_recalc_cell_sizes (week_view); - - if (g_date_valid (&week_view->first_day_shown)) - e_week_view_set_first_day_shown (week_view, - &week_view->first_day_shown); -} - - -gint -e_week_view_get_weeks_shown (EWeekView *week_view) -{ - g_return_val_if_fail (E_IS_WEEK_VIEW (week_view), 1); - - return week_view->weeks_shown; -} - - -void -e_week_view_set_weeks_shown (EWeekView *week_view, - gint weeks_shown) -{ - GtkAdjustment *adjustment; - gint page_increment, page_size; - - g_return_if_fail (E_IS_WEEK_VIEW (week_view)); - - weeks_shown = MIN (weeks_shown, E_WEEK_VIEW_MAX_WEEKS); - - if (week_view->weeks_shown == weeks_shown) - return; - - week_view->weeks_shown = weeks_shown; - - if (week_view->multi_week_view) { - page_increment = 4; - page_size = 5; - - adjustment = GTK_RANGE (week_view->vscrollbar)->adjustment; - adjustment->page_increment = page_increment; - adjustment->page_size = page_size; - gtk_adjustment_changed (adjustment); - - e_week_view_recalc_cell_sizes (week_view); - - if (g_date_valid (&week_view->first_day_shown)) - e_week_view_set_first_day_shown (week_view, &week_view->first_day_shown); - - /* Make sure the events are reloaded. */ - e_week_view_queue_reload_events (week_view); - } -} - - -gboolean -e_week_view_get_compress_weekend (EWeekView *week_view) -{ - g_return_val_if_fail (E_IS_WEEK_VIEW (week_view), FALSE); - - return week_view->compress_weekend; -} - - -void -e_week_view_set_compress_weekend (EWeekView *week_view, - gboolean compress) -{ - gboolean need_reload = FALSE; - - g_return_if_fail (E_IS_WEEK_VIEW (week_view)); - - if (week_view->compress_weekend == compress) - return; - - week_view->compress_weekend = compress; - - /* The option only affects the month view. */ - if (!week_view->multi_week_view) - return; - - e_week_view_recalc_cell_sizes (week_view); - - need_reload = e_week_view_recalc_display_start_day (week_view); - - /* If the display_start_day has changed we need to recalculate the - date range shown and reload all events, otherwise we only need to - do a reshape. */ - if (need_reload) { - /* Recalculate the days shown and reload if necessary. */ - if (g_date_valid (&week_view->first_day_shown)) - e_week_view_set_first_day_shown (week_view, &week_view->first_day_shown); - } else { - week_view->events_need_reshape = TRUE; - e_week_view_check_layout (week_view); - } -} - - -/* Whether we display event end times. */ -gboolean -e_week_view_get_show_event_end_times (EWeekView *week_view) -{ - g_return_val_if_fail (E_IS_WEEK_VIEW (week_view), TRUE); - - return week_view->show_event_end_times; -} - - -void -e_week_view_set_show_event_end_times (EWeekView *week_view, - gboolean show) -{ - g_return_if_fail (E_IS_WEEK_VIEW (week_view)); - - if (week_view->show_event_end_times != show) { - week_view->show_event_end_times = show; - e_week_view_recalc_cell_sizes (week_view); - week_view->events_need_reshape = TRUE; - e_week_view_check_layout (week_view); - } -} - - -/* The first day of the week, 0 (Monday) to 6 (Sunday). */ -gint -e_week_view_get_week_start_day (EWeekView *week_view) -{ - g_return_val_if_fail (E_IS_WEEK_VIEW (week_view), 0); - - return week_view->week_start_day; -} - - -void -e_week_view_set_week_start_day (EWeekView *week_view, - gint week_start_day) -{ - g_return_if_fail (E_IS_WEEK_VIEW (week_view)); - g_return_if_fail (week_start_day >= 0); - g_return_if_fail (week_start_day < 7); - - if (week_view->week_start_day == week_start_day) - return; - - week_view->week_start_day = week_start_day; - - e_week_view_recalc_display_start_day (week_view); - - /* Recalculate the days shown and reload if necessary. */ - if (g_date_valid (&week_view->first_day_shown)) - e_week_view_set_first_day_shown (week_view, - &week_view->first_day_shown); -} - - -/* Whether we use 12-hour or 24-hour format. */ -gboolean -e_week_view_get_24_hour_format (EWeekView *week_view) -{ - g_return_val_if_fail (E_IS_WEEK_VIEW (week_view), FALSE); - - return week_view->use_24_hour_format; -} - - -void -e_week_view_set_24_hour_format (EWeekView *week_view, - gboolean use_24_hour) -{ - g_return_if_fail (E_IS_WEEK_VIEW (week_view)); - - if (week_view->use_24_hour_format == use_24_hour) - return; - - week_view->use_24_hour_format = use_24_hour; - - /* We need to re-layout the events since the time format affects the - sizes. */ - e_week_view_recalc_cell_sizes (week_view); - week_view->events_need_reshape = TRUE; - e_week_view_check_layout (week_view); - gtk_widget_queue_draw (week_view->main_canvas); -} - - -static gboolean -e_week_view_recalc_display_start_day (EWeekView *week_view) -{ - gint display_start_day; - - /* The display start day defaults to week_start_day, but we have - to use Saturday if the weekend is compressed and week_start_day - is Sunday. */ - display_start_day = week_view->week_start_day; - - if (display_start_day == 6 - && (!week_view->multi_week_view || week_view->compress_weekend)) - display_start_day = 5; - - if (week_view->display_start_day != display_start_day) { - week_view->display_start_day = display_start_day; - return TRUE; - } - - return FALSE; -} - - -static gboolean -e_week_view_update_event_cb (EWeekView *week_view, - gint event_num, - gpointer data) -{ - EWeekViewEvent *event; - EWeekViewEventSpan *span; - gint span_num; - gchar *text; - CalComponent *comp; - - comp = data; - - event = &g_array_index (week_view->events, EWeekViewEvent, event_num); - - gtk_object_unref (GTK_OBJECT (event->comp)); - event->comp = comp; - gtk_object_ref (GTK_OBJECT (comp)); - - for (span_num = 0; span_num < event->num_spans; span_num++) { - span = &g_array_index (week_view->spans, EWeekViewEventSpan, - event->spans_index + span_num); - - if (span->text_item) { - CalComponentText t; - - cal_component_get_summary (event->comp, &t); - text = (char*) t.value; - gnome_canvas_item_set (span->text_item, - "text", text ? text : "", - NULL); - - e_week_view_reshape_event_span (week_view, event_num, - span_num); - } - } - - return TRUE; -} - - -/* This calls a given function for each event instance that matches the given - uid. Note that it is safe for the callback to remove the event (since we - step backwards through the arrays). */ -static void -e_week_view_foreach_event_with_uid (EWeekView *week_view, - const gchar *uid, - EWeekViewForeachEventCallback callback, - gpointer data) -{ - EWeekViewEvent *event; - gint event_num; - - for (event_num = week_view->events->len - 1; - event_num >= 0; - event_num--) { - const char *u; - - event = &g_array_index (week_view->events, EWeekViewEvent, - event_num); - - cal_component_get_uid (event->comp, &u); - if (u && !strcmp (uid, u)) { - if (!(*callback) (week_view, event_num, data)) - return; - } - } -} - - -static gboolean -e_week_view_remove_event_cb (EWeekView *week_view, - gint event_num, - gpointer data) -{ - EWeekViewEvent *event; - EWeekViewEventSpan *span; - gint span_num; - - event = &g_array_index (week_view->events, EWeekViewEvent, event_num); - - /* If we were editing this event, set editing_event_num to -1 so - on_editing_stopped doesn't try to update the event. */ - if (week_view->editing_event_num == event_num) - week_view->editing_event_num = -1; - - /* We leave the span elements in the array, but set the canvas item - pointers to NULL. */ - for (span_num = 0; span_num < event->num_spans; span_num++) { - span = &g_array_index (week_view->spans, EWeekViewEventSpan, - event->spans_index + span_num); - - if (span->text_item) { - gtk_object_destroy (GTK_OBJECT (span->text_item)); - span->text_item = NULL; - } - if (span->background_item) { - gtk_object_destroy (GTK_OBJECT (span->background_item)); - span->background_item = NULL; - } - } - - gtk_object_unref (GTK_OBJECT (event->comp)); - - g_array_remove_index (week_view->events, event_num); - week_view->events_need_layout = TRUE; - - return TRUE; -} - - -void -e_week_view_get_day_position (EWeekView *week_view, - gint day, - gint *day_x, - gint *day_y, - gint *day_w, - gint *day_h) -{ - gint week, day_of_week, row, col, weekend_col, box, weekend_box; - - *day_x = *day_y = *day_w = *day_h = 0; - g_return_if_fail (day >= 0); - - if (week_view->multi_week_view) { - g_return_if_fail (day < week_view->weeks_shown * 7); - - week = day / 7; - col = day % 7; - day_of_week = (week_view->display_start_day + day) % 7; - if (week_view->compress_weekend && day_of_week >= 5) { - /* In the compressed view Saturday is above Sunday and - both have just one row as opposed to 2 for all the - other days. */ - if (day_of_week == 5) { - *day_y = week_view->row_offsets[week * 2]; - *day_h = week_view->row_heights[week * 2]; - } else { - *day_y = week_view->row_offsets[week * 2 + 1]; - *day_h = week_view->row_heights[week * 2 + 1]; - col--; - } - /* Both Saturday and Sunday are in the same column. */ - *day_x = week_view->col_offsets[col]; - *day_w = week_view->col_widths[col]; - } else { - /* If the weekend is compressed and the day is after - the weekend we have to move back a column. */ - if (week_view->compress_weekend) { - /* Calculate where the weekend column is. - Note that 5 is Saturday. */ - weekend_col = (5 + 7 - week_view->display_start_day) % 7; - if (col > weekend_col) - col--; - } - - *day_y = week_view->row_offsets[week * 2]; - *day_h = week_view->row_heights[week * 2] - + week_view->row_heights[week * 2 + 1]; - *day_x = week_view->col_offsets[col]; - *day_w = week_view->col_widths[col]; - } - } else { - g_return_if_fail (day < 7); - - /* Calculate which box to place the day in, from 0-5. - Note that in the week view the weekends are always - compressed and share a box. */ - box = day; - day_of_week = (week_view->display_start_day + day) % 7; - weekend_box = (5 + 7 - week_view->display_start_day) % 7; - if (box > weekend_box) - box--; - - if (box < 3) { - *day_x = week_view->col_offsets[0]; - *day_w = week_view->col_widths[0]; - } else { - *day_x = week_view->col_offsets[1]; - *day_w = week_view->col_widths[1]; - } - - row = (box % 3) * 2; - if (day_of_week < 5) { - *day_y = week_view->row_offsets[row]; - *day_h = week_view->row_heights[row] - + week_view->row_heights[row + 1]; - } else if (day_of_week == 5) { - /* Saturday. */ - *day_y = week_view->row_offsets[row]; - *day_h = week_view->row_heights[row]; - - } else { - /* Sunday. */ - *day_y = week_view->row_offsets[row + 1]; - *day_h = week_view->row_heights[row + 1]; - } - } -} - - -/* Returns the bounding box for a span of an event. Usually this can easily - be determined by the start & end days and row of the span, which are set in - e_week_view_layout_event(). Though we need a special case for the weekends - when they are compressed, since the span may not fit. - The bounding box includes the entire width of the days in the view (but - not the vertical line down the right of the last day), though the displayed - event doesn't normally extend to the edges of the day. - It returns FALSE if the span isn't visible. */ -gboolean -e_week_view_get_span_position (EWeekView *week_view, - gint event_num, - gint span_num, - gint *span_x, - gint *span_y, - gint *span_w) -{ - EWeekViewEvent *event; - EWeekViewEventSpan *span; - gint end_day_of_week, num_days; - gint start_x, start_y, start_w, start_h; - gint end_x, end_y, end_w, end_h; - - g_return_val_if_fail (E_IS_WEEK_VIEW (week_view), FALSE); - g_return_val_if_fail (event_num < week_view->events->len, FALSE); - - event = &g_array_index (week_view->events, EWeekViewEvent, event_num); - - g_return_val_if_fail (span_num < event->num_spans, FALSE); - - span = &g_array_index (week_view->spans, EWeekViewEventSpan, - event->spans_index + span_num); - - if (span->row >= week_view->rows_per_cell) - return FALSE; - - end_day_of_week = (week_view->display_start_day + span->start_day + span->num_days - 1) % 7; - num_days = span->num_days; - /* Check if the row will not be visible in compressed cells. */ - if (span->row >= week_view->rows_per_compressed_cell) { - if (week_view->multi_week_view) { - if (week_view->compress_weekend) { - /* If it ends on a Saturday and is 1 day long - we skip it, else we shorten it. If it ends - on a Sunday it must be 1 day long and we - skip it. */ - if (end_day_of_week == 5) { /* Sat */ - if (num_days == 1) { - return FALSE; - } else { - num_days--; - } - } else if (end_day_of_week == 6) { /* Sun */ - return FALSE; - } - } - } else { - /* All spans are 1 day long in the week view, so we - just skip it. */ - if (end_day_of_week > 4) - return FALSE; - } - } - - e_week_view_get_day_position (week_view, span->start_day, - &start_x, &start_y, &start_w, &start_h); - *span_y = start_y + week_view->events_y_offset - + span->row * (week_view->row_height - + E_WEEK_VIEW_EVENT_Y_SPACING); - if (num_days == 1) { - *span_x = start_x; - *span_w = start_w - 1; - } else { - e_week_view_get_day_position (week_view, - span->start_day + num_days - 1, - &end_x, &end_y, &end_w, &end_h); - *span_x = start_x; - *span_w = end_x + end_w - start_x - 1; - } - - return TRUE; -} - - - -static gboolean -e_week_view_on_button_press (GtkWidget *widget, - GdkEventButton *event, - EWeekView *week_view) -{ - gint x, y, day; - -#if 0 - g_print ("In e_week_view_on_button_press\n"); -#endif - - /* Handle scroll wheel events */ - if (event->button == 4 || event->button == 5) { - GtkAdjustment *adj = GTK_RANGE (week_view->vscrollbar)->adjustment; - gfloat new_value; - - new_value = adj->value + ((event->button == 4) ? - -adj->page_increment: - adj->page_increment); - new_value = CLAMP (new_value, adj->lower, adj->upper - adj->page_size); - gtk_adjustment_set_value (adj, new_value); - - return TRUE; - } - - /* If an event is pressed just return. */ - if (week_view->pressed_event_num != -1) - return FALSE; - - /* Convert the mouse position to a week & day. */ - x = event->x; - y = event->y; - day = e_week_view_convert_position_to_day (week_view, x, y); - if (day == -1) - return FALSE; - - /* Start the selection drag. */ - if (event->button == 1) { - if (!GTK_WIDGET_HAS_FOCUS (week_view)) - gtk_widget_grab_focus (GTK_WIDGET (week_view)); - - if (gdk_pointer_grab (GTK_LAYOUT (widget)->bin_window, FALSE, - GDK_POINTER_MOTION_MASK - | GDK_BUTTON_RELEASE_MASK, - FALSE, NULL, event->time) == 0) { - week_view->selection_start_day = day; - week_view->selection_end_day = day; - week_view->selection_drag_pos = E_WEEK_VIEW_DRAG_END; - - /* FIXME: Optimise? */ - gtk_widget_queue_draw (week_view->main_canvas); - } - } else if (event->button == 3) { - if (!GTK_WIDGET_HAS_FOCUS (week_view)) - gtk_widget_grab_focus (GTK_WIDGET (week_view)); - e_week_view_show_popup_menu (week_view, event, -1); - } - - return FALSE; -} - - -static gboolean -e_week_view_on_button_release (GtkWidget *widget, - GdkEventButton *event, - EWeekView *week_view) -{ - time_t start, end; - -#if 0 - g_print ("In e_week_view_on_button_release\n"); -#endif - - if (week_view->selection_drag_pos != E_WEEK_VIEW_DRAG_NONE) { - week_view->selection_drag_pos = E_WEEK_VIEW_DRAG_NONE; - gdk_pointer_ungrab (event->time); - start = week_view->day_starts[week_view->selection_start_day]; - end = week_view->day_starts[week_view->selection_end_day + 1]; - - if (week_view->calendar) - gnome_calendar_set_selected_time_range (week_view->calendar, start, end); - } - - return FALSE; -} - - -static gboolean -e_week_view_on_motion (GtkWidget *widget, - GdkEventMotion *mevent, - EWeekView *week_view) -{ - gint x, y, day; - -#if 0 - g_print ("In e_week_view_on_motion\n"); -#endif - - /* Convert the mouse position to a week & day. */ - x = mevent->x; - y = mevent->y; - day = e_week_view_convert_position_to_day (week_view, x, y); - if (day == -1) - return FALSE; - - if (week_view->selection_drag_pos != E_WEEK_VIEW_DRAG_NONE) { - e_week_view_update_selection (week_view, day); - return TRUE; - } - - return FALSE; -} - - -/* Converts a position in the canvas window to a day offset from the first - day displayed. Returns -1 if the position is outside the grid. */ -static gint -e_week_view_convert_position_to_day (EWeekView *week_view, - gint x, - gint y) -{ - gint col, row, grid_x = -1, grid_y = -1, week, day; - gint weekend_col, box, weekend_box; - - /* First we convert it to a grid position. */ - for (col = 0; col <= week_view->columns; col++) { - if (x < week_view->col_offsets[col]) { - grid_x = col - 1; - break; - } - } - - for (row = 0; row <= week_view->rows; row++) { - if (y < week_view->row_offsets[row]) { - grid_y = row - 1; - break; - } - } - - /* If the mouse is outside the grid return FALSE. */ - if (grid_x == -1 || grid_y == -1) - return -1; - - /* Now convert the grid position to a week and day. */ - if (week_view->multi_week_view) { - week = grid_y / 2; - day = grid_x; - - if (week_view->compress_weekend) { - weekend_col = (5 + 7 - week_view->display_start_day) % 7; - if (grid_x > weekend_col - || (grid_x == weekend_col && grid_y % 2 == 1)) - day++; - } - } else { - week = 0; - - box = grid_x * 3 + grid_y / 2; - weekend_box = (5 + 7 - week_view->display_start_day) % 7; - day = box; - if (box > weekend_box - ||( box == weekend_box && grid_y % 2 == 1)) - day++; - } - - return week * 7 + day; -} - - -static void -e_week_view_update_selection (EWeekView *week_view, - gint day) -{ - gint tmp_day; - gboolean need_redraw = FALSE; - -#if 0 - g_print ("Updating selection %i,%i\n", week, day); -#endif - - if (week_view->selection_drag_pos == E_WEEK_VIEW_DRAG_START) { - if (day != week_view->selection_start_day) { - need_redraw = TRUE; - week_view->selection_start_day = day; - } - } else { - if (day != week_view->selection_end_day) { - need_redraw = TRUE; - week_view->selection_end_day = day; - } - } - - /* Switch the drag position if necessary. */ - if (week_view->selection_start_day > week_view->selection_end_day) { - tmp_day = week_view->selection_start_day; - week_view->selection_start_day = week_view->selection_end_day; - week_view->selection_end_day = tmp_day; - if (week_view->selection_drag_pos == E_WEEK_VIEW_DRAG_START) - week_view->selection_drag_pos = E_WEEK_VIEW_DRAG_END; - else - week_view->selection_drag_pos = E_WEEK_VIEW_DRAG_START; - } - - /* FIXME: Optimise? */ - if (need_redraw) { - gtk_widget_queue_draw (week_view->main_canvas); - } -} - - -/* This frees any events currently loaded, and queues a reload. */ -static void -e_week_view_queue_reload_events (EWeekView *week_view) -{ - e_week_view_free_events (week_view); - - if (week_view->reload_events_idle_id == 0) { - /* We'll use a low priority here, so the user can scroll - the view quickly. */ - week_view->reload_events_idle_id = g_idle_add_full - (G_PRIORITY_LOW, - e_week_view_reload_events_idle_cb, week_view, NULL); - } -} - - -static gboolean -e_week_view_reload_events_idle_cb (gpointer data) -{ - EWeekView *week_view; - - g_return_val_if_fail (E_IS_WEEK_VIEW (data), FALSE); - - GDK_THREADS_ENTER (); - - week_view = E_WEEK_VIEW (data); - - week_view->reload_events_idle_id = 0; - - e_week_view_reload_events (week_view); - - GDK_THREADS_LEAVE (); - return FALSE; -} - - -static void -e_week_view_reload_events (EWeekView *week_view) -{ - gint num_days; - - e_week_view_free_events (week_view); - - if (!(week_view->client - && cal_client_get_load_state (week_view->client) == CAL_CLIENT_LOAD_LOADED)) - return; - - /* Only load events if the date range has been set. */ - if (g_date_valid (&week_view->first_day_shown)) { - num_days = week_view->multi_week_view - ? week_view->weeks_shown * 7 : 7; - -#if 0 - g_print ("EWeekView (%s) generating instances\n", - week_view->multi_week_view ? "Month View" : "Week View"); -#endif - cal_client_generate_instances (week_view->client, - CALOBJ_TYPE_EVENT, - week_view->day_starts[0], - week_view->day_starts[num_days], - e_week_view_add_event, - week_view); - } - - week_view->events_need_reshape = TRUE; - e_week_view_check_layout (week_view); - - gtk_widget_queue_draw (week_view->main_canvas); -} - - -static void -e_week_view_free_events (EWeekView *week_view) -{ - EWeekViewEvent *event; - EWeekViewEventSpan *span; - gint event_num, span_num, num_days, day; - - /* Reset all our indices. */ - week_view->pressed_event_num = -1; - week_view->pressed_span_num = -1; - week_view->editing_event_num = -1; - week_view->editing_span_num = -1; - week_view->popup_event_num = -1; - - for (event_num = 0; event_num < week_view->events->len; event_num++) { - event = &g_array_index (week_view->events, EWeekViewEvent, - event_num); - gtk_object_unref (GTK_OBJECT (event->comp)); - } - - g_array_set_size (week_view->events, 0); - - /* Destroy all the old canvas items. */ - if (week_view->spans) { - for (span_num = 0; span_num < week_view->spans->len; - span_num++) { - span = &g_array_index (week_view->spans, - EWeekViewEventSpan, span_num); - if (span->background_item) - gtk_object_destroy (GTK_OBJECT (span->background_item)); - if (span->text_item) - gtk_object_destroy (GTK_OBJECT (span->text_item)); - } - g_array_free (week_view->spans, TRUE); - week_view->spans = NULL; - } - - /* Clear the number of rows used per day. */ - num_days = week_view->multi_week_view ? week_view->weeks_shown * 7 : 7; - for (day = 0; day <= num_days; day++) { - week_view->rows_per_day[day] = 0; - } -} - - -/* This adds one event to the view, adding it to the appropriate array. */ -static gboolean -e_week_view_add_event (CalComponent *comp, - time_t start, - time_t end, - gpointer data) - -{ - EWeekView *week_view; - EWeekViewEvent event; - gint num_days; - struct tm start_tm, end_tm; - - week_view = E_WEEK_VIEW (data); - - /* Check that the event times are valid. */ - num_days = week_view->multi_week_view ? week_view->weeks_shown * 7 : 7; - -#if 0 - g_print ("View start:%li end:%li Event start:%li end:%li\n", - week_view->day_starts[0], week_view->day_starts[num_days], - start, end); -#endif - - g_return_val_if_fail (start <= end, TRUE); - g_return_val_if_fail (start < week_view->day_starts[num_days], TRUE); - g_return_val_if_fail (end > week_view->day_starts[0], TRUE); - - start_tm = *(localtime (&start)); - end_tm = *(localtime (&end)); - - event.comp = comp; - gtk_object_ref (GTK_OBJECT (event.comp)); - event.start = start; - event.end = end; - event.spans_index = 0; - event.num_spans = 0; - - event.start_minute = start_tm.tm_hour * 60 + start_tm.tm_min; - event.end_minute = end_tm.tm_hour * 60 + end_tm.tm_min; - if (event.end_minute == 0 && start != end) - event.end_minute = 24 * 60; - - g_array_append_val (week_view->events, event); - week_view->events_sorted = FALSE; - week_view->events_need_layout = TRUE; - - return TRUE; -} - - -/* This lays out the events, or reshapes them, as necessary. */ -static void -e_week_view_check_layout (EWeekView *week_view) -{ - /* Don't bother if we aren't visible. */ - if (!GTK_WIDGET_VISIBLE (week_view)) - return; - - /* Make sure the events are sorted (by start and size). */ - e_week_view_ensure_events_sorted (week_view); - - if (week_view->events_need_layout) - e_week_view_layout_events (week_view); - - if (week_view->events_need_layout || week_view->events_need_reshape) - e_week_view_reshape_events (week_view); - - week_view->events_need_layout = FALSE; - week_view->events_need_reshape = FALSE; -} - - -static void -e_week_view_layout_events (EWeekView *week_view) -{ - EWeekViewEvent *event; - EWeekViewEventSpan *span; - gint num_days, day, event_num, span_num; - guint8 *grid; - GArray *spans, *old_spans; - - /* This is a temporary 2-d grid which is used to place events. - Each element is 0 if the position is empty, or 1 if occupied. - We allocate the maximum size possible here, assuming that each - event will need its own row. */ - grid = g_new0 (guint8, E_WEEK_VIEW_MAX_ROWS_PER_CELL * 7 - * E_WEEK_VIEW_MAX_WEEKS); - - /* We create a new array of spans, which will replace the old one. */ - spans = g_array_new (FALSE, FALSE, sizeof (EWeekViewEventSpan)); - - /* Clear the number of rows used per day. */ - num_days = week_view->multi_week_view ? week_view->weeks_shown * 7 : 7; - for (day = 0; day <= num_days; day++) { - week_view->rows_per_day[day] = 0; - } - - /* Iterate over the events, finding which weeks they cover, and putting - them in the first free row available. */ - for (event_num = 0; event_num < week_view->events->len; event_num++) { - event = &g_array_index (week_view->events, EWeekViewEvent, - event_num); - e_week_view_layout_event (week_view, event, grid, spans); - } - - /* Free the grid. */ - g_free (grid); - - /* Replace the spans array. */ - old_spans = week_view->spans; - week_view->spans = spans; - - /* Destroy the old spans array, destroying any unused canvas items. */ - if (old_spans) { - for (span_num = 0; span_num < old_spans->len; span_num++) { - span = &g_array_index (old_spans, EWeekViewEventSpan, - span_num); - if (span->background_item) - gtk_object_destroy (GTK_OBJECT (span->background_item)); - if (span->text_item) - gtk_object_destroy (GTK_OBJECT (span->text_item)); - } - g_array_free (old_spans, TRUE); - } -} - - -static void -e_week_view_layout_event (EWeekView *week_view, - EWeekViewEvent *event, - guint8 *grid, - GArray *spans) -{ - gint start_day, end_day, span_start_day, span_end_day, rows_per_cell; - gint free_row, row, day, span_num, spans_index, num_spans, max_day; - EWeekViewEventSpan span, *old_span; - - start_day = e_week_view_find_day (week_view, event->start, FALSE); - end_day = e_week_view_find_day (week_view, event->end, TRUE); - max_day = week_view->multi_week_view ? week_view->weeks_shown * 7 - 1 - : 7 - 1; - start_day = CLAMP (start_day, 0, max_day); - end_day = CLAMP (end_day, 0, max_day); - -#if 0 - g_print ("In e_week_view_layout_event Start:%i End: %i\n", - start_day, end_day); -#endif - - /* Iterate through each of the spans of the event, where each span - is a sequence of 1 or more days displayed next to each other. */ - span_start_day = start_day; - rows_per_cell = E_WEEK_VIEW_MAX_ROWS_PER_CELL; - span_num = 0; - spans_index = spans->len; - num_spans = 0; - while (span_start_day <= end_day) { - span_end_day = e_week_view_find_span_end (week_view, - span_start_day); - span_end_day = MIN (span_end_day, end_day); -#if 0 - g_print (" Span start:%i end:%i\n", span_start_day, - span_end_day); -#endif - /* Try each row until we find a free one or we fall off the - bottom of the available rows. */ - row = 0; - free_row = -1; - while (free_row == -1 && row < rows_per_cell) { - free_row = row; - for (day = span_start_day; day <= span_end_day; - day++) { - if (grid[day * rows_per_cell + row]) { - free_row = -1; - break; - } - } - row++; - }; - - if (free_row != -1) { - /* Mark the cells as full. */ - for (day = span_start_day; day <= span_end_day; - day++) { - grid[day * rows_per_cell + free_row] = 1; - week_view->rows_per_day[day] = MAX (week_view->rows_per_day[day], free_row + 1); - } -#if 0 - g_print (" Span start:%i end:%i row:%i\n", - span_start_day, span_end_day, free_row); -#endif - /* Add the span to the array, and try to reuse any - canvas items from the old spans. */ - span.start_day = span_start_day; - span.num_days = span_end_day - span_start_day + 1; - span.row = free_row; - span.background_item = NULL; - span.text_item = NULL; - if (event->num_spans > span_num) { - old_span = &g_array_index (week_view->spans, EWeekViewEventSpan, event->spans_index + span_num); - span.background_item = old_span->background_item; - span.text_item = old_span->text_item; - old_span->background_item = NULL; - old_span->text_item = NULL; - } - - g_array_append_val (spans, span); - num_spans++; - } - - span_start_day = span_end_day + 1; - span_num++; - } - - /* Set the event's spans. */ - event->spans_index = spans_index; - event->num_spans = num_spans; -} - - -static void -e_week_view_ensure_events_sorted (EWeekView *week_view) -{ - if (!week_view->events_sorted) { - qsort (week_view->events->data, - week_view->events->len, - sizeof (EWeekViewEvent), - e_week_view_event_sort_func); - week_view->events_sorted = TRUE; - } -} - - -static gint -e_week_view_event_sort_func (const void *arg1, - const void *arg2) -{ - EWeekViewEvent *event1, *event2; - - event1 = (EWeekViewEvent*) arg1; - event2 = (EWeekViewEvent*) arg2; - - if (event1->start < event2->start) - return -1; - if (event1->start > event2->start) - return 1; - - if (event1->end > event2->end) - return -1; - if (event1->end < event2->end) - return 1; - - return 0; -} - - -static void -e_week_view_reshape_events (EWeekView *week_view) -{ - EWeekViewEvent *event; - gint event_num, span_num; - gint num_days, day, day_x, day_y, day_w, day_h, max_rows; - gboolean is_weekend; - - for (event_num = 0; event_num < week_view->events->len; event_num++) { - event = &g_array_index (week_view->events, EWeekViewEvent, - event_num); - for (span_num = 0; span_num < event->num_spans; span_num++) { - e_week_view_reshape_event_span (week_view, event_num, - span_num); - } - } - - /* Reshape the jump buttons and show/hide them as appropriate. */ - num_days = week_view->multi_week_view ? week_view->weeks_shown * 7 : 7; - for (day = 0; day < num_days; day++) { - - is_weekend = ((week_view->display_start_day + day) % 7 >= 5) ? TRUE : FALSE; - if (!is_weekend || (week_view->multi_week_view - && !week_view->compress_weekend)) - max_rows = week_view->rows_per_cell; - else - max_rows = week_view->rows_per_compressed_cell; - - /* Determine whether the jump button should be shown. */ - if (week_view->rows_per_day[day] <= max_rows) { - gnome_canvas_item_hide (week_view->jump_buttons[day]); - } else { - e_week_view_get_day_position (week_view, day, - &day_x, &day_y, - &day_w, &day_h); - - gnome_canvas_item_set (week_view->jump_buttons[day], - "GnomeCanvasPixbuf::x", (gdouble) (day_x + day_w - E_WEEK_VIEW_JUMP_BUTTON_X_PAD - E_WEEK_VIEW_JUMP_BUTTON_WIDTH), - "GnomeCanvasPixbuf::y", (gdouble) (day_y + day_h - E_WEEK_VIEW_JUMP_BUTTON_Y_PAD - E_WEEK_VIEW_JUMP_BUTTON_HEIGHT), - NULL); - - gnome_canvas_item_show (week_view->jump_buttons[day]); - gnome_canvas_item_raise_to_top (week_view->jump_buttons[day]); - } - } - - for (day = num_days; day < E_WEEK_VIEW_MAX_WEEKS * 7; day++) { - gnome_canvas_item_hide (week_view->jump_buttons[day]); - } -} - - -static void -e_week_view_reshape_event_span (EWeekView *week_view, - gint event_num, - gint span_num) -{ - EWeekViewEvent *event; - EWeekViewEventSpan *span; - GdkFont *font; - gint span_x, span_y, span_w, num_icons, icons_width, time_width; - gint min_text_x, max_text_w, width; - gboolean show_icons = TRUE, use_max_width = FALSE; - gboolean one_day_event; - CalComponent *comp; - gdouble text_x, text_y, text_w, text_h; - gchar *text, *end_of_line; - gint line_len, text_width; - - event = &g_array_index (week_view->events, EWeekViewEvent, event_num); - span = &g_array_index (week_view->spans, EWeekViewEventSpan, - event->spans_index + span_num); - comp = event->comp; - font = GTK_WIDGET (week_view)->style->font; - - one_day_event = e_week_view_is_one_day_event (week_view, event_num); - - /* If the span will not be visible destroy the canvas items and - return. */ - if (!e_week_view_get_span_position (week_view, event_num, span_num, - &span_x, &span_y, &span_w)) { - if (span->background_item) - gtk_object_destroy (GTK_OBJECT (span->background_item)); - if (span->text_item) - gtk_object_destroy (GTK_OBJECT (span->text_item)); - span->background_item = NULL; - span->text_item = NULL; - return; - } - - /* If we are editing a long event we don't show the icons and the EText - item uses the maximum width available. */ - if (!one_day_event && week_view->editing_event_num == event_num - && week_view->editing_span_num == span_num) { - show_icons = FALSE; - use_max_width = TRUE; - } - - /* Calculate how many icons we need to show. */ - num_icons = 0; - if (show_icons) { - if (cal_component_has_alarms (comp)) - num_icons++; - if (cal_component_has_recurrences (comp)) - num_icons++; - } - - /* Create the background canvas item if necessary. */ - if (!span->background_item) { - span->background_item = - gnome_canvas_item_new (GNOME_CANVAS_GROUP (GNOME_CANVAS (week_view->main_canvas)->root), - e_week_view_event_item_get_type (), - NULL); - } - - gnome_canvas_item_set (span->background_item, - "event_num", event_num, - "span_num", span_num, - NULL); - - /* Create the text item if necessary. */ - if (!span->text_item) { - CalComponentText text; - - cal_component_get_summary (comp, &text); - span->text_item = - gnome_canvas_item_new (GNOME_CANVAS_GROUP (GNOME_CANVAS (week_view->main_canvas)->root), - e_text_get_type (), - "font_gdk", GTK_WIDGET (week_view)->style->font, - "anchor", GTK_ANCHOR_NW, - "clip", TRUE, -#if 0 - "max_lines", 1, -#endif - "editable", TRUE, - "text", text.value ? text.value : "", - "use_ellipsis", TRUE, - "fill_color_rgba", GNOME_CANVAS_COLOR(0, 0, 0), - NULL); - gtk_signal_connect (GTK_OBJECT (span->text_item), "event", - GTK_SIGNAL_FUNC (e_week_view_on_text_item_event), - week_view); - } - - /* Calculate the position of the text item. - For events < 1 day it starts after the times & icons and ends at the - right edge of the span. - For events >= 1 day we need to determine whether times are shown at - the start and end of the span, then try to center the text item with - the icons in the middle, but making sure we don't go over the times. - */ - - - /* Calculate the space necessary to display a time, e.g. "13:00". */ - time_width = e_week_view_get_time_string_width (week_view); - - /* Calculate the space needed for the icons. */ - icons_width = (E_WEEK_VIEW_ICON_WIDTH + E_WEEK_VIEW_ICON_X_PAD) - * num_icons - E_WEEK_VIEW_ICON_X_PAD + E_WEEK_VIEW_ICON_R_PAD; - - /* The y position and height are the same for both event types. */ - text_y = span_y + E_WEEK_VIEW_EVENT_BORDER_HEIGHT - + E_WEEK_VIEW_EVENT_TEXT_Y_PAD; - text_h = font->ascent + font->descent; - - if (one_day_event) { - /* Note that 1-day events don't have a border. Although we - still use the border height to position the events - vertically so they still line up neatly (see above), - we don't use the border width or edge padding at all. */ - text_x = span_x + E_WEEK_VIEW_EVENT_L_PAD; - - switch (week_view->time_format) { - case E_WEEK_VIEW_TIME_BOTH_SMALL_MIN: - case E_WEEK_VIEW_TIME_BOTH: - /* These have 2 time strings with a small space between - them and some space before the EText item. */ - text_x += time_width * 2 - + E_WEEK_VIEW_EVENT_TIME_SPACING - + E_WEEK_VIEW_EVENT_TIME_X_PAD; - break; - case E_WEEK_VIEW_TIME_START_SMALL_MIN: - case E_WEEK_VIEW_TIME_START: - /* These have just 1 time string with some space - before the EText item. */ - text_x += time_width + E_WEEK_VIEW_EVENT_TIME_X_PAD; - break; - case E_WEEK_VIEW_TIME_NONE: - break; - } - - /* The icons_width includes space on the right of the icons. */ - text_x += icons_width; - - /* The width of the EText item extends right to the edge of the - event, just inside the border. */ - text_w = span_x + span_w - E_WEEK_VIEW_EVENT_R_PAD - text_x; - - } else { - if (use_max_width) { - /* When we are editing the event we use all the - available width. */ - text_x = span_x + E_WEEK_VIEW_EVENT_L_PAD - + E_WEEK_VIEW_EVENT_BORDER_WIDTH - + E_WEEK_VIEW_EVENT_EDGE_X_PAD; - text_w = span_x + span_w - E_WEEK_VIEW_EVENT_R_PAD - - E_WEEK_VIEW_EVENT_BORDER_WIDTH - - E_WEEK_VIEW_EVENT_EDGE_X_PAD - text_x; - } else { - /* Get the width of the text of the event. This is a - bit of a hack. It would be better if EText could - tell us this. */ - gtk_object_get (GTK_OBJECT (span->text_item), - "text", &text, - NULL); - text_width = 0; - if (text) { - /* It should only have one line of text in it. - I'm not sure we need this any more. */ - end_of_line = strchr (text, '\n'); - if (end_of_line) - line_len = end_of_line - text; - else - line_len = strlen (text); - text_width = gdk_text_width (font, text, - line_len); - g_free (text); - } - - /* Add on the width of the icons and find the default - position, which centers the icons + text. */ - width = text_width + icons_width; - text_x = span_x + (span_w - width) / 2; - - /* Now calculate the left-most valid position, and make - sure we don't go to the left of that. */ - min_text_x = span_x + E_WEEK_VIEW_EVENT_L_PAD - + E_WEEK_VIEW_EVENT_BORDER_WIDTH - + E_WEEK_VIEW_EVENT_EDGE_X_PAD; - /* See if we will want to display the start time, and - if so take that into account. */ - if (event->start > week_view->day_starts[span->start_day]) - min_text_x += time_width - + E_WEEK_VIEW_EVENT_TIME_X_PAD; - - /* Now make sure we don't go to the left of the minimum - position. */ - text_x = MAX (text_x, min_text_x); - - /* Now calculate the largest valid width, using the - calculated x position, and make sure we don't - exceed that. */ - max_text_w = span_x + span_w - E_WEEK_VIEW_EVENT_R_PAD - - E_WEEK_VIEW_EVENT_BORDER_WIDTH - - E_WEEK_VIEW_EVENT_EDGE_X_PAD - text_x; - if (event->end < week_view->day_starts[span->start_day - + span->num_days]) - max_text_w -= time_width - + E_WEEK_VIEW_EVENT_TIME_X_PAD; - - text_w = MIN (width, max_text_w); - - /* Now take out the space for the icons. */ - text_x += icons_width; - text_w -= icons_width; - } - } - - /* Make sure we don't try to use a negative width. */ - text_w = MAX (text_w, 0); - - gnome_canvas_item_set (span->text_item, - "clip_width", (gdouble) text_w, - "clip_height", (gdouble) text_h, - NULL); - e_canvas_item_move_absolute (span->text_item, text_x, text_y); -} - - -/* Finds the day containing the given time. - If include_midnight_in_prev_day is TRUE then if the time exactly - matches the start of a day the previous day is returned. This is useful - when calculating the end day of an event. */ -static gint -e_week_view_find_day (EWeekView *week_view, - time_t time_to_find, - gboolean include_midnight_in_prev_day) -{ - gint num_days, day; - time_t *day_starts; - - num_days = week_view->multi_week_view ? week_view->weeks_shown * 7 : 7; - day_starts = week_view->day_starts; - - if (time_to_find < day_starts[0]) - return -1; - if (time_to_find > day_starts[num_days]) - return num_days; - - for (day = 1; day <= num_days; day++) { - if (time_to_find <= day_starts[day]) { - if (time_to_find == day_starts[day] - && !include_midnight_in_prev_day) - return day; - return day - 1; - } - } - - g_assert_not_reached (); - return num_days; -} - - -/* This returns the last possible day in the same span as the given day. - A span is all the days which are displayed next to each other from left to - right. In the week view all spans are only 1 day, since Tuesday is below - Monday rather than beside it etc. In the month view, if the weekends are not - compressed then each week is a span, otherwise we have to break a span up - on Saturday, use a separate span for Sunday, and start again on Monday. */ -static gint -e_week_view_find_span_end (EWeekView *week_view, - gint day) -{ - gint week, col, sat_col, end_col; - - if (week_view->multi_week_view) { - week = day / 7; - col = day % 7; - - /* We default to the last column in the row. */ - end_col = 6; - - /* If the weekend is compressed we must end any spans on - Saturday and Sunday. */ - if (week_view->compress_weekend) { - sat_col = (5 + 7 - week_view->display_start_day) % 7; - if (col <= sat_col) - end_col = sat_col; - else if (col == sat_col + 1) - end_col = sat_col + 1; - } - - return week * 7 + end_col; - } else { - return day; - } -} - - -static void -e_week_view_on_adjustment_changed (GtkAdjustment *adjustment, - EWeekView *week_view) -{ - GDate date; - gint week_offset; - struct tm tm; - time_t lower, start, end; - guint32 old_first_day_julian, new_first_day_julian; - - /* If we don't have a valid date set yet, just return. */ - if (!g_date_valid (&week_view->first_day_shown)) - return; - - /* Determine the first date shown. */ - date = week_view->base_date; - week_offset = floor (adjustment->value + 0.5); - g_date_add_days (&date, week_offset * 7); - - /* Convert the old & new first days shown to julian values. */ - old_first_day_julian = g_date_julian (&week_view->first_day_shown); - new_first_day_julian = g_date_julian (&date); - - /* If we are already showing the date, just return. */ - if (old_first_day_julian == new_first_day_julian) - return; - - /* Set the new first day shown. */ - week_view->first_day_shown = date; - - /* Convert it to a time_t. */ - g_date_to_struct_tm (&date, &tm); - lower = mktime (&tm); - lower = time_day_begin (lower); - - e_week_view_recalc_day_starts (week_view, lower); - e_week_view_queue_reload_events (week_view); - - /* Update the selection, if needed. */ - if (week_view->selection_start_day != -1) { - start = week_view->day_starts[week_view->selection_start_day]; - end = week_view->day_starts[week_view->selection_end_day + 1]; - if (week_view->calendar) - gnome_calendar_set_selected_time_range (week_view->calendar, start, end); - } - - gtk_widget_queue_draw (week_view->main_canvas); -} - - -void -e_week_view_start_editing_event (EWeekView *week_view, - gint event_num, - gint span_num, - gchar *initial_text) -{ - EWeekViewEvent *event; - EWeekViewEventSpan *span; - ETextEventProcessor *event_processor = NULL; - ETextEventProcessorCommand command; - - /* If we are already editing the event, just return. */ - if (event_num == week_view->editing_event_num - && span_num == week_view->editing_span_num) - return; - - event = &g_array_index (week_view->events, EWeekViewEvent, event_num); - span = &g_array_index (week_view->spans, EWeekViewEventSpan, - event->spans_index + span_num); - - /* If the event is not shown, don't try to edit it. */ - if (!span->text_item) - return; - - if (initial_text) { - gnome_canvas_item_set (span->text_item, - "text", initial_text, - NULL); - } - - /* FIXME: This implicitly stops any edit of another item, causing it - to be sent to the server and resulting in a call to obj_updated_cb() - which may reload all the events and so our span and text item may - actually be destroyed. So we often get a SEGV. */ - e_canvas_item_grab_focus (span->text_item); - - /* Try to move the cursor to the end of the text. */ - gtk_object_get (GTK_OBJECT (span->text_item), - "event_processor", &event_processor, - NULL); - if (event_processor) { - command.action = E_TEP_MOVE; - command.position = E_TEP_END_OF_BUFFER; - gtk_signal_emit_by_name (GTK_OBJECT (event_processor), - "command", &command); - } -} - - -/* This stops any current edit. */ -void -e_week_view_stop_editing_event (EWeekView *week_view) -{ - GtkWidget *toplevel; - - /* Check we are editing an event. */ - if (week_view->editing_event_num == -1) - return; - - /* Set focus to the toplevel so the item loses focus. */ - toplevel = gtk_widget_get_toplevel (GTK_WIDGET (week_view)); - if (toplevel && GTK_IS_WINDOW (toplevel)) - gtk_window_set_focus (GTK_WINDOW (toplevel), NULL); -} - - -static gboolean -e_week_view_on_text_item_event (GnomeCanvasItem *item, - GdkEvent *event, - EWeekView *week_view) -{ - gint event_num, span_num; - -#if 0 - g_print ("In e_week_view_on_text_item_event\n"); -#endif - - switch (event->type) { - case GDK_KEY_PRESS: - if (event && event->key.keyval == GDK_Return) { - /* We set the keyboard focus to the EDayView, so the - EText item loses it and stops the edit. */ - gtk_widget_grab_focus (GTK_WIDGET (week_view)); - - /* Stop the signal last or we will also stop any - other events getting to the EText item. */ - gtk_signal_emit_stop_by_name (GTK_OBJECT (item), - "event"); - return TRUE; - } - break; - case GDK_BUTTON_PRESS: - if (!e_week_view_find_event_from_item (week_view, item, - &event_num, &span_num)) - return FALSE; - - if (event->button.button == 3) { - if (!GTK_WIDGET_HAS_FOCUS (week_view)) - gtk_widget_grab_focus (GTK_WIDGET (week_view)); - e_week_view_show_popup_menu (week_view, - (GdkEventButton*) event, - event_num); - gtk_signal_emit_stop_by_name (GTK_OBJECT (item->canvas), - "button_press_event"); - return TRUE; - } - - week_view->pressed_event_num = event_num; - week_view->pressed_span_num = span_num; - - /* Only let the EText handle the event while editing. */ - if (!E_TEXT (item)->editing) { - gtk_signal_emit_stop_by_name (GTK_OBJECT (item), - "event"); - - if (event) { - week_view->drag_event_x = event->button.x; - week_view->drag_event_y = event->button.y; - } else - g_warning ("No GdkEvent"); - - /* FIXME: Remember the day offset from the start of - the event, for DnD. */ - - return TRUE; - } - break; - case GDK_BUTTON_RELEASE: - if (!E_TEXT (item)->editing) { - /* This shouldn't ever happen. */ - if (!e_week_view_find_event_from_item (week_view, - item, - &event_num, - &span_num)) - return FALSE; - - if (week_view->pressed_event_num != -1 - && week_view->pressed_event_num == event_num - && week_view->pressed_span_num == span_num) { - e_week_view_start_editing_event (week_view, - event_num, - span_num, - NULL); - week_view->pressed_event_num = -1; - } - - /* Stop the signal last or we will also stop any - other events getting to the EText item. */ - gtk_signal_emit_stop_by_name (GTK_OBJECT (item), - "event"); - return TRUE; - } - week_view->pressed_event_num = -1; - break; - case GDK_FOCUS_CHANGE: - if (event->focus_change.in) { - e_week_view_on_editing_started (week_view, item); - } else { - e_week_view_on_editing_stopped (week_view, item); - } - - return FALSE; - default: - break; - } - - return FALSE; -} - - -static void -e_week_view_on_editing_started (EWeekView *week_view, - GnomeCanvasItem *item) -{ - gint event_num, span_num; - - if (!e_week_view_find_event_from_item (week_view, item, - &event_num, &span_num)) - return; - -#if 0 - g_print ("In e_week_view_on_editing_started event_num:%i span_num:%i\n", event_num, span_num); -#endif - - week_view->editing_event_num = event_num; - week_view->editing_span_num = span_num; - - /* We need to reshape long events so the whole width is used while - editing. */ - if (!e_week_view_is_one_day_event (week_view, event_num)) { - e_week_view_reshape_event_span (week_view, event_num, - span_num); - } -} - - -static void -e_week_view_on_editing_stopped (EWeekView *week_view, - GnomeCanvasItem *item) -{ - gint event_num, span_num; - EWeekViewEvent *event; - EWeekViewEventSpan *span; - gchar *text = NULL; - CalComponentText summary; - const char *uid; - - /* 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. */ - event_num = week_view->editing_event_num; - span_num = week_view->editing_span_num; - - /* If no item is being edited, just return. */ - if (event_num == -1) - return; - - event = &g_array_index (week_view->events, EWeekViewEvent, event_num); - span = &g_array_index (week_view->spans, EWeekViewEventSpan, - event->spans_index + span_num); - - /* Reset the edit fields. */ - week_view->editing_event_num = -1; - - /* Check that the event is still valid. */ - cal_component_get_uid (event->comp, &uid); - if (!uid) - return; - - gtk_object_get (GTK_OBJECT (span->text_item), - "text", &text, - NULL); - - /* Only update the summary if necessary. */ - cal_component_get_summary (event->comp, &summary); - if (text && summary.value && !strcmp (text, summary.value)) { - g_free (text); - if (!e_week_view_is_one_day_event (week_view, event_num)) - e_week_view_reshape_event_span (week_view, event_num, - span_num); - return; - } - - summary.value = text; - cal_component_set_summary (event->comp, &summary); - g_free (text); - - if (!cal_client_update_object (week_view->client, event->comp)) - g_message ("e_week_view_on_editing_stopped(): Could not update the object!"); -} - - -static gboolean -e_week_view_find_event_from_item (EWeekView *week_view, - GnomeCanvasItem *item, - gint *event_num_return, - gint *span_num_return) -{ - EWeekViewEvent *event; - EWeekViewEventSpan *span; - gint event_num, span_num, num_events; - - num_events = week_view->events->len; - for (event_num = 0; event_num < num_events; event_num++) { - event = &g_array_index (week_view->events, EWeekViewEvent, - event_num); - for (span_num = 0; span_num < event->num_spans; span_num++) { - span = &g_array_index (week_view->spans, - EWeekViewEventSpan, - event->spans_index + span_num); - if (span->text_item == item) { - *event_num_return = event_num; - *span_num_return = span_num; - return TRUE; - } - } - } - - return FALSE; -} - - -/* Finds the index of the event with the given uid. - Returns TRUE if an event with the uid was found. - Note that for recurring events there may be several EWeekViewEvents, one - for each instance, all with the same iCalObject and uid. So only use this - function if you know the event doesn't recur or you are just checking to - see if any events with the uid exist. */ -static gboolean -e_week_view_find_event_from_uid (EWeekView *week_view, - const gchar *uid, - gint *event_num_return) -{ - EWeekViewEvent *event; - gint event_num, num_events; - - num_events = week_view->events->len; - for (event_num = 0; event_num < num_events; event_num++) { - const char *u; - - event = &g_array_index (week_view->events, EWeekViewEvent, - event_num); - - cal_component_get_uid (event->comp, &u); - if (u && !strcmp (uid, u)) { - *event_num_return = event_num; - return TRUE; - } - } - - return FALSE; -} - - -gboolean -e_week_view_is_one_day_event (EWeekView *week_view, - gint event_num) -{ - EWeekViewEvent *event; - EWeekViewEventSpan *span; - - event = &g_array_index (week_view->events, EWeekViewEvent, event_num); - if (event->num_spans != 1) - return FALSE; - - span = &g_array_index (week_view->spans, EWeekViewEventSpan, - event->spans_index); - - if (event->start == week_view->day_starts[span->start_day] - && event->end == week_view->day_starts[span->start_day + 1]) - return FALSE; - - if (span->num_days == 1 - && event->start >= week_view->day_starts[span->start_day] - && event->end <= week_view->day_starts[span->start_day + 1]) - return TRUE; - - return FALSE; -} - - -static gint -e_week_view_key_press (GtkWidget *widget, GdkEventKey *event) -{ - EWeekView *week_view; - CalComponent *comp; - gint event_num; - gchar *initial_text; - CalComponentDateTime date; - struct icaltimetype itt; - time_t dtstart, dtend; - const char *uid; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (E_IS_WEEK_VIEW (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - week_view = E_WEEK_VIEW (widget); - - /* The Escape key aborts a resize operation. */ -#if 0 - if (week_view->resize_drag_pos != E_WEEK_VIEW_POS_NONE) { - if (event->keyval == GDK_Escape) { - e_week_view_abort_resize (week_view, event->time); - } - return FALSE; - } -#endif - - if (week_view->selection_start_day == -1) - return FALSE; - - /* We only want to start an edit with a return key or a simple - character. */ - if (event->keyval == GDK_Return) { - initial_text = NULL; - } else if ((event->keyval < 0x20) - || (event->keyval > 0xFF) - || (event->length == 0) - || (event->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK))) { - return FALSE; - } else { - initial_text = event->string; - } - - /* Add a new event covering the selected range. */ - comp = cal_component_new (); - cal_component_set_new_vtype (comp, CAL_COMPONENT_EVENT); - dtstart = week_view->day_starts[week_view->selection_start_day]; - dtend = week_view->day_starts[week_view->selection_end_day + 1]; - - date.value = &itt; - date.tzid = NULL; - - *date.value = icaltime_from_timet (dtstart, FALSE); - cal_component_set_dtstart (comp, &date); - *date.value = icaltime_from_timet (dtend, FALSE); - cal_component_set_dtend (comp, &date); - - /* We add the event locally and start editing it. We don't send the - new event to the server until the edit is finished. - FIXME: If we get an obj-updated or obj-removed signal while editing - the event, and we have to do a re-layout, we may lose this new - event. */ - e_week_view_add_event (comp, dtstart, dtend, week_view); - e_week_view_check_layout (week_view); - gtk_widget_queue_draw (week_view->main_canvas); - - cal_component_get_uid (comp, &uid); - if (e_week_view_find_event_from_uid (week_view, uid, &event_num)) { - e_week_view_start_editing_event (week_view, event_num, 0, - initial_text); - } else { - g_warning ("Couldn't find event to start editing.\n"); - } - - gtk_object_unref (GTK_OBJECT (comp)); - - return TRUE; -} - - -void -e_week_view_show_popup_menu (EWeekView *week_view, - GdkEventButton *bevent, - gint event_num) -{ - EWeekViewEvent *event; - int have_selection, not_being_edited, num_items, i; - struct menu_item *context_menu; - - static struct menu_item items[] = { - { N_("New appointment..."), (GtkSignalFunc) e_week_view_on_new_appointment, NULL, TRUE } - }; - - static struct menu_item child_items[] = { - { N_("Schedule meeting"), (GtkSignalFunc) e_week_view_on_schedule_meet, NULL, TRUE }, - - { NULL, NULL, NULL, TRUE}, - - { N_("Edit this appointment..."), (GtkSignalFunc) e_week_view_on_edit_appointment, NULL, TRUE }, - { N_("Delete this appointment"), (GtkSignalFunc) e_week_view_on_delete_appointment, NULL, TRUE }, - - { NULL, NULL, NULL, TRUE }, - - { N_("New appointment..."), (GtkSignalFunc) e_week_view_on_new_appointment, NULL, TRUE } - }; - - static struct menu_item recur_child_items[] = { - { N_("Make this appointment movable"), (GtkSignalFunc) e_week_view_on_unrecur_appointment, NULL, TRUE }, - { N_("Schedule meeting"), (GtkSignalFunc) e_week_view_on_schedule_meet, NULL, TRUE }, - - { NULL, NULL, NULL, TRUE }, - - { N_("Edit this appointment..."), (GtkSignalFunc) e_week_view_on_edit_appointment, NULL, TRUE }, - { N_("Delete this occurrence"), (GtkSignalFunc) e_week_view_on_delete_occurrence, NULL, TRUE }, - { N_("Delete all occurrences"), (GtkSignalFunc) e_week_view_on_delete_appointment, NULL, TRUE }, - - { NULL, NULL, NULL, TRUE }, - - { N_("New appointment..."), (GtkSignalFunc) e_week_view_on_new_appointment, NULL, TRUE } - }; - - have_selection = GTK_WIDGET_HAS_FOCUS (week_view) - && week_view->selection_start_day != -1; - - if (event_num == -1) { - num_items = 1; - context_menu = &items[0]; - context_menu[0].sensitive = have_selection; - } else { - event = &g_array_index (week_view->events, - EWeekViewEvent, event_num); - - /* This used to be set only if the event wasn't being edited - in the event editor, but we can't check that at present. - We could possibly set up another method of checking it. */ - not_being_edited = TRUE; - - if (cal_component_has_recurrences (event->comp)) { - num_items = 7; - context_menu = &recur_child_items[0]; - context_menu[0].sensitive = not_being_edited; - context_menu[2].sensitive = not_being_edited; - context_menu[3].sensitive = not_being_edited; - context_menu[4].sensitive = not_being_edited; - context_menu[6].sensitive = have_selection; - } else { - num_items = 4; - context_menu = &child_items[0]; - context_menu[0].sensitive = not_being_edited; - context_menu[1].sensitive = not_being_edited; - context_menu[3].sensitive = have_selection; - } - } - - for (i = 0; i < num_items; i++) - context_menu[i].data = week_view; - - week_view->popup_event_num = event_num; - popup_menu (context_menu, num_items, bevent); -} - - -static void -e_week_view_on_new_appointment (GtkWidget *widget, gpointer data) -{ - EWeekView *week_view; - CalComponent *comp; - CalComponentDateTime date; - struct icaltimetype itt; - time_t dt; - - week_view = E_WEEK_VIEW (data); - - comp = cal_component_new (); - cal_component_set_new_vtype (comp, CAL_COMPONENT_EVENT); - - date.value = &itt; - date.tzid = NULL; - - dt = week_view->day_starts[week_view->selection_start_day]; - *date.value = icaltime_from_timet (dt, TRUE); - cal_component_set_dtstart (comp, &date); - - dt = week_view->day_starts[week_view->selection_end_day + 1]; - *date.value = icaltime_from_timet (dt, TRUE); - cal_component_set_dtend (comp, &date); - - cal_component_commit_sequence (comp); - - if (week_view->calendar) - gnome_calendar_edit_object (week_view->calendar, comp); - else - g_warning ("Calendar not set"); - - gtk_object_unref (GTK_OBJECT (comp)); -} - - -static void -e_week_view_on_edit_appointment (GtkWidget *widget, gpointer data) -{ - EWeekView *week_view; - EWeekViewEvent *event; - - week_view = E_WEEK_VIEW (data); - - if (week_view->popup_event_num == -1) - return; - - event = &g_array_index (week_view->events, EWeekViewEvent, - week_view->popup_event_num); - - if (week_view->calendar) - gnome_calendar_edit_object (week_view->calendar, event->comp); - else - g_warning ("Calendar not set"); -} - - -static void -e_week_view_on_delete_occurrence (GtkWidget *widget, gpointer data) -{ - EWeekView *week_view; - EWeekViewEvent *event; - CalComponent *comp; - - week_view = E_WEEK_VIEW (data); - - if (week_view->popup_event_num == -1) - return; - - event = &g_array_index (week_view->events, EWeekViewEvent, - week_view->popup_event_num); - - /* We must duplicate the CalComponent, or we won't know it has changed - when we get the "update_event" callback. */ - - comp = cal_component_clone (event->comp); - cal_comp_util_add_exdate (comp, icaltime_from_timet (event->start, TRUE)); - - if (!cal_client_update_object (week_view->client, comp)) - g_message ("e_week_view_on_delete_occurrence(): Could not update the object!"); - - gtk_object_unref (GTK_OBJECT (comp)); -} - - -static void -e_week_view_on_delete_appointment (GtkWidget *widget, gpointer data) -{ - EWeekView *week_view; - EWeekViewEvent *event; - - week_view = E_WEEK_VIEW (data); - - if (week_view->popup_event_num == -1) - return; - - event = &g_array_index (week_view->events, EWeekViewEvent, - week_view->popup_event_num); - - if (delete_component_dialog (event->comp, widget)) { - const char *uid; - - cal_component_get_uid (event->comp, &uid); - - /* We don't check the return value; FALSE can mean the object - * was not in the server anyways. - */ - cal_client_remove_object (week_view->client, uid); - } -} - -static void -e_week_view_on_schedule_meet (GtkWidget *widget, gpointer data) -{ - EWeekView *week_view; - EWeekViewEvent *event; - EMeetingEditor *editor; - - week_view = E_WEEK_VIEW (data); - - if (week_view->popup_event_num == -1) - return; - - event = &g_array_index (week_view->events, EWeekViewEvent, - week_view->popup_event_num); - - editor = e_meeting_editor_new (event->comp, week_view->client); - - e_meeting_edit (editor); - e_meeting_editor_free (editor); -} - -static void -e_week_view_on_unrecur_appointment (GtkWidget *widget, gpointer data) -{ - EWeekView *week_view; - EWeekViewEvent *event; - CalComponent *comp, *new_comp; - CalComponentDateTime date; - struct icaltimetype itt; - - week_view = E_WEEK_VIEW (data); - - 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_clone (event->comp); - cal_comp_util_add_exdate (comp, icaltime_from_timet (event->start, TRUE)); - - /* 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_clone (event->comp); - 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 = NULL; - - *date.value = icaltime_from_timet (event->start, TRUE); - cal_component_set_dtstart (new_comp, &date); - *date.value = icaltime_from_timet (event->end, TRUE); - 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 (week_view->client, comp)) - g_message ("e_week_view_on_unrecur_appointment(): Could not update the object!"); - - gtk_object_unref (GTK_OBJECT (comp)); - - if (!cal_client_update_object (week_view->client, new_comp)) - g_message ("e_week_view_on_unrecur_appointment(): Could not update the object!"); - - gtk_object_unref (GTK_OBJECT (new_comp)); -} - - -static gboolean -e_week_view_on_jump_button_event (GnomeCanvasItem *item, - GdkEvent *event, - EWeekView *week_view) -{ - gint day; - - if (event->type == GDK_BUTTON_PRESS) { - for (day = 0; day < E_WEEK_VIEW_MAX_WEEKS * 7; day++) { - if (item == week_view->jump_buttons[day]) { - if (week_view->calendar) - gnome_calendar_dayjump - (week_view->calendar, - week_view->day_starts[day]); - else - g_warning ("Calendar not set"); - return TRUE; - } - } - - } - - return FALSE; -} - - -/* Converts an hour from 0-23 to the preferred time format, and returns the - suffix to add and the width of it in the normal font. */ -void -e_week_view_convert_time_to_display (EWeekView *week_view, - gint hour, - gint *display_hour, - gchar **suffix, - gint *suffix_width) -{ - /* Calculate the actual hour number to display. For 12-hour - format we convert 0-23 to 12-11am/12-11pm. */ - *display_hour = hour; - if (week_view->use_24_hour_format) { - *suffix = ""; - *suffix_width = 0; - } else { - if (hour < 12) { - *suffix = week_view->am_string; - *suffix_width = week_view->am_string_width; - } else { - *display_hour -= 12; - *suffix = week_view->pm_string; - *suffix_width = week_view->pm_string_width; - } - - /* 12-hour uses 12:00 rather than 0:00. */ - if (*display_hour == 0) - *display_hour = 12; - } -} - - -gint -e_week_view_get_time_string_width (EWeekView *week_view) -{ - gint time_width; - - if (week_view->use_small_font && week_view->small_font) - time_width = week_view->digit_width * 2 - + week_view->small_digit_width * 2; - else - time_width = week_view->digit_width * 4 - + week_view->colon_width; - - if (!week_view->use_24_hour_format) - time_width += MAX (week_view->am_string_width, - week_view->pm_string_width); - - return time_width; -} diff --git a/calendar/gui/e-week-view.h b/calendar/gui/e-week-view.h deleted file mode 100644 index 47362d0ee6..0000000000 --- a/calendar/gui/e-week-view.h +++ /dev/null @@ -1,448 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 1999, Helix Code, Inc. - * Copyright 2001, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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 - */ -#ifndef _E_WEEK_VIEW_H_ -#define _E_WEEK_VIEW_H_ - -#include <gtk/gtktable.h> -#include <libgnomeui/gnome-canvas.h> - -#include "gnome-cal.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - * EWeekView - displays the Week & Month views of the calendar. - */ - -/* The maximum number of weeks we show. 5 is usually enough for 1 month, - but we allow 6 for longer selections. */ -#define E_WEEK_VIEW_MAX_WEEKS 6 - -/* The size of the reminder & recurrence icons, and padding around them. - X_PAD is the padding between icons. R_PAD is the padding on the right of - the last icon, before the event text. */ -#define E_WEEK_VIEW_ICON_WIDTH 16 -#define E_WEEK_VIEW_ICON_HEIGHT 16 -#define E_WEEK_VIEW_ICON_X_PAD 0 -#define E_WEEK_VIEW_ICON_Y_PAD 0 -#define E_WEEK_VIEW_ICON_R_PAD 2 - -/* The space on the left & right outside of the event. (The triangle to - indicate the event continues is displayed in this space). */ -#define E_WEEK_VIEW_EVENT_L_PAD 2 -#define E_WEEK_VIEW_EVENT_R_PAD 2 - -/* The vertical spacing between rows of events. */ -#define E_WEEK_VIEW_EVENT_Y_SPACING 1 - -/* The size of the border around long events. */ -#define E_WEEK_VIEW_EVENT_BORDER_WIDTH 1 -#define E_WEEK_VIEW_EVENT_BORDER_HEIGHT 1 - -/* The padding on the top and bottom of the event text. */ -#define E_WEEK_VIEW_EVENT_TEXT_Y_PAD 1 - -/* The space between the start and end times. */ -#define E_WEEK_VIEW_EVENT_TIME_SPACING 2 - -/* The space between the time and the event text or icons. */ -#define E_WEEK_VIEW_EVENT_TIME_X_PAD 2 - -/* The space between the borders of long events and any text of icons. */ -#define E_WEEK_VIEW_EVENT_EDGE_X_PAD 2 - -/* The padding above and on the right of the date string at the top of each - cell. */ -#define E_WEEK_VIEW_DATE_T_PAD 2 -#define E_WEEK_VIEW_DATE_R_PAD 4 - -/* The padding above and below the line under the date string, in the Week - view, and also the space on the left of it. */ -#define E_WEEK_VIEW_DATE_LINE_T_PAD 1 -#define E_WEEK_VIEW_DATE_LINE_B_PAD 1 -#define E_WEEK_VIEW_DATE_LINE_L_PAD 10 - -/* The padding below the date string in the Month view. */ -#define E_WEEK_VIEW_DATE_B_PAD 1 - -/* These index our colors array. */ -typedef enum -{ - E_WEEK_VIEW_COLOR_EVEN_MONTHS, - E_WEEK_VIEW_COLOR_ODD_MONTHS, - E_WEEK_VIEW_COLOR_EVENT_BACKGROUND, - E_WEEK_VIEW_COLOR_EVENT_BORDER, - E_WEEK_VIEW_COLOR_EVENT_TEXT, - E_WEEK_VIEW_COLOR_GRID, - E_WEEK_VIEW_COLOR_SELECTED, - E_WEEK_VIEW_COLOR_DATES, - E_WEEK_VIEW_COLOR_DATES_SELECTED, - - E_WEEK_VIEW_COLOR_LAST -} EWeekViewColors; - -/* These specify which part of the selection we are dragging, if any. */ -typedef enum -{ - E_WEEK_VIEW_DRAG_NONE, - E_WEEK_VIEW_DRAG_START, - E_WEEK_VIEW_DRAG_END -} EWeekViewDragPosition; - -/* These specify which times are shown for the 1-day events. We use the small - font for the minutes if it can be loaded and the option is on. */ -typedef enum -{ - E_WEEK_VIEW_TIME_NONE, - E_WEEK_VIEW_TIME_START, - E_WEEK_VIEW_TIME_BOTH, - E_WEEK_VIEW_TIME_START_SMALL_MIN, - E_WEEK_VIEW_TIME_BOTH_SMALL_MIN -} EWeekViewTimeFormat; - -/* Specifies the position of the mouse. */ -typedef enum -{ - E_WEEK_VIEW_POS_OUTSIDE, - E_WEEK_VIEW_POS_NONE, - E_WEEK_VIEW_POS_EVENT, - E_WEEK_VIEW_POS_LEFT_EDGE, - E_WEEK_VIEW_POS_RIGHT_EDGE -} EWeekViewPosition; - - -typedef struct _EWeekViewEventSpan EWeekViewEventSpan; -struct _EWeekViewEventSpan { - guint start_day : 6; - guint num_days : 3; - guint row : 7; - GnomeCanvasItem *background_item; - GnomeCanvasItem *text_item; -}; - -typedef struct _EWeekViewEvent EWeekViewEvent; -struct _EWeekViewEvent { - CalComponent *comp; - time_t start; - time_t end; - guint16 start_minute; /* Minutes from the start of the day. */ - guint16 end_minute; - gint spans_index; - guint num_spans; -}; - - -#define E_WEEK_VIEW(obj) GTK_CHECK_CAST (obj, e_week_view_get_type (), EWeekView) -#define E_WEEK_VIEW_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, e_week_view_get_type (), EWeekViewClass) -#define E_IS_WEEK_VIEW(obj) GTK_CHECK_TYPE (obj, e_week_view_get_type ()) - - -typedef struct _EWeekView EWeekView; -typedef struct _EWeekViewClass EWeekViewClass; - -struct _EWeekView -{ - GtkTable table; - - /* The top canvas where the dates are shown. */ - GtkWidget *titles_canvas; - GnomeCanvasItem *titles_canvas_item; - - /* The main canvas where the appointments are shown. */ - GtkWidget *main_canvas; - GnomeCanvasItem *main_canvas_item; - - GnomeCanvasItem *jump_buttons[E_WEEK_VIEW_MAX_WEEKS * 7]; - - GtkWidget *vscrollbar; - - /* The calendar we are associated with. */ - GnomeCalendar *calendar; - - /* Calendar client object we are monitoring */ - CalClient *client; - - /* The array of EWeekViewEvent elements. */ - GArray *events; - gboolean events_sorted; - gboolean events_need_layout; - gboolean events_need_reshape; - - /* The id of our idle function to reload all events. */ - gint reload_events_idle_id; - - /* An array of EWeekViewEventSpan elements. Each event has its own - space within this array, and uses the spans_index and num_spans - fields of the EWeekViewEvent struct to access it. */ - GArray *spans; - - /* The start of each day displayed. */ - time_t day_starts[E_WEEK_VIEW_MAX_WEEKS * 7 + 1]; - - /* The base date, where the adjustment value is 0. */ - GDate base_date; - - /* The first day shown in the view. */ - GDate first_day_shown; - - /* If we are displaying multiple weeks in rows. If this is FALSE only - one week is shown, with a different layout. */ - gboolean multi_week_view; - - /* How many weeks we are showing. This is only relevant if - display_month is TRUE. */ - gint weeks_shown; - - /* If Sat & Sun are compressed. Only applicable in month view, since - they are always compressed into 1 cell in the week view. */ - gboolean compress_weekend; - - /* Whether we use show event end times. */ - gboolean show_event_end_times; - - /* The first day of the week, 0 (Monday) to 6 (Sunday). */ - gint week_start_day; - - /* Whether we use 12-hour of 24-hour format. */ - gboolean use_24_hour_format; - - /* The first day of the week we display, 0 (Monday) to 6 (Sunday). - This will usually be week_start_day, but if the weekend is - compressed, and week_start_day is Sunday we have to use Saturday. */ - gint display_start_day; - - /* The vertical offset of the events from the top of the cells. */ - gint events_y_offset; - - /* The height of the events, not including spacing between them. */ - gint row_height; - - /* The number of rows of events in each cell. */ - gint rows_per_cell; - gint rows_per_compressed_cell; - - /* The number of rows we have used for each day (i.e. each cell) */ - gint rows_per_day[E_WEEK_VIEW_MAX_WEEKS * 7]; - - /* If the small font is used for displaying the minutes. */ - gboolean use_small_font; - - /* Small font to display the minutes. */ - GdkFont *small_font; - - /* The widths of various pieces of text, used to determine which of - several date formats to display, set in e_week_view_style_set(). */ - gint space_width; /* One space character ' '. */ - gint colon_width; /* Size of ':' in the font. */ - gint slash_width; /* Size of '/' in the font. */ - gint digit_width; /* Size of a '0' digit. */ - gint small_digit_width; /* Size of a small_font '0' digit. */ - gint day_widths[7]; /* Monday first. */ - gint max_day_width; - gint abbr_day_widths[7]; - gint max_abbr_day_width; - gint month_widths[12]; - gint max_month_width; - gint abbr_month_widths[12]; - gint max_abbr_month_width; - - /* The size of the main grid of days and of the cells. A row - corresponds to a compressed day, so normal days usually take - up 2 rows. Note that the offsets arrays have one more element - than the widths/heights arrays since they also contain the - right/bottom edge. */ - gint rows; - gint columns; - gint col_widths[7]; - gint col_offsets[8]; - gint row_heights[E_WEEK_VIEW_MAX_WEEKS * 2]; - gint row_offsets[E_WEEK_VIEW_MAX_WEEKS * 2 + 1]; - - /* This specifies which times we are showing for the events, depending - on how much room is available. */ - EWeekViewTimeFormat time_format; - - /* The GC used for painting in different colors. */ - GdkGC *main_gc; - - /* The icons. */ - GdkPixmap *reminder_icon; - GdkBitmap *reminder_mask; - GdkPixmap *recurrence_icon; - GdkBitmap *recurrence_mask; - - /* Colors for drawing. */ - GdkColor colors[E_WEEK_VIEW_COLOR_LAST]; - - /* The normal & resizing cursors. */ - GdkCursor *normal_cursor; - GdkCursor *move_cursor; - GdkCursor *resize_width_cursor; - - /* This remembers the last cursor set on the window. */ - GdkCursor *last_cursor_set; - - /* The currently selected region, in days from the first day shown. - If selection_start_day is -1 there is no current selection. */ - gint selection_start_day; - gint selection_end_day; - - /* This specifies which end of the selection is being dragged, or is - E_WEEK_VIEW_DRAG_NONE if the selection isn't being dragged. */ - EWeekViewDragPosition selection_drag_pos; - - /* This is the event the mouse button was pressed on. If the button - is released we start editing it, but if the mouse is dragged we set - this to -1. */ - gint pressed_event_num; - gint pressed_span_num; - - /* The event span currently being edited. The num is -1 if no event is - being edited. */ - gint editing_event_num; - gint editing_span_num; - - /* The event that the context menu is for. */ - gint popup_event_num; - - /* The last mouse position when dragging, in the entire canvas. */ - gint drag_event_x; - gint drag_event_y; - - /* "am" and "pm" in the current locale, and their widths. */ - gchar *am_string; - gchar *pm_string; - gint am_string_width; - gint pm_string_width; -}; - -struct _EWeekViewClass -{ - GtkTableClass parent_class; -}; - - -GtkType e_week_view_get_type (void); -GtkWidget* e_week_view_new (void); - -void e_week_view_set_calendar (EWeekView *week_view, - GnomeCalendar *calendar); - -/* The first day shown. Note that it will be rounded down to the start of a - week when set. The returned value will be invalid if no date has been set - yet. */ -void e_week_view_get_first_day_shown (EWeekView *week_view, - GDate *date); -void e_week_view_set_first_day_shown (EWeekView *week_view, - GDate *date); - -void e_week_view_set_cal_client (EWeekView *week_view, - CalClient *client); - -/* 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. */ -void e_week_view_get_selected_time_range (EWeekView *week_view, - time_t *start_time, - time_t *end_time); -void e_week_view_set_selected_time_range (EWeekView *week_view, - time_t start_time, - time_t end_time); - - -/* Whether to display 1 week or 1 month (5 weeks). It defaults to 1 week. */ -gboolean e_week_view_get_multi_week_view (EWeekView *week_view); -void e_week_view_set_multi_week_view (EWeekView *week_view, - gboolean multi_week_view); - -/* The number of weeks shown in the multi-week view. */ -gint e_week_view_get_weeks_shown (EWeekView *week_view); -void e_week_view_set_weeks_shown (EWeekView *week_view, - gint weeks_shown); - -/* Whether the weekend (Sat/Sun) should be compressed into 1 cell in the Month - view. In the Week view they are always compressed. */ -gboolean e_week_view_get_compress_weekend (EWeekView *week_view); -void e_week_view_set_compress_weekend (EWeekView *week_view, - gboolean compress); - -/* Whether we display event end times. */ -gboolean e_week_view_get_show_event_end_times (EWeekView *week_view); -void e_week_view_set_show_event_end_times (EWeekView *week_view, - gboolean show); - -/* The first day of the week, 0 (Monday) to 6 (Sunday). */ -gint e_week_view_get_week_start_day (EWeekView *week_view); -void e_week_view_set_week_start_day (EWeekView *week_view, - gint week_start_day); - -/* Whether we use 12-hour or 24-hour format. */ -gboolean e_week_view_get_24_hour_format (EWeekView *week_view); -void e_week_view_set_24_hour_format (EWeekView *week_view, - gboolean use_24_hour); - - - -/* - * Internal functions called by the associated canvas items. - */ -void e_week_view_get_day_position (EWeekView *week_view, - gint day, - gint *day_x, - gint *day_y, - gint *day_w, - gint *day_h); -gboolean e_week_view_get_span_position (EWeekView *week_view, - gint event_num, - gint span_num, - gint *span_x, - gint *span_y, - gint *span_w); -gboolean e_week_view_is_one_day_event (EWeekView *week_view, - gint event_num); -void e_week_view_start_editing_event (EWeekView *week_view, - gint event_num, - gint span_num, - gchar *initial_text); -void e_week_view_stop_editing_event (EWeekView *week_view); - -void e_week_view_show_popup_menu (EWeekView *week_view, - GdkEventButton *event, - gint event_num); - -void e_week_view_convert_time_to_display (EWeekView *week_view, - gint hour, - gint *display_hour, - gchar **suffix, - gint *suffix_width); -gint e_week_view_get_time_string_width (EWeekView *week_view); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_WEEK_VIEW_H_ */ diff --git a/calendar/gui/event-editor-dialog.glade b/calendar/gui/event-editor-dialog.glade deleted file mode 100644 index 615bd3eed3..0000000000 --- a/calendar/gui/event-editor-dialog.glade +++ /dev/null @@ -1,1408 +0,0 @@ -<?xml version="1.0"?> -<GTK-Interface> - -<project> - <name>event-editor-dialog</name> - <program_name>event-editor-dialog</program_name> - <directory></directory> - <source_directory>.</source_directory> - <pixmaps_directory>pixmaps</pixmaps_directory> - <language>C</language> - <gnome_support>True</gnome_support> - <gettext_support>True</gettext_support> - <output_main_file>False</output_main_file> - <output_support_files>False</output_support_files> - <output_build_files>False</output_build_files> -</project> - -<widget> - <class>GnomePropertyBox</class> - <name>event-editor-dialog</name> - <visible>False</visible> - <position>GTK_WIN_POS_NONE</position> - <modal>False</modal> - <allow_shrink>False</allow_shrink> - <allow_grow>False</allow_grow> - <auto_shrink>False</auto_shrink> - - <widget> - <class>GtkNotebook</class> - <child_name>GnomeDock:contents</child_name> - <name>notebook1</name> - <border_width>2</border_width> - <can_focus>True</can_focus> - <show_tabs>True</show_tabs> - <show_border>True</show_border> - <tab_pos>GTK_POS_TOP</tab_pos> - <scrollable>False</scrollable> - <tab_hborder>2</tab_hborder> - <tab_vborder>2</tab_vborder> - <popup_enable>False</popup_enable> - - <widget> - <class>GtkVBox</class> - <name>vbox51</name> - <border_width>4</border_width> - <homogeneous>False</homogeneous> - <spacing>6</spacing> - - <widget> - <class>GtkTable</class> - <name>table11</name> - <rows>1</rows> - <columns>2</columns> - <homogeneous>False</homogeneous> - <row_spacing>4</row_spacing> - <column_spacing>4</column_spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label56</name> - <label>Su_mmary:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>7.45058e-09</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <default_focus_target>general-summary</default_focus_target> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>general-summary</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - </widget> - - <widget> - <class>GtkFrame</class> - <name>frame31</name> - <label>Date & Time</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkTable</class> - <name>table12</name> - <border_width>4</border_width> - <rows>2</rows> - <columns>3</columns> - <homogeneous>False</homogeneous> - <row_spacing>4</row_spacing> - <column_spacing>4</column_spacing> - - <widget> - <class>GtkLabel</class> - <name>label57</name> - <label>_Start time:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label58</name> - <label>_End time:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkCheckButton</class> - <name>all-day-event</name> - <can_focus>True</can_focus> - <label>A_ll day event</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <child> - <left_attach>2</left_attach> - <right_attach>3</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>Custom</class> - <name>start-time</name> - <creation_function>make_date_edit</creation_function> - <string1></string1> - <string2></string2> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Tue, 16 May 2000 19:11:05 GMT</last_modification_time> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>True</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>False</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>Custom</class> - <name>end-time</name> - <creation_function>make_date_edit</creation_function> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Tue, 16 May 2000 19:11:10 GMT</last_modification_time> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>True</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>False</xfill> - <yfill>True</yfill> - </child> - </widget> - </widget> - </widget> - - <widget> - <class>GtkScrolledWindow</class> - <name>scrolledwindow12</name> - <hscrollbar_policy>GTK_POLICY_NEVER</hscrollbar_policy> - <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy> - <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy> - <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkText</class> - <name>description</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text></text> - </widget> - </widget> - - <widget> - <class>GtkFrame</class> - <name>frame32</name> - <label>Classification</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkHBox</class> - <name>hbox52</name> - <border_width>2</border_width> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - - <widget> - <class>GtkRadioButton</class> - <name>classification-public</name> - <can_focus>True</can_focus> - <label>Pu_blic</label> - <active>True</active> - <draw_indicator>True</draw_indicator> - <group>classification_radio_group</group> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkRadioButton</class> - <name>classification-private</name> - <can_focus>True</can_focus> - <label>Pri_vate</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <group>classification_radio_group</group> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkRadioButton</class> - <name>classification-confidential</name> - <can_focus>True</can_focus> - <label>_Confidential</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <group>classification_radio_group</group> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> - </widget> - - <widget> - <class>GtkHBox</class> - <name>hbox53</name> - <homogeneous>False</homogeneous> - <spacing>2</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkButton</class> - <name>contacts-button</name> - <can_focus>True</can_focus> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label59</name> - <label>_Contacts...</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>4</xpad> - <ypad>0</ypad> - </widget> - </widget> - - <widget> - <class>GtkEntry</class> - <name>contacts</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - </widget> - - <widget> - <class>GtkButton</class> - <name>categories-button</name> - <can_focus>True</can_focus> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label60</name> - <label>Ca_tegories...</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>4</xpad> - <ypad>0</ypad> - </widget> - </widget> - - <widget> - <class>GtkEntry</class> - <name>categories</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - </widget> - </widget> - </widget> - - <widget> - <class>GtkLabel</class> - <child_name>Notebook:tab</child_name> - <name>label61</name> - <label>Appointment</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - - <widget> - <class>GtkVBox</class> - <name>vbox52</name> - <border_width>4</border_width> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - - <widget> - <class>GtkFrame</class> - <name>frame33</name> - <label>Appointment Basics</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkTable</class> - <name>table13</name> - <border_width>4</border_width> - <rows>2</rows> - <columns>2</columns> - <homogeneous>False</homogeneous> - <row_spacing>2</row_spacing> - <column_spacing>2</column_spacing> - - <widget> - <class>GtkLabel</class> - <name>label62</name> - <label>Su_mmary:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <default_focus_target>reminder-summary</default_focus_target> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label63</name> - <label>_Starting date:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>reminder-summary</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>True</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkAlignment</class> - <name>reminder-starting-data</name> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xscale>0</xscale> - <yscale>0</yscale> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>Custom</class> - <name>reminder-starting-date</name> - <creation_function>make_date_edit</creation_function> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Fri, 22 Sep 2000 20:51:38 GMT</last_modification_time> - </widget> - </widget> - </widget> - </widget> - - <widget> - <class>GtkFrame</class> - <name>frame34</name> - <label>Reminders</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkVBox</class> - <name>vbox53</name> - <border_width>4</border_width> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - - <widget> - <class>GtkHBox</class> - <name>hbox54</name> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkOptionMenu</class> - <name>reminder-action</name> - <can_focus>True</can_focus> - <items>Show a dialog -Play a sound -Send an email -Run a program -</items> - <initial_choice>0</initial_choice> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkSpinButton</class> - <name>reminder-interval-value</name> - <can_focus>True</can_focus> - <climb_rate>1</climb_rate> - <digits>0</digits> - <numeric>True</numeric> - <update_policy>GTK_UPDATE_ALWAYS</update_policy> - <snap>False</snap> - <wrap>False</wrap> - <value>1</value> - <lower>0</lower> - <upper>100</upper> - <step>1</step> - <page>10</page> - <page_size>10</page_size> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - </widget> - - <widget> - <class>GtkOptionMenu</class> - <name>reminder-value-units</name> - <can_focus>True</can_focus> - <items>minute(s) -hour(s) -day(s) -</items> - <initial_choice>0</initial_choice> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkOptionMenu</class> - <name>reminder-relative</name> - <can_focus>True</can_focus> - <items>before -after -</items> - <initial_choice>0</initial_choice> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkOptionMenu</class> - <name>reminder-time</name> - <can_focus>True</can_focus> - <items>start of appointment -end of appointment -</items> - <initial_choice>0</initial_choice> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkButton</class> - <name>button9</name> - <can_focus>True</can_focus> - <label>Settings...</label> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> - - <widget> - <class>GtkHBox</class> - <name>hbox55</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkScrolledWindow</class> - <name>scrolledwindow13</name> - <hscrollbar_policy>GTK_POLICY_NEVER</hscrollbar_policy> - <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy> - <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy> - <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkCList</class> - <name>reminder-list</name> - <can_focus>True</can_focus> - <columns>1</columns> - <column_widths>80</column_widths> - <selection_mode>GTK_SELECTION_BROWSE</selection_mode> - <show_titles>False</show_titles> - <shadow_type>GTK_SHADOW_IN</shadow_type> - - <widget> - <class>GtkLabel</class> - <child_name>CList:title</child_name> - <name>label64</name> - <label>label55</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - </widget> - </widget> - - <widget> - <class>GtkVButtonBox</class> - <name>vbuttonbox2</name> - <layout_style>GTK_BUTTONBOX_START</layout_style> - <spacing>10</spacing> - <child_min_width>85</child_min_width> - <child_min_height>27</child_min_height> - <child_ipad_x>7</child_ipad_x> - <child_ipad_y>0</child_ipad_y> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkButton</class> - <name>reminder-add</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <label>Add</label> - </widget> - - <widget> - <class>GtkButton</class> - <name>reminder-delete</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <label>Delete</label> - </widget> - </widget> - </widget> - </widget> - </widget> - </widget> - - <widget> - <class>GtkLabel</class> - <child_name>Notebook:tab</child_name> - <name>label65</name> - <label>Reminder</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - - <widget> - <class>GtkVBox</class> - <name>vbox54</name> - <border_width>4</border_width> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - - <widget> - <class>GtkFrame</class> - <name>frame35</name> - <label>Appointment Basics</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkTable</class> - <name>table14</name> - <border_width>4</border_width> - <rows>2</rows> - <columns>2</columns> - <homogeneous>False</homogeneous> - <row_spacing>2</row_spacing> - <column_spacing>2</column_spacing> - - <widget> - <class>GtkLabel</class> - <name>label66</name> - <label>Su_mmary:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <default_focus_target>recurrence-summary</default_focus_target> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label67</name> - <label>_Starting date:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>recurrence-summary</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>True</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkAlignment</class> - <name>alignment40</name> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xscale>0</xscale> - <yscale>0</yscale> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>Custom</class> - <name>recurrence-starting-date</name> - <creation_function>make_date_edit</creation_function> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Fri, 22 Sep 2000 20:51:38 GMT</last_modification_time> - </widget> - </widget> - </widget> - </widget> - - <widget> - <class>GtkVBox</class> - <name>vbox55</name> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkFrame</class> - <name>frame36</name> - <label>Recurrence Rule</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkVBox</class> - <name>vbox56</name> - <border_width>4</border_width> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - - <widget> - <class>GtkHBox</class> - <name>hbox56</name> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkRadioButton</class> - <name>recurrence-none</name> - <can_focus>True</can_focus> - <label>No recurrence</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <group>recurrence-radio</group> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkRadioButton</class> - <name>recurrence-simple</name> - <can_focus>True</can_focus> - <label>Simple recurrence</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <group>recurrence-radio</group> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkRadioButton</class> - <name>recurrence-custom</name> - <can_focus>True</can_focus> - <label>Custom recurrence</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <group>recurrence-radio</group> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> - - <widget> - <class>GtkHBox</class> - <name>hbox57</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkHBox</class> - <name>recurrence-params</name> - <homogeneous>False</homogeneous> - <spacing>2</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label68</name> - <label>Every</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkSpinButton</class> - <name>recurrence-interval-value</name> - <can_focus>True</can_focus> - <climb_rate>1</climb_rate> - <digits>0</digits> - <numeric>True</numeric> - <update_policy>GTK_UPDATE_ALWAYS</update_policy> - <snap>False</snap> - <wrap>False</wrap> - <value>1</value> - <lower>1</lower> - <upper>10000</upper> - <step>1</step> - <page>10</page> - <page_size>10</page_size> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkOptionMenu</class> - <name>recurrence-interval-unit</name> - <can_focus>True</can_focus> - <items>day(s) -week(s) -month(s) -year(s) -</items> - <initial_choice>0</initial_choice> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkAlignment</class> - <name>recurrence-special</name> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xscale>0</xscale> - <yscale>0</yscale> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>Placeholder</class> - </widget> - </widget> - - <widget> - <class>GtkOptionMenu</class> - <name>recurrence-ending-menu</name> - <can_focus>True</can_focus> - <items>for -until -forever -</items> - <initial_choice>0</initial_choice> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkAlignment</class> - <name>recurrence-ending-special</name> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xscale>0</xscale> - <yscale>0</yscale> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>Placeholder</class> - </widget> - </widget> - </widget> - - <widget> - <class>GtkAlignment</class> - <name>recurrence-custom-warning-bin</name> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xscale>1</xscale> - <yscale>1</yscale> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>Placeholder</class> - </widget> - </widget> - </widget> - </widget> - </widget> - - <widget> - <class>GtkHBox</class> - <name>hbox59</name> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkFrame</class> - <name>frame37</name> - <label>Exceptions</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkHBox</class> - <name>hbox60</name> - <border_width>4</border_width> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - - <widget> - <class>GtkVBox</class> - <name>vbox57</name> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkButton</class> - <name>recurrence-exception-add</name> - <can_focus>True</can_focus> - <label>Add</label> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkButton</class> - <name>recurrence-exception-modify</name> - <can_focus>True</can_focus> - <label>Modify</label> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkButton</class> - <name>recurrence-exception-delete</name> - <can_focus>True</can_focus> - <label>Delete</label> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> - - <widget> - <class>GtkVBox</class> - <name>vbox58</name> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>Custom</class> - <name>recurrence-exception-date</name> - <creation_function>make_date_edit</creation_function> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Tue, 16 May 2000 01:42:29 GMT</last_modification_time> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkScrolledWindow</class> - <name>scrolledwindow14</name> - <hscrollbar_policy>GTK_POLICY_NEVER</hscrollbar_policy> - <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy> - <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy> - <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkCList</class> - <name>recurrence-exception-list</name> - <can_focus>True</can_focus> - <columns>1</columns> - <column_widths>80</column_widths> - <selection_mode>GTK_SELECTION_BROWSE</selection_mode> - <show_titles>False</show_titles> - <shadow_type>GTK_SHADOW_IN</shadow_type> - - <widget> - <class>GtkLabel</class> - <child_name>CList:title</child_name> - <name>label69</name> - <label>label21</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - </widget> - </widget> - </widget> - </widget> - </widget> - - <widget> - <class>GtkVBox</class> - <name>vbox59</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label70</name> - <label>Preview</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkAlignment</class> - <name>recurrence-preview-bin</name> - <xalign>0</xalign> - <yalign>0</yalign> - <xscale>1</xscale> - <yscale>1</yscale> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>Placeholder</class> - </widget> - </widget> - </widget> - </widget> - </widget> - </widget> - - <widget> - <class>GtkLabel</class> - <child_name>Notebook:tab</child_name> - <name>label71</name> - <label>Recurrence</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - </widget> -</widget> - -</GTK-Interface> diff --git a/calendar/gui/event-editor.c b/calendar/gui/event-editor.c deleted file mode 100644 index 47ef3efa6e..0000000000 --- a/calendar/gui/event-editor.c +++ /dev/null @@ -1,3318 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* Evolution calendar - Event editor dialog - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: Miguel de Icaza <miguel@ximian.com> - * Federico Mena-Quintero <federico@ximian.com> - * Seth Alves <alves@hungry.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#include <config.h> -#include <glade/glade.h> -#include <e-util/e-dialog-widgets.h> -#include <widgets/misc/e-dateedit.h> -#include <gal/widgets/e-unicode.h> -#include <gal/widgets/e-categories.h> -#include <cal-util/timeutil.h> -#include "dialogs/delete-comp.h" -#include "dialogs/save-comp.h" -#include "calendar-config.h" -#include "event-editor.h" -#include "e-meeting-edit.h" -#include "calendar-config.h" -#include "tag-calendar.h" -#include "weekday-picker.h" -#include "widget-util.h" - - -enum {BEFORE, AFTER}; -enum {MINUTES, HOURS, DAYS}; - -/* Reminder maps */ -static const int reminder_action_map[] = { - CAL_ALARM_DISPLAY, - CAL_ALARM_AUDIO, - CAL_ALARM_EMAIL, - CAL_ALARM_PROCEDURE, - -1 -}; - -static const int reminder_value_map[] = { - MINUTES, - HOURS, - DAYS, - -1 -}; - -static const int reminder_relative_map[] = { - BEFORE, - AFTER, - -1 -}; - -static const int reminder_time_map[] = { - CAL_ALARM_TRIGGER_RELATIVE_START, - CAL_ALARM_TRIGGER_RELATIVE_END, - -1 -}; - -/* Recurrence maps */ -static const int recur_freq_map[] = { - ICAL_DAILY_RECURRENCE, - ICAL_WEEKLY_RECURRENCE, - ICAL_MONTHLY_RECURRENCE, - ICAL_YEARLY_RECURRENCE, - -1 -}; - -enum month_day_options { - MONTH_DAY_NTH, - MONTH_DAY_MON, - MONTH_DAY_TUE, - MONTH_DAY_WED, - MONTH_DAY_THU, - MONTH_DAY_FRI, - MONTH_DAY_SAT, - MONTH_DAY_SUN -}; - -static const int month_day_options_map[] = { - MONTH_DAY_NTH, - MONTH_DAY_MON, - MONTH_DAY_TUE, - MONTH_DAY_WED, - MONTH_DAY_THU, - MONTH_DAY_FRI, - MONTH_DAY_SAT, - MONTH_DAY_SUN, - -1 -}; - -/* Row data for the reminders */ -typedef enum {NEW_ALARM, EXISTING_ALARM} ReminderStatus; - -typedef struct { - ReminderStatus status; - CalComponentAlarm *alarm; -} ReminderData; - -struct _EventEditorPrivate { - /* Glade XML data */ - GladeXML *xml; - - /* Client to use */ - CalClient *client; - - /* Calendar object/uid we are editing; this is an internal copy */ - CalComponent *comp; - - /* Widgets from the Glade file */ - - GtkWidget *app; - - GtkWidget *general_summary; - - GtkWidget *start_time; - GtkWidget *end_time; - GtkWidget *all_day_event; - - GtkWidget *description; - - GtkWidget *classification_public; - GtkWidget *classification_private; - GtkWidget *classification_confidential; - - GtkWidget *categories; - GtkWidget *categories_btn; - - GtkWidget *reminder_summary; - GtkWidget *reminder_starting_date; - - GtkWidget *reminder_list; - GtkWidget *reminder_add; - GtkWidget *reminder_delete; - - GtkWidget *reminder_action; - GtkWidget *reminder_interval_value; - GtkWidget *reminder_value_units; - GtkWidget *reminder_relative; - GtkWidget *reminder_time; - - GtkWidget *recurrence_summary; - GtkWidget *recurrence_starting_date; - - GtkWidget *recurrence_none; - GtkWidget *recurrence_simple; - GtkWidget *recurrence_custom; - - GtkWidget *recurrence_params; - GtkWidget *recurrence_interval_value; - GtkWidget *recurrence_interval_unit; - GtkWidget *recurrence_special; - GtkWidget *recurrence_ending_menu; - GtkWidget *recurrence_ending_special; - GtkWidget *recurrence_custom_warning_bin; - - /* For weekly recurrences, created by hand */ - GtkWidget *recurrence_weekday_picker; - guint8 recurrence_weekday_day_mask; - guint8 recurrence_weekday_blocked_day_mask; - - /* For monthly recurrences, created by hand */ - GtkWidget *recurrence_month_index_spin; - int recurrence_month_index; - - GtkWidget *recurrence_month_day_menu; - enum month_day_options recurrence_month_day; - - /* For ending date, created by hand */ - GtkWidget *recurrence_ending_date_edit; - time_t recurrence_ending_date; - - /* For ending count of occurrences, created by hand */ - GtkWidget *recurrence_ending_count_spin; - int recurrence_ending_count; - - /* More widgets from the Glade file */ - - GtkWidget *recurrence_exception_date; - GtkWidget *recurrence_exception_list; - GtkWidget *recurrence_exception_add; - GtkWidget *recurrence_exception_modify; - GtkWidget *recurrence_exception_delete; - - GtkWidget *recurrence_preview_bin; - - /* For the recurrence preview, the actual widget */ - GtkWidget *recurrence_preview_calendar; - - /* Call event_editor_set_changed() to set this to TRUE when any field - in the dialog is changed. When the user closes the dialog we will - prompt to save changes. */ - gboolean changed; -}; - - - -static void event_editor_class_init (EventEditorClass *class); -static void event_editor_init (EventEditor *ee); -static void event_editor_destroy (GtkObject *object); - -static GtkObjectClass *parent_class; - - -static void append_reminder (EventEditor *ee, CalComponentAlarm *alarm, ReminderStatus status); -static void append_exception (EventEditor *ee, time_t t); -static void check_all_day (EventEditor *ee); -static void set_all_day (GtkWidget *toggle, EventEditor *ee); -static void date_changed_cb (EDateEdit *dedit, gpointer data); -static void preview_recur (EventEditor *ee); -static void recur_to_comp_object (EventEditor *ee, CalComponent *comp); -static void reminder_to_comp_object (EventEditor *ee, CalComponent *comp); -static void reminder_add_cb (GtkWidget *widget, EventEditor *ee); -static void reminder_delete_cb (GtkWidget *widget, EventEditor *ee); -static void recurrence_exception_add_cb (GtkWidget *widget, EventEditor *ee); -static void recurrence_exception_modify_cb (GtkWidget *widget, EventEditor *ee); -static void recurrence_exception_delete_cb (GtkWidget *widget, EventEditor *ee); -static void field_changed (GtkWidget *widget, - EventEditor *ee); -static void event_editor_set_changed (EventEditor *ee, - gboolean changed); -static gboolean prompt_to_save_changes (EventEditor *ee); -static void categories_clicked (GtkWidget *button, EventEditor *ee); - - - -/** - * event_editor_get_type: - * - * Registers the #EventEditor class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the #EventEditor class. - **/ -GtkType -event_editor_get_type (void) -{ - static GtkType event_editor_type = 0; - - if (!event_editor_type) { - static const GtkTypeInfo event_editor_info = { - "EventEditor", - sizeof (EventEditor), - sizeof (EventEditorClass), - (GtkClassInitFunc) event_editor_class_init, - (GtkObjectInitFunc) event_editor_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - event_editor_type = gtk_type_unique (GTK_TYPE_OBJECT, &event_editor_info); - } - - return event_editor_type; -} - -/* Class initialization function for the event editor */ -static void -event_editor_class_init (EventEditorClass *class) -{ - GtkObjectClass *object_class; - - object_class = (GtkObjectClass *) class; - - parent_class = gtk_type_class (GTK_TYPE_OBJECT); - - object_class->destroy = event_editor_destroy; -} - -/* Object initialization function for the event editor */ -static void -event_editor_init (EventEditor *ee) -{ - EventEditorPrivate *priv; - - priv = g_new0 (EventEditorPrivate, 1); - ee->priv = priv; - - event_editor_set_changed (ee, FALSE); -} - -/* Frees the rows and the row data in the recurrence exceptions GtkCList */ -static void -free_exception_clist_data (GtkCList *clist) -{ - int i; - - for (i = 0; i < clist->rows; i++) { - gpointer data; - - data = gtk_clist_get_row_data (clist, i); - g_free (data); - gtk_clist_set_row_data (clist, i, NULL); - } - - gtk_clist_clear (clist); -} - -/* Destroy handler for the event editor */ -static void -event_editor_destroy (GtkObject *object) -{ - EventEditor *ee; - EventEditorPrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_EVENT_EDITOR (object)); - - ee = EVENT_EDITOR (object); - priv = ee->priv; - - free_exception_clist_data (GTK_CLIST (priv->recurrence_exception_list)); - - if (priv->app) { - gtk_signal_disconnect_by_data (GTK_OBJECT (priv->app), ee); - gtk_widget_destroy (priv->app); - priv->app = NULL; - } - - if (priv->comp) { - gtk_object_unref (GTK_OBJECT (priv->comp)); - priv->comp = NULL; - } - - if (priv->client) { - gtk_signal_disconnect_by_data (GTK_OBJECT (priv->client), ee); - gtk_object_unref (GTK_OBJECT (priv->client)); - priv->client = NULL; - } - - if (priv->xml) { - gtk_object_unref (GTK_OBJECT (priv->xml)); - priv->xml = NULL; - } - - g_free (priv); - ee->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - -/* Creates an appropriate title for the event editor dialog */ -static char * -make_title_from_comp (CalComponent *comp) -{ - const char *summary; - CalComponentVType type; - CalComponentText text; - - if (!comp) - return g_strdup (_("Edit Appointment")); - - cal_component_get_summary (comp, &text); - if (text.value) - summary = text.value; - else - summary = _("No summary"); - - - type = cal_component_get_vtype (comp); - switch (type) { - case CAL_COMPONENT_EVENT: - return g_strdup_printf (_("Appointment - %s"), summary); - - case CAL_COMPONENT_TODO: - return g_strdup_printf (_("Task - %s"), summary); - - case CAL_COMPONENT_JOURNAL: - return g_strdup_printf (_("Journal entry - %s"), summary); - - default: - g_message ("make_title_from_comp(): Cannot handle object of type %d", type); - return NULL; - } -} - -/* Sets the event editor's window title from a calendar component */ -static void -set_title_from_comp (EventEditor *ee, CalComponent *comp) -{ - EventEditorPrivate *priv; - char *title, *tmp; - - priv = ee->priv; - - title = make_title_from_comp (comp); - tmp = e_utf8_to_gtk_string (priv->app, title); - g_free (title); - - if (tmp) { - gtk_window_set_title (GTK_WINDOW (priv->app), tmp); - g_free (tmp); - } else { - g_message ("set_title_from_comp(): Could not convert the title from UTF8"); - gtk_window_set_title (GTK_WINDOW (priv->app), ""); - } -} - -/* Callback used when the recurrence weekday picker changes */ -static void -recur_weekday_picker_changed_cb (WeekdayPicker *wp, gpointer data) -{ - EventEditor *ee; - - ee = EVENT_EDITOR (data); - event_editor_set_changed (ee, TRUE); - preview_recur (ee); -} - -/* Creates the special contents for weekly recurrences */ -static void -make_recur_weekly_special (EventEditor *ee) -{ - EventEditorPrivate *priv; - GtkWidget *hbox; - GtkWidget *label; - WeekdayPicker *wp; - - priv = ee->priv; - - g_assert (GTK_BIN (priv->recurrence_special)->child == NULL); - g_assert (priv->recurrence_weekday_picker == NULL); - - /* Create the widgets */ - - hbox = gtk_hbox_new (FALSE, 2); - gtk_container_add (GTK_CONTAINER (priv->recurrence_special), hbox); - - label = gtk_label_new (_("on")); - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); - - wp = WEEKDAY_PICKER (weekday_picker_new ()); - - priv->recurrence_weekday_picker = GTK_WIDGET (wp); - gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (wp), FALSE, FALSE, 0); - - gtk_widget_show_all (hbox); - - /* Set the weekdays */ - - weekday_picker_set_week_start_day (wp, calendar_config_get_week_start_day ()); - weekday_picker_set_days (wp, priv->recurrence_weekday_day_mask); - weekday_picker_set_blocked_days (wp, priv->recurrence_weekday_blocked_day_mask); - - gtk_signal_connect (GTK_OBJECT (wp), "changed", - GTK_SIGNAL_FUNC (recur_weekday_picker_changed_cb), ee); -} - -/* Creates the option menu for the monthly recurrence days */ -static GtkWidget * -make_recur_month_menu (void) -{ - static const char *options[] = { - N_("day"), - N_("Monday"), - N_("Tuesday"), - N_("Wednesday"), - N_("Thursday"), - N_("Friday"), - N_("Saturday"), - N_("Sunday") - }; - - GtkWidget *menu; - GtkWidget *omenu; - int i; - - menu = gtk_menu_new (); - - for (i = 0; i < sizeof (options) / sizeof (options[0]); i++) { - GtkWidget *item; - - item = gtk_menu_item_new_with_label (_(options[i])); - gtk_menu_append (GTK_MENU (menu), item); - gtk_widget_show (item); - } - - omenu = gtk_option_menu_new (); - gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu); - - return omenu; -} - -/* For monthly recurrences, changes the valid range of the recurrence day index - * spin button; e.g. month days are 1-31 while the valid range for a Sunday is - * the 1st through 5th of the month. - */ -static void -adjust_day_index_spin (EventEditor *ee) -{ - EventEditorPrivate *priv; - GtkAdjustment *adj; - enum month_day_options month_day; - - priv = ee->priv; - - g_assert (priv->recurrence_month_day_menu != NULL); - g_assert (GTK_IS_OPTION_MENU (priv->recurrence_month_day_menu)); - g_assert (priv->recurrence_month_index_spin != NULL); - g_assert (GTK_IS_SPIN_BUTTON (priv->recurrence_month_index_spin)); - - month_day = e_dialog_option_menu_get (priv->recurrence_month_day_menu, month_day_options_map); - - adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->recurrence_month_index_spin)); - - switch (month_day) { - case MONTH_DAY_NTH: - adj->upper = 31; - gtk_adjustment_changed (adj); - break; - - case MONTH_DAY_MON: - case MONTH_DAY_TUE: - case MONTH_DAY_WED: - case MONTH_DAY_THU: - case MONTH_DAY_FRI: - case MONTH_DAY_SAT: - case MONTH_DAY_SUN: - adj->upper = 5; - gtk_adjustment_changed (adj); - - if (adj->value > 5) { - adj->value = 5; - gtk_adjustment_value_changed (adj); - } - - break; - - default: - g_assert_not_reached (); - } -} - -/* Callback used when the monthly day selection menu changes. We need to change - * the valid range of the day index spin button; e.g. days are 1-31 while a - * Sunday is the 1st through 5th. - */ -static void -month_day_menu_selection_done_cb (GtkMenuShell *menu_shell, gpointer data) -{ - EventEditor *ee; - - ee = EVENT_EDITOR (data); - adjust_day_index_spin (ee); - event_editor_set_changed (ee, TRUE); - preview_recur (ee); -} - -/* Callback used when the month index value changes. */ -static void -recur_month_index_value_changed_cb (GtkAdjustment *adj, gpointer data) -{ - EventEditor *ee; - - ee = EVENT_EDITOR (data); - event_editor_set_changed (ee, TRUE); - preview_recur (ee); -} - -/* Creates the special contents for monthly recurrences */ -static void -make_recur_monthly_special (EventEditor *ee) -{ - EventEditorPrivate *priv; - GtkWidget *hbox; - GtkWidget *label; - GtkAdjustment *adj; - GtkWidget *menu; - - priv = ee->priv; - - g_assert (GTK_BIN (priv->recurrence_special)->child == NULL); - g_assert (priv->recurrence_month_index_spin == NULL); - g_assert (priv->recurrence_month_day_menu == NULL); - - /* Create the widgets */ - - hbox = gtk_hbox_new (FALSE, 2); - gtk_container_add (GTK_CONTAINER (priv->recurrence_special), hbox); - - label = gtk_label_new (_("on the")); - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); - - adj = GTK_ADJUSTMENT (gtk_adjustment_new (1, 1, 31, 1, 10, 10)); - priv->recurrence_month_index_spin = gtk_spin_button_new (adj, 1, 0); - gtk_box_pack_start (GTK_BOX (hbox), priv->recurrence_month_index_spin, FALSE, FALSE, 0); - - label = gtk_label_new (_("th")); - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); - - priv->recurrence_month_day_menu = make_recur_month_menu (); - gtk_box_pack_start (GTK_BOX (hbox), priv->recurrence_month_day_menu, FALSE, FALSE, 0); - - gtk_widget_show_all (hbox); - - /* Set the options */ - - e_dialog_spin_set (priv->recurrence_month_index_spin, priv->recurrence_month_index); - e_dialog_option_menu_set (priv->recurrence_month_day_menu, - priv->recurrence_month_day, - month_day_options_map); - adjust_day_index_spin (ee); - - gtk_signal_connect (GTK_OBJECT (adj), "value_changed", - GTK_SIGNAL_FUNC (recur_month_index_value_changed_cb), ee); - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->recurrence_month_day_menu)); - gtk_signal_connect (GTK_OBJECT (menu), "selection_done", - GTK_SIGNAL_FUNC (month_day_menu_selection_done_cb), ee); -} - -/* Changes the recurrence-special widget to match the interval units. - * - * For daily recurrences: nothing. - * For weekly recurrences: weekday selector. - * For monthly recurrences: "on the" <nth> [day, Weekday] - * For yearly recurrences: nothing. - */ -static void -make_recurrence_special (EventEditor *ee) -{ - EventEditorPrivate *priv; - icalrecurrencetype_frequency frequency; - - priv = ee->priv; - - if (GTK_BIN (priv->recurrence_special)->child != NULL) { - gtk_widget_destroy (GTK_BIN (priv->recurrence_special)->child); - - priv->recurrence_weekday_picker = NULL; - priv->recurrence_month_index_spin = NULL; - priv->recurrence_month_day_menu = NULL; - } - - frequency = e_dialog_option_menu_get (priv->recurrence_interval_unit, recur_freq_map); - - switch (frequency) { - case ICAL_DAILY_RECURRENCE: - gtk_widget_hide (priv->recurrence_special); - break; - - case ICAL_WEEKLY_RECURRENCE: - make_recur_weekly_special (ee); - gtk_widget_show (priv->recurrence_special); - break; - - case ICAL_MONTHLY_RECURRENCE: - make_recur_monthly_special (ee); - gtk_widget_show (priv->recurrence_special); - break; - - case ICAL_YEARLY_RECURRENCE: - gtk_widget_hide (priv->recurrence_special); - break; - - default: - g_assert_not_reached (); - } -} - -/* Callback used when the ending-until date editor changes */ -static void -recur_ending_until_changed_cb (EDateEdit *de, gpointer data) -{ - EventEditor *ee; - - ee = EVENT_EDITOR (data); - event_editor_set_changed (ee, TRUE); - preview_recur (ee); -} - -/* Creates the special contents for "ending until" (end date) recurrences */ -static void -make_recur_ending_until_special (EventEditor *ee) -{ - EventEditorPrivate *priv; - EDateEdit *de; - - priv = ee->priv; - - g_assert (GTK_BIN (priv->recurrence_ending_special)->child == NULL); - g_assert (priv->recurrence_ending_date_edit == NULL); - - /* Create the widget */ - - priv->recurrence_ending_date_edit = date_edit_new (TRUE, FALSE); - de = E_DATE_EDIT (priv->recurrence_ending_date_edit); - - gtk_container_add (GTK_CONTAINER (priv->recurrence_ending_special), GTK_WIDGET (de)); - gtk_widget_show_all (GTK_WIDGET (de)); - - /* Set the value */ - - e_date_edit_set_time (de, priv->recurrence_ending_date); - - gtk_signal_connect (GTK_OBJECT (de), "changed", - GTK_SIGNAL_FUNC (recur_ending_until_changed_cb), ee); -} - -/* Callback used when the ending-count value changes */ -static void -recur_ending_count_value_changed_cb (GtkAdjustment *adj, gpointer data) -{ - EventEditor *ee; - - ee = EVENT_EDITOR (data); - event_editor_set_changed (ee, TRUE); - preview_recur (ee); -} - -/* Creates the special contents for the occurrence count case */ -static void -make_recur_ending_count_special (EventEditor *ee) -{ - EventEditorPrivate *priv; - GtkWidget *hbox; - GtkWidget *label; - GtkAdjustment *adj; - - priv = ee->priv; - - g_assert (GTK_BIN (priv->recurrence_ending_special)->child == NULL); - g_assert (priv->recurrence_ending_count_spin == NULL); - - /* Create the widgets */ - - hbox = gtk_hbox_new (FALSE, 2); - gtk_container_add (GTK_CONTAINER (priv->recurrence_ending_special), hbox); - - adj = GTK_ADJUSTMENT (gtk_adjustment_new (1, 1, 10000, 1, 10, 10)); - priv->recurrence_ending_count_spin = gtk_spin_button_new (adj, 1, 0); - gtk_box_pack_start (GTK_BOX (hbox), priv->recurrence_ending_count_spin, FALSE, FALSE, 0); - - label = gtk_label_new (_("occurrences")); - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); - - gtk_widget_show_all (hbox); - - /* Set the values */ - - e_dialog_spin_set (priv->recurrence_ending_count_spin, - priv->recurrence_ending_count); - - gtk_signal_connect (GTK_OBJECT (adj), "value_changed", - GTK_SIGNAL_FUNC (recur_ending_count_value_changed_cb), ee); -} - -enum ending_type { - ENDING_FOR, - ENDING_UNTIL, - ENDING_FOREVER -}; - -static const int ending_types_map[] = { - ENDING_FOR, - ENDING_UNTIL, - ENDING_FOREVER, - -1 -}; - -/* Changes the recurrence-ending-special widget to match the ending date option. - * - * For: <n> [days, weeks, months, years, occurrences] - * Until: <date selector> - * Forever: nothing. - */ -static void -make_recurrence_ending_special (EventEditor *ee) -{ - EventEditorPrivate *priv; - enum ending_type ending_type; - - priv = ee->priv; - - if (GTK_BIN (priv->recurrence_ending_special)->child != NULL) { - gtk_widget_destroy (GTK_BIN (priv->recurrence_ending_special)->child); - - priv->recurrence_ending_date_edit = NULL; - priv->recurrence_ending_count_spin = NULL; - } - - ending_type = e_dialog_option_menu_get (priv->recurrence_ending_menu, ending_types_map); - - switch (ending_type) { - case ENDING_FOR: - make_recur_ending_count_special (ee); - gtk_widget_show (priv->recurrence_ending_special); - break; - - case ENDING_UNTIL: - make_recur_ending_until_special (ee); - gtk_widget_show (priv->recurrence_ending_special); - break; - - case ENDING_FOREVER: - gtk_widget_hide (priv->recurrence_ending_special); - break; - - default: - g_assert_not_reached (); - } -} - -enum recur_type { - RECUR_NONE, - RECUR_SIMPLE, - RECUR_CUSTOM -}; - -static const int recur_type_map[] = { - RECUR_NONE, - RECUR_SIMPLE, - RECUR_CUSTOM, - -1 -}; - -/* Sensitizes the recurrence widgets based on the state of the recurrence type - * radio group. - */ -static void -sensitize_recur_widgets (EventEditor *ee) -{ - EventEditorPrivate *priv; - enum recur_type type; - GtkWidget *label; - - priv = ee->priv; - - type = e_dialog_radio_get (priv->recurrence_none, recur_type_map); - - if (GTK_BIN (priv->recurrence_custom_warning_bin)->child) - gtk_widget_destroy (GTK_BIN (priv->recurrence_custom_warning_bin)->child); - - switch (type) { - case RECUR_NONE: - gtk_widget_set_sensitive (priv->recurrence_params, FALSE); - gtk_widget_show (priv->recurrence_params); - gtk_widget_hide (priv->recurrence_custom_warning_bin); - break; - - case RECUR_SIMPLE: - gtk_widget_set_sensitive (priv->recurrence_params, TRUE); - gtk_widget_show (priv->recurrence_params); - gtk_widget_hide (priv->recurrence_custom_warning_bin); - break; - - case RECUR_CUSTOM: - gtk_widget_set_sensitive (priv->recurrence_params, FALSE); - gtk_widget_hide (priv->recurrence_params); - - label = gtk_label_new (_("This appointment contains recurrences that Evolution " - "cannot edit.")); - gtk_container_add (GTK_CONTAINER (priv->recurrence_custom_warning_bin), label); - gtk_widget_show_all (priv->recurrence_custom_warning_bin); - break; - - default: - g_assert_not_reached (); - } -} - -/* Callback used when one of the recurrence type radio buttons is toggled. We - * enable or the recurrence parameters. - */ -static void -recurrence_type_toggled_cb (GtkToggleButton *toggle, gpointer data) -{ - EventEditor *ee; - - ee = EVENT_EDITOR (data); - - event_editor_set_changed (ee, TRUE); - - if (toggle->active) { - sensitize_recur_widgets (ee); - preview_recur (ee); - } -} - -/* Callback used when the recurrence interval value spin button changes. */ -static void -recur_interval_value_changed_cb (GtkAdjustment *adj, gpointer data) -{ - EventEditor *ee; - - ee = EVENT_EDITOR (data); - event_editor_set_changed (ee, TRUE); - preview_recur (ee); -} - -/* Callback used when the recurrence interval option menu changes. We need to - * change the contents of the recurrence special widget. - */ -static void -recur_interval_selection_done_cb (GtkMenuShell *menu_shell, gpointer data) -{ - EventEditor *ee; - - ee = EVENT_EDITOR (data); - event_editor_set_changed (ee, TRUE); - make_recurrence_special (ee); - preview_recur (ee); -} - -/* Callback used when the recurrence ending option menu changes. We need to - * change the contents of the ending special widget. - */ -static void -recur_ending_selection_done_cb (GtkMenuShell *menu_shell, gpointer data) -{ - EventEditor *ee; - - ee = EVENT_EDITOR (data); - event_editor_set_changed (ee, TRUE); - make_recurrence_ending_special (ee); - preview_recur (ee); -} - -/* Gets the widgets from the XML file and returns if they are all available. - * For the widgets whose values can be simply set with e-dialog-utils, it does - * that as well. - */ -static gboolean -get_widgets (EventEditor *ee) -{ - EventEditorPrivate *priv; - - priv = ee->priv; - -#define GW(name) glade_xml_get_widget (priv->xml, name) - - priv->app = GW ("event-editor-dialog"); - - priv->general_summary = GW ("general-summary"); - - priv->start_time = GW ("start-time"); - priv->end_time = GW ("end-time"); - priv->all_day_event = GW ("all-day-event"); - - priv->description = GW ("description"); - - priv->classification_public = GW ("classification-public"); - priv->classification_private = GW ("classification-private"); - priv->classification_confidential = GW ("classification-confidential"); - - priv->categories = GW ("categories"); - priv->categories_btn = GW ("categories-button"); - - priv->reminder_summary = GW ("reminder-summary"); - priv->reminder_starting_date = GW ("reminder-starting-date"); - - priv->reminder_list = GW ("reminder-list"); - priv->reminder_add = GW ("reminder-add"); - priv->reminder_delete = GW ("reminder-delete"); - - priv->reminder_action = GW ("reminder-action"); - priv->reminder_interval_value = GW ("reminder-interval-value"); - priv->reminder_value_units = GW ("reminder-value-units"); - priv->reminder_relative = GW ("reminder-relative"); - priv->reminder_time = GW ("reminder-time"); - - priv->recurrence_summary = GW ("recurrence-summary"); - priv->recurrence_starting_date = GW ("recurrence-starting-date"); - - priv->recurrence_none = GW ("recurrence-none"); - priv->recurrence_simple = GW ("recurrence-simple"); - priv->recurrence_custom = GW ("recurrence-custom"); - priv->recurrence_params = GW ("recurrence-params"); - - priv->recurrence_interval_value = GW ("recurrence-interval-value"); - priv->recurrence_interval_unit = GW ("recurrence-interval-unit"); - priv->recurrence_special = GW ("recurrence-special"); - priv->recurrence_ending_menu = GW ("recurrence-ending-menu"); - priv->recurrence_ending_special = GW ("recurrence-ending-special"); - priv->recurrence_custom_warning_bin = GW ("recurrence-custom-warning-bin"); - - priv->recurrence_exception_date = GW ("recurrence-exception-date"); - priv->recurrence_exception_list = GW ("recurrence-exception-list"); - priv->recurrence_exception_add = GW ("recurrence-exception-add"); - priv->recurrence_exception_modify = GW ("recurrence-exception-modify"); - priv->recurrence_exception_delete = GW ("recurrence-exception-delete"); - - priv->recurrence_preview_bin = GW ("recurrence-preview-bin"); - -#undef GW - - return (priv->app - && priv->general_summary - && priv->start_time - && priv->end_time - && priv->all_day_event - && priv->description - && priv->classification_public - && priv->classification_private - && priv->classification_confidential - && priv->reminder_summary - && priv->reminder_starting_date - && priv->reminder_list - && priv->reminder_add - && priv->reminder_delete - && priv->reminder_action - && priv->reminder_interval_value - && priv->reminder_value_units - && priv->reminder_relative - && priv->reminder_time - && priv->recurrence_summary - && priv->recurrence_starting_date - && priv->recurrence_none - && priv->recurrence_simple - && priv->recurrence_custom - && priv->recurrence_params - && priv->recurrence_interval_value - && priv->recurrence_interval_unit - && priv->recurrence_special - && priv->recurrence_ending_menu - && priv->recurrence_ending_special - && priv->recurrence_custom_warning_bin - && priv->recurrence_exception_date - && priv->recurrence_exception_list - && priv->recurrence_exception_add - && priv->recurrence_exception_modify - && priv->recurrence_exception_delete - && priv->recurrence_preview_bin); -} - -/* Syncs the contents of two entry widgets, while blocking signals from each - * other. - */ -static void -sync_entries (EventEditor *ee, GtkEditable *source, GtkEditable *dest) -{ - char *str; - - gtk_signal_handler_block_by_data (GTK_OBJECT (dest), ee); - - str = gtk_editable_get_chars (source, 0, -1); - gtk_entry_set_text (GTK_ENTRY (dest), str); - g_free (str); - - gtk_signal_handler_unblock_by_data (GTK_OBJECT (dest), ee); -} - -/* Syncs the contents of two date editor widgets, while blocking signals on the - * specified data. - */ -static void -sync_date_edits (EventEditor *ee, EDateEdit *source, EDateEdit *dest) -{ - time_t t; - - gtk_signal_handler_block_by_data (GTK_OBJECT (dest), ee); - - t = e_date_edit_get_time (source); - e_date_edit_set_time (dest, t); - - gtk_signal_handler_unblock_by_data (GTK_OBJECT (dest), ee); -} - -/* Callback used when one of the general or recurrence summary entries change; - * we sync the other entry to it. - */ -static void -summary_changed_cb (GtkEditable *editable, gpointer data) -{ - EventEditor *ee; - EventEditorPrivate *priv; - - ee = EVENT_EDITOR (data); - priv = ee->priv; - - if (editable != GTK_EDITABLE (priv->general_summary)) - sync_entries (ee, editable, GTK_EDITABLE (priv->general_summary)); - if (editable != GTK_EDITABLE (priv->reminder_summary)) - sync_entries (ee, editable, GTK_EDITABLE (priv->reminder_summary)); - if (editable != GTK_EDITABLE (priv->recurrence_summary)) - sync_entries (ee, editable, GTK_EDITABLE (priv->recurrence_summary)); -} - -/* Callback used when one of the general or recurrence starting date widgets - * change; we sync the other date editor to it. - */ -static void -start_date_changed_cb (EDateEdit *de, gpointer data) -{ - EventEditor *ee; - EventEditorPrivate *priv; - - ee = EVENT_EDITOR (data); - priv = ee->priv; - - if (de != E_DATE_EDIT (priv->start_time)) - sync_date_edits (ee,de, E_DATE_EDIT (priv->start_time)); - if (de != E_DATE_EDIT (priv->reminder_starting_date)) - sync_date_edits (ee, de, E_DATE_EDIT (priv->reminder_starting_date)); - if (de != E_DATE_EDIT (priv->recurrence_starting_date)) - sync_date_edits (ee, de, E_DATE_EDIT (priv->recurrence_starting_date)); -} - -/* Callback used when the displayed date range in the recurrence preview - * calendar changes. - */ -static void -recur_preview_date_range_changed_cb (ECalendarItem *item, gpointer data) -{ - EventEditor *ee; - - ee = EVENT_EDITOR (data); - preview_recur (ee); -} - -/* Hooks the widget signals */ -static void -init_widgets (EventEditor *ee) -{ - EventEditorPrivate *priv; - GtkWidget *menu; - GtkAdjustment *adj; - ECalendar *ecal; - - priv = ee->priv; - - /* Summary in the main, reminder and recurrence pages */ - gtk_signal_connect (GTK_OBJECT (priv->general_summary), "changed", - GTK_SIGNAL_FUNC (summary_changed_cb), ee); - gtk_signal_connect (GTK_OBJECT (priv->reminder_summary), "changed", - GTK_SIGNAL_FUNC (summary_changed_cb), ee); - gtk_signal_connect (GTK_OBJECT (priv->recurrence_summary), "changed", - GTK_SIGNAL_FUNC (summary_changed_cb), ee); - - /* Categories button */ - gtk_signal_connect (GTK_OBJECT (priv->categories_btn), "clicked", - GTK_SIGNAL_FUNC (categories_clicked), ee); - - /* Start dates in the main and recurrence pages */ - - gtk_signal_connect (GTK_OBJECT (priv->start_time), "changed", - GTK_SIGNAL_FUNC (start_date_changed_cb), ee); - gtk_signal_connect (GTK_OBJECT (priv->reminder_starting_date), "changed", - GTK_SIGNAL_FUNC (start_date_changed_cb), ee); - gtk_signal_connect (GTK_OBJECT (priv->recurrence_starting_date), "changed", - GTK_SIGNAL_FUNC (start_date_changed_cb), ee); - - /* Start and end times */ - - gtk_signal_connect (GTK_OBJECT (priv->start_time), "changed", - GTK_SIGNAL_FUNC (date_changed_cb), ee); - gtk_signal_connect (GTK_OBJECT (priv->end_time), "changed", - GTK_SIGNAL_FUNC (date_changed_cb), ee); - - gtk_signal_connect (GTK_OBJECT (priv->all_day_event), "toggled", - GTK_SIGNAL_FUNC (set_all_day), ee); - - /* Reminder buttons */ - - gtk_signal_connect (GTK_OBJECT (priv->reminder_add), "clicked", - GTK_SIGNAL_FUNC (reminder_add_cb), ee); - gtk_signal_connect (GTK_OBJECT (priv->reminder_delete), "clicked", - GTK_SIGNAL_FUNC (reminder_delete_cb), ee); - - /* Recurrence preview */ - - priv->recurrence_preview_calendar = e_calendar_new (); - ecal = E_CALENDAR (priv->recurrence_preview_calendar); - gtk_signal_connect (GTK_OBJECT (ecal->calitem), "date_range_changed", - GTK_SIGNAL_FUNC (recur_preview_date_range_changed_cb), ee); - calendar_config_configure_e_calendar (ecal); - e_calendar_item_set_max_days_sel (ecal->calitem, 0); - gtk_container_add (GTK_CONTAINER (priv->recurrence_preview_bin), - priv->recurrence_preview_calendar); - gtk_widget_show (priv->recurrence_preview_calendar); - - /* Recurrence types */ - - gtk_signal_connect (GTK_OBJECT (priv->recurrence_none), "toggled", - GTK_SIGNAL_FUNC (recurrence_type_toggled_cb), ee); - gtk_signal_connect (GTK_OBJECT (priv->recurrence_simple), "toggled", - GTK_SIGNAL_FUNC (recurrence_type_toggled_cb), ee); - gtk_signal_connect (GTK_OBJECT (priv->recurrence_custom), "toggled", - GTK_SIGNAL_FUNC (recurrence_type_toggled_cb), ee); - - /* Recurrence interval */ - - adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->recurrence_interval_value)); - gtk_signal_connect (GTK_OBJECT (adj), "value_changed", - GTK_SIGNAL_FUNC (recur_interval_value_changed_cb), ee); - - /* Recurrence units */ - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->recurrence_interval_unit)); - gtk_signal_connect (GTK_OBJECT (menu), "selection_done", - GTK_SIGNAL_FUNC (recur_interval_selection_done_cb), ee); - - /* Recurrence ending */ - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->recurrence_ending_menu)); - gtk_signal_connect (GTK_OBJECT (menu), "selection_done", - GTK_SIGNAL_FUNC (recur_ending_selection_done_cb), ee); - - /* Exception buttons */ - - gtk_signal_connect (GTK_OBJECT (priv->recurrence_exception_add), "clicked", - GTK_SIGNAL_FUNC (recurrence_exception_add_cb), ee); - gtk_signal_connect (GTK_OBJECT (priv->recurrence_exception_modify), "clicked", - GTK_SIGNAL_FUNC (recurrence_exception_modify_cb), ee); - gtk_signal_connect (GTK_OBJECT (priv->recurrence_exception_delete), "clicked", - GTK_SIGNAL_FUNC (recurrence_exception_delete_cb), ee); - - - /* - * Connect the default signal handler to use to make sure the "changed" - * field gets set whenever a field is changed. - */ - - /* Appointment Page */ - gtk_signal_connect (GTK_OBJECT (priv->general_summary), "changed", - GTK_SIGNAL_FUNC (field_changed), ee); - gtk_signal_connect (GTK_OBJECT (priv->description), "changed", - GTK_SIGNAL_FUNC (field_changed), ee); - gtk_signal_connect (GTK_OBJECT (priv->classification_public), - "toggled", - GTK_SIGNAL_FUNC (field_changed), ee); - gtk_signal_connect (GTK_OBJECT (priv->classification_private), - "toggled", - GTK_SIGNAL_FUNC (field_changed), ee); - gtk_signal_connect (GTK_OBJECT (priv->classification_confidential), - "toggled", - GTK_SIGNAL_FUNC (field_changed), ee); - - - /* Recurrence Page. */ -} - -static const int classification_map[] = { - CAL_COMPONENT_CLASS_PUBLIC, - CAL_COMPONENT_CLASS_PRIVATE, - CAL_COMPONENT_CLASS_CONFIDENTIAL, - -1 -}; - -static const int month_pos_map[] = { 0, 1, 2, 3, 4, -1 }; -static const int weekday_map[] = { 0, 1, 2, 3, 4, 5, 6, -1 }; - -/* Fills the widgets with default values */ -static void -clear_widgets (EventEditor *ee) -{ - EventEditorPrivate *priv; - time_t now; - GtkAdjustment *adj; - GtkWidget *menu; - - priv = ee->priv; - - now = time (NULL); - - /* Summary, description */ - - e_dialog_editable_set (priv->general_summary, NULL); /* will also change recur summary */ - e_dialog_editable_set (priv->description, NULL); - - /* Start and end times */ - - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_time), ee); - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->end_time), ee); - - e_date_edit_set_time (E_DATE_EDIT (priv->start_time), now); /* will set recur start too */ - e_date_edit_set_time (E_DATE_EDIT (priv->end_time), now); - - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->start_time), ee); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->end_time), ee); - - check_all_day (ee); - - /* Classification */ - - e_dialog_radio_set (priv->classification_public, - CAL_COMPONENT_CLASS_PRIVATE, classification_map); - - /* Recurrences */ - - priv->recurrence_weekday_day_mask = 0; - - priv->recurrence_month_index = 1; - priv->recurrence_month_day = MONTH_DAY_NTH; - - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->recurrence_none), ee); - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->recurrence_simple), ee); - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->recurrence_custom), ee); - e_dialog_radio_set (priv->recurrence_none, RECUR_NONE, recur_type_map); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->recurrence_none), ee); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->recurrence_simple), ee); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->recurrence_custom), ee); - - adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->recurrence_interval_value)); - gtk_signal_handler_block_by_data (GTK_OBJECT (adj), ee); - e_dialog_spin_set (priv->recurrence_interval_value, 1); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (adj), ee); - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->recurrence_interval_unit)); - gtk_signal_handler_block_by_data (GTK_OBJECT (menu), ee); - e_dialog_option_menu_set (priv->recurrence_interval_unit, ICAL_DAILY_RECURRENCE, - recur_freq_map); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), ee); - - priv->recurrence_ending_date = time (NULL); - priv->recurrence_ending_count = 1; - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->recurrence_ending_menu)); - gtk_signal_handler_block_by_data (GTK_OBJECT (menu), ee); - e_dialog_option_menu_set (priv->recurrence_ending_menu, ENDING_FOREVER, - ending_types_map); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), ee); - - /* Exceptions list */ - - free_exception_clist_data (GTK_CLIST (priv->recurrence_exception_list)); -} - -/* Fills the recurrence ending date widgets with the values from the calendar - * component. - */ -static void -fill_ending_date (EventEditor *ee, struct icalrecurrencetype *r) -{ - EventEditorPrivate *priv; - GtkWidget *menu; - - priv = ee->priv; - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->recurrence_ending_menu)); - gtk_signal_handler_block_by_data (GTK_OBJECT (menu), ee); - - if (r->count == 0) { - if (r->until.year == 0) { - /* Forever */ - - e_dialog_option_menu_set (priv->recurrence_ending_menu, - ENDING_FOREVER, - ending_types_map); - } else { - /* Ending date */ - - priv->recurrence_ending_date = icaltime_as_timet (r->until); - e_dialog_option_menu_set (priv->recurrence_ending_menu, - ENDING_UNTIL, - ending_types_map); - } - } else { - /* Count of occurrences */ - - priv->recurrence_ending_count = r->count; - e_dialog_option_menu_set (priv->recurrence_ending_menu, - ENDING_FOR, - ending_types_map); - } - - gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), ee); - - make_recurrence_ending_special (ee); -} - -/* Counts the number of elements in the by_xxx fields of an icalrecurrencetype */ -static int -count_by_xxx (short *field, int max_elements) -{ - int i; - - for (i = 0; i < max_elements; i++) - if (field[i] == ICAL_RECURRENCE_ARRAY_MAX) - break; - - return i; -} - -/* Re-tags the recurrence preview calendar based on the current information of - * the event editor. - */ -static void -preview_recur (EventEditor *ee) -{ - EventEditorPrivate *priv; - CalComponent *comp; - CalComponentDateTime cdt; - GSList *l; - - priv = ee->priv; - g_assert (priv->comp != NULL); - - /* Create a scratch component with the start/end and - * recurrence/excepttion information from the one we are editing. - */ - - comp = cal_component_new (); - cal_component_set_new_vtype (comp, CAL_COMPONENT_EVENT); - - cal_component_get_dtstart (priv->comp, &cdt); - cal_component_set_dtstart (comp, &cdt); - cal_component_free_datetime (&cdt); - - cal_component_get_dtend (priv->comp, &cdt); - cal_component_set_dtend (comp, &cdt); - cal_component_free_datetime (&cdt); - - cal_component_get_exdate_list (priv->comp, &l); - cal_component_set_exdate_list (comp, l); - cal_component_free_exdate_list (l); - - cal_component_get_exrule_list (priv->comp, &l); - cal_component_set_exrule_list (comp, l); - cal_component_free_recur_list (l); - - cal_component_get_rdate_list (priv->comp, &l); - cal_component_set_rdate_list (comp, l); - cal_component_free_period_list (l); - - cal_component_get_rrule_list (priv->comp, &l); - cal_component_set_rrule_list (comp, l); - cal_component_free_recur_list (l); - - recur_to_comp_object (ee, comp); - - tag_calendar_by_comp (E_CALENDAR (priv->recurrence_preview_calendar), comp); - gtk_object_unref (GTK_OBJECT (comp)); -} - -/* Fills in the exception widgets with the data from the calendar component */ -static void -fill_exception_widgets (EventEditor *ee) -{ - EventEditorPrivate *priv; - GSList *list, *l; - - priv = ee->priv; - g_assert (priv->comp != NULL); - - /* Exceptions list */ - - cal_component_get_exdate_list (priv->comp, &list); - - for (l = list; l; l = l->next) { - CalComponentDateTime *cdt; - time_t ext; - - cdt = l->data; - ext = icaltime_as_timet (*cdt->value); - append_exception (ee, ext); - } - - cal_component_free_exdate_list (list); -} - -/* Computes a weekday mask for the start day of a calendar component, for use in - * a WeekdayPicker widget. - */ -static guint8 -get_start_weekday_mask (CalComponent *comp) -{ - CalComponentDateTime dt; - guint8 retval; - - cal_component_get_dtstart (comp, &dt); - - if (dt.value) { - time_t t; - struct tm tm; - - t = icaltime_as_timet (*dt.value); - tm = *localtime (&t); - - retval = 0x1 << tm.tm_wday; - } else - retval = 0; - - cal_component_free_datetime (&dt); - - return retval; -} - -/* Sets some sane defaults for the data sources for the recurrence special - * widgets, even if they will not be used immediately. - */ -static void -set_recur_special_defaults (EventEditor *ee) -{ - EventEditorPrivate *priv; - guint8 mask; - - priv = ee->priv; - - mask = get_start_weekday_mask (priv->comp); - - priv->recurrence_weekday_day_mask = mask; - priv->recurrence_weekday_blocked_day_mask = mask; -} - -static char * -get_alarm_duration_string (struct icaldurationtype *duration) -{ - GString *string = g_string_new (NULL); - char *ret; - - if (duration->days > 1) - g_string_sprintf (string, _(" %d days"), duration->days); - else if (duration->days == 1) - g_string_append (string, _(" 1 day")); - - if (duration->weeks > 1) - g_string_sprintf (string, _(" %d weeks"), duration->weeks); - else if (duration->weeks == 1) - g_string_append (string, _(" 1 week")); - - if (duration->hours > 1) - g_string_sprintf (string, _(" %d hours"), duration->hours); - else if (duration->hours == 1) - g_string_append (string, _(" 1 hour")); - - if (duration->minutes > 1) - g_string_sprintf (string, _(" %d minutes"), duration->minutes); - else if (duration->minutes == 1) - g_string_append (string, _(" 1 minute")); - - if (duration->seconds > 1) - g_string_sprintf (string, _(" %d seconds"), duration->seconds); - else if (duration->seconds == 1) - g_string_append (string, _(" 1 second")); - - ret = string->str; - g_string_free (string, FALSE); - - return ret; -} - -static char * -get_alarm_string (CalComponentAlarm *alarm) -{ - CalAlarmAction action; - CalAlarmTrigger trigger; - char string[256]; - char *dur; - - string [0] = '\0'; - - cal_component_alarm_get_action (alarm, &action); - cal_component_alarm_get_trigger (alarm, &trigger); - - switch (action) { - case CAL_ALARM_AUDIO: - strcat (string, _("Play a sound")); - break; - case CAL_ALARM_DISPLAY: - strcat (string, _("Show a dialog")); - break; - case CAL_ALARM_EMAIL: - strcat (string, _("Send an email")); - break; - case CAL_ALARM_PROCEDURE: - strcat (string, _("Run a program")); - break; - case CAL_ALARM_NONE: - case CAL_ALARM_UNKNOWN: - strcat (string, _("Unknown")); - break; - } - - switch (trigger.type) { - case CAL_ALARM_TRIGGER_RELATIVE_START: - dur = get_alarm_duration_string (&trigger.u.rel_duration); - strcat (string, dur); - g_free (dur); - - if (trigger.u.rel_duration.is_neg) - strcat (string, _(" before start of appointment")); - else - strcat (string, _(" after start of appointment")); - break; - case CAL_ALARM_TRIGGER_RELATIVE_END: - dur = get_alarm_duration_string (&trigger.u.rel_duration); - strcat (string, dur); - g_free (dur); - - if (trigger.u.rel_duration.is_neg) - strcat (string, _(" before end of appointment")); - else - strcat (string, _(" after end of appointment")); - break; - case CAL_ALARM_TRIGGER_NONE: - case CAL_ALARM_TRIGGER_ABSOLUTE: - strcat (string, _("Unknown")); - break; - } - - return g_strdup (string); -} - -static void -fill_reminder_widgets (EventEditor *ee) -{ - EventEditorPrivate *priv; - GList *alarms, *l; - GtkCList *clist; - - int row = 0; - - priv = ee->priv; - g_assert (priv->comp != NULL); - - if (!cal_component_has_alarms (priv->comp)) - return; - - alarms = cal_component_get_alarm_uids (priv->comp); - - clist = GTK_CLIST (priv->reminder_list); - for (l = alarms; l != NULL; l = l->next, row++) { - CalComponentAlarm *ca = cal_component_get_alarm (priv->comp, l->data); - - /* Add it to the clist */ - append_reminder (ee, ca, EXISTING_ALARM); - } - cal_component_free_alarm_uids (alarms); -} - -/* Fills in the recurrence widgets with the values from the calendar component. - * This function is particularly tricky because it has to discriminate between - * recurrences we support for editing and the ones we don't. We only support at - * most one recurrence rule; no rdates or exrules (exdates are handled just fine - * elsewhere). - */ -static void -fill_recurrence_widgets (EventEditor *ee) -{ - EventEditorPrivate *priv; - GSList *rrule_list; - int len; - struct icalrecurrencetype *r; - int n_by_second, n_by_minute, n_by_hour; - int n_by_day, n_by_month_day, n_by_year_day; - int n_by_week_no, n_by_month, n_by_set_pos; - GtkWidget *menu; - GtkAdjustment *adj; - - priv = ee->priv; - g_assert (priv->comp != NULL); - - fill_exception_widgets (ee); - - /* Set up defaults for the special widgets */ - - set_recur_special_defaults (ee); - - /* No recurrences? */ - - if (!cal_component_has_rdates (priv->comp) - && !cal_component_has_rrules (priv->comp) - && !cal_component_has_exrules (priv->comp)) { - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->recurrence_none), ee); - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->recurrence_simple), ee); - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->recurrence_custom), ee); - e_dialog_radio_set (priv->recurrence_none, RECUR_NONE, recur_type_map); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->recurrence_none), ee); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->recurrence_simple), ee); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->recurrence_custom), ee); - - gtk_widget_set_sensitive (priv->recurrence_custom, FALSE); - - sensitize_recur_widgets (ee); - preview_recur (ee); - return; - } - - /* See if it is a custom set we don't support */ - - cal_component_get_rrule_list (priv->comp, &rrule_list); - len = g_slist_length (rrule_list); - if (len > 1 - || cal_component_has_rdates (priv->comp) - || cal_component_has_exrules (priv->comp)) - goto custom; - - /* Down to one rule, so test that one */ - - g_assert (len == 1); - r = rrule_list->data; - - /* Any funky frequency? */ - - if (r->freq == ICAL_SECONDLY_RECURRENCE - || r->freq == ICAL_MINUTELY_RECURRENCE - || r->freq == ICAL_HOURLY_RECURRENCE) - goto custom; - - /* Any funky shit? */ - -#define N_HAS_BY(field) (count_by_xxx (field, sizeof (field) / sizeof (field[0]))) - - n_by_second = N_HAS_BY (r->by_second); - n_by_minute = N_HAS_BY (r->by_minute); - n_by_hour = N_HAS_BY (r->by_hour); - n_by_day = N_HAS_BY (r->by_day); - n_by_month_day = N_HAS_BY (r->by_month_day); - n_by_year_day = N_HAS_BY (r->by_year_day); - n_by_week_no = N_HAS_BY (r->by_week_no); - n_by_month = N_HAS_BY (r->by_month); - n_by_set_pos = N_HAS_BY (r->by_set_pos); - - if (n_by_second != 0 - || n_by_minute != 0 - || n_by_hour != 0) - goto custom; - - /* Filter the funky shit based on the frequency; if there is nothing - * weird we can actually set the widgets. - */ - - switch (r->freq) { - case ICAL_DAILY_RECURRENCE: - if (n_by_day != 0 - || n_by_month_day != 0 - || n_by_year_day != 0 - || n_by_week_no != 0 - || n_by_month != 0 - || n_by_set_pos != 0) - goto custom; - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->recurrence_interval_unit)); - gtk_signal_handler_block_by_data (GTK_OBJECT (menu), ee); - e_dialog_option_menu_set (priv->recurrence_interval_unit, ICAL_DAILY_RECURRENCE, - recur_freq_map); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), ee); - break; - - case ICAL_WEEKLY_RECURRENCE: { - int i; - guint8 day_mask; - - if (n_by_month_day != 0 - || n_by_year_day != 0 - || n_by_week_no != 0 - || n_by_month != 0 - || n_by_set_pos != 0) - goto custom; - - day_mask = 0; - - for (i = 0; i < 8 && r->by_day[i] != ICAL_RECURRENCE_ARRAY_MAX; i++) { - enum icalrecurrencetype_weekday weekday; - int pos; - - weekday = icalrecurrencetype_day_day_of_week (r->by_day[i]); - pos = icalrecurrencetype_day_position (r->by_day[i]); - - if (pos != 0) - goto custom; - - switch (weekday) { - case ICAL_SUNDAY_WEEKDAY: - day_mask |= 1 << 0; - break; - - case ICAL_MONDAY_WEEKDAY: - day_mask |= 1 << 1; - break; - - case ICAL_TUESDAY_WEEKDAY: - day_mask |= 1 << 2; - break; - - case ICAL_WEDNESDAY_WEEKDAY: - day_mask |= 1 << 3; - break; - - case ICAL_THURSDAY_WEEKDAY: - day_mask |= 1 << 4; - break; - - case ICAL_FRIDAY_WEEKDAY: - day_mask |= 1 << 5; - break; - - case ICAL_SATURDAY_WEEKDAY: - day_mask |= 1 << 6; - break; - - default: - break; - } - } - - priv->recurrence_weekday_day_mask = day_mask; - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->recurrence_interval_unit)); - gtk_signal_handler_block_by_data (GTK_OBJECT (menu), ee); - e_dialog_option_menu_set (priv->recurrence_interval_unit, ICAL_WEEKLY_RECURRENCE, - recur_freq_map); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), ee); - break; - } - - case ICAL_MONTHLY_RECURRENCE: - if (n_by_year_day != 0 - || n_by_week_no != 0 - || n_by_month != 0 - || n_by_set_pos != 0) - goto custom; - - if (n_by_month_day == 1) { - int nth; - - nth = r->by_month_day[0]; - if (nth < 1) - goto custom; - - priv->recurrence_month_index = nth; - priv->recurrence_month_day = MONTH_DAY_NTH; - } else if (n_by_day == 1) { - enum icalrecurrencetype_weekday weekday; - int pos; - enum month_day_options month_day; - - weekday = icalrecurrencetype_day_day_of_week (r->by_day[0]); - pos = icalrecurrencetype_day_position (r->by_day[0]); - - if (pos < 1) - goto custom; - - switch (weekday) { - case ICAL_MONDAY_WEEKDAY: - month_day = MONTH_DAY_MON; - break; - - case ICAL_TUESDAY_WEEKDAY: - month_day = MONTH_DAY_TUE; - break; - - case ICAL_WEDNESDAY_WEEKDAY: - month_day = MONTH_DAY_WED; - break; - - case ICAL_THURSDAY_WEEKDAY: - month_day = MONTH_DAY_THU; - break; - - case ICAL_FRIDAY_WEEKDAY: - month_day = MONTH_DAY_FRI; - break; - - case ICAL_SATURDAY_WEEKDAY: - month_day = MONTH_DAY_SAT; - break; - - case ICAL_SUNDAY_WEEKDAY: - month_day = MONTH_DAY_SUN; - break; - - default: - goto custom; - } - - priv->recurrence_month_index = pos; - priv->recurrence_month_day = month_day; - } else - goto custom; - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->recurrence_interval_unit)); - gtk_signal_handler_block_by_data (GTK_OBJECT (menu), ee); - e_dialog_option_menu_set (priv->recurrence_interval_unit, ICAL_MONTHLY_RECURRENCE, - recur_freq_map); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), ee); - break; - - case ICAL_YEARLY_RECURRENCE: - if (n_by_day != 0 - || n_by_month_day != 0 - || n_by_year_day != 0 - || n_by_week_no != 0 - || n_by_month != 0 - || n_by_set_pos != 0) - goto custom; - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->recurrence_interval_unit)); - gtk_signal_handler_block_by_data (GTK_OBJECT (menu), ee); - e_dialog_option_menu_set (priv->recurrence_interval_unit, ICAL_YEARLY_RECURRENCE, - recur_freq_map); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), ee); - break; - - default: - goto custom; - } - - /* If we got here it means it is a simple recurrence */ - - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->recurrence_none), ee); - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->recurrence_simple), ee); - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->recurrence_custom), ee); - e_dialog_radio_set (priv->recurrence_simple, RECUR_SIMPLE, recur_type_map); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->recurrence_none), ee); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->recurrence_simple), ee); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->recurrence_custom), ee); - - gtk_widget_set_sensitive (priv->recurrence_custom, FALSE); - - sensitize_recur_widgets (ee); - make_recurrence_special (ee); - - adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->recurrence_interval_value)); - gtk_signal_handler_block_by_data (GTK_OBJECT (adj), ee); - e_dialog_spin_set (priv->recurrence_interval_value, r->interval); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (adj), ee); - - fill_ending_date (ee, r); - - goto out; - - custom: - - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->recurrence_none), ee); - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->recurrence_simple), ee); - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->recurrence_custom), ee); - e_dialog_radio_set (priv->recurrence_custom, RECUR_CUSTOM, recur_type_map); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->recurrence_none), ee); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->recurrence_simple), ee); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->recurrence_custom), ee); - - gtk_widget_set_sensitive (priv->recurrence_custom, TRUE); - sensitize_recur_widgets (ee); - - out: - - cal_component_free_recur_list (rrule_list); - preview_recur (ee); -} - -/* Fills in the widgets with the value from the calendar component */ -static void -fill_widgets (EventEditor *ee) -{ - EventEditorPrivate *priv; - CalComponentText text; - CalComponentClassification cl; - CalComponentDateTime d; - GSList *l; - time_t dtstart, dtend; - const char *categories; - - priv = ee->priv; - - clear_widgets (ee); - - if (!priv->comp) - return; - - /* Summary, description(s) */ - - cal_component_get_summary (priv->comp, &text); - e_dialog_editable_set (priv->general_summary, text.value); /* will also set recur summary */ - - cal_component_get_description_list (priv->comp, &l); - if (l) { - text = *(CalComponentText *)l->data; - e_dialog_editable_set (priv->description, text.value); - } - cal_component_free_text_list (l); - - /* Start and end times */ - - /* All-day events are inclusive, i.e. if the end date shown is 2nd Feb - then the event includes all of the 2nd Feb. We would normally show - 3rd Feb as the end date, since it really ends at midnight on 3rd, - so we have to subtract a day so we only show the 2nd. */ - cal_component_get_dtstart (priv->comp, &d); - dtstart = icaltime_as_timet (*d.value); - cal_component_free_datetime (&d); - - cal_component_get_dtend (priv->comp, &d); - dtend = icaltime_as_timet (*d.value); - cal_component_free_datetime (&d); - - if (time_day_begin (dtstart) == dtstart - && time_day_begin (dtend) == dtend) { - dtend = time_add_day (dtend, -1); - } - - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_time), ee); - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->end_time), ee); - - e_date_edit_set_time (E_DATE_EDIT (priv->start_time), dtstart); - e_date_edit_set_time (E_DATE_EDIT (priv->reminder_starting_date), dtstart); - e_date_edit_set_time (E_DATE_EDIT (priv->recurrence_starting_date), dtstart); - e_date_edit_set_time (E_DATE_EDIT (priv->end_time), dtend); - - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->start_time), ee); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->end_time), ee); - - check_all_day (ee); - - /* Classification */ - - cal_component_get_classification (priv->comp, &cl); - - switch (cl) { - case CAL_COMPONENT_CLASS_PUBLIC: - e_dialog_radio_set (priv->classification_public, CAL_COMPONENT_CLASS_PUBLIC, - classification_map); - case CAL_COMPONENT_CLASS_PRIVATE: - e_dialog_radio_set (priv->classification_public, CAL_COMPONENT_CLASS_PRIVATE, - classification_map); - case CAL_COMPONENT_CLASS_CONFIDENTIAL: - e_dialog_radio_set (priv->classification_public, CAL_COMPONENT_CLASS_CONFIDENTIAL, - classification_map); - default: - /* What do do? We can't g_assert_not_reached() since it is a - * value from an external file. - */ - } - - /* Categories */ - cal_component_get_categories (priv->comp, &categories); - e_dialog_editable_set (priv->categories, categories); - - /* Reminders */ - fill_reminder_widgets (ee); - - /* Recurrences */ - fill_recurrence_widgets (ee); - - /* Do this last, since the callbacks will set it to TRUE. */ - event_editor_set_changed (ee, FALSE); -} - - -/** - * event_editor_update_widgets: - * @ee: An event editor. - * - * Causes an event editor dialog to re-read the values of its calendar component - * object. This function should be used if the #CalComponent is changed by - * external means while it is open in the editor. - **/ -void -event_editor_update_widgets (EventEditor *ee) -{ - g_return_if_fail (ee != NULL); - g_return_if_fail (IS_EVENT_EDITOR (ee)); - - fill_widgets (ee); -} - - - -/* Decode the radio button group for classifications */ -static CalComponentClassification -classification_get (GtkWidget *widget) -{ - return e_dialog_radio_get (widget, classification_map); -} - -/* Encondes a position/weekday pair into the proper format for - * icalrecurrencetype.by_day. - */ -static short -nth_weekday (int pos, icalrecurrencetype_weekday weekday) -{ - g_assert (pos > 0 && pos <= 5); - - return (pos << 3) | (int) weekday; -} - -static void -reminder_to_comp_object (EventEditor *ee, CalComponent *comp) -{ - EventEditorPrivate *priv; - GtkCList *reminder_list; - ReminderData *rdata; - int i; - - priv = ee->priv; - - reminder_list = GTK_CLIST (priv->reminder_list); - for (i = 0; i < reminder_list->rows; i++) { - rdata = gtk_clist_get_row_data (reminder_list, i); - if (rdata->status == NEW_ALARM) - cal_component_add_alarm (priv->comp, rdata->alarm); - g_free (rdata); - } -} - -/* Gets the simple recurrence data from the recurrence widgets and stores it in - * the calendar component object. - */ -static void -simple_recur_to_comp_object (EventEditor *ee, CalComponent *comp) -{ - EventEditorPrivate *priv; - struct icalrecurrencetype r; - GSList l; - enum ending_type ending_type; - - priv = ee->priv; - - icalrecurrencetype_clear (&r); - - /* Frequency, interval, week start */ - - r.freq = e_dialog_option_menu_get (priv->recurrence_interval_unit, recur_freq_map); - r.interval = e_dialog_spin_get_int (priv->recurrence_interval_value); - r.week_start = ICAL_SUNDAY_WEEKDAY + calendar_config_get_week_start_day (); - - /* Frequency-specific data */ - - switch (r.freq) { - case ICAL_DAILY_RECURRENCE: - /* Nothing else is required */ - break; - - case ICAL_WEEKLY_RECURRENCE: { - guint8 day_mask; - int i; - - g_assert (GTK_BIN (priv->recurrence_special)->child != NULL); - g_assert (priv->recurrence_weekday_picker != NULL); - g_assert (IS_WEEKDAY_PICKER (priv->recurrence_weekday_picker)); - - day_mask = weekday_picker_get_days (WEEKDAY_PICKER (priv->recurrence_weekday_picker)); - - i = 0; - - if (day_mask & (1 << 0)) - r.by_day[i++] = ICAL_SUNDAY_WEEKDAY; - - if (day_mask & (1 << 1)) - r.by_day[i++] = ICAL_MONDAY_WEEKDAY; - - if (day_mask & (1 << 2)) - r.by_day[i++] = ICAL_TUESDAY_WEEKDAY; - - if (day_mask & (1 << 3)) - r.by_day[i++] = ICAL_WEDNESDAY_WEEKDAY; - - if (day_mask & (1 << 4)) - r.by_day[i++] = ICAL_THURSDAY_WEEKDAY; - - if (day_mask & (1 << 5)) - r.by_day[i++] = ICAL_FRIDAY_WEEKDAY; - - if (day_mask & (1 << 6)) - r.by_day[i++] = ICAL_SATURDAY_WEEKDAY; - - break; - } - - case ICAL_MONTHLY_RECURRENCE: { - int day_index; - enum month_day_options month_day; - - g_assert (GTK_BIN (priv->recurrence_special)->child != NULL); - g_assert (priv->recurrence_month_index_spin != NULL); - g_assert (GTK_IS_SPIN_BUTTON (priv->recurrence_month_index_spin)); - g_assert (priv->recurrence_month_day_menu != NULL); - g_assert (GTK_IS_OPTION_MENU (priv->recurrence_month_day_menu)); - - day_index = e_dialog_spin_get_int (priv->recurrence_month_index_spin); - month_day = e_dialog_option_menu_get (priv->recurrence_month_day_menu, - month_day_options_map); - - switch (month_day) { - case MONTH_DAY_NTH: - r.by_month_day[0] = day_index; - break; - - case MONTH_DAY_MON: - r.by_day[0] = nth_weekday (day_index, ICAL_MONDAY_WEEKDAY); - break; - - case MONTH_DAY_TUE: - r.by_day[0] = nth_weekday (day_index, ICAL_TUESDAY_WEEKDAY); - break; - - case MONTH_DAY_WED: - r.by_day[0] = nth_weekday (day_index, ICAL_WEDNESDAY_WEEKDAY); - break; - - case MONTH_DAY_THU: - r.by_day[0] = nth_weekday (day_index, ICAL_THURSDAY_WEEKDAY); - break; - - case MONTH_DAY_FRI: - r.by_day[0] = nth_weekday (day_index, ICAL_FRIDAY_WEEKDAY); - break; - - case MONTH_DAY_SAT: - r.by_day[0] = nth_weekday (day_index, ICAL_SATURDAY_WEEKDAY); - break; - - case MONTH_DAY_SUN: - r.by_day[0] = nth_weekday (day_index, ICAL_SUNDAY_WEEKDAY); - break; - - default: - g_assert_not_reached (); - } - - break; - } - - case ICAL_YEARLY_RECURRENCE: - /* Nothing else is required */ - break; - - default: - g_assert_not_reached (); - } - - /* Ending date */ - - ending_type = e_dialog_option_menu_get (priv->recurrence_ending_menu, ending_types_map); - - switch (ending_type) { - case ENDING_FOR: - g_assert (priv->recurrence_ending_count_spin != NULL); - g_assert (GTK_IS_SPIN_BUTTON (priv->recurrence_ending_count_spin)); - - r.count = e_dialog_spin_get_int (priv->recurrence_ending_count_spin); - break; - - case ENDING_UNTIL: - g_assert (priv->recurrence_ending_date_edit != NULL); - g_assert (E_IS_DATE_EDIT (priv->recurrence_ending_date_edit)); - - r.until = icaltime_from_timet ( - e_date_edit_get_time (E_DATE_EDIT (priv->recurrence_ending_date_edit)), - TRUE); - break; - - case ENDING_FOREVER: - /* Nothing to be done */ - break; - - default: - g_assert_not_reached (); - } - - /* Set the recurrence */ - - l.data = &r; - l.next = NULL; - - cal_component_set_rrule_list (comp, &l); -} - -/* Gets the data from the recurrence widgets and stores it in the calendar - * component object. - */ -static void -recur_to_comp_object (EventEditor *ee, CalComponent *comp) -{ - EventEditorPrivate *priv; - enum recur_type recur_type; - GtkCList *exception_list; - GSList *list; - int i; - - priv = ee->priv; - - recur_type = e_dialog_radio_get (priv->recurrence_none, recur_type_map); - - switch (recur_type) { - case RECUR_NONE: - cal_component_set_rdate_list (comp, NULL); - cal_component_set_rrule_list (comp, NULL); - cal_component_set_exrule_list (comp, NULL); - break; - - case RECUR_SIMPLE: - cal_component_set_rdate_list (comp, NULL); - cal_component_set_exrule_list (comp, NULL); - simple_recur_to_comp_object (ee, comp); - break; - - case RECUR_CUSTOM: - /* We just keep whatever the component has currently */ - break; - - default: - g_assert_not_reached (); - } - - /* Set exceptions */ - - list = NULL; - exception_list = GTK_CLIST (priv->recurrence_exception_list); - for (i = 0; i < exception_list->rows; i++) { - CalComponentDateTime *cdt; - time_t *tim; - - cdt = g_new (CalComponentDateTime, 1); - cdt->value = g_new (struct icaltimetype, 1); - cdt->tzid = NULL; - - tim = gtk_clist_get_row_data (exception_list, i); - *cdt->value = icaltime_from_timet (*tim, FALSE); - - list = g_slist_prepend (list, cdt); - } - - cal_component_set_exdate_list (comp, list); - cal_component_free_exdate_list (list); -} - -/* Gets the data from the widgets and stores it in the calendar component object */ -static void -dialog_to_comp_object (EventEditor *ee, CalComponent *comp) -{ - EventEditorPrivate *priv; - CalComponentDateTime date; - time_t t; - gboolean all_day_event; - char *cat, *str; - - priv = ee->priv; - - /* Summary */ - - str = e_dialog_editable_get (priv->general_summary); - if (!str || strlen (str) == 0) - cal_component_set_summary (comp, NULL); - else { - CalComponentText text; - - text.value = str; - text.altrep = NULL; - - cal_component_set_summary (comp, &text); - } - - if (str) - g_free (str); - - /* Description */ - - str = e_dialog_editable_get (priv->description); - if (!str || strlen (str) == 0) - cal_component_set_description_list (comp, NULL); - else { - GSList l; - CalComponentText text; - - text.value = str; - text.altrep = NULL; - l.data = &text; - l.next = NULL; - - cal_component_set_description_list (comp, &l); - } - - if (!str) - g_free (str); - - /* Dates */ - - date.value = g_new (struct icaltimetype, 1); - date.tzid = NULL; - - t = e_date_edit_get_time (E_DATE_EDIT (priv->start_time)); - if (t != -1) { - *date.value = icaltime_from_timet (t, FALSE); - cal_component_set_dtstart (comp, &date); - } else { - /* FIXME: What do we do here? */ - } - - /* If the all_day toggle is set, the end date is inclusive of the - entire day on which it points to. */ - all_day_event = e_dialog_toggle_get (priv->all_day_event); - t = e_date_edit_get_time (E_DATE_EDIT (priv->end_time)); - if (t != -1) { - if (all_day_event) - t = time_day_end (t); - - *date.value = icaltime_from_timet (t, FALSE); - cal_component_set_dtend (comp, &date); - } else { - /* FIXME: What do we do here? */ - } - g_free (date.value); - - /* Categories */ - cat = e_dialog_editable_get (priv->categories); - cal_component_set_categories (comp, cat); - - if (cat) - g_free (cat); - - cal_component_set_classification (comp, classification_get (priv->classification_public)); - - /* Reminder information */ - reminder_to_comp_object (ee, comp); - - /* Recurrence information */ - recur_to_comp_object (ee, comp); - - cal_component_commit_sequence (comp); -} - -/* Fills the calendar component object from the data in the widgets and commits - * the component to the storage. - */ -static void -save_event_object (EventEditor *ee) -{ - EventEditorPrivate *priv; - - priv = ee->priv; - - if (!priv->comp) - return; - - dialog_to_comp_object (ee, priv->comp); - set_title_from_comp (ee, priv->comp); - - if (!cal_client_update_object (priv->client, priv->comp)) - g_message ("save_event_object(): Could not update the object!"); - else - event_editor_set_changed (ee, FALSE); -} - -/* Closes the dialog box and emits the appropriate signals */ -static void -close_dialog (EventEditor *ee) -{ - EventEditorPrivate *priv; - - priv = ee->priv; - - g_assert (priv->app != NULL); - - gtk_object_destroy (GTK_OBJECT (ee)); -} - - - -/* Callback used when the dialog box is "applied" */ -static void -ee_apply_event_cb (GtkWidget *widget, gint page_num, gpointer data) -{ - EventEditor *ee; - - g_return_if_fail (IS_EVENT_EDITOR (data)); - - ee = EVENT_EDITOR (data); - - if (page_num != -1) - return; - - save_event_object (ee); -} - -/* Callback used when the dialog box is destroyed */ -static gint -ee_close_event_cb (GtkWidget *widget, gpointer data) -{ - EventEditor *ee; - - g_return_val_if_fail (IS_EVENT_EDITOR (data), TRUE); - - ee = EVENT_EDITOR (data); - - if (prompt_to_save_changes (ee)) - close_dialog (ee); - - return TRUE; -} - -/* Callback used when the dialog box is destroyed */ -static gint -ee_delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data) -{ - EventEditor *ee; - - g_return_val_if_fail (IS_EVENT_EDITOR (data), TRUE); - - ee = EVENT_EDITOR (data); - - if (prompt_to_save_changes (ee)) - close_dialog (ee); - - return TRUE; -} - -/** - * event_editor_construct: - * @ee: An event editor. - * - * Constructs an event editor by loading its Glade data. - * - * Return value: The same object as @ee, or NULL if the widgets could not be - * created. In the latter case, the event editor will automatically be - * destroyed. - **/ -EventEditor * -event_editor_construct (EventEditor *ee) -{ - EventEditorPrivate *priv; - - g_return_val_if_fail (ee != NULL, NULL); - g_return_val_if_fail (IS_EVENT_EDITOR (ee), NULL); - - priv = ee->priv; - - /* Load the content widgets */ - - priv->xml = glade_xml_new (EVOLUTION_GLADEDIR "/event-editor-dialog.glade", NULL); - if (!priv->xml) { - g_message ("event_editor_construct(): Could not load the Glade XML file!"); - goto error; - } - - if (!get_widgets (ee)) { - g_message ("event_editor_construct(): Could not find all widgets in the XML file!"); - goto error; - } - - init_widgets (ee); - - /* Hook to destruction of the dialog */ - gtk_signal_connect (GTK_OBJECT (priv->app), "apply", - GTK_SIGNAL_FUNC (ee_apply_event_cb), ee); - gtk_signal_connect (GTK_OBJECT (priv->app), "close", - GTK_SIGNAL_FUNC (ee_close_event_cb), ee); - gtk_signal_connect (GTK_OBJECT (priv->app), "delete_event", - GTK_SIGNAL_FUNC (ee_delete_event_cb), ee); - - /* Add focus to the summary entry */ - gtk_widget_grab_focus (GTK_WIDGET (priv->general_summary)); - - return ee; - - error: - - gtk_object_unref (GTK_OBJECT (ee)); - return NULL; -} - -/** - * event_editor_new: - * - * Creates a new event editor dialog. - * - * Return value: A newly-created event editor dialog, or NULL if the event - * editor could not be created. - **/ -EventEditor * -event_editor_new (void) -{ - EventEditor *ee; - - ee = EVENT_EDITOR (gtk_type_new (TYPE_EVENT_EDITOR)); - return event_editor_construct (EVENT_EDITOR (ee)); -} - -/* Brings attention to a window by raising it and giving it focus */ -static void -raise_and_focus (GtkWidget *widget) -{ - g_assert (GTK_WIDGET_REALIZED (widget)); - gdk_window_show (widget->window); - gtk_widget_grab_focus (widget); -} - -/* Callback used when the calendar client tells us that an object changed */ -static void -obj_updated_cb (CalClient *client, const char *uid, gpointer data) -{ - EventEditor *ee; - EventEditorPrivate *priv; - CalComponent *comp; - CalClientGetStatus status; - const gchar *editing_uid; - - ee = EVENT_EDITOR (data); - - g_return_if_fail (IS_EVENT_EDITOR (ee)); - - priv = ee->priv; - - /* If we aren't showing the object which has been updated, return. */ - if (!priv->comp) - return; - cal_component_get_uid (priv->comp, &editing_uid); - if (strcmp (uid, editing_uid)) - return; - - - /* Get the event from the server. */ - status = cal_client_get_object (priv->client, uid, &comp); - - switch (status) { - case CAL_CLIENT_GET_SUCCESS: - /* Everything is fine */ - break; - - case CAL_CLIENT_GET_SYNTAX_ERROR: - g_message ("obj_updated_cb(): Syntax error when 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; - } - - raise_and_focus (priv->app); -} - -/* Callback used when the calendar client tells us that an object was removed */ -static void -obj_removed_cb (CalClient *client, const char *uid, gpointer data) -{ - EventEditor *ee; - EventEditorPrivate *priv; - const gchar *editing_uid; - - ee = EVENT_EDITOR (data); - - g_return_if_fail (ee != NULL); - g_return_if_fail (IS_EVENT_EDITOR (ee)); - - priv = ee->priv; - - /* If we aren't showing the object which has been updated, return. */ - if (!priv->comp) - return; - cal_component_get_uid (priv->comp, &editing_uid); - if (strcmp (uid, editing_uid)) - return; - - - raise_and_focus (priv->app); -} - -/** - * event_editor_set_cal_client: - * @ee: An event editor. - * @client: Calendar client. - * - * Sets the calendar client than an event editor will use for updating its - * calendar components. - **/ -void -event_editor_set_cal_client (EventEditor *ee, CalClient *client) -{ - EventEditorPrivate *priv; - - g_return_if_fail (ee != NULL); - g_return_if_fail (IS_EVENT_EDITOR (ee)); - - priv = ee->priv; - - if (client == priv->client) - return; - - if (client) - g_return_if_fail (IS_CAL_CLIENT (client)); - - if (client) - g_return_if_fail (cal_client_get_load_state (client) == CAL_CLIENT_LOAD_LOADED); - - if (client) - gtk_object_ref (GTK_OBJECT (client)); - - if (priv->client) { - gtk_signal_disconnect_by_data (GTK_OBJECT (priv->client), ee); - gtk_object_unref (GTK_OBJECT (priv->client)); - } - - priv->client = client; - - if (priv->client) { - gtk_signal_connect (GTK_OBJECT (priv->client), "obj_updated", - GTK_SIGNAL_FUNC (obj_updated_cb), ee); - gtk_signal_connect (GTK_OBJECT (priv->client), "obj_removed", - GTK_SIGNAL_FUNC (obj_removed_cb), ee); - } -} - -/** - * event_editor_get_cal_client: - * @ee: An event editor. - * - * Queries the calendar client that an event editor is using to update its - * calendar components. - * - * Return value: A calendar client object. - **/ -CalClient * -event_editor_get_cal_client (EventEditor *ee) -{ - EventEditorPrivate *priv; - - g_return_val_if_fail (ee != NULL, NULL); - g_return_val_if_fail (IS_EVENT_EDITOR (ee), NULL); - - priv = ee->priv; - return priv->client; -} - -/** - * event_editor_set_event_object: - * @ee: An event editor. - * @comp: A calendar object. - * - * Sets the calendar object that an event editor dialog will manipulate. - **/ -void -event_editor_set_event_object (EventEditor *ee, CalComponent *comp) -{ - EventEditorPrivate *priv; - - g_return_if_fail (ee != NULL); - g_return_if_fail (IS_EVENT_EDITOR (ee)); - - priv = ee->priv; - - if (priv->comp) { - gtk_object_unref (GTK_OBJECT (priv->comp)); - priv->comp = NULL; - } - - if (comp) { - priv->comp = cal_component_clone (comp); - } - - set_title_from_comp (ee, priv->comp); - fill_widgets (ee); -} - -/** - * event_editor_focus: - * @ee: An event editor. - * - * Makes sure an event editor is shown, on top of other windows, and focused. - **/ -void -event_editor_focus (EventEditor *ee) -{ - EventEditorPrivate *priv; - - g_return_if_fail (ee != NULL); - g_return_if_fail (IS_EVENT_EDITOR (ee)); - - priv = ee->priv; - gtk_widget_show_now (priv->app); - raise_and_focus (priv->app); -} - -/* Checks if the event's time starts and ends at midnight, and sets the - * "all day event" box accordingly. - */ -static void -check_all_day (EventEditor *ee) -{ - EventEditorPrivate *priv; - time_t ev_start, ev_end; - gboolean all_day = FALSE; - - priv = ee->priv; - - /* Currently we just return if the date is not set or not valid. - I'm not entirely sure this is the corrent thing to do. */ - ev_start = e_date_edit_get_time (E_DATE_EDIT (priv->start_time)); - g_return_if_fail (ev_start != -1); - - ev_end = e_date_edit_get_time (E_DATE_EDIT (priv->end_time)); - g_return_if_fail (ev_end != -1); - - /* all day event checkbox */ - if (time_day_begin (ev_start) == ev_start - && time_day_begin (ev_end) == ev_end) - all_day = TRUE; - - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->all_day_event), ee); - - e_dialog_toggle_set (priv->all_day_event, all_day); - - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->all_day_event), ee); - - e_date_edit_set_show_time (E_DATE_EDIT (priv->start_time), !all_day); - e_date_edit_set_show_time (E_DATE_EDIT (priv->end_time), !all_day); -} - -/* - * Callback: all day event button toggled. - * Note that this should only be called when the user explicitly toggles the - * button. Be sure to block this handler when the toggle button's state is set - * within the code. - */ -static void -set_all_day (GtkWidget *toggle, EventEditor *ee) -{ - EventEditorPrivate *priv; - struct tm start_tm, end_tm; - time_t start_t, end_t; - gboolean all_day; - - priv = ee->priv; - - event_editor_set_changed (ee, TRUE); - - /* When the all_day toggle is turned on, the start date is rounded down - to the start of the day, and end date is rounded down to the start - of the day on which the event ends. The event is then taken to be - inclusive of the days between the start and end days. - Note that if the event end is at midnight, we do not round it down - to the previous day, since if we do that and the user repeatedly - turns the all_day toggle on and off, the event keeps shrinking. - (We'd also need to make sure we didn't adjust the time when the - radio button is initially set.) - - When the all_day_toggle is turned off, we set the event start to the - start of the working day, and if the event end is on or before the - day of the event start we set it to one hour after the event start. - */ - all_day = GTK_TOGGLE_BUTTON (toggle)->active; - - /* - * Start time. - */ - start_t = e_date_edit_get_time (E_DATE_EDIT (priv->start_time)); - g_return_if_fail (start_t != -1); - - start_tm = *localtime (&start_t); - - if (all_day) { - /* Round down to the start of the day. */ - start_tm.tm_hour = 0; - start_tm.tm_min = 0; - start_tm.tm_sec = 0; - } else { - /* Set to the start of the working day. */ - start_tm.tm_hour = calendar_config_get_day_start_hour (); - start_tm.tm_min = calendar_config_get_day_start_minute (); - start_tm.tm_sec = 0; - } - - /* - * End time. - */ - end_t = e_date_edit_get_time (E_DATE_EDIT (priv->end_time)); - g_return_if_fail (end_t != -1); - - end_tm = *localtime (&end_t); - - if (all_day) { - /* Round down to the start of the day. */ - end_tm.tm_hour = 0; - end_tm.tm_min = 0; - end_tm.tm_sec = 0; - } else { - /* If the event end is now on or before the event start day, - make it end one hour after the start. mktime() will fix any - overflows. */ - if (end_tm.tm_year < start_tm.tm_year - || (end_tm.tm_year == start_tm.tm_year - && end_tm.tm_mon < start_tm.tm_mon) - || (end_tm.tm_year == start_tm.tm_year - && end_tm.tm_mon == start_tm.tm_mon - && end_tm.tm_mday <= start_tm.tm_mday)) { - end_tm.tm_year = start_tm.tm_year; - end_tm.tm_mon = start_tm.tm_mon; - end_tm.tm_mday = start_tm.tm_mday; - end_tm.tm_hour = start_tm.tm_hour + 1; - } - } - - /* Block date_changed_cb, or dates_changed() will be called after the - start time is set (but before the end time is set) and will call - check_all_day() and mess us up. */ - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_time), ee); - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->end_time), ee); - - /* will set recur start too */ - e_date_edit_set_time (E_DATE_EDIT (priv->start_time), mktime (&start_tm)); - - e_date_edit_set_time (E_DATE_EDIT (priv->end_time), mktime (&end_tm)); - - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->start_time), ee); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->end_time), ee); - - e_date_edit_set_show_time (E_DATE_EDIT (priv->start_time), !all_day); - e_date_edit_set_show_time (E_DATE_EDIT (priv->end_time), !all_day); - - preview_recur (ee); -} - -/* Callback used when the start or end date widgets change. We check that the - * start date < end date and we set the "all day event" button as appropriate. - */ -static void -date_changed_cb (EDateEdit *dedit, gpointer data) -{ - EventEditor *ee; - EventEditorPrivate *priv; - time_t start, end; - struct tm tm_start, tm_end; - - ee = EVENT_EDITOR (data); - priv = ee->priv; - - event_editor_set_changed (ee, TRUE); - - /* Ensure that start < end */ - - start = e_date_edit_get_time (E_DATE_EDIT (priv->start_time)); - g_return_if_fail (start != -1); - end = e_date_edit_get_time (E_DATE_EDIT (priv->end_time)); - g_return_if_fail (end != -1); - - if (start >= end) { - tm_start = *localtime (&start); - tm_end = *localtime (&end); - - if (start == end && tm_start.tm_hour == 0 - && tm_start.tm_min == 0 && tm_start.tm_sec == 0) { - /* If the start and end times are the same, but both - are on day boundaries, then that is OK since it - means we have an all-day event lasting 1 day. - So we do nothing here. */ - - } else if (GTK_WIDGET (dedit) == priv->start_time) { - /* Modify the end time */ - - tm_end.tm_year = tm_start.tm_year; - tm_end.tm_mon = tm_start.tm_mon; - tm_end.tm_mday = tm_start.tm_mday; - tm_end.tm_hour = tm_start.tm_hour + 1; - tm_end.tm_min = tm_start.tm_min; - tm_end.tm_sec = tm_start.tm_sec; - - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->end_time), ee); - e_date_edit_set_time (E_DATE_EDIT (priv->end_time), mktime (&tm_end)); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->end_time), ee); - } else if (GTK_WIDGET (dedit) == priv->end_time) { - /* Modify the start time */ - - tm_start.tm_year = tm_end.tm_year; - tm_start.tm_mon = tm_end.tm_mon; - tm_start.tm_mday = tm_end.tm_mday; - tm_start.tm_hour = tm_end.tm_hour - 1; - tm_start.tm_min = tm_end.tm_min; - tm_start.tm_sec = tm_end.tm_sec; - - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_time), ee); - e_date_edit_set_time (E_DATE_EDIT (priv->start_time), mktime (&tm_start)); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->start_time), ee); - } else - g_assert_not_reached (); - } - - /* Set the "all day event" button as appropriate */ - - check_all_day (ee); - - /* Retag the recurrence preview calendar */ - - preview_recur (ee); -} - -/* Appends an alarm to the list */ -static void -append_reminder (EventEditor *ee, CalComponentAlarm *alarm, ReminderStatus status) -{ - EventEditorPrivate *priv; - GtkCList *clist; - ReminderData *rdata; - char *c[1]; - int i; - - priv = ee->priv; - - clist = GTK_CLIST (priv->reminder_list); - - c[0] = get_alarm_string (alarm); - i = e_utf8_gtk_clist_append (clist, c); - - rdata = g_new (ReminderData, 1); - rdata->status = status; - rdata->alarm = alarm; - gtk_clist_set_row_data (clist, i, rdata); - gtk_clist_select_row (clist, i, 0); - g_free (c[0]); - - gtk_widget_set_sensitive (priv->reminder_delete, TRUE); -} - -/* Callback for the "add reminder" button */ -static void -reminder_add_cb (GtkWidget *widget, EventEditor *ee) -{ - EventEditorPrivate *priv; - CalComponentAlarm *alarm; - CalAlarmTrigger trigger; - - priv = ee->priv; - - event_editor_set_changed (ee, TRUE); - - alarm = cal_component_alarm_new (); - - memset (&trigger, 0, sizeof (CalAlarmTrigger)); - trigger.type = e_dialog_option_menu_get (priv->reminder_time, reminder_time_map); - if (e_dialog_option_menu_get (priv->reminder_relative, reminder_relative_map) == BEFORE) - trigger.u.rel_duration.is_neg = 1; - else - trigger.u.rel_duration.is_neg = 0; - - switch (e_dialog_option_menu_get (priv->reminder_relative, reminder_relative_map)) { - case MINUTES: - trigger.u.rel_duration.minutes = e_dialog_spin_get_int (priv->reminder_interval_value); - break; - case HOURS: - trigger.u.rel_duration.hours = e_dialog_spin_get_int (priv->reminder_interval_value); - break; - case DAYS: - trigger.u.rel_duration.days = e_dialog_spin_get_int (priv->reminder_interval_value); - break; - } - cal_component_alarm_set_trigger (alarm, trigger); - - cal_component_alarm_set_action (alarm, e_dialog_option_menu_get (priv->reminder_action, reminder_action_map)); - - append_reminder (ee, alarm, NEW_ALARM); -} - -/* Callback for the "delete reminder" button */ -static void -reminder_delete_cb (GtkWidget *widget, EventEditor *ee) -{ - EventEditorPrivate *priv; - GtkCList *clist; - ReminderData *rdata; - int sel; - - priv = ee->priv; - - clist = GTK_CLIST (priv->reminder_list); - if (!clist->selection) - return; - - event_editor_set_changed (ee, TRUE); - - sel = GPOINTER_TO_INT (clist->selection->data); - - rdata = gtk_clist_get_row_data (clist, sel); - - if (rdata->status == EXISTING_ALARM) { - const char *uid; - - uid = cal_component_alarm_get_uid (rdata->alarm); - cal_component_remove_alarm (priv->comp, uid); - } - cal_component_alarm_free (rdata->alarm); - g_free (rdata); - - gtk_clist_remove (clist, sel); - if (sel >= clist->rows) - sel--; - - if (clist->rows > 0) - gtk_clist_select_row (clist, sel, 0); - else - gtk_widget_set_sensitive (priv->reminder_delete, FALSE); -} - - -/* Builds a static string out of an exception date */ -static char * -get_exception_string (time_t t) -{ - static char buf[256]; - - strftime (buf, sizeof (buf), _("%a %b %d %Y"), localtime (&t)); - return buf; -} - -/* Appends an exception date to the list */ -static void -append_exception (EventEditor *ee, time_t t) -{ - EventEditorPrivate *priv; - time_t *tt; - char *c[1]; - int i; - GtkCList *clist; - - priv = ee->priv; - - tt = g_new (time_t, 1); - *tt = t; - - clist = GTK_CLIST (priv->recurrence_exception_list); - - c[0] = get_exception_string (t); - i = e_utf8_gtk_clist_append (clist, c); - - gtk_clist_set_row_data (clist, i, tt); - gtk_clist_select_row (clist, i, 0); - - gtk_widget_set_sensitive (priv->recurrence_exception_modify, TRUE); - gtk_widget_set_sensitive (priv->recurrence_exception_delete, TRUE); -} - - -/* Callback for the "add exception" button */ -static void -recurrence_exception_add_cb (GtkWidget *widget, EventEditor *ee) -{ - EventEditorPrivate *priv; - time_t t; - - priv = ee->priv; - - event_editor_set_changed (ee, TRUE); - t = e_date_edit_get_time (E_DATE_EDIT (priv->recurrence_exception_date)); - append_exception (ee, t); - preview_recur (ee); -} - -/* Callback for the "modify exception" button */ -static void -recurrence_exception_modify_cb (GtkWidget *widget, EventEditor *ee) -{ - EventEditorPrivate *priv; - GtkCList *clist; - time_t *t; - int sel; - - priv = ee->priv; - - clist = GTK_CLIST (priv->recurrence_exception_list); - if (!clist->selection) - return; - - event_editor_set_changed (ee, TRUE); - - sel = GPOINTER_TO_INT (clist->selection->data); - - t = gtk_clist_get_row_data (clist, sel); - *t = e_date_edit_get_time (E_DATE_EDIT (priv->recurrence_exception_date)); - - e_utf8_gtk_clist_set_text (clist, sel, 0, get_exception_string (*t)); - - preview_recur (ee); -} - -/* Callback for the "delete exception" button */ -static void -recurrence_exception_delete_cb (GtkWidget *widget, EventEditor *ee) -{ - EventEditorPrivate *priv; - GtkCList *clist; - int sel; - - priv = ee->priv; - - clist = GTK_CLIST (priv->recurrence_exception_list); - if (!clist->selection) - return; - - event_editor_set_changed (ee, TRUE); - - sel = GPOINTER_TO_INT (clist->selection->data); - - g_free (gtk_clist_get_row_data (clist, sel)); /* free the time_t stored there */ - - gtk_clist_remove (clist, sel); - if (sel >= clist->rows) - sel--; - - if (clist->rows > 0) - gtk_clist_select_row (clist, sel, 0); - else { - gtk_widget_set_sensitive (priv->recurrence_exception_modify, FALSE); - gtk_widget_set_sensitive (priv->recurrence_exception_delete, FALSE); - } - - preview_recur (ee); -} - - -GtkWidget * -make_date_edit (void) -{ - return date_edit_new (TRUE, TRUE); -} - - -GtkWidget * -make_spin_button (int val, int low, int high) -{ - GtkAdjustment *adj; - GtkWidget *spin; - - adj = GTK_ADJUSTMENT (gtk_adjustment_new (val, low, high, 1, 10, 10)); - spin = gtk_spin_button_new (adj, 0.5, 0); - gtk_widget_set_usize (spin, 60, 0); - - return spin; -} - - -/* This is called when most fields are changed (except those which already - have signal handlers). It just sets the "changed" flag. */ -static void -field_changed (GtkWidget *widget, - EventEditor *ee) -{ - EventEditorPrivate *priv; - - g_return_if_fail (IS_EVENT_EDITOR (ee)); - - priv = ee->priv; - - event_editor_set_changed (ee, TRUE); -} - - -static void -event_editor_set_changed (EventEditor *ee, - gboolean changed) -{ - EventEditorPrivate *priv; - - priv = ee->priv; - -#if 0 - g_print ("In event_editor_set_changed: %s\n", - changed ? "TRUE" : "FALSE"); -#endif - - priv->changed = changed; - - if (priv->app) - gnome_property_box_set_state (GNOME_PROPERTY_BOX (priv->app), changed); -} - - -/* This checks if the "changed" field is set, and if so it prompts to save - the changes using a "Save/Discard/Cancel" modal dialog. It then saves the - changes if requested. It returns TRUE if the dialog should now be closed. */ -static gboolean -prompt_to_save_changes (EventEditor *ee) -{ - EventEditorPrivate *priv; - - priv = ee->priv; - - if (!priv->changed) - return TRUE; - - switch (save_component_dialog (GTK_WINDOW (priv->app))) { - case 0: /* Save */ - /* FIXME: If an error occurs here, we should popup a dialog - and then return FALSE. */ - save_event_object (ee); - return TRUE; - case 1: /* Discard */ - return TRUE; - case 2: /* Cancel */ - default: - return FALSE; - break; - } -} - -static void -categories_clicked (GtkWidget *button, EventEditor *ee) -{ - char *categories; - GnomeDialog *dialog; - int result; - GtkWidget *entry; - - entry = ee->priv->categories; - categories = e_utf8_gtk_entry_get_text (GTK_ENTRY (entry)); - - dialog = GNOME_DIALOG (e_categories_new (categories)); - result = gnome_dialog_run (dialog); - g_free (categories); - - if (result == 0) { - gtk_object_get (GTK_OBJECT (dialog), - "categories", &categories, - NULL); - e_utf8_gtk_entry_set_text (GTK_ENTRY (entry), categories); - g_free (categories); - } - gtk_object_destroy (GTK_OBJECT (dialog)); -} diff --git a/calendar/gui/event-editor.h b/calendar/gui/event-editor.h deleted file mode 100644 index 60be54c784..0000000000 --- a/calendar/gui/event-editor.h +++ /dev/null @@ -1,77 +0,0 @@ -/* Evolution calendar - Event editor dialog - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: Miguel de Icaza <miguel@ximian.com> - * Federico Mena-Quintero <federico@ximian.com> - * Seth Alves <alves@hungry.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef __EVENT_EDITOR_DIALOG_H__ -#define __EVENT_EDITOR_DIALOG_H__ - -#include <libgnome/gnome-defs.h> -#include <gtk/gtkobject.h> -#include "gnome-cal.h" - - - -#define TYPE_EVENT_EDITOR (event_editor_get_type ()) -#define EVENT_EDITOR(obj) (GTK_CHECK_CAST ((obj), TYPE_EVENT_EDITOR, EventEditor)) -#define EVENT_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_EVENT_EDITOR, \ - EventEditorClass)) -#define IS_EVENT_EDITOR(obj) (GTK_CHECK_TYPE ((obj), TYPE_EVENT_EDITOR)) -#define IS_EVENT_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), TYPE_EVENT_EDITOR)) - -typedef struct _EventEditor EventEditor; -typedef struct _EventEditorClass EventEditorClass; -typedef struct _EventEditorPrivate EventEditorPrivate; - -struct _EventEditor { - GtkObject object; - - /* Private data */ - EventEditorPrivate *priv; -}; - -struct _EventEditorClass { - GtkObjectClass parent_class; -}; - - -GtkType event_editor_get_type (void); -EventEditor *event_editor_construct (EventEditor *ee); - -EventEditor *event_editor_new (void); - -void event_editor_set_cal_client (EventEditor *ee, CalClient *client); -CalClient *event_editor_get_cal_client (EventEditor *ee); - -void event_editor_set_event_object (EventEditor *ee, CalComponent *comp); - -void event_editor_focus (EventEditor *ee); - -void event_editor_update_widgets (EventEditor *ee); - - -GtkWidget *make_date_edit (void); -GtkWidget *make_spin_button (int val, int low, int high); - - - -#endif /* __EVENT_EDITOR_DIALOG_H__ */ diff --git a/calendar/gui/evolution-calendar-control.c b/calendar/gui/evolution-calendar-control.c deleted file mode 100644 index 7ebe2b5f8e..0000000000 --- a/calendar/gui/evolution-calendar-control.c +++ /dev/null @@ -1,201 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -#include <config.h> -#include <gnome.h> -#include <glade/glade.h> -#include <bonobo.h> -#include <bonobo/bonobo-control.h> -#include <glade/glade.h> - -#ifdef USING_OAF -#include <liboaf/liboaf.h> -#else -#include <libgnorba/gnorba.h> -#endif - -#include <cal-util/timeutil.h> -#include <gui/alarm.h> -#include <gui/gnome-cal.h> -#include <gui/calendar-commands.h> - -#define PROPERTY_CALENDAR_URI "folder_uri" - -#define PROPERTY_CALENDAR_URI_IDX 1 - -#ifdef USING_OAF -#define CONTROL_FACTORY_ID "OAFIID:control-factory:calendar:f4f90989-0f50-4af2-ad94-8bbdf331f0bc" -#else -#define CONTROL_FACTORY_ID "control-factory:calendar" -#endif - -CORBA_Environment ev; -CORBA_ORB orb; - - -static void -control_activate_cb (BonoboControl *control, - gboolean activate, - gpointer user_data) -{ - if (activate) - calendar_control_activate (control, user_data); - else - calendar_control_deactivate (control); -} - - - -static void -init_bonobo (int *argc, char **argv) -{ -#ifdef USING_OAF - /* FIXME: VERSION instead of "0.0". */ - gnome_init_with_popt_table ("evolution-calendar", "0.0", - *argc, argv, oaf_popt_options, - 0, NULL); - oaf_init (*argc, argv); -#else - gnome_CORBA_init_with_popt_table ( - "evolution-calendar", "0.0", - argc, argv, NULL, 0, NULL, GNORBA_INIT_SERVER_FUNC, &ev); -#endif - - if (bonobo_init (CORBA_OBJECT_NIL, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL) == FALSE) - g_error (_("Could not initialize Bonobo")); - - glade_gnome_init (); -} - - - -static void -get_prop (BonoboPropertyBag *bag, - BonoboArg *arg, - guint arg_id, - gpointer user_data) -{ - /*GnomeCalendar *gcal = user_data;*/ - - switch (arg_id) { - - case PROPERTY_CALENDAR_URI_IDX: - /* - if (fb && fb->uri) - BONOBO_ARG_SET_STRING (arg, fb->uri); - else - BONOBO_ARG_SET_STRING (arg, ""); - */ - break; - - default: - g_warning ("Unhandled arg %d\n", arg_id); - } -} - -static void -set_prop (BonoboPropertyBag *bag, - const BonoboArg *arg, - guint arg_id, - gpointer user_data) -{ - GnomeCalendar *gcal = user_data; - char *filename; - - switch (arg_id) { - - case PROPERTY_CALENDAR_URI_IDX: - printf ("set_prop: '%s'\n", BONOBO_ARG_GET_STRING (arg)); - filename = g_strdup_printf ("%s/calendar.vcf", - BONOBO_ARG_GET_STRING (arg)); - calendar_set_uri (gcal, filename); - g_free (filename); - break; - - default: - g_warning ("Unhandled arg %d\n", arg_id); - break; - } -} - - -static void -calendar_properties_init (GnomeCalendar *gcal) -{ - gcal->properties = bonobo_property_bag_new (get_prop, set_prop, gcal); - - bonobo_property_bag_add (gcal->properties, - PROPERTY_CALENDAR_URI, - PROPERTY_CALENDAR_URI_IDX, - BONOBO_ARG_STRING, - NULL, - _("The URI that the calendar will display"), - 0); - - bonobo_control_set_property_bag (gcal->control, gcal->properties); -} - - - -static BonoboObject * -calendar_control_factory (BonoboGenericFactory *Factory, void *closure) -{ - BonoboControl *control; - - /* Create the control. */ - GnomeCalendar *cal = new_calendar (full_name, NULL, NULL, 0); - - gtk_widget_show (GTK_WIDGET (cal)); - - control = bonobo_control_new (GTK_WIDGET (cal)); - cal->control = control; - - calendar_properties_init (cal); - - gtk_signal_connect (GTK_OBJECT (control), "activate", - control_activate_cb, cal); - - return BONOBO_OBJECT (control); -} - - -static void -calendar_control_factory_init (void) -{ - static BonoboGenericFactory *factory = NULL; - - if (factory != NULL) - return; - - puts ("XXXXXX - initializing calendar factory!!!"); - - factory = bonobo_generic_factory_new (CONTROL_FACTORY_ID, calendar_control_factory, NULL); - - if (factory == NULL) - g_error ("I could not register a Calendar control factory."); -} - - -int -main (int argc, char **argv) -{ - init_bonobo (&argc, argv); - glade_gnome_init (); - alarm_init (); - e_cursors_init (); - - init_calendar (); - - //g_log_set_always_fatal ((GLogLevelFlags) 0xFFFF); - g_log_set_always_fatal (G_LOG_LEVEL_ERROR | - G_LOG_LEVEL_CRITICAL | - G_LOG_LEVEL_WARNING); - - CORBA_exception_init (&ev); - - calendar_control_factory_init (); - component_factory_init (); - - bonobo_main (); - - return 0; -} diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c deleted file mode 100644 index 3937d31781..0000000000 --- a/calendar/gui/gnome-cal.c +++ /dev/null @@ -1,1531 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Evolution calendar - Main calendar view widget - * - * Copyright (C) 1998 The Free Software Foundation - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: Miguel de Icaza <miguel@ximian.com> - * Federico Mena-Quintero <federico@ximian.com> - * Seth Alves <alves@hungry.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#include <config.h> -#include <unistd.h> -#include <signal.h> -#include <sys/wait.h> -#include <fcntl.h> -#include <gal/e-paned/e-hpaned.h> -#include <gal/e-paned/e-vpaned.h> -#include <cal-util/timeutil.h> -#include "dialogs/alarm-notify-dialog.h" -#include "e-calendar-table.h" -#include "e-day-view.h" -#include "e-week-view.h" -#include "event-editor.h" -#include "gnome-cal.h" -#include "component-factory.h" -#include "calendar-commands.h" -#include "calendar-config.h" -#include "tag-calendar.h" - - - -/* These must match the page numbers in the GtkNotebook. */ -typedef enum { - VIEW_NOT_SET = -1, - VIEW_DAY = 0, - VIEW_WORK_WEEK, - VIEW_WEEK, - VIEW_MONTH -} ViewType; - -/* Private part of the GnomeCalendar structure */ -struct _GnomeCalendarPrivate { - /* - * The Calendar Folder. - */ - - /* The calendar client object we monitor */ - CalClient *client; - - /* - * The TaskPad Folder. - */ - - /* The calendar client object we monitor */ - CalClient *task_pad_client; - - /* - * Fields for the calendar view - */ - - /* Mapping of component UIDs to event editors */ - GHashTable *object_editor_hash; - - /* This is the last selection explicitly selected by the user. We try - to keep it the same when we switch views, but we may have to alter - it depending on the view (e.g. the week views only select days, so - any times are lost. */ - time_t selection_start_time; - time_t selection_end_time; - - /* Widgets */ - - GtkWidget *hpane; - GtkWidget *notebook; - GtkWidget *vpane; - ECalendar *date_navigator; - GtkWidget *todo; - - GtkWidget *day_view; - GtkWidget *work_week_view; - GtkWidget *week_view; - GtkWidget *month_view; - - /* These are the toolbar radio buttons for switching views. */ - GtkWidget *day_button; - GtkWidget *work_week_button; - GtkWidget *week_button; - GtkWidget *month_button; - - /* 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. */ - ViewType current_view_type; - gboolean range_selected; - - /* These are the saved positions of the panes. They are multiples of - calendar month widths & heights in the date navigator, so that they - will work OK after theme changes. */ - gfloat hpane_pos; - gfloat vpane_pos; - gfloat hpane_pos_month_view; - gfloat vpane_pos_month_view; - - /* The signal handler id for our GtkCalendar "day_selected" handler. */ - guint day_selected_id; - - /* Whether we are being destroyed and should not mess with the object - * editor hash table. - */ - guint in_destroy : 1; -}; - - - -static void gnome_calendar_class_init (GnomeCalendarClass *class); -static void gnome_calendar_init (GnomeCalendar *gcal); -static void gnome_calendar_destroy (GtkObject *object); - -static void gnome_calendar_set_view_internal (GnomeCalendar *gcal, - char *page_name, - gboolean range_selected, - gboolean focus); -static void gnome_calendar_set_pane_positions (GnomeCalendar *gcal); -static void gnome_calendar_update_view_times (GnomeCalendar *gcal); -static void gnome_calendar_update_date_navigator (GnomeCalendar *gcal); - -static void gnome_calendar_on_date_navigator_style_set (GtkWidget *widget, - GtkStyle *previous_style, - gpointer data); -static void gnome_calendar_update_paned_quanta (GnomeCalendar *gcal); -static void gnome_calendar_on_date_navigator_size_allocate (GtkWidget *widget, - GtkAllocation *allocation, - gpointer data); -static void gnome_calendar_on_date_navigator_date_range_changed (ECalendarItem *calitem, - GnomeCalendar *gcal); -static void gnome_calendar_on_date_navigator_selection_changed (ECalendarItem *calitem, - GnomeCalendar *gcal); -static gboolean gnome_calendar_get_days_shown (GnomeCalendar *gcal, - GDate *start_date, - gint *days_shown); - - -static GtkVBoxClass *parent_class; - - - - -GtkType -gnome_calendar_get_type (void) -{ - static GtkType gnome_calendar_type = 0; - - if (!gnome_calendar_type) { - static const GtkTypeInfo gnome_calendar_info = { - "GnomeCalendar", - sizeof (GnomeCalendar), - sizeof (GnomeCalendarClass), - (GtkClassInitFunc) gnome_calendar_class_init, - (GtkObjectInitFunc) gnome_calendar_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - gnome_calendar_type = gtk_type_unique (GTK_TYPE_VBOX, &gnome_calendar_info); - } - - return gnome_calendar_type; -} - -/* Class initialization function for the gnome calendar */ -static void -gnome_calendar_class_init (GnomeCalendarClass *class) -{ - GtkObjectClass *object_class; - - object_class = (GtkObjectClass *) class; - - parent_class = gtk_type_class (GTK_TYPE_VBOX); - - object_class->destroy = gnome_calendar_destroy; -} - -static void -setup_widgets (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - GtkWidget *w; - gchar *filename; - CalendarModel *model; - - priv = gcal->priv; - - /* The main HPaned, with the notebook of calendar views on the left - and the ECalendar and ToDo list on the right. */ - priv->hpane = e_hpaned_new (); - gtk_widget_show (priv->hpane); - gtk_box_pack_start (GTK_BOX (gcal), priv->hpane, TRUE, TRUE, 0); - - /* The Notebook containing the 4 calendar views. */ - priv->notebook = gtk_notebook_new (); - gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->notebook), FALSE); - gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), FALSE); - gtk_widget_show (priv->notebook); - e_paned_pack1 (E_PANED (priv->hpane), priv->notebook, TRUE, TRUE); - - /* The VPaned widget, to contain the GtkCalendar & ToDo list. */ - priv->vpane = e_vpaned_new (); - gtk_widget_show (priv->vpane); - e_paned_pack2 (E_PANED (priv->hpane), priv->vpane, FALSE, TRUE); - - /* The ECalendar. */ - w = e_calendar_new (); - priv->date_navigator = E_CALENDAR (w); - e_calendar_item_set_days_start_week_sel (priv->date_navigator->calitem, 9); - e_calendar_item_set_max_days_sel (priv->date_navigator->calitem, 42); - gtk_widget_show (w); - - e_paned_pack1 (E_PANED (priv->vpane), w, FALSE, TRUE); - gtk_signal_connect (GTK_OBJECT (priv->date_navigator), - "style_set", - GTK_SIGNAL_FUNC (gnome_calendar_on_date_navigator_style_set), - gcal); - gtk_signal_connect_after (GTK_OBJECT (priv->date_navigator), - "size_allocate", - (GtkSignalFunc) gnome_calendar_on_date_navigator_size_allocate, - gcal); - gtk_signal_connect (GTK_OBJECT (priv->date_navigator->calitem), - "selection_changed", - (GtkSignalFunc) gnome_calendar_on_date_navigator_selection_changed, - gcal); - gtk_signal_connect (GTK_OBJECT (priv->date_navigator->calitem), - "date_range_changed", - GTK_SIGNAL_FUNC (gnome_calendar_on_date_navigator_date_range_changed), - gcal); - - /* The ToDo list. */ - priv->todo = e_calendar_table_new (); - model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo)); - calendar_model_set_new_comp_vtype (model, CAL_COMPONENT_TODO); - e_paned_pack2 (E_PANED (priv->vpane), priv->todo, TRUE, TRUE); - gtk_widget_show (priv->todo); - - filename = g_strdup_printf ("%s/config/TaskPad", evolution_dir); - e_calendar_table_load_state (E_CALENDAR_TABLE (priv->todo), filename); - g_free (filename); - - /* The Day View. */ - priv->day_view = e_day_view_new (); - e_day_view_set_calendar (E_DAY_VIEW (priv->day_view), gcal); - gtk_widget_show (priv->day_view); - gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), - priv->day_view, gtk_label_new ("")); - - /* The Work Week View. */ - priv->work_week_view = e_day_view_new (); - e_day_view_set_work_week_view (E_DAY_VIEW (priv->work_week_view), - TRUE); - e_day_view_set_days_shown (E_DAY_VIEW (priv->work_week_view), 5); - e_day_view_set_calendar (E_DAY_VIEW (priv->work_week_view), gcal); - gtk_widget_show (priv->work_week_view); - gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), - priv->work_week_view, gtk_label_new ("")); - - /* The Week View. */ - priv->week_view = e_week_view_new (); - e_week_view_set_calendar (E_WEEK_VIEW (priv->week_view), gcal); - gtk_widget_show (priv->week_view); - gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), - priv->week_view, gtk_label_new ("")); - - /* The Month View. */ - priv->month_view = e_week_view_new (); - e_week_view_set_calendar (E_WEEK_VIEW (priv->month_view), gcal); - e_week_view_set_multi_week_view (E_WEEK_VIEW (priv->month_view), TRUE); - gtk_widget_show (priv->month_view); - gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), - priv->month_view, gtk_label_new ("")); - - gnome_calendar_update_config_settings (gcal, TRUE); -} - -/* Object initialization function for the gnome calendar */ -static void -gnome_calendar_init (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - - priv = g_new0 (GnomeCalendarPrivate, 1); - gcal->priv = priv; - - priv->object_editor_hash = g_hash_table_new (g_str_hash, g_str_equal); - - priv->current_view_type = VIEW_NOT_SET; - priv->range_selected = FALSE; - - setup_widgets (gcal); - - priv->selection_start_time = time_day_begin (time (NULL)); - priv->selection_end_time = time_add_day (priv->selection_start_time, 1); -} - -/* Used from g_hash_table_foreach(); frees an UID string */ -static void -destroy_editor_cb (gpointer key, gpointer value, gpointer data) -{ - EventEditor *ee; - - ee = EVENT_EDITOR (value); - gtk_object_unref (GTK_OBJECT (ee)); -} - -static void -gnome_calendar_destroy (GtkObject *object) -{ - GnomeCalendar *gcal; - GnomeCalendarPrivate *priv; - gchar *filename; - - g_return_if_fail (object != NULL); - g_return_if_fail (GNOME_IS_CALENDAR (object)); - - gcal = GNOME_CALENDAR (object); - priv = gcal->priv; - - /* Save the TaskPad layout. */ - filename = g_strdup_printf ("%s/config/TaskPad", evolution_dir); - e_calendar_table_save_state (E_CALENDAR_TABLE (priv->todo), filename); - g_free (filename); - - if (priv->client) { -#if 0 - alarm_notify_remove_client (priv->client); -#endif - gtk_object_unref (GTK_OBJECT (priv->client)); - priv->client = NULL; - } - - if (priv->task_pad_client) { -#if 0 - alarm_notify_remove_client (priv->task_pad_client); -#endif - gtk_object_unref (GTK_OBJECT (priv->task_pad_client)); - priv->task_pad_client = NULL; - } - - priv->in_destroy = TRUE; - g_hash_table_foreach (priv->object_editor_hash, destroy_editor_cb, NULL); - g_hash_table_destroy (priv->object_editor_hash); - priv->object_editor_hash = NULL; - - g_free (priv); - gcal->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - -static GtkWidget * -get_current_page (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - - priv = gcal->priv; - - return GTK_NOTEBOOK (priv->notebook)->cur_page->child; -} - -char * -gnome_calendar_get_current_view_name (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - GtkWidget *page; - - g_return_val_if_fail (gcal != NULL, NULL); - g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL); - - priv = gcal->priv; - - page = get_current_page (gcal); - - if (page == priv->day_view) - return "dayview"; - else if (page == priv->work_week_view) - return "workweekview"; - else if (page == priv->week_view) - return "weekview"; - else if (page == priv->month_view) - return "monthview"; - else { - g_assert_not_reached (); - return NULL; - } -} - -void -gnome_calendar_goto (GnomeCalendar *gcal, time_t new_time) -{ - GnomeCalendarPrivate *priv; - - g_return_if_fail (gcal != NULL); - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - g_return_if_fail (new_time != -1); - - priv = gcal->priv; - - priv->selection_start_time = time_day_begin (new_time); - priv->selection_end_time = time_add_day (priv->selection_start_time, 1); - - gnome_calendar_update_view_times (gcal); - gnome_calendar_update_date_navigator (gcal); -} - - -static void -gnome_calendar_update_view_times (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - GtkWidget *page; - - priv = gcal->priv; - - page = get_current_page (gcal); - - if (page == priv->day_view || page == priv->work_week_view) { - e_day_view_set_selected_time_range (E_DAY_VIEW (page), - priv->selection_start_time, - priv->selection_end_time); - } else if (page == priv->week_view || page == priv->month_view) { - e_week_view_set_selected_time_range (E_WEEK_VIEW (page), - priv->selection_start_time, - priv->selection_end_time); - } else { - g_warning ("My penguin is gone!"); - g_assert_not_reached (); - } -} - -static void -gnome_calendar_direction (GnomeCalendar *gcal, int direction) -{ - GnomeCalendarPrivate *priv; - GtkWidget *cp; - time_t start_time, end_time; - - priv = gcal->priv; - - cp = get_current_page (gcal); - - start_time = priv->selection_start_time; - end_time = priv->selection_end_time; - - if (cp == priv->day_view) { - start_time = time_add_day (start_time, direction); - end_time = time_add_day (end_time, direction); - } else if (cp == priv->work_week_view) { - start_time = time_add_week (start_time, direction); - end_time = time_add_week (end_time, direction); - } else if (cp == priv->week_view) { - start_time = time_add_week (start_time, direction); - end_time = time_add_week (end_time, direction); - } else if (cp == priv->month_view) { - start_time = time_add_month (start_time, direction); - end_time = time_add_month (end_time, direction); - } else { - g_warning ("Weee! Where did the penguin go?"); - g_assert_not_reached (); - return; - } - - priv->selection_start_time = start_time; - priv->selection_end_time = end_time; - - gnome_calendar_update_view_times (gcal); - gnome_calendar_update_date_navigator (gcal); -} - -void -gnome_calendar_next (GnomeCalendar *gcal) -{ - g_return_if_fail (gcal != NULL); - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - - gnome_calendar_direction (gcal, 1); -} - -void -gnome_calendar_previous (GnomeCalendar *gcal) -{ - g_return_if_fail (gcal != NULL); - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - - gnome_calendar_direction (gcal, -1); -} - -void -gnome_calendar_dayjump (GnomeCalendar *gcal, time_t time) -{ - GnomeCalendarPrivate *priv; - - g_return_if_fail (gcal != NULL); - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - - priv = gcal->priv; - - priv->selection_start_time = time_day_begin (time); - priv->selection_end_time = time_add_day (priv->selection_start_time, 1); - if (priv->day_button) - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->day_button), TRUE); - else - gnome_calendar_set_view (gcal, "dayview", FALSE, TRUE); -} - -void -gnome_calendar_goto_today (GnomeCalendar *gcal) -{ - g_return_if_fail (gcal != NULL); - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - - gnome_calendar_goto (gcal, time (NULL)); - - gtk_widget_grab_focus (get_current_page (gcal)); -} - - -/* This sets which view is currently shown. It also updates the selection time - of the view so it shows the appropriate days. */ -void -gnome_calendar_set_view (GnomeCalendar *gcal, - char *page_name, - gboolean range_selected, - gboolean focus) -{ - g_return_if_fail (gcal != NULL); - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - g_return_if_fail (page_name != NULL); - - gnome_calendar_set_view_internal (gcal, page_name, range_selected, focus); - gnome_calendar_update_view_times (gcal); - gnome_calendar_update_date_navigator (gcal); -} - - -/* This sets the view without changing the selection or updating the date - navigator. If a range of dates isn't selected it will also reset the number - of days/weeks shown to the default (i.e. 1 day for the day view or 5 weeks - for the month view). */ -static void -gnome_calendar_set_view_internal (GnomeCalendar *gcal, - char *page_name, - gboolean range_selected, - gboolean focus) -{ - GnomeCalendarPrivate *priv; - int view; - gboolean round_selection; - GtkWidget *focus_widget; - - priv = gcal->priv; - - round_selection = FALSE; - - if (!strcmp (page_name, "dayview")) { - view = VIEW_DAY; - focus_widget = priv->day_view; - - if (!range_selected) - e_day_view_set_days_shown (E_DAY_VIEW (priv->day_view), 1); - } else if (!strcmp (page_name, "workweekview")) { - view = VIEW_WORK_WEEK; - focus_widget = priv->work_week_view; - } else if (!strcmp (page_name, "weekview")) { - view = VIEW_WEEK; - focus_widget = priv->week_view; - round_selection = TRUE; - } else if (!strcmp (page_name, "monthview")) { - view = VIEW_MONTH; - focus_widget = priv->month_view; - - if (!range_selected) - e_week_view_set_weeks_shown (E_WEEK_VIEW (priv->month_view), 5); - round_selection = TRUE; - } else { - g_warning ("Unknown calendar view: %s", page_name); - g_assert_not_reached (); - return; - } - - priv->current_view_type = view; - priv->range_selected = range_selected; - - calendar_config_set_default_view (view); - - gtk_notebook_set_page (GTK_NOTEBOOK (priv->notebook), view); - - if (focus) - gtk_widget_grab_focus (focus_widget); - - gnome_calendar_set_pane_positions (gcal); - - /* For the week & month views we want the selection in the date - navigator to be rounded to the nearest week when the arrow buttons - are pressed to move to the previous/next month. */ - gtk_object_set (GTK_OBJECT (priv->date_navigator->calitem), - "round_selection_when_moving", round_selection, - NULL); -} - - -static void -gnome_calendar_set_pane_positions (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - gint top_border, bottom_border, left_border, right_border; - gint col_width, row_height; - gfloat right_pane_width, top_pane_height; - - priv = gcal->priv; - - /* Get the size of the calendar month width & height. */ - e_calendar_get_border_size (priv->date_navigator, - &top_border, &bottom_border, - &left_border, &right_border); - gtk_object_get (GTK_OBJECT (priv->date_navigator->calitem), - "row_height", &row_height, - "column_width", &col_width, - NULL); - - if (priv->current_view_type == VIEW_MONTH && !priv->range_selected) { - right_pane_width = priv->hpane_pos_month_view; - top_pane_height = priv->vpane_pos_month_view; - } else { - right_pane_width = priv->hpane_pos; - top_pane_height = priv->vpane_pos; - } - - /* We add the borders before multiplying due to the way we are using - the EPaned quantum feature. */ - if (right_pane_width < 0.001) - right_pane_width = 0.0; - else - right_pane_width = (right_pane_width * (col_width + left_border + right_border) - + 0.5); - if (top_pane_height < 0.001) - top_pane_height = 0.0; - else - top_pane_height = (top_pane_height * (row_height + top_border + bottom_border) - + 0.5); - - e_paned_set_position (E_PANED (priv->hpane), -1); - e_paned_set_position (E_PANED (priv->vpane), -1); - - /* We add one to each dimension since we can't use 0. */ - - gtk_widget_set_usize (priv->vpane, right_pane_width + 1, -2); - gtk_widget_set_usize (GTK_WIDGET (priv->date_navigator), -2, top_pane_height + 1); -} - -/* Loads the initial data into the calendar; this should be called right after - * the cal_opened signal from the client is invoked. - */ -static void -initial_load (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - - priv = gcal->priv; - - tag_calendar_by_client (priv->date_navigator, priv->client); -} - -/* Displays an error to indicate that opening a calendar failed */ -static void -open_error (GnomeCalendar *gcal, const char *uri) -{ - char *msg; - - msg = g_strdup_printf (_("Could not open the folder in `%s'"), uri); - gnome_error_dialog_parented (msg, GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (gcal)))); - g_free (msg); -} - -/* Displays an error to indicate that the specified URI method is not supported */ -static void -method_error (GnomeCalendar *gcal, const char *uri) -{ - char *msg; - - msg = g_strdup_printf (_("The method required to open `%s' is not supported"), uri); - gnome_error_dialog_parented (msg, GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (gcal)))); - g_free (msg); -} - -/* Callback from the calendar client when a calendar is loaded */ -static void -cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data) -{ - GnomeCalendar *gcal; - GnomeCalendarPrivate *priv; - - gcal = GNOME_CALENDAR (data); - priv = gcal->priv; - - switch (status) { - case CAL_CLIENT_OPEN_SUCCESS: - if (client == priv->client) - initial_load (gcal); - - break; - - case CAL_CLIENT_OPEN_ERROR: - open_error (gcal, cal_client_get_uri (client)); - break; - - case CAL_CLIENT_OPEN_NOT_FOUND: - /* bullshit; we did not specify only_if_exists */ - g_assert_not_reached (); - return; - - case CAL_CLIENT_OPEN_METHOD_NOT_SUPPORTED: - method_error (gcal, cal_client_get_uri (client)); - break; - - default: - g_assert_not_reached (); - return; - } -} - -/* Callback from the calendar client when an object is updated */ -static void -obj_updated_cb (CalClient *client, const char *uid, gpointer data) -{ - GnomeCalendar *gcal; - GnomeCalendarPrivate *priv; - - gcal = GNOME_CALENDAR (data); - priv = gcal->priv; - - tag_calendar_by_client (priv->date_navigator, priv->client); -} - -/* Callback from the calendar client when an object is removed */ -static void -obj_removed_cb (CalClient *client, const char *uid, gpointer data) -{ - GnomeCalendar *gcal; - GnomeCalendarPrivate *priv; - - gcal = GNOME_CALENDAR (data); - priv = gcal->priv; - - tag_calendar_by_client (priv->date_navigator, priv->client); -} - -GtkWidget * -gnome_calendar_construct (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - gint view; - gchar *page; - - g_return_val_if_fail (gcal != NULL, NULL); - g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL); - - priv = gcal->priv; - - /* - * Calendar Folder Client. - */ - priv->client = cal_client_new (); - if (!priv->client) - return NULL; - - gtk_signal_connect (GTK_OBJECT (priv->client), "cal_opened", - GTK_SIGNAL_FUNC (cal_opened_cb), gcal); - gtk_signal_connect (GTK_OBJECT (priv->client), "obj_updated", - GTK_SIGNAL_FUNC (obj_updated_cb), gcal); - gtk_signal_connect (GTK_OBJECT (priv->client), "obj_removed", - GTK_SIGNAL_FUNC (obj_removed_cb), gcal); - -#if 0 - alarm_notify_add_client (priv->client); -#endif - - e_day_view_set_cal_client (E_DAY_VIEW (priv->day_view), - priv->client); - e_day_view_set_cal_client (E_DAY_VIEW (priv->work_week_view), - priv->client); - e_week_view_set_cal_client (E_WEEK_VIEW (priv->week_view), - priv->client); - e_week_view_set_cal_client (E_WEEK_VIEW (priv->month_view), - priv->client); - - /* - * TaskPad Folder Client. - */ - priv->task_pad_client = cal_client_new (); - if (!priv->task_pad_client) - return NULL; - - gtk_signal_connect (GTK_OBJECT (priv->task_pad_client), "cal_opened", - GTK_SIGNAL_FUNC (cal_opened_cb), gcal); - -#if 0 - alarm_notify_add_client (priv->task_pad_client); -#endif - - e_calendar_table_set_cal_client (E_CALENDAR_TABLE (priv->todo), - priv->task_pad_client); - - - /* Get the default view to show. */ - view = calendar_config_get_default_view (); - switch (view) { - case 1: - page = "workweekview"; - break; - case 2: - page = "weekview"; - break; - case 3: - page = "monthview"; - break; - default: - page = "dayview"; - break; - } - - gnome_calendar_set_view (gcal, page, FALSE, FALSE); - - return GTK_WIDGET (gcal); -} - -GtkWidget * -gnome_calendar_new (void) -{ - GnomeCalendar *gcal; - - gcal = gtk_type_new (gnome_calendar_get_type ()); - - if (!gnome_calendar_construct (gcal)) { - g_message ("gnome_calendar_new(): Could not construct the calendar GUI"); - gtk_object_unref (GTK_OBJECT (gcal)); - return NULL; - } - - return GTK_WIDGET (gcal); -} - -/** - * gnome_calendar_get_cal_client: - * @gcal: A calendar view. - * - * Queries the calendar client interface object that a calendar view is using. - * - * Return value: A calendar client interface object. - **/ -CalClient * -gnome_calendar_get_cal_client (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - - g_return_val_if_fail (gcal != NULL, NULL); - g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL); - - priv = gcal->priv; - - return priv->client; -} - -gboolean -gnome_calendar_open (GnomeCalendar *gcal, char *str_uri) -{ - GnomeCalendarPrivate *priv; - char *tasks_uri; - gboolean success; - - 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->client) == CAL_CLIENT_LOAD_NOT_LOADED, - FALSE); - - g_return_val_if_fail ( - cal_client_get_load_state (priv->task_pad_client) == CAL_CLIENT_LOAD_NOT_LOADED, - FALSE); - - if (!cal_client_open_calendar (priv->client, str_uri, FALSE)) { - g_message ("gnome_calendar_open(): Could not issue the request"); - return FALSE; - } - - /* Open the appropriate Tasks folder to show in the TaskPad. - Currently we just show the folder named "Tasks", but it will be - a per-calendar option in future. */ - - tasks_uri = g_strdup_printf ("%s/local/Tasks/tasks.ics", evolution_dir); - success = cal_client_open_calendar (priv->task_pad_client, tasks_uri, FALSE); - g_free (tasks_uri); - - if (!success) { - g_message ("gnome_calendar_open(): Could not issue the request"); - return FALSE; - } - - return TRUE; -} - -/* Tells the calendar to reload all config settings. - If initializing is TRUE it sets the pane positions as well. (We don't - want to reset the pane positions after the user clicks 'Apply' in the - preferences dialog.) */ -void -gnome_calendar_update_config_settings (GnomeCalendar *gcal, - gboolean initializing) -{ - GnomeCalendarPrivate *priv; - CalWeekdays working_days; - gint week_start_day, time_divisions; - gint start_hour, start_minute, end_hour, end_minute; - gboolean use_24_hour, show_event_end, compress_weekend; - - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - - priv = gcal->priv; - - working_days = calendar_config_get_working_days (); - /* CalWeekdays and EDayViewDays use the same bit-masks, so we can - use the same value. */ - e_day_view_set_working_days (E_DAY_VIEW (priv->day_view), - (EDayViewDays) working_days); - e_day_view_set_working_days (E_DAY_VIEW (priv->work_week_view), - (EDayViewDays) working_days); - - /* Note that this is 0 (Sun) to 6 (Sat). */ - week_start_day = calendar_config_get_week_start_day (); - - /* Convert it to 0 (Mon) to 6 (Sun), which is what we use. */ - week_start_day = (week_start_day + 6) % 7; - - e_day_view_set_week_start_day (E_DAY_VIEW (priv->day_view), - week_start_day); - e_day_view_set_week_start_day (E_DAY_VIEW (priv->work_week_view), - week_start_day); - e_week_view_set_week_start_day (E_WEEK_VIEW (priv->week_view), - week_start_day); - e_week_view_set_week_start_day (E_WEEK_VIEW (priv->month_view), - week_start_day); - - start_hour = calendar_config_get_day_start_hour (); - start_minute = calendar_config_get_day_start_minute (); - end_hour = calendar_config_get_day_end_hour (); - end_minute = calendar_config_get_day_end_minute (); - e_day_view_set_working_day (E_DAY_VIEW (priv->day_view), - start_hour, start_minute, - end_hour, end_minute); - e_day_view_set_working_day (E_DAY_VIEW (priv->work_week_view), - start_hour, start_minute, - end_hour, end_minute); - - use_24_hour = calendar_config_get_24_hour_format (); - e_day_view_set_24_hour_format (E_DAY_VIEW (priv->day_view), - use_24_hour); - e_day_view_set_24_hour_format (E_DAY_VIEW (priv->work_week_view), - use_24_hour); - e_week_view_set_24_hour_format (E_WEEK_VIEW (priv->week_view), - use_24_hour); - e_week_view_set_24_hour_format (E_WEEK_VIEW (priv->month_view), - use_24_hour); - - time_divisions = calendar_config_get_time_divisions (); - e_day_view_set_mins_per_row (E_DAY_VIEW (priv->day_view), - time_divisions); - e_day_view_set_mins_per_row (E_DAY_VIEW (priv->work_week_view), - time_divisions); - - show_event_end = calendar_config_get_show_event_end (); - e_day_view_set_show_event_end_times (E_DAY_VIEW (priv->day_view), - show_event_end); - e_day_view_set_show_event_end_times (E_DAY_VIEW (priv->work_week_view), - show_event_end); - e_week_view_set_show_event_end_times (E_WEEK_VIEW (priv->week_view), - show_event_end); - e_week_view_set_show_event_end_times (E_WEEK_VIEW (priv->month_view), - show_event_end); - - compress_weekend = calendar_config_get_compress_weekend (); - e_week_view_set_compress_weekend (E_WEEK_VIEW (priv->month_view), - compress_weekend); - - calendar_config_configure_e_calendar (E_CALENDAR (priv->date_navigator)); - - if (initializing) { - priv->hpane_pos = calendar_config_get_hpane_pos (); - priv->vpane_pos = calendar_config_get_vpane_pos (); - priv->hpane_pos_month_view = calendar_config_get_month_hpane_pos (); - priv->vpane_pos_month_view = calendar_config_get_month_vpane_pos (); - } else { - gnome_calendar_update_paned_quanta (gcal); - } - - /* The range of days shown may have changed, so we update the date - navigator if needed. */ - gnome_calendar_update_date_navigator (gcal); -} - - -void -gnome_calendar_set_selected_time_range (GnomeCalendar *gcal, - time_t start_time, - time_t end_time) -{ - GnomeCalendarPrivate *priv; - - priv = gcal->priv; - - priv->selection_start_time = start_time; - priv->selection_end_time = end_time; - - gnome_calendar_update_date_navigator (gcal); -} - -/** - * gnome_calendar_get_selected_time_range: - * @gcal: A calendar view. - * @start_time: Return value for the start of the time selection. - * @end_time: Return value for the end of the time selection. - * - * Queries the time selection range on the calendar view. - **/ -void -gnome_calendar_get_selected_time_range (GnomeCalendar *gcal, - time_t *start_time, - time_t *end_time) -{ - GnomeCalendarPrivate *priv; - - g_return_if_fail (gcal != NULL); - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - - priv = gcal->priv; - - if (start_time) - *start_time = priv->selection_start_time; - - if (end_time) - *end_time = priv->selection_end_time; -} - - -/* Callback used when an event editor dialog is closed */ -struct editor_closure -{ - GnomeCalendar *gcal; - char *uid; -}; - -static void -editor_closed_cb (GtkWidget *widget, gpointer data) -{ - GnomeCalendar *gcal; - GnomeCalendarPrivate *priv; - struct editor_closure *ec; - gboolean result; - gpointer orig_key; - char *orig_uid; - - ec = (struct editor_closure *) data; - gcal = ec->gcal; - priv = gcal->priv; - - result = g_hash_table_lookup_extended (priv->object_editor_hash, ec->uid, &orig_key, NULL); - g_assert (result != FALSE); - - orig_uid = orig_key; - - if (!priv->in_destroy) - g_hash_table_remove (priv->object_editor_hash, orig_uid); - - g_free (orig_uid); - - g_free (ec); -} - -void -gnome_calendar_edit_object (GnomeCalendar *gcal, CalComponent *comp) -{ - GnomeCalendarPrivate *priv; - EventEditor *ee; - struct editor_closure *ec; - const char *uid; - - g_return_if_fail (gcal != NULL); - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - g_return_if_fail (comp != NULL); - - priv = gcal->priv; - - cal_component_get_uid (comp, &uid); - - ee = g_hash_table_lookup (priv->object_editor_hash, uid); - if (!ee) { - ec = g_new0 (struct editor_closure, 1); - - ee = event_editor_new (); - if (!ee) { - g_message ("gnome_calendar_edit_object(): Could not create the event editor"); - return; - } - - ec->gcal = gcal; - ec->uid = g_strdup (uid); - - g_hash_table_insert (priv->object_editor_hash, ec->uid, ee); - - gtk_signal_connect (GTK_OBJECT (ee), "destroy", - GTK_SIGNAL_FUNC (editor_closed_cb), - ec); - - event_editor_set_cal_client (EVENT_EDITOR (ee), priv->client); - event_editor_set_event_object (EVENT_EDITOR (ee), comp); - } - - event_editor_focus (ee); -} - -/** - * 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) -{ - CalComponent *comp; - time_t dtstart, dtend; - CalComponentDateTime dt; - struct icaltimetype itt; - - g_return_if_fail (gcal != NULL); - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - - gnome_calendar_get_current_time_range (gcal, &dtstart, &dtend); - dt.value = &itt; - dt.tzid = NULL; - - comp = cal_component_new (); - cal_component_set_new_vtype (comp, CAL_COMPONENT_EVENT); - - itt = icaltime_from_timet (dtstart, FALSE); - cal_component_set_dtstart (comp, &dt); - - itt = icaltime_from_timet (dtend, FALSE); - cal_component_set_dtend (comp, &dt); - - cal_component_commit_sequence (comp); - - gnome_calendar_edit_object (gcal, comp); - gtk_object_unref (GTK_OBJECT (comp)); - -} - -/* Returns the selected time range for the current view. Note that this may be - different from the fields in the GnomeCalendar, since the view may clip - this or choose a more appropriate time. */ -void -gnome_calendar_get_current_time_range (GnomeCalendar *gcal, - time_t *start_time, - time_t *end_time) -{ - GnomeCalendarPrivate *priv; - GtkWidget *page; - - priv = gcal->priv; - - page = get_current_page (gcal); - - if (page == priv->day_view || page == priv->work_week_view) - e_day_view_get_selected_time_range (E_DAY_VIEW (page), start_time, end_time); - else if (page == priv->week_view || page == priv->month_view) - e_week_view_get_selected_time_range (E_WEEK_VIEW (page), start_time, end_time); - else { - g_message ("My penguin is gone!"); - g_assert_not_reached (); - } -} - - - -/* This updates the month shown and the days selected in the calendar, if - necessary. */ -static void -gnome_calendar_update_date_navigator (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - GDate start_date, end_date; - gint days_shown; - - priv = gcal->priv; - - /* If the ECalendar isn't visible, we just return. */ - if (!GTK_WIDGET_VISIBLE (priv->date_navigator)) - return; - - if (gnome_calendar_get_days_shown (gcal, &start_date, &days_shown)) { - end_date = start_date; - g_date_add_days (&end_date, days_shown - 1); - - e_calendar_item_set_selection (priv->date_navigator->calitem, - &start_date, &end_date); - } -} - - -static gboolean -gnome_calendar_get_days_shown (GnomeCalendar *gcal, - GDate *start_date, - gint *days_shown) -{ - GnomeCalendarPrivate *priv; - GtkWidget *page; - - priv = gcal->priv; - - page = get_current_page (gcal); - - if (page == priv->day_view || page == priv->work_week_view) { - g_date_clear (start_date, 1); - g_date_set_time (start_date, E_DAY_VIEW (page)->lower); - *days_shown = e_day_view_get_days_shown (E_DAY_VIEW (page)); - return TRUE; - } else if (page == priv->week_view || page == priv->month_view) { - *start_date = E_WEEK_VIEW (page)->first_day_shown; - if (e_week_view_get_multi_week_view (E_WEEK_VIEW (page))) - *days_shown = e_week_view_get_weeks_shown (E_WEEK_VIEW (page)) * 7; - else - *days_shown = 7; - - return TRUE; - } else { - g_assert_not_reached (); - return FALSE; - } -} - - -static void -gnome_calendar_on_date_navigator_selection_changed (ECalendarItem *calitem, - GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - GDate start_date, end_date, new_start_date, new_end_date; - gint days_shown, new_days_shown; - gint start_year, start_month, start_day; - gint end_year, end_month, end_day; - gboolean starts_on_week_start_day; - struct tm tm; - - priv = gcal->priv; - - starts_on_week_start_day = FALSE; - - if (!gnome_calendar_get_days_shown (gcal, &start_date, &days_shown)) - return; - - end_date = start_date; - g_date_add_days (&end_date, days_shown - 1); - - e_calendar_item_get_selection (calitem, &new_start_date, &new_end_date); - - /* If the selection hasn't changed just return. */ - if (!g_date_compare (&start_date, &new_start_date) - && !g_date_compare (&end_date, &new_end_date)) - return; - - new_days_shown = g_date_julian (&new_end_date) - g_date_julian (&new_start_date) + 1; - - /* If a complete week is selected we show the Week view. - Note that if weekends are compressed and the week start day is set - to Sunday we don't actually show complete weeks in the Week view, - so this may need tweaking. */ - if (g_date_weekday (&new_start_date) % 7 == calendar_config_get_week_start_day ()) - starts_on_week_start_day = TRUE; - - /* Switch views as appropriate, and change the number of days or weeks - shown. */ - if (new_days_shown > 9) { - e_week_view_set_weeks_shown (E_WEEK_VIEW (priv->month_view), - (new_days_shown + 6) / 7); - e_week_view_set_first_day_shown (E_WEEK_VIEW (priv->month_view), &new_start_date); - - gnome_calendar_set_view_internal (gcal, "monthview", TRUE, FALSE); - gnome_calendar_update_date_navigator (gcal); - } else if (new_days_shown == 7 && starts_on_week_start_day) { - e_week_view_set_first_day_shown (E_WEEK_VIEW (priv->week_view), &new_start_date); - - gnome_calendar_set_view_internal (gcal, "weekview", TRUE, FALSE); - gnome_calendar_update_date_navigator (gcal); - } else { - start_year = g_date_year (&new_start_date); - start_month = g_date_month (&new_start_date) - 1; - start_day = g_date_day (&new_start_date); - end_year = g_date_year (&new_end_date); - end_month = g_date_month (&new_end_date) - 1; - end_day = g_date_day (&new_end_date); - - tm.tm_year = start_year - 1900; - tm.tm_mon = start_month; - tm.tm_mday = start_day; - tm.tm_hour = 0; - tm.tm_min = 0; - tm.tm_sec = 0; - tm.tm_isdst = -1; - priv->selection_start_time = mktime (&tm); - - tm.tm_year = end_year - 1900; - tm.tm_mon = end_month; - tm.tm_mday = end_day + 1; /* mktime() will normalize this. */ - tm.tm_hour = 0; - tm.tm_min = 0; - tm.tm_sec = 0; - tm.tm_isdst = -1; - priv->selection_end_time = mktime (&tm); - - e_day_view_set_days_shown (E_DAY_VIEW (priv->day_view), new_days_shown); - gnome_calendar_set_view (gcal, "dayview", TRUE, FALSE); - } - - gnome_calendar_update_view_buttons (gcal); - gtk_widget_grab_focus (get_current_page (gcal)); -} - - -static void -gnome_calendar_on_date_navigator_date_range_changed (ECalendarItem *calitem, - GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - - priv = gcal->priv; - - tag_calendar_by_client (priv->date_navigator, priv->client); -} - - -static void -gnome_calendar_on_date_navigator_style_set (GtkWidget *widget, - GtkStyle *previous_style, - gpointer data) -{ - gnome_calendar_update_paned_quanta (GNOME_CALENDAR (data)); -} - - -static void -gnome_calendar_update_paned_quanta (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - gint row_height, col_width; - gint top_border, bottom_border, left_border, right_border; - - priv = gcal->priv; - - e_calendar_get_border_size (priv->date_navigator, - &top_border, &bottom_border, - &left_border, &right_border); - gtk_object_get (GTK_OBJECT (priv->date_navigator->calitem), - "row_height", &row_height, - "column_width", &col_width, - NULL); - - /* The EPaned quantum feature works better if we add on the calendar - borders to the quantum size. Otherwise if you shrink the date - navigator you get left with the border widths/heights which looks - bad. EPaned should be more flexible really. */ - col_width += left_border + right_border; - row_height += top_border + bottom_border; - - /* We don't have to use the EPaned quantum feature. We could just let - the calendar expand to fill the allocated space, showing as many - months as will fit. But for that to work nicely the EPaned should - resize the widgets as the bar is dragged. Otherwise the user has - to mess around to get the number of months that they want. */ -#if 1 - gtk_object_set (GTK_OBJECT (priv->hpane), - "quantum", (guint) col_width, - NULL); - gtk_object_set (GTK_OBJECT (priv->vpane), - "quantum", (guint) row_height, - NULL); -#endif - - gnome_calendar_set_pane_positions (gcal); -} - - -static void -gnome_calendar_on_date_navigator_size_allocate (GtkWidget *widget, - GtkAllocation *allocation, - gpointer data) -{ - GnomeCalendar *gcal; - GnomeCalendarPrivate *priv; - gint width, height, row_height, col_width; - gint top_border, bottom_border, left_border, right_border; - gfloat hpane_pos, vpane_pos; - - gcal = GNOME_CALENDAR (data); - priv = gcal->priv; - - if (priv->current_view_type != VIEW_NOT_SET) { - e_calendar_get_border_size (priv->date_navigator, - &top_border, &bottom_border, - &left_border, &right_border); - gtk_object_get (GTK_OBJECT (priv->date_navigator->calitem), - "row_height", &row_height, - "column_width", &col_width, - NULL); - - /* We subtract one from each dimension since we added 1 in - gnome_calendar_set_view_internal(). */ - width = allocation->width - 1; - height = allocation->height - 1; - - /* We add the border sizes to work around the EPaned - quantized feature. */ - col_width += left_border + right_border; - row_height += top_border + bottom_border; - - hpane_pos = (gfloat) width / col_width; - vpane_pos = (gfloat) height / row_height; - - if (priv->current_view_type == VIEW_MONTH - && !priv->range_selected) { - priv->hpane_pos_month_view = hpane_pos; - priv->vpane_pos_month_view = vpane_pos; - calendar_config_set_month_hpane_pos (hpane_pos); - calendar_config_set_month_vpane_pos (vpane_pos); - } else { - priv->hpane_pos = hpane_pos; - priv->vpane_pos = vpane_pos; - calendar_config_set_hpane_pos (hpane_pos); - calendar_config_set_vpane_pos (vpane_pos); - } - } -} - -void -gnome_calendar_set_view_buttons (GnomeCalendar *gcal, - GtkWidget *day_button, - GtkWidget *work_week_button, - GtkWidget *week_button, - GtkWidget *month_button) -{ - GnomeCalendarPrivate *priv; - - g_return_if_fail (gcal != NULL); - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - g_return_if_fail (day_button != NULL); - g_return_if_fail (GTK_IS_TOGGLE_BUTTON (day_button)); - g_return_if_fail (work_week_button != NULL); - g_return_if_fail (GTK_IS_TOGGLE_BUTTON (work_week_button)); - g_return_if_fail (week_button != NULL); - g_return_if_fail (GTK_IS_TOGGLE_BUTTON (week_button)); - g_return_if_fail (month_button != NULL); - g_return_if_fail (GTK_IS_TOGGLE_BUTTON (month_button)); - - priv = gcal->priv; - - priv->day_button = day_button; - priv->work_week_button = work_week_button; - priv->week_button = week_button; - priv->month_button = month_button; -} - -/* This makes the appropriate radio button in the toolbar active. It blocks the - * signals so that we can do a clean setup without affecting the views. - */ -void -gnome_calendar_update_view_buttons (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - GtkWidget *page, *button; - - priv = gcal->priv; - - page = get_current_page (gcal); - - if (page == priv->day_view) - button = priv->day_button; - else if (page == priv->work_week_view) - button = priv->work_week_button; - else if (page == priv->week_view) - button = priv->week_button; - else if (page == priv->month_view) - button = priv->month_button; - else { - g_assert_not_reached (); - return; - } - - if (button) { - gtk_signal_handler_block_by_data (GTK_OBJECT (button), gcal); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (button), gcal); - } -} diff --git a/calendar/gui/gnome-cal.h b/calendar/gui/gnome-cal.h deleted file mode 100644 index 5b4f2623b6..0000000000 --- a/calendar/gui/gnome-cal.h +++ /dev/null @@ -1,133 +0,0 @@ -/* Evolution calendar - Main calendar view widget - * - * Copyright (C) 1998 The Free Software Foundation - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: Miguel de Icaza <miguel@ximian.com> - * Federico Mena-Quintero <federico@ximian.com> - * Seth Alves <alves@hungry.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef GNOME_CALENDAR_APP_H -#define GNOME_CALENDAR_APP_H - -#include <time.h> -#include <libgnome/gnome-defs.h> -#include <gtk/gtkvbox.h> -#include <bonobo.h> -#include <widgets/misc/e-calendar.h> -#include <cal-client/cal-client.h> - -BEGIN_GNOME_DECLS - - - -#define GNOME_TYPE_CALENDAR (gnome_calendar_get_type ()) -#define GNOME_CALENDAR(obj) (GTK_CHECK_CAST ((obj), GNOME_TYPE_CALENDAR, GnomeCalendar)) -#define GNOME_CALENDAR_CLASS(klass) (GTK_CHECK_CAST_CLASS ((klass), GNOME_TYPE_CALENDAR, \ - GnomeCalendarClass)) -#define GNOME_IS_CALENDAR(obj) (GTK_CHECK_TYPE ((obj), GNOME_TYPE_CALENDAR)) -#define GNOME_IS_CALENDAR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_CALENDAR)) - -typedef struct _GnomeCalendar GnomeCalendar; -typedef struct _GnomeCalendarClass GnomeCalendarClass; -typedef struct _GnomeCalendarPrivate GnomeCalendarPrivate; - -struct _GnomeCalendar { - GtkVBox vbox; - - /* Private data */ - GnomeCalendarPrivate *priv; -}; - -struct _GnomeCalendarClass { - GtkVBoxClass parent_class; -}; - - -typedef enum { - CALENDAR_OPEN, - CALENDAR_OPEN_OR_CREATE -} GnomeCalendarOpenMode; - -GtkType gnome_calendar_get_type (void); -GtkWidget *gnome_calendar_construct (GnomeCalendar *gcal); - -GtkWidget *gnome_calendar_new (void); - -CalClient *gnome_calendar_get_cal_client (GnomeCalendar *gcal); - -gboolean gnome_calendar_open (GnomeCalendar *gcal, char *str_uri); -/* -int gnome_calendar_create (GnomeCalendar *gcal, - char *file); -*/ -void gnome_calendar_next (GnomeCalendar *gcal); -void gnome_calendar_previous (GnomeCalendar *gcal); -void gnome_calendar_goto (GnomeCalendar *gcal, - time_t new_time); -void gnome_calendar_dayjump (GnomeCalendar *gcal, - time_t time); -/* Jumps to the current day */ -void gnome_calendar_goto_today (GnomeCalendar *gcal); -char *gnome_calendar_get_current_view_name (GnomeCalendar *gcal); -void gnome_calendar_set_view (GnomeCalendar *gcal, - char *page_name, - gboolean reset_range_shown, - gboolean focus); - -void gnome_calendar_set_selected_time_range (GnomeCalendar *gcal, - time_t start_time, - time_t end_time); -void gnome_calendar_get_selected_time_range (GnomeCalendar *gcal, - time_t *start_time, - time_t *end_time); - -void gnome_calendar_edit_object (GnomeCalendar *gcal, - CalComponent *comp); - -void gnome_calendar_new_appointment (GnomeCalendar *gcal); - -/* Returns the selected time range for the current view. Note that this may be - different from the fields in the GnomeCalendar, since the view may clip - this or choose a more appropriate time. */ -void gnome_calendar_get_current_time_range (GnomeCalendar *gcal, - time_t *start_time, - time_t *end_time); - -/* Tells the calendar to reload all config settings. initializing should be - TRUE when we are setting the config settings for the first time. */ -void gnome_calendar_update_config_settings (GnomeCalendar *gcal, - gboolean initializing); - -void gnome_calendar_set_view_buttons (GnomeCalendar *gcal, - GtkWidget *day_button, - GtkWidget *work_week_button, - GtkWidget *week_button, - GtkWidget *month_button); - -/* This makes the appropriate radio button in the toolbar active. - It sets the ignore_view_button_clicks flag so the "clicked" signal handlers - just return without doing anything. */ -void gnome_calendar_update_view_buttons (GnomeCalendar *gcal); - - - -END_GNOME_DECLS - -#endif diff --git a/calendar/gui/gnome-cal.html b/calendar/gui/gnome-cal.html deleted file mode 100644 index 5a7d0a537f..0000000000 --- a/calendar/gui/gnome-cal.html +++ /dev/null @@ -1,44 +0,0 @@ -<!-- Some simple instructions on how to use the help browser --> -<BODY> -<!-- <TITLE>GNOME Calendar Documentation</TITLE> --> -<H2> GNOME Calendar Documentation </H2> -<p> -The GNOME calendar program is the calendaring program of the GNOME -system. It uses the vCalendar standard for transfering calendar -information (and is also the on-disk format used). - -<p> - -<a name="cmdline"> -<h2>Command line options</h2> - -Several options are available on the command line, they are: -<ul> - <li><tt>--events</tt> Displays the events for the date - specified (or today, if no date is specified). - - <li><tt>--from DATE</tt> Define the beginning of the range for - the event display, or the startup day on the calenday views. - By default, the event will span the whole day specified in - DATE. - - <li><tt>--to DATE</tt> Define the range end for the event - display. If this is not specified, it will default to the end - of the day specified by the <tt>--from</tt> option. - - <li><tt>--file FILE</tt> Set the calendar to the FILE - specified on the command line. - - <li><tt>--todo</tt> Dumps the to-do values to standard output. -</ul> - -<p> - -DATE is interpreted as being in the local time- zone, unless a -specific timezone is specified. Examples of valid date specifications -include: "1 month ago", "2 hours ago", "400000 seconds ago", "last -year", "last Monday", "yesterday", "a fortnight ago", "3/31/92 -10:00:07 PST", "January 23, 1987 10:05pm", "22:00 GMT". - -</BODY> - diff --git a/calendar/gui/gnome-calendar-conduit.png b/calendar/gui/gnome-calendar-conduit.png Binary files differdeleted file mode 100644 index e867ba90b2..0000000000 --- a/calendar/gui/gnome-calendar-conduit.png +++ /dev/null diff --git a/calendar/gui/goto-dialog.glade b/calendar/gui/goto-dialog.glade deleted file mode 100644 index 289ad7ab69..0000000000 --- a/calendar/gui/goto-dialog.glade +++ /dev/null @@ -1,154 +0,0 @@ -<?xml version="1.0"?> -<GTK-Interface> - -<project> - <name>preferences</name> - <program_name>preferences</program_name> - <directory></directory> - <source_directory>src</source_directory> - <pixmaps_directory>pixmaps</pixmaps_directory> - <language>C</language> - <gnome_support>True</gnome_support> - <gettext_support>True</gettext_support> -</project> - -<widget> - <class>GnomeDialog</class> - <name>goto-dialog</name> - <visible>False</visible> - <title>Go To Date</title> - <type>GTK_WINDOW_TOPLEVEL</type> - <position>GTK_WIN_POS_NONE</position> - <modal>False</modal> - <allow_shrink>False</allow_shrink> - <allow_grow>False</allow_grow> - <auto_shrink>False</auto_shrink> - <auto_close>False</auto_close> - <hide_on_close>False</hide_on_close> - - <widget> - <class>GtkVBox</class> - <child_name>GnomeDialog:vbox</child_name> - <name>dialog-vbox1</name> - <homogeneous>False</homogeneous> - <spacing>8</spacing> - <child> - <padding>4</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkHButtonBox</class> - <child_name>GnomeDialog:action_area</child_name> - <name>dialog-action_area1</name> - <layout_style>GTK_BUTTONBOX_END</layout_style> - <spacing>8</spacing> - <child_min_width>85</child_min_width> - <child_min_height>27</child_min_height> - <child_ipad_x>7</child_ipad_x> - <child_ipad_y>0</child_ipad_y> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - <pack>GTK_PACK_END</pack> - </child> - - <widget> - <class>GtkButton</class> - <name>button4</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <label>Go To Today</label> - <stock_pixmap>GNOME_STOCK_PIXMAP_JUMP_TO</stock_pixmap> - </widget> - - <widget> - <class>GtkButton</class> - <name>button5</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button> - </widget> - </widget> - - <widget> - <class>GtkVBox</class> - <name>vbox</name> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkHBox</class> - <name>hbox12</name> - <homogeneous>True</homogeneous> - <spacing>4</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkOptionMenu</class> - <name>month</name> - <can_focus>True</can_focus> - <items>January -February -March -April -May -June -July -August -September -October -November -December -</items> - <initial_choice>0</initial_choice> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkSpinButton</class> - <name>year</name> - <can_focus>True</can_focus> - <climb_rate>1</climb_rate> - <digits>0</digits> - <numeric>True</numeric> - <update_policy>GTK_UPDATE_IF_VALID</update_policy> - <snap>False</snap> - <wrap>False</wrap> - <value>1969</value> - <lower>1969</lower> - <upper>2038</upper> - <step>1</step> - <page>5</page> - <page_size>10</page_size> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - </widget> - </widget> - - <widget> - <class>Placeholder</class> - </widget> - </widget> - </widget> -</widget> - -</GTK-Interface> diff --git a/calendar/gui/goto.c b/calendar/gui/goto.c deleted file mode 100644 index 9d5b9a43b0..0000000000 --- a/calendar/gui/goto.c +++ /dev/null @@ -1,213 +0,0 @@ -/* Go to date dialog for Evolution - * - * Copyright (C) 1998 Red Hat, Inc. - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: Federico Mena <federico@ximian.com> - * JP Rosevear <jpr@ximian.com> - */ - -#include <config.h> -#include <glade/glade.h> -#include "calendar-commands.h" -#include "tag-calendar.h" -#include "goto.h" - -typedef struct -{ - GladeXML *xml; - GtkWidget *dialog; - - GtkWidget *month; - GtkWidget *year; - ECalendar *ecal; - GtkWidget *vbox; - - GnomeCalendar *gcal; - gint year_val; - gint month_val; - gint day_val; - -} GoToDialog; - -GoToDialog *dlg = NULL; - -/* Callback used when the year adjustment is changed */ -static void -year_changed (GtkAdjustment *adj, gpointer data) -{ - GoToDialog *dlg = data; - - dlg->year_val = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (dlg->year)); - e_calendar_item_set_first_month (dlg->ecal->calitem, dlg->year_val, dlg->month_val); -} - -/* Callback used when a month button is toggled */ -static void -month_changed (GtkToggleButton *toggle, gpointer data) -{ - GoToDialog *dlg = data; - GtkWidget *menu, *active; - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (dlg->month)); - active = gtk_menu_get_active (GTK_MENU (menu)); - dlg->month_val = g_list_index (GTK_MENU_SHELL (menu)->children, active); - - e_calendar_item_set_first_month (dlg->ecal->calitem, dlg->year_val, dlg->month_val); -} - -static void -ecal_date_range_changed (ECalendarItem *calitem, gpointer user_data) -{ - GoToDialog *dlg = user_data; - CalClient *client; - - client = gnome_calendar_get_cal_client (dlg->gcal); - if (client) - tag_calendar_by_client (dlg->ecal, client); -} - -/* Event handler for day groups in the month item. A button press makes the calendar jump to the - * selected day and destroys the Go-to dialog box. - */ -static void -ecal_event (ECalendarItem *calitem, gpointer user_data) -{ - GoToDialog *dlg = user_data; - GDate start_date, end_date; - struct tm tm; - time_t et; - - e_calendar_item_get_selection (calitem, &start_date, &end_date); - g_date_to_struct_tm (&start_date, &tm); - et = mktime (&tm); - - gnome_calendar_goto (dlg->gcal, et); - - gnome_dialog_close (GNOME_DIALOG (dlg->dialog)); -} - -/* Creates the ecalendar */ -static void -create_ecal (GoToDialog *dlg) -{ - ECalendarItem *calitem; - - dlg->ecal = E_CALENDAR (e_calendar_new ()); - calitem = dlg->ecal->calitem; - - e_calendar_item_set_display_popup (calitem, FALSE); - gtk_widget_show (GTK_WIDGET (dlg->ecal)); - gtk_box_pack_start (GTK_BOX (dlg->vbox), GTK_WIDGET (dlg->ecal), TRUE, TRUE, 0); - - e_calendar_item_set_first_month (calitem, dlg->year_val, dlg->month_val); - - ecal_date_range_changed (calitem, dlg); -} - -static void -goto_today (GoToDialog *dlg) -{ - gnome_calendar_goto_today (dlg->gcal); -} - -/* Gets the widgets from the XML file and returns if they are all available. */ -static gboolean -get_widgets (GoToDialog *dlg) -{ -#define GW(name) glade_xml_get_widget (dlg->xml, name) - - dlg->dialog = GW ("goto-dialog"); - - dlg->month = GW ("month"); - dlg->year = GW ("year"); - dlg->vbox = GW ("vbox"); - -#undef GW - - return (dlg->dialog - && dlg->month - && dlg->year - && dlg->vbox); -} - -static void -goto_dialog_init_widgets (GoToDialog *dlg) -{ - GtkWidget *menu; - GtkAdjustment *adj; - GList *l; - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (dlg->month)); - for (l = GTK_MENU_SHELL (menu)->children; l != NULL; l = l->next) - gtk_signal_connect (GTK_OBJECT (menu), "selection_done", - GTK_SIGNAL_FUNC (month_changed), dlg); - - adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (dlg->year)); - gtk_signal_connect (GTK_OBJECT (adj), "value_changed", - (GtkSignalFunc) year_changed, dlg); - - gtk_signal_connect (GTK_OBJECT (dlg->ecal->calitem), - "date_range_changed", - GTK_SIGNAL_FUNC (ecal_date_range_changed), - dlg); - gtk_signal_connect (GTK_OBJECT (dlg->ecal->calitem), - "selection_changed", - (GtkSignalFunc) ecal_event, - dlg); -} - -/* Creates a "goto date" dialog and runs it */ -void -goto_dialog (GnomeCalendar *gcal) -{ - GtkWidget *menu; - time_t start_time; - struct tm tm; - int b; - - if (dlg) { - return; - } - - dlg = g_new0 (GoToDialog, 1); - - /* Load the content widgets */ - dlg->xml = glade_xml_new (EVOLUTION_GLADEDIR "/goto-dialog.glade", NULL); - if (!dlg->xml) { - g_message ("goto_dialog(): Could not load the Glade XML file!"); - return; - } - - if (!get_widgets (dlg)) { - g_message ("goto_dialog(): Could not find all widgets in the XML file!"); - return; - } - dlg->gcal = gcal; - - gnome_calendar_get_selected_time_range (dlg->gcal, &start_time, NULL); - tm = *localtime (&start_time); - dlg->year_val = tm.tm_year + 1900; - dlg->month_val = tm.tm_mon; - dlg->day_val = tm.tm_mday; - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (dlg->month)); - gtk_option_menu_set_history (GTK_OPTION_MENU (dlg->month), dlg->month_val); - gtk_spin_button_set_value (GTK_SPIN_BUTTON (dlg->year), dlg->year_val); - - create_ecal (dlg); - - goto_dialog_init_widgets (dlg); - - gnome_dialog_set_parent (GNOME_DIALOG (dlg->dialog), - GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (gcal)))); - - b = gnome_dialog_run_and_close (GNOME_DIALOG (dlg->dialog)); - if (b == 0) - goto_today (dlg); - - gtk_object_unref (GTK_OBJECT (dlg->xml)); - g_free (dlg); - dlg = NULL; -} diff --git a/calendar/gui/goto.h b/calendar/gui/goto.h deleted file mode 100644 index b40c222fc4..0000000000 --- a/calendar/gui/goto.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Evolution calendar - Go To Date dialog - * - * Copyright (C) 1998 Red Hat, Inc. - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: Federico Mena <federico@ximian.com> - * JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef GOTO_DIALOG_H -#define GOTO_DIALOG_H - -#include "gnome-cal.h" - -void goto_dialog (GnomeCalendar *gcal); - -#endif diff --git a/calendar/gui/itip-utils.c b/calendar/gui/itip-utils.c deleted file mode 100644 index f090f051d6..0000000000 --- a/calendar/gui/itip-utils.c +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * itip-utils.c - * - * Authors: - * Jesse Pavel <jpavel@helixcode.com> - * - * Copyright 2000, Helix Code, Inc. - */ - -#include "itip-utils.h" - -gchar *partstat_values[] = { - "Needs action", - "Accepted", - "Declined", - "Tentative", - "Delegated", - "Completed", - "In Progress", - "Unknown" -}; - -gchar *role_values[] = { - "Chair", - "Required Participant", - "Optional Participant", - "Non-Participant", - "Other" -}; - - - -/* Note that I have to iterate and check myself because - ical_property_get_xxx_parameter doesn't take into account the - kind of parameter for which you wish to search! */ -icalparameter * -get_icalparam_by_type (icalproperty *prop, icalparameter_kind kind) -{ - icalparameter *param; - - for (param = icalproperty_get_first_parameter (prop, ICAL_ANY_PARAMETER); - param != NULL && icalparameter_isa (param) != kind; - param = icalproperty_get_next_parameter (prop, ICAL_ANY_PARAMETER) ); - - return param; -} - - diff --git a/calendar/gui/itip-utils.h b/calendar/gui/itip-utils.h deleted file mode 100644 index a2f825be8b..0000000000 --- a/calendar/gui/itip-utils.h +++ /dev/null @@ -1,15 +0,0 @@ - -#ifndef ITIP_UTILS_HEADER -#define ITIP_UTILS_HEADER - -#include <config.h> -#include <ical.h> -#include <string.h> -#include <glib.h> - -extern gchar *partstat_values[]; -extern gchar *role_values[]; - -icalparameter * get_icalparam_by_type (icalproperty *prop, icalparameter_kind kind); - -#endif diff --git a/calendar/gui/jump.xpm b/calendar/gui/jump.xpm deleted file mode 100644 index d974142d9a..0000000000 --- a/calendar/gui/jump.xpm +++ /dev/null @@ -1,14 +0,0 @@ -/* XPM */ -static char * jump_xpm[] = { -"16 8 3 1", -" c None", -". c #000000", -"+ c #FFFF00", -"................", -".++++++++++++++.", -".++++++++++++++.", -".++..++..++..++.", -".++..++..++..++.", -".++++++++++++++.", -".++++++++++++++.", -"................"}; diff --git a/calendar/gui/main.c b/calendar/gui/main.c deleted file mode 100644 index dccf4c4af0..0000000000 --- a/calendar/gui/main.c +++ /dev/null @@ -1,87 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* control-factory.c - * - * Copyright (C) 2000 Helix Code, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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: Ettore Perazzoli - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <glade/glade.h> -#include <bonobo.h> -#include <glade/glade.h> - -#include <liboaf/liboaf.h> - -#include <gal/widgets/e-cursors.h> - -#include "alarm.h" -#include "calendar-commands.h" -#include "calendar-config.h" -#include "component-factory.h" -#include "control-factory.h" -#include "e-itip-control.h" -#include "tasks-control-factory.h" - -static void -init_bonobo (int argc, char **argv) -{ - if (gnome_init_with_popt_table ("evolution-calendar", VERSION, argc, argv, - oaf_popt_options, 0, NULL) != 0) - g_error (_("Could not initialize GNOME")); - - oaf_init (argc, argv); - - if (bonobo_init (CORBA_OBJECT_NIL, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL) == FALSE) - g_error (_("Could not initialize Bonobo")); -} - - -int -main (int argc, char **argv) -{ - bindtextdomain(PACKAGE, EVOLUTION_LOCALEDIR); - textdomain(PACKAGE); - - init_bonobo (argc, argv); - glade_gnome_init (); - alarm_init (); - e_cursors_init (); - -#if 0 - //g_log_set_always_fatal ((GLogLevelFlags) 0xFFFF); - g_log_set_always_fatal (G_LOG_LEVEL_ERROR | - G_LOG_LEVEL_CRITICAL | - G_LOG_LEVEL_WARNING); -#endif - - control_factory_init (); - component_factory_init (); - e_itip_control_factory_init (); - tasks_control_factory_init (); - - bonobo_main (); - - alarm_done (); - calendar_config_write_on_exit (); - - return 0; -} diff --git a/calendar/gui/popup-menu.c b/calendar/gui/popup-menu.c deleted file mode 100644 index 550fede0f3..0000000000 --- a/calendar/gui/popup-menu.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Popup menu utilities for gncal - * - * Copyright (C) 1998 The Free Software Foundation - * - * Author: Federico Mena <quartic@gimp.org> - */ - -#include <config.h> -#include <gtk/gtkmenuitem.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <gal/widgets/e-gui-utils.h> -#include "popup-menu.h" - - -void -popup_menu (struct menu_item *items, int nitems, GdkEventButton *event) -{ - GtkWidget *menu; - GtkWidget *item; - int i; - - menu = gtk_menu_new (); - - /* Make sure the menu is destroyed when it disappears. */ - e_auto_kill_popup_menu_on_hide (GTK_MENU (menu)); - - for (i = 0; i < nitems; i++) { - if (items[i].text) { - item = gtk_menu_item_new_with_label (_(items[i].text)); - gtk_signal_connect (GTK_OBJECT (item), "activate", - items[i].callback, - items[i].data); - gtk_widget_set_sensitive (item, items[i].sensitive); - } else - item = gtk_menu_item_new (); - - gtk_widget_show (item); - gtk_menu_append (GTK_MENU (menu), item); - } - - gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, event->button, event->time); -} diff --git a/calendar/gui/popup-menu.h b/calendar/gui/popup-menu.h deleted file mode 100644 index a4590dbb98..0000000000 --- a/calendar/gui/popup-menu.h +++ /dev/null @@ -1,25 +0,0 @@ -/* Popup menu utilities for gncal - * - * Copyright (C) 1998 The Free Software Foundation - * - * Author: Federico Mena <quartic@gimp.org> - */ - -#ifndef POPUP_MENU_H -#define POPUP_MENU_H - -#include <gdk/gdktypes.h> -#include <gtk/gtksignal.h> - - -struct menu_item { - char *text; - GtkSignalFunc callback; - gpointer data; - int sensitive; -}; - -void popup_menu (struct menu_item *items, int nitems, GdkEventButton *event); - - -#endif diff --git a/calendar/gui/print.c b/calendar/gui/print.c deleted file mode 100644 index 9d5b5f891d..0000000000 --- a/calendar/gui/print.c +++ /dev/null @@ -1,1322 +0,0 @@ -/* Evolution calendar - Print support - * - * Copyright (C) 2000 Helix Code, Inc. - * - * Authors: Michael Zucchi <notzed@helixcode.com> - * Federico Mena-Quintero <federico@helixcode.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#include <config.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <math.h> -#include <libgnome/gnome-paper.h> -#include <libgnomeui/gnome-dialog.h> -#include <libgnomeprint/gnome-print.h> -#include <libgnomeprint/gnome-print-copies.h> -#include <libgnomeprint/gnome-print-master.h> -#include <libgnomeprint/gnome-print-master-preview.h> -#include <libgnomeprint/gnome-print-preview.h> -#include <libgnomeprint/gnome-printer-dialog.h> -#include <e-util/e-dialog-widgets.h> -#include <gal/widgets/e-unicode.h> -#include <cal-util/timeutil.h> -#include "calendar-commands.h" -#include "gnome-cal.h" -#include "print.h" - - - -/* copied from gnome-month-item.c this should be shared?? */ - -/* Number of days in a month, for normal and leap years */ -static const int days_in_month[2][12] = { - { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, - { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } -}; - -/* The weird month of September 1752, where 3 Sep through 13 Sep were eliminated due to the - * Gregorian reformation. - */ -static const int sept_1752[42] = { - 0, 0, 1, 2, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0 -}; - -#define REFORMATION_DAY 639787 /* First day of the reformation, counted from 1 Jan 1 */ -#define MISSING_DAYS 11 /* They corrected out 11 days */ -#define THURSDAY 4 /* First day of reformation */ -#define SATURDAY 6 /* Offset value; 1 Jan 1 was a Saturday */ -#define SEPT_1752_START 2 /* Start day within month */ -#define SEPT_1752_END 20 /* End day within month */ - -/* FIXME: This needs to be able to render using all the options from the new - * calendar configuration stuff. - */ -#define WEEK_STARTS_ON_MONDAY FALSE - -struct pdinfo -{ - GList *slots; -}; - -struct psinfo -{ - GList *events; -}; - -struct ptinfo -{ - GList *todos; -}; - -struct einfo -{ - char *text; - time_t start; - time_t end; - int count; -}; - - -/* Returns the number of leap years since year 1 up to (but not including) the specified year */ -static int -leap_years_up_to (int year) -{ - return (year / 4 /* trivial leapness */ - - ((year > 1700) ? (year / 100 - 17) : 0) /* minus centuries since 1700 */ - + ((year > 1600) ? ((year - 1600) / 400) : 0)); /* plus centuries since 1700 divisible by 400 */ -} - -/* Returns whether the specified year is a leap year */ -static int -is_leap_year (int year) -{ - if (year <= 1752) - return !(year % 4); - else - return (!(year % 4) && (year % 100)) || !(year % 400); -} - -/* Returns the 1-based day number within the year of the specified date */ -static int -day_in_year (int day, int month, int year) -{ - int is_leap, i; - - is_leap = is_leap_year (year); - - for (i = 0; i < month; i++) - day += days_in_month [is_leap][i]; - - return day; -} - -/* Returns the day of the week (zero-based, zero is Sunday) for the specified date. For the days - * that were removed on the Gregorian reformation, it returns Thursday. - */ -static int -day_in_week (int day, int month, int year) -{ - int n; - - n = (year - 1) * 365 + leap_years_up_to (year - 1) + day_in_year (day, month, year); - - if (n < REFORMATION_DAY) - return (n - 1 + SATURDAY) % 7; - - if (n >= (REFORMATION_DAY + MISSING_DAYS)) - return (n - 1 + SATURDAY - MISSING_DAYS) % 7; - - return THURSDAY; -} - -/* Fills the 42-element days array with the day numbers for the specified month. Slots outside the - * bounds of the month are filled with zeros. The starting and ending indexes of the days are - * returned in the start and end arguments. - */ -static void -build_month (int month, int year, int start_on_monday, int *days, int *start, int *end) -{ - int i; - int d_month, d_week; - - /* Note that months are zero-based, so September is month 8 */ - - if ((year == 1752) && (month == 8)) { - memcpy (days, sept_1752, 42 * sizeof (int)); - - if (start) - *start = SEPT_1752_START; - - if (end) - *end = SEPT_1752_END; - - return; - } - - for (i = 0; i < 42; i++) - days[i] = 0; - - d_month = days_in_month[is_leap_year (year)][month]; - d_week = day_in_week (1, month, year); - - if (start_on_monday) - d_week = (d_week + 6) % 7; - - for (i = 0; i < d_month; i++) - days[d_week + i] = i + 1; - - if (start) - *start = d_week; - - if (end) - *end = d_week + d_month - 1; -} - - -enum align_box { - ALIGN_LEFT=1, - ALIGN_RIGHT, - ALIGN_CENTRE, - ALIGN_BORDER= 1<<8 -}; - -/* width = width of border, -'ve is no border - fillcolour = shade of fill, -'ve is no fill */ -static void -print_border(GnomePrintContext *pc, double l, double r, double t, double b, double width, double fillcolour) -{ - int i; - gnome_print_gsave (pc); - if (fillcolour<0.0) - i=1; - else - i=0; - for (;i<2;i++) { - gnome_print_moveto(pc, l, t); - gnome_print_lineto(pc, l, b); - gnome_print_lineto(pc, r, b); - gnome_print_lineto(pc, r, t); - gnome_print_lineto(pc, l, t); - if (i==0) { - gnome_print_setrgbcolor(pc, fillcolour, fillcolour, fillcolour); - gnome_print_fill(pc); - if (width<0.0) - i=2; - } else { - gnome_print_setrgbcolor(pc, 0, 0, 0); - gnome_print_setlinewidth(pc, width); - gnome_print_stroke(pc); - } - } - gnome_print_grestore (pc); -} - -/* outputs 1 line of aligned text in a box */ -static void -print_text(GnomePrintContext *pc, GnomeFont *font, const char *text, enum align_box align, double l, double r, double t, double b) -{ - double w, x; - gnome_print_gsave (pc); - w = gnome_font_get_width_string(font, text); - switch (align&3) { - default: - case ALIGN_LEFT: - x = l; - break; - case ALIGN_RIGHT: - x = l+(r-l)-w-2; - break; - case ALIGN_CENTRE: - x = l+((r-l)-w)/2; - break; - } - gnome_print_moveto(pc, x, t - gnome_font_get_size (font)); - gnome_print_setfont(pc, font); - gnome_print_setrgbcolor (pc, 0,0,0); - gnome_print_show(pc, text); - gnome_print_grestore (pc); -} - -/* gets/frees the font for you, as a bold font */ -static void -print_text_size(GnomePrintContext *pc, double size, const char *text, enum align_box align, double l, double r, double t, double b) -{ - GnomeFont *font; - - font = gnome_font_new_closest ("Times", GNOME_FONT_BOLD, 0, size); - print_text(pc, font, text, align, l, r, t, b); - gtk_object_unref (GTK_OBJECT (font)); -} - -static void -titled_box(GnomePrintContext *pc, const char *text, GnomeFont *font, enum align_box align, double *l, double *r, double *t, double *b, double linewidth) -{ - if (align&ALIGN_BORDER) { - gnome_print_gsave(pc); - print_border(pc, *l, *r, *t, *t-gnome_font_get_size(font)-gnome_font_get_size(font)*0.4, linewidth, 0.9); - print_border(pc, *l, *r, *t-gnome_font_get_size(font)-gnome_font_get_size(font)*0.4, *b, linewidth, -1.0); - gnome_print_grestore(pc); - *l+=2; - *r-=2; - *b+=2; - } - print_text(pc, font, text, align, *l, *r, *t, *b); - *t-=gnome_font_get_size(font)*1.4; -} - -enum datefmt { - DATE_MONTH = 1 << 0, - DATE_DAY = 1 << 1, - DATE_DAYNAME = 1 << 2, - DATE_YEAR = 1 << 3 -}; - -static char *days[] = { - N_("1st"), N_("2nd"), N_("3rd"), N_("4th"), N_("5th"), - N_("6th"), N_("7th"), N_("8th"), N_("9th"), N_("10th"), - N_("11th"), N_("12th"), N_("13th"), N_("14th"), N_("15th"), - N_("16th"), N_("17th"), N_("18th"), N_("19th"), N_("20th"), - N_("21st"), N_("22nd"), N_("23rd"), N_("24th"), N_("25th"), - N_("26th"), N_("27th"), N_("28th"), N_("29th"), N_("30th"), - N_("31st") -}; - -/* - format the date 'nicely' and consistently for various headers -*/ -static char * -format_date(time_t time, int flags, char *buffer, int bufflen) -{ - char fmt[64]; - struct tm tm; - - tm = *localtime(&time); - fmt[0] = 0; - if (flags & DATE_DAYNAME) { - strcat(fmt, "%A"); - } - if (flags & DATE_DAY) { - if (flags & DATE_DAYNAME) - strcat(fmt, " "); - strcat(fmt, gettext(days[tm.tm_mday-1])); - } - if (flags & DATE_MONTH) { - if (flags & (DATE_DAY|DATE_DAYNAME)) - strcat(fmt, " "); - strcat(fmt, "%B"); - if ((flags & (DATE_DAY|DATE_YEAR)) == (DATE_DAY|DATE_YEAR)) - strcat(fmt, ","); - } - if (flags & DATE_YEAR) { - if (flags & (DATE_DAY|DATE_DAYNAME|DATE_MONTH)) - strcat(fmt, " "); - strcat(fmt, "%Y"); - } - strftime(buffer, bufflen, fmt, &tm); - return buffer; -} - - -/* - print out the month small, embolden any days with events. -*/ -static void -print_month_small (GnomePrintContext *pc, GnomeCalendar *gcal, - time_t month, double left, double right, double top, double bottom, - int titleflags, time_t greystart, time_t greyend, int bordertitle) -{ - CalClient *client; - GnomeFont *font, *font_bold, *font_normal; - time_t now, next; - int x, y; - int days[42]; - int day; - char buf[100]; - struct tm tm; - double xpad, ypad, size; - char *daynames[] = { _("Su"), _("Mo"), _("Tu"), _("We"), _("Th"), _("Fr"), _("Sa") }; - - client = gnome_calendar_get_cal_client (gcal); - - xpad = (right-left)/7; - ypad = (top-bottom)/8.3; - if (xpad>ypad) - size=ypad; - else - size=xpad; - - size = (xpad+ypad)/3.0; - - tm = *localtime (&month); - - /* get month days */ - build_month(tm.tm_mon, tm.tm_year+1900, WEEK_STARTS_ON_MONDAY, days, 0, 0); - - /* build day-busy bits */ - now = time_month_begin(month); - - /* get title */ - format_date(month, titleflags, buf, 100); - font = gnome_font_new_closest ("Times", GNOME_FONT_BOLD, 1, size*1.2); /* title font */ - if (bordertitle) - print_border(pc, - left, left+7*xpad, top, top-gnome_font_get_size(font)*1.3, - 1.0, 0.9); - print_text(pc, font, buf, ALIGN_CENTRE, - left, left+7*xpad, top, top - gnome_font_get_size (font)); - gtk_object_unref (GTK_OBJECT (font)); - - font_normal = gnome_font_new_closest ("Times", GNOME_FONT_BOOK, 0, size); - font_bold = gnome_font_new_closest ("Times", GNOME_FONT_BOLD, 0, size); - - gnome_print_setrgbcolor (pc, 0,0,0); - for (x=0;x<7;x++) { - print_text(pc, font_bold, daynames[(WEEK_STARTS_ON_MONDAY?x+1:x)%7], ALIGN_CENTRE, - left+x*xpad, left+(x+1)*xpad, bottom+7*ypad, bottom+7*ypad-gnome_font_get_size(font_bold)); - } - - for (y=0;y<6;y++) { - for (x=0;x<7;x++) { - day = days[y*7+x]; - if (day!=0) { - GList *uids; - - 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 (now)); - font = uids ? font_bold : font_normal; - cal_obj_uid_list_free (uids); - - next = time_add_day(now, 1); - if ((now>=greystart && now<greyend) - || (greystart>=now && greystart<next)) { - print_border(pc, - left+x*xpad+xpad*0.1, - left+(x+1)*xpad+xpad*0.1, - bottom+(5-y)*ypad+gnome_font_get_size(font)-ypad*0.15, - bottom+(5-y)*ypad-ypad*0.15, - -1.0, 0.75); - } - print_text(pc, font, buf, ALIGN_RIGHT, - left+x*xpad, left+(x+1)*xpad, bottom+(5-y)*ypad+gnome_font_get_size(font), bottom+(5-y)*ypad); - now = next; - } - } - } - gtk_object_unref (GTK_OBJECT (font_normal)); - gtk_object_unref (GTK_OBJECT (font_bold)); -} - - - -/* wraps text into the print context, not taking up more than its allowed space */ -static double -bound_text(GnomePrintContext *pc, GnomeFont *font, const char *text, - double left, double right, double top, double bottom, double indent) -{ - double maxwidth = right-left; - double width; - const char *p; - char *wordstart; - int c; - char *outbuffer, *o, *outbuffendmarker; - int outbufflen; - int dump=0; - int first=1; - - g_return_val_if_fail(text!=NULL, top); - - if (top<bottom) { - /* too much to fit in appointment printout */ - return top; - } - - outbufflen = 1024; - outbuffer = g_malloc(outbufflen); - outbuffendmarker = outbuffer+outbufflen-2; - - top -= gnome_font_get_size (font); - gnome_print_setfont (pc, font); - - width=0; - p = text; - wordstart = outbuffer; - o = outbuffer; - while ((c=*p)) { - if (c=='\n') { - wordstart=o; - dump=1; - } else { - /* grow output buffer if required */ - if (o>=outbuffendmarker) { - char *newbuf; - outbufflen*=2; - newbuf = g_realloc(outbuffer, outbufflen); - o = newbuf+(o-outbuffer); - wordstart = newbuf+(o-outbuffer); - outbuffer = newbuf; - outbuffendmarker = outbuffer+outbufflen-2; - } - *o++=c; - if (c==' ') - wordstart = o; - width+=gnome_font_get_glyph_width(font, gnome_font_lookup_default (font, c)); - if (width>maxwidth) - dump=1; - else - dump=0; - } - if (dump) { - if (wordstart==outbuffer) - wordstart=o; - c=*wordstart; - *wordstart=0; - gnome_print_moveto(pc, left, top); - gnome_print_show(pc, outbuffer); - *wordstart=c; - memcpy(outbuffer, wordstart, o-wordstart); - width = gnome_font_get_width_string_n(font, outbuffer, o-wordstart); - o=outbuffer+(o-wordstart); - wordstart = outbuffer; - top -= gnome_font_get_size (font); - if (top<bottom) { - /* too much to fit, drop the rest */ - g_free(outbuffer); - return top; - } - if (first) { - left += indent; - maxwidth -= indent; - first=0; - } - } - p++; - } - if (dump==0) { - *o=0; - gnome_print_moveto(pc, left, top); - gnome_print_show(pc, outbuffer); - top -= gnome_font_get_size (font); - } - g_free(outbuffer); - return top; -} - -/* - * Print Day Details - */ -static gboolean -print_day_details_cb (CalComponent *comp, time_t istart, time_t iend, gpointer data) -{ - CalComponentText text; - GList *l, *col = NULL; - struct pdinfo *pdi = (struct pdinfo *)data; - struct einfo *ei; - - ei = g_new (struct einfo, 1); - - cal_component_get_summary (comp, &text); - ei->text = g_strdup (text.value); - - ei->start = istart; - ei->end = iend; - ei->count = 0; - - for (l = pdi->slots; l; l = l->next) { - struct einfo *testei; - - col = (GList *)l->data; - testei = (struct einfo *)col->data; - - if (ei->start >= testei->end) { - col = g_list_prepend (col, ei); - l->data = col; - return TRUE; - } - - testei->count++; - ei->count++; - } - - col = NULL; - col = g_list_prepend (col, ei); - pdi->slots = g_list_append (pdi->slots, col); - - return TRUE; -} - -static void -print_day_details (GnomePrintContext *pc, GnomeCalendar *gcal, time_t whence, - double left, double right, double top, double bottom) -{ - CalClient *client; - struct pdinfo pdi; - time_t start, end; - GList *l; - int num_slots, i; - GnomeFont *font_hour, *font_minute, *font_summary; - double yinc, y, yend, x, xend; - double width=40, slot_width; - char buf[20]; - - client = gnome_calendar_get_cal_client (gcal); - - yinc = (top-bottom)/24; - - /* fill static detail */ - font_hour = gnome_font_new_closest ("Times", GNOME_FONT_BOLD, 0, yinc/2); - font_minute = gnome_font_new_closest ("Times", GNOME_FONT_BOLD, 0, yinc/3); - font_summary = gnome_font_new_closest ("Times", GNOME_FONT_BOOK, 0, yinc/3); - - gnome_print_setrgbcolor (pc, 0, 0, 0); - - /* internal lines */ - gnome_print_setlinewidth(pc, 0.0); - gnome_print_moveto(pc, left+width, bottom); - gnome_print_lineto(pc, left+width, top); - gnome_print_stroke (pc); - - for (i=0;i<24;i++) { - y = top - yinc*(i+1); - print_border(pc, left+1, left+width-1, y, y+yinc-1, -1.0, 0.9); - gnome_print_setrgbcolor (pc, 0, 0, 0); - - /* the hour label/minute */ - sprintf(buf, "%d", i); - print_text(pc, font_hour, buf, ALIGN_RIGHT, left, left+width/2, y+yinc, y); - switch(i) { - case 12: sprintf(buf, _("pm")); break; - case 0: sprintf(buf, _("am")); break; - default: sprintf(buf, "00"); break; - } - print_text(pc, font_minute, buf, ALIGN_LEFT, left+width/2, left+width/2, y+yinc, y); - - /* internal lines */ - gnome_print_moveto(pc, left+width, y); - gnome_print_lineto(pc, right, y); - gnome_print_stroke (pc); - gnome_print_moveto(pc, left+width/2, y+yinc/2); - gnome_print_lineto(pc, right, y+yinc/2); - gnome_print_stroke (pc); - - } - - start = time_day_begin(whence); - end = time_day_end(start); - - pdi.slots = NULL; - - cal_client_generate_instances (client, CALOBJ_TYPE_EVENT, start, end, - print_day_details_cb, &pdi); - - num_slots = g_list_length (pdi.slots); - slot_width = (right-left-width)/num_slots; - - for (i = num_slots, l = pdi.slots; l; i--, l = l->next) { - GList *e = (GList *)l->data; - - for (; e; e = e->next) { - struct einfo *ei = (struct einfo *)e->data; - - y = top - (top - bottom) * (ei->start - start) / (end - start) - 1; - yend = top - (top - bottom) * (ei->end - start) / (end - start) + 1; - x = left + width + slot_width * (num_slots - i); - - if (num_slots > 0) - x++; - - if (i == 0) - xend = x + (num_slots - ei->count) * slot_width - 2; - else - xend = x + slot_width - 2; - - print_border (pc, x, xend, y, yend, 0.0, 0.9); - - bound_text (pc, font_summary, ei->text, x, xend, y, yend, 0); - - g_free (ei); - } - g_list_free (e); - } - g_list_free (pdi.slots); - - print_border (pc, left, right, top, bottom, 1.0, -1.0); - - gtk_object_unref (GTK_OBJECT (font_hour)); - gtk_object_unref (GTK_OBJECT (font_minute)); - gtk_object_unref (GTK_OBJECT (font_summary)); -} - -/* - * Print Day Summary - */ -#if 0 -#define TIME_FMT "%X" -#else -#define TIME_FMT "%l:%M%p" -#endif - -static gboolean -print_day_summary_cb (CalComponent *comp, time_t istart, time_t iend, gpointer data) -{ - CalComponentText text; - struct psinfo *psi = (struct psinfo *)data; - struct einfo *ei; - - ei = g_new (struct einfo, 1); - - cal_component_get_summary (comp, &text); - ei->text = g_strdup (text.value); - - ei->start = istart; - ei->end = iend; - ei->count = 0; - - psi->events = g_list_append (psi->events, ei); - - return TRUE; -} - -static void -print_day_summary (GnomePrintContext *pc, GnomeCalendar *gcal, time_t whence, - double left, double right, double top, double bottom, - double size, int totime, int titleformat) -{ - CalClient *client; - struct psinfo psi; - time_t start, end; - GList *l; - GnomeFont *font_summary; - double y, yend, x, xend, inc, incsmall; - char buf[100]; - double margin; - struct tm tm; - - client = gnome_calendar_get_cal_client (gcal); - - /* fill static detail */ - font_summary = gnome_font_new_closest ("Times", GNOME_FONT_BOOK, 0, size); - - gnome_print_setfont (pc, font_summary); - - start = time_day_begin(whence); - end = time_day_end(start); - - tm = *localtime(&start); - - format_date(start, titleformat, buf, 100); - titled_box (pc, buf, font_summary, ALIGN_RIGHT | ALIGN_BORDER, - &left, &right, &top, &bottom, 0.0); - - psi.events = NULL; - - cal_client_generate_instances (client, CALOBJ_TYPE_EVENT, start, end, - print_day_summary_cb, &psi); - inc = size*0.3; - incsmall = size*0.2; - - y = top-inc; - yend = bottom-incsmall; - - /* do a good rough approximation of the 'widest' time */ - tm.tm_year = 2000; - tm.tm_mon = 12; - tm.tm_mday = 22; - tm.tm_sec = 22; - tm.tm_min = 22; - tm.tm_hour = 23; - strftime(buf, 100, TIME_FMT, &tm); - margin = gnome_font_get_width_string(font_summary, buf); - - for (l = psi.events; l; l = l->next) { - struct einfo *ei = (struct einfo *)l->data; - - x = left + incsmall; - xend = right - inc; - - if (y - gnome_font_get_size (font_summary) < bottom) - break; - - tm = *localtime (&ei->start); - strftime (buf, 100, TIME_FMT, &tm); - gnome_print_moveto (pc, x + (margin - - gnome_font_get_width_string (font_summary, buf)), - y - gnome_font_get_size (font_summary)); - gnome_print_show (pc, buf); - - if (totime) { - tm = *localtime (&ei->end); - strftime (buf, 100, TIME_FMT, &tm); - gnome_print_moveto (pc, - (x + margin + inc - + (margin - - gnome_font_get_width_string (font_summary, buf))), - y - gnome_font_get_size (font_summary)); - gnome_print_show (pc, buf); - - y = bound_text (pc, font_summary, ei->text, - x + margin * 2 + inc * 2, xend, - y, yend, 0); - } else { - /* we also indent back after each time is printed */ - y = bound_text (pc, font_summary, ei->text, - x + margin + inc, xend, - y, yend, -margin + inc); - } - - y += gnome_font_get_size (font_summary) - inc; - - g_free (ei); - } - g_list_free (psi.events); - - gtk_object_unref (GTK_OBJECT (font_summary)); -} - -static void -print_week_summary (GnomePrintContext *pc, GnomeCalendar *gcal, time_t whence, - double left, double right, double top, double bottom) -{ - double y, l, r, t, b; - time_t now; - int i; - - l = left; - r = (right-left)/2+left; - t = top; - y = (top-bottom)/3; - b = top-y; - now = time_week_begin(whence); /* returns sunday, we need monday */ - now = time_add_day(now, 1); - for (i = 0; i < 7; i++) { - print_day_summary (pc, gcal, now, l, r, t, b, - 10, TRUE, DATE_DAY | DATE_DAYNAME | DATE_MONTH); - now = time_add_day (now, 1); - switch (i) { - case 5: - y /= 2.0; - b += y; - case 0: - case 1: - case 3: - case 4: - t -= y; - b -= y; - break; - case 2: - l = r; - r = right; - t = top; - b = t-y; - break; - case 6: - break; - } - } -} - -static void -print_year_summary (GnomePrintContext *pc, GnomeCalendar *gcal, time_t whence, - double left, double right, double top, double bottom, int morerows) -{ - double y, x, l, r, t, b; - time_t now; - int xx, yy, rows, cols; - - l = left; - t = top; - if (morerows) { - rows=4; - cols=3; - } else { - rows=3; - cols=4; - } - y = (top-bottom)/rows; - x = (right-left)/cols; - r = l+x; - b = top-y; - now = time_year_begin(whence); - for (yy = 0; yy < rows; yy++) { - t = top - y * yy; - b = t - y; - for (xx = 0; xx < cols; xx++) { - l = left + x * xx; - r = l + x; - print_month_small (pc, gcal, now, - l + 8, r - 8, t - 8, b + 8, DATE_MONTH, 0, 0, TRUE); - now = time_add_month (now, 1); - } - } -} - -static void -print_month_summary (GnomePrintContext *pc, GnomeCalendar *gcal, time_t whence, - double left, double right, double top, double bottom) -{ - time_t now, today; - int days[42]; - int day; - struct tm tm; - int x, y; - char buf[100]; - GnomeFont *font_days; - - now = time_month_begin(whence); - tm = *localtime (&now); - - /* get month days */ - build_month(tm.tm_mon, tm.tm_year+1900, WEEK_STARTS_ON_MONDAY, days, 0, 0); - - /* a little margin */ - top -= 4; - - /* do day names ... */ - font_days = gnome_font_new_closest ("Times", GNOME_FONT_BOLD, 0, 10); - gnome_print_setfont(pc, font_days); - for (x=0;x<7;x++) { - today = time_add_day(now, days[6+x]); - format_date(today, DATE_DAYNAME, buf, 100); - print_text(pc, font_days, buf, ALIGN_CENTRE, - (right-left)*x/7+left, (right-left)*(x+1)/7+left, - top, top-gnome_font_get_size(font_days)); - } - top -= gnome_font_get_size(font_days)*1.5; - gtk_object_unref (GTK_OBJECT (font_days)); - - for (y=0;y<6;y++) { - for (x=0;x<7;x++) { - day = days[y*7+x]; - if (day!=0) { - print_day_summary (pc, gcal, now, - (right-left)*x/7+left, - (right-left)*(x+1)/7+left, - top - (top-bottom)*y/6, - top - (top-bottom)*(y+1)/6, 6, FALSE, - day==1?(DATE_DAY|DATE_MONTH):DATE_DAY); - now = time_add_day(now, 1); - } - } - } -} - -static void -print_todo_details (GnomePrintContext *pc, GnomeCalendar *gcal, time_t start, time_t end, - double left, double right, double top, double bottom) -{ - CalClient *client; - GList *uids; - GList *l; - GnomeFont *font_summary; - double y, yend, x, xend; - - client = gnome_calendar_get_cal_client (gcal); - - font_summary = gnome_font_new_closest ("Times", GNOME_FONT_BOOK, 0, 10); - - gnome_print_setrgbcolor (pc, 0, 0, 0); - gnome_print_setlinewidth (pc, 0.0); - - titled_box (pc, _("Tasks"), font_summary, - ALIGN_CENTRE | ALIGN_BORDER, &left, &right, &top, &bottom, 1.0); - - y = top - 3; - yend = bottom - 2; - - uids = cal_client_get_uids (client, CALOBJ_TYPE_TODO); - - for (l = uids; l; l = l->next) { - char *uid; - CalComponent *comp; - CalClientGetStatus status; - CalComponentText summary; - - uid = l->data; - - status = cal_client_get_object (client, uid, &comp); - - switch (status) { - case CAL_CLIENT_GET_SUCCESS: - break; - - case CAL_CLIENT_GET_NOT_FOUND: - /* Nothing: the object may have been removed from the server */ - continue; - - case CAL_CLIENT_GET_SYNTAX_ERROR: - g_message ("print_todo_details(): Syntax error while getting object `%s'", - uid); - continue; - - default: - g_assert_not_reached (); - } - - cal_component_get_summary (comp, &summary); - - if (!summary.value) - continue; - - x = left; - xend = right - 2; - - if (y < bottom) - break; - - y = bound_text (pc, font_summary, summary.value, x + 2, xend, y, yend, 0); - y += gnome_font_get_size (font_summary); - gnome_print_moveto (pc, x, y - 3); - gnome_print_lineto (pc, xend, y - 3); - gnome_print_stroke (pc); - y -= 3; - } - - cal_obj_uid_list_free (uids); - - gtk_object_unref (GTK_OBJECT (font_summary)); -} - -#if 0 - -static GnomePrintContext * -print_context (int preview, char *paper) -{ - GtkWidget *toplevel, *canvas, *sw; - GnomePrinter *printer; - GnomePrintContext *pc; - - if (preview) { - gtk_widget_push_colormap (gdk_rgb_get_cmap ()); - gtk_widget_push_visual (gdk_rgb_get_visual ()); - - toplevel = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_widget_set_usize (toplevel, 700, 700); - sw = gtk_scrolled_window_new (NULL, NULL); - canvas = gnome_canvas_new_aa (); - gtk_container_add (GTK_CONTAINER (toplevel), sw); - gtk_container_add (GTK_CONTAINER (sw), canvas); - - gnome_canvas_set_pixels_per_unit((GnomeCanvas *)canvas, 1); - - pc = gnome_print_preview_new ((GnomeCanvas *)canvas, paper); - - gtk_widget_show_all (toplevel); - - gtk_widget_pop_visual (); - gtk_widget_pop_colormap (); - } else { - printer = gnome_printer_dialog_new_modal (); - - if (!printer) - return NULL; - - pc = gnome_print_context_new_with_paper_size (printer, paper); - } - - return pc; -} - -#endif - -/* Value for the PrintView enum */ -static const int print_view_map[] = { - PRINT_VIEW_DAY, - PRINT_VIEW_WEEK, - PRINT_VIEW_MONTH, - PRINT_VIEW_YEAR, - -1 -}; - -/* Creates the range selector widget for printing a calendar */ -static GtkWidget * -range_selector_new (GtkWidget *dialog, time_t at, int *view) -{ - GtkWidget *box; - GtkWidget *radio; - GSList *group; - char text[1024]; - char str1[512]; - char str2[512]; - struct tm tm; - time_t week_begin, week_end; - struct tm week_begin_tm, week_end_tm; - - box = gtk_vbox_new (FALSE, GNOME_PAD_SMALL); - - tm = *localtime (&at); - - /* Day */ - - strftime (text, sizeof (text), _("Current day (%a %b %d %Y)"), &tm); - radio = gtk_radio_button_new_with_label (NULL, text); - group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio)); - gtk_box_pack_start (GTK_BOX (box), radio, FALSE, FALSE, 0); - - /* Week */ - - week_begin = time_week_begin (at); - week_end = time_add_day (time_week_end (at), -1); - - week_begin_tm = *localtime (&week_begin); - week_end_tm = *localtime (&week_end); - - if (week_begin_tm.tm_mon == week_end_tm.tm_mon) { - strftime (str1, sizeof (str1), _("%a %b %d"), &week_begin_tm); - strftime (str2, sizeof (str2), _("%a %d %Y"), &week_end_tm); - } else { - if (week_begin_tm.tm_year == week_end_tm.tm_year) { - strftime (str1, sizeof (str1), _("%a %b %d"), &week_begin_tm); - strftime (str2, sizeof (str2), _("%a %b %d %Y"), &week_end_tm); - } else { - strftime (str1, sizeof (str1), _("%a %b %d %Y"), &week_begin_tm); - strftime (str2, sizeof (str2), _("%a %b %d %Y"), &week_end_tm); - } - } - - g_snprintf (text, sizeof (text), _("Current week (%s - %s)"), str1, str2); - - radio = gtk_radio_button_new_with_label (group, text); - group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio)); - gtk_box_pack_start (GTK_BOX (box), radio, FALSE, FALSE, 0); - - /* Month */ - - strftime (text, sizeof (text), _("Current month (%b %Y)"), &tm); - radio = gtk_radio_button_new_with_label (group, text); - group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio)); - gtk_box_pack_start (GTK_BOX (box), radio, FALSE, FALSE, 0); - - /* Year */ - - strftime (text, sizeof (text), _("Current year (%Y)"), &tm); - radio = gtk_radio_button_new_with_label (group, text); - group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio)); - gtk_box_pack_start (GTK_BOX (box), radio, FALSE, FALSE, 0); - - /* Select default */ - - e_dialog_widget_hook_value (dialog, radio, view, (gpointer) print_view_map); - - gtk_widget_show_all (box); - return box; -} - -void -print_calendar (GnomeCalendar *gcal, gboolean preview, time_t at, PrintView default_view) -{ - GnomePrinter *printer; - GnomePrintMaster *gpm; - GnomePrintContext *pc; - int copies, collate; - const GnomePaper *paper_info; - double l, r, t, b, todo, header; - char buf[100]; - time_t when; - - g_return_if_fail (gcal != NULL); - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - - printer = NULL; - copies = 1; - collate = FALSE; - - if (!preview) { - GtkWidget *gpd; - GtkWidget *range; - int view; - - gpd = gnome_print_dialog_new (_("Print Calendar"), - GNOME_PRINT_DIALOG_RANGE | GNOME_PRINT_DIALOG_COPIES); - - view = (int) default_view; - range = range_selector_new (gpd, at, &view); - gnome_print_dialog_construct_range_custom (GNOME_PRINT_DIALOG (gpd), range); - - gnome_dialog_set_default (GNOME_DIALOG (gpd), GNOME_PRINT_PRINT); - - /* Run dialog */ - - switch (gnome_dialog_run (GNOME_DIALOG (gpd))) { - case GNOME_PRINT_PRINT: - break; - - case GNOME_PRINT_PREVIEW: - preview = TRUE; - break; - - case -1: - return; - - default: - gnome_dialog_close (GNOME_DIALOG (gpd)); - return; - } - - e_dialog_get_values (gpd); - default_view = (PrintView) view; - - gnome_print_dialog_get_copies (GNOME_PRINT_DIALOG (gpd), &copies, &collate); - printer = gnome_print_dialog_get_printer (GNOME_PRINT_DIALOG (gpd)); - - gnome_dialog_close (GNOME_DIALOG (gpd)); - } - - /* FIXME: allow configuration of paper size */ - - gpm = gnome_print_master_new (); - - paper_info = gnome_paper_with_name (gnome_paper_name_default ()); - gnome_print_master_set_paper (gpm, paper_info); - - if (printer) - gnome_print_master_set_printer (gpm, printer); - - gnome_print_master_set_copies (gpm, copies, collate); - - pc = gnome_print_master_get_context (gpm); - - l = gnome_paper_lmargin (paper_info); - r = gnome_paper_pswidth (paper_info) - gnome_paper_rmargin (paper_info); - t = gnome_paper_psheight (paper_info) - gnome_paper_tmargin (paper_info); - b = gnome_paper_bmargin (paper_info); - - /* depending on the view, do a different output */ - switch (default_view) { - case PRINT_VIEW_DAY: { - int i, days = 1; - - for (i = 0; i < days; i++) { - todo = ((r - l) / 5) * 4 + l; - header = t - 70; - print_todo_details (pc, gcal, 0, INT_MAX, todo, r, header, b); - print_day_details (pc, gcal, at, l, todo - 2.0, header, b); - - print_border (pc, l, r, t, header + 2.0, 1.0, 0.9); - - print_month_small (pc, gcal, at, r - 190, r - 104, t - 4, - header + 8, DATE_MONTH | DATE_YEAR, at, at, FALSE); - print_month_small (pc, gcal, time_add_month (at, 1), r - 90, r - 4, t - 4, - header + 8, DATE_MONTH | DATE_YEAR, 0, 0, FALSE); - - format_date (at, DATE_DAY | DATE_MONTH | DATE_YEAR, buf, 100); - print_text_size (pc, 24, buf, ALIGN_LEFT, l + 3, todo, t - 3, header); - - format_date (at, DATE_DAYNAME, buf, 100); - print_text_size (pc, 18, buf, ALIGN_LEFT, l + 3, todo, t - 27 - 4, header); - gnome_print_showpage (pc); - at = time_add_day (at, 1); - } - break; - } - - case PRINT_VIEW_WEEK: - header = t - 70; - print_week_summary (pc, gcal, at, l, r, header, b); - - /* more solid total outline */ - print_border (pc, l, r, header, b, 1.0, -1.0); - - /* header border */ - print_border (pc, l, r, t, header + 2.0, 1.0, 0.9); - - when = time_week_begin (at); - when = time_add_day (when, 1); - - print_month_small (pc, gcal, at, r - 90, r - 4, t - 4, - header + 8, DATE_MONTH | DATE_YEAR, when, time_add_week (when, 1), - FALSE); - print_month_small (pc, gcal, time_add_month (at, -1), r - 190, r - 104, t - 4, - header + 8, DATE_MONTH | DATE_YEAR, when, time_add_week (when, 1), - FALSE); - - format_date (when, DATE_DAY | DATE_MONTH | DATE_YEAR, buf, 100); - print_text_size (pc, 24, buf, ALIGN_LEFT, l + 3, r, t - 4, header); - - when = time_add_day (when, 6); - format_date (when, DATE_DAY | DATE_MONTH | DATE_YEAR, buf, 100); - print_text_size (pc, 24, buf, ALIGN_LEFT, l + 3, r, t - 24 - 3, header); - gnome_print_showpage (pc); - break; - - case PRINT_VIEW_MONTH: - header = t - 70; - gnome_print_rotate (pc, 90); - gnome_print_translate (pc, 0, -gnome_paper_pswidth (paper_info)); - /*print_month_summary(pc, cal, at, l, r, header, b);*/ - print_month_summary (pc, gcal, at, b, t, r - 70, l); - - print_border (pc, b, t, r, r - 72.0, 1.0, 0.9); - - print_month_small (pc, gcal, time_add_month (at, 1), - t - (t - b) / 7 + 2, t - 8, r - 4, r - 68, - DATE_MONTH | DATE_YEAR, 0, 0, FALSE); - print_month_small (pc, gcal, time_add_month (at, -1), - b + 8, b + (t - b) / 7 - 2, r - 4, r - 68, - DATE_MONTH | DATE_YEAR, 0, 0, FALSE); - - /* centered title */ - format_date (at, DATE_MONTH | DATE_YEAR, buf, 100); - print_text_size (pc, 24, buf, ALIGN_CENTRE, b + 3, t, r - 3, l); - gnome_print_showpage (pc); - break; - - case PRINT_VIEW_YEAR: -#if 0 - /* landscape */ - gnome_print_rotate(pc, 90); - gnome_print_translate(pc, 0, -gnome_paper_pswidth(paper_info)); - print_year_summary(pc, gcal, at, b, t, r-50, l, FALSE); - - /* centered title */ - format_date(at, DATE_YEAR, buf, 100); - print_text_size(pc, 24, buf, ALIGN_CENTRE, b+3, t, r-3, l); -#else - /* portrait */ - print_year_summary(pc, gcal, at, l, r, t-50, b, TRUE); - - /* centered title */ - format_date(at, DATE_YEAR, buf, 100); - print_text_size(pc, 24, buf, ALIGN_CENTRE, l+3, r, t-3, b); -#endif - gnome_print_showpage(pc); - break; - - default: - g_assert_not_reached (); - } - - gnome_print_master_close (gpm); - - if (preview) { - GnomePrintMasterPreview *gpmp; - - gpmp = gnome_print_master_preview_new (gpm, _("Print Preview")); - gtk_widget_show (GTK_WIDGET (gpmp)); - } else - gnome_print_master_print (gpm); - - gtk_object_unref (GTK_OBJECT (gpm)); -} diff --git a/calendar/gui/print.h b/calendar/gui/print.h deleted file mode 100644 index e88c4a8e01..0000000000 --- a/calendar/gui/print.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Evolution calendar - Print support - * - * Copyright (C) 2000 Helix Code, Inc. - * - * Authors: Michael Zucchi <notzed@helixcode.com> - * Federico Mena-Quintero <federico@helixcode.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef PRINT_H -#define PRINT_H - -#include "gnome-cal.h" - - - -typedef enum { - PRINT_VIEW_DAY, - PRINT_VIEW_WEEK, - PRINT_VIEW_MONTH, - PRINT_VIEW_YEAR -} PrintView; - -void print_calendar (GnomeCalendar *gcal, gboolean preview, time_t at, PrintView default_view); - - - -#endif diff --git a/calendar/gui/recur.xpm b/calendar/gui/recur.xpm deleted file mode 100644 index bb34fa4568..0000000000 --- a/calendar/gui/recur.xpm +++ /dev/null @@ -1,21 +0,0 @@ -/* XPM */ -static char * recur_xpm[] = { -"16 16 2 1", -" c None", -". c #333366", -" ", -" ", -" .. ..... ", -" ... .... ", -" .. .... ", -" .. ..... ", -" .. . .. ", -" .. .. ", -" .. . .. ", -" ..... .. ", -" .... .. ", -" .... ... ", -" ..... .. ", -" ", -" ", -" "}; diff --git a/calendar/gui/tag-calendar.c b/calendar/gui/tag-calendar.c deleted file mode 100644 index 12cc264f1c..0000000000 --- a/calendar/gui/tag-calendar.c +++ /dev/null @@ -1,172 +0,0 @@ -/* Evolution calendar - Utilities for tagging ECalendar widgets - * - * Copyright (C) 2000 Helix Code, Inc. - * - * Authors: Damon Chaplin <damon@helixcode.com> - * Federico Mena-Quintero <federico@helixcode.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <cal-util/timeutil.h> -#include "tag-calendar.h" - - - -struct calendar_tag_closure { - ECalendarItem *calitem; - time_t start_time; - time_t end_time; -}; - -/* Clears all the tags in a calendar and fills a closure structure with the - * necessary information for iterating over occurrences. - * Returns FALSE if the calendar has no dates shown. - */ -static gboolean -prepare_tag (ECalendar *ecal, struct calendar_tag_closure *c) -{ - gint start_year, start_month, start_day; - gint end_year, end_month, end_day; - struct tm start_tm = { 0 }, end_tm = { 0 }; - - e_calendar_item_clear_marks (ecal->calitem); - - if (!e_calendar_item_get_date_range (ecal->calitem, - &start_year, &start_month, - &start_day, - &end_year, &end_month, &end_day)) - return FALSE; - - start_tm.tm_year = start_year - 1900; - start_tm.tm_mon = start_month; - start_tm.tm_mday = start_day; - start_tm.tm_hour = 0; - start_tm.tm_min = 0; - start_tm.tm_sec = 0; - start_tm.tm_isdst = -1; - - end_tm.tm_year = end_year - 1900; - end_tm.tm_mon = end_month; - end_tm.tm_mday = end_day + 1; - end_tm.tm_hour = 0; - end_tm.tm_min = 0; - end_tm.tm_sec = 0; - end_tm.tm_isdst = -1; - - c->calitem = ecal->calitem; - c->start_time = mktime (&start_tm); - c->end_time = mktime (&end_tm); - - return TRUE; -} - -/* Marks the specified range in an ECalendar; called from cal_client_generate_instances() */ -static gboolean -tag_calendar_cb (CalComponent *comp, - time_t istart, - time_t iend, - gpointer data) -{ - struct calendar_tag_closure *c = data; - time_t t; - - t = time_day_begin (istart); - - do { - struct tm tm; - - tm = *localtime (&t); - - e_calendar_item_mark_day (c->calitem, tm.tm_year + 1900, - tm.tm_mon, tm.tm_mday, - E_CALENDAR_ITEM_MARK_BOLD); - - t = time_day_end (t); - } while (t < iend); - - return TRUE; -} - -/** - * tag_calendar_by_client: - * @ecal: Calendar widget to tag. - * @client: A calendar client object. - * - * Tags an #ECalendar widget with the events that occur in its current time - * range. The occurrences are extracted from the specified calendar @client. - **/ -void -tag_calendar_by_client (ECalendar *ecal, CalClient *client) -{ - struct calendar_tag_closure c; - - g_return_if_fail (ecal != NULL); - g_return_if_fail (E_IS_CALENDAR (ecal)); - g_return_if_fail (client != NULL); - g_return_if_fail (IS_CAL_CLIENT (client)); - - /* If the ECalendar isn't visible, we just return. */ - if (!GTK_WIDGET_VISIBLE (ecal)) - return; - - if (cal_client_get_load_state (client) != CAL_CLIENT_LOAD_LOADED) - return; - - if (!prepare_tag (ecal, &c)) - return; - -#if 0 - g_print ("DateNavigator generating instances\n"); -#endif - cal_client_generate_instances (client, CALOBJ_TYPE_EVENT, - c.start_time, c.end_time, - tag_calendar_cb, &c); -} - -/** - * tag_calendar_by_comp: - * @ecal: Calendar widget to tag. - * @comp: A calendar component object. - * - * Tags an #ECalendar widget with any occurrences of a specific calendar - * component that occur within the calendar's current time range. - **/ -void -tag_calendar_by_comp (ECalendar *ecal, CalComponent *comp) -{ - struct calendar_tag_closure c; - - g_return_if_fail (ecal != NULL); - g_return_if_fail (E_IS_CALENDAR (ecal)); - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - - /* If the ECalendar isn't visible, we just return. */ - if (!GTK_WIDGET_VISIBLE (ecal)) - return; - - if (!prepare_tag (ecal, &c)) - return; - -#if 0 - g_print ("DateNavigator generating instances\n"); -#endif - cal_recur_generate_instances (comp, c.start_time, c.end_time, tag_calendar_cb, &c); -} diff --git a/calendar/gui/tag-calendar.h b/calendar/gui/tag-calendar.h deleted file mode 100644 index 970035b03c..0000000000 --- a/calendar/gui/tag-calendar.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Evolution calendar - Utilities for tagging ECalendar widgets - * - * Copyright (C) 2000 Helix Code, Inc. - * - * Authors: Damon Chaplin <damon@helixcode.com> - * Federico Mena-Quintero <federico@helixcode.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef TAG_CALENDAR_H -#define TAG_CALENDAR_H - -#include <widgets/misc/e-calendar.h> -#include <cal-client/cal-client.h> - -void tag_calendar_by_client (ECalendar *ecal, CalClient *client); -void tag_calendar_by_comp (ECalendar *ecal, CalComponent *comp); - -#endif diff --git a/calendar/gui/task-assigned-to.xpm b/calendar/gui/task-assigned-to.xpm deleted file mode 100644 index d60eeafa2d..0000000000 --- a/calendar/gui/task-assigned-to.xpm +++ /dev/null @@ -1,30 +0,0 @@ -/* XPM */ -static char * task_assigned_to_xpm[] = { -"16 16 11 1", -" c None", -". c #000000", -"+ c #FFFFFF", -"@ c #F3F3F3", -"# c #CCCCCC", -"$ c #B2B2B2", -"% c #ECECEC", -"& c #ABCCAB", -"* c #768E76", -"= c #5E705E", -"- c #EEEEEE", -" . . . . . ", -" ........... ", -" .+.+.+.+.+.@. ", -" .+.#.#.#.#.$. ", -" .+%%%%%%%%%$. ", -" .+#######..$. ", -" .+%%%%%%%.&.. ", -" .+##......&&. ", -" .+%%.&&&&&&&&. ", -" .+##.&*&*&*&*&.", -" .+%%.========. ", -" .+##......==. ", -" .+%%%%%%%.=.. ", -" .-$$$$$$$..$. ", -" ........... ", -" "}; diff --git a/calendar/gui/task-assigned.xpm b/calendar/gui/task-assigned.xpm deleted file mode 100644 index 9b245c0c49..0000000000 --- a/calendar/gui/task-assigned.xpm +++ /dev/null @@ -1,30 +0,0 @@ -/* XPM */ -static char * task_assigned_xpm[] = { -"16 16 11 1", -" c None", -". c #000000", -"+ c #FFFFFF", -"@ c #F3F3F3", -"# c #CCCCCC", -"$ c #B2B2B2", -"% c #ECECEC", -"& c #FFCC66", -"* c #CC9933", -"= c #996600", -"- c #EEEEEE", -" . . . . . ", -" ........... ", -" .+.+.+.+.+.@. ", -" .+.#.#.#.#.$. ", -" .+%%%%%%%%%$. ", -" .+##..#####$. ", -" .+%%.&.%%%%$. ", -"......&&.###$. ", -".&&&&&&&&.%%$. ", -".&*&*&*&*&.#$. ", -".========.%%$. ", -"......==.###$. ", -" .+%%.=.%%%%$. ", -" .-$$..$$$$$$. ", -" ........... ", -" "}; diff --git a/calendar/gui/task-recurring.xpm b/calendar/gui/task-recurring.xpm deleted file mode 100644 index 634cd87a84..0000000000 --- a/calendar/gui/task-recurring.xpm +++ /dev/null @@ -1,59 +0,0 @@ -/* XPM */ -static char * task_recurring_xpm[] = { -"16 16 40 1", -" c None", -". c #000000", -"+ c #FFFFFF", -"@ c #F3F3F3", -"# c #CCCCCC", -"$ c #B2B2B2", -"% c #ECECEC", -"& c #BFBFC3", -"* c #A2A2B0", -"= c #454572", -"- c #9898A9", -"; c #85859C", -"> c #333366", -", c #4F4F79", -"' c #B3B3C3", -") c #A3A3B7", -"! c #9696AD", -"~ c #464672", -"{ c #7F7F99", -"] c #C9C9CA", -"^ c #3D3D6D", -"/ c #3B3B6B", -"( c #A4A4B8", -"_ c #B5B5C4", -": c #D1D1D8", -"< c #9191A4", -"[ c #B5B5BD", -"} c #9F9FAE", -"| c #4A4A76", -"1 c #40406F", -"2 c #E9E9E9", -"3 c #8F8FA9", -"4 c #9D9DAC", -"5 c #9090A4", -"6 c #55557F", -"7 c #ADADBE", -"8 c #484875", -"9 c #B9B9C7", -"0 c #DCDCE0", -"a c #EEEEEE", -" . . . . . ", -" ........... ", -" .+.+.+.+.+.@. ", -" .+.#.#.#.#.$. ", -" .+%%%%%%%%%$. ", -" .+&*=-#;>>,$. ", -" .+'>)%%!>>'$. ", -" .+~{]##;^/~$. ", -" .+>(%%%_:(>$. ", -" .+><[}###<>$. ", -" .+|^1!%%23|$. ", -" .+4>>;##5>4$. ", -" .+6>>!%7890$. ", -" .a$$$$$$$$$$. ", -" ........... ", -" "}; diff --git a/calendar/gui/task.xpm b/calendar/gui/task.xpm deleted file mode 100644 index 4a53c3e9ab..0000000000 --- a/calendar/gui/task.xpm +++ /dev/null @@ -1,27 +0,0 @@ -/* XPM */ -static char * task_xpm[] = { -"16 16 8 1", -" c None", -". c #000000", -"+ c #FFFFFF", -"@ c #F3F3F3", -"# c #CCCCCC", -"$ c #B2B2B2", -"% c #ECECEC", -"& c #EEEEEE", -" . . . . . ", -" ........... ", -" .+.+.+.+.+.@. ", -" .+.#.#.#.#.$. ", -" .+%%%%%%%%%$. ", -" .+#########$. ", -" .+%%%%%%%%%$. ", -" .+#########$. ", -" .+%%%%%%%%%$. ", -" .+#########$. ", -" .+%%%%%%%%%$. ", -" .+#########$. ", -" .+%%%%%%%%%$. ", -" .&$$$$$$$$$$. ", -" ........... ", -" "}; diff --git a/calendar/gui/tasks-control-factory.c b/calendar/gui/tasks-control-factory.c deleted file mode 100644 index 635bd72bc0..0000000000 --- a/calendar/gui/tasks-control-factory.c +++ /dev/null @@ -1,77 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* tasks-control-factory.c - * - * Copyright (C) 2000 Helix Code, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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. - * - * Authors: Ettore Perazzoli - * Damon Chaplin <damon@helixcode.com> - */ - -#include <config.h> -#include <bonobo.h> -#include <bonobo/bonobo-control.h> - -#include <liboaf/liboaf.h> - -#include "tasks-control-factory.h" -#include "tasks-control.h" - - -#define TASKS_CONTROL_FACTORY_ID "OAFIID:GNOME_Evolution_Tasks_ControlFactory" - - -CORBA_Environment ev; -CORBA_ORB orb; - -static BonoboObject *tasks_control_factory_fn (BonoboGenericFactory *Factory, - void *data); - - -/* Registers the factory with Bonobo. Should be called on startup. */ -void -tasks_control_factory_init (void) -{ - static BonoboGenericFactory *factory = NULL; - - if (factory != NULL) - return; - - factory = bonobo_generic_factory_new (TASKS_CONTROL_FACTORY_ID, - tasks_control_factory_fn, NULL); - - if (factory == NULL) - g_error ("I could not register a Tasks control factory."); -} - - -/* Callback factory function to create a tasks control. */ -static BonoboObject * -tasks_control_factory_fn (BonoboGenericFactory *Factory, - void *data) -{ - BonoboControl *control; - - control = tasks_control_new (); - - if (control) - return BONOBO_OBJECT (control); - else - return NULL; -} - - diff --git a/calendar/gui/tasks-control-factory.h b/calendar/gui/tasks-control-factory.h deleted file mode 100644 index 217ebc68fc..0000000000 --- a/calendar/gui/tasks-control-factory.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* tasks-control-factory.h - * - * Copyright (C) 2000 Helix Code, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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. - * - * Authors: Federico Mena Quintero <federico@helixcode.com> - * Damon Chaplin <damon@helixcode.com> - */ - -#ifndef _TASKS_CONTROL_FACTORY_H_ -#define _TASKS_CONTROL_FACTORY_H_ - -void tasks_control_factory_init (void); -BonoboControl *tasks_control_factory_new_control (void); - -#endif /* _TASKS_CONTROL_FACTORY_H_ */ diff --git a/calendar/gui/tasks-control.c b/calendar/gui/tasks-control.c deleted file mode 100644 index 08b49ff306..0000000000 --- a/calendar/gui/tasks-control.c +++ /dev/null @@ -1,231 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* tasks-control.c - * - * Copyright (C) 2000 Helix Code, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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. - * - * Authors: Damon Chaplin <damon@helixcode.com> - * Ettore Perazzoli - */ - -#include <config.h> -#include <gnome.h> -#include <bonobo.h> -#include <bonobo/bonobo-control.h> -#include "e-tasks.h" -#include "tasks-control.h" - - -#define TASKS_CONTROL_PROPERTY_URI "folder_uri" -#define TASKS_CONTROL_PROPERTY_URI_IDX 1 - - -static void tasks_control_properties_init (BonoboControl *control, - ETasks *tasks); -static void tasks_control_get_property (BonoboPropertyBag *bag, - BonoboArg *arg, - guint arg_id, - CORBA_Environment *ev, - gpointer user_data); -static void tasks_control_set_property (BonoboPropertyBag *bag, - const BonoboArg *arg, - guint arg_id, - CORBA_Environment *ev, - gpointer user_data); -static void tasks_control_activate_cb (BonoboControl *control, - gboolean activate, - gpointer user_data); -static void tasks_control_activate (BonoboControl *control, - ETasks *tasks); -static void tasks_control_deactivate (BonoboControl *control); - -static void tasks_control_new_task_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path); - - -BonoboControl * -tasks_control_new (void) -{ - BonoboControl *control; - GtkWidget *tasks; - - tasks = e_tasks_new (); - if (!tasks) - return NULL; - - gtk_widget_show (tasks); - - control = bonobo_control_new (tasks); - if (!control) { - g_message ("control_factory_fn(): could not create the control!"); - return NULL; - } - - tasks_control_properties_init (control, E_TASKS (tasks)); - - gtk_signal_connect (GTK_OBJECT (control), "activate", - GTK_SIGNAL_FUNC (tasks_control_activate_cb), - tasks); - - return control; -} - - -/* Creates the property bag for our new control. */ -static void -tasks_control_properties_init (BonoboControl *control, - ETasks *tasks) - -{ - BonoboPropertyBag *pbag; - - pbag = bonobo_property_bag_new (tasks_control_get_property, - tasks_control_set_property, tasks); - - bonobo_property_bag_add (pbag, - TASKS_CONTROL_PROPERTY_URI, - TASKS_CONTROL_PROPERTY_URI_IDX, - BONOBO_ARG_STRING, - NULL, - _("The URI of the tasks folder to display"), - 0); - - bonobo_control_set_properties (control, pbag); -} - - -/* Gets a property of our control. FIXME: Finish. */ -static void -tasks_control_get_property (BonoboPropertyBag *bag, - BonoboArg *arg, - guint arg_id, - CORBA_Environment *ev, - gpointer user_data) -{ - /*GnomeCalendar *gcal = user_data;*/ - - switch (arg_id) { - - case TASKS_CONTROL_PROPERTY_URI_IDX: - /* - if (fb && fb->uri) - BONOBO_ARG_SET_STRING (arg, fb->uri); - else - BONOBO_ARG_SET_STRING (arg, ""); - */ - break; - - default: - g_warning ("Unhandled arg %d\n", arg_id); - } -} - - -static void -tasks_control_set_property (BonoboPropertyBag *bag, - const BonoboArg *arg, - guint arg_id, - CORBA_Environment *ev, - gpointer user_data) -{ - ETasks *tasks = user_data; - char *filename; - - switch (arg_id) { - - case TASKS_CONTROL_PROPERTY_URI_IDX: - filename = g_strdup_printf ("%s/tasks.ics", - BONOBO_ARG_GET_STRING (arg)); - e_tasks_open (tasks, filename); - g_free (filename); - break; - - default: - g_warning ("Unhandled arg %d\n", arg_id); - break; - } -} - - -static void -tasks_control_activate_cb (BonoboControl *control, - gboolean activate, - gpointer user_data) -{ - if (activate) - tasks_control_activate (control, user_data); - else - tasks_control_deactivate (control); -} - - -static BonoboUIVerb verbs [] = { - BONOBO_UI_VERB ("TasksNewTask", tasks_control_new_task_cmd), - - BONOBO_UI_VERB_END -}; - -static void -tasks_control_activate (BonoboControl *control, - ETasks *tasks) -{ - Bonobo_UIContainer remote_uih; - BonoboUIComponent *uic; - - uic = bonobo_control_get_ui_component (control); - g_assert (uic != NULL); - - remote_uih = bonobo_control_get_remote_ui_container (control); - bonobo_ui_component_set_container (uic, remote_uih); - bonobo_object_release_unref (remote_uih, NULL); - - bonobo_ui_component_add_verb_list_with_data (uic, verbs, tasks); - - bonobo_ui_component_freeze (uic, NULL); - - bonobo_ui_util_set_ui (uic, EVOLUTION_DATADIR, - "evolution-tasks.xml", - "evolution-tasks"); - - e_tasks_setup_menus(tasks, uic); - - bonobo_ui_component_thaw (uic, NULL); -} - - -static void -tasks_control_deactivate (BonoboControl *control) -{ - BonoboUIComponent *uic = bonobo_control_get_ui_component (control); - g_assert (uic != NULL); - - bonobo_ui_component_rm (uic, "/", NULL); - bonobo_ui_component_unset_container (uic); -} - - -static void -tasks_control_new_task_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path) -{ - ETasks *tasks = data; - - e_tasks_new_task (tasks); -} - diff --git a/calendar/gui/tasks-control.h b/calendar/gui/tasks-control.h deleted file mode 100644 index d2f0f4e2fb..0000000000 --- a/calendar/gui/tasks-control.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* tasks-control.h - * - * Copyright (C) 2000 Helix Code, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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. - * - * Authors: Federico Mena Quintero <federico@helixcode.com> - * Damon Chaplin <damon@helixcode.com> - */ - -#ifndef _TASKS_CONTROL_H_ -#define _TASKS_CONTROL_H_ - - -BonoboControl *tasks_control_new (void); - - -#endif /* _TASKS_CONTROL_H_ */ diff --git a/calendar/gui/tasks-migrate.c b/calendar/gui/tasks-migrate.c deleted file mode 100644 index a658479cac..0000000000 --- a/calendar/gui/tasks-migrate.c +++ /dev/null @@ -1,308 +0,0 @@ -/* Evolution calendar - Migrate tasks from the calendar folder to the tasks folder - * - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <gtk/gtkwindow.h> -#include <gtk/gtksignal.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <libgnomeui/gnome-dialog-util.h> -#include <cal-client/cal-client.h> -#include "component-factory.h" -#include "tasks-migrate.h" - - - -/* Client for the calendar folder */ -static CalClient *calendar_client = NULL; - -/* Client for the tasks folder */ -static CalClient *tasks_client = NULL; - -/* Whether we have done the migration yet */ -static gboolean migrated = FALSE; - - - -/* Performs the actual migration process */ -static void -migrate (void) -{ - GList *uids; - GList *l; - gboolean success; - gboolean at_least_one; - - g_assert (calendar_client != NULL); - g_assert (tasks_client != NULL); - g_assert (cal_client_get_load_state (calendar_client) == CAL_CLIENT_LOAD_LOADED); - g_assert (cal_client_get_load_state (tasks_client) == CAL_CLIENT_LOAD_LOADED); - - uids = cal_client_get_uids (calendar_client, CALOBJ_TYPE_TODO); - - success = TRUE; - at_least_one = FALSE; - - for (l = uids; l; l = l->next) { - const char *uid; - CalComponent *comp; - CalClientGetStatus status; - - at_least_one = TRUE; - - uid = l->data; - status = cal_client_get_object (calendar_client, uid, &comp); - - switch (status) { - case CAL_CLIENT_GET_SUCCESS: - if (cal_client_update_object (tasks_client, comp)) - cal_client_remove_object (calendar_client, uid); - else - success = FALSE; - - gtk_object_unref (GTK_OBJECT (comp)); - break; - - case CAL_CLIENT_GET_NOT_FOUND: - /* This is OK; the object may have disappeared from the server */ - break; - - case CAL_CLIENT_GET_SYNTAX_ERROR: - success = FALSE; - break; - - default: - g_assert_not_reached (); - } - } - - cal_obj_uid_list_free (uids); - - if (!at_least_one) - return; - - if (success) - gnome_ok_dialog (_("Evolution has taken the tasks that were in your calendar folder " - "and automatically migrated them to the new tasks folder.")); - else - gnome_ok_dialog (_("Evolution has tried to take the tasks that were in your " - "calendar folder and migrate them to the new tasks folder.\n" - "Some of the tasks could not be migrated, so " - "this process may be attempted again in the future.")); -} - -/* Displays an error to indicate that a calendar could not be opened */ -static void -open_error (const char *uri) -{ - char *msg; - - msg = g_strdup_printf (_("Could not open `%s'; no items from the calendar folder " - "will be migrated to the tasks folder."), - uri); - gnome_error_dialog (msg); - g_free (msg); -} - -/* Displays an error to indicate that a URI method is not supported */ -static void -method_error (const char *uri) -{ - char *msg; - - msg = g_strdup_printf (_("The method required to load `%s' is not supported; " - "no items from the calendar folder will be migrated " - "to the tasks folder."), - uri); - gnome_error_dialog (msg); - g_free (msg); -} - -/* Callback used when the tasks client is finished loading */ -static void -tasks_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data) -{ - g_assert (calendar_client != NULL); - g_assert (cal_client_get_load_state (calendar_client) == CAL_CLIENT_LOAD_LOADED); - - switch (status) { - case CAL_CLIENT_OPEN_SUCCESS: - migrate (); - break; - - case CAL_CLIENT_OPEN_ERROR: - open_error (cal_client_get_uri (client)); - migrated = FALSE; - break; - - case CAL_CLIENT_OPEN_NOT_FOUND: - /* This can't happen because we did not specify only_if_exists when - * issuing the open request. - */ - g_assert_not_reached (); - break; - - case CAL_CLIENT_OPEN_METHOD_NOT_SUPPORTED: - method_error (cal_client_get_uri (client)); - migrated = FALSE; - break; - - default: - g_assert_not_reached (); - } - - gtk_object_unref (GTK_OBJECT (calendar_client)); - calendar_client = NULL; - - gtk_object_unref (GTK_OBJECT (tasks_client)); - tasks_client = NULL; -} - -/* Initiates the loading process for the tasks client */ -static gboolean -load_tasks_client (void) -{ - char *uri; - gboolean success; - - g_assert (calendar_client != NULL); - g_assert (cal_client_get_load_state (calendar_client) == CAL_CLIENT_LOAD_LOADED); - - tasks_client = cal_client_new (); - if (!tasks_client) - goto error; - - gtk_signal_connect (GTK_OBJECT (tasks_client), "cal_opened", - GTK_SIGNAL_FUNC (tasks_opened_cb), - NULL); - - uri = g_strdup_printf ("%s/local/Tasks/tasks.ics", evolution_dir); - success = cal_client_open_calendar (tasks_client, uri, FALSE); - g_free (uri); - - if (success) - return TRUE; - - error: - g_message ("load_tasks_client(): could not issue open request for the tasks client"); - - if (tasks_client) { - gtk_object_unref (GTK_OBJECT (tasks_client)); - tasks_client = NULL; - } - - return FALSE; -} - -/* Callback used when the calendar client finishes loading */ -static void -calendar_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data) -{ - switch (status) { - case CAL_CLIENT_OPEN_SUCCESS: - if (!load_tasks_client ()) { - migrated = FALSE; - break; - } - - return; - - case CAL_CLIENT_OPEN_ERROR: - open_error (cal_client_get_uri (client)); - migrated = FALSE; - break; - - case CAL_CLIENT_OPEN_NOT_FOUND: - /* This is OK; the calendar folder did not exist in the first - * place so there is nothing to migrate. - */ - break; - - case CAL_CLIENT_OPEN_METHOD_NOT_SUPPORTED: - method_error (cal_client_get_uri (client)); - migrated = FALSE; - break; - - default: - g_assert_not_reached (); - } - - gtk_object_unref (GTK_OBJECT (calendar_client)); - calendar_client = NULL; -} - -/* Initiates the loading process for the calendar client */ -static gboolean -load_calendar_client (void) -{ - char *uri; - gboolean success; - - /* First we load the calendar client; the tasks client will be loaded - * later only if the former one succeeds. - */ - - calendar_client = cal_client_new (); - if (!calendar_client) - goto error; - - gtk_signal_connect (GTK_OBJECT (calendar_client), "cal_opened", - GTK_SIGNAL_FUNC (calendar_opened_cb), - NULL); - - uri = g_strdup_printf ("%s/local/Calendar/calendar.ics", evolution_dir); - success = cal_client_open_calendar (calendar_client, uri, TRUE); - g_free (uri); - - if (success) - return TRUE; - - error: - g_message ("load_calendar_client(): could not issue open request for the calendar client"); - - if (calendar_client) { - gtk_object_unref (GTK_OBJECT (calendar_client)); - calendar_client = NULL; - } - - return FALSE; -} - -/** - * tasks_migrate: - * - * Initiates the asynchronous process that migrates the tasks from the default - * user calendar folder to the default tasks folder. This is because Evolution - * used to store tasks in the same folder as the calendar by default, but they - * are separate folders now. - **/ -void -tasks_migrate (void) -{ - g_assert (!migrated); - migrated = TRUE; - - if (!load_calendar_client ()) - migrated = FALSE; -} diff --git a/calendar/gui/tasks-migrate.h b/calendar/gui/tasks-migrate.h deleted file mode 100644 index 01f124222b..0000000000 --- a/calendar/gui/tasks-migrate.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Evolution calendar - Migrate tasks from the calendar folder to the tasks folder - * - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef TASKS_MIGRATE_H -#define TASKS_MIGRATE_H - - -void tasks_migrate (void); - - -#endif diff --git a/calendar/gui/test.vcf b/calendar/gui/test.vcf deleted file mode 100644 index bfe93b3c14..0000000000 --- a/calendar/gui/test.vcf +++ /dev/null @@ -1,133 +0,0 @@ -BEGIN:VCALENDAR -PRODID:-//GNOME//NONSGML GnomeCalendar//EN -TZ:MST -VERSION:0.13 -BEGIN:VEVENT -UID:KOrganizer - 846930886 -SEQUENCE:1 -DTSTART:19980601T150000 -DTEND:19980601T150000 -DCREATED:19980402T023558 -LAST-MODIFIED:19980402T023558 -SUMMARY:Cada dos dias de 06/01 al 07/01 -STATUS:NEEDS ACTION -CLASS:PUBLIC -PRIORITY:0 -TRANSP:0 -RELATED-TO:0 -RRULE:D2 19980701T140000 -END:VEVENT - -BEGIN:VEVENT -UID:KOrganizer - 846930886 -SEQUENCE:1 -DTSTART:19980501T140000 -DTEND:19980501T140000 -DCREATED:19980402T023558 -LAST-MODIFIED:19980402T023558 -SUMMARY:5 dias. -STATUS:NEEDS ACTION -CLASS:PUBLIC -PRIORITY:0 -TRANSP:0 -RELATED-TO:0 -RRULE:D1 #5 -END:VEVENT - -BEGIN:VEVENT -UID:KOrganizer - 846930886 -SEQUENCE:1 -DTSTART:19980501T140000 -DTEND:19980501T150000 -DCREATED:19980402T023558 -LAST-MODIFIED:19980429T004635 -SUMMARY:Diariamente de 05/01 al 06/01 -STATUS:NEEDS ACTION -CLASS:PRIVATE -PRIORITY:0 -TRANSP:0 -RELATED-TO:0 -RRULE:D1 19980601T000000 -END:VEVENT - -BEGIN:VEVENT -UID:KOrganizer - 1804289383 -SEQUENCE:1 -DTSTART:19980415T010000 -DTEND:19980415T013000 -DCREATED:19980402T023552 -LAST-MODIFIED:19980330T225948 -SUMMARY:Diario durante 5 dias -STATUS:NEEDS ACTION -CLASS:PUBLIC -PRIORITY:0 -TRANSP:0 -RELATED-TO:0 -RRULE:D1 #5 -END:VEVENT - -BEGIN:VEVENT -UID:KOrganizer - 1804289383 -SEQUENCE:1 -DTSTART:19980415T010000 -DTEND:19980415T013000 -DCREATED:19980402T023552 -LAST-MODIFIED:19980330T225948 -SUMMARY:Diario durante 5 dias -STATUS:NEEDS ACTION -CLASS:PUBLIC -PRIORITY:0 -TRANSP:0 -RELATED-TO:0 -RRULE:D1 #5 -END:VEVENT - -BEGIN:VTODO -UID:KOrganizer - 846930886 -SEQUENCE:1 -DTSTART:19980415T140000 -DUE:19691231T180000 -DCREATED:19980402T023558 -LAST-MODIFIED:19980402T023558 -SUMMARY:Normal -STATUS:NEEDS ACTION -CLASS:PUBLIC -PRIORITY:0 -TRANSP:0 -RELATED-TO:0 -END:VTODO - -BEGIN:VTODO -UID:KOrganizer - 1804289383 -SEQUENCE:1 -DTSTART:19980415T120000 -DUE:19691231T180000 -DCREATED:19980402T023552 -LAST-MODIFIED:19980330T225948 -SUMMARY:Semanal -- 4 semanas -STATUS:NEEDS ACTION -CLASS:PUBLIC -PRIORITY:0 -TRANSP:0 -RELATED-TO:0 -RRULE:W1 WE #4 -END:VTODO - -BEGIN:VTODO -UID:KOrganizer - 1804289383 -SEQUENCE:1 -DTSTART:19980415T003000 -DUE:19691231T180000 -DCREATED:19980402T023552 -LAST-MODIFIED:19980330T225948 -SUMMARY:Semana: Mi, Ju, Vi, Dom (10 veces) -STATUS:NEEDS ACTION -CLASS:PUBLIC -PRIORITY:0 -TRANSP:0 -RELATED-TO:0 -RRULE:W1 SU WE TH FR #10 -END:VTODO - -END:VCALENDAR - diff --git a/calendar/gui/test2.vcf b/calendar/gui/test2.vcf deleted file mode 100644 index 6446507989..0000000000 --- a/calendar/gui/test2.vcf +++ /dev/null @@ -1,133 +0,0 @@ -BEGIN:VCALENDAR -PRODID:-//GNOME//NONSGML GnomeCalendar//EN -TZ:MST -VERSION:0.13 -BEGIN:VEVENT -UID:KOrganizer - 8469308861 -SEQUENCE:1 -DTSTART:19980601T150000 -DTEND:19980601T150000 -DCREATED:19980402T023558 -LAST-MODIFIED:19980402T023558 -SUMMARY:Cada dos dias de 06/01 al 07/01 -STATUS:NEEDS ACTION -CLASS:PUBLIC -PRIORITY:0 -TRANSP:0 -RELATED-TO:0 -RRULE:D2 19980701T140000 -END:VEVENT - -BEGIN:VEVENT -UID:KOrganizer - 8469308862 -SEQUENCE:1 -DTSTART:19980501T140000 -DTEND:19980501T140000 -DCREATED:19980402T023558 -LAST-MODIFIED:19980402T023558 -SUMMARY:5 dias. -STATUS:NEEDS ACTION -CLASS:PUBLIC -PRIORITY:0 -TRANSP:0 -RELATED-TO:0 -RRULE:D1 #5 -END:VEVENT - -BEGIN:VEVENT -UID:KOrganizer - 8469308863 -SEQUENCE:1 -DTSTART:19980501T140000 -DTEND:19980501T150000 -DCREATED:19980402T023558 -LAST-MODIFIED:19980429T004635 -SUMMARY:Diariamente de 05/01 al 06/01 -STATUS:NEEDS ACTION -CLASS:PRIVATE -PRIORITY:0 -TRANSP:0 -RELATED-TO:0 -RRULE:D1 19980601T000000 -END:VEVENT - -BEGIN:VEVENT -UID:KOrganizer - 18042893834 -SEQUENCE:1 -DTSTART:19980415T010000 -DTEND:19980415T013000 -DCREATED:19980402T023552 -LAST-MODIFIED:19980330T225948 -SUMMARY:Diario durante 5 dias -STATUS:NEEDS ACTION -CLASS:PUBLIC -PRIORITY:0 -TRANSP:0 -RELATED-TO:0 -RRULE:D1 #5 -END:VEVENT - -BEGIN:VEVENT -UID:KOrganizer - 18042893835 -SEQUENCE:1 -DTSTART:19980415T010000 -DTEND:19980415T013000 -DCREATED:19980402T023552 -LAST-MODIFIED:19980330T225948 -SUMMARY:Diario durante 5 dias -STATUS:NEEDS ACTION -CLASS:PUBLIC -PRIORITY:0 -TRANSP:0 -RELATED-TO:0 -RRULE:D1 #5 -END:VEVENT - -BEGIN:VTODO -UID:KOrganizer - 8469308866 -SEQUENCE:1 -DTSTART:19980415T140000 -DUE:19691231T180000 -DCREATED:19980402T023558 -LAST-MODIFIED:19980402T023558 -SUMMARY:Normal -STATUS:NEEDS ACTION -CLASS:PUBLIC -PRIORITY:0 -TRANSP:0 -RELATED-TO:0 -END:VTODO - -BEGIN:VTODO -UID:KOrganizer - 18042893837 -SEQUENCE:1 -DTSTART:19980415T120000 -DUE:19691231T180000 -DCREATED:19980402T023552 -LAST-MODIFIED:19980330T225948 -SUMMARY:Semanal -- 4 semanas -STATUS:NEEDS ACTION -CLASS:PUBLIC -PRIORITY:0 -TRANSP:0 -RELATED-TO:0 -RRULE:W1 WE #4 -END:VTODO - -BEGIN:VTODO -UID:KOrganizer - 18042893838 -SEQUENCE:1 -DTSTART:19980415T003000 -DUE:19691231T180000 -DCREATED:19980402T023552 -LAST-MODIFIED:19980330T225948 -SUMMARY:Semana: Mi, Ju, Vi, Dom (10 veces) -STATUS:NEEDS ACTION -CLASS:PUBLIC -PRIORITY:0 -TRANSP:0 -RELATED-TO:0 -RRULE:W1 SU WE TH FR #10 -END:VTODO - -END:VCALENDAR - diff --git a/calendar/gui/topic.dat b/calendar/gui/topic.dat deleted file mode 100644 index edc7813b26..0000000000 --- a/calendar/gui/topic.dat +++ /dev/null @@ -1,2 +0,0 @@ -gnome-cal.html Manual -gnome-cal.html#cmdline Command line options
\ No newline at end of file diff --git a/calendar/gui/weekday-picker.c b/calendar/gui/weekday-picker.c deleted file mode 100644 index 3d19ac8b37..0000000000 --- a/calendar/gui/weekday-picker.c +++ /dev/null @@ -1,573 +0,0 @@ -/* Evolution calendar - Week day picker widget - * - * Copyright (C) 2000 Helix Code, Inc. - * - * Author: Federico Mena-Quintero <federico@helixcode.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtksignal.h> -#include <libgnomeui/gnome-canvas-rect-ellipse.h> -#include <libgnomeui/gnome-canvas-text.h> -#include <libgnome/gnome-i18n.h> -#include "weekday-picker.h" - - - -#define PADDING 2 - -/* Private part of the WeekdayPicker structure */ -struct _WeekdayPickerPrivate { - /* Selected days; see weekday_picker_set_days() */ - guint8 day_mask; - - /* Blocked days; these cannot be modified */ - guint8 blocked_day_mask; - - /* Day that defines the start of the week; 0 = Sunday, ..., 6 = Saturday */ - int week_start_day; - - /* Metrics */ - int font_ascent, font_descent; - int max_letter_width; - - /* Components */ - GnomeCanvasItem *boxes[7]; - GnomeCanvasItem *labels[7]; -}; - - - -/* Signal IDs */ -enum { - CHANGED, - LAST_SIGNAL -}; - -static void weekday_picker_class_init (WeekdayPickerClass *class); -static void weekday_picker_init (WeekdayPicker *wp); -static void weekday_picker_finalize (GtkObject *object); - -static void weekday_picker_realize (GtkWidget *widget); -static void weekday_picker_size_request (GtkWidget *widget, GtkRequisition *requisition); -static void weekday_picker_size_allocate (GtkWidget *widget, GtkAllocation *allocation); -static void weekday_picker_style_set (GtkWidget *widget, GtkStyle *previous_style); - -static GnomeCanvasClass *parent_class; - -static guint wp_signals[LAST_SIGNAL]; - - - -/** - * weekday_picker_get_type: - * - * Registers the #WeekdayPicker class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the #WeekdayPicker class. - **/ -GtkType -weekday_picker_get_type (void) -{ - static GtkType weekday_picker_type = 0; - - if (!weekday_picker_type) { - static const GtkTypeInfo weekday_picker_info = { - "WeekdayPicker", - sizeof (WeekdayPicker), - sizeof (WeekdayPickerClass), - (GtkClassInitFunc) weekday_picker_class_init, - (GtkObjectInitFunc) weekday_picker_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - weekday_picker_type = gtk_type_unique (GNOME_TYPE_CANVAS, &weekday_picker_info); - } - - return weekday_picker_type; -} - -/* Class initialization function for the weekday picker */ -static void -weekday_picker_class_init (WeekdayPickerClass *class) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - - object_class = (GtkObjectClass *) class; - widget_class = (GtkWidgetClass *) class; - - parent_class = gtk_type_class (GNOME_TYPE_CANVAS); - - wp_signals[CHANGED] = - gtk_signal_new ("changed", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (WeekdayPickerClass, changed), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - gtk_object_class_add_signals (object_class, wp_signals, LAST_SIGNAL); - - object_class->finalize = weekday_picker_finalize; - - widget_class->realize = weekday_picker_realize; - widget_class->size_request = weekday_picker_size_request; - widget_class->size_allocate = weekday_picker_size_allocate; - widget_class->style_set = weekday_picker_style_set; - - class->changed = NULL; -} - -/* Event handler for the day items */ -static gint -day_event_cb (GnomeCanvasItem *item, GdkEvent *event, gpointer data) -{ - WeekdayPicker *wp; - WeekdayPickerPrivate *priv; - int i; - guint8 day_mask; - - wp = WEEKDAY_PICKER (data); - priv = wp->priv; - - if (!(event->type == GDK_BUTTON_PRESS && event->button.button == 1)) - return FALSE; - - /* Find which box was clicked */ - - for (i = 0; i < 7; i++) - if (priv->boxes[i] == item || priv->labels[i] == item) - break; - - g_assert (i != 7); - - /* Turn on that day */ - - i += priv->week_start_day; - if (i >= 7) - i -= 7; - - if (priv->blocked_day_mask & (0x1 << i)) - return TRUE; - - if (priv->day_mask & (0x1 << i)) - day_mask = priv->day_mask & ~(0x1 << i); - else - day_mask = priv->day_mask | (0x1 << i); - - weekday_picker_set_days (wp, day_mask); - - return TRUE; -} - - -/* Creates the canvas items for the weekday picker. The items are empty until - * they are configured elsewhere. - */ -static void -create_items (WeekdayPicker *wp) -{ - WeekdayPickerPrivate *priv; - GnomeCanvasGroup *parent; - int i; - - priv = wp->priv; - - parent = gnome_canvas_root (GNOME_CANVAS (wp)); - - for (i = 0; i < 7; i++) { - priv->boxes[i] = gnome_canvas_item_new (parent, - GNOME_TYPE_CANVAS_RECT, - NULL); - gtk_signal_connect (GTK_OBJECT (priv->boxes[i]), "event", - GTK_SIGNAL_FUNC (day_event_cb), - wp); - - priv->labels[i] = gnome_canvas_item_new (parent, - GNOME_TYPE_CANVAS_TEXT, - NULL); - gtk_signal_connect (GTK_OBJECT (priv->labels[i]), "event", - GTK_SIGNAL_FUNC (day_event_cb), - wp); - } -} - -/* Object initialization function for the weekday picker */ -static void -weekday_picker_init (WeekdayPicker *wp) -{ - WeekdayPickerPrivate *priv; - - GTK_WIDGET_UNSET_FLAGS (wp, GTK_CAN_FOCUS); - - priv = g_new0 (WeekdayPickerPrivate, 1); - - wp->priv = priv; - - create_items (wp); -} - -/* Finalize handler for the weekday picker */ -static void -weekday_picker_finalize (GtkObject *object) -{ - WeekdayPicker *wp; - WeekdayPickerPrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_WEEKDAY_PICKER (object)); - - wp = WEEKDAY_PICKER (object); - priv = wp->priv; - - g_free (priv); - wp->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->finalize) - (* GTK_OBJECT_CLASS (parent_class)->finalize) (object); -} - -static void -colorize_items (WeekdayPicker *wp) -{ - WeekdayPickerPrivate *priv; - GdkColor *outline; - GdkColor *fill, *sel_fill; - GdkColor *text_fill, *sel_text_fill; - int i; - - priv = wp->priv; - - outline = >K_WIDGET (wp)->style->fg[GTK_WIDGET_STATE (wp)]; - - fill = >K_WIDGET (wp)->style->base[GTK_WIDGET_STATE (wp)]; - text_fill = >K_WIDGET (wp)->style->fg[GTK_WIDGET_STATE (wp)]; - - sel_fill = >K_WIDGET (wp)->style->bg[GTK_STATE_SELECTED]; - sel_text_fill = >K_WIDGET (wp)->style->fg[GTK_STATE_SELECTED]; - - for (i = 0; i < 7; i++) { - int day; - GdkColor *f, *t; - - day = i + priv->week_start_day; - if (day >= 7) - day -= 7; - - if (priv->day_mask & (0x1 << day)) { - f = sel_fill; - t = sel_text_fill; - } else { - f = fill; - t = text_fill; - } - - gnome_canvas_item_set (priv->boxes[i], - "fill_color_gdk", f, - "outline_color_gdk", outline, - NULL); - - gnome_canvas_item_set (priv->labels[i], - "fill_color_gdk", t, - NULL); - } -} - -/* Configures the items in the weekday picker by setting their attributes. */ -static void -configure_items (WeekdayPicker *wp) -{ - WeekdayPickerPrivate *priv; - int width, height; - int box_width; - const char *str; - int i; - - priv = wp->priv; - - width = GTK_WIDGET (wp)->allocation.width; - height = GTK_WIDGET (wp)->allocation.height; - - box_width = (width - 1) / 7; - str = _("SMTWTFS"); - - for (i = 0; i < 7; i++) { - char *c; - int day; - - day = i + priv->week_start_day; - if (day >= 7) - day -= 7; - - gnome_canvas_item_set (priv->boxes[i], - "x1", (double) (i * box_width), - "y1", (double) 0, - "x2", (double) ((i + 1) * box_width), - "y2", (double) (height - 1), - "width_pixels", 0, - NULL); - - c = g_strndup (str + day, 1); - gnome_canvas_item_set (priv->labels[i], - "text", c, - "font_gdk", GTK_WIDGET (wp)->style->font, - "x", (double) (i * box_width) + box_width / 2.0, - "y", (double) (1 + PADDING), - "anchor", GTK_ANCHOR_N, - NULL); - g_free (c); - } - - colorize_items (wp); -} - -/* Realize handler for the weekday picker */ -static void -weekday_picker_realize (GtkWidget *widget) -{ - WeekdayPicker *wp; - - wp = WEEKDAY_PICKER (widget); - - if (GTK_WIDGET_CLASS (parent_class)->realize) - (* GTK_WIDGET_CLASS (parent_class)->realize) (widget); - - configure_items (wp); -} - -/* Size_request handler for the weekday picker */ -static void -weekday_picker_size_request (GtkWidget *widget, GtkRequisition *requisition) -{ - WeekdayPicker *wp; - WeekdayPickerPrivate *priv; - - wp = WEEKDAY_PICKER (widget); - priv = wp->priv; - - requisition->width = (priv->max_letter_width + 2 * PADDING + 1) * 7 + 1; - requisition->height = (priv->font_ascent + priv->font_descent + 2 * PADDING + 2); -} - -/* Size_allocate handler for the weekday picker */ -static void -weekday_picker_size_allocate (GtkWidget *widget, GtkAllocation *allocation) -{ - WeekdayPicker *wp; - - wp = WEEKDAY_PICKER (widget); - - if (GTK_WIDGET_CLASS (parent_class)->size_allocate) - (* GTK_WIDGET_CLASS (parent_class)->size_allocate) (widget, allocation); - - gnome_canvas_set_scroll_region (GNOME_CANVAS (wp), - 0, 0, allocation->width, allocation->height); - - configure_items (wp); -} - -/* Style_set handler for the weekday picker */ -static void -weekday_picker_style_set (GtkWidget *widget, GtkStyle *previous_style) -{ - WeekdayPicker *wp; - WeekdayPickerPrivate *priv; - int max_width; - const char *str; - int i, len; - - wp = WEEKDAY_PICKER (widget); - priv = wp->priv; - - priv->font_ascent = widget->style->font->ascent; - priv->font_descent = widget->style->font->descent; - - max_width = 0; - - str = _("SMTWTFS"); - len = strlen (str); - - for (i = 0; i < len; i++) { - int w; - - w = gdk_char_measure (widget->style->font, str[i]); - if (w > max_width) - max_width = w; - } - - priv->max_letter_width = max_width; - - configure_items (wp); - - if (GTK_WIDGET_CLASS (parent_class)->style_set) - (* GTK_WIDGET_CLASS (parent_class)->style_set) (widget, previous_style); -} - - - -/** - * weekday_picker_new: - * @void: - * - * Creates a new weekday picker widget. - * - * Return value: A newly-created weekday picker. - **/ -GtkWidget * -weekday_picker_new (void) -{ - return gtk_type_new (TYPE_WEEKDAY_PICKER); -} - -/** - * weekday_picker_set_days: - * @wp: A weekday picker. - * @day_mask: Bitmask with the days to be selected. - * - * Sets the days that are selected in a weekday picker. In the @day_mask, - * Sunday is bit 0, Monday is bit 1, etc. - **/ -void -weekday_picker_set_days (WeekdayPicker *wp, guint8 day_mask) -{ - WeekdayPickerPrivate *priv; - - g_return_if_fail (wp != NULL); - g_return_if_fail (IS_WEEKDAY_PICKER (wp)); - - priv = wp->priv; - - priv->day_mask = day_mask; - colorize_items (wp); - - gtk_signal_emit (GTK_OBJECT (wp), wp_signals[CHANGED]); -} - -/** - * weekday_picker_get_days: - * @wp: A weekday picker. - * - * Queries the days that are selected in a weekday picker. - * - * Return value: Bit mask of selected days. Sunday is bit 0, Monday is bit 1, - * etc. - **/ -guint8 -weekday_picker_get_days (WeekdayPicker *wp) -{ - WeekdayPickerPrivate *priv; - - g_return_val_if_fail (wp != NULL, 0); - g_return_val_if_fail (IS_WEEKDAY_PICKER (wp), 0); - - priv = wp->priv; - return priv->day_mask; -} - -/** - * weekday_picker_set_blocked_days: - * @wp: A weekday picker. - * @blocked_day_mask: Bitmask with the days to be blocked. - * - * Sets the days that the weekday picker will prevent from being modified by the - * user. The @blocked_day_mask is specified in the same way as in - * weekday_picker_set_days(). - **/ -void -weekday_picker_set_blocked_days (WeekdayPicker *wp, guint8 blocked_day_mask) -{ - WeekdayPickerPrivate *priv; - - g_return_if_fail (wp != NULL); - g_return_if_fail (IS_WEEKDAY_PICKER (wp)); - - priv = wp->priv; - priv->blocked_day_mask = blocked_day_mask; -} - -/** - * weekday_picker_get_blocked_days: - * @wp: A weekday picker. - * - * Queries the set of days that the weekday picker prevents from being modified - * by the user. - * - * Return value: Bit mask of blocked days, with the same format as that returned - * by weekday_picker_get_days(). - **/ -guint -weekday_picker_get_blocked_days (WeekdayPicker *wp) -{ - WeekdayPickerPrivate *priv; - - g_return_val_if_fail (wp != NULL, 0); - g_return_val_if_fail (IS_WEEKDAY_PICKER (wp), 0); - - priv = wp->priv; - return priv->blocked_day_mask; -} - -/** - * weekday_picker_set_week_start_day: - * @wp: A weekday picker. - * @week_start_day: Index of the day that defines the start of the week; 0 is - * Sunday, 1 is Monday, etc. - * - * Sets the day that defines the start of the week for a weekday picker. - **/ -void -weekday_picker_set_week_start_day (WeekdayPicker *wp, int week_start_day) -{ - WeekdayPickerPrivate *priv; - - g_return_if_fail (wp != NULL); - g_return_if_fail (IS_WEEKDAY_PICKER (wp)); - g_return_if_fail (week_start_day >= 0 && week_start_day < 7); - - priv = wp->priv; - priv->week_start_day = week_start_day; - - configure_items (wp); -} - -/** - * weekday_picker_get_week_start_day: - * @wp: A weekday picker. - * - * Queries the day that defines the start of the week in a weekday picker. - * - * Return value: Index of the day that defines the start of the week. See - * weekday_picker_set_week_start_day() to see how this is represented. - **/ -int -weekday_picker_get_week_start_day (WeekdayPicker *wp) -{ - WeekdayPickerPrivate *priv; - - g_return_val_if_fail (wp != NULL, -1); - g_return_val_if_fail (IS_WEEKDAY_PICKER (wp), -1); - - priv = wp->priv; - return priv->week_start_day; -} diff --git a/calendar/gui/weekday-picker.h b/calendar/gui/weekday-picker.h deleted file mode 100644 index 00c51b7a62..0000000000 --- a/calendar/gui/weekday-picker.h +++ /dev/null @@ -1,73 +0,0 @@ -/* Evolution calendar - Week day picker widget - * - * Copyright (C) 2000 Helix Code, Inc. - * - * Author: Federico Mena-Quintero <federico@helixcode.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef WEEKDAY_PICKER_H -#define WEEKDAY_PICKER_H - -#include <libgnome/gnome-defs.h> -#include <libgnomeui/gnome-canvas.h> - -BEGIN_GNOME_DECLS - - - -#define TYPE_WEEKDAY_PICKER (weekday_picker_get_type ()) -#define WEEKDAY_PICKER(obj) (GTK_CHECK_CAST ((obj), TYPE_WEEKDAY_PICKER, WeekdayPicker)) -#define WEEKDAY_PICKER_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_WEEKDAY_PICKER, \ - WeekdayPickerClass)) -#define IS_WEEKDAY_PICKER(obj) (GTK_CHECK_TYPE ((obj), TYPE_WEEKDAY_PICKER)) -#define IS_WEEKDAY_PICKER_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), TYPE_WEEKDAY_PICKER)) - -typedef struct _WeekdayPicker WeekdayPicker; -typedef struct _WeekdayPickerClass WeekdayPickerClass; -typedef struct _WeekdayPickerPrivate WeekdayPickerPrivate; - -struct _WeekdayPicker { - GnomeCanvas canvas; - - /* Private data */ - WeekdayPickerPrivate *priv; -}; - -struct _WeekdayPickerClass { - GnomeCanvasClass parent_class; - - void (* changed) (WeekdayPicker *wp); -}; - -GtkType weekday_picker_get_type (void); - -GtkWidget *weekday_picker_new (void); - -void weekday_picker_set_days (WeekdayPicker *wp, guint8 day_mask); -guint8 weekday_picker_get_days (WeekdayPicker *wp); - -void weekday_picker_set_blocked_days (WeekdayPicker *wp, guint8 blocked_day_mask); -guint weekday_picker_get_blocked_days (WeekdayPicker *wp); - -void weekday_picker_set_week_start_day (WeekdayPicker *wp, int week_start_day); -int weekday_picker_get_week_start_day (WeekdayPicker *wp); - - - -END_GNOME_DECLS - -#endif diff --git a/calendar/gui/widget-util.c b/calendar/gui/widget-util.c deleted file mode 100644 index d6034ce8b0..0000000000 --- a/calendar/gui/widget-util.c +++ /dev/null @@ -1,54 +0,0 @@ -/* Evolution calendar - Widget utilities - * - * Copyright (C) 2000 Helix Code, Inc. - * - * Author: Federico Mena-Quintero <federico@helixcode.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <widgets/misc/e-dateedit.h> -#include "calendar-config.h" -#include "widget-util.h" - - - -/** - * date_edit_new: - * @show_date: Whether to show a date picker in the widget. - * @show_time: Whether to show a time picker in the widget. - * - * Creates a new #EDateEdit widget, configured using the calendar's preferences. - * - * Return value: A newly-created #EDateEdit widget. - **/ -GtkWidget * -date_edit_new (gboolean show_date, gboolean show_time) -{ - EDateEdit *dedit; - - dedit = E_DATE_EDIT (e_date_edit_new ()); - - e_date_edit_set_show_date (dedit, show_date); - e_date_edit_set_show_time (dedit, show_time); - - calendar_config_configure_e_date_edit (dedit); - - return GTK_WIDGET (dedit); -} diff --git a/calendar/gui/widget-util.h b/calendar/gui/widget-util.h deleted file mode 100644 index 930e0f9b6e..0000000000 --- a/calendar/gui/widget-util.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Evolution calendar - Widget utilities - * - * Copyright (C) 2000 Helix Code, Inc. - * - * Author: Federico Mena-Quintero <federico@helixcode.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef WIDGET_UTIL_H -#define WIDGET_UTIL_H - -#include <gtk/gtkwidget.h> - - -GtkWidget *date_edit_new (gboolean show_date, gboolean show_time); - - -#endif diff --git a/calendar/idl/.cvsignore b/calendar/idl/.cvsignore deleted file mode 100644 index b840c21800..0000000000 --- a/calendar/idl/.cvsignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile.in -Makefile
\ No newline at end of file diff --git a/calendar/idl/Makefile.am b/calendar/idl/Makefile.am deleted file mode 100644 index ec6b4e45f0..0000000000 --- a/calendar/idl/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ -idldir = $(datadir)/idl - -idl_DATA = \ - evolution-calendar.idl - -EXTRA_DIST = \ - $(idl_DATA) diff --git a/calendar/idl/evolution-calendar.idl b/calendar/idl/evolution-calendar.idl deleted file mode 100644 index c3de81e41f..0000000000 --- a/calendar/idl/evolution-calendar.idl +++ /dev/null @@ -1,211 +0,0 @@ -/* Evolution calendar interface - * - * Copyright (C) 2000 Eskil Heyn Olsen - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Eskil Heyn Olsen <deity@eskil.dk> - * Federico Mena-Quintero <federico@ximian.com> - */ - -#ifndef _EVOLUTION_CALENDAR_IDL_ -#define _EVOLUTION_CALENDAR_IDL_ - -#include <Bonobo.idl> - -module GNOME { -module Evolution { - -module Calendar { - /* A calendar component (event/todo/journal/etc), represented as an - * iCalendar string. - */ - typedef string CalObj; - - /* A unique identifier for a calendar component */ - typedef string CalObjUID; - - /* Sequence of unique identifiers */ - typedef sequence<CalObjUID> CalObjUIDSeq; - - /* A unique identifier for an alarm subcomponent */ - typedef string CalAlarmUID; - - /* Flags for getting UID sequences */ - typedef long CalObjType; - const CalObjType TYPE_EVENT = 1 << 0; - const CalObjType TYPE_TODO = 1 << 1; - const CalObjType TYPE_JOURNAL = 1 << 2; - const CalObjType TYPE_ANY = 0x07; - - /* Types of object changes made */ - typedef long CalObjChangeType; - const CalObjChangeType ADDED = 1 << 0; - const CalObjChangeType MODIFIED = 1 << 1; - const CalObjChangeType DELETED = 1 << 2; - - /* Types of alarms */ - enum AlarmType { - MAIL, - PROGRAM, - DISPLAY, - AUDIO - }; - - /* Used to store a time_t */ - typedef unsigned long Time_t; - - /* An instance of a calendar component that actually occurs. These are - * "virtual" objects in that they are used to represent instances of - * recurring events and alarms. "Real" objects just contain the - * information required to figure out the times at which they recur or - * trigger. - */ - struct CalObjInstance { - CalObjUID uid; - Time_t start; - Time_t end; - }; - - /* Used to transfer a list of component occurrences */ - typedef sequence<CalObjInstance> CalObjInstanceSeq; - - /* An object change */ - struct CalObjChange { - CalObj calobj; - CalObjChangeType type; - }; - - /* Used to transfer a list of changed components */ - typedef sequence<CalObjChange> CalObjChangeSeq; - - /* An alarm trigger instance */ - struct CalAlarmInstance { - CalAlarmUID auid; - Time_t trigger; - Time_t occur; - }; - - /* Used to represent a list of alarm triggers for a single component */ - typedef sequence<CalAlarmInstance> CalAlarmInstanceSeq; - - /* Alarms for a component */ - struct CalComponentAlarms { - CalObj calobj; - CalAlarmInstanceSeq alarms; - }; - - /* Used to represent a list of components plus their triggers */ - typedef sequence<CalComponentAlarms> CalComponentAlarmsSeq; - - interface Listener; - - /* Calendar client interface */ - interface Cal : Bonobo::Unknown { - exception NotFound {}; - exception InvalidRange {}; - exception InvalidObject {}; - - /* A calendar is identified by its URI */ - readonly attribute string uri; - - /* Gets the number of components of the specified types */ - long countObjects (in CalObjType type); - - /* Gets a component based on its URI */ - CalObj getObject (in CalObjUID uid) - raises (NotFound); - - /* Gets a list of UIDs based on component type */ - CalObjUIDSeq getUIds (in CalObjType type); - - /* Gets a list of components that changed based on object type */ - CalObjChangeSeq getChanges (in CalObjType type, in string change_id); - - /* Gets a list of components that occur or recur in the specified time range */ - CalObjUIDSeq getObjectsInRange (in CalObjType type, - in Time_t start, in Time_t end) - raises (InvalidRange); - - /* Gets a list of the components that have alarms that trigger - * in the specified range of time, and the trigger/occurrence - * structures themselves. - */ - CalComponentAlarmsSeq getAlarmsInRange (in Time_t start, in Time_t end) - raises (InvalidRange); - - /* Gets the alarms for the specified component that trigger in - * the specified time range. - */ - CalComponentAlarms getAlarmsForObject (in CalObjUID uid, - in Time_t start, in Time_t end) - raises (NotFound, InvalidRange); - - - /* Updates a component by adding it if it does not exist or by - * changing an existing one. - */ - void updateObject (in CalObjUID uid, in CalObj calobj) - raises (InvalidObject); - - /* Removes a component */ - void removeObject (in CalObjUID uid) - raises (NotFound); - }; - - /* Listener for changes in a calendar */ - interface Listener : Bonobo::Unknown { - /* Return status when opening a calendar */ - enum OpenStatus { - SUCCESS, /* All OK */ - ERROR, /* Generic error */ - NOT_FOUND, /* Requested opening in only_if_exists mode - * when the URI did not exist. - */ - METHOD_NOT_SUPPORTED /* A method handler is not registered */ - }; - - /* Called from a CalFactory when a calendar is initially opened. - * The listener must remember the cal object. - */ - void notifyCalOpened (in OpenStatus status, in Cal cal); - - /* Called from a Calendar when a component is added or changed */ - void notifyObjUpdated (in CalObjUID uid); - - /* Called from a Calendar when a component is removed */ - void notifyObjRemoved (in CalObjUID uid); - }; - - /* A calendar factory, can load and create calendars */ - interface CalFactory : Bonobo::Unknown { - exception NilListener {}; - - /* Open a calendar from an URI */ - void open (in string uri, in boolean only_if_exists, in Listener listener) - raises (NilListener); - }; - - /* Interface to the alarm notification service */ - interface AlarmNotify : Bonobo::Unknown { - exception InvalidURI {}; - exception BackendContactError {}; - exception NotFound {}; - - /* Adds a calendar to the alarm notification system */ - void addCalendar (in string uri) - raises (InvalidURI, BackendContactError); - - /* Removes a calendar from the alarm notification system */ - void removeCalendar (in string uri) - raises (NotFound); - - /* Makes the alarm notification daemon unconditionally exit */ - void die (); - }; -}; - -}; -}; - -#endif diff --git a/calendar/pcs/.cvsignore b/calendar/pcs/.cvsignore deleted file mode 100644 index ac51a554db..0000000000 --- a/calendar/pcs/.cvsignore +++ /dev/null @@ -1,11 +0,0 @@ -Makefile -Makefile.in -.deps -.libs -.pure -*.la -*.lo -evolution-calendar-stubs.c -evolution-calendar-skels.c -evolution-calendar-common.c -evolution-calendar.h diff --git a/calendar/pcs/Makefile.am b/calendar/pcs/Makefile.am deleted file mode 100644 index 984dcde86a..0000000000 --- a/calendar/pcs/Makefile.am +++ /dev/null @@ -1,42 +0,0 @@ -INCLUDES = \ - -DG_LOG_DOMAIN=\"wombat-pcs\" \ - -I$(top_srcdir) \ - -I$(top_srcdir)/calendar \ - -I$(top_srcdir)/libical/src/libical \ - -I$(top_builddir)/libical/src/libical \ - $(BONOBO_VFS_GNOME_CFLAGS) \ - -DGNOMELOCALEDIR=\""$(localedir)"\" - -CORBA_GENERATED = \ - evolution-calendar.h \ - evolution-calendar-common.c \ - evolution-calendar-skels.c \ - evolution-calendar-stubs.c - -idls = \ - $(srcdir)/../idl/evolution-calendar.idl - -idl_flags = -I $(srcdir) `$(GNOME_CONFIG) --cflags idl` -I $(datadir)/idl - -$(CORBA_GENERATED): $(idls) - $(ORBIT_IDL) $(idl_flags) $(srcdir)/../idl/evolution-calendar.idl - -noinst_LIBRARIES = libpcs.a - -libpcs_a_SOURCES = \ - $(CORBA_GENERATED) \ - cal.c \ - cal.h \ - cal-backend.c \ - cal-backend.h \ - cal-backend-file.c \ - cal-backend-file.h \ - cal-common.h \ - cal-factory.c \ - cal-factory.h \ - job.c \ - job.h - - -BUILT_SOURCES = $(CORBA_GENERATED) -CLEANFILES += $(BUILT_SOURCES) diff --git a/calendar/pcs/cal-backend-db.c b/calendar/pcs/cal-backend-db.c deleted file mode 100644 index e83b6fd3d1..0000000000 --- a/calendar/pcs/cal-backend-db.c +++ /dev/null @@ -1,1452 +0,0 @@ -/* Evolution calendar - iCalendar DB backend - * - * Copyright (C) 2001 Ximian, Inc. - * - * Author: Rodrigo Moya <rodrigo@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#include <config.h> -#include <gtk/gtksignal.h> -#include "cal-util/cal-recur.h" -#include "cal-backend-db.h" -#include <db.h> -#if DB_VERSION_MAJOR < 3 -# error "You need libdb3 to compile the DB backend" -#endif - -#define ENVIRONMENT_DIRECTORY "%s/evolution/local/Calendar/db.environment" - -/* structure to identify an open cursor */ -typedef struct { - gint ref; - DBC* dbc; - DB* parent_db; - - /* data in the cursor */ - GList *keys; - GList *data; -} CalBackendDBCursor; - -/* private part of the CalBackendDB structure */ -struct _CalBackendDBPrivate { - /* URI where the calendar data is stored */ - GnomeVFSURI *uri; - - /* Berkeley DB's library handles */ - DB_ENV *environment; - DB *objects_db; - DB *history_db; - - /* list of open cursors */ - GList *cursors; - - /* list of clients using this backend */ - GList *clients; -}; - -static void cal_backend_db_class_init (CalBackendDBClass *klass); -static void cal_backend_db_init (CalBackendDB *cbdb); -static void cal_backend_db_destroy (GtkObject *object); - -static GnomeVFSURI *cal_backend_db_get_uri (CalBackend *backend); -static void cal_backend_db_add_cal (CalBackend *backend, Cal *cal); -static CalBackendOpenStatus cal_backend_db_open (CalBackend *backend, - GnomeVFSURI *uri, - gboolean only_if_exists); - -static int cal_backend_db_get_n_objects (CalBackend *backend, CalObjType type); -static char *cal_backend_db_get_object (CalBackend *backend, const char *uid); -static CalObjType cal_backend_db_get_type_by_uid (CalBackend *backend, const char *uid); -static GList* cal_backend_db_get_uids (CalBackend *backend, CalObjType type); -static GList* cal_backend_db_get_objects_in_range (CalBackend *backend, - CalObjType type, - time_t start, - time_t end); -static GNOME_Evolution_Calendar_CalObjChangeSeq *cal_backend_db_get_changes ( - CalBackend *backend, CalObjType type, const char *change_id); - -static GNOME_Evolution_Calendar_CalComponentAlarmsSeq *cal_backend_db_get_alarms_in_range ( - CalBackend *backend, time_t start, time_t end); - -static GNOME_Evolution_Calendar_CalComponentAlarms *cal_backend_db_get_alarms_for_object ( - CalBackend *backend, const char *uid, time_t start, time_t end, gboolean *object_found); - -static gboolean cal_backend_db_update_object (CalBackend *backend, - const char *uid, - const char *calobj); -static gboolean cal_backend_db_remove_object (CalBackend *backend, const char *uid); - -static void close_cursor (CalBackendDB *cbdb, CalBackendDBCursor *cursor); -static CalBackendDBCursor *open_cursor (CalBackendDB *cbdb, DB *db); -static CalBackendDBCursor *find_cursor_by_db (CalBackendDB *cbdb, DB *db); -static DBT *find_record_by_id (CalBackendDBCursor *cursor, const gchar *id); - -static DB_TXN *begin_transaction (CalBackendDB *cbdb); -static void commit_transaction (DB_TXN *tid); -static void rollback_transaction (DB_TXN *tid); - -static CalBackendClass *parent_class; - -/** - * cal_backend_db_get_type: - * @void: - * - * Registers the #CalBackendDB class if necessary and returns the type ID - * associated to it. - * - * Return value: The type ID of the #CalBackendDB class. - */ -GtkType -cal_backend_db_get_type (void) -{ - static GtkType cal_backend_db_type = 0; - - if (!cal_backend_db_type) { - static const GtkTypeInfo cal_backend_db_info = { - "CalBackendDB", - sizeof (CalBackendDB), - sizeof (CalBackendDBClass), - (GtkClassInitFunc) cal_backend_db_class_init, - (GtkObjectInitFunc) cal_backend_db_init, - NULL, - NULL, - (GtkClassInitFunc) NULL - }; - - cal_backend_db_type = gtk_type_unique(CAL_BACKEND_TYPE, &cal_backend_db_info); - } - - return cal_backend_db_type; -} - -/* class initialization function for the DB backend */ -static void -cal_backend_db_class_init (CalBackendDBClass *klass) -{ - GtkObjectClass *object_class; - CalBackendClass *backend_class; - - object_class = (GtkObjectClass *) klass; - backend_class = (CalBackendClass *) klass; - - parent_class = gtk_type_class(CAL_BACKEND_TYPE); - - object_class->destroy = cal_backend_db_destroy; - - backend_class->get_uri = cal_backend_db_get_uri; - backend_class->add_cal = cal_backend_db_add_cal; - backend_class->open = cal_backend_db_open; - backend_class->get_n_objects = cal_backend_db_get_n_objects; - backend_class->get_object = cal_backend_db_get_object; - backend_class->get_type_by_uid = cal_backend_db_get_type_by_uid; - backend_class->get_uids = cal_backend_db_get_uids; - backend_class->get_objects_in_range = cal_backend_db_get_objects_in_range; - backend_class->get_changes = cal_backend_db_get_changes; - backend_class->get_alarms_in_range = cal_backend_db_get_alarms_in_range; - backend_class->get_alarms_for_object = cal_backend_db_get_alarms_for_object; - backend_class->update_object = cal_backend_db_update_object; - backend_class->remove_object = cal_backend_db_remove_object; -} - -/* object initialization function for the DB backend */ -static void -cal_backend_db_init (CalBackendDB *cbdb) -{ - CalBackendDBPrivate *priv; - - priv = g_new0(CalBackendDBPrivate, 1); - cbdb->priv = priv; -} - -/* Destroy handler for the DB backend */ -static void -cal_backend_db_destroy (GtkObject *object) -{ - CalBackendDB *cbdb; - CalBackendDBPrivate *priv; - GList *node; - - g_return_if_fail(object != NULL); - g_return_if_fail(IS_CAL_BACKEND_DB(object)); - - cbdb = CAL_BACKEND_DB(object); - priv = cbdb->priv; - - g_assert(cbdb->priv->clients == NULL); - - /* clean up */ - if (priv->uri) { - gnome_vfs_uri_unref(priv->uri); - priv->uri = NULL; - } - - /* close open cursors */ - while ((node = g_list_first(cbdb->priv->cursors))) { - close_cursor(cbdb, (CalBackendDBCursor *) node->data); - } - - /* close open databases */ - if (cbdb->priv->objects_db) - cbdb->priv->objects_db->close(cbdb->priv->objects_db, 0); - if (cbdb->priv->history_db) - cbdb->priv->history_db->close(cbdb->priv->history_db, 0); - - /* close DB environment */ - if (cbdb->priv->environment) - cbdb->priv->environment->close(cbdb->priv->environment, 0); - - g_free((gpointer) priv); - cbdb->priv = NULL; - - if (GTK_OBJECT_CLASS(parent_class)->destroy) - (*GTK_OBJECT_CLASS(parent_class)->destroy)(object); -} - -/* - * Private functions - */ - -/* close an open cursor and frees all associated memory */ -static void -close_cursor (CalBackendDB *cbdb, CalBackendDBCursor *cursor) -{ - GList *node; - DBT *dbt; - - g_return_if_fail(cursor != NULL); - - cursor->ref--; - if (cursor->ref > 0) - return; - - /* free all keys and data */ - while ((node = g_list_first(cursor->keys))) { - dbt = (DBT *) node->data; - cursor->keys = g_list_remove(cursor->keys, (gpointer) dbt); - g_free((gpointer) dbt); - } - while ((node = g_list_first(cursor->data))) { - dbt = (DBT *) node->data; - cursor->data = g_list_remove(cursor->data, (gpointer) dbt); - g_free((gpointer) dbt); - } - - /* finally, close the cursor */ - cursor->dbc->c_close(cursor->dbc); - - cbdb->priv->cursors = g_list_remove(cbdb->priv->cursors, (gpointer) cursor); - g_free((gpointer) cursor); -} - -/* open a cursor for the given database */ -static CalBackendDBCursor * -open_cursor (CalBackendDB *cbdb, DB *db) -{ - CalBackendDBCursor *cursor; - gint ret; - - g_return_val_if_fail(IS_CAL_BACKEND_DB(cbdb), NULL); - g_return_val_if_fail(db != NULL, NULL); - - /* search for the cursor in our list of cursors */ - cursor = find_cursor_by_db(cbdb, db); - if (cursor) { - cursor->ref++; - return cursor; - } - - /* create the cursor */ - cursor = g_new0(CalBackendDBCursor, 1); - cursor->parent_db = db; - cursor->ref = 1; - - ret = db->cursor(db, NULL, &cursor->dbc, 0); - if (ret == 0) { - DBT key; - DBT data; - - /* read data */ - memset(&key, 0, sizeof(key)); - memset(&data, 0, sizeof(data)); - - while ((ret = cursor->dbc->c_get(cursor->dbc, &key, &data, DB_NEXT)) == 0) { - cursor->keys = g_list_append(cursor->keys, g_memdup(&key, sizeof(key))); - cursor->data = g_list_append(cursor->data, g_memdup(&data, sizeof(data))); - - memset(&key, 0, sizeof(key)); - memset(&data, 0, sizeof(data)); - } - if (ret == DB_NOTFOUND) { - cbdb->priv->cursors = g_list_prepend(cbdb->priv->cursors, (gpointer) cursor); - return cursor; - } - - /* close cursor on error */ - close_cursor(cbdb, cursor); - } - - return NULL; -} - -/* search for a cursor in the given backend */ -static CalBackendDBCursor * -find_cursor_by_db (CalBackendDB *cbdb, DB *db) -{ - GList *node; - - g_return_val_if_fail(IS_CAL_BACKEND_DB(cbdb), NULL); - g_return_val_if_fail(cbdb->priv != NULL, NULL); - g_return_val_if_fail(db != NULL, NULL); - - for (node = g_list_first(cbdb->priv->cursors); node != NULL; node = g_list_next(node)) { - CalBackendDBCursor* cursor = (CalBackendDBCursor *) node->data; - - if (cursor && cursor->parent_db == db) - return cursor; - } - - return NULL; /* not found */ -} - -/* finds a record in a cursor by its ID */ -static DBT * -find_record_by_id (CalBackendDBCursor *cursor, const gchar *id) -{ - GList *node; - - g_return_val_if_fail(cursor != NULL, NULL); - g_return_val_if_fail(id != NULL, NULL); - - - for (node = g_list_first(cursor->keys); node != NULL; node = g_list_next(node)) { - DBT *key; - - key = (DBT *) node->data; - if (key && !strcmp(key->data, id)) { - GList *tmp; - - tmp = g_list_nth(cursor->data, g_list_position(cursor->keys, node)); - if (tmp) - return (DBT *) tmp->data; - return NULL; /* no data associated with this key */ - } - } - - return NULL; /* not found */ -} - -/* start a new transaction */ -static DB_TXN * -begin_transaction (CalBackendDB *cbdb) -{ - DB_TXN *tid; - gint ret; - - g_return_val_if_fail(IS_CAL_BACKEND_DB(cbdb), NULL); - g_return_val_if_fail(cbdb->priv != NULL, NULL); - - if ((ret = txn_begin(cbdb->priv->environment, NULL, &tid, 0)) != 0) { - /* TODO: error logging */ - return NULL; - } - - return tid; -} - -/* finish successfully a transaction */ -static void -commit_transaction (DB_TXN *tid) -{ - gint ret; - - g_return_if_fail(tid != NULL); - - if ((ret = txn_commit(tid, 0)) != 0) { - /* TODO: error logging? */ - } -} - -/* abort a transaction */ -static void -rollback_transaction (DB_TXN *tid) -{ - gint ret; - - g_return_if_fail(tid != NULL); - - if ((ret = txn_abort(tid)) != 0) { - /* TODO: error logging? */ - } -} - -/* - * Calendar backend methods - */ - -/* get_uri handler for the DB backend */ -static GnomeVFSURI * -cal_backend_db_get_uri (CalBackend *backend) -{ - CalBackendDB *cbdb; - - cbdb = CAL_BACKEND_DB(backend); - g_return_val_if_fail(IS_CAL_BACKEND_DB(cbdb), NULL); - g_return_val_if_fail(cbdb->priv != NULL, NULL); - - return cbdb->priv->uri; -} - -/* callback used when a Cal is destroyed */ -static void -destroy_cal_cb (GtkObject *object, gpointer data) -{ - Cal *cal; - Cal *tmp_cal; - CalBackendDB *cbdb; - GList *node; - - cal = CAL(object); - cbdb = CAL_BACKEND_DB(data); - - g_return_if_fail(IS_CAL_BACKEND_DB(cbdb)); - g_return_if_fail(cbdb->priv != NULL); - - /* find the Cal in the list of clients */ - for (node = cbdb->priv->clients; node != NULL; node = g_list_next(node)) { - tmp_cal = CAL(node->data); - if (tmp_cal == cal) - break; - } - - if (node) { - /* disconnect this Cal */ - cbdb->priv->clients = g_list_remove_link(cbdb->priv->clients, node); - g_list_free_1(node); - - /* when all clients go away, notify the parent factory about it so that - * it may decide to kill the backend or not. - */ - if (!cbdb->priv->clients) - cal_backend_last_client_gone(CAL_BACKEND(cbdb)); - } -} - -/* add_cal_handler for the DB backend */ -static void -cal_backend_db_add_cal (CalBackend *backend, Cal *cal) -{ - CalBackendDB *cbdb; - - cbdb = CAL_BACKEND_DB(backend); - g_return_if_fail(IS_CAL_BACKEND_DB(cbdb)); - g_return_if_fail(cbdb->priv != NULL); - g_return_if_fail(IS_CAL(cal)); - - /* we do not keep a reference to the Cal since the calendar user agent - * owns it - */ - gtk_signal_connect(GTK_OBJECT(cal), - "destroy", - GTK_SIGNAL_FUNC(destroy_cal_cb), - backend); - - cbdb->priv->clients = g_list_prepend(cbdb->priv->clients, (gpointer) cal); -} - -/* database file initialization */ -static gboolean -open_database_file (CalBackendDB *cbdb, const gchar *str_uri, gboolean only_if_exists) -{ - gint ret; - struct stat sb; - gchar *dir; - - g_return_val_if_fail(IS_CAL_BACKEND_DB(cbdb), FALSE); - g_return_val_if_fail(cbdb->priv != NULL, FALSE); - g_return_val_if_fail(cbdb->priv->objects_db != NULL, FALSE); - g_return_val_if_fail(cbdb->priv->history_db != NULL, FALSE); - g_return_val_if_fail(str_uri != NULL, FALSE); - - /* initialize DB environment (for transactions) */ - dir = g_strdup_printf(ENVIRONMENT_DIRECTORY, g_get_home_dir()); - if (stat(dir, &sb) != 0) { - - /* if the directory exists, we're done, since DB will fail if it's the - * wrong one. If it does not exist, create the environment */ - if (mkdir(dir, S_IRWXU) != 0) { - g_free((gpointer) dir); - return FALSE; - } - - /* create the environment handle */ - if ((ret = db_env_create(&cbdb->priv->environment, 0)) != 0) { - g_free((gpointer) dir); - return FALSE; - } - - cbdb->priv->environment->set_errpfx(cbdb->priv->environment, "cal-backend-db"); - - /* open the transactional environment */ - if ((ret = cbdb->priv->environment->open(cbdb->priv->environment, - ENVIRONMENT_DIRECTORY, - DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | - DB_INIT_MPOOL | DB_INIT_TXN | - DB_RECOVER | DB_THREAD, - S_IRUSR | S_IWUSR)) != 0) { - g_free((gpointer) dir); - return FALSE; - } - } - - g_free((gpointer) dir); - - /* open/create objects database into given file */ - if ((ret = db_create(&cbdb->priv->objects_db, cbdb->priv->environment, 0)) != 0 - || (ret = db_create(&cbdb->priv->history_db, cbdb->priv->environment, 0)) != 0) { - return FALSE; - } - - if (only_if_exists) { - ret = cbdb->priv->objects_db->open(cbdb->priv->objects_db, - str_uri, - "calendar_objects", - DB_HASH, - DB_THREAD, - 0644); - } - else { - ret = cbdb->priv->objects_db->open(cbdb->priv->objects_db, - str_uri, - "calendar_objects", - DB_HASH, - DB_CREATE | DB_THREAD, - 0644); - } - if (ret == 0) { - /* now, open the history database */ - ret = cbdb->priv->history_db->open(cbdb->priv->history_db, - str_uri, - "calendar_history", - DB_BTREE, - DB_CREATE, - 0644); - if (ret == 0) return TRUE; - - /* close objects database on error */ - cbdb->priv->objects_db->close(cbdb->priv->objects_db, 0); - } - - return FALSE; -} - -/* open handler for the DB backend */ -static CalBackendOpenStatus -cal_backend_db_open (CalBackend *backend, GnomeVFSURI *uri, gboolean only_if_exists) -{ - CalBackendDB *cbdb; - gchar *str_uri; - - cbdb = CAL_BACKEND_DB(backend); - g_return_val_if_fail(IS_CAL_BACKEND_DB(cbdb), CAL_BACKEND_OPEN_ERROR); - g_return_val_if_fail(cbdb->priv != NULL, CAL_BACKEND_OPEN_ERROR); - g_return_val_if_fail(uri != NULL, CAL_BACKEND_OPEN_ERROR); - g_return_val_if_fail(cbdb->priv->objects_db == NULL, CAL_BACKEND_OPEN_ERROR); - - /* open the given URI */ - if (!gnome_vfs_uri_is_local(uri)) - return CAL_BACKEND_OPEN_ERROR; - str_uri = gnome_vfs_uri_to_string(uri, - (GNOME_VFS_URI_HIDE_USER_NAME - | GNOME_VFS_URI_HIDE_PASSWORD - | GNOME_VFS_URI_HIDE_HOST_NAME - | GNOME_VFS_URI_HIDE_HOST_PORT - | GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD)); - - /* open database file */ - if (!open_database_file(cbdb, (const gchar *) str_uri, only_if_exists)) { - g_free((gpointer) str_uri); - return CAL_BACKEND_OPEN_ERROR; - } - - gnome_vfs_uri_ref(uri); - cbdb->priv->uri = uri; - g_free((gpointer) str_uri); - - return CAL_BACKEND_OPEN_SUCCESS; -} - -/* get_n_objects handler for the DB backend */ -static int -cal_backend_db_get_n_objects (CalBackend *backend, CalObjType type) -{ - CalBackendDB *cbdb; - CalBackendDBCursor *cursor; - int total_count = 0; - - cbdb = CAL_BACKEND_DB(backend); - g_return_val_if_fail(IS_CAL_BACKEND_DB(cbdb), -1); - g_return_val_if_fail(cbdb->priv != NULL, -1); - - /* open the cursor */ - cursor = open_cursor(cbdb, cbdb->priv->objects_db); - if (cursor) { - GList *node; - - /* we traverse all data, to check for each object's type */ - for (node = g_list_first(cursor->data); node != NULL; node = g_list_next(node)) { - icalcomponent *icalcomp; - DBT *data = (DBT *) node->data; - - icalcomp = icalparser_parse_string((char *) data->data); - if (icalcomp) { - switch (icalcomponent_isa(icalcomp)) { - case ICAL_VEVENT_COMPONENT : - if (type & CALOBJ_TYPE_EVENT) - total_count++; - break; - case ICAL_VTODO_COMPONENT : - if (type & CALOBJ_TYPE_TODO) - total_count++; - break; - case ICAL_VJOURNAL_COMPONENT : - if (type & CALOBJ_TYPE_JOURNAL) - total_count++; - break; - default : - break; - } - icalcomponent_free(icalcomp); - } - } - close_cursor(cbdb, cursor); - } - - return total_count; -} - -/* get_object handler for the DB backend */ -static char * -cal_backend_db_get_object (CalBackend *backend, const char *uid) -{ - CalBackendDB *cbdb; - gint ret; - DBT key; - DBT data; - - cbdb = CAL_BACKEND_DB(backend); - g_return_val_if_fail(IS_CAL_BACKEND_DB(cbdb), NULL); - g_return_val_if_fail(cbdb->priv != NULL, NULL); - g_return_val_if_fail(cbdb->priv->objects_db != NULL, NULL); - g_return_val_if_fail(uid != NULL, NULL); - - memset(&key, 0, sizeof(key)); - memset(&data, 0, sizeof(data)); - key.data = (void *) uid; - key.size = strlen(uid); // + 1 - - /* read record from database */ - if ((ret = cbdb->priv->objects_db->get(cbdb->priv->objects_db, - NULL, - &key, - &data, - 0)) == 0) { - gchar *str = g_strdup((gchar *) data.data); - return str; - } - - return NULL; -} - -/* get_type_by_uid handler for the DB backend */ -static CalObjType -cal_backend_db_get_type_by_uid (CalBackend *backend, const char *uid) -{ - CalBackendDB *cbdb; - DBT key; - DBT data; - gint ret; - - cbdb = CAL_BACKEND_DB(backend); - g_return_val_if_fail(IS_CAL_BACKEND_DB(cbdb), CAL_COMPONENT_NO_TYPE); - g_return_val_if_fail(cbdb->priv != NULL, CAL_COMPONENT_NO_TYPE); - g_return_val_if_fail(cbdb->priv->objects_db != NULL, CAL_COMPONENT_NO_TYPE); - g_return_val_if_fail(uid != NULL, CAL_COMPONENT_NO_TYPE); - - memset(&key, 0, sizeof(key)); - memset(&data, 0, sizeof(data)); - key.data = (void *) uid; - key.size = strlen(uid); // + 1 - - /* read record from database */ - if ((ret = cbdb->priv->objects_db->get(cbdb->priv->objects_db, - NULL, - &key, - &data, - 0)) == 0) { - icalcomponent *icalcomp = icalparser_parse_string((char *) data.data); - if (icalcomp) { - CalObjType type; - - switch (icalcomponent_isa(icalcomp)) { - case ICAL_VEVENT_COMPONENT : - type = CALOBJ_TYPE_EVENT; - break; - case ICAL_VTODO_COMPONENT : - type = CALOBJ_TYPE_TODO; - break; - case ICAL_VJOURNAL_COMPONENT : - type = CALOBJ_TYPE_JOURNAL; - break; - default : - type = CAL_COMPONENT_NO_TYPE; - } - - icalcomponent_free(icalcomp); - return type; - } - } - - return CAL_COMPONENT_NO_TYPE; -} - -static GList * -add_uid_if_match (GList *list, CalBackendDBCursor *cursor, GList *data_node, CalObjType type) -{ - DBT *data; - - g_return_val_if_fail(cursor != NULL, list); - g_return_val_if_fail(data_node != NULL, list); - - data = (DBT *) data_node->data; - if (data) { - icalcomponent *icalcomp; - gchar *uid = NULL; - - icalcomp = icalparser_parse_string(data->data); - if (!icalcomp) return list; - - switch (icalcomponent_isa(icalcomp)) { - case ICAL_VEVENT_COMPONENT : - if (type & CALOBJ_TYPE_EVENT) - uid = (gchar *) icalcomponent_get_uid(icalcomp); - break; - case ICAL_VTODO_COMPONENT : - if (type & CALOBJ_TYPE_TODO) - uid = (gchar *) icalcomponent_get_uid(icalcomp); - break; - case ICAL_VJOURNAL_COMPONENT : - if (type & CALOBJ_TYPE_JOURNAL) - uid = (gchar *) icalcomponent_get_uid(icalcomp); - break; - default : - uid = NULL; - } - - if (uid) - list = g_list_prepend(list, g_strdup(uid)); - icalcomponent_free(icalcomp); - } - - return list; -} - -/* get_uids handler for the DB backend */ -static GList * -cal_backend_db_get_uids (CalBackend *backend, CalObjType type) -{ - CalBackendDB *cbdb; - GList *list = NULL; - CalBackendDBCursor *cursor; - - cbdb = CAL_BACKEND_DB(backend); - g_return_val_if_fail(IS_CAL_BACKEND_DB(cbdb), NULL); - g_return_val_if_fail(cbdb->priv != NULL, NULL); - g_return_val_if_fail(cbdb->priv->objects_db != NULL, NULL); - - /* open cursor */ - cursor = open_cursor(cbdb, cbdb->priv->objects_db); - if (cursor) { - GList *node; - - /* we traverse all data, to check for each object's type */ - for (node = g_list_first(cursor->data); node != NULL; node = g_list_next(node)) { - list = add_uid_if_match(list, cursor, node, type); - } - close_cursor(cbdb, cursor); - } - - return list; -} - -/* callback used from cal_recur_generate_instances(): adds the component's UID to - * our hash table - */ -static gboolean -add_instance (CalComponent *comp, time_t start, time_t end, gpointer data) -{ - GHashTable *uid_hash; - const char *uid; - const char *old_uid; - - uid_hash = data; - - cal_component_get_uid(comp, &uid); - - old_uid = g_hash_table_lookup(uid_hash, uid); - if (old_uid) - return FALSE; - - g_hash_table_insert(uid_hash, (char *) uid, NULL); - return FALSE; -} - -/* creates the list of UIDs in the given range */ -static void -get_instances_in_range (GHashTable *uid_hash, - CalBackendDBCursor *cursor, - CalObjType type, - time_t start, - time_t end) -{ - GList *node; - - g_return_if_fail(uid_hash != NULL); - g_return_if_fail(cursor != NULL); - - for (node = g_list_first(cursor->data); node != NULL; node = g_list_next(node)) { - DBT *data; - icalcomponent *icalcomp; - - data = (DBT *) node->data; - if (data) { - icalcomp = icalparser_parse_string((char *) data->data); - if (icalcomp) { - CalComponent *comp = cal_component_new(); - cal_component_set_icalcomponent(comp, icalcomp); - - switch (icalcomponent_isa(icalcomp)) { - case ICAL_VEVENT_COMPONENT : - if (type & CALOBJ_TYPE_EVENT) - cal_recur_generate_instances(comp, - start, - end, - add_instance, - uid_hash); - break; - case ICAL_VTODO_COMPONENT : - if (type & CALOBJ_TYPE_TODO) - cal_recur_generate_instances(comp, - start, - end, - add_instance, - uid_hash); - break; - case ICAL_VJOURNAL_COMPONENT : - if (type & CALOBJ_TYPE_JOURNAL) - cal_recur_generate_instances(comp, - start, - end, - add_instance, - uid_hash); - break; - default : - break; - } - - gtk_object_unref(GTK_OBJECT(comp)); - icalcomponent_free(icalcomp); - } - } - } -} - -/* callback used from g_hash_table_foreach: adds a UID from the hash table to our list */ -static void -add_uid_to_list (gpointer key, gpointer value, gpointer data) -{ - GList **list; - const char *uid; - - list = (GList **) data; - - uid = (const char *) key; - *list = g_list_prepend(*list, (gpointer) g_strdup(uid)); -} - -/* get_objects_in_range handler for the DB backend */ -static GList * -cal_backend_db_get_objects_in_range (CalBackend *backend, - CalObjType type, - time_t start, - time_t end) -{ - CalBackendDB *cbdb; - GList *list = NULL; - CalBackendDBCursor *cursor; - - cbdb = CAL_BACKEND_DB(backend); - g_return_val_if_fail(IS_CAL_BACKEND_DB(cbdb), NULL); - g_return_val_if_fail(cbdb->priv != NULL, NULL); - - /* open cursor */ - cursor = open_cursor(cbdb, cbdb->priv->objects_db); - if (cursor) { - GHashTable *uid_hash; - - /* build the hash table */ - uid_hash = g_hash_table_new(g_str_hash, g_str_equal); - get_instances_in_range(uid_hash, cursor, type, start, end); - - /* build the list to be returned from the hash table */ - g_hash_table_foreach(uid_hash, add_uid_to_list, &list); - g_hash_table_destroy(uid_hash); - - close_cursor(cbdb, cursor); - } - - return list; -} - -/* get_changes handler for the DB backend */ -static GNOME_Evolution_Calendar_CalObjChangeSeq * -cal_backend_db_get_changes (CalBackend *backend, CalObjType type, const char *change_id) -{ - CalBackendDB *cbdb; - - cbdb = CAL_BACKEND_DB(backend); - g_return_val_if_fail(IS_CAL_BACKEND_DB(cbdb), NULL); - g_return_val_if_fail(cbdb->priv != NULL, NULL); - - return NULL; -} - -/* computes the range of time in which recurrences should be generated for a - * component in order to compute alarm trigger times. - */ -static void -compute_alarm_range (CalComponent *comp, - GList *alarm_uids, - time_t start, - time_t end, - time_t *alarm_start, - time_t *alarm_end) -{ - GList *l; - - *alarm_start = start; - *alarm_end = end; - - for (l = alarm_uids; l; l = l->next) { - const char *auid; - CalComponentAlarm *alarm; - CalAlarmTrigger trigger; - struct icaldurationtype *dur; - time_t dur_time; - - auid = l->data; - alarm = cal_component_get_alarm (comp, auid); - g_assert (alarm != NULL); - - cal_component_alarm_get_trigger (alarm, &trigger); - cal_component_alarm_free (alarm); - - switch (trigger.type) { - case CAL_ALARM_TRIGGER_NONE: - case CAL_ALARM_TRIGGER_ABSOLUTE: - continue; - case CAL_ALARM_TRIGGER_RELATIVE_START: - case CAL_ALARM_TRIGGER_RELATIVE_END: - dur = &trigger.u.rel_duration; - dur_time = icaldurationtype_as_int (*dur); - - if (dur->is_neg) - *alarm_end = MAX (*alarm_end, end + dur_time); - else - *alarm_start = MIN (*alarm_start, start - dur_time); - - break; - default: - g_assert_not_reached (); - } - } - - g_assert (*alarm_start <= *alarm_end); -} - -/* closure data to generate alarm occurrences */ -struct alarm_occurrence_data { - /* these are the info we have */ - GList *alarm_uids; - time_t start; - time_t end; - - /* this is what we compute */ - GSList *triggers; - int n_triggers; -}; - -/* callback used from cal_recur_generate_instances(); generates triggers for all - * of a component's RELATIVE alarms. - */ -static gboolean -add_alarm_occurrences_cb (CalComponent *comp, time_t start, time_t end, gpointer data) -{ - struct alarm_occurrence_data *aod; - GList *l; - - aod = data; - - for (l = aod->alarm_uids; l; l = l->next) { - const char *auid; - CalComponentAlarm *alarm; - CalAlarmTrigger trigger; - struct icaldurationtype *dur; - time_t dur_time; - time_t occur_time, trigger_time; - CalAlarmInstance *instance; - - auid = l->data; - alarm = cal_component_get_alarm (comp, auid); - g_assert (alarm != NULL); - - cal_component_alarm_get_trigger (alarm, &trigger); - cal_component_alarm_free (alarm); - - if (trigger.type != CAL_ALARM_TRIGGER_RELATIVE_START - && trigger.type != CAL_ALARM_TRIGGER_RELATIVE_END) - continue; - - dur = &trigger.u.rel_duration; - dur_time = icaldurationtype_as_int (*dur); - - if (trigger.type == CAL_ALARM_TRIGGER_RELATIVE_START) - occur_time = start; - else - occur_time = end; - - if (dur->is_neg) - trigger_time = occur_time - dur_time; - else - trigger_time = occur_time + dur_time; - - if (trigger_time < aod->start || trigger_time >= aod->end) - continue; - - instance = g_new (CalAlarmInstance, 1); - instance->auid = auid; - instance->trigger = trigger_time; - instance->occur = occur_time; - - aod->triggers = g_slist_prepend (aod->triggers, instance); - aod->n_triggers++; - } - - return TRUE; -} - -/* generates the absolute triggers for a component */ -static void -generate_absolute_triggers (CalComponent *comp, struct alarm_occurrence_data *aod) -{ - GList *l; - - for (l = aod->alarm_uids; l; l = l->next) { - const char *auid; - CalComponentAlarm *alarm; - CalAlarmTrigger trigger; - time_t abs_time; - CalAlarmInstance *instance; - - auid = l->data; - alarm = cal_component_get_alarm (comp, auid); - g_assert (alarm != NULL); - - cal_component_alarm_get_trigger (alarm, &trigger); - cal_component_alarm_free (alarm); - - if (trigger.type != CAL_ALARM_TRIGGER_ABSOLUTE) - continue; - - abs_time = icaltime_as_timet (trigger.u.abs_time); - - if (abs_time < aod->start || abs_time >= aod->end) - continue; - - instance = g_new (CalAlarmInstance, 1); - instance->auid = auid; - instance->trigger = abs_time; - instance->occur = abs_time; /* No particular occurrence, so just use the same time */ - - aod->triggers = g_slist_prepend (aod->triggers, instance); - aod->n_triggers++; - } -} - -/* compares two alarm instances; called from g_slist_sort() */ -static gint -compare_alarm_instance (gconstpointer a, gconstpointer b) -{ - const CalAlarmInstance *aia, *aib; - - aia = a; - aib = b; - - if (aia->trigger < aib->trigger) - return -1; - else if (aia->trigger > aib->trigger) - return 1; - else - return 0; -} - -/* generates alarm instances for a calendar component. Returns the instances - * structure, or NULL if no alarm instances occurred in the specified time - * range. - */ -static CalComponentAlarms * -generate_alarms_for_comp (CalComponent *comp, time_t start, time_t end) -{ - CalComponentAlarms *alarms = NULL; - GList *alarm_uids; - time_t alarm_start, alarm_end; - struct alarm_occurrence_data aod; - - g_return_val_if_fail(IS_CAL_COMPONENT(comp), NULL); - - if (!cal_component_has_alarms(comp)) - return NULL; - - alarm_uids = cal_component_get_alarm_uids(comp); - compute_alarm_range(comp, alarm_uids, start, end, &alarm_start, &alarm_end); - - aod.alarm_uids = alarm_uids; - aod.start = start; - aod.end = end; - aod.triggers = NULL; - aod.n_triggers = 0; - cal_recur_generate_instances(comp, alarm_start, alarm_end, add_alarm_occurrences_cb, &aod); - - /* we add the ABSOLUTE triggers separately */ - generate_absolute_triggers(comp, &aod); - - if (aod.n_triggers == 0) - return NULL; - - /* create the component alarm instances structure */ - alarms = g_new (CalComponentAlarms, 1); - alarms->comp = comp; - gtk_object_ref (GTK_OBJECT (alarms->comp)); - alarms->alarms = g_slist_sort (aod.triggers, compare_alarm_instance); - - return alarms; -} - -/* retrieve list of alarms */ -static GSList * -get_list_of_alarms (CalBackendDBCursor *cursor, time_t start, time_t end) -{ - GSList *list = NULL; - GList *node; - - g_return_val_if_fail(cursor != NULL, NULL); - - for (node = g_list_first(cursor->data); node != NULL; node = g_list_next(node)) { - icalcomponent *icalcomp; - icalcomponent_kind kind; - DBT *data; - - data = (DBT *) node->data; - if (data) { - icalcomp = icalparser_parse_string((char *) data->data); - if (icalcomp) { - /* per RFC 2445, only VEVENTs and VTODOs can have alarms */ - kind = icalcomponent_isa(icalcomp); - if (kind == ICAL_VEVENT_COMPONENT || kind == ICAL_VTODO_COMPONENT) { - CalComponent *comp; - CalComponentAlarms *alarms; - - /* create the CalComponent to compute the alarms */ - comp = cal_component_new(); - cal_component_set_icalcomponent(comp, icalcomp); - - alarms = generate_alarms_for_comp(comp, start, end); - if (alarms) - list = g_slist_prepend(list, (gpointer) alarms); - - gtk_object_unref(GTK_OBJECT(comp)); - } - - icalcomponent_free(icalcomp); - } - } - } - - return list; -} - -/* fills a CORBA sequence of alarm instances */ -static void -fill_alarm_instances_seq (GNOME_Evolution_Calendar_CalAlarmInstanceSeq *seq, GSList *alarms) -{ - int n_alarms; - GSList *l; - int i; - - n_alarms = g_slist_length(alarms); - - CORBA_sequence_set_release(seq, TRUE); - seq->_length = n_alarms; - seq->_buffer = CORBA_sequence_GNOME_Evolution_Calendar_CalAlarmInstance_allocbuf(n_alarms); - - for (l = alarms, i = 0; l != NULL; l = l->next, i++) { - CalAlarmInstance *instance; - GNOME_Evolution_Calendar_CalAlarmInstance *corba_instance; - - instance = (CalAlarmInstance *) l->data; - corba_instance = seq->_buffer + i; - - corba_instance->auid = CORBA_string_dup(instance->auid); - corba_instance->trigger = (long) instance->trigger; - corba_instance->occur = (long) instance->occur; - } -} - -/* get_alarms_in_range handler for the DB backend */ -static GNOME_Evolution_Calendar_CalComponentAlarmsSeq * -cal_backend_db_get_alarms_in_range (CalBackend *backend, time_t start, time_t end) -{ - CalBackendDB *cbdb; - CalBackendDBCursor *cursor; - gint number_of_alarms; - GSList *alarm_list; - GSList *node; - gint i; - GNOME_Evolution_Calendar_CalComponentAlarmsSeq *seq = NULL; - - cbdb = CAL_BACKEND_DB(backend); - g_return_val_if_fail(IS_CAL_BACKEND_DB(cbdb), NULL); - g_return_val_if_fail(cbdb->priv != NULL, NULL); - g_return_val_if_fail (start != -1 && end != -1, NULL); - g_return_val_if_fail (start <= end, NULL); - - /* open cursor */ - cursor = open_cursor(cbdb, cbdb->priv->objects_db); - if (cursor) { - alarm_list = get_list_of_alarms(cursor, start, end); - number_of_alarms = g_slist_length(alarm_list); - - /* create the CORBA sequence */ - seq = GNOME_Evolution_Calendar_CalComponentAlarmsSeq__alloc(); - CORBA_sequence_set_release(seq, TRUE); - seq->_length = number_of_alarms; - seq->_buffer = CORBA_sequence_GNOME_Evolution_Calendar_CalComponentAlarms_allocbuf( - number_of_alarms); - - /* populate CORBA sequence */ - for (node = alarm_list, i = 0; node != NULL; node = node->next, i++) { - CalComponentAlarms *alarms; - gchar *comp_str; - - alarms = (CalComponentAlarms *) node->data; - - comp_str = cal_component_get_as_string (alarms->comp); - seq->_buffer[i].calobj = CORBA_string_dup(comp_str); - g_free((gpointer) comp_str); - - fill_alarm_instances_seq(&seq->_buffer[i].alarms, alarms->alarms); - - cal_component_alarms_free(alarms); - } - - g_slist_free(alarm_list); - close_cursor(cbdb, cursor); - } - - return seq; -} - -/* get_alarms_for_object handler for the DB backend */ -static GNOME_Evolution_Calendar_CalComponentAlarms * -cal_backend_db_get_alarms_for_object (CalBackend *backend, - const char *uid, - time_t start, - time_t end, - gboolean *object_found) -{ - CalBackendDB *cbdb; - CalBackendDBCursor *cursor; - GNOME_Evolution_Calendar_CalComponentAlarms *corba_alarms = NULL; - DBT *data; - gchar *comp_str; - CalComponentAlarms *alarms; - - cbdb = CAL_BACKEND_DB(backend); - g_return_val_if_fail(IS_CAL_BACKEND_DB(cbdb), NULL); - g_return_val_if_fail(cbdb->priv != NULL, NULL); - g_return_val_if_fail(uid != NULL, NULL); - g_return_val_if_fail(start != -1 && end != -1, NULL); - g_return_val_if_fail(start <= end, NULL); - g_return_val_if_fail(object_found != NULL, NULL); - - *object_found = FALSE; - - /* open the cursor */ - cursor = open_cursor(cbdb, cbdb->priv->objects_db); - if (cursor) { - data = find_record_by_id(cursor, uid); - if (data) { - icalcomponent *icalcomp; - CalComponent *comp; - - *object_found = TRUE; - - comp_str = (gchar *) data->data; - - icalcomp = icalparser_parse_string(comp_str); - if (!icalcomp) { - close_cursor(cbdb, cursor); - return NULL; - } - - comp = cal_component_new(); - cal_component_set_icalcomponent(comp, icalcomp); - - /* create the CORBA alarms */ - corba_alarms = GNOME_Evolution_Calendar_CalComponentAlarms__alloc(); - corba_alarms->calobj = CORBA_string_dup (comp_str); - - /* populate the CORBA sequence */ - alarms = generate_alarms_for_comp(comp, start, end); - if (alarms) { - fill_alarm_instances_seq(&corba_alarms->alarms, alarms->alarms); - cal_component_alarms_free(alarms); - } - else - fill_alarm_instances_seq(&corba_alarms->alarms, NULL); - - gtk_object_unref(GTK_OBJECT(comp)); - icalcomponent_free(icalcomp); - } - - close_cursor(cbdb, cursor); - } - - return corba_alarms; -} - -/* do notifications to Cal clients */ -static void -do_notify (CalBackendDB *cbdb, void (*notify_fn)(Cal *, gchar *), const gchar *uid) -{ - GList *node; - - g_return_if_fail(IS_CAL_BACKEND_DB(cbdb)); - g_return_if_fail(cbdb->priv != NULL); - g_return_if_fail(notify_fn != NULL); - g_return_if_fail(uid != NULL); - - /* FIXME: do notification asynchronously */ - for (node = g_list_first(cbdb->priv->clients); node != NULL; node = g_list_next(node)) { - Cal *cal; - - cal = CAL(node->data); - (*notify_fn)(cal, (gpointer) uid); - } -} - -/* update_object handler for the DB backend */ -static gboolean -cal_backend_db_update_object (CalBackend *backend, const char *uid, const char *calobj) -{ - CalBackendDB *cbdb; - DB_TXN *tid; - DBT key; - DBT new_data; - gint ret; - - cbdb = CAL_BACKEND_DB(backend); - g_return_val_if_fail(IS_CAL_BACKEND_DB(cbdb), FALSE); - g_return_val_if_fail(cbdb->priv != NULL, FALSE); - g_return_val_if_fail(cbdb->priv->objects_db != NULL, FALSE); - g_return_val_if_fail(uid != NULL, FALSE); - g_return_val_if_fail(calobj != NULL, FALSE); - - /* start transaction */ - tid = begin_transaction(cbdb); - if (!tid) - return FALSE; - - memset(&key, 0, sizeof(key)); - key.data = (void *) uid; - key.size = strlen(uid); // + 1 - - memset(&new_data, 0, sizeof(new_data)); - new_data.data = (void *) calobj; - new_data.size = strlen(calobj); // + 1 - - if ((ret = cbdb->priv->objects_db->put(cbdb->priv->objects_db, - tid, - &key, - &new_data, - 0)) != 0) { - rollback_transaction(tid); - return FALSE; - } - - /* TODO: update history database */ - commit_transaction(tid); - - do_notify(cbdb, cal_notify_update, uid); - return TRUE; -} - -/* remove_object handler for the DB backend */ -static gboolean -cal_backend_db_remove_object (CalBackend *backend, const char *uid) -{ - CalBackendDB *cbdb; - DB_TXN *tid; - DBT key; - gint ret; - - cbdb = CAL_BACKEND_DB(backend); - g_return_val_if_fail(IS_CAL_BACKEND_DB(cbdb), FALSE); - g_return_val_if_fail(cbdb->priv != NULL, FALSE); - g_return_val_if_fail(uid != NULL, FALSE); - - memset(&key, 0, sizeof(key)); - key.data = (void *) uid; - key.size = strlen(uid); // + 1 - - /* start transaction */ - tid = begin_transaction(cbdb); - if (!tid) - return FALSE; - - /* remove record from database */ - if ((ret = cbdb->priv->objects_db->del(cbdb->priv->objects_db, tid, &key, 0)) != 0) { - rollback_transaction(tid); - return FALSE; - } - - /* TODO: update history database */ - commit_transaction(tid); - - do_notify(cbdb, cal_notify_remove, uid); - - return TRUE; -} diff --git a/calendar/pcs/cal-backend-db.h b/calendar/pcs/cal-backend-db.h deleted file mode 100644 index c73dbb5a83..0000000000 --- a/calendar/pcs/cal-backend-db.h +++ /dev/null @@ -1,57 +0,0 @@ -/* Evolution calendar - iCalendar DB backend - * - * Copyright (C) 2001 Ximian, Inc. - * - * Author: Rodrigo Moya <rodrigo@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef CAL_BACKEND_DB_H -#define CAL_BACKEND_DB_H - -#include "cal-backend.h" - -BEGIN_GNOME_DECLS - -#define CAL_BACKEND_DB_TYPE (cal_backend_db_get_type ()) -#define CAL_BACKEND_DB(obj) (GTK_CHECK_CAST ((obj), CAL_BACKEND_DB_TYPE, \ - CalBackendDB)) -#define CAL_BACKEND_DB_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), CAL_BACKEND_DB_TYPE, \ - CalBackendDBClass)) -#define IS_CAL_BACKEND_DB(obj) (GTK_CHECK_TYPE ((obj), CAL_BACKEND_DB_TYPE)) -#define IS_CAL_BACKEND_DB_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), CAL_BACKEND_DB_TYPE)) - -typedef struct _CalBackendDB CalBackendDB; -typedef struct _CalBackendDBClass CalBackendDBClass; - -typedef struct _CalBackendDBPrivate CalBackendDBPrivate; - -struct _CalBackendDB { - CalBackend backend; - - /* Private data */ - CalBackendDBPrivate *priv; -}; - -struct _CalBackendDBClass { - CalBackendClass parent_class; -}; - -GtkType cal_backend_db_get_type (void); - -END_GNOME_DECLS - -#endif diff --git a/calendar/pcs/cal-backend-file.c b/calendar/pcs/cal-backend-file.c deleted file mode 100644 index b3b3196324..0000000000 --- a/calendar/pcs/cal-backend-file.c +++ /dev/null @@ -1,1594 +0,0 @@ -/* Evolution calendar - iCalendar file backend - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#include <config.h> -#include <gtk/gtksignal.h> -#include "e-util/e-dbhash.h" -#include "cal-util/cal-recur.h" -#include "cal-backend-file.h" - - - -/* Private part of the CalBackendFile structure */ -struct _CalBackendFilePrivate { - /* URI where the calendar data is stored */ - GnomeVFSURI *uri; - - /* List of Cal objects with their listeners */ - GList *clients; - - /* Toplevel VCALENDAR component */ - icalcomponent *icalcomp; - - /* All the CalComponent objects in the calendar, hashed by UID. The - * hash key *is* the uid returned by cal_component_get_uid(); it is not - * copied, so don't free it when you remove an object from the hash - * table. - */ - GHashTable *comp_uid_hash; - - /* All event, to-do, and journal components in the calendar; they are - * here just for easy access (i.e. so that you don't have to iterate - * over the comp_uid_hash). If you need *all* the components in the - * calendar, iterate over the hash instead. - */ - GList *events; - GList *todos; - GList *journals; - - /* Idle handler for saving the calendar when it is dirty */ - guint idle_id; -}; - - - -static void cal_backend_file_class_init (CalBackendFileClass *class); -static void cal_backend_file_init (CalBackendFile *cbfile); -static void cal_backend_file_destroy (GtkObject *object); - -static GnomeVFSURI *cal_backend_file_get_uri (CalBackend *backend); -static void cal_backend_file_add_cal (CalBackend *backend, Cal *cal); -static CalBackendOpenStatus cal_backend_file_open (CalBackend *backend, GnomeVFSURI *uri, - gboolean only_if_exists); - -static int cal_backend_file_get_n_objects (CalBackend *backend, CalObjType type); -static char *cal_backend_file_get_object (CalBackend *backend, const char *uid); -static CalObjType cal_backend_file_get_type_by_uid (CalBackend *backend, const char *uid); -static GList *cal_backend_file_get_uids (CalBackend *backend, CalObjType type); -static GList *cal_backend_file_get_objects_in_range (CalBackend *backend, CalObjType type, - time_t start, time_t end); -static GNOME_Evolution_Calendar_CalObjChangeSeq *cal_backend_file_get_changes ( - CalBackend *backend, CalObjType type, const char *change_id); - -static GNOME_Evolution_Calendar_CalComponentAlarmsSeq *cal_backend_file_get_alarms_in_range ( - CalBackend *backend, time_t start, time_t end); - -static GNOME_Evolution_Calendar_CalComponentAlarms *cal_backend_file_get_alarms_for_object ( - CalBackend *backend, const char *uid, - time_t start, time_t end, gboolean *object_found); - -static gboolean cal_backend_file_update_object (CalBackend *backend, const char *uid, - const char *calobj); -static gboolean cal_backend_file_remove_object (CalBackend *backend, const char *uid); - -static CalBackendClass *parent_class; - - - -/** - * cal_backend_file_get_type: - * @void: - * - * Registers the #CalBackendFile class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the #CalBackendFile class. - **/ -GtkType -cal_backend_file_get_type (void) -{ - static GtkType cal_backend_file_type = 0; - - if (!cal_backend_file_type) { - static const GtkTypeInfo cal_backend_file_info = { - "CalBackendFile", - sizeof (CalBackendFile), - sizeof (CalBackendFileClass), - (GtkClassInitFunc) cal_backend_file_class_init, - (GtkObjectInitFunc) cal_backend_file_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - cal_backend_file_type = gtk_type_unique (CAL_BACKEND_TYPE, &cal_backend_file_info); - } - - return cal_backend_file_type; -} - -/* Class initialization function for the file backend */ -static void -cal_backend_file_class_init (CalBackendFileClass *class) -{ - GtkObjectClass *object_class; - CalBackendClass *backend_class; - - object_class = (GtkObjectClass *) class; - backend_class = (CalBackendClass *) class; - - parent_class = gtk_type_class (CAL_BACKEND_TYPE); - - object_class->destroy = cal_backend_file_destroy; - - backend_class->get_uri = cal_backend_file_get_uri; - backend_class->add_cal = cal_backend_file_add_cal; - backend_class->open = cal_backend_file_open; - backend_class->get_n_objects = cal_backend_file_get_n_objects; - backend_class->get_object = cal_backend_file_get_object; - backend_class->get_type_by_uid = cal_backend_file_get_type_by_uid; - backend_class->get_uids = cal_backend_file_get_uids; - backend_class->get_objects_in_range = cal_backend_file_get_objects_in_range; - backend_class->get_changes = cal_backend_file_get_changes; - backend_class->get_alarms_in_range = cal_backend_file_get_alarms_in_range; - backend_class->get_alarms_for_object = cal_backend_file_get_alarms_for_object; - backend_class->update_object = cal_backend_file_update_object; - backend_class->remove_object = cal_backend_file_remove_object; -} - -/* Object initialization function for the file backend */ -static void -cal_backend_file_init (CalBackendFile *cbfile) -{ - CalBackendFilePrivate *priv; - - priv = g_new0 (CalBackendFilePrivate, 1); - cbfile->priv = priv; -} - -/* g_hash_table_foreach() callback to destroy a CalComponent */ -static void -free_cal_component (gpointer key, gpointer value, gpointer data) -{ - CalComponent *comp; - - comp = CAL_COMPONENT (value); - gtk_object_unref (GTK_OBJECT (comp)); -} - -/* Saves the calendar data */ -static void -save (CalBackendFile *cbfile) -{ - CalBackendFilePrivate *priv; - GnomeVFSHandle *handle = NULL; - GnomeVFSResult result; - GnomeVFSFileSize out; - gchar *tmp; - char *buf; - - priv = cbfile->priv; - g_assert (priv->uri != NULL); - g_assert (priv->icalcomp != NULL); - - /* Make a backup copy of the file if it exists */ - tmp = gnome_vfs_uri_to_string (priv->uri, GNOME_VFS_URI_HIDE_NONE); - if (tmp) { - GnomeVFSURI *backup_uri; - gchar *backup_uristr; - - backup_uristr = g_strconcat (tmp, "~", NULL); - backup_uri = gnome_vfs_uri_new (backup_uristr); - - result = gnome_vfs_move_uri (priv->uri, backup_uri, TRUE); - gnome_vfs_uri_unref (backup_uri); - - g_free (tmp); - g_free (backup_uristr); - } - - /* Now write the new file out */ - result = gnome_vfs_create_uri (&handle, priv->uri, - GNOME_VFS_OPEN_WRITE, - FALSE, 0666); - - if (result != GNOME_VFS_OK) - goto error; - - buf = icalcomponent_as_ical_string (priv->icalcomp); - result = gnome_vfs_write (handle, buf, strlen (buf) * sizeof (char), &out); - - if (result != GNOME_VFS_OK) - goto error; - - gnome_vfs_close (handle); - - return; - - error: - g_warning ("Error writing calendar file."); - return; -} - -/* Destroy handler for the file backend */ -static void -cal_backend_file_destroy (GtkObject *object) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_CAL_BACKEND_FILE (object)); - - cbfile = CAL_BACKEND_FILE (object); - priv = cbfile->priv; - - g_assert (priv->clients == NULL); - - /* Save if necessary */ - - if (priv->idle_id != 0) { - save (cbfile); - g_source_remove (priv->idle_id); - priv->idle_id = 0; - } - - /* Clean up */ - - if (priv->uri) { - gnome_vfs_uri_unref (priv->uri); - priv->uri = NULL; - } - - if (priv->comp_uid_hash) { - g_hash_table_foreach (priv->comp_uid_hash, - free_cal_component, NULL); - g_hash_table_destroy (priv->comp_uid_hash); - priv->comp_uid_hash = NULL; - } - - g_list_free (priv->events); - g_list_free (priv->todos); - g_list_free (priv->journals); - - priv->events = NULL; - priv->todos = NULL; - priv->journals = NULL; - - if (priv->icalcomp) { - icalcomponent_free (priv->icalcomp); - priv->icalcomp = NULL; - } - - g_free (priv); - cbfile->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - - -/* Looks up a component by its UID on the backend's component hash table */ -static CalComponent * -lookup_component (CalBackendFile *cbfile, const char *uid) -{ - CalBackendFilePrivate *priv; - CalComponent *comp; - - priv = cbfile->priv; - - comp = g_hash_table_lookup (priv->comp_uid_hash, uid); - - return comp; -} - - - -/* Calendar backend methods */ - -/* Get_uri handler for the file backend */ -static GnomeVFSURI * -cal_backend_file_get_uri (CalBackend *backend) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (priv->icalcomp != NULL, NULL); - g_assert (priv->uri != NULL); - - return priv->uri; -} - -/* Callback used when a Cal is destroyed */ -static void -cal_destroy_cb (GtkObject *object, gpointer data) -{ - Cal *cal; - Cal *lcal; - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - GList *l; - - cal = CAL (object); - - cbfile = CAL_BACKEND_FILE (data); - priv = cbfile->priv; - - /* Find the cal in the list of clients */ - - for (l = priv->clients; l; l = l->next) { - lcal = CAL (l->data); - - if (lcal == cal) - break; - } - - g_assert (l != NULL); - - /* Disconnect */ - - priv->clients = g_list_remove_link (priv->clients, l); - g_list_free_1 (l); - - /* When all clients go away, notify the parent factory about it so that - * it may decide whether to kill the backend or not. - */ - if (!priv->clients) - cal_backend_last_client_gone (CAL_BACKEND (cbfile)); -} - -/* Add_cal handler for the file backend */ -static void -cal_backend_file_add_cal (CalBackend *backend, Cal *cal) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_if_fail (priv->icalcomp != NULL); - g_return_if_fail (cal != NULL); - g_return_if_fail (IS_CAL (cal)); - - /* We do not keep a reference to the Cal since the calendar user agent - * owns it. - */ - - gtk_signal_connect (GTK_OBJECT (cal), "destroy", - GTK_SIGNAL_FUNC (cal_destroy_cb), - backend); - - priv->clients = g_list_prepend (priv->clients, cal); -} - -/* Idle handler; we save the calendar since it is dirty */ -static gboolean -save_idle (gpointer data) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - - cbfile = CAL_BACKEND_FILE (data); - priv = cbfile->priv; - - g_assert (priv->icalcomp != NULL); - - save (cbfile); - - priv->idle_id = 0; - return FALSE; -} - -/* Marks the file backend as dirty and queues a save operation */ -static void -mark_dirty (CalBackendFile *cbfile) -{ - CalBackendFilePrivate *priv; - - priv = cbfile->priv; - - if (priv->idle_id != 0) - return; - - priv->idle_id = g_idle_add (save_idle, cbfile); -} - -/* Checks if the specified component has a duplicated UID and if so changes it */ -static void -check_dup_uid (CalBackendFile *cbfile, CalComponent *comp) -{ - CalBackendFilePrivate *priv; - CalComponent *old_comp; - const char *uid; - char *new_uid; - - priv = cbfile->priv; - - cal_component_get_uid (comp, &uid); - - old_comp = g_hash_table_lookup (priv->comp_uid_hash, uid); - if (!old_comp) - return; /* Everything is fine */ - - g_message ("check_dup_uid(): Got object with duplicated UID `%s', changing it...", uid); - - new_uid = cal_component_gen_uid (); - cal_component_set_uid (comp, new_uid); - g_free (new_uid); - - /* FIXME: I think we need to reset the SEQUENCE property and reset the - * CREATED/DTSTAMP/LAST-MODIFIED. - */ - - mark_dirty (cbfile); -} - -/* Tries to add an icalcomponent to the file backend. We only store the objects - * of the types we support; all others just remain in the toplevel component so - * that we don't lose them. - */ -static void -add_component (CalBackendFile *cbfile, CalComponent *comp, gboolean add_to_toplevel) -{ - CalBackendFilePrivate *priv; - GList **list; - const char *uid; - - priv = cbfile->priv; - - switch (cal_component_get_vtype (comp)) { - case CAL_COMPONENT_EVENT: - list = &priv->events; - break; - - case CAL_COMPONENT_TODO: - list = &priv->todos; - break; - - case CAL_COMPONENT_JOURNAL: - list = &priv->journals; - break; - - default: - g_assert_not_reached (); - return; - } - - /* Ensure that the UID is unique; some broken implementations spit - * components with duplicated UIDs. - */ - check_dup_uid (cbfile, comp); - cal_component_get_uid (comp, &uid); - g_hash_table_insert (priv->comp_uid_hash, (char *)uid, comp); - - *list = g_list_prepend (*list, comp); - - /* Put the object in the toplevel component if required */ - - if (add_to_toplevel) { - icalcomponent *icalcomp; - - icalcomp = cal_component_get_icalcomponent (comp); - g_assert (icalcomp != NULL); - - icalcomponent_add_component (priv->icalcomp, icalcomp); - } -} - -/* Removes a component from the backend's hash and lists. Does not perform - * notification on the clients. Also removes the component from the toplevel - * icalcomponent. - */ -static void -remove_component (CalBackendFile *cbfile, CalComponent *comp) -{ - CalBackendFilePrivate *priv; - icalcomponent *icalcomp; - const char *uid; - GList **list, *l; - - priv = cbfile->priv; - - /* Remove the icalcomp from the toplevel */ - - icalcomp = cal_component_get_icalcomponent (comp); - g_assert (icalcomp != NULL); - - icalcomponent_remove_component (priv->icalcomp, icalcomp); - - /* Remove it from our mapping */ - - cal_component_get_uid (comp, &uid); - g_hash_table_remove (priv->comp_uid_hash, uid); - - switch (cal_component_get_vtype (comp)) { - case CAL_COMPONENT_EVENT: - list = &priv->events; - break; - - case CAL_COMPONENT_TODO: - list = &priv->todos; - break; - - case CAL_COMPONENT_JOURNAL: - list = &priv->journals; - break; - - default: - /* Make the compiler shut up. */ - list = NULL; - g_assert_not_reached (); - } - - l = g_list_find (*list, comp); - g_assert (l != NULL); - - *list = g_list_remove_link (*list, l); - g_list_free_1 (l); - - gtk_object_unref (GTK_OBJECT (comp)); -} - -/* Scans the toplevel VCALENDAR component and stores the objects it finds */ -static void -scan_vcalendar (CalBackendFile *cbfile) -{ - CalBackendFilePrivate *priv; - icalcompiter iter; - - priv = cbfile->priv; - g_assert (priv->icalcomp != NULL); - g_assert (priv->comp_uid_hash != NULL); - - for (iter = icalcomponent_begin_component (priv->icalcomp, ICAL_ANY_COMPONENT); - icalcompiter_deref (&iter) != NULL; - icalcompiter_next (&iter)) { - icalcomponent *icalcomp; - icalcomponent_kind kind; - CalComponent *comp; - - icalcomp = icalcompiter_deref (&iter); - - kind = icalcomponent_isa (icalcomp); - - if (!(kind == ICAL_VEVENT_COMPONENT - || kind == ICAL_VTODO_COMPONENT - || kind == ICAL_VJOURNAL_COMPONENT)) - continue; - - comp = cal_component_new (); - - if (!cal_component_set_icalcomponent (comp, icalcomp)) - continue; - - add_component (cbfile, comp, FALSE); - } -} - -/* Callback used from icalparser_parse() */ -static char * -get_line_fn (char *s, size_t size, void *data) -{ - FILE *file; - - file = data; - return fgets (s, size, file); -} - -/* Parses an open iCalendar file and returns a toplevel component with the contents */ -static icalcomponent * -parse_file (FILE *file) -{ - icalparser *parser; - icalcomponent *icalcomp; - - parser = icalparser_new (); - icalparser_set_gen_data (parser, file); - - icalcomp = icalparser_parse (parser, get_line_fn); - icalparser_free (parser); - - return icalcomp; -} - -/* Parses an open iCalendar file and loads it into the backend */ -static CalBackendOpenStatus -open_cal (CalBackendFile *cbfile, GnomeVFSURI *uri, FILE *file) -{ - CalBackendFilePrivate *priv; - icalcomponent *icalcomp; - - priv = cbfile->priv; - - icalcomp = parse_file (file); - - if (fclose (file) != 0) { - if (icalcomp) - icalcomponent_free (icalcomp); - - return CAL_BACKEND_OPEN_ERROR; - } - - if (!icalcomp) - return CAL_BACKEND_OPEN_ERROR; - - /* FIXME: should we try to demangle XROOT components and - * individual components as well? - */ - - if (icalcomponent_isa (icalcomp) != ICAL_VCALENDAR_COMPONENT) - return CAL_BACKEND_OPEN_ERROR; - - priv->icalcomp = icalcomp; - - priv->comp_uid_hash = g_hash_table_new (g_str_hash, g_str_equal); - scan_vcalendar (cbfile); - - gnome_vfs_uri_ref (uri); - priv->uri = uri; - - return CAL_BACKEND_OPEN_SUCCESS; -} - -static CalBackendOpenStatus -create_cal (CalBackendFile *cbfile, GnomeVFSURI *uri) -{ - CalBackendFilePrivate *priv; - icalproperty *prop; - - priv = cbfile->priv; - - /* Create the new calendar information */ - - priv->icalcomp = icalcomponent_new (ICAL_VCALENDAR_COMPONENT); - - /* RFC 2445, section 4.7.1 */ - prop = icalproperty_new_calscale ("GREGORIAN"); - icalcomponent_add_property (priv->icalcomp, prop); - - /* RFC 2445, section 4.7.3 */ - prop = icalproperty_new_prodid ("-//Ximian//NONSGML Evolution Calendar//EN"); - icalcomponent_add_property (priv->icalcomp, prop); - - /* RFC 2445, section 4.7.4. This is the iCalendar spec version, *NOT* - * the product version! Do not change this! - */ - prop = icalproperty_new_version ("2.0"); - icalcomponent_add_property (priv->icalcomp, prop); - - /* Create our internal data */ - - priv->comp_uid_hash = g_hash_table_new (g_str_hash, g_str_equal); - - gnome_vfs_uri_ref (uri); - priv->uri = uri; - - mark_dirty (cbfile); - - return CAL_BACKEND_OPEN_SUCCESS; -} - -/* Open handler for the file backend */ -static CalBackendOpenStatus -cal_backend_file_open (CalBackend *backend, GnomeVFSURI *uri, gboolean only_if_exists) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - char *str_uri; - FILE *file; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (priv->icalcomp == NULL, CAL_BACKEND_OPEN_ERROR); - g_return_val_if_fail (uri != NULL, CAL_BACKEND_OPEN_ERROR); - - g_assert (priv->uri == NULL); - g_assert (priv->comp_uid_hash == NULL); - - if (!gnome_vfs_uri_is_local (uri)) - return CAL_BACKEND_OPEN_ERROR; - - str_uri = gnome_vfs_uri_to_string (uri, - (GNOME_VFS_URI_HIDE_USER_NAME - | GNOME_VFS_URI_HIDE_PASSWORD - | GNOME_VFS_URI_HIDE_HOST_NAME - | GNOME_VFS_URI_HIDE_HOST_PORT - | GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD)); - - /* Load! */ - file = fopen (str_uri, "r"); - g_free (str_uri); - - if (file) - return open_cal (cbfile, uri, file); - else { - if (only_if_exists) - return CAL_BACKEND_OPEN_NOT_FOUND; - - return create_cal (cbfile, uri); - } -} - -/* Get_n_objects handler for the file backend */ -static int -cal_backend_file_get_n_objects (CalBackend *backend, CalObjType type) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - int n; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (priv->icalcomp != NULL, -1); - - n = 0; - - if (type & CALOBJ_TYPE_EVENT) - n += g_list_length (priv->events); - - if (type & CALOBJ_TYPE_TODO) - n += g_list_length (priv->todos); - - if (type & CALOBJ_TYPE_JOURNAL) - n += g_list_length (priv->journals); - - return n; -} - -/* Get_object handler for the file backend */ -static char * -cal_backend_file_get_object (CalBackend *backend, const char *uid) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - CalComponent *comp; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (uid != NULL, NULL); - - g_return_val_if_fail (priv->icalcomp != NULL, NULL); - g_assert (priv->comp_uid_hash != NULL); - - comp = lookup_component (cbfile, uid); - - if (!comp) - return NULL; - - return cal_component_get_as_string (comp); -} - -static CalObjType -cal_backend_file_get_type_by_uid (CalBackend *backend, const char *uid) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - CalComponent *comp; - CalComponentVType type; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - comp = lookup_component (cbfile, uid); - if (!comp) - return CAL_COMPONENT_NO_TYPE; - - type = cal_component_get_vtype (comp); - switch (type) { - case CAL_COMPONENT_EVENT: - return CALOBJ_TYPE_EVENT; - case CAL_COMPONENT_TODO: - return CALOBJ_TYPE_TODO; - case CAL_COMPONENT_JOURNAL: - return CALOBJ_TYPE_JOURNAL; - default: - return CAL_COMPONENT_NO_TYPE; - } -} - -/* Builds a list of UIDs from a list of CalComponent objects */ -static void -build_uids_list (GList **list, GList *components) -{ - GList *l; - - for (l = components; l; l = l->next) { - CalComponent *comp; - const char *uid; - - comp = CAL_COMPONENT (l->data); - cal_component_get_uid (comp, &uid); - *list = g_list_prepend (*list, g_strdup (uid)); - } -} - -/* Get_uids handler for the file backend */ -static GList * -cal_backend_file_get_uids (CalBackend *backend, CalObjType type) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - GList *list; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (priv->icalcomp != NULL, NULL); - - list = NULL; - - if (type & CALOBJ_TYPE_EVENT) - build_uids_list (&list, priv->events); - - if (type & CALOBJ_TYPE_TODO) - build_uids_list (&list, priv->todos); - - if (type & CALOBJ_TYPE_JOURNAL) - build_uids_list (&list, priv->journals); - - return list; -} - -/* Callback used from cal_recur_generate_instances(); adds the component's UID - * to our hash table. - */ -static gboolean -add_instance (CalComponent *comp, time_t start, time_t end, gpointer data) -{ - GHashTable *uid_hash; - const char *uid; - const char *old_uid; - - uid_hash = data; - - /* We only care that the component's UID is listed in the hash table; - * that's why we only allow generation of one instance (i.e. return - * FALSE every time). - */ - - cal_component_get_uid (comp, &uid); - - old_uid = g_hash_table_lookup (uid_hash, uid); - if (old_uid) - return FALSE; - - g_hash_table_insert (uid_hash, (char *) uid, NULL); - return FALSE; -} - -/* Populates a hash table with the UIDs of the components that occur or recur - * within a specific time range. - */ -static void -get_instances_in_range (GHashTable *uid_hash, GList *components, time_t start, time_t end) -{ - GList *l; - - for (l = components; l; l = l->next) { - CalComponent *comp; - - comp = CAL_COMPONENT (l->data); - cal_recur_generate_instances (comp, start, end, add_instance, uid_hash); - } -} - -/* Used from g_hash_table_foreach(), adds a UID from the hash table to our list */ -static void -add_uid_to_list (gpointer key, gpointer value, gpointer data) -{ - GList **list; - const char *uid; - char *uid_copy; - - list = data; - - uid = key; - uid_copy = g_strdup (uid); - - *list = g_list_prepend (*list, uid_copy); -} - -/* Get_objects_in_range handler for the file backend */ -static GList * -cal_backend_file_get_objects_in_range (CalBackend *backend, CalObjType type, - time_t start, time_t end) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - GList *event_list; - GHashTable *uid_hash; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (priv->icalcomp != NULL, NULL); - - g_return_val_if_fail (start != -1 && end != -1, NULL); - g_return_val_if_fail (start <= end, NULL); - - uid_hash = g_hash_table_new (g_str_hash, g_str_equal); - - if (type & CALOBJ_TYPE_EVENT) - get_instances_in_range (uid_hash, priv->events, start, end); - - if (type & CALOBJ_TYPE_TODO) - get_instances_in_range (uid_hash, priv->todos, start, end); - - if (type & CALOBJ_TYPE_JOURNAL) - get_instances_in_range (uid_hash, priv->journals, start, end); - - event_list = NULL; - g_hash_table_foreach (uid_hash, add_uid_to_list, &event_list); - g_hash_table_destroy (uid_hash); - - return event_list; -} - - -typedef struct -{ - CalBackend *backend; - GList *changes; - GList *change_ids; -} CalBackendFileComputeChangesData; - -static void -cal_backend_file_compute_changes_foreach_key (const char *key, gpointer data) -{ - CalBackendFileComputeChangesData *be_data = data; - char *calobj = cal_backend_get_object (be_data->backend, key); - - if (calobj == NULL) { - CalComponent *comp; - GNOME_Evolution_Calendar_CalObjChange *coc; - - comp = cal_component_new (); - cal_component_set_new_vtype (comp, CAL_COMPONENT_TODO); - cal_component_set_uid (comp, key); - - coc = GNOME_Evolution_Calendar_CalObjChange__alloc (); - coc->calobj = CORBA_string_dup (cal_component_get_as_string (comp)); - coc->type = GNOME_Evolution_Calendar_DELETED; - be_data->changes = g_list_prepend (be_data->changes, coc); - be_data->change_ids = g_list_prepend (be_data->change_ids, (gpointer) key); - } -} - -static GNOME_Evolution_Calendar_CalObjChangeSeq * -cal_backend_file_compute_changes (CalBackend *backend, CalObjType type, const char *change_id) -{ - char *filename; - EDbHash *ehash; - CalBackendFileComputeChangesData be_data; - GNOME_Evolution_Calendar_CalObjChangeSeq *seq; - GList *uids, *changes = NULL, *change_ids = NULL; - GList *i, *j; - int n; - - /* Find the changed ids - FIX ME, path should not be hard coded */ - if (type == GNOME_Evolution_Calendar_TYPE_TODO) - filename = g_strdup_printf ("%s/evolution/local/Tasks/%s.db", g_get_home_dir (), change_id); - else - filename = g_strdup_printf ("%s/evolution/local/Calendar/%s.db", g_get_home_dir (), change_id); - ehash = e_dbhash_new (filename); - g_free (filename); - - uids = cal_backend_get_uids (backend, type); - - /* Calculate adds and modifies */ - for (i = uids; i != NULL; i = i->next) { - GNOME_Evolution_Calendar_CalObjChange *coc; - char *uid = i->data; - char *calobj = cal_backend_get_object (backend, uid); - - g_assert (calobj != NULL); - - /* check what type of change has occurred, if any */ - switch (e_dbhash_compare (ehash, uid, calobj)) { - case E_DBHASH_STATUS_SAME: - break; - case E_DBHASH_STATUS_NOT_FOUND: - coc = GNOME_Evolution_Calendar_CalObjChange__alloc (); - coc->calobj = CORBA_string_dup (calobj); - coc->type = GNOME_Evolution_Calendar_ADDED; - changes = g_list_prepend (changes, coc); - change_ids = g_list_prepend (change_ids, uid); - break; - case E_DBHASH_STATUS_DIFFERENT: - coc = GNOME_Evolution_Calendar_CalObjChange__alloc (); - coc->calobj = CORBA_string_dup (calobj); - coc->type = GNOME_Evolution_Calendar_ADDED; - changes = g_list_append (changes, coc); - change_ids = g_list_prepend (change_ids, uid); - break; - } - } - - /* Calculate deletions */ - be_data.backend = backend; - be_data.changes = changes; - be_data.change_ids = change_ids; - e_dbhash_foreach_key (ehash, (EDbHashFunc)cal_backend_file_compute_changes_foreach_key, &be_data); - changes = be_data.changes; - change_ids = be_data.change_ids; - - /* Build the sequence and update the hash */ - n = g_list_length (changes); - - seq = GNOME_Evolution_Calendar_CalObjChangeSeq__alloc (); - seq->_length = n; - seq->_buffer = CORBA_sequence_GNOME_Evolution_Calendar_CalObjChange_allocbuf (n); - CORBA_sequence_set_release (seq, TRUE); - - for (i = changes, j = change_ids, n = 0; i != NULL; i = i->next, j = j->next, n++) { - GNOME_Evolution_Calendar_CalObjChange *coc = i->data; - GNOME_Evolution_Calendar_CalObjChange *seq_coc; - char *uid = j->data; - - /* sequence building */ - seq_coc = &seq->_buffer[n]; - seq_coc->calobj = CORBA_string_dup (coc->calobj); - seq_coc->type = coc->type; - - /* hash updating */ - if (coc->type == GNOME_Evolution_Calendar_ADDED - || coc->type == GNOME_Evolution_Calendar_MODIFIED) { - e_dbhash_add (ehash, uid, coc->calobj); - } else { - e_dbhash_remove (ehash, uid); - } - - CORBA_free (coc); - } - e_dbhash_write (ehash); - e_dbhash_destroy (ehash); - - cal_obj_uid_list_free (uids); - g_list_free (change_ids); - g_list_free (changes); - - return seq; -} - -/* Get_changes handler for the file backend */ -static GNOME_Evolution_Calendar_CalObjChangeSeq * -cal_backend_file_get_changes (CalBackend *backend, CalObjType type, const char *change_id) -{ - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - - return cal_backend_file_compute_changes (backend, type, change_id); -} - -/* Computes the range of time in which recurrences should be generated for a - * component in order to compute alarm trigger times. - */ -static void -compute_alarm_range (CalComponent *comp, GList *alarm_uids, time_t start, time_t end, - time_t *alarm_start, time_t *alarm_end) -{ - GList *l; - - *alarm_start = start; - *alarm_end = end; - - for (l = alarm_uids; l; l = l->next) { - const char *auid; - CalComponentAlarm *alarm; - CalAlarmTrigger trigger; - struct icaldurationtype *dur; - time_t dur_time; - - auid = l->data; - alarm = cal_component_get_alarm (comp, auid); - g_assert (alarm != NULL); - - cal_component_alarm_get_trigger (alarm, &trigger); - cal_component_alarm_free (alarm); - - switch (trigger.type) { - case CAL_ALARM_TRIGGER_NONE: - case CAL_ALARM_TRIGGER_ABSOLUTE: - continue; - - case CAL_ALARM_TRIGGER_RELATIVE_START: - case CAL_ALARM_TRIGGER_RELATIVE_END: - dur = &trigger.u.rel_duration; - dur_time = icaldurationtype_as_int (*dur); - - if (dur->is_neg) - *alarm_end = MAX (*alarm_end, end + dur_time); - else - *alarm_start = MIN (*alarm_start, start - dur_time); - - break; - - default: - g_assert_not_reached (); - } - } - - g_assert (*alarm_start <= *alarm_end); -} - -/* Closure data to generate alarm occurrences */ -struct alarm_occurrence_data { - /* These are the info we have */ - GList *alarm_uids; - time_t start; - time_t end; - - /* This is what we compute */ - GSList *triggers; - int n_triggers; -}; - -/* Callback used from cal_recur_generate_instances(); generates triggers for all - * of a component's RELATIVE alarms. - */ -static gboolean -add_alarm_occurrences_cb (CalComponent *comp, time_t start, time_t end, gpointer data) -{ - struct alarm_occurrence_data *aod; - GList *l; - - aod = data; - - for (l = aod->alarm_uids; l; l = l->next) { - const char *auid; - CalComponentAlarm *alarm; - CalAlarmTrigger trigger; - struct icaldurationtype *dur; - time_t dur_time; - time_t occur_time, trigger_time; - CalAlarmInstance *instance; - - auid = l->data; - alarm = cal_component_get_alarm (comp, auid); - g_assert (alarm != NULL); - - cal_component_alarm_get_trigger (alarm, &trigger); - cal_component_alarm_free (alarm); - - if (trigger.type != CAL_ALARM_TRIGGER_RELATIVE_START - && trigger.type != CAL_ALARM_TRIGGER_RELATIVE_END) - continue; - - dur = &trigger.u.rel_duration; - dur_time = icaldurationtype_as_int (*dur); - - if (trigger.type == CAL_ALARM_TRIGGER_RELATIVE_START) - occur_time = start; - else - occur_time = end; - - if (dur->is_neg) - trigger_time = occur_time - dur_time; - else - trigger_time = occur_time + dur_time; - - if (trigger_time < aod->start || trigger_time >= aod->end) - continue; - - instance = g_new (CalAlarmInstance, 1); - instance->auid = auid; - instance->trigger = trigger_time; - instance->occur = occur_time; - - aod->triggers = g_slist_prepend (aod->triggers, instance); - aod->n_triggers++; - } - - return TRUE; -} - -/* Generates the absolute triggers for a component */ -static void -generate_absolute_triggers (CalComponent *comp, struct alarm_occurrence_data *aod) -{ - GList *l; - - for (l = aod->alarm_uids; l; l = l->next) { - const char *auid; - CalComponentAlarm *alarm; - CalAlarmTrigger trigger; - time_t abs_time; - CalAlarmInstance *instance; - - auid = l->data; - alarm = cal_component_get_alarm (comp, auid); - g_assert (alarm != NULL); - - cal_component_alarm_get_trigger (alarm, &trigger); - cal_component_alarm_free (alarm); - - if (trigger.type != CAL_ALARM_TRIGGER_ABSOLUTE) - continue; - - abs_time = icaltime_as_timet (trigger.u.abs_time); - - if (abs_time < aod->start || abs_time >= aod->end) - continue; - - instance = g_new (CalAlarmInstance, 1); - instance->auid = auid; - instance->trigger = abs_time; - instance->occur = abs_time; /* No particular occurrence, so just use the same time */ - - aod->triggers = g_slist_prepend (aod->triggers, instance); - aod->n_triggers++; - } -} - -/* Compares two alarm instances; called from g_slist_sort() */ -static gint -compare_alarm_instance (gconstpointer a, gconstpointer b) -{ - const CalAlarmInstance *aia, *aib; - - aia = a; - aib = b; - - if (aia->trigger < aib->trigger) - return -1; - else if (aia->trigger > aib->trigger) - return 1; - else - return 0; -} - -/* Generates alarm instances for a calendar component. Returns the instances - * structure, or NULL if no alarm instances occurred in the specified time - * range. - */ -static CalComponentAlarms * -generate_alarms_for_comp (CalComponent *comp, time_t start, time_t end) -{ - GList *alarm_uids; - time_t alarm_start, alarm_end; - struct alarm_occurrence_data aod; - CalComponentAlarms *alarms; - - if (!cal_component_has_alarms (comp)) - return NULL; - - alarm_uids = cal_component_get_alarm_uids (comp); - compute_alarm_range (comp, alarm_uids, start, end, &alarm_start, &alarm_end); - - aod.alarm_uids = alarm_uids; - aod.start = start; - aod.end = end; - aod.triggers = NULL; - aod.n_triggers = 0; - cal_recur_generate_instances (comp, alarm_start, alarm_end, add_alarm_occurrences_cb, &aod); - - /* We add the ABSOLUTE triggers separately */ - generate_absolute_triggers (comp, &aod); - - if (aod.n_triggers == 0) - return NULL; - - /* Create the component alarm instances structure */ - - alarms = g_new (CalComponentAlarms, 1); - alarms->comp = comp; - gtk_object_ref (GTK_OBJECT (alarms->comp)); - alarms->alarms = g_slist_sort (aod.triggers, compare_alarm_instance); - - return alarms; -} - -/* Iterates through all the components in the comps list and generates alarm - * instances for them; putting them in the comp_alarms list. Returns the number - * of elements it added to that list. - */ -static int -generate_alarms_for_list (GList *comps, time_t start, time_t end, GSList **comp_alarms) -{ - GList *l; - int n; - - n = 0; - - for (l = comps; l; l = l->next) { - CalComponent *comp; - CalComponentAlarms *alarms; - - comp = CAL_COMPONENT (l->data); - alarms = generate_alarms_for_comp (comp, start, end); - - if (alarms) { - *comp_alarms = g_slist_prepend (*comp_alarms, alarms); - n++; - } - } - - return n; -} - -/* Fills a CORBA sequence of alarm instances */ -static void -fill_alarm_instances_seq (GNOME_Evolution_Calendar_CalAlarmInstanceSeq *seq, GSList *alarms) -{ - int n_alarms; - GSList *l; - int i; - - n_alarms = g_slist_length (alarms); - - CORBA_sequence_set_release (seq, TRUE); - seq->_length = n_alarms; - seq->_buffer = CORBA_sequence_GNOME_Evolution_Calendar_CalAlarmInstance_allocbuf (n_alarms); - - for (l = alarms, i = 0; l; l = l->next, i++) { - CalAlarmInstance *instance; - GNOME_Evolution_Calendar_CalAlarmInstance *corba_instance; - - instance = l->data; - corba_instance = seq->_buffer + i; - - corba_instance->auid = CORBA_string_dup (instance->auid); - corba_instance->trigger = (long) instance->trigger; - corba_instance->occur = (long) instance->occur; - } -} - -/* Get_alarms_in_range handler for the file backend */ -static GNOME_Evolution_Calendar_CalComponentAlarmsSeq * -cal_backend_file_get_alarms_in_range (CalBackend *backend, time_t start, time_t end) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - int n_comp_alarms; - GSList *comp_alarms; - GSList *l; - int i; - GNOME_Evolution_Calendar_CalComponentAlarmsSeq *seq; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (priv->icalcomp != NULL, NULL); - - g_return_val_if_fail (start != -1 && end != -1, NULL); - g_return_val_if_fail (start <= end, NULL); - - /* Per RFC 2445, only VEVENTs and VTODOs can have alarms */ - - n_comp_alarms = 0; - comp_alarms = NULL; - - n_comp_alarms += generate_alarms_for_list (priv->events, start, end, &comp_alarms); - n_comp_alarms += generate_alarms_for_list (priv->todos, start, end, &comp_alarms); - - seq = GNOME_Evolution_Calendar_CalComponentAlarmsSeq__alloc (); - CORBA_sequence_set_release (seq, TRUE); - seq->_length = n_comp_alarms; - seq->_buffer = CORBA_sequence_GNOME_Evolution_Calendar_CalComponentAlarms_allocbuf ( - n_comp_alarms); - - for (l = comp_alarms, i = 0; l; l = l->next, i++) { - CalComponentAlarms *alarms; - char *comp_str; - - alarms = l->data; - - comp_str = cal_component_get_as_string (alarms->comp); - seq->_buffer[i].calobj = CORBA_string_dup (comp_str); - g_free (comp_str); - - fill_alarm_instances_seq (&seq->_buffer[i].alarms, alarms->alarms); - - cal_component_alarms_free (alarms); - } - - g_slist_free (comp_alarms); - - return seq; -} - -/* Get_alarms_for_object handler for the file backend */ -static GNOME_Evolution_Calendar_CalComponentAlarms * -cal_backend_file_get_alarms_for_object (CalBackend *backend, const char *uid, - time_t start, time_t end, gboolean *object_found) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - CalComponent *comp; - char *comp_str; - GNOME_Evolution_Calendar_CalComponentAlarms *corba_alarms; - CalComponentAlarms *alarms; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (priv->icalcomp != NULL, NULL); - - g_return_val_if_fail (uid != NULL, NULL); - g_return_val_if_fail (start != -1 && end != -1, NULL); - g_return_val_if_fail (start <= end, NULL); - g_return_val_if_fail (object_found != NULL, NULL); - - comp = lookup_component (cbfile, uid); - if (!comp) { - *object_found = FALSE; - return NULL; - } - - *object_found = TRUE; - - comp_str = cal_component_get_as_string (comp); - corba_alarms = GNOME_Evolution_Calendar_CalComponentAlarms__alloc (); - - corba_alarms->calobj = CORBA_string_dup (comp_str); - g_free (comp_str); - - alarms = generate_alarms_for_comp (comp, start, end); - if (alarms) { - fill_alarm_instances_seq (&corba_alarms->alarms, alarms->alarms); - cal_component_alarms_free (alarms); - } else - fill_alarm_instances_seq (&corba_alarms->alarms, NULL); - - return corba_alarms; -} - -/* Notifies a backend's clients that an object was updated */ -static void -notify_update (CalBackendFile *cbfile, const char *uid) -{ - CalBackendFilePrivate *priv; - GList *l; - - priv = cbfile->priv; - - for (l = priv->clients; l; l = l->next) { - Cal *cal; - - cal = CAL (l->data); - cal_notify_update (cal, uid); - } -} - -/* Notifies a backend's clients that an object was removed */ -static void -notify_remove (CalBackendFile *cbfile, const char *uid) -{ - CalBackendFilePrivate *priv; - GList *l; - - priv = cbfile->priv; - - for (l = priv->clients; l; l = l->next) { - Cal *cal; - - cal = CAL (l->data); - cal_notify_remove (cal, uid); - } -} - -/* Update_object handler for the file backend */ -static gboolean -cal_backend_file_update_object (CalBackend *backend, const char *uid, const char *calobj) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - icalcomponent *icalcomp; - icalcomponent_kind kind; - CalComponent *old_comp; - CalComponent *comp; - const char *comp_uid; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (priv->icalcomp != NULL, FALSE); - - g_return_val_if_fail (uid != NULL, FALSE); - g_return_val_if_fail (calobj != NULL, FALSE); - - /* Pull the component from the string and ensure that it is sane */ - - icalcomp = icalparser_parse_string ((char *) calobj); - - if (!icalcomp) - return FALSE; - - kind = icalcomponent_isa (icalcomp); - - if (!(kind == ICAL_VEVENT_COMPONENT - || kind == ICAL_VTODO_COMPONENT - || kind == ICAL_VJOURNAL_COMPONENT)) { - /* We don't support this type of component */ - icalcomponent_free (icalcomp); - return FALSE; - } - - comp = cal_component_new (); - if (!cal_component_set_icalcomponent (comp, icalcomp)) { - gtk_object_unref (GTK_OBJECT (comp)); - icalcomponent_free (icalcomp); - return FALSE; - } - - /* Check the UID for sanity's sake */ - - cal_component_get_uid (comp, &comp_uid); - - if (strcmp (uid, comp_uid) != 0) { - gtk_object_unref (GTK_OBJECT (comp)); - return FALSE; - } - - /* Update the component */ - - old_comp = lookup_component (cbfile, uid); - - if (old_comp) - remove_component (cbfile, old_comp); - - add_component (cbfile, comp, TRUE); - - mark_dirty (cbfile); - - /* FIXME: do the notification asynchronously */ - notify_update (cbfile, comp_uid); - - return TRUE; -} - -/* Remove_object handler for the file backend */ -static gboolean -cal_backend_file_remove_object (CalBackend *backend, const char *uid) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - CalComponent *comp; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (priv->icalcomp != NULL, FALSE); - - g_return_val_if_fail (uid != NULL, FALSE); - - comp = lookup_component (cbfile, uid); - if (!comp) - return FALSE; - - remove_component (cbfile, comp); - mark_dirty (cbfile); - - /* FIXME: do the notification asynchronously */ - notify_remove (cbfile, uid); - - return TRUE; -} - diff --git a/calendar/pcs/cal-backend-file.h b/calendar/pcs/cal-backend-file.h deleted file mode 100644 index a85c6d20fd..0000000000 --- a/calendar/pcs/cal-backend-file.h +++ /dev/null @@ -1,63 +0,0 @@ -/* Evolution calendar - iCalendar file backend - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef CAL_BACKEND_FILE_H -#define CAL_BACKEND_FILE_H - -#include <libgnome/gnome-defs.h> -#include "cal-backend.h" - -BEGIN_GNOME_DECLS - - - -#define CAL_BACKEND_FILE_TYPE (cal_backend_file_get_type ()) -#define CAL_BACKEND_FILE(obj) (GTK_CHECK_CAST ((obj), CAL_BACKEND_FILE_TYPE, \ - CalBackendFile)) -#define CAL_BACKEND_FILE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), CAL_BACKEND_FILE_TYPE, \ - CalBackendFileClass)) -#define IS_CAL_BACKEND_FILE(obj) (GTK_CHECK_TYPE ((obj), CAL_BACKEND_FILE_TYPE)) -#define IS_CAL_BACKEND_FILE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), CAL_BACKEND_FILE_TYPE)) - -typedef struct _CalBackendFile CalBackendFile; -typedef struct _CalBackendFileClass CalBackendFileClass; - -typedef struct _CalBackendFilePrivate CalBackendFilePrivate; - -struct _CalBackendFile { - CalBackend backend; - - /* Private data */ - CalBackendFilePrivate *priv; -}; - -struct _CalBackendFileClass { - CalBackendClass parent_class; -}; - -GtkType cal_backend_file_get_type (void); - - - -END_GNOME_DECLS - -#endif diff --git a/calendar/pcs/cal-backend.c b/calendar/pcs/cal-backend.c deleted file mode 100644 index a8c6aa9776..0000000000 --- a/calendar/pcs/cal-backend.c +++ /dev/null @@ -1,418 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Evolution calendar - generic backend class - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#include <config.h> -#include <gtk/gtk.h> -#include <gnome-xml/parser.h> -#include <gnome-xml/parserInternals.h> -#include <gnome-xml/xmlmemory.h> - -#include "cal-backend.h" -#include "libversit/vcc.h" - - - -/* Signal IDs */ -enum { - LAST_CLIENT_GONE, - LAST_SIGNAL -}; - -static void cal_backend_class_init (CalBackendClass *class); - -static guint cal_backend_signals[LAST_SIGNAL]; - -#define CLASS(backend) (CAL_BACKEND_CLASS (GTK_OBJECT (backend)->klass)) - - - -/** - * cal_backend_get_type: - * @void: - * - * Registers the #CalBackend class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the #CalBackend class. - **/ -GtkType -cal_backend_get_type (void) -{ - static GtkType cal_backend_type = 0; - - if (!cal_backend_type) { - static const GtkTypeInfo cal_backend_info = { - "CalBackend", - sizeof (CalBackend), - sizeof (CalBackendClass), - (GtkClassInitFunc) cal_backend_class_init, - (GtkObjectInitFunc) NULL, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - cal_backend_type = - gtk_type_unique (GTK_TYPE_OBJECT, &cal_backend_info); - } - - return cal_backend_type; -} - -/* Class initialization function for the calendar backend */ -static void -cal_backend_class_init (CalBackendClass *class) -{ - GtkObjectClass *object_class; - - object_class = (GtkObjectClass *) class; - - cal_backend_signals[LAST_CLIENT_GONE] = - gtk_signal_new ("last_client_gone", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (CalBackendClass, last_client_gone), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - gtk_object_class_add_signals (object_class, cal_backend_signals, LAST_SIGNAL); -} - - - -/** - * cal_backend_get_uri: - * @backend: A calendar backend. - * - * Queries the URI of a calendar backend, which must already have an open - * calendar. - * - * Return value: The URI where the calendar is stored. - **/ -GnomeVFSURI * -cal_backend_get_uri (CalBackend *backend) -{ - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - - g_assert (CLASS (backend)->get_uri != NULL); - return (* CLASS (backend)->get_uri) (backend); -} - -/** - * cal_backend_add_cal: - * @backend: A calendar backend. - * @cal: A calendar client interface object. - * - * Adds a calendar client interface object to a calendar @backend. - * The calendar backend must already have an open calendar. - **/ -void -cal_backend_add_cal (CalBackend *backend, Cal *cal) -{ - g_return_if_fail (backend != NULL); - g_return_if_fail (IS_CAL_BACKEND (backend)); - - g_assert (CLASS (backend)->add_cal != NULL); - (* CLASS (backend)->add_cal) (backend, cal); -} - -/** - * cal_backend_open: - * @backend: A calendar backend. - * @uri: URI that contains the calendar data. - * @only_if_exists: Whether the calendar should be opened only if it already - * exists. If FALSE, a new calendar will be created when the specified @uri - * does not exist. - * - * Opens a calendar backend with data from a calendar stored at the specified - * URI. - * - * Return value: An operation status code. - **/ -CalBackendOpenStatus -cal_backend_open (CalBackend *backend, GnomeVFSURI *uri, gboolean only_if_exists) -{ - CalBackendOpenStatus result; - - g_return_val_if_fail (backend != NULL, CAL_BACKEND_OPEN_ERROR); - g_return_val_if_fail (IS_CAL_BACKEND (backend), CAL_BACKEND_OPEN_ERROR); - g_return_val_if_fail (uri != NULL, CAL_BACKEND_OPEN_ERROR); - - g_assert (CLASS (backend)->open != NULL); - result = (* CLASS (backend)->open) (backend, uri, only_if_exists); - - return result; -} - -/** - * cal_backend_get_n_objects: - * @backend: A calendar backend. - * @type: Types of objects that will be included in the count. - * - * Queries the number of calendar objects of a particular type. - * - * Return value: Number of objects of the specified @type. - **/ -int -cal_backend_get_n_objects (CalBackend *backend, CalObjType type) -{ - g_return_val_if_fail (backend != NULL, -1); - g_return_val_if_fail (IS_CAL_BACKEND (backend), -1); - - g_assert (CLASS (backend)->get_n_objects != NULL); - return (* CLASS (backend)->get_n_objects) (backend, type); -} - -/** - * cal_backend_get_object: - * @backend: A calendar backend. - * @uid: Unique identifier for a calendar object. - * - * Queries a calendar backend for a calendar object based on its unique - * identifier. - * - * Return value: The string representation of a complete calendar wrapping the - * the sought object, or NULL if no object had the specified UID. A complete - * calendar is returned because you also need the timezone data. - **/ -char * -cal_backend_get_object (CalBackend *backend, const char *uid) -{ - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - g_return_val_if_fail (uid != NULL, NULL); - - g_assert (CLASS (backend)->get_object != NULL); - return (* CLASS (backend)->get_object) (backend, uid); -} - -/** - * cal_backend_get_uids: - * @backend: A calendar backend. - * @type: Bitmask with types of objects to return. - * - * Builds 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. The list should be - * freed using the cal_obj_uid_list_free() function. - **/ -GList * -cal_backend_get_uids (CalBackend *backend, CalObjType type) -{ - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - - g_assert (CLASS (backend)->get_uids != NULL); - return (* CLASS (backend)->get_uids) (backend, type); -} - - -/** - * cal_backend_get_objects_in_range: - * @backend: A calendar backend. - * @type: Bitmask with types of objects to return. - * @start: Start time for query. - * @end: End time for query. - * - * Builds a list of unique identifiers corresponding to calendar objects of the - * specified type that occur or recur within the specified time range. - * - * Return value: A list of UID strings. The list should be freed using the - * cal_obj_uid_list_free() function. - **/ -GList * -cal_backend_get_objects_in_range (CalBackend *backend, CalObjType type, - time_t start, time_t end) -{ - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - g_return_val_if_fail (start != -1 && end != -1, NULL); - g_return_val_if_fail (start <= end, NULL); - - g_assert (CLASS (backend)->get_objects_in_range != NULL); - return (* CLASS (backend)->get_objects_in_range) (backend, type, start, end); -} - -/** - * cal_backend_get_changes: - * @backend: A calendar backend - * @type: Bitmask with types of objects to return. - * @change_id: A unique uid for the callers change list - * - * Builds a sequence of objects and the type of change that occurred on them since - * the last time the give change_id was seen - * - * Return value: A list of the objects that changed and the type of change - **/ -GNOME_Evolution_Calendar_CalObjChangeSeq * -cal_backend_get_changes (CalBackend *backend, CalObjType type, const char *change_id) -{ - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - g_return_val_if_fail (change_id != NULL, NULL); - - g_assert (CLASS (backend)->get_changes != NULL); - return (* CLASS (backend)->get_changes) (backend, type, change_id); -} - -/** - * cal_backend_get_alarms_in_range: - * @backend: A calendar backend. - * @start: Start time for query. - * @end: End time for query. - * @valid_range: Return value that says whether the range is valid or not. - * - * Builds a sorted list of the alarms that trigger in the specified time range. - * - * Return value: A sequence of component alarm instances structures, or NULL - * if @valid_range returns FALSE. - **/ -GNOME_Evolution_Calendar_CalComponentAlarmsSeq * -cal_backend_get_alarms_in_range (CalBackend *backend, time_t start, time_t end, gboolean *valid_range) -{ - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - g_return_val_if_fail (valid_range != NULL, NULL); - - g_assert (CLASS (backend)->get_alarms_in_range != NULL); - - if (!(start != -1 && end != -1 && start <= end)) { - *valid_range = FALSE; - return NULL; - } else { - *valid_range = TRUE; - return (* CLASS (backend)->get_alarms_in_range) (backend, start, end); - } -} - -/** - * cal_backend_get_alarms_for_object: - * @backend: A calendar backend. - * @uid: Unique identifier for a calendar object. - * @start: Start time for query. - * @end: End time for query. - * @result: Return value for the result code for the operation. - * - * Builds a sorted list of the alarms of the specified event that trigger in a - * particular time range. - * - * Return value: A structure of the component's alarm instances, or NULL if @result - * returns something other than #CAL_BACKEND_GET_ALARMS_SUCCESS. - **/ -GNOME_Evolution_Calendar_CalComponentAlarms * -cal_backend_get_alarms_for_object (CalBackend *backend, const char *uid, - time_t start, time_t end, - CalBackendGetAlarmsForObjectResult *result) -{ - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - g_return_val_if_fail (uid != NULL, NULL); - g_return_val_if_fail (result != NULL, NULL); - - g_assert (CLASS (backend)->get_alarms_for_object != NULL); - - if (!(start != -1 && end != -1 && start <= end)) { - *result = CAL_BACKEND_GET_ALARMS_INVALID_RANGE; - return NULL; - } else { - gboolean object_found; - GNOME_Evolution_Calendar_CalComponentAlarms *alarms; - - alarms = (* CLASS (backend)->get_alarms_for_object) (backend, uid, start, end, - &object_found); - - if (object_found) - *result = CAL_BACKEND_GET_ALARMS_SUCCESS; - else - *result = CAL_BACKEND_GET_ALARMS_NOT_FOUND; - - return alarms; - } -} - -/** - * cal_backend_update_object: - * @backend: A calendar backend. - * @uid: Unique identifier of the object to update. - * @calobj: String representation of the new calendar object. - * - * Updates an object in a calendar backend. It will replace any existing - * object that has the same UID as the specified one. The backend will in - * turn notify all of its clients about the change. - * - * Return value: TRUE on success, FALSE on being passed an invalid object or one - * with an unsupported type. - **/ -gboolean -cal_backend_update_object (CalBackend *backend, const char *uid, const char *calobj) -{ - g_return_val_if_fail (backend != NULL, FALSE); - g_return_val_if_fail (IS_CAL_BACKEND (backend), FALSE); - g_return_val_if_fail (uid != NULL, FALSE); - g_return_val_if_fail (calobj != NULL, FALSE); - - g_assert (CLASS (backend)->update_object != NULL); - return (* CLASS (backend)->update_object) (backend, uid, calobj); -} - -/** - * cal_backend_remove_object: - * @backend: A calendar backend. - * @uid: Unique identifier of the object to remove. - * - * Removes an object in a calendar backend. The backend will notify all of its - * clients about the change. - * - * Return value: TRUE on success, FALSE on being passed an UID for an object - * that does not exist in the backend. - **/ -gboolean -cal_backend_remove_object (CalBackend *backend, const char *uid) -{ - g_return_val_if_fail (backend != NULL, FALSE); - g_return_val_if_fail (IS_CAL_BACKEND (backend), FALSE); - g_return_val_if_fail (uid != NULL, FALSE); - - g_assert (CLASS (backend)->remove_object != NULL); - return (* CLASS (backend)->remove_object) (backend, uid); -} - -/** - * cal_backend_last_client_gone: - * @backend: A calendar backend. - * - * Emits the "last_client_gone" signal of a calendar backend. This function is - * to be used only by backend implementations. - **/ -void -cal_backend_last_client_gone (CalBackend *backend) -{ - g_return_if_fail (backend != NULL); - g_return_if_fail (IS_CAL_BACKEND (backend)); - - gtk_signal_emit (GTK_OBJECT (backend), cal_backend_signals[LAST_CLIENT_GONE]); -} - diff --git a/calendar/pcs/cal-backend.h b/calendar/pcs/cal-backend.h deleted file mode 100644 index 3784601ddf..0000000000 --- a/calendar/pcs/cal-backend.h +++ /dev/null @@ -1,142 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Evolution calendar - generic backend class - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef CAL_BACKEND_H -#define CAL_BACKEND_H - -#include <libgnome/gnome-defs.h> -#include <libgnomevfs/gnome-vfs.h> -#include <cal-util/cal-util.h> -#include <cal-util/cal-component.h> -#include "evolution-calendar.h" -#include "cal-common.h" -#include "cal.h" - -BEGIN_GNOME_DECLS - - - -#define CAL_BACKEND_TYPE (cal_backend_get_type ()) -#define CAL_BACKEND(obj) (GTK_CHECK_CAST ((obj), CAL_BACKEND_TYPE, CalBackend)) -#define CAL_BACKEND_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), CAL_BACKEND_TYPE, \ - CalBackendClass)) -#define IS_CAL_BACKEND(obj) (GTK_CHECK_TYPE ((obj), CAL_BACKEND_TYPE)) -#define IS_CAL_BACKEND_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), CAL_BACKEND_TYPE)) - -/* Load status values */ -typedef enum { - CAL_BACKEND_OPEN_SUCCESS, /* Loading OK */ - CAL_BACKEND_OPEN_ERROR, /* We need better error reporting in libversit */ - CAL_BACKEND_OPEN_NOT_FOUND -} CalBackendOpenStatus; - -/* Result codes for ::get_alarms_in_range() */ -typedef enum { - CAL_BACKEND_GET_ALARMS_SUCCESS, - CAL_BACKEND_GET_ALARMS_NOT_FOUND, - CAL_BACKEND_GET_ALARMS_INVALID_RANGE -} CalBackendGetAlarmsForObjectResult; - -struct _CalBackend { - GtkObject object; -}; - -struct _CalBackendClass { - GtkObjectClass parent_class; - - /* Notification signals */ - void (* last_client_gone) (CalBackend *backend); - - /* Virtual methods */ - GnomeVFSURI *(* get_uri) (CalBackend *backend); - void (* add_cal) (CalBackend *backend, Cal *cal); - - CalBackendOpenStatus (* open) (CalBackend *backend, GnomeVFSURI *uri, - gboolean only_if_exists); - - /* General object acquirement and information related virtual methods */ - int (* get_n_objects) (CalBackend *backend, CalObjType type); - char *(* get_object) (CalBackend *backend, const char *uid); - CalObjType(* get_type_by_uid) (CalBackend *backend, const char *uid); - GList *(* get_uids) (CalBackend *backend, CalObjType type); - - GList *(* get_objects_in_range) (CalBackend *backend, CalObjType type, - time_t start, time_t end); - - /* Change related virtual methods */ - GNOME_Evolution_Calendar_CalObjChangeSeq * (* get_changes) ( - CalBackend *backend, CalObjType type, const char *change_id); - - /* Alarm related virtual methods */ - GNOME_Evolution_Calendar_CalComponentAlarmsSeq *(* get_alarms_in_range) ( - CalBackend *backend, time_t start, time_t end); - GNOME_Evolution_Calendar_CalComponentAlarms *(* get_alarms_for_object) ( - CalBackend *backend, const char *uid, - time_t start, time_t end, gboolean *object_found); - - /* Object manipulation virtual methods */ - gboolean (* update_object) (CalBackend *backend, const char *uid, const char *calobj); - gboolean (* remove_object) (CalBackend *backend, const char *uid); -}; - -GtkType cal_backend_get_type (void); - -GnomeVFSURI *cal_backend_get_uri (CalBackend *backend); - -void cal_backend_add_cal (CalBackend *backend, Cal *cal); - -CalBackendOpenStatus cal_backend_open (CalBackend *backend, GnomeVFSURI *uri, - gboolean only_if_exists); - -int cal_backend_get_n_objects (CalBackend *backend, CalObjType type); - -char *cal_backend_get_object (CalBackend *backend, const char *uid); - -GList *cal_backend_get_uids (CalBackend *backend, CalObjType type); - -GList *cal_backend_get_objects_in_range (CalBackend *backend, CalObjType type, - time_t start, time_t end); - -GNOME_Evolution_Calendar_CalObjChangeSeq * cal_backend_get_changes ( - CalBackend *backend, CalObjType type, const char *change_id); - -GNOME_Evolution_Calendar_CalComponentAlarmsSeq *cal_backend_get_alarms_in_range ( - CalBackend *backend, time_t start, time_t end, gboolean *valid_range); - -GNOME_Evolution_Calendar_CalComponentAlarms *cal_backend_get_alarms_for_object ( - CalBackend *backend, const char *uid, - time_t start, time_t end, - CalBackendGetAlarmsForObjectResult *result); - - -gboolean cal_backend_update_object (CalBackend *backend, const char *uid, const char *calobj); - -gboolean cal_backend_remove_object (CalBackend *backend, const char *uid); - -void cal_backend_last_client_gone (CalBackend *backend); - - - -END_GNOME_DECLS - -#endif diff --git a/calendar/pcs/cal-common.h b/calendar/pcs/cal-common.h deleted file mode 100644 index 3454742ce8..0000000000 --- a/calendar/pcs/cal-common.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Evolution calendar server - common declarations - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef CAL_COMMON_H -#define CAL_COMMON_H - -#include <libgnome/gnome-defs.h> - -BEGIN_GNOME_DECLS - - - -typedef struct _CalBackend CalBackend; -typedef struct _CalBackendClass CalBackendClass; - -typedef struct _Cal Cal; -typedef struct _CalClass CalClass; - - - -END_GNOME_DECLS - -#endif diff --git a/calendar/pcs/cal-factory.c b/calendar/pcs/cal-factory.c deleted file mode 100644 index d0bbd278d1..0000000000 --- a/calendar/pcs/cal-factory.c +++ /dev/null @@ -1,799 +0,0 @@ -/* Evolution calendar factory - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#include <config.h> -#include <ctype.h> -#include <stdio.h> -#include <gtk/gtksignal.h> -#include <liboaf/liboaf.h> -#include "cal.h" -#include "cal-backend.h" -#include "cal-factory.h" -#include "job.h" - - - -/* OAF ID for registration */ -#define CAL_FACTORY_OAF_ID "OAFIID:GNOME_Evolution_Wombat_CalendarFactory" - -/* Private part of the CalFactory structure */ -struct _CalFactoryPrivate { - /* Hash table from URI method strings to GtkType * for backend class types */ - GHashTable *methods; - - /* Hash table from GnomeVFSURI structures to CalBackend objects */ - GHashTable *backends; - - /* Whether we have been registered with OAF yet */ - guint registered : 1; -}; - - - -/* Signal IDs */ -enum { - LAST_CALENDAR_GONE, - LAST_SIGNAL -}; - -static void cal_factory_class_init (CalFactoryClass *class); -static void cal_factory_init (CalFactory *factory); -static void cal_factory_destroy (GtkObject *object); - -static POA_GNOME_Evolution_Calendar_CalFactory__vepv cal_factory_vepv; - -static BonoboObjectClass *parent_class; - -static guint cal_factory_signals[LAST_SIGNAL]; - - - -/** - * cal_factory_get_type: - * @void: - * - * Registers the #CalFactory class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the #CalFactory class. - **/ -GtkType -cal_factory_get_type (void) -{ - static GtkType cal_factory_type = 0; - - if (!cal_factory_type) { - static const GtkTypeInfo cal_factory_info = { - "CalFactory", - sizeof (CalFactory), - sizeof (CalFactoryClass), - (GtkClassInitFunc) cal_factory_class_init, - (GtkObjectInitFunc) cal_factory_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - cal_factory_type = gtk_type_unique (bonobo_object_get_type (), &cal_factory_info); - } - - return cal_factory_type; -} - -/* CORBA class initialization function for the calendar factory */ -static void -init_cal_factory_corba_class (void) -{ - cal_factory_vepv.Bonobo_Unknown_epv = bonobo_object_get_epv (); - cal_factory_vepv.GNOME_Evolution_Calendar_CalFactory_epv = cal_factory_get_epv (); -} - -/* Class initialization function for the calendar factory */ -static void -cal_factory_class_init (CalFactoryClass *class) -{ - GtkObjectClass *object_class; - - object_class = (GtkObjectClass *) class; - - parent_class = gtk_type_class (bonobo_object_get_type ()); - - cal_factory_signals[LAST_CALENDAR_GONE] = - gtk_signal_new ("last_calendar_gone", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (CalFactoryClass, last_calendar_gone), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - gtk_object_class_add_signals (object_class, cal_factory_signals, LAST_SIGNAL); - - object_class->destroy = cal_factory_destroy; - - init_cal_factory_corba_class (); -} - -/* Object initialization function for the calendar factory */ -static void -cal_factory_init (CalFactory *factory) -{ - CalFactoryPrivate *priv; - - priv = g_new0 (CalFactoryPrivate, 1); - factory->priv = priv; - - priv->methods = g_hash_table_new (g_str_hash, g_str_equal); - priv->backends = g_hash_table_new (gnome_vfs_uri_hash, gnome_vfs_uri_hequal); - priv->registered = FALSE; -} - -/* Frees a method/GtkType * pair from the methods hash table */ -static void -free_method (gpointer key, gpointer value, gpointer data) -{ - char *method; - GtkType *type; - - method = key; - type = value; - - g_free (method); - g_free (type); -} - -/* Frees a uri/backend pair from the backends hash table */ -static void -free_backend (gpointer key, gpointer value, gpointer data) -{ - GnomeVFSURI *uri; - CalBackend *backend; - - uri = key; - backend = value; - - gnome_vfs_uri_unref (uri); - gtk_object_unref (GTK_OBJECT (backend)); -} - -/* Destroy handler for the calendar */ -static void -cal_factory_destroy (GtkObject *object) -{ - CalFactory *factory; - CalFactoryPrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_CAL_FACTORY (object)); - - factory = CAL_FACTORY (object); - priv = factory->priv; - - g_hash_table_foreach (priv->methods, free_method, NULL); - g_hash_table_destroy (priv->methods); - priv->methods = NULL; - - /* Should we assert that there are no more backends? */ - - g_hash_table_foreach (priv->backends, free_backend, NULL); - g_hash_table_destroy (priv->backends); - priv->backends = NULL; - - if (priv->registered) { - CORBA_Object obj; - - obj = bonobo_object_corba_objref (BONOBO_OBJECT (factory)); - oaf_active_server_unregister (CAL_FACTORY_OAF_ID, obj); - priv->registered = FALSE; - } - - g_free (priv); - factory->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - - -/* Opening calendars */ - -/* Looks up a calendar backend in a factory's hash table of uri->cal */ -static CalBackend * -lookup_backend (CalFactory *factory, GnomeVFSURI *uri) -{ - CalFactoryPrivate *priv; - CalBackend *backend; - - priv = factory->priv; - - backend = g_hash_table_lookup (priv->backends, uri); - return backend; -} - -/* Callback used when a backend loses its last connected client */ -static void -backend_last_client_gone_cb (CalBackend *backend, gpointer data) -{ - CalFactory *factory; - CalFactoryPrivate *priv; - GnomeVFSURI *uri; - gpointer orig_key; - gboolean result; - GnomeVFSURI *orig_uri; - - fprintf (stderr, "backend_last_client_gone_cb() called!\n"); - - factory = CAL_FACTORY (data); - priv = factory->priv; - - /* Remove the backend from the hash table */ - - uri = cal_backend_get_uri (backend); - g_assert (uri != NULL); - - result = g_hash_table_lookup_extended (priv->backends, uri, &orig_key, NULL); - g_assert (result != FALSE); - - orig_uri = orig_key; - - g_hash_table_remove (priv->backends, orig_uri); - gnome_vfs_uri_unref (orig_uri); - - gtk_object_unref (GTK_OBJECT (backend)); - - /* Notify upstream if there are no more backends */ - - if (g_hash_table_size (priv->backends) == 0) - gtk_signal_emit (GTK_OBJECT (factory), cal_factory_signals[LAST_CALENDAR_GONE]); -} - -/* Adds a backend to the calendar factory's hash table */ -static void -add_backend (CalFactory *factory, GnomeVFSURI *uri, CalBackend *backend) -{ - CalFactoryPrivate *priv; - - priv = factory->priv; - - gnome_vfs_uri_ref (uri); - g_hash_table_insert (priv->backends, uri, backend); - - gtk_signal_connect (GTK_OBJECT (backend), "last_client_gone", - GTK_SIGNAL_FUNC (backend_last_client_gone_cb), - factory); -} - -/* Tries to launch a backend for the method of the specified URI. If there is - * no such method registered in the factory, it sends the listener the - * MethodNotSupported error code. - */ -static CalBackend * -launch_backend_for_uri (CalFactory *factory, GnomeVFSURI *uri, GNOME_Evolution_Calendar_Listener listener) -{ - CalFactoryPrivate *priv; - char *method; - GtkType *type; - CalBackend *backend; - - priv = factory->priv; - - /* FIXME: add an accessor function to gnome-vfs */ - method = uri->method_string; - - type = g_hash_table_lookup (priv->methods, method); - - if (!type) { - CORBA_Environment ev; - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_Listener_notifyCalOpened ( - listener, - GNOME_Evolution_Calendar_Listener_METHOD_NOT_SUPPORTED, - CORBA_OBJECT_NIL, - &ev); - - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("launch_backend_for_uri(): could not notify the listener"); - - CORBA_exception_free (&ev); - return NULL; - } - - backend = gtk_type_new (*type); - if (!backend) - g_message ("launch_backend_for_uri(): could not launch the backend"); - - return backend; -} - -/* Opens a calendar backend and puts it in the factory's backend hash table */ -static CalBackend * -open_backend (CalFactory *factory, GnomeVFSURI *uri, gboolean only_if_exists, - GNOME_Evolution_Calendar_Listener listener) -{ - CalFactoryPrivate *priv; - CalBackend *backend; - CalBackendOpenStatus status; - CORBA_Environment ev; - - priv = factory->priv; - - backend = launch_backend_for_uri (factory, uri, listener); - if (!backend) - return NULL; - - status = cal_backend_open (backend, uri, only_if_exists); - - switch (status) { - case CAL_BACKEND_OPEN_SUCCESS: - add_backend (factory, uri, backend); - return backend; - - case CAL_BACKEND_OPEN_ERROR: - gtk_object_unref (GTK_OBJECT (backend)); - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_Listener_notifyCalOpened ( - listener, - GNOME_Evolution_Calendar_Listener_ERROR, - CORBA_OBJECT_NIL, - &ev); - - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("open_backend(): could not notify the listener"); - - CORBA_exception_free (&ev); - return NULL; - - case CAL_BACKEND_OPEN_NOT_FOUND: - gtk_object_unref (GTK_OBJECT (backend)); - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_Listener_notifyCalOpened ( - listener, - GNOME_Evolution_Calendar_Listener_NOT_FOUND, - CORBA_OBJECT_NIL, - &ev); - - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("open_backend(): could not notify the listener"); - - CORBA_exception_free (&ev); - return NULL; - - default: - g_assert_not_reached (); - return NULL; - } -} - -/* Adds a listener to a calendar backend by creating a calendar client interface - * object. - */ -static void -add_calendar_client (CalFactory *factory, CalBackend *backend, GNOME_Evolution_Calendar_Listener listener) -{ - Cal *cal; - CORBA_Environment ev; - - cal = cal_new (backend, listener); - if (!cal) { - g_message ("add_calendar_client(): could not create the calendar client interface"); - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_Listener_notifyCalOpened ( - listener, - GNOME_Evolution_Calendar_Listener_ERROR, - CORBA_OBJECT_NIL, - &ev); - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("add_calendar_client(): could not notify the listener"); - - CORBA_exception_free (&ev); - return; - } - - cal_backend_add_cal (backend, cal); - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_Listener_notifyCalOpened ( - listener, - GNOME_Evolution_Calendar_Listener_SUCCESS, - bonobo_object_corba_objref (BONOBO_OBJECT (cal)), - &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("add_calendar_client(): could not notify the listener"); - bonobo_object_unref (BONOBO_OBJECT (cal)); - } - - CORBA_exception_free (&ev); -} - -/* Job data */ -typedef struct { - CalFactory *factory; - char *uri; - gboolean only_if_exists; - GNOME_Evolution_Calendar_Listener listener; -} OpenJobData; - -/* Job handler for the open calendar command */ -static void -open_fn (gpointer data) -{ - OpenJobData *jd; - CalFactory *factory; - GnomeVFSURI *uri; - gboolean only_if_exists; - GNOME_Evolution_Calendar_Listener listener; - CalBackend *backend; - CORBA_Environment ev; - - jd = data; - g_assert (jd->uri != NULL); - - /* Check the URI */ - - uri = gnome_vfs_uri_new (jd->uri); - g_free (jd->uri); - - only_if_exists = jd->only_if_exists; - factory = jd->factory; - listener = jd->listener; - g_free (jd); - - if (!uri) { - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_Listener_notifyCalOpened ( - listener, - GNOME_Evolution_Calendar_Listener_ERROR, - CORBA_OBJECT_NIL, - &ev); - - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("open_fn(): Could not notify the listener!"); - - CORBA_exception_free (&ev); - goto out; - } - - /* Look up the backend and create it if needed */ - - backend = lookup_backend (factory, uri); - - if (!backend) - backend = open_backend (factory, uri, only_if_exists, listener); - - gnome_vfs_uri_unref (uri); - - if (backend) - add_calendar_client (factory, backend, listener); - - out: - - CORBA_exception_init (&ev); - CORBA_Object_release (listener, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("open_fn(): could not release the listener"); - - CORBA_exception_free (&ev); -} - - - -/* CORBA servant implementation */ - -/* CalFactory::open method */ -static void -CalFactory_open (PortableServer_Servant servant, - const CORBA_char *uri, - CORBA_boolean only_if_exists, - GNOME_Evolution_Calendar_Listener listener, - CORBA_Environment *ev) -{ - CalFactory *factory; - CalFactoryPrivate *priv; - CORBA_Environment ev2; - gboolean result; - OpenJobData *jd; - GNOME_Evolution_Calendar_Listener listener_copy; - - factory = CAL_FACTORY (bonobo_object_from_servant (servant)); - priv = factory->priv; - - CORBA_exception_init (&ev2); - result = CORBA_Object_is_nil (listener, &ev2); - - if (ev2._major != CORBA_NO_EXCEPTION || result) { - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_GNOME_Evolution_Calendar_CalFactory_NilListener, - NULL); - - CORBA_exception_free (&ev2); - return; - } - CORBA_exception_free (&ev2); - - CORBA_exception_init (&ev2); - listener_copy = CORBA_Object_duplicate (listener, &ev2); - - if (ev2._major != CORBA_NO_EXCEPTION) { - g_message ("CalFactory_open(): could not duplicate the listener"); - CORBA_exception_free (&ev2); - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_GNOME_Evolution_Calendar_CalFactory_NilListener, - NULL); - return; - } - - CORBA_exception_free (&ev2); - - jd = g_new (OpenJobData, 1); - jd->factory = factory; - jd->uri = g_strdup (uri); - jd->only_if_exists = only_if_exists; - jd->listener = listener_copy; - - job_add (open_fn, jd); -} - -/** - * cal_factory_get_epv: - * @void: - * - * Creates an EPV for the CalFactory CORBA class. - * - * Return value: A newly-allocated EPV. - **/ -POA_GNOME_Evolution_Calendar_CalFactory__epv * -cal_factory_get_epv (void) -{ - POA_GNOME_Evolution_Calendar_CalFactory__epv *epv; - - epv = g_new0 (POA_GNOME_Evolution_Calendar_CalFactory__epv, 1); - epv->open = CalFactory_open; - - return epv; -} - - - -/** - * cal_factory_construct: - * @factory: A calendar factory. - * @corba_factory: CORBA object for the calendar factory. - * - * Constructs a calendar factory by binding the corresponding CORBA object to - * it. - * - * Return value: The same object as the @factory argument. - **/ -CalFactory * -cal_factory_construct (CalFactory *factory, GNOME_Evolution_Calendar_CalFactory corba_factory) -{ - g_return_val_if_fail (factory != NULL, NULL); - g_return_val_if_fail (IS_CAL_FACTORY (factory), NULL); - - bonobo_object_construct (BONOBO_OBJECT (factory), corba_factory); - return factory; -} - -/** - * cal_factory_corba_object_create: - * @object: #BonoboObject that will wrap the CORBA object. - * - * Creates and activates the CORBA object that is wrapped by the specified - * calendar factory @object. - * - * Return value: An activated object reference or #CORBA_OBJECT_NIL in case of - * failure. - **/ -GNOME_Evolution_Calendar_CalFactory -cal_factory_corba_object_create (BonoboObject *object) -{ - POA_GNOME_Evolution_Calendar_CalFactory *servant; - CORBA_Environment ev; - - g_return_val_if_fail (object != NULL, CORBA_OBJECT_NIL); - g_return_val_if_fail (IS_CAL_FACTORY (object), CORBA_OBJECT_NIL); - - servant = (POA_GNOME_Evolution_Calendar_CalFactory *) g_new0 (BonoboObjectServant, 1); - servant->vepv = &cal_factory_vepv; - - CORBA_exception_init (&ev); - POA_GNOME_Evolution_Calendar_CalFactory__init ((PortableServer_Servant) servant, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("cal_factory_corba_object_create(): could not init the servant"); - g_free (servant); - CORBA_exception_free (&ev); - return CORBA_OBJECT_NIL; - } - - CORBA_exception_free (&ev); - return (GNOME_Evolution_Calendar_CalFactory) bonobo_object_activate_servant (object, servant); -} - -/** - * cal_factory_new: - * @void: - * - * Creates a new #CalFactory object. - * - * Return value: A newly-created #CalFactory, or NULL if its corresponding CORBA - * object could not be created. - **/ -CalFactory * -cal_factory_new (void) -{ - CalFactory *factory; - CORBA_Environment ev; - GNOME_Evolution_Calendar_CalFactory corba_factory; - gboolean retval; - - factory = gtk_type_new (CAL_FACTORY_TYPE); - - corba_factory = cal_factory_corba_object_create (BONOBO_OBJECT (factory)); - - CORBA_exception_init (&ev); - retval = CORBA_Object_is_nil (corba_factory, &ev); - - if (ev._major != CORBA_NO_EXCEPTION || retval) { - g_message ("cal_factory_new(): could not create the CORBA factory"); - bonobo_object_unref (BONOBO_OBJECT (factory)); - CORBA_exception_free (&ev); - return NULL; - } - CORBA_exception_free (&ev); - - return cal_factory_construct (factory, corba_factory); -} - -/* Returns the lowercase version of a string */ -static char * -str_tolower (const char *s) -{ - char *str; - unsigned char *p; - - str = g_strdup (s); - for (p = str; *p; p++) - if (isalpha (*p)) - *p = tolower (*p); - - return str; -} - -/** - * cal_factory_oaf_register: - * @factory: A calendar factory. - * - * Registers a calendar factory with the OAF object activation daemon. This - * function must be called before any clients can activate the factory. - * - * Return value: TRUE on success, FALSE otherwise. - **/ -gboolean -cal_factory_oaf_register (CalFactory *factory) -{ - CalFactoryPrivate *priv; - OAF_RegistrationResult result; - CORBA_Object obj; - - g_return_val_if_fail (factory != NULL, FALSE); - g_return_val_if_fail (IS_CAL_FACTORY (factory), FALSE); - - priv = factory->priv; - - g_return_val_if_fail (!priv->registered, FALSE); - - obj = bonobo_object_corba_objref (BONOBO_OBJECT (factory)); - result = oaf_active_server_register (CAL_FACTORY_OAF_ID, obj); - - switch (result) { - case OAF_REG_SUCCESS: - priv->registered = TRUE; - return TRUE; - - case OAF_REG_NOT_LISTED: - g_message ("cal_factory_oaf_register(): Cannot register the calendar factory: " - "not listed"); - break; - - case OAF_REG_ALREADY_ACTIVE: - g_message ("cal_factory_oaf_register(): Cannot register the calendar factory: " - "already active"); - break; - - case OAF_REG_ERROR: - default: - g_message ("cal_factory_oaf_register(): Cannot register the calendar factory: " - "generic error"); - break; - } - - return FALSE; -} - -/** - * cal_factory_register_method: - * @factory: A calendar factory. - * @method: Method for the URI, i.e. "http", "file", etc. - * @backend_type: Class type of the backend to create for this @method. - * - * Registers the type of a #CalBackend subclass that will be used to handle URIs - * with a particular method. When the factory is asked to open a particular - * URI, it will look in its list of registered methods and create a backend of - * the appropriate type. - **/ -void -cal_factory_register_method (CalFactory *factory, const char *method, GtkType backend_type) -{ - CalFactoryPrivate *priv; - GtkType *type; - char *method_str; - - g_return_if_fail (factory != NULL); - g_return_if_fail (IS_CAL_FACTORY (factory)); - g_return_if_fail (method != NULL); - g_return_if_fail (backend_type != 0); - g_return_if_fail (gtk_type_is_a (backend_type, CAL_BACKEND_TYPE)); - - priv = factory->priv; - - method_str = str_tolower (method); - - type = g_hash_table_lookup (priv->methods, method_str); - if (type) { - g_message ("cal_factory_register_method(): Method `%s' already registered!", - method_str); - g_free (method_str); - return; - } - - type = g_new (GtkType, 1); - *type = backend_type; - - g_hash_table_insert (priv->methods, method_str, type); -} - -/** - * cal_factory_get_n_backends: - * @factory: A calendar factory. - * - * Queries the number of running calendar backends in a calendar factory. - * - * Return value: Number of running backends. - **/ -int -cal_factory_get_n_backends (CalFactory *factory) -{ - CalFactoryPrivate *priv; - - g_return_val_if_fail (factory != NULL, -1); - g_return_val_if_fail (IS_CAL_FACTORY (factory), -1); - - priv = factory->priv; - return g_hash_table_size (priv->backends); -} diff --git a/calendar/pcs/cal-factory.h b/calendar/pcs/cal-factory.h deleted file mode 100644 index ac28a5935b..0000000000 --- a/calendar/pcs/cal-factory.h +++ /dev/null @@ -1,81 +0,0 @@ -/* Evolution calendar factory - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef CAL_FACTORY_H -#define CAL_FACTORY_H - -#include <libgnome/gnome-defs.h> -#include <bonobo/bonobo-object.h> - -#include "calendar/pcs/evolution-calendar.h" - -BEGIN_GNOME_DECLS - - - -#define CAL_FACTORY_TYPE (cal_factory_get_type ()) -#define CAL_FACTORY(obj) (GTK_CHECK_CAST ((obj), CAL_FACTORY_TYPE, CalFactory)) -#define CAL_FACTORY_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), CAL_FACTORY_TYPE, \ - CalFactoryClass)) -#define IS_CAL_FACTORY(obj) (GTK_CHECK_TYPE ((obj), CAL_FACTORY_TYPE)) -#define IS_CAL_FACTORY_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), CAL_FACTORY_TYPE)) - -typedef struct _CalFactory CalFactory; -typedef struct _CalFactoryClass CalFactoryClass; - -typedef struct _CalFactoryPrivate CalFactoryPrivate; - -struct _CalFactory { - BonoboObject object; - - /* Private data */ - CalFactoryPrivate *priv; -}; - -struct _CalFactoryClass { - BonoboObjectClass parent_class; - - /* Notification signals */ - void (* last_calendar_gone) (CalFactory *factory); -}; - -GtkType cal_factory_get_type (void); - -CalFactory *cal_factory_construct (CalFactory *factory, - GNOME_Evolution_Calendar_CalFactory corba_factory); -GNOME_Evolution_Calendar_CalFactory cal_factory_corba_object_create (BonoboObject *object); - -CalFactory *cal_factory_new (void); - -gboolean cal_factory_oaf_register (CalFactory *factory); - -void cal_factory_register_method (CalFactory *factory, const char *method, GtkType backend_type); - -int cal_factory_get_n_backends (CalFactory *factory); - -POA_GNOME_Evolution_Calendar_CalFactory__epv *cal_factory_get_epv (void); - - - -END_GNOME_DECLS - -#endif diff --git a/calendar/pcs/cal.c b/calendar/pcs/cal.c deleted file mode 100644 index 69eccd7f55..0000000000 --- a/calendar/pcs/cal.c +++ /dev/null @@ -1,666 +0,0 @@ -/* Evolution calendar client interface object - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#include <config.h> -#include "cal.h" -#include "cal-backend.h" - - - -/* Private part of the Cal structure */ -struct _CalPrivate { - /* Our backend */ - CalBackend *backend; - - /* Listener on the client we notify */ - GNOME_Evolution_Calendar_Listener listener; -}; - - - -static void cal_class_init (CalClass *class); -static void cal_init (Cal *cal); -static void cal_destroy (GtkObject *object); - -static POA_GNOME_Evolution_Calendar_Cal__vepv cal_vepv; - -static BonoboObjectClass *parent_class; - - - -/** - * cal_get_type: - * @void: - * - * Registers the #Cal class if necessary, and returns the type ID associated to - * it. - * - * Return value: The type ID of the #Cal class. - **/ -GtkType -cal_get_type (void) -{ - static GtkType cal_type = 0; - - if (!cal_type) { - static const GtkTypeInfo cal_info = { - "Cal", - sizeof (Cal), - sizeof (CalClass), - (GtkClassInitFunc) cal_class_init, - (GtkObjectInitFunc) cal_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - cal_type = gtk_type_unique (BONOBO_OBJECT_TYPE, &cal_info); - } - - return cal_type; -} - -/* CORBA class initialzation function for the calendar */ -static void -init_cal_corba_class (void) -{ - cal_vepv.Bonobo_Unknown_epv = bonobo_object_get_epv (); - cal_vepv.GNOME_Evolution_Calendar_Cal_epv = cal_get_epv (); -} - -/* Class initialization function for the calendar */ -static void -cal_class_init (CalClass *class) -{ - GtkObjectClass *object_class; - - object_class = (GtkObjectClass *) class; - - parent_class = gtk_type_class (BONOBO_OBJECT_TYPE); - - object_class->destroy = cal_destroy; - - init_cal_corba_class (); -} - -/* Object initialization function for the calendar */ -static void -cal_init (Cal *cal) -{ - CalPrivate *priv; - - priv = g_new0 (CalPrivate, 1); - cal->priv = priv; - - priv->listener = CORBA_OBJECT_NIL; -} - -/* Destroy handler for the calendar */ -static void -cal_destroy (GtkObject *object) -{ - Cal *cal; - CalPrivate *priv; - CORBA_Environment ev; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_CAL (object)); - - cal = CAL (object); - priv = cal->priv; - - priv->backend = NULL; - - CORBA_exception_init (&ev); - CORBA_Object_release (priv->listener, &ev); - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("cal_destroy(): could not release the listener"); - - CORBA_exception_free (&ev); - - g_free (priv); - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - - -/* CORBA servant implementation */ - -/* Cal::get_uri method */ -static CORBA_char * -Cal_get_uri (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - GnomeVFSURI *uri; - char *str_uri; - CORBA_char *str_uri_copy; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - uri = cal_backend_get_uri (priv->backend); - str_uri = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE); - str_uri_copy = CORBA_string_dup (str_uri); - g_free (str_uri); - - return str_uri_copy; -} - -/* Converts a calendar object type from its CORBA representation to our own - * representation. - */ -static CalObjType -uncorba_obj_type (GNOME_Evolution_Calendar_CalObjType type) -{ - return (((type & GNOME_Evolution_Calendar_TYPE_EVENT) ? CALOBJ_TYPE_EVENT : 0) - | ((type & GNOME_Evolution_Calendar_TYPE_TODO) ? CALOBJ_TYPE_TODO : 0) - | ((type & GNOME_Evolution_Calendar_TYPE_JOURNAL) ? CALOBJ_TYPE_JOURNAL : 0)); -} - -/* Cal::get_n_objects method */ -static CORBA_long -Cal_get_n_objects (PortableServer_Servant servant, - GNOME_Evolution_Calendar_CalObjType type, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - int t; - int n; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - t = uncorba_obj_type (type); - n = cal_backend_get_n_objects (priv->backend, t); - return n; -} - -/* Cal::get_object method */ -static GNOME_Evolution_Calendar_CalObj -Cal_get_object (PortableServer_Servant servant, - const GNOME_Evolution_Calendar_CalObjUID uid, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - char *calobj; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - calobj = cal_backend_get_object (priv->backend, uid); - - if (calobj) { - CORBA_char *calobj_copy; - - calobj_copy = CORBA_string_dup (calobj); - g_free (calobj); - return calobj_copy; - } else { - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_GNOME_Evolution_Calendar_Cal_NotFound, - NULL); - return NULL; - } -} - -static GNOME_Evolution_Calendar_CalObjUIDSeq * -build_uid_seq (GList *uids) -{ - GNOME_Evolution_Calendar_CalObjUIDSeq *seq; - GList *l; - int n, i; - - n = g_list_length (uids); - - seq = GNOME_Evolution_Calendar_CalObjUIDSeq__alloc (); - CORBA_sequence_set_release (seq, TRUE); - seq->_length = n; - seq->_buffer = CORBA_sequence_GNOME_Evolution_Calendar_CalObjUID_allocbuf (n); - - /* Fill the sequence */ - - for (i = 0, l = uids; l; i++, l = l->next) { - char *uid; - - uid = l->data; - seq->_buffer[i] = CORBA_string_dup (uid); - } - - return seq; -} - -/* Cal::get_uids method */ -static GNOME_Evolution_Calendar_CalObjUIDSeq * -Cal_get_uids (PortableServer_Servant servant, - GNOME_Evolution_Calendar_CalObjType type, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - GList *uids; - GNOME_Evolution_Calendar_CalObjUIDSeq *seq; - int t; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - t = uncorba_obj_type (type); - - uids = cal_backend_get_uids (priv->backend, t); - seq = build_uid_seq (uids); - - cal_obj_uid_list_free (uids); - - return seq; -} - -/* Cal::get_changes method */ -static GNOME_Evolution_Calendar_CalObjChangeSeq * -Cal_get_changes (PortableServer_Servant servant, - GNOME_Evolution_Calendar_CalObjType type, - const CORBA_char *change_id, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - int t; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - t = uncorba_obj_type (type); - - return cal_backend_get_changes (priv->backend, t, change_id); -} - -/* Cal::get_objects_in_range method */ -static GNOME_Evolution_Calendar_CalObjUIDSeq * -Cal_get_objects_in_range (PortableServer_Servant servant, - GNOME_Evolution_Calendar_CalObjType type, - GNOME_Evolution_Calendar_Time_t start, - GNOME_Evolution_Calendar_Time_t end, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - int t; - time_t t_start, t_end; - GNOME_Evolution_Calendar_CalObjUIDSeq *seq; - GList *uids; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - t = uncorba_obj_type (type); - t_start = (time_t) start; - t_end = (time_t) end; - - if (t_start > t_end || t_start == -1 || t_end == -1) { - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_GNOME_Evolution_Calendar_Cal_InvalidRange, - NULL); - return NULL; - } - - uids = cal_backend_get_objects_in_range (priv->backend, t, t_start, t_end); - seq = build_uid_seq (uids); - - cal_obj_uid_list_free (uids); - - return seq; -} - -/* Cal::get_alarms_in_range method */ -static GNOME_Evolution_Calendar_CalComponentAlarmsSeq * -Cal_get_alarms_in_range (PortableServer_Servant servant, - GNOME_Evolution_Calendar_Time_t start, - GNOME_Evolution_Calendar_Time_t end, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - time_t t_start, t_end; - gboolean valid_range; - GNOME_Evolution_Calendar_CalComponentAlarmsSeq *seq; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - t_start = (time_t) start; - t_end = (time_t) end; - - seq = cal_backend_get_alarms_in_range (priv->backend, t_start, t_end, &valid_range); - if (!valid_range) { - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_GNOME_Evolution_Calendar_Cal_InvalidRange, - NULL); - return NULL; - } - - return seq; -} - -/* Cal::get_alarms_for_object method */ -static GNOME_Evolution_Calendar_CalComponentAlarms * -Cal_get_alarms_for_object (PortableServer_Servant servant, - const GNOME_Evolution_Calendar_CalObjUID uid, - GNOME_Evolution_Calendar_Time_t start, - GNOME_Evolution_Calendar_Time_t end, - CORBA_Environment * ev) -{ - Cal *cal; - CalPrivate *priv; - time_t t_start, t_end; - GNOME_Evolution_Calendar_CalComponentAlarms *alarms; - CalBackendGetAlarmsForObjectResult result; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - t_start = (time_t) start; - t_end = (time_t) end; - - alarms = cal_backend_get_alarms_for_object (priv->backend, uid, t_start, t_end, &result); - - switch (result) { - case CAL_BACKEND_GET_ALARMS_SUCCESS: - return alarms; - - case CAL_BACKEND_GET_ALARMS_NOT_FOUND: - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_GNOME_Evolution_Calendar_Cal_NotFound, - NULL); - return NULL; - - case CAL_BACKEND_GET_ALARMS_INVALID_RANGE: - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_GNOME_Evolution_Calendar_Cal_InvalidRange, - NULL); - return NULL; - - default: - g_assert_not_reached (); - return NULL; - } -} - -/* Cal::update_object method */ -static void -Cal_update_object (PortableServer_Servant servant, - const GNOME_Evolution_Calendar_CalObjUID uid, - const GNOME_Evolution_Calendar_CalObj calobj, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - if (!cal_backend_update_object (priv->backend, uid, calobj)) - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_GNOME_Evolution_Calendar_Cal_InvalidObject, - NULL); -} - -/* Cal::remove_object method */ -static void -Cal_remove_object (PortableServer_Servant servant, - const GNOME_Evolution_Calendar_CalObjUID uid, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - if (!cal_backend_remove_object (priv->backend, uid)) - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_GNOME_Evolution_Calendar_Cal_NotFound, - NULL); -} - -/** - * cal_get_epv: - * @void: - * - * Creates an EPV for the Cal CORBA class. - * - * Return value: A newly-allocated EPV. - **/ -POA_GNOME_Evolution_Calendar_Cal__epv * -cal_get_epv (void) -{ - POA_GNOME_Evolution_Calendar_Cal__epv *epv; - - epv = g_new0 (POA_GNOME_Evolution_Calendar_Cal__epv, 1); - epv->_get_uri = Cal_get_uri; - epv->countObjects = Cal_get_n_objects; - epv->getObject = Cal_get_object; - epv->getUIds = Cal_get_uids; - epv->getChanges = Cal_get_changes; - epv->getObjectsInRange = Cal_get_objects_in_range; - epv->getAlarmsInRange = Cal_get_alarms_in_range; - epv->getAlarmsForObject = Cal_get_alarms_for_object; - epv->updateObject = Cal_update_object; - epv->removeObject = Cal_remove_object; - - return epv; -} - - - -/** - * cal_construct: - * @cal: A calendar client interface. - * @corba_cal: CORBA object for the calendar. - * @backend: Calendar backend that this @cal presents an interface to. - * @listener: Calendar listener for notification. - * - * Constructs a calendar client interface object by binding the corresponding - * CORBA object to it. The calendar interface is bound to the specified - * @backend, and will notify the @listener about changes to the calendar. - * - * Return value: The same object as the @cal argument. - **/ -Cal * -cal_construct (Cal *cal, - GNOME_Evolution_Calendar_Cal corba_cal, - CalBackend *backend, - GNOME_Evolution_Calendar_Listener listener) -{ - CalPrivate *priv; - CORBA_Environment ev; - - g_return_val_if_fail (cal != NULL, NULL); - g_return_val_if_fail (IS_CAL (cal), NULL); - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - - priv = cal->priv; - - CORBA_exception_init (&ev); - priv->listener = CORBA_Object_duplicate (listener, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("cal_construct: could not duplicate the listener"); - priv->listener = CORBA_OBJECT_NIL; - CORBA_exception_free (&ev); - return NULL; - } - - CORBA_exception_free (&ev); - - priv->backend = backend; - - bonobo_object_construct (BONOBO_OBJECT (cal), corba_cal); - return cal; -} - -/** - * cal_corba_object_create: - * @object: #BonoboObject that will wrap the CORBA object. - * - * Creates and activates the CORBA object that is wrapped by the specified - * calendar client interface @object. - * - * Return value: An activated object reference or #CORBA_OBJECT_NIL in case of - * failure. - **/ -GNOME_Evolution_Calendar_Cal -cal_corba_object_create (BonoboObject *object) -{ - POA_GNOME_Evolution_Calendar_Cal *servant; - CORBA_Environment ev; - - g_return_val_if_fail (object != NULL, CORBA_OBJECT_NIL); - g_return_val_if_fail (IS_CAL (object), CORBA_OBJECT_NIL); - - servant = (POA_GNOME_Evolution_Calendar_Cal *) g_new0 (BonoboObjectServant, 1); - servant->vepv = &cal_vepv; - - CORBA_exception_init (&ev); - POA_GNOME_Evolution_Calendar_Cal__init ((PortableServer_Servant) servant, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("cal_corba_object_create(): could not init the servant"); - g_free (servant); - CORBA_exception_free (&ev); - return CORBA_OBJECT_NIL; - } - - CORBA_exception_free (&ev); - return (GNOME_Evolution_Calendar_Cal) bonobo_object_activate_servant (object, servant); -} - -/** - * cal_new: - * @backend: A calendar backend. - * @listener: A calendar listener. - * - * Creates a new calendar client interface object and binds it to the specified - * @backend and @listener objects. - * - * Return value: A newly-created #Cal calendar client interface object, or NULL - * if its corresponding CORBA object could not be created. - **/ -Cal * -cal_new (CalBackend *backend, GNOME_Evolution_Calendar_Listener listener) -{ - Cal *cal, *retval; - GNOME_Evolution_Calendar_Cal corba_cal; - CORBA_Environment ev; - gboolean ret; - - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - - cal = CAL (gtk_type_new (CAL_TYPE)); - corba_cal = cal_corba_object_create (BONOBO_OBJECT (cal)); - - CORBA_exception_init (&ev); - ret = CORBA_Object_is_nil ((CORBA_Object) corba_cal, &ev); - if (ev._major != CORBA_NO_EXCEPTION || ret) { - g_message ("cal_new(): could not create the CORBA object"); - bonobo_object_unref (BONOBO_OBJECT (cal)); - CORBA_exception_free (&ev); - return NULL; - } - - CORBA_exception_free (&ev); - - retval = cal_construct (cal, corba_cal, backend, listener); - if (!retval) { - g_message ("cal_new(): could not construct the calendar client interface"); - bonobo_object_unref (BONOBO_OBJECT (cal)); - return NULL; - } - - return retval; -} - -/** - * cal_notify_update: - * @cal: A calendar client interface. - * @uid: UID of object that was updated. - * - * Notifies a listener attached to a calendar client interface object about an - * update to a calendar object. - **/ -void -cal_notify_update (Cal *cal, const char *uid) -{ - CalPrivate *priv; - CORBA_Environment ev; - - g_return_if_fail (cal != NULL); - g_return_if_fail (IS_CAL (cal)); - g_return_if_fail (uid != NULL); - - priv = cal->priv; - g_return_if_fail (priv->listener != CORBA_OBJECT_NIL); - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_Listener_notifyObjUpdated (priv->listener, (char *) uid, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("cal_notify_update(): could not notify the listener " - "about an updated object"); - - CORBA_exception_free (&ev); -} - -/** - * cal_notify_remove: - * @cal: A calendar client interface. - * @uid: UID of object that was removed. - * - * Notifies a listener attached to a calendar client interface object about a - * calendar object that was removed. - **/ -void -cal_notify_remove (Cal *cal, const char *uid) -{ - CalPrivate *priv; - CORBA_Environment ev; - - g_return_if_fail (cal != NULL); - g_return_if_fail (IS_CAL (cal)); - g_return_if_fail (uid != NULL); - - priv = cal->priv; - g_return_if_fail (priv->listener != CORBA_OBJECT_NIL); - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_Listener_notifyObjRemoved (priv->listener, (char *) uid, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("cal_notify_remove(): could not notify the listener " - "about a removed object"); - - CORBA_exception_free (&ev); -} diff --git a/calendar/pcs/cal.h b/calendar/pcs/cal.h deleted file mode 100644 index 844640cd8d..0000000000 --- a/calendar/pcs/cal.h +++ /dev/null @@ -1,73 +0,0 @@ -/* Evolution calendar client interface object - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef CAL_H -#define CAL_H - -#include <libgnome/gnome-defs.h> -#include <bonobo/bonobo-object.h> -#include "calendar/pcs/evolution-calendar.h" -#include "cal-common.h" - -BEGIN_GNOME_DECLS - - - -#define CAL_TYPE (cal_get_type ()) -#define CAL(obj) (GTK_CHECK_CAST ((obj), CAL_TYPE, Cal)) -#define CAL_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), CAL_TYPE, CalClass)) -#define IS_CAL(obj) (GTK_CHECK_TYPE ((obj), CAL_TYPE)) -#define IS_CAL_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), CAL_TYPE)) - -typedef struct _CalPrivate CalPrivate; - -struct _Cal { - BonoboObject object; - - /* Private data */ - CalPrivate *priv; -}; - -struct _CalClass { - BonoboObjectClass parent_class; -}; - -GtkType cal_get_type (void); - -Cal *cal_construct (Cal *cal, - GNOME_Evolution_Calendar_Cal corba_cal, - CalBackend *backend, - GNOME_Evolution_Calendar_Listener listener); -GNOME_Evolution_Calendar_Cal cal_corba_object_create (BonoboObject *object); - -Cal *cal_new (CalBackend *backend, GNOME_Evolution_Calendar_Listener listener); - -void cal_notify_update (Cal *cal, const char *uid); -void cal_notify_remove (Cal *cal, const char *uid); - -POA_GNOME_Evolution_Calendar_Cal__epv *cal_get_epv (void); - - - -END_GNOME_DECLS - -#endif diff --git a/calendar/pcs/job.c b/calendar/pcs/job.c deleted file mode 100644 index f8223f0bab..0000000000 --- a/calendar/pcs/job.c +++ /dev/null @@ -1,99 +0,0 @@ -/* GNOME personal calendar server - job manager - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#include <config.h> -#include "job.h" - - - -/* The job list */ - -typedef struct { - JobFunc func; - gpointer data; -} Job; - -static GSList *jobs_head; -static GSList *jobs_tail; - -static guint jobs_idle_id; - - - -/* Runs a job and dequeues it */ -static gboolean -run_job (gpointer data) -{ - Job *job; - GSList *l; - - g_assert (jobs_head != NULL); - - job = jobs_head->data; - (* job->func) (job->data); - g_free (job); - - l = jobs_head; - jobs_head = g_slist_remove_link (jobs_head, jobs_head); - g_slist_free_1 (l); - - if (!jobs_head) { - jobs_tail = NULL; - jobs_idle_id = 0; - return FALSE; - } else - return TRUE; -} - -/** - * job_add: - * @func: Function to run the job. - * @data: Data to pass to @function. - * - * Adds a job to the queue. The job will automatically be run asynchronously. - **/ -void -job_add (JobFunc func, gpointer data) -{ - Job *job; - - g_return_if_fail (func != NULL); - - job = g_new (Job, 1); - job->func = func; - job->data = data; - - if (!jobs_head) { - g_assert (jobs_tail == NULL); - g_assert (jobs_idle_id == 0); - - jobs_head = g_slist_append (NULL, job); - jobs_tail = jobs_head; - - jobs_idle_id = g_idle_add (run_job, NULL); - } else { - g_assert (jobs_tail != NULL); - g_assert (jobs_idle_id != 0); - - jobs_tail = g_slist_append (jobs_tail, job)->next; - } -} diff --git a/calendar/pcs/job.h b/calendar/pcs/job.h deleted file mode 100644 index f9a0d86923..0000000000 --- a/calendar/pcs/job.h +++ /dev/null @@ -1,36 +0,0 @@ -/* GNOME personal calendar server - job manager - * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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. - */ - -#ifndef JOB_H -#define JOB_H - -#include <glib.h> - - - -typedef void (* JobFunc) (gpointer data); - -void job_add (JobFunc func, gpointer data); - - - -#endif |