diff options
Diffstat (limited to 'calendar')
239 files changed, 0 insertions, 118806 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 e4fda3d3bc..0000000000 --- a/calendar/AUTHORS +++ /dev/null @@ -1,7 +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> -JP Rosevear <jpr@ximian.com> -Damon Chaplin <damon@ximian.com> diff --git a/calendar/ChangeLog b/calendar/ChangeLog deleted file mode 100644 index 64748151dd..0000000000 --- a/calendar/ChangeLog +++ /dev/null @@ -1,16584 +0,0 @@ -2002-05-14 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/schedule-page.c (schedule_page_construct): set the - working hours for the meeting time selector - -2002-05-14 JP Rosevear <jpr@ximian.com> - - * cal-util/cal-component.h: make the range datetime member a - struct not a pointer - - * cal-util/cal-component.c (cal_component_get_recurid): take a - pointer to a range - (cal_component_set_recurid): ditto - - * gui/itip-utils.c (comp_minimal): get/set the recurrence id - properly - -2002-05-09 Ettore Perazzoli <ettore@ximian.com> - - * gui/e-itip-control.c (get_servers): use - GNOME_Evolution_Storage__get_folderList instead of - GNOME_Evolution_Storage_getFolderList since I have now changed - that to be an attribute instead of a method. - -2002-05-07 JP Rosevear <jpr@ximian.com> - - * gui/e-itip-control.c (start_calendar_server): start a server a - uri - (start_default_server): start a default server - (get_servers): get all clients for all folders of the given - type(s) - (find_server): locate a server for a particular uid - (init): get_servers, listen for object_requested signal - (destroy): destroy all clients - (write_html): put options is there own cell - (get_publish_options): place selector in if param is true - (get_request_options): ditto - (get_real_item): only try and look up the item if we know its in - the server - (show_current_event): find the server (if any) for the current - comp - (show_current_todo): ditto - (update_attendee_status): if there is no server for the comp, it - doesn't exist - (remove_item): ditto - (button_selected_cb): get a client for the selected folder - (object_requested_cb): draw the folder button in - - * gui/calendar-config.h: new protos - - * gui/calendar-config.c (calendar_config_default_tasks_folder): - get default tasks uri - (calendar_config_default_calendar_folder): get default calendar - uri - - * cal-client/cal-client.c (get_default_uri): use - cal_util_expand_uri - - * cal-util/cal-util.h: new proto - - * cal-util/cal-util.c (cal_util_expand_uri): tack on the file name - if its a file uri - -2002-05-03 Rodrigo Moya <rodrigo@ximian.com> - - * gui/e-tasks.c (e_tasks_delete_selected): - (e_tasks_complete_selected): show progress messages - on the status bar. - -2002-05-02 Rodrigo Moya <rodrigo@ximian.com> - - * pcs/query.c: #include <gtk/gtkmain.h> to avoid warnings. - -2002-05-02 JP Rosevear <jpr@ximian.com> - - * gui/e-week-view.c (free_view_popup): only discard the popup if - we created one - -2002-05-02 Rodrigo Moya <rodrigo@ximian.com> - - * pcs/query.c: refactored a bit, to not do things in idle loops. - -2002-05-01 JP Rosevear <jpr@ximian.com> - - * gui/print.c (print_day_details): modify the start and end hours - to accomodate all the events in the day - - * gui/e-day-view.c (free_view_popup): only discard the popup if we - created one - -2002-04-30 JP Rosevear <jpr@ximian.com> - - * gui/gnome-cal.c (gnome_calendar_construct): remove setup_widgets - from here - (gnome_calendar_init): move setup_widgets back here - -2002-04-26 Jeffrey Stedfast <fejj@ximian.com> - - * gui/Makefile.am: Don't link to libibex anymore!! - -2002-04-24 JP Rosevear <jpr@ximian.com> - - * gui/e-day-view.c (e_day_view_on_pilot_settings): launch pilot - settings capplet - - * gui/e-week-view.c (e_week_view_on_pilot_settings): ditto - -2002-04-24 JP Rosevear <jpr@ximian.com> - - * gui/e-week-view.c (free_view_popup): free the view popup - (e_week_view_show_popup_menu): add the view popup to the - "main_item" menu and listen for destruction - - * gui/e-day-view.c (free_view_popup): as above - (e_day_view_on_event_right_click): as above - - * gui/e-week-view.h: add class member - - * gui/e-day-view.h: add a class member - - * gui/gnome-cal.h: new protos - - * gui/gnome-cal.c (set_view): set the instance view id properly - when switching views - (gnome_calendar_setup_view_popup): generate a view popup - (gnome_calendar_discard_view_popup): destroy a view popup - -2002-04-22 Rodrigo Moya <rodrigo@ximian.com> - - * pcs/cal.c (impl_Cal_get_alarms_in_range): raise an exception if the - backend's method returns NULL, since we can't send a NULL pointer to - ORBit. - -2002-04-19 Anna Marie Dirks <anna@ximian.com> - - * gui/dialogs/cal-prefs-dialog.glade: Collapsed notebook into two pages - and added accelerators for everything, as part of my config dialog - polishing project - -2002-04-18 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/recurrence-page.c (simple_recur_to_comp): properly - handle -ve recurrence values - (month_num_submenu_selection_done_cb): track the current date in - use - (make_recur_month_num_submenu): make a submenu of dates - (make_recur_month_num_menu): make the date/relation option menu - (month_num_menu_selection_done_cb): update the date properly and - keep both option menus consistent - (month_day_menu_selection_done_cb): keep both option menus - consistent - (make_monthly_special): listen for selection done signal - (make_recurrence_special): destroy old month_num_menu - (recurrence_page_fill_widgets): properly handle -ve recurrence - values - -2002-04-18 JP Rosevear <jpr@ximian.com> - - * gui/e-day-view.c (e_day_view_on_settings): show the settings - - * gui/e-week-view.c (e_week_view_on_settings): ditto - - * gui/calendar-commands.c (control_util_show_settings): show the - settings dialog - - * gui/calendar-commands.h: new proto - - * gui/control-factory.c (control_factory_new_control): set the - control as object data on the calendar - -2002-04-17 Christopher James Lahey <clahey@ximian.com> - - * gui/e-calendar-table.c, gui/e-day-view.c, gui/e-week-view.c, - gui/dialogs/meeting-page.c: Updated these to match the new - EPopupMenu. - -2002-04-05 Rodrigo Moya <rodrigo@ximian.com> - - * pcs/cal-backend.[ch] (cal_backend_get_query): new method. - - * pcs/cal-backend-file.c (cal_backend_file_get_query): new method. - - * pcs/cal.c (impl_Cal_get_query): call the CalBackend's implementation - instead of calling query_new directly. - - * pcs/query.[ch]: fixed headers. - -2002-04-10 Dan Winship <danw@ximian.com> - - * gui/gnome-cal.c (gnome_calendar_open): Fix this: Rodrigo's patch - used one of the functions I just removed. :) - -2002-04-10 Rodrigo Moya <rodrigo@ximian.com> - - * gui/gnome-cal.c (gnome_calendar_open): use the default uri for - tasks (as stored in the configuration) when the calendar URI is not - a local one (connector, etc). - -2002-04-10 Dan Winship <danw@ximian.com> - - * cal-client/cal-client.c (get_default_uri): Use new-and-improved - default folder URI config paths. - - * gui/calendar-config.c (calendar_config_{get,set}_default_uri, - calendar_config_{get,set}_default_tasks_uri): Remove these. The - shell owns this information now. (Weren't being used anyway.) - - * gui/component-factory.c (get_data_uri): Fix another place that - hardcoded tacking foo.ics on to the end of URLs. - -2002-04-08 Dan Winship <danw@ximian.com> - - * gui/component-factory.c (create_view): Add view_info arg. If the - view_info is non-empty and this is a calendar folder, set the - "view" property on the control's propertybag. - - * gui/control-factory.c (calendar_properties_init): Set up the - "view" property. - (get_prop, set_prop): handle the "view" property by - getting/setting the GnomeCalendar's view. Unfortunately, this - doesn't actually work. See #23208. - - * gui/calendar-commands.c (calendar_control_activate): Set the UI - component's container before calling - gnome_calendar_set_ui_component so that the search bar - initialization will work. - -2002-04-06 JP Rosevear <jpr@ximian.com> - - * pcs/cal-backend-db.[hc]: Remove dead files. - -2002-04-06 JP Rosevear <jpr@ximian.com> - - * gui/GNOME_Evolution_Calendar.oaf.in: add config_item:type - -2002-04-01 Kjartan Maraas <kmaraas@gnome.org> - - * gui/e-itip-control.c: Fix a string. - -2002-04-01 Rodrigo Moya <rodrigo@ximian.com> - - * pcs/cal-backend-db.c: simple fix for DB3 header inclusion in - Mac OS X, by Max Horn <max@quendi.de> - -2002-03-31 JP Rosevear <jpr@ximian.com> - - * gui/e-itip-control.c (clean_up): free the my_address member - (find_my_address): fall back on a CN match if possible - (change_status): handle changing the status of a non-existent - address by adding a new attendee - (update_attendee_status): if the attendee response is not from a - user on the list of attendees, ask the user if they want to add - the attendee any how (as an optional participant) - (ok_clicked_cb): if we are suppose to rsvp and the status was ok, - but the attendee address is not known, find it - -2002-03-29 Ettore Perazzoli <ettore@ximian.com> - - * gui/GNOME_Evolution_Calendar.oaf.in: Set a priority for the - config item. Rename to "Calendar and Tasks". - -2002-03-29 JP Rosevear <jpr@ximian.com> - - * conduits/calendar/Makefile.am: s/libversit.la/libversit.a/ - - * conduits/todo/Makefile.am: ditto - -2002-03-29 JP Rosevear <jpr@ximian.com> - - * gui/e-calendar-table.c: implement new pop up menu items for - "Save as", "Print", "Assign Task", "Forward as iCalendar" - - * gui/e-day-view.c: similarly, also "Publish Free/Busy - Information" and "New Meeting" and "New Task" - - * gui/e-week-view.c: ditto - - * gui/dialogs/task-editor.c (show_assignment): move the assignment - page stuff here - (task_editor_show_assignment): use it - (assign_task_cmd): ditto - - * gui/dialogs/task-editor.h: new proto - - * gui/dialogs/comp-editor.c (save_as_cmd): use new e-util file - selector function - - * meeting-mockup.glade: Remove old file - - * topic.dat - -2002-03-19 Dan Winship <danw@ximian.com> - - * cal-util/Makefile.am: s/libversit.la/libversit.a/ - - * cal-client/Makefile.am: Likewise - - * gui/Makefile.am: Likewise - -2002-03-18 Ettore Perazzoli <ettore@ximian.com> - - * gui/cal-search-bar.c: Removed `search_menu_items'. - (cal_search_bar_menu_activated): Removed. - (cal_search_bar_class_init): Don't install. - (cal_search_bar_construct): No menu items here. - -2002-03-15 Jeffrey Stedfast <fejj@ximian.com> - - * gui/e-day-view.c: Updated to use new EPopupMenu API. - - * gui/e-week-view.c: Updated to use new EPopupMenu API. - - * gui/e-calendar-table.c: Updated to use new EPopupMenu API. - -2002-03-15 Ettore Perazzoli <ettore@ximian.com> - - * gui/tasks-control.c (tasks_control_activate): Call - `e_tasks_set_ui_component()' here to give it the - BonoboUIComponent. - (tasks_control_deactivate): Likewise, call it here to unset the - BonoboUIComponent. - - * gui/e-tasks.c (e_tasks_set_ui_component): New. - - * gui/calendar-commands.c (calendar_control_activate): Call - gnome_calendar_set_ui_component() here. - (calendar_control_deactivate): ...And here, with a NULL - BonoboUIComponent. - - * gui/gnome-cal.c (gnome_calendar_set_ui_component): New. - -2002-03-15 JP Rosevear <jpr@ximian.com> - - * gui/main.c: use bonobo exception macros to tidy - - * gui/itip-control-factory.c: ditto - - * gui/gnome-cal.c: ditto - - * gui/comp-editor-factory.c: ditto - - * gui/calendar-commands.c: ditto - -2002-03-14 JP Rosevear <jpr@ximian.com> - - * idl/evolution-calendar.idl: add all day event editor mode - - * gui/component-factory.c: clean up exception handling - (sc_user_create_new_item_cb): support the all day event id - (create_object): add a user creatable all day appointment item - - * gui/comp-editor-factory.c (get_default_event): get a default - event either all day or starting at the top of the hour - (get_default_task): get a default task - (edit_new): support the all day event mode - - * gui/calendar-commands.c: remove unused functions/verbs - -2002-03-13 Ettore Perazzoli <ettore@ximian.com> - - * gui/GNOME_Evolution_Calendar.oaf.in: Add an - "evolution:config_item:icon_path" attribute so we get an icon for - the calendar preferences. - -2002-03-12 Ettore Perazzoli <ettore@ximian.com> - - * gui/dialogs/cal-prefs-dialog.glade: Add <visible>False</visible> - to cal-prefs-dialog so it doesn't get shown when we load the Glade - file with libglade. - - * gui/component-factory.c (owner_set_cb): Register the - ConfigControl factory. - - * gui/tasks-control.c: Removed verb "TaskSettings". - (tasks_control_settings_cmd): Removed. - - * gui/calendar-commands.c: Removed verb "CalendarSettings". - (settings_cmd): Removed. - - * gui/dialogs/cal-prefs-dialog.c: Renamed `CalPrefsDialogPrivate' - to `DialogData'. Replace `dialog' member with a `page' member. - Remove `toplevel_notebook' member. - (init_widgets): Renamed from `cal_prefs_dialog_init_widgets'. - Just get a DialogData. - (get_widgets): Get a DialogData pointer. - (cal_prefs_dialog_destroy): Removed. - (config_control_destroy_callback): New, signal handler for - ::destroy for ConfigControl. - (cal_prefs_dialog_new): Create a new DialogData, connect all the - signal handlers. - (create_time_edit): Renamed from - `cal_prefs_dialog_create_time_edit'. - (cal_prefs_dialog_show): Removed. - (cal_prefs_dialog_button_clicked): Removed. - (show_task_list_config): Get a DialogData. - (show_config): Renamed from `cal_prefs_dialog_show_config'. - Likewise. - (update_task_list_config): Likewise. - (update_config): Renamed from - `cal_prefs_dialog_update_config'. Likewise. - (color_set_callback): New callback, makes the dialog report - changes when the setting in any of the color widgets is changed. - (widget_changed_callback): New callback, makes the dialog report - changes when any of the widgets changes status. - (connect_changed): New utility function to connect this callback - to all the widgets. - (setup_widgets): Connect all the widgets. - (cal_prefs_dialog_new): Call `setup_widgets'. - - * gui/config-control-factory.c: New. - * gui/config-control-factory.h: New. - - * gui/GNOME_Evolution_Calendar.oaf.in: Add - OAFIID:GNOME_Evolution_Calendar_ConfigControl and - OAFIID:GNOME_Evolution_Calendar_ConfigControlFactory. - -2002-03-06 Rodrigo Moya <rodrigo@ximian.com> - - Should fix #21240 - - * gui/alarm-notify/alarm-notify.c: replaced use of GnomeVFSURI - with EUri, to allow non-registered methods. - -2002-03-05 Rodrigo Moya <rodrigo@ximian.com> - - * gui/e-itip-control.c (e_itip_control_set_data): reverted my last - change of adding the METHOD property to the incoming request. - - * gui/itip-utils.c (comp_string): added extra - X-MICROSOFT-CDO-REPLYTIME property for broken Outlook. Should fix - #20783. - -2002-03-04 Dan Winship <danw@ximian.com> - - * gui/itip-utils.c (comp_compliant): Reset the DTSTAMP of the new - component. (RFC2245 says DTSTAMP corresponds to the time the - particular iCalendar representation of the object was created.) - Fixes #21198. - -2002-03-05 JP Rosevear <jpr@ximian.com> - - * gui/print.c: remove unneeded parameter from print_text_size - everywhere - (get_font_for_size): calculate a font size based on the available - height - (print_text): calculate the top of where the font should be drawn - (print_text_size): use get_font_for_size - (print_day_background): use get_font_for_size - -2002-03-05 JP Rosevear <jpr@ximian.com> - - * gui/e-meeting-time-sel-item.c - (e_meeting_time_selector_item_draw): pass the real table - to e_meeting_model_etable_view_to_model_row - (e_meeting_time_selector_item_paint_busy_periods): ditto - - * gui/dialogs/meeting-page.c (right_click_cb): ditto - - * gui/e-meeting-model.h: update protos - - * gui/e-meeting-model.c - (e_meeting_model_etable_model_to_view_row): take in to account the - fact the table used the without model - (e_meeting_model_etable_view_to_model_row): ditto - -2002-03-04 Damon Chaplin <damon@ximian.com> - - * gui/tasks-control.c: added support for printing the Tasks table. - I hacked it a bit so the user could choose portrait or landscape mode. - This is bug #9677. ETable printing has a few issues, though, and it - isn't very pretty. - -2002-03-04 Dan Winship <danw@ximian.com> - - * gui/itip-utils.c (comp_subject): Prefix the subject with an - indicator like "Accepted" or "Cancelled" explaining what the - action is, since Outlook doesn't display any of that information - inline like we do. (20780) - -2002-02-28 Rodrigo Moya <rodrigo@ximian.com> - - * calendar/gui/e-itip-control.c (e_itip_control_set_data): added the - METHOD property to the top level component we create. - -2002-02-26 Rodrigo Moya <rodrigo@ximian.com> - - * gui/control-factory.c (set_prop): - * gui/tasks-control.c (tasks_control_set_property): display an error - message if the call to gnome_calendar_open or e_tasks_open does not - return TRUE. Fixes #20346. - -2002-02-25 Dan Winship <danw@ximian.com> - - * gui/itip-utils.c (itip_send_comp): use - GNOME_Evolution_Composer_setBody rather than _setMultipartType and - _attachData now, to send a message containing just a text/calendar - part. Fixes 14705. Mostly. - (comp_content_type): Include the filename here since we can't add - a Content-Disposition now. - -2002-02-24 Chris Toshok <toshok@ximian.com> - - * gui/cal-search-bar.c (cal_search_bar_class_init): change - query_changed to search_activated. - (cal_search_bar_search_activated): rename - cal_search_bar_query_changed to this. - -2002-02-21 Ettore Perazzoli <ettore@ximian.com> - - * gui/component-factory.c (add_creatable_item): New helper - function. - (create_object): Add icons for the various user creatable items. - -2002-02-19 JP Rosevear <jpr@ximian.com> - - * gui/e-itip-control.c (send_item): pass extra itip_send_comp - params - (send_freebusy): ditto - (ok_clicked_cb): ditto, including the timezones culled from the - component - - * gui/e-week-view.c: pass extra itip_send_comp params - - * gui/calendar-commands.c: ditto - - * gui/e-day-view.c: ditto - - * gui/dialogs/task-editor.c: ditto - - * gui/dialogs/event-editor.c: ditto - - * gui/dialogs/comp-editor.c: ditto - - * gui/itip-utils.h (itip_send_comp): update proto - - * gui/itip-utils.c (foreach_tzid_callback): check the passed in - zones, then the builtin time zones then the client - -2002-02-19 JP Rosevear <jpr@ximian.com> - - * gui/e-itip-control.c (find_my_address): strip the ical value and - do a case insensitive compare - (find_attendee): ditto - (change_status): put the error message here - (ok_clicked_cb): don't update the item or rsvp unless - change_status was successful, trip the ical value and do a case - insensitive compare - - * gui/itip-utils.c (get_address): strip the incoming address - (itip_strip_mailto): use g_strncasecmp - (comp_limit_attendees): strip the ical value and do a case - insensitive compare - -2002-02-14 JP Rosevear <jpr@ximian.com> - - * gui/e-meeting-model.c: use new column enums - (set_value_at): emit pre-change/cell change signals - (destroy): destroy refresh_queue and refresh_data - (init): init new elements - (refresh_queue_add): if the attendee is being refreshed already, - possibly update the start/end times to look for and update the - callback info, otherwise add it to the queue - (refresh_queue_remove): remove a refreshing attende from the queue - (process_callbacks): make all the callbacks and remove the - attendee from the queue - (process_free_busy): process the callbacks immediately if parsing - fails or on successful completion of processing - (async_close): process free busy - (cursor_cb): we're only looking for one at a time now - (refresh_busy_periods): idle callback to start processing the queue - (e_meeting_model_refresh_all_busy_periods): add every row to the queue - (e_meeting_model_refresh_busy_periods): add a single row to the queue - - * gui/e-meeting-model.h: new protos, enum the columns - - * gui/e-meeting-time-sel.c: use new compare time function - (e_meeting_time_selector_construct): listen for a cell changed - signal and use separate callbacks for rows_inserted and - rows_deleted - (e_meeting_time_selector_refresh_free_busy): util function to - refresh free busy info - (e_meeting_time_selector_on_update_free_busy): use above - (rows_inserted_cb): refresh free busy on the new rows - (cell_changed_cb): refresh free busy on the row when the address - changes - (rows_deleted_cb): redraw - - * gui/e-meeting-utils.[hc]: a holding spot for a meeting time - comparison function - - * gui/Makefile.am: compile new files - -2002-02-13 Rodrigo Moya <rodrigo@ximian.com> - - * gui/control-factory.c (set_prop): don't append 'calendar.ics' - to the URI. - (get_prop): finished. - - * gui/tasks-control.c (tasks_control_set_property): don't append - 'tasks.ics' to the URI. - (tasks_control_get_property): finished. - - * gui/gnome-cal.c (gnome_calendar_open): - * gui/e-tasks.c (e_tasks_open): append $filename.ics to the uri to be - opened if the uri is local. Leave intact in other cases. - -2002-02-08 Damon Chaplin <damon@ximian.com> - - * gui/comp-util.c (cal_comp_util_compare_event_timezones): check if - the CalComponentDateTime values are set before trying to use them. - Possibly fixes bug #18529. - - * importers/icalendar-importer.c: added vCalendar importer and - intelligent GnomeCalendar importer code here, as it shares a lot of - code with the iCalendar importer. - - NOTE: check_folder_type() needs to be finished at some point. - It needs a new shell Corba call so it can decide whether to import - events or tasks into the folder. Currently it just imports both. - - * importers/main.c (importer_factory_fn): create vCalendar importer - or GnomeCalendar importer if required. - - * importers/evolution-calendar-importer.h: added declarations for - creating a vCalendar importer and intelligent Gnome Calendar importer. - - * importers/Makefile.am: added -DEVOLUTION_SOUNDDIR so the importer - knows what filename to use for audio alarms in vCalendar files. - Added libicalvcal-evolution to LDADD. - - * importers/GNOME_Evolution_Calendar_Importer.oaf.in: added vCalendar - importer and intelligent Gnome Calendar importer. - - * gui/comp-util.c (cal_comp_util_compare_event_timezones): return TRUE - if the event uses UTC. We don't want to flag all events from Outlook, - which use UTC. - -2002-02-08 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/task-details-page.glade: change custom widget - creator to e_url_entry_new - - * gui/dialogs/task-details-page.c (get_widgets): get the url entry - and its entry - -2002-02-08 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/task-details-page.glade: add a custom widget created - with e_url_button_new - - * gui/dialogs/task-details-page.c (task_details_page_init): init - url_button member to NULL - (init_widgets): set the url button entry - (get_widgets): get the url button - - * gui/calendar-commands.c (pixmaps): use new all day event icon - -2002-02-07 JP Rosevear <jpr@ximian.com> - - * gui/e-day-view.c: pass meeting boolean for - gnome_calendar_edit_object and gnome_calendar_new_appointment_for - - * gui/e-week-view-event-item.c: ditto - - * gui/e-week-view.c: ditto - - * gui/tasks-control.c (confirm_expunge): kill warning - - * gui/calendar-commands.c (new_meeting_cb): show a new meeting - dialog - (new_event_cb): pass new param - - * gui/gnome-cal.c (gnome_calendar_edit_object): take meeting - boolean and show meeting page if true - (gnome_calendar_new_appointment_for): takeing meeting param and - pass to above - (gnome_calendar_new_appointment): add new param - - * gui/gnome-cal.h: update proto - - * gui/component-factory.c (create_component): take a comp editor - mode, determine vtype - (sc_user_create_new_item_cb): check for meeting user creatable - item - (create_object): add meeting as user creatable item - - * gui/comp-editor-factory.c (edit_new): get a comp editor mode - now, determine vtype and show meeting page if required - (queue_edit_new): get comp editor mode - (impl_editNew): ditto, plus queue the mode directly instead of - determining the vtype - - * gui/dialogs/event-editor.c (show_meeting): new internal util - function to show meeting page - (event_editor_show_meeting): show the meeting - (schedule_meeting_cmd): use show_meeting - - * gui/dialogs/event-editor.h: new proto - - * idl/evolution-calendar.idl: editNew takes a mode rather than a - type now - - * cal-util/Makefile.am: fix includes - -2002-02-07 Christopher James Lahey <clahey@ximian.com> - - * gui/e-tasks.c (e_tasks_setup_view_menus), gui/gnome-cal.c - (gnome_calendar_setup_view_menus): Made these use the new - GalViewMenus stuff. - -2002-02-06 Damon Chaplin <damon@ximian.com> - - * cal-util/cal-recur.c (cal_recur_from_icalproperty): convert months - from 1-12 to 0-11. Fixes bug #19235. - -2002-02-04 JP Rosevear <jpr@ximian.com> - - * conduits/todo/todo-conduit.c (e_todo_gui_new): new gui routines - for conduit settings - (e_todo_gui_fill_config): ditto - (e_todo_gui_fill_widgets): ditto - (e_todo_gui_destroy): ditto - (e_todo_context_destroy): destroy new_cfg and gui properly - (local_record_from_comp): set the priority to the default setting - if none is set on the icalendar object - (fill_widgets): fill gui widgets - (create_settings_window): create gui - -2002-01-30 JP Rosevear <jpr@ximian.com> - - * gui/e-itip-control.c (write_html): if this is a reply, print the - attendee status - -2002-01-25 Federico Mena Quintero <federico@ximian.com> - - * gui/dialogs/alarm-options.glade: Use 1 instead of zero as the - minimum value for the repetitions spin button as we use a check - box to specify whether the alarm has repetitions or not. Fixes - bug #19054. - -2002-01-24 Ettore Perazzoli <ettore@ximian.com> - - * importers/Makefile.am (evolution_calendar_importer_LDADD): - Ooops. Forgot to use EVOLUTION_CALENDAR_LIBS here. - -2002-01-24 Ettore Perazzoli <ettore@ximian.com> - - * conduits/calendar/Makefile.am: Use - EVOLUTION_CALENDAR_CONDUIT_LIBS and - EVOLUTION_CALENDAR_CONDUIT_CFLAGS. - * conduits/todo/Makefile.am: Likewise. - - * cal-client/Makefile.am: Use EVOLUTION_CALENDAR_LIBS and - EVOLUTION_CALENDAR_CFLAGS. - * cal-util/Makefile.am: Likewise. - * gui/alarm-notify/Makefile.am: Likewise. - * gui/Makefile.am: Likewise. - -2002-01-23 Ettore Perazzoli <ettore@ximian.com> - - * gui/component-factory.c (create_object): Pass a NULL @icon to - `evolution_shell_component_add_user_creatable_item()'. - -2002-01-21 JP Rosevear <jpr@ximian.com> - - * conduits/todo/todo-conduit.c (todoconduit_load_configuration): - return a new configuration struct, load default priority setting - (todoconduit_save_configuration): save default priority setting - (e_todo_context_new): dupe configuration - - * conduits/calendar/calendar-conduit.c (e_calendar_context_new): - set ps to NULL - -2002-01-17 Damon Chaplin <damon@ximian.com> - - * gui/dialogs/alarm-page.c (get_alarm_string): save the alarm string - in the correct variable (str), so it actually gets shown for alarms - with specific trigger times. Fixes bug #18801. - -2002-01-15 Rodrigo Moya <rodrigo@ximian.com> - - * gui/dialogs/task-page.c (task_page_fill_widgets): default component - classification to PUBLIC. Fixes internal bug #1066 - -2002-01-14 JP Rosevear <jpr@ximian.com> - - * conduits/calendar/calendar-conduit.c: move all functions here, - get rid of header files, use e-pilot-settings to display gui - - * conduits/todo/todo-conduit.c: as above - -2002-01-14 JP Rosevear <jpr@ximian.com> - - * gui/gnome-cal.c (get_current_time): use icaltimetype_to_tm - -2002-01-14 JP Rosevear <jpr@ximian.com> - - * gui/e-week-view-main-item.c (e_week_view_main_item_draw_day): - figure out when today is and highlight if it is not selected - - * gui/e-week-view.h: enum the "today" color - - * gui/e-week-view.c (e_week_view_realize): init the "today" color - -2002-01-13 JP Rosevear <jpr@ximian.com> - - * gui/alarm-notify/save.h: add protos - - * gui/alarm-notify/save.c (save_blessed_program): records a - program as blessed - (is_blessed_program): checks to see if a program is blessed - - * gui/alarm-notify/alarm-queue.c (procedure_notification_dialog): - popup a dialog notifying the user that is a program and let them - not see the dialog about this program again - (procedure_notification): use above - -2002-01-11 Damon Chaplin <damon@ximian.com> - - * gui/e-timezone-entry.c: - * gui/e-itip-control.c (write_label_piece): - * gui/calendar-config.c (on_timezone_set): translate timezone names - when displayed. Fixes bug #6544. - -2002-01-03 JP Rosevear <jpr@ximian.com> - - * gui/tasks-control.c (tasks_control_complete_cmd): new verb - callback - (sensitize_commands): set sensitivity of mark complete command - - * gui/e-tasks.h: new proto - - * gui/e-tasks.c (e_tasks_complete_selected): mark selected tasks - in the table as complete - - * gui/e-calendar-table.h: new proto - - * gui/e-calendar-table.c (e_calendar_table_complete_selected): - mark selected rows as complete - -2002-01-03 JP Rosevear <jpr@ximian.com> - - * gui/tasks-control.c (confirm_expunge): only need one warning - message now - - * gui/e-tasks.c (create_sexp): change the logic to expunge all - completed tasks not just hidden ones - -2002-01-03 JP Rosevear <jpr@ximian.com> - - * gui/tasks-control.c (confirm_expunge): confirm expunging of the - tasks - (tasks_control_expunge_cmd): verb callback - - * gui/calendar-config.c (config_read): read confirm expunge value - (calendar_config_write): write confirm expunge value - (calendar_config_write_on_exit): ditto - (calendar_config_get_confirm_expunge): get value - (calendar_config_set_confirm_expunge): set value - - * gui/calendar-config.h: new proto - - * gui/e-itip-control.c (start_calendar_server): kill warning - - * gui/e-tasks.c (e_tasks_init): init query member to NULL - (set_status_message): util function to set status message - (e_tasks_open): use above - (cal_opened_cb): ditto - (create_sexp): create sexp of items to be deleted - (query_obj_updated_cb): remove any items found - (query_eval_error_cb): bail out on error - (query_query_done_cb): tidy when done - (e_tasks_delete_completed): set up query - - * gui/e-tasks.h: new proto - - * gui/calendar-model.c (query_query_done_cb): use g_warning - instead of printing to stderr - (query_eval_error_cb): ditto - (update_query): clear the status message if we can't create the - query - - * gui/tag-calendar.c (resolve_tzid_cb): make this static - -2001-12-21 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/comp-editor.c: remove needs send signal related - cruft - (save_comp_with_send): with send_component_dialog, indicate if the - meeting info is newly created or not - (real_edit_comp): remember if the dialog initially needs a send - - * gui/dialogs/send-comp.c (send_component_dialog): take a "new" - parameter indicating whether the dialog should intimate if the - component to be sent is a new meeting or not - - * gui/dialogs/send-comp.h: update proto - - * gui/dialogs/comp-editor.c: remove no longer used needs_send - notification and signal - - * gui/dialogs/comp-editor.h: remove proto - - * gui/e-day-view.c (e_day_view_on_main_canvas_drag_data_received): add new - param to send_component_dialog - (e_day_view_finish_long_event_resize): ditto - (e_day_view_finish_resize): ditto - (e_day_view_on_editing_stopped): ditto - (e_day_view_on_top_canvas_drag_data_received): ditto - - * gui/e-week-view.c (e_week_view_on_editing_stopped): add new - param to send_component_dialog - -2001-12-21 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/comp-editor.h: inherit from bonobo window - - * gui/dialogs/comp-editor.c: inherit from bonobo window - (comp_editor_key_press_event): Look for an escape key press and - close the window if found - -2001-12-20 Ettore Perazzoli <ettore@ximian.com> - - [Fixes #17377, Evolution doesn't work on multi-depth displays.] - - * gui/main.c (main): Push GdkRGB visual and colormap. - -2001-12-19 JP Rosevear <jpr@ximian.com> - - * conduits/calendar/calendar-conduit.c (check_for_slow_setting): - go slow and clear the map if the last uri and the current uri do - not match - (post_sync): save the last uri - - * conduits/calendar/calendar-conduit-config.h: handle a last uri - config option - - * conduits/todo/todo-conduit-config.h: ditto - - * conduits/calendar/calendar-conduit.c (start_calendar_server): - use the open_default_calendar method - - * conduits/todo/todo-conduit.c (start_calendar_server): same as above - - * cal-client/Makefile.am: link with bonobo conf - - * cal-client/cal-client.h: new protos - - * idl/evolution-calendar.idl: make sure open method raises - appropriate exceptions - - * gui/e-itip-control.c (start_calendar_server): use - cal_client_open_default_* calls - - * cal-client/cal-client.c (real_open_calendar): do the real work - of loading - (cal_client_open_calendar): use above - (get_fall_back_uri): get the basic local uri - (get_default_uri): get the default uri from the config db - (cal_client_open_default_calendar): open the default uri or the - fallback if the method is unsupported - (cal_client_open_default_tasks): same for tasks - -2001-12-17 JP Rosevear <jpr@ximian.com> - - * gui/e-itip-control.c (send_item): use get_real_item - (get_refresh_options): uncomment out - (get_real_item): obtain the real object which has the uid of the - item received - (show_current_todo): use get_refresh_options for refresh method - and provide the description and summary from the real component - since its not in the reply - (show_current_event): ditto - (send_item): use get_real_item - -2001-12-17 JP Rosevear <jpr@ximian.com> - - * gui/itip-utils.c (comp_limit_attendees): can't remove properties - in an iteration loop, so remove them outside the loop - (comp_minimal): don't set a recurid if there isn't one, add the x - properties to the clone - (comp_compliant): unref the clone for DECLINECOUNTER - - * gui/e-itip-control.c (get_refresh_options): make function - available again - (show_current_event): use it here - (ok_clicked_cb): can't remove properties in an iteration loop, so - remove them outside the loop - - * cal-util/cal-component.c (free_icalcomponent): properly free the - attendee list - (cal_component_rescan): don't destroy the alarm hash - -2001-12-13 Damon Chaplin <damon@ximian.com> - - * zones.h: new file to contain all timezone names for translation. - We won't be using the translations in 1.0.1, but it gives translators - time before we do use them in 1.0.2. - - * Makefile.am: added zones.h to EXTRA_DIST. - -2001-12-12 JP Rosevear <jpr@ximian.com> - - * gui/e-day-view.c (e_day_view_on_top_canvas_button_release): - ungrab the pointer before calling - e_day_view_finish_long_event_resize - (e_day_view_on_main_canvas_button_release): ditto - (e_day_view_finish_long_event_resize): ask if the meeting should - be sent - (e_day_view_finish_resize): ditto - (e_day_view_on_editing_stopped): ditto - (e_day_view_on_top_canvas_drag_data_received): ditto - (e_day_view_on_main_canvas_drag_data_received): ditto - -2001-12-11 JP Rosevear <jpr@ximian.com> - - * gui/e-meeting-model.c (process_free_busy_comp): properly convert - the dtstart and dtend times if they are UTC - (cursor_cb): if we don't have anybody to get f/b info for, process - the callbacks immediately - (e_meeting_model_refresh_busy_periods): take start/end times, - calculate the timet values with object timezone - (e_meeting_model_etable_model_to_view_row): proper cast - (e_meeting_model_etable_view_to_model_row): ditto - (async_open): bail out if we couldn't open properly - - * gui/e-meeting-time-sel.c - (e_meeting_time_selector_on_update_free_busy): use defines for - determining the number of days before and after of free busy to - request - (e_meeting_time_selector_update_dates_shown): use defines for the - number of days shown - - * gui/e-meeting-model.h: update proto - -2001-12-10 Damon Chaplin <damon@ximian.com> - - * gui/control-factory.c (control_factory_new_control): removed code - that connects to GnomeCalendar's "dates_shown_changed" signal. - - * gui/calendar-commands.c (gcal_calendar_dates_change_cb): - (calendar_control_activate): moved it here, so it gets reconnected - whenever the control is activated. Fixes bug #15798. - -2001-12-10 Damon Chaplin <damon@ximian.com> - - * importers/GNOME_Evolution_Calendar_Importer.oaf.in: fixed executable - name. Fixes bug #16880. - -2001-12-08 JP Rosevear <jpr@ximian.com> - - * conduits/calendar/calendar-conduit.c (local_record_from_comp): - if we have an alarm that can be represented on the pilot, set the - appointment fields appropriately, if the duration has values for - minutes and/or hours and/or days, use the lowest common - denominator - (comp_from_remote_record): if the appointment on the pilot has an - alarm, find the first alarm an item currently had that is relative - to the start and with a negative duration and update it (or create - a new one if no valid ones exist) - - * cal-util/cal-component.c (cal_component_get_alarm_uids): build - list in the order they appear in the component so we get - consisting order for the gui and for the pilot - -2001-12-08 Rodrigo Moya <rodrigo@ximian.com> - - * gui/calendar-config.c (calendar_config_get_default_uri): - (calendar_config_get_default_tasks_uri): s/%/%s - -2001-11-09 Federico Mena Quintero <federico@ximian.com> - - (committed by Damon) - - Fix bug #14699. - - * pcs/query.c (QueryState): Added a state QUERY_WAIT_FOR_BACKEND - to indicate that the query is not populated as we are waiting for - the backend to be opened. - (query_init): Start in the QUERY_WAIT_FOR_BACKEND state. - (query_destroy): Only disconnect from the backend if we are in a - state that implies that we are connected to its signals. - (query_construct): If the backend is already loaded, immediately - set the state to QUERY_START_PENDING. - (backend_opened_cb): Disconnect from the backend's "opened" - signal. Set the state to QUERY_START_PENDING. - (match_component): We can now only match components if the query - is in progress or if it is done. Assert to that effect, and do - not ensure_sexp(). - (match_component): Do not check for a nonexistent component using - g_return_if_fail(). Also, there is no need to ref/unref the - component. - (backend_obj_updated_cb): Assert to the effect of our state. - (backend_obj_removed_cb): Likewise. - (parse_sexp): Renamed from ensure_sexp(). Assert that the query - has not started. Do not disconnect from the backend's signals - here, since we have no connections. - (start_query_cb): Set the state to QUERY_IN_PROGRESS here instead - of in populate_query(). - -2001-12-07 Rodrigo Moya <rodrigo@ximian.com> - - * gui/calendar-config.c (calendar_config_get_default_uri): - (calendar_config_get_default_tasks_uri): if the key in the config - database does not exist, just return the local URIs, but never - return NULL - -2001-12-06 Rodrigo Moya <rodrigo@ximian.com> - - * gui/dialogs/event-page.c (event_page_fill_widgets): default - component classification to PUBLIC - -2001-12-06 Jon Trowbridge <trow@ximian.com> - - * gui/dialogs/event-editor.c (event_editor_destroy): Explicitly - destroy the EMeetingModel. This is a hack to work around problems - with the reference counting; we are still leaking the - EMeetingModels. - - * gui/e-meeting-time-sel.c - (e_meeting_time_selector_construct): Ref our EMeetingModel. - (e_meeting_time_selector_destroy): Unref the model. - - * gui/e-meeting-model.c (destroy): Properly destroy - corba_select_names with a call to bonobo_object_release_unref. - (Fixes 14002) - -2001-12-05 Rodrigo Moya <rodrigo@ximian.com> - - * gui/dialogs/event-page.glade: added entry for the LOCATION field - - * gui/dialogs/event-page.c: added support for the new LOCATION entry - added in the Event editor. - -2001-12-05 Zbigniew Chyla <cyba@gnome.pl> - - * gui/itip-utils.c (comp_subject, comp_description): - Marked strings for translation. - -2001-12-03 Damon Chaplin <damon@ximian.com> - - * gui/e-meeting-model.c: - * gui/calendar-model.c: make sure we call e_table_model_pre_change() - before changing the model. - - * gui/calendar-config.c (calendar_config_configure_e_calendar_table): - removed call to e_table_model_changed(). calendar_model_refresh() - results in that anyway. - -2001-12-03 Damon Chaplin <damon@ximian.com> - - * gui/e-calendar-table.etspec: disabled 'Alarms', 'End Date' and - 'Show Time As' fields, as these are not useful for tasks. We may want - to reenable them later if we add a table view of calendar events. - -2001-12-02 Rodrigo Moya <rodrigo@ximian.com> - - * gui/calendar-offline-handler.c (backend_cal_opened): connect to - "cal_set_mode" signal before calling cal_client_set_mode. Also, - s/cal_mode_set/cal_set_mode - (backend_go_offline): connect to "cal_opened" signal before calling - cal_client_open_calendar - -2001-11-30 Damon Chaplin <damon@ximian.com> - - * gui/e-itip-control.c (remove_item): only show the dialog if we - created it. Hopefully fixes bug #15774. - Also ifdef'ed out a lot of code that isn't currently used, including - code to use a label which is never created. The unused code was there - to support handling multiple iTIP objects in a message, but was never - updated when we switched to use HTML for the control. Fixes bug #16232. - -2001-11-28 Federico Mena Quintero <federico@ximian.com> - - * gui/gnome-cal.c (gnome_calendar_new_task): Set the category of - the new task to that of the search bar. Fixes bug #15533. - -2001-11-27 Rodrigo Moya <rodrigo@ximian.com> - - * gui/e-itip-control.c (update_attendee_status): - * gui/itip-utils.c (comp_to_list): fixed typos in translatable - strings. Fixes Ximian #15456 - -2001-11-14 Damon Chaplin <damon@ximian.com> - - * gui/print.c: Substituted gnome_font_get_width_string() with - gnome_font_get_width_utf8() and gnome_font_get_width_string_n() - with gnome_font_get_width_utf8_sized(). Fixes calendar part of #15379. - -2001-11-14 Federico Mena Quintero <federico@ximian.com> - - * gui/calendar-model.c (date_value_to_string): Convert the buffer - to UTF8. - (calendar_model_value_to_string): Do not convert the string fields - to UTF8 again; they are already in UTF8. Fixes the UTF8-related - bits of bug #15304. - -2001-11-14 Damon Chaplin <damon@ximian.com> - - * gui/calendar-model.c: - * cal-util/cal-component.h: #ifdef'ed out the LOCATION field for now, - since it wasn't supported everywhere, or in the .etspec file. - -2001-11-14 Damon Chaplin <damon@ximian.com> - - * gui/e-calendar-table.c: don't abort when e_table_selected_count() - returns odd values. There seems to be a bug in ETable. This is to - avoid bug #13843. - -2001-11-13 Federico Mena Quintero <federico@ximian.com> - - (committed to CVS by Damon) - Fixes bug #15137. - - * gui/e-day-view.c (e_day_view_on_delete_appointment): Do not try - to operate on the event if it gets deleted while stopping the - edition. - (e_day_view_on_event_double_click): Likewise. - (e_day_view_on_long_event_button_press): Likewise. - (e_day_view_on_event_button_press): Likewise. - (e_day_view_on_long_event_click): Likewise. - (e_day_view_on_event_click): Likewise. - - * gui/e-week-view.c (e_week_view_on_text_item_event): Likewise. - -2001-11-14 JP Rosevear <jpr@ximian.com> - - * conduits/calendar/calendar-conduit.c (pre_sync): remove silly - debug warning - -2001-11-13 Damon Chaplin <damon@ximian.com> - - * gui/alarm-notify/config-data.c (ensure_inited): - * gui/calendar-config.c (config_read): - * conduits/todo/todo-conduit.c (get_default_timezone): - * conduits/calendar/calendar-conduit.c (get_default_timezone): - make the timezone default to UTC. Fixes bug #14362. - -2001-11-13 Rodrigo Moya <rodrigo@ximian.com> - - * gui/e-week-view.c (selection_received): only change the day, - month and year for the start date, for not screwing up the start - time, which was being set to midnight always (Fixes Ximian #5287) - Also, deal correctly with VCALENDAR components - - * gui/e-day-view.c (selection_received): dela correctly with - VCALENDAR components being pasted - -2001-11-11 Federico Mena Quintero <federico@ximian.com> - - * gui/alarm-notify/save.c (get_calendars_to_load): The last - argument to the bonobo_config_get_XXX_with_default() is a gboolean - *, not a CORBA_Environment *. Fixes bug #14655. - -2001-11-11 JP Rosevear <jpr@ximian.com> - - * pcs/cal-backend-file.c (free_busy_instance): recurrence - expansion callback for free/busy - (create_user_free_busy): expand recurrences and use date/time - values for dtstart and dtend - -2001-11-11 JP Rosevear <jpr@ximian.com> - - * gui/e-meeting-model.h: new protos - - * gui/e-meeting-model.c (e_meeting_model_get_zone): accessor - (e_meeting_model_set_zone): ditto - (init): init to the calendar default zone - (process_free_busy_comp): take the zone to convert to as a param - (e_meeting_model_refresh_busy_periods): redraw properly - - * gui/dialogs/schedule-page.c (update_time): set the zone of the - model - -2001-11-09 Damon Chaplin <damon@ximian.com> - - * gui/e-week-view.c (e_week_view_key_press): don't subtract a day - from DTEND. For DATE values we don't include the entire day now. - Fixes bug #14842. - -2001-11-09 Damon Chaplin <damon@ximian.com> - - * gui/e-week-view-layout.c (e_week_view_layout_events): fix buffer - overflow. Fixes bug #10285 (the printing of lines & dates in the - printout of the month view). - -2001-11-09 Zbigniew Chyla <cyba@gnome.pl> - - * gui/dialogs/meeting-page.c - (meeting_page_fill_widgets): Convert strings to GTK+ encoding. - (meeting_page_destroy): Free allocated strings before freeing the list - itself. - -2001-11-08 JP Rosevear <jpr@ximian.com> - - * gui/e-meeting-time-sel.c - (e_meeting_time_selector_timeout_handler): don't let an empty - event occur for all days when auto scrolling - -2001-11-08 Rodrigo Moya <rodrigo@ximian.com> - - * pcs/cal-backend-file.c - (cal_backend_file_compute_changes_foreach_key): don't leak the - string returned by cal_component_get_as_string nor the temporary - CalComponent we create - -2001-11-08 JP Rosevear <jpr@ximian.com> - - * gui/e-itip-control.c (ok_clicked_cb): don't add the item, remove - it if declining (in case it was added before) - (remove_item): Since we can't discern between an item not found - and another error, always say the removal is complete - -2001-11-07 Zbigniew Chyla <cyba@gnome.pl> - - * gui/e-cell-date-edit-text.c (ecd_get_text): - Convert generated string to UTF-8. - -2001-11-07 JP Rosevear <jpr@ximian.com> - - * gui/e-meeting-time-sel.c - (e_meeting_time_selector_on_start_time_changed): emit changed - signal - (e_meeting_time_selector_on_end_time_changed): emit changed - signal, if end time is now before start time and all day event, - make sure a whole day is still selected - (e_meeting_time_selector_drag_meeting_time): calculate the first - and last_time's in whole days for all day events - (e_meeting_time_selector_timeout_handler): calculate the drag time - to be whole days for all day events and scroll the canvas even if - we don't update the time so the user can see where they're headed - -2001-11-06 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/event-editor.c (event_editor_edit_comp): make sure - to remove all attendees from the model when we edit a new comp, - append the pages if they are needed and we weren't showing them - before - - * gui/dialogs/task-editor.c (task_editor_edit_comp): same as above - - * gui/dialogs/comp-editor.c (comp_editor_remove_page): check for a - return value indicating the page was not found and return if so - -2001-11-05 Ettore Perazzoli <ettore@ximian.com> - - * gui/dialogs/e-delegate-dialog.c: #include - "Evolution-Addressbook-SelectNames.h", not - "../Evolution-Addressbook-SelectNames.h". Grrr. - -2001-11-05 JP Rosevear <jpr@ximian.com> - - * gui/e-meeting-time-sel.c (e_meeting_time_selector_class_init): - add a changed signal - (e_meeting_time_selector_construct): emit changed signal - (e_meeting_time_selector_set_meeting_time): ditto - (e_meeting_time_selector_set_all_day): set the all day setting - (e_meeting_time_selector_autopick): emit changed signal - (e_meeting_time_selector_find_nearest_interval): find proper - interval when in all day mode - (e_meeting_time_selector_find_nearest_interval_backward): ditto - (e_meeting_time_selector_drag_meeting_time): for all day events, - move the time when past the 12 hour mark, and and always make sure - 1 full day is selected, emit changed signal when appropriate - (e_meeting_time_selector_update_start_date_edit): set date and - time of day together - (e_meeting_time_selector_update_end_date_edit): ditto, and adjust - display time if all day event - - * gui/e-meeting-time-sel-item.c - (e_meeting_time_selector_item_draw): remove unused variable - (e_meeting_time_selector_item_button_press): for all day mode, - make the interval a whole day - - * gui/dialogs/schedule-page.c (update_time): set the meeting time - selector setting instead of manual mucking with the e-date-edit - widgets - (init_widgets): listen to the changed signal of the meeting time - selector instead of propagating multiple events as it updates - - * gui/dialogs/event-page.c (update_time): block time zone change - signals - -2001-11-05 Damon Chaplin <damon@ximian.com> - - * gui/calendar-model.c (dup_date_edit_value): removed ';' in the wrong - place. Fixes bug #14421. - -2001-11-05 Dan Winship <danw@ximian.com> - - * gui/alarm-notify/Makefile.am (evolution_alarm_notify_LDFLAGS): - -export-dynamic for libglade custom widget. - -2001-11-04 Damon Chaplin <damon@ximian.com> - - * gui/comp-editor-factory.c (get_default_component): use TZID from the - builtin timezone, instead of using the location name. - -2001-11-02 Federico Mena Quintero <federico@ximian.com> - - * cal-util/cal-util.c (compute_alarm_range): Short-circuit the - calculation of the repeat time if there are zero repetitions. - (compute_alarm_range): I'm a moron. De-reference alarm_start when - subtracting stuff from it! Fixes bug #14209. - -2001-10-31 Ettore Perazzoli <ettore@ximian.com> - - * gui/dialogs/Makefile.am: Added rules to generate - `Evolution-Addressbook-SelectNames.h'. - - * gui/dialogs/comp-editor-util.h: #include - "Evolution-Addressbook-SelectNames.h" from this directory. - -2001-10-31 Federico Mena Quintero <federico@ximian.com> - - * gui/dialogs/alarm-options.c: #include <string.h> - -2001-10-31 Federico Mena Quintero <federico@ximian.com> - - * gui/gnome-cal.c (dn_query_obj_updated_cb): If a query is not in - progress, just retag the whole thing. An event may change dates - and tag_calendar_by_comp() would not know how to untag the old - dates. Fixes bug #10220. - - * pcs/query.c (start_query_cb): Connect to the backend's - "obj_updated" and "obj_removed" signals here instead of in - query_construct(). If a query is started while another one is - notifying of an update, these signal connections would get appened - to the running signal (the one that triggered the notification - about an update) and the new signal handlers would also get - called. We are really not interested in updates before we - populate the query, because we'll catch the changes anyways. - -2001-10-31 Federico Mena Quintero <federico@ximian.com> - - Fix bug #13723. - - * gui/gnome-cal.h (GnomeCalendarClass): New signals - "calendar_focus_change", "taskpad_focus_change", and - "taskpad_selection_changed". Renamed "selection_changed" to - "calendar_selection_changed". - - * gui/gnome-cal.c (gnome_calendar_get_num_tasks_selected): New - function. - (setup_widgets): Connect to the focus event signals of the task - pad and the calendar view widgets. - (gnome_calendar_delete_selection): Renamed from - gnome_calendar_delete_event(). - (gnome_calendar_cut_clipboard): Handle the current focus location. - (gnome_calendar_copy_clipboard): Likewise. - (gnome_calendar_paste_clipboard): Likewise. - (gnome_calendar_delete_selection): Likewise. - (table_selection_change_cb): New callback. - - * gui/calendar-commands.c (sensitize_calendar_commands): Take in - whether we should unconditionally disable everything. - (sensitize_taskpad_commands): Analogous function to the above. - (gcal_calendar_focus_change_cb): New callback, used for calendar - views. - (gcal_taskpad_focus_change_cb): New callback, used for the - taskpad. - - * gui/e-day-view.c (e_day_view_key_press): Use a better test for - keys that should start editing. Fixes bug #6447. - - * gui/e-week-view.c (e_week_view_key_press): Likewise. - -2001-10-31 Christopher James Lahey <clahey@ximian.com> - - * gui/calendar-model.c: Make the pre_changes and changes match - here. - -2001-10-31 JP Rosevear <jpr@ximian.com> - - * gui/itip-utils.c (itip_send_comp): send as mixed rather than - alternative - -2001-10-31 Ettore Perazzoli <ettore@ximian.com> - - * gui/alarm-notify/save.c (KEY_CALENDARS_TO_LOAD): - Removed. - (KEY_NUM_CALENDARS_TO_LOAD): New key, containing the number of - calendars to load. - (BASE_KEY_CALENDAR_TO_LOAD): New base key name for the URIs of the - calendars to load. - (save_calendars_to_load): Rewrote to not use a sequence, to work - around an ORBit bug that causes bonobo-moniker-xmldb to crash. - (get_calendars_to_load): Likewise. - -2001-10-30 Damon Chaplin <damon@ximian.com> - - * gui/dialogs/comp-editor.c (comp_editor_remove_page): disconnect - signals added in append_page(). Fixes Gtk-Critical warning about - GtkAccelGroup being added twice to a window. - -2001-10-30 JP Rosevear <jpr@ximian.com> - - * gui/itip-utils.c (itip_send_comp): set a body for the message - -2001-10-30 Dan Winship <danw@ximian.com> - - * gui/itip-utils.c (itip_send_comp): call - GNOME_Evolution_Composer_setMultipartType to get a - multipart/alternative. - -2001-10-30 JP Rosevear <jpr@ximian.com> - - * gui/e-meeting-time-sel.c - (e_meeting_time_selector_on_start_time_changed): don't overwrite - memory - (e_meeting_time_selector_on_end_time_changed): ditto - -2001-10-30 Damon Chaplin <damon@ximian.com> - - * gui/calendar-model.c (dup_date_edit_value): return NULL if passed - NULL. Should fix bug #14048. - -2001-10-30 Federico Mena Quintero <federico@ximian.com> - - * gui/calendar-config.c (config_read): Do not ignore the - exceptions of the cases that do not have defaults. - -2001-10-30 JP Rosevear <jpr@ximian.com> - - * gui/e-meeting-time-sel.c - (e_meeting_time_selector_drag_meeting_time): if we are doing all - day stuff, make the drag increment 1 day at a time - -2001-10-30 Federico Mena Quintero <federico@ximian.com> - - * gui/dialogs/meeting-page.c (meeting_page_fill_component): Add - _() to a string that was missing it. - -2001-10-30 Federico Mena Quintero <federico@ximian.com> - - * gui/dialogs/meeting-page.c (table_canvas_focus_out_cb): Commit - the ETable click-to-add for if the dialog is being destroyed. - Should fix bug #13959. - -2001-10-30 Federico Mena Quintero <federico@ximian.com> - - * gui/itip-utils.c (itip_send_comp): Allocate enough space for the - string! (was missing the null terminator) Possibly fixes #13924. - Thanks a *LOT* to Michael Zucchi for running this through Purify. - -2001-10-30 JP Rosevear <jpr@ximian.com> - - * gui/e-meeting-time-sel-item.c - (e_meeting_time_selector_item_button_press): move in whole day - increments if we are in all day mode - - * gui/e-meeting-time-sel.c - (e_meeting_time_selector_on_start_time_changed): get rid of - localtime call - (e_meeting_time_selector_on_end_time_changed): ditto - (e_meeting_time_selector_update_start_date_edit): set the date - editor using the meeting time fields directly - (e_meeting_time_selector_update_end_date_edit): ditto - - * gui/dialogs/schedule-page.c (update_time): do the set_show_time - stuff first - - * conduits/calendar/calendar-conduit.c (process_multi_day): don't - adjust the time, set the default timezone for date values - -2001-10-30 Dan Winship <danw@ximian.com> - - * gui/alarm-notify/Makefile.am (INCLUDES): - s/BONOBO_HTML_GNOME_LIBS/BONOBO_HTML_GNOME_CFLAGS/ - -2001-10-30 JP Rosevear <jpr@ximian.com> - - * gui/e-meeting-model.c (e_meeting_model_count_actual_attendees): - count the actual attendees (doesn't include people delegating - - * gui/e-meeting-time-sel.c: use - e_meeting_model_count_actual_attendees (renamed) - - * gui/e-meeting-time-sel-item.c: use - e_meeting_model_etable_view_to_model_row calls instead of calling - on the model directly, use e_meeting_model_count_actual_attendees - - * gui/e-meeting-model.c - (e_meeting_model_etable_model_to_view_row): get the real mapping - (e_meeting_model_etable_view_to_model_row): ditto - (get_key): e-table-without callback - (duplicate_key): ditto - (free_gotten_key): ditto - (free_duplicated_key): ditto - (init): create without model - (e_meeting_model_etable_from_model): build etable from without - model - - * gui/e-meeting-model.h: update protos - - * gui/dialogs/meeting-page.c (right_click_cb): convert row from - view to model row - -2001-10-30 Damon Chaplin <damon@ximian.com> - - * gui/dialogs/task-page.c (task_page_fill_widgets): set to the default - timezone for DATE values, in case the user switches to a DATE-TIME. - -2001-10-30 Damon Chaplin <damon@ximian.com> - - * gui/dialogs/task-page.c: handle DATE values for Start and Due dates. - -2001-10-30 Damon Chaplin <damon@ximian.com> - - * gui/dialogs/schedule-page.c: - * gui/dialogs/event-page.c: - * gui/dialogs/comp-editor-util.c: updated code to handle DATE values. - - * gui/gnome-cal.c (gnome_calendar_new_appointment_for): - * gui/e-day-view.c (e_day_view_key_press): updated DATE code. - - * gui/e-cell-date-edit-text.c: - * gui/calendar-model.c: updated to support DATE values. - - * cal-util/cal-recur.c (cal_recur_generate_instances_of_rule): updated - to use DATE values in same way as Outlook - i.e. the DTEND date is - not included entirely. Though I did make it so that if the DTSTART - and DTEND used the same DATE value, it includes the entire day. - So 1-day events should be the same. Long All-Day events will be - 1 day shorter. - - * cal-util/cal-component.c (cal_component_get_start_plus_duration): - don't subtract a day from the end date. - - * gui/tasks-control.c: updated the EPixmap paths for Cut/Copy etc. - Removed Print & Print Preview paths, since we don't have menu commands - for these any more. - -2001-10-30 Federico Mena Quintero <federico@ximian.com> - - Fix bug #10016. - - * gui/dialogs/comp-editor.c (comp_editor_merge_ui): Use - bonobo_ui_util_set_ui() instead of doing things by hand. Hmmm, if - only that function had a way of telling us whether it failed so - that we could avoid setting the verb list... - - * gui/dialogs/event-editor.c (event_editor_init): Do not pass the - filename with the full path so that Bonobo can find it in a smart - way. - - * gui/dialogs/task-editor.c (task_editor_init): Likewise. - -2001-10-30 Federico Mena Quintero <federico@ximian.com> - - * gui/dialogs/delete-comp.c (delete_component_dialog): Use an - EMessageBox instead of a gnome_dialog_question so that the label - gets line breaking. Fixes bug #11260. - -2001-10-29 Federico Mena Quintero <federico@ximian.com> - - Fix bug #13649. - - * gui/calendar-config.c - (calendar_config_get_use_default_reminder): New function. - (calendar_config_set_use_default_reminder): New function. - (calendar_config_get_default_reminder_interval): New function. - (calendar_config_set_default_reminder_interval): New function. - (calendar_config_get_default_reminder_units): New function. - (calendar_config_set_default_reminder_units): New function. - (config_read): Get the options for default reminders. - (calendar_config_write): Set the options for default reminders. - - * gui/dialogs/cal-prefs-dialog.c (cal_prefs_dialog_show_config): - Set the default reminder widgets from the config values. - (cal_prefs_dialog_update_config): Set the config values from the - widgets. - - * gui/comp-util.c (cal_comp_event_new_with_defaults): New - function; creates a VEVENT component with the default alarm. - - * gui/e-day-view.c (e_day_view_key_press): Use - cal_comp_event_new_with_defaults (); - - * gui/e-week-view.c (e_week_view_key_press): Likewise. - * gui/calendar-model.c (calendar_model_append_row): Likewise. - * gui/comp-editor-factory.c (get_default_component): Likewise. - * gui/gnome-cal.c (gnome_calendar_new_appointment_for): Likewise. - - * cal-util/cal-component.c (ensure_alarm_properties_cb): Ensure we - have a DESCRIPTION property. - (cal_component_commit_sequence): Ensure we have the mandatory - alarm properties. - -2001-10-30 JP Rosevear <jpr@ximian.com> - - * gui/e-meeting-model.c (process_section): process an individual - section here - (select_names_ok_cb): call above - (get_select_name_dialog): listen for ok:dialog signal - -2001-10-29 Damon Chaplin <damon@ximian.com> - - * importers/Makefile.am (evolution_calendar_importer_LDADD): - * gui/Makefile.am (evolution_calendar_LDADD): - * cal-util/Makefile.am (test_recur_LDADD): - * cal-client/Makefile.am (client_test_LDADD): use libical-evolution.la - - * gui/dialogs/schedule-page.c: save the timezone passed in for the - start time, so if our times are changed we use this. Also, if the - end time was passed in in a different timezone, convert it. - Also hide the time fields for DATE values. Note that DATE values still - do not work. - - * gui/dialogs/meeting-page.glade: changed "Invite Others" to - "Invite Others..." to be consistent with the other page. - - * gui/dialogs/event-page.c (times_updated): - (all_day_event_toggled_cb): set is_date if appropriate. - - * gui/e-itip-control.c (write_label_piece): convert all UTC times to - the current timezone. Outlook sends simple, non-recurring, events as - UTC times, which isn't very useful. - -2001-10-29 Federico Mena Quintero <federico@ximian.com> - - * gui/main.c (launch_alarm_daemon): Launch the alarm daemon as - soon as the calendar component is started. Fixes bug #13867; - we can't really do much better than this. - -2001-10-29 Federico Mena Quintero <federico@ximian.com> - - * gui/tasks-control.c (pixmaps): Fix the verb names for the - pixmaps in the Edit menu; they were out of synch with the XML - UI description. - -2001-10-29 Chris Toshok <toshok@ximian.com> - - * pcs/cal-factory.c (cal_factory_dump_active_backends): new - function. - (dump_backend): new function. - - * pcs/cal-factory.h: add prototype for - cal_factory_dump_active_backends. - -2001-10-29 Federico Mena Quintero <federico@ximian.com> - - Fix bug #12163. - - * cal-util/cal-util.c (compute_alarm_range): Take alarm - repetitions into account. - (add_alarm_occurrences_cb): Add alarm repetitions. - (generate_absolute_triggers): Likewise. - (generate_absolute_triggers): Oops, absolute triggers are in UTC, - so convert them as such. Also, pay attention to the timezones of - the dtstart and dtend properties. - -2001-10-29 JP Rosevear <jpr@ximian.com> - - * importers/Makefile.am: include the header as a source so it gets - dist'ed. - -2001-10-29 Ettore Perazzoli <ettore@ximian.com> - - * importers/Makefile.am (INCLUDES): - s/BONOBO_CFLAGS/BONOBO_GNOME_CFLAGS/. - -2001-10-29 Rodrigo Moya <rodrigo@ximian.com> - - * importers/icalendar-importer.c (load_file_fn): fixed URI - construction, which was preventing importing into the root - calendar (~/evo/local/Calendar/) - -2001-10-29 JP Rosevear <jpr@ximian.com> - - * conduits/calendar/calendar-conduit.c (is_all_day): handle date - values - -2001-10-29 Rodrigo Moya <rodrigo@ximian.com> - - * importers/: added evolution-calendar-importer binary, starting - with an iCalendar file importer - -2001-10-29 JP Rosevear <jpr@ximian.com> - - * conduits/todo/todo-conduit-config.h - (todoconduit_load_configuration): get the management object by id - - * conduits/calendar/calendar-conduit-config.h - (calconduit_load_configuration): ditto - -2001-10-29 Rodrigo Moya <rodrigo@ximian.com> - - * gui/calendar-config.[ch] (calendar_config_get_default_uri): - (calendar_config_set_default_uri): - (calendar_config_get_default_tasks_uri): - (calendar_config_set_default_tasks_uri): new functions for setting - and retrieving the default calendar URIs - - * gui/e-itip-control.c (init): don't use - hard-coded URI, but use the default calendar URI, as returned - by calendar_config_get_default_uri - (start_calendar_server): added a "gboolean tasks" parameter, so - that the local tasks.ics file is used if the calendar to be - started is for tasks when no default tasks URI is found in - the configuration - -2001-10-28 JP Rosevear <jpr@ximian.com> - - * conduits/calendar/calendar-conduit.c (add_record): unref the - comp when finished - - * conduits/todo/todo-conduit.c (add_record): ditto - -2001-10-28 Damon Chaplin <damon@ximian.com> - - * gui/dialogs/task-page.c (task_page_fill_widgets): added break - statements after each case, when setting the classification. - Fixes bug #13772. - -2001-10-28 Rodrigo Moya <rodrigo@ximian.com> - - * cal-client/cal-client.c (destroy_wombat_client): removed this - function, as we don't need to unref at all the WombatClient - object, since it is aggregated to the CalListener object, which - will take care of unrefing it (Fixes Ximian #12001) - (cal_client_open_calendar): create the WombatClient here - -2001-10-28 Damon Chaplin <damon@ximian.com> - - * gui/print.c (print_todo_details): get the tasks directly from the - CalendarModel, so we get the filtering & sorting for free. Fixes - bug #10280. Hmm. This seems too easy. It isn't going to work is it... - - * gui/gnome-cal.c (gnome_calendar_get_task_pad): new function to get - the TaskPad ECalendarTable, for printing. - - * gui/calendar-model.c: - * gui/calendar-config.c (calendar_config_get_hide_completed_tasks_sexp): - split this out from calendar-model.c so we could use it for printing, - but ended up doing that a different way. - - * gui/dialogs/task-page.c (init_widgets): removed a duplicated signal - connected to field_changed_cb(). - -2001-10-27 Damon Chaplin <damon@ximian.com> - - * gui/print.c (print_week_view): - (range_selector_new): when the week start day is set to Sunday, we - have to be careful to make sure we print the correct week, since - the previous Saturday is actually printed first. Fixes bug #13687. - (print_week_summary): always set compress_weekend to true if - multi_week_view is FALSE (i.e. we are printing the week view). - Fixes bug #13688. - - * gui/e-itip-control.c (send_freebusy): use the timezones from the - DTSTART and DTEND. - (write_label_piece): output the date-time and the timezone after it. - Note that we may want to convert it to the current timezone and display - that as well. Also converted COMPLETED to the current timezone. - And fixed all uses of old timezone functions. - - * gui/dialogs/comp-editor.c (commit_all_fields): added function to - set the focus in the window to NULL, so all fields lose their focus, - so they emit "changed" signals and update their values if needed. - We call this when most menu commands are used, e.g. 'Save and Close', - 'Print' etc. Fixes bug #11434. In future we should also check fields - are valid and show dialogs if they are not. - - * gui/calendar-model.c (get_completed): use the completed value - properly. Fixes bug #13694. - - * cal-util/timeutil.c (icaltimetype_to_tm_with_zone): don't check - from_zone and to_zone != NULL. A NULL zone is valid, it is for - floating times. - -2001-10-27 Federico Mena Quintero <federico@ximian.com> - - * gui/e-day-view.c (e_day_view_on_text_item_event): Cancel editing - if the user presses Escape. - - * gui/e-week-view.c (e_week_view_on_text_item_event): Likewise. - - * gui/cal-search-bar.c: #include <string.h> - -2001-10-27 Federico Mena Quintero <federico@ximian.com> - - * gui/e-day-view.c (e_day_view_on_editing_stopped): Delete - appointments with empty summaries. Fixes Ximian bug #780. - - * gui/e-week-view.c (e_week_view_on_editing_stopped): Likewise. - - * gui/dialogs/delete-comp.c (delete_component_dialog): Added an - argument to specify whether we unconditionally want single - components to be considered as not having a summary. - - * gui/comp-util.c (cal_comp_confirm_delete_empty_comp): New - function. - - * gui/misc.[ch]: New files with miscellaneous utility functions; - moved string_is_empty() over from calendar-model.c. - - * gui/calendar-model.c: Use the string_is_empty() - function from misc.c. - - * gui/Makefile.am (evolution_calendar_SOURCES): Added misc.[ch] to - the list of sources. - -2001-10-27 JP Rosevear <jpr@ximian.com> - - * conduits/todo/todo-conduit.c (local_record_from_comp): touch on - lookup - (check_for_slow_setting): write touched only if slow sync - (match): touch on lookup - - * conduits/calendar/calendar-conduit.c (local_record_from_comp): - touch the record on lookup - (check_for_slow_setting): write touched only if slow sync - (pre_sync): don't touch on lookup - (match): touch on lookup - -2001-10-26 JP Rosevear <jpr@ximian.com> - - * conduits/calendar/e-calendar.conduit.in: remove the merges as - valid sync types - - * conduits/todo/e-todo.conduit.in: as above - - * conduits/calendar/calendar-conduit.c (pre_sync): write out only - the touched records if we are doing copies - - * conduits/todo/todo-conduit.c: as above - - * conduits/calendar/calendar-conduit-config.h - (calconduit_load_configuration): get the sync type - - * conduits/todo/todo-conduit-config.h: as above - -2001-10-26 Damon Chaplin <damon@ximian.com> - - * gui/e-itip-control.c (write_label_piece): convert the formatted - date to UTF-8. - - * cal-util/cal-recur.c (CAL_OBJ_DEBUG): turn off debug functions. - - * gui/dialogs/comp-editor-util.c (parse_contact_string): handle UTF8 - correctly. Bug #4450. Good enough for 1.0. - - * gui/e-week-view-event-item.c (e_week_view_draw_time): set the gc - color before drawing. Should fix bug #11469. - - * gui/dialogs/task-editor.c (task_editor_edit_comp): show or hide the - meeting page as appropriate. Note this may be called more than once, - if the task gets updated somewhere else and the user clicks 'Update - the object'. Hopefully fixes bug #12930. - - * gui/print.c (print_comp_item): printed more fields and made a little - prettier. Fixes bug #9352. - (print_date_label): used the correct timezones for each date field. - - * *.c: removed several debug messages. - -2001-10-26 JP Rosevear <jpr@ximian.com> - - * conduits/calendar/calendar-conduit.c (check_for_slow_setting): - make debug output more accurate - - * conduits/todo/todo-conduit.c (check_for_slow_setting): ditto - -2001-10-26 JP Rosevear <jpr@ximian.com> - - * conduits/todo/todo-conduit.c (pre_sync): remove the uid from the - map if was archived and is now deleted - - * conduits/calendar/calendar-conduit.c: ditto - -2001-10-26 Rodrigo Moya <rodrigo@ximian.com> - - * gui/e-calendar_table.c (delete_selected_components): - (selection_received): added status bar messages - - * gui/e-day-view.c (e_day_view_cut_clipboard): - (selection_received): likewise - - * gui/e-week-view.c (e_week_view_cut_clipboard): - (selection_received): likewise - -2001-10-26 JP Rosevear <jpr@ximian.com> - - * conduits/calendar/calendar-conduit.h: modify fields - - * conduits/todo/todo-conduit.h: as above - - * conduits/calendar/calendar-conduit.c (print_remote): free the - struct after use - (e_calendar_context_new): explicitly init context fields - (e_calendar_context_destroy): free local records and properly free - changed hash elements - (start_calendar_server_cb): tidy - (start_calendar_server): ditto - (free_local): free a local record - (local_record_to_pilot_record): use a static buffer to avoid leaks - (local_record_from_comp): only copy over alarm stuff from the - original record, we sync everything else - (local_record_from_uid): unref the comp when we are done - (pre_sync): free change_id - (post_sync): ditto - (for_each): track locals - (for_each_modified): ditto - (free_match): use free_local - - * conduits/todo/todo-conduit.c: as above - -2001-10-26 Federico Mena Quintero <federico@ximian.com> - - * pcs/cal.c (cal_construct): Get a fresh CORBA_Environment for - every CORBA call. Hopefully will fix #11978, but I'm not sure - about what else could be happening. - (cal_get_password): Free the exception. - -2001-10-25 Damon Chaplin <damon@ximian.com> - - * gui/e-itip-control.c: used functions to get PUBLISH_OPTIONS etc., - so we can translate them. - -2001-10-25 Damon Chaplin <damon@ximian.com> - - * cal-util/cal-recur.c (cal_obj_bysetpos_filter): subtract 1 from - any positive BYSETPOS value, since our array is 0-based. - - * gui/dialogs/recurrence-page.c (simple_recur_to_comp): - (recurrence_page_fill_widgets): Outlook (2000) will not accept monthly - recurrences like BYDAY=2TU. Instead it uses BYDAY=TU;BYSETPOS=2. - So to be compatable with it we now do the same, although we still - accept and convert the old format. - - * cal-client/cal-client.c (cal_client_get_component_as_string): new - function to return a complete VCALENDAR string containing a VEVENT - or VTODO with all the VTIMEZONEs it uses. - - * gui/dialogs/comp-editor.c (save_as_ok): use above function so we - save the VTIMEZONE data with the VEVENT/VTODO. Fixes bug #8626. - Also made sure we output "METHOD:PUBLISH" since Outlook (2000) will - not import it otherwise. - - * gui/dialogs/comp-editor.c (page_mapped_cb): - (page_unmapped_cb): install/uninstall the GtkAccelGroup for the page. - (comp_editor_append_page): connect to the map/unmap signals to - install/uninstall the accelerators. (This is all for bug #11609, - though of course it doesn't work too well in GTK+ 1.2 anyway.) - - * gui/dialogs/task-page.c (get_widgets): - * gui/dialogs/task-details-page.c (get_widgets): - * gui/dialogs/schedule-page.c (get_widgets): - * gui/dialogs/recurrence-page.c (get_widgets): - * gui/dialogs/meeting-page.c (get_widgets): - * gui/dialogs/event-page.c (get_widgets): - * gui/dialogs/alarm-page.c (get_widgets): got the GtkAccelGroup from - the original window, ref'ed it and placed it in the CompEditorPage - struct. - - * gui/dialogs/comp-editor-page.c (comp_editor_page_destroy): unref - any GtkAccelGroup for the page. - - * gui/dialogs/task-page.glade: changed '_Confidential' to - 'Con_fidential' as it clashed with '_Contacts'. It now matches the - event editor as well. - - * gui/dialogs/event-page.glade: - * gui/dialogs/task-page.glade: Set CAN_FOCUS to TRUE for the custom - EDateEdit widgets, and set them as the accel targets of the labels. - -2001-10-25 Rodrigo Moya <rodrigo@ximian.com> - - * gui/dialogs/comp-editor.c (save_comp): show an error message when - we can't update the object on the calendar server - -2001-10-25 Federico Mena Quintero <federico@ximian.com> - - * gui/control-factory.c: Ifdef-ed out the PersistFile bits. - - * gui/GNOME_Evolution_Calendar.oaf.in: The tasks folder does not - support the PersistFile interface; removed it. Removed it as well - from the calendar folder since it is aggregated but not actually - implemented. - -2001-10-25 Federico Mena Quintero <federico@ximian.com> - - * gui/component-factory.c (xfer_folder): Handle tasks folders as - well; was always using "calendar.ics" as the filename. - -2001-10-24 Damon Chaplin <damon@ximian.com> - - * gui/GNOME_Evolution_Calendar.oaf.in: added sections for Tasks - factory and control. I hope someone checks these! - -2001-10-24 Ettore Perazzoli <ettore@ximian.com> - - * gui/component-factory.c (xfer_folder): Fixed to only copy the - `calendar.ics' and `calendar.ics~' files. - -2001-10-24 Damon Chaplin <damon@ximian.com> - - * pcs/cal-backend-file.c (cal_backend_file_update_objects): when - iterating over the subcomponents, use 'subcomp' rather than 'icalcomp'. - That meant it wasn't working at all well when an entire VCALENDAR - was passed in. - - * cal-util/cal-component.c: handle DURATION property used instead of - DTEND or DUE. In cal_component_get_dtend/due we will return DTSTART - + DURATION if necessary. In set_dtend/due we remove any DURATION - property. Fixes bug #11262. - - * gui/e-meeting-model.c (build_etable): - * gui/e-calendar-table.c (e_calendar_table_init): use U_ for the - ECellCombo popdown strings, as it expects UTF-8 strings. - -2001-10-24 JP Rosevear <jpr@ximian.com> - - * gui/e-meeting-time-sel.c (e_meeting_time_selector_construct): - track the spacer vbox - (e_meeting_time_selector_style_set): make sure the rows are the - correct size for the style - - * gui/e-meeting-time-sel-item.c - (e_meeting_time_selector_item_paint_day_top): slight adjustments - to where the text is drawn - - * gui/e-meeting-time-sel.h: new member - - * gui/e-meeting-model.c (build_etable): ensure uniform row height - - * conduits/todo/todo-conduit.c (comp_from_remote_record): mark - status as completed in appropriate places and don't overwrite - legitimate percentages and such - -2001-10-24 Federico Mena Quintero <federico@ximian.com> - - Fixes bug #5282. - - * cal-util/timeutil.c (icaltimetype_to_tm_with_zone): New function - to avoid copying the same code all over the place. - (icaltimetype_to_tm): Also set the tm.tm_wday. - - * gui/alarm-notify/alarm-queue.c (queue_midnight_refresh): Use - time_day_end_with_zone(). - (load_alarms_for_today): Likewise. And oops, we were only - computing the times and not loading the alarms. - (obj_updated_cb): Likewise. - (load_alarms): Removed assertion that is no longer valid because - we may load the alarms for a client in two stages. - - * gui/dialogs/alarm-page.c (get_alarm_string): Convert absolute - trigger times to the local timezone. - - * gui/alarm-notify/alarm-notify-dialog.c (write_html_heading): - Convert the times to the local timezone. - (alarm_notify_dialog): Likewise, for the window title. - (alarm_notify_dialog): Set the window layer to WIN_LAYER_ONTOP. - - * gui/e-cell-date-edit-text.c (ecd_get_text): Use - icaltimetype_to_tm_with_zone(). - - * gui/alarm-notify/save.c (get_config_db): Made public. - (discard_config_db): Made public. - - * gui/alarm-notify/config-data.[ch]: New files with functions to - fetch the calendar configuration data used by the alarm daemon. - -2001-10-23 Damon Chaplin <damon@ximian.com> - - * cal-util/cal-component.c (cal_component_event_dates_match): make sure - we free all the CalComponentDateTime's when we are finished. - - * gui/gnome-cal.c (gnome_calendar_notify_dates_shown_changed): just - return if no time range is set. - -2001-10-23 JP Rosevear <jpr@ximian.com> - - * gui/e-meeting-time-sel.c - (e_meeting_time_selector_table_vadjustment_changed): adjust the - display canvas when the table scrolls - (e_meeting_time_selector_construct): listen for table scrolling - -2001-10-23 JP Rosevear <jpr@ximian.com> - - * gui/e-meeting-model.c (build_etable): no longer set the - scrollbar policy here - - * gui/e-meeting-time-sel.c - (e_meeting_time_selector_update_main_canvas_scroll_region): add an - extra row to the height so the click to add row can be properly - seen - (e_meeting_time_selector_construct): set the scrollbar policy for - the etable scrolled - -2001-10-23 JP Rosevear <jpr@ximian.com> - - * cal-util/timeutil.c (icaltimetype_to_tm): convert an - icaltimetype to a tm - (tm_to_icaltimetype): vice versa - - * cal-util/timeutil.h: new protos - - * conduits/calendar/calendar-conduit.c: replace all mktime and - localtime calls (except for debugging calls) - - * conduits/todo/todo-conduit.c: ditto - (comp_from_remote_record): make sure the completed time is in UTC - -2001-10-23 Rodrigo Moya <rodrigo@ximian.com> - - * cal-client/cal-query.c (cal_query_construct) set priv->corba_query - to CORBA_OBJECT_NIL if there was an error - -2001-10-22 Damon Chaplin <damon@ximian.com> - - * idl/evolution-calendar.idl: added setDefaultTimezone() method. - - * pcs/cal-backend.c (cal_backend_get_default_timezone): - (cal_backend_set_default_timezone): new functions to call class - methods. - - * pcs/cal-backend-file.c: lots of changes to handle the default - timezone and use it. - - * pcs/query.c: use the default timezone. - - * gui/dialogs/task-details-page.c (date_changed_cb): initialized - completed_tt. - - * gui/dialogs/event-page.c: changed it to handle DATE values. The - 'All Day Event' checkbox is only set now when the DTSTART and DTEND - are DATE values. - - * gui/dialogs/comp-editor-util.c (comp_editor_free_dates): free the - CalComponentDateTime structs as well. - - * gui/e-tasks.c: set the default timezone on the server. - - * gui/tag-calendar.c: - * gui/gnome-cal.c: - * gui/e-week-view.c: - * gui/e-day-view.c: updates to handle DATE values. - - * gui/e-calendar-table.c (date_compare_cb): updated to use the new - ECellDateEditValue values, so it now works. - (percent_compare_cb): updated to use GPOINTER_TO_INT values. - (e_calendar_table_init): use an ECellPercent for the percent field - and an ECellDateEditText for the date fields. - - * gui/comp-util.c (cal_comp_util_compare_event_timezones): return TRUE - if the DTSTART or DTEND is a DATE value. We don't want to show the - timezone icons for DATE values. - - * gui/comp-editor-factory.c (resolve_pending_requests): set the default - timezone on the server. - - * gui/calendar-model.c: major changes to support sorting properly. - For date and percent fields we now use subclasses of ECellText, so - we don't use a char* as the model value. For the percent field we now - use a GINT_TO_POINTER. For the date fields we now use a - ECellDateEditValue* as the value. - - * gui/calendar-config.c (calendar_config_configure_e_cell_date_edit): - set the timezone and use_24_hour flags of the new ECellDateEditText. - - * conduits/todo/todo-conduit.c (pre_sync): - * conduits/calendar/calendar-conduit.c (pre_sync): set the default - timezone on the server. - - * cal-util/timeutil.c (time_days_in_month): removed debug message. - - * cal-util/test-recur.c: try to handle timezones in the iCalendar - file properly, and updated to pass default timezone. - - * cal-util/cal-util.c (cal_util_generate_alarms_for_comp): - (cal_util_generate_alarms_for_list): added default timezone argument. - - * cal-util/cal-recur.c: changed many of the functions to take a default - timezone, to use to resolve DATE and floating DATE-TIME values. - - * cal-client/cal-client.c (cal_client_set_default_timezone): new - function to set the default timezone. - (cal_client_ensure_timezone_on_server): new function to ensure that - a given timezone is on the server. - - * gui/e-cell-date-edit-text.c: new subclass of ECellText to display - and edit a date value. - - * cal-util/cal-recur.c (cal_obj_byday_expand_monthly): changed week_num - to -week_num when calculating the weeks to go back from the end of the - month for things like BYDAY=-2WE. Fixes bug #11525. - (cal_recur_generate_instances_of_rule): only go up to MAX_YEAR (2037). - We can't really handle anything past that anyway. - (cal_recur_ensure_rule_end_date): initialize cb_date.end_date to 0, - so if the RULE doesn't generate COUNT instances we save 0 as the - time_t. - -2001-10-22 Federico Mena Quintero <federico@ximian.com> - - * gui/tasks-control-factory.c (tasks_control_factory_fn): Put up a - warning dialog box if we failed to create the tasks control. - Fixes bug #13033. - -2001-10-22 JP Rosevear <jpr@ximian.com> - - * gui/e-itip-control.c (set_date_label): write out the correct - time in the control - - * pcs/cal.c (build_fb_seq): utility function to build sequences of - f/b data - (impl_Cal_get_free_busy): use above so we never return a NULL - - * conduits/calendar/calendar-conduit-config.h - (calconduit_save_configuration): fix c/p error - (calconduit_load_configuration): ditto - -2001-10-22 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/meeting-page.c (meeting_page_destroy): we don't need - to save the state - - * gui/e-meeting-time-sel.c (e_meeting_time_selector_destroy): - ditto - - * gui/e-meeting-model.c (build_etable): listen for the etable - being destroyed - (table_destroy_cb): save the state when the etable is destroyed - -2001-10-21 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/schedule-page.c (init_widgets): listen for changes - in the date editors - (schedule_page_set_dates): update the times when they change - elsewhere - (update_time): set the time in the dialog - (time_changed_cb): notify of changed times - - * gui/dialogs/comp-editor.c (page_dates_changed_cb): don't call - the set dates function on the page that noted the change - (page_summary_changed_cb): same for set summary function - - * gui/dialogs/event-page.c (update_time): move time setting stuff - to util function - (event_page_set_dates): use it - (event_page_fill_component): ditto - - * gui/e-meeting-time-sel.h: fix comment - -2001-10-19 Federico Mena Quintero <federico@ximian.com> - - * gui/alarm-notify/alarm-notify.c (add_uri_to_load): Do not assert - if we fail to load the URI list. This would of course have been a - bonobo-conf activation problem. - (remove_uri_to_load): Likewise. - - * gui/alarm-notify/notify-main.c (load_calendars): Likewise. - - * gui/alarm-notify/alarm-queue.c (load_missed_alarms): Make the - time range half-open so that we do not display the last alarm - twice. - -2001-10-19 Rodrigo Moya <rodrigo@ximian.com> - - * gui/calendar-model.c (calendar_model_set_status_message): make - it a public function - - * gui/e-tasks.c (e_tasks_open): display progress messages - (cal_opened_cb): clean up status bar messages - - * gui/gnome-cal.c (gnome_calendar_open): display progress messages - (client_cal_opened_cb): clean up status bar messages - -2001-10-19 Rodrigo Moya <rodrigo@ximian.com> - - * gui/calendar-model.c (set_status_message): new function - (update_query): call set_status_message - (query_query_done_cb): - (query_eval_error_cb): clean up status bar messages - (get_location, set_location): new functions for setting and - retrieving the location in the calendar model - -2001-10-19 Rodrigo Moya <rodrigo@ximian.com> - - * gui/component-factory.c (owner_set_cb): keep a reference to the - EvolutionShellClient component - - * gui/e-week-view.c (e_week_view_set_status_message): new function - (update_query): call e_week_view_set_status_message - (query_query_done_cb): - (query_eval_error_cb): clean up status bar messages - - * gui/e-day-view.c (e_day_view_set_status_message): new function - (update_query): call e_day_view_set_status_message - (query_query_done_cb): - (query_eval_error_cb): clean up status bar messages - - * gui/Makefile.am: added EVOLUTION_IMAGESDIR to CFLAGS - -2001-10-18 JP Rosevear <jpr@ximian.com> - - * gui/e-meeting-time-sel.c - (e_meeting_time_selector_on_invite_others_button_clicked): call - the invite others dialog in the model - - * gui/e-meeting-attendee.c (e_meeting_attendee_get_atype): pick - attendee type based on role and cutype - - * gui/e-meeting-attendee.h: remove proto - - * gui/Makefile.am: compile select names idl - - * gui/e-meeting-model.h: new proto - - * gui/dialogs/meeting-page.c: remove invite others dialogs bits - from here - - * gui/e-meeting-model.c (e_meeting_model_invite_others_dialog): - and put them here - - * gui/dialogs/Makefile.am: compile corba bits in parent dir - - * gui/dialogs/comp-editor-util.h: reflect above in includes - - * gui/dialogs/e-delegate-dialog.c: ditto - - * gui/dialogs/schedule-page.c: ditto and clean includes - -2001-10-18 Larry Ewing <lewing@ximian.com> - - * gui/alarm-notify/alarm-notify-dialog.c: add html widget - (url_requested_cb): add function to load images from file as they - are requested. - (write_html_heading): convert to using html. - (alarm_notify_dialog): convert to use html display. - (make_html_display): this is the function the custom widget in the - galde file uses to create the html widget. - - * gui/alarm-notify/alarm-notify.glade: add placeholder for the - custom html widget. - - * gui/alarm-notify/Makefile.am: add flags for gtkhtml and gal. - -2001-10-18 Federico Mena Quintero <federico@ximian.com> - - Adds session management for the alarm daemon. Also makes it store - a list of calendars to be monitored. Those calendars will all be - loaded when the alarm daemon starts up. - - * idl/evolution-calendar.idl (AlarmNotify): Removed the ::die() - method. The alarm daemon now handles termination via the session - manager's commands. - - * gui/alarm-notify/notify-main.c (set_session_parameters): New - function, sets some parameters so that the session manager can - restart the daemon via the evolution-alarm-client program. Also, - sets up the "die" signal so that the daemon can terminate when the - session ends. - (load_calendars): New function to load the calendars on startup. - (main): Set the session parameters. Load the calendars on startup. - - * gui/alarm-notify/alarm-notify.c (alarm_notify_add_calendar): New - function, moved over from the impl_ function. Added a - load_afterwards argument to indicate whether the calendar should - just be loaded or if it should also be added to the list of - calendars to load on startup. - (AlarmNotify_addCalendar): Use alarm_notify_add_calendar(). - (AlarmNotify_removeCalendar): Remove the calendar from the list of - calendars to load on startup. - - * gui/alarm-notify/save.c (save_calendars_to_load): New function, - saves a sequence of the URIs to load. - (get_calendars_to_load): New function, loads a sequence of - calendars to load. - - * gui/alarm-notify/alarm.h: Removed stale prototype for alarm_init(). - - * gui/component-factory.c (remove_folder): Ask the alarm daemon to - stop monitoring alarms for the folder that is being deleted. - -2001-10-18 JP Rosevear <jpr@ximian.com> - - * gui/e-meeting-time-sel.c - - * gui/e-meeting-time-sel-item.c - (e_meeting_time_selector_item_paint_day_top): use 12 or 24 hour - settings - - * gui/e-meeting-time-sel.c: strings for 12 hour setting - (e_meeting_time_selector_construct): increase width slightly - - * gui/e-meeting-time-sel.h: extern the new char array - -2001-10-18 Rodrigo Moya <rodrigo@ximian.com> - - * cal-util/cal-component.[ch] (cal_component_get_location): - (cal_component_set_location): new functions - -2001-10-18 JP Rosevear <jpr@ximian.com> - - * gui/e-meeting-model.c (process_callbacks): util routine to - handle calling back - (async_close): use above - (e_meeting_model_refresh_busy_periods): ditto - -2001-10-17 JP Rosevear <jpr@ximian.com> - - * conduits/todo/todo-conduit.c (local_record_from_comp): translate - 1-5 priorites to 1-9 priorities better - (comp_from_remote_record): ditto - -2001-10-17 JP Rosevear <jpr@ximian.com> - - * idl/evolution-calendar.idl: allow some decent exceptions - -2001-10-17 Rodrigo Moya <rodrigo@ximian.com> - - * pcs/query.c (match_component): there may be cases when the backend - will return an invalid component from a valid UID (an UID returned - by the get_uids method), so don't abort if that's the case - -2001-10-15 Damon Chaplin <damon@ximian.com> - - * gui/dialogs/cal-prefs-dialog.glade: removed Help button. Do we have - any others? - -2001-10-15 Larry Ewing <lewing@ximian.com> - - * gui/dialogs/comp-editor.c (set_icon_from_comp): remove warnings. - -2001-10-15 JP Rosevear <jpr@ximian.com> - - * conduits/calendar/calendar-conduit.c (process_multi_day): - function to break up multi day events into single events for both - evo and the pilot and create new CalClientChange structures - (pre_sync): call above function, and adjust changed list if - necessary - -2001-10-15 JP Rosevear <jpr@ximian.com> - - * conduits/calendar/calendar-conduit.c (is_all_day): util function - to determine if event is all day - (local_record_from_comp): use new util function - (comp_from_remote_record): kill use of deprecated time functions - -2001-10-13 Larry Ewing <lewing@ximian.com> - - * gui/dialogs/comp-editor.c (real_edit_comp): call - set_icon_from_comp. - (set_icon_from_comp): set the window icon from the comp. - (make_icon_from_comp): get the icon path based on comp type. - - * gui/dialogs/Makefile.am (iconsdir): EVOLUTION_ICONSDIR bits. - -2001-10-13 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/task-editor.c (task_editor_send_comp): send - cancellation comp if necessary - -2001-10-12 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/alarm-page.c: return fill_component success - - * gui/dialogs/task-page.c: ditto - - * gui/dialogs/task-details-page.c: ditto - - * gui/dialogs/schedule-page.c: ditto - - * gui/dialogs/recurrence-page.c: ditto - - * gui/dialogs/event-page.c: ditto - - * gui/dialogs/meeting-page.c: use e_notice instead of - duplicate_error - (meeting_page_get_cancel_comp): duh, deleted_attendees is an array - now - (meeting_page_fill_component): spew gui errors if there is no - organizer or no attendees, return success - - * gui/dialogs/event-editor.c (event_editor_send_comp): always call - parent method and don't send the cancellation comp if the method - is publish - (refresh_meeting_cmd): use the orginal comp to refresh - (forward_cmd): prompt the user for the version they want to send - (current, original) - - * gui/dialogs/task-editor.c (forward_cmd): as above - (refresh_task_cmd): ditto - - * gui/dialogs/comp-editor-page.c - (comp_editor_page_fill_component): return boolean of whether the - component could be filled or not - - * gui/dialogs/comp-editor-page.h: update proto - - * gui/dialogs/comp-editor.c (prompt_to_save_changes): take a param - on whether to try and send or not - (comp_editor_get_current_comp): only fill component if its changed - (comp_editor_save_comp): prompt user as well - - * gui/dialogs/comp-editor.h: change proto - - * gui/itip-utils.c: replace error_dialog with e_notice - (comp_content_type): specify charset - -2001-10-11 Larry Ewing <lewing@ximian.com> - - * gui/e-itip-control.c: large reworking of i18n tagging and now - uses gtk_html_stream write and U_ where appropriate. More to - come. - -2001-10-10 Larry Ewing <lewing@ximian.com> - - * gui/e-itip-control.c (init): set the default character set to - utf-8. - -2001-10-10 Federico Mena Quintero <federico@ximian.com> - - * pcs/cal-factory.c (lookup_backend): Return the original key in - the hash table if requested. - (backend_last_client_gone_cb): Use lookup_backend() so that we - have the URI mangling done for us. - (impl_CalFactory_open): The type should be GtkType *, not GtkType! - -2001-10-10 JP Rosevear <jpr@ximian.com> - - * cal-client/cal-client.c (cal_set_mode_cb): remove unneeded - assertions - -2001-10-10 JP Rosevear <jpr@ximian.com> - - * pcs/cal-factory.c (add_uri): fix logic checks - - * gui/dialogs/event-editor.c (event_editor_init): init the - exisiting_org boolean - (set_menu_sens): base sensitivity on existing_org boolean - (event_editor_edit_comp): set exisiting_org boolean - - * gui/dialogs/task-editor.c: same as above - - * gui/calendar-offline-handler.c (add_connection): handle the - protocol or host being unknown - - * cal-util/cal-component.c (cal_component_has_organizer): - implement - -2001-10-09 Federico Mena Quintero <federico@ximian.com> - - Fixes bug #884. - - * gui/alarm-notify/save.[ch]: New files with functions to - save/load the last notification time. - - * gui/alarm-notify/alarm-queue.c (alarm_trigger_cb): Save the last - notification time. - (alarm_queue_init): Load the last notification time when the - daemon is inited. - (alarm_queue_add_client): Load the alarms that we missed while the - alarm daemon was not running. - (cal_opened_cb): Likewise. - - * gui/alarm-notify/Makefile.am (evolution_alarm_notify_SOURCES): - Added save.[ch] to the list of sources. - -2001-10-09 JP Rosevear <jpr@ximian.com> - - * gui/itip-utils.c (get_address): util function to get address - (itip_addresses_get_default): get only the default address - (itip_address_free): free single address - (itip_addresses_free): use above - (comp_limit_attendees): limit the number of attendees to one, the - user - (comp_sentby): set the sentby parameter if the user is not the - organizer - (comp_minimal): remove extraneous info for send (for refresh and - declinecounter) - (comp_compliant): remove all alarms, do various things to make the - components comply with itip spec based on method - (itip_send_comp): use comp_compliant method - - * gui/itip-utils.h: new protos - - * gui/e-itip-control.c: rescan the component when necessary - (get_next): don't get stuck in infinite loop if there are no - viewable components - (e_itip_control_set_data): if there are no viewable components, - spit an error message - - * gui/dialogs/meeting-page.h: tidy - - * gui/dialogs/meeting-page.c (meeting_page_fill_widgets): use - organizer's cn if possible - (other_clicked_cb): no longer doing the sent by stuff directly, - hide more widgets - - * pcs/query.c: use bonobo exception stuff - - * cal-util/cal-component.c (cal_component_rescan): have the comp - rescan its libical component (for when you change things directly) - (free_icalcomponent): take a param on whether to free the - component or just clean up the mappings - (cal_component_has_attendees): util function - - * cal-util/cal-component.h: new protos - -2001-10-09 Rodrigo Moya <rodrigo@ximian.com> - - * pcs/cal-factory.c (lookup_backend, add_backend): deal correctly with - URIs to be inserted into the hash table, so that we don't add the same - backend over and over because the URI strings were different (although - refering to the same backend) - - * pcs/cal-backend-file.c (mail_account_*): moved to a common place - (cal_backend_file_open): check if "uristr != NULL" and not - "uri != NULL" - - * pcs/cal-backend-util.c: moved to here - - * gui/e-day-view.c: add missing header file - -2001-10-09 Dan Winship <danw@ximian.com> - - * gui/e-meeting-model.c (process_free_busy_comp): Fix incorrect - variable name check. - -2001-10-03 JP Rosevear <jpr@ximian.com> - - * gui/itip-utils.c (itip_send_comp): refactor functionality into - several function - (comp_string): if we are publishing, empty the attendee list - - * gui/dialogs/event-editor.c (schedule_meeting_cmd): when we - schedule a new meeting, mark the event editor as changed - - * pcs/cal.c (cal_class_init): get correct parent class - - * gui/dialogs/comp-editor.c (comp_editor_merge_ui): use the - generated ui component name - -2001-10-03 Rodrigo Moya <rodrigo@ximian.com> - - * gui/component-factory.c: - * gui/calendar-offline-handler.c: - * gui/comp-editor-factory.c: replace use of gnome_vfs_uri with e_uri - - * gui/e-meeting-model.c (start_addressbook_server): make it return void, - since the return value does not mind - - * pcs/cal.c: - * pcs/cal-factory.c: - * pcs/cal-backend.[ch]: don't use GnomeVFS for URI management - - * pcs/cal-backend-file.c: ditto, only use GnomeVFS for internal - operations - - * cal-client/cal-client.c (cal_client_open_calendar): don't CORBA_exception_free - before checking for exceptions - -2001-10-03 Christopher James Lahey <clahey@ximian.com> - - * gui/e-calendar-table.etspec: Added priorities to a bunch of - these columns. Fixes Ximian bug #7158. - -2001-10-03 Damon Chaplin <damon@ximian.com> - - * gui/comp-util.c (cal_comp_util_add_exdate): save the EXDATE as a - DATE-TIME value, since we know the exact time. Fixes bug #11278. - (Before we were setting is_date, but icaltime_from_timet_with_zone() - didn't convert it properly. We need to figure out how to handle DATEs - when using time_t's.) - - * gui/dialogs/recurrence-page.c (get_exception_string): use - e_time_format_date_and_time() so we show the time as well, if the - exception is a DATE-TIME value. - - * cal-util/timeutil.c: removed time_add_month(), time_year_begin(), - time_month_begin() & time_week_begin() - old pre-timezone functions - which we no longer use. - - * cal-util/cal-recur.c (cal_recur_from_icalproperty): set - ir.until.is_date to FALSE before converting to a time_t. - Hopefully fixes bug #5034. - -2001-10-02 Ettore Perazzoli <ettore@ximian.com> - - * gui/dialogs/comp-editor.c (setup_widgets): Use - `bonobo_ui_component_new_default()', not - `bonobo_ui_component_new()'. - -2001-10-02 JP Rosevear <jpr@ximian.com> - - * cal-client/cal-query.c: use bonobo-exception to tidy - -2001-10-02 JP Rosevear <jpr@ximian.com> - - * conduits/calendar/calendar-conduit.c (nth_weekday): handle -1 as - well - (comp_from_remote_record): fix monthly by day recurrences and - handle "last" day type - -2001-10-01 Damon Chaplin <damon@ximian.com> - - * gui/dialogs/comp-editor.c (comp_editor_destroy): unref the page - objects here, instead of in close_dialog(). (This was fixed a while - ago, but accidentally reverted.) Fixes bug #7543. - -2001-10-01 Federico Mena Quintero <federico@ximian.com> - - * gui/alarm-notify/alarm-notify-dialog.c (alarm_notify_dialog): - Set the window state to sticky. Thanks to Peter Teichman for the - suggestion. - -2001-10-01 JP Rosevear <jpr@ximian.com> - - * conduits/calendar/calendar-conduit.c (local_record_from_comp): - Convert the comp exceptions to the pilot record - (comp_from_remote_record): record exceptions on the desktop and - use time zone stuff on recurrence end date - -2001-10-01 JP Rosevear <jpr@ximian.com> - - * pcs/cal-backend-file.c (cal_backend_file_compute_changes): - strdup the uid to avoid double free, write out only after - everything is done - -2001-10-01 Rodrigo Moya <rodrigo@ximian.com> - - * gui/gnome-cal.c (gnome_calendar_open): don't use - gnome_vfs_uri_is_local on URIs created with - gnome_vfs_uri_new_private - -2001-09-28 Damon Chaplin <damon@ximian.com> - - * gui/print.c (print_comp_item): use bound_text to print the summary, - so it wraps instead of being clipped to 1 line. Fixes part 3 of bug - #10285, I think. - - * gui/dialogs/alarm-page.glade: left-aligned the Date/Time label. - Also set the width of the Summary & Date/Time labels to 10, and set - expand to TRUE, to make sure that the dialog doesn't keep getting - wider as the summary text on the main page gets longer. Could possibly - use an EClippedLabel here instead, so we get a '...' at the end if it - is clipped. - - * gui/dialogs/recurrence-page.glade: changed Summary & Date/Time - widths as above. - - * gui/print.c (print_calendar): use landscape mode for the month - preview. - (print_border_with_triangles): use EPSILON to account for floating - point errors. Hopefully fixes part 2b of bug #10285. - -2001-09-28 JP Rosevear <jpr@ximian.com> - - * conduits/calendar/calendar-conduit.c (local_record_from_comp): - Handle the fields and category we don't sync by making sure we - don't overwrite them - (local_record_to_pilot_record): use local record category - (pre_sync): track db info - - * conduits/calendar/calendar-conduit.h: db info field - - * conduits/todo/todo-conduit.[hc]: same as above - - * pcs/cal-backend-file.c - (cal_backend_file_compute_changes_foreach_key): create a dummy - component of the right type and strdup the uid - (cal_backend_file_compute_changes): sync the db hash after each - change and free the uid - -2001-09-28 JP Rosevear <jpr@ximian.com> - - * cal-client/cal-client.c (cal_client_open_calendar): init the - execption rather than freeing it - -2001-09-28 Rodrigo Moya <rodrigo@ximian.com> - - * cal-client/cal-client.c (cal_client_construct): use bonobo-exception - for exceptions - (cal_client_open_calendar): likewise - -2001-09-27 Ettore Perazzoli <ettore@ximian.com> - - * gui/calendar-commands.c (pixmaps): Update pixmap menu paths; - /menu/ComponentToolsPlaceholder/Tools -> - /menu/Tools/ComponentPlaceholder . - * gui/tasks-control.c: Likewise. - -2001-09-27 Rodrigo Moya <rodrigo@ximian.com> - - * idl/evolution-calendar.idl: added InvalidURI and UnsupportedMethod - exceptions to the CalFactory interface - - * pcs/cal-factory.c (impl_CalFactory_open): raise InvalidURI exception on - URI errors and UnsupportedMethod when we don't support the method for - a given URI - -2001-09-26 Rodrigo Moya <rodrigo@ximian.com> - - * cal-client/cal-client.c: added support for using multiple calendar - factories - (cal_client_uri_list): use the list of factories loaded for this - CalClient - -2001-09-26 Damon Chaplin <damon@ximian.com> - - * gui/e-calendar-table.c (date_compare_cb): - (percent_compare_cb): - (priority_compare_cb): added comparison functions for these special - cell types. But the date and percent ones don't work yet due to the - use of static text buffers for return cell values. - (e_calendar_table_init): added the comparison functions to the - ETableExtras. NOTE: task_compare_cb() never seems to be called. - I'm not sure why it is there. - - * gui/e-calendar-table.etspec: set the comparison function names for - the date/percent/priority fields. - - * cal-util/cal-util.c (cal_util_priority_to_string): - (cal_util_priority_from_string): new utility functions. - - * gui/calendar-model.c (get_priority): - (set_priority): used above utility functions, and removed the warning - dialog which isn't useful now that the field isn't editable. - - * gui/dialogs/event-page.c (times_updated): handle timezones and for - all-day events make sure it stays an all-day event after adjusting. - Fixes bugs #5945 and #10222. - - * gui/calendar-commands.c (pixmaps): fixed the E_PIXMAP paths - the - edit items were moved beneath 'EditPlaceholder'. This gets rid of - those long Bonobo warnings! (and we get the icons back) - - * gui/dialogs/comp-editor.c (pixmaps): removed the PrintPreview toolbar - icon, since it doesn't appear in the xml file. Gets rid of warning. - - * gui/dialogs/event-page.c (notify_dates_changed): new function to - emit the notification signal when the dates are changed. It also - handles timezones now. - - * gui/dialogs/comp-editor-page.h (CompEditorPageDates): used - CalComponentDateTime for start/end/due so we have the timezone as well - as the time. - - * gui/dialogs/comp-editor-util.c (comp_editor_dates): updated to get - the timezones as well as the times. - (comp_editor_free_dates): new function needed to free all the structs. - - * gui/dialogs/recurrence-page.c (recurrence_page_set_dates): added call - to preview_recur() to make sure the preview gets updated. - - * gui/dialogs/alarm-page.c (alarm_page_fill_widgets): free the - CompEditorPageDates struct after use. - - * gui/tag-calendar.c (tag_calendar_by_comp): added 'comp_is_on_server' - argument. If FALSE, we try to use builtin timezones first. This is - needed for the recurrence page of the event editor, because the - timezones may not have been added to the server yet. This and the - changes to the notification stuff should fix bug #5034. - - * gui/gnome-cal.c (dn_query_obj_updated_cb): call above - tag_calendar_by_comp() with TRUE since the events will be on the - server in this case. - - * gui/e-day-view-layout.c: - * gui/e-day-view.c: made sure an event always takes up at least one - row, even when the start & end times are the same. Fixes bug #5944. - I don't know if we should try to also handle events with the end time - before the start time. - - * gui/e-week-view.c (e_week_view_style_set): check that the small font - is actually smaller than the normal font. If it isn't, don't use it. - Hopefully fixes bug #6876. - (e_week_view_on_new_appointment): if only one day is selected, then - we set the initial time of the event to 1/2-hour from the start of the - working day, to differentiate 'New Appointment' from 'New All Day - Event'. Fixes bug #8892. - - * gui/e-day-view.c (e_day_view_on_new_appointment): do the same as the - above. - -2001-09-26 Federico Mena Quintero <federico@ximian.com> - - Fixes the GUI part of bug #7892. - - * gui/dialogs/alarm-page.c (get_alarm_duration_string): Return - NULL if the duration is zero. - (get_alarm_string): Handle duration of zero. Also, hopefully - make the strings be more l10n-friendly. - - * gui/alarm-notify/alarm.c (alarm_ready_cb): I am a moron. Fix - reversed test. - -2001-09-26 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/comp-editor.c (comp_editor_destroy): disconnect - signals first thing - -2001-09-26 Dan Winship <danw@ximian.com> - - * gui/Makefile.am (evolution_calendar_LDFLAGS): Add - -export-dynamic to make glade custom widgets work on non-Linux. - -2001-09-26 Rodrigo Moya <rodrigo@ximian.com> - - * cal-util/cal-util.h: added CAL_MODE_INVALID to CalMode enum - -2001-09-26 JP Rosevear <jpr@ximian.com> - - * pcs/cal.h: new proto - - * pcs/cal.c (impl_Cal_set_mode): implement set mode method - (cal_class_init): set setMode function in epv - (cal_notify_mode): notify listener of mode change - - * pcs/cal-factory.c (add_uri): deal with UriType renaming - - * pcs/cal-backend.h: add new virtual methods and protos - - * pcs/cal-backend.c (cal_backend_class_init): init new virtual - methods to null - (cal_backend_set_mode): sets mode - (cal_backend_get_mode): gets mode - - * pcs/cal-backend-file.c (cal_backend_file_class_init): overide - get_mode and set_mode methods - (cal_backend_file_get_mode): return mode - (notify_mode): have listeners notified of the set mode call - (cal_backend_file_set_mode): set the mode by indicating not - supported - - * cal-client/cal-listener.h: update proto - - * cal-client/cal-listener.c (impl_notifyCalSetMode): implement set - mode callback - (cal_listener_construct): take set mode callback - (cal_listener_new): ditto - - * cal-client/cal-client.h: update protos, add signal proto - - * cal-client/cal-client.c (cal_client_class_init): add - cal_set_mode signal - (cal_set_mode_cb): handle set mode callback from listener - (cal_client_open_calendar): pass additional param to cal_listener_new - (cal_client_set_mode): wrapper to set the calendar mode - - * idl/evolution-calendar.idl: make UriType into CalMode, add - SetModeStatus enum and notifyCalSetMode method to the listener - - * gui/calendar-offline-handler.c (create_connection_list): fetch - the uri list ourselves - (impl_prepareForOffline): reflect param change of - create_connect_list - (update_offline): ditto - (backend_cal_set_mode): set mode call back - (backend_cal_opened): cal opened call back, set mode to local - (impl_goOffline): reflect UriType renaming - - * cal-util/cal-util.h: rename UriType to CalMode - -2001-09-25 Federico Mena Quintero <federico@ximian.com> - - Warning fixes courtesy of Chris Lahey <clahey@ximian.com>. - - * gui/e-itip-control.c (write_html): Warning fixes. Also, don't - strdup() more than necessary. - - * gui/e-meeting-time-sel.c (e_meeting_time_selector_refresh_cb): - Warning fixes. - - * gui/itip-utils.c (itip_addresses_get): Warning fixes. - - * gui/print.c (print_day_background): Warning fixes. - - * gui/dialogs/alarm-options.c (alarm_to_aalarm_widgets): Warning - fixes. - (alarm_to_palarm_widgets): Likewise. - - * gui/dialogs/delete-comp.c: #include "../calendar-config.h" - -2001-09-25 Federico Mena Quintero <federico@ximian.com> - - * gui/alarm-notify/alarm.c (alarm_ready_cb): Check that the - timeout is not set up before we create a new one; the alarm_fn - callback may cause the alarm system to re-enter and add a new - alarm. Fixes bug #10840. - (pop_alarm): Assert that there is at least one alarm in the queue. - -2001-09-25 JP Rosevear <jpr@ximian.com> - - * pcs/cal.c: use bonobo-exception stuff to clean code - - * pcs/cal-factory.c (add_uri): add uri to the list if the type - matches - (impl_CalFactory_uriList): implement uriList method - - * pcs/cal-backend.h: new virtual function member - - * pcs/cal-backend.c (cal_backend_is_remote): call virtual function - - * pcs/cal-backend-file.c (cal_backend_file_class_init): override - virtual function - (cal_backend_file_is_remote): new virtual function, always return - FALSE - - * idl/evolution-calendar.idl: uriList factory call, with flags for - types to get - - * gui/dialogs/comp-editor.c (comp_editor_destroy): cast to remove - warning - - * gui/e-itip-control.c (write_label_piece): kill warnings by take - const char * - - * gui/component-factory.c (create_object): aggregate offline - interface - - * gui/Makefile.am: compile new files - - * calobj.[hc]: Remove obsolete files - - * cal-util/cal-util.h: enum URI types for uriList call - - * cal-client/cal-client.c (build_uri_list): build list from string - sequence - (cal_client_uri_list): factory call to get uri list - - * cal-client/cal-client.h: new proto - - * cal-client/cal-client.c: use bonobo exception stuff to clean - code - - * gui/calendar-offline-handler.[hc]: Start some skeleton routines - for online/offline handling - - * pcs/cal-factory.c (launch_backend_for_uri): use accessor and - remove FIXME - -2001-09-23 JP Rosevear <jpr@ximian.com> - - * gui/e-itip-control.c (set_date_label): base text on component - type - -2001-09-20 Rodrigo Moya <rodrigo@ximian.com> - - * gui/component-factory.c: don't use gnome_vfs_uri_new_private - (fixes Ximian #10544) - -2001-09-20 Federico Mena Quintero <federico@ximian.com> - - * gui/component-factory.c: #include a few files we were missing - from libgnomevfs. - -2001-09-20 JP Rosevear <jpr@ximian.com> - - * pcs/cal-backend-file.c (load_db): gets a config db - (cal_backend_file_destroy): release config db - (cal_backend_file_init): use load_db - (mail_account_get): gets a mail account by number - (mail_account_get_default): gets the default mail account - (mail_account_is_valid): looks to see if any accounts have the - given address - (create_user_free_busy): modularize so we can call multiple times - if necessary, set organizer - (cal_backend_file_get_free_busy): if the list of users is null, - use the default account otherwise get the same info for each - address that is an identity in the mailer - - * gui/itip-utils.c (itip_addresses_get): s/gint/glong/ for bonobo - conf returns - - * gui/calendar-commands.c (publish_freebusy_cmd): fix problems - from a merge so that we publish 6 weeks of free/busy information - again - -2001-09-20 Larry Ewing <lewing@ximian.com> - - * gui/dialogs/recurrence-page.c (recurrence_page_destroy): make - sure to release the ref on priv->comp. - - * gui/dialogs/comp-editor.c (real_edit_comp): make sure to release - the ref on priv->comp. - -2001-09-19 Federico Mena Quintero <federico@ximian.com> - - * gui/alarm-notify/alarm-queue.c (audio_notification): Display a - notification message always, in addition to playing the sound. - (procedure_notification): Present a confirmation dialog before - actually running the alarm's program. - (procedure_notification): Use gnome_execute_shell() instead of - gnome_execute_async() so that we handle multiple arguments - properly. Plus, it is most likely what the user expects. - (mail_notification): Display a message about unsupported email - reminders instead of blindly dropping the alarm. - - * gui/dialogs/alarm-options.glade: Added an explanatory message - about mail alarms not being supported. - - * gui/dialogs/alarm-page.glade: Removed the "Send an email" - option. - - * gui/dialogs/alarm-page.c (action_map): Removed CAL_ALARM_EMAIL. - -2001-09-19 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/task-editor.c (init_widgets): listen for model - changes - (task_editor_edit_comp): add the attendees to the model and notify - of need send - (row_count_changed_cb): mark as changed when row added/deleted - (model_row_changed_cb): mark as changed when row changes - - * gui/dialogs/event-editor.c (init_widgets): listen for model - changes - (event_editor_init): flip page order - (event_editor_edit_comp): set needs send value - (schedule_meeting_cmd): flip page order - (row_count_changed_cb): mark as changed when row added/deleted - (model_row_changed_cb): mark as changed when row changes - - * gui/dialogs/schedule-page.c: remove model change notification - stuff - (schedule_page_fill_widgets): no need to do the needs_send here - because the editor handles this since it owns the model - - * gui/dialogs/event-editor.c (init_widgets): listen for model - changes - (event_editor_init): flip page order - (event_editor_edit_comp): set needs send value - (schedule_meeting_cmd): flip page order - (row_count_changed_cb): mark as changed when row added/deleted - (model_row_changed_cb): mark as changed when row changes - - * gui/dialogs/meeting-page.c (meeting_page_fill_widgets): no need - to do the needs_send here because the editor handles this since it - owns the model - (invite_entry_changed): ditto - - * gui/dialogs/comp-editor.c (comp_editor_set_changed): new - accessor - (comp_editor_get_changed): ditto - (comp_editor_set_needs_send): ditto - (comp_editor_get_needs_send): ditto - - * gui/dialogs/comp-editor.h: new protos - - * gui/itip-utils.c (itip_addresses_get): reflect configuration - path changes in the mailer - - * gui/e-meeting-model.c: remove commented out code, ifdef one - section for later - -2001-09-19 Rodrigo Moya <rodrigo@ximian.com> - - * pcs/cal-factory.c (cal_factory_oaf_register): add a new parameter - (const char *iid) to specify the OAFIID of the factory being - registered - -2001-09-19 JP Rosevear <jpr@ximian.com> - - * gui/e-meeting-model.c (e_meeting_model_refresh_busy_periods): - remove silly debug #if 0 - - * gui/calendar-commands.c (publish_freebusy_cmd): g_list_free - rather than g_free - - * gui/e-itip-control.c (write_html): eliminate code path that - caused double freed memory - -2001-09-18 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/schedule-page.*: A page that shows the meeting time - selector and free/busy data for attendees - - * gui/dialogs/meeting-page.c: use the meeting model to track/edit - attendees, remove table value conversion routines and simple table - routines - (set_attendees): take a pointer array - (meeting_page_destroy): destroy the pointer array, save state - (meeting_page_init): new pointer array - (meeting_page_fill_widgets): don't null the deleted attendees - field - (popup_delegate_cb): array add - (popup_delete_cb): array add - (cleanup_attendees): iterate over the array to unref now - (meeting_page_fill_widgets): don't null out fields, no need to add - attendees here - (invite_entry_changed): use e_meeting_attendee routines - (popup_delegate_cb): ditto - (popup_delete_cb): ditto - (meeting_page_new): take new arg and pass it to construct - (meeting_page_construct): take new arg, use e-meeting-model - routines to construct table - - * gui/dialogs/task-editor.c (task_editor_init): new meeting model - (task_editor_destroy): unref the model - - * gui/dialogs/event-editor.c (event_editor_init): make new model - and pass it to meeting and schedule pages - (event_editor_set_cal_client): virtual function, set meeting model - client - (event_editor_edit_comp): add the attendees to the model - (event_editor_destroy): unref model - - * gui/dialogs/comp-editor.h: add virtual function - * gui/dialogs/comp-editor.c (comp_editor_set_cal_client): make - set_cal_client a virutal function - - * gui/e-meeting-types.h: generally useful type defines - - * gui/e-meeting-time-sel*.[hc]: Move here and use an e-table for - the attendee list and extract display information from the new - meeting model and attendees - - * gui/e-meeting-time-sel.etspec: spec for the table - - * gui/e-meeting-attendee.[hc]: meeting attendees for the model, - with to/from conversions for CalComponentAttendee structure, emits - changed signal and allows getting and setting of free busy - periods - - * gui/e-meeting-model.[hc]: move the model out on its own - - * gui/e-itip-control.c (write_error_html): clean up warnings - -2001-09-18 Federico Mena Quintero <federico@ximian.com> - - Fixes bug #6350. - - * gui/component-factory.c (remove_folder): Use a simplified method - for removing our folder data; we just need to remove calendar.ics - or tasks.ics and the corresponding backup files. - -2001-09-18 Federico Mena Quintero <federico@ximian.com> - - Fixes bug #2830. - - * gui/calendar-config.c (calendar_config_get_confirm_delete): New - function. - (calendar_config_set_confirm_delete): New function. - (config_read): Get the default value for the ConfirmDelete option. - (calendar_config_write): Set the value of ConfirmDelete. - - * gui/dialogs/delete-comp.c (delete_component_dialog): Handle the - configuration option for confirmation. - - * gui/dialogs/cal-prefs-dialog.c (CalPrefsDialogPrivate): Added - the fields for the Other page. - (get_widgets): Handle the new widgets. - (cal_prefs_dialog_show_config): Likewise. - (cal_prefs_dialog_update_config): Likewise. - -2001-09-18 Rodrigo Moya <rodrigo@ximian.com> - - * cal-client/cal-client-multi.[ch]: new class for managing multiple - calendars, with an API very similar to the CalClient one, - for ease of transition from one to the other - - * gui/component-factory.c (xfer_folder, remove_folder, create_folder): - reworked to be able to manage folders for any calendar backend, and - not only the file: one - -2001-09-18 Rodrigo Moya <rodrigo@ximian.com> - - * idl/evolution-calendar.idl: changed signature for the getFreeBusy - method, to return a sequence of CalObj's, and added sequence of users - as a new parameter to that method - - * cal-client/cal-client.c (cal_client_get_free_busy): adapted to new - IDL method signature, by adding a new "GList *users" parameter, for - callers to be able to specify a list of users - - * pcs/cal-backend.[ch] (cal_backend_get_free_busy): - * pcs/cal-backend-file.c (cal_backend_file_get_free_busy): add the - "GList *users" parameter. In cal_backend_file_get_free_busy, call - lookup_component to get the CalComponent for each uid, instead - of calling cal_backend_get_object, which meant converting the - component to a string and then parsing it again. - - * cal-client/client-test.c (cal_opened_cb): - * gui/e-itip-control.c (send_freebusy): - * gui/calendar-commands.c (publish_freebusy_cmd): adapted to - new getFreeBusy method signature - -2001-09-17 Damon Chaplin <damon@ximian.com> - - * gui/calendar-model.c: added a timeout to refresh the list every - 10 minutes. Not ideal, as the user may be editing a task when it gets - refreshed. - (adjust_query_sexp): use the 'completed-before?' operator to filter - out tasks according to the config settings. - - * gui/dialogs/task-details-page.c (task_details_page_fill_widgets): - added support for the 'Completed' date. This code must have got lost - somewhere, as it used to work. - (date_changed_cb): set the priv->updating flag while updating the other - widgets. - - * pcs/cal-backend-file.c (cal_backend_file_update_objects): made sure - we freed the components. - - * pcs/query.c (func_completed_before): added 'completed-before?' - operator. - - * gui/calendar-config.c (calendar_config_configure_e_cell_date_edit): - don't set the lower & upper hour. Use 0-24 like the EDateEdit does. - - * gui/dialogs/cal-prefs-dialog.c (cal_prefs_dialog_show_config): set - the 12/24-hour time format options sensitive only if we support both. - - * gui/calendar-config.c (config_read): if the locale doesn't define - 'am' and 'pm' strings then we must use 24-hour format. - - * gui/calendar-commands.c (calendar_set_folder_bar_label): don't - translate the '%d' as it doesn't make much sense. Resolves bug #8027. - -2001-09-17 Federico Mena Quintero <federico@ximian.com> - - * gui/component-factory.c (owner_set_cb): Do not call - calendar_config_init() here. - - * gui/main.c (main): Call calendar_config_init() here. - -2001-09-17 Federico Mena Quintero <federico@ximian.com> - - * gui/alarm-notify/alarm.c (queue_alarm): Duh, only setup the - timeout if the list was empty. - (alarm_ready_cb): Notify with the ID of the original alarm. - (alarm_remove): Likewise. - -2001-09-17 Federico Mena Quintero <federico@ximian.com> - - Switch the alarm system from using SIGALRM to normal glib timers. - Also, use a more robust de-queueing mechanism. - - * gui/alarm-notify/alarm.c (alarm_init): Removed. - (alarm_done): Remove the glib timeout instead of closing the pipes - and the signal handler. - (alarm_add): Allow adding alarms that happen before right now. - (queue_alarm): Use a glib timer instead of a signal. - (alarm_remove): Adjust the timeout as appropriate. - - * gui/alarm-notify/notify-main.c (main): There is no need to - initialize the alarm system now. - - * gui/main.c (main): Likewise. - -2001-09-17 JP Rosevear <jpr@ximian.com> - - * gui/calendar-model.c (calendar_model_init): get itip addresses - (calendar_model_destroy): destroy same - (calendar_model_value_at): do more thorough checking on whether to - use recurring, assigned, assigned to or regular task icons - -2001-09-17 JP Rosevear <jpr@ximian.com> - - * cal-util/cal-component.c (for_each_remove_all_alarms): for each - call back, removes the alarms - (cal_component_remove_all_alarms): remove all alarms from the - component - - * cal-util/cal-component.h: new proto - - * gui/e-itip-control.c (write_error_html): writes error messages - rather than normal html - - * gui/itip-utils.c (itip_send_comp): remove all alarms if the - method warrants it - -2001-09-16 Christopher James Lahey <clahey@ximian.com> - - * gui/dialogs/meeting-page.c (build_etable): Updated this to match - the new ETableSimple interface. - -2001-09-14 Ettore Perazzoli <ettore@ximian.com> - - [Automake 1.5 fixes pointed out by Richard Boulton - <richard@tartarus.org>, as per #9258.] - - * cal-client/Makefile.am: Set CLEANFILES directly instead of using - `+='. - * gui/Makefile.am: Likewise. - * gui/alarm-notify/Makefile.am: Likewise. - * pcs/Makefile.am: Likewise. - -2001-09-14 Damon Chaplin <damon@ximian.com> - - * gui/e-itip-control.c (ok_clicked_cb): added space after 'identities' - in the message. Fixes bug #9896. - -2001-09-14 JP Rosevear <jpr@ximian.com> - - * conduits/calendar/e-calendar.conduit.in: remove translation - marker for now - -2001-09-13 JP Rosevear <jpr@ximian.com> - - * cal-util/cal-component.h: use ical partstat, role, cutypes - directly - - * cal-util/cal-component.c: ditto - - * gui/e-itip-control.c (find_my_address): set my addresses if the - addresses match - (find_attendee): strstr returns non-null on a match - (write_html): use new icon, select the name displayed (organizer - or attendee) based on method, - (ok_clicked_cb): when rsvp'ing strip off all but the attendee - being replied for as is specified in the spec - (find_attendee_partstat): new util function to extract the - partstat of an attendee - (update_attendee_status): updates the partstat of a specific - attendee in the reply message - - * gui/dialogs/meeting-page.c: use ical partstat, role, cutypes - directly - (popup_delegate_cb): if we delegate, notify of needs send and - changed - (popup_delete_cb): notify of needs send and changed for each - deletion - -2001-09-12 JP Rosevear <jpr@ximian.com> - - * gui/calendar-commands.c (publish_freebusy_cmd): send 6 weeks of - free busy info starting with the UTC start of day - - * gui/itip-utils.c (get_label): create a text representation of - the given icaltime - (itip_send_comp): if the summary is empty, set the subject based - on the type of component, put the right extension on free/busy - components and base descriptions on type of component, include - start/end for free/busy info - -2001-09-11 Federico Mena Quintero <federico@ximian.com> - - * gui/alarm-notify/alarm-queue.c (display_notification): Added an - use_description argument so that other alarms can fall back to - this type. - (audio_notification): Implemented. - (remove_comp): Call remove_queued_alarm() here; there is no longer - a destroy notification function for alarms so must we do this - manually. - (alarm_trigger_cb): Do not pass the alarm to the notification - functions so that we can free it ourselves before all the alarms - in the component get freed. - (display_notification): Get the alarm here instead of getting it - as an argument. - (procedure_notification): Implemented. - -2001-09-11 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/meeting-page.c (invite_entry_changed): free the - destination vector when we finish with it, if we actually add - anyone, notify listeners of the needs send and changed info. Fixes - bug #8632. - -2001-09-10 Zbigniew Chyla <cyba@gnome.pl> - - * gui/print.c - (format_date): Convert string generated by strftime to UTF-8. - (print_week_view_background): Ditto. - (print_month_summary): Ditto. - (print_month_small): Use U_() instead of _(). - (print_day_background): Ditto. - (print_todo_details): Ditto. - (print_date_label): Convert generated string to UTF-8. - -2001-09-10 Federico Mena Quintero <federico@ximian.com> - - * cal-util/cal-component.c (cal_component_alarm_get_attach): - Handle the new icalattach type instead of struct icalattachtype. - (cal_component_alarm_set_attach): Likewise. - - * gui/dialogs/alarm-options.c (alarm_to_aalarm_widgets): Likewise. - (alarm_to_palarm_widgets): Likewise. - (aalarm_widgets_to_alarm): Likewise. - (palarm_widgets_to_alarm): Likewise. - -2001-09-05 Ettore Perazzoli <ettore@ximian.com> - - [Fix #958, ShellComponents should not be created by factories, for - the calendar.] - - * gui/GNOME_Evolution_Calendar.oaf.in: Remove the - ShellComponentFactory. - - * gui/component-factory.c (create_object): Renamed from - `component_fn'. Don't get any args. - (component_factory_init): Create the component using - `create_object()' and register it into OAF. - (COMPONENT_FACTORY_ID): Removed. - (COMPONENT_ID): New. - -2001-09-04 Federico Mena Quintero <federico@ximian.com> - - * gui/component-factory.c (sc_user_create_new_item_cb): - Implemented. - - * gui/main.c (component_editor_factory_init): New function to - create the factory for the comp_editor_factory. - - * gui/comp-editor-factory.c: Finished implementation. - - * gui/alarm-notify/alarm-queue.c (edit_component): Implemented the - Edit command. - - * gui/Makefile.am (evolution_calendar_SOURCES): Added - comp-editor-factory.[ch] to the list of sources. - -2001-09-03 Damon Chaplin <damon@ximian.com> - - * gui/calendar-commands.c (calendar_control_activate): - * gui/tasks-control.c (tasks_control_activate): don't call - calendar_config_check_timezone_set() now, since the startup wizard - handles that. - - * gui/e-tasks.c (e_tasks_class_init): changed selection_changed signal - to GTK_RUN_LAST. It has no reason to be GTK_RUN_FIRST. - - * gui/gnome-cal.c: - * gui/e-week-view.c: - * gui/e-day-view.c: added "selection_changed" signal, - XX_delete_event() and XX_get_num_events_selected(). - - * gui/e-day-view-top-item.c (e_day_view_top_item_draw): fix the shadow - around the dates at the top - it was 1 pixel off. - - * gui/calendar-commands.c: added sensitize_commands(), similar to in - tasks-control.c, so we only make Cut/Copy/Delete sensitive when an - event is selected. Also added delete_event_cmd(). - - * gui/dialogs/task-page.c (task_page_set_summary): - * gui/dialogs/event-page.c (event_page_set_summary): do nothing, - since the summary only gets changed on the main event/task page now. - Fixes bug #6939. - - * gui/e-day-view.c (e_day_view_on_main_canvas_drag_data_received): - (e_day_view_on_top_canvas_drag_data_received): check that we are - dragging an event from the same EDayView. We currently don't support - DnD from other widgets. - (e_day_view_update_top_canvas_drag): only get the summary if we - actually have an event. Fixes bug #5162. - - * gui/e-day-view.c (e_day_view_on_editing_stopped): if the text hasn't - changed we need to call e_day_view_update_event_label() to show the - times again if necessary. Fixes bug #1813. - - * gui/dialogs/comp-editor.c (comp_editor_destroy): destroy the - CompEditorPage objects here rather than in close_dialog(), after the - widgets have been destroyed. We do this because the widgets have lots - of signal handlers connected with the CompEditorPage objects as the - signal data, so we want to ensure that the data pointer is always - valid. (Alternatively we could disconnect all the handlers when the - CompEditorPage objects are destroyed, or use connect_while_alive()). - Fixes bug #7543. - - Note: there is still a small bug in that if you type in a time and - then hit 'Save and Close', the time won't be saved. I'm not sure - where this should be fixed - should the actions which close the - dialog grab the focus to the toplevel, so any widgets currently - being edited finish the edit and emit 'changed'? - - * gui/dialogs/recurrence-page.c (append_exception): use - gtk_clist_set_row_data_full() so freeing is handled automatically by - the GtkClist. This helps avoid problems at destroy-time. - (exception_delete_cb): just call gtk_clist_remove() now. No need to - free the row data as GtkCList now handles it. - (recurrence_page_destroy): no need to free the data in the clist. - - * gui/dialogs/alarm-page.c: ditto. - - * gui/dialogs/meeting-page.c: ditto. - (etable_destroy_cb): save the ETable state in this new handler cb - rather than in the destroy method, since the widget will already be - destroyed by then. - -2001-08-31 Damon Chaplin <damon@ximian.com> - - * gui/e-itip-control.c: changed 3 occurrences of 'Replyed' to 'replied' - -2001-08-31 Zbigniew Chyla <cyba@gnome.pl> - - * gui/e-itip-control.c (write_html): - Marked strings for translation (with U_). - - * gui/itip-utils.c (itip_send_comp): - Ditto. - -2001-08-31 Damon Chaplin <damon@ximian.com> - - * gui/dialogs/comp-editor-util.c (comp_editor_contacts_to_widget): - (comp_editor_contacts_to_component): fix debugging messages so they - use "" rather than NULL. Fixes bug #8559. - -2001-08-29 Federico Mena Quintero <federico@ximian.com> - - * pcs/cal-backend-file.c (cal_backend_file_remove_object): See if - the set of categories changed by using the removed_categories hash - table. - (cal_backend_file_init): Create a table of removed categories. - This allows us to notify if and only if the set of category - changes when an object is updated/removed, instead of - unconditionally notifying if an object is updated. - (cal_backend_file_update_objects): Only notify if the set of - categories really changed. - (update_categories_from_comp): Shuffle the categories between the - priv->categories and priv->removed_categories lists. - -2001-08-28 Federico Mena Quintero <federico@ximian.com> - - Fixes bug #7879, a query may receive an update notification from - the backend before the query itself gets populated. - - * pcs/query.c (ensure_sexp): New function; ensures that the esexp - is created and notifies of parse errors. It is the bulk of - start_query_cb() but put in a separate function so that we can - share it elsewhere. - (start_query_cb): Use ensure_sexp(). - (process_component_cb): Oops, notify of a successfully finished - query. - (match_component): Call ensure_sexp(). This function can be - called by the backend notification callbacks before the query is - populated, so we need to make sure the esexp exists here. - -2001-08-22 Federico Mena Quintero <federico@ximian.com> - - * gui/cal-search-bar.c (cal_search_bar_construct): Set the - "category is" criterion as the default for the calendar and tasks. - -2001-08-22 Federico Mena Quintero <federico@ximian.com> - - * gui/dialogs/recurrence-page.c (recurrence_page_fill_widgets): - Unset the priv->updating flag before returning in the case the - component has no recurrence information. Fixes bug #6850. - -2001-08-22 Federico Mena Quintero <federico@ximian.com> - - * gui/alarm-notify/alarm-queue.c (QueuedAlarm): Added a snooze - flag to differentiate snoozed alarms from real occurrences. - (add_component_alarms): Do not specify a destroy function for the - alarm trigger. We handle this in the callbacks now. - (alarm_trigger_cb): Just remove the alarms for the unimplemented - notification types. - (create_snooze): Implemented snooze. - (notify_dialog_cb): Snooze as appropriate. - -2001-08-22 JP Rosevear <jpr@ximian.com> - - * gui/itip-utils.c (foreach_tzid_callback): call back to add - timezones to the top level - (itip_send_comp): call icalcomponent_foreach_tzid - -2001-08-22 Dan Winship <danw@ximian.com> - - * gui/gnome-cal.c: #include <libgnomevfs/gnome-vfs-types.h> so - this will compile against gnome-vfs 1.0.1. - -2001-08-22 Rodrigo Moya <rodrigo@ximian.com> - - * gui/gnome-cal.c (gnome_calendar_open): open the tasks folder - associated with the calendar being opened, and not always the local - tasks.ics file - - * pcs/cal-factory.c (open_fn): use gnome_vfs_uri_new_private when - parsing the URI to allow non-registered URIs - -2001-08-21 Federico Mena Quintero <federico@ximian.com> - - * gui/dialogs/alarm-options.c (alarm_to_palarm_widgets): Handle - the case where there is no attachment. Fixes bug #7257. - -2001-08-21 JP Rosevear <jpr@ximian.com> - - * gui/e-itip-control.c (write_html): strip the mailto bit for the - email address if we display it - -2001-08-21 Damon Chaplin <damon@ximian.com> - - * pcs/query.c (func_is_completed): added new e-sexp operator. We - don't currently use it though. - - * gui/dialogs/cal-prefs-dialog.glade: Changed '_Overdue' to 'O_verdue' - since we have an '_Other' notebook tab. Added '_Hide' accel. - - * gui/dialogs/cal-prefs-dialog.c: hooked up config options to dialog. - - * gui/calendar-config.c: added config options for hiding completed - tasks. - - * gui/e-week-view-event-item.c (e_week_view_event_item_draw): - * gui/e-day-view-top-item.c (e_day_view_top_item_draw_long_event): - * gui/e-day-view.c (e_day_view_reshape_long_event): added 2 pixels - extra space between icons and text for long events, and 1 pixel space - between icons in all events. - (e_day_view_realize): changed the background color to match the - EGrayBar in the shell. - -2001-08-21 Rodrigo Moya <rodrigo@ximian.com> - - * pcs/cal-backend-util.[ch]: new files to contain utility functions - for calendar backends - - * pcs/cal-backend.c (cal_backend_add_cal): implement it here, and not in - the calendar backends. Add a "cal_added" signal, so that backends are - notified when a new Cal is added, if they need to - (cal_backend_get_type_by_uid): implement it here - - * pcs/cal-backend-file.c (fill_alarm_instances_seq): moved to - cal-backend-util.c - (cal_backend_file_add_cal): removed - (cal_backend_file_init): connect to the "cal_added" signal in the - CalBackend class so that we can update categories when a new Cal is - added - (cal_backend_file_get_type_by_uid): removed - - * pcs/cal-backend-db.c (fill_alarm_instances_seq): moved to - cal-backend-util.c - (cal_backend_db_add_cal): removed - (cal_backend_db_get_type_by_uid): removed - - * AUTHORS: added JP and Damon to list of authors - -2001-08-20 Rodrigo Moya <rodrigo@ximian.com> - - * cal-util/cal-util.[ch] (cal_util_generate_alarms_for_list): - (cal_util_generate_alarms_for_comp): - new functions moved from the CalBackendFile, to allow its use outside - of it. The signature has changed a little bit, since these functions - need a way to get the timezones from the callers, so a callback - function to resolve the timezones has been added to the list of - parameters - - * pcs/cal-backend-file.c (generate_alarms_for_list): - (generate_alarms_for_comp): moved to cal-util, with all their related - functions/structures - - * pcs/cal-backend-db.c: removed functions that were moved to cal-util - -2001-08-20 Damon Chaplin <damon@ximian.com> - - * gui/dialogs/comp-editor.c (pixmaps): use Delete icon in menu, and - change to bigger Save icon in toolbar. - - * gui/tasks-control.c: - * gui/calendar-commands.c (pixmaps): used new_task-16.png and - goto-16.png. - -2001-08-20 Damon Chaplin <damon@ximian.com> - - * gui/calendar-commands.c (pixmaps): added delete icons for menu - and toolbar. - -2001-08-20 Damon Chaplin <damon@ximian.com> - - * gui/tasks-control.c: added Cut/Copy/Paste icons for toolbar. - -2001-08-20 Damon Chaplin <damon@ximian.com> - - * gui/tasks-control.c: uses new delete icons in menu & toolbar. - -2001-08-19 Ettore Perazzoli <ettore@ximian.com> - - * gui/component-factory.c: Update the folder list to include a - display name and a description. - -2001-08-20 Damon Chaplin <damon@ximian.com> - - * gui/dialogs/comp-editor.c (pixmaps): use new delete icon for toolbar. - -2001-08-19 Damon Chaplin <damon@ximian.com> - - * gui/e-itip-control.c: fixed typo, 'send' -> 'sent'. Bug #7621. - -2001-08-18 Damon Chaplin <damon@ximian.com> - - * gui/dialogs/cal-prefs-dialog.glade: added option to hide completed - tasks after a given number of minutes/hours/days. Unfinished. - - * gui/dialogs/event-page.c (event_page_fill_component): initialize - zone to NULL to avoid a warning. - (contacts_clicked_cb): work around a bug in SelectNames by notifying - that the page has changed when you click the 'Contacts' button. - Otherwise it is easy to lose changes. - - * gui/dialogs/task-page.c (contacts_clicked_cb): ditto. - -2001-08-18 Damon Chaplin <damon@ximian.com> - - * gui/dialogs/comp-editor.c (pixmaps): used new Save/Save As icons. - - * gui/tasks-control.c: - * gui/calendar-commands.c (pixmaps): added new Cut/Copy/Paste icons, - and changed the 'New Task' icon to use the bigger one I made. - -2001-08-05 Zbigniew Chyla <cyba@gnome.pl> - - * gui/dialogs/task-page.c (summary_changed_cb): - Use e_dialog_editable_get instead of gtk_editable_get_chars (we need - UTF-8 string). - -2001-08-18 Zbigniew Chyla <cyba@gnome.pl> - - * gui/calendar-config.c (locale_uses_24h_time_format): New. - (config_read): Use locale's setting as default for - /Calendar/Display/Use24HourFormat so that Europeans don't have to - switch to 24-hour format manually. - -2001-08-17 JP Rosevear <jpr@ximian.com> - - * gui/e-itip-control.c (destroy): destroy the addresses - (clean_up): don't free the addresses, we need them - -2001-08-17 Damon Chaplin <damon@ximian.com> - - * gui/gnome-cal.c (gnome_calendar_new_task): new function to open the - task editor to add a new task. - - * gui/calendar-commands.c: added new_task_cb() to create a new task - in the calendar folder, and added menu commands for it, and a toolbar - button (I think that is what Ettore wanted. Maybe he just meant menu - commands. Anyway, it is easy to take out.) Note that we don't have a - decent icon for 'New Task' for the toolbar. - Also added the new Goto button (but we don't have a similar one for - the menu command). - -2001-08-16 Iain Holmes <iain@ximian.com> - - * gui/Makefile.am: Add the libetimezonedialog.a lib link - - * gui/calendar-config.c: Change the #include for the timezone dialog - - * gui/e-timezone-entry.c: Ditto. - - * gui/dialogs/Makefile.am: Remove the e-timezone-dialog stuff. - -2001-08-16 Damon Chaplin <damon@ximian.com> - - * gui/dialogs/event-page.c: hide the timezone fields for all-day - events. We will use DATE values for these eventually, and these - don't have timezones associated with them. Currently we just use the - default timezone for all-day events, as a workaround until we have - DATE values working. - - * gui/dialogs/comp-editor-util.c (comp_editor_new_date_edit): added - make_time_insensitive flag. Though we may not use it. - - * gui/dialogs/event-page.glade: made the 'All day event' toggle - right-aligned, so it doesn't move when the other widgets are shown - and hidden. - - * gui/e-timezone-entry.c (e_timezone_entry_set_default_timezone): new - function to set the default timezone of the widget. If the current - timezone setting matches the default then the entry field is hidden. - Most people won't use timezones so this makes the GUI simpler. - - * gui/dialogs/event-page.c (init_widgets): - * gui/dialogs/task-page.c (init_widgets): set the default timezone - using the above function. - - * gui/dialogs/task-page.c (task_page_fill_widgets): if the start date - or due date is not set, we use the default timezone, so the user - doesn't have to set this each time they set the date. - -2001-08-16 Federico Mena Quintero <federico@ximian.com> - - * gui/dialogs/alarm-page.c (alarm_page_fill_widgets): If the - component has no alarms remember to set the priv->updating flag to - FALSE before returning. - -2001-08-16 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/e-delegate-dialog.c - (e_delegate_dialog_get_delegate_name): get the destinations - property, not the text property - -2001-08-16 Federico Mena Quintero <federico@ximian.com> - - * gui/dialogs/alarm-page.c (clear_widgets): Set the default-to-add - notification to be display a message 15 minutes before the start - of the appointment. Fixes bug #7175. - -2001-08-16 Federico Mena Quintero <federico@ximian.com> - - * gui/dialogs/comp-editor-util.c (comp_editor_strip_categories): - New function to strip surrounding whitespace from a string of - categories entered by the user. - - * gui/dialogs/task-page.c (task_page_fill_component): Use - comp_editor_strip_categories(). - - * gui/dialogs/event-page.c (event_page_fill_component): Likewise. - -2001-08-16 Federico Mena Quintero <federico@ximian.com> - - * gui/calendar-config.c (calendar_config_configure_e_date_edit): - Do not set the time popup range. We also want to be able to - create appointments that are not within nine-to-five! Think of - going to the movies! Fixes bug #7436. - - * gui/dialogs/cal-prefs-dialog.glade: "am/pm" is now "AM/PM". - Fixes bug #7367. - -2001-08-16 Jon Trowbridge <trow@ximian.com> - - * gui/cal-search-bar.c: Changed to reflect my renaming of some of - the more hideously-named functions in the ESearchBar API. - -2001-08-15 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/comp-editor.c (save_comp): only fill the component - and save it if something has changed - (save_comp_with_send): only try to send if something has changed - and the editor needs a send - -2001-08-15 Federico Mena Quintero <federico@ximian.com> - - * gui/dialogs/cal-prefs-dialog.glade: OK, re-added the default - alarm options. Way too many people are asking for them. - -2001-08-15 Federico Mena Quintero <federico@ximian.com> - - * gui/component-factory.c (factory_fn): Add the user creatable - items. The callback is not actually implemented yet; this is just - to finalize the GUI. - - * gui/dialogs/cal-prefs-dialog.glade: Added an option to ask for - confirmation when deleting items. Added underlined shortcuts - (they may not all work currently). - -2001-08-14 Damon Chaplin <damon@ximian.com> - - * gui/dialogs/task-page.c: - * gui/dialogs/event-page.c: added support for the Contacts field. - Note that I'm not sure what we should put in the iCalendar CONTACT - properties. Currently we put "name <email>", but it isn't recognized - as a contact when we reopen the dialog, so we may need more info here. - Also we currently use a simple parser to parse the above format, and - we should maybe use some camel function. - - * gui/dialogs/task-page.glade: - * gui/dialogs/event-page.glade: replaced the GtkEntry fields for the - Contacts with a GtkEventBox which we put the BonoboControl in at - runtime. - - * gui/dialogs/meeting-page.c (invite_entry_changed): added FIXMEs - since it doesn't seem to be freeing the EDestination stuff. JP? - - * gui/dialogs/comp-editor-util.c: added bunch of utility functions to - handle the Contacts field in the main Event and Task pages. - - * gui/gnome-cal.c: added visible_start and visible_end fields, so we - only emit the 'dates-shown-changed' signal when really necessary. - Currently changing the folder title bar label results in a complete - redraw of the Evolution window (silly GtkLabel queueing a resize), - so we want to avoid that as much as possible. - (gnome_calendar_new_appointment_for): only move the event's end time - to the end of the day if it is not already 00:00:00. - - * gui/e-week-view-event-item.c: - * gui/e-week-view.c: - * gui/e-day-view.c: added support for double-clicking on an event to - open it, and for double-clicking on the background to create a new - event. There is still a minor problem to sort out, but it basically - works. - - * cal-util/cal-component.c: added support for CONTACT properties, - mainly by copying the code for COMMENT properties which are exactly - the same type. - - * gui/e-day-view.c (e_day_view_realize): use the same color for the - top canvas background as the shortcut bar, to make it look a little - nicer (I think). Although we still have the theme problem with - hard-coded colors. - -2001-08-14 Federico Mena Quintero <federico@ximian.com> - - * gui/e-calendar-table.etspec: Made the click-to-add message - shorter. Fixes bug #7177. - -2001-08-14 Federico Mena Quintero <federico@ximian.com> - - * gui/calendar-commands.c (pixmaps): Added Tigert's new icons for - Prev and Next. - -2001-08-14 Federico Mena Quintero <federico@ximian.com> - - * gui/cal-search-bar.c (make_suboptions): Make the "Any Category" - item consistent with the one in the addressbook. Also, free the - items correctly. - -2001-08-14 Federico Mena Quintero <federico@ximian.com> - - * gui/cal-search-bar.c (get_current_category): Handle an array of - categories in the CalSearchBar instead of our own menu items. - (notify_query_contains): Fetch the text from the search bar here - instead of in regen_query(). - (regen_query): Handle category searches. - (notify_category_is): New function. - (cal_search_bar_construct): Do not create an option menu. - (make_suboptions): New function to create the suboption items from - the list of categories. - (notify_query_contains): Do not include a category sexp here. - -2001-08-13 JP Rosevear <jpr@ximian.com> - - * gui/e-itip-control.c (update_item): add dialog for feedback - (remove_item): ditto - (send_item): ditto - (send_freebusy): ditto - -2001-08-13 JP Rosevear <jpr@ximian.com> - - * gui/e-itip-control.c: rewrite the gui to use gtkhtml - - * gui/Makefile.am: define the icon dir - -2001-08-12 Kjartan Maraas <kmaraas@gnome.org> - - * gui/e-itip-control.h: Remove #include <config.h> from here. - * gui/itip-utilss.h: Same here. - -2001-08-11 Ettore Perazzoli <ettore@ximian.com> - - * gui/tasks-control.c: Update the paths of the Tools menu - according to the changes in the XML [i.e. things are moved to the - ComponentToolsPlaceholder]. - - * gui/calendar-commands.c: Likewise. - -2001-08-11 Damon Chaplin <damon@ximian.com> - - * gui/dialogs/event-page.c (init_widgets): - * gui/dialogs/task-page.c (init_widgets): turn on word-wrap for the - description fields. Fixes bug #6821. - -2001-08-10 Jon Trowbridge <trow@ximian.com> - - * gui/cal-search-bar.c: Where we have ESearchBarItems, set their - subitems to NULL. - -2001-08-09 Damon Chaplin <damon@ximian.com> - - * pcs/cal-backend.c (cal_backend_get_object_component): added new - backend method to get the component given a UID. - - * pcs/cal-backend-file.c (cal_backend_file_get_object_component): - added implementation of above virtual method. - - * pcs/query.c (match_component): use the new backend function to get - the CalComponent rather than the string. This avoids converting all - the calendar components to strings and parsing them back into - components for every query! (That wasn't a good idea, was it ;) - - * gui/e-week-view.c: - * gui/e-day-view.c: use a timeout handler to layout the events, - to avoid doing a layout for each event we get from a query. - - * gui/print.c (print_day_add_event): - * gui/e-day-view.c (e_day_view_add_event): set start_row_or_col and - num_columns to 0. They are guint8's. - - * gui/e-week-view.c (e_week_view_free_events): hide all the jump - buttons. Fixes bug #5946. - - * gui/calendar-commands.c (calendar_set_folder_bar_label): added the - day numbers for the month view. - - * gui/dialogs/recurrence-page.glade: changed "_Delete" to "_Remove", - since it clashed with "_Add". Also added underlined accelerators for - the recurrence radio buttons. Note that none of these accelerators - actually work at present, due to the way we are using .glade files - for each notebook page. I need to add a bug about this. - Also, the "_Action" menu doesn't popup when I press Alt+A, even though - the "_File" menu does popup when I press Alt+F. Strange. - - * pcs/cal-backend-file.c (cal_backend_file_get_timezone_object): - removed debug msgs. - -2001-08-09 Rodrigo Moya <rodrigo@ximian.com> - - * 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-week-view-event-item.c (e_week_view_event_item_draw_icons): - unref the GdkPixmap and GdkBitmap returned by the function - e_categories_config_get_icon_for () - -2001-08-09 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/task-page.*: Remove progress frame - - * gui/dialogs/task-details-page.*: Put in progress frame, remove - basics frame - - * gui/dialogs/task-editor.c (set_menu_sens): util function to set - menu sensitivity based on state - (task_editor_init): add meeting page - (task_editor_edit_comp): show page if necessary - (task_editor_destroy): unref meeting page - (assign_task_cmd): bring up meeting page - (refresh_task_cmd): save before sending - (forward_cmd): ditto - - * gui/dialogs/comp-editor.c (save_cmd): implement new save command - -2001-08-09 Federico Mena Quintero <federico@ximian.com> - - * gui/e-itip-control.c (destroy): Chain to the destroy handler in - the parent class! - - * gui/dialogs/comp-editor-page.c (comp_editor_page_destroy): - Likewise. Sigh. - - * gui/cal-search-bar.c (cal_search_bar_destroy): Whoops, added a - destroy handler. - -2001-08-08 Damon Chaplin <damon@ximian.com> - - * gui/goto-dialog.glade: removed underlined accelerator key from - "_Go To Today" button. GnomeDialog doesn't actually support underlined - accelerator keys for buttons. We could hack it, like Glade does, if - we really need to. Fixes bug #6418. - -2001-08-08 Federico Mena Quintero <federico@ximian.com> - - * gui/e-day-view.c (update_query): Stop editing any event. Fixes - bug #5949. - -2001-08-08 Federico Mena Quintero <federico@ximian.com> - - * gui/dialogs/alarm-page.c (alarm_page_fill_component): Duuuh, set - the alarm_copy on the component, not the original alarm. Fixes - bug #5214. - -2001-08-08 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/meeting-page.c (set_attendees): set the attendees of - a component - (meeting_page_fill_component): use above - (meeting_page_get_cancel_comp): return a comp with the attendees - to be cancelled - - * gui/dialogs/meeting-page.h: get a component that will be sent as - a cancellation - - * gui/dialogs/event-editor.c (event_editor_class_init): override - send_comp class method - (event_editor_send_comp): send cancellation notices to deleted - attendees - (refresh_meeting_cmd): save before send - (forward_cmd): ditto - - * gui/dialogs/comp-editor.c (comp_editor_class_init): set default - send_comp method - (real_send_comp): do the real work - (comp_editor_send_comp): call class method - (save_comp): don't do any sending - (save_comp_with_send): save and send here - (prompt_to_save_changes): use above - (save_close_cmd): ditto - - * gui/dialogs/comp-editor.h: add virtual function - -2001-08-08 Rodrigo Moya <rodrigo@ximian.com> - - * gui/e-week-view-event-item.c - (e_week_view_event_item_draw_icons): don't use a NULL mask in the - call to gdk_gc_set_clip_mask - - * gui/e-day-view-top-item.c (e_day_view_top_item_draw_long_event): - ditto - - * gui/e-day-view-main-item.c - (e_day_view_main_item_draw_day_event): ditto - -2001-08-08 JP Rosevear <jpr@ximian.com> - - * conduits/calendar/calendar-conduit-config.h: fix pre-processor - macros - - * conduits/calendar/calendar-conduit.h: ditto - - * conduits/todo/todo-conduit-config.h: fix pre-processor macros - - * conduits/todo/todo-conduit.h: ditto - -2001-08-07 Federico Mena Quintero <federico@ximian.com> - - * cal-client/cal-listener.c (cal_listener_stop_notification): New - function to stop further notification from happening. - (impl_notifyCalOpened): Do not notify if requested. - (impl_notifyObjUpdated): Likewise. - (impl_notifyObjRemoved): Likewise. - (impl_notifyCategoriesChanged): Likewise. - (CalListenerPrivate): Do not keep a reference to the server-side - Cal. This would create a circular reference since the server - keeps a reference to the listener. - (cal_listener_destroy): Likewise. - (impl_notifyCalOpened): Likewise. - - * pcs/cal.c (cal_destroy): bonobo_object_release_unref() the listener. - - * cal-client/cal-client.c (cal_client_destroy): Ask the listener - to stop notifications. Also, do not unref it as the server does - that itself when we unref the Cal. - -2001-08-07 Federico Mena Quintero <federico@ximian.com> - - * gui/calendar-model.c (calendar_model_free_value): Only unref the - FIELD_COMPONENT if it is non-NULL. We return a NULL for that - field from ::initialize_value(), after all. Fixes bug #6098. - -2001-08-07 JP Rosevear <jpr@ximian.com> - - * gui/itip-utils.c (itip_send_comp): Make calendar.ics the - suggested name when attaching the ical object - -2001-08-06 Damon Chaplin <damon@ximian.com> - - * gui/e-week-view.h: - * gui/e-day-view.h: added 'different_timezone' fields to EDayViewEvent - and EWeekViewEvent, to note that the event is in a different timezone. - We now compute this once when we add the event to the array, rather - than each time we draw the event. If it is set, we will draw the - timezone icon next to the event. - - * gui/e-day-view-main-item.c: take transparency into account when - drawing the blue vertical bars to represent busy time. - - * gui/tag-calendar.c: take transparency into account when tagging - the mini calendar. - - * gui/e-calendar-table.c (e_calendar_table_init): removed the "None" - options for transparency and classification, since these properties - have defaults anyway, so we may as well use those to keep it simple. - Also use "Free" and "Busy" for transparency, rather than "Transparent" - and "Opaque". - - * gui/calendar-model.c: updated classification & transparency code - as above. - - * gui/e-calendar-table.etspec: changed "Transparency" to "Show Time As" - since people have a chance of understanding that. - - * gui/e-week-view.c: - * gui/e-day-view.c: - * gui/gnome-cal.c: added functions to get the visible time range. - - * gui/calendar-commands.c: finished stuff to set the folder bar - label to the dates currently displayed. - - * gui/control-factory.c (control_factory_new_control): connected - signal to update the folder title bar label when the dates shown - are changed. I had to connect it here since we need the BonoboControl - in the callback, and I don't know how to get the control from the - widget. - - * gui/tasks-control.c (tasks_control_activate): clear the folder bar - label. We could display something here at some point. - - * gui/dialogs/recurrence-page.glade: changed "_Add" to "A_dd", since - we have an "_Actions" menu. (These also use Alt+key, right?) - - * gui/dialogs/event-page.glade: - * gui/dialogs/event-page.c: added 'Show Time As' field, which is - really the TRANSP property but with a better name! - Also changed one of the "_Confidential" to "Con_fidential" since we - already have "_Contacts" using the same 'C' key. - - * pcs/cal-backend-file.c (cal_backend_file_get_free_busy): skip - events that are TRANSPARENT. Also added comment as this code looks - inefficient. - - * cal-util/cal-component.c: removed stuff for comparing timezones. - - * gui/comp-util.c (cal_comp_util_compare_event_timezones): moved the - above function here, and updated it to compare the UTC offsets of the - times as well as the TZIDs. - -2001-08-06 Federico Mena Quintero <federico@ximian.com> - - * gui/dialogs/cal-prefs-dialog.glade: In process of fixing bug - #6005. The "Calendar" page is now "Display", and it has no - frames. The "Task list" page has colons between the labels and - the color pickers, and it has no frame. - -2001-08-06 Rodrigo Moya <rodrigo@ximian.com> - - * cal-client/cal-client.c (destroy_wombat_client): added check for - NULL pointers. Maybe fixes #5203 (I can't reproduce it, so I'm not - sure) - -2001-08-03 Federico Mena Quintero <federico@ximian.com> - - * cal-client/query-listener.c (query_listener_stop_notification): - New function; stops further notification from happening. This is - needed since the listener is destroyed asynchronously from the - Wombat and the corresponding CalQuery may already have died. - (impl_notifyObjUpdated): Do not notify if requested. - (impl_notifyObjRemoved): Likewise. - (impl_notifyQueryDone): Likewise. - (impl_notifyEvalError): Likewise. - - * cal-client/cal-query.c (cal_query_destroy): Use - query_listener_stop_notification(). - - * cal-client/cal-listener.c (cal_listener_destroy): Nullify the - pointers to the callback functions. - - * gui/e-day-view.c (update_query): Commit our state of no longer - having a query before unrefing it. We may reenter from the ORBit - main loop and we *really* want this information to be committed. - - * gui/e-week-view.c (update_query): Likewise. - - * gui/calendar-model.c (update_query): Likewise. - - * gui/tag-calendar.c (tag_calendar_by_comp): Added a "clear_first" - argument that indicates whether the ECalendar should be cleared of - any marks first. - - * gui/calendar-commands.c (calendar_control_activate): Removed - ifdefed-out view buttons code from the Gnomecal days. - - * gui/gnome-cal.c (client_categories_changed_cb): Merge the - categories of the calendar and tasks clients so that we can - display the categories in both sets. - (gnome_calendar_construct): Connect to "categories_changed" on - both clients. - (gnome_calendar_on_date_navigator_selection_changed): Removed call - to gnome_calendar_update_view_buttons(). - (gnome_calendar_update_view_buttons): Removed. We cannot have - this until Bonobo supports radio toolbar items. - (gnome_calendar_set_view_buttons): Removed. - (gnome_calendar_dayjump): Do not use priv->day_button. - (GnomeCalendarPrivate): Removed the {day,work_week,week,month}_button - fields. - (gnome_calendar_set_query): Start a retagging process of the date - navigator so that it reflects the current query. - (update_query): New function to restart a query for the date navigator. - (initial_load): Use update_query() instead of tagging the date - navigator directly. - (gnome_calendar_on_date_navigator_date_range_changed): Likewise. - (client_cal_opened_cb): Use update_query() instead of initial_load(). - (initial_load): Removed. - (client_obj_updated_cb): Removed. - (client_obj_removed_cb): Removed. - (gnome_calendar_new_appointment_for): Set the default category of - the new component. - (search_bar_category_changed_cb): Set the default category for the - calendar views. - - * gui/cal-search-bar.c (cal_search_bar_set_categories): Sort the - categories before creating the menu. - - * gui/e-day-view.c (adjust_query_sexp): Return NULL instead of - "#f" if the time range is not set yet. - (update_query): Do not start a query if the time range is not set. - (e_day_view_set_default_category): New function. - (e_day_view_key_press): Set the default category on the new - component. - - * gui/e-week-view.c (adjust_query_sexp): Analogous to the above. - (update_query): Analogous to the above. - (e_week_view_set_default_category): Analogous to the above. - (e_week_view_key_press): Analogous to the above. - -2001-08-03 Federico Mena Quintero <federico@ximian.com> - - Fixes bug #1407. - - * gui/dialogs/cal-prefs-dialog.glade: Removed the alarm - preferences page, since we decided it was unnecessary. - -2001-08-03 Zbigniew Chyla <cyba@gnome.pl> - - I18n fixes. - - * gui/dialogs/event-page.c (summary_changed_cb): - Use e_dialog_editable_get instead of gtk_editable_get_chars (we need - UTF-8 string). - - * gui/itip-utils.c: - Added missing #include <config.h> - -2001-08-02 Jon Trowbridge <trow@ximian.com> - - * gui/Makefile.am: Added camel dependency (now needed by ebook). - -2001-08-01 Federico Mena Quintero <federico@ximian.com> - - * gui/calendar-model.c (calendar_model_value_is_empty): If the - default category is the same as the value passed in to this - function, return TRUE. This could be a hack or not, but it - prevents two items from being added to the table if a category is - selected. - - * gui/e-tasks.c (setup_widgets): Allow the search bar to shrink - horizontally. - - * gui/dialogs/task-page.c (clear_widgets): Pass valid values to - e_dialog_option_menu_set(); these need to come from the status map. - -2001-08-01 Damon Chaplin <damon@ximian.com> - - * cal-client/cal-client.c: removed debugging messages. - -2001-08-01 Federico Mena Quintero <federico@ximian.com> - - The calendar search bar widget now includes a drop-down menu of - available categories. - - * pcs/query.c (func_has_categories): Handle one and only one #f - value as meaning "unfiled", for components that have no categories - at all. - - * pcs/cal-backend-file.c (open_cal): Duh, do not notify here about - changed categories since at this point we don't have any clients - bound to us yet. - (create_cal): Likewise. - (cal_backend_file_add_cal): Notify here. - - * gui/cal-search-bar.h (CalSearchBarClass): New signal - "category_changed". - - * gui/cal-search-bar.c (cal_search_bar_construct): Add a drop-down - menu for the list of categories. - (search_option_items): Removed the "Has category" option, since we - now have the drop-down menu instad and it would be confusing to - have both options. - (regen_query): Likewise. Also, this function is now the old - cal_search_bar_query_changed() and is shared by that very function - and by the callback from the drop-down menu. - (notify_query_contains): Include the sub-sexp for the categories. - (cal_search_bar_set_categories): New function. - (cal_search_bar_get_category): New function. - (categories_selection_done_cb): Emit the "category_changed" signal. - - * gui/e-tasks.c (obj_updated_cb): Removed function since it did - not do anything; all updates are handled by the CalendarModel. - (obj_removed_cb): Likewise. - (ETasksPrivate): Removed the fields for the categories option - menu, since now it is in the ESearchBar. - (search_bar_sexp_changed_cb): Use calendar_model_set_query() - directly here, as we do not need to frob the sexp anymore. - (update_query): Removed. - (client_categories_changed_cb): New callback. - (search_bar_category_changed_cb): New callback. - (e_tasks_new_task): Set the default category on the component to - the one that is selected in the search bar. - (e_tasks_on_filter_selected): Removed. - (e_tasks_on_categories_changed): Removed. - (e_tasks_rebuild_categories_menu): Removed. - (e_tasks_add_menu_item): Removed. - (e_tasks_setup_view_menus): Sanitized not to sink objects wildly. - (e_tasks_discard_view_menus): New function. - - * gui/calendar-model.h (CalendarModelClass): Removed the - "categories_changed" signal since this is handled in the Wombat - now. - - * gui/calendar-model.c (calendar_model_get_categories): Removed. - (calendar_model_set_value_at): Do not collect the categories. - (query_obj_updated_cb): Likewise. - (calendar_model_collect_categories): Removed. - (calendar_model_set_default_category): Constify. - - * gui/tasks-control.c (tasks_control_deactivate): Call - e_tasks_discard_view_menus(). - - * gui/gnome-cal.c (search_bar_category_changed_cb): Set the - default category for the task pad's model. - -2001-07-31 Federico Mena Quintero <federico@ximian.com> - - The Wombat now keeps track of which categories are present in the - objects of a calendar. It will notify the clients of changes in - this set. This is to make the category drop-down menus in the - calendar/tasks views be always up to date. - - * idl/evolution-calendar.idl (Listener): Added a - notifyCategoriesChanged() method. The Wombat now keeps track of - the categories within a calendar. - - * cal-client/cal-listener.[ch]: Switched it to use BonoboXObject. - Also added the notifyCategoriesChanged implementation. - - * cal-client/cal-client.[ch]: Added a "categories_changed" signal. - - * pcs/cal-backend-file.c: Maintain a list of the live categories. - (update_categories_from_comp): New function to maintain the set of - live categories. - (add_component): Update the set of categories. - (remove_component): Likewise. - (open_cal): Notify about changes in the set of categories. - (create_cal): Likewise. - (cal_backend_file_update_objects): Likewise. - (cal_backend_file_remove_object): Likewise. - (notify_categories_changed): New function to notify the clients - about the current set of categories. - - * pcs/cal.c (cal_notify_categories_changed): New function. - -2001-07-31 Rodrigo Moya <rodrigo@ximian.com> - - * gui/e-day-view.c (selection_received): - * gui/e-week-view.c (selection_received): yes, set the end date, but - correctly calculated, not by using the component's duration, which - may not exist. Now really fixes #5836 - -2001-07-31 Rodrigo Moya <rodrigo@ximian.com> - - * gui/e-day-view.c (selection_received): - * gui/e-week-view.c (selection_received): don't set the end date - for the pasted components, since it will be recalculated when the start - date is set, thus keeping the same duration than the original - cut/copied component. Fixes #5836 - -2001-07-30 Damon Chaplin <damon@ximian.com> - - * gui/gnome-cal.c: - * gui/calendar-commands.c (clear_folder_bar_label): started some code - to show the currently displayed dates in the folder title bar. - Unfinished. - - * gui/e-itip-control.c (set_date_label): - * conduits/todo/todo-conduit.c (local_record_from_comp): - * conduits/calendar/calendar-conduit.c (local_record_from_comp): free - the CalComponentDateTimes. (Note the iTIP control needs updating for - timezone support.) - - * cal-util/cal-component.c: Changed CalComponentDateTime so that the - TZID is malloc'ed and freed rather than being a pointer to a static - string. This was causing problems as sometimes we were freeing the - string that was being pointed to, so we got corrupted TZIDs. - - * gui/comp-util.c (cal_comp_util_add_exdate): set TZID to NULL. - DATE values do not have timezones. - - * gui/e-week-view.c: - * gui/e-day-view.c: Moved 'Paste' after the New Appointment commands, - since I think they are more commonly-used. Also added underlined - accelerator keys. - - * gui/e-calendar-table.c: changed 'Edit this task' to 'Open' in the - popup menu to be consistent with other folders, and separated from the - clipboard commands. Also changed to use EPopupMenu so the accelerators - work, and the masks may be useful at some point. - - * gui/dialogs/recurrence-page.c: use DATE values for UNTIL, since - that makes it simpler. Fixes bug #5034. - - * gui/calendar-config.c (calendar_config_set_timezone): strdup the - location string. Fixes bug #4990. - - * gui/tag-calendar.c (tag_calendar_cb): take 1 off iend as the times - don't include the end time. - - * gui/e-week-view-layout.c (e_week_view_layout_event): fixed - days_shown. Fixes bug #5709. - - * cal-client/cal-client.c (cal_client_get_timezone): took out some - debugging messages. - -2001-07-30 Damon Chaplin <damon@ximian.com> - - * gui/dialogs/cal-prefs-dialog.glade: added Help button. Though of - course it doesn't do anything yet. - -2001-07-30 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/meeting-page.c: Mark strings for translation - -2001-07-30 Rodrigo Moya <rodrigo@ximian.com> - - * cal-client/client-test.c (cal_opened_cb): call - cal_client_get_free_busy for testing the new method - - * pcs/cal-backend-file.c (cal_backend_file_get_free_busy): implemented - -2001-07-28 Federico Mena Quintero <federico@ximian.com> - - Fixes bug #5352. - - * gui/dialogs/cal-prefs-dialog.c (cal_prefs_dialog_show): Added a - `page' argument so that we can select which page to show when - popping up the dialog. - (cal_prefs_dialog_construct): Added the `page' argument as well. - (cal_prefs_dialog_new): Likewise. - - * gui/calendar-commands.c (settings_cmd): Set the page to the main - calendar settings one. - - * gui/tasks-control.c (tasks_control_settings_cmd): Implemented - callback for the "Task Settings" command. - (verbs): Added the "TasksSettings" verb. - (pixmaps): Added an icon for the tasks settings command. - -2001-07-27 JP Rosevear <jpr@ximian.com> - - * conduits/calendar/calendar-conduit.c (local_record_from_comp): - recur is always in UTC - -2001-07-27 JP Rosevear <jpr@ximian.com> - - * conduits/calendar/calendar-conduit.c: handle timezones - everywhere - (get_timezone): new function to get a timezone based - on a tzid - (get_default_timezone): get default timezone - - * conduits/calendar/calendar-conduit.h: time zone field for the - context - - * conduits/calendar/Makefile.am: link to bonobo conf - - * conduits/todo/todo-conduit.c: handle timezones - everywhere - (get_timezone): new function to get a timezone based - on a tzid - (get_default_timezone): get default timezone - - * conduits/todo/todo-conduit.h: time zone field for the - context - - * conduits/todo/Makefile.am: link to bonobo conf - -2001-07-27 Rodrigo Moya <rodrigo@ximian.com> - - * gui/e-day-view-main-item.c (e_day_view_main_item_draw_day_event): - * gui/e-day-view-top-item.c (e_day_view_top_item_draw_long_event): - * gui/e-week-view-event-item.c (e_week_view_event_item_draw_icons): - initialize to NULL some pointers - - * e-calendar-table.c (selection_received): deal correctly with - VCALENDAR objects - (e_calendar_table_copy_clipboard): g_strdup the value returned by - icalcomponent_get_as_ical_string - -2001-07-27 Federico Mena Quintero <federico@ximian.com> - - * gui/gnome-cal.c (gnome_calendar_set_query): Constify and set the - query sexp on the task pad's model as well. - -2001-07-27 Federico Mena Quintero <federico@ximian.com> - - * gui/cal-search-bar.[ch]: New files with a derivative of - ESearchBar that generates sexps for calendar queries directly. - - * gui/gnome-cal.c (setup_widgets): Use CalSearchBar instead of - ESearchBar. - - * gui/e-calendar-table.h (ECalendarTable): Removed the ->colors - array since it is handled by ETableExtras now. - - * gui/e-calendar-table.[ch]: Removed the subset_model. Now we use - the live query facility to filter tasks. Removed the filter - function stuff as well. - - * gui/e-tasks.c (e_tasks_construct): Use - calendar_model_set_cal_client() directly instead of - e_calendar_table_set_model(). - (setup_widgets): Create a calendar search bar for the tasks - component. - (search_bar_sexp_changed_cb): Set the query sexp on the table model. - (e_tasks_on_filter_selected): Regenerate the query from the - selected category and the current sexp. - (update_query): New convenience function to recompute the real - query sexp. - - * gui/gnome-cal.c (gnome_calendar_construct): Likewise. - - * gui/e-calendar-table.c (e_calendar_table_set_cal_client): - Removed function; people are now supposed to get the model from - the calendar table and operate on it. - - * gui/calendar-commands.c (verbs): Consistency fixes with the XML - file. - (pixmaps): Likewise. - - * gui/Makefile.am (evolution_calendar_SOURCES): Added - cal-search-bar.[ch] to the list of sources. - -2001-07-20 Federico Mena Quintero <federico@ximian.com> - - * idl/evolution-calendar.idl (CompEditorFactory): New interface to - a centralized factory for calendar component editors. Has - editExisting() and editNew() methods to edit an existing component - from a URI/UID pair, and to create a new component in a calendar - that is in a particular URI, respectively. - - * gui/comp-editor-factory.[ch]: Implementation files for the - component editor factory. - - * gui/GNOME_Evolution_Calendar.oaf.in: Added the CompEditorFactory - stuff. - - * gui/Makefile.am (evolution_calendar_SOURCES): Added - comp-editor-factory.[ch] to the list of sources. - -2001-07-26 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/meeting-page.c (invite_entry_changed): when an entry - has changed, iterate over the elements of the entry and add them - to the list if need be - (get_select_name_dialog): add a Chair Persons section - - * gui/itip-utils.c (itip_send_comp): send the empty string as - subject if there is no summary - -2001-07-26 JP Rosevear <jpr@ximian.com> - - * gui/itip-utils.c (itip_send_comp): send the empty string as - subject if there is no summary - - * gui/dialogs/meeting-page.c (cleanup_attendees): free a list of - attendees - (meeting_page_fill_widgets): clean up attendee lists and fix typo - (find_match): add ability to return pos of match - (popup_delete_cb): if deletion happens, make sure to tidy up - delegation chain - - * gui/dialogs/e-delegate-dialog.c (e_delegate_dialog_construct): - use the destination rather than text property - (e_delegate_dialog_get_delegate): ditto - (e_delegate_dialog_new): take name/address pair for dialog default - - * gui/dialogs/e-delegate-dialog.h: update protos - - * gui/e-itip-control.c (clean_up): only unref the object if we - have one - - * gui/itip-control-factory.c (stream_read): make sure we null - terminate the final buffer - - * gui/itip-utils.c (itip_send_comp): strip the mailto: from the - organizer address if necessary - -2001-07-26 Damon Chaplin <damon@ximian.com> - - * gui/dialogs/recurrence-page.c (exception_select_row_cb): check that - the row passed in is valid. Sometimes we get the "row-selected" - signal for row 0 when there are no rows in the list. Fixes bug #4266. - - * cal-client/cal-client.c (cal_client_get_object): prefetch all the - timezone data needed by the object, to try to avoid making Corba - calls all over the place. They can cause problems because they call - the GTK+ main loop recursively. This currently leads to an assertion - failure in the GnomeCanvas occasionally. - -2001-07-25 JP Rosevear <jpr@ximian.com> - - * gui/e-itip-control.c (e_itip_control_set_data): gracefully - handle the lack of a method - -2001-07-25 Rodrigo Moya <rodrigo@ximian.com> - - * gui/e-day-view.c (selection_received_cb): check type of component - before actually pasting. - Deal with VCALENDAR components also (fixes bug #5140) - - * gui/e-week-view.c (selection_received_cb): ditto - - * cal-client/cal-client.c (cal_client_update_object): check the return - value from cal_component_get_as_string and don't call - GNOME_Evolution_Calendar_Cal_updateObjects if NULL - -2001-07-25 Damon Chaplin <damon@ximian.com> - - * gui/dialogs/comp-editor.c (pixmaps): used the new print preview icon. - - * gui/print.c (range_selector_new): changed the 'Current day/week...' - strings to 'Selected day/week...' to make a little less confusing. - Fixes bug #5451. - -2001-07-25 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/meeting-page.c (is_duplicate): see if the address is - already in the list of attendees - (duplicate_error): throw up an error dialog - (popup_delegate_cb): if the attendee has already delegated, delete - the old delegatee - (value_at): cast to kill warnings - (append_row): don't add the new attendee if they are already in - the list - -2001-07-24 Damon Chaplin <damon@ximian.com> - - * gui/dialogs/recurrence-page.c (get_exception_string): calculate - tmp_tm.tm_wday ourselves. strftime has a habit of crashing if you - have weird values here. I think this fixes bug #4574. - -2001-07-24 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/meeting-page.c (value_at): stip the delto and - delfrom - (popup_delegate_cb): show a delegate dialog and add the new - delegatee and update the delegator - (add_section): listen for changes in a more direct manner - (get_select_name_dialog): add_section now takes a limit argument - - * gui/dialogs/e-delegate-dialog.[hc]: New dialog to query the user - for a person to delegate to - - * gui/dialogs/Makefile.am: build/install new files - - * gui/Makefile.am: add ldadd line for ebook - -2001-07-21 Damon Chaplin <damon@ximian.com> - - * gui/e-week-view-event-item.c (e_week_view_event_item_draw): fixed - the test to see whether we should draw the icons. - -2001-07-22 Ettore Perazzoli <ettore@ximian.com> - - * gui/component-factory.c (get_local_file_name_for_folder_type): - New helper function. - (remove_folder): Add a @type arg and handle it, by deleting - "tasks.ics" instead of "calendar.ics" if the type is "tasks". If - the type is not "tasks" or "calendar", report an - `UNSUPPORTED_TYPE' error. - (xfer_folder): Likewise. - -2001-07-21 Ettore Perazzoli <ettore@ximian.com> - - * gui/component-factory.c: Make folders of type "calendar" and - "tasks" user-creatable by setting `user_creatable' to %TRUE in the - `EvolutionShellComponentFolderType's. - -2001-07-19 Federico Mena Quintero <federico@ximian.com> - - * gui/dialogs/event-editor.h (event_editor_update_widgets): - Removed unused prototype. - - * gui/dialogs/task-editor.h (task_editor_update_widgets): - Likewise. - -2001-07-19 JP Rosevear <jpr@ximian.com> - - * gui/e-itip-control.c (clean_up): free various data related - settings - (destroy): use cleanup and unref the clients - (e_itip_control_set_data): clean up before setting the data and - store the timezones in a top level component - (update_item): use cal_client_update_objects and our top level - (including the timezones) - -2001-07-19 Damon Chaplin <damon@ximian.com> - - * gui/dialogs/comp-editor.c (pixmaps): - * gui/calendar-commands.c (pixmaps): updated to use new print icon. - -2001-07-17 Damon Chaplin <damon@ximian.com> - - * gui/dialogs/recurrence-page.c (init_widgets): don't show the time - in the EDateEdit widget for adding EXDATEs. - - * cal-util/cal-component.c (cal_component_alarm_set_trigger): don't - set t.time.is_date to -1. It is a boolean flag, 0 or 1. We probably - don't want a date value, so we leave it at 0. - -2001-07-18 Rodrigo Moya <rodrigo@ximian.com> - - * gui/e-day-view-main-item.c (e_day_view_main_item_draw_day_event): - do not discard drawing icon if mask is NULL - - * gui/e-day-view-top-item.c (e_day_view_top_item_draw_long_event): - ditto - -2001-07-17 JP Rosevear <jpr@ximian.com> - - * gui/e-itip-control.c (get_next): find the next displayable - component - (get_prev): find the previous displayable component - (e_itip_control_set_data): use above - (prev_clicked_cb): ditto - (next_clicked_cb): ditto - -2001-07-17 Federico Mena Quintero <federico@ximian.com> - - Really fixes #4380. The previous fix was necessary but not - sufficient; it worked for me because my system timezone happens to - match the Evolution timezone --- if they don't match, the bug - would persist. Not matching is *not* an error; it is just a - matter of Unix sucking a lot and XST not being finished :) - - * cal-util/timeutil.c (time_to_gdate_with_zone): New function. We - cannot use g_date_set_time() anymore because it does not take - timezones into account. - - * gui/gnome-cal.c (get_days_shown): Use the function above. - - * gui/e-day-view.c (e_day_view_find_work_week_start): Likewise. - - * gui/e-week-view.c (e_week_view_set_selected_time_range): Likewise. - -2001-07-17 Jon Trowbridge <trow@ximian.com> - - * gui/dialogs/meeting-page.c (invite_entry_changed): Print - a g_message when the list of invited people changes - in the SelectNames control. - (add_section): #if 0/#endif out some (broken?) code. - (get_select_name_dialog): Listen for changes in the - SelectNames control. - -2001-07-17 Damon Chaplin <damon@ximian.com> - - * gui/dialogs/e-timezone-dialog.c (e_timezone_dialog_destroy): destroy - the dialog widget here. Fixes bug #4198. - -2001-07-16 Damon Chaplin <damon@ximian.com> - - * gui/dialogs/task-page.c (task_page_fill_widgets): - * gui/dialogs/event-page.c (event_page_fill_widgets): try to use - builtin timezones before getting them from the server. When creating - new events/tasks the timezones may not be on the server. - - * gui/dialogs/event-page.c (event_page_fill_widgets): for all-day - events we subtract a day from the end date rather than add it. - - * gui/dialogs/e-timezone-dialog.c (on_map_leave): ignore the event - if it isn't a GDK_CROSSING_NORMAL event. For some reason we are getting - leave events when the button is pressed, which meant that selecting - timezones in the map didn't work. - - * gui/dialogs/comp-editor-util.c (comp_editor_dates): - * gui/print.c (print_date_label): only free icaltimetype if not NULL. - -2001-07-12 Taylor Hayward <taylorhayward@yahoo.com> - - * gui/goto-dialog.glade: - * gui/meeting-mockup.glade: - * gui/alarm-notifyålarm-notify.glade: - * gui/dialogs/alarm-page.glade: - * gui/dialogs/meeting-page.glade: - * gui/dialogs/recurrence-page.glade: Added missing underlined - shortcuts. - -2001-07-12 JP Rosevear <jpr@ximian.com> - - * cal-util/cal-util.h: new proto - - * cal-util/cal-util.c (cal_util_new_top_level): standard place to - get your top level calendar component - - * pcs/cal-backend-file.c (create_cal): use it - - * gui/itip-utils.c (itip_send_comp): ditto - - * gui/e-calendar-table.c (e_calendar_table_copy_clipboard): ditto - -2001-07-12 JP Rosevear <jpr@ximian.com> - - * gui/e-calendar-table.c (e_calendar_table_copy_clipboard): fix - typo breaking compilation - - * gui/dialogs/meeting-page.c: fix include - - * gui/dialogs/Makefile.am: build select names idl here - - * gui/Makefile.am: remove select names compilation from here - -2001-07-12 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/task-details-page.c (task_details_page_set_dates): - guard against infinite loops with the updating boolean, fixes 4270 - -2001-07-12 Rodrigo Moya <rodrigo@ximian.com> - - * gui/e-calendar-table.c: added support for multiple selections in - cut/copy/paste. Also, it's now ready for the - s/update_object/update_objects change (I think) - -2001-07-11 Damon Chaplin <damon@ximian.com> - - * idl/evolution-calendar.idl: renamed updateObject to updateObjects - and removed the UID argument, since it can add/update multiple objects - at once. (It can't yet, but it will!) - - * pcs/cal.c: - * pcs/cal-backend.[hc]: - * pcs/cal-backend-file.c: renamed update_object to update_objects and - got rid of the UID arg. - - * cal-client/cal-client.c (cal_client_update_objects): new function to - add/update multiple objects in one go, i.e for iTIP and for importing - calendars. - - * gui/print.c (print_date_label): fixed type bug. - - * gui/e-week-view.[hc]: - * gui/e-week-view-event-item.c: draw the timezone icons if the event's - DTSTART or DTEND is in a different timezone to the current one. - Note that we may want to change this so it compares the UTC offsets - rather than the TZIDs, since currently it will draw the icons for all - events coming from iTIP requests from other clients. - -2001-07-11 Federico Mena Quintero <federico@ximian.com> - - Fixes bug #4380 as well as some leftovers from the days of struct - tm and some uninitialized values. - - * gui/gnome-cal.c - (gnome_calendar_on_date_navigator_selection_changed): Initialize - the icaltimetype structures completely. - (gnome_calendar_init): Do not reset priv->zone to NULL here, since - it was set by gnome_calendar_update_config_settings() from - setup_widgets(). - - * gui/calendar-model.c (set_completed): Do not set is_daylight. - - * gui/e-day-view.c (e_day_view_convert_grid_position_to_time): - Likewise. - - * gui/e-week-view.c (e_week_view_set_timezone): Likewise. - - * cal-util/cal-recur.c (generate_instances_for_chunk): Likewise, - and initialize start_tt and end_tt completely. - - * cal-util/timeutil.c (time_year_begin_with_zone): Likewise. - (time_month_begin_with_zone): Likewise. - (time_week_begin_with_zone): Likewise. - (time_day_begin_with_zone): Likewise. - (time_day_end_with_zone): Likewise. - (time_from_isodate): Likewise. - - * gui/dialogs/task-page.c (task_page_fill_component): Initialize - icaltime before using it. - - * gui/dialogs/event-page.c (event_page_fill_component): Likewise. - - * gui/dialogs/recurrence-page.c (simple_recur_to_comp): Removed an - unused icaltimetype. - - * gui/dialogs/task-details-page.c - (task_details_page_fill_component): Initialize icaltime before - using it. - -2001-07-11 JP Rosevear <jpr@ximian.com> - - * gui/component-factory.c: fix the calendar not exiting with a - gross hack because i don't have time to fix the ref counting right - now - -2001-07-11 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/meeting-page.c: be careful about adding and - stripping MAILTO:'s properly - - * gui/dialogs/meeting-page.etspec: add missing columns - - * gui/itip-utils.c (itip_strip_mailto): point to the real start of - the email address - - * gui/itip-utils.h: add proto - - * gui/itip-control-factory.c: get rid of the my address property - - * gui/e-itip-control.c: use the users real identity to figure out - which attendee they are - (find_my_address): figure out who the user is among the attendees - - * gui/e-itip-control.h: remove protos - - * gui/dialogs/Makefile.am: extra dist etspecs - - * gui/Makefile.am: ditto - -2001-07-11 Kjartan Maraas <kmaraas@gnome.org> - - * gui/e-calendar-table.c: Added a hack to get the last - string translated since xml-i18n-tools doesn't recognize - _click-to-add-message="Click here to add a task". - -2001-07-10 Peter Williams <peterw@ximian.com> - - * gui/Makefile.am (BUILT_SOURCES): Move this higher so that - Makefile properly depends on us. Fixes distcheck. - -2001-07-11 Jason Leach <jleach@ximian.com> - - [Fix bug #4389: ETableSpecification still in e-calendar-table.c - file] - - * gui/e-calendar-table.etspec: New file containing the spec that - was in e-calendar-table.c as a big string. - - * gui/e-calendar-table.c (e_calendar_table_init): Use the spec - file instead of a string. - (e_calendar_table_get_spec): Removed this function, we don't need - it anymore. - - * gui/e-tasks.c (e_tasks_setup_menus): Don't load from string, - from file instead. - - * gui/Makefile.am: Necessary changes to get the new .etspec file - installed. - -2001-07-10 Jason Leach <jleach@ximian.com> - - [Fix bug #4388: ETableSpecification still in meeting-page.c file] - - * gui/dialogs/meeting-page.etspec: New file containing the spec - that was previously in meeting-page.c as a string. - - * gui/dialogs/meeting-page.c: One line change to get it to use - this spec file instead of a string. - - * gui/dialogs/Makefile.am: Necessary changes to get the new - meeting-page.etspec installed. - -2001-07-10 Damon Chaplin <damon@ximian.com> - - * gui/calendar-model.c: - * gui/e-calendar-table.c: - * gui/e-day-view-main-item.c: - * gui/e-day-view-top-item.c: - * gui/e-day-view.[hc]: - * gui/e-week-view.c: - * gui/gnome-cal.c: - * gui/print.c: - * gui/dialogs/cal-prefs-dialog.c: - * gui/dialogs/comp-editor-util.c: - * gui/dialogs/event-page.c: - * pcs/cal-backend-file.c: - * pcs/query.c: - * cal-util/cal-component.[hc]: - * cal-util/cal-recur.c: - * cal-util/timeutil.[hc]: - * cal-client/cal-client.[hc]: more timezone updates. I'm pretty much - done with the calendar code now, except for alarms and conduits, - which Federico and JP know more about. And there are a couple of - other minor things to fix. But it is still pretty buggy. - -2001-07-10 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/meeting-page.c: Add popup support so you can delete - users from the list - - * gui/dialogs/comp-editor.c (setup_widgets): fix typo - -2001-07-10 Federico Mena Quintero <federico@ximian.com> - - * gui/alarm-notify/alarm-queue.c (alarm_trigger_cb): Handle the - different alarm actions. - (display_notification): Do the alarm notification dialog here. - - * gui/alarm-notify/alarm-notify-dialog.c (make_heading): Take in a - CalComponentVType, not a whole component. - (alarm_notify_dialog): Take in a CalComponentVType and the final - message instead of generating it ourselves. - -2001-07-09 Federico Mena Quintero <federico@ximian.com> - - * pcs/cal-backend-file.c (generate_alarms_for_comp): Pass the - parent vCalendar component as the timezone closure of - cal_recur_generate_instances(). - - * gui/dialogs/alarm-page.c (get_alarm_string): Make the string - consistent with the option menu text. - (get_alarm_string): Removed extra spaces from the last part of the - alarm string. - -2001-07-09 Federico Mena Quintero <federico@ximian.com> - - * gui/e-day-view.c (e_day_view_key_press): Use - e_utf8_from_gtk_event_key() so that we can input utf8 text - properly. - (e_day_view_cut_clipboard): Constify. - (e_day_view_on_cut): Constify. - (e_day_view_reshape_long_event): Remove unused variable. - - * gui/e-week-view.c (e_week_view_key_press): Use - e_utf8_from_gtk_event_key() so that we can input utf8 text - properly. - (e_week_view_cut_clipboard): Constify. - (e_week_view_on_cut): Constify. - - * cal-client/cal-client.c (cal_client_resolve_tzid_cb): Fix the - prototype so that this matches CalRecurResolveTimezoneFn. Also - renamed it so that it is clear that it is supposed to be a - callback. - -2001-07-06 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/meeting-page.c (init_widgets): connect to the entry - not the combo - - * gui/dialogs/event-editor.c (set_menu_sens): set menu - sensitivities based on whether or not the meeting page is shown - (event_editor_init): call above - (event_editor_edit_comp): ditto - (schedule_meeting_cmd): ditto - - * gui/dialogs/comp-editor.h: new proto - - * gui/dialogs/comp-editor.c (comp_editor_set_ui_prop): new - function to allow for set of ui props (esp. "sensitive") - -2001-07-06 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/meeting-page.c (clear_widgets): actually clear some - widgets and hide/show widgets in the default setup - (meeting_page_destroy): destroy the address lists - (meeting_page_fill_widgets): allow the user to select among their - identities as a new organizer, or show the existing organizer as - label - (meeting_page_fill_component): set the "MAILTO:" bit of the - organizer to match spec, set CN properly if we know it - (get_widgets): load new widgets - (other_clicked_cb): handle "Other Organizer" click - (change_clicked_cb): handle "Change Organizer" click - (init_widgets): listen for clicks on new buttons - - * gui/dialogs/comp-editor.c (comp_editor_remove_page): remove the - page from our internal list and unref it - - * gui/itip-utils.c (itip_addresses_get): get the configure mail - identities - (itip_addresses_free): free a list of identities returned by - itip_addresses_get - - * gui/itip-utils.h: remove obsolete protos, and new protos - - * gui/gnome-cal.html: Remove ancient file - -2001-07-04 Federico Mena Quintero <federico@ximian.com> - - Fixes bug #4018 and what would be the analogous bugs for the other - component editors. - - * gui/dialogs/comp-editor-page.h (CompEditorPageClass): New - virtual method "::focus_main_widget()". - - * gui/dialogs/comp-editor-page.c - (comp_editor_page_focus_main_widget): New function. - - * gui/dialogs/comp-editor.c (comp_editor_append_page): If we are - inserting the main page, ask it to focus its main widget. - - * gui/dialogs/alarm-page.c (alarm_page_focus_main_widget): - Implemented. - - * gui/dialogs/event-page.c (event_page_focus_main_widget): - Implemented. - #include "e-util/e-categories-config.h". - - * gui/dialogs/meeting-page.c (meeting_page_focus_main_widget): - Implemented. - - * gui/dialogs/recurrence-page.c - (recurrence_page_focus_main_widget): Implemented. - - * gui/dialogs/task-details-page.c - (task_details_page_focus_main_widget): Implemented. - - * gui/dialogs/task-page.c (task_page_focus_main_widget): - Implemented. - -2001-07-04 Federico Mena Quintero <federico@ximian.com> - - * gui/calendar-commands.c (clear_folder_bar_label): New function. - (calendar_control_activate): Clear the folder bar label; we really - don't have anything interesting to display. - -2001-07-03 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/meeting-page.c: Add new columns for information - specification - (meeting_page_destroy): save the table state - (build_etable): load new table state - - * gui/dialogs/task-editor.c (task_editor_destroy): unref pages - - * gui/dialogs/event-editor.c (event_editor_destroy): unref pages - - * gui/dialogs/comp-editor.c (setup_widgets): kill warning - (comp_editor_append_page): ref page passed in - (close_dialog): unref pages - -2001-07-03 Damon Chaplin <damon@ximian.com> - - * gui/e-day-view.c (query_obj_updated_cb): fix warning, and added - some debug messages. - - * gui/dialogs/comp-editor-util.c (write_label_piece): - * gui/e-day-view-top-item.c (e_day_view_top_item_draw): call mktime() - to set the weekday, though this is a temporary fix. - -2001-07-03 Damon Chaplin <damon@ximian.com> - - * pcs/cal-backend.[hc]: added virtual method to get a VTIMEZONE - component given a TZID. We need this to resolve TZIDs when expanding - an event using cal_recur_generate_instances() in query.c. - - * pcs/cal-backend-file.c (cal_backend_file_get_timezone): implemented - virtual method. - (cal_backend_file_update_object): fixed bug, kind -> child_kind. - - * pcs/query.c (func_occur_in_time_range): use the virtual method for - resolving TZIDs. The other way didn't work anyway, as we didn't have - the entire VCALENDAR with VTIMEZONEs in it. - - * gui/dialogs/recurrence-page.c (init_widgets): - (make_ending_until_special): moved the call to - e_date_edit_set_get_time_callback() from init_widgets to - make_ending_until_special(), since that is where the widget gets - created. - - * gui/e-timezone-entry.c (e_timezone_entry_set_timezone): handle zone - being NULL. - -2001-07-02 Federico Mena Quintero <federico@ximian.com> - - * gui/dialogs/alarm-options.[ch]: New files with the alarm options - dialog; this configures the repeat/duration properties and the - options specific to each alarm action type. - - * gui/dialogs/alarm-page.c (AlarmPagePrivate): Added the alarm - options button. Also, keep an alarm structure which we are - editing and an alarm options dialog. - (init_widgets): Connect to the options button. - (add_clicked_cb): Clone the component we are editing instead of - creating a new one so that we preserve the data from the alarm - options dialog. - (button_options_clicked_cb): Pop up the alarm options dialog. - - * cal-util/cal-component.c (cal_component_alarm_new): Doh, - initialize the other fields in the new alarm. - -2001-07-03 Damon Chaplin <damon@ximian.com> - - * cal-client/cal-client.[hc] - * cal-util/cal-component.c - * cal-util/cal-recur.[hc] - * cal-util/test-recur.c - * cal-util/timeutil.c - * gui/calendar-config.c - * gui/calendar-model.[hc] - * gui/comp-util.[hc] - * gui/e-calendar-table.c - * gui/e-day-view-main-item.c - * gui/e-day-view-top-item.c - * gui/e-day-view.[hc] - * gui/e-itip-control.c - * gui/e-timezone-entry.[hc] - * gui/e-week-view.[hc] - * gui/gnome-cal.[hc] - * gui/goto.c - * gui/tag-calendar.[hc] - * gui/dialogs/cal-prefs-dialog.c - * gui/dialogs/comp-editor-page.[hc] - * gui/dialogs/comp-editor-util.[hc] - * gui/dialogs/comp-editor.c - * gui/dialogs/e-timezone-dialog.[hc] - * gui/dialogs/event-page.c - * gui/dialogs/meeting-page.c - * gui/dialogs/recurrence-page.c - * gui/dialogs/task-details-page.c - * gui/dialogs/task-details-page.glade - * gui/dialogs/task-page.c - * idl/evolution-calendar.idl - * pcs/cal-backend-file.c - * pcs/cal-backend.c - * pcs/cal-backend.h - * pcs/cal.c - * pcs/query.c: timezone changes everywhere. There's still quite a - few things to update, and its not working well at present. - -2001-07-02 JP Rosevear <jpr@ximian.com> - - * gui/calendar-commands.c (publish_freebusy_cmd): publish - free/busy information for the currently viewed time range - -2001-07-02 Christopher James Lahey <clahey@ximian.com> - - * gui/Makefile.am (INCLUDES): Added $(BONOBO_CONF_CFLAGS). - (evolution_calendar_LDADD): Added $(BONOBO_CONF_LIBS). - -2001-07-02 Federico Mena Quintero <federico@ximian.com> - - Support for ATTACH, DESCRIPTION properties in alarm components. - - * cal-util/cal-component.c (scan_alarm_property): Deal with - ATTACH, DESCRIPTION properties. - (cal_component_alarm_get_attach): New function. Libical is - actually bogus; supposedly icalattachtype structures are - refcounted but the property functions return them by value. - (cal_copmonent_alarm_set_attach): New function. - (cal_component_alarm_get_description): New function. - (cal_component_alarm_set_description): New function. - -2001-07-02 Federico Mena Quintero <federico@ximian.com> - - Support for repeat/duration properties in alarm components. - - * cal-util/cal-component.h (CalAlarmRepeat): New structure that - pairs the repeat/duration values of an alarm component, which must - be set both together or not set at all. - - * cal-util/cal-component.c (CalComponentAlarm): Added fields for - the repeat and duration properties. - (scan_alarm_property): Scan the DURATION and REPEAT properties. - (make_alarm): Nullify/initialize all the fields in the alarm. - (cal_component_alarm_get_repeat): New function. - (cal_component_alarm_set_repeat): New function. - - * gui/dialogs/alarm-page.glade: Changed the label of display - alarms from "Show a dialog" to "Display a message". - -2001-07-02 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/task-details-page.c - (task_details_page_fill_widgets): fill in delegated from field - -2001-07-02 Rodrigo Moya <rodrigo@ximian.com> - - * gui/dialogs/task-page.c (categories_clicked_cb): - * gui/dialogs/event-page.c (categories_clicked_cb): use the new - self-contained e_categories_config_open_dialog_for_entry() function - - * gui/e-week-view-event-item.c (e_week_view_item_draw_icons): - * gui/e-day-view-top-item.c (e_day_view_reshape_long_event): - (e_day_view_reshape_day_event): ditto - * gui/e-day-view-main-item.c (e_day_view_main_item_draw_day_event): - use e_categories_config_get_icon_for() to retrieve the icon - associated with each category - -2001-07-02 JP Rosevear <jpr@ximian.com> - - * gui/e-itip-control.c (send_freebusy): implement - - * cal-util/cal-component.c (set_attendee_list): add the delto - property rather than the delfrom property twice - - * gui/dialogs/task-editor.c (task_editor_edit_comp): show - delegation info if appropriate - (delegate_task_cmd): delegate command - (cancel_task_cmd): cancel command - (refresh_task_cmd): refresh command - - * gui/dialogs/task-details-page.c: Load new widgets - (task_details_page_show_delegation): show/hide delegation info widgets - - * gui/dialogs/task-details-page.h: new proto - - * gui/dialogs/event-editor.c (event_editor_edit_comp): free - attendee list when finished - - * gui/dialogs/comp-editor.c (setup_widgets): explicitly show the - widgets, update pixmaps after the verbs have been added - (comp_editor_focus): don't do a show all - -2001-07-02 Federico Mena Quintero <federico@ximian.com> - - Fixes bug #1406. - - * gui/calendar-config.c (config_read): Handle the options for the - task list colors. - (calendar_config_write): Ditto. - (calendar_config_get_tasks_due_today_color): New function. - (calendar_config_set_tasks_due_today_color): New function. - (calendar_config_get_tasks_overdue_color): New function. - (calendar_config_set_tasks_overdue_color): New function. - (calendar_config_configure_e_calendar_table): Use - e_table_model_changed() for the colors. - - * gui/dialogs/cal-prefs-dialog.glade: Updated the options for the - task list and alarms. - - * gui/dialogs/cal-prefs-dialog.c (cal_prefs_dialog_show_config): - Update the task list settings. - (cal_prefs_dialog_update_config): Ditto. - - * gui/calendar-model.c (get_color): Deal with tasks for today as - well as overdue tasks. Make it cleaner, even though we have to - duplicate a chunk of is_overdue(). - - * gui/calendar-commands.c (preferences_cmd): Renamed from - properties_cmd(). - -2001-07-01 Rodrigo Moya <rodrigo@ximian.com> - - * gui/e-day-view-main-item.c - (e_day_view_main_item_draw_day_event): draw icons per category - - * gui/e-day-view-top-item.c - (e_day_view_top_item_draw_long_event): draw icons per category - - * gui/e-day-view.c - (e_day_view_reshape_long_event): - (e_day_view_reshape_day_event): calculate space for category icons - - * gui/e-week-view-event-item.c - (e_week_view_event_item_draw_icons): draw icons per category - - * gui/e-week-view.c - (e_week_view_reshape_event_span): calculate space for category icons - -2001-07-01 Rodrigo Moya <rodrigo@ximian.com> - - * gui/e-day-view.c (e_day_view_*_clipboard): fixed clibpoard - command activation from the menu entries. CTRL-C and CTRL-X don't - work though, since it seems the key presses are being captured by - the text item - - gui/e-week-view.c (e_week_view_*_clipboard): ditto - -2001-06-30 Federico Mena Quintero <federico@ximian.com> - - * gui/e-week-view-event-item.c - (e_week_view_event_item_button_press): Only set the - pressed_event_num and pressed_span_num if button 1 was pressed. - Fix up return values a bit. This fixes bug #3780. - - * gui/gnome-cal.c - (gnome_calendar_on_date_navigator_selection_changed): Doh, the - call for the day view was supposed to be - gnome_calendar_set_view(), not set_view(). Fixes bug #3779. - -2001-06-30 Rodrigo Moya <rodrigo@ximian.com> - - * gui/tasks-control.c (tasks_control_cut_cmd): call - e_calendar_table_cut_clipboard with the correct object - - (tasks_control_copy_cmd): ditto - - (sensitize_commands): sensitize clipboard commands based on the - number of selected tasks - -2001-06-28 Rodrigo Moya <rodrigo@ximian.com> - - * gui/e-calendar-table.[ch] (e_calendar_table_cut_clipboard), - (e_calendar_table_copy_clipboard), - (e_calendar_table_paste_clipboard): new functions for allowing the - execution of clipboard-related commands - - * gui/tasks-control.c (tasks_control_cut_cmd), - (tasks_control_copy_cmd), (tasks_control_paste_cmd): added - callbacks for the new clipboard-related menu entries - -2001-06-28 Rodrigo Moya <rodrigo@ximian.com> - - * gui/component-factory.c: removed not-uses-anymore parameter in - call to evolution_shell_component_new - - * gui/gnome-cal.[ch] (gnome_calendar_cut_clipboard), - (gnome_calendar_copy_clipboard), (gnome_calendar_paste_clipboard): - new functions for allowing execution of clipboard-related commands - - * gui/e-day-view.[ch] (e_day_view_cut_clipboard), - (e_day_view_copy_clipboard), (e_day_view_paste_clipboard): ditto - - * gui/e-week-view.[ch] (e_week_view_cut_clipboard), - (e_week_view_copy_clipboard), (e_week_view_paste_clipboard): ditto - -2001-06-27 Rodrigo Moya <rodrigo@ximian.com> - - * gui/calendar-commands.c (cut_event_cmd), - (copy_event_cmd), (paste_event_cmd): added callbacks for the new - clipboard-related menu entries - -2001-06-27 Ettore Perazzoli <ettore@ximian.com> - - * gui/component-factory.c (factory_fn): Pass NULL as the - @external_uri_schemas argument to - `evolution_shell_component_new()'. - -2001-06-27 Peter Williams <peterw@ximian.com> - - * conduits/*/Makefile.am (INCLUDES): More srcdir != builddir - fixes. - -2001-06-27 Rodrigo Moya <rodrigo@ximian.com> - - * gui/e-calendar-table.c (selection_received): fixed - (e_calendar_table_on_copy): fixed - -2001-06-26 Federico Mena Quintero <federico@ximian.com> - - * idl/evolution-calendar.idl (CalAlarmInstance): Renamed the occur - field to occur_start; added an occur_end field. This way we can - present the complete times for the occurrence from the server. - - * cal-util/cal-component.h (CalAlarmInstance): Likewise. - - * pcs/cal-backend-file.c (add_alarm_occurrences_cb): Fill the new - fields appropriately. - (generate_absolute_triggers): Likewise; we use -1 in case the - component has no DTSTART or DTEND because there are no meaningful - occurrence dates here. - (fill_alarm_instances_seq): Fill in the new fields. - - * cal-client/cal-client.c (build_alarm_instance_list): Likewise. - - * gui/alarm-notify/alarm-notify-dialog.c (alarm_notify_dialog): - Take in both the occur_start and occur_end times. - - * gui/goto.c (goto_dialog): Free the dlg structure on the bail-out - cases. - - * gui/dialogs/event-page.c (get_widgets): Do not assert if we - cannot find the main widget; just return FALSE. - - * gui/dialogs/alarm-page.c (get_widgets): Likewise. - - * gui/dialogs/task-page.c (get_widgets): Likewise. - - * gui/dialogs/task-details-page.c (get_widgets): Likewise. - - * gui/dialogs/meeting-page.c (get_widgets): Likewise. - -2001-06-25 Peter Williams <peterw@ximian.com> - - * conduits/calendar/Makefile.am (INCLUDES): Fixes for - srcdir != builddir. Link to the static libwombat. - - * conduits/todo/Makefile.am (INCLUDES): Here too. - -2001-06-24 Federico Mena Quintero <federico@ximian.com> - - * gui/alarm-notify/notify-main.c (main): Initialize libglade. - - * pcs/cal-backend-file.c (compute_alarm_range): - icaldurationtype_as_int() will now return a negative value if - dur->is_neg is true, so we need to flip the sign of some - operations here. - (add_alarm_occurrences_cb): Likewise. - - * pcs/cal-backend-db.c (compute_alarm_range): Likewise. - (add_alarm_occurrences_cb): Likewise. - -2001-06-24 Federico Mena Quintero <federico@ximian.com> - - * gui/alarm-notify/alarm-notify.c: Converted to use BonoboXObject. - - * gui/gnome-cal.c (gnome_calendar_open): Ask the alarm - notification service to add the calendar and tasks URIs. - (add_alarms): New function. - - * gui/alarm-notify/notify-main.c (main): Doh, fixed typo in the - OAFIID. - (main): Initialize and shut down gnome-vfs. - - * gui/Makefile.am (IDLS): Added evolution-calendar.idl, sigh. - (evolution_calendar_SOURCES): Added the files generated from the IDL. - - * gui/alarm-notify/alarm-queue.c (alarm_trigger_cb): New function - used when an alarm is triggered. - - * gui/dialogs/Makefile.am: Removed the alarm-notify-dialog files; - they are now in gui/alarm-notify. - - * gui/alarm-notify/Makefile.am: Added the alarm-notify-dialog - files. - - * pcs/cal.c (cal_forget_password): This was incorrectly named - cal_client_forget_password(); renamed it. - - * gui/main.c (main): Initialize and shut down gnome-vfs. - -2001-06-23 Federico Mena Quintero <federico@ximian.com> - - * gui/e-calendar-table.c (task_compare_cb): New function to - compare tasks like the Pilot task list. - - * cal-util/cal-component.h (CalComponentField): Added a - semi-hackish CAL_COMPONENT_FIELD_COMPONENT. In the ETable model, - it is intended to return a pointer to the component itself. - - * gui/calendar-model.c (calendar_model_value_at): Return the - component itself for CAL_COMPONENT_FIELD_COMPONENT. Be more - paranoid about invalid columns. - (calendar_model_set_value_at): Be more paranoid about invalid - columns. - (calendar_model_duplicate_value): Ref the component field. - (calendar_model_initialize_value): Deal with the component field. - (calendar_model_value_is_empty): Likewise. - (calendar_model_value_to_string): Likewise. - -2001-06-22 Jeffrey Stedfast <fejj@ximian.com> - - * gui/Makefile.am: Added itip-control-factory.* to the build. - -2001-06-22 Rodrigo Moya <rodrigo@ximian.com> - - * pcs/cal.[ch] (cal_get_password): new function for the backends to - be able to call the getPassword method on the associated - WombatClient - (cal_forget_password): ditto for the forgetPassword method - -2001-06-22 Rodrigo Moya <rodrigo@ximian.com> - - * idl/evolution-calendar.idl: changed getFreeBusy method to return - a CalObj instead of a sequence - - * cal-client/cal-client.[ch] (cal_client_get_free_busy): changed it to - work like the cal_client_get_object function, that is, it does not - return anymore a list of UIDs, but a CalClientGetStatus code, and - added a new parameter for the caller to get the component back when - this function returns - (cal_client_open): aggregate WombatClient interface to the CalListener - being used - - * pcs/cal-backend-db.c, pcs/cal-backend-file.c (..get_free_busy): set - return value to "char *" as it will be returning a FreeBusy object, - and not a list of UIDs - - * pcs/cal-backend.[ch] (cal_backend_get_free_busy): ditto - - * pcs/cal.c (cal_construct): queryInterface on the listener to obtain - the WombatClient interface - -2001-06-21 JP Rosevear <jpr@ximian.com> - - * gui/main.c (main): update to new call - - * gui/e-itip-control.[hc]: break the widget bits out on their own - into a proper object, basic stuff seems to be working again - - * gui/itip-control-factory.c: put the control specific bits here - from e-itip-control.c - - * gui/itip-control-factory.h: new header - -2001-06-21 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/Makefile.am (gladedir): add include path - - * gui/dialogs/comp-editor.c (setup_widgets): remove buttons and - use evolution's standard ui config - - * gui/print.c (print_comp_item): print description text - -2001-06-21 Rodrigo Moya <rodrigo@ximian.com> - - * cal-client/cal-client.[ch]: - (cal_client_init): create a WombatClient when creating a CalClient - object, so that we can receive authentication notifications from - the wombat - (cal_client_destroy): destroy the WombatClient object when dying - (cal_client_set_auth_func): new function to set the authentication - function to be called when a password is required by the calendar - server (through the WombatClient object) - (cal_client_get_free_busy): new function for calling the new IDL - method Cal::getFreeBusy - - * gui/alarm-notify/Makefile.am: add libwombat to LDADD - - * gui/Makefile.am: add libwombat to LDADD - -2001-06-20 Dave Camp <dave@ximian.com> - - * gui/itip-utils.c (itip_send_comp): Changed attach_data - to be a GNOME_Evolution_Composer_AttachmentData rather than a - CORBA_char*. - -2001-06-20 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/comp-editor.c (print_cmd): print menu command - (print_preview_cmd): ditto for print preview - (print_setup_cmd): ditto for print setup - (comp_editor_set_cal_client): listen for updated and removed - signals - (obj_updated_cb): if the item changes else where, query the user - for the course of action - (obj_removed_cb): ditto for removal - - * gui/print.c (print_setup): rudimentary page setup support - (print_comp): rudimentary individual event/task printing support - - * gui/print.h: new protos - - * gui/dialogs/changed-comp.[hc]: dialog to query the user about - what to do when a item is changed elsewhere - - * gui/dialogs/Makefile.am: build new files - - * gui/dialogs/send-comp.c (send_component_dialog): remove useless - assignment - -2001-06-20 Rodrigo Moya <rodrigo@ximian.com> - - * idl/evolution-calendar.idl: added getFreeBusy method - - * pcs/cal.c (impl_Cal_get_free_busy): implementation of the new - getFreeBusy added method - - * pcs/cal-backend.[ch]: added new virtual method to the CalBackend - class (get_free_busy) - - * pcs/cal-backend-db.c (cal_backend_db_get_free_busy): new function, - not implemented yet - - * pcs/cal-backend-file.c (cal_backend_file_get_free_busy): new funtion, - not implemented yet - -2001-06-20 Damon Chaplin <damon@ximian.com> - - * gui/calendar-config.[hc]: - * gui/gnome-cal.[hc]: - * gui/tasks-control.c (tasks_control_activate): - * gui/calendar-commands.c (calendar_control_activate): moved the - function to check for a default timezone to calendar-config.c, and - also used it in the tasks control. - - * gui/dialogs/e-timezone-dialog.h: #include <gtk/gtkwidget.h> fix. - -2001-06-20 Damon Chaplin <damon@ximian.com> - - * gui/calendar-commands.c (calendar_control_activate): - * gui/gnome-cal.[hc]: added code to show the timezone dialog if the - user hasn't set a default timezone yet. - - * gui/dialogs/e-timezone-dialog.c (e_timezone_dialog_add_timezones): - set the "None" item string before adding it to the combo, to stop the - combo putting "None" in the entry initially. - -2001-06-19 Rodrigo Moya <rodrigo@ximian.com> - - * gui/e-calendar-table.[ch]: added cut/copy/paste support. It works - with single selections (a single component selected) and with - multiple ones (several components selected) - -2001-06-19 Damon Chaplin <damon@ximian.com> - - * gui/dialogs/event-page.c: if the timezones of the start and end of - the event are the same, then if the start timezone is changed we - change the end timezone as well, since that is what most users will - want. - -2001-06-19 Damon Chaplin <damon@ximian.com> - - * pcs/cal.c: - * idl/evolution-calendar.idl: - * cal-client/cal-client.[hc]: removed stuff to get builtin timezone - info from the server. - -2001-06-19 Damon Chaplin <damon@ximian.com> - - * gui/dialogs/cal-prefs-dialog.c: added a 'Time zone' setting. Also - rearranged a little, adding a new 'General' page, since we had too - many settings on the 'Calendar' page. - - * gui/e-timezone-entry.[hc]: - * gui/dialogs/e-timezone-dialog.[hc]: - * gui/dialogs/comp-editor.c: - * gui/dialogs/comp-editor-page.[hc]: - * gui/dialogs/event-page.c: - * gui/dialogs/task-details-page.c: - * gui/dialogs/task-page.c: removed CalClient stuff. The timezone dialog - now uses the timezone data directly from the client's libical library. - -2001-06-19 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/task-editor.c (task_editor_init): add ui - (forward_cmd): implement forward command - - * gui/dialogs/comp-editor.c (save_as_ok): bug fix, seems to work - now - -2001-06-19 JP Rosevear <jpr@ximian.com> - - * gui/control-factory.c (control_factory_init): add auto exit unref - - * gui/component-factory.c (destroy_cb): destroy our selves if we - have no more shells - (component_factory_init): add auto exit unref - -2001-06-19 JP Rosevear <jpr@ximian.com> - - * gui/Makefile.am: don't compile or install the old meeting edit - stuff - - * gui/e-week-view.c: ditto - - * gui/e-day-view.c: Remove scheduling menu option - -2001-06-19 JP Rosevear <jpr@ximian.com> - - * gui/itip-utils.c: add some needed commas - (itip_send_comp): if publishing, don't set the to list and show - the message. unless publishing, just send the email - - * gui/Makefile.am: remove typo - -2001-06-19 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/send-comp.c: itip/imip send dialog - - * gui/dialogs/send-comp.h: new proto - - * gui/dialogs/recurrence-page.c (recurrence_page_set_dates): only - use the weekday picker if visible - - * gui/dialogs/meeting-page.c: just show the meeting list - - * gui/dialogs/event-editor.c (event_editor_edit_comp): remove the - meeting page if no attendees - (schedule_meeting_cmd): schedule a meeting menu item - (refresh_meeting_cmd): refresh meeting request menu item - (cancel_meeting_cmd): ditto for cancel - (forward_cmd): send as attachment - - * gui/dialogs/comp-editor.c (comp_editor_remove_page): remove page - from dialog - (comp_editor_show_page): show a given page - (comp_editor_get_current_comp): return a cal component - representing the current widget state - (comp_editor_save_comp): save the cal component - (comp_editor_delete_comp): delete the cal component - (comp_editor_send_comp): send the cal component - (comp_editor_merge_ui): merge xml in to the bonobo gui - (setup_widgets): use a bonobo window instead of a gtk window, add menus again - (save_as_cmd): save to file on disk - still broken - (save_close_cmd): close menu command - (save_close_cmd): save and close menu command - - * gui/dialogs/comp-editor.h: new protos - - * gui/dialogs/cancel-comp.c (cancel_component_dialog): itip/imip - cancellation dialog - - * gui/dialogs/cancel-comp.h: new proto - - * gui/dialogs/Makefile.am: build new files - - * gui/dialogs/comp-editor-page.c - (comp_editor_page_notify_needs_send): emit needs_send signal - - * gui/dialogs/comp-editor-page.h: new signal protos - - * gui/itip-utils.c (itip_send_comp): new function to send cal - components - - * gui/itip-utils.h: new proto - - * gui/e-itip-control.c (pstream_load): trim using cal-component - wrapper stuff - (accept_button_clicked_cb): use itip_send_comp - (tentative_button_clicked_cb): ditto - (decline_button_clicked_cb): ditto - - * gui/Makefile.am: compile select name idl stuff - - * cal-util/cal-component.c (cal_component_get_organizer): get the organizer - (cal_component_set_organizer): set the organizer - (cal_component_get_recurid): get the recurrence id - (cal_component_set_recurid): set the recurrence id - (set_attendee_list): actually set the attendee list - (get_attendee_list): build the attendee list - - * cal-util/cal-component.h: new protos - -2001-06-19 Damon Chaplin <damon@ximian.com> - - * gui/dialogs/task-details-page.glade: - * gui/dialogs/task-page.glade: - * gui/dialogs/event-page.glade: added timezone fields. Also moved the - 'All Day' flag into an alignment so it doesn't mess up the height of - the other widgets. - - * gui/dialogs/task-details-page.c: - * gui/dialogs/task-page.c: - * gui/dialogs/event-page.c: added code to handle the timezone fields. - This still needs to be hooked up when the libical code is finished. - - * gui/dialogs/e-timezone-dialog.c (on_map_leave): new function to - clear the preview label and turn off the highlighted point on the - map when you move the mouse outside it. - (find_selected_point): new function to try to find the point - corresponding to the text in the combo. - (on_combo_changed): call the above function to update the selected - point. - (on_map_leave): turn off the preview point & label when the mouse - leaves the map. - (e_timezone_dialog_set_cal_client): changed it so that selecting "None" - clears the entry. - - * gui/dialogs/comp-editor-page.[hc]: added set_cal_client() virtual - method since some pages need to access the CalClient to get timezone - information. Also added comp_editor_page_set_cal_client() to call - the virtual method. - - * gui/dialogs/comp-editor.c (comp_editor_set_cal_client): called - comp_editor_page_set_cal_client() on each page. - - * gui/calendar-config.c: added functions to get & set the timezone. - -2001-06-18 Eskil Heyn Olsen <eskil@eskil.dk> - - * conduits/calendar/calendar-conduit.c: (comp_from_remote_record), - (check_for_slow_setting), (conduit_get_gpilot_conduit): - * conduits/todo/todo-conduit.c: (check_for_slow_setting), - (conduit_get_gpilot_conduit): - Tweaked for some gnome-pilot api changes - -2001-06-15 Federico Mena Quintero <federico@ximian.com> - - * gui/calendar-view.[ch]: New files with the generic calendar view - object. It sucks that we have to implement at least two classes - to define a GalView and its factory. - - * gui/calendar-view-factory.[ch]: New files; factory for calendar - views. - - * gui/gnome-cal.h (GnomeCalendarViewType): Moved from gnome-cal.c - and renamed from ViewType. We no longer use strings to identify - the view types. - - * gui/gnome-cal.c (gnome_calendar_get_view_type): New function. - (set_view): Renamed from gnome_calendar_set_view_internal(). - (gnome_calendar_set_query): Made public; renamed from set_query(). - (gnome_calendar_setup_view_menus): New function to set up the view - collection and the GalViewMenus. - (gnome_calendar_discard_view_menus): New function to discard them. - - * gui/calendar-commands.c (calendar_control_activate): Set up the - GalView menus. - (calendar_control_deactivate): Discard the GalView menus. - - * gui/e-day-view.c: #include <gtk/gtkinvisible.h> - - * gui/dialogs/comp-editor.c (comp_editor_get_type): The type info - structure should be static. - -2001-06-15 Rodrigo Moya <rodrigo@ximian.com> - - * gui/e-day-view.c (selection_received): generate a new UID - when pasting - - * gui/e-week-view.c (selection_received): ditto - -2001-06-15 Rodrigo Moya <rodrigo@ximian.com> - - * gui/e-day-view.c (selection_received): finished implementation - of Paste stuff - - * gui/e-week-view.c (selection_received): ditto - -2001-06-14 Rodrigo Moya <rodrigo@ximian.com> - - * gui/e-day-view.[ch]: added popup menu items for cut/copy/paste - - * gui/e-week-view.[ch]: ditto - -2001-06-14 Damon Chaplin <damon@ximian.com> - - * gui/e-timezone-entry.[hc]: new widget to enter a timezone. - - * gui/Makefile.am (evolution_calendar_SOURCES): added the above. - * gui/Makefile.am (evolution_calendar_LDADD): had to move - libcal-dialogs.a above libmiscwidgets.a to get it to compile. - -2001-06-14 Damon Chaplin <damon@ximian.com> - - * gui/dialogs/e-timezone-dialog.[hc]: - * gui/dialogs/e-timezone-dialog.glade: new dialog for setting the - time zone. - - * gui/dialogs/Makefile.am: added timezone dialog files. - - * idl/evolution-calendar.idl: added CalTimezoneInfo struct and seq, - and getBuiltinTimezoneInfo method. - - * pcs/cal.c (impl_Cal_get_builtin_timezone_info): implemented method. - (cal_class_init): added method to epv. - - * cal-client/cal-client.c (struct CalClientPrivate): added - timezone_info array to contain cached info on builtin timezone city - names and coordinates. - (cal_client_get_builtin_timezone_info): new function to get the info - about builtin timezones. - - * cal-client/cal-client.h: added CalTimezoneInfo struct, to contain - the city names and coords of the builtin timezones. - -2001-06-13 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/comp-editor-util.c (comp_editor_date_label): remove - unnecessary space - - * gui/dialogs/task-page.c (task_page_set_summary): indicate we are - updating, Fixes #3307 - -2001-06-13 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/task-details-page.c (task_details_page_set_dates): - set the completed time in the date editor if appropriate - - * gui/dialogs/task-page.c (task_page_set_dates): if we are - updating, return - (complete_date_changed): don't returns if we are updating - the - guards are done in the calling function - (status_changed): indicate when we are updating and when we are - finished, round the completion time to the nearest minute - (percent_complete_changed): indicate when are updating and when we - are finished - (percent_complete_changed): notify of the date change after the - option menu is updated - -2001-06-11 Rodrigo Moya <rodrigo@ximian.com> - - * gui/e-day-view.[ch]: added cut&paste support, by using a GtkInvisible - widget to manage the clipboard selections. - - * gui/e-week-view.[ch]: ditto - -2001-06-08 Iain Holmes <iain@ximian.com> - - * gui/component-factory.c: Removed the executive-summary includes. - (component_factory_init): Don't init the summary factory. - - * gui/calendar-summary.[ch]: Removed. - - * gui/Makefile.am: Remove executive-summary stuff, move some libs - around a bit. - -2001-06-04 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/recurrence-page.c (recurrence_page_set_dates): - update the blocked/selected days if the starting day of the - appointment changes, fixes #2188 - - * gui/dialogs/task-details-page.h: tidy proto - -2001-06-03 Ettore Perazzoli <ettore@ximian.com> - - * gui/e-itip-control.c: #include <bonobo/bonobo-context.h> instead - of <bonobo/bonobo-running-context.h>. - * gui/tasks-control-factory.c: Likewise. - - * gui/Makefile.am (evolution_calendar_LDADD): Move `$(DB3_LDADD)' - before libeutil. - -2001-06-01 JP Rosevear <jpr@ximian.com> - - * gui/Makefile.am: no longer build widget-util.*, the code has - been moved - -2001-06-01 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/event-page.c (make_date_edit): use new func - - * gui/dialogs/task-details-page.c - (task_details_page_create_date_edit): ditto - - * gui/dialogs/recurrence-page.c (make_ending_until_special): ditto - - * gui/dialogs/comp-editor-util.c (comp_editor_new_date_edit): - rename date_edit_new function - - * gui/dialogs/comp-editor-util.h: new proto - - * gui/dialogs/task-page.c (task_page_set_summary): no longer any - need to block/unblock the handler - (task_page_create_date_edit): use new func - -2001-06-01 JP Rosevear <jpr@ximian.com> - - * gui/.cvsignore: Update - - * gui/evolution-calendar-control.c: Remove dead file - - * gui/*.vcf: Remove dead files - -2001-06-01 JP Rosevear <jpr@ximian.com> - - * gui/dialogs/comp-editor-page.[hc]: renamed from editor-page for - consistency, more complete implementation - - * gui/dialogs/comp-editor.[hc]: More complete implementation - - * gui/dialogs/*-page.*: The various pages needed to construct the - event and task dialogs - - * gui/dialogs/comp-editor-util.[hc]: useful utility functions for the - component editor pages to use - - * gui/dialogs/Makefile.am: Build and install new files - - * gui/event-editor*: Remove, obsoleted by the new comp-editor - stuff - - * gui/dialogs/task-editor-dialog.glade: ditto - - * gui/e-calendar-table.c (open_task): update to use comp editor - stuff - - * gui/e-tasks.c (e_tasks_new_task): ditto - - * gui/gnome-cal.c (gnome_calendar_edit_object): ditto - - * gui/Makefile.am: don't build non-existent files nor try to - install them - -2001-06-01 JP Rosevear <jpr@ximian.com> - - * gui/e-itip-control.c (e_itip_control_factory_init): ditto - - * gui/tasks-control-factory.c (tasks_control_factory_init): - auto_exit_unref the factory - -2001-06-01 Ettore Perazzoli <ettore@ximian.com> - - * gui/Makefile.am (evolution_calendar_LDADD): Add `$(DB3_LDADD)'. - -2001-05-29 Federico Mena Quintero <federico@ximian.com> - - * gui/e-tasks.c (e_tasks_get_calendar_table): New function. - - * gui/tasks-control.c (tasks_control_activate): Connect to the - "selection_changed" signal of the tasks widget here, not in - tasks_control_new(). Also, update the sensitivity of the commands - here for the first time. - (tasks_control_deactivate): Disconnect from the signal here since - it only makes sense to monitor selection changes while the control - is active. - (selection_changed_cb): Removed hack that tested the presence of - the remote UI container. - (sensitize_commands): New function. - -2001-05-28 Damon Chaplin <damon@ximian.com> - - * gui/e-week-view-layout.[hc]: - * gui/e-day-view-layout.[hc]: new files to contain layout code split - off from EDayView an EWeekView, so we can use it for printing. - - * gui/print.c: rewritten to use the same layout code as the EDayView - and EWeekView widgets. - - * gui/gnome-cal.c (gnome_calendar_get_task_pad_cal_client): added - function so we can get the CalClient used for the TaskPad for printing. - - * gui/Makefile.am (evolution_calendar_SOURCES): added - e-day-view-layout.[hc] amd e-week-view-layout.[hc]. - - * cal-util/timeutil.c (time_week_begin): - (time_week_end): added week_start_day argument. - - * cal-util/cal-recur.c: added comments describing problems in it. - -2001-05-27 Rodrigo Moya <rodrigo@ximian.com> - - * gui/component-factory.c (remove_folder): implemented the - 'remove_folder' function for the calendar shell component - (xfer_folder): ditto for 'xfer_folder' - -2001-05-27 Dan Winship <danw@ximian.com> - - * gui/calendar-commands.c: #include - "evolution-shell-component-utils.h" rather than "e-gui-utils.h" - for e_pixmaps_update. - - * gui/tasks-control.c: Likewise. - -2001-05-25 Peter Williams <peterw@ximian.com> - - * gui/Makefile.am: Reference libeshell.la instead of libeshell.a. - -2001-05-23 Federico Mena Quintero <federico@ximian.com> - - * gui/dialogs/recurrence-page.c: Finished porting from the old - event-editor.c. Made it store a clone of the component for when - we need to expand the recurrence set. - - * gui/dialogs/event-page.c (event_page_get_dates): New function. - - * gui/dialogs/editor-page.c (editor_page_set_dates): Renamed from - editor_page_set_dtstart(); now sets both DTSTART and DTEND. - - * gui/dialogs/alarm-page.c (alarm_page_set_dates): Ahem, it is a - label, not an entry. - -2001-05-21 Federico Mena Quintero <federico@ximian.com> - - Fix bug #2831; the tasks toolbar and menu now have a button to - delete the selected tasks. - - * gui/e-calendar-table.c (e_calendar_table_delete_selected): New - function. - (delete_cb): Use e_calendar_table_delete_selected(). - (e_calendar_table_get_table): New function. - - * gui/tasks-control.c (tasks_control_new_task_cmd): Handle the - delete command. - (selection_changed_cb): Change the sensitivity of the TasksDelete - command when the selection in the table changes. - - * gui/e-tasks.c (table_selection_change_cb): Notify upstream when - the ETable selection changes. - -2001-05-18 Federico Mena Quintero <federico@ximian.com> - - Fix bug #2829. - - * gui/dialogs/delete-comp.c (delete_component_dialog): Allow the - caller to specify whether just one or many components are to be - deleted. - - * gui/e-calendar-table.c (tasks_popup_one): Popup menu definition - for when one and only one task is selected. - (tasks_popup_many): Likewise, for more than one task. - (e_calendar_table_on_right_click): Do not create a structure for - the closure data; we can simply pass the cal_table. Use a - different menu depending on the number of selected tasks. - (mark_as_complete_cb): Renamed; now iterates over the selected - rows. - (delete_selected_components): New function to delete all the - selected components. - (delete_cb): Adjusted for delete_component_dialog(). - (open_task): New function, simply open a CalComponent in the task - editor. - (open_task_by_row): Renamed; use open_task(). - - * gui/e-week-view.c (e_week_view_on_delete_appointment): Updated - for delete_component_dialog(). - - * gui/e-day-view.c (e_day_view_on_delete_appointment): Likewise. - -2001-05-16 Duncan Mak <duncan@ximian.com> - - * gui/Makefile.am (evolution_calendar_SOURCES): removed - editor-page.[ch] because they've now moved dialogs. - -2001-05-16 Federico Mena Quintero <federico@ximian.com> - - Split the event and task editors into different objects for the - separate pages; this way they can be shared by both editors. - - * gui/dialogs/editor-page.[ch]: New abstract class for a page in a - calendar component editor. - - * gui/dialogs/event-page.[ch]: Main page of an event editor. - - * gui/dialogs/alarm-page.[ch]: Alarm page of a calendar component - editor. - - * gui/dialogs/recurrence-page.[ch]: Recurrence page of a calendar - component editor. - - * gui/dialogs/event-page.c (event_page_fill_widgets): Eeek, this - was missing a bunch of break statements. - (event_page_fill_component): Use a temporary variable rather than - allocating a struct icaltimetype. - - * gui/dialogs/alarm-page.c (get_alarm_string): Do not use - fixed-size buffers. - (alarm_page_fill_widgets): Use cal_obj_uid_list_free(). - (append_reminder): Now the list stores the plain CalComponentAlarm - structures in the row data. We do *NOT* want to be frobbing the - component's data directly. Rather, we clone the alarms from the - component and maintain them on our own. - (alarm_page_fill_component): Clone the alarms before adding them - to the component so that we maintain the invariant that the alarm - structures in the list did *not* come from the component. - - * cal-util/cal-component.c (cal_component_add_alarm): Added - documentation. - (cal_component_remove_alarm): Added documentation. - (cal_component_remove_alarm): Do a lookup in our hash table of - alarms instead of scanning the whole component. - (CalComponentAlarm): Removed the `parent' field, since it was - unused. - (cal_component_free_alarm_uids): Removed function, since - cal_component_get_alarm_uids() is documented so that the user will - know that he must use cal_obj_uid_list_free(). - (cal_component_alarm_clone): New function. - -2001-05-09 Federico Mena Quintero <federico@ximian.com> - - * gui/Makefile.am (evolution_calendar_SOURCES): Added - editor-page.[ch] to the list of sources. - -2001-05-09 JP Rosevear <jpr@ximian.com> - - * gui/event-editor.c (reminder_add_cb): switch on the correct - widget and map - -2001-05-08 JP Rosevear <jpr@ximian.com> - - * gui/e-itip-control.c (e_itip_control_factory): unref the - property bag when we finish with it - - * gui/evolution-calendar-control.c (calendar_properties_init): ditto - - * gui/control-factory.c (calendar_properties_init): ditto - - * gui/calendar-summary.c (create_summary_view): ditto - -2001-05-08 JP Rosevear <jpr@ximian.com> - - * cal-util/cal-component.c (cal_component_alarm_free): - (cal_component_alarm_free): free the alarm component if it doesn't - have a parent, rather than if it does - - * gui/Makefile.am: sanitize LD_ADDS and CFLAGS so the libtool - lines are shorter (fixes problem on solaries due to sed) - -2001-05-07 JP Rosevear <jpr@ximian.com> - - * pcs/cal-factory.[hc]: Convert to bonobo xobject - - * pcs/cal.[hc]: Convert to bonobo xobject - -2001-05-07 Gediminas Paulauskas <menesis@delfi.lt> - - * gui/event-editor.c (make_title_from_comp): conversion summary - from utf8 here, use translated strings as is. - (set_title_from_comp): reflect this, simplify. - - * gui/dialogs/task-editor.c: updated copies of above functions here. - - * gui/gnome-cal.c: use defines from widgets/misc/e-filter-bar.h for - consistency in "Show all". - -2001-05-04 JP Rosevear <jpr@ximian.com> - - * gui/calendar-model.c (calendar_model_append_row): unref the - calcomponent when we're done with it - - * cal-util/cal-component.c (cal_component_gen_uid): free the iso - date string when we finish with it - -2001-04-27 JP Rosevear <jpr@ximian.com> - - * gui/e-meeting-edit.c (put_property_in_list): remove hardcoded - values - (edit_attendee): ditto, and there are only 4 roles now - - * gui/e-meeting-dialog.glade: tweak - - * gui/itip-utils.c: There shouldn't be an "other" role - -2001-04-26 JP Rosevear <jpr@ximian.com> - - * gui/e-meeting-edit.c (edit_attendee): use enums not hard code - values - -2001-04-26 JP Rosevear <jpr@ximian.com> - - * gui/e-meeting-edit.c (add_button_clicked_cb): - icalparameter_new_rsvp now takes an enum - -2001-04-26 JP Rosevear <jpr@ximian.com> - - * cal-util/cal-component.c (cal_component_alarm_set_trigger): the - value type should be inited with ICAL_VALUE_* rather than - ICAL_*_VALUE because it is a param argument. - -2001-04-26 Federico Mena Quintero <federico@ximian.com> - - * gui/calendar-model.c (get_is_overdue): Replace "<" by "<=" in - the comparison for due dates against the current time. This makes - tasks appear immediately as red when you click Now in the due date - popup field. - - This is not a complete solution to the more general problem of - tasks staying the same color even if they become overdue while the - task list remains the same on the screen. This has been logged as - bug #2399. - -2001-04-26 Ettore Perazzoli <ettore@ximian.com> - - * gui/dialogs/Makefile.am (INCLUDES): Add `$(EXTRA_GNOME_CFLAGS)'. - -2001-04-26 Dan Winship <danw@ximian.com> - - * conduits/todo/Makefile.am (libetodo_conduit_la_LIBADD): Remove - UNICODE_LIBS - - * cal-client/Makefile.am (client_test_LDADD): Remove -lunicode - -2001-04-24 Duncan Mak <duncan@ximian.com> - - * gui/alarm-notify/notify-main.c (funny_trigger_cb): Fixed - Strftime so it uses the locale prefered way to display date/time. - ("%x %X" instead of "%Y/%m/%d %H:%M:%S") - -2001-04-21 Gediminas Paulauskas <menesis@delfi.lt> - - * gui/calendar-summary.c: translate "Things to do" etc. and convert them - to utf8. Changed some link from helixcode to ximian. - -2001-04-18 Ettore Perazzoli <ettore@ximian.com> - - * gui/dialogs/Makefile.am (INCLUDES): Add - `-I$(top_srcdir)/calendar/cal-client', - `-I$(top_builddir)/calendar/cal-client'. - * gui/Makefile.am (INCLUDES): Likewise. - - * cal-client/cal-query.h: #include "evolution-calendar.h". - -2001-04-17 Federico Mena Quintero <federico@ximian.com> - - * gui/event-editor.c (init_widgets): Connect to the "changed" - signal of the categories entry so that they will be applied - correctly. - (EventEditorPrivate): Added fields for the contacts button and - entry. - (init_widgets): Disable the contacts widgets as we do not support - them yet. - (get_widgets): Get the contacts widgets. - - * gui/dialogs/task-editor.c (get_widgets): Get the contacts - button, which was missing. - (init_widgets): Disable the contacts widgets as we do not support - them yet. - - * pcs/query.c (matches_text_list): Use e_utf8_strstrcasedecomp() - instead of plain e_utf8_strstrcase(). - (matches_summary): Likewise. - -2001-04-17 JP Rosevear <jpr@ximian.com> - - * cal-util/cal-component.c (cal_component_alarm_set_action): the - libical action stuff uses enums rather than strings to enumerate - the various actions now - (cal_component_alarm_get_action): ditto - -2001-04-17 Ettore Perazzoli <ettore@ximian.com> - - * gui/alarm-notify/Makefile.am (evolution_alarm_notify_SOURCES): - Add `$(CORBA_GENERATED)'. - -2001-04-16 Dan Winship <danw@ximian.com> - - * pcs/Makefile.am (INCLUDES): Add EXTRA_GNOME_CFLAGS, for gal. - -2001-04-15 Federico Mena Quintero <federico@ximian.com> - - * gui/gnome-cal.c (setup_widgets): Create the ESearchBar thingy. - (search_bar_query_changed_cb): Build the different queries based - on the type and string. - - * pcs/query.c (backend_obj_updated_cb): Ref the query while we are - notifying the listener so that it will not disappear from under us. - (backend_obj_removed_cb): Likewise. - (process_component_cb): Likewise. - (func_contains): New function to match text fields. - (matches_comment): New function to match comment lists. - (matches_description): New function to match description lists. - (matches_summary): New function to match summaries. - (matches_any): New function to match any text field. - (func_has_categories): New function to match categories. - -2001-04-14 Federico Mena Quintero <federico@ximian.com> - - * gui/alarm-notify/notify-main.c (main): Initialize the trigger - and queue systems. - -2001-04-13 Dan Winship <danw@ximian.com> - - * cal-util/timeutil.c (time_from_isodate): Fix the syntactic bogon - here, and attempt to fix the logical bogon too. (tm_gmtoff and - timezone have opposite signs... I'm assuming Federico tested the - Linux case, so I'm flipping the sign of the BSD case. But maybe he - didn't and it's supposed to be the other way...) - -2001-04-12 Federico Mena Quintero <federico@ximian.com> - - * gui/e-day-view.c (update_query): New function to restart a query - for the day view. - (query_obj_updated_cb): Renamed from obj_updated_cb(); updated for - queries instead of calendar clients. - (query_obj_removed_cb): Likewise. - (cal_opened_cb): Just update_query() instead of queueing reloading - all the events. - (e_day_view_set_cal_client): Likewise. - (e_day_view_set_query): Likewise. - (e_day_view_set_selected_time_range): Likewise. - (e_day_view_set_days_shown): Likewise. - (e_day_view_recalc_work_week): Likewise. - (e_day_view_queue_reload_events): Removed function now that events - are updated entirely by the query. - (e_day_view_reload_events_idle_cb): Likewise. - (e_day_view_reload_events): Likewise. - (e_day_view_init): Use a pretty arrow instead of GDK_TOP_LEFT_ARROW. - - * gui/e-week-view.c: Analogous changes to the ones in e-day-view.c. - (e_week_view_init): Use a pretty arrow instead of GDK_TOP_LEFT_ARROW. - - * cal-util/timeutil.c (isodate_from_time_t): Return a g_strdup()ed - version of the string instead of a pointer to a static buffer. - (time_from_isodate): Resurrected function. Polished up to our - current standards of paranoia. - - * pcs/query.c (func_time_now): New function (time-now). - (func_make_time): New function (make-time ISODATE). - (func_time_add_day): New function (time-add-day TIME N). - (func_time_day_begin): New function (time-day-begin TIME). - (func_time_day_end): New function (time-day-end TIME). - (func_occur_in_time_range): Use time_t values instead of ints. - (match_component): Free the stringized component. Free the ESexp - result value. - - * gui/e-day-view.h: Removed a couple of unused prototypes. - - * pcs/query.c (query_destroy): Oops, disconnect from the backend. - - * pcs/cal.c (Cal_get_query): Duplicate the query reference before - we return it. - - * gui/calendar-commands.c (pixmaps): Fixed paths to image files. - -2001-04-11 JP Rosevear <jpr@ximian.com> - - * pcs/cal-backend-file.c (cal_backend_file_compute_changes): - prepend to both changes and change_ids when different and mark as - modified, not added - -2001-04-11 Christopher James Lahey <clahey@ximian.com> - - * gui/calendar-model.c (calendar_model_append_row): Fix this to - just send the data to the wombat instead of inserting it - ourselves. - -2001-04-11 Gediminas Paulauskas <menesis@delfi.lt> - - Display fixes, thanks to Kjartan for finding these. - - * gui/event-editor.c: use simple (not e_utf8_) gtk_clist_append for - strings which are never in utf-8. - * dialogs/delete-comp.c (delete_component_dialog): convert only - summary from utf-8 to gtk charset. Translated values are in correct - craset already. - -2001-04-04 Kjartan Maraas <kmaraas@gnome.org> - - * gui/calendar-commands.c: Fix headers. - * gui/calendar-config.c: Same here. - * gui/calendar-model.c: Same here. - * gui/e-day-view-time-item.c: Same here. - * gui/e-day-view-top-item.c: Same here. - * gui/e-day-view.c: Same here. - * gui/e-meeting-edit.c: Same here. - * gui/e-week-view-main-item.c: Same here. - * gui/e-week-view.c: Same here. - * gui/event-editor.c: Same here. - * gui/gnome-cal.c: Same here. - * gui/goto.c: Same here. - * gui/main.c: Same her. - * gui/print.c: Same here. - -2001-04-02 Federico Mena Quintero <federico@ximian.com> - - * gui/e-tasks.c (e_tasks_setup_menus): Plug leak. - - * gui/event-editor.c (obj_updated_cb): Do nothing for now until we - think of something sensible to do. - (obj_removed_cb): Likewise. - - * gui/dialogs/task-editor.c (obj_updated_cb): Likewise. - (obj_removed_cb): Likewise. - - * gui/event-editor.c (dialog_to_comp_object): Plug leak. - -2001-04-01 Federico Mena Quintero <federico@ximian.com> - - Client-side glue for the live query engine. - - * cal-client/query-listener.[ch]: New files with the - implementation fo the QueryListener interface. - - * cal-client/cal-query.[ch]: New files with the client-side - convenience object for live queries. - - * cal-client/cal-listener.h (CalListenerClass): Removed unused - slots for signal handlers. - - * cal-client/Makefile.am (libcal_clientinclude_HEADERS): Now we - install the evolution-calendar.h header. This sucks a bit. - -2001-04-01 Gediminas Paulauskas <menesis@delfi.lt> - - * gui/calendar-commands.c: use new pixmap cache. Added some menu icons - and changed filenames of renamed icons. - * gui/tasks-control.c: added icons for new task and print in menu. - -2001-03-29 Federico Mena Quintero <federico@ximian.com> - - Engine for live queries to calendars. A query object watches a - CalBackend in the PCS and is otherwise completely separate from - it; backends need to do nothing to support live queries. Right - now we have the following functions: - - (get-vtype) - - Returns a string indicating the type of component - (VEVENT, VTODO, VJOURNAL, VFREEBUSY, VTIMEZONE, - UNKNOWN). - - (occur-in-time-range? START END) - - START - int, time_t start of the time range - END - int, time_t end of the time range - - Returns a boolean indicating whether the component - has any occurrences in the specified time range. - - * idl/evolution-calendar.idl (Cal::getQuery): New method that - initiates a live query. - (Query): New interface for a handle to a live query. - (QueryListener): New interface for a listener to changes in a live - query. - - * pcs/query.[ch]: New files with the live query engine. - - * pcs/cal-backend.h (CalBackendClass): Added notification signals - so that the query system can catch them. - (CalBackendClass): New virtual method ::get_load_state(). - - * pcs/cal-backend.c (cal_backend_opened): - (cal_backend_obj_updated): - (cal_backend_obj_updated): New functions to emit the notification - signals; to be used only by backend implementations. - (cal_backend_get_load_state): New function. - - * pcs/cal-backend-file.c (notify_update): Call - cal_backend_obj_updated(). - (notify_remove): Call call_backend_obj_removed(). - (open_cal): Free the icalcomp if it is not of the correct type. - (cal_backend_file_get_load_state): Implemented new method. - - * pcs/cal-backend-db.c (cal_backend_db_update_object): Call - cal_backend_obj_updated(). - (cal_backend_db_remove_object): Call cal_backend_obj_removed(). - (cal_backend_db_get_load_state): Implemented new method. - - * pcs/cal.c (Cal_get_query): Implementation of the ::getQuery() - method. - -2001-03-27 Anna Marie Dirks <anna@ximian.com> - - * gui/e-itip-control.c: fixed button placement to comply - with gnome standards. - -2001-03-27 Anna Marie Dirks <anna@ximian.com> - - * gui/e-itip-control.glade: fixed spacing and label alignment to - comply with gnome standards. Also removed shadows from extraneous - scrolled windows to avoid bevelitous. There are many more changes - that need to happen to this viewer, but they all require a hacker - to do some c-coding, so I will avoid committing them until after the - .10 release. - -2001-03-26 Kjartan Maraas <kmaraas@gnome.org> - - * cal-client/client-test.c: Replace includes of <gnome.h>, <bonobo.h> - and <gtk/gtk.h> with the needed headers to speed up compile. - * cal-util/test-recur.c: Same here for <gtk/gtk.h> - * gui/calendar-commands.c: Replace <bonobo.h> and remove - <libgnorba/gnorba.h> - * gui/calendar-summary.c: Replace <gnome.h> and <bonobo.h> - * gui/calendar-summary.h: Added <bonobo/bonobo-generic-factory.h> - * gui/component-factory.c: Remove <bonobo.h> - * gui/control-factory.c: Replace <bonobo.h> - * gui/e-calendar-table.c: Remove <gnome.h> - * gui/e-itip-control.c: Replace <gnome.h> and <bonobo.h> - * gui/e-meeting-edit.c: Replace <bonobo.h> - * gui/e-tasks.c: Replace <gnome.h> - * gui/e-tasks.h: Replace <bonobo.h> - * gui/gnome-cal.h: Remove <bonobo.h> - * gui/main.c: Replace <bonobo.h> and <glade/glade.h> - * gui/tasks-control-factory.c: Replace <bonobo.h> - * gui/tasks-control.c: Replace <gnome.h> and <bonobo.h> - * gui/weekday-picker.c: Add <string.h> and <libgnome/gnome-defs.h> - * gui/alarm-notify/client-main.c: Remove <gnome.h> and <bonobo.h> - * gui/alarm-notify/notify-main.c: Replace <gnome.h> and <bonobo.h> - * gui/dialogs/alarm-notify-dialog.c: Replace <gnome.h> - * pcs/cal-backend.c: Replace <gtk/gtk.h> - -2001-03-25 Federico Mena Quintero <federico@ximian.com> - - * gui/e-calendar-table.c (e_calendar_table_init): The - model_rows_{inserted,deleted} signals changed names; deal with it. - (e_calendar_table_on_rows_inserted): Updated for new ETable API. - (e_calendar_table_on_rows_deleted): Likewise. - - * gui/gnome-cal.h (GnomeCalendarOpenMode): Removed unused enum. - - * gui/gnome-cal.c (gnome_calendar_open): Constify. - - * gui/calendar-commands.c (calendar_set_uri): Removed function, - since it was just calling gnome_calendar_open(). - - * gui/control-factory.c (set_prop): Replace usage of - calendar_set_uri() with gnome_calendar_open(). - (load_calendar): Likewise. - (calendar_persist_init): Made static. - - * gui/e-tasks.c: #include "calendar-config.h" - (e_tasks_update_all_config_settings): We are configuring a table, - not a calendar! Use the appropriate function. - -2001-03-17 Miguel de Icaza <miguel@ximian.com> - - * gui/e-day-view.c (e_day_view_on_new_event, - e_day_view_on_new_appointment): Simplifed this function to use the - shared code. - - * gui/e-week-view.c (e_week_view_on_new_event, - e_week_view_on_new_appointment): ditto. - - * gui/gnome-cal.c (gnome_calendar_new_appointment_for): New - function used to launch editor components with a time range. A - bunch of functions use this code now instead of duplicating code - all over the place - - * gui/e-week-view.c (e_week_view_new_event): Moved functionality - here from e_day_view_on_new_appointment. Allows setting for "full - day" event. - (e_week_view_on_new_full_day): New function for making a full day - event. - (e_week_view_on_goto_date): Go To support. - (e_week_view_on_goto_today): Goto today support. - - * gui/e-day-view.c (e_day_view_new_event): Moved functionality - here from e_day_view_on_new_appointment. Allows setting for "full - day" event. - (e_day_view_on_new_full_day): New function for making a full day - event. - (e_day_view_on_goto_date): Go To support. - (e_day_view_on_goto_today): Goto today support. - - * main_items: Add New All Day Event; Go to Today; Go to Date. - -2001-03-07 Miguel de Icaza <miguel@ximian.com> - - * gui/control-factory.c (calendar_persist_init): New function: - inits the BonoboPersistFile server. - - * gui/GNOME_Evolution_Calendar.oaf.in: Added BonoboPropertyBag to - the list of supported interfaces that were supported but not - reported. Add the new PersistFile. - - Add text/calendar mime type attribute. - -2001-03-15 Dan Winship <danw@ximian.com> - - * gui/e-week-view.c (e_week_view_start_editing_event): - * gui/e-day-view.c (e_day_view_start_editing_event): Update - arguments to e_canvas_item_grab_focus. - -2001-03-15 Gediminas Paulauskas <menesis@delfi.lt> - - * gui/*.xpm: moved to ../art. - * gui/Makefile.am: removed *.xpm and oaf_DATA from EXTRA_DIST. - * gui/e-calendar-table.c, gui/e-day-view.c, gui/e-week-view.c: - #include "art/*.xpm". - -2001-03-09 JP Rosevear <jpr@ximian.com> - - * conduits/todo/Makefile.am: PISOCK_INCLUDEDIR has become - PISOCK_CFLAGS in gnome-pilot.m4 and remove capplet foo - - * conduits/calendar/Makefile.am: ditto - -2001-03-08 Ettore Perazzoli <ettore@ximian.com> - - * gui/component-factory.c (factory_fn): Specify a NULL - `EvolutionShellComponentGetDndSelectionFn'. - -2001-02-27 Miguel de Icaza <miguel@ximian.com> - - * gui/e-day-view.c (e_day_view_on_event_right_click): Reorganize - the menus to have entries always in a consistent fashion, as - reported to the genepool mailing list. - (e_day_view_on_event_right_click): Added a FIXME comment to the - FIXME comment without a FIXME. - - Now we use e_popup_menu. This allows us to hide/show items on - demand, and to sensitize/de-sensitize items depending on their - state. - - This will also let us add icon support (when we get nice icons for - this) - - * gui/e-week-view.c (e_week_view_show_popup_menu): Ditto. - - The files popup-menu.c and popup-menu.h can now be removed. - -2001-03-05 Damon Chaplin <damon@ximian.com> - - * gui/e-tasks.c: keep list of all Tasks folders so we can update the - preference settings when necessary. - - * gui/gnome-cal.c: configure the TaskPad according to the settings. - - * gui/e-calendar-table.c: use ECellCombo and ECellDateEdit for fields, - so the tasks folders is almost usable now. - - * gui/calendar-model.c: added support for the Status property. - - * gui/calendar-config.[hc]: added convenience functions to setup - ECalendarTable and ECellDateEdit objects. - - * gui/calendar-commands.c: connected to "destroy" signal of calendars - so we can remove them from all_calendars list. - - * gui/dialogs/cal-prefs-dialog.c (cal_prefs_dialog_update_config): - call e_tasks_update_all_config_settings() to update all the settings - in the Tasks folders as well. - - * cal-util/cal-component.h: added CAL_COMPONENT_FIELD_STATUS. - - * cal-util/cal-component.c (cal_component_get_transparency): fixed - calls to strcasecmp so they check for '== 0'. - - Applied patch from Miguel... - -2001-02-27 Miguel de Icaza <miguel@ximian.com> - - * gui/e-day-view.c (e_day_view_on_event_right_click): Reorganize - the menus to have entries always in a consistent fashion, as - reported to the genepool mailing list. - (e_day_view_on_event_right_click): Added a FIXME comment to the - FIXME comment without a FIXME. - - Now we use e_popup_menu. This allows us to hide/show items on - demand, and to sensitize/de-sensitize items depending on their - state. - - This will also let us add icon support (when we get nice icons for - this) - - * gui/e-week-view.c (e_week_view_show_popup_menu): Ditto. - - The files popup-menu.c and popup-menu.h can now be removed. - -2001-03-02 JP Rosevear <jpr@ximian.com> - - * conduits/todo/e-todo.conduit.in: update for new pilot foo - - * conduits/calendar/e-calendar.conduit.in: ditto - - * conduits/todo/Makefile.am: update sed script - - * conduits/calendar/Makefile.am: ditto - -2001-02-28 Federico Mena Quintero <federico@ximian.com> - - * gui/event-editor.c (recurrence_exception_select_row_cb): New - function to set the EDateEdit's value when a row is selected in - the exception date list. Fixes bug #1638. - (append_exception): Set the value as well. Block/unblock signals - from the clist as appropriate. Gotta love non-model/view widgets. - (recurrence_exception_delete_cb): Be more paranoid about the - contents of the list row's data. - (recur_to_comp_object): Likewise. - (fill_exception_widgets): Select the first row after we are done - appending the exception dates. - -2001-02-26 Federico Mena Quintero <federico@ximian.com> - - * gui/alarm-notify/Makefile.am (libalarm_a_SOURCES): Create a - little stand-alone library for the low-level alarm trigger - mechanism. This is so that the GUI parts of the calendar can use - it in addition to the alarm daemon. - - * gui/main.c: #include "alarm-notify/alarm.h". - - * gui/calendar-summary.c: Likewise. - (alarm_fn): Do not remove the previous alarm; it is removed - automatically when it is triggered. - - * gui/Makefile.am (evolution_calendar_SOURCES): Removed alarm.[ch] - from the sources. - - * gui/alarm.[ch]: Removed obsolete files. - -2001-02-23 Federico Mena Quintero <federico@ximian.com> - - * gui/alarm-notify/alarm-notify.c (AlarmNotify_addCalendar): - Switched to using our own refcounted structure for loaded clients. - (AlarmNotify_removeCalendar): Ditto. Also, do the full - destruction of the client. - (alarm_notify_destroy): Destroy each element in the hash table. - - * cal-client/cal-client.c (cal_client_construct): Test for - exceptions from OAF when activating the Wombat calendar factory. - - * gui/alarm-notify/GNOME_Evolution_Calendar_AlarmNotify.oaf.in: - New .oaf.in file. - - * gui/alarm-notify/Makefile.am (oaf_in_files): Updated. - - * gui/GNOME_Evolution_Calendar.oaf.in: Put all the servers here - instead of in a million files. - - * gui/GNOME_Evolution_Calendar_Control.oaf.in: Removed file. - - * gui/GNOME_Evolution_Calendar_gnomecal.oaf.in: Removed *REALLY* - obsolete file. - - * gui/Makefile.am (oaf_in_files): Updated. - -2001-02-23 Rodrigo Moya <rodrigo@ximian.com> - - * pcs/cal-backend-db.c (add_history): fixed generation of history records - -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 89cea775bd..0000000000 --- a/calendar/Makefile.am +++ /dev/null @@ -1,9 +0,0 @@ -if ENABLE_PILOT_CONDUITS -CONDUIT_DIR = conduits -else -CONDUIT_DIR = -endif - -SUBDIRS = idl cal-util pcs cal-client gui importers $(CONDUIT_DIR) - -EXTRA_DIST = zones.h 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 de4b85e51f..0000000000 --- a/calendar/cal-client/Makefile.am +++ /dev/null @@ -1,90 +0,0 @@ -# -# libcal-client -# - -CORBA_GENERATED = \ - evolution-calendar-common.c \ - evolution-calendar-skels.c \ - evolution-calendar-stubs.c - -CORBA_HEADERS_GENERATED = \ - evolution-calendar.h - -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 \ - -I$(top_builddir)/libwombat \ - -I$(top_srcdir)/libwombat \ - $(EVOLUTION_CALENDAR_CFLAGS) - -lib_LTLIBRARIES = libcal-client.la - -libcal_clientincludedir = $(includedir)/evolution/cal-client - -libcal_client_la_SOURCES = \ - $(CORBA_GENERATED) \ - cal-client-multi.c \ - cal-client-types.c \ - cal-client.c \ - cal-listener.c \ - cal-listener.h \ - cal-query.c \ - query-listener.c \ - query-listener.h - -libcal_clientinclude_HEADERS = \ - $(CORBA_HEADERS_GENERATED) \ - cal-client-multi.h \ - cal-client-types.h \ - cal-client.h \ - cal-query.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 = \ - $(EVOLUTION_CALENDAR_LIBS) \ - $(top_builddir)/calendar/cal-util/libcal-util.la \ - $(top_builddir)/libversit/libversit.a \ - $(top_builddir)/libical/src/libical/libical-evolution.la \ - $(top_builddir)/libwombat/libwombat.la \ - libcal-client.la - -BUILT_SOURCES = $(CORBA_GENERATED) -CLEANFILES = $(BUILT_SOURCES) - -dist-hook: - cd $(distdir); rm -f $(BUILT_SOURCES) diff --git a/calendar/cal-client/cal-client-multi.c b/calendar/cal-client/cal-client-multi.c deleted file mode 100644 index aeebc72fda..0000000000 --- a/calendar/cal-client/cal-client-multi.c +++ /dev/null @@ -1,706 +0,0 @@ -/* Evolution calendar client - * - * 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <gtk/gtksignal.h> -#include "cal-client-multi.h" - -/* Private part of the CalClientMulti structure */ -struct _CalClientMultiPrivate { - GHashTable *calendars; - GList *uris; -}; - -static void cal_client_multi_class_init (CalClientMultiClass *klass); -static void cal_client_multi_init (CalClientMulti *multi); -static void cal_client_multi_destroy (GtkObject *object); - -/* signal IDs */ -enum { - CAL_OPENED, - OBJ_UPDATED, - OBJ_REMOVED, - CATEGORIES_CHANGED, - FORGET_PASSWORD, - LAST_SIGNAL -}; - -static guint cal_multi_signals[LAST_SIGNAL]; -static GtkObjectClass *parent_class = NULL; - -/* - * Private functions - */ - -/** - * cal_client_multi_get_type - * - * Registers the #CalClientMulti class if necessary, and returns the type ID - * assigned to it. - * - * Returns: The type ID of the #CalClientMulti class - */ -GtkType -cal_client_multi_get_type (void) -{ - static GtkType type = 0; - - if (!type) { - static const GtkTypeInfo info = { - "CalClientMulti", - sizeof (CalClientMulti), - sizeof (CalClientMultiClass), - (GtkClassInitFunc) cal_client_multi_class_init, - (GtkObjectInitFunc) cal_client_multi_init, - NULL, - NULL, - (GtkClassInitFunc) NULL - }; - - type = gtk_type_unique (GTK_TYPE_OBJECT, &info); - } - - return type; -} - -/* class initialization function for the multi calendar client */ -static void -cal_client_multi_class_init (CalClientMultiClass *klass) -{ - GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass); - - parent_class = gtk_type_class (GTK_TYPE_OBJECT); - - cal_multi_signals[CAL_OPENED] = - gtk_signal_new ("cal_opened", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (CalClientMultiClass, cal_opened), - gtk_marshal_NONE__POINTER_INT, - GTK_TYPE_NONE, 2, - GTK_TYPE_POINTER, GTK_TYPE_ENUM); - cal_multi_signals[OBJ_UPDATED] = - gtk_signal_new ("obj_updated", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (CalClientMultiClass, obj_updated), - gtk_marshal_NONE__POINTER_POINTER, - GTK_TYPE_NONE, 2, - GTK_TYPE_POINTER, GTK_TYPE_STRING); - cal_multi_signals[OBJ_REMOVED] = - gtk_signal_new ("obj_removed", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (CalClientMultiClass, obj_removed), - gtk_marshal_NONE__POINTER_POINTER, - GTK_TYPE_NONE, 2, - GTK_TYPE_POINTER, GTK_TYPE_STRING); - cal_multi_signals[CATEGORIES_CHANGED] = - gtk_signal_new ("categories_changed", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (CalClientMultiClass, categories_changed), - gtk_marshal_NONE__POINTER_POINTER, - GTK_TYPE_NONE, 2, - GTK_TYPE_POINTER, GTK_TYPE_POINTER); - cal_multi_signals[FORGET_PASSWORD] = - gtk_signal_new ("forget_password", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (CalClientMultiClass, forget_password), - gtk_marshal_NONE__POINTER_POINTER, - GTK_TYPE_NONE, 2, - GTK_TYPE_STRING, GTK_TYPE_STRING); - - object_class->destroy = cal_client_multi_destroy; -} - -/* object initialization function for the multi calendar client */ -static void -cal_client_multi_init (CalClientMulti *multi) -{ - multi->priv = g_new0 (CalClientMultiPrivate, 1); - multi->priv->calendars = g_hash_table_new (g_str_hash, g_str_equal); - multi->priv->uris = NULL; -} - -static void -free_calendar (gpointer key, gpointer value, gpointer data) -{ - CalClientMulti *multi = (CalClientMulti *) data; - - g_return_if_fail (IS_CAL_CLIENT_MULTI (multi)); - - multi->priv->uris = g_list_remove (multi->priv->uris, key); - - g_free (key); - gtk_object_unref (GTK_OBJECT (value)); -} - -/* destroy handler for the multi calendar client */ -static void -cal_client_multi_destroy (GtkObject *object) -{ - CalClientMulti *multi = (CalClientMulti *) object; - - g_return_if_fail (IS_CAL_CLIENT_MULTI (multi)); - - /* free memory */ - g_hash_table_foreach (multi->priv->calendars, free_calendar, multi); - g_hash_table_destroy (multi->priv->calendars); - g_list_free (multi->priv->uris); - - g_free (multi->priv); - multi->priv = NULL; - - /* chain to parent class' destroy handler */ - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - -/** - * cal_client_multi_new - * - * Creates a new multi-calendar client. This allows you to merge several - * #CalClient objects into one entity, making it easier to manage - * multiple calendars. - * - * Returns: A newly-created multi-calendar client. - */ -CalClientMulti * -cal_client_multi_new (void) -{ - CalClientMulti *multi; - - multi = gtk_type_new (CAL_CLIENT_MULTI_TYPE); - return multi; -} - -/* CalClient's signal handlers */ -static void -client_cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer user_data) -{ - CalClientMulti *multi = (CalClientMulti *) user_data; - - g_return_if_fail (IS_CAL_CLIENT (client)); - g_return_if_fail (IS_CAL_CLIENT_MULTI (multi)); - - gtk_signal_emit (GTK_OBJECT (multi), - cal_multi_signals[CAL_OPENED], - client, status); -} - -static void -client_obj_updated_cb (CalClient *client, const char *uid, gpointer user_data) -{ - CalClientMulti *multi = (CalClientMulti *) user_data; - - g_return_if_fail (IS_CAL_CLIENT (client)); - g_return_if_fail (IS_CAL_CLIENT_MULTI (multi)); - - gtk_signal_emit (GTK_OBJECT (multi), - cal_multi_signals[OBJ_UPDATED], - client, uid); -} - -static void -client_obj_removed_cb (CalClient *client, const char *uid, gpointer user_data) -{ - CalClientMulti *multi = (CalClientMulti *) user_data; - - g_return_if_fail (IS_CAL_CLIENT (client)); - g_return_if_fail (IS_CAL_CLIENT_MULTI (multi)); - - gtk_signal_emit (GTK_OBJECT (multi), - cal_multi_signals[OBJ_REMOVED], - client, uid); -} - -static void -client_categories_changed_cb (CalClient *client, GPtrArray *categories, gpointer user_data) -{ - CalClientMulti *multi = (CalClientMulti *) user_data; - - g_return_if_fail (IS_CAL_CLIENT (client)); - g_return_if_fail (IS_CAL_CLIENT_MULTI (multi)); - - gtk_signal_emit (GTK_OBJECT (multi), - cal_multi_signals[CATEGORIES_CHANGED], - client, categories); -} - -static void -client_forget_password_cb (CalClient *client, const char *key, gpointer user_data) -{ - CalClientMulti *multi = (CalClientMulti *) user_data; - - g_return_if_fail (IS_CAL_CLIENT (client)); - g_return_if_fail (IS_CAL_CLIENT_MULTI (multi)); - - gtk_signal_emit (GTK_OBJECT (multi), - cal_multi_signals[FORGET_PASSWORD], - client, key); -} -/** - * cal_client_multi_add_client - * @multi: A #CalClientMulti object. - * @client: The #CalClient object to be added. - * - * Aggregates the given #CalClient to a #CalClientMulti object, - * thus adding it to the list of managed calendars. - */ -void -cal_client_multi_add_client (CalClientMulti *multi, CalClient *client) -{ - char *uri; - CalClient *old_client; - - g_return_if_fail (IS_CAL_CLIENT_MULTI (multi)); - g_return_if_fail (IS_CAL_CLIENT (client)); - - uri = g_strdup (cal_client_get_uri (client)); - old_client = g_hash_table_lookup (multi->priv->calendars, uri); - if (old_client) { - g_free (uri); - return; - } - - gtk_object_ref (GTK_OBJECT (client)); - multi->priv->uris = g_list_append (multi->priv->uris, uri); - g_hash_table_insert (multi->priv->calendars, uri, client); - - /* set up CalClient's signal handlers */ - gtk_signal_disconnect_by_data (GTK_OBJECT (client), multi); - gtk_signal_connect (GTK_OBJECT (client), - "cal_opened", - GTK_SIGNAL_FUNC (client_cal_opened_cb), - multi); - gtk_signal_connect (GTK_OBJECT (client), - "obj_updated", - GTK_SIGNAL_FUNC (client_obj_updated_cb), - multi); - gtk_signal_connect (GTK_OBJECT (client), - "obj_removed", - GTK_SIGNAL_FUNC (client_obj_removed_cb), - multi); - gtk_signal_connect (GTK_OBJECT (client), - "categories_changed", - GTK_SIGNAL_FUNC (client_categories_changed_cb), - multi); - gtk_signal_connect (GTK_OBJECT (client), - "forget_password", - GTK_SIGNAL_FUNC (client_forget_password_cb), - multi); -} - -typedef struct { - CalClientAuthFunc func; - gpointer user_data; -} AuthFuncData; - -static void -set_auth_func (gpointer key, gpointer value, gpointer user_data) -{ - AuthFuncData *cb_data = (AuthFuncData *) user_data; - CalClient *client = (CalClient *) value; - - g_return_if_fail (IS_CAL_CLIENT (client)); - g_return_if_fail (cb_data != NULL); - - cal_client_set_auth_func (client, cb_data->func, cb_data->user_data); -} - -/** - * cal_client_multi_set_auth_func - * @multi: A #CalClientMulti object. - * @func: The authentication function. - * @user_data: Data to be passed to the authentication function. - * - * Sets the authentication function for all the clients in the - * given #CalClientMulti. - */ -void -cal_client_multi_set_auth_func (CalClientMulti *multi, - CalClientAuthFunc func, - gpointer user_data) -{ - AuthFuncData *cb_data; - - g_return_if_fail (IS_CAL_CLIENT_MULTI (multi)); - - cb_data = g_new0 (AuthFuncData, 1); - cb_data->func = func; - cb_data->user_data = user_data; - g_hash_table_foreach (multi->priv->calendars, set_auth_func, cb_data); - - g_free (cb_data); -} - -/** - * cal_client_multi_open_calendar - * @multi: A #CalClientMulti object. - * @str_uri: The URI of the calendar to be open - * @only_if_exists: - * - * Open a new calendar in the given #CalClientMulti object. - * - * Returns: a pointer to the new #CalClient - */ -CalClient * -cal_client_multi_open_calendar (CalClientMulti *multi, - const char *str_uri, - gboolean only_if_exists) -{ - CalClient *client; - gboolean result; - - g_return_val_if_fail (IS_CAL_CLIENT_MULTI (multi), FALSE); - - client = cal_client_new (); - - result = cal_client_open_calendar (client, str_uri, only_if_exists); - if (result) { - cal_client_multi_add_client (multi, client); - gtk_object_unref (GTK_OBJECT (client)); - return client; - } - - gtk_object_unref (GTK_OBJECT (client)); - - return NULL; -} - -/** - * cal_client_multi_get_client_for_uri - * @multi: A #CalClientMulti object. - * @uri: The URI for the client. - * - * Returns the #CalClient object associated with the given - * @uri for the given #CalClientMulti object. - * - * Returns: a pointer to the client or NULL if no client is - * associated with that URI. - */ -CalClient * -cal_client_multi_get_client_for_uri (CalClientMulti *multi, const char *uri) -{ - g_return_val_if_fail (IS_CAL_CLIENT_MULTI (multi), NULL); - g_return_val_if_fail (uri != NULL, NULL); - - return g_hash_table_lookup (multi->priv->calendars, uri); -} - -/** - * cal_client_multi_get_n_objects - * @multi: A #CalClientMulti object. - * @type: Type for objects - * - * Get the count of objects of the given type(s) for a #CalClientMulti - * object. - * - * Returns: The count of objects of the given type(s). - */ -int -cal_client_multi_get_n_objects (CalClientMulti *multi, - CalObjType type) -{ - CalClient *client; - GList *l; - int count = 0; - - g_return_val_if_fail (IS_CAL_CLIENT_MULTI (multi), -1); - - for (l = multi->priv->uris; l; l = l->next) { - client = cal_client_multi_get_client_for_uri (multi, - (const char *) l->data); - if (IS_CAL_CLIENT (client)) - count += cal_client_get_n_objects (client, type); - } - - return count; -} - -/** - * cal_client_multi_get_object - */ -CalClientGetStatus -cal_client_multi_get_object (CalClientMulti *multi, - const char *uid, - CalComponent **comp) -{ - CalClient *client; - GList *l; - - g_return_val_if_fail (IS_CAL_CLIENT_MULTI (multi), CAL_CLIENT_GET_NOT_FOUND); - g_return_val_if_fail (uid != NULL, CAL_CLIENT_GET_NOT_FOUND); - - for (l = multi->priv->uris; l; l = l->next) { - client = cal_client_multi_get_client_for_uri (multi, - (const char *) l->data); - if (IS_CAL_CLIENT (client)) { - CalClientGetStatus status; - - status = cal_client_get_object (client, uid, comp); - if (status == CAL_CLIENT_GET_SUCCESS) - return status; - } - } - - return CAL_CLIENT_GET_NOT_FOUND; -} - -/** - * cal_client_multi_get_timezone - * @multi: A #CalClientMulti object. - * @tzid: ID for the timezone to be retrieved. - * @zone: A pointer to where the icaltimezone object will be copied. - */ -CalClientGetStatus -cal_client_multi_get_timezone (CalClientMulti *multi, - const char *tzid, - icaltimezone **zone) -{ - CalClient *client; - GList *l; - - g_return_val_if_fail (IS_CAL_CLIENT_MULTI (multi), CAL_CLIENT_GET_NOT_FOUND); - g_return_val_if_fail (tzid != NULL, CAL_CLIENT_GET_NOT_FOUND); - - for (l = multi->priv->uris; l; l = l->next) { - client = cal_client_multi_get_client_for_uri (multi, - (const char *) l->data); - if (IS_CAL_CLIENT (client)) { - CalClientGetStatus status; - - status = cal_client_get_timezone (client, tzid, zone); - if (status == CAL_CLIENT_GET_SUCCESS) - return status; - } - } - - return CAL_CLIENT_GET_NOT_FOUND; -} - -/** - * cal_client_multi_get_uids - * @multi: A #CalClientMulti object. - * @type: Type of objects whose IDs will be returned. - * - * Returns a list of UIDs for all the objects of the given - * type(s) that are in the calendars managed by a - * #CalClientMulti object - * - * Returns: a GList of UIDs. - */ -GList * -cal_client_multi_get_uids (CalClientMulti *multi, CalObjType type) -{ - CalClient *client; - GList *l; - GList *result = NULL; - - g_return_val_if_fail (IS_CAL_CLIENT_MULTI (multi), NULL); - - for (l = multi->priv->uris; l; l = l->next) { - client = cal_client_multi_get_client_for_uri (multi, - (const char *) l->data); - if (IS_CAL_CLIENT (client)) { - GList *tmp; - - tmp = cal_client_get_uids (client, type); - if (tmp) - result = g_list_concat (result, tmp); - } - } - - return result; -} - -/** - * cal_client_multi_get_changes - * @multi: A #CalClientMulti object. - * @type: Object type. - * @change_id: Change ID. - * - * Returns a list of changes for the given #CalClientMulti - * object. - */ -GList * -cal_client_multi_get_changes (CalClientMulti *multi, - CalObjType type, - const char *change_id) -{ - CalClient *client; - GList *l; - GList *result = NULL; - - g_return_val_if_fail (IS_CAL_CLIENT_MULTI (multi), NULL); - - for (l = multi->priv->uris; l; l = l->next) { - client = cal_client_multi_get_client_for_uri (multi, - (const char *) l->data); - if (IS_CAL_CLIENT (client)) { - GList *tmp; - - tmp = cal_client_get_changes (client, type, change_id); - if (tmp) - result = g_list_concat (result, tmp); - } - } - - return result; -} - -/** - * cal_client_multi_get_objects_in_range - * @multi: A #CalClientMulti object. - * @type: Type for objects. - * @start: Start time. - * @end: End time. - * - * Retrieves a list of all calendar components that are - * scheduled within the given time range. The information is - * retrieved from all the calendars being managed by the - * given #CalClientMulti object. - * - * Returns: A list of UID strings. This should be freed using the - * #cal_obj_uid_list_free() function. - **/ -GList * -cal_client_multi_get_objects_in_range (CalClientMulti *multi, - CalObjType type, - time_t start, - time_t end) -{ - CalClient *client; - GList *l; - GList *result = NULL; - - g_return_val_if_fail (IS_CAL_CLIENT_MULTI (multi), NULL); - - for (l = multi->priv->uris; l; l = l->next) { - client = cal_client_multi_get_client_for_uri (multi, - (const char *) l->data); - if (IS_CAL_CLIENT (client)) { - GList *tmp; - - tmp = cal_client_get_objects_in_range (client, type, start, end); - if (tmp) - result = g_list_concat (result, tmp); - } - } - - return result; -} - -/** - * cal_client_multi_get_free_busy - * @multi: A #CalClientMulti object. - * @users: List of users to retrieve F/B information for. - * @start: Start time. - * @end: End time. - * - * Retrieves Free/Busy information for the given users in all - * the calendars being managed by the given #CalClient multi - * object. - * - * Returns: A GList of VFREEBUSY CalComponents - */ -GList * -cal_client_multi_get_free_busy (CalClientMulti *multi, - GList *users, - time_t start, - time_t end) -{ - CalClient *client; - GList *l; - GList *result = NULL; - - g_return_val_if_fail (IS_CAL_CLIENT_MULTI (multi), NULL); - - for (l = multi->priv->uris; l; l = l->next) { - client = cal_client_multi_get_client_for_uri (multi, - (const char *) l->data); - if (IS_CAL_CLIENT (client)) { - GList *tmp; - - tmp = cal_client_get_free_busy (client, users, start, end); - if (tmp) - result = g_list_concat (result, tmp); - } - } - - return result; -} - -/** - * cal_client_multi_generate_instances - */ -void -cal_client_multi_generate_instances (CalClientMulti *multi, - CalObjType type, - time_t start, - time_t end, - CalRecurInstanceFn cb, - gpointer cb_data) -{ - CalClient *client; - GList *l; - - g_return_if_fail (IS_CAL_CLIENT_MULTI (multi)); - - for (l = multi->priv->uris; l; l = l->next) { - client = cal_client_multi_get_client_for_uri (multi, - (const char *) l->data); - if (IS_CAL_CLIENT (client)) { - cal_client_generate_instances ( - client, type, start, end, cb, cb_data); - } - } -} - -/** - * cal_client_multi_get_alarms_in_range - */ -GSList * -cal_client_multi_get_alarms_in_range (CalClientMulti *multi, time_t start, time_t end) -{ - CalClient *client; - GList *l; - GSList *result = NULL; - - g_return_val_if_fail (IS_CAL_CLIENT_MULTI (multi), NULL); - - for (l = multi->priv->uris; l; l = l->next) { - client = cal_client_multi_get_client_for_uri (multi, - (const char *) l->data); - if (IS_CAL_CLIENT (client)) { - GSList *tmp; - - tmp = cal_client_get_alarms_in_range (client, start, end); - if (tmp) - result = g_slist_concat (result, tmp); - } - } - - return result; -} diff --git a/calendar/cal-client/cal-client-multi.h b/calendar/cal-client/cal-client-multi.h deleted file mode 100644 index cded02e194..0000000000 --- a/calendar/cal-client/cal-client-multi.h +++ /dev/null @@ -1,104 +0,0 @@ -/* Evolution calendar client - * - * 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef CAL_CLIENT_MULTI_H -#define CAL_CLIENT_MULTI_H - -#include <cal-client/cal-client.h> - -BEGIN_GNOME_DECLS - -#define CAL_CLIENT_MULTI_TYPE (cal_client_multi_get_type ()) -#define CAL_CLIENT_MULTI(obj) (GTK_CHECK_CAST ((obj), CAL_CLIENT_MULTI_TYPE, CalClientMulti)) -#define CAL_CLIENT_MULTI_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), CAL_CLIENT_MULTI_TYPE, CalClientMultiClass)) -#define IS_CAL_CLIENT_MULTI(obj) (GTK_CHECK_TYPE ((obj), CAL_CLIENT_MULTI_TYPE)) -#define IS_CAL_CLIENT_MULTI_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), CAL_CLIENT_MULTI_TYPE)) - -typedef struct _CalClientMulti CalClientMulti; -typedef struct _CalClientMultiClass CalClientMultiClass; -typedef struct _CalClientMultiPrivate CalClientMultiPrivate; - -struct _CalClientMulti { - GtkObject object; - - /* Private data */ - CalClientMultiPrivate *priv; -}; - -struct _CalClientMultiClass { - GtkObjectClass parent_class; - - /* notification signals */ - void (* cal_opened) (CalClientMulti *multi, CalClient *client, CalClientOpenStatus status); - - void (* obj_updated) (CalClientMulti *multi, CalClient *client, const char *uid); - void (* obj_removed) (CalClientMulti *multi, CalClient *client, const char *uid); - - void (* categories_changed) (CalClientMulti *multi, CalClient *client, GPtrArray *categories); - - void (* forget_password) (CalClientMulti *multi, CalClient *client, const char *key); -}; - -GtkType cal_client_multi_get_type (void); - -CalClientMulti *cal_client_multi_new (void); - -void cal_client_multi_add_client (CalClientMulti *multi, CalClient *client); -void cal_client_multi_set_auth_func (CalClientMulti *multi, - CalClientAuthFunc func, - gpointer user_data); - -CalClient *cal_client_multi_open_calendar (CalClientMulti *multi, - const char *str_uri, - gboolean only_if_exists); -CalClient *cal_client_multi_get_client_for_uri (CalClientMulti *multi, - const char *uri); - -int cal_client_multi_get_n_objects (CalClientMulti *multi, CalObjType type); -CalClientGetStatus cal_client_multi_get_object (CalClientMulti *multi, - const char *uid, - CalComponent **comp); -CalClientGetStatus cal_client_multi_get_timezone (CalClientMulti *multi, - const char *tzid, - icaltimezone **zone); -GList *cal_client_multi_get_uids (CalClientMulti *multi, CalObjType type); -GList *cal_client_multi_get_changes (CalClientMulti *multi, - CalObjType type, - const char *change_id); -GList *cal_client_multi_get_objects_in_range (CalClientMulti *multi, - CalObjType type, - time_t start, - time_t end); -GList *cal_client_multi_get_free_busy (CalClientMulti *multi, - GList *users, - time_t start, - time_t end); -void cal_client_multi_generate_instances (CalClientMulti *multi, - CalObjType type, - time_t start, - time_t end, - CalRecurInstanceFn cb, - gpointer cb_data); -GSList *cal_client_multi_get_alarms_in_range (CalClientMulti *multi, - time_t start, time_t end); - -END_GNOME_DECLS - -#endif diff --git a/calendar/cal-client/cal-client-types.c b/calendar/cal-client/cal-client-types.c deleted file mode 100644 index 6ce98c02c2..0000000000 --- a/calendar/cal-client/cal-client-types.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Evolution calendar utilities and types - * - * Copyright (C) 2000 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#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 9727fc9b3d..0000000000 --- a/calendar/cal-client/cal-client-types.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Evolution calendar utilities and types - * - * Copyright (C) 2000 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#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 30402bf126..0000000000 --- a/calendar/cal-client/cal-client.c +++ /dev/null @@ -1,2552 +0,0 @@ -/* Evolution calendar client - * - * Copyright (C) 2001 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtksignal.h> -#include <liboaf/liboaf.h> -#include <bonobo/bonobo-exception.h> -#include <bonobo/bonobo-moniker-util.h> -#include <bonobo-conf/bonobo-config-database.h> -#include <libgnome/gnome-util.h> - -#include "cal-client-types.h" -#include "cal-client.h" -#include "cal-listener.h" -#include "wombat-client.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 factories we are contacting */ - GList *factories; - - /* Our calendar listener implementation */ - CalListener *listener; - - /* The calendar client interface object we are contacting */ - GNOME_Evolution_Calendar_Cal cal; - - /* The authentication function */ - CalClientAuthFunc auth_func; - gpointer auth_user_data; - - /* The WombatClient */ - WombatClient *w_client; - - /* A cache of timezones retrieved from the server, to avoid getting - them repeatedly for each get_object() call. */ - GHashTable *timezones; - - /* The default timezone to use to resolve DATE and floating DATE-TIME - values. */ - icaltimezone *default_zone; -}; - - - -/* Signal IDs */ -enum { - CAL_OPENED, - CAL_SET_MODE, - OBJ_UPDATED, - OBJ_REMOVED, - CATEGORIES_CHANGED, - FORGET_PASSWORD, - 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 char *client_get_password_cb (WombatClient *w_client, - const gchar *prompt, - const gchar *key, - gpointer user_data); -static void client_forget_password_cb (WombatClient *w_client, - const gchar *key, - gpointer user_data); -static void cal_client_get_object_timezones_cb (icalparameter *param, - void *data); - -static guint cal_client_signals[LAST_SIGNAL]; - -static GtkObjectClass *parent_class; - - - -/** - * cal_client_get_type: - * - * Registers the #CalClient class if necessary, and returns the type ID assigned - * to it. - * - * Return value: The type ID of the #CalClient class. - **/ -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; -} - -#define marshal_NONE__ENUM_ENUM gtk_marshal_NONE__INT_INT - -/* 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[CAL_SET_MODE] = - gtk_signal_new ("cal_set_mode", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (CalClientClass, cal_set_mode), - marshal_NONE__ENUM_ENUM, - GTK_TYPE_NONE, 2, - GTK_TYPE_ENUM, - 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); - cal_client_signals[CATEGORIES_CHANGED] = - gtk_signal_new ("categories_changed", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (CalClientClass, categories_changed), - gtk_marshal_NONE__POINTER, - GTK_TYPE_NONE, 1, - GTK_TYPE_POINTER); - cal_client_signals[FORGET_PASSWORD] = - gtk_signal_new ("forget_password", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (CalClientClass, forget_password), - gtk_marshal_NONE__STRING, - GTK_TYPE_NONE, 1, - GTK_TYPE_STRING); - - gtk_object_class_add_signals (object_class, cal_client_signals, LAST_SIGNAL); - - class->cal_opened = NULL; - class->obj_updated = NULL; - class->obj_removed = NULL; - class->categories_changed = NULL; - class->forget_password = NULL; - - 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->factories = NULL; - priv->timezones = g_hash_table_new (g_str_hash, g_str_equal); - priv->w_client = NULL; - priv->default_zone = icaltimezone_get_utc_timezone (); -} - -/* Gets rid of the factories that a client knows about */ -static void -destroy_factories (CalClient *client) -{ - CalClientPrivate *priv; - CORBA_Object factory; - CORBA_Environment ev; - int result; - GList *f; - - priv = client->priv; - - CORBA_exception_init (&ev); - - for (f = priv->factories; f; f = f->next) { - factory = f->data; - - result = CORBA_Object_is_nil (factory, &ev); - if (BONOBO_EX (&ev)) { - g_message ("destroy_factories(): could not see if a factory was nil"); - CORBA_exception_free (&ev); - - continue; - } - - if (result) - continue; - - CORBA_Object_release (factory, &ev); - if (BONOBO_EX (&ev)) { - g_message ("destroy_factories(): could not release a factory"); - CORBA_exception_free (&ev); - } - } - - g_list_free (priv->factories); - priv->factories = 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 (BONOBO_EX (&ev)) { - 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 (BONOBO_EX (&ev)) - g_message ("destroy_cal(): could not unref the calendar client interface object"); - - CORBA_exception_free (&ev); - - CORBA_exception_init (&ev); - CORBA_Object_release (priv->cal, &ev); - if (BONOBO_EX (&ev)) - g_message ("destroy_cal(): could not release the calendar client interface object"); - - CORBA_exception_free (&ev); - priv->cal = CORBA_OBJECT_NIL; - -} - -static void -free_timezone (gpointer key, gpointer value, gpointer data) -{ - /* Note that the key comes from within the icaltimezone value, so we - don't free that. */ - icaltimezone_free (value, TRUE); -} - -/* 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; - - /* The server unrefs the query listener, so we just NULL it out here */ - if (priv->listener) { - cal_listener_stop_notification (priv->listener); - priv->listener = NULL; - } - - priv->w_client = NULL; - destroy_factories (client); - destroy_cal (client); - - priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED; - - if (priv->uri) { - g_free (priv->uri); - priv->uri = NULL; - } - - g_hash_table_foreach (priv->timezones, free_timezone, NULL); - g_hash_table_destroy (priv->timezones); - priv->timezones = NULL; - - g_free (priv); - client->priv = NULL; - - if (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 (BONOBO_EX (&ev)) { - g_message ("cal_opened_cb(): could not duplicate the " - "calendar client interface"); - CORBA_exception_free (&ev); - goto error; - } - CORBA_exception_free (&ev); - - 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 cal_set_mode notification from the listener */ -static void -cal_set_mode_cb (CalListener *listener, - GNOME_Evolution_Calendar_Listener_SetModeStatus status, - GNOME_Evolution_Calendar_CalMode mode, - gpointer data) -{ - CalClient *client; - CalClientPrivate *priv; - CalClientSetModeStatus client_status; - - client = CAL_CLIENT (data); - priv = client->priv; - - client_status = CAL_CLIENT_OPEN_ERROR; - - switch (status) { - case GNOME_Evolution_Calendar_Listener_MODE_SET: - client_status = CAL_CLIENT_SET_MODE_SUCCESS; - break; - case GNOME_Evolution_Calendar_Listener_MODE_NOT_SET: - client_status = CAL_CLIENT_SET_MODE_ERROR; - break; - case GNOME_Evolution_Calendar_Listener_MODE_NOT_SUPPORTED: - client_status = CAL_CLIENT_SET_MODE_NOT_SUPPORTED; - break; - default: - g_assert_not_reached (); - } - - /* 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_SET_MODE], - client_status, mode); - - 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); -} - -/* Handle the categories_changed signal from the listener */ -static void -categories_changed_cb (CalListener *listener, const GNOME_Evolution_Calendar_StringSeq *categories, - gpointer data) -{ - CalClient *client; - GPtrArray *cats; - int i; - - client = CAL_CLIENT (data); - - cats = g_ptr_array_new (); - g_ptr_array_set_size (cats, categories->_length); - - for (i = 0; i < categories->_length; i++) - cats->pdata[i] = categories->_buffer[i]; - - gtk_signal_emit (GTK_OBJECT (client), cal_client_signals[CATEGORIES_CHANGED], cats); - - g_ptr_array_free (cats, TRUE); -} - - -/* Handle the get_password signal from the Wombatclient */ -static gchar * -client_get_password_cb (WombatClient *w_client, - const gchar *prompt, - const gchar *key, - gpointer user_data) -{ - CalClient *client; - - client = CAL_CLIENT (user_data); - g_return_val_if_fail (IS_CAL_CLIENT (client), NULL); - - if (client->priv->auth_func) - return client->priv->auth_func (client, prompt, key, client->priv->auth_user_data); - - return NULL; -} - -/* Handle the forget_password signal from the WombatClient */ -static void -client_forget_password_cb (WombatClient *w_client, - const gchar *key, - gpointer user_data) -{ - CalClient *client; - - client = CAL_CLIENT (user_data); - g_return_if_fail (IS_CAL_CLIENT (client)); - - gtk_signal_emit (GTK_OBJECT (client), - cal_client_signals [FORGET_PASSWORD], - key); -} - - - -/** - * cal_client_construct: - * @client: A calendar client. - * - * Constructs a calendar client object by contacting all available - * calendar factories. - * - * 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; - OAF_ServerInfoList *servers; - CORBA_Environment ev; - int i; - - 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; - - CORBA_exception_init (&ev); - - servers = oaf_query ("repo_ids.has ('IDL:GNOME/Evolution/Calendar/CalFactory:1.0')", NULL, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("Cannot perform OAF query for Calendar servers."); - CORBA_exception_free (&ev); - return NULL; - } - - if (servers->_length == 0) - g_warning ("No Calendar servers installed."); - - for (i = 0; i < servers->_length; i++) { - const OAF_ServerInfo *info; - - info = servers->_buffer + i; - - g_print ("Factory: %s\n", info->iid); - factory = (GNOME_Evolution_Calendar_CalFactory) - oaf_activate_from_id (info->iid, 0, NULL, &ev); - if (BONOBO_EX (&ev)) { - g_warning ("cal_client_construct: Could not activate calendar server %s", info->iid); - CORBA_free (servers); - CORBA_exception_free (&ev); - return NULL; - } - - priv->factories = g_list_prepend (priv->factories, factory); - } - - CORBA_free (servers); - - CORBA_exception_free (&ev); - 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_set_auth_func - * @client: A calendar client. - * @func: The authentication function - * @data: User data to be used when calling the authentication function - * - * Associates the given authentication function with a calendar client. This - * function will be called any time the calendar server needs a password - * from the client. So, calendar clients should provide such authentication - * function, which, when called, should act accordingly (by showing a dialog - * box, for example, to ask the user for the password). - * - * The authentication function must have the following form: - * char * auth_func (CalClient *client, - * const gchar *prompt, - * const gchar *key, - * gpointer user_data) - */ -void -cal_client_set_auth_func (CalClient *client, CalClientAuthFunc func, gpointer data) -{ - g_return_if_fail (client != NULL); - g_return_if_fail (IS_CAL_CLIENT (client)); - - client->priv->auth_func = func; - client->priv->auth_user_data = data; -} - -static gboolean -real_open_calendar (CalClient *client, const char *str_uri, gboolean only_if_exists, gboolean *supported) -{ - CalClientPrivate *priv; - GNOME_Evolution_Calendar_Listener corba_listener; - int unsupported; - GList *f; - CORBA_Environment ev; - - priv = client->priv; - g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_NOT_LOADED, FALSE); - g_assert (priv->uri == NULL); - - g_return_val_if_fail (str_uri != NULL, FALSE); - - priv->listener = cal_listener_new (cal_opened_cb, - cal_set_mode_cb, - obj_updated_cb, - obj_removed_cb, - categories_changed_cb, - client); - if (!priv->listener) { - g_message ("cal_client_open_calendar(): could not create the listener"); - return FALSE; - } - - /* create the WombatClient */ - priv->w_client = wombat_client_new ( - (WombatClientGetPasswordFn) client_get_password_cb, - (WombatClientForgetPasswordFn) client_forget_password_cb, - (gpointer) client); - bonobo_object_add_interface (BONOBO_OBJECT (priv->listener), - BONOBO_OBJECT (priv->w_client)); - - corba_listener = (GNOME_Evolution_Calendar_Listener) (BONOBO_OBJREF (priv->listener)); - - priv->load_state = CAL_CLIENT_LOAD_LOADING; - priv->uri = g_strdup (str_uri); - - unsupported = 0; - for (f = priv->factories; f; f = f->next) { - CORBA_exception_init (&ev); - - GNOME_Evolution_Calendar_CalFactory_open (f->data, str_uri, - only_if_exists, - corba_listener, &ev); - if (!BONOBO_EX (&ev)) - break; - else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_CalFactory_UnsupportedMethod)) - unsupported++; - } - - if (supported != NULL) { - if (unsupported == g_list_length (priv->factories)) - *supported = FALSE; - else - *supported = TRUE; - } - - if (BONOBO_EX (&ev)) { - 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; - } - - return TRUE; -} - -/** - * 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) -{ - g_return_val_if_fail (client != NULL, FALSE); - g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE); - - return real_open_calendar (client, str_uri, only_if_exists, NULL); -} - -static char * -get_fall_back_uri (gboolean tasks) -{ - if (tasks) - return g_concat_dir_and_file (g_get_home_dir (), - "evolution/local/" - "Tasks/tasks.ics"); - else - return g_concat_dir_and_file (g_get_home_dir (), - "evolution/local/" - "Calendar/calendar.ics"); -} - -static char * -get_default_uri (gboolean tasks) -{ - Bonobo_ConfigDatabase db; - char *uri; - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - db = bonobo_get_object ("wombat:", "Bonobo/ConfigDatabase", &ev); - - if (BONOBO_EX (&ev) || db == CORBA_OBJECT_NIL) { - CORBA_exception_free (&ev); - return NULL; - } - - if (tasks) - uri = bonobo_config_get_string (db, "/DefaultFolders/tasks_uri", &ev); - else - uri = bonobo_config_get_string (db, "/DefaultFolders/calendar_uri", &ev); - bonobo_object_release_unref (db, NULL); - - if (BONOBO_EX (&ev)) { - CORBA_exception_free (&ev); - uri = get_fall_back_uri (tasks); - } else { - uri = cal_util_expand_uri (uri, tasks); - } - - return uri; -} - -gboolean -cal_client_open_default_calendar (CalClient *client, gboolean only_if_exists) -{ - char *default_uri, *fall_back; - gboolean result, supported; - - g_return_val_if_fail (client != NULL, FALSE); - g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE); - - default_uri = get_default_uri (FALSE); - fall_back = get_fall_back_uri (FALSE); - - result = real_open_calendar (client, default_uri, only_if_exists, &supported); - if (!supported && strcmp (fall_back, default_uri)) - result = real_open_calendar (client, fall_back, only_if_exists, NULL); - - g_free (default_uri); - g_free (fall_back); - - return result; -} - -gboolean -cal_client_open_default_tasks (CalClient *client, gboolean only_if_exists) -{ - char *default_uri, *fall_back; - gboolean result, supported; - - g_return_val_if_fail (client != NULL, FALSE); - g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE); - - default_uri = get_default_uri (TRUE); - fall_back = get_fall_back_uri (TRUE); - - result = real_open_calendar (client, default_uri, only_if_exists, &supported); - if (!supported && strcmp (fall_back, default_uri)) - result = real_open_calendar (client, fall_back, only_if_exists, NULL); - - g_free (default_uri); - g_free (fall_back); - - return result; -} - -/* Builds an URI list out of a CORBA string sequence */ -static GList * -build_uri_list (GNOME_Evolution_Calendar_StringSeq *seq) -{ - GList *uris = NULL; - int i; - - for (i = 0; i < seq->_length; i++) - uris = g_list_prepend (uris, g_strdup (seq->_buffer[i])); - - return uris; -} - -/** - * cal_client_uri_list: - * @client: A calendar client - * @type: type of uri's to get - * - * - * Return value: A list of URI's open on the wombat - **/ -GList * -cal_client_uri_list (CalClient *client, CalMode mode) -{ - CalClientPrivate *priv; - GNOME_Evolution_Calendar_StringSeq *uri_seq; - GList *uris = NULL; - CORBA_Environment ev; - GList *f; - - g_return_val_if_fail (client != NULL, FALSE); - g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE); - - priv = client->priv; - - for (f = priv->factories; f; f = f->next) { - CORBA_exception_init (&ev); - uri_seq = GNOME_Evolution_Calendar_CalFactory_uriList (f->data, mode, &ev); - - if (BONOBO_EX (&ev)) { - g_message ("cal_client_uri_list(): request failed"); - - /* free memory and return */ - g_list_foreach (uris, (GFunc) g_free, NULL); - g_list_free (uris); - uris = NULL; - break; - } - else - uris = g_list_concat (uris, build_uri_list (uri_seq)); - - CORBA_exception_free (&ev); - } - - return uris; -} - -/** - * 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)); -} - -gboolean -cal_client_set_mode (CalClient *client, CalMode mode) -{ - CalClientPrivate *priv; - gboolean retval = TRUE; - CORBA_Environment ev; - - 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); - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_Cal_setMode (priv->cal, mode, &ev); - - if (BONOBO_EX (&ev)) - retval = FALSE; - - CORBA_exception_free (&ev); - - return retval; -} - -/** - * cal_client_get_n_objects: - * @client: A calendar client. - * @type: Type of objects that will be counted. - * - * Counts the number of calendar components of the specified @type. This can be - * used to count how many events, to-dos, or journals there are, for example. - * - * Return value: Number of components. - **/ -int -cal_client_get_n_objects (CalClient *client, CalObjType type) -{ - CalClientPrivate *priv; - CORBA_Environment ev; - int n; - int t; - - g_return_val_if_fail (client != NULL, -1); - g_return_val_if_fail (IS_CAL_CLIENT (client), -1); - - priv = client->priv; - g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, -1); - - t = corba_obj_type (type); - - CORBA_exception_init (&ev); - n = GNOME_Evolution_Calendar_Cal_countObjects (priv->cal, t, &ev); - - if (BONOBO_EX (&ev)) { - g_message ("cal_client_get_n_objects(): could not get the number of objects"); - CORBA_exception_free (&ev); - return -1; - } - - CORBA_exception_free (&ev); - return n; -} - - -/* This is used in the callback which fetches all the timezones needed for an - object. */ -typedef struct _CalClientGetTimezonesData CalClientGetTimezonesData; -struct _CalClientGetTimezonesData { - CalClient *client; - - /* This starts out at CAL_CLIENT_GET_SUCCESS. If an error occurs this - contains the last error. */ - CalClientGetStatus status; -}; - - -/** - * 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; - CalClientGetTimezonesData cb_data; - - 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 (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound)) - goto out; - else if (BONOBO_EX (&ev)) { - g_message ("cal_client_get_object(): could not get the object"); - goto out; - } - - 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; - } - - /* Now make sure we have all timezones needed for this object. - We do this to try to avoid any problems caused by getting a timezone - in the middle of other code. Any calls to ORBit result in a - recursive call of the GTK+ main loop, which can cause problems for - code that doesn't expect it. Currently GnomeCanvas has problems if - we try to get a timezone in the middle of a redraw, and there is a - resize pending, which leads to an assert failure and an abort. */ - cb_data.client = client; - cb_data.status = CAL_CLIENT_GET_SUCCESS; - icalcomponent_foreach_tzid (icalcomp, - cal_client_get_object_timezones_cb, - &cb_data); - - retval = cb_data.status; - - out: - - CORBA_exception_free (&ev); - return retval; -} - - -static void -cal_client_get_object_timezones_cb (icalparameter *param, - void *data) -{ - CalClientGetTimezonesData *cb_data = data; - const char *tzid; - icaltimezone *zone; - CalClientGetStatus status; - - tzid = icalparameter_get_tzid (param); - if (!tzid) { - cb_data->status = CAL_CLIENT_GET_SYNTAX_ERROR; - return; - } - - status = cal_client_get_timezone (cb_data->client, tzid, &zone); - if (status != CAL_CLIENT_GET_SUCCESS) - cb_data->status = status; -} - - -CalClientGetStatus -cal_client_get_timezone (CalClient *client, - const char *tzid, - icaltimezone **zone) -{ - CalClientPrivate *priv; - CORBA_Environment ev; - GNOME_Evolution_Calendar_CalObj comp_str; - CalClientGetStatus retval; - icalcomponent *icalcomp; - icaltimezone *tmp_zone; - - g_return_val_if_fail (client != NULL, CAL_CLIENT_GET_NOT_FOUND); - g_return_val_if_fail (IS_CAL_CLIENT (client), CAL_CLIENT_GET_NOT_FOUND); - - priv = client->priv; - g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, - CAL_CLIENT_GET_NOT_FOUND); - - g_return_val_if_fail (zone != NULL, CAL_CLIENT_GET_NOT_FOUND); - - /* If tzid is NULL or "" we return NULL, since it is a 'local time'. */ - if (!tzid || !tzid[0]) { - *zone = NULL; - return CAL_CLIENT_GET_SUCCESS; - } - - /* If it is UTC, we return the special UTC timezone. */ - if (!strcmp (tzid, "UTC")) { - *zone = icaltimezone_get_utc_timezone (); - return CAL_CLIENT_GET_SUCCESS; - } - - /* See if we already have it in the cache. */ - tmp_zone = g_hash_table_lookup (priv->timezones, tzid); - if (tmp_zone) { - *zone = tmp_zone; - return CAL_CLIENT_GET_SUCCESS; - } - - retval = CAL_CLIENT_GET_NOT_FOUND; - *zone = NULL; - - /* We don't already have it, so we try to get it from the server. */ - CORBA_exception_init (&ev); - comp_str = GNOME_Evolution_Calendar_Cal_getTimezoneObject (priv->cal, (char *) tzid, &ev); - - if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound)) - goto out; - else if (BONOBO_EX (&ev)) { - g_message ("cal_client_get_timezone(): could not get the object"); - goto out; - } - - icalcomp = icalparser_parse_string (comp_str); - CORBA_free (comp_str); - - if (!icalcomp) { - retval = CAL_CLIENT_GET_SYNTAX_ERROR; - goto out; - } - - tmp_zone = icaltimezone_new (); - if (!tmp_zone) { - /* FIXME: Needs better error code - out of memory. Or just - abort like GTK+ does? */ - retval = CAL_CLIENT_GET_NOT_FOUND; - goto out; - } - - if (!icaltimezone_set_component (tmp_zone, icalcomp)) { - retval = CAL_CLIENT_GET_SYNTAX_ERROR; - goto out; - } - - /* Now add it to the cache, to avoid the server call in future. */ - g_hash_table_insert (priv->timezones, icaltimezone_get_tzid (tmp_zone), - tmp_zone); - - *zone = tmp_zone; - retval = CAL_CLIENT_GET_SUCCESS; - - out: - - CORBA_exception_free (&ev); - return retval; -} - -/* Resolves TZIDs for the recurrence generator. */ -icaltimezone* -cal_client_resolve_tzid_cb (const char *tzid, gpointer data) -{ - CalClient *client; - icaltimezone *zone = NULL; - CalClientGetStatus status; - - g_return_val_if_fail (data != NULL, NULL); - g_return_val_if_fail (IS_CAL_CLIENT (data), NULL); - - client = CAL_CLIENT (data); - - /* FIXME: Handle errors. */ - status = cal_client_get_timezone (client, tzid, &zone); - - return zone; -} - - -/* Builds an UID list out of a CORBA UID sequence */ -static GList * -build_uid_list (GNOME_Evolution_Calendar_CalObjUIDSeq *seq) -{ - GList *uids; - int i; - - uids = NULL; - - for (i = 0; i < seq->_length; i++) - uids = g_list_prepend (uids, g_strdup (seq->_buffer[i])); - - return uids; -} - -/** - * cal_client_get_uids: - * @client: A calendar client. - * @type: Bitmask with types of objects to return. - * - * Queries a calendar for a list of unique identifiers corresponding to calendar - * objects whose type matches one of the types specified in the @type flags. - * - * Return value: A list of strings that are the sought UIDs. This should be - * freed using the cal_obj_uid_list_free() function. - **/ -GList * -cal_client_get_uids (CalClient *client, CalObjType type) -{ - 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 (BONOBO_EX (&ev)) { - 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 (BONOBO_EX (&ev)) { - 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 (BONOBO_EX (&ev)) { - 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; -} - -/** - * cal_client_get_free_busy - * @client:: A calendar client. - * @users: List of users to retrieve free/busy information for. - * @start: Start time for query. - * @end: End time for query. - * - * Gets free/busy information from the calendar server. - * - * Returns: a GList of VFREEBUSY CalComponents - */ -GList * -cal_client_get_free_busy (CalClient *client, GList *users, - time_t start, time_t end) -{ - CalClientPrivate *priv; - CORBA_Environment ev; - GNOME_Evolution_Calendar_UserList *corba_list; - GNOME_Evolution_Calendar_CalObjSeq *calobj_list; - GList *l; - GList *comp_list = NULL; - int len, i; - - 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); - - /* create the CORBA user list to be passed to the backend */ - len = g_list_length (users); - - corba_list = GNOME_Evolution_Calendar_UserList__alloc (); - CORBA_sequence_set_release (corba_list, TRUE); - corba_list->_length = len; - corba_list->_buffer = CORBA_sequence_GNOME_Evolution_Calendar_User_allocbuf (len); - - for (l = g_list_first (users), i = 0; l; l = l->next, i++) - corba_list->_buffer[i] = CORBA_string_dup ((CORBA_char *) l->data); - - /* call the method on the backend */ - CORBA_exception_init (&ev); - - calobj_list = GNOME_Evolution_Calendar_Cal_getFreeBusy (priv->cal, corba_list, - start, end, &ev); - CORBA_free (corba_list); - if (BONOBO_EX (&ev) || !calobj_list) { - g_message ("cal_client_get_free_busy(): could not get the objects"); - CORBA_exception_free (&ev); - return NULL; - } - - for (i = 0; i < calobj_list->_length; i++) { - CalComponent *comp; - icalcomponent *icalcomp; - icalcomponent_kind kind; - - icalcomp = icalparser_parse_string (calobj_list->_buffer[i]); - if (!icalcomp) - continue; - - kind = icalcomponent_isa (icalcomp); - if (kind == ICAL_VFREEBUSY_COMPONENT) { - comp = cal_component_new (); - if (!cal_component_set_icalcomponent (comp, icalcomp)) { - icalcomponent_free (icalcomp); - gtk_object_unref (GTK_OBJECT (comp)); - continue; - } - - comp_list = g_list_append (comp_list, comp); - } - else - icalcomponent_free (icalcomp); - } - - CORBA_exception_free (&ev); - CORBA_free (calobj_list); - - return comp_list; -} - -/* Callback used when an object is updated and we must update the copy we have */ -static void -generate_instances_obj_updated_cb (CalClient *client, const char *uid, gpointer data) -{ - GHashTable *uid_comp_hash; - CalComponent *comp; - 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, - cal_client_resolve_tzid_cb, client, - priv->default_zone); - 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_start = corba_instance->occur_start; - instance->occur_end = corba_instance->occur_end; - - alarms = g_slist_prepend (alarms, instance); - } - - return g_slist_reverse (alarms); -} - -/* Builds a list of CalComponentAlarms structures */ -static GSList * -build_component_alarms_list (GNOME_Evolution_Calendar_CalComponentAlarmsSeq *seq) -{ - 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 (BONOBO_EX (&ev)) { - 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 (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound)) - goto out; - else if (BONOBO_EX (&ev)) { - g_message ("cal_client_get_alarms_for_object(): could not get the alarm range"); - goto out; - } - - icalcomp = icalparser_parse_string (corba_alarms->calobj); - if (!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; -} - -typedef struct _ForeachTZIDCallbackData ForeachTZIDCallbackData; -struct _ForeachTZIDCallbackData { - CalClient *client; - GHashTable *timezone_hash; - gboolean include_all_timezones; - gboolean success; -}; - -/* This adds the VTIMEZONE given by the TZID parameter to the GHashTable in - data. */ -static void -foreach_tzid_callback (icalparameter *param, void *cbdata) -{ - ForeachTZIDCallbackData *data = cbdata; - CalClientPrivate *priv; - const char *tzid; - icaltimezone *zone; - icalcomponent *vtimezone_comp; - char *vtimezone_as_string; - - priv = data->client->priv; - - /* Get the TZID string from the parameter. */ - tzid = icalparameter_get_tzid (param); - if (!tzid) - return; - - /* Check if we've already added it to the GHashTable. */ - if (g_hash_table_lookup (data->timezone_hash, tzid)) - return; - - if (data->include_all_timezones) { - CalClientGetStatus status; - - status = cal_client_get_timezone (data->client, tzid, &zone); - if (status != CAL_CLIENT_GET_SUCCESS) { - data->success = FALSE; - return; - } - } else { - /* Check if it is in our cache. If it is, it must already be - on the server so return. */ - if (g_hash_table_lookup (priv->timezones, tzid)) - return; - - /* Check if it is a builtin timezone. If it isn't, return. */ - zone = icaltimezone_get_builtin_timezone_from_tzid (tzid); - if (!zone) - return; - } - - /* Convert it to a string and add it to the hash. */ - vtimezone_comp = icaltimezone_get_component (zone); - if (!vtimezone_comp) - return; - - vtimezone_as_string = icalcomponent_as_ical_string (vtimezone_comp); - - g_hash_table_insert (data->timezone_hash, (char*) tzid, - g_strdup (vtimezone_as_string)); -} - -/* This appends the value string to the GString given in data. */ -static void -append_timezone_string (gpointer key, gpointer value, gpointer data) -{ - GString *vcal_string = data; - - g_string_append (vcal_string, value); - g_free (value); -} - - -/* This simply frees the hash values. */ -static void -free_timezone_string (gpointer key, gpointer value, gpointer data) -{ - g_free (value); -} - - -/* This converts the VEVENT/VTODO to a string. If include_all_timezones is - TRUE, it includes all the VTIMEZONE components needed for the VEVENT/VTODO. - If not, it only includes builtin timezones that may not be on the server. - - To do that we check every TZID in the component to see if it is a builtin - timezone. If it is, we see if it it in our cache. If it is in our cache, - then we know the server already has it and we don't need to send it. - If it isn't in our cache, then we need to send it to the server. - If we need to send any timezones to the server, then we have to create a - complete VCALENDAR object, otherwise we can just send a single VEVENT/VTODO - as before. */ -static char* -cal_client_get_component_as_string_internal (CalClient *client, - CalComponent *comp, - gboolean include_all_timezones) -{ - GHashTable *timezone_hash; - GString *vcal_string; - int initial_vcal_string_len; - ForeachTZIDCallbackData cbdata; - char *obj_string; - - CalClientPrivate *priv; - - priv = client->priv; - - timezone_hash = g_hash_table_new (g_str_hash, g_str_equal); - - /* Add any timezones needed to the hash. We use a hash since we only - want to add each timezone once at most. */ - cbdata.client = client; - cbdata.timezone_hash = timezone_hash; - cbdata.include_all_timezones = include_all_timezones; - cbdata.success = TRUE; - icalcomponent_foreach_tzid (cal_component_get_icalcomponent (comp), - foreach_tzid_callback, &cbdata); - if (!cbdata.success) { - g_hash_table_foreach (timezone_hash, free_timezone_string, - NULL); - return NULL; - } - - /* Create the start of a VCALENDAR, to add the VTIMEZONES to, - and remember its length so we know if any VTIMEZONEs get added. */ - vcal_string = g_string_new (NULL); - g_string_append (vcal_string, - "BEGIN:VCALENDAR\n" - "PRODID:-//Ximian//NONSGML Evolution Calendar//EN\n" - "VERSION:2.0\n" - "METHOD:PUBLISH\n"); - initial_vcal_string_len = vcal_string->len; - - /* Now concatenate all the timezone strings. This also frees the - timezone strings as it goes. */ - g_hash_table_foreach (timezone_hash, append_timezone_string, - vcal_string); - - /* Get the string for the VEVENT/VTODO. */ - obj_string = cal_component_get_as_string (comp); - - /* If there were any timezones to send, create a complete VCALENDAR, - else just send the VEVENT/VTODO string. */ - if (!include_all_timezones - && vcal_string->len == initial_vcal_string_len) { - g_string_free (vcal_string, TRUE); - } else { - g_string_append (vcal_string, obj_string); - g_string_append (vcal_string, "END:VCALENDAR\n"); - g_free (obj_string); - obj_string = vcal_string->str; - g_string_free (vcal_string, FALSE); - } - - g_hash_table_destroy (timezone_hash); - - return obj_string; -} - -/** - * cal_client_get_component_as_string: - * @client: A calendar client. - * @comp: A calendar component object. - * - * Gets a calendar component as an iCalendar string, with a toplevel - * VCALENDAR component and all VTIMEZONEs needed for the component. - * - * Return value: the component as a complete iCalendar string, or NULL on - * failure. The string should be freed after use. - **/ -char* -cal_client_get_component_as_string (CalClient *client, - CalComponent *comp) -{ - return cal_client_get_component_as_string_internal (client, comp, - TRUE); -} - - -/** - * 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; - - 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_client_get_component_as_string_internal (client, - comp, FALSE); - if (obj_string == NULL) - return FALSE; - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_Cal_updateObjects (priv->cal, obj_string, &ev); - g_free (obj_string); - - if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_InvalidObject)) - goto out; - else if (BONOBO_EX (&ev)) { - g_message ("cal_client_update_object(): could not update the object"); - goto out; - } - - retval = TRUE; - - out: - CORBA_exception_free (&ev); - return retval; -} - -/** - * cal_client_update_objects: - * @client: A calendar client. - * @icalcomp: A toplevel VCALENDAR libical component. - * - * Asks a calendar to add or update one or more components, possibly including - * VTIMEZONE data. Any existing components with the same UIDs will be - * replaced. The VTIMEZONE data will be compared to existing VTIMEZONEs in - * the calendar, and the VTIMEZONEs may possibly be renamed, as well as all - * references to them throughout the VCALENDAR. - * - * The client program should not assume that the objects are actually in the - * server's storage until it has received the "obj_updated" notification - * signal. - * - * Return value: TRUE on success, FALSE on specifying an invalid component. - **/ -gboolean -cal_client_update_objects (CalClient *client, icalcomponent *icalcomp) -{ - CalClientPrivate *priv; - CORBA_Environment ev; - gboolean retval; - char *obj_string; - - 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 (icalcomp != NULL, FALSE); - - retval = FALSE; - - /* Libical owns this memory, using one of its temporary buffers. */ - obj_string = icalcomponent_as_ical_string (icalcomp); - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_Cal_updateObjects (priv->cal, obj_string, &ev); - - if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_InvalidObject)) - goto out; - else if (BONOBO_EX (&ev)) { - g_message ("cal_client_update_objects(): could not update the objects"); - 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 (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound)) - goto out; - else if (BONOBO_EX (&ev)) { - g_message ("cal_client_remove_object(): could not remove the object"); - goto out; - } - - retval = TRUE; - - out: - CORBA_exception_free (&ev); - return retval; -} - -/** - * cal_client_get_query: - * @client: A calendar client. - * @sexp: S-expression representing the query. - * - * Creates a live query object from a loaded calendar. - * - * Return value: A query object that will emit notification signals as calendar - * components are added and removed from the query in the server. - **/ -CalQuery * -cal_client_get_query (CalClient *client, const char *sexp) -{ - CalClientPrivate *priv; - - 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, FALSE); - - g_return_val_if_fail (sexp != NULL, NULL); - - return cal_query_new (priv->cal, sexp); -} - - -/* This ensures that the given timezone is on the server. We use this to pass - the default timezone to the server, so it can resolve DATE and floating - DATE-TIME values into specific times. (Most of our IDL interface uses - time_t values to pass specific times from the server to the client.) */ -static gboolean -cal_client_ensure_timezone_on_server (CalClient *client, icaltimezone *zone) -{ - CalClientPrivate *priv; - char *tzid, *obj_string; - icaltimezone *tmp_zone; - GString *vcal_string; - gboolean retval = FALSE; - icalcomponent *vtimezone_comp; - char *vtimezone_as_string; - CORBA_Environment ev; - - priv = client->priv; - - /* If the zone is NULL or UTC we don't need to do anything. */ - if (!zone) - return TRUE; - - tzid = icaltimezone_get_tzid (zone); - - if (!strcmp (tzid, "UTC")) - return TRUE; - - /* See if we already have it in the cache. If we do, it must be on - the server already. */ - tmp_zone = g_hash_table_lookup (priv->timezones, tzid); - if (tmp_zone) - return TRUE; - - /* Now we have to send it to the server, in case it doesn't already - have it. */ - - vcal_string = g_string_new (NULL); - g_string_append (vcal_string, - "BEGIN:VCALENDAR\n" - "PRODID:-//Ximian//NONSGML Evolution Calendar//EN\n" - "VERSION:2.0\n"); - - /* Convert the timezone to a string and add it. */ - vtimezone_comp = icaltimezone_get_component (zone); - if (!vtimezone_comp) { - g_string_free (vcal_string, TRUE); - return FALSE; - } - - /* We don't need to free this string as libical owns it. */ - vtimezone_as_string = icalcomponent_as_ical_string (vtimezone_comp); - g_string_append (vcal_string, vtimezone_as_string); - - g_string_append (vcal_string, "END:VCALENDAR\n"); - - obj_string = vcal_string->str; - g_string_free (vcal_string, FALSE); - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_Cal_updateObjects (priv->cal, obj_string, &ev); - g_free (obj_string); - - if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_InvalidObject)) - goto out; - else if (BONOBO_EX (&ev)) { - g_message ("cal_client_ensure_timezone_on_server(): could not add the timezone to the server"); - goto out; - } - - retval = TRUE; - - out: - CORBA_exception_free (&ev); - return retval; -} - - -gboolean -cal_client_set_default_timezone (CalClient *client, icaltimezone *zone) -{ - CalClientPrivate *priv; - gboolean retval = FALSE; - CORBA_Environment ev; - const char *tzid; - - g_return_val_if_fail (client != NULL, FALSE); - g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE); - g_return_val_if_fail (zone != NULL, FALSE); - - priv = client->priv; - - g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, - FALSE); - - /* Make sure the server has the VTIMEZONE data. */ - if (!cal_client_ensure_timezone_on_server (client, zone)) - return FALSE; - - /* Now set the default timezone on the server. */ - CORBA_exception_init (&ev); - tzid = icaltimezone_get_tzid (zone); - GNOME_Evolution_Calendar_Cal_setDefaultTimezone (priv->cal, - (char *) tzid, &ev); - - if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_NotFound)) - goto out; - else if (BONOBO_EX (&ev)) { - g_message ("cal_client_set_default_timezone(): could not set the default timezone"); - goto out; - } - - retval = TRUE; - - priv->default_zone = zone; - - 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 a362059f3a..0000000000 --- a/calendar/cal-client/cal-client.h +++ /dev/null @@ -1,183 +0,0 @@ -/* Evolution calendar client - * - * Copyright (C) 2001 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#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> -#include <cal-client/cal-query.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; - -/* Set mode status for the cal_client_set_mode function */ -typedef enum { - CAL_CLIENT_SET_MODE_SUCCESS, - CAL_CLIENT_SET_MODE_ERROR, - CAL_CLIENT_SET_MODE_NOT_SUPPORTED -} CalClientSetModeStatus; - -/* 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 (* cal_set_mode) (CalClient *client, CalClientSetModeStatus status, CalMode mode); - - void (* obj_updated) (CalClient *client, const char *uid); - void (* obj_removed) (CalClient *client, const char *uid); - - void (* categories_changed) (CalClient *client, GPtrArray *categories); - - void (* forget_password) (CalClient *client, const char *key); -}; - -typedef gchar * (* CalClientAuthFunc) (CalClient *client, - const gchar *prompt, - const gchar *key, - gpointer user_data); - -GtkType cal_client_get_type (void); - -CalClient *cal_client_construct (CalClient *client); - -CalClient *cal_client_new (void); - -void cal_client_set_auth_func (CalClient *client, CalClientAuthFunc func, gpointer data); - -/* Sets the default timezone to use to resolve DATE and floating DATE-TIME - values. This will typically be from the user's timezone setting. Call this - before using any other functions. It will pass the default timezone on to - the server. Returns TRUE on success. */ -gboolean cal_client_set_default_timezone (CalClient *client, icaltimezone *zone); - -gboolean cal_client_open_calendar (CalClient *client, const char *str_uri, gboolean only_if_exists); -gboolean cal_client_open_default_calendar (CalClient *client, gboolean only_if_exists); -gboolean cal_client_open_default_tasks (CalClient *client, gboolean only_if_exists); - -GList *cal_client_uri_list (CalClient *client, CalMode mode); - -CalClientLoadState cal_client_get_load_state (CalClient *client); - -const char *cal_client_get_uri (CalClient *client); - -gboolean cal_client_set_mode (CalClient *client, CalMode mode); - -int cal_client_get_n_objects (CalClient *client, CalObjType type); - -CalClientGetStatus cal_client_get_object (CalClient *client, - const char *uid, - CalComponent **comp); - -CalClientGetStatus cal_client_get_timezone (CalClient *client, - const char *tzid, - icaltimezone **zone); - -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); - -GList *cal_client_get_free_busy (CalClient *client, GList *users, - 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); - -/* Add or update a single object. When adding an object only builtin timezones - are allowed. To use external VTIMEZONE data call update_objects() instead.*/ -gboolean cal_client_update_object (CalClient *client, CalComponent *comp); - -/* Add or update multiple objects, possibly including VTIMEZONE data. */ -gboolean cal_client_update_objects (CalClient *client, icalcomponent *icalcomp); - -gboolean cal_client_remove_object (CalClient *client, const char *uid); - -CalQuery *cal_client_get_query (CalClient *client, const char *sexp); - -/* Resolves TZIDs for the recurrence generator. */ -icaltimezone *cal_client_resolve_tzid_cb (const char *tzid, gpointer data); - -/* Returns a complete VCALENDAR for a VEVENT/VTODO including all VTIMEZONEs - used by the component. It also includes a 'METHOD:PUBLISH' property. */ -char* cal_client_get_component_as_string (CalClient *client, - CalComponent *comp); - - - - -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 c3fe31e60d..0000000000 --- a/calendar/cal-client/cal-listener.c +++ /dev/null @@ -1,364 +0,0 @@ -/* Evolution calendar listener - * - * Copyright (C) 2001 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#include <config.h> -#include "cal-listener.h" - - - -/* Private part of the CalListener structure */ -struct CalListenerPrivate { - /* Notification functions and their closure data */ - CalListenerCalOpenedFn cal_opened_fn; - CalListenerCalSetModeFn cal_set_mode_fn; - CalListenerObjUpdatedFn obj_updated_fn; - CalListenerObjRemovedFn obj_removed_fn; - CalListenerCategoriesChangedFn categories_changed_fn; - gpointer fn_data; - - /* Whether notification is desired */ - gboolean notify : 1; -}; - - - -static void cal_listener_class_init (CalListenerClass *class); -static void cal_listener_init (CalListener *listener); -static void cal_listener_destroy (GtkObject *object); - -static void impl_notifyCalOpened (PortableServer_Servant servant, - GNOME_Evolution_Calendar_Listener_OpenStatus status, - GNOME_Evolution_Calendar_Cal cal, - CORBA_Environment *ev); -static void impl_notifyCalSetMode (PortableServer_Servant servant, - GNOME_Evolution_Calendar_Listener_SetModeStatus status, - GNOME_Evolution_Calendar_CalMode mode, - CORBA_Environment *ev); -static void impl_notifyObjUpdated (PortableServer_Servant servant, - GNOME_Evolution_Calendar_CalObjUID uid, - CORBA_Environment *ev); -static void impl_notifyObjRemoved (PortableServer_Servant servant, - GNOME_Evolution_Calendar_CalObjUID uid, - CORBA_Environment *ev); -static void impl_notifyCategoriesChanged (PortableServer_Servant servant, - const GNOME_Evolution_Calendar_StringSeq *categories, - CORBA_Environment *ev); - -static BonoboXObjectClass *parent_class; - - - -BONOBO_X_TYPE_FUNC_FULL (CalListener, - GNOME_Evolution_Calendar_Listener, - BONOBO_X_OBJECT_TYPE, - cal_listener); - -/* 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_X_OBJECT_TYPE); - - class->epv.notifyCalOpened = impl_notifyCalOpened; - class->epv.notifyCalSetMode = impl_notifyCalSetMode; - class->epv.notifyObjUpdated = impl_notifyObjUpdated; - class->epv.notifyObjRemoved = impl_notifyObjRemoved; - class->epv.notifyCategoriesChanged = impl_notifyCategoriesChanged; - - object_class->destroy = cal_listener_destroy; -} - -/* 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_opened_fn = NULL; - priv->obj_updated_fn = NULL; - priv->obj_removed_fn = NULL; - priv->categories_changed_fn = NULL; - - priv->notify = TRUE; -} - -/* Destroy handler for the calendar listener */ -static void -cal_listener_destroy (GtkObject *object) -{ - CalListener *listener; - CalListenerPrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_CAL_LISTENER (object)); - - listener = CAL_LISTENER (object); - priv = listener->priv; - - priv->cal_opened_fn = NULL; - priv->obj_updated_fn = NULL; - priv->obj_removed_fn = NULL; - priv->categories_changed_fn = NULL; - priv->fn_data = NULL; - - priv->notify = FALSE; - - g_free (priv); - listener->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - - -/* CORBA servant implementation */ - -/* ::notifyCalOpened method */ -static void -impl_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->notify) - 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); - - g_assert (priv->cal_opened_fn != NULL); - (* priv->cal_opened_fn) (listener, status, cal, priv->fn_data); -} - -/* ::notifyCalSetMode method */ -static void -impl_notifyCalSetMode (PortableServer_Servant servant, - GNOME_Evolution_Calendar_Listener_SetModeStatus status, - GNOME_Evolution_Calendar_CalMode mode, - CORBA_Environment *ev) -{ - CalListener *listener; - CalListenerPrivate *priv; - - listener = CAL_LISTENER (bonobo_object_from_servant (servant)); - priv = listener->priv; - - if (!priv->notify) - return; - - g_assert (priv->cal_set_mode_fn != NULL); - (* priv->cal_set_mode_fn) (listener, status, mode, priv->fn_data); -} - -/* ::notifyObjUpdated method */ -static void -impl_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; - - if (!priv->notify) - return; - - g_assert (priv->obj_updated_fn != NULL); - (* priv->obj_updated_fn) (listener, uid, priv->fn_data); -} - -/* ::notifyObjRemoved method */ -static void -impl_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; - - if (!priv->notify) - return; - - g_assert (priv->obj_removed_fn != NULL); - (* priv->obj_removed_fn) (listener, uid, priv->fn_data); -} - -/* ::notifyCategoriesChanged method */ -static void -impl_notifyCategoriesChanged (PortableServer_Servant servant, - const GNOME_Evolution_Calendar_StringSeq *categories, - CORBA_Environment *ev) -{ - CalListener *listener; - CalListenerPrivate *priv; - - listener = CAL_LISTENER (bonobo_object_from_servant (servant)); - priv = listener->priv; - - if (!priv->notify) - return; - - g_assert (priv->categories_changed_fn != NULL); - (* priv->categories_changed_fn) (listener, categories, priv->fn_data); -} - - - -/** - * cal_listener_construct: - * @listener: A calendar listener. - * @cal_opened_fn: Function that will be called to notify that a calendar was - * opened. - * @obj_updated_fn: Function that will be called to notify that an object in the - * calendar was updated. - * @obj_removed_fn: Function that will be called to notify that an object in the - * calendar was removed. - * @categories_changed_fn: Function that will be called to notify that the list - * of categories that are present in the calendar's objects has changed. - * @fn_data: Closure data pointer that will be passed to the notification - * functions. - * - * Constructs a calendar listener by setting the callbacks that it will use for - * notification from the calendar server. - * - * Return value: the same object as the @listener argument. - **/ -CalListener * -cal_listener_construct (CalListener *listener, - CalListenerCalOpenedFn cal_opened_fn, - CalListenerCalSetModeFn cal_set_mode_fn, - CalListenerObjUpdatedFn obj_updated_fn, - CalListenerObjRemovedFn obj_removed_fn, - CalListenerCategoriesChangedFn categories_changed_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 (cal_set_mode_fn != NULL, NULL); - g_return_val_if_fail (obj_updated_fn != NULL, NULL); - g_return_val_if_fail (obj_removed_fn != NULL, NULL); - g_return_val_if_fail (categories_changed_fn != NULL, NULL); - - priv = listener->priv; - - priv->cal_opened_fn = cal_opened_fn; - priv->cal_set_mode_fn = cal_set_mode_fn; - priv->obj_updated_fn = obj_updated_fn; - priv->obj_removed_fn = obj_removed_fn; - priv->categories_changed_fn = categories_changed_fn; - priv->fn_data = fn_data; - - return listener; -} - -/** - * cal_listener_new: - * @cal_opened_fn: Function that will be called to notify that a calendar was - * opened. - * @obj_updated_fn: Function that will be called to notify that an object in the - * calendar was updated. - * @obj_removed_fn: Function that will be called to notify that an object in the - * calendar was removed. - * @categories_changed_fn: Function that will be called to notify that the list - * of categories that are present in the calendar's objects has changed. - * @fn_data: Closure data pointer that will be passed to the notification - * functions. - * - * Creates a new #CalListener object. - * - * Return value: A newly-created #CalListener object. - **/ -CalListener * -cal_listener_new (CalListenerCalOpenedFn cal_opened_fn, - CalListenerCalSetModeFn cal_set_mode_fn, - CalListenerObjUpdatedFn obj_updated_fn, - CalListenerObjRemovedFn obj_removed_fn, - CalListenerCategoriesChangedFn categories_changed_fn, - gpointer fn_data) -{ - CalListener *listener; - - g_return_val_if_fail (cal_opened_fn != NULL, NULL); - g_return_val_if_fail (obj_updated_fn != NULL, NULL); - g_return_val_if_fail (obj_removed_fn != NULL, NULL); - g_return_val_if_fail (categories_changed_fn != NULL, NULL); - - listener = gtk_type_new (CAL_LISTENER_TYPE); - return cal_listener_construct (listener, - cal_opened_fn, - cal_set_mode_fn, - obj_updated_fn, - obj_removed_fn, - categories_changed_fn, - fn_data); -} - -/** - * cal_listener_stop_notification: - * @listener: A calendar listener. - * - * Informs a calendar listener that no further notification is desired. The - * callbacks specified when the listener was created will no longer be invoked - * after this function is called. - **/ -void -cal_listener_stop_notification (CalListener *listener) -{ - CalListenerPrivate *priv; - - g_return_if_fail (listener != NULL); - g_return_if_fail (IS_CAL_LISTENER (listener)); - - priv = listener->priv; - g_return_if_fail (priv->notify != FALSE); - - priv->notify = FALSE; -} diff --git a/calendar/cal-client/cal-listener.h b/calendar/cal-client/cal-listener.h deleted file mode 100644 index c7488e6e97..0000000000 --- a/calendar/cal-client/cal-listener.h +++ /dev/null @@ -1,100 +0,0 @@ -/* Evolution calendar listener - * - * Copyright (C) 2001 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef CAL_LISTENER_H -#define CAL_LISTENER_H - -#include <libgnome/gnome-defs.h> -#include <bonobo/bonobo-xobject.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 CalListenerPrivate CalListenerPrivate; - -typedef struct { - BonoboXObject xobject; - - /* Private data */ - CalListenerPrivate *priv; -} CalListener; - -typedef struct { - BonoboXObjectClass parent_class; - - POA_GNOME_Evolution_Calendar_Listener__epv epv; -} CalListenerClass; - -/* Notification functions */ -typedef void (* CalListenerCalOpenedFn) (CalListener *listener, - GNOME_Evolution_Calendar_Listener_OpenStatus status, - GNOME_Evolution_Calendar_Cal cal, - gpointer data); - -typedef void (* CalListenerCalSetModeFn) (CalListener *listener, - GNOME_Evolution_Calendar_Listener_SetModeStatus status, - GNOME_Evolution_Calendar_CalMode mode, - gpointer data); - -typedef void (* CalListenerObjUpdatedFn) (CalListener *listener, - const GNOME_Evolution_Calendar_CalObjUID uid, - gpointer data); -typedef void (* CalListenerObjRemovedFn) (CalListener *listener, - const GNOME_Evolution_Calendar_CalObjUID uid, - gpointer data); - -typedef void (* CalListenerCategoriesChangedFn) (CalListener *listener, - const GNOME_Evolution_Calendar_StringSeq *categories, - gpointer data); - - -GtkType cal_listener_get_type (void); - -CalListener *cal_listener_construct (CalListener *listener, - CalListenerCalOpenedFn cal_opened_fn, - CalListenerCalSetModeFn cal_set_mode_fn, - CalListenerObjUpdatedFn obj_updated_fn, - CalListenerObjRemovedFn obj_removed_fn, - CalListenerCategoriesChangedFn categories_changed_fn, - gpointer fn_data); - -CalListener *cal_listener_new (CalListenerCalOpenedFn cal_opened_fn, - CalListenerCalSetModeFn cal_set_mode_fn, - CalListenerObjUpdatedFn obj_updated_fn, - CalListenerObjRemovedFn obj_removed_fn, - CalListenerCategoriesChangedFn categories_changed_fn, - gpointer fn_data); - -void cal_listener_stop_notification (CalListener *listener); - - - -END_GNOME_DECLS - -#endif diff --git a/calendar/cal-client/cal-query.c b/calendar/cal-client/cal-query.c deleted file mode 100644 index 97e7b81240..0000000000 --- a/calendar/cal-client/cal-query.c +++ /dev/null @@ -1,406 +0,0 @@ -/* Evolution calendar - Live query client object - * - * Copyright (C) 2001 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtksignal.h> -#include <bonobo/bonobo-exception.h> -#include "cal-query.h" -#include "query-listener.h" - - - -/* Private part of the CalQuery structure */ -struct _CalQueryPrivate { - /* Our query listener implementation */ - QueryListener *ql; - - /* Handle to the query in the server */ - GNOME_Evolution_Calendar_Query corba_query; -}; - - - -static void cal_query_class_init (CalQueryClass *class); -static void cal_query_init (CalQuery *query); -static void cal_query_destroy (GtkObject *object); - -/* Signal IDs */ -enum { - OBJ_UPDATED, - OBJ_REMOVED, - QUERY_DONE, - EVAL_ERROR, - LAST_SIGNAL -}; - -static void marshal_obj_updated (GtkObject *object, - GtkSignalFunc func, gpointer func_data, - GtkArg *args); -static void marshal_query_done (GtkObject *object, - GtkSignalFunc func, gpointer func_data, - GtkArg *args); - -static guint query_signals[LAST_SIGNAL]; - -static GtkObjectClass *parent_class; - - - -/** - * cal_query_get_type: - * - * Registers the #CalQuery class if necessary, and returns the type ID assigned - * to it. - * - * Return value: The type ID of the #CalQuery class. - **/ -GtkType -cal_query_get_type (void) -{ - static GtkType cal_query_type = 0; - - if (!cal_query_type) { - static const GtkTypeInfo cal_query_info = { - "CalQuery", - sizeof (CalQuery), - sizeof (CalQueryClass), - (GtkClassInitFunc) cal_query_class_init, - (GtkObjectInitFunc) cal_query_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - cal_query_type = gtk_type_unique (GTK_TYPE_OBJECT, &cal_query_info); - } - - return cal_query_type; -} - -/* Class initialization function for the calendar query */ -static void -cal_query_class_init (CalQueryClass *class) -{ - GtkObjectClass *object_class; - - object_class = (GtkObjectClass *) class; - - parent_class = gtk_type_class (GTK_TYPE_OBJECT); - - query_signals[OBJ_UPDATED] = - gtk_signal_new ("obj_updated", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (CalQueryClass, obj_updated), - marshal_obj_updated, - GTK_TYPE_NONE, 4, - GTK_TYPE_STRING, - GTK_TYPE_BOOL, - GTK_TYPE_INT, - GTK_TYPE_INT); - query_signals[OBJ_REMOVED] = - gtk_signal_new ("obj_removed", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (CalQueryClass, obj_removed), - gtk_marshal_NONE__STRING, - GTK_TYPE_NONE, 1, - GTK_TYPE_STRING); - query_signals[QUERY_DONE] = - gtk_signal_new ("query_done", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (CalQueryClass, query_done), - marshal_query_done, - GTK_TYPE_NONE, 2, - GTK_TYPE_ENUM, - GTK_TYPE_STRING); - query_signals[EVAL_ERROR] = - gtk_signal_new ("eval_error", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (CalQueryClass, eval_error), - gtk_marshal_NONE__STRING, - GTK_TYPE_NONE, 1, - GTK_TYPE_STRING); - - gtk_object_class_add_signals (object_class, query_signals, LAST_SIGNAL); - - class->obj_updated = NULL; - class->obj_removed = NULL; - class->query_done = NULL; - class->eval_error = NULL; - - object_class->destroy = cal_query_destroy; -} - -/* Object initialization function for the calendar query */ -static void -cal_query_init (CalQuery *query) -{ - CalQueryPrivate *priv; - - priv = g_new0 (CalQueryPrivate, 1); - query->priv = priv; - - priv->ql = NULL; - priv->corba_query = CORBA_OBJECT_NIL; -} - -/* Destroy handler for the calendar query */ -static void -cal_query_destroy (GtkObject *object) -{ - CalQuery *query; - CalQueryPrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_CAL_QUERY (object)); - - query = CAL_QUERY (object); - priv = query->priv; - - /* The server unrefs the query listener, so we just NULL it out here */ - query_listener_stop_notification (priv->ql); - priv->ql = NULL; - - if (priv->corba_query != CORBA_OBJECT_NIL) { - CORBA_Environment ev; - - CORBA_exception_init (&ev); - bonobo_object_release_unref (priv->corba_query, &ev); - - if (BONOBO_EX (&ev)) - g_message ("cal_query_destroy(): Could not release/unref the query"); - - CORBA_exception_free (&ev); - priv->corba_query = CORBA_OBJECT_NIL; - } - - g_free (priv); - query->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - - -/* Marshalers */ - -typedef void (* ObjUpdatedFunc) (CalQuery *query, const char *uid, - gboolean query_in_progress, int n_scanned, int total, - gpointer data); - -static void -marshal_obj_updated (GtkObject *object, GtkSignalFunc func, gpointer func_data, GtkArg *args) -{ - ObjUpdatedFunc f; - - f = (ObjUpdatedFunc) func; - - (* f) (CAL_QUERY (object), GTK_VALUE_STRING (args[0]), - GTK_VALUE_BOOL (args[1]), GTK_VALUE_INT (args[2]), GTK_VALUE_INT (args[3]), - func_data); -} - -typedef void (* QueryDoneFunc) (CalQuery *query, CalQueryDoneStatus status, const char *error_str, - gpointer data); - -static void -marshal_query_done (GtkObject *object, GtkSignalFunc func, gpointer func_data, GtkArg *args) -{ - QueryDoneFunc f; - - f = (QueryDoneFunc) func; - - (* f) (CAL_QUERY (object), GTK_VALUE_ENUM (args[0]), GTK_VALUE_STRING (args[1]), - func_data); -} - - - -/* Callback used when an object is updated in the query */ -static void -obj_updated_cb (QueryListener *ql, - const GNOME_Evolution_Calendar_CalObjUID uid, - CORBA_boolean query_in_progress, - CORBA_long n_scanned, - CORBA_long total, - gpointer data) -{ - CalQuery *query; - - query = CAL_QUERY (data); - - gtk_signal_emit (GTK_OBJECT (query), query_signals[OBJ_UPDATED], - uid, query_in_progress, (int) n_scanned, (int) total); -} - -/* Callback used when an object is removed from the query */ -static void -obj_removed_cb (QueryListener *ql, - const GNOME_Evolution_Calendar_CalObjUID uid, - gpointer data) -{ - CalQuery *query; - - query = CAL_QUERY (data); - - gtk_signal_emit (GTK_OBJECT (query), query_signals[OBJ_REMOVED], - uid); -} - -/* Callback used when the query terminates */ -static void -query_done_cb (QueryListener *ql, - GNOME_Evolution_Calendar_QueryListener_QueryDoneStatus corba_status, - const CORBA_char *error_str, - gpointer data) -{ - CalQuery *query; - CalQueryDoneStatus status; - - query = CAL_QUERY (data); - - switch (corba_status) { - case GNOME_Evolution_Calendar_QueryListener_SUCCESS: - status = CAL_QUERY_DONE_SUCCESS; - break; - - case GNOME_Evolution_Calendar_QueryListener_PARSE_ERROR: - status = CAL_QUERY_DONE_PARSE_ERROR; - break; - - default: - g_assert_not_reached (); - return; - } - - gtk_signal_emit (GTK_OBJECT (query), query_signals[QUERY_DONE], - status, error_str); -} - -/* Callback used when an error occurs when evaluating the query */ -static void -eval_error_cb (QueryListener *ql, - const CORBA_char *error_str, - gpointer data) -{ - CalQuery *query; - - query = CAL_QUERY (data); - - gtk_signal_emit (GTK_OBJECT (query), query_signals[EVAL_ERROR], - error_str); -} - -/** - * cal_query_construct: - * @query: A calendar query. - * @cal: Handle to an open calendar. - * @sexp: S-expression that defines the query. - * - * Constructs a query object by issuing the query creation request to the - * calendar server. - * - * Return value: The same value as @query on success, or NULL if the request - * failed. - **/ -CalQuery * -cal_query_construct (CalQuery *query, - GNOME_Evolution_Calendar_Cal cal, - const char *sexp) -{ - CalQueryPrivate *priv; - GNOME_Evolution_Calendar_QueryListener corba_ql; - CORBA_Environment ev; - - g_return_val_if_fail (query != NULL, NULL); - g_return_val_if_fail (IS_CAL_QUERY (query), NULL); - g_return_val_if_fail (sexp != NULL, NULL); - - priv = query->priv; - - priv->ql = query_listener_new (obj_updated_cb, - obj_removed_cb, - query_done_cb, - eval_error_cb, - query); - if (!priv->ql) { - g_message ("cal_query_construct(): Could not create the query listener"); - return NULL; - } - - corba_ql = BONOBO_OBJREF (priv->ql); - - CORBA_exception_init (&ev); - priv->corba_query = GNOME_Evolution_Calendar_Cal_getQuery (cal, sexp, corba_ql, &ev); - - if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_Cal_CouldNotCreate)) { - g_message ("cal_query_construct(): The server could not create the query"); - goto error; - } else if (BONOBO_EX (&ev)) { - g_message ("cal_query_construct(): Could not issue the getQuery() request"); - goto error; - } - - CORBA_exception_free (&ev); - - return query; - - error: - - CORBA_exception_free (&ev); - - bonobo_object_unref (BONOBO_OBJECT (priv->ql)); - priv->ql = NULL; - priv->corba_query = CORBA_OBJECT_NIL; - return NULL; -} - -/** - * cal_query_new: - * @cal: Handle to an open calendar. - * @sexp: S-expression that defines the query. - * - * Creates a new query object by issuing the query creation request to the - * calendar server. - * - * Return value: A newly-created query object, or NULL if the request failed. - **/ -CalQuery * -cal_query_new (GNOME_Evolution_Calendar_Cal cal, - const char *sexp) -{ - CalQuery *query; - - query = gtk_type_new (CAL_QUERY_TYPE); - - if (!cal_query_construct (query, cal, sexp)) { - gtk_object_unref (GTK_OBJECT (query)); - return NULL; - } - - return query; -} diff --git a/calendar/cal-client/cal-query.h b/calendar/cal-client/cal-query.h deleted file mode 100644 index 5af5f3864d..0000000000 --- a/calendar/cal-client/cal-query.h +++ /dev/null @@ -1,81 +0,0 @@ -/* Evolution calendar - Live query client object - * - * Copyright (C) 2001 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef CAL_QUERY_H -#define CAL_QUERY_H - -#include <libgnome/gnome-defs.h> -#include <gtk/gtkobject.h> - -#include "evolution-calendar.h" - -BEGIN_GNOME_DECLS - - - -#define CAL_QUERY_TYPE (cal_query_get_type ()) -#define CAL_QUERY(obj) (GTK_CHECK_CAST ((obj), CAL_QUERY_TYPE, CalQuery)) -#define CAL_QUERY_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), CAL_QUERY_TYPE, CalQueryClass)) -#define IS_CAL_QUERY(obj) (GTK_CHECK_TYPE ((obj), CAL_QUERY_TYPE)) -#define IS_CAL_QUERY_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), CAL_QUERY_TYPE)) - -/* Status values when a query terminates */ -typedef enum { - CAL_QUERY_DONE_SUCCESS, - CAL_QUERY_DONE_PARSE_ERROR -} CalQueryDoneStatus; - -typedef struct _CalQueryPrivate CalQueryPrivate; - -typedef struct { - GtkObject object; - - /* Private data */ - CalQueryPrivate *priv; -} CalQuery; - -typedef struct { - GtkObjectClass parent_class; - - /* Notification signals */ - - void (* obj_updated) (CalQuery *query, const char *uid, - gboolean query_in_progress, int n_scanned, int total); - void (* obj_removed) (CalQuery *query, const char *uid); - - void (* query_done) (CalQuery *query, CalQueryDoneStatus status, const char *error_str); - - void (* eval_error) (CalQuery *query, const char *error_str); -} CalQueryClass; - -GtkType cal_query_get_type (void); - -CalQuery *cal_query_construct (CalQuery *query, - GNOME_Evolution_Calendar_Cal cal, - const char *sexp); - -CalQuery *cal_query_new (GNOME_Evolution_Calendar_Cal cal, - const char *sexp); - - - -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 56651566eb..0000000000 --- a/calendar/cal-client/client-test.c +++ /dev/null @@ -1,239 +0,0 @@ -/* Evolution calendar client - test program - * - * Copyright (C) 2000 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#include <config.h> -#include <stdlib.h> -#include <gtk/gtkmain.h> -#include <gtk/gtksignal.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <libgnomeui/gnome-init.h> -#include <liboaf/liboaf.h> -#include <bonobo/bonobo-main.h> -#include "cal-client.h" -#include "cal-util/cal-component.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) { - GList *comp_list; - - /* get free/busy information */ - comp_list = cal_client_get_free_busy (client, NULL, 0, time (NULL)); - if (comp_list) { - GList *l; - - for (l = comp_list; l; l = l->next) { - char *comp_str; - - comp_str = cal_component_get_as_string (CAL_COMPONENT (l->data)); - gtk_object_unref (GTK_OBJECT (l->data)); - cl_printf (client, "Free/Busy -> %s\n", comp_str); - g_free (comp_str); - } - g_list_free (comp_list); - } - - 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) -{ - char *dir; - - 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); - } - - dir = g_strdup_printf ("%s/evolution/local/Calendar/calendar.ics", g_get_home_dir ()); - create_client (&client1, dir, FALSE); - g_free (dir); - create_client (&client2, "/cvs/evolution/calendar/cal-client/test.ics", TRUE); - - bonobo_main (); - return 0; -} diff --git a/calendar/cal-client/query-listener.c b/calendar/cal-client/query-listener.c deleted file mode 100644 index 1b21c1e667..0000000000 --- a/calendar/cal-client/query-listener.c +++ /dev/null @@ -1,321 +0,0 @@ -/* Evolution calendar - Live search query listener convenience object - * - * Copyright (C) 2001 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "query-listener.h" - - - -/* Private part of the QueryListener structure */ - -struct _QueryListenerPrivate { - /* Callbacks for notification and their closure data */ - QueryListenerObjUpdatedFn obj_updated_fn; - QueryListenerObjRemovedFn obj_removed_fn; - QueryListenerQueryDoneFn query_done_fn; - QueryListenerEvalErrorFn eval_error_fn; - gpointer fn_data; - - /* Whether notification is desired */ - gboolean notify : 1; -}; - - - -static void query_listener_class_init (QueryListenerClass *class); -static void query_listener_init (QueryListener *ql); -static void query_listener_destroy (GtkObject *object); - -static void impl_notifyObjUpdated (PortableServer_Servant servant, - GNOME_Evolution_Calendar_CalObjUID uid, - CORBA_boolean query_in_progress, - CORBA_long n_scanned, - CORBA_long total, - CORBA_Environment *ev); - -static void impl_notifyObjRemoved (PortableServer_Servant servant, - GNOME_Evolution_Calendar_CalObjUID uid, - CORBA_Environment *ev); - -static void impl_notifyQueryDone (PortableServer_Servant servant, - GNOME_Evolution_Calendar_QueryListener_QueryDoneStatus corba_status, - const CORBA_char *error_str, - CORBA_Environment *ev); - -static void impl_notifyEvalError (PortableServer_Servant servant, - const CORBA_char *error_str, - CORBA_Environment *ev); - -static BonoboXObjectClass *parent_class; - - - -BONOBO_X_TYPE_FUNC_FULL (QueryListener, - GNOME_Evolution_Calendar_QueryListener, - BONOBO_X_OBJECT_TYPE, - query_listener); - -/* Class initialization function for the live search query listener */ -static void -query_listener_class_init (QueryListenerClass *class) -{ - GtkObjectClass *object_class; - - object_class = (GtkObjectClass *) class; - - parent_class = gtk_type_class (BONOBO_X_OBJECT_TYPE); - - object_class->destroy = query_listener_destroy; - - class->epv.notifyObjUpdated = impl_notifyObjUpdated; - class->epv.notifyObjRemoved = impl_notifyObjRemoved; - class->epv.notifyQueryDone = impl_notifyQueryDone; - class->epv.notifyEvalError = impl_notifyEvalError; -} - -/* Object initialization function for the live search query listener */ -static void -query_listener_init (QueryListener *ql) -{ - QueryListenerPrivate *priv; - - priv = g_new0 (QueryListenerPrivate, 1); - ql->priv = priv; - - priv->obj_updated_fn = NULL; - priv->obj_removed_fn = NULL; - priv->query_done_fn = NULL; - priv->eval_error_fn = NULL; - priv->fn_data = NULL; - - priv->notify = TRUE; -} - -/* Destroy handler for the live search query listener */ -static void -query_listener_destroy (GtkObject *object) -{ - QueryListener *ql; - QueryListenerPrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_QUERY_LISTENER (object)); - - ql = QUERY_LISTENER (object); - priv = ql->priv; - - priv->obj_updated_fn = NULL; - priv->obj_removed_fn = NULL; - priv->query_done_fn = NULL; - priv->eval_error_fn = NULL; - priv->fn_data = NULL; - - priv->notify = FALSE; - - g_free (priv); - ql->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - - -/* CORBA method implementations */ - -/* ::notifyObjUpdated() method */ -static void -impl_notifyObjUpdated (PortableServer_Servant servant, - GNOME_Evolution_Calendar_CalObjUID uid, - CORBA_boolean query_in_progress, - CORBA_long n_scanned, - CORBA_long total, - CORBA_Environment *ev) -{ - QueryListener *ql; - QueryListenerPrivate *priv; - - ql = QUERY_LISTENER (bonobo_object_from_servant (servant)); - priv = ql->priv; - - if (!priv->notify) - return; - - g_assert (priv->obj_updated_fn != NULL); - (* priv->obj_updated_fn) (ql, uid, query_in_progress, n_scanned, total, priv->fn_data); -} - -/* ::notifyObjRemoved() method */ -static void -impl_notifyObjRemoved (PortableServer_Servant servant, - GNOME_Evolution_Calendar_CalObjUID uid, - CORBA_Environment *ev) -{ - QueryListener *ql; - QueryListenerPrivate *priv; - - ql = QUERY_LISTENER (bonobo_object_from_servant (servant)); - priv = ql->priv; - - if (!priv->notify) - return; - - g_assert (priv->obj_removed_fn != NULL); - (* priv->obj_removed_fn) (ql, uid, priv->fn_data); -} - -/* ::notifyQueryDone() method */ -static void -impl_notifyQueryDone (PortableServer_Servant servant, - GNOME_Evolution_Calendar_QueryListener_QueryDoneStatus corba_status, - const CORBA_char *error_str, - CORBA_Environment *ev) -{ - QueryListener *ql; - QueryListenerPrivate *priv; - - ql = QUERY_LISTENER (bonobo_object_from_servant (servant)); - priv = ql->priv; - - if (!priv->notify) - return; - - g_assert (priv->query_done_fn != NULL); - (* priv->query_done_fn) (ql, corba_status, error_str, priv->fn_data); -} - -/* ::notifyEvalError() method */ -static void -impl_notifyEvalError (PortableServer_Servant servant, - const CORBA_char *error_str, - CORBA_Environment *ev) -{ - QueryListener *ql; - QueryListenerPrivate *priv; - - ql = QUERY_LISTENER (bonobo_object_from_servant (servant)); - priv = ql->priv; - - if (!priv->notify) - return; - - g_assert (priv->eval_error_fn != NULL); - (* priv->eval_error_fn) (ql, error_str, priv->fn_data); -} - - - -/** - * query_listener_construct: - * @ql: A query listener. - * @obj_updated_fn: Callback to use when a component is updated in the query. - * @obj_removed_fn: Callback to use when a component is removed from the query. - * @query_done_fn: Callback to use when a query is done. - * @eval_error_fn: Callback to use when an evaluation error happens during a query. - * @fn_data: Closure data to pass to the callbacks. - * - * Constructs a query listener by setting the callbacks it will use for - * notification from the calendar server. - * - * Return value: The same value as @ql. - **/ -QueryListener * -query_listener_construct (QueryListener *ql, - QueryListenerObjUpdatedFn obj_updated_fn, - QueryListenerObjRemovedFn obj_removed_fn, - QueryListenerQueryDoneFn query_done_fn, - QueryListenerEvalErrorFn eval_error_fn, - gpointer fn_data) -{ - QueryListenerPrivate *priv; - - g_return_val_if_fail (ql != NULL, NULL); - g_return_val_if_fail (IS_QUERY_LISTENER (ql), NULL); - g_return_val_if_fail (obj_updated_fn != NULL, NULL); - g_return_val_if_fail (obj_removed_fn != NULL, NULL); - g_return_val_if_fail (query_done_fn != NULL, NULL); - g_return_val_if_fail (eval_error_fn != NULL, NULL); - - priv = ql->priv; - - priv->obj_updated_fn = obj_updated_fn; - priv->obj_removed_fn = obj_removed_fn; - priv->query_done_fn = query_done_fn; - priv->eval_error_fn = eval_error_fn; - priv->fn_data = fn_data; - - return ql; -} - -/** - * query_listener_new: - * @obj_updated_fn: Callback to use when a component is updated in the query. - * @obj_removed_fn: Callback to use when a component is removed from the query. - * @query_done_fn: Callback to use when a query is done. - * @eval_error_fn: Callback to use when an evaluation error happens during a query. - * @fn_data: Closure data to pass to the callbacks. - * - * Creates a new query listener object. - * - * Return value: A newly-created query listener object. - **/ -QueryListener * -query_listener_new (QueryListenerObjUpdatedFn obj_updated_fn, - QueryListenerObjRemovedFn obj_removed_fn, - QueryListenerQueryDoneFn query_done_fn, - QueryListenerEvalErrorFn eval_error_fn, - gpointer fn_data) -{ - QueryListener *ql; - - ql = gtk_type_new (QUERY_LISTENER_TYPE); - - return query_listener_construct (ql, - obj_updated_fn, - obj_removed_fn, - query_done_fn, - eval_error_fn, - fn_data); -} - -/** - * query_listener_stop_notification: - * @ql: A query listener. - * - * Informs a query listener that no further notification is desired. The - * callbacks specified when the listener was created will no longer be invoked - * after this function is called. - **/ -void -query_listener_stop_notification (QueryListener *ql) -{ - QueryListenerPrivate *priv; - - g_return_if_fail (ql != NULL); - g_return_if_fail (IS_QUERY_LISTENER (ql)); - - priv = ql->priv; - g_return_if_fail (priv->notify != FALSE); - - priv->notify = FALSE; -} diff --git a/calendar/cal-client/query-listener.h b/calendar/cal-client/query-listener.h deleted file mode 100644 index e553d37a49..0000000000 --- a/calendar/cal-client/query-listener.h +++ /dev/null @@ -1,97 +0,0 @@ -/* Evolution calendar - Live search query listener implementation - * - * Copyright (C) 2001 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef QUERY_LISTENER_H -#define QUERY_LISTENER_H - -#include <bonobo/bonobo-xobject.h> -#include "evolution-calendar.h" - -BEGIN_GNOME_DECLS - - - -#define QUERY_LISTENER_TYPE (query_listener_get_type ()) -#define QUERY_LISTENER(obj) (GTK_CHECK_CAST ((obj), QUERY_LISTENER_TYPE, QueryListener)) -#define QUERY_LISTENER_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), QUERY_LISTENER_TYPE, \ - QueryListenerClass)) -#define IS_QUERY_LISTENER(obj) (GTK_CHECK_TYPE ((obj), QUERY_LISTENER_TYPE)) -#define IS_QUERY_LISTENER_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), QUERY_LISTENER_TYPE)) - -typedef struct _QueryListenerPrivate QueryListenerPrivate; - -typedef struct { - BonoboXObject xobject; - - /* Private data */ - QueryListenerPrivate *priv; -} QueryListener; - -typedef struct { - BonoboXObjectClass parent_class; - - POA_GNOME_Evolution_Calendar_QueryListener__epv epv; -} QueryListenerClass; - -/* Notification functions */ - -typedef void (* QueryListenerObjUpdatedFn) (QueryListener *ql, - const GNOME_Evolution_Calendar_CalObjUID uid, - CORBA_boolean query_in_progress, - CORBA_long n_scanned, - CORBA_long total, - gpointer data); - -typedef void (* QueryListenerObjRemovedFn) (QueryListener *ql, - const GNOME_Evolution_Calendar_CalObjUID uid, - gpointer data); - -typedef void (* QueryListenerQueryDoneFn) ( - QueryListener *ql, - GNOME_Evolution_Calendar_QueryListener_QueryDoneStatus status, - const CORBA_char *error_str, - gpointer data); - -typedef void (* QueryListenerEvalErrorFn) (QueryListener *ql, - const CORBA_char *error_str, - gpointer data); - -GtkType query_listener_get_type (void); - -QueryListener *query_listener_construct (QueryListener *ql, - QueryListenerObjUpdatedFn obj_updated_fn, - QueryListenerObjRemovedFn obj_removed_fn, - QueryListenerQueryDoneFn query_done_fn, - QueryListenerEvalErrorFn eval_error_fn, - gpointer fn_data); - -QueryListener *query_listener_new (QueryListenerObjUpdatedFn obj_updated_fn, - QueryListenerObjRemovedFn obj_removed_fn, - QueryListenerQueryDoneFn query_done_fn, - QueryListenerEvalErrorFn eval_error_fn, - gpointer fn_data); - -void query_listener_stop_notification (QueryListener *ql); - - - -END_GNOME_DECLS - -#endif 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 bb94577c16..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 \ - $(EVOLUTION_CALENDAR_CFLAGS) - -# -# 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.a \ - $(top_builddir)/libical/src/libical/libical-evolution.la \ - $(EVOLUTION_CALENDAR_LIBS) diff --git a/calendar/cal-util/cal-component.c b/calendar/cal-util/cal-component.c deleted file mode 100644 index a618e0ef4b..0000000000 --- a/calendar/cal-util/cal-component.c +++ /dev/null @@ -1,5214 +0,0 @@ -/* Evolution calendar - iCalendar component object - * - * Copyright (C) 2000 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#include <config.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include <glib.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.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; - - struct attendee { - icalproperty *prop; - icalparameter *cutype_param; - icalparameter *member_param; - icalparameter *role_param; - icalparameter *partstat_param; - icalparameter *rsvp_param; - icalparameter *delto_param; - icalparameter *delfrom_param; - icalparameter *sentby_param; - icalparameter *cn_param; - icalparameter *language_param; - }; - - GSList *attendee_list; - - icalproperty *categories; - - icalproperty *classification; - - struct text { - icalproperty *prop; - icalparameter *altrep_param; - }; - - GSList *comment_list; /* list of struct text */ - - icalproperty *completed; - - GSList *contact_list; /* list of struct text */ - - icalproperty *created; - - GSList *description_list; /* list of struct text */ - - struct datetime { - icalproperty *prop; - icalparameter *tzid_param; - }; - - struct datetime dtstart; - struct datetime dtend; - - icalproperty *dtstamp; - - /* The DURATION property can be used instead of the VEVENT DTEND or - the VTODO DUE dates. We do not use it directly ourselves, but we - must be able to handle it from incoming data. If a DTEND or DUE - is requested, we convert the DURATION if necessary. If DTEND or - DUE is set, we remove any DURATION. */ - icalproperty *duration; - - struct datetime due; - - GSList *exdate_list; /* list of struct datetime */ - GSList *exrule_list; /* list of icalproperty objects */ - - struct organizer { - icalproperty *prop; - icalparameter *sentby_param; - icalparameter *cn_param; - icalparameter *language_param; - }; - - struct organizer organizer; - - icalproperty *geo; - icalproperty *last_modified; - icalproperty *percent; - icalproperty *priority; - - struct period { - icalproperty *prop; - icalparameter *value_param; - }; - - struct recur_id { - struct datetime recur_time; - - icalparameter *range_param; - }; - - struct recur_id recur_id; - - 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; - icalproperty *location; - - /* 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 { - /* Alarm icalcomponent we wrap */ - icalcomponent *icalcomp; - - /* Our extension UID property */ - icalproperty *uid; - - /* Properties */ - - icalproperty *action; - icalproperty *attach; /* FIXME: see scan_alarm_property() below */ - - struct { - icalproperty *prop; - icalparameter *altrep_param; - } description; - - icalproperty *duration; - icalproperty *repeat; - 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, gboolean free) -{ - CalComponentPrivate *priv; - GSList *l; - - priv = comp->priv; - - if (!priv->icalcomp) - return; - - /* Free the icalcomponent */ - - if (free && icalcomponent_get_parent (priv->icalcomp) == NULL) { - icalcomponent_free (priv->icalcomp); - priv->icalcomp = NULL; - } - - /* Free the mappings */ - - priv->uid = NULL; - - priv->status = NULL; - - for (l = priv->attendee_list; l != NULL; l = l->next) - g_free (l->data); - g_slist_free (priv->attendee_list); - priv->attendee_list = NULL; - - priv->categories = NULL; - - priv->classification = NULL; - priv->comment_list = NULL; - priv->completed = NULL; - priv->contact_list = 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->duration = 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; - priv->location = 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, TRUE); - 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) -{ - char *iso, *ret; - 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"; - } - - iso = isodate_from_time_t (t); - ret = g_strdup_printf ("%s-%d-%d-%d-%d@%s", - iso, - getpid (), - getgid (), - getppid (), - serial++, - hostname); - g_free (iso); - - return ret; -} - -/** - * 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 an attendee property */ -static void -scan_attendee (CalComponent *comp, GSList **attendee_list, icalproperty *prop) -{ - struct attendee *attendee; - - attendee = g_new (struct attendee, 1); - attendee->prop = prop; - - attendee->cutype_param = icalproperty_get_first_parameter (prop, ICAL_CUTYPE_PARAMETER); - attendee->member_param = icalproperty_get_first_parameter (prop, ICAL_MEMBER_PARAMETER); - attendee->role_param = icalproperty_get_first_parameter (prop, ICAL_ROLE_PARAMETER); - attendee->partstat_param = icalproperty_get_first_parameter (prop, ICAL_PARTSTAT_PARAMETER); - attendee->rsvp_param = icalproperty_get_first_parameter (prop, ICAL_RSVP_PARAMETER); - attendee->delto_param = icalproperty_get_first_parameter (prop, ICAL_DELEGATEDTO_PARAMETER); - attendee->delfrom_param = icalproperty_get_first_parameter (prop, ICAL_DELEGATEDFROM_PARAMETER); - attendee->sentby_param = icalproperty_get_first_parameter (prop, ICAL_SENTBY_PARAMETER); - attendee->cn_param = icalproperty_get_first_parameter (prop, ICAL_CN_PARAMETER); - attendee->language_param = icalproperty_get_first_parameter (prop, ICAL_LANGUAGE_PARAMETER); - - *attendee_list = g_slist_append (*attendee_list, attendee); -} - -/* 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 and attendee property */ -static void -scan_organizer (CalComponent *comp, struct organizer *organizer, icalproperty *prop) -{ - organizer->prop = prop; - - organizer->sentby_param = icalproperty_get_first_parameter (prop, ICAL_SENTBY_PARAMETER); - organizer->cn_param = icalproperty_get_first_parameter (prop, ICAL_CN_PARAMETER); - organizer->language_param = icalproperty_get_first_parameter (prop, ICAL_LANGUAGE_PARAMETER); -} - -/* 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_id (CalComponent *comp, struct recur_id *recur_id, icalproperty *prop) -{ - scan_datetime (comp, &recur_id->recur_time, prop); - - recur_id->range_param = icalproperty_get_first_parameter (prop, ICAL_RANGE_PARAMETER); -} - -/* 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_ATTENDEE_PROPERTY: - scan_attendee (comp, &priv->attendee_list, 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_CONTACT_PROPERTY: - scan_text (comp, &priv->contact_list, 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_DURATION_PROPERTY: - priv->duration = 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_ORGANIZER_PROPERTY: - scan_organizer (comp, &priv->organizer, prop); - break; - - case ICAL_PERCENTCOMPLETE_PROPERTY: - priv->percent = prop; - break; - - case ICAL_PRIORITY_PROPERTY: - priv->priority = prop; - break; - - case ICAL_RECURRENCEID_PROPERTY: - scan_recur_id (comp, &priv->recur_id, 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; - - case ICAL_LOCATION_PROPERTY : - priv->location = 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; -} - -/* 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_with_zone (tim, FALSE, icaltimezone_get_utc_timezone ()); - - 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, TRUE); - - 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, TRUE); - - 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; -} - -void -cal_component_rescan (CalComponent *comp) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - - priv = comp->priv; - - /* Clear everything out */ - free_icalcomponent (comp, FALSE); - - /* Rescan */ - scan_icalcomponent (comp); - ensure_mandatory_properties (comp); -} - -/** - * 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; -} - -/* Used from g_hash_table_foreach(); ensures that an alarm subcomponent - * has the mandatory properties it needs. - */ -static void -ensure_alarm_properties_cb (gpointer key, gpointer value, gpointer data) -{ - CalComponent *comp; - CalComponentPrivate *priv; - icalcomponent *alarm; - icalproperty *prop; - enum icalproperty_action action; - const char *str; - - alarm = value; - - comp = CAL_COMPONENT (data); - priv = comp->priv; - - prop = icalcomponent_get_first_property (alarm, ICAL_ACTION_PROPERTY); - if (!prop) - return; - - action = icalproperty_get_action (prop); - - switch (action) { - case ICAL_ACTION_DISPLAY: - /* Ensure we have a DESCRIPTION property */ - prop = icalcomponent_get_first_property (alarm, ICAL_DESCRIPTION_PROPERTY); - if (prop) - break; - - if (!priv->summary.prop) - str = _("Untitled appointment"); - else - str = icalproperty_get_summary (priv->summary.prop); - - prop = icalproperty_new_description (str); - icalcomponent_add_property (alarm, prop); - - break; - - default: - break; - /* FIXME: add other action types here */ - } -} - -/* Ensures that alarm subcomponents have the mandatory properties they need, - * even when clients may not have set them properly. - */ -static void -ensure_alarm_properties (CalComponent *comp) -{ - CalComponentPrivate *priv; - - priv = comp->priv; - - g_hash_table_foreach (priv->alarm_uid_hash, ensure_alarm_properties_cb, comp); -} - -/** - * 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); - - ensure_alarm_properties (comp); - - 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); -} - -/** - * cal_component_get_contact_list: - * @comp: A calendar component object. - * @text_list: Return value for the contact properties and their parameters, as - * a list of #CalComponentText structures. This should be freed using the - * cal_component_free_text_list() function. - * - * Queries the contact of a calendar component object. The contact property can - * appear several times inside a calendar component, and so a list of - * #CalComponentText is returned. - **/ -void -cal_component_get_contact_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->contact_list, icalproperty_get_contact, text_list); -} - -/** - * cal_component_set_contact_list: - * @comp: A calendar component object. - * @text_list: List of #CalComponentText structures. - * - * Sets the contact of a calendar component object. The contact property can - * appear several times inside a calendar component, and so a list of - * #CalComponentText structures is used. - **/ -void -cal_component_set_contact_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_contact, &priv->contact_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 the icaltimetype has is_utc set, we set "UTC" as the TZID. - This makes the timezone code simpler. */ - if (datetime->tzid_param) - dt->tzid = g_strdup (icalparameter_get_tzid (datetime->tzid_param)); - else if (dt->value && dt->value->is_utc) - dt->tzid = g_strdup ("UTC"); - 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 we are setting the property to NULL (i.e. removing it), then - we remove it if it exists. */ - 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 the TZID is set to "UTC", we set the is_utc flag. */ - if (dt->tzid && !strcmp (dt->tzid, "UTC")) - dt->value->is_utc = 1; - else - dt->value->is_utc = 0; - - 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 the TZID is set to "UTC", we don't want to save the TZID. */ - if (dt->tzid && strcmp (dt->tzid, "UTC")) { - 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; - } -} - - -/* This tries to get the DTSTART + DURATION for a VEVENT or VTODO. In a - VEVENT this is used for the DTEND if no DTEND exists, In a VTOTO it is - used for the DUE date if DUE doesn't exist. */ -static void -cal_component_get_start_plus_duration (CalComponent *comp, - CalComponentDateTime *dt) -{ - CalComponentPrivate *priv; - struct icaldurationtype duration; - - priv = comp->priv; - - if (!priv->duration) - return; - - /* Get the DTSTART time. */ - get_datetime (&priv->dtstart, icalproperty_get_dtstart, dt); - if (!dt->value) - return; - - duration = icalproperty_get_duration (priv->duration); - - /* The DURATION shouldn't be negative, but just return DTSTART if it - is, i.e. assume it is 0. */ - if (duration.is_neg) - return; - - /* If DTSTART is a DATE value, then we need to check if the DURATION - includes any hours, minutes or seconds. If it does, we need to - make the DTEND/DUE a DATE-TIME value. */ - duration.days += duration.weeks * 7; - if (dt->value->is_date) { - if (duration.hours != 0 || duration.minutes != 0 - || duration.seconds != 0) { - dt->value->is_date = 0; - } - } - - /* Add on the DURATION. */ - icaltime_adjust (dt->value, duration.days, duration.hours, - duration.minutes, duration.seconds); -} - - -/** - * 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); - - /* If we don't have a DTEND property, then we try to get DTSTART - + DURATION. */ - if (!dt->value) - cal_component_get_start_plus_duration (comp, 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); - - /* Make sure we remove any existing DURATION property, as it can't be - used with a DTEND. If DTEND is set to NULL, i.e. removed, we also - want to remove any DURATION. */ - if (priv->duration) { - icalcomponent_remove_property (priv->icalcomp, priv->duration); - icalproperty_free (priv->duration); - priv->duration = NULL; - } - - priv->need_sequence_inc = TRUE; -} - -/** - * cal_component_get_dtstamp: - * @comp: A calendar component object. - * @t: A 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); - - /* If we don't have a DTEND property, then we try to get DTSTART - + DURATION. */ - if (!dt->value) - cal_component_get_start_plus_duration (comp, 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); - - /* Make sure we remove any existing DURATION property, as it can't be - used with a DTEND. If DTEND is set to NULL, i.e. removed, we also - want to remove any DURATION. */ - if (priv->duration) { - icalcomponent_remove_property (priv->icalcomp, priv->duration); - icalproperty_free (priv->duration); - priv->duration = NULL; - } - - 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 = g_strdup (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; - - /* Removing the DATE or DATE-TIME property will also remove - any TZID parameter. */ - 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_organizer: - * @comp: A calendar component object - * @organizer: A value for the organizer - * - * Queries the organizer property of a calendar component object - **/ -void -cal_component_get_organizer (CalComponent *comp, CalComponentOrganizer *organizer) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (organizer != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - if (priv->organizer.prop) - organizer->value = icalproperty_get_organizer (priv->organizer.prop); - else - organizer->value = NULL; - - if (priv->organizer.sentby_param) - organizer->sentby = icalparameter_get_sentby (priv->organizer.sentby_param); - else - organizer->sentby = NULL; - - if (priv->organizer.cn_param) - organizer->cn = icalparameter_get_sentby (priv->organizer.cn_param); - else - organizer->cn = NULL; - - if (priv->organizer.language_param) - organizer->language = icalparameter_get_sentby (priv->organizer.language_param); - else - organizer->language = NULL; - -} - -/** - * cal_component_set_organizer: - * @comp: A calendar component object. - * @organizer: Value for the organizer property - * - * Sets the organizer of a calendar component object - **/ -void -cal_component_set_organizer (CalComponent *comp, CalComponentOrganizer *organizer) -{ - 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 (!organizer) { - if (priv->organizer.prop) { - icalcomponent_remove_property (priv->icalcomp, priv->organizer.prop); - icalproperty_free (priv->organizer.prop); - - priv->organizer.prop = NULL; - priv->organizer.sentby_param = NULL; - priv->organizer.cn_param = NULL; - priv->organizer.language_param = NULL; - } - - return; - } - - g_return_if_fail (organizer->value != NULL); - - if (priv->organizer.prop) - icalproperty_set_organizer (priv->organizer.prop, (char *) organizer->value); - else { - priv->organizer.prop = icalproperty_new_organizer ((char *) organizer->value); - icalcomponent_add_property (priv->icalcomp, priv->organizer.prop); - } - - if (organizer->sentby) { - g_assert (priv->organizer.prop != NULL); - - if (priv->organizer.sentby_param) - icalparameter_set_sentby (priv->organizer.sentby_param, - (char *) organizer->sentby); - else { - priv->organizer.sentby_param = icalparameter_new_sentby ( - (char *) organizer->sentby); - icalproperty_add_parameter (priv->organizer.prop, - priv->organizer.sentby_param); - } - } else if (priv->organizer.sentby_param) { - icalproperty_remove_parameter (priv->organizer.prop, ICAL_SENTBY_PARAMETER); - icalparameter_free (priv->organizer.sentby_param); - priv->organizer.sentby_param = NULL; - } - - if (organizer->cn) { - g_assert (priv->organizer.prop != NULL); - - if (priv->organizer.cn_param) - icalparameter_set_cn (priv->organizer.cn_param, - (char *) organizer->cn); - else { - priv->organizer.cn_param = icalparameter_new_cn ( - (char *) organizer->cn); - icalproperty_add_parameter (priv->organizer.prop, - priv->organizer.cn_param); - } - } else if (priv->organizer.cn_param) { - icalproperty_remove_parameter (priv->organizer.prop, ICAL_CN_PARAMETER); - icalparameter_free (priv->organizer.cn_param); - priv->organizer.cn_param = NULL; - } - - if (organizer->language) { - g_assert (priv->organizer.prop != NULL); - - if (priv->organizer.language_param) - icalparameter_set_language (priv->organizer.language_param, - (char *) organizer->language); - else { - priv->organizer.language_param = icalparameter_new_language ( - (char *) organizer->language); - icalproperty_add_parameter (priv->organizer.prop, - priv->organizer.language_param); - } - } else if (priv->organizer.language_param) { - icalproperty_remove_parameter (priv->organizer.prop, ICAL_LANGUAGE_PARAMETER); - icalparameter_free (priv->organizer.language_param); - priv->organizer.language_param = NULL; - } - - -} - - -/** - * cal_component_has_organizer: - * @comp: - * - * - * - * Return value: - **/ -gboolean -cal_component_has_organizer (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; - - return priv->organizer.prop != NULL; -} - -/** - * 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_recurid: - * @comp: A calendar component object. - * @recur_id: Return value for the recurrence id property - * - * Queries the recurrence id property of a calendar component object - **/ -void -cal_component_get_recurid (CalComponent *comp, CalComponentRange *recur_id) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (recur_id != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - get_datetime (&priv->recur_id.recur_time, - icalproperty_get_recurrenceid, - &recur_id->datetime); -} - -/** - * cal_component_set_recurid: - * @comp: A calendar component object. - * @recur_id: Value for the recurrence id property. - * - * Sets the recurrence id property of a calendar component object. - **/ -void -cal_component_set_recurid (CalComponent *comp, CalComponentRange *recur_id) -{ - 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->recur_id.recur_time, - icalproperty_new_recurrenceid, - icalproperty_set_recurrenceid, - &recur_id->datetime); -} - -/** - * 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") == 0) - *transp = CAL_COMPONENT_TRANSP_TRANSPARENT; - else if (strcasecmp (val, "OPAQUE") == 0) - *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); - } -} - -/* Gets a text list value */ -static void -get_attendee_list (GSList *attendee_list, GSList **al) -{ - GSList *l; - - *al = NULL; - - if (!attendee_list) - return; - - for (l = attendee_list; l; l = l->next) { - struct attendee *attendee; - CalComponentAttendee *a; - - attendee = l->data; - g_assert (attendee->prop != NULL); - - a = g_new0 (CalComponentAttendee, 1); - a->value = icalproperty_get_attendee (attendee->prop); - - if (attendee->member_param) - a->member = icalparameter_get_member (attendee->member_param); - if (attendee->cutype_param) - a->cutype = icalparameter_get_cutype (attendee->cutype_param); - if (attendee->role_param) - a->role = icalparameter_get_role (attendee->role_param); - if (attendee->partstat_param) - a->status = icalparameter_get_role (attendee->partstat_param); - if (attendee->rsvp_param && icalparameter_get_rsvp (attendee->rsvp_param) == ICAL_RSVP_TRUE) - a->rsvp = TRUE; - else - a->rsvp = FALSE; - if (attendee->delfrom_param) - a->delfrom = icalparameter_get_sentby (attendee->delfrom_param); - if (attendee->delto_param) - a->delto = icalparameter_get_sentby (attendee->delto_param); - if (attendee->sentby_param) - a->sentby = icalparameter_get_sentby (attendee->sentby_param); - if (attendee->cn_param) - a->cn = icalparameter_get_sentby (attendee->cn_param); - if (attendee->language_param) - a->language = icalparameter_get_sentby (attendee->language_param); - - *al = g_slist_prepend (*al, a); - } - - *al = g_slist_reverse (*al); -} - - -/* Sets a text list value */ -static void -set_attendee_list (CalComponent *comp, - GSList **attendee_list, - GSList *al) -{ - CalComponentPrivate *priv; - GSList *l; - - priv = comp->priv; - - /* Remove old attendees */ - - for (l = *attendee_list; l; l = l->next) { - struct attendee *attendee; - - attendee = l->data; - g_assert (attendee->prop != NULL); - - icalcomponent_remove_property (priv->icalcomp, attendee->prop); - icalproperty_free (attendee->prop); - g_free (attendee); - } - - g_slist_free (*attendee_list); - *attendee_list = NULL; - - /* Add in new attendees */ - - for (l = al; l; l = l->next) { - CalComponentAttendee *a; - struct attendee *attendee; - - a = l->data; - g_return_if_fail (a->value != NULL); - - attendee = g_new0 (struct attendee, 1); - - attendee->prop = icalproperty_new_attendee (a->value); - icalcomponent_add_property (priv->icalcomp, attendee->prop); - - if (a->member) { - attendee->member_param = icalparameter_new_member (a->member); - icalproperty_add_parameter (attendee->prop, attendee->member_param); - } - - attendee->cutype_param = icalparameter_new_cutype (a->cutype); - icalproperty_add_parameter (attendee->prop, attendee->cutype_param); - - attendee->role_param = icalparameter_new_role (a->role); - icalproperty_add_parameter (attendee->prop, attendee->role_param); - - attendee->partstat_param = icalparameter_new_partstat (a->status); - icalproperty_add_parameter (attendee->prop, attendee->partstat_param); - - if (a->rsvp) - attendee->rsvp_param = icalparameter_new_rsvp (ICAL_RSVP_TRUE); - else - attendee->rsvp_param = icalparameter_new_rsvp (ICAL_RSVP_FALSE); - icalproperty_add_parameter (attendee->prop, attendee->rsvp_param); - - if (a->delfrom) { - attendee->delfrom_param = icalparameter_new_delegatedfrom (a->delfrom); - icalproperty_add_parameter (attendee->prop, attendee->delfrom_param); - } - if (a->delto) { - attendee->delto_param = icalparameter_new_delegatedto (a->delto); - icalproperty_add_parameter (attendee->prop, attendee->delto_param); - } - if (a->sentby) { - attendee->sentby_param = icalparameter_new_sentby (a->sentby); - icalproperty_add_parameter (attendee->prop, attendee->sentby_param); - } - if (a->cn) { - attendee->cn_param = icalparameter_new_cn (a->cn); - icalproperty_add_parameter (attendee->prop, attendee->cn_param); - } - if (a->language) { - attendee->language_param = icalparameter_new_language (a->language); - icalproperty_add_parameter (attendee->prop, attendee->language_param); - } - - *attendee_list = g_slist_prepend (*attendee_list, attendee); - } - - *attendee_list = g_slist_reverse (*attendee_list); -} - -/** - * cal_component_get_attendee_list: - * @comp: A calendar component object. - * @attendee_list: Return value for the attendee property. - * This should be freed using the cal_component_free_attendee_list () - * function. - * - * Queries the attendee properties of the calendar component object - **/ -void -cal_component_get_attendee_list (CalComponent *comp, GSList **attendee_list) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (attendee_list != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - get_attendee_list (priv->attendee_list, attendee_list); -} - -/** - * cal_component_set_attendee_list: - * @comp: A calendar component object. - * @attendee_list: Values for attendee properties - * - * Sets the attendees of a calendar component object - **/ -void -cal_component_set_attendee_list (CalComponent *comp, GSList *attendee_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_attendee_list (comp, &priv->attendee_list, attendee_list); -} - -gboolean -cal_component_has_attendees (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; - - if (g_slist_length (priv->attendee_list) > 0) - return TRUE; - - return FALSE; -} - -/** - * cal_component_get_location: - * @comp: A calendar component object. - * @url: Return value for the location. - * - * Queries the location property of a calendar component object. - **/ -void -cal_component_get_location (CalComponent *comp, const char **location) -{ - CalComponentPrivate *priv; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (location != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - if (priv->location) - *location = icalproperty_get_location (priv->location); - else - *location = NULL; -} - -/** - * cal_component_set_location: - * @comp: A calendar component object. - * @url: Location value. - * - * Sets the location property of a calendar component object. - **/ -void -cal_component_set_location (CalComponent *comp, const char *location) -{ - 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 (!location || !(*location)) { - if (priv->location) { - icalcomponent_remove_property (priv->icalcomp, priv->location); - icalproperty_free (priv->location); - priv->location = NULL; - } - - return; - } - - if (priv->location) - icalproperty_set_location (priv->location, (char *) location); - else { - priv->location = icalproperty_new_location ((char *) location); - icalcomponent_add_property (priv->icalcomp, priv->location); - } -} - - - -/** - * 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); - - g_free (dt->value); - g_free ((char*)dt->tzid); -} - -/** - * 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 ((char*)cdt->tzid); - - 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_free_attendee_list: - * @attendee_list: - * - * - **/ -void -cal_component_free_attendee_list (GSList *attendee_list) -{ - GSList *l; - - for (l = attendee_list; l; l = l->next) { - CalComponentAttendee *attendee; - - g_assert (l->data != NULL); - - attendee = l->data; - g_return_if_fail (attendee != NULL); - g_free (attendee); - } - - g_slist_free (attendee_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; -} - -/** - * cal_component_add_alarm: - * @comp: A calendar component. - * @alarm: An alarm. - * - * Adds an alarm subcomponent to a calendar component. You should have created - * the @alarm by using cal_component_alarm_new(); it is invalid to use a - * #CalComponentAlarm structure that came from cal_component_get_alarm(). After - * adding the alarm, the @alarm structure is no longer valid because the - * internal structures may change and you should get rid of it by using - * cal_component_alarm_free(). - **/ -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; - - add_alarm (comp, alarm->icalcomp, icalproperty_get_x (alarm->uid)); - icalcomponent_add_component (priv->icalcomp, alarm->icalcomp); -} - -/** - * cal_component_remove_alarm: - * @comp: A calendar component. - * @auid: UID of the alarm to remove. - * - * Removes an alarm subcomponent from a calendar component. If the alarm that - * corresponds to the specified @auid had been fetched with - * cal_component_get_alarm(), then those alarm structures will be invalid; you - * should get rid of them with cal_component_alarm_free() before using this - * function. - **/ -void -cal_component_remove_alarm (CalComponent *comp, const char *auid) -{ - CalComponentPrivate *priv; - icalcomponent *alarm; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (auid != NULL); - - priv = comp->priv; - g_return_if_fail (priv->icalcomp != NULL); - - alarm = g_hash_table_lookup (priv->alarm_uid_hash, auid); - if (!alarm) - return; - - g_hash_table_remove (priv->alarm_uid_hash, auid); - icalcomponent_remove_component (priv->icalcomp, alarm); - icalcomponent_free (alarm); -} - -static gboolean -for_each_remove_all_alarms (gpointer key, gpointer value, gpointer data) -{ - CalComponent *comp = CAL_COMPONENT (data); - CalComponentPrivate *priv; - icalcomponent *alarm = value; - - priv = comp->priv; - - icalcomponent_remove_component (priv->icalcomp, alarm); - icalcomponent_free (alarm); - - return TRUE; -} - -/** - * cal_component_remove_all_alarms: - * @comp: A calendar component - * - * Remove all alarms from the calendar component - **/ -void -cal_component_remove_all_alarms (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); - - g_hash_table_foreach_remove (priv->alarm_uid_hash, for_each_remove_all_alarms, comp); -} - - -/* 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_ATTACH_PROPERTY: - /* FIXME: mail alarms may have any number of these, not just one */ - alarm->attach = prop; - break; - - case ICAL_DESCRIPTION_PROPERTY: - alarm->description.prop = prop; - alarm->description.altrep_param = icalproperty_get_first_parameter ( - prop, ICAL_ALTREP_PARAMETER); - break; - - case ICAL_DURATION_PROPERTY: - alarm->duration = prop; - break; - - case ICAL_REPEAT_PROPERTY: - alarm->repeat = 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 (icalcomponent *subcomp) -{ - CalComponentAlarm *alarm; - icalproperty *prop; - - alarm = g_new (CalComponentAlarm, 1); - - alarm->icalcomp = subcomp; - alarm->uid = NULL; - - alarm->action = NULL; - alarm->attach = NULL; - alarm->description.prop = NULL; - alarm->description.altrep_param = NULL; - alarm->duration = NULL; - alarm->repeat = NULL; - alarm->trigger = 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; -} - -/** - * 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; - icalcompiter iter; - 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; - for (iter = icalcomponent_begin_component (priv->icalcomp, ICAL_VALARM_COMPONENT); - icalcompiter_deref (&iter) != NULL; - icalcompiter_next (&iter)) { - icalcomponent *subcomp; - icalproperty *prop; - - 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; - - xname = icalproperty_get_x_name (prop); - g_assert (xname != NULL); - - if (strcmp (xname, EVOLUTION_ALARM_UID_PROPERTY) == 0) { - const char *auid; - - auid = alarm_uid_from_prop (prop); - l = g_list_append (l, g_strdup (auid)); - } - } - } - - 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 (alarm); - else - return 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; - char *new_auid ; - - alarm = g_new (CalComponentAlarm, 1); - - 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); - - alarm->action = NULL; - alarm->attach = NULL; - alarm->description.prop = NULL; - alarm->description.altrep_param = NULL; - alarm->duration = NULL; - alarm->repeat = NULL; - alarm->trigger = NULL; - - return alarm; -} - -/** - * cal_component_alarm_clone: - * @alarm: An alarm subcomponent. - * - * Creates a new alarm subcomponent by copying the information from another one. - * - * Return value: A newly-created alarm subcomponent with the same values as the - * original one. Should be freed with cal_component_alarm_free(). - **/ -CalComponentAlarm * -cal_component_alarm_clone (CalComponentAlarm *alarm) -{ - icalcomponent *icalcomp; - - g_return_val_if_fail (alarm != NULL, NULL); - - icalcomp = icalcomponent_new_clone (alarm->icalcomp); - return make_alarm (icalcomp); -} - -/** - * 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->uid = NULL; - alarm->action = NULL; - alarm->attach = NULL; - alarm->description.prop = NULL; - alarm->description.altrep_param = NULL; - alarm->duration = NULL; - alarm->repeat = NULL; - alarm->trigger = NULL; - - g_free (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) -{ - enum icalproperty_action ipa; - - 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; - } - - ipa = icalproperty_get_action (alarm->action); - - switch (ipa) { - case ICAL_ACTION_AUDIO: - *action = CAL_ALARM_AUDIO; - break; - - case ICAL_ACTION_DISPLAY: - *action = CAL_ALARM_DISPLAY; - break; - - case ICAL_ACTION_EMAIL: - *action = CAL_ALARM_EMAIL; - break; - - case ICAL_ACTION_PROCEDURE: - *action = CAL_ALARM_PROCEDURE; - break; - - case ICAL_ACTION_NONE: - *action = CAL_ALARM_NONE; - break; - - default: - *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) -{ - enum icalproperty_action ipa; - - 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: - ipa = ICAL_ACTION_AUDIO; - break; - - case CAL_ALARM_DISPLAY: - ipa = ICAL_ACTION_DISPLAY; - break; - - case CAL_ALARM_EMAIL: - ipa = ICAL_ACTION_EMAIL; - break; - - case CAL_ALARM_PROCEDURE: - ipa = ICAL_ACTION_PROCEDURE; - break; - - default: - g_assert_not_reached (); - ipa = ICAL_ACTION_NONE; - } - - if (alarm->action) - icalproperty_set_action (alarm->action, ipa); - else { - alarm->action = icalproperty_new_action (ipa); - icalcomponent_add_property (alarm->icalcomp, alarm->action); - } -} - -/** - * cal_component_alarm_get_attach: - * @alarm: An alarm. - * @attach: Return value for the attachment; should be freed using icalattach_unref(). - * - * Queries the attachment property of an alarm. - **/ -void -cal_component_alarm_get_attach (CalComponentAlarm *alarm, icalattach **attach) -{ - g_return_if_fail (alarm != NULL); - g_return_if_fail (attach != NULL); - - g_assert (alarm->icalcomp != NULL); - - if (alarm->attach) { - *attach = icalproperty_get_attach (alarm->attach); - icalattach_ref (*attach); - } else - *attach = NULL; -} - -/** - * cal_component_alarm_set_attach: - * @alarm: An alarm. - * @attach: Attachment property or NULL to remove an existing property. - * - * Sets the attachment property of an alarm. - **/ -void -cal_component_alarm_set_attach (CalComponentAlarm *alarm, icalattach *attach) -{ - g_return_if_fail (alarm != NULL); - - g_assert (alarm->icalcomp != NULL); - - if (alarm->attach) { - icalcomponent_remove_property (alarm->icalcomp, alarm->attach); - icalproperty_free (alarm->attach); - alarm->attach = NULL; - } - - if (attach) { - alarm->attach = icalproperty_new_attach (attach); - icalcomponent_add_property (alarm->icalcomp, alarm->attach); - } -} - -/** - * cal_component_alarm_get_description: - * @alarm: An alarm. - * @description: Return value for the description property and its parameters. - * - * Queries the description property of an alarm. - **/ -void -cal_component_alarm_get_description (CalComponentAlarm *alarm, CalComponentText *description) -{ - g_return_if_fail (alarm != NULL); - g_return_if_fail (description != NULL); - - g_assert (alarm->icalcomp != NULL); - - if (alarm->description.prop) - description->value = icalproperty_get_description (alarm->description.prop); - else - description->value = NULL; - - if (alarm->description.altrep_param) - description->altrep = icalparameter_get_altrep (alarm->description.altrep_param); - else - description->altrep = NULL; -} - -/** - * cal_component_alarm_set_description: - * @alarm: An alarm. - * @description: Description property and its parameters, or NULL for no description. - * - * Sets the description property of an alarm. - **/ -void -cal_component_alarm_set_description (CalComponentAlarm *alarm, CalComponentText *description) -{ - g_return_if_fail (alarm != NULL); - - g_assert (alarm->icalcomp != NULL); - - if (alarm->description.prop) { - icalcomponent_remove_property (alarm->icalcomp, alarm->description.prop); - icalproperty_free (alarm->description.prop); - - alarm->description.prop = NULL; - alarm->description.altrep_param = NULL; - } - - if (!description) - return; - - g_return_if_fail (description->value != NULL); - - alarm->description.prop = icalproperty_new_description (description->value); - icalcomponent_add_property (alarm->icalcomp, alarm->description.prop); - - if (description->altrep) { - alarm->description.altrep_param = icalparameter_new_altrep ( - (char *) description->altrep); - icalproperty_add_parameter (alarm->description.prop, - alarm->description.altrep_param); - } -} - -/** - * cal_component_alarm_get_repeat: - * @alarm: An alarm. - * @repeat: Return value for the repeat/duration properties. - * - * Queries the repeat/duration properties of an alarm. - **/ -void -cal_component_alarm_get_repeat (CalComponentAlarm *alarm, CalAlarmRepeat *repeat) -{ - g_return_if_fail (alarm != NULL); - g_return_if_fail (repeat != NULL); - - g_assert (alarm->icalcomp != NULL); - - if (!(alarm->repeat && alarm->duration)) { - repeat->repetitions = 0; - memset (&repeat->duration, 0, sizeof (repeat->duration)); - return; - } - - repeat->repetitions = icalproperty_get_repeat (alarm->repeat); - repeat->duration = icalproperty_get_duration (alarm->duration); -} - -/** - * cal_component_alarm_set_repeat: - * @alarm: An alarm. - * @repeat: Repeat/duration values. To remove any repetitions from the alarm, - * set the @repeat.repetitions to 0. - * - * Sets the repeat/duration values for an alarm. - **/ -void -cal_component_alarm_set_repeat (CalComponentAlarm *alarm, CalAlarmRepeat repeat) -{ - g_return_if_fail (alarm != NULL); - g_return_if_fail (repeat.repetitions >= 0); - - g_assert (alarm->icalcomp != NULL); - - /* Delete old properties */ - - if (alarm->repeat) { - icalcomponent_remove_property (alarm->icalcomp, alarm->repeat); - icalproperty_free (alarm->repeat); - alarm->repeat = NULL; - } - - if (alarm->duration) { - icalcomponent_remove_property (alarm->icalcomp, alarm->duration); - icalproperty_free (alarm->duration); - alarm->duration = NULL; - } - - /* Set the new properties */ - - if (repeat.repetitions == 0) - return; /* For zero extra repetitions the properties should not exist */ - - alarm->repeat = icalproperty_new_repeat (repeat.repetitions); - icalcomponent_add_property (alarm->icalcomp, alarm->repeat); - - alarm->duration = icalproperty_new_duration (repeat.duration); - icalcomponent_add_property (alarm->icalcomp, alarm->duration); -} - -/** - * 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; - value_type = ICAL_VALUE_DURATION; - related = ICAL_RELATED_START; - break; - - case CAL_ALARM_TRIGGER_RELATIVE_END: - t.duration = trigger.u.rel_duration; - value_type = ICAL_VALUE_DURATION; - related = ICAL_RELATED_END; - break; - - case CAL_ALARM_TRIGGER_ABSOLUTE: - t.time = trigger.u.abs_time; - value_type = ICAL_VALUE_DATETIME; - 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); - } - } -} - -/* 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; - gboolean retval = TRUE; - - 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) { - retval = FALSE; - goto out; - } - } else { - if (icaltime_compare (*comp1_dtstart.value, - *comp2_dtstart.value)) { - retval = FALSE; - goto out; - } - } - - if (comp1_dtend.value == NULL || comp2_dtend.value == NULL) { - if (comp1_dtend.value != comp2_dtend.value) { - retval = FALSE; - goto out; - } - } else { - if (icaltime_compare (*comp1_dtend.value, - *comp2_dtend.value)) { - retval = FALSE; - goto out; - } - } - - /* Now check the timezones. */ - if (!cal_component_strings_match (comp1_dtstart.tzid, - comp2_dtstart.tzid)) { - retval = FALSE; - goto out; - } - - if (!cal_component_strings_match (comp1_dtend.tzid, - comp2_dtend.tzid)) { - retval = FALSE; - } - - out: - - cal_component_free_datetime (&comp1_dtstart); - cal_component_free_datetime (&comp1_dtend); - cal_component_free_datetime (&comp2_dtstart); - cal_component_free_datetime (&comp2_dtend); - - return retval; -} - diff --git a/calendar/cal-util/cal-component.h b/calendar/cal-util/cal-component.h deleted file mode 100644 index 4961c504e4..0000000000 --- a/calendar/cal-util/cal-component.h +++ /dev/null @@ -1,438 +0,0 @@ -/* Evolution calendar - iCalendar component object - * - * Copyright (C) 2000 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#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. - * - * NOTE: These are also used in the ETable specification, and the column - * numbers are saved in the user settings file. So don't reorder them! - */ -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_STATUS, - CAL_COMPONENT_FIELD_COMPONENT, /* not a real field */ -#if 0 - CAL_COMPONENT_FIELD_LOCATION, -#endif - 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; - -/* The type of range */ -typedef enum { - CAL_COMPONENT_RANGE_SINGLE, - CAL_COMPONENT_RANGE_THISPRIOR, - CAL_COMPONENT_RANGE_THISFUTURE, -} CalComponentRangeType; - -typedef struct { - CalComponentRangeType type; - - CalComponentDateTime datetime; -} CalComponentRange; - -/* 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; - -/* Organizer & Attendee */ -typedef struct { - const char *value; - - const char *member; - icalparameter_cutype cutype; - icalparameter_role role; - icalparameter_partstat status; - gboolean rsvp; - - const char *delto; - const char *delfrom; - const char *sentby; - const char *cn; - const char *language; -} CalComponentAttendee; - -typedef struct { - const char *value; - const char *sentby; - const char *cn; - const char *language; -} CalComponentOrganizer; - -/* 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); -void cal_component_rescan (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_contact_list (CalComponent *comp, GSList **text_list); -void cal_component_set_contact_list (CalComponent *comp, GSList *text_list); - -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_organizer (CalComponent *comp, CalComponentOrganizer *organizer); -void cal_component_set_organizer (CalComponent *comp, CalComponentOrganizer *organizer); -gboolean cal_component_has_organizer (CalComponent *comp); - -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_recurid (CalComponent *comp, CalComponentRange *recur_id); -void cal_component_set_recurid (CalComponent *comp, CalComponentRange *recur_id); - -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); - -void cal_component_get_attendee_list (CalComponent *comp, GSList **attendee_list); -void cal_component_set_attendee_list (CalComponent *comp, GSList *attendee_list); -gboolean cal_component_has_attendees (CalComponent *comp); - -void cal_component_get_location (CalComponent *comp, const char **location); -void cal_component_set_location (CalComponent *comp, const char *location); - -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); -void cal_component_free_attendee_list (GSList *attendee_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_start; - time_t occur_end; -} 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; - -typedef struct { - /* Number of extra repetitions, zero for none */ - int repetitions; - - /* Interval between repetitions */ - struct icaldurationtype duration; -} CalAlarmRepeat; - -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); -void cal_component_remove_all_alarms (CalComponent *comp); - -GList *cal_component_get_alarm_uids (CalComponent *comp); -CalComponentAlarm *cal_component_get_alarm (CalComponent *comp, const char *auid); - -void cal_component_alarms_free (CalComponentAlarms *alarms); - -/* CalComponentAlarms */ -CalComponentAlarm *cal_component_alarm_new (void); -CalComponentAlarm *cal_component_alarm_clone (CalComponentAlarm *alarm); -void cal_component_alarm_free (CalComponentAlarm *alarm); - -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_attach (CalComponentAlarm *alarm, icalattach **attach); -void cal_component_alarm_set_attach (CalComponentAlarm *alarm, icalattach *attach); - -void cal_component_alarm_get_description (CalComponentAlarm *alarm, CalComponentText *description); -void cal_component_alarm_set_description (CalComponentAlarm *alarm, CalComponentText *description); - -void cal_component_alarm_get_repeat (CalComponentAlarm *alarm, CalAlarmRepeat *repeat); -void cal_component_alarm_set_repeat (CalComponentAlarm *alarm, CalAlarmRepeat repeat); - -void cal_component_alarm_get_trigger (CalComponentAlarm *alarm, CalAlarmTrigger *trigger); -void cal_component_alarm_set_trigger (CalComponentAlarm *alarm, CalAlarmTrigger trigger); - - - -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 e050004031..0000000000 --- a/calendar/cal-util/cal-recur.c +++ /dev/null @@ -1,3980 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Evolution calendar recurrence rule functions - * - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Damon Chaplin <damon@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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. - * - * - * FIXME: I think there are a few errors in this code: - * - * 1) I'm not sure it should be generating events in parallel like it says - * above. That needs to be checked. - * - * 2) I didn't think about timezone changes when implementing this. I just - * assumed all the occurrences of the event would be in local time. - * But when clocks go back or forwards due to daylight-saving time, some - * special handling may be needed, especially for the shorter frequencies. - * e.g. for a MINUTELY frequency it should probably iterate over all the - * minutes before and after clocks go back (i.e. some may be the same local - * time but have different UTC offsets). For longer frequencies, if an - * occurrence lands on the overlapping or non-existant time when clocks - * go back/forward, then it may need to choose which of the times to use - * or move the time forward or something. I'm not sure this is clear in the - * spec. - */ - -/* This is the maximum year we will go up to (inclusive). Since we use time_t - values we can't go past 2037 anyway, and some of our VTIMEZONEs may stop - at 2037 as well. */ -#define MAX_YEAR 2037 - -/* 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, inclusive. 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 flags; /* The meaning of this depends on where the - CalObjTime is used. In most cases this is - set to TRUE to indicate that this is an - RDATE with an end or a duration set. - In the exceptions code, this is set to TRUE - to indicate that this is an EXDATE with a - DATE value. */ -}; - -/* 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, - CalRecurResolveTimezoneFn tz_cb, - gpointer tz_cb_data, - icaltimezone *default_timezone); - -static CalRecurrence * cal_recur_from_icalproperty (icalproperty *prop, - gboolean exception, - icaltimezone *zone, - gboolean convert_end_date); -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, - icaltimezone *zone, - 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, - gboolean convert_end_date, - CalRecurInstanceFn cb, - gpointer cb_data); - -static GArray* cal_obj_expand_recurrence (CalObjTime *event_start, - icaltimezone *zone, - 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, - icaltimezone *zone); -static gint cal_obj_date_only_compare_func (const void *arg1, - const void *arg2); - - - -static gboolean cal_recur_ensure_end_dates (CalComponent *comp, - gboolean refresh, - CalRecurResolveTimezoneFn tz_cb, - gpointer tz_cb_data); -static gboolean cal_recur_ensure_rule_end_date (CalComponent *comp, - icalproperty *prop, - gboolean exception, - gboolean refresh, - CalRecurResolveTimezoneFn tz_cb, - gpointer tz_cb_data); -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, - icaltimezone *default_timezone); -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, - CalRecurResolveTimezoneFn tz_cb, - gpointer tz_cb_data, - icaltimezone *default_timezone) -{ -#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, tz_cb, tz_cb_data, - default_timezone); -} - - -/* - * 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, - CalRecurResolveTimezoneFn tz_cb, - gpointer tz_cb_data, - icaltimezone *default_timezone) -{ - 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, convert_end_date = FALSE; - icaltimezone *start_zone = NULL, *end_zone = NULL; - - g_return_if_fail (comp != NULL); - g_return_if_fail (cb != NULL); - g_return_if_fail (tz_cb != NULL); - g_return_if_fail (start >= -1); - g_return_if_fail (end >= -1); - - /* Get dtstart, dtend, recurrences, and exceptions. Note that - cal_component_get_dtend() will convert a DURATION property to a - DTEND so we don't need to worry about that. */ - - 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; - } - - /* For DATE-TIME values with a TZID, we use the supplied callback to - resolve the TZID. For DATE values and DATE-TIME values without a - TZID (i.e. floating times) we use the default timezone. */ - if (dtstart.tzid && !dtstart.value->is_date) { - start_zone = (*tz_cb) (dtstart.tzid, tz_cb_data); - } else { - start_zone = default_timezone; - - /* Flag that we need to convert the saved ENDDATE property - to the default timezone. */ - convert_end_date = TRUE; - } - - dtstart_time = icaltime_as_timet_with_zone (*dtstart.value, - start_zone); - if (start == -1) - start = dtstart_time; - - if (dtend.value) { - /* If both DTSTART and DTEND are DATE values, and they are the - same day, we add 1 day to DTEND. This means that most - events created with the old Evolution behavior will still - work OK. I'm not sure what Outlook does in this case. */ - if (dtstart.value->is_date && dtend.value->is_date) { - if (icaltime_compare_date_only (*dtstart.value, - *dtend.value) == 0) { - icaltime_adjust (dtend.value, 1, 0, 0, 0); - } - } - } else { - /* If there is no DTEND, then if DTSTART is a DATE-TIME value - we use the same time (so we have a single point in time). - If DTSTART is a DATE value we add 1 day. */ - dtend.value = g_new (struct icaltimetype, 1); - *dtend.value = *dtstart.value; - - if (dtstart.value->is_date) { - icaltime_adjust (dtend.value, 1, 0, 0, 0); - } - } - - if (dtend.tzid && !dtend.value->is_date) { - end_zone = (*tz_cb) (dtend.tzid, tz_cb_data); - } else { - end_zone = default_timezone; - } - - /* We don't do this any more, since Outlook assumes that the DTEND - date is not included. */ -#if 0 - /* If DTEND is a DATE value, we add 1 day to it so that it includes - the entire day. */ - if (dtend.value->is_date) { - dtend.value->hour = 0; - dtend.value->minute = 0; - dtend.value->second = 0; - icaltime_adjust (dtend.value, 1, 0, 0, 0); - } -#endif - dtend_time = icaltime_as_timet_with_zone (*dtend.value, end_zone); - - /* 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, tz_cb, tz_cb_data); - - 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. We do all calculation - in the timezone of the DTSTART. */ - cal_object_time_from_time (&interval_start, start, start_zone); - if (end != -1) - cal_object_time_from_time (&interval_end, end - 1, start_zone); - - cal_object_time_from_time (&event_start, dtstart_time, start_zone); - cal_object_time_from_time (&event_end, dtend_time, start_zone); - - /* 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 <= MAX_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.flags = FALSE; - } - - if (!generate_instances_for_chunk (comp, dtstart_time, - start_zone, - rrules, rdates, - exrules, exdates, - single_rule, - &event_start, - start, - &chunk_start, &chunk_end, - days, seconds, - convert_end_date, - 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: - * @prop: An RRULE or EXRULE #icalproperty. - * @exception: TRUE if this is an EXRULE rather than an RRULE. - * @zone: The DTSTART timezone, used for converting the UNTIL property if it - * is given as a DATE value. - * @convert_end_date: TRUE if the saved end date needs to be converted to the - * given @zone timezone. This is needed if the DTSTART is a DATE or floating - * time. - * - * 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, - icaltimezone *zone, gboolean convert_end_date) -{ - struct icalrecurrencetype ir; - CalRecurrence *r; - gint max_elements, i; - GList *elem; - - 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) { - /* If COUNT is set, we use the pre-calculated enddate. - Note that this can be 0 if the RULE doesn't actually - generate COUNT instances. */ - r->enddate = cal_recur_get_rule_end_date (prop, convert_end_date ? zone : NULL); - } else { - if (icaltime_is_null_time (ir.until)) { - /* If neither COUNT or UNTIL is set, the event - recurs forever. */ - r->enddate = 0; - } else if (ir.until.is_date) { - /* If UNTIL is a DATE, we stop at the end of - the day, in local time (with the DTSTART timezone). - Note that UNTIL is inclusive so we stop before - midnight. */ - ir.until.hour = 23; - ir.until.minute = 59; - ir.until.second = 59; - ir.until.is_date = FALSE; - - r->enddate = icaltime_as_timet_with_zone (ir.until, - zone); -#if 0 - g_print (" until: %li - %s", r->enddate, ctime (&r->enddate)); -#endif - - } else { - /* If UNTIL is a DATE-TIME, it must be in UTC. */ - icaltimezone *utc_zone; - utc_zone = icaltimezone_get_utc_timezone (); - r->enddate = icaltime_as_timet_with_zone (ir.until, - utc_zone); - } - } - - 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])); - for (elem = r->bymonth; elem; elem = elem->next) { - /* We need to convert from 1-12 to 0-11, i.e. subtract 1. */ - int month = GPOINTER_TO_INT (elem->data) - 1; - elem->data = GINT_TO_POINTER (month); - } - - 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, - icaltimezone *zone, - 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, - gboolean convert_end_date, - 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 icaltimetype start_tt, end_tt; - 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, zone, - convert_end_date); - - tmp_occs = cal_obj_expand_recurrence (event_start, zone, 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 RDATE occurrence dates. If they have an end time - or duration set, flag them as RDATEs, and store a pointer to the - period in the rdate_periods array. Otherwise we can just treat them - as normal occurrences. */ - for (elem = rdates; elem; elem = elem->next) { - CalComponentPeriod *p; - CalObjRecurrenceDate rdate; - - p = elem->data; - - /* FIXME: We currently assume RDATEs are in the same timezone - as DTSTART. We should get the RDATE timezone and convert - to the DTSTART timezone first. */ - cotime.year = p->start.year; - cotime.month = p->start.month - 1; - cotime.day = p->start.day; - cotime.hour = p->start.hour; - cotime.minute = p->start.minute; - cotime.second = p->start.second; - cotime.flags = FALSE; - - /* 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) - FIXME. */ - if (p->type != CAL_COMPONENT_PERIOD_DATETIME - || p->u.end.second != -1) { - cotime.flags = 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, zone, - convert_end_date); - - tmp_occs = cal_obj_expand_recurrence (event_start, zone, 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; - - cdt = elem->data; - - /* FIXME: We currently assume EXDATEs are in the same timezone - as DTSTART. We should get the EXDATE timezone and convert - to the DTSTART timezone first. */ - cotime.year = cdt->value->year; - cotime.month = cdt->value->month - 1; - cotime.day = cdt->value->day; - - /* If the EXDATE has a DATE value, set the time to the start - of the day and set flags to TRUE so we know to skip all - occurrences on that date. */ - if (cdt->value->is_date) { - cotime.hour = 0; - cotime.minute = 0; - cotime.second = 0; - cotime.flags = TRUE; - } else { - cotime.hour = cdt->value->hour; - cotime.minute = cdt->value->minute; - cotime.second = cdt->value->second; - cotime.flags = FALSE; - } - - 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_tt = icaltime_null_time (); - start_tt.year = occ->year; - start_tt.month = occ->month + 1; - start_tt.day = occ->day; - start_tt.hour = occ->hour; - start_tt.minute = occ->minute; - start_tt.second = occ->second; - start_time = icaltime_as_timet_with_zone (start_tt, zone); - - if (start_time == -1) { - g_warning ("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->flags) { - /* If it is an RDATE, we see if the end date or - duration was set. If not, we use the same duration - as the original occurrence. */ - 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_tt = icaltime_null_time (); - end_tt.year = occ->year; - end_tt.month = occ->month + 1; - end_tt.day = occ->day; - end_tt.hour = occ->hour; - end_tt.minute = occ->minute; - end_tt.second = occ->second; - end_time = icaltime_as_timet_with_zone (end_tt, zone); - - if (end_time == -1) { - g_warning ("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; - - 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) { - /* FIXME: We currently assume RDATEs are in the same timezone - as DTSTART. We should get the RDATE timezone and convert - to the DTSTART timezone first. */ - occ->year = p->u.end.year; - occ->month = p->u.end.month - 1; - occ->day = p->u.end.day; - occ->hour = p->u.end.hour; - occ->minute = p->u.end.minute; - occ->second = p->u.end.second; - occ->flags = FALSE; - } 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, - icaltimezone *zone, - 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, zone); - 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 frequency"); - 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 with an end or - duration set, 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->flags && !current_time_is_exception) { - last_occ_kept = &g_array_index (occs, - CalObjTime, - j - 1); - last_occ_kept->flags = 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) { - /* If the exception is an EXDATE with - a DATE value, we only have to - compare the date. */ - if (ex_occ->flags) - cmp = cal_obj_date_only_compare_func (ex_occ, occ); - else - cmp = cal_obj_time_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) { - /* We are keeping this occurrence, so we move it to - the next free space, unless its position hasn't - changed (i.e. all previous occurrences were also - kept). */ - 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; - /* Positive values need to be decremented since the array is - 0-based. */ - else - pos--; - - 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); - - /* This calculates the number of days to step - backwards from the last day of the month - to the weekday we want. */ - offset = (last_weekday + 7 - weekday) % 7; - - /* This adds on the weeks. */ - 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; -} - - -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; -} - - -/* 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, - icaltimezone *zone) -{ - struct icaltimetype tt; - - tt = icaltime_from_timet_with_zone (t, FALSE, zone); - - cotime->year = tt.year; - cotime->month = tt.month - 1; - cotime->day = tt.day; - cotime->hour = tt.hour; - cotime->minute = tt.minute; - cotime->second = tt.second; - cotime->flags = 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, - CalRecurResolveTimezoneFn tz_cb, - gpointer tz_cb_data) -{ - 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, - tz_cb, tz_cb_data); - } - - /* 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, - tz_cb, tz_cb_data); - } - - 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, - CalRecurResolveTimezoneFn tz_cb, - gpointer tz_cb_data) -{ - 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, NULL) != -1) - return FALSE; - } - - /* Calculate the end date. Note that we initialize end_date to 0, so - if the RULE doesn't generate COUNT instances we save a time_t of 0. - Also note that we use the UTC timezone as the default timezone. - In get_end_date() if the DTSTART is a DATE or floating time, we will - convert the ENDDATE to the current timezone. */ - cb_data.count = rule.count; - cb_data.instances = 0; - cb_data.end_date = 0; - cal_recur_generate_instances_of_rule (comp, prop, -1, -1, - cal_recur_ensure_rule_end_date_cb, - &cb_data, tz_cb, tz_cb_data, - icaltimezone_get_utc_timezone ()); - - /* 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; -} - - -/* If default_timezone is set, the saved ENDDATE parameter is assumed to be - in that timezone. This is used when the DTSTART is a DATE or floating - value, since the RRULE end date will change depending on the timezone that - it is evaluated in. */ -static time_t -cal_recur_get_rule_end_date (icalproperty *prop, - icaltimezone *default_timezone) -{ - icalparameter *param; - const char *xname, *xvalue; - icalvalue *value; - struct icaltimetype icaltime; - icaltimezone *zone; - - 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); - - zone = default_timezone ? default_timezone : - icaltimezone_get_utc_timezone (); - return icaltime_as_timet_with_zone (icaltime, - zone); - } - } - - 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; - icaltimezone *utc_zone; - struct icaltimetype icaltime; - const char *end_date_string, *xname; - - /* We save the value as a UTC DATE-TIME. */ - utc_zone = icaltimezone_get_utc_timezone (); - icaltime = icaltime_from_timet_with_zone (end_date, FALSE, utc_zone); - 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 6ffeb2cb8a..0000000000 --- a/calendar/cal-util/cal-recur.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Evolution calendar recurrence rule functions - * - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Damon Chaplin <damon@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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); - -typedef icaltimezone* (* CalRecurResolveTimezoneFn) (const char *tzid, - 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. - * - * The tz_cb is used to resolve references to timezones. It is passed a TZID - * and should return the icaltimezone* corresponding to that TZID. We need to - * do this as we access timezones in different ways on the client & server. - * - * The default_timezone argument is used for DTSTART or DTEND properties that - * are DATE values or do not have a TZID (i.e. floating times). - */ -void cal_recur_generate_instances (CalComponent *comp, - time_t start, - time_t end, - CalRecurInstanceFn cb, - gpointer cb_data, - CalRecurResolveTimezoneFn tz_cb, - gpointer tz_cb_data, - icaltimezone *default_timezone); - -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 8ba1ff7d63..0000000000 --- a/calendar/cal-util/cal-util.c +++ /dev/null @@ -1,560 +0,0 @@ -/* Evolution calendar utilities and types - * - * Copyright (C) 2000 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#include <config.h> -#include <stdlib.h> -#include <string.h> -#include <glib.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <libgnome/gnome-util.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); -} - -icalcomponent * -cal_util_new_top_level (void) -{ - icalcomponent *icalcomp; - icalproperty *prop; - - icalcomp = icalcomponent_new (ICAL_VCALENDAR_COMPONENT); - - /* RFC 2445, section 4.7.1 */ - prop = icalproperty_new_calscale ("GREGORIAN"); - icalcomponent_add_property (icalcomp, prop); - - /* RFC 2445, section 4.7.3 */ - prop = icalproperty_new_prodid ("-//Ximian//NONSGML Evolution Calendar//EN"); - icalcomponent_add_property (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 (icalcomp, prop); - - return icalcomp; -} - -/* 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; - time_t repeat_time; - - *alarm_start = start; - *alarm_end = end; - - repeat_time = 0; - - for (l = alarm_uids; l; l = l->next) { - const char *auid; - CalComponentAlarm *alarm; - CalAlarmTrigger trigger; - struct icaldurationtype *dur; - time_t dur_time; - CalAlarmRepeat repeat; - - auid = l->data; - alarm = cal_component_get_alarm (comp, auid); - g_assert (alarm != NULL); - - cal_component_alarm_get_trigger (alarm, &trigger); - cal_component_alarm_get_repeat (alarm, &repeat); - cal_component_alarm_free (alarm); - - switch (trigger.type) { - case CAL_ALARM_TRIGGER_NONE: - case CAL_ALARM_TRIGGER_ABSOLUTE: - break; - - case CAL_ALARM_TRIGGER_RELATIVE_START: - case CAL_ALARM_TRIGGER_RELATIVE_END: - dur = &trigger.u.rel_duration; - dur_time = icaldurationtype_as_int (*dur); - - if (repeat.repetitions != 0) { - int rdur; - - rdur = repeat.repetitions * icaldurationtype_as_int (repeat.duration); - repeat_time = MAX (repeat_time, rdur); - } - - if (dur->is_neg) - /* If the duration is negative then dur_time - * will be negative as well; that is why we - * subtract to expand the range. - */ - *alarm_end = MAX (*alarm_end, end - dur_time); - else - *alarm_start = MIN (*alarm_start, start - dur_time); - - break; - - default: - g_assert_not_reached (); - } - } - - *alarm_start -= repeat_time; - - 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; -}; - -static void -add_trigger (struct alarm_occurrence_data *aod, const char *auid, time_t trigger, - time_t occur_start, time_t occur_end) -{ - CalAlarmInstance *instance; - - instance = g_new (CalAlarmInstance, 1); - instance->auid = auid; - instance->trigger = trigger; - instance->occur_start = occur_start; - instance->occur_end = occur_end; - - aod->triggers = g_slist_prepend (aod->triggers, instance); - aod->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; - CalAlarmRepeat repeat; - struct icaldurationtype *dur; - time_t dur_time; - time_t occur_time, trigger_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_get_repeat (alarm, &repeat); - 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 is true then dur_time will already be - * negative. So we do not need to test for dur->is_neg here; we - * can simply add the dur_time value to the occur_time and get - * the correct result. - */ - - trigger_time = occur_time + dur_time; - - /* Add repeating alarms */ - - if (repeat.repetitions != 0) { - int i; - time_t repeat_time; - - repeat_time = icaldurationtype_as_int (repeat.duration); - - for (i = 0; i < repeat.repetitions; i++) { - time_t t; - - t = trigger_time + (i + 1) * repeat_time; - - if (t >= aod->start && t < aod->end) - add_trigger (aod, auid, t, start, end); - } - } - - /* Add the trigger itself */ - - if (trigger_time >= aod->start && trigger_time < aod->end) - add_trigger (aod, auid, trigger_time, start, end); - } - - return TRUE; -} - -/* Generates the absolute triggers for a component */ -static void -generate_absolute_triggers (CalComponent *comp, struct alarm_occurrence_data *aod, - CalRecurResolveTimezoneFn resolve_tzid, - gpointer user_data, - icaltimezone *default_timezone) -{ - GList *l; - CalComponentDateTime dt_start, dt_end; - - cal_component_get_dtstart (comp, &dt_start); - cal_component_get_dtend (comp, &dt_end); - - for (l = aod->alarm_uids; l; l = l->next) { - const char *auid; - CalComponentAlarm *alarm; - CalAlarmRepeat repeat; - CalAlarmTrigger trigger; - time_t abs_time; - time_t occur_start, occur_end; - icaltimezone *zone; - - auid = l->data; - alarm = cal_component_get_alarm (comp, auid); - g_assert (alarm != NULL); - - cal_component_alarm_get_trigger (alarm, &trigger); - cal_component_alarm_get_repeat (alarm, &repeat); - cal_component_alarm_free (alarm); - - if (trigger.type != CAL_ALARM_TRIGGER_ABSOLUTE) - continue; - - /* Absolute triggers are always in UTC; see RFC 2445 section 4.8.6.3 */ - zone = icaltimezone_get_utc_timezone (); - - abs_time = icaltime_as_timet_with_zone (trigger.u.abs_time, zone); - - /* No particular occurrence, so just use the times from the component */ - - if (dt_start.value) { - if (dt_start.tzid && !dt_start.value->is_date) - zone = (* resolve_tzid) (dt_start.tzid, user_data); - else - zone = default_timezone; - - occur_start = icaltime_as_timet_with_zone (*dt_start.value, zone); - } else - occur_start = -1; - - if (dt_end.value) { - if (dt_end.tzid && !dt_end.value->is_date) - zone = (* resolve_tzid) (dt_end.tzid, user_data); - else - zone = default_timezone; - - occur_end = icaltime_as_timet_with_zone (*dt_end.value, zone); - } else - occur_end = -1; - - /* Add repeating alarms */ - - if (repeat.repetitions != 0) { - int i; - time_t repeat_time; - - repeat_time = icaldurationtype_as_int (repeat.duration); - - for (i = 0; i < repeat.repetitions; i++) { - time_t t; - - t = abs_time + (i + 1) * repeat_time; - - if (t >= aod->start && t < aod->end) - add_trigger (aod, auid, t, occur_start, occur_end); - } - } - - /* Add the trigger itself */ - - if (abs_time >= aod->start && abs_time < aod->end) - add_trigger (aod, auid, abs_time, occur_start, occur_end); - } - - cal_component_free_datetime (&dt_start); - cal_component_free_datetime (&dt_end); -} - -/* 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; -} - -/** - * cal_util_generate_alarms_for_comp - * @comp: the CalComponent to generate alarms from - * @start: start time - * @end: end time - * @resolve_tzid: callback for resolving timezones - * @user_data: data to be passed to the resolve_tzid callback - * @default_timezone: the timezone used to resolve DATE and floating DATE-TIME - * values. - * - * Generates alarm instances for a calendar component. Returns the instances - * structure, or NULL if no alarm instances occurred in the specified time - * range. - */ -CalComponentAlarms * -cal_util_generate_alarms_for_comp (CalComponent *comp, - time_t start, - time_t end, - CalRecurResolveTimezoneFn resolve_tzid, - gpointer user_data, - icaltimezone *default_timezone) -{ - 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, - resolve_tzid, user_data, - default_timezone); - - /* We add the ABSOLUTE triggers separately */ - generate_absolute_triggers (comp, &aod, resolve_tzid, user_data, default_timezone); - - 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; -} - -/** - * cal_util_generate_alarms_for_list - * @comps: list of CalComponent's - * @start: start time - * @end: end time - * @comp_alarms: list to be returned - * @resolve_tzid: callback for resolving timezones - * @user_data: data to be passed to the resolve_tzid callback - * @default_timezone: the timezone used to resolve DATE and floating DATE-TIME - * values. - * - * 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. - */ -int -cal_util_generate_alarms_for_list (GList *comps, - time_t start, - time_t end, - GSList **comp_alarms, - CalRecurResolveTimezoneFn resolve_tzid, - gpointer user_data, - icaltimezone *default_timezone) -{ - GList *l; - int n; - - n = 0; - - for (l = comps; l; l = l->next) { - CalComponent *comp; - CalComponentAlarms *alarms; - - comp = CAL_COMPONENT (l->data); - alarms = cal_util_generate_alarms_for_comp (comp, start, end, resolve_tzid, user_data, default_timezone); - - if (alarms) { - *comp_alarms = g_slist_prepend (*comp_alarms, alarms); - n++; - } - } - - return n; -} - - -/* Converts an iCalendar PRIORITY value to a translated string. Any unknown - priority value (i.e. not 0-9) will be returned as "" (undefined). */ -char * -cal_util_priority_to_string (int priority) -{ - char *retval; - - if (priority <= 0) - retval = ""; - else if (priority <= 4) - retval = _("High"); - else if (priority == 5) - retval = _("Normal"); - else if (priority <= 9) - retval = _("Low"); - else - retval = ""; - - return retval; -} - - -/* Converts a translated priority string to an iCalendar priority value. - Returns -1 if the priority string is not valid. */ -int -cal_util_priority_from_string (const char *string) -{ - int priority; - - /* An empty string is the same as 'None'. */ - if (!string || !string[0] || !g_strcasecmp (string, _("Undefined"))) - priority = 0; - else if (!g_strcasecmp (string, _("High"))) - priority = 3; - else if (!g_strcasecmp (string, _("Normal"))) - priority = 5; - else if (!g_strcasecmp (string, _("Low"))) - priority = 7; - else - priority = -1; - - return priority; -} - -char * -cal_util_expand_uri (char *uri, gboolean tasks) -{ - char *file_uri, *file_name; - - if (!strncmp (uri, "file://", 7)) { - file_uri = uri + 7; - if (strlen (file_uri) > 4 - && !strcmp (file_uri + strlen (file_uri) - 4, ".ics")) { - - /* it's a .ics file */ - return g_strdup (uri); - } - - /* we assume it's a dir and glom <type>.ics onto the end. */ - if (tasks) - file_name = g_concat_dir_and_file (file_uri, "tasks.ics"); - else - file_name = g_concat_dir_and_file (file_uri, "calendar.ics"); - file_uri = g_strdup_printf("file://%s", file_name); - g_free(file_name); - } else { - file_uri = g_strdup (uri); - } - - return file_uri; -} diff --git a/calendar/cal-util/cal-util.h b/calendar/cal-util/cal-util.h deleted file mode 100644 index d4ccfb5388..0000000000 --- a/calendar/cal-util/cal-util.h +++ /dev/null @@ -1,92 +0,0 @@ -/* Evolution calendar utilities and types - * - * Copyright (C) 2000 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef CAL_UTIL_H -#define CAL_UTIL_H - -#include <libgnome/gnome-defs.h> -#include <ical.h> -#include <time.h> -#include <glib.h> -#include <cal-util/cal-component.h> -#include <cal-util/cal-recur.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; - -/* Used for mode stuff */ -typedef enum { - CAL_MODE_INVALID = -1, - CAL_MODE_LOCAL = 1 << 0, - CAL_MODE_REMOTE = 1 << 1, - CAL_MODE_ANY = 0x07 -} CalMode; - -void cal_obj_uid_list_free (GList *list); - -icalcomponent *cal_util_new_top_level (void); - -CalComponentAlarms *cal_util_generate_alarms_for_comp (CalComponent *comp, - time_t start, - time_t end, - CalRecurResolveTimezoneFn resolve_tzid, - gpointer user_data, - icaltimezone *default_timezone); -int cal_util_generate_alarms_for_list (GList *comps, - time_t start, - time_t end, - GSList **comp_alarms, - CalRecurResolveTimezoneFn resolve_tzid, - gpointer user_data, - icaltimezone *default_timezone); - -icaltimezone *cal_util_resolve_tzid (const char *tzid, gpointer data); - -char *cal_util_priority_to_string (int priority); -int cal_util_priority_from_string (const char *string); - -char *cal_util_expand_uri (char *uri, gboolean tasks); - - -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 5078a1db94..0000000000 --- a/calendar/cal-util/test-recur.c +++ /dev/null @@ -1,220 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 2000, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -/* - * 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 <stdlib.h> -#include <string.h> -#include <gtk/gtkmain.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); -} - - -/* This resolves any TZIDs in the components. The VTIMEZONEs must be in the - file we are reading. */ -static icaltimezone* -resolve_tzid_cb (const char *tzid, - gpointer user_data) -{ - icalcomponent *vcalendar_comp = user_data; - - if (!tzid || !tzid[0]) - return NULL; - else if (!strcmp (tzid, "UTC")) - return icaltimezone_get_utc_timezone (); - - return icalcomponent_get_timezone (vcalendar_comp, tzid); -} - - -static void -generate_occurrences (icalcomponent *icalcomp) -{ - icalcompiter iter; - icaltimezone *default_timezone; - - /* This is the timezone we will use for DATE and floating values. */ - default_timezone = icaltimezone_get_utc_timezone (); - - 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, - resolve_tzid_cb, icalcomp, - default_timezone); -#else - cal_recur_generate_instances (comp, -1, -1, - occurrence_cb, &occurrences, - resolve_tzid_cb, icalcomp, - default_timezone); -#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 3dcf8dc384..0000000000 --- a/calendar/cal-util/timeutil.c +++ /dev/null @@ -1,600 +0,0 @@ -/* Miscellaneous time-related utilities - * - * Copyright (C) 1998 The Free Software Foundation - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Federico Mena <federico@ximian.com> - * Miguel de Icaza <miguel@ximian.com> - * Damon Chaplin <damon@ximian.com> - */ - -#include <string.h> -#include <ctype.h> -#include <glib.h> -#include <ical.h> -#include "timeutil.h" - - - -#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 */ - - -/* Number of days in a month, using 0 (Jan) to 11 (Dec). For leap years, - add 1 to February (month 1). */ -static const int days_in_month[12] = { - 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 -}; - - - -/************************************************************************** - * time_t manipulation functions. - * - * NOTE: these use the Unix timezone functions like mktime() and localtime() - * and so should not be used in Evolution. New Evolution code should use - * icaltimetype values rather than time_t values wherever possible. - **************************************************************************/ - -static 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); -} - -/* 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; - - 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; - } - - return new_time; -} - -time_t -time_add_week (time_t time, int weeks) -{ - return time_add_day (time, weeks * 7); -} - -/* 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); -} - - -/************************************************************************** - * time_t manipulation functions, using timezones in libical. - * - * NOTE: these are only here to make the transition to the timezone - * functions easier. New code should use icaltimetype values rather than - * time_t values wherever possible. - **************************************************************************/ - - -/* Adds or subtracts a number of days to/from the given time_t value, using - the given timezone. - NOTE: this function is only here to make the transition to the timezone - functions easier. New code should use icaltimetype values and - icaltime_adjust() to add or subtract days, hours, minutes & seconds. */ -time_t -time_add_day_with_zone (time_t time, int days, icaltimezone *zone) -{ - struct icaltimetype tt; - - /* Convert to an icaltimetype. */ - tt = icaltime_from_timet_with_zone (time, FALSE, zone); - - /* Add/subtract the number of days. */ - icaltime_adjust (&tt, days, 0, 0, 0); - - /* Convert back to a time_t. */ - return icaltime_as_timet_with_zone (tt, zone); -} - - -/* Adds or subtracts a number of weeks to/from the given time_t value, using - the given timezone. - NOTE: this function is only here to make the transition to the timezone - functions easier. New code should use icaltimetype values and - icaltime_adjust() to add or subtract days, hours, minutes & seconds. */ -time_t -time_add_week_with_zone (time_t time, int weeks, icaltimezone *zone) -{ - return time_add_day_with_zone (time, weeks * 7, zone); -} - - -/* Adds or subtracts a number of months to/from the given time_t value, using - the given timezone. - - If the day would be off the end of the month (e.g. adding 1 month to - 30th January, would lead to an invalid day, 30th February), it moves it - down to the last day in the month, e.g. 28th Feb (or 29th in a leap year.) - - NOTE: this function is only here to make the transition to the timezone - functions easier. New code should use icaltimetype values and - icaltime_adjust() to add or subtract days, hours, minutes & seconds. */ -time_t -time_add_month_with_zone (time_t time, int months, icaltimezone *zone) -{ - struct icaltimetype tt; - int day, days_in_month; - - /* Convert to an icaltimetype. */ - tt = icaltime_from_timet_with_zone (time, FALSE, zone); - - /* Add on the number of months. */ - tt.month += months; - - /* Save the day, and set it to 1, so we don't overflow into the next - month. */ - day = tt.day; - tt.day = 1; - - /* Normalize it, fixing any month overflow. */ - tt = icaltime_normalize (tt); - - /* If we go past the end of a month, set it to the last day. */ - days_in_month = time_days_in_month (tt.year, tt.month - 1); - if (day > days_in_month) - day = days_in_month; - - tt.day = day; - - /* Convert back to a time_t. */ - return icaltime_as_timet_with_zone (tt, zone); -} - - -/* Returns the start of the year containing the given time_t, using the given - timezone. - NOTE: this function is only here to make the transition to the timezone - functions easier. New code should use icaltimetype values and - icaltime_adjust() to add or subtract days, hours, minutes & seconds. */ -time_t -time_year_begin_with_zone (time_t time, icaltimezone *zone) -{ - struct icaltimetype tt; - - /* Convert to an icaltimetype. */ - tt = icaltime_from_timet_with_zone (time, FALSE, zone); - - /* Set it to the start of the year. */ - tt.month = 1; - tt.day = 1; - tt.hour = 0; - tt.minute = 0; - tt.second = 0; - - /* Convert back to a time_t. */ - return icaltime_as_timet_with_zone (tt, zone); -} - - -/* Returns the start of the month containing the given time_t, using the given - timezone. - NOTE: this function is only here to make the transition to the timezone - functions easier. New code should use icaltimetype values and - icaltime_adjust() to add or subtract days, hours, minutes & seconds. */ -time_t -time_month_begin_with_zone (time_t time, icaltimezone *zone) -{ - struct icaltimetype tt; - - /* Convert to an icaltimetype. */ - tt = icaltime_from_timet_with_zone (time, FALSE, zone); - - /* Set it to the start of the month. */ - tt.day = 1; - tt.hour = 0; - tt.minute = 0; - tt.second = 0; - - /* Convert back to a time_t. */ - return icaltime_as_timet_with_zone (tt, zone); -} - - -/* Returns the start of the week containing the given time_t, using the given - timezone. week_start_day should use the same values as mktime(), - i.e. 0 (Sun) to 6 (Sat). - NOTE: this function is only here to make the transition to the timezone - functions easier. New code should use icaltimetype values and - icaltime_adjust() to add or subtract days, hours, minutes & seconds. */ -time_t -time_week_begin_with_zone (time_t time, int week_start_day, icaltimezone *zone) -{ - struct icaltimetype tt; - int weekday, offset; - - /* Convert to an icaltimetype. */ - tt = icaltime_from_timet_with_zone (time, FALSE, zone); - - /* Get the weekday. */ - weekday = time_day_of_week (tt.day, tt.month - 1, tt.year); - - /* Calculate the current offset from the week start day. */ - offset = (weekday + 7 - week_start_day) % 7; - - /* Set it to the start of the month. */ - tt.day -= offset; - tt.hour = 0; - tt.minute = 0; - tt.second = 0; - - /* Normalize it, to fix any overflow. */ - tt = icaltime_normalize (tt); - - /* Convert back to a time_t. */ - return icaltime_as_timet_with_zone (tt, zone); -} - - -/* Returns the start of the day containing the given time_t, using the given - timezone. - NOTE: this function is only here to make the transition to the timezone - functions easier. New code should use icaltimetype values and - icaltime_adjust() to add or subtract days, hours, minutes & seconds. */ -time_t -time_day_begin_with_zone (time_t time, icaltimezone *zone) -{ - struct icaltimetype tt; - - /* Convert to an icaltimetype. */ - tt = icaltime_from_timet_with_zone (time, FALSE, zone); - - /* Set it to the start of the day. */ - tt.hour = 0; - tt.minute = 0; - tt.second = 0; - - /* Convert back to a time_t. */ - return icaltime_as_timet_with_zone (tt, zone); -} - - -/* Returns the end of the day containing the given time_t, using the given - timezone. (The end of the day is the start of the next day.) - NOTE: this function is only here to make the transition to the timezone - functions easier. New code should use icaltimetype values and - icaltime_adjust() to add or subtract days, hours, minutes & seconds. */ -time_t -time_day_end_with_zone (time_t time, icaltimezone *zone) -{ - struct icaltimetype tt; - - /* Convert to an icaltimetype. */ - tt = icaltime_from_timet_with_zone (time, FALSE, zone); - - /* Set it to the start of the next day. */ - tt.day++; - tt.hour = 0; - tt.minute = 0; - tt.second = 0; - - /* Normalize it, to fix any overflow. */ - tt = icaltime_normalize (tt); - - /* Convert back to a time_t. */ - return icaltime_as_timet_with_zone (tt, zone); -} - -/** - * time_to_gdate_with_zone: - * @date: Destination #GDate value. - * @time: A time value. - * @zone: Desired timezone for destination @date, or NULL if the UTC timezone - * is desired. - * - * Converts a time_t value to a #GDate structure using the specified timezone. - * This is analogous to g_date_set_time() but takes the timezone into account. - **/ -void -time_to_gdate_with_zone (GDate *date, time_t time, icaltimezone *zone) -{ - struct icaltimetype tt; - - g_return_if_fail (date != NULL); - g_return_if_fail (time != -1); - - tt = icaltime_from_timet_with_zone (time, FALSE, - zone ? zone : icaltimezone_get_utc_timezone ()); - - g_date_set_dmy (date, tt.day, tt.month, tt.year); -} - - -/************************************************************************** - * General time functions. - **************************************************************************/ - - -/* Returns the number of days in the month. Year is the normal year, e.g. 2001. - Month is 0 (Jan) to 11 (Dec). */ -int -time_days_in_month (int year, int month) -{ - int days; - - g_return_val_if_fail (year >= 1900, 0); - g_return_val_if_fail ((month >= 0) && (month < 12), 0); - - days = days_in_month[month]; - if (month == 1 && time_is_leap_year (year)) - days++; - - return days; -} - - -/* Returns the 1-based day number within the year of the specified date. - Year is the normal year, e.g. 2001. Month is 0 to 11. */ -int -time_day_of_year (int day, int month, int year) -{ - int i; - - for (i = 0; i < month; i++) { - day += days_in_month[i]; - - if (month == 1 && time_is_leap_year (year)) - day++; - } - - return day; -} - - -/* Returns the day of the week for the specified date, 0 (Sun) to 6 (Sat). - For the days that were removed on the Gregorian reformation, it returns - Thursday. Year is the normal year, e.g. 2001. Month is 0 to 11. */ -int -time_day_of_week (int day, int month, int year) -{ - int n; - - n = (year - 1) * 365 + time_leap_years_up_to (year - 1) - + time_day_of_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; -} - - -/* Returns whether the specified year is a leap year. Year is the normal year, - e.g. 2001. */ -gboolean -time_is_leap_year (int year) -{ - if (year <= 1752) - return !(year % 4); - else - return (!(year % 4) && (year % 100)) || !(year % 400); -} - - -/* Returns the number of leap years since year 1 up to (but not including) the - specified year. Year is the normal year, e.g. 2001. */ -int -time_leap_years_up_to (int year) -{ - /* There is normally a leap year every 4 years, except at the turn of - centuries since 1700. But there is a leap year on centuries since 1700 - which are divisible by 400. */ - return (year / 4 - - ((year > 1700) ? (year / 100 - 17) : 0) - + ((year > 1600) ? ((year - 1600) / 400) : 0)); -} - - -/** - * isodate_from_time_t: - * @t: A time value. - * - * Creates an ISO 8601 UTC representation from a time value. - * - * Return value: String with the ISO 8601 representation of the UTC time. - **/ -char * -isodate_from_time_t (time_t t) -{ - struct tm *tm; - char isotime[40]; - - tm = gmtime (&t); - strftime (isotime, sizeof (isotime)-1, "%Y%m%dT%H%M%SZ", tm); - return g_strdup (isotime); -} - -/** - * time_from_isodate: - * @str: Date/time value in ISO 8601 format. - * - * Converts an ISO 8601 UTC time string into a time_t value. - * - * Return value: Time_t corresponding to the specified ISO string. - * Note that we only allow UTC times at present. - **/ -time_t -time_from_isodate (const char *str) -{ - struct icaltimetype tt = icaltime_null_time (); - icaltimezone *utc_zone; - int len, i; - - g_return_val_if_fail (str != NULL, -1); - - /* yyyymmdd[Thhmmss[Z]] */ - - len = strlen (str); - - if (!(len == 8 || len == 15 || len == 16)) - return -1; - - for (i = 0; i < len; i++) - if (!((i != 8 && i != 15 && isdigit (str[i])) - || (i == 8 && str[i] == 'T') - || (i == 15 && str[i] == 'Z'))) - return -1; - -#define digit_at(x,y) (x[y] - '0') - - tt.year = digit_at (str, 0) * 1000 - + digit_at (str, 1) * 100 - + digit_at (str, 2) * 10 - + digit_at (str, 3); - - tt.month = digit_at (str, 4) * 10 - + digit_at (str, 5); - - tt.day = digit_at (str, 6) * 10 - + digit_at (str, 7); - - if (len > 8) { - tt.hour = digit_at (str, 9) * 10 - + digit_at (str, 10); - tt.minute = digit_at (str, 11) * 10 - + digit_at (str, 12); - tt.second = digit_at (str, 13) * 10 - + digit_at (str, 14); - } - - utc_zone = icaltimezone_get_utc_timezone (); - - return icaltime_as_timet_with_zone (tt, utc_zone); -} - -struct tm -icaltimetype_to_tm (struct icaltimetype *itt) -{ - struct tm tm; - - memset (&tm, 0, sizeof (struct tm)); - - if (!itt->is_date) { - tm.tm_sec = itt->second; - tm.tm_min = itt->minute; - tm.tm_hour = itt->hour; - } - - tm.tm_mday = itt->day; - tm.tm_mon = itt->month - 1; - tm.tm_year = itt->year - 1900; - tm.tm_wday = time_day_of_week (itt->day, itt->month - 1, itt->year); - tm.tm_isdst = -1; - - return tm; -} - -/** - * icaltimetype_to_tm_with_zone: - * @itt: A time value. - * @from_zone: Source timezone. - * @to_zone: Destination timezone. - * - * Converts a time value from one timezone to another, and returns a struct tm - * representation of the time. - * - * Return value: The converted time as a struct tm. All fields will be - * set properly except for tm.tm_yday. - **/ -struct tm -icaltimetype_to_tm_with_zone (struct icaltimetype *itt, - icaltimezone *from_zone, - icaltimezone *to_zone) -{ - struct tm tm; - struct icaltimetype itt_copy; - - memset (&tm, 0, sizeof (tm)); - tm.tm_isdst = -1; - - g_return_val_if_fail (itt != NULL, tm); - - itt_copy = *itt; - - icaltimezone_convert_time (&itt_copy, from_zone, to_zone); - tm = icaltimetype_to_tm (&itt_copy); - - return tm; -} - -struct icaltimetype -tm_to_icaltimetype (struct tm *tm, gboolean is_date) -{ - struct icaltimetype itt; - - memset (&itt, 0, sizeof (struct icaltimetype)); - - if (!is_date) { - itt.second = tm->tm_sec; - itt.minute = tm->tm_min; - itt.hour = tm->tm_hour; - } - - itt.day = tm->tm_mday; - itt.month = tm->tm_mon + 1; - itt.year = tm->tm_year+ 1900; - - itt.is_utc = 0; - itt.is_date = is_date; - - return itt; -} - diff --git a/calendar/cal-util/timeutil.h b/calendar/cal-util/timeutil.h deleted file mode 100644 index 77a8f180e1..0000000000 --- a/calendar/cal-util/timeutil.h +++ /dev/null @@ -1,122 +0,0 @@ -/* Miscellaneous time-related utilities - * - * Copyright (C) 1998 The Free Software Foundation - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Federico Mena <federico@ximian.com> - * Miguel de Icaza <miguel@ximian.com> - * Damon Chaplin <damon@ximian.com> - */ - -#ifndef TIMEUTIL_H -#define TIMEUTIL_H - - -#include <time.h> -#include <ical.h> -#include <glib.h> - - -/************************************************************************** - * General time functions. - **************************************************************************/ - -/* Returns the number of days in the month. Year is the normal year, e.g. 2001. - Month is 0 (Jan) to 11 (Dec). */ -int time_days_in_month (int year, int month); - -/* Returns the 1-based day number within the year of the specified date. - Year is the normal year, e.g. 2001. Month is 0 to 11. */ -int time_day_of_year (int day, int month, int year); - -/* Returns the day of the week for the specified date, 0 (Sun) to 6 (Sat). - For the days that were removed on the Gregorian reformation, it returns - Thursday. Year is the normal year, e.g. 2001. Month is 0 to 11. */ -int time_day_of_week (int day, int month, int year); - -/* Returns whether the specified year is a leap year. Year is the normal year, - e.g. 2001. */ -gboolean time_is_leap_year (int year); - -/* Returns the number of leap years since year 1 up to (but not including) the - specified year. Year is the normal year, e.g. 2001. */ -int time_leap_years_up_to (int year); - -/* Convert to or from an ISO 8601 representation of a time, in UTC, - e.g. "20010708T183000Z". */ -char *isodate_from_time_t (time_t t); -time_t time_from_isodate (const char *str); - - -/************************************************************************** - * time_t manipulation functions. - * - * NOTE: these use the Unix timezone functions like mktime() and localtime() - * and so should not be used in Evolution. New Evolution code should use - * icaltimetype values rather than time_t values wherever possible. - **************************************************************************/ - -/* Add or subtract a number of days, weeks or months. */ -time_t time_add_day (time_t time, int days); -time_t time_add_week (time_t time, int weeks); - -/* Returns the beginning or end of the day. */ -time_t time_day_begin (time_t t); -time_t time_day_end (time_t t); - - -/************************************************************************** - * time_t manipulation functions, using timezones in libical. - * - * NOTE: these are only here to make the transition to the timezone - * functions easier. New code should use icaltimetype values rather than - * time_t values wherever possible. - **************************************************************************/ - -/* Adds or subtracts a number of days to/from the given time_t value, using - the given timezone. */ -time_t time_add_day_with_zone (time_t time, int days, icaltimezone *zone); - -/* Adds or subtracts a number of weeks to/from the given time_t value, using - the given timezone. */ -time_t time_add_week_with_zone (time_t time, int weeks, icaltimezone *zone); - -/* Adds or subtracts a number of months to/from the given time_t value, using - the given timezone. */ -time_t time_add_month_with_zone (time_t time, int months, icaltimezone *zone); - -/* Returns the start of the year containing the given time_t, using the given - timezone. */ -time_t time_year_begin_with_zone (time_t time, icaltimezone *zone); - -/* Returns the start of the month containing the given time_t, using the given - timezone. */ -time_t time_month_begin_with_zone (time_t time, icaltimezone *zone); - -/* Returns the start of the week containing the given time_t, using the given - timezone. week_start_day should use the same values as mktime(), - i.e. 0 (Sun) to 6 (Sat). */ -time_t time_week_begin_with_zone (time_t time, int week_start_day, - icaltimezone *zone); - -/* Returns the start of the day containing the given time_t, using the given - timezone. */ -time_t time_day_begin_with_zone (time_t time, icaltimezone *zone); - -/* Returns the end of the day containing the given time_t, using the given - timezone. (The end of the day is the start of the next day.) */ -time_t time_day_end_with_zone (time_t time, icaltimezone *zone); - -void time_to_gdate_with_zone (GDate *date, time_t time, icaltimezone *zone); - -/************************************************************************** - * struct tm manipulation - **************************************************************************/ - -struct tm icaltimetype_to_tm (struct icaltimetype *itt); -struct tm icaltimetype_to_tm_with_zone (struct icaltimetype *itt, - icaltimezone *from_zone, - icaltimezone *to_zone); -struct icaltimetype tm_to_icaltimetype (struct tm *tm, gboolean is_date); - -#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 d92667bb04..0000000000 --- a/calendar/conduits/calendar/Makefile.am +++ /dev/null @@ -1,41 +0,0 @@ -INCLUDES = \ - -I$(top_srcdir) \ - -I$(top_srcdir)/calendar \ - -I$(top_builddir)/calendar/cal-client \ - -I$(top_srcdir)/libical/src/libical \ - -I$(top_builddir)/libical/src/libical \ - -I$(top_srcdir)/e-util \ - -I$(top_builddir)/e-util \ - $(EVOLUTION_CALENDAR_CONDUIT_CFLAGS) - -# Calendar Conduit -e_calendar_conduitsdir=$(libdir)/gnome-pilot/conduits -e_calendar_conduits_LTLIBRARIES = libecalendar_conduit.la - -libecalendar_conduit_la_SOURCES = \ - calendar-conduit.c - -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.a \ - $(top_builddir)/libical/src/libical/libical-static.la \ - $(top_builddir)/libwombat/libwombat-static.la \ - $(top_builddir)/e-util/libeconduit-static.la \ - $(EVOLUTION_CALENDAR_CONDUIT_LIBS) - -e-calendar.conduit: e-calendar.conduit.in Makefile - sed -e 's^\@prefix\@^$(prefix)^g' \ - -e 's^\@datadir\@^$(datadir)^g' \ - < $(srcdir)/e-calendar.conduit.in > e-calendar.conduit.tmp \ - && mv e-calendar.conduit.tmp e-calendar.conduit - -Conduitdir = $(datadir)/gnome-pilot/conduits/ -Conduit_DATA = e-calendar.conduit - -EXTRA_DIST = \ - e-calendar.conduit.in - -install-data-local: - $(mkinstalldirs) $(Conduitdir) diff --git a/calendar/conduits/calendar/calendar-conduit.c b/calendar/conduits/calendar/calendar-conduit.c deleted file mode 100644 index f86e753232..0000000000 --- a/calendar/conduits/calendar/calendar-conduit.c +++ /dev/null @@ -1,1778 +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 Ximian, Inc. - * - * Authors: Eskil Heyn Olsen <deity@eskil.dk> - * JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#include <config.h> - -#include <bonobo.h> -#include <bonobo-conf/bonobo-config-database.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-dlp.h> -#include <pi-datebook.h> -#include <gpilotd/gnome-pilot-conduit.h> -#include <gpilotd/gnome-pilot-conduit-sync-abs.h> -#include <libgpilotdCM/gnome-pilot-conduit-management.h> -#include <libgpilotdCM/gnome-pilot-conduit-config.h> -#include <e-pilot-map.h> -#include <e-pilot-settings.h> -#include <e-pilot-util.h> - -GnomePilotConduit * conduit_get_gpilot_conduit (guint32); -void conduit_destroy_gpilot_conduit (GnomePilotConduit*); - -#define CONDUIT_VERSION "0.1.6" -#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) - -#define PILOT_MAX_ADVANCE 99 - -typedef struct _ECalLocalRecord ECalLocalRecord; -typedef struct _ECalConduitCfg ECalConduitCfg; -typedef struct _ECalConduitContext ECalConduitContext; - -/* Local Record */ -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 appointment structure */ - struct Appointment *appt; -}; - -static void -calconduit_destroy_record (ECalLocalRecord *local) -{ - gtk_object_unref (GTK_OBJECT (local->comp)); - free_Appointment (local->appt); - g_free (local->appt); - g_free (local); -} - -/* Configuration */ -struct _ECalConduitCfg { - guint32 pilot_id; - GnomePilotConduitSyncType sync_type; - - gboolean secret; - gchar *last_uri; -}; - -static ECalConduitCfg * -calconduit_load_configuration (guint32 pilot_id) -{ - ECalConduitCfg *c; - GnomePilotConduitManagement *management; - GnomePilotConduitConfig *config; - gchar prefix[256]; - - c = g_new0 (ECalConduitCfg, 1); - g_assert (c != NULL); - - /* Pilot ID */ - c->pilot_id = pilot_id; - - /* Sync Type */ - management = gnome_pilot_conduit_management_new ("e_calendar_conduit", GNOME_PILOT_CONDUIT_MGMT_ID); - config = gnome_pilot_conduit_config_new (management, pilot_id); - if (!gnome_pilot_conduit_config_is_enabled (config, &c->sync_type)) - c->sync_type = GnomePilotConduitSyncTypeNotSet; - gtk_object_unref (GTK_OBJECT (config)); - gtk_object_unref (GTK_OBJECT (management)); - - /* Custom settings */ - g_snprintf (prefix, 255, "/gnome-pilot.d/e-calendar-conduit/Pilot_%u/", pilot_id); - gnome_config_push_prefix (prefix); - - c->secret = gnome_config_get_bool ("secret=FALSE"); - c->last_uri = gnome_config_get_string ("last_uri"); - - gnome_config_pop_prefix (); - - return c; -} - -static void -calconduit_save_configuration (ECalConduitCfg *c) -{ - gchar prefix[256]; - - g_snprintf (prefix, 255, "/gnome-pilot.d/e-calendar-conduit/Pilot_%u/", c->pilot_id); - gnome_config_push_prefix (prefix); - - gnome_config_set_bool ("secret", c->secret); - gnome_config_set_string ("last_uri", c->last_uri); - - gnome_config_pop_prefix (); - - gnome_config_sync (); - gnome_config_drop_all (); -} - -static ECalConduitCfg* -calconduit_dupe_configuration (ECalConduitCfg *c) -{ - ECalConduitCfg *retval; - - g_return_val_if_fail (c != NULL, NULL); - - retval = g_new0 (ECalConduitCfg, 1); - retval->pilot_id = c->pilot_id; - retval->sync_type = c->sync_type; - retval->secret = c->secret; - retval->last_uri = g_strdup (c->last_uri); - - return retval; -} - -static void -calconduit_destroy_configuration (ECalConduitCfg *c) -{ - g_return_if_fail (c != NULL); - - g_free (c->last_uri); - g_free (c); -} - -/* Context */ -struct _ECalConduitContext { - ECalConduitCfg *cfg; - GnomePilotDBInfo *dbi; - - ECalConduitCfg *new_cfg; - GtkWidget *ps; - - struct AppointmentAppInfo ai; - - CalClient *client; - - icaltimezone *timezone; - GList *uids; - GList *changed; - GHashTable *changed_hash; - GList *locals; - - EPilotMap *map; -}; - -static ECalConduitContext * -e_calendar_context_new (guint32 pilot_id) -{ - ECalConduitContext *ctxt; - - ctxt = g_new0 (ECalConduitContext, 1); - g_assert (ctxt != NULL); - - ctxt->cfg = calconduit_load_configuration (pilot_id); - ctxt->new_cfg = calconduit_dupe_configuration (ctxt->cfg); - ctxt->ps = NULL; - ctxt->dbi = NULL; - ctxt->client = NULL; - ctxt->timezone = NULL; - ctxt->uids = NULL; - ctxt->changed = NULL; - ctxt->changed_hash = NULL; - ctxt->locals = NULL; - ctxt->map = NULL; - - return ctxt; -} - -static gboolean -e_calendar_context_foreach_change (gpointer key, gpointer value, gpointer data) -{ - g_free (key); - - return TRUE; -} - -static void -e_calendar_context_destroy (ECalConduitContext *ctxt) -{ - GList *l; - - 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->uids != NULL) - cal_obj_uid_list_free (ctxt->uids); - - if (ctxt->changed != NULL) - cal_client_change_list_free (ctxt->changed); - - if (ctxt->changed_hash != NULL) { - g_hash_table_foreach_remove (ctxt->changed_hash, e_calendar_context_foreach_change, NULL); - g_hash_table_destroy (ctxt->changed_hash); - } - - if (ctxt->locals != NULL) { - for (l = ctxt->locals; l != NULL; l = l->next) - calconduit_destroy_record (l->data); - g_list_free (ctxt->locals); - } - - if (ctxt->map != NULL) - e_pilot_map_destroy (ctxt->map); -} - -/* 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 : ""); - - free_Appointment (&appt); - - return buff; -} - -/* Calendar Server routines */ -static void -start_calendar_server_cb (CalClient *cal_client, - CalClientOpenStatus status, - gpointer data) -{ - gboolean *success = data; - - if (status == CAL_CLIENT_OPEN_SUCCESS) { - *success = TRUE; - } else { - *success = FALSE; - WARN ("Failed to open calendar!\n"); - } - - gtk_main_quit (); /* end the sub event loop */ -} - -static int -start_calendar_server (ECalConduitContext *ctxt) -{ - gboolean success = FALSE; - - g_return_val_if_fail (ctxt != NULL, -2); - - ctxt->client = cal_client_new (); - - gtk_signal_connect (GTK_OBJECT (ctxt->client), "cal_opened", - start_calendar_server_cb, &success); - - if (!cal_client_open_default_calendar (ctxt->client, FALSE)) - return -1; - - /* run a sub event loop to turn cal-client's async load - notification into a synchronous call */ - gtk_main (); - - if (success) - return 0; - - return -1; -} - -/* Utility routines */ -static icaltimezone * -get_timezone (CalClient *client, const char *tzid) -{ - icaltimezone *timezone = NULL; - - timezone = icaltimezone_get_builtin_timezone_from_tzid (tzid); - if (timezone == NULL) - cal_client_get_timezone (client, tzid, &timezone); - - return timezone; -} - -static icaltimezone * -get_default_timezone (void) -{ - Bonobo_ConfigDatabase db; - icaltimezone *timezone = NULL; - char *location; - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - db = bonobo_get_object ("wombat:", "Bonobo/ConfigDatabase", &ev); - - if (BONOBO_EX (&ev) || db == CORBA_OBJECT_NIL) { - CORBA_exception_free (&ev); - return NULL; - } - - CORBA_exception_free (&ev); - - location = bonobo_config_get_string_with_default (db, - "/Calendar/Display/Timezone", "UTC", NULL); - if (!location || !location[0]) { - g_free (location); - location = g_strdup ("UTC"); - } - - timezone = icaltimezone_get_builtin_timezone (location); - g_free (location); - - bonobo_object_release_unref (db, NULL); - - return timezone; -} - - -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 gboolean -is_all_day (CalClient *client, CalComponentDateTime *dt_start, CalComponentDateTime *dt_end) -{ - time_t dt_start_time, dt_end_time; - icaltimezone *timezone; - - if (dt_start->value->is_date && dt_end->value->is_date) - return TRUE; - - timezone = get_timezone (client, dt_start->tzid); - dt_start_time = icaltime_as_timet_with_zone (*dt_start->value, timezone); - dt_end_time = icaltime_as_timet_with_zone (*dt_end->value, get_timezone (client, dt_end->tzid)); - - if (dt_end_time == time_add_day_with_zone (dt_start_time, 1, timezone)) - return TRUE; - - return FALSE; -} - -static gboolean -process_multi_day (ECalConduitContext *ctxt, CalClientChange *ccc, GList **multi_uid, GList **multi_ccc) -{ - CalComponentDateTime dt_start, dt_end; - icaltimezone *tz_start, *tz_end; - time_t event_start, event_end, day_end; - struct icaltimetype *old_start_value, *old_end_value; - const char *uid; - gboolean last = FALSE; - gboolean ret = TRUE; - - *multi_ccc = NULL; - *multi_uid = NULL; - - if (ccc->type == CAL_CLIENT_CHANGE_DELETED) - return FALSE; - - /* Start time */ - cal_component_get_dtstart (ccc->comp, &dt_start); - if (dt_start.value->is_date) - tz_start = ctxt->timezone; - else - tz_start = get_timezone (ctxt->client, dt_start.tzid); - event_start = icaltime_as_timet_with_zone (*dt_start.value, tz_start); - - cal_component_get_dtend (ccc->comp, &dt_end); - if (dt_end.value->is_date) - tz_end = ctxt->timezone; - else - tz_end = get_timezone (ctxt->client, dt_end.tzid); - event_end = icaltime_as_timet_with_zone (*dt_end.value, tz_end); - - day_end = time_day_end_with_zone (event_start, ctxt->timezone); - if (day_end >= event_end) { - ret = FALSE; - goto cleanup; - } else if (cal_component_has_recurrences (ccc->comp)) { - ret = TRUE; - goto cleanup; - } - - old_start_value = dt_start.value; - old_end_value = dt_end.value; - while (!last) { - CalComponent *clone = cal_component_clone (ccc->comp); - char *new_uid = cal_component_gen_uid (); - struct icaltimetype start_value, end_value; - CalClientChange *c = g_new0 (CalClientChange, 1); - - if (day_end >= event_end) { - day_end = event_end; - last = TRUE; - } - - cal_component_set_uid (clone, new_uid); - - start_value = icaltime_from_timet_with_zone (event_start, FALSE, tz_start); - dt_start.value = &start_value; - cal_component_set_dtstart (clone, &dt_start); - - end_value = icaltime_from_timet_with_zone (day_end, FALSE, tz_end); - dt_end.value = &end_value; - cal_component_set_dtend (clone, &dt_end); - - cal_client_update_object (ctxt->client, clone); - - c->comp = clone; - c->type = CAL_CLIENT_CHANGE_ADDED; - - *multi_ccc = g_list_prepend (*multi_ccc, c); - *multi_uid = g_list_prepend (*multi_uid, new_uid); - - event_start = day_end; - day_end = time_day_end_with_zone (event_start, ctxt->timezone); - } - dt_start.value = old_start_value; - dt_end.value = old_end_value; - - cal_component_get_uid (ccc->comp, &uid); - cal_client_remove_object (ctxt->client, uid); - ccc->type = CAL_CLIENT_CHANGE_DELETED; - - cleanup: - cal_component_free_datetime (&dt_start); - cal_component_free_datetime (&dt_end); - - return ret; -} - -static short -nth_weekday (int pos, icalrecurrencetype_weekday weekday) -{ - g_assert ((pos > 0 && pos <= 5) || (pos == -1)); - - return ((abs (pos) * 8) + weekday) * (pos < 0 ? -1 : 1); -} - -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; - static char record[0xffff]; - - g_assert (local->comp != NULL); - g_assert (local->appt != NULL ); - - p.ID = local->local.ID; - p.category = local->local.category; - p.attr = local->local.attr; - p.archived = local->local.archived; - p.secret = local->local.secret; - - /* Generate pilot record structure */ - p.record = record; - 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, *edl = NULL, *l; - CalComponentText *description; - CalComponentDateTime dt_start, dt_end; - CalComponentClassification classif; - icaltimezone *default_tz = ctxt->timezone; - 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, TRUE); - compute_status (ctxt, local, uid); - - local->appt = g_new0 (struct Appointment, 1); - - /* Handle the fields and category we don't sync by making sure - * we don't overwrite them - */ - if (local->local.ID != 0) { - struct Appointment appt; - char record[0xffff]; - int cat = 0; - - if (dlp_ReadRecordById (ctxt->dbi->pilot_socket, - ctxt->dbi->db_handle, - local->local.ID, &record, - NULL, NULL, NULL, &cat) > 0) { - local->local.category = cat; - memset (&appt, 0, sizeof (struct Appointment)); - unpack_Appointment (&appt, record, 0xffff); - local->appt->alarm = appt.alarm; - local->appt->advance = appt.advance; - local->appt->advanceUnits = appt.advanceUnits; - free_Appointment (&appt); - } - } - - /* 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; - } - - /* Start/End */ - cal_component_get_dtstart (comp, &dt_start); - cal_component_get_dtend (comp, &dt_end); - if (dt_start.value) { - icaltimezone_convert_time (dt_start.value, - get_timezone (ctxt->client, dt_start.tzid), - default_tz); - local->appt->begin = icaltimetype_to_tm (dt_start.value); - } - - if (dt_start.value && dt_end.value) { - if (is_all_day (ctxt->client, &dt_start, &dt_end)) { - local->appt->event = 1; - } else { - icaltimezone_convert_time (dt_end.value, - get_timezone (ctxt->client, dt_end.tzid), - default_tz); - local->appt->end = icaltimetype_to_tm (dt_end.value); - local->appt->event = 0; - } - } else { - local->appt->event = 1; - } - cal_component_free_datetime (&dt_start); - cal_component_free_datetime (&dt_end); - - /* 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; - icaltimezone_convert_time (&recur->until, - icaltimezone_get_utc_timezone (), - default_tz); - local->appt->repeatEnd = icaltimetype_to_tm (&recur->until); - } - - cal_component_free_recur_list (list); - } - - /* Exceptions */ - cal_component_get_exdate_list (comp, &edl); - local->appt->exceptions = g_slist_length (edl); - local->appt->exception = g_new0 (struct tm, local->appt->exceptions); - for (l = edl, i = 0; l != NULL; l = l->next, i++) { - CalComponentDateTime *dt = l->data; - - icaltimezone_convert_time (dt->value, - icaltimezone_get_utc_timezone (), - default_tz); - *local->appt->exception = icaltimetype_to_tm (dt->value); - } - cal_component_free_exdate_list (edl); - - /* Alarm */ - local->appt->alarm = 0; - if (cal_component_has_alarms (comp)) { - GList *uids, *l; - CalComponentAlarm *alarm; - CalAlarmTrigger trigger; - - uids = cal_component_get_alarm_uids (comp); - for (l = uids; l != NULL; l = l->next) { - alarm = cal_component_get_alarm (comp, l->data); - cal_component_alarm_get_trigger (alarm, &trigger); - - if ((trigger.type == CAL_ALARM_TRIGGER_RELATIVE_START - && trigger.u.rel_duration.is_neg)) { - local->appt->advanceUnits = advMinutes; - local->appt->advance = - trigger.u.rel_duration.minutes - + trigger.u.rel_duration.hours * 60 - + trigger.u.rel_duration.days * 60 * 24 - + trigger.u.rel_duration.weeks * 7 * 60 * 24; - - if (local->appt->advance > PILOT_MAX_ADVANCE) { - local->appt->advanceUnits = advHours; - local->appt->advance = - trigger.u.rel_duration.minutes / 60 - + trigger.u.rel_duration.hours - + trigger.u.rel_duration.days * 24 - + trigger.u.rel_duration.weeks * 7 * 24; - } - if (local->appt->advance > PILOT_MAX_ADVANCE) { - local->appt->advanceUnits = advDays; - local->appt->advance = - trigger.u.rel_duration.minutes / (60 * 24) - + trigger.u.rel_duration.hours / 24 - + trigger.u.rel_duration.days - + trigger.u.rel_duration.weeks * 7; - } - if (local->appt->advance > PILOT_MAX_ADVANCE) - local->appt->advance = PILOT_MAX_ADVANCE; - - local->appt->alarm = 1; - break; - } - cal_component_alarm_free (alarm); - } - cal_obj_uid_list_free (uids); - } - - 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); - gtk_object_unref (GTK_OBJECT (comp)); - } 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); - gtk_object_unref (GTK_OBJECT (comp)); - } else { - INFO ("Object did not exist"); - } -} - -static CalComponent * -comp_from_remote_record (GnomePilotConduitSyncAbs *conduit, - GnomePilotRecord *remote, - CalComponent *in_comp, - icaltimezone *timezone) -{ - CalComponent *comp; - struct Appointment appt; - struct icaltimetype now = icaltime_from_timet_with_zone (time (NULL), FALSE, timezone), it; - struct icalrecurrencetype recur; - CalComponentText summary = {NULL, NULL}; - CalComponentDateTime dt = {NULL, icaltimezone_get_tzid (timezone)}; - GSList *edl = NULL; - char *txt; - int pos, i; - - 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_description_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 = tm_to_icaltimetype (&appt.begin, FALSE); - dt.value = ⁢ - cal_component_set_dtstart (comp, &dt); - } - - if (appt.event) { - it = tm_to_icaltimetype (&appt.begin, FALSE); - icaltime_adjust (&it, 1, 0, 0, 0); - dt.value = ⁢ - cal_component_set_dtend (comp, &dt); - } else if (!is_empty_time (appt.end)) { - it = tm_to_icaltimetype (&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; - if (appt.repeatDay < domLastSun) - recur.by_day[0] = nth_weekday ((appt.repeatDay / 7) + 1, - get_ical_day (appt.repeatDay % 7)); - else - recur.by_day[0] = nth_weekday (-1, get_ical_day (appt.repeatDay % 7)); - 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) { - recur.until = tm_to_icaltimetype (&appt.repeatEnd, TRUE); - } - - 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); - } - - /* Exceptions */ - for (i = 0; i < appt.exceptions; i++) { - struct tm ex; - CalComponentDateTime *dt = g_new0 (CalComponentDateTime, 1); - - dt->value = g_new0 (struct icaltimetype, 1); - dt->tzid = NULL; - - ex = appt.exception[i]; - *dt->value = tm_to_icaltimetype (&ex, TRUE); - - edl = g_slist_prepend (edl, dt); - } - cal_component_set_exdate_list (comp, edl); - cal_component_free_exdate_list (edl); - - /* Alarm */ - if (appt.alarm) { - CalComponentAlarm *alarm = NULL; - CalAlarmTrigger trigger; - gboolean found = FALSE; - - if (cal_component_has_alarms (comp)) { - GList *uids, *l; - - uids = cal_component_get_alarm_uids (comp); - for (l = uids; l != NULL; l = l->next) { - alarm = cal_component_get_alarm (comp, l->data); - cal_component_alarm_get_trigger (alarm, &trigger); - if ((trigger.type == CAL_ALARM_TRIGGER_RELATIVE_START - && trigger.u.rel_duration.is_neg)) { - found = TRUE; - break; - } - cal_component_alarm_free (alarm); - } - cal_obj_uid_list_free (uids); - } - if (!found) - alarm = cal_component_alarm_new (); - - memset (&trigger, 0, sizeof (CalAlarmTrigger)); - trigger.type = CAL_ALARM_TRIGGER_RELATIVE_START; - trigger.u.rel_duration.is_neg = 1; - switch (appt.advanceUnits) { - case advMinutes: - trigger.u.rel_duration.minutes = appt.advance; - break; - case advHours: - trigger.u.rel_duration.hours = appt.advance; - break; - case advDays: - trigger.u.rel_duration.days = appt.advance; - break; - } - cal_component_alarm_set_trigger (alarm, trigger); - cal_component_alarm_set_action (alarm, CAL_ALARM_DISPLAY); - - if (!found) - cal_component_add_alarm (comp, alarm); - cal_component_alarm_free (alarm); - } - - 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) -{ - GnomePilotConduitStandard *conduit = GNOME_PILOT_CONDUIT_STANDARD (c); - int map_count; - const char *uri; - - /* If there are objects but no log */ - map_count = g_hash_table_size (ctxt->map->pid_map); - if (map_count == 0) - gnome_pilot_conduit_standard_set_slow (conduit, TRUE); - - /* Or if the URI's don't match */ - uri = cal_client_get_uri (ctxt->client); - LOG(" Current URI %s (%s)\n", uri, ctxt->cfg->last_uri ? ctxt->cfg->last_uri : "<NONE>"); - if (ctxt->cfg->last_uri != NULL && strcmp (ctxt->cfg->last_uri, uri)) { - gnome_pilot_conduit_standard_set_slow (conduit, TRUE); - e_pilot_map_clear (ctxt->map); - } - - if (gnome_pilot_conduit_standard_get_slow (conduit)) { - ctxt->map->write_touched_only = TRUE; - LOG (" doing slow sync\n"); - } else { - LOG (" doing fast sync\n"); - } -} - -/* Pilot syncing callbacks */ -static gint -pre_sync (GnomePilotConduit *conduit, - GnomePilotDBInfo *dbi, - ECalConduitContext *ctxt) -{ - GnomePilotConduitSyncAbs *abs_conduit; - GList *removed = NULL, *added = NULL, *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); - - ctxt->dbi = dbi; - 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; - } - - /* Get the timezone */ - ctxt->timezone = get_default_timezone (); - if (ctxt->timezone == NULL) - return -1; - LOG (" Using timezone: %s", icaltimezone_get_tzid (ctxt->timezone)); - - /* Set the default timezone on the backend. */ - if (ctxt->timezone) - cal_client_set_default_timezone (ctxt->client, ctxt->timezone); - - /* 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); - g_free (change_id); - - /* See if we need to split up any events */ - for (l = ctxt->changed; l != NULL; l = l->next) { - CalClientChange *ccc = l->data; - GList *multi_uid = NULL, *multi_ccc = NULL; - - if (process_multi_day (ctxt, ccc, &multi_uid, &multi_ccc)) { - ctxt->uids = g_list_concat (ctxt->uids, multi_uid); - - added = g_list_concat (added, multi_ccc); - removed = g_list_prepend (removed, ccc); - } - } - - /* Remove the events that were split up */ - g_list_concat (ctxt->changed, added); - for (l = removed; l != NULL; l = l->next) { - CalClientChange *ccc = l->data; - const char *uid; - - cal_component_get_uid (ccc->comp, &uid); - if (e_pilot_map_lookup_pid (ctxt->map, uid, FALSE) == 0) { - ctxt->changed = g_list_remove (ctxt->changed, ccc); - gtk_object_unref (GTK_OBJECT (ccc->comp)); - g_free (ccc); - } - } - g_list_free (removed); - - 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; - } - } else if (ccc->type == CAL_CLIENT_CHANGE_DELETED) { - e_pilot_map_remove_by_uid (ctxt->map, uid); - } - } - - /* Set the count information */ - num_records = cal_client_get_n_objects (ctxt->client, CALOBJ_TYPE_EVENT); - 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); - - 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); - if (ctxt->cfg->sync_type == GnomePilotConduitSyncTypeCopyToPilot - || ctxt->cfg->sync_type == GnomePilotConduitSyncTypeCopyFromPilot) - ctxt->map->write_touched_only = TRUE; - - 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); - - g_free (ctxt->cfg->last_uri); - ctxt->cfg->last_uri = g_strdup (cal_client_get_uri (ctxt->client)); - calconduit_save_configuration (ctxt->cfg); - - 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); - g_free (change_id); - - LOG ("---------------------------------------------------------\n"); - - 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); - g_list_prepend (ctxt->locals, *local); - - 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); - g_list_prepend (ctxt->locals, *local); - } 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, -1); - - if (*local == NULL) { - LOG ("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); - g_list_prepend (ctxt->locals, *local); - } 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); - g_list_prepend (ctxt->locals, *local); - } 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, ctxt->timezone); - update_comp (conduit, comp, ctxt); - - cal_component_get_uid (comp, &uid); - e_pilot_map_insert (ctxt->map, remote->ID, uid, FALSE); - - gtk_object_unref (GTK_OBJECT (comp)); - - 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, ctxt->timezone); - 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, TRUE); - - 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); - - calconduit_destroy_record (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; -} - -/* Pilot Settings Callbacks */ -static void -fill_widgets (ECalConduitContext *ctxt) -{ - e_pilot_settings_set_secret (E_PILOT_SETTINGS (ctxt->ps), - ctxt->cfg->secret); -} - -static gint -create_settings_window (GnomePilotConduit *conduit, - GtkWidget *parent, - ECalConduitContext *ctxt) -{ - LOG ("create_settings_window"); - - ctxt->ps = e_pilot_settings_new (); - gtk_container_add (GTK_CONTAINER (parent), ctxt->ps); - gtk_widget_show (ctxt->ps); - - fill_widgets (ctxt); - - return 0; -} -static void -display_settings (GnomePilotConduit *conduit, ECalConduitContext *ctxt) -{ - LOG ("display_settings"); - - fill_widgets (ctxt); -} - -static void -save_settings (GnomePilotConduit *conduit, ECalConduitContext *ctxt) -{ - LOG ("save_settings"); - - ctxt->new_cfg->secret = - e_pilot_settings_get_secret (E_PILOT_SETTINGS (ctxt->ps)); - - calconduit_save_configuration (ctxt->new_cfg); -} - -static void -revert_settings (GnomePilotConduit *conduit, ECalConduitContext *ctxt) -{ - LOG ("revert_settings"); - - calconduit_save_configuration (ctxt->cfg); - calconduit_destroy_configuration (ctxt->new_cfg); - ctxt->new_cfg = calconduit_dupe_configuration (ctxt->cfg); -} - -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); - - ctxt = e_calendar_context_new (pilot_id); - gtk_object_set_data (GTK_OBJECT (retval), "calconduit_context", ctxt); - - /* Sync signals */ - 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); - - /* Gui Settings */ - gtk_signal_connect (retval, "create_settings_window", (GtkSignalFunc) create_settings_window, ctxt); - gtk_signal_connect (retval, "display_settings", (GtkSignalFunc) display_settings, ctxt); - gtk_signal_connect (retval, "save_settings", (GtkSignalFunc) save_settings, ctxt); - gtk_signal_connect (retval, "revert_settings", (GtkSignalFunc) revert_settings, 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/e-calendar.conduit.in b/calendar/conduits/calendar/e-calendar.conduit.in deleted file mode 100644 index e75d889234..0000000000 --- a/calendar/conduits/calendar/e-calendar.conduit.in +++ /dev/null @@ -1,9 +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="valid-synctypes" value="synchronize copy_from_pilot copy_to_pilot"/> - <conduit-attribute name="settings" value="TRUE"/> - <conduit-attribute name="icon" value="@datadir@/images/evolution/conduits/48_evo-calendar-conduit.png"/> -</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 036e4f153a..0000000000 --- a/calendar/conduits/todo/Makefile.am +++ /dev/null @@ -1,41 +0,0 @@ -INCLUDES = \ - -I$(top_srcdir) \ - -I$(top_srcdir)/calendar \ - -I$(top_builddir)/calendar/cal-client \ - -I$(top_srcdir)/libical/src/libical \ - -I$(top_builddir)/libical/src/libical \ - -I$(top_srcdir)/e-util \ - -I$(top_builddir)/e-util \ - $(EVOLUTION_CALENDAR_CONDUIT_CFLAGS) - -# ToDo Conduit -e_todo_conduitsdir=$(libdir)/gnome-pilot/conduits -e_todo_conduits_LTLIBRARIES = libetodo_conduit.la - -libetodo_conduit_la_SOURCES = \ - todo-conduit.c - -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.a \ - $(top_builddir)/libical/src/libical/libical-static.la \ - $(top_builddir)/libwombat/libwombat-static.la \ - $(top_builddir)/e-util/libeconduit-static.la \ - $(EVOLUTION_CALENDAR_CONDUIT_LIBS) - -e-todo.conduit: e-todo.conduit.in Makefile - sed -e 's^\@prefix\@^$(prefix)^g' \ - -e 's^\@datadir\@^$(datadir)^g' \ - < $(srcdir)/e-todo.conduit.in > e-todo.conduit.tmp \ - && mv e-todo.conduit.tmp e-todo.conduit - -Conduitdir = $(datadir)/gnome-pilot/conduits/ -Conduit_DATA = e-todo.conduit - -EXTRA_DIST = \ - e-todo.conduit.in - -install-data-local: - $(mkinstalldirs) $(Conduitdir) diff --git a/calendar/conduits/todo/e-todo.conduit.in b/calendar/conduits/todo/e-todo.conduit.in deleted file mode 100644 index a7bea27a8f..0000000000 --- a/calendar/conduits/todo/e-todo.conduit.in +++ /dev/null @@ -1,9 +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="valid-synctypes" value="synchronize copy_from_pilot copy_to_pilot"/> - <conduit-attribute name="settings" value="TRUE"/> - <conduit-attribute name="icon" value="@datadir@/images/evolution/conduits/48_evo-todo-conduit.png"/> -</gnome-pilot-conduit> diff --git a/calendar/conduits/todo/todo-conduit.c b/calendar/conduits/todo/todo-conduit.c deleted file mode 100644 index a460bd6ebc..0000000000 --- a/calendar/conduits/todo/todo-conduit.c +++ /dev/null @@ -1,1435 +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 Ximian, Inc. - * - * Authors: Eskil Heyn Olsen <deity@eskil.dk> - * JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#include <config.h> - -#include <liboaf/liboaf.h> -#include <bonobo.h> -#include <bonobo-conf/bonobo-config-database.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-dlp.h> -#include <pi-todo.h> -#include <libical/src/libical/icaltypes.h> -#include <gpilotd/gnome-pilot-conduit.h> -#include <gpilotd/gnome-pilot-conduit-sync-abs.h> -#include <libgpilotdCM/gnome-pilot-conduit-management.h> -#include <libgpilotdCM/gnome-pilot-conduit-config.h> -#include <e-pilot-map.h> -#include <e-pilot-settings.h> -#include <e-pilot-util.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_TODOCONDUIT 1 -/* #undef DEBUG_TODOCONDUIT */ - -#ifdef DEBUG_TODOCONDUIT -#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) - -typedef struct _EToDoLocalRecord EToDoLocalRecord; -typedef struct _EToDoConduitCfg EToDoConduitCfg; -typedef struct _EToDoConduitGui EToDoConduitGui; -typedef struct _EToDoConduitContext EToDoConduitContext; - -/* Local Record */ -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; -}; - -static void -todoconduit_destroy_record (EToDoLocalRecord *local) -{ - gtk_object_unref (GTK_OBJECT (local->comp)); - free_ToDo (local->todo); - g_free (local->todo); - g_free (local); -} - -/* Configuration */ -struct _EToDoConduitCfg { - guint32 pilot_id; - GnomePilotConduitSyncType sync_type; - - gboolean secret; - gint priority; - - gchar *last_uri; -}; - -static EToDoConduitCfg * -todoconduit_load_configuration (guint32 pilot_id) -{ - EToDoConduitCfg *c; - GnomePilotConduitManagement *management; - GnomePilotConduitConfig *config; - 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); - - c->pilot_id = pilot_id; - - management = gnome_pilot_conduit_management_new ("e_todo_conduit", GNOME_PILOT_CONDUIT_MGMT_ID); - config = gnome_pilot_conduit_config_new (management, pilot_id); - if (!gnome_pilot_conduit_config_is_enabled (config, &c->sync_type)) - c->sync_type = GnomePilotConduitSyncTypeNotSet; - gtk_object_unref (GTK_OBJECT (config)); - gtk_object_unref (GTK_OBJECT (management)); - - /* Custom settings */ - gnome_config_push_prefix (prefix); - - c->secret = gnome_config_get_bool ("secret=FALSE"); - c->priority = gnome_config_get_int ("priority=3"); - c->last_uri = gnome_config_get_string ("last_uri"); - - gnome_config_pop_prefix (); - - return c; -} - -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 ("secret", c->secret); - gnome_config_set_int ("priority", c->priority); - gnome_config_set_string ("last_uri", c->last_uri); - gnome_config_pop_prefix (); - - gnome_config_sync (); - gnome_config_drop_all (); -} - -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->pilot_id = c->pilot_id; - - retval->secret = c->secret; - retval->priority = c->priority; - retval->last_uri = g_strdup (c->last_uri); - - return retval; -} - -static void -todoconduit_destroy_configuration (EToDoConduitCfg *c) -{ - g_return_if_fail (c != NULL); - - g_free (c->last_uri); - g_free (c); -} - -/* Gui */ -struct _EToDoConduitGui { - GtkWidget *priority; -}; - -static EToDoConduitGui * -e_todo_gui_new (EPilotSettings *ps) -{ - EToDoConduitGui *gui; - GtkWidget *lbl; - GtkObject *adj; - gint rows; - - g_return_val_if_fail (ps != NULL, NULL); - g_return_val_if_fail (E_IS_PILOT_SETTINGS (ps), NULL); - - gtk_table_resize (GTK_TABLE (ps), E_PILOT_SETTINGS_TABLE_ROWS + 1, E_PILOT_SETTINGS_TABLE_COLS); - - gui = g_new0 (EToDoConduitGui, 1); - - rows = E_PILOT_SETTINGS_TABLE_ROWS; - lbl = gtk_label_new (_("Default Priority:")); - gtk_misc_set_alignment (GTK_MISC (lbl), 0.0, 0.5); - adj = gtk_adjustment_new (1, 1, 5, 1, 5, 5); - gui->priority = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 1.0, 0); - gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (gui->priority), TRUE); - gtk_table_attach_defaults (GTK_TABLE (ps), lbl, 0, 1, rows, rows + 1); - gtk_table_attach_defaults (GTK_TABLE (ps), gui->priority, 1, 2, rows, rows + 1); - gtk_widget_show (lbl); - gtk_widget_show (gui->priority); - - return gui; -} - -static void -e_todo_gui_fill_widgets (EToDoConduitGui *gui, EToDoConduitCfg *cfg) -{ - g_return_if_fail (gui != NULL); - g_return_if_fail (cfg != NULL); - - gtk_spin_button_set_value (GTK_SPIN_BUTTON (gui->priority), cfg->priority); -} - -static void -e_todo_gui_fill_config (EToDoConduitGui *gui, EToDoConduitCfg *cfg) -{ - g_return_if_fail (gui != NULL); - g_return_if_fail (cfg != NULL); - - cfg->priority = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (gui->priority)); -} - -static void -e_todo_gui_destroy (EToDoConduitGui *gui) -{ - g_free (gui); -} - -/* Context */ -struct _EToDoConduitContext { - GnomePilotDBInfo *dbi; - - EToDoConduitCfg *cfg; - EToDoConduitCfg *new_cfg; - EToDoConduitGui *gui; - GtkWidget *ps; - - struct ToDoAppInfo ai; - - CalClient *client; - - icaltimezone *timezone; - GList *uids; - GList *changed; - GHashTable *changed_hash; - GList *locals; - - EPilotMap *map; -}; - -static EToDoConduitContext * -e_todo_context_new (guint32 pilot_id) -{ - EToDoConduitContext *ctxt = g_new0 (EToDoConduitContext, 1); - - ctxt->cfg = todoconduit_load_configuration (pilot_id); - ctxt->new_cfg = todoconduit_dupe_configuration (ctxt->cfg); - ctxt->gui = NULL; - ctxt->ps = NULL; - ctxt->client = NULL; - ctxt->uids = NULL; - ctxt->changed_hash = NULL; - ctxt->changed = NULL; - ctxt->locals = NULL; - ctxt->map = NULL; - - return ctxt; -} - -static gboolean -e_todo_context_foreach_change (gpointer key, gpointer value, gpointer data) -{ - g_free (key); - - return TRUE; -} - -static void -e_todo_context_destroy (EToDoConduitContext *ctxt) -{ - GList *l; - - g_return_if_fail (ctxt != NULL); - - if (ctxt->cfg != NULL) - todoconduit_destroy_configuration (ctxt->cfg); - if (ctxt->new_cfg != NULL) - todoconduit_destroy_configuration (ctxt->new_cfg); - if (ctxt->gui != NULL) - e_todo_gui_destroy (ctxt->gui); - - if (ctxt->client != NULL) - gtk_object_unref (GTK_OBJECT (ctxt->client)); - - if (ctxt->uids != NULL) - cal_obj_uid_list_free (ctxt->uids); - - if (ctxt->changed_hash != NULL) { - g_hash_table_foreach_remove (ctxt->changed_hash, e_todo_context_foreach_change, NULL); - g_hash_table_destroy (ctxt->changed_hash); - } - - if (ctxt->locals != NULL) { - for (l = ctxt->locals; l != NULL; l = l->next) - todoconduit_destroy_record (l->data); - g_list_free (ctxt->locals); - } - - if (ctxt->changed != NULL) - cal_client_change_list_free (ctxt->changed); - - if (ctxt->map != NULL) - e_pilot_map_destroy (ctxt->map); - - g_free (ctxt); -} - -/* 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 : ""); - - free_ToDo (&todo); - - return buff; -} - - -/* Calendar Server routines */ -static void -start_calendar_server_cb (CalClient *cal_client, - CalClientOpenStatus status, - gpointer data) -{ - gboolean *success = data; - - if (status == CAL_CLIENT_OPEN_SUCCESS) { - *success = TRUE; - } else { - *success = FALSE; - WARN ("Failed to open calendar!\n"); - } - - gtk_main_quit (); /* end the sub event loop */ -} - -static int -start_calendar_server (EToDoConduitContext *ctxt) -{ - gboolean success = FALSE; - - g_return_val_if_fail (ctxt != NULL, -2); - - ctxt->client = cal_client_new (); - - gtk_signal_connect (GTK_OBJECT (ctxt->client), "cal_opened", - start_calendar_server_cb, &success); - - if (!cal_client_open_default_tasks (ctxt->client, FALSE)) - return -1; - - /* run a sub event loop to turn cal-client's async load - notification into a synchronous call */ - gtk_main (); - - if (success) - return 0; - - return -1; -} - -/* Utility routines */ -static icaltimezone * -get_timezone (CalClient *client, const char *tzid) -{ - icaltimezone *timezone = NULL; - - timezone = icaltimezone_get_builtin_timezone_from_tzid (tzid); - if (timezone == NULL) - cal_client_get_timezone (client, tzid, &timezone); - - return timezone; -} - -static icaltimezone * -get_default_timezone (void) -{ - Bonobo_ConfigDatabase db; - icaltimezone *timezone = NULL; - char *location; - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - db = bonobo_get_object ("wombat:", "Bonobo/ConfigDatabase", &ev); - - if (BONOBO_EX (&ev) || db == CORBA_OBJECT_NIL) { - CORBA_exception_free (&ev); - return NULL; - } - - CORBA_exception_free (&ev); - - location = bonobo_config_get_string_with_default (db, - "/Calendar/Display/Timezone", "UTC", NULL); - if (!location || !location[0]) { - g_free (location); - location = g_strdup ("UTC"); - } - - timezone = icaltimezone_get_builtin_timezone (location); - g_free (location); - - bonobo_object_release_unref (db, NULL); - - return timezone; -} - -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; - static char record[0xffff]; - - g_assert (local->comp != NULL); - g_assert (local->todo != NULL ); - - LOG ("local_record_to_pilot_record\n"); - - p.ID = local->local.ID; - p.category = local->local.category; - p.attr = local->local.attr; - p.archived = local->local.archived; - p.secret = local->local.secret; - - /* Generate pilot record structure */ - p.record = record; - 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; - icalproperty_status status; - CalComponentText summary; - GSList *d_list = NULL; - CalComponentText *description; - CalComponentDateTime due; - CalComponentClassification classif; - icaltimezone *default_tz = get_default_timezone (); - - 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, TRUE); - - compute_status (ctxt, local, uid); - - local->todo = g_new0 (struct ToDo,1); - - /* Don't overwrite the category */ - if (local->local.ID != 0) { - char record[0xffff]; - int cat = 0; - - if (dlp_ReadRecordById (ctxt->dbi->pilot_socket, - ctxt->dbi->db_handle, - local->local.ID, &record, - NULL, NULL, NULL, &cat) > 0) { - local->local.category = cat; - } - } - - /* 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) { - icaltimezone_convert_time (due.value, - get_timezone (ctxt->client, due.tzid), - default_tz); - local->todo->due = icaltimetype_to_tm (due.value); - local->todo->indefinite = 0; - } else { - local->todo->indefinite = 1; - } - cal_component_free_datetime (&due); - - cal_component_get_status (comp, &status); - if (status == ICAL_STATUS_COMPLETED) - local->todo->complete = 1; - else - local->todo->complete = 0; - - cal_component_get_priority (comp, &priority); - if (priority && *priority != 0) { - if (*priority <= 3) - local->todo->priority = 1; - else if (*priority == 4) - local->todo->priority = 2; - else if (*priority == 5) - local->todo->priority = 3; - else if (*priority <= 7) - local->todo->priority = 4; - else - local->todo->priority = 5; - - cal_component_free_priority (priority); - } else { - local->todo->priority = ctxt->cfg->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); - gtk_object_unref (GTK_OBJECT (comp)); - } 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); - gtk_object_unref (GTK_OBJECT (comp)); - } else { - INFO ("Object did not exist"); - } - - -} - - -static CalComponent * -comp_from_remote_record (GnomePilotConduitSyncAbs *conduit, - GnomePilotRecord *remote, - CalComponent *in_comp, - icaltimezone *timezone) -{ - CalComponent *comp; - struct ToDo todo; - CalComponentText summary = {NULL, NULL}; - CalComponentDateTime dt = {NULL, icaltimezone_get_tzid (timezone)}; - struct icaltimetype due, now; - icaltimezone *utc_zone; - int priority; - char *txt; - - g_return_val_if_fail (remote != NULL, NULL); - - memset (&todo, 0, sizeof (struct ToDo)); - unpack_ToDo (&todo, remote->record, remote->length); - - utc_zone = icaltimezone_get_utc_timezone (); - now = icaltime_from_timet_with_zone (time (NULL), FALSE, - utc_zone); - - 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); - cal_component_set_status (comp, ICAL_STATUS_COMPLETED); - } else { - int *percent = NULL; - icalproperty_status status; - - cal_component_set_completed (comp, NULL); - - cal_component_get_percent (comp, &percent); - if (percent == NULL || *percent == 100) { - int p = 0; - cal_component_set_percent (comp, &p); - } - if (percent != NULL) - cal_component_free_percent (percent); - - cal_component_get_status (comp, &status); - if (status == ICAL_STATUS_COMPLETED) - cal_component_set_status (comp, ICAL_STATUS_NEEDSACTION); - } - - if (!is_empty_time (todo.due)) { - due = tm_to_icaltimetype (&todo.due, FALSE); - dt.value = &due; - cal_component_set_due (comp, &dt); - } - - switch (todo.priority) { - case 1: - priority = 3; - break; - case 2: - priority = 4; - break; - case 3: - priority = 5; - break; - case 4: - priority = 7; - break; - default: - priority = 9; - } - - cal_component_set_priority (comp, &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) -{ - GnomePilotConduitStandard *conduit = GNOME_PILOT_CONDUIT_STANDARD (c); - int map_count; - const char *uri; - - /* If there are no objects or objects but no log */ - map_count = g_hash_table_size (ctxt->map->pid_map); - if (map_count == 0) - gnome_pilot_conduit_standard_set_slow (conduit, TRUE); - - /* Or if the URI's don't match */ - uri = cal_client_get_uri (ctxt->client); - LOG(" Current URI %s (%s)\n", uri, ctxt->cfg->last_uri ? ctxt->cfg->last_uri : "<NONE>"); - if (ctxt->cfg->last_uri != NULL && strcmp (ctxt->cfg->last_uri, uri)) { - gnome_pilot_conduit_standard_set_slow (conduit, TRUE); - e_pilot_map_clear (ctxt->map); - } - - if (gnome_pilot_conduit_standard_get_slow (conduit)) { - ctxt->map->write_touched_only = TRUE; - LOG (" doing slow sync\n"); - } 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->dbi = dbi; - 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; - } - - /* Get the timezone */ - ctxt->timezone = get_default_timezone (); - if (ctxt->timezone == NULL) - return -1; - LOG (" Using timezone: %s", icaltimezone_get_tzid (ctxt->timezone)); - - /* 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); - g_free (change_id); - - 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; - } - } else if (ccc->type == CAL_CLIENT_CHANGE_DELETED) { - e_pilot_map_remove_by_uid (ctxt->map, uid); - } - } - - /* 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); - - 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); - if (ctxt->cfg->sync_type == GnomePilotConduitSyncTypeCopyToPilot - || ctxt->cfg->sync_type == GnomePilotConduitSyncTypeCopyFromPilot) - ctxt->map->write_touched_only = TRUE; - - 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); - - g_free (ctxt->cfg->last_uri); - ctxt->cfg->last_uri = g_strdup (cal_client_get_uri (ctxt->client)); - todoconduit_save_configuration (ctxt->cfg); - - 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); - g_free (change_id); - - LOG ("---------------------------------------------------------\n"); - - 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); - g_list_prepend (ctxt->locals, *local); - - 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); - g_list_prepend (ctxt->locals, *local); - } 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 ("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); - g_list_prepend (ctxt->locals, *local); - } 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); - g_list_prepend (ctxt->locals, *local); - } 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, ctxt->timezone); - update_comp (conduit, comp, ctxt); - - cal_component_get_uid (comp, &uid); - e_pilot_map_insert (ctxt->map, remote->ID, uid, FALSE); - - gtk_object_unref (GTK_OBJECT (comp)); - - 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, ctxt->timezone); - 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, TRUE); - - 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); - - todoconduit_destroy_record (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; -} - -/* Pilot Settings Callbacks */ -static void -fill_widgets (EToDoConduitContext *ctxt) -{ - e_pilot_settings_set_secret (E_PILOT_SETTINGS (ctxt->ps), - ctxt->cfg->secret); - - e_todo_gui_fill_widgets (ctxt->gui, ctxt->cfg); -} - -static gint -create_settings_window (GnomePilotConduit *conduit, - GtkWidget *parent, - EToDoConduitContext *ctxt) -{ - LOG ("create_settings_window"); - - ctxt->ps = e_pilot_settings_new (); - ctxt->gui = e_todo_gui_new (E_PILOT_SETTINGS (ctxt->ps)); - - gtk_container_add (GTK_CONTAINER (parent), ctxt->ps); - gtk_widget_show (ctxt->ps); - - fill_widgets (ctxt); - - return 0; -} -static void -display_settings (GnomePilotConduit *conduit, EToDoConduitContext *ctxt) -{ - LOG ("display_settings"); - - fill_widgets (ctxt); -} - -static void -save_settings (GnomePilotConduit *conduit, EToDoConduitContext *ctxt) -{ - LOG ("save_settings"); - - ctxt->new_cfg->secret = e_pilot_settings_get_secret (E_PILOT_SETTINGS (ctxt->ps)); - e_todo_gui_fill_config (ctxt->gui, ctxt->new_cfg); - - todoconduit_save_configuration (ctxt->new_cfg); -} - -static void -revert_settings (GnomePilotConduit *conduit, EToDoConduitContext *ctxt) -{ - LOG ("revert_settings"); - - todoconduit_save_configuration (ctxt->cfg); - todoconduit_destroy_configuration (ctxt->new_cfg); - ctxt->new_cfg = todoconduit_dupe_configuration (ctxt->cfg); -} - -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); - - 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); - - /* Gui Settings */ - gtk_signal_connect (retval, "create_settings_window", (GtkSignalFunc) create_settings_window, ctxt); - gtk_signal_connect (retval, "display_settings", (GtkSignalFunc) display_settings, ctxt); - gtk_signal_connect (retval, "save_settings", (GtkSignalFunc) save_settings, ctxt); - gtk_signal_connect (retval, "revert_settings", (GtkSignalFunc) revert_settings, 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/gui/.cvsignore b/calendar/gui/.cvsignore deleted file mode 100644 index cd98cc234e..0000000000 --- a/calendar/gui/.cvsignore +++ /dev/null @@ -1,24 +0,0 @@ -Makefile.in -Makefile -.deps -_libs -.libs -.pure -evolution-calendar -evolution-calendar.pure -evolution-calendar.h -evolution-calendar-common.c -evolution-calendar-skels.c -evolution-calendar-stubs.c -*.lo -Evolution-Addressbook-SelectNames-common.c -Evolution-Addressbook-SelectNames-skels.c -Evolution-Addressbook-SelectNames-stubs.c -Evolution-Addressbook-SelectNames.h -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/GNOME_Evolution_Calendar.oaf.in b/calendar/gui/GNOME_Evolution_Calendar.oaf.in deleted file mode 100644 index ce53fba7e6..0000000000 --- a/calendar/gui/GNOME_Evolution_Calendar.oaf.in +++ /dev/null @@ -1,200 +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_ShellComponent" - type="exe" - location="evolution-calendar"> - - <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:ObjectFactory: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_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"/> - <item value="IDL:Bonobo/PropertyBag:1.0"/> - </oaf_attribute> - - <oaf_attribute name="bonobo:supported_mime_types" type="stringv"> - <item value="text/calendar"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - _value="A sample Bonobo control which displays an calendar."/> -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Tasks_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 Evolution Tasks control"/> -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Tasks_Control" - type="factory" - location="OAFIID:GNOME_Evolution_Tasks_ControlFactory"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:BonoboControl/tasks-control:1.0"/> - <item value="IDL:Bonobo/Control:1.0"/> - <item value="IDL:Bonobo/PropertyBag:1.0"/> - </oaf_attribute> - - <oaf_attribute name="bonobo:supported_mime_types" type="stringv"> - <item value="text/calendar"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - _value="A Bonobo control which displays a task list."/> -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_CompEditorFactory_Factory" - 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 to create a component editor factory"/> -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_CompEditorFactory" - type="factory" - location="OAFIID:GNOME_Evolution_Calendar_CompEditorFactory_Factory"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution/Calendar/CompEditorFactory:1.0"/> - <item value="IDL:Bonobo/Unknown:1.0"/> - </oaf_attribute> - - <oaf_attribute name="description" type="string" - _value="Factory to centralize calendar component editor dialogs"/> -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_ConfigControlFactory" - type="exe" - location="evolution-calendar"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/ObjectFactory:1.0"/> - </oaf_attribute> - -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_ConfigControl" - type="factory" - location="OAFIID:GNOME_Evolution_Calendar_ConfigControlFactory"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution/ConfigControl:1.0"/> - </oaf_attribute> - - <oaf_attribute name="evolution:config_item:title" type="string" - _value="Calendar and Tasks"/> - - <oaf_attribute name="evolution:config_item:description" type="string" - _value="This page can be used to configure Calendar and Task preferences"/> - - <oaf_attribute name="evolution:config_item:icon_name" type="string" - value="evolution-calendar.png"/> - - <oaf_attribute name="evolution:config_item:type" type="stringv"> - <item value="calendar"/> - <item value="tasks"/> - </oaf_attribute> - - <oaf_attribute name="evolution:config_item:priority" type="string" value="-7"/> - - <oaf_attribute name="description" type="string" - _value="Configuration control for the Evolution Calendar."/> - -</oaf_server> - -</oaf_info> diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am deleted file mode 100644 index 20e2207907..0000000000 --- a/calendar/gui/Makefile.am +++ /dev/null @@ -1,213 +0,0 @@ -## CORBA stuff - -IDLS = \ - $(top_srcdir)/composer/Evolution-Composer.idl \ - $(top_srcdir)/calendar/idl/evolution-calendar.idl \ - $(top_srcdir)/addressbook/gui/component/select-names/Evolution-Addressbook-SelectNames.idl - -IDL_GENERATED = \ - Evolution-Composer.h \ - Evolution-Composer-common.c \ - Evolution-Composer-skels.c \ - Evolution-Composer-stubs.c \ - Evolution-Addressbook-SelectNames.h \ - Evolution-Addressbook-SelectNames-common.c \ - Evolution-Addressbook-SelectNames-skels.c \ - Evolution-Addressbook-SelectNames-stubs.c \ - evolution-calendar.h \ - evolution-calendar-common.c \ - evolution-calendar-skels.c \ - evolution-calendar-stubs.c - -$(IDL_GENERATED): $(IDLS) - $(ORBIT_IDL) -I $(srcdir) -I $(datadir)/idl `$(GNOME_CONFIG) --cflags idl` \ - $(srcdir)/../../composer/Evolution-Composer.idl - $(ORBIT_IDL) -I $(srcdir) -I $(datadir)/idl `$(GNOME_CONFIG) --cflags idl` \ - $(top_srcdir)/calendar/idl/evolution-calendar.idl - $(ORBIT_IDL) -I $(srcdir) -I $(datadir)/idl `$(GNOME_CONFIG) --cflags idl` \ - $(top_srcdir)/addressbook/gui/component/select-names/Evolution-Addressbook-SelectNames.idl - -BUILT_SOURCES = $(IDL_GENERATED) - -SUBDIRS = alarm-notify 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)/calendar/cal-client \ - -I$(top_builddir)/calendar/cal-client \ - -I$(top_srcdir)/libical/src/libical \ - -I$(top_builddir)/libical/src/libical \ - -I$(top_srcdir)/addressbook/backend/ebook \ - -I$(top_builddir)/addressbook/backend/ebook \ - -I$(top_srcdir)/widgets \ - -I$(includedir) \ - -DEVOLUTION_DATADIR=\""$(datadir)"\" \ - -DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \ - -DEVOLUTION_ETSPECDIR=\""$(etspecdir)"\" \ - -DEVOLUTION_ICONSDIR=\""$(iconsdir)"\" \ - -DEVOLUTION_LOCALEDIR=\""$(localedir)"\" \ - -DEVOLUTION_IMAGESDIR=\""$(datadir)"/images/evolution\" \ - $(EVOLUTION_CALENDAR_CFLAGS) - -iconsdir = $(datadir)/images/evolution - -gladedir = $(datadir)/evolution/glade -glade_DATA = \ - e-itip-control.glade \ - goto-dialog.glade - -etspecdir = $(datadir)/evolution/etspec/ -etspec_DATA = e-calendar-table.etspec e-meeting-time-sel.etspec - -evolution_calendar_SOURCES = \ - $(IDL_GENERATED) \ - cal-search-bar.c \ - cal-search-bar.h \ - calendar-config.c \ - calendar-config.h \ - calendar-commands.c \ - calendar-commands.h \ - calendar-model.c \ - calendar-model.h \ - calendar-offline-handler.c \ - calendar-offline-handler.h \ - calendar-view.c \ - calendar-view.h \ - calendar-view-factory.c \ - calendar-view-factory.h \ - comp-editor-factory.c \ - comp-editor-factory.h \ - comp-util.c \ - comp-util.h \ - config-control-factory.c \ - config-control-factory.h \ - control-factory.c \ - control-factory.h \ - component-factory.c \ - component-factory.h \ - e-calendar-table.h \ - e-calendar-table.c \ - e-cell-date-edit-text.h \ - e-cell-date-edit-text.c \ - e-day-view-layout.c \ - e-day-view-layout.h \ - 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-attendee.c \ - e-meeting-attendee.h \ - e-meeting-model.c \ - e-meeting-model.h \ - e-meeting-time-sel.c \ - e-meeting-time-sel.h \ - e-meeting-time-sel-item.c \ - e-meeting-time-sel-item.h \ - e-meeting-types.h \ - e-meeting-utils.c \ - e-meeting-utils.h \ - e-week-view-event-item.c \ - e-week-view-event-item.h \ - e-week-view-layout.c \ - e-week-view-layout.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 \ - e-timezone-entry.c \ - e-timezone-entry.h \ - gnome-cal.c \ - gnome-cal.h \ - goto.c \ - goto.h \ - itip-control-factory.c \ - itip-control-factory.h \ - itip-utils.c \ - itip-utils.h \ - main.c \ - misc.c \ - misc.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 - -evolution_calendar_LDADD = \ - alarm-notify/libalarm.a \ - $(DB3_LDADD) \ - $(top_builddir)/widgets/menus/libmenus.la \ - $(top_builddir)/shell/libeshell.la \ - $(top_builddir)/calendar/cal-client/libcal-client.la \ - $(top_builddir)/calendar/cal-util/libcal-util.la \ - $(top_builddir)/e-util/libeutil.la \ - $(top_builddir)/libical/src/libical/libical-evolution.la \ - $(top_builddir)/libwombat/libwombat.la \ - $(top_builddir)/addressbook/backend/ebook/libebook.la \ - $(top_builddir)/camel/libcamel.la \ - $(top_builddir)/libversit/libversit.a \ - $(top_builddir)/e-util/ename/libename.la \ - dialogs/libcal-dialogs.a \ - $(top_builddir)/widgets/e-timezone-dialog/libetimezonedialog.a \ - $(top_builddir)/widgets/misc/libemiscwidgets.a \ - $(EVOLUTION_CALENDAR_LIBS) - -evolution_calendar_LDFLAGS = -export-dynamic - -oafdir = $(datadir)/oaf -oaf_in_files = \ - GNOME_Evolution_Calendar.oaf.in - -oaf_DATA = $(oaf_in_files:.oaf.in=.oaf) - -@XML_I18N_MERGE_OAF_RULE@ - -EXTRA_DIST = \ - $(glade_DATA) \ - $(etspec_DATA) \ - $(oaf_in_files) - -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 - -CLEANFILES = $(BUILT_SOURCES) - -dist-hook: - cd $(distdir); rm -f $(BUILT_SOURCES) diff --git a/calendar/gui/alarm-notify/.cvsignore b/calendar/gui/alarm-notify/.cvsignore deleted file mode 100644 index 479589e914..0000000000 --- a/calendar/gui/alarm-notify/.cvsignore +++ /dev/null @@ -1,11 +0,0 @@ -.deps -.libs -.pure -Makefile -Makefile.in -evolution-calendar-stubs.c -evolution-calendar-skels.c -evolution-calendar-common.c -evolution-calendar.h -evolution-alarm-notify -GNOME_Evolution_Calendar_AlarmNotify.oaf diff --git a/calendar/gui/alarm-notify/GNOME_Evolution_Calendar_AlarmNotify.oaf.in b/calendar/gui/alarm-notify/GNOME_Evolution_Calendar_AlarmNotify.oaf.in deleted file mode 100644 index 86f5c71493..0000000000 --- a/calendar/gui/alarm-notify/GNOME_Evolution_Calendar_AlarmNotify.oaf.in +++ /dev/null @@ -1,24 +0,0 @@ -<oaf_info> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_AlarmNotify_Factory" - type="exe" - location="evolution-alarm-notify"> - - <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 alarm notification service"/> - -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_AlarmNotify" - type="factory" - location="OAFIID:GNOME_Evolution_Calendar_AlarmNotify_Factory"> - - <oaf_attribute name="description" type="string" - _value="Alarm notification service"/> -</oaf_server> - -</oaf_info> diff --git a/calendar/gui/alarm-notify/Makefile.am b/calendar/gui/alarm-notify/Makefile.am deleted file mode 100644 index 6d77398ade..0000000000 --- a/calendar/gui/alarm-notify/Makefile.am +++ /dev/null @@ -1,83 +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 - -noinst_LIBRARIES = libalarm.a - -libalarm_a_SOURCES = \ - alarm.c \ - alarm.h - -INCLUDES = \ - -DG_LOG_DOMAIN=\"evolution-alarm-notify\" \ - -I$(top_srcdir) \ - -I$(top_srcdir)/calendar \ - -I$(top_builddir)/calendar \ - -I$(top_srcdir)/libical/src/libical \ - -I$(top_builddir)/libical/src/libical \ - -I$(top_srcdir)/widgets \ - -I$(includedir) \ - -DEVOLUTION_DATADIR=\""$(datadir)"\" \ - -DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \ - -DEVOLUTION_ICONSDIR=\""$(iconsdir)"\" \ - -DEVOLUTION_LOCALEDIR=\""$(localedir)"\" \ - $(EVOLUTION_CALENDAR_CFLAGS) - -iconsdir = $(datadir)/images/evolution - -gladedir = $(datadir)/evolution/glade - -glade_DATA = \ - alarm-notify.glade - -evolution_alarm_notify_SOURCES = \ - $(CORBA_GENERATED) \ - alarm-notify.c \ - alarm-notify.h \ - alarm-notify-dialog.c \ - alarm-notify-dialog.h \ - alarm-queue.c \ - alarm-queue.h \ - config-data.c \ - config-data.h \ - notify-main.c \ - save.c \ - save.h - -evolution_alarm_notify_LDADD = \ - libalarm.a \ - $(top_builddir)/calendar/cal-client/libcal-client.la \ - $(top_builddir)/calendar/cal-util/libcal-util.la \ - $(top_builddir)/libical/src/libical/libical-evolution.la \ - $(top_builddir)/libwombat/libwombat.la \ - $(top_builddir)/e-util/libeutil.la \ - $(EVOLUTION_CALENDAR_LIBS) - -evolution_alarm_notify_LDFLAGS = -export-dynamic - -oafdir = $(datadir)/oaf -oaf_in_files = \ - GNOME_Evolution_Calendar_AlarmNotify.oaf.in - -oaf_DATA = $(oaf_in_files:.oaf.in=.oaf) - -@XML_I18N_MERGE_OAF_RULE@ - -EXTRA_DIST = \ - $(oaf_DATA) \ - $(oaf_in_files) \ - $(glade_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 2ad6783cf9..0000000000 --- a/calendar/gui/alarm-notify/alarm-notify-dialog.c +++ /dev/null @@ -1,412 +0,0 @@ -/* Evolution calendar - alarm notification dialog - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2001 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#include <config.h> -#include <stdio.h> -#include <string.h> -#include <gtk/gtklabel.h> -#include <gtk/gtkspinbutton.h> -#include <gtk/gtksignal.h> -#include <gtk/gtkwindow.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <libgnomeui/gnome-winhints.h> -#include <libgnomeui/gnome-window-icon.h> -#include <glade/glade.h> -#include <e-util/e-time-utils.h> -#include <gal/util/e-unicode-i18n.h> -#include <gal/widgets/e-unicode.h> -#include <gal/widgets/e-scroll-frame.h> -#include <gtkhtml/gtkhtml.h> -#include <gtkhtml/gtkhtml-stream.h> -#include "cal-util/timeutil.h" -#include "alarm-notify-dialog.h" -#include "config-data.h" - - -GtkWidget *make_html_display (gchar *widget_name, char *s1, char *s2, int scroll, int shadow); - -/* The useful contents of the alarm notify dialog */ -typedef struct { - GladeXML *xml; - - GtkWidget *dialog; - GtkWidget *close; - GtkWidget *snooze; - GtkWidget *edit; - GtkWidget *heading; - GtkWidget *message; - GtkWidget *snooze_time; - GtkWidget *html; - - 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); -} - -static void -url_requested_cb (GtkHTML *html, const char *url, GtkHTMLStream *stream, gpointer data) -{ - - if (!strncmp ("file:///", url, strlen ("file:///"))) { - FILE *fp; - const char *filename = url + strlen ("file://"); - char buf[4096]; - size_t len; - - fp = fopen (filename, "r"); - - if (fp == NULL) { - g_warning ("Error opening image: %s\n", url); - gtk_html_stream_close (stream, GTK_HTML_STREAM_ERROR); - return; - } - - while ((len = fread (buf, 1, sizeof(buf), fp)) > 0) - gtk_html_stream_write (stream, buf, len); - - if (feof (fp)) { - fclose (fp); - gtk_html_stream_close (stream, GTK_HTML_STREAM_OK); - return; - } - - fclose (fp); - } - - g_warning ("Error loading image"); - gtk_html_stream_close (stream, GTK_HTML_STREAM_ERROR); - return; -} - -GtkWidget * -make_html_display (gchar *widget_name, char *s1, char *s2, int scroll, int shadow) -{ - GtkWidget *html, *frame; - - gtk_widget_push_visual(gdk_rgb_get_visual()); - gtk_widget_push_colormap(gdk_rgb_get_cmap()); - - html = gtk_html_new(); - - gtk_html_set_default_content_type (GTK_HTML (html), - "charset=utf-8"); - gtk_html_load_empty (GTK_HTML (html)); - - gtk_signal_connect (GTK_OBJECT (html), "url_requested", - GTK_SIGNAL_FUNC (url_requested_cb), - NULL); - - gtk_widget_pop_colormap(); - gtk_widget_pop_visual(); - - frame = e_scroll_frame_new(NULL, NULL); - - e_scroll_frame_set_policy(E_SCROLL_FRAME(frame), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - - - e_scroll_frame_set_shadow_type (E_SCROLL_FRAME (frame), - GTK_SHADOW_IN); - - gtk_widget_set_usize (frame, 300, 200); - - gtk_container_add(GTK_CONTAINER (frame), html); - - gtk_widget_show_all(frame); - - gtk_object_set_user_data(GTK_OBJECT (frame), html); - return frame; -} - -static void -write_times (GtkHTMLStream *stream, char *start, char *end) -{ - if (start) - gtk_html_stream_printf (stream, "<b>%s</b> %s<br>", U_("Starting:"), start); - if (end) - gtk_html_stream_printf (stream, "<b>%s</b> %s<br>", U_("Ending:"), end); - -} - -/* Converts a time_t to a string, relative to the specified timezone */ -static char * -timet_to_str_with_zone (time_t t, icaltimezone *zone) -{ - struct icaltimetype itt; - struct tm tm; - char buf[256]; - - if (t == -1) - return g_strdup (_("invalid time")); - - itt = icaltime_from_timet_with_zone (t, FALSE, zone); - tm = icaltimetype_to_tm (&itt); - - e_time_format_date_and_time (&tm, config_data_get_24_hour_format (), - FALSE, FALSE, buf, sizeof (buf)); - return g_strdup (buf); -} - -/* Creates a heading for the alarm notification dialog */ -static void -write_html_heading (GtkHTMLStream *stream, const char *message, - CalComponentVType vtype, time_t occur_start, time_t occur_end) -{ - char *buf; - char *start, *end; - char *bg_path = "file://" EVOLUTION_ICONSDIR "/bcg.png"; - char *image_path = "file://" EVOLUTION_ICONSDIR "/alarm.png"; - icaltimezone *current_zone; - - /* Stringize the times */ - - current_zone = config_data_get_timezone (); - - buf = timet_to_str_with_zone (occur_start, current_zone); - start = e_utf8_from_locale_string (buf); - g_free (buf); - - buf = timet_to_str_with_zone (occur_end, current_zone); - end = e_utf8_from_locale_string (buf); - g_free (buf); - - /* Write the header */ - - gtk_html_stream_printf (stream, - "<HTML><BODY background=\"%s\">" - "<TABLE WIDTH=\"100%%\">" - "<TR>" - "<TD><IMG SRC=\"%s\" ALIGN=\"top\" BORDER=\"0\"></TD>" - "<TD><H1>%s</H1></TD>" - "</TR>" - "</TABLE>", - bg_path, - image_path, - U_("Evolution Alarm")); - - gtk_html_stream_printf (stream, "<br><br><font size=\"+2\">%s</font><br><br>", message); - - /* Write the times */ - - switch (vtype) { - case CAL_COMPONENT_EVENT: - write_times (stream, start, end); - break; - - case CAL_COMPONENT_TODO: - write_times (stream, start, end); - break; - - default: - /* Only VEVENTs and VTODOs can have alarms */ - g_assert_not_reached (); - break; - } - - g_free (start); - g_free (end); -} - -/** - * alarm_notify_dialog: - * @trigger: Trigger time for the alarm. - * @occur_start: Start of occurrence time for the event. - * @occur_end: End of occurrence time for the event. - * @vtype: Type of the component which corresponds to the alarm. - * @message; Message to display in the dialog; usually comes from the component. - * @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_start, time_t occur_end, - CalComponentVType vtype, const char *message, - AlarmNotifyFunc func, gpointer func_data) -{ - AlarmNotify *an; - GtkHTMLStream *stream; - icaltimezone *current_zone; - char *buf, *title; - - g_return_val_if_fail (trigger != -1, FALSE); - - /* Only VEVENTs or VTODOs can have alarms */ - g_return_val_if_fail (vtype == CAL_COMPONENT_EVENT || vtype == CAL_COMPONENT_TODO, FALSE); - g_return_val_if_fail (message != NULL, 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->message = glade_xml_get_widget (an->xml, "message"); - an->snooze_time = glade_xml_get_widget (an->xml, "snooze-time"); - an->html = gtk_object_get_user_data (GTK_OBJECT (glade_xml_get_widget (an->xml, "frame"))); - - if (!(an->dialog && an->close && an->snooze && an->edit && an->heading && an->message - && 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 */ - - current_zone = config_data_get_timezone (); - - buf = timet_to_str_with_zone (trigger, current_zone); - title = g_strdup_printf (_("Alarm on %s"), buf); - g_free (buf); - - gtk_window_set_title (GTK_WINDOW (an->dialog), title); - g_free (title); - - /* html heading */ - stream = gtk_html_begin (GTK_HTML (an->html)); - write_html_heading (stream, message, vtype, occur_start, occur_end); - gtk_html_stream_close (stream, GTK_HTML_STREAM_OK); - - /* 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! */ - - if (!GTK_WIDGET_REALIZED (an->dialog)) - gtk_widget_realize (an->dialog); - - gnome_win_hints_set_state (an->dialog, WIN_STATE_STICKY); - gnome_win_hints_set_layer (an->dialog, WIN_LAYER_ONTOP); - gnome_window_icon_set_from_file (GTK_WINDOW (an->dialog), EVOLUTION_ICONSDIR "/alarm.png"); - - 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 812463de8d..0000000000 --- a/calendar/gui/alarm-notify/alarm-notify-dialog.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Evolution calendar - alarm notification dialog - * - * Copyright (C) 2001 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#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_start, time_t occur_end, - CalComponentVType vtype, const char *message, - 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 7dbb77ceeb..0000000000 --- a/calendar/gui/alarm-notify/alarm-notify.c +++ /dev/null @@ -1,426 +0,0 @@ -/* Evolution calendar - Alarm notification service object - * - * Copyright (C) 2001 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <cal-client/cal-client.h> -#include "alarm-notify.h" -#include "alarm-queue.h" -#include "save.h" -#include "e-util/e-url.h" - - - -/* A loaded client */ -typedef struct { - /* The actual client */ - CalClient *client; - - /* The URI of the client in gnome-vfs's format. This *is* the key that - * is stored in the uri_client_hash hash table below. - */ - EUri *uri; - - /* Number of times clients have requested this URI to be added to the - * alarm notification system. - */ - int refcount; -} LoadedClient; - -/* Private part of the AlarmNotify structure */ -struct _AlarmNotifyPrivate { - /* Mapping from EUri's to LoadedClient structures */ - 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 void AlarmNotify_addCalendar (PortableServer_Servant servant, - const CORBA_char *str_uri, - CORBA_Environment *ev); -static void AlarmNotify_removeCalendar (PortableServer_Servant servant, - const CORBA_char *str_uri, - CORBA_Environment *ev); - - -static BonoboXObjectClass *parent_class; - - - -BONOBO_X_TYPE_FUNC_FULL (AlarmNotify, - GNOME_Evolution_Calendar_AlarmNotify, - BONOBO_X_OBJECT_TYPE, - alarm_notify); - -/* 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_X_OBJECT_TYPE); - - class->epv.addCalendar = AlarmNotify_addCalendar; - class->epv.removeCalendar = AlarmNotify_removeCalendar; - - object_class->destroy = alarm_notify_destroy; -} - -/* 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 (g_str_hash, g_str_equal); -} - -/* Callback used from g_hash-table_forach(), used to destroy a loade client */ -static void -destroy_loaded_client_cb (gpointer key, gpointer value, gpointer data) -{ - LoadedClient *lc; - char *str_uri; - - str_uri = key; - lc = value; - - g_free (str_uri); - gtk_object_unref (GTK_OBJECT (lc->client)); - e_uri_free (lc->uri); - g_free (lc); -} - -/* 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; - - g_hash_table_foreach (priv->uri_client_hash, destroy_loaded_client_cb, NULL); - - g_hash_table_destroy (priv->uri_client_hash); - priv->uri_client_hash = NULL; - - g_free (priv); - an->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - - -/* CORBA servant implementation */ - -/* Looks for a canonicalized URI inside an array of URIs; returns the index - * within the array or -1 if not found. - */ -static int -find_uri_index (GPtrArray *uris, const char *str_uri) -{ - int i; - - for (i = 0; i < uris->len; i++) { - char *uri; - - uri = uris->pdata[i]; - if (strcmp (uri, str_uri) == 0) - break; - } - - if (i == uris->len) - return -1; - else - return i; -} - -/* Frees an array of URIs and the URIs within it. */ -static void -free_uris (GPtrArray *uris) -{ - int i; - - for (i = 0; i < uris->len; i++) { - char *uri; - - uri = uris->pdata[i]; - g_free (uri); - } - - g_ptr_array_free (uris, TRUE); -} - -/* Adds an URI to the list of calendars to load on startup */ -static void -add_uri_to_load (EUri *uri) -{ - char *str_uri; - GPtrArray *loaded_uris; - int i; - - /* Canonicalize the URI */ - str_uri = e_uri_to_string (uri, FALSE); - g_assert (str_uri != NULL); - - loaded_uris = get_calendars_to_load (); - if (!loaded_uris) { - g_message ("add_uri_to_load(): Could not get the list of calendars to load; " - "will not add `%s'", str_uri); - g_free (str_uri); - return; - } - - /* Look for the URI in the list of calendars to load */ - - i = find_uri_index (loaded_uris, str_uri); - - /* We only need to add the URI if we didn't find it among the list of - * calendars. - */ - if (i != -1) { - g_free (str_uri); - free_uris (loaded_uris); - return; - } - - g_ptr_array_add (loaded_uris, str_uri); - save_calendars_to_load (loaded_uris); - - free_uris (loaded_uris); -} - -/* Removes an URI from the list of calendars to load on startup */ -static void -remove_uri_to_load (EUri *uri) -{ - char *str_uri; - GPtrArray *loaded_uris; - char *loaded_uri; - int i; - - /* Canonicalize the URI */ - str_uri = e_uri_to_string (uri, FALSE); - g_assert (str_uri != NULL); - - loaded_uris = get_calendars_to_load (); - if (!loaded_uris) { - g_message ("remove_uri_to_load(): Could not get the list of calendars to load; " - "will not add `%s'", str_uri); - g_free (str_uri); - return; - } - - /* Look for the URI in the list of calendars to load */ - - i = find_uri_index (loaded_uris, str_uri); - g_free (str_uri); - - /* If we didn't find it, there is no need to remove it */ - if (i == -1) { - free_uris (loaded_uris); - return; - } - - loaded_uri = loaded_uris->pdata[i]; - g_free (loaded_uri); - - g_ptr_array_remove_index (loaded_uris, i); - save_calendars_to_load (loaded_uris); - - free_uris (loaded_uris); -} - -/* AlarmNotify::addCalendar method */ -static void -AlarmNotify_addCalendar (PortableServer_Servant servant, - const CORBA_char *str_uri, - CORBA_Environment *ev) -{ - AlarmNotify *an; - - an = ALARM_NOTIFY (bonobo_object_from_servant (servant)); - alarm_notify_add_calendar (an, str_uri, TRUE, ev); -} - -/* AlarmNotify::removeCalendar method */ -static void -AlarmNotify_removeCalendar (PortableServer_Servant servant, - const CORBA_char *str_uri, - CORBA_Environment *ev) -{ - AlarmNotify *an; - AlarmNotifyPrivate *priv; - LoadedClient *lc; - EUri *uri; - char *orig_str; - gboolean found; - - an = ALARM_NOTIFY (bonobo_object_from_servant (servant)); - priv = an->priv; - - uri = e_uri_new (str_uri); - if (!uri) { - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_GNOME_Evolution_Calendar_AlarmNotify_InvalidURI, - NULL); - return; - } - - remove_uri_to_load (uri); - - found = g_hash_table_lookup_extended (priv->uri_client_hash, str_uri, - (gpointer *) &orig_str, - (gpointer *) &lc); - e_uri_free (uri); - - if (!lc) { - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_GNOME_Evolution_Calendar_AlarmNotify_NotFound, - NULL); - return; - } - - g_assert (lc->refcount > 0); - - lc->refcount--; - if (lc->refcount > 0) - return; - - g_hash_table_remove (priv->uri_client_hash, str_uri); - - g_free (orig_str); - gtk_object_unref (GTK_OBJECT (lc->client)); - e_uri_free (lc->uri); - g_free (lc); -} - - - -/** - * 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; - - an = gtk_type_new (TYPE_ALARM_NOTIFY); - return an; -} - -/** - * alarm_notify_add_calendar: - * @an: An alarm notification service. - * @uri: URI of the calendar to load. - * @load_afterwards: Whether this calendar should be loaded in the future - * when the alarm daemon starts up. - * @ev: CORBA environment for exceptions. - * - * Tells the alarm notification service to load a calendar and start monitoring - * its alarms. It can optionally be made to save the URI of this calendar so - * that it can be loaded in the future when the alarm daemon starts up. - **/ -void -alarm_notify_add_calendar (AlarmNotify *an, const char *str_uri, gboolean load_afterwards, - CORBA_Environment *ev) -{ - AlarmNotifyPrivate *priv; - EUri *uri; - CalClient *client; - LoadedClient *lc; - - g_return_if_fail (an != NULL); - g_return_if_fail (IS_ALARM_NOTIFY (an)); - g_return_if_fail (str_uri != NULL); - g_return_if_fail (ev != NULL); - - priv = an->priv; - - uri = e_uri_new (str_uri); - if (!uri) { - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_GNOME_Evolution_Calendar_AlarmNotify_InvalidURI, - NULL); - return; - } - - if (load_afterwards) - add_uri_to_load (uri); - - lc = g_hash_table_lookup (priv->uri_client_hash, str_uri); - - if (lc) { - e_uri_free (uri); - g_assert (lc->refcount > 0); - lc->refcount++; - return; - } - - client = cal_client_new (); - - if (client) { - if (cal_client_open_calendar (client, str_uri, FALSE)) { - lc = g_new (LoadedClient, 1); - lc->client = client; - lc->uri = uri; - lc->refcount = 1; - g_hash_table_insert (priv->uri_client_hash, - g_strdup (str_uri), lc); - - alarm_queue_add_client (client); - } else { - gtk_object_unref (GTK_OBJECT (client)); - client = NULL; - } - } - - if (!client) { - e_uri_free (uri); - - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_GNOME_Evolution_Calendar_AlarmNotify_BackendContactError, - NULL); - return; - } -} diff --git a/calendar/gui/alarm-notify/alarm-notify.glade b/calendar/gui/alarm-notify/alarm-notify.glade deleted file mode 100644 index e71828ca53..0000000000 --- a/calendar/gui/alarm-notify/alarm-notify.glade +++ /dev/null @@ -1,220 +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> -</project> - -<widget> - <class>GtkWindow</class> - <name>alarm-notify</name> - <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> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - - <widget> - <class>GtkHBox</class> - <name>hbox3</name> - <homogeneous>False</homogeneous> - <spacing>8</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkVBox</class> - <name>vbox5</name> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>heading</name> - <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>message</name> - <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>Custom</class> - <name>frame</name> - <creation_function>make_html_display</creation_function> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Thu, 11 Oct 2001 08:19:04 GMT</last_modification_time> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - </widget> - </widget> - - <widget> - <class>GtkVBox</class> - <name>vbox4</name> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkButton</class> - <name>close</name> - <can_focus>True</can_focus> - <label>C_lose</label> - <relief>GTK_RELIEF_NORMAL</relief> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkButton</class> - <name>snooze</name> - <can_focus>True</can_focus> - <label>Snoo_ze</label> - <relief>GTK_RELIEF_NORMAL</relief> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkButton</class> - <name>edit</name> - <can_focus>True</can_focus> - <label>_Edit appointment</label> - <relief>GTK_RELIEF_NORMAL</relief> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> - </widget> - - <widget> - <class>GtkHSeparator</class> - <name>hseparator1</name> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - </widget> - - <widget> - <class>GtkHBox</class> - <name>hbox4</name> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label4</name> - <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> - <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 858c3a7d87..0000000000 --- a/calendar/gui/alarm-notify/alarm-notify.h +++ /dev/null @@ -1,65 +0,0 @@ -/* Evolution calendar - Alarm notification service object - * - * Copyright (C) 2000 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef ALARM_NOTIFY_H -#define ALARM_NOTIFY_H - -#include <bonobo/bonobo-xobject.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 { - BonoboXObject xobject; - - /* Private data */ - AlarmNotifyPrivate *priv; -}; - -struct _AlarmNotifyClass { - BonoboXObjectClass parent_class; - - POA_GNOME_Evolution_Calendar_AlarmNotify__epv epv; -}; - -GtkType alarm_notify_get_type (void); - -AlarmNotify *alarm_notify_new (void); - -void alarm_notify_add_calendar (AlarmNotify *an, const char *str_uri, gboolean load_afterwards, - CORBA_Environment *ev); - - - - -#endif diff --git a/calendar/gui/alarm-notify/alarm-queue.c b/calendar/gui/alarm-notify/alarm-queue.c deleted file mode 100644 index fd22649e71..0000000000 --- a/calendar/gui/alarm-notify/alarm-queue.c +++ /dev/null @@ -1,1031 +0,0 @@ -/* Evolution calendar - Alarm queueing engine - * - * 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <glib.h> -#include <liboaf/liboaf.h> -#include <bonobo/bonobo-object.h> -#include <gtk/gtksignal.h> -#include <gtk/gtkbox.h> -#include <gtk/gtklabel.h> -#include <gtk/gtkcheckbutton.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <libgnome/gnome-exec.h> -#include <libgnome/gnome-sound.h> -#include <libgnomeui/gnome-dialog.h> -#include <libgnomeui/gnome-dialog-util.h> -#include <libgnomeui/gnome-dialog.h> -#include <libgnomeui/gnome-stock.h> -#include <libgnomeui/gnome-uidefs.h> -#include <cal-util/timeutil.h> -#include "alarm.h" -#include "alarm-notify-dialog.h" -#include "alarm-queue.h" -#include "config-data.h" -#include "save.h" - - - -/* Whether the queueing system has been initialized */ -static gboolean alarm_queue_inited; - -/* When the alarm queue system is inited, this gets set to the last time an - * alarm notification was issued. This lets us present any notifications that - * should have happened while the alarm daemon was not running. - */ -static time_t saved_notification_time; - -/* 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 CompQueuedAlarms->alarms->alarms list */ - CalAlarmInstance *instance; - - /* Whether this is a snoozed queued alarm or a normal one */ - guint snooze : 1; -} QueuedAlarm; - -/* Alarm ID for the midnight refresh function */ -static gpointer midnight_refresh_id = NULL; - -static void display_notification (time_t trigger, CompQueuedAlarms *cqa, - gpointer alarm_id, gboolean use_description); -static void audio_notification (time_t trigger, CompQueuedAlarms *cqa, gpointer alarm_id); -static void mail_notification (time_t trigger, CompQueuedAlarms *cqa, gpointer alarm_id); -static void procedure_notification (time_t trigger, CompQueuedAlarms *cqa, gpointer alarm_id); - - - -/* Alarm queue engine */ - -static void load_alarms_for_today (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; - icaltimezone *zone; - - g_assert (midnight_refresh_id == NULL); - - zone = config_data_get_timezone (); - - midnight = time_day_end_with_zone (time (NULL), zone); - - 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_for_today (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); -} - -/* Looks up a queued alarm based on its alarm ID */ -static QueuedAlarm * -lookup_queued_alarm (CompQueuedAlarms *cqa, gpointer alarm_id) -{ - GSList *l; - QueuedAlarm *qa; - - qa = NULL; - - for (l = cqa->queued_alarms; l; l = l->next) { - qa = l->data; - if (qa->alarm_id == alarm_id) - break; - } - - g_assert (l != NULL); - return qa; -} - -/* Removes an alarm from the list of alarms of a component. If the alarm was - * the last one listed for the component, it removes the component itself. - */ -static void -remove_queued_alarm (CompQueuedAlarms *cqa, gpointer alarm_id) -{ - QueuedAlarm *qa; - const char *uid; - GSList *l; - - qa = NULL; - - for (l = cqa->queued_alarms; l; l = l->next) { - qa = l->data; - if (qa->alarm_id == alarm_id) - break; - } - - g_assert (l != NULL); - - 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); -} - -/* Callback used when an alarm triggers */ -static void -alarm_trigger_cb (gpointer alarm_id, time_t trigger, gpointer data) -{ - CompQueuedAlarms *cqa; - CalComponent *comp; - QueuedAlarm *qa; - CalComponentAlarm *alarm; - CalAlarmAction action; - - cqa = data; - comp = cqa->alarms->comp; - - save_notification_time (trigger); - - qa = lookup_queued_alarm (cqa, alarm_id); - - /* Decide what to do based on the alarm action. We use the trigger that - * is passed to us instead of the one from the instance structure - * because this may be a snoozed alarm instead of an original - * occurrence. - */ - - alarm = cal_component_get_alarm (comp, qa->instance->auid); - g_assert (alarm != NULL); - - cal_component_alarm_get_action (alarm, &action); - cal_component_alarm_free (alarm); - - switch (action) { - case CAL_ALARM_AUDIO: - audio_notification (trigger, cqa, alarm_id); - break; - - case CAL_ALARM_DISPLAY: - display_notification (trigger, cqa, alarm_id, TRUE); - break; - - case CAL_ALARM_EMAIL: - mail_notification (trigger, cqa, alarm_id); - break; - - case CAL_ALARM_PROCEDURE: - procedure_notification (trigger, cqa, alarm_id); - break; - - default: - g_assert_not_reached (); - break; - } -} - -/* 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, NULL); - 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; - qa->snooze = FALSE; - - 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 the alarms of a client for a given range of time */ -static void -load_alarms (ClientAlarms *ca, time_t start, time_t end) -{ - GSList *comp_alarms; - GSList *l; - - comp_alarms = cal_client_get_alarms_in_range (ca->client, start, end); - - for (l = comp_alarms; l; l = l->next) { - CalComponentAlarms *alarms; - - alarms = l->data; - add_component_alarms (ca, alarms); - } - - g_slist_free (comp_alarms); -} - -/* Loads today's remaining alarms for a client */ -static void -load_alarms_for_today (ClientAlarms *ca) -{ - time_t now, day_end; - icaltimezone *zone; - - now = time (NULL); - - zone = config_data_get_timezone (); - - day_end = time_day_end_with_zone (now, zone); - load_alarms (ca, now, day_end); -} - -/* Adds any alarms that should have occurred while the alarm daemon was not - * running. - */ -static void -load_missed_alarms (ClientAlarms *ca) -{ - time_t now; - - now = time (NULL); - - g_assert (saved_notification_time != -1); - - /* We add 1 to the saved_notification_time to make the time ranges - * half-open; we do not want to display the "last" displayed alarm - * twice, once when it occurs and once when the alarm daemon restarts. - */ - load_alarms (ca, saved_notification_time + 1, now); -} - -/* Called when a calendar client finished loading; we load its alarms */ -static void -cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data) -{ - ClientAlarms *ca; - - ca = data; - - if (status != CAL_CLIENT_OPEN_SUCCESS) - return; - - load_alarms_for_today (ca); - load_missed_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 in remove_queued_alarm(). The qa will be freed there as - * well. - */ - l = l->next; - - alarm_remove (qa->alarm_id); - remove_queued_alarm (cqa, 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; - icaltimezone *zone; - - ca = data; - - remove_comp (ca, uid); - - now = time (NULL); - - zone = config_data_get_timezone (); - - day_end = time_day_end_with_zone (now, zone); - - 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); -} - - - -/* Notification functions */ - -/* Creates a snooze alarm based on an existing one. The snooze offset is - * compued with respect to the current time. - */ -static void -create_snooze (CompQueuedAlarms *cqa, gpointer alarm_id, int snooze_mins) -{ - QueuedAlarm *orig_qa, *qa; - CalAlarmInstance *instance; - time_t t; - gpointer new_id; - - orig_qa = lookup_queued_alarm (cqa, alarm_id); - - t = time (NULL); - t += snooze_mins * 60; - - new_id = alarm_add (t, alarm_trigger_cb, cqa, NULL); - if (!new_id) { - g_message ("create_snooze(): Could not schedule a trigger for " - "%ld, discarding...", (long) t); - return; - } - - instance = g_new (CalAlarmInstance, 1); - instance->auid = orig_qa->instance->auid; - instance->trigger = t; - instance->occur_start = orig_qa->instance->occur_start; - instance->occur_end = orig_qa->instance->occur_end; - - cqa->alarms->alarms = g_slist_prepend (cqa->alarms->alarms, instance); - - qa = g_new (QueuedAlarm, 1); - qa->alarm_id = new_id; - qa->instance = instance; - qa->snooze = TRUE; - - cqa->queued_alarms = g_slist_prepend (cqa->queued_alarms, qa); -} - -/* Launches a component editor for a component */ -static void -edit_component (CompQueuedAlarms *cqa) -{ - CalComponent *comp; - const char *uid; - const char *uri; - CORBA_Environment ev; - GNOME_Evolution_Calendar_CompEditorFactory factory; - - comp = cqa->alarms->comp; - cal_component_get_uid (comp, &uid); - - uri = cal_client_get_uri (cqa->parent_client->client); - - /* Get the factory */ - - CORBA_exception_init (&ev); - factory = oaf_activate_from_id ("OAFIID:GNOME_Evolution_Calendar_CompEditorFactory", - 0, NULL, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("edit_component(): Could not activate the component editor factory"); - CORBA_exception_free (&ev); - return; - } - CORBA_exception_free (&ev); - - /* Edit the component */ - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_CompEditorFactory_editExisting (factory, uri, (char *) uid, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("edit_component(): Exception while editing the component"); - - CORBA_exception_free (&ev); - - /* Get rid of the factory */ - - CORBA_exception_init (&ev); - bonobo_object_release_unref (factory, &ev); - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("edit_component(): Could not unref the calendar component factory"); - - CORBA_exception_free (&ev); -} - -struct notify_dialog_closure { - CompQueuedAlarms *cqa; - gpointer alarm_id; -}; - -/* Callback used from the alarm notify dialog */ -static void -notify_dialog_cb (AlarmNotifyResult result, int snooze_mins, gpointer data) -{ - struct notify_dialog_closure *c; - - c = data; - - switch (result) { - case ALARM_NOTIFY_SNOOZE: - create_snooze (c->cqa, c->alarm_id, snooze_mins); - break; - - case ALARM_NOTIFY_EDIT: - edit_component (c->cqa); - break; - - case ALARM_NOTIFY_CLOSE: - /* Do nothing */ - break; - - default: - g_assert_not_reached (); - } - - remove_queued_alarm (c->cqa, c->alarm_id); - g_free (c); -} - -/* Performs notification of a display alarm */ -static void -display_notification (time_t trigger, CompQueuedAlarms *cqa, - gpointer alarm_id, gboolean use_description) -{ - CalComponent *comp; - CalComponentVType vtype; - CalComponentText text; - QueuedAlarm *qa; - const char *message; - struct notify_dialog_closure *c; - gboolean use_summary; - - comp = cqa->alarms->comp; - qa = lookup_queued_alarm (cqa, alarm_id); - g_assert (qa != NULL); - - vtype = cal_component_get_vtype (comp); - - /* Pick a sensible notification message. First we try the DESCRIPTION - * from the alarm, then the SUMMARY of the component. - */ - - use_summary = TRUE; - message = NULL; - - if (use_description) { - CalComponentAlarm *alarm; - - alarm = cal_component_get_alarm (comp, qa->instance->auid); - g_assert (alarm != NULL); - - cal_component_alarm_get_description (alarm, &text); - cal_component_alarm_free (alarm); - - if (text.value) { - message = text.value; - use_summary = FALSE; - } - } - - if (use_summary) { - cal_component_get_summary (comp, &text); - if (text.value) - message = text.value; - else - message = _("No description available."); - } - - c = g_new (struct notify_dialog_closure, 1); - c->cqa = cqa; - c->alarm_id = alarm_id; - - if (!alarm_notify_dialog (trigger, - qa->instance->occur_start, qa->instance->occur_end, - vtype, message, - notify_dialog_cb, c)) - g_message ("display_notification(): Could not create the alarm notify dialog"); -} - -/* Performs notification of an audio alarm */ -static void -audio_notification (time_t trigger, CompQueuedAlarms *cqa, - gpointer alarm_id) -{ - QueuedAlarm *qa; - CalComponent *comp; - CalComponentAlarm *alarm; - icalattach *attach; - - comp = cqa->alarms->comp; - qa = lookup_queued_alarm (cqa, alarm_id); - g_assert (qa != NULL); - - alarm = cal_component_get_alarm (comp, qa->instance->auid); - g_assert (alarm != NULL); - - cal_component_alarm_get_attach (alarm, &attach); - cal_component_alarm_free (alarm); - - if (attach && icalattach_get_is_url (attach)) { - const char *url; - - url = icalattach_get_url (attach); - g_assert (url != NULL); - - gnome_sound_play (url); /* this sucks */ - } - - if (attach) - icalattach_unref (attach); - - /* We present a notification message in addition to playing the sound */ - display_notification (trigger, cqa, alarm_id, FALSE); -} - -/* Performs notification of a mail alarm */ -static void -mail_notification (time_t trigger, CompQueuedAlarms *cqa, gpointer alarm_id) -{ - GtkWidget *dialog; - - /* FIXME */ - - display_notification (trigger, cqa, alarm_id, FALSE); - - dialog = gnome_warning_dialog (_("Evolution does not support calendar reminders with\n" - "email notifications yet, but this reminder was\n" - "configured to send an email. Evolution will display\n" - "a normal reminder dialog box instead.")); - gnome_dialog_run (GNOME_DIALOG (dialog)); -} - -/* Performs notification of a procedure alarm */ -static gboolean -procedure_notification_dialog (const char *cmd, const char *url) -{ - GtkWidget *dialog, *label, *checkbox; - char *str; - int btn; - - if (is_blessed_program (url)) - return TRUE; - - dialog = gnome_dialog_new (_("Warning"), - GNOME_STOCK_BUTTON_YES, - GNOME_STOCK_BUTTON_NO, - NULL); - - str = g_strdup_printf (_("An Evolution Calendar reminder is about to trigger. " - "This reminder is configured to run the following program:\n\n" - " %s\n\n" - "Are you sure you want to run this program?"), - cmd); - label = gtk_label_new (str); - gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); - gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT); - gtk_widget_show (label); - gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), - label, TRUE, TRUE, 4); - g_free (str); - - checkbox = gtk_check_button_new_with_label - (_("Do not ask me about this program again.")); - gtk_widget_show (checkbox); - gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), - checkbox, TRUE, TRUE, 4); - - /* Run the dialog */ - btn = gnome_dialog_run (GNOME_DIALOG (dialog)); - if (btn == GNOME_YES && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbox))) - save_blessed_program (url); - gnome_dialog_close (GNOME_DIALOG (dialog)); - - return (btn == GNOME_YES); -} - -static void -procedure_notification (time_t trigger, CompQueuedAlarms *cqa, gpointer alarm_id) -{ - QueuedAlarm *qa; - CalComponent *comp; - CalComponentAlarm *alarm; - CalComponentText description; - icalattach *attach; - const char *url; - char *cmd; - int result; - - comp = cqa->alarms->comp; - qa = lookup_queued_alarm (cqa, alarm_id); - g_assert (qa != NULL); - - alarm = cal_component_get_alarm (comp, qa->instance->auid); - g_assert (alarm != NULL); - - cal_component_alarm_get_attach (alarm, &attach); - cal_component_alarm_get_description (alarm, &description); - cal_component_alarm_free (alarm); - - /* If the alarm has no attachment, simply display a notification dialog. */ - if (!attach) - goto fallback; - - if (!icalattach_get_is_url (attach)) { - icalattach_unref (attach); - goto fallback; - } - - url = icalattach_get_url (attach); - g_assert (url != NULL); - - /* Ask for confirmation before executing the stuff */ - if (description.value) - cmd = g_strconcat (url, " ", description.value, NULL); - else - cmd = (char *) url; - - result = 0; - if (procedure_notification_dialog (cmd, url)) - result = gnome_execute_shell (NULL, cmd); - - if (cmd != (char *) url) - g_free (cmd); - - icalattach_unref (attach); - - /* Fall back to display notification if we got an error */ - if (result < 0) - goto fallback; - - remove_queued_alarm (cqa, alarm_id); - return; - - fallback: - - display_notification (trigger, cqa, alarm_id, FALSE); -} - - - -/** - * alarm_queue_init: - * - * Initializes the alarm queueing system. This should be called near the - * beginning of the program. - **/ -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 (); - - saved_notification_time = get_saved_notification_time (); - if (saved_notification_time == -1) { - saved_notification_time = time (NULL); - save_notification_time (saved_notification_time); - } - - 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_get_load_state (client) != CAL_CLIENT_LOAD_LOADED) - gtk_signal_connect (GTK_OBJECT (client), "cal_opened", - GTK_SIGNAL_FUNC (cal_opened_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_get_load_state (client) == CAL_CLIENT_LOAD_LOADED) { - load_alarms_for_today (ca); - load_missed_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); -} diff --git a/calendar/gui/alarm-notify/alarm-queue.h b/calendar/gui/alarm-notify/alarm-queue.h deleted file mode 100644 index a37119145f..0000000000 --- a/calendar/gui/alarm-notify/alarm-queue.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Evolution calendar - Alarm queueing engine - * - * 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#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 8c6c4c59cd..0000000000 --- a/calendar/gui/alarm-notify/alarm.c +++ /dev/null @@ -1,305 +0,0 @@ -/* Evolution calendar - Low-level alarm timer mechanism - * - * Copyright (C) 2000 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#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" - - - -/* Our glib timeout */ -static guint timeout_id; - -/* The list of pending alarms */ -static GList *alarms = NULL; - -/* A queued alarm structure */ -typedef struct { - time_t trigger; - AlarmFunction alarm_fn; - gpointer data; - AlarmDestroyNotify destroy_notify_fn; -} AlarmRecord; - -static void setup_timeout (time_t now); - - - -/* Removes the head alarm from the queue. Does not touch the timeout_id. */ -static void -pop_alarm (void) -{ - AlarmRecord *ar; - GList *l; - - g_assert (alarms != NULL); - - ar = alarms->data; - - l = alarms; - alarms = g_list_remove_link (alarms, l); - g_list_free_1 (l); - - g_free (ar); -} - -/* Callback from the alarm timeout */ -static gboolean -alarm_ready_cb (gpointer data) -{ - time_t now; - - g_assert (alarms != NULL); - timeout_id = 0; - - now = time (NULL); - - while (alarms) { - AlarmRecord *notify_id, *ar; - AlarmRecord ar_copy; - - ar = alarms->data; - - if (ar->trigger > now) - break; - - notify_id = ar; - - ar_copy = *ar; - ar = &ar_copy; - - pop_alarm (); /* This will free the original AlarmRecord; that's why we copy it */ - - (* ar->alarm_fn) (notify_id, ar->trigger, ar->data); - - if (ar->destroy_notify_fn) - (* ar->destroy_notify_fn) (notify_id, ar->data); - } - - if (alarms) { - /* We need this check because one of the alarm_fn above may have - * re-entered and added an alarm of its own, so the timer will - * already be set up. - */ - if (timeout_id == 0) - setup_timeout (now); - } else - g_assert (timeout_id == 0); - - return FALSE; -} - -/* Sets up a timeout for the next minute. We do not need to be concerned with - * timezones here, as this is just a periodic check on the alarm queue. - */ -static void -setup_timeout (time_t now) -{ - time_t next, diff; - struct tm tm; - - g_assert (timeout_id == 0); - g_assert (alarms != NULL); - - tm = *localtime (&now); - tm.tm_sec = 0; - tm.tm_min++; /* next minute */ - - next = mktime (&tm); - g_assert (next != -1); - - diff = next - now; - - g_assert (diff >= 0); - timeout_id = g_timeout_add (diff * 1000, alarm_ready_cb, NULL); -} - -/* Used from g_list_insert_sorted(); compares the trigger times of two AlarmRecord structures. */ -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 void -queue_alarm (AlarmRecord *ar) -{ - time_t now; - AlarmRecord *old_head; - - if (alarms) { - g_assert (timeout_id != 0); - - old_head = alarms->data; - } else { - g_assert (timeout_id == 0); - - old_head = NULL; - } - - alarms = g_list_insert_sorted (alarms, ar, compare_alarm_by_time); - - if (old_head == alarms->data) - return; - - /* Set the timer for removal upon activation */ - - if (!old_head) { - now = time (NULL); - setup_timeout (now); - } -} - - - -/** - * 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) -{ - AlarmRecord *ar; - - g_return_val_if_fail (trigger != -1, NULL); - g_return_val_if_fail (alarm_fn != NULL, NULL); - - ar = g_new (AlarmRecord, 1); - ar->trigger = trigger; - ar->alarm_fn = alarm_fn; - ar->data = data; - ar->destroy_notify_fn = destroy_notify_fn; - - queue_alarm (ar); - - return ar; -} - -/** - * alarm_remove: - * @alarm: A queued alarm identifier. - * - * Removes an alarm from the alarm queue. - **/ -void -alarm_remove (gpointer alarm) -{ - AlarmRecord *notify_id, *ar; - AlarmRecord ar_copy; - AlarmRecord *old_head; - GList *l; - - 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; - - notify_id = ar; - - if (old_head == ar) { - ar_copy = *ar; - ar = &ar_copy; - pop_alarm (); /* This will free the original AlarmRecord; that's why we copy it */ - } else { - alarms = g_list_remove_link (alarms, l); - g_list_free_1 (l); - } - - /* Reset the timeout */ - - g_assert (timeout_id != 0); - - if (!alarms) { - g_source_remove (timeout_id); - timeout_id = 0; - } - - /* Notify about destructiono of the alarm */ - - if (ar->destroy_notify_fn) - (* ar->destroy_notify_fn) (notify_id, ar->data); - -} - -/** - * alarm_done: - * - * Terminates the alarm timer mechanism. This should be called at the end of - * the program. - **/ -void -alarm_done (void) -{ - GList *l; - - if (timeout_id == 0) { - g_assert (alarms == NULL); - return; - } - - g_assert (alarms != NULL); - - g_source_remove (timeout_id); - timeout_id = 0; - - 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; -} diff --git a/calendar/gui/alarm-notify/alarm.h b/calendar/gui/alarm-notify/alarm.h deleted file mode 100644 index 23fde886c9..0000000000 --- a/calendar/gui/alarm-notify/alarm.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Evolution calendar - Low-level alarm timer mechanism - * - * Copyright (C) 2000 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#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_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/config-data.c b/calendar/gui/alarm-notify/config-data.c deleted file mode 100644 index 71170a3ad6..0000000000 --- a/calendar/gui/alarm-notify/config-data.c +++ /dev/null @@ -1,112 +0,0 @@ -/* Evolution calendar - Configuration values for the alarm notification daemon - * - * 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "config-data.h" -#include "save.h" - - - -/* Whether we have initied ourselves by reading the data from the configuration engine */ -static gboolean inited; - -/* Configuration values */ -static icaltimezone *local_timezone; -static gboolean use_24_hour_format; - - - -/* Copied from ../calendar-config.c; returns whether the locale has 'am' and - * 'pm' strings defined. - */ -static gboolean -locale_supports_12_hour_format (void) -{ - char s[16]; - time_t t = 0; - - strftime (s, sizeof s, "%p", gmtime (&t)); - return s[0] != '\0'; -} - -/* Ensures that the configuration values have been read */ -static void -ensure_inited (void) -{ - Bonobo_ConfigDatabase db; - char *location; - - if (inited) - return; - - inited = TRUE; - - db = get_config_db (); - if (db == CORBA_OBJECT_NIL) { - /* This sucks */ - local_timezone = icaltimezone_get_utc_timezone (); - - /* This sucks as well */ - use_24_hour_format = TRUE; - - return; - } - - location = bonobo_config_get_string_with_default (db, - "/Calendar/Display/Timezone", "UTC", NULL); - if (location && location[0]) { - local_timezone = icaltimezone_get_builtin_timezone (location); - } else { - local_timezone = icaltimezone_get_utc_timezone (); - } - g_free (location); - - if (locale_supports_12_hour_format ()) { - /* Wasn't the whole point of a configuration engine *NOT* to - * have apps specify their own stupid defaults everywhere, but - * just in a schema file? - */ - use_24_hour_format = bonobo_config_get_boolean_with_default ( - db, - "/Calendar/Display/Use24HourFormat", FALSE, NULL); - } else - use_24_hour_format = TRUE; - - discard_config_db (db); -} - -icaltimezone * -config_data_get_timezone (void) -{ - ensure_inited (); - - return local_timezone; -} - -gboolean -config_data_get_24_hour_format (void) -{ - ensure_inited (); - - return use_24_hour_format; -} diff --git a/calendar/gui/alarm-notify/config-data.h b/calendar/gui/alarm-notify/config-data.h deleted file mode 100644 index 06a73ba562..0000000000 --- a/calendar/gui/alarm-notify/config-data.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Evolution calendar - Configuration values for the alarm notification daemon - * - * 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef CONFIG_DATA_H -#define CONFIG_DATA_H - -#include <glib.h> -#include <ical.h> - -icaltimezone *config_data_get_timezone (void); - -gboolean config_data_get_24_hour_format (void); - -#endif diff --git a/calendar/gui/alarm-notify/notify-main.c b/calendar/gui/alarm-notify/notify-main.c deleted file mode 100644 index 8b6daab254..0000000000 --- a/calendar/gui/alarm-notify/notify-main.c +++ /dev/null @@ -1,205 +0,0 @@ -/* Evolution calendar - Alarm notification service main file - * - * Copyright (C) 2000 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <glib.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <libgnomeui/gnome-init.h> -#include <libgnomevfs/gnome-vfs-init.h> -#include <glade/glade.h> -#include <bonobo/bonobo-main.h> -#include <bonobo/bonobo-generic-factory.h> -#include <liboaf/liboaf.h> -#include "alarm.h" -#include "alarm-queue.h" -#include "alarm-notify.h" -#include "save.h" - - - -static GnomeClient *master_client = NULL; - -static BonoboGenericFactory *factory; - -static AlarmNotify *alarm_notify_service; - - -/* Callback for the master client's "die" signal. We must terminate the daemon - * since the session is ending. - */ -static void -client_die_cb (GnomeClient *client) -{ - gtk_main_quit (); -} - -/* Sees if a session manager is present. If so, it tells the SM how to restart - * the daemon when the session starts. It also sets the die callback so that - * the daemon can terminate properly when the session ends. - */ -static void -set_session_parameters (char **argv) -{ - int flags; - char *args[2]; - - master_client = gnome_master_client (); - flags = gnome_client_get_flags (master_client); - - if (!(flags & GNOME_CLIENT_IS_CONNECTED)) - return; - - /* The daemon should always be started up by the session manager when - * the session starts. The daemon will take care of loading whatever - * calendars it was told to load. - */ - gnome_client_set_restart_style (master_client, GNOME_RESTART_ANYWAY); - - args[0] = argv[0]; - args[1] = NULL; - - gnome_client_set_restart_command (master_client, 1, args); - - gtk_signal_connect (GTK_OBJECT (master_client), "die", - GTK_SIGNAL_FUNC (client_die_cb), NULL); -} - -/* Creates the singleton alarm notify service object */ -static gboolean -init_alarm_notify_service (void) -{ - g_assert (alarm_notify_service == NULL); - - alarm_notify_service = alarm_notify_new (); - return (alarm_notify_service != NULL); -} - -/* 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) -{ - g_assert (alarm_notify_service != NULL); - - bonobo_object_ref (BONOBO_OBJECT (alarm_notify_service)); - return BONOBO_OBJECT (alarm_notify_service); -} - -/* Loads the calendars that the alarm daemon has been told to load in the past */ -static void -load_calendars (void) -{ - GPtrArray *uris; - int i; - - uris = get_calendars_to_load (); - if (!uris) { - g_message ("load_calendars(): Could not get the list of calendars to load"); - return; - } - - for (i = 0; i < uris->len; i++) { - char *uri; - CORBA_Environment ev; - - uri = uris->pdata[i]; - - CORBA_exception_init (&ev); - alarm_notify_add_calendar (alarm_notify_service, uri, FALSE, &ev); - - if (ev._major == CORBA_USER_EXCEPTION) { - char *ex_id; - - ex_id = CORBA_exception_id (&ev); - if (strcmp (ex_id, ex_GNOME_Evolution_Calendar_AlarmNotify_InvalidURI) == 0) - g_message ("load_calendars(): Invalid URI `%s'; will not load " - "that calendar.", uri); - else if (strcmp (ex_id, - ex_GNOME_Evolution_Calendar_AlarmNotify_BackendContactError) - == 0) - g_message ("load_calendars(): Could not contact the backend " - "while trying to load `%s'", uri); - } else if (ev._major != CORBA_NO_EXCEPTION) - g_message ("load_calendars(): Exception while loading calendar `%s'", uri); - - CORBA_exception_free (&ev); - - g_free (uri); - } - - g_ptr_array_free (uris, TRUE); -} - -int -main (int argc, char **argv) -{ - free (malloc (8)); - - 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")); - - if (!gnome_vfs_init ()) - g_error (_("Could not initialize gnome-vfs")); - - glade_gnome_init (); - - alarm_queue_init (); - - if (!init_alarm_notify_service ()) - g_error (_("Could not create the alarm notify service")); - - factory = bonobo_generic_factory_new ("OAFIID:GNOME_Evolution_Calendar_AlarmNotify_Factory", - alarm_notify_factory_fn, NULL); - if (!factory) - g_error (_("Could not create the alarm notify service factory")); - - set_session_parameters (argv); - - load_calendars (); - - bonobo_main (); - - bonobo_object_unref (BONOBO_OBJECT (factory)); - factory = NULL; - - /* FIXME: free the alarm_notify_service */ - - alarm_queue_done (); - alarm_done (); - - gnome_vfs_shutdown (); - - return 0; -} diff --git a/calendar/gui/alarm-notify/save.c b/calendar/gui/alarm-notify/save.c deleted file mode 100644 index 92dc94b65a..0000000000 --- a/calendar/gui/alarm-notify/save.c +++ /dev/null @@ -1,315 +0,0 @@ -/* Evolution calendar - Functions to save alarm notification times - * - * 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <bonobo/bonobo-arg.h> -#include <bonobo/bonobo-exception.h> -#include <bonobo/bonobo-moniker-util.h> -#include "evolution-calendar.h" -#include "save.h" - - - -/* Key names for the configuration values */ - -#define KEY_LAST_NOTIFICATION_TIME "/Calendar/AlarmNotify/LastNotificationTime" -#define KEY_NUM_CALENDARS_TO_LOAD "/Calendar/AlarmNotify/NumCalendarsToLoad" -#define BASE_KEY_CALENDAR_TO_LOAD "/Calendar/AlarmNotify/CalendarToLoad" -#define KEY_NUM_BLESSED_PROGRAMS "/Calendar/AlarmNotify/NumBlessedPrograms" -#define BASE_KEY_BLESSED_PROGRAM "/Calendar/AlarmNotify/BlessedProgram" - - - -/* Tries to get the config database object; returns CORBA_OBJECT_NIL on failure. */ -Bonobo_ConfigDatabase -get_config_db (void) -{ - CORBA_Environment ev; - Bonobo_ConfigDatabase db; - - CORBA_exception_init (&ev); - - db = bonobo_get_object ("wombat:", "Bonobo/ConfigDatabase", &ev); - if (BONOBO_EX (&ev) || db == CORBA_OBJECT_NIL) { - g_message ("get_config_db(): Could not get the config database object"); - db = CORBA_OBJECT_NIL; - } - - CORBA_exception_free (&ev); - return db; -} - -/* Syncs a database and unrefs it */ -void -discard_config_db (Bonobo_ConfigDatabase db) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - Bonobo_ConfigDatabase_sync (db, &ev); - if (BONOBO_EX (&ev)) - g_message ("discard_config_db(): Got an exception during the sync command"); - - CORBA_exception_free (&ev); - - CORBA_exception_init (&ev); - - bonobo_object_release_unref (db, &ev); - if (BONOBO_EX (&ev)) - g_message ("discard_config_db(): Could not release/unref the database"); - - CORBA_exception_free (&ev); -} - -/** - * save_notification_time: - * @t: A time value. - * - * Saves the last notification time so that it can be fetched the next time the - * alarm daemon is run. This way the daemon can show alarms that should have - * triggered while it was not running. - **/ -void -save_notification_time (time_t t) -{ - Bonobo_ConfigDatabase db; - CORBA_Environment ev; - - g_return_if_fail (t != -1); - - db = get_config_db (); - if (db == CORBA_OBJECT_NIL) - return; - - CORBA_exception_init (&ev); - - bonobo_config_set_long (db, KEY_LAST_NOTIFICATION_TIME, (long) t, &ev); - if (BONOBO_EX (&ev)) - g_message ("save_notification_time(): Could not save the value"); - - CORBA_exception_free (&ev); - - discard_config_db (db); -} - -/** - * get_saved_notification_time: - * - * Queries the last saved value for alarm notification times. - * - * Return value: The last saved value, or -1 if no value had been saved before. - **/ -time_t -get_saved_notification_time (void) -{ - Bonobo_ConfigDatabase db; - long t; - - db = get_config_db (); - if (db == CORBA_OBJECT_NIL) - return -1; - - t = bonobo_config_get_long_with_default (db, KEY_LAST_NOTIFICATION_TIME, -1, NULL); - - discard_config_db (db); - - return (time_t) t; -} - -/** - * save_calendars_to_load: - * @uris: A list of URIs of calendars. - * - * Saves the list of calendars that should be loaded the next time the alarm - * daemon starts up. - **/ -void -save_calendars_to_load (GPtrArray *uris) -{ - Bonobo_ConfigDatabase db; - CORBA_Environment ev; - int len, i; - - g_return_if_fail (uris != NULL); - - db = get_config_db (); - if (db == CORBA_OBJECT_NIL) - return; - - len = uris->len; - - CORBA_exception_init (&ev); - - bonobo_config_set_long (db, KEY_NUM_CALENDARS_TO_LOAD, len, &ev); - if (BONOBO_EX (&ev)) - g_warning ("Cannot save config key %s -- %s", KEY_NUM_CALENDARS_TO_LOAD, BONOBO_EX_ID (&ev)); - - for (i = 0; i < len; i++) { - const char *uri; - char *key; - - uri = uris->pdata[i]; - - key = g_strdup_printf ("%s%d", BASE_KEY_CALENDAR_TO_LOAD, i); - bonobo_config_set_string (db, key, uri, &ev); - if (BONOBO_EX (&ev)) - g_warning ("Cannot save config key %s -- %s", key, BONOBO_EX_ID (&ev)); - g_free (key); - } - - CORBA_exception_free (&ev); - - discard_config_db (db); -} - -/** - * get_calendars_to_load: - * - * Gets the list of calendars that should be loaded when the alarm daemon starts - * up. - * - * Return value: A list of URIs, or NULL if the value could not be retrieved. - **/ -GPtrArray * -get_calendars_to_load (void) -{ - Bonobo_ConfigDatabase db; - GPtrArray *uris; - int len, i; - - db = get_config_db (); - if (db == CORBA_OBJECT_NIL) - return NULL; - - /* Getting the default value below is not necessarily an error, as we - * may not have saved the list of calendar yet. - */ - - len = bonobo_config_get_long_with_default (db, KEY_NUM_CALENDARS_TO_LOAD, 0, NULL); - - uris = g_ptr_array_new (); - g_ptr_array_set_size (uris, len); - - for (i = 0; i < len; i++) { - char *key; - gboolean used_default; - - key = g_strdup_printf ("%s%d", BASE_KEY_CALENDAR_TO_LOAD, i); - uris->pdata[i] = bonobo_config_get_string_with_default (db, key, "", &used_default); - if (used_default) - g_message ("get_calendars_to_load(): Could not read calendar name %d", i); - - g_free (key); - } - - return uris; -} - -/** - * save_blessed_program: - * @program: a program name - * - * Saves a program name as "blessed" - **/ -void -save_blessed_program (const char *program) -{ - Bonobo_ConfigDatabase db; - CORBA_Environment ev; - char *key; - int len; - - g_return_if_fail (program != NULL); - - db = get_config_db (); - if (db == CORBA_OBJECT_NIL) - return; - - /* Up the number saved */ - len = bonobo_config_get_long_with_default (db, KEY_NUM_BLESSED_PROGRAMS, 0, NULL); - len++; - - bonobo_config_set_long (db, KEY_NUM_BLESSED_PROGRAMS, len, &ev); - if (BONOBO_EX (&ev)) - g_warning ("Cannot save config key %s -- %s", KEY_NUM_BLESSED_PROGRAMS, BONOBO_EX_ID (&ev)); - - /* Save the program name */ - key = g_strdup_printf ("%s%d", BASE_KEY_BLESSED_PROGRAM, len - 1); - bonobo_config_set_string (db, key, program, &ev); - if (BONOBO_EX (&ev)) - g_warning ("Cannot save config key %s -- %s", key, BONOBO_EX_ID (&ev)); - g_free (key); - - CORBA_exception_free (&ev); - - discard_config_db (db); -} - -/** - * is_blessed_program: - * @program: a program name - * - * Checks to see if a program is blessed - * - * Return value: TRUE if program is blessed, FALSE otherwise - **/ -gboolean -is_blessed_program (const char *program) -{ - Bonobo_ConfigDatabase db; - int len, i; - - g_return_val_if_fail (program != NULL, FALSE); - - db = get_config_db (); - if (db == CORBA_OBJECT_NIL) - return FALSE; - - /* Getting the default value below is not necessarily an error, as we - * may not have saved the list of calendar yet. - */ - - len = bonobo_config_get_long_with_default (db, KEY_NUM_BLESSED_PROGRAMS, 0, NULL); - - for (i = 0; i < len; i++) { - char *key, *value; - gboolean used_default; - - key = g_strdup_printf ("%s%d", BASE_KEY_BLESSED_PROGRAM, i); - value = bonobo_config_get_string_with_default (db, key, "", &used_default); - if (used_default) - g_message ("get_calendars_to_load(): Could not read calendar name %d", i); - - if (value != NULL && !strcmp (value, program)) { - g_free (key); - g_free (value); - return TRUE; - } - - g_free (key); - g_free (value); - } - - return FALSE; -} diff --git a/calendar/gui/alarm-notify/save.h b/calendar/gui/alarm-notify/save.h deleted file mode 100644 index 50371e0a5b..0000000000 --- a/calendar/gui/alarm-notify/save.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Evolution calendar - Functions to save alarm notification times - * - * 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef SAVE_H -#define SAVE_H - -#include <time.h> -#include <bonobo-conf/bonobo-config-database.h> - -Bonobo_ConfigDatabase get_config_db (void); -void discard_config_db (Bonobo_ConfigDatabase db); - -void save_notification_time (time_t t); -time_t get_saved_notification_time (void); - -void save_calendars_to_load (GPtrArray *uris); -GPtrArray *get_calendars_to_load (void); - -void save_blessed_program (const char *program); -gboolean is_blessed_program (const char *program); - -#endif diff --git a/calendar/gui/cal-search-bar.c b/calendar/gui/cal-search-bar.c deleted file mode 100644 index 2483b2b126..0000000000 --- a/calendar/gui/cal-search-bar.c +++ /dev/null @@ -1,544 +0,0 @@ -/* Evolution calendar - Search bar widget for calendar views - * - * Copyright (C) 2001 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <string.h> -#include <glib.h> -#include <gtk/gtkmenu.h> -#include <gtk/gtkmenuitem.h> -#include <gtk/gtkoptionmenu.h> -#include <gtk/gtksignal.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <gal/widgets/e-unicode.h> -#include "cal-search-bar.h" - - - -/* IDs and option items for the ESearchBar */ -enum { - SEARCH_ANY_FIELD_CONTAINS, - SEARCH_SUMMARY_CONTAINS, - SEARCH_DESCRIPTION_CONTAINS, - SEARCH_COMMENT_CONTAINS, - SEARCH_CATEGORY_IS, -}; - -static ESearchBarItem search_option_items[] = { - { N_("Any field contains"), SEARCH_ANY_FIELD_CONTAINS, NULL }, - { N_("Summary contains"), SEARCH_SUMMARY_CONTAINS, NULL }, - { N_("Description contains"), SEARCH_DESCRIPTION_CONTAINS, NULL }, - { N_("Comment contains"), SEARCH_COMMENT_CONTAINS, NULL }, - { N_("Category is"), SEARCH_CATEGORY_IS, NULL }, - { NULL, -1, NULL } -}; - -/* IDs for the categories suboptions */ -#define CATEGORIES_ALL 0 -#define CATEGORIES_UNMATCHED 1 -#define CATEGORIES_OFFSET 3 - -/* Private part of the CalSearchBar structure */ -struct CalSearchBarPrivate { - /* Array of categories */ - GPtrArray *categories; -}; - - - -static void cal_search_bar_class_init (CalSearchBarClass *class); -static void cal_search_bar_init (CalSearchBar *cal_search); -static void cal_search_bar_destroy (GtkObject *object); - -static void cal_search_bar_search_activated (ESearchBar *search); - -static ESearchBarClass *parent_class = NULL; - -/* Signal IDs */ -enum { - SEXP_CHANGED, - CATEGORY_CHANGED, - LAST_SIGNAL -}; - -static guint cal_search_bar_signals[LAST_SIGNAL] = { 0 }; - - - -/** - * cal_search_bar_get_type: - * - * Registers the #CalSearchBar class if necessary and returns the type ID - * associated to it. - * - * Return value: The type ID of the #CalSearchBar class. - **/ -GtkType -cal_search_bar_get_type (void) -{ - static GtkType cal_search_bar_type = 0; - - if (!cal_search_bar_type) { - static const GtkTypeInfo cal_search_bar_info = { - "CalSearchBar", - sizeof (CalSearchBar), - sizeof (CalSearchBarClass), - (GtkClassInitFunc) cal_search_bar_class_init, - (GtkObjectInitFunc) cal_search_bar_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - cal_search_bar_type = gtk_type_unique (E_SEARCH_BAR_TYPE, &cal_search_bar_info); - } - - return cal_search_bar_type; -} - -/* Class initialization function for the calendar search bar */ -static void -cal_search_bar_class_init (CalSearchBarClass *class) -{ - ESearchBarClass *e_search_bar_class; - GtkObjectClass *object_class; - - e_search_bar_class = (ESearchBarClass *) class; - object_class = (GtkObjectClass *) class; - - parent_class = gtk_type_class (E_SEARCH_BAR_TYPE); - - cal_search_bar_signals[SEXP_CHANGED] = - gtk_signal_new ("sexp_changed", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (CalSearchBarClass, sexp_changed), - gtk_marshal_NONE__STRING, - GTK_TYPE_NONE, 1, - GTK_TYPE_STRING); - - cal_search_bar_signals[CATEGORY_CHANGED] = - gtk_signal_new ("category_changed", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (CalSearchBarClass, category_changed), - gtk_marshal_NONE__STRING, - GTK_TYPE_NONE, 1, - GTK_TYPE_STRING); - - gtk_object_class_add_signals (object_class, cal_search_bar_signals, LAST_SIGNAL); - - class->sexp_changed = NULL; - class->category_changed = NULL; - - e_search_bar_class->search_activated = cal_search_bar_search_activated; - - object_class->destroy = cal_search_bar_destroy; -} - -/* Object initialization function for the calendar search bar */ -static void -cal_search_bar_init (CalSearchBar *cal_search) -{ - CalSearchBarPrivate *priv; - - priv = g_new (CalSearchBarPrivate, 1); - cal_search->priv = priv; - - priv->categories = g_ptr_array_new (); - g_ptr_array_set_size (priv->categories, 0); -} - -/* Frees an array of categories */ -static void -free_categories (GPtrArray *categories) -{ - int i; - - for (i = 0; i < categories->len; i++) { - g_assert (categories->pdata[i] != NULL); - g_free (categories->pdata[i]); - } - - g_ptr_array_free (categories, TRUE); -} - -/* Destroy handler for the calendar search bar */ -static void -cal_search_bar_destroy (GtkObject *object) -{ - CalSearchBar *cal_search; - CalSearchBarPrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_CAL_SEARCH_BAR (object)); - - cal_search = CAL_SEARCH_BAR (object); - priv = cal_search->priv; - - if (priv->categories) { - free_categories (priv->categories); - priv->categories = NULL; - } - - g_free (priv); - cal_search->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - - -/* Emits the "sexp_changed" signal for the calendar search bar */ -static void -notify_sexp_changed (CalSearchBar *cal_search, const char *sexp) -{ - gtk_signal_emit (GTK_OBJECT (cal_search), cal_search_bar_signals[SEXP_CHANGED], - sexp); -} - -/* Returns the string of the currently selected category, NULL for "Unmatched", - * or (const char *) 1 for "All". - */ -static const char * -get_current_category (CalSearchBar *cal_search) -{ - CalSearchBarPrivate *priv; - int id, subid; - - priv = cal_search->priv; - - g_assert (priv->categories != NULL); - - id = e_search_bar_get_item_id (E_SEARCH_BAR (cal_search)); - if (id != SEARCH_CATEGORY_IS) - return NULL; - - subid = e_search_bar_get_subitem_id (E_SEARCH_BAR (cal_search)); - if (subid == CATEGORIES_ALL) - return (const char *) 1; - else if (subid == CATEGORIES_UNMATCHED) - return NULL; - else { - int i; - - i = subid - CATEGORIES_OFFSET; - g_assert (i >= 0 && i < priv->categories->len); - - return priv->categories->pdata[i]; - } -} - -/* Sets the query string to be (contains? "field" "text") */ -static void -notify_query_contains (CalSearchBar *cal_search, const char *field) -{ - char *text; - char *sexp; - - text = e_search_bar_get_text (E_SEARCH_BAR (cal_search)); - if (!text) - return; /* This is an error in the UTF8 conversion, not an empty string! */ - - sexp = g_strdup_printf ("(contains? \"%s\" \"%s\")", field, text); - g_free (text); - - notify_sexp_changed (cal_search, sexp); - g_free (sexp); -} - -/* Returns a sexp for the selected category in the drop-down menu. The "All" - * option is returned as (const char *) 1, and the "Unfiled" option is returned - * as NULL. - */ -static char * -get_category_sexp (CalSearchBar *cal_search) -{ - const char *category; - - category = get_current_category (cal_search); - - if (category == NULL) - return g_strdup ("(has-categories? #f)"); /* Unfiled items */ - else if (category == (const char *) 1) - return NULL; /* All items */ - else - return g_strdup_printf ("(has-categories? \"%s\")", category); /* Specific category */ -} - -/* Sets the query string to the appropriate match for categories */ -static void -notify_category_is (CalSearchBar *cal_search) -{ - char *sexp; - - sexp = get_category_sexp (cal_search); - if (!sexp) - notify_sexp_changed (cal_search, "#t"); /* Match all */ - else - notify_sexp_changed (cal_search, sexp); - - if (sexp) - g_free (sexp); -} - -/* Creates a new query from the values in the widgets and notifies upstream */ -static void -regen_query (CalSearchBar *cal_search) -{ - CalSearchBarPrivate *priv; - int id; - const char *category; - - priv = cal_search->priv; - - /* Fetch the data from the ESearchBar's entry widgets */ - - id = e_search_bar_get_item_id (E_SEARCH_BAR (cal_search)); - - /* Generate the different types of queries */ - - switch (id) { - case SEARCH_ANY_FIELD_CONTAINS: - notify_query_contains (cal_search, "any"); - break; - - case SEARCH_SUMMARY_CONTAINS: - notify_query_contains (cal_search, "summary"); - break; - - case SEARCH_DESCRIPTION_CONTAINS: - notify_query_contains (cal_search, "description"); - break; - - case SEARCH_COMMENT_CONTAINS: - notify_query_contains (cal_search, "comment"); - break; - - case SEARCH_CATEGORY_IS: - notify_category_is (cal_search); - - category = cal_search_bar_get_category (cal_search); - gtk_signal_emit (GTK_OBJECT (cal_search), cal_search_bar_signals[CATEGORY_CHANGED], - category); - break; - - default: - g_assert_not_reached (); - } -} - -/* search_activated handler for the calendar search bar */ -static void -cal_search_bar_search_activated (ESearchBar *search) -{ - CalSearchBar *cal_search; - - cal_search = CAL_SEARCH_BAR (search); - regen_query (cal_search); -} - - - -/* Creates the suboptions menu for the ESearchBar with the list of categories */ -static void -make_suboptions (CalSearchBar *cal_search) -{ - CalSearchBarPrivate *priv; - ESearchBarSubitem *subitems; - int i; - - priv = cal_search->priv; - - g_assert (priv->categories != NULL); - - /* Categories plus "all", "unmatched", separator, terminator */ - subitems = g_new (ESearchBarSubitem, priv->categories->len + 3 + 1); - - /* All, unmatched, separator */ - - subitems[0].text = _("Any Category"); - subitems[0].id = CATEGORIES_ALL; - subitems[0].translate = FALSE; - - subitems[1].text = _("Unmatched"); - subitems[1].id = CATEGORIES_UNMATCHED; - subitems[1].translate = FALSE; - - /* All the other items */ - - if (priv->categories->len > 0) { - subitems[2].text = NULL; /* separator */ - subitems[2].id = 0; - - for (i = 0; i < priv->categories->len; i++) { - const char *category; - char *str; - - category = priv->categories->pdata[i]; - str = e_utf8_to_gtk_string (GTK_WIDGET (cal_search), category); - if (!str) - str = g_strdup (""); - - subitems[i + CATEGORIES_OFFSET].text = str; - subitems[i + CATEGORIES_OFFSET].id = i + CATEGORIES_OFFSET; - subitems[i + CATEGORIES_OFFSET].translate = FALSE; - } - - subitems[i + CATEGORIES_OFFSET].id = -1; /* terminator */ - } else - subitems[2].id = -1; /* terminator */ - - e_search_bar_set_suboption (E_SEARCH_BAR (cal_search), SEARCH_CATEGORY_IS, subitems); - - /* Free the strings */ - for (i = 0; i < priv->categories->len; i++) - g_free (subitems[i + CATEGORIES_OFFSET].text); - - g_free (subitems); -} - -/** - * cal_search_bar_construct: - * @cal_search: A calendar search bar. - * - * Constructs a calendar search bar by binding its menu and option items. - * - * Return value: The same value as @cal_search. - **/ -CalSearchBar * -cal_search_bar_construct (CalSearchBar *cal_search) -{ - g_return_val_if_fail (cal_search != NULL, NULL); - g_return_val_if_fail (IS_CAL_SEARCH_BAR (cal_search), NULL); - - e_search_bar_construct (E_SEARCH_BAR (cal_search), NULL, search_option_items); - make_suboptions (cal_search); - - e_search_bar_set_ids (E_SEARCH_BAR (cal_search), SEARCH_CATEGORY_IS, CATEGORIES_ALL); - - return cal_search; -} - -/** - * cal_search_bar_new: - * - * Creates a new calendar search bar. - * - * Return value: A newly-created calendar search bar. You should connect to the - * "sexp_changed" signal to monitor changes in the generated sexps. - **/ -GtkWidget * -cal_search_bar_new (void) -{ - CalSearchBar *cal_search; - - cal_search = gtk_type_new (TYPE_CAL_SEARCH_BAR); - return GTK_WIDGET (cal_search_bar_construct (cal_search)); -} - -/* Used from qsort() */ -static int -compare_categories_cb (const void *a, const void *b) -{ - const char **ca, **cb; - - ca = (const char **) a; - cb = (const char **) b; - - /* FIXME: should use some utf8 strcoll() thingy */ - return strcmp (*ca, *cb); -} - -/* Creates a sorted array of categories based on the original one; copies the - * string values. - */ -static GPtrArray * -sort_categories (GPtrArray *categories) -{ - GPtrArray *c; - int i; - - c = g_ptr_array_new (); - g_ptr_array_set_size (c, categories->len); - - for (i = 0; i < categories->len; i++) - c->pdata[i] = g_strdup (categories->pdata[i]); - - qsort (c->pdata, c->len, sizeof (gpointer), compare_categories_cb); - - return c; -} - -/** - * cal_search_bar_set_categories: - * @cal_search: A calendar search bar. - * @categories: Array of pointers to strings for the category names. - * - * Sets the list of categories that are to be shown in the drop-down list - * of a calendar search bar. The search bar will automatically add an item - * for "unfiled" components, that is, those that have no categories assigned - * to them. - **/ -void -cal_search_bar_set_categories (CalSearchBar *cal_search, GPtrArray *categories) -{ - CalSearchBarPrivate *priv; - - g_return_if_fail (cal_search != NULL); - g_return_if_fail (IS_CAL_SEARCH_BAR (cal_search)); - g_return_if_fail (categories != NULL); - - priv = cal_search->priv; - - g_assert (priv->categories != NULL); - free_categories (priv->categories); - - priv->categories = sort_categories (categories); - make_suboptions (cal_search); -} - -/** - * cal_search_bar_get_category: - * @cal_search: A calendar search bar. - * - * Queries the currently selected category name in a calendar search bar. - * If "All" or "Unfiled" are selected, this function will return NULL. - * - * Return value: Name of the selected category, or NULL if there is no - * selected category. - **/ -const char * -cal_search_bar_get_category (CalSearchBar *cal_search) -{ - const char *category; - - category = get_current_category (cal_search); - - if (!category || category == (const char *) 1) - return NULL; - else - return category; -} diff --git a/calendar/gui/cal-search-bar.h b/calendar/gui/cal-search-bar.h deleted file mode 100644 index 5cfb29fa76..0000000000 --- a/calendar/gui/cal-search-bar.h +++ /dev/null @@ -1,71 +0,0 @@ -/* Evolution calendar - Search bar widget for calendar views - * - * Copyright (C) 2001 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef CAL_SEARCH_BAR_H -#define CAL_SEARCH_BAR_H - -#include <libgnome/gnome-defs.h> -#include "widgets/misc/e-search-bar.h" -#include "widgets/misc/e-filter-bar.h" - -BEGIN_GNOME_DECLS - - - -#define TYPE_CAL_SEARCH_BAR (cal_search_bar_get_type ()) -#define CAL_SEARCH_BAR(obj) (GTK_CHECK_CAST ((obj), TYPE_CAL_SEARCH_BAR, CalSearchBar)) -#define CAL_SEARCH_BAR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_CAL_SEARCH_BAR, \ - CalSearchBarClass)) -#define IS_CAL_SEARCH_BAR(obj) (GTK_CHECK_TYPE ((obj), TYPE_CAL_SEARCH_BAR)) -#define IS_CAL_SEARCH_BAR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), TYPE_CAL_SEARCH_BAR)) - -typedef struct CalSearchBarPrivate CalSearchBarPrivate; - -typedef struct { - ESearchBar search_bar; - - /* Private data */ - CalSearchBarPrivate *priv; -} CalSearchBar; - -typedef struct { - ESearchBarClass parent_class; - - /* Notification signals */ - - void (* sexp_changed) (CalSearchBar *cal_search, const char *sexp); - void (* category_changed) (CalSearchBar *cal_search, const char *category); -} CalSearchBarClass; - -GtkType cal_search_bar_get_type (void); - -CalSearchBar *cal_search_bar_construct (CalSearchBar *cal_search); - -GtkWidget *cal_search_bar_new (void); - -void cal_search_bar_set_categories (CalSearchBar *cal_search, GPtrArray *categories); - -const char *cal_search_bar_get_category (CalSearchBar *cal_search); - - - -END_GNOME_DECLS - -#endif diff --git a/calendar/gui/calendar-commands.c b/calendar/gui/calendar-commands.c deleted file mode 100644 index 30a1654f1b..0000000000 --- a/calendar/gui/calendar-commands.c +++ /dev/null @@ -1,811 +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 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#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 <gdk-pixbuf/gdk-pixbuf.h> -#include <gtk/gtkfilesel.h> -#include <gtk/gtkmain.h> -#include <gtk/gtksignal.h> - -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-util.h> -#include <libgnomeui/gnome-dialog-util.h> -#include <libgnomeui/gnome-messagebox.h> -#include <libgnomeui/gnome-stock.h> -#include <libgnome/gnome-util.h> -#include <libgnome/gnome-i18n.h> -#include <bonobo/bonobo-ui-util.h> -#include <bonobo/bonobo-exception.h> -#include <cal-util/timeutil.h> -#include "shell/Evolution.h" -#include "calendar-commands.h" -#include "calendar-config.h" -#include "gnome-cal.h" -#include "goto.h" -#include "print.h" -#include "dialogs/cal-prefs-dialog.h" -#include "itip-utils.h" -#include "evolution-shell-component-utils.h" - -/* A list of all of the calendars started */ -static GList *all_calendars = NULL; - -/* Focusing information for the calendar view. We have to keep track of this - * ourselves because with Bonobo controls, we may get unpaired focus_out events. - */ -typedef struct { - guint calendar_focused : 1; - guint taskpad_focused : 1; -} FocusData; - -/* Prints the calendar at its current view and time range */ -static void -print (GnomeCalendar *gcal, gboolean preview) -{ - time_t start; - GnomeCalendarViewType view_type; - PrintView print_view; - - gnome_calendar_get_current_time_range (gcal, &start, NULL); - view_type = gnome_calendar_get_view (gcal); - - switch (view_type) { - case GNOME_CAL_DAY_VIEW: - print_view = PRINT_VIEW_DAY; - break; - - case GNOME_CAL_WORK_WEEK_VIEW: - case GNOME_CAL_WEEK_VIEW: - print_view = PRINT_VIEW_WEEK; - break; - - case GNOME_CAL_MONTH_VIEW: - print_view = PRINT_VIEW_MONTH; - break; - - default: - g_assert_not_reached (); - return; - } - - 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); -} - -static void -file_print_preview_cb (BonoboUIComponent *uic, gpointer data, const char *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - print (gcal, TRUE); -} - -/* 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); -} - -void -calendar_goto_today (GnomeCalendar *gcal) -{ - set_clock_cursor (gcal); - gnome_calendar_goto_today (gcal); - set_normal_cursor (gcal); -} - -static void -today_clicked (BonoboUIComponent *uic, gpointer data, const char *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - calendar_goto_today (gcal); -} - -static void -goto_clicked (BonoboUIComponent *uic, gpointer data, const char *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - goto_dialog (gcal); -} - -static void -show_day_view_clicked (BonoboUIComponent *uic, gpointer data, const char *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - gnome_calendar_set_view (gcal, GNOME_CAL_DAY_VIEW, 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, GNOME_CAL_WORK_WEEK_VIEW, 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, GNOME_CAL_WEEK_VIEW, 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, GNOME_CAL_MONTH_VIEW, FALSE, TRUE); -} - - - -static void -cut_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - set_clock_cursor (gcal); - gnome_calendar_cut_clipboard (gcal); - set_normal_cursor (gcal); -} - -static void -copy_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - set_clock_cursor (gcal); - gnome_calendar_copy_clipboard (gcal); - set_normal_cursor (gcal); -} - -static void -paste_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - set_clock_cursor (gcal); - gnome_calendar_paste_clipboard (gcal); - set_normal_cursor (gcal); -} - -static void -delete_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - set_clock_cursor (gcal); - gnome_calendar_delete_selection (gcal); - set_normal_cursor (gcal); -} - -static void -publish_freebusy_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path) -{ - GnomeCalendar *gcal; - CalClient *client; - GList *comp_list; - icaltimezone *utc; - time_t start = time (NULL), end; - - gcal = GNOME_CALENDAR (data); - - utc = icaltimezone_get_utc_timezone (); - start = time_day_begin_with_zone (start, utc); - end = time_add_week_with_zone (start, 6, utc); - - client = gnome_calendar_get_cal_client (gcal); - comp_list = cal_client_get_free_busy (client, NULL, start, end); - if (comp_list) { - GList *l; - - for (l = comp_list; l; l = l->next) { - CalComponent *comp = CAL_COMPONENT (l->data); - itip_send_comp (CAL_COMPONENT_METHOD_PUBLISH, comp, client, NULL); - - gtk_object_unref (GTK_OBJECT (comp)); - } - - g_list_free (comp_list); - } -} - -/* Does a queryInterface on the control's parent control frame for the ShellView interface */ -static GNOME_Evolution_ShellView -get_shell_view_interface (BonoboControl *control) -{ - Bonobo_ControlFrame control_frame; - GNOME_Evolution_ShellView shell_view; - CORBA_Environment ev; - - control_frame = bonobo_control_get_control_frame (control); - - g_assert (control_frame != CORBA_OBJECT_NIL); - - CORBA_exception_init (&ev); - shell_view = Bonobo_Unknown_queryInterface (control_frame, - "IDL:GNOME/Evolution/ShellView:1.0", - &ev); - if (BONOBO_EX (&ev)) { - g_message ("get_shell_view_interface(): " - "Could not queryInterface() on the control frame"); - shell_view = CORBA_OBJECT_NIL; - goto out; - } - - CORBA_exception_free (&ev); - - out: - - return shell_view; -} - -/* Displays the currently displayed time range in the folder bar label on the - shell view, according to which view we are showing. */ -void -calendar_set_folder_bar_label (GnomeCalendar *gcal, BonoboControl *control) -{ - icaltimezone *zone; - struct icaltimetype start_tt, end_tt; - time_t start_time, end_time; - struct tm start_tm, end_tm; - char buffer[512], end_buffer[256]; - GnomeCalendarViewType view; - - gnome_calendar_get_visible_time_range (gcal, &start_time, &end_time); - zone = gnome_calendar_get_timezone (gcal); - - start_tt = icaltime_from_timet_with_zone (start_time, FALSE, zone); - start_tm.tm_year = start_tt.year - 1900; - start_tm.tm_mon = start_tt.month - 1; - start_tm.tm_mday = start_tt.day; - start_tm.tm_hour = start_tt.hour; - start_tm.tm_min = start_tt.minute; - start_tm.tm_sec = start_tt.second; - start_tm.tm_isdst = -1; - start_tm.tm_wday = time_day_of_week (start_tt.day, start_tt.month - 1, - start_tt.year); - - /* Take one off end_time so we don't get an extra day. */ - end_tt = icaltime_from_timet_with_zone (end_time - 1, FALSE, zone); - end_tm.tm_year = end_tt.year - 1900; - end_tm.tm_mon = end_tt.month - 1; - end_tm.tm_mday = end_tt.day; - end_tm.tm_hour = end_tt.hour; - end_tm.tm_min = end_tt.minute; - end_tm.tm_sec = end_tt.second; - end_tm.tm_isdst = -1; - end_tm.tm_wday = time_day_of_week (end_tt.day, end_tt.month - 1, - end_tt.year); - - view = gnome_calendar_get_view (gcal); - - switch (view) { - case GNOME_CAL_DAY_VIEW: - case GNOME_CAL_WORK_WEEK_VIEW: - case GNOME_CAL_WEEK_VIEW: - if (start_tm.tm_year == end_tm.tm_year - && start_tm.tm_mon == end_tm.tm_mon - && start_tm.tm_mday == end_tm.tm_mday) { - strftime (buffer, sizeof (buffer), - _("%A %d %B %Y"), &start_tm); - } else if (start_tm.tm_year == end_tm.tm_year) { - strftime (buffer, sizeof (buffer), - _("%a %d %b"), &start_tm); - strftime (end_buffer, sizeof (end_buffer), - _("%a %d %b %Y"), &end_tm); - strcat (buffer, " - "); - strcat (buffer, end_buffer); - } else { - strftime (buffer, sizeof (buffer), - _("%a %d %b %Y"), &start_tm); - strftime (end_buffer, sizeof (end_buffer), - _("%a %d %b %Y"), &end_tm); - strcat (buffer, " - "); - strcat (buffer, end_buffer); - } - break; - case GNOME_CAL_MONTH_VIEW: - if (start_tm.tm_year == end_tm.tm_year) { - if (start_tm.tm_mon == end_tm.tm_mon) { - strftime (buffer, sizeof (buffer), - "%d", &start_tm); - strftime (end_buffer, sizeof (end_buffer), - _("%d %B %Y"), &end_tm); - strcat (buffer, " - "); - strcat (buffer, end_buffer); - } else { - strftime (buffer, sizeof (buffer), - _("%d %B"), &start_tm); - strftime (end_buffer, sizeof (end_buffer), - _("%d %B %Y"), &end_tm); - strcat (buffer, " - "); - strcat (buffer, end_buffer); - } - } else { - strftime (buffer, sizeof (buffer), - _("%d %B %Y"), &start_tm); - strftime (end_buffer, sizeof (end_buffer), - _("%d %B %Y"), &end_tm); - strcat (buffer, " - "); - strcat (buffer, end_buffer); - } - break; - default: - g_assert_not_reached (); - } - - control_util_set_folder_bar_label (control, buffer); -} - -void -control_util_set_folder_bar_label (BonoboControl *control, char *label) -{ - GNOME_Evolution_ShellView shell_view; - CORBA_Environment ev; - - shell_view = get_shell_view_interface (control); - if (shell_view == CORBA_OBJECT_NIL) - return; - - CORBA_exception_init (&ev); - GNOME_Evolution_ShellView_setFolderBarLabel (shell_view, label, &ev); - - if (BONOBO_EX (&ev)) - g_message ("control_util_set_folder_bar_label(): Could not set the folder bar label"); - - CORBA_exception_free (&ev); -} - -void -control_util_show_settings (GnomeCalendar *gcal) -{ - BonoboControl *control; - GNOME_Evolution_ShellView shell_view; - CORBA_Environment ev; - - control = gtk_object_get_data (GTK_OBJECT (gcal), "control"); - if (control == NULL) - return; - - shell_view = get_shell_view_interface (control); - if (shell_view == CORBA_OBJECT_NIL) - return; - - CORBA_exception_init (&ev); - - GNOME_Evolution_ShellView_showSettings (shell_view, &ev); - - if (BONOBO_EX (&ev)) - g_message ("control_util_show_settings(): Could not show settings"); - - CORBA_exception_free (&ev); -} - -/* Sensitizes the UI Component menu/toolbar calendar commands based on the - * number of selected events. (This will always be 0 or 1 currently.) If enable - * is FALSE, all will be disabled. Otherwise, the currently-selected number of - * events will be used. - */ -static void -sensitize_calendar_commands (GnomeCalendar *gcal, BonoboControl *control, gboolean enable) -{ - BonoboUIComponent *uic; - int n_selected; - - uic = bonobo_control_get_ui_component (control); - g_assert (uic != NULL); - - n_selected = enable ? gnome_calendar_get_num_events_selected (gcal) : 0; - - bonobo_ui_component_set_prop (uic, "/commands/Cut", "sensitive", - n_selected == 0 ? "0" : "1", - NULL); - bonobo_ui_component_set_prop (uic, "/commands/Copy", "sensitive", - n_selected == 0 ? "0" : "1", - NULL); - bonobo_ui_component_set_prop (uic, "/commands/Paste", "sensitive", - enable ? "1" : "0", - NULL); - bonobo_ui_component_set_prop (uic, "/commands/Delete", "sensitive", - n_selected == 0 ? "0" : "1", - NULL); -} - -/* Sensitizes the UI Component menu/toolbar tasks commands based on the number - * of selected tasks. If enable is FALSE, all will be disabled. Otherwise, the - * currently-selected number of tasks will be used. - */ -static void -sensitize_taskpad_commands (GnomeCalendar *gcal, BonoboControl *control, gboolean enable) -{ - BonoboUIComponent *uic; - int n_selected; - - uic = bonobo_control_get_ui_component (control); - g_assert (uic != NULL); - - n_selected = enable ? gnome_calendar_get_num_tasks_selected (gcal) : 0; - - bonobo_ui_component_set_prop (uic, "/commands/Cut", "sensitive", - n_selected == 0 ? "0" : "1", - NULL); - bonobo_ui_component_set_prop (uic, "/commands/Copy", "sensitive", - n_selected == 0 ? "0" : "1", - NULL); - bonobo_ui_component_set_prop (uic, "/commands/Paste", "sensitive", - enable ? "1" : "0", - NULL); - bonobo_ui_component_set_prop (uic, "/commands/Delete", "sensitive", - n_selected == 0 ? "0" : "1", - NULL); -} - -/* Callback used when the dates shown by the GnomeCalendar are changed. - We want to update the dates in the folder bar. */ -static void -gcal_calendar_dates_change_cb (GnomeCalendar *gcal, gpointer data) -{ - BonoboControl *control; - - control = BONOBO_CONTROL (data); - - calendar_set_folder_bar_label (gcal, control); -} - -/* Callback used when the selection in the calendar views changes */ -static void -gcal_calendar_selection_changed_cb (GnomeCalendar *gcal, gpointer data) -{ - BonoboControl *control; - - control = BONOBO_CONTROL (data); - - sensitize_calendar_commands (gcal, control, TRUE); -} - -/* Callback used when the selection in the taskpad changes */ -static void -gcal_taskpad_selection_changed_cb (GnomeCalendar *gcal, gpointer data) -{ - BonoboControl *control; - - control = BONOBO_CONTROL (data); - - sensitize_taskpad_commands (gcal, control, TRUE); -} - -/* Callback used when the focus changes for a calendar view */ -static void -gcal_calendar_focus_change_cb (GnomeCalendar *gcal, gboolean in, gpointer data) -{ - BonoboControl *control; - FocusData *focus; - - control = BONOBO_CONTROL (data); - - focus = gtk_object_get_data (GTK_OBJECT (control), "focus_data"); - g_assert (focus != NULL); - - if (in) { - gtk_signal_connect (GTK_OBJECT (gcal), "calendar_selection_changed", - GTK_SIGNAL_FUNC (gcal_calendar_selection_changed_cb), control); - sensitize_calendar_commands (gcal, control, TRUE); - focus->calendar_focused = TRUE; - } else if (focus->calendar_focused) { - gtk_signal_disconnect_by_func (GTK_OBJECT (gcal), - GTK_SIGNAL_FUNC (gcal_calendar_selection_changed_cb), - control); - sensitize_calendar_commands (gcal, control, FALSE); - focus->calendar_focused = FALSE; - } -} - -/* Callback used when the taskpad focus changes */ -static void -gcal_taskpad_focus_change_cb (GnomeCalendar *gcal, gboolean in, gpointer data) -{ - BonoboControl *control; - FocusData *focus; - - control = BONOBO_CONTROL (data); - - focus = gtk_object_get_data (GTK_OBJECT (control), "focus_data"); - g_assert (focus != NULL); - - if (in) { - gtk_signal_connect (GTK_OBJECT (gcal), "taskpad_selection_changed", - GTK_SIGNAL_FUNC (gcal_taskpad_selection_changed_cb), control); - sensitize_taskpad_commands (gcal, control, TRUE); - focus->taskpad_focused = TRUE; - } else if (focus->taskpad_focused) { - /* With Bonobo controls, we may get unpaired focus_out events. - * That is why we have to keep track of this ourselves instead - * of blindly assumming that we are getting this event because - * the taskpad was in fact focused. - */ - gtk_signal_disconnect_by_func (GTK_OBJECT (gcal), - GTK_SIGNAL_FUNC (gcal_taskpad_selection_changed_cb), - control); - sensitize_taskpad_commands (gcal, control, FALSE); - focus->taskpad_focused = FALSE; - } - -} - - -static BonoboUIVerb verbs [] = { - BONOBO_UI_VERB ("CalendarPrint", file_print_cb), - BONOBO_UI_VERB ("CalendarPrintPreview", file_print_preview_cb), - - BONOBO_UI_VERB ("Cut", cut_cmd), - BONOBO_UI_VERB ("Copy", copy_cmd), - BONOBO_UI_VERB ("Paste", paste_cmd), - BONOBO_UI_VERB ("Delete", delete_cmd), - - BONOBO_UI_VERB ("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 ("PublishFreeBusy", publish_freebusy_cmd), - - BONOBO_UI_VERB_END -}; - -static EPixmap pixmaps [] = -{ - E_PIXMAP ("/menu/File/New/NewFirstItem/NewAppointment", "new_appointment.xpm"), - E_PIXMAP ("/menu/File/New/NewFirstItem/NewMeeting", "meeting.xpm"), - E_PIXMAP ("/menu/File/New/NewFirstItem/NewTask", "new_task-16.png"), - E_PIXMAP ("/menu/EditPlaceholder/Edit/Cut", "16_cut.png"), - E_PIXMAP ("/menu/EditPlaceholder/Edit/Copy", "16_copy.png"), - E_PIXMAP ("/menu/EditPlaceholder/Edit/Paste", "16_paste.png"), - E_PIXMAP ("/menu/EditPlaceholder/Edit/Delete", "evolution-trash-mini.png"), - E_PIXMAP ("/menu/File/Print/Print", "print.xpm"), - E_PIXMAP ("/menu/File/Print/PrintPreview", "print-preview.xpm"), - E_PIXMAP ("/menu/View/ViewBegin/Goto", "goto-16.png"), - - E_PIXMAP ("/Toolbar/New", "buttons/new_appointment.png"), - E_PIXMAP ("/Toolbar/NewTask", "buttons/new_task.png"), - E_PIXMAP ("/Toolbar/Print", "buttons/print.png"), - E_PIXMAP ("/Toolbar/Delete", "buttons/delete-message.png"), - E_PIXMAP ("/Toolbar/Prev", "buttons/arrow-left-24.png"), - E_PIXMAP ("/Toolbar/Next", "buttons/arrow-right-24.png"), - E_PIXMAP ("/Toolbar/Goto", "buttons/goto-24.png"), - E_PIXMAP ("/Toolbar/DayView", "buttons/dayview.xpm"), - E_PIXMAP ("/Toolbar/WorkWeekView", "buttons/workweekview.xpm"), - E_PIXMAP ("/Toolbar/WeekView", "buttons/weekview.xpm"), - E_PIXMAP ("/Toolbar/MonthView", "buttons/monthview.xpm"), - - E_PIXMAP_END -}; - -void -calendar_control_activate (BonoboControl *control, - GnomeCalendar *gcal) -{ - Bonobo_UIContainer remote_uih; - BonoboUIComponent *uic; - FocusData *focus; - - 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); - - gnome_calendar_set_ui_component (gcal, uic); - - bonobo_ui_component_add_verb_list_with_data (uic, verbs, gcal); - - bonobo_ui_component_freeze (uic, NULL); - - bonobo_ui_util_set_ui (uic, EVOLUTION_DATADIR, - "evolution-calendar.xml", - "evolution-calendar"); - - e_pixmaps_update (uic, pixmaps); - - gnome_calendar_setup_view_menus (gcal, uic); - - gtk_signal_connect (GTK_OBJECT (gcal), "dates_shown_changed", - GTK_SIGNAL_FUNC (gcal_calendar_dates_change_cb), - control); - gtk_signal_connect (GTK_OBJECT (gcal), "calendar_focus_change", - GTK_SIGNAL_FUNC (gcal_calendar_focus_change_cb), control); - gtk_signal_connect (GTK_OBJECT (gcal), "taskpad_focus_change", - GTK_SIGNAL_FUNC (gcal_taskpad_focus_change_cb), control); - - sensitize_calendar_commands (gcal, control, FALSE); - sensitize_taskpad_commands (gcal, control, FALSE); - - bonobo_ui_component_thaw (uic, NULL); - - /* Show the dialog for setting the timezone if the user hasn't chosen - a default timezone already. This is done in the startup wizard now, - so we don't do it here. */ -#if 0 - calendar_config_check_timezone_set (); -#endif - - calendar_set_folder_bar_label (gcal, control); - - focus = g_new (FocusData, 1); - focus->calendar_focused = FALSE; - focus->taskpad_focused = FALSE; - - gtk_object_set_data (GTK_OBJECT (control), "focus_data", focus); -} - -void -calendar_control_deactivate (BonoboControl *control, GnomeCalendar *gcal) -{ - FocusData *focus; - BonoboUIComponent *uic; - - uic = bonobo_control_get_ui_component (control); - g_assert (uic != NULL); - - gnome_calendar_set_ui_component (gcal, uic); - - focus = gtk_object_get_data (GTK_OBJECT (control), "focus_data"); - g_assert (focus != NULL); - - gtk_object_remove_data (GTK_OBJECT (control), "focus_data"); - g_free (focus); - - gnome_calendar_discard_view_menus (gcal); - - gtk_signal_disconnect_by_data (GTK_OBJECT (gcal), control); - - bonobo_ui_component_rm (uic, "/", NULL); - bonobo_ui_component_unset_container (uic); -} - -/* Removes a calendar from our list of all calendars when it is destroyed. */ -static void -on_calendar_destroyed (GnomeCalendar *gcal) -{ - all_calendars = g_list_remove (all_calendars, gcal); -} - -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; - } - - gtk_signal_connect (GTK_OBJECT (gcal), "destroy", - GTK_SIGNAL_FUNC (on_calendar_destroyed), NULL); - - all_calendars = g_list_prepend (all_calendars, gcal); - - return GNOME_CALENDAR (gcal); -} diff --git a/calendar/gui/calendar-commands.h b/calendar/gui/calendar-commands.h deleted file mode 100644 index 9ebac6eef4..0000000000 --- a/calendar/gui/calendar-commands.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Evolution calendar - Commands for the calendar GUI control - * - * Copyright (C) 1998 The Free Software Foundation - * Copyright (C) 2000 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef CALENDAR_COMMANDS_H -#define CALENDAR_COMMANDS_H - -#include "gnome-cal.h" - -#include <bonobo/bonobo-control.h> -#include <bonobo/bonobo-ui-component.h> - -/* This tells all the calendars to reload the config settings. */ -void update_all_config_settings (void); - -GnomeCalendar *new_calendar (void); - -void calendar_control_activate (BonoboControl *control, GnomeCalendar *gcal); -void calendar_control_deactivate (BonoboControl *control, GnomeCalendar *gcal); - -void calendar_goto_today (GnomeCalendar *gcal); - -void calendar_set_folder_bar_label (GnomeCalendar *gcal, BonoboControl *control); - -/* Used by calendar and tasks control to set the folder title bar label. */ -void control_util_set_folder_bar_label (BonoboControl *control, char *label); - -/* Used by calendar views and tasks to show the settings dialog */ -void control_util_show_settings (GnomeCalendar *gcal); - -#endif /* CALENDAR_COMMANDS_H */ diff --git a/calendar/gui/calendar-component.c b/calendar/gui/calendar-component.c deleted file mode 100644 index b4a2b3ab89..0000000000 --- a/calendar/gui/calendar-component.c +++ /dev/null @@ -1,729 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* component-factory.c - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Ettore Perazzoli <ettore@ximian.com> - */ - -#include <config.h> - -#include <errno.h> -#include <libgnomevfs/gnome-vfs-types.h> -#include <libgnomevfs/gnome-vfs-uri.h> -#include <libgnomevfs/gnome-vfs-ops.h> -#include <libgnomevfs/gnome-vfs-directory.h> -#include <libgnomevfs/gnome-vfs-file-info.h> - -#include <bonobo/bonobo-generic-factory.h> -#include <bonobo/bonobo-context.h> -#include <bonobo/bonobo-exception.h> -#include "evolution-shell-component.h" -#include "calendar-offline-handler.h" -#include "component-factory.h" -#include "tasks-control-factory.h" -#include "config-control-factory.h" -#include "control-factory.h" -#include "calendar-config.h" -#include "tasks-control.h" -#include "tasks-migrate.h" - - - -/* OAFIID for the component. */ -#define COMPONENT_ID "OAFIID:GNOME_Evolution_Calendar_ShellComponent" - -/* Folder type IDs */ -#define FOLDER_CALENDAR "calendar" -#define FOLDER_TASKS "tasks" - -/* IDs for user creatable items */ -#define CREATE_EVENT_ID "event" -#define CREATE_ALLDAY_EVENT_ID "allday-event" -#define CREATE_MEETING_ID "meeting" -#define CREATE_TASK_ID "task" - -char *evolution_dir; -EvolutionShellClient *global_shell_client = NULL; - -static const EvolutionShellComponentFolderType folder_types[] = { - { FOLDER_CALENDAR, - "evolution-calendar.png", - N_("Calendar"), - N_("Folder containing appointments and events"), - TRUE, NULL, NULL }, - { FOLDER_TASKS, - "evolution-tasks.png", - N_("Tasks"), - N_("Folder containing to-do items"), - TRUE, NULL, NULL }, - { NULL, NULL } -}; - - - -/* EvolutionShellComponent methods and signals. */ - -static EvolutionShellComponentResult -create_view (EvolutionShellComponent *shell_component, - const char *physical_uri, - const char *type, - const char *view_info, - BonoboControl **control_return, - void *closure) -{ - BonoboControl *control; - - if (!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); - if (!g_strcasecmp (type, "calendar") && *view_info) - bonobo_control_set_property (control, "view", view_info, 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; - GnomeVFSURI *uri; - - CORBA_exception_init (&ev); - - if (strcmp (type, FOLDER_CALENDAR) && strcmp (type, FOLDER_TASKS)) { - GNOME_Evolution_ShellComponentListener_notifyResult ( - listener, - GNOME_Evolution_ShellComponentListener_UNSUPPORTED_TYPE, - &ev); - CORBA_exception_free (&ev); - return; - } - - uri = gnome_vfs_uri_new (physical_uri); - if (uri) { - /* we don't need to do anything */ - GNOME_Evolution_ShellComponentListener_notifyResult ( - listener, - GNOME_Evolution_ShellComponentListener_OK, &ev); - gnome_vfs_uri_unref (uri); - } - else { - GNOME_Evolution_ShellComponentListener_notifyResult ( - listener, - GNOME_Evolution_ShellComponentListener_INVALID_URI, - &ev); - } - - CORBA_exception_free (&ev); -} - -/* Asks the alarm daemon to stop monitoring the specified URI */ -static void -stop_alarms (GnomeVFSURI *uri) -{ - char *str_uri; - CORBA_Environment ev; - GNOME_Evolution_Calendar_AlarmNotify an; - - /* Activate the alarm notification service */ - - CORBA_exception_init (&ev); - an = oaf_activate_from_id ("OAFIID:GNOME_Evolution_Calendar_AlarmNotify", 0, NULL, &ev); - - if (BONOBO_EX (&ev)) { - g_message ("stop_alarms(): Could not activate the alarm notification service"); - CORBA_exception_free (&ev); - return; - } - CORBA_exception_free (&ev); - - /* Ask the service to remove the URI from its list of calendars */ - - str_uri = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE); - g_assert (str_uri != NULL); - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_AlarmNotify_removeCalendar (an, str_uri, &ev); - g_free (str_uri); - - if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_AlarmNotify_InvalidURI)) { - g_message ("stop_alarms(): Invalid URI reported from the alarm notification service"); - } else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_AlarmNotify_NotFound)) { - /* This is OK; the service may not have loaded that calendar */ - } else if (BONOBO_EX (&ev)) { - g_message ("stop_alarms(): Could not issue the removeCalendar request"); - } - - CORBA_exception_free (&ev); - - /* Get rid of the service */ - - CORBA_exception_init (&ev); - bonobo_object_release_unref (an, &ev); - if (BONOBO_EX (&ev)) - g_message ("stop_alarms(): Could not unref the alarm notification service"); - CORBA_exception_free (&ev); -} - -static void -remove_folder (EvolutionShellComponent *shell_component, - const char *physical_uri, - const char *type, - const GNOME_Evolution_ShellComponentListener listener, - void *closure) -{ - GnomeVFSURI *dir_uri, *data_uri, *backup_uri; - GnomeVFSResult data_result, backup_result; - - /* check type */ - if (strcmp (type, FOLDER_CALENDAR) && strcmp (type, FOLDER_TASKS)) { - CORBA_Environment ev; - - CORBA_exception_init (&ev); - GNOME_Evolution_ShellComponentListener_notifyResult ( - listener, - GNOME_Evolution_ShellComponentListener_UNSUPPORTED_TYPE, - &ev); - - if (BONOBO_EX (&ev)) - g_message ("remove_folder(): Could not notify the listener of " - "an unsupported folder type"); - - CORBA_exception_free (&ev); - return; - } - - /* check URI */ - dir_uri = gnome_vfs_uri_new (physical_uri); - if (!dir_uri) { - CORBA_Environment ev; - - CORBA_exception_init (&ev); - GNOME_Evolution_ShellComponentListener_notifyResult ( - listener, - GNOME_Evolution_ShellComponentListener_INVALID_URI, - &ev); - CORBA_exception_free (&ev); - return; - } - - /* Compute the URIs of the appropriate files */ - - if (strcmp (type, FOLDER_CALENDAR) == 0) { - data_uri = gnome_vfs_uri_append_file_name (dir_uri, "calendar.ics"); - backup_uri = gnome_vfs_uri_append_file_name (dir_uri, "calendar.ics~"); - } else if (strcmp (type, FOLDER_TASKS) == 0) { - data_uri = gnome_vfs_uri_append_file_name (dir_uri, "tasks.ics"); - backup_uri = gnome_vfs_uri_append_file_name (dir_uri, "tasks.ics~"); - } else { - g_assert_not_reached (); - return; - } - - if (!data_uri || !backup_uri) { - CORBA_Environment ev; - - g_message ("remove_folder(): Could not generate the data/backup URIs"); - - CORBA_exception_init (&ev); - GNOME_Evolution_ShellComponentListener_notifyResult ( - listener, - GNOME_Evolution_ShellComponentListener_INVALID_URI, - &ev); - - if (BONOBO_EX (&ev)) - g_message ("remove_folder(): Could not notify the listener " - "of an invalid URI"); - - CORBA_exception_free (&ev); - - goto out; - } - - /* Ask the alarm daemon to stop monitoring this URI */ - - stop_alarms (data_uri); - - /* Delete the data and backup files; the shell will take care of the rest */ - - data_result = gnome_vfs_unlink_from_uri (data_uri); - backup_result = gnome_vfs_unlink_from_uri (backup_uri); - - if ((data_result == GNOME_VFS_OK || data_result == GNOME_VFS_ERROR_NOT_FOUND) - && (backup_result == GNOME_VFS_OK || backup_result == GNOME_VFS_ERROR_NOT_FOUND)) { - CORBA_Environment ev; - - CORBA_exception_init (&ev); - GNOME_Evolution_ShellComponentListener_notifyResult ( - listener, - GNOME_Evolution_ShellComponentListener_OK, - &ev); - - if (BONOBO_EX (&ev)) - g_message ("remove_folder(): Could not notify the listener about success"); - - CORBA_exception_free (&ev); - } else { - CORBA_Environment ev; - - CORBA_exception_init (&ev); - GNOME_Evolution_ShellComponentListener_notifyResult ( - listener, - GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED, - &ev); - - if (BONOBO_EX (&ev)) - g_message ("remove_folder(): Could not notify the listener about failure"); - - CORBA_exception_free (&ev); - } - - out: - - gnome_vfs_uri_unref (dir_uri); - - if (data_uri) - gnome_vfs_uri_unref (data_uri); - - if (backup_uri) - gnome_vfs_uri_unref (backup_uri); -} - -static GNOME_Evolution_ShellComponentListener_Result -xfer_file (GnomeVFSURI *base_src_uri, - GnomeVFSURI *base_dest_uri, - const char *file_name, - int remove_source) -{ - GnomeVFSURI *src_uri, *dest_uri; - GnomeVFSHandle *hin, *hout; - GnomeVFSResult result; - GnomeVFSFileInfo file_info; - GnomeVFSFileSize size; - char *buffer; - - src_uri = gnome_vfs_uri_append_file_name (base_src_uri, file_name); - - result = gnome_vfs_open_uri (&hin, src_uri, GNOME_VFS_OPEN_READ); - if (result == GNOME_VFS_ERROR_NOT_FOUND) { - gnome_vfs_uri_unref (src_uri); - return GNOME_Evolution_ShellComponentListener_OK; /* No need to xfer anything. */ - } - if (result != GNOME_VFS_OK) { - gnome_vfs_uri_unref (src_uri); - return GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED; - } - - result = gnome_vfs_get_file_info_uri (src_uri, &file_info, GNOME_VFS_FILE_INFO_DEFAULT); - if (result != GNOME_VFS_OK) { - gnome_vfs_uri_unref (src_uri); - return GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED; - } - - dest_uri = gnome_vfs_uri_append_file_name (base_dest_uri, file_name); - - result = gnome_vfs_create_uri (&hout, dest_uri, GNOME_VFS_OPEN_WRITE, FALSE, 0600); - if (result != GNOME_VFS_OK) { - gnome_vfs_close (hin); - gnome_vfs_uri_unref (src_uri); - gnome_vfs_uri_unref (dest_uri); - return GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED; - } - - /* write source file to destination file */ - buffer = g_malloc (file_info.size); - result = gnome_vfs_read (hin, buffer, file_info.size, &size); - if (result != GNOME_VFS_OK) { - gnome_vfs_close (hin); - gnome_vfs_close (hout); - gnome_vfs_uri_unref (src_uri); - gnome_vfs_uri_unref (dest_uri); - g_free (buffer); - return GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED; - } - - result = gnome_vfs_write (hout, buffer, file_info.size, &size); - if (result != GNOME_VFS_OK) { - gnome_vfs_close (hin); - gnome_vfs_close (hout); - gnome_vfs_uri_unref (src_uri); - gnome_vfs_uri_unref (dest_uri); - g_free (buffer); - return GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED; - } - - if (remove_source) { - char *text_uri; - - /* Sigh, we have to do this as there is no gnome_vfs_unlink_uri(). :-( */ - - text_uri = gnome_vfs_uri_to_string (src_uri, GNOME_VFS_URI_HIDE_NONE); - result = gnome_vfs_unlink (text_uri); - g_free (text_uri); - } - - gnome_vfs_close (hin); - gnome_vfs_close (hout); - gnome_vfs_uri_unref (src_uri); - gnome_vfs_uri_unref (dest_uri); - g_free (buffer); - - return GNOME_Evolution_ShellComponentListener_OK; -} - -static void -xfer_folder (EvolutionShellComponent *shell_component, - const char *source_physical_uri, - const char *destination_physical_uri, - const char *type, - gboolean remove_source, - const GNOME_Evolution_ShellComponentListener listener, - void *closure) -{ - CORBA_Environment ev; - GnomeVFSURI *src_uri; - GnomeVFSURI *dest_uri; - GnomeVFSResult result; - char *filename, *backup_filename; - - CORBA_exception_init (&ev); - - /* check type */ - if (strcmp (type, FOLDER_CALENDAR) && strcmp (type, FOLDER_TASKS)) { - GNOME_Evolution_ShellComponentListener_notifyResult ( - listener, - GNOME_Evolution_ShellComponentListener_UNSUPPORTED_TYPE, - &ev); - CORBA_exception_free (&ev); - return; - } - - /* check URIs */ - src_uri = gnome_vfs_uri_new (source_physical_uri); - dest_uri = gnome_vfs_uri_new (destination_physical_uri); - if (!src_uri || ! dest_uri) { - GNOME_Evolution_ShellComponentListener_notifyResult ( - listener, - GNOME_Evolution_ShellComponentListener_INVALID_URI, - &ev); - gnome_vfs_uri_unref (src_uri); - gnome_vfs_uri_unref (dest_uri); - CORBA_exception_free (&ev); - return; - } - - if (strcmp (type, FOLDER_CALENDAR) == 0) { - filename = "calendar.ics"; - backup_filename = "calendar.ics~"; - } else if (strcmp (type, FOLDER_TASKS) == 0) { - filename = "tasks.ics"; - backup_filename = "tasks.ics~"; - } else { - g_assert_not_reached (); - return; - } - - result = xfer_file (src_uri, dest_uri, filename, remove_source); - if (result == GNOME_Evolution_ShellComponentListener_OK) - result = xfer_file (src_uri, dest_uri, backup_filename, remove_source); - - GNOME_Evolution_ShellComponentListener_notifyResult (listener, result, &ev); - - gnome_vfs_uri_unref (src_uri); - gnome_vfs_uri_unref (dest_uri); - - CORBA_exception_free (&ev); -} - -static GList *shells = NULL; - -static void -owner_set_cb (EvolutionShellComponent *shell_component, - EvolutionShellClient *shell_client, - const char *evolution_homedir, - gpointer user_data) -{ - static gboolean migrated = FALSE; - - evolution_dir = g_strdup (evolution_homedir); - - if (!migrated) { - tasks_migrate (); - migrated = TRUE; - } - - shells = g_list_append (shells, shell_component); - - global_shell_client = shell_client; - - config_control_factory_register (bonobo_object_corba_objref (BONOBO_OBJECT (shell_client))); -} - -static void -owner_unset_cb (EvolutionShellComponent *shell_component, - gpointer user_data) -{ - shells = g_list_remove (shells, shell_component); - - if (g_list_length (shells) == 0) - gtk_main_quit (); -} - -/* Computes the final URI for a calendar component */ -static char * -get_data_uri (const char *uri, CalComponentVType vtype) -{ - if (uri) { - if (*uri != '/' && strncmp (uri, "file:", 5) != 0) - return g_strdup (uri); - if (vtype == CAL_COMPONENT_EVENT) - return g_concat_dir_and_file (uri, "calendar.ics"); - else if (vtype == CAL_COMPONENT_TODO) - return g_concat_dir_and_file (uri, "tasks.ics"); - else - g_assert_not_reached (); - } else { - if (vtype == CAL_COMPONENT_EVENT) - return g_concat_dir_and_file (g_get_home_dir (), - "evolution/local/Calendar/calendar.ics"); - else if (vtype == CAL_COMPONENT_TODO) - return g_concat_dir_and_file (g_get_home_dir (), - "evolution/local/Tasks/tasks.ics"); - else - g_assert_not_reached (); - } - - return NULL; -} - -/* Creates a calendar component at a specified URI. If the URI is NULL then it - * uses the default folder for that type of component. - */ -static void -create_component (const char *uri, GNOME_Evolution_Calendar_CompEditorFactory_CompEditorMode type) -{ - char *real_uri; - CORBA_Environment ev; - GNOME_Evolution_Calendar_CompEditorFactory factory; - CalComponentVType vtype; - - switch (type) { - case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_EVENT: - case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_ALLDAY_EVENT: - case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_MEETING: - vtype = CAL_COMPONENT_EVENT; - break; - case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_TODO: - vtype = CAL_COMPONENT_TODO; - break; - default: - g_assert_not_reached (); - return; - } - - real_uri = get_data_uri (uri, vtype); - - /* Get the factory */ - - CORBA_exception_init (&ev); - factory = oaf_activate_from_id ("OAFIID:GNOME_Evolution_Calendar_CompEditorFactory", - 0, NULL, &ev); - - if (BONOBO_EX (&ev)) { - g_message ("create_component(): Could not activate the component editor factory"); - CORBA_exception_free (&ev); - g_free (real_uri); - return; - } - CORBA_exception_free (&ev); - - /* Create the item */ - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_CompEditorFactory_editNew (factory, real_uri, type, &ev); - - if (BONOBO_EX (&ev)) - g_message ("create_component(): Exception while creating the component"); - - CORBA_exception_free (&ev); - g_free (real_uri); - - /* Get rid of the factory */ - - CORBA_exception_init (&ev); - bonobo_object_release_unref (factory, &ev); - if (BONOBO_EX (&ev)) - g_message ("create_component(): Could not unref the calendar component factory"); - - CORBA_exception_free (&ev); -} - -/* Callback used when we must create a user-creatable item */ -static void -sc_user_create_new_item_cb (EvolutionShellComponent *shell_component, - const char *id, - const char *parent_folder_physical_uri, - const char *parent_folder_type) -{ - if (strcmp (id, CREATE_EVENT_ID) == 0) { - if (strcmp (parent_folder_type, FOLDER_CALENDAR) == 0) - create_component (parent_folder_physical_uri, - GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_EVENT); - else - create_component (NULL, - GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_EVENT); - } else if (strcmp (id, CREATE_ALLDAY_EVENT_ID) == 0) { - if (strcmp (parent_folder_type, FOLDER_CALENDAR) == 0) - create_component (parent_folder_physical_uri, - GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_ALLDAY_EVENT); - else - create_component (NULL, - GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_ALLDAY_EVENT); - } else if (strcmp (id, CREATE_MEETING_ID) == 0) { - if (strcmp (parent_folder_type, FOLDER_CALENDAR) == 0) - create_component (parent_folder_physical_uri, - GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_MEETING); - else - create_component (NULL, - GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_MEETING); - } else if (strcmp (id, CREATE_TASK_ID) == 0) { - if (strcmp (parent_folder_type, FOLDER_TASKS) == 0) - create_component (parent_folder_physical_uri, - GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_TODO); - else - create_component (NULL, - GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_TODO); - } else - g_assert_not_reached (); -} - - -/* The factory function. */ - -static void -add_creatable_item (EvolutionShellComponent *shell_component, - const char *id, - const char *description, - const char *menu_description, - char menu_shortcut, - const char *icon_name) -{ - char *icon_path; - GdkPixbuf *icon; - - if (icon_name == NULL) { - icon_path = NULL; - icon = NULL; - } else { - icon_path = g_concat_dir_and_file (EVOLUTION_ICONSDIR, icon_name); - icon = gdk_pixbuf_new_from_file (icon_path); - } - - evolution_shell_component_add_user_creatable_item (shell_component, - id, - description, - menu_description, - menu_shortcut, - icon); - - if (icon != NULL) - gdk_pixbuf_unref (icon); - g_free (icon_path); -} - -static BonoboObject * -create_object (void) -{ - EvolutionShellComponent *shell_component; - CalendarOfflineHandler *offline_handler; - - shell_component = evolution_shell_component_new (folder_types, - NULL, - create_view, - create_folder, - remove_folder, - xfer_folder, - NULL, /* populate_folder_context_menu_fn */ - NULL, /* get_dnd_selection_fn */ - NULL /* closure */); - - /* Offline handler */ - offline_handler = calendar_offline_handler_new (); - bonobo_object_add_interface (BONOBO_OBJECT (shell_component), - BONOBO_OBJECT (offline_handler)); - - 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); - - /* User creatable items */ - - add_creatable_item (shell_component, CREATE_MEETING_ID, - _("New meeting"), _("_Meeting"), - 's', "meeting-request.png"); - - add_creatable_item (shell_component, CREATE_TASK_ID, - _("New task"), _("_Task"), - 't', "new_task-16.png"); - - add_creatable_item (shell_component, CREATE_ALLDAY_EVENT_ID, - _("New All Day Appointment"), _("All _Day Appointment"), - 'd', "new_all_day_event.png"); - - add_creatable_item (shell_component, CREATE_EVENT_ID, - _("New appointment"), _("_Appointment"), - 'a', "new_appointment.xpm"); - - gtk_signal_connect (GTK_OBJECT (shell_component), "user_create_new_item", - GTK_SIGNAL_FUNC (sc_user_create_new_item_cb), NULL); - - return BONOBO_OBJECT (shell_component); -} - - -void -component_factory_init (void) -{ - BonoboObject *object; - int result; - - object = create_object (); - - result = oaf_active_server_register (COMPONENT_ID, bonobo_object_corba_objref (object)); - - if (result == OAF_REG_ERROR) - g_error ("Cannot initialize Evolution's calendar component."); -} diff --git a/calendar/gui/calendar-component.h b/calendar/gui/calendar-component.h deleted file mode 100644 index 576255cb6d..0000000000 --- a/calendar/gui/calendar-component.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* component-factory.h - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: 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 572db1fe2c..0000000000 --- a/calendar/gui/calendar-config.c +++ /dev/null @@ -1,1203 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Authors : - * Damon Chaplin <damon@ximian.com> - * Rodrigo Moya <rodrigo@ximian.com> - * - * Copyright 2000, Ximian, Inc. - * Copyright 2000, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -/* - * calendar-config.c - functions to load/save/get/set user settings. - */ - -#include <config.h> -#include <time.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-config.h> -#include <libgnomeui/gnome-dialog.h> -#include <widgets/e-timezone-dialog/e-timezone-dialog.h> -#include <cal-util/timeutil.h> -#include "component-factory.h" -#include "calendar-commands.h" -#include "e-tasks.h" -#include "e-cell-date-edit-text.h" -#include "calendar-config.h" -#include <bonobo/bonobo-exception.h> -#include <bonobo/bonobo-moniker-util.h> -#include <bonobo-conf/bonobo-config-database.h> - -typedef struct -{ - gchar *timezone; - 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; - char *tasks_due_today_color; - char *tasks_overdue_color; - gboolean hide_completed_tasks; - CalUnits hide_completed_tasks_units; - gint hide_completed_tasks_value; - gboolean confirm_delete; - gboolean confirm_expunge; - gboolean use_default_reminder; - int default_reminder_interval; - CalUnits default_reminder_units; -} CalendarConfig; - - -static CalendarConfig *config = NULL; - -static void config_read (void); - -static void on_timezone_set (GnomeDialog *dialog, - int button, - ETimezoneDialog *etd); -static gboolean on_timezone_dialog_delete_event (GnomeDialog *dialog, - GdkEvent *event, - ETimezoneDialog *etd); - -void -calendar_config_init (void) -{ - if (config) - return; - - config = g_new0 (CalendarConfig, 1); - - config_read (); -} - -/* Returns TRUE if the locale has 'am' and 'pm' strings defined, in which - case the user can choose between 12 and 24-hour time formats. */ -gboolean -calendar_config_locale_supports_12_hour_format (void) -{ - char s[16]; - time_t t = 0; - - strftime (s, sizeof s, "%p", gmtime (&t)); - return s[0] != '\0'; -} - -static void -config_read (void) -{ - Bonobo_ConfigDatabase db; - CORBA_Environment ev; - char *units; - - CORBA_exception_init (&ev); - - db = bonobo_get_object ("wombat:", "Bonobo/ConfigDatabase", &ev); - - if (BONOBO_EX (&ev) || db == CORBA_OBJECT_NIL) { - CORBA_exception_free (&ev); - return; - } - - CORBA_exception_free (&ev); - - /* Default to UTC if the timezone is not set or is "". */ - config->timezone = bonobo_config_get_string_with_default (db, - "/Calendar/Display/Timezone", "UTC", NULL); - if (!config->timezone || !config->timezone[0]) { - g_free (config->timezone); - config->timezone = g_strdup ("UTC"); - } - - config->working_days = bonobo_config_get_long_with_default (db, - "/Calendar/Display/WorkingDays", CAL_MONDAY | CAL_TUESDAY | - CAL_WEDNESDAY | CAL_THURSDAY | CAL_FRIDAY, NULL); - - config->week_start_day = bonobo_config_get_long_with_default (db, - "/Calendar/Display/WeekStartDay", 1, NULL); - - /* If the locale defines 'am' and 'pm' strings then the user has the - choice of 12-hour or 24-hour time format, with 12-hour as the - default. If the locale doesn't have 'am' and 'pm' strings we have - to use 24-hour format, or strftime()/strptime() won't work. */ - if (calendar_config_locale_supports_12_hour_format ()) { - config->use_24_hour_format = bonobo_config_get_boolean_with_default (db, "/Calendar/Display/Use24HourFormat", FALSE, NULL); - } else { - config->use_24_hour_format = TRUE; - } - - config->week_start_day = bonobo_config_get_long_with_default (db, - "/Calendar/Display/WeekStartDay", 1, NULL); - - config->day_start_hour = bonobo_config_get_long_with_default (db, - "/Calendar/Display/DayStartHour", 9, NULL); - - config->day_start_minute = bonobo_config_get_long_with_default (db, - "/Calendar/Display/DayStartMinute", 0, NULL); - - config->day_end_hour = bonobo_config_get_long_with_default (db, - "/Calendar/Display/DayEndHour", 17, NULL); - - config->day_end_minute = bonobo_config_get_long_with_default (db, - "/Calendar/Display/DayEndMinute", 0, NULL); - - config->time_divisions = bonobo_config_get_long_with_default (db, - "/Calendar/Display/TimeDivisions", 30, NULL); - - config->view = bonobo_config_get_long_with_default (db, - "/Calendar/Display/View", 0, NULL); - - config->hpane_pos = bonobo_config_get_float_with_default (db, - "/Calendar/Display/HPanePosition", 1.0, NULL); - - config->vpane_pos = bonobo_config_get_float_with_default (db, - "/Calendar/Display/VPanePosition", 1.0, NULL); - - config->month_hpane_pos = bonobo_config_get_float_with_default (db, - "/Calendar/Display/MonthHPanePosition", 0.0, NULL); - - config->month_vpane_pos = bonobo_config_get_float_with_default (db, - "/Calendar/Display/MonthVPanePosition", 1.0, NULL); - - config->compress_weekend = bonobo_config_get_boolean_with_default (db, - "/Calendar/Display/CompressWeekend", TRUE, NULL); - - config->show_event_end = bonobo_config_get_boolean_with_default (db, - "/Calendar/Display/ShowEventEndTime", TRUE, NULL); - - /* 'DateNavigator' settings. */ - - config->dnav_show_week_no = bonobo_config_get_boolean_with_default (db, - "/Calendar/DateNavigator/ShowWeekNumbers", FALSE, NULL); - - /* Task list settings */ - - config->tasks_due_today_color = bonobo_config_get_string_with_default ( - db, "/Calendar/Tasks/Colors/TasksDueToday", "blue", NULL); - - config->tasks_overdue_color = bonobo_config_get_string_with_default ( - db, "/Calendar/Tasks/Colors/TasksOverdue", "red", NULL); - - config->hide_completed_tasks = bonobo_config_get_boolean_with_default ( - db, "/Calendar/Tasks/HideCompletedTasks", FALSE, NULL); - - units = bonobo_config_get_string_with_default (db, - "/Calendar/Tasks/HideCompletedTasksUnits", "days", NULL); - - if (!strcmp (units, "minutes")) - config->hide_completed_tasks_units = CAL_MINUTES; - else if (!strcmp (units, "hours")) - config->hide_completed_tasks_units = CAL_HOURS; - else - config->hide_completed_tasks_units = CAL_DAYS; - - g_free (units); - - config->hide_completed_tasks_value = bonobo_config_get_long_with_default ( - db, "/Calendar/Tasks/HideCompletedTasksValue", 1, NULL); - - /* Confirmation */ - config->confirm_delete = bonobo_config_get_boolean_with_default ( - db, "/Calendar/Other/ConfirmDelete", TRUE, NULL); - config->confirm_expunge = bonobo_config_get_boolean_with_default ( - db, "/Calendar/Other/ConfirmExpunge", TRUE, NULL); - - /* Default reminders */ - config->use_default_reminder = bonobo_config_get_boolean_with_default ( - db, "/Calendar/Other/UseDefaultReminder", FALSE, NULL); - - config->default_reminder_interval = bonobo_config_get_long_with_default ( - db, "/Calendar/Other/DefaultReminderInterval", 15, NULL); - - units = bonobo_config_get_string_with_default (db, - "/Calendar/Other/DefaultReminderUnits", "minutes", NULL); - - if (!strcmp (units, "days")) - config->default_reminder_units = CAL_DAYS; - else if (!strcmp (units, "hours")) - config->default_reminder_units = CAL_HOURS; - else - config->default_reminder_units = CAL_MINUTES; /* changed from above because - * if bonobo-config fucks up - * we want minutes, not days! - */ - g_free (units); - - bonobo_object_release_unref (db, NULL); -} - -/* Returns the string representation of a units value */ -static const char * -units_to_string (CalUnits units) -{ - switch (units) { - case CAL_DAYS: - return "days"; - - case CAL_HOURS: - return "hours"; - - case CAL_MINUTES: - return "minutes"; - - default: - g_assert_not_reached (); - return NULL; - } -} - -void -calendar_config_write (void) -{ - Bonobo_ConfigDatabase db; - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - db = bonobo_get_object ("wombat:", "Bonobo/ConfigDatabase", &ev); - - if (BONOBO_EX (&ev) || db == CORBA_OBJECT_NIL) { - CORBA_exception_free (&ev); - return; - } - - if (config->timezone) - bonobo_config_set_string (db, "/Calendar/Display/Timezone", - config->timezone, NULL); - - bonobo_config_set_long (db, "/Calendar/Display/WorkingDays", - config->working_days, NULL); - bonobo_config_set_boolean (db, "/Calendar/Display/Use24HourFormat", - config->use_24_hour_format, NULL); - bonobo_config_set_long (db, "/Calendar/Display/WeekStartDay", - config->week_start_day, NULL); - bonobo_config_set_long (db, "/Calendar/Display/DayStartHour", - config->day_start_hour, NULL); - bonobo_config_set_long (db, "/Calendar/Display/DayStartMinute", - config->day_start_minute, NULL); - bonobo_config_set_long (db, "/Calendar/Display/DayEndHour", - config->day_end_hour, NULL); - bonobo_config_set_long (db, "/Calendar/Display/DayEndMinute", - config->day_end_minute, NULL); - bonobo_config_set_boolean (db, "/Calendar/Display/CompressWeekend", - config->compress_weekend, NULL); - bonobo_config_set_boolean (db, "/Calendar/Display/ShowEventEndTime", - config->show_event_end, NULL); - - bonobo_config_set_boolean (db, - "/Calendar/DateNavigator/ShowWeekNumbers", - config->dnav_show_week_no, NULL); - - bonobo_config_set_string (db, "/Calendar/Tasks/Colors/TasksDueToday", - config->tasks_due_today_color, NULL); - - bonobo_config_set_string (db, "/Calendar/Tasks/Colors/TasksOverdue", - config->tasks_overdue_color, NULL); - - bonobo_config_set_boolean (db, "/Calendar/Tasks/HideCompletedTasks", - config->hide_completed_tasks, NULL); - - bonobo_config_set_string (db, - "/Calendar/Tasks/HideCompletedTasksUnits", - units_to_string (config->hide_completed_tasks_units), NULL); - bonobo_config_set_long (db, - "/Calendar/Tasks/HideCompletedTasksValue", - config->hide_completed_tasks_value, NULL); - - bonobo_config_set_boolean (db, "/Calendar/Other/ConfirmDelete", config->confirm_delete, NULL); - bonobo_config_set_boolean (db, "/Calendar/Other/ConfirmExpunge", config->confirm_expunge, NULL); - - bonobo_config_set_boolean (db, "/Calendar/Other/UseDefaultReminder", - config->use_default_reminder, NULL); - - bonobo_config_set_long (db, "/Calendar/Other/DefaultReminderInterval", - config->default_reminder_interval, NULL); - - bonobo_config_set_string (db, "/Calendar/Other/DefaultReminderUnits", - units_to_string (config->default_reminder_units), NULL); - - Bonobo_ConfigDatabase_sync (db, &ev); - - bonobo_object_release_unref (db, NULL); - - CORBA_exception_free (&ev); -} - -void -calendar_config_write_on_exit (void) -{ - Bonobo_ConfigDatabase db; - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - db = bonobo_get_object ("wombat:", "Bonobo/ConfigDatabase", &ev); - - if (BONOBO_EX (&ev) || db == CORBA_OBJECT_NIL) { - CORBA_exception_free (&ev); - return; - } - - bonobo_config_set_long (db, "/Calendar/Display/View", - config->view, NULL); - bonobo_config_set_long (db, "/Calendar/Display/TimeDivisions", - config->time_divisions, NULL); - bonobo_config_set_float (db, "/Calendar/Display/HPanePosition", - config->hpane_pos, NULL); - bonobo_config_set_float (db, "/Calendar/Display/VPanePosition", - config->vpane_pos, NULL); - bonobo_config_set_float (db, "/Calendar/Display/MonthHPanePosition", - config->month_hpane_pos, NULL); - bonobo_config_set_float (db, "/Calendar/Display/MonthVPanePosition", - config->month_vpane_pos, NULL); - - bonobo_config_set_boolean (db, "/Calendar/Other/ConfirmExpunge", - config->confirm_expunge, NULL); - - Bonobo_ConfigDatabase_sync (db, &ev); - - bonobo_object_release_unref (db, NULL); - - CORBA_exception_free (&ev); -} - - -/* - * Calendar Settings. - */ - -/* The current timezone, e.g. "Europe/London". It may be NULL, in which case - you should assume UTC (though Evolution will show the timezone-setting - dialog the next time a calendar or task folder is selected). */ -gchar* -calendar_config_get_timezone (void) -{ - return config->timezone; -} - - -/* Sets the timezone. If set to NULL it defaults to UTC. - FIXME: Should check it is being set to a valid timezone. */ -void -calendar_config_set_timezone (gchar *timezone) -{ - g_free (config->timezone); - - if (timezone && timezone[0]) - config->timezone = g_strdup (timezone); - else - config->timezone = g_strdup ("UTC"); -} - - -/* 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; -} - - -/* Settings to hide completed tasks. */ -gboolean -calendar_config_get_hide_completed_tasks (void) -{ - return config->hide_completed_tasks; -} - - -void -calendar_config_set_hide_completed_tasks (gboolean hide) -{ - config->hide_completed_tasks = hide; -} - - -CalUnits -calendar_config_get_hide_completed_tasks_units (void) -{ - return config->hide_completed_tasks_units; -} - - -void -calendar_config_set_hide_completed_tasks_units (CalUnits units) -{ - config->hide_completed_tasks_units = units; -} - - -gint -calendar_config_get_hide_completed_tasks_value (void) -{ - return config->hide_completed_tasks_value; -} - - -void -calendar_config_set_hide_completed_tasks_value (gint value) -{ - config->hide_completed_tasks_value = value; -} - -/** - * calendar_config_get_confirm_delete: - * - * Queries the configuration value for whether a confirmation dialog is - * presented when deleting calendar/tasks items. - * - * Return value: Whether confirmation is required when deleting items. - **/ -gboolean -calendar_config_get_confirm_delete (void) -{ - return config->confirm_delete; -} - -/** - * calendar_config_set_confirm_delete: - * @confirm: Whether confirmation is required when deleting items. - * - * Sets the configuration value for whether a confirmation dialog is presented - * when deleting calendar/tasks items. - **/ -void -calendar_config_set_confirm_delete (gboolean confirm) -{ - config->confirm_delete = confirm; -} - -/** - * calendar_config_get_confirm_expunge: - * - * Queries the configuration value for whether a confirmation dialog is - * presented when expunging calendar/tasks items. - * - * Return value: Whether confirmation is required when expunging items. - **/ -gboolean -calendar_config_get_confirm_expunge (void) -{ - return config->confirm_expunge; -} - -/** - * calendar_config_set_confirm_expunge: - * @confirm: Whether confirmation is required when expunging items. - * - * Sets the configuration value for whether a confirmation dialog is presented - * when expunging calendar/tasks items. - **/ -void -calendar_config_set_confirm_expunge (gboolean confirm) -{ - config->confirm_expunge = confirm; -} - -/* 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; - - g_return_if_fail (E_IS_CALENDAR (cal)); - - 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, and whether we - use 24 hour format. */ -void -calendar_config_configure_e_date_edit (EDateEdit *dedit) -{ - gboolean dnav_show_week_no, use_24_hour; - gint week_start_day; - - g_return_if_fail (E_IS_DATE_EDIT (dedit)); - - 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 (); - - 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); -} - - -/* This sets all the common config settings for an ECellDateEdit ETable item. - These are the settings for the ECalendar popup and the time list (if we use - 24 hour format, and the hours of the working day). */ -void -calendar_config_configure_e_cell_date_edit (ECellDateEdit *ecde) -{ - gboolean use_24_hour; - gint start_hour, end_hour; - ECellPopup *ecp; - ECellDateEditText *ecd; - char *location; - icaltimezone *zone; - - g_return_if_fail (E_IS_CELL_DATE_EDIT (ecde)); - - ecp = E_CELL_POPUP (ecde); - ecd = E_CELL_DATE_EDIT_TEXT (ecp->child); - - location = calendar_config_get_timezone (); - zone = icaltimezone_get_builtin_timezone (location); - - calendar_config_configure_e_calendar (E_CALENDAR (ecde->calendar)); - - 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++; - - e_cell_date_edit_freeze (ecde); - gtk_object_set (GTK_OBJECT (ecde), - "use_24_hour_format", use_24_hour, -#if 0 - /* We use the default 0 - 24 now. */ - "lower_hour", start_hour, - "upper_hour", end_hour, -#endif - NULL); - e_cell_date_edit_thaw (ecde); - - e_cell_date_edit_text_set_timezone (ecd, zone); - e_cell_date_edit_text_set_use_24_hour_format (ecd, use_24_hour); -} - - -/* This sets all the common config settings for an ECalendarTable widget. - These are the settings for the ECalendar popup and the time list (if we use - 24 hour format, and the hours of the working day). */ -void -calendar_config_configure_e_calendar_table (ECalendarTable *cal_table) -{ - CalendarModel *model; - gboolean use_24_hour; - char *location; - icaltimezone *zone; - - g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table)); - - use_24_hour = calendar_config_get_24_hour_format (); - - model = e_calendar_table_get_model (cal_table); - calendar_model_set_use_24_hour_format (model, use_24_hour); - - location = calendar_config_get_timezone (); - zone = icaltimezone_get_builtin_timezone (location); - calendar_model_set_timezone (model, zone); - - calendar_config_configure_e_cell_date_edit (cal_table->dates_cell); - - /* Reload the event/tasks, since the 'Hide Completed Tasks' option - may have been changed, so the query needs to be updated. */ - calendar_model_refresh (model); -} - - - -void -calendar_config_check_timezone_set () -{ - ETimezoneDialog *timezone_dialog; - GtkWidget *dialog; - GList *elem; - char *zone; - - zone = calendar_config_get_timezone (); - if (zone && zone[0]) - return; - - /* Show timezone dialog. */ - timezone_dialog = e_timezone_dialog_new (); - dialog = e_timezone_dialog_get_toplevel (timezone_dialog); - - /* Hide the cancel button, which is the 2nd button. */ - elem = g_list_nth (GNOME_DIALOG (dialog)->buttons, 1); - gtk_widget_hide (elem->data); - - gtk_signal_connect (GTK_OBJECT (dialog), "clicked", - GTK_SIGNAL_FUNC (on_timezone_set), - timezone_dialog); - gtk_signal_connect (GTK_OBJECT (dialog), "delete-event", - GTK_SIGNAL_FUNC (on_timezone_dialog_delete_event), - timezone_dialog); - - gtk_widget_show (dialog); -} - - -static void -on_timezone_set (GnomeDialog *dialog, - int button, - ETimezoneDialog *etd) -{ - char *display_name; - icaltimezone *zone; - - e_timezone_dialog_get_timezone (etd, &display_name); - - /* We know it can only be a builtin timezone, since there is no way - to set it to anything else. */ - zone = e_timezone_dialog_get_builtin_timezone (display_name); - if (zone) { - calendar_config_set_timezone (icaltimezone_get_location (zone)); - - calendar_config_write (); - update_all_config_settings (); - e_tasks_update_all_config_settings (); - } - - gtk_object_unref (GTK_OBJECT (etd)); -} - - -static gboolean -on_timezone_dialog_delete_event (GnomeDialog *dialog, - GdkEvent *event, - ETimezoneDialog *etd) -{ - gtk_object_unref (GTK_OBJECT (etd)); - return TRUE; -} - - -/** - * calendar_config_get_tasks_due_today_color: - * - * Queries the color to be used to display tasks that are due today. - * - * Return value: An X color specification. - **/ -const char * -calendar_config_get_tasks_due_today_color (void) -{ - g_assert (config->tasks_due_today_color != NULL); - return config->tasks_due_today_color; -} - -/** - * calendar_config_set_tasks_due_today_color: - * @color: X color specification - * - * Sets the color to be used to display tasks that are due today. - **/ -void -calendar_config_set_tasks_due_today_color (const char *color) -{ - g_return_if_fail (color != NULL); - - g_assert (config->tasks_due_today_color != NULL); - - g_free (config->tasks_due_today_color); - config->tasks_due_today_color = g_strdup (color); -} - -/** - * calendar_config_get_tasks_overdue_color: - * - * Queries the color to be used to display overdue tasks. - * - * Return value: An X color specification. - **/ -const char * -calendar_config_get_tasks_overdue_color (void) -{ - g_assert (config->tasks_overdue_color != NULL); - return config->tasks_overdue_color; -} - -/** - * calendar_config_set_tasks_overdue_color: - * @color: X color specification - * - * Sets the color to be used to display overdue tasks. - **/ -void -calendar_config_set_tasks_overdue_color (const char *color) -{ - g_return_if_fail (color != NULL); - - g_assert (config->tasks_overdue_color != NULL); - - g_free (config->tasks_overdue_color); - config->tasks_overdue_color = g_strdup (color); -} - -/** - * calendar_config_get_use_default_reminder: - * - * Queries whether new appointments should be created with a default reminder. - * - * Return value: Boolean value indicating whether new appointments should be - * created with a default reminder from the values of - * calendar_config_get_default_reminder_interval() and - * calendar_config_get_default_reminder_units(). - **/ -gboolean -calendar_config_get_use_default_reminder (void) -{ - return config->use_default_reminder; -} - -/** - * calendar_config_set_use_default_reminder: - * @value: Whether to create new appointments with a default reminder. - * - * Sets whether newly-created appointments should get a default reminder set - * them. - **/ -void -calendar_config_set_use_default_reminder (gboolean value) -{ - config->use_default_reminder = value; -} - -/** - * calendar_config_get_default_reminder_interval: - * - * Queries the interval for the default reminder of newly-created - * appointments, i.e. 5 in "5 minutes". - * - * Return value: Interval for default reminders. - **/ -int -calendar_config_get_default_reminder_interval (void) -{ - return config->default_reminder_interval; -} - -/** - * calendar_config_set_default_reminder_interval: - * @interval: Interval value, e.g. 5 for "5 minutes". - * - * Sets the interval that should be used for the default reminder in new - * appointments. - **/ -void -calendar_config_set_default_reminder_interval (int interval) -{ - config->default_reminder_interval = interval; -} - -/** - * calendar_config_get_default_reminder_units: - * - * Queries the units of time in which default reminders should be created for - * new appointments, e.g. CAL_MINUTES for "5 minutes". - * - * Return value: Time units for default reminders. - **/ -CalUnits -calendar_config_get_default_reminder_units (void) -{ - return config->default_reminder_units; -} - -/** - * calendar_config_set_default_reminder_units: - * @units: Time units, e.g. CAL_MINUTES for "5 minutes". - * - * Sets the units to be used for default reminders in new appointments. - **/ -void -calendar_config_set_default_reminder_units (CalUnits units) -{ - config->default_reminder_units = units; -} - -/** - * calendar_config_get_hide_completed_tasks_sexp: - * - * Returns the subexpression to use to filter out completed tasks according - * to the config settings. The returned sexp should be freed. - **/ -char* -calendar_config_get_hide_completed_tasks_sexp (void) -{ - char *sexp = NULL; - - if (calendar_config_get_hide_completed_tasks ()) { - CalUnits units; - gint value; - - units = calendar_config_get_hide_completed_tasks_units (); - value = calendar_config_get_hide_completed_tasks_value (); - - if (value == 0) { - /* If the value is 0, we want to hide completed tasks - immediately, so we filter out all completed tasks.*/ - sexp = g_strdup ("(not is-completed?)"); - } else { - char *location, *isodate; - icaltimezone *zone; - struct icaltimetype tt; - time_t t; - - /* Get the current time, and subtract the appropriate - number of days/hours/minutes. */ - location = calendar_config_get_timezone (); - zone = icaltimezone_get_builtin_timezone (location); - tt = icaltime_current_time_with_zone (zone); - - switch (units) { - case CAL_DAYS: - icaltime_adjust (&tt, -value, 0, 0, 0); - break; - case CAL_HOURS: - icaltime_adjust (&tt, 0, -value, 0, 0); - break; - case CAL_MINUTES: - icaltime_adjust (&tt, 0, 0, -value, 0); - break; - default: - g_assert_not_reached (); - } - - t = icaltime_as_timet_with_zone (tt, zone); - - /* Convert the time to an ISO date string, and build - the query sub-expression. */ - isodate = isodate_from_time_t (t); - sexp = g_strdup_printf ("(not (completed-before? (make-time \"%s\")))", isodate); - } - } - - return sexp; -} - -char * -calendar_config_default_calendar_folder (void) -{ - Bonobo_ConfigDatabase db; - char *uri; - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - db = bonobo_get_object ("wombat:", "Bonobo/ConfigDatabase", &ev); - - if (BONOBO_EX (&ev) || db == CORBA_OBJECT_NIL) { - CORBA_exception_free (&ev); - return NULL; - } - - uri = bonobo_config_get_string (db, "/DefaultFolders/calendar_uri", &ev); - bonobo_object_release_unref (db, NULL); - - if (BONOBO_EX (&ev)) { - CORBA_exception_free (&ev); - return NULL; - } - - return uri; -} - -char * -calendar_config_default_tasks_folder (void) -{ - Bonobo_ConfigDatabase db; - char *uri; - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - db = bonobo_get_object ("wombat:", "Bonobo/ConfigDatabase", &ev); - - if (BONOBO_EX (&ev) || db == CORBA_OBJECT_NIL) { - CORBA_exception_free (&ev); - return NULL; - } - - uri = bonobo_config_get_string (db, "/DefaultFolders/tasks_uri", &ev); - bonobo_object_release_unref (db, NULL); - - if (BONOBO_EX (&ev)) { - CORBA_exception_free (&ev); - return NULL; - } - - return uri; -} - diff --git a/calendar/gui/calendar-config.h b/calendar/gui/calendar-config.h deleted file mode 100644 index 6f0a9ee0fd..0000000000 --- a/calendar/gui/calendar-config.h +++ /dev/null @@ -1,189 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Authors : - * Damon Chaplin <damon@ximian.com> - * Rodrigo Moya <rodrigo@ximian.com> - * - * Copyright 2000, Ximian, Inc. - * Copyright 2000, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -/* - * 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> -#include <widgets/misc/e-cell-date-edit.h> -#include "e-calendar-table.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; - - -/* Units for settings. */ -typedef enum -{ - CAL_DAYS, - CAL_HOURS, - CAL_MINUTES -} CalUnits; - - -void calendar_config_init (void); -void calendar_config_write (void); -void calendar_config_write_on_exit (void); - - -/* - * Calendar Settings. - */ - -/* The current timezone, e.g. "Europe/London". */ -gchar* calendar_config_get_timezone (void); -void calendar_config_set_timezone (gchar *timezone); - -/* 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); - -/* Colors for the task list */ -const char *calendar_config_get_tasks_due_today_color (void); -void calendar_config_set_tasks_due_today_color (const char *color); - -const char *calendar_config_get_tasks_overdue_color (void); -void calendar_config_set_tasks_overdue_color (const char *color); - -/* Settings to hide completed tasks. */ -gboolean calendar_config_get_hide_completed_tasks (void); -void calendar_config_set_hide_completed_tasks (gboolean hide); - -CalUnits calendar_config_get_hide_completed_tasks_units(void); -void calendar_config_set_hide_completed_tasks_units(CalUnits units); - -gint calendar_config_get_hide_completed_tasks_value(void); -void calendar_config_set_hide_completed_tasks_value(gint value); - -char* calendar_config_get_hide_completed_tasks_sexp (void); - -/* Confirmation options */ -gboolean calendar_config_get_confirm_delete (void); -void calendar_config_set_confirm_delete (gboolean confirm); - -gboolean calendar_config_get_confirm_expunge (void); -void calendar_config_set_confirm_expunge (gboolean confirm); - -/* Default reminder options */ -gboolean calendar_config_get_use_default_reminder (void); -void calendar_config_set_use_default_reminder (gboolean value); - -int calendar_config_get_default_reminder_interval (void); -void calendar_config_set_default_reminder_interval (int interval); - -CalUnits calendar_config_get_default_reminder_units (void); -void calendar_config_set_default_reminder_units (CalUnits units); - - -/* Convenience functions to configure common properties of ECalendar, - EDateEdit & ECalendarTable widgets, and the ECellDateEdit ETable cell. */ -void calendar_config_configure_e_calendar (ECalendar *cal); -void calendar_config_configure_e_date_edit (EDateEdit *dedit); -void calendar_config_configure_e_calendar_table (ECalendarTable *cal_table); -void calendar_config_configure_e_cell_date_edit (ECellDateEdit *ecde); - -/* Shows the timezone dialog if the user hasn't set a default timezone. */ -void calendar_config_check_timezone_set (void); - -/* Returns TRUE if the locale has 'am' and 'pm' strings defined, i.e. it - supports 12-hour time format. */ -gboolean calendar_config_locale_supports_12_hour_format(void); - -/* Default folders, read-only */ -char *calendar_config_default_calendar_folder (void); -char *calendar_config_default_tasks_folder (void); - -#endif /* _CALENDAR_CONFIG_H_ */ diff --git a/calendar/gui/calendar-model.c b/calendar/gui/calendar-model.c deleted file mode 100644 index e8317402ac..0000000000 --- a/calendar/gui/calendar-model.c +++ /dev/null @@ -1,2465 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* Evolution calendar - Data model for ETable - * - * Copyright (C) 2000 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#include <config.h> - -#include <math.h> -#include <sys/types.h> - -#include <ctype.h> - -#include <libgnomeui/gnome-messagebox.h> -#include <libgnomeui/gnome-stock.h> -#include <libgnome/gnome-i18n.h> -#include <gal/widgets/e-unicode.h> -#include <e-util/e-time-utils.h> -#include <cal-util/timeutil.h> -#include "calendar-commands.h" -#include "calendar-config.h" -#include "comp-util.h" -#include "itip-utils.h" -#include "calendar-model.h" -#include "evolution-activity-client.h" -#include "e-cell-date-edit-text.h" -#include "misc.h" - -/* This specifies how often we refresh the list, so that completed tasks are - hidden according to the config setting, and overdue tasks change color etc. - It is in milliseconds, so this is 10 minutes. - Note that if the user is editing an item in the list, they will probably - lose their edit, so this isn't ideal. */ -#define CALENDAR_MODEL_REFRESH_TIMEOUT 1000 * 60 * 10 - -/* These hold the date values of the objects, so we can free the values when - we no longer need them. */ -typedef struct _CalendarModelObjectData CalendarModelObjectData; -struct _CalendarModelObjectData { - ECellDateEditValue *dtstart; - ECellDateEditValue *dtend; - ECellDateEditValue *due; - ECellDateEditValue *completed; -}; - -/* We use a pointer to this value to indicate that the property is not set. */ -static ECellDateEditValue unset_date_edit_value; - -/* Private part of the ECalendarModel structure */ -struct _CalendarModelPrivate { - /* Calendar client we are using */ - CalClient *client; - - /* Types of objects we are dealing with */ - CalObjType type; - - /* S-expression for query and the query object */ - char *sexp; - CalQuery *query; - - /* Array of pointers to calendar objects */ - GArray *objects; - - /* Array of CalendarModelObjectData* holding data for each of the - objects in the objects array above. */ - GArray *objects_data; - - /* 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; - - /* 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; - - /* Addresses for determining icons */ - GList *addresses; - - /* The current timezone. */ - icaltimezone *zone; - - /* The id of our timeout function for refreshing the list. */ - gint timeout_id; - - /* The activity client used to show messages on the status bar. */ - EvolutionActivityClient *activity; -}; - - - -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 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 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); - - 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; -} - - -static gboolean -calendar_model_timeout_cb (gpointer data) -{ - CalendarModel *model; - - g_return_val_if_fail (IS_CALENDAR_MODEL (data), FALSE); - - model = CALENDAR_MODEL (data); - - GDK_THREADS_ENTER (); - - calendar_model_refresh (model); - - GDK_THREADS_LEAVE (); - return TRUE; -} - - -/* 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->sexp = g_strdup ("#t"); /* match all by default */ - priv->query = NULL; - - priv->objects = g_array_new (FALSE, TRUE, sizeof (CalComponent *)); - priv->objects_data = g_array_new (FALSE, FALSE, sizeof (CalendarModelObjectData)); - 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->timeout_id = g_timeout_add (CALENDAR_MODEL_REFRESH_TIMEOUT, - calendar_model_timeout_cb, model); - - priv->addresses = itip_addresses_get (); - - priv->zone = NULL; - - priv->activity = NULL; -} - -static void -calendar_model_free_object_data (CalendarModel *model, - CalendarModelObjectData *object_data) -{ - if (object_data->dtstart != &unset_date_edit_value) - g_free (object_data->dtstart); - - if (object_data->dtend != &unset_date_edit_value) - g_free (object_data->dtend); - - if (object_data->due != &unset_date_edit_value) - g_free (object_data->due); - - if (object_data->completed != &unset_date_edit_value) - g_free (object_data->completed); -} - -/* 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; - CalendarModelObjectData *object_data; - - comp = g_array_index (priv->objects, CalComponent *, i); - g_assert (comp != NULL); - gtk_object_unref (GTK_OBJECT (comp)); - - object_data = &g_array_index (priv->objects_data, - CalendarModelObjectData, i); - calendar_model_free_object_data (model, object_data); - } - - g_array_set_size (priv->objects, 0); - g_array_set_size (priv->objects_data, 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; - - if (priv->timeout_id) { - g_source_remove (priv->timeout_id); - priv->timeout_id = 0; - } - - /* 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; - } - - if (priv->sexp) { - g_free (priv->sexp); - priv->sexp = NULL; - } - - if (priv->query) { - gtk_signal_disconnect_by_data (GTK_OBJECT (priv->query), model); - gtk_object_unref (GTK_OBJECT (priv->query)); - priv->query = 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_array_free (priv->objects_data, TRUE); - priv->objects_data = NULL; - - g_free (priv->default_category); - - itip_addresses_free (priv->addresses); - - if (priv->activity) { - gtk_object_unref (GTK_OBJECT (priv->activity)); - priv->activity = NULL; - } - - /* 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; -} - -/* 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_PRIVATE: - return _("Private"); - - case CAL_COMPONENT_CLASS_CONFIDENTIAL: - return _("Confidential"); - - default: - return _("Public"); - } -} - -/* Returns an ECellDateEditValue* for a COMPLETED property of a - calendar component. Note that we cache these in the objects_data array so - we can free them eventually. */ -static ECellDateEditValue* -get_completed (CalendarModel *model, - CalComponent *comp, - int row) -{ - CalendarModelPrivate *priv; - CalendarModelObjectData *object_data; - struct icaltimetype *completed; - - priv = model->priv; - - object_data = &g_array_index (priv->objects_data, - CalendarModelObjectData, row); - - if (!object_data->completed) { - cal_component_get_completed (comp, &completed); - - if (completed) { - object_data->completed = g_new (ECellDateEditValue, 1); - object_data->completed->tt = *completed; - object_data->completed->zone = icaltimezone_get_utc_timezone (); - cal_component_free_icaltimetype (completed); - } else { - object_data->completed = &unset_date_edit_value; - } - } - - return (object_data->completed == &unset_date_edit_value) - ? NULL : object_data->completed; -} - -/* Returns an ECellDateEditValue* for a DTSTART, DTEND or DUE property of a - calendar component. Note that we cache these in the objects_data array so - we can free them eventually. */ -static ECellDateEditValue* -get_date_edit_value (CalendarModel *model, CalComponent *comp, - int col, int row) -{ - CalendarModelPrivate *priv; - CalComponentDateTime dt; - CalendarModelObjectData *object_data; - ECellDateEditValue **value; - - priv = model->priv; - - object_data = &g_array_index (priv->objects_data, - CalendarModelObjectData, row); - - if (col == CAL_COMPONENT_FIELD_DTSTART) - value = &object_data->dtstart; - else if (col == CAL_COMPONENT_FIELD_DTEND) - value = &object_data->dtend; - else - value = &object_data->due; - - if (!(*value)) { - if (col == CAL_COMPONENT_FIELD_DTSTART) - cal_component_get_dtstart (comp, &dt); - else if (col == CAL_COMPONENT_FIELD_DTEND) - cal_component_get_dtend (comp, &dt); - else - cal_component_get_due (comp, &dt); - - if (dt.value) { - CalClientGetStatus status; - icaltimezone *zone; - - /* For a DTEND with a DATE value, we subtract 1 from - the day to display it. */ - if (col == CAL_COMPONENT_FIELD_DTEND - && dt.value->is_date) { - icaltime_adjust (dt.value, -1, 0, 0, 0); - } - - *value = g_new (ECellDateEditValue, 1); - (*value)->tt = *dt.value; - - /* FIXME: TIMEZONES: Handle error. */ - status = cal_client_get_timezone (model->priv->client, - dt.tzid, &zone); - (*value)->zone = zone; - } else { - *value = &unset_date_edit_value; - } - - cal_component_free_datetime (&dt); - } - - return (*value == &unset_date_edit_value) ? NULL : *value; -} - -/* 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 int -get_percent (CalComponent *comp) -{ - int *percent, retval; - - cal_component_get_percent (comp, &percent); - - if (percent) { - retval = *percent; - cal_component_free_percent (percent); - } else { - retval = -1; - } - - return retval; -} - -/* Builds a string for the PRIORITY property of a calendar component */ -static char * -get_priority (CalComponent *comp) -{ - int *priority; - char *retval = ""; - - cal_component_get_priority (comp, &priority); - - if (priority) { - retval = cal_util_priority_to_string (*priority); - cal_component_free_priority (priority); - } - - return retval; -} - -/* 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); - - if (transp == CAL_COMPONENT_TRANSP_TRANSPARENT) - return _("Free"); - else - return _("Busy"); -} - -/* 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 -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 component is overdue. Sigh, this is very similar to - * get_color() below. - */ -static gboolean -is_overdue (CalendarModel *model, 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 { - struct icaltimetype now_tt; - CalClientGetStatus status; - icaltimezone *zone; - - /* Second, is it already completed? */ - - if (is_complete (comp)) { - retval = FALSE; - goto out; - } - - /* Third, are we overdue as of right now? */ - - /* Get the current time in the same timezone as the DUE date.*/ - /* FIXME: TIMEZONES: Handle error. */ - status = cal_client_get_timezone (model->priv->client, dt.tzid, - &zone); - now_tt = icaltime_current_time_with_zone (zone); - - if (icaltime_compare (*dt.value, now_tt) <= 0) - retval = TRUE; - else - retval = FALSE; - } - - out: - - cal_component_free_datetime (&dt); - - return retval; -} - -/* Computes the color to be used to display a component */ -static const char * -get_color (CalendarModel *model, CalComponent *comp) -{ - CalComponentDateTime dt; - const char *retval; - - cal_component_get_due (comp, &dt); - - /* First, do we have a due date? */ - - if (!dt.value) - retval = NULL; - else { - struct icaltimetype now_tt; - CalClientGetStatus status; - icaltimezone *zone; - - /* Second, is it already completed? */ - - if (is_complete (comp)) { - retval = NULL; - goto out; - } - - /* Third, is it due today? */ - - /* Get the current time in the same timezone as the DUE date.*/ - /* FIXME: TIMEZONES: Handle error. */ - status = cal_client_get_timezone (model->priv->client, dt.tzid, - &zone); - now_tt = icaltime_current_time_with_zone (zone); - - if (icaltime_compare_date_only (*dt.value, now_tt) == 0) { - retval = calendar_config_get_tasks_due_today_color (); - goto out; - } - - /* Fourth, are we overdue as of right now? We use <= in the - * comparison below so that the table entries change color - * immediately. - */ - - if (icaltime_compare (*dt.value, now_tt) <= 0) - retval = calendar_config_get_tasks_overdue_color (); - else - retval = NULL; - } - - out: - - cal_component_free_datetime (&dt); - - return retval; -} - -static void * -get_status (CalComponent *comp) -{ - icalproperty_status status; - - cal_component_get_status (comp, &status); - - switch (status) { - case ICAL_STATUS_NONE: - return ""; - - case ICAL_STATUS_NEEDSACTION: - return _("Not Started"); - - case ICAL_STATUS_INPROCESS: - return _("In Progress"); - - case ICAL_STATUS_COMPLETED: - return _("Completed"); - - case ICAL_STATUS_CANCELLED: - return _("Cancelled"); - - default: - g_assert_not_reached (); - return NULL; - } -} - -#if 0 -static void * -get_location (CalComponent *comp) -{ - const char *location; - - cal_component_get_location (comp, &location); - return (void*) location; -} -#endif - -/* 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); - -#if 0 - g_print ("In calendar_model_value_at: %i\n", col); -#endif - - 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, row); - - case CAL_COMPONENT_FIELD_DTEND: - case CAL_COMPONENT_FIELD_DTSTART: - case CAL_COMPONENT_FIELD_DUE: - return get_date_edit_value (model, comp, col, row); - - case CAL_COMPONENT_FIELD_GEO: - return get_geo (comp); - - case CAL_COMPONENT_FIELD_PERCENT: - return GINT_TO_POINTER (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: - { - ItipAddress *ia; - CalComponentOrganizer organizer; - GSList *attendees = NULL, *sl; - gint retval = 0; - - if (cal_component_has_recurrences (comp)) - return GINT_TO_POINTER (1); - - cal_component_get_organizer (comp, &organizer); - if (organizer.value != NULL) { - GList *l; - const char *text = itip_strip_mailto (organizer.value); - - for (l = priv->addresses; l != NULL; l = l->next) { - ia = l->data; - - if (!strcmp (text, ia->address)) { - retval = 3; - goto cleanup; - } - } - } - - cal_component_get_attendee_list (comp, &attendees); - for (sl = attendees; sl != NULL; sl = sl->next) { - CalComponentAttendee *ca = sl->data; - const char *text; - GList *l; - - text = itip_strip_mailto (ca->value); - for (l = priv->addresses; l != NULL; l = l->next) { - ia = l->data; - - if (!strcmp (text, ia->address)) { - if (ca->delto != NULL) - retval = 3; - else - retval = 2; - goto cleanup; - } - } - } - - cleanup: - cal_component_free_attendee_list (attendees); - return GINT_TO_POINTER (retval); - break; - } - case CAL_COMPONENT_FIELD_COMPLETE: - return GINT_TO_POINTER (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 (is_overdue (model, comp)); - - case CAL_COMPONENT_FIELD_COLOR: - return (void *) get_color (model, comp); - - case CAL_COMPONENT_FIELD_STATUS: - return get_status (comp); - - case CAL_COMPONENT_FIELD_COMPONENT: - return comp; - -#if 0 - case CAL_COMPONENT_FIELD_LOCATION : - return get_location (comp); -#endif - - default: - g_message ("calendar_model_value_at(): Requested invalid column %d", col); - g_assert_not_reached (); - return NULL; - } -} - -/* 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); -} - - -static void -set_classification (CalComponent *comp, - const char *value) -{ - CalComponentClassification classif; - - if (!g_strcasecmp (value, _("Private"))) - classif = CAL_COMPONENT_CLASS_PRIVATE; - else if (!g_strcasecmp (value, _("Confidential"))) - classif = CAL_COMPONENT_CLASS_CONFIDENTIAL; - else - classif = CAL_COMPONENT_CLASS_PUBLIC; - - cal_component_set_classification (comp, classif); -} - - -/* 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 void *value) -{ - ECellDateEditValue *dv = (ECellDateEditValue*) value; - - if (!dv) { - ensure_task_not_complete (comp); - } else { - time_t t; - - /* We assume that COMPLETED is entered in the current timezone, - even though it gets stored in UTC. */ - t = icaltime_as_timet_with_zone (dv->tt, dv->zone); - - ensure_task_complete (comp, t); - } -} - -/* Sets a CalComponentDateTime value */ -static void -set_datetime (CalendarModel *model, CalComponent *comp, const void *value, - void (* set_func) (CalComponent *comp, CalComponentDateTime *dt), - gboolean is_dtend) -{ - ECellDateEditValue *dv = (ECellDateEditValue*) value; - - if (!dv) { - (* set_func) (comp, NULL); - } else { - CalComponentDateTime dt; - - dt.value = &dv->tt; - dt.tzid = icaltimezone_get_tzid (dv->zone); - - /* For a DTEND with a DATE value, we add 1 day to it. */ - if (is_dtend && dt.value->is_date) { - icaltime_adjust (dt.value, 1, 0, 0, 0); - } - - (* 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); -} - -/* Sets the percent value of a calendar component */ -static void -set_percent (CalComponent *comp, const void *value) -{ - gint percent = GPOINTER_TO_INT (value); - - g_return_if_fail (percent >= -1); - g_return_if_fail (percent <= 100); - - /* A value of -1 means it isn't set. */ - if (percent == -1) { - cal_component_set_percent (comp, NULL); - ensure_task_not_complete (comp); - } else { - cal_component_set_percent (comp, &percent); - - if (percent == 100) - ensure_task_complete (comp, -1); - else - ensure_task_not_complete (comp); - } -} - -/* Sets the priority of a calendar component */ -static void -set_priority (CalComponent *comp, const char *value) -{ - int priority; - - priority = cal_util_priority_from_string (value); - /* If the priority is invalid (which should never happen) output a - warning and set it to undefined. */ - if (priority == -1) { - g_warning ("Invalid priority"); - priority = 0; - } - - 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 transparency of a calendar component */ -static void -set_transparency (CalComponent *comp, const char *value) -{ - CalComponentTransparency transp; - - if (!g_strcasecmp (value, _("Free"))) - transp = CAL_COMPONENT_TRANSP_TRANSPARENT; - else - transp = CAL_COMPONENT_TRANSP_OPAQUE; - - cal_component_set_transparency (comp, transp); -} - -/* 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); - } -} - -/* Sets the status of a calendar component. */ -static void -set_status (CalComponent *comp, const char *value) -{ - icalproperty_status status; - int percent; - - /* An empty string is the same as 'None'. */ - if (!value[0] || !g_strcasecmp (value, _("None"))) - status = ICAL_STATUS_NONE; - else if (!g_strcasecmp (value, _("Not Started"))) - status = ICAL_STATUS_NEEDSACTION; - else if (!g_strcasecmp (value, _("In Progress"))) - status = ICAL_STATUS_INPROCESS; - else if (!g_strcasecmp (value, _("Completed"))) - status = ICAL_STATUS_COMPLETED; - else if (!g_strcasecmp (value, _("Cancelled"))) - status = ICAL_STATUS_CANCELLED; - else { - g_warning ("Invalid status: %s\n", value); - return; - } - - cal_component_set_status (comp, status); - - if (status == ICAL_STATUS_NEEDSACTION) { - percent = 0; - cal_component_set_percent (comp, &percent); - cal_component_set_completed (comp, NULL); - } else if (status == ICAL_STATUS_COMPLETED) { - ensure_task_complete (comp, -1); - } -} - -#if 0 -static void -set_location (CalComponent *comp, const char *value) -{ - if (string_is_empty (value)) { - cal_component_set_location (comp, NULL); - return; - } - - cal_component_set_location (comp, value); -} -#endif - -/* 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); - -#if 0 - g_print ("In calendar_model_set_value_at: %i\n", col); -#endif - - switch (col) { - case CAL_COMPONENT_FIELD_CATEGORIES: - set_categories (comp, value); - break; - - case CAL_COMPONENT_FIELD_CLASSIFICATION: - set_classification (comp, value); - break; - - 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, - TRUE); - 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, - FALSE); - break; - - case CAL_COMPONENT_FIELD_DUE: - set_datetime (model, comp, value, cal_component_set_due, - FALSE); - 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; - - case CAL_COMPONENT_FIELD_TRANSPARENCY: - set_transparency (comp, value); - break; - - case CAL_COMPONENT_FIELD_URL: - set_url (comp, value); - break; - - case CAL_COMPONENT_FIELD_COMPLETE: - set_complete (comp, value); - break; - - case CAL_COMPONENT_FIELD_STATUS: - set_status (comp, value); - break; - -#if 0 - case CAL_COMPONENT_FIELD_LOCATION : - set_location (comp, value); - break; -#endif - - default: - g_message ("calendar_model_set_value_at(): Requested invalid column %d", col); - g_assert_not_reached (); - 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_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: - case CAL_COMPONENT_FIELD_COMPLETE: - case CAL_COMPONENT_FIELD_STATUS: - 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; - - model = CALENDAR_MODEL (etm); - priv = model->priv; - - /* FIXME: This should support other types of components, but for now it - * is only used for the task list. - */ - if (priv->new_comp_vtype == CAL_COMPONENT_EVENT) - comp = cal_comp_event_new_with_defaults (); - else { - comp = cal_component_new (); - cal_component_set_new_vtype (comp, priv->new_comp_vtype); - } - - set_categories (comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_CATEGORIES, row)); - set_classification (comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_CLASSIFICATION, row)); - set_completed (model, comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_COMPLETED, row)); - /* FIXME: Need to reset dtstart if dtend happens before it */ - set_datetime (model, comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_DTEND, row), cal_component_set_dtend, TRUE); - /* FIXME: Need to reset dtend if dtstart happens after it */ - set_datetime (model, comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_DTSTART, row), cal_component_set_dtstart, FALSE); - set_datetime (model, comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_DUE, row), cal_component_set_due, FALSE); - set_geo (comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_GEO, row)); - set_percent (comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_PERCENT, row)); - set_priority (comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_PRIORITY, row)); - set_summary (comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_SUMMARY, row)); - set_transparency (comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_TRANSPARENCY, row)); - set_url (comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_URL, row)); - set_complete (comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_COMPLETE, row)); - set_status (comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_STATUS, row)); - - if (!cal_client_update_object (priv->client, comp)) { - /* FIXME: Show error dialog. */ - g_message ("calendar_model_append_row(): Could not add new object!"); - } - - gtk_object_unref (GTK_OBJECT (comp)); -} - -/* Duplicates a string value */ -static char * -dup_string (const char *value) -{ - return g_strdup (value); -} - -static void* -dup_date_edit_value (const void *value) -{ - ECellDateEditValue *dv, *orig_dv; - - if (value == NULL) - return NULL; - - orig_dv = (ECellDateEditValue*) value; - - dv = g_new (ECellDateEditValue, 1); - *dv = *orig_dv; - - return dv; -} - -/* 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_GEO: - case CAL_COMPONENT_FIELD_PRIORITY: - case CAL_COMPONENT_FIELD_SUMMARY: - case CAL_COMPONENT_FIELD_TRANSPARENCY: - case CAL_COMPONENT_FIELD_URL: - case CAL_COMPONENT_FIELD_STATUS: - return dup_string (value); - - case CAL_COMPONENT_FIELD_COMPLETED: - case CAL_COMPONENT_FIELD_DTEND: - case CAL_COMPONENT_FIELD_DTSTART: - case CAL_COMPONENT_FIELD_DUE: - return dup_date_edit_value (value); - - case CAL_COMPONENT_FIELD_HAS_ALARMS: - case CAL_COMPONENT_FIELD_ICON: - case CAL_COMPONENT_FIELD_COMPLETE: - case CAL_COMPONENT_FIELD_PERCENT: - case CAL_COMPONENT_FIELD_RECURRING: - case CAL_COMPONENT_FIELD_OVERDUE: - case CAL_COMPONENT_FIELD_COLOR: - return (void *) value; - - case CAL_COMPONENT_FIELD_COMPONENT: { - CalComponent *comp; - - comp = CAL_COMPONENT (value); - gtk_object_ref (GTK_OBJECT (comp)); - return comp; - } - - 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: - if (value) - g_free (value); - break; - - case CAL_COMPONENT_FIELD_CLASSIFICATION: - break; - - 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_PRIORITY: - case CAL_COMPONENT_FIELD_SUMMARY: - case CAL_COMPONENT_FIELD_STATUS: - if (value) - g_free (value); - break; - - case CAL_COMPONENT_FIELD_TRANSPARENCY: - break; - - case CAL_COMPONENT_FIELD_URL: - if (value) - g_free (value); - break; - - case CAL_COMPONENT_FIELD_PERCENT: - 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: - break; - - case CAL_COMPONENT_FIELD_COMPONENT: - if (value) - gtk_object_unref (GTK_OBJECT (value)); - break; - - default: - g_message ("calendar_model_free_value(): Requested invalid column %d", col); - } -} - -/* 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_GEO: - case CAL_COMPONENT_FIELD_PRIORITY: - case CAL_COMPONENT_FIELD_SUMMARY: - case CAL_COMPONENT_FIELD_TRANSPARENCY: - case CAL_COMPONENT_FIELD_URL: - case CAL_COMPONENT_FIELD_STATUS: - return init_string (); - - case CAL_COMPONENT_FIELD_COMPLETED: - case CAL_COMPONENT_FIELD_DTEND: - case CAL_COMPONENT_FIELD_DTSTART: - case CAL_COMPONENT_FIELD_DUE: - 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: - case CAL_COMPONENT_FIELD_COMPONENT: - return NULL; - - case CAL_COMPONENT_FIELD_PERCENT: - return GINT_TO_POINTER (-1); - - 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) -{ - CalendarModel *model; - CalendarModelPrivate *priv; - - g_return_val_if_fail (col >= 0 && col < CAL_COMPONENT_FIELD_NUM_FIELDS, TRUE); - - model = CALENDAR_MODEL (etm); - priv = model->priv; - - switch (col) { - case CAL_COMPONENT_FIELD_CATEGORIES: - /* This could be a hack or not. If the categories field only - * contains the default category, then it possibly means that - * the user has not entered anything at all in the click-to-add; - * the category is in the value because we put it there in - * calendar_model_initialize_value(). - */ - if (priv->default_category && value && strcmp (priv->default_category, value) == 0) - return TRUE; - else - return string_is_empty (value); - - case CAL_COMPONENT_FIELD_CLASSIFICATION: /* actually goes here, not by itself */ - case CAL_COMPONENT_FIELD_GEO: - case CAL_COMPONENT_FIELD_PRIORITY: - case CAL_COMPONENT_FIELD_SUMMARY: - case CAL_COMPONENT_FIELD_TRANSPARENCY: - case CAL_COMPONENT_FIELD_URL: - case CAL_COMPONENT_FIELD_STATUS: - return string_is_empty (value); - - case CAL_COMPONENT_FIELD_COMPLETED: - case CAL_COMPONENT_FIELD_DTEND: - case CAL_COMPONENT_FIELD_DTSTART: - case CAL_COMPONENT_FIELD_DUE: - return value ? FALSE : TRUE; - - case CAL_COMPONENT_FIELD_PERCENT: - return (GPOINTER_TO_INT (value) < 0) ? TRUE : FALSE; - - 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: - case CAL_COMPONENT_FIELD_COMPONENT: - return TRUE; - - default: - g_message ("calendar_model_value_is_empty(): Requested invalid column %d", col); - return TRUE; - } -} - -static char* -date_value_to_string (ETableModel *etm, const void *value) -{ - CalendarModel *model; - CalendarModelPrivate *priv; - ECellDateEditValue *dv = (ECellDateEditValue *) value; - struct icaltimetype tt; - struct tm tmp_tm; - char buffer[64]; - - model = CALENDAR_MODEL (etm); - priv = model->priv; - - if (!dv) - return g_strdup (""); - - /* We currently convert all the dates to the current timezone. */ - tt = dv->tt; - icaltimezone_convert_time (&tt, dv->zone, priv->zone); - - tmp_tm.tm_year = tt.year - 1900; - tmp_tm.tm_mon = tt.month - 1; - tmp_tm.tm_mday = tt.day; - tmp_tm.tm_hour = tt.hour; - tmp_tm.tm_min = tt.minute; - tmp_tm.tm_sec = tt.second; - tmp_tm.tm_isdst = -1; - - tmp_tm.tm_wday = time_day_of_week (tt.day, tt.month - 1, tt.year); - - e_time_format_date_and_time (&tmp_tm, priv->use_24_hour_format, - TRUE, FALSE, - buffer, sizeof (buffer)); - return e_utf8_from_locale_string (buffer); -} - - -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_GEO: - case CAL_COMPONENT_FIELD_PRIORITY: - case CAL_COMPONENT_FIELD_SUMMARY: - case CAL_COMPONENT_FIELD_TRANSPARENCY: - case CAL_COMPONENT_FIELD_URL: - case CAL_COMPONENT_FIELD_STATUS: - return g_strdup (value); - - case CAL_COMPONENT_FIELD_COMPLETED: - case CAL_COMPONENT_FIELD_DTEND: - case CAL_COMPONENT_FIELD_DTSTART: - case CAL_COMPONENT_FIELD_DUE: - return date_value_to_string (etm, value); - - case CAL_COMPONENT_FIELD_ICON: - if (GPOINTER_TO_INT (value) == 0) - return e_utf8_from_locale_string (_("Normal")); - else if (GPOINTER_TO_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; - - case CAL_COMPONENT_FIELD_COMPONENT: - return NULL; - - case CAL_COMPONENT_FIELD_PERCENT: - if (GPOINTER_TO_INT (value) < 0) - return NULL; - else - return g_strdup_printf ("%i%%", GPOINTER_TO_INT (value)); - - 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 component is updated in the live query */ -static void -query_obj_updated_cb (CalQuery *query, const char *uid, - gboolean query_in_progress, int n_scanned, int total, - gpointer data) -{ - CalendarModel *model; - CalendarModelPrivate *priv; - int orig_idx; - CalComponent *new_comp; - const char *new_comp_uid; - int *new_idx; - CalClientGetStatus status; - CalendarModelObjectData new_object_data = { NULL, NULL, NULL, NULL }; - - model = CALENDAR_MODEL (data); - priv = model->priv; - - e_table_model_pre_change (E_TABLE_MODEL (model)); - - orig_idx = remove_object (model, uid); - - status = cal_client_get_object (priv->client, uid, &new_comp); - - switch (status) { - case CAL_CLIENT_GET_SUCCESS: - /* 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); - g_array_append_val (priv->objects_data, new_object_data); - - 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); - g_array_insert_val (priv->objects_data, orig_idx, - new_object_data); - - 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); - } - - 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); - else - e_table_model_no_change (E_TABLE_MODEL (model)); - - 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); - else - e_table_model_no_change (E_TABLE_MODEL (model)); - - break; - - default: - g_assert_not_reached (); - } -} - -/* Callback used when a component is removed from the live query */ -static void -query_obj_removed_cb (CalQuery *query, const char *uid, gpointer data) -{ - CalendarModel *model; - int idx; - - model = CALENDAR_MODEL (data); - - e_table_model_pre_change (E_TABLE_MODEL (model)); - - idx = remove_object (model, uid); - - if (idx != -1) - e_table_model_row_deleted (E_TABLE_MODEL (model), idx); - else - e_table_model_no_change (E_TABLE_MODEL (model)); -} - -/* Callback used when a query ends */ -static void -query_query_done_cb (CalQuery *query, CalQueryDoneStatus status, const char *error_str, gpointer data) -{ - CalendarModel *model; - - model = CALENDAR_MODEL (data); - - /* FIXME */ - - calendar_model_set_status_message (model, NULL); - - if (status != CAL_QUERY_DONE_SUCCESS) - g_warning ("query done: %s\n", error_str); -} - -/* Callback used when an evaluation error occurs when running a query */ -static void -query_eval_error_cb (CalQuery *query, const char *error_str, gpointer data) -{ - CalendarModel *model; - - model = CALENDAR_MODEL (data); - - /* FIXME */ - - calendar_model_set_status_message (model, NULL); - - g_warning ("eval error: %s\n", error_str); -} - -/* Builds a complete query sexp for the calendar model by adding the predicates - * to filter only for the type of objects that the model supports, and - * whether we want completed tasks. - */ -static char * -adjust_query_sexp (CalendarModel *model, const char *sexp) -{ - CalendarModelPrivate *priv; - CalObjType type; - char *type_sexp; - char *completed_sexp; - char *new_sexp; - - priv = model->priv; - - type = priv->type; - - if (!(type & CALOBJ_TYPE_ANY)) - type_sexp = g_strdup ("#t"); - else - type_sexp = g_strdup_printf ( - "(or %s %s %s)", - (type & CALOBJ_TYPE_EVENT) ? "(= (get-vtype) \"VEVENT\")" : "", - (type & CALOBJ_TYPE_TODO) ? "(= (get-vtype) \"VTODO\")" : "", - (type & CALOBJ_TYPE_JOURNAL) ? "(= (get-vtype) \"VJOURNAL\")" : ""); - - /* Create a sub-expression for filtering out completed tasks, based on - the config settings. */ - completed_sexp = calendar_config_get_hide_completed_tasks_sexp (); - - new_sexp = g_strdup_printf ("(and %s %s %s)", type_sexp, - completed_sexp ? completed_sexp : "", - sexp); - g_free (type_sexp); - g_free (completed_sexp); - -#if 0 - g_print ("Calendar model sexp:\n%s\n", new_sexp); -#endif - - return new_sexp; -} - -/* Restarts a query */ -static void -update_query (CalendarModel *model) -{ - CalendarModelPrivate *priv; - CalQuery *old_query; - char *real_sexp; - - priv = model->priv; - - e_table_model_pre_change (E_TABLE_MODEL (model)); - free_objects (model); - e_table_model_changed (E_TABLE_MODEL (model)); - - if (!(priv->client - && cal_client_get_load_state (priv->client) == CAL_CLIENT_LOAD_LOADED)) - return; - - old_query = priv->query; - priv->query = NULL; - - if (old_query) { - gtk_signal_disconnect_by_data (GTK_OBJECT (old_query), model); - gtk_object_unref (GTK_OBJECT (old_query)); - } - - g_assert (priv->sexp != NULL); - real_sexp = adjust_query_sexp (model, priv->sexp); - - calendar_model_set_status_message (model, _("Searching")); - priv->query = cal_client_get_query (priv->client, real_sexp); - g_free (real_sexp); - - if (!priv->query) { - g_message ("update_query(): Could not create the query"); - calendar_model_set_status_message (model, NULL); - return; - } - - gtk_signal_connect (GTK_OBJECT (priv->query), "obj_updated", - GTK_SIGNAL_FUNC (query_obj_updated_cb), model); - gtk_signal_connect (GTK_OBJECT (priv->query), "obj_removed", - GTK_SIGNAL_FUNC (query_obj_removed_cb), model); - gtk_signal_connect (GTK_OBJECT (priv->query), "query_done", - GTK_SIGNAL_FUNC (query_query_done_cb), model); - gtk_signal_connect (GTK_OBJECT (priv->query), "eval_error", - GTK_SIGNAL_FUNC (query_eval_error_cb), 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); - - if (status != CAL_CLIENT_OPEN_SUCCESS) - return; - - update_query (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; - CalendarModelObjectData *object_data; - - 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); - - object_data = &g_array_index (priv->objects_data, - CalendarModelObjectData, *idx); - calendar_model_free_object_data (model, object_data); - g_array_remove_index (priv->objects_data, *idx); - - gtk_object_unref (GTK_OBJECT (orig_comp)); - - n = *idx; - g_free (idx); - - return n; -} - -/* Displays messages on the status bar */ -#define EVOLUTION_TASKS_PROGRESS_IMAGE "evolution-tasks-mini.png" -static GdkPixbuf *progress_icon[2] = { NULL, NULL }; - -void -calendar_model_set_status_message (CalendarModel *model, const char *message) -{ - extern EvolutionShellClient *global_shell_client; /* ugly */ - CalendarModelPrivate *priv; - - g_return_if_fail (IS_CALENDAR_MODEL (model)); - - priv = model->priv; - - if (!message || !*message) { - if (priv->activity) { - gtk_object_unref (GTK_OBJECT (priv->activity)); - priv->activity = NULL; - } - } - else if (!priv->activity) { - int display; - char *client_id = g_strdup_printf ("%p", model); - - if (progress_icon[0] == NULL) - progress_icon[0] = gdk_pixbuf_new_from_file (EVOLUTION_IMAGESDIR "/" EVOLUTION_TASKS_PROGRESS_IMAGE); - priv->activity = evolution_activity_client_new ( - global_shell_client, client_id, - progress_icon, message, TRUE, &display); - - g_free (client_id); - } - else - evolution_activity_client_update (priv->activity, message, -1.0); -} - -/** - * 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; - - 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)); - } - - priv->client = client; - priv->type = type; - - if (priv->client) { - if (cal_client_get_load_state (priv->client) == CAL_CLIENT_LOAD_LOADED) - update_query (model); - else - gtk_signal_connect (GTK_OBJECT (priv->client), "cal_opened", - GTK_SIGNAL_FUNC (cal_opened_cb), model); - } -} - -/** - * calendar_model_set_query: - * @model: A calendar model. - * @sexp: Sexp that defines the query. - * - * Sets the query sexp that a calendar model will use to filter its contents. - **/ -void -calendar_model_set_query (CalendarModel *model, const char *sexp) -{ - CalendarModelPrivate *priv; - - g_return_if_fail (model != NULL); - g_return_if_fail (IS_CALENDAR_MODEL (model)); - g_return_if_fail (sexp != NULL); - - priv = model->priv; - - if (priv->sexp) - g_free (priv->sexp); - - priv->sexp = g_strdup (sexp); - - update_query (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 server. */ -static void -ensure_task_complete (CalComponent *comp, - time_t completed_date) -{ - struct icaltimetype *old_completed = NULL; - 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) { - icaltimezone *utc_zone; - struct icaltimetype new_completed; - - /* COMPLETED is stored in UTC. */ - utc_zone = icaltimezone_get_utc_timezone (); - new_completed = icaltime_from_timet_with_zone (completed_date, - FALSE, - utc_zone); - 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) { - e_table_model_pre_change (E_TABLE_MODEL (model)); - 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, - const char *default_category) -{ - g_return_if_fail (IS_CALENDAR_MODEL (model)); - - g_free (model->priv->default_category); - model->priv->default_category = g_strdup (default_category); -} - - - -/* The current timezone. */ -icaltimezone* -calendar_model_get_timezone (CalendarModel *model) -{ - g_return_val_if_fail (IS_CALENDAR_MODEL (model), NULL); - - return model->priv->zone; -} - - -void -calendar_model_set_timezone (CalendarModel *model, - icaltimezone *zone) -{ - g_return_if_fail (IS_CALENDAR_MODEL (model)); - - if (model->priv->zone != zone) { - e_table_model_pre_change (E_TABLE_MODEL (model)); - model->priv->zone = zone; - - /* The timezone affects the times shown for COMPLETED and - maybe other fields, so we need to redisplay everything. */ - e_table_model_changed (E_TABLE_MODEL (model)); - } -} - - -/** - * calendar_model_refresh: - * @model: A calendar model. - * - * Refreshes the calendar model, reloading the events/tasks from the server. - * Be careful about doing this when the user is editing an event/task. - **/ -void -calendar_model_refresh (CalendarModel *model) -{ - g_return_if_fail (model != NULL); - g_return_if_fail (IS_CALENDAR_MODEL (model)); - - update_query (model); -} diff --git a/calendar/gui/calendar-model.h b/calendar/gui/calendar-model.h deleted file mode 100644 index 6ac175034c..0000000000 --- a/calendar/gui/calendar-model.h +++ /dev/null @@ -1,100 +0,0 @@ -/* Evolution calendar - Data model for ETable - * - * Copyright (C) 2000 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#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; -}; - -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_query (CalendarModel *model, - const char *sexp); - -void calendar_model_refresh (CalendarModel *model); - -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); - -/* The current timezone. */ -icaltimezone* calendar_model_get_timezone (CalendarModel *model); -void calendar_model_set_timezone (CalendarModel *model, - icaltimezone *zone); - -void calendar_model_set_default_category (CalendarModel *model, - const char *default_category); - -void calendar_model_set_status_message (CalendarModel *model, - const char *message); - - - -END_GNOME_DECLS - -#endif diff --git a/calendar/gui/calendar-offline-handler.c b/calendar/gui/calendar-offline-handler.c deleted file mode 100644 index a01d3fa160..0000000000 --- a/calendar/gui/calendar-offline-handler.c +++ /dev/null @@ -1,282 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* calendar-offline-handler.c - * - * Copyright (C) 2001 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: - * Ettore Perazzoli <ettore@ximian.com> - * Dan Winship <danw@ximian.com> - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtkmain.h> -#include <gtk/gtksignal.h> -#include <bonobo/bonobo-exception.h> -#include <gal/util/e-util.h> -#include "e-util/e-url.h" -#include <cal-client/cal-client.h> -#include "calendar-offline-handler.h" - -#define PARENT_TYPE bonobo_x_object_get_type () -static BonoboXObjectClass *parent_class = NULL; - -struct _CalendarOfflineHandlerPrivate { - CalClient *client; - - GNOME_Evolution_OfflineProgressListener listener_interface; - - gboolean is_offline; -}; - -static void -add_connection (gpointer data, gpointer user_data) -{ - EUri *uri = e_uri_new (data); - GNOME_Evolution_ConnectionList *list = user_data; - - g_return_if_fail (uri != NULL); - - if (uri->host != NULL) - list->_buffer[list->_length].hostName = CORBA_string_dup (uri->host); - else - list->_buffer[list->_length].hostName = CORBA_string_dup ("Unknown"); - if (uri->protocol != NULL) - list->_buffer[list->_length].type = CORBA_string_dup (uri->protocol); - else - list->_buffer[list->_length].type = CORBA_string_dup ("Unknown"); - list->_length++; - - e_uri_free (uri); -} - -static GNOME_Evolution_ConnectionList * -create_connection_list (CalendarOfflineHandler *offline_handler) -{ - CalendarOfflineHandlerPrivate *priv; - GNOME_Evolution_ConnectionList *list; - GList *uris; - - priv = offline_handler->priv; - - uris = cal_client_uri_list (priv->client, CAL_MODE_REMOTE); - - list = GNOME_Evolution_ConnectionList__alloc (); - list->_length = 0; - list->_maximum = g_list_length (uris); - list->_buffer = CORBA_sequence_GNOME_Evolution_Connection_allocbuf (list->_maximum); - - g_list_foreach (uris, add_connection, list); - - return list; -} - -/* GNOME::Evolution::Offline methods. */ -static CORBA_boolean -impl__get_isOffline (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - CalendarOfflineHandler *offline_handler; - CalendarOfflineHandlerPrivate *priv; - - offline_handler = CALENDAR_OFFLINE_HANDLER (bonobo_object_from_servant (servant)); - priv = offline_handler->priv; - - return priv->is_offline; -} - -static void -impl_prepareForOffline (PortableServer_Servant servant, - GNOME_Evolution_ConnectionList **active_connection_list, - CORBA_Environment *ev) -{ - CalendarOfflineHandler *offline_handler; - CalendarOfflineHandlerPrivate *priv; - - offline_handler = CALENDAR_OFFLINE_HANDLER (bonobo_object_from_servant (servant)); - priv = offline_handler->priv; - - *active_connection_list = create_connection_list (offline_handler); -} - -static void -update_offline (CalendarOfflineHandler *offline_handler) -{ - CalendarOfflineHandlerPrivate *priv; - GNOME_Evolution_ConnectionList *connection_list; - CORBA_Environment ev; - - priv = offline_handler->priv; - - connection_list = create_connection_list (offline_handler); - - CORBA_exception_init (&ev); - - GNOME_Evolution_OfflineProgressListener_updateProgress (priv->listener_interface, - connection_list, &ev); - - if (BONOBO_EX (&ev)) - g_warning ("Error updating offline progress"); - - CORBA_exception_free (&ev); -} - -static void -backend_cal_set_mode (CalClient *client, CalClientSetModeStatus status, CalMode mode, gpointer data) -{ - CalendarOfflineHandler *offline_handler = data; - - update_offline (offline_handler); -} - -static void -backend_cal_opened (CalClient *client, CalClientOpenStatus status, gpointer data) -{ - CalendarOfflineHandler *offline_handler = data; - - if (status != CAL_CLIENT_OPEN_SUCCESS) { - update_offline (offline_handler); - gtk_object_unref (GTK_OBJECT (client)); - return; - } - - gtk_signal_connect (GTK_OBJECT (client), "cal_set_mode", - backend_cal_set_mode, offline_handler); - cal_client_set_mode (client, CAL_MODE_LOCAL); -} - -static void -backend_go_offline (gpointer data, gpointer user_data) -{ - CalendarOfflineHandler *offline_handler = user_data; - char *uri = data; - CalClient *client; - gboolean success; - - client = cal_client_new (); - gtk_signal_connect (GTK_OBJECT (client), "cal_opened", - backend_cal_opened, offline_handler); - success = cal_client_open_calendar (client, uri, TRUE); - if (!success) { - update_offline (offline_handler); - gtk_object_unref (GTK_OBJECT (client)); - return; - } -} - -static void -impl_goOffline (PortableServer_Servant servant, - const GNOME_Evolution_OfflineProgressListener progress_listener, - CORBA_Environment *ev) -{ - CalendarOfflineHandler *offline_handler; - CalendarOfflineHandlerPrivate *priv; - GList *uris; - - offline_handler = CALENDAR_OFFLINE_HANDLER (bonobo_object_from_servant (servant)); - priv = offline_handler->priv; - - /* To update the status */ - priv->listener_interface = CORBA_Object_duplicate (progress_listener, ev); - - uris = cal_client_uri_list (priv->client, CAL_MODE_REMOTE); - - g_list_foreach (uris, backend_go_offline, offline_handler); -} - -static void -impl_goOnline (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - CalendarOfflineHandler *offline_handler; - CalendarOfflineHandlerPrivate *priv; - - offline_handler = CALENDAR_OFFLINE_HANDLER (bonobo_object_from_servant (servant)); - priv = offline_handler->priv; -} - -/* GtkObject methods. */ - -static void -impl_destroy (GtkObject *object) -{ - CalendarOfflineHandler *offline_handler; - CalendarOfflineHandlerPrivate *priv; - - offline_handler = CALENDAR_OFFLINE_HANDLER (object); - priv = offline_handler->priv; - - if (priv->listener_interface != CORBA_OBJECT_NIL) { - CORBA_Environment ev; - - CORBA_exception_init (&ev); - CORBA_Object_release (priv->listener_interface, &ev); - CORBA_exception_free (&ev); - } - - g_free (priv); - - if (GTK_OBJECT_CLASS (parent_class)->destroy != NULL) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - -/* GTK+ type initialization. */ - -static void -calendar_offline_handler_class_init (CalendarOfflineHandlerClass *klass) -{ - GtkObjectClass *object_class; - POA_GNOME_Evolution_Offline__epv *epv; - - object_class = GTK_OBJECT_CLASS (klass); - object_class->destroy = impl_destroy; - - epv = & klass->epv; - epv->_get_isOffline = impl__get_isOffline; - epv->prepareForOffline = impl_prepareForOffline; - epv->goOffline = impl_goOffline; - epv->goOnline = impl_goOnline; - - parent_class = gtk_type_class (PARENT_TYPE); -} - -static void -calendar_offline_handler_init (CalendarOfflineHandler *offline_handler) -{ - CalendarOfflineHandlerPrivate *priv; - - priv = g_new (CalendarOfflineHandlerPrivate, 1); - offline_handler->priv = priv; - - priv->client = cal_client_new (); - priv->listener_interface = CORBA_OBJECT_NIL; - priv->is_offline = FALSE; -} - -CalendarOfflineHandler * -calendar_offline_handler_new (void) -{ - CalendarOfflineHandler *new; - - new = gtk_type_new (calendar_offline_handler_get_type ()); - - return new; -} - -BONOBO_X_TYPE_FUNC_FULL (CalendarOfflineHandler, GNOME_Evolution_Offline, PARENT_TYPE, calendar_offline_handler); diff --git a/calendar/gui/calendar-offline-handler.h b/calendar/gui/calendar-offline-handler.h deleted file mode 100644 index 4b87fd659f..0000000000 --- a/calendar/gui/calendar-offline-handler.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* calendar-offline-handler.h - * - * Copyright (C) 2001 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Ettore Perazzoli <ettore@ximian.com> - */ - -#ifndef _CALENDAR_OFFLINE_HANDLER_H_ -#define _CALENDAR_OFFLINE_HANDLER_H_ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <bonobo/bonobo-xobject.h> -#include "Evolution.h" - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -#define CALENDAR_TYPE_OFFLINE_HANDLER (calendar_offline_handler_get_type ()) -#define CALENDAR_OFFLINE_HANDLER(obj) (GTK_CHECK_CAST ((obj), CALENDAR_TYPE_OFFLINE_HANDLER, CalendarOfflineHandler)) -#define CALENDAR_OFFLINE_HANDLER_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), CALENDAR_TYPE_OFFLINE_HANDLER, CalendarOfflineHandlerClass)) -#define CALENDAR_IS_OFFLINE_HANDLER(obj) (GTK_CHECK_TYPE ((obj), CALENDAR_TYPE_OFFLINE_HANDLER)) -#define CALENDAR_IS_OFFLINE_HANDLER_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), CALENDAR_TYPE_OFFLINE_HANDLER)) - - -typedef struct _CalendarOfflineHandler CalendarOfflineHandler; -typedef struct _CalendarOfflineHandlerPrivate CalendarOfflineHandlerPrivate; -typedef struct _CalendarOfflineHandlerClass CalendarOfflineHandlerClass; - -struct _CalendarOfflineHandler { - BonoboXObject parent; - - CalendarOfflineHandlerPrivate *priv; -}; - -struct _CalendarOfflineHandlerClass { - BonoboXObjectClass parent_class; - - POA_GNOME_Evolution_Offline__epv epv; -}; - - -GtkType calendar_offline_handler_get_type (void); -CalendarOfflineHandler *calendar_offline_handler_new (void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _CALENDAR_OFFLINE_HANDLER_H_ */ diff --git a/calendar/gui/calendar-view-factory.c b/calendar/gui/calendar-view-factory.c deleted file mode 100644 index 0c3f0562f9..0000000000 --- a/calendar/gui/calendar-view-factory.c +++ /dev/null @@ -1,252 +0,0 @@ -/* Evolution calendar - Generic view factory for calendar views - * - * Copyright (C) 2001 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <glib.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include "calendar-view-factory.h" -#include "calendar-view.h" - - - -/* Private part of the CalendarViewFactory structure */ -struct _CalendarViewFactoryPrivate { - /* Type of views created by this factory */ - GnomeCalendarViewType view_type; -}; - - - -static void calendar_view_factory_class_init (CalendarViewFactoryClass *class); -static void calendar_view_factory_init (CalendarViewFactory *cal_view_factory); -static void calendar_view_factory_destroy (GtkObject *object); - -static const char *calendar_view_factory_get_title (GalViewFactory *factory); -static const char *calendar_view_factory_get_type_code (GalViewFactory *factory); -static GalView *calendar_view_factory_new_view (GalViewFactory *factory, const char *name); - -static GalViewFactoryClass *parent_class = NULL; - - - -/** - * calendar_view_factory_get_type: - * - * Registers the #CalendarViewFactory class if necessary, and returns the type - * ID associated to it. - * - * Return value: The type ID of the #CalendarViewFactory class. - **/ -GtkType -calendar_view_factory_get_type (void) -{ - static GtkType calendar_view_factory_type; - - if (!calendar_view_factory_type) { - static const GtkTypeInfo calendar_view_factory_info = { - "CalendarViewFactory", - sizeof (CalendarViewFactory), - sizeof (CalendarViewFactoryClass), - (GtkClassInitFunc) calendar_view_factory_class_init, - (GtkObjectInitFunc) calendar_view_factory_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - calendar_view_factory_type = gtk_type_unique (GAL_VIEW_FACTORY_TYPE, - &calendar_view_factory_info); - } - - return calendar_view_factory_type; -} - -/* Class initialization function for the calendar view factory */ -static void -calendar_view_factory_class_init (CalendarViewFactoryClass *class) -{ - GalViewFactoryClass *gal_view_factory_class; - GtkObjectClass *object_class; - - parent_class = gtk_type_class (GAL_VIEW_FACTORY_TYPE); - - gal_view_factory_class = (GalViewFactoryClass *) class; - object_class = (GtkObjectClass *) class; - - gal_view_factory_class->get_title = calendar_view_factory_get_title; - gal_view_factory_class->get_type_code = calendar_view_factory_get_type_code; - gal_view_factory_class->new_view = calendar_view_factory_new_view; - - object_class->destroy = calendar_view_factory_destroy; -} - -/* Object initialization class for the calendar view factory */ -static void -calendar_view_factory_init (CalendarViewFactory *cal_view_factory) -{ - CalendarViewFactoryPrivate *priv; - - priv = g_new0 (CalendarViewFactoryPrivate, 1); - cal_view_factory->priv = priv; -} - -/* Destroy method for the calendar view factory */ -static void -calendar_view_factory_destroy (GtkObject *object) -{ - CalendarViewFactory *cal_view_factory; - CalendarViewFactoryPrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_CALENDAR_VIEW_FACTORY (object)); - - cal_view_factory = CALENDAR_VIEW_FACTORY (object); - priv = cal_view_factory->priv; - - g_free (priv); - cal_view_factory->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - - -/* get_title method for the calendar view factory */ -static const char * -calendar_view_factory_get_title (GalViewFactory *factory) -{ - CalendarViewFactory *cal_view_factory; - CalendarViewFactoryPrivate *priv; - - cal_view_factory = CALENDAR_VIEW_FACTORY (factory); - priv = cal_view_factory->priv; - - switch (priv->view_type) { - case GNOME_CAL_DAY_VIEW: - return _("Day View"); - - case GNOME_CAL_WORK_WEEK_VIEW: - return _("Work Week View"); - - case GNOME_CAL_WEEK_VIEW: - return _("Week View"); - - case GNOME_CAL_MONTH_VIEW: - return _("Month View"); - - default: - g_assert_not_reached (); - return NULL; - } -} - -/* get_type_code method for the calendar view factory */ -static const char * -calendar_view_factory_get_type_code (GalViewFactory *factory) -{ - CalendarViewFactory *cal_view_factory; - CalendarViewFactoryPrivate *priv; - - cal_view_factory = CALENDAR_VIEW_FACTORY (factory); - priv = cal_view_factory->priv; - - switch (priv->view_type) { - case GNOME_CAL_DAY_VIEW: - return "day_view"; - - case GNOME_CAL_WORK_WEEK_VIEW: - return "work_week_view"; - - case GNOME_CAL_WEEK_VIEW: - return "week_view"; - - case GNOME_CAL_MONTH_VIEW: - return "month_view"; - - default: - g_assert_not_reached (); - return NULL; - } -} - -/* new_view method for the calendar view factory */ -static GalView * -calendar_view_factory_new_view (GalViewFactory *factory, const char *name) -{ - CalendarViewFactory *cal_view_factory; - CalendarViewFactoryPrivate *priv; - CalendarView *cal_view; - - cal_view_factory = CALENDAR_VIEW_FACTORY (factory); - priv = cal_view_factory->priv; - - cal_view = calendar_view_new (priv->view_type, name); - return GAL_VIEW (cal_view); -} - - - -/** - * calendar_view_factory_construct: - * @cal_view_factory: A calendar view factory. - * @view_type: Type of calendar views that the factory will create. - * - * Constructs a calendar view factory by setting the type of views it will - * create. - * - * Return value: The same value as @cal_view_factory. - **/ -CalendarViewFactory * -calendar_view_factory_construct (CalendarViewFactory *cal_view_factory, - GnomeCalendarViewType view_type) -{ - CalendarViewFactoryPrivate *priv; - - g_return_val_if_fail (cal_view_factory != NULL, NULL); - g_return_val_if_fail (IS_CALENDAR_VIEW_FACTORY (cal_view_factory), NULL); - - priv = cal_view_factory->priv; - - priv->view_type = view_type; - - return cal_view_factory; -} - -/** - * calendar_view_factory_new: - * @view_type: Type of calendar views that the factory will create. - * - * Creates a new factory for calendar views. - * - * Return value: A newly-created calendar view factory. - **/ -CalendarViewFactory * -calendar_view_factory_new (GnomeCalendarViewType view_type) -{ - CalendarViewFactory *cal_view_factory; - - cal_view_factory = gtk_type_new (TYPE_CALENDAR_VIEW_FACTORY); - return calendar_view_factory_construct (cal_view_factory, view_type); -} diff --git a/calendar/gui/calendar-view-factory.h b/calendar/gui/calendar-view-factory.h deleted file mode 100644 index 6b3409afeb..0000000000 --- a/calendar/gui/calendar-view-factory.h +++ /dev/null @@ -1,65 +0,0 @@ -/* Evolution calendar - Generic view factory for calendar views - * - * Copyright (C) 2001 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef CALENDAR_VIEW_FACTORY_H -#define CALENDAR_VIEW_FACTORY_H - -#include <libgnome/gnome-defs.h> -#include <gal/menus/gal-view-factory.h> -#include "gnome-cal.h" - -BEGIN_GNOME_DECLS - - - -#define TYPE_CALENDAR_VIEW_FACTORY (calendar_view_factory_get_type ()) -#define CALENDAR_VIEW_FACTORY(obj) (GTK_CHECK_CAST ((obj), TYPE_CALENDAR_VIEW_FACTORY, \ - CalendarViewFactory)) -#define CALENDAR_VIEW_FACTORY_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), \ - TYPE_CALENDAR_VIEW_FACTORY, CalendarViewClass)) -#define IS_CALENDAR_VIEW_FACTORY(obj) (GTK_CHECK_TYPE ((obj), TYPE_CALENDAR_VIEW_FACTORY)) -#define IS_CALENDAR_VIEW_FACTORY_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), \ - TYPE_CALENDAR_VIEW_FACTORY)) - -typedef struct _CalendarViewFactoryPrivate CalendarViewFactoryPrivate; - -typedef struct { - GalViewFactory factory; - - /* Private data */ - CalendarViewFactoryPrivate *priv; -} CalendarViewFactory; - -typedef struct { - GalViewFactoryClass parent_class; -} CalendarViewFactoryClass; - -GtkType calendar_view_factory_get_type (void); - -CalendarViewFactory *calendar_view_factory_construct (CalendarViewFactory *cal_view_factory, - GnomeCalendarViewType view_type); - -CalendarViewFactory *calendar_view_factory_new (GnomeCalendarViewType view_type); - - - -END_GNOME_DECLS - -#endif diff --git a/calendar/gui/calendar-view.c b/calendar/gui/calendar-view.c deleted file mode 100644 index 7ab5e9f13c..0000000000 --- a/calendar/gui/calendar-view.c +++ /dev/null @@ -1,316 +0,0 @@ -/* Evolution calendar - Generic view object for calendar views - * - * Copyright (C) 2001 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "calendar-view.h" - - - -/* Private part of the CalendarView structure */ -struct _CalendarViewPrivate { - /* Type of the view */ - GnomeCalendarViewType view_type; - - /* Title of the view */ - char *title; -}; - - - -static void calendar_view_class_init (CalendarViewClass *class); -static void calendar_view_init (CalendarView *cview); -static void calendar_view_destroy (GtkObject *object); - -static void calendar_view_edit (GalView *view); -static void calendar_view_load (GalView *view, const char *filename); -static void calendar_view_save (GalView *view, const char *filename); -static const char *calendar_view_get_title (GalView *view); -static void calendar_view_set_title (GalView *view, const char *title); -static const char *calendar_view_get_type_code (GalView *view); -static GalView *calendar_view_clone (GalView *view); - -static GalViewClass *parent_class = NULL; - - - -/** - * calendar_view_get_type: - * - * Registers the #CalendarView class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the #CalendarView class. - **/ -GtkType -calendar_view_get_type (void) -{ - static GtkType calendar_view_type; - - if (!calendar_view_type) { - static const GtkTypeInfo calendar_view_info = { - "CalendarView", - sizeof (CalendarView), - sizeof (CalendarViewClass), - (GtkClassInitFunc) calendar_view_class_init, - (GtkObjectInitFunc) calendar_view_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - calendar_view_type = gtk_type_unique (GAL_VIEW_TYPE, &calendar_view_info); - } - - return calendar_view_type; -} - -/* Class initialization function for the calendar view */ -static void -calendar_view_class_init (CalendarViewClass *class) -{ - GalViewClass *gal_view_class; - GtkObjectClass *object_class; - - parent_class = gtk_type_class (GAL_VIEW_TYPE); - - gal_view_class = (GalViewClass *) class; - object_class = (GtkObjectClass *) class; - - gal_view_class->edit = calendar_view_edit; - gal_view_class->load = calendar_view_load; - gal_view_class->save = calendar_view_save; - gal_view_class->get_title = calendar_view_get_title; - gal_view_class->set_title = calendar_view_set_title; - gal_view_class->get_type_code = calendar_view_get_type_code; - gal_view_class->clone = calendar_view_clone; - - object_class->destroy = calendar_view_destroy; -} - -/* Object initialization function for the calendar view */ -static void -calendar_view_init (CalendarView *cal_view) -{ - CalendarViewPrivate *priv; - - priv = g_new0 (CalendarViewPrivate, 1); - cal_view->priv = priv; - - priv->title = NULL; -} - -/* Destroy method for the calendar view */ -static void -calendar_view_destroy (GtkObject *object) -{ - CalendarView *cal_view; - CalendarViewPrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_CALENDAR_VIEW (object)); - - cal_view = CALENDAR_VIEW (object); - priv = cal_view->priv; - - if (priv->title) { - g_free (priv->title); - priv->title = NULL; - } - - g_free (priv); - cal_view->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - - -/* edit method of the calendar view */ -static void -calendar_view_edit (GalView *view) -{ - /* nothing */ -} - -/* load method of the calendar view */ -static void -calendar_view_load (GalView *view, const char *filename) -{ - /* nothing */ -} - -/* save method of the calendar view */ -static void -calendar_view_save (GalView *view, const char *filename) -{ - /* nothing */ -} - -/* get_title method of the calendar view */ -static const char * -calendar_view_get_title (GalView *view) -{ - CalendarView *cal_view; - CalendarViewPrivate *priv; - - cal_view = CALENDAR_VIEW (view); - priv = cal_view->priv; - - return priv->title; -} - -/* set_title method of the calendar view */ -static void -calendar_view_set_title (GalView *view, const char *title) -{ - CalendarView *cal_view; - CalendarViewPrivate *priv; - - cal_view = CALENDAR_VIEW (view); - priv = cal_view->priv; - - if (priv->title) - g_free (priv->title); - - priv->title = g_strdup (title); -} - -/* get_type_code method for the calendar view */ -static const char * -calendar_view_get_type_code (GalView *view) -{ - CalendarView *cal_view; - CalendarViewPrivate *priv; - - cal_view = CALENDAR_VIEW (view); - priv = cal_view->priv; - - switch (priv->view_type) { - case GNOME_CAL_DAY_VIEW: - return "day_view"; - - case GNOME_CAL_WORK_WEEK_VIEW: - return "work_week_view"; - - case GNOME_CAL_WEEK_VIEW: - return "week_view"; - - case GNOME_CAL_MONTH_VIEW: - return "month_view"; - - default: - g_assert_not_reached (); - return NULL; - } -} - -/* clone method for the calendar view */ -static GalView * -calendar_view_clone (GalView *view) -{ - CalendarView *cal_view; - CalendarViewPrivate *priv; - CalendarView *new_view; - CalendarViewPrivate *new_priv; - - cal_view = CALENDAR_VIEW (view); - priv = cal_view->priv; - - new_view = gtk_type_new (TYPE_CALENDAR_VIEW); - new_priv = new_view->priv; - - new_priv->view_type = priv->view_type; - new_priv->title = g_strdup (priv->title); - - return GAL_VIEW (new_view); -} - - - -/** - * calendar_view_construct: - * @cal_view: A calendar view. - * @view_type: The type of calendar view that this object will represent. - * @title: Title for the view. - * - * Constructs a calendar view by setting its view type and title. - * - * Return value: The same value as @cal_view. - **/ -CalendarView * -calendar_view_construct (CalendarView *cal_view, - GnomeCalendarViewType view_type, - const char *title) -{ - CalendarViewPrivate *priv; - - g_return_val_if_fail (cal_view != NULL, NULL); - g_return_val_if_fail (IS_CALENDAR_VIEW (cal_view), NULL); - g_return_val_if_fail (title != NULL, NULL); - - priv = cal_view->priv; - - priv->view_type = view_type; - priv->title = g_strdup (title); - - return cal_view; -} - -/** - * calendar_view_new: - * @view_type: The type of calendar view that this object will represent. - * @title: Title for the view. - * - * Creates a new calendar view object. - * - * Return value: A newly-created calendar view. - **/ -CalendarView * -calendar_view_new (GnomeCalendarViewType view_type, const char *title) -{ - CalendarView *cal_view; - - cal_view = gtk_type_new (TYPE_CALENDAR_VIEW); - return calendar_view_construct (cal_view, view_type, title); -} - -/** - * calendar_view_get_view_type: - * @cal_view: A calendar view. - * - * Queries the calendar view type of a calendar view. - * - * Return value: Type of calendar view. - **/ -GnomeCalendarViewType -calendar_view_get_view_type (CalendarView *cal_view) -{ - CalendarViewPrivate *priv; - - g_return_val_if_fail (cal_view != NULL, GNOME_CAL_DAY_VIEW); - g_return_val_if_fail (IS_CALENDAR_VIEW (cal_view), GNOME_CAL_DAY_VIEW); - - priv = cal_view->priv; - return priv->view_type; -} diff --git a/calendar/gui/calendar-view.h b/calendar/gui/calendar-view.h deleted file mode 100644 index 515038d874..0000000000 --- a/calendar/gui/calendar-view.h +++ /dev/null @@ -1,67 +0,0 @@ -/* Evolution calendar - Generic view object for calendar views - * - * Copyright (C) 2001 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef CALENDAR_VIEW_H -#define CALENDAR_VIEW_H - -#include <libgnome/gnome-defs.h> -#include <gal/menus/gal-view.h> -#include "gnome-cal.h" - -BEGIN_GNOME_DECLS - - - -#define TYPE_CALENDAR_VIEW (calendar_view_get_type ()) -#define CALENDAR_VIEW(obj) (GTK_CHECK_CAST ((obj), TYPE_CALENDAR_VIEW, CalendarView)) -#define CALENDAR_VIEW_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_CALENDAR_VIEW, \ - CalendarViewClass)) -#define IS_CALENDAR_VIEW(obj) (GTK_CHECK_TYPE ((obj), TYPE_CALENDAR_VIEW)) -#define IS_CALENDAR_VIEW_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), TYPE_CALENDAR_VIEW)) - -typedef struct _CalendarViewPrivate CalendarViewPrivate; - -typedef struct { - GalView view; - - /* Private data */ - CalendarViewPrivate *priv; -} CalendarView; - -typedef struct { - GalViewClass parent_class; -} CalendarViewClass; - -GtkType calendar_view_get_type (void); - -CalendarView *calendar_view_construct (CalendarView *cal_view, - GnomeCalendarViewType view_type, - const char *title); - -CalendarView *calendar_view_new (GnomeCalendarViewType view_type, - const char *title); - -GnomeCalendarViewType calendar_view_get_view_type (CalendarView *cal_view); - - - -END_GNOME_DECLS - -#endif diff --git a/calendar/gui/comp-editor-factory.c b/calendar/gui/comp-editor-factory.c deleted file mode 100644 index 805e0a5c0b..0000000000 --- a/calendar/gui/comp-editor-factory.c +++ /dev/null @@ -1,714 +0,0 @@ -/* Evolution calendar - Component editor factory object - * - * 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <bonobo/bonobo-exception.h> -#include <evolution-calendar.h> -#include <e-util/e-url.h> -#include <cal-client/cal-client.h> -#include "calendar-config.h" -#include "comp-editor-factory.h" -#include "comp-util.h" -#include "dialogs/event-editor.h" -#include "dialogs/task-editor.h" - - - -/* A pending request */ - -typedef enum { - REQUEST_EXISTING, - REQUEST_NEW -} RequestType; - -typedef struct { - RequestType type; - - union { - struct { - char *uid; - } existing; - - struct { - GNOME_Evolution_Calendar_CompEditorFactory_CompEditorMode type; - } new; - } u; -} Request; - -/* A client we have open */ -typedef struct { - /* Our parent CompEditorFactory */ - CompEditorFactory *factory; - - /* Uri of the calendar, used as key in the clients hash table */ - char *uri; - - /* Client of the calendar */ - CalClient *client; - - /* Hash table of Component structures that belong to this client */ - GHashTable *uid_comp_hash; - - /* Pending requests; they are pending if the client is still being opened */ - GSList *pending; - - /* Whether this is open or still waiting */ - guint open : 1; -} OpenClient; - -/* A component that is being edited */ -typedef struct { - /* Our parent client */ - OpenClient *parent; - - /* UID of the component we are editing, used as the key in the hash table */ - const char *uid; - - /* Component we are editing */ - CalComponent *comp; - - /* Component editor that is open */ - CompEditor *editor; -} Component; - -/* Private part of the CompEditorFactory structure */ -struct CompEditorFactoryPrivate { - /* Hash table of URI->OpenClient */ - GHashTable *uri_client_hash; -}; - - - -static void comp_editor_factory_class_init (CompEditorFactoryClass *class); -static void comp_editor_factory_init (CompEditorFactory *factory); -static void comp_editor_factory_destroy (GtkObject *object); - -static void impl_editExisting (PortableServer_Servant servant, - const CORBA_char *str_uri, - const GNOME_Evolution_Calendar_CalObjUID uid, - CORBA_Environment *ev); -static void impl_editNew (PortableServer_Servant servant, - const CORBA_char *str_uri, - const GNOME_Evolution_Calendar_CalObjType type, - CORBA_Environment *ev); - -static BonoboXObjectClass *parent_class = NULL; - - - -BONOBO_X_TYPE_FUNC_FULL (CompEditorFactory, - GNOME_Evolution_Calendar_CompEditorFactory, - BONOBO_X_OBJECT_TYPE, - comp_editor_factory); - -/* Class initialization function for the component editor factory */ -static void -comp_editor_factory_class_init (CompEditorFactoryClass *class) -{ - GtkObjectClass *object_class; - - object_class = (GtkObjectClass *) class; - - parent_class = gtk_type_class (BONOBO_X_OBJECT_TYPE); - - class->epv.editExisting = impl_editExisting; - class->epv.editNew = impl_editNew; - - object_class->destroy = comp_editor_factory_destroy; -} - -/* Object initialization function for the component editor factory */ -static void -comp_editor_factory_init (CompEditorFactory *factory) -{ - CompEditorFactoryPrivate *priv; - - priv = g_new (CompEditorFactoryPrivate, 1); - factory->priv = priv; - - priv->uri_client_hash = g_hash_table_new (g_str_hash, g_str_equal); -} - -/* Used from g_hash_table_foreach(); frees a component structure */ -static void -free_component_cb (gpointer key, gpointer value, gpointer data) -{ - Component *c; - - c = value; - - c->parent = NULL; - c->uid = NULL; - - gtk_object_unref (GTK_OBJECT (c->comp)); - c->comp = NULL; - - g_free (c); -} - -/* Frees a Request structure */ -static void -free_request (Request *r) -{ - if (r->type == REQUEST_EXISTING) { - g_assert (r->u.existing.uid != NULL); - g_free (r->u.existing.uid); - } - - g_free (r); -} - -/* Frees an OpenClient structure */ -static void -free_client (OpenClient *oc) -{ - GSList *l; - - g_free (oc->uri); - oc->uri = NULL; - - gtk_object_unref (GTK_OBJECT (oc->client)); - oc->client = NULL; - - g_hash_table_foreach (oc->uid_comp_hash, free_component_cb, NULL); - g_hash_table_destroy (oc->uid_comp_hash); - oc->uid_comp_hash = NULL; - - for (l = oc->pending; l; l = l->next) { - Request *r; - - r = l->data; - free_request (r); - } - g_slist_free (oc->pending); - oc->pending = NULL; - - g_free (oc); -} - -/* Used from g_hash_table_foreach(); frees a client structure */ -static void -free_client_cb (gpointer key, gpointer value, gpointer data) -{ - OpenClient *oc; - - oc = value; - free_client (oc); -} - -/* Destroy handler for the component editor factory */ -static void -comp_editor_factory_destroy (GtkObject *object) -{ - CompEditorFactory *factory; - CompEditorFactoryPrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_COMP_EDITOR_FACTORY (object)); - - factory = COMP_EDITOR_FACTORY (object); - priv = factory->priv; - - g_hash_table_foreach (priv->uri_client_hash, free_client_cb, NULL); - g_hash_table_destroy (priv->uri_client_hash); - priv->uri_client_hash = NULL; - - g_free (priv); - factory->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - - -/* Callback used when a component editor gets destroyed */ -static void -editor_destroy_cb (GtkObject *object, gpointer data) -{ - Component *c; - OpenClient *oc; - CompEditorFactory *factory; - CompEditorFactoryPrivate *priv; - - c = data; - oc = c->parent; - factory = oc->factory; - priv = factory->priv; - - /* Free the Component */ - - g_hash_table_remove (oc->uid_comp_hash, c->uid); - gtk_object_unref (GTK_OBJECT (c->comp)); - g_free (c); - - /* See if we need to free the client */ - - g_assert (oc->pending == NULL); - - if (g_hash_table_size (oc->uid_comp_hash) != 0) - return; - - g_hash_table_remove (priv->uri_client_hash, oc->uri); - free_client (oc); -} - -/* Starts editing an existing component on a client that is already open */ -static void -edit_existing (OpenClient *oc, const char *uid) -{ - CalComponent *comp; - CalClientGetStatus status; - CompEditor *editor; - Component *c; - CalComponentVType vtype; - - g_assert (oc->open); - - /* Get the object */ - - status = cal_client_get_object (oc->client, uid, &comp); - - switch (status) { - case CAL_CLIENT_GET_SUCCESS: - /* see below */ - break; - - case CAL_CLIENT_GET_NOT_FOUND: - /* The object disappeared from the server */ - return; - - case CAL_CLIENT_GET_SYNTAX_ERROR: - g_message ("edit_exiting(): Syntax error while getting component `%s'", uid); - return; - - default: - g_assert_not_reached (); - return; - } - - /* Create the appropriate type of editor */ - - vtype = cal_component_get_vtype (comp); - - switch (vtype) { - case CAL_COMPONENT_EVENT: - editor = COMP_EDITOR (event_editor_new ()); - break; - - case CAL_COMPONENT_TODO: - editor = COMP_EDITOR (task_editor_new ()); - break; - - default: - g_message ("edit_exiting(): Unsupported object type %d", (int) vtype); - gtk_object_unref (GTK_OBJECT (comp)); - return; - } - - /* Set the client/object on the editor */ - - c = g_new (Component, 1); - c->parent = oc; - cal_component_get_uid (comp, &c->uid); - c->comp = comp; - c->editor = editor; - - g_hash_table_insert (oc->uid_comp_hash, (char *) c->uid, c); - - gtk_signal_connect (GTK_OBJECT (editor), "destroy", - GTK_SIGNAL_FUNC (editor_destroy_cb), c); - - comp_editor_set_cal_client (editor, oc->client); - comp_editor_edit_comp (editor, comp); - comp_editor_focus (editor); -} - -/* Creates a component with the appropriate defaults for the specified component - * type. - */ -static CalComponent * -get_default_event (gboolean all_day) -{ - CalComponent *comp; - struct icaltimetype itt; - CalComponentDateTime dt; - char *location; - icaltimezone *zone; - - comp = cal_comp_event_new_with_defaults (); - - location = calendar_config_get_timezone (); - zone = icaltimezone_get_builtin_timezone (location); - - if (all_day) { - itt = icaltime_today (); - - dt.value = &itt; - dt.tzid = icaltimezone_get_tzid (zone); - - cal_component_set_dtstart (comp, &dt); - cal_component_set_dtend (comp, &dt); - } else { - itt = icaltime_current_time_with_zone (zone); - itt.hour++; - itt.minute = 0; - itt.second = 0; - - dt.value = &itt; - dt.tzid = icaltimezone_get_tzid (zone); - - cal_component_set_dtstart (comp, &dt); - itt.hour++; - cal_component_set_dtend (comp, &dt); - } - - cal_component_commit_sequence (comp); - - return comp; -} - -static CalComponent * -get_default_task (void) -{ - CalComponent *comp; - - comp = cal_component_new (); - cal_component_set_new_vtype (comp, CAL_COMPONENT_TODO); - - return comp; -} - -/* Edits a new object in the context of a client */ -static void -edit_new (OpenClient *oc, const GNOME_Evolution_Calendar_CompEditorFactory_CompEditorMode type) -{ - CalComponent *comp; - Component *c; - CompEditor *editor; - - switch (type) { - case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_EVENT: - case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_MEETING: - editor = COMP_EDITOR (event_editor_new ()); - comp = get_default_event (FALSE); - break; - case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_ALLDAY_EVENT: - editor = COMP_EDITOR (event_editor_new ()); - comp = get_default_event (TRUE); - break; - case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_TODO: - editor = COMP_EDITOR (task_editor_new ()); - comp = get_default_task (); - break; - default: - g_assert_not_reached (); - return; - } - - c = g_new (Component, 1); - c->parent = oc; - cal_component_get_uid (comp, &c->uid); - c->comp = comp; - - c->editor = editor; - - g_hash_table_insert (oc->uid_comp_hash, (char *) c->uid, c); - - gtk_signal_connect (GTK_OBJECT (editor), "destroy", - GTK_SIGNAL_FUNC (editor_destroy_cb), c); - - comp_editor_set_cal_client (editor, oc->client); - comp_editor_edit_comp (editor, comp); - if (type == GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_MEETING) - event_editor_show_meeting (EVENT_EDITOR (editor)); - comp_editor_focus (editor); -} - -/* Resolves all the pending requests for a client */ -static void -resolve_pending_requests (OpenClient *oc) -{ - CompEditorFactory *factory; - CompEditorFactoryPrivate *priv; - GSList *l; - char *location; - icaltimezone *zone; - - factory = oc->factory; - priv = factory->priv; - - g_assert (oc->pending != NULL); - - /* Set the default timezone in the backend. */ - location = calendar_config_get_timezone (); - zone = icaltimezone_get_builtin_timezone (location); - if (zone) - cal_client_set_default_timezone (oc->client, zone); - - for (l = oc->pending; l; l = l->next) { - Request *request; - - request = l->data; - - switch (request->type) { - case REQUEST_EXISTING: - edit_existing (oc, request->u.existing.uid); - break; - - case REQUEST_NEW: - edit_new (oc, request->u.new.type); - break; - } - - free_request (request); - } - - g_slist_free (oc->pending); - oc->pending = NULL; -} - -/* Callback used when a client is finished opening. We resolve all the pending - * requests. - */ -static void -cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data) -{ - OpenClient *oc; - CompEditorFactory *factory; - CompEditorFactoryPrivate *priv; - - oc = data; - factory = oc->factory; - priv = factory->priv; - - switch (status) { - case CAL_CLIENT_OPEN_SUCCESS: - oc->open = TRUE; - resolve_pending_requests (oc); - return; - - case CAL_CLIENT_OPEN_ERROR: - g_message ("cal_opened_cb(): Error while opening the calendar"); - break; - - case CAL_CLIENT_OPEN_NOT_FOUND: - /* bullshit; we specified only_if_exists = FALSE */ - g_assert_not_reached (); - return; - - case CAL_CLIENT_OPEN_METHOD_NOT_SUPPORTED: - g_message ("cal_opened_cb(): Method not supported when opening the calendar"); - break; - - default: - g_assert_not_reached (); - return; - } - - g_hash_table_remove (priv->uri_client_hash, oc->uri); - free_client (oc); -} - -/* Creates a new OpenClient structure and queues the component editing/creation - * process until the client is open. Returns NULL if it could not issue the - * open request. - */ -static OpenClient * -open_client (CompEditorFactory *factory, const char *uristr) -{ - CompEditorFactoryPrivate *priv; - CalClient *client; - OpenClient *oc; - - priv = factory->priv; - - client = cal_client_new (); - if (!client) - return NULL; - - oc = g_new (OpenClient, 1); - oc->factory = factory; - - oc->uri = g_strdup (uristr); - - oc->client = client; - oc->uid_comp_hash = g_hash_table_new (g_str_hash, g_str_equal); - oc->pending = NULL; - oc->open = FALSE; - - gtk_signal_connect (GTK_OBJECT (oc->client), "cal_opened", - GTK_SIGNAL_FUNC (cal_opened_cb), oc); - - if (!cal_client_open_calendar (oc->client, uristr, FALSE)) { - g_free (oc->uri); - gtk_object_unref (GTK_OBJECT (oc->client)); - g_hash_table_destroy (oc->uid_comp_hash); - g_free (oc); - - return NULL; - } - - g_hash_table_insert (priv->uri_client_hash, oc->uri, oc); - - return oc; -} - -/* Looks up an open client or queues it for being opened. Returns the client or - * NULL on failure; in the latter case it sets the ev exception. - */ -static OpenClient * -lookup_open_client (CompEditorFactory *factory, const char *str_uri, CORBA_Environment *ev) -{ - CompEditorFactoryPrivate *priv; - OpenClient *oc; - EUri *uri; - - priv = factory->priv; - - /* Look up the client */ - - uri = e_uri_new (str_uri); - if (!uri) { - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_CompEditorFactory_InvalidURI); - return NULL; - } - e_uri_free (uri); - - oc = g_hash_table_lookup (priv->uri_client_hash, str_uri); - if (!oc) { - oc = open_client (factory, str_uri); - if (!oc) { - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_CompEditorFactory_BackendContactError); - return NULL; - } - } - - return oc; -} - -/* Queues a request for editing an existing object */ -static void -queue_edit_existing (OpenClient *oc, const char *uid) -{ - Request *request; - - g_assert (!oc->open); - - request = g_new (Request, 1); - request->type = REQUEST_EXISTING; - request->u.existing.uid = g_strdup (uid); - - oc->pending = g_slist_append (oc->pending, request); -} - -/* ::editExisting() method implementation */ -static void -impl_editExisting (PortableServer_Servant servant, - const CORBA_char *str_uri, - const GNOME_Evolution_Calendar_CalObjUID uid, - CORBA_Environment *ev) -{ - CompEditorFactory *factory; - CompEditorFactoryPrivate *priv; - OpenClient *oc; - Component *c; - - factory = COMP_EDITOR_FACTORY (bonobo_object_from_servant (servant)); - priv = factory->priv; - - oc = lookup_open_client (factory, str_uri, ev); - if (!oc) - return; - - if (!oc->open) { - queue_edit_existing (oc, uid); - return; - } - - /* Look up the component */ - - c = g_hash_table_lookup (oc->uid_comp_hash, uid); - if (!c) - edit_existing (oc, uid); - else { - g_assert (c->editor != NULL); - comp_editor_focus (c->editor); - } -} - -/* Queues a request for creating a new object */ -static void -queue_edit_new (OpenClient *oc, const GNOME_Evolution_Calendar_CompEditorFactory_CompEditorMode type) -{ - Request *request; - - g_assert (!oc->open); - - request = g_new (Request, 1); - request->type = REQUEST_NEW; - request->u.new.type = type; - - oc->pending = g_slist_append (oc->pending, request); -} - -/* ::editNew() method implementation */ -static void -impl_editNew (PortableServer_Servant servant, - const CORBA_char *str_uri, - const GNOME_Evolution_Calendar_CompEditorFactory_CompEditorMode corba_type, - CORBA_Environment *ev) -{ - CompEditorFactory *factory; - CompEditorFactoryPrivate *priv; - OpenClient *oc; - - factory = COMP_EDITOR_FACTORY (bonobo_object_from_servant (servant)); - priv = factory->priv; - - oc = lookup_open_client (factory, str_uri, ev); - if (!oc) - return; - - if (!oc->open) - queue_edit_new (oc, corba_type); - else - edit_new (oc, corba_type); -} - - - -/** - * comp_editor_factory_new: - * - * Creates a new calendar component editor factory. - * - * Return value: A newly-created component editor factory. - **/ -CompEditorFactory * -comp_editor_factory_new (void) -{ - return gtk_type_new (TYPE_COMP_EDITOR_FACTORY); -} - - diff --git a/calendar/gui/comp-editor-factory.h b/calendar/gui/comp-editor-factory.h deleted file mode 100644 index 21e27941fc..0000000000 --- a/calendar/gui/comp-editor-factory.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Evolution calendar - Component editor factory object - * - * 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef COMP_EDITOR_FACTORY_H -#define COMP_EDITOR_FACTORY_H - -#include <bonobo/bonobo-xobject.h> -#include "evolution-calendar.h" - - - -#define TYPE_COMP_EDITOR_FACTORY (comp_editor_factory_get_type ()) -#define COMP_EDITOR_FACTORY(obj) (GTK_CHECK_CAST ((obj), TYPE_COMP_EDITOR_FACTORY, \ - CompEditorFactory)) -#define COMP_EDITOR_FACTORY_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), \ - TYPE_COMP_EDITOR_FACTORY, CompEditorFactoryClass)) -#define IS_COMP_EDITOR_FACTORY(obj) (GTK_CHECK_TYPE ((obj), TYPE_COMP_EDITOR_FACTORY)) -#define IS_COMP_EDITOR_FACTORY_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), TYPE_COMP_EDITOR_FACTORY)) - -typedef struct CompEditorFactoryPrivate CompEditorFactoryPrivate; - -typedef struct { - BonoboXObject xobject; - - /* Private data */ - CompEditorFactoryPrivate *priv; -} CompEditorFactory; - -typedef struct { - BonoboXObjectClass parent_class; - - POA_GNOME_Evolution_Calendar_CompEditorFactory__epv epv; -} CompEditorFactoryClass; - -GtkType comp_editor_factory_get_type (void); - -CompEditorFactory *comp_editor_factory_new (void); - - - -#endif diff --git a/calendar/gui/comp-util.c b/calendar/gui/comp-util.c deleted file mode 100644 index 5edfb90af5..0000000000 --- a/calendar/gui/comp-util.c +++ /dev/null @@ -1,325 +0,0 @@ -/* Evolution calendar - Utilities for manipulating CalComponent objects - * - * Copyright (C) 2000 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "calendar-config.h" -#include "comp-util.h" -#include "dialogs/delete-comp.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, time_t t, icaltimezone *zone) -{ - 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 = icaltime_from_timet_with_zone (t, FALSE, zone); - cdt->tzid = g_strdup (icaltimezone_get_tzid (zone)); - - list = g_slist_append (list, cdt); - cal_component_set_exdate_list (comp, list); - cal_component_free_exdate_list (list); -} - - - -/* Returns TRUE if the TZIDs are equivalent, i.e. both NULL or the same. */ -static gboolean -cal_component_compare_tzid (const char *tzid1, const char *tzid2) -{ - gboolean retval = TRUE; - - if (tzid1) { - if (!tzid2 || strcmp (tzid1, tzid2)) - retval = FALSE; - } else { - if (tzid2) - retval = FALSE; - } - - return retval; -} - -/** - * cal_comp_util_compare_event_timezones: - * @comp: A calendar component object. - * @client: A #CalClient. - * - * Checks if the component uses the given timezone for both the start and - * the end time, or if the UTC offsets of the start and end times are the same - * as in the given zone. - * - * Returns: TRUE if the component's start and end time are at the same UTC - * offset in the given timezone. - **/ -gboolean -cal_comp_util_compare_event_timezones (CalComponent *comp, - CalClient *client, - icaltimezone *zone) -{ - CalClientGetStatus status; - CalComponentDateTime start_datetime, end_datetime; - const char *tzid; - gboolean retval = FALSE; - icaltimezone *start_zone, *end_zone; - int offset1, offset2; - - tzid = icaltimezone_get_tzid (zone); - - cal_component_get_dtstart (comp, &start_datetime); - cal_component_get_dtend (comp, &end_datetime); - - /* If either the DTSTART or the DTEND is a DATE value, we return TRUE. - Maybe if one was a DATE-TIME we should check that, but that should - not happen often. */ - if ((start_datetime.value && start_datetime.value->is_date) - || (end_datetime.value && end_datetime.value->is_date)) { - retval = TRUE; - goto out; - } - - /* If the event uses UTC for DTSTART & DTEND, return TRUE. Outlook - will send single events as UTC, so we don't want to mark all of - these. */ - if ((!start_datetime.value || start_datetime.value->is_utc) - && (!end_datetime.value || end_datetime.value->is_utc)) { - retval = TRUE; - goto out; - } - - /* If the event uses floating time for DTSTART & DTEND, return TRUE. - Imported vCalendar files will use floating times, so we don't want - to mark all of these. */ - if (!start_datetime.tzid && !end_datetime.tzid) { - retval = TRUE; - goto out; - } - - /* FIXME: DURATION may be used instead. */ - if (cal_component_compare_tzid (tzid, start_datetime.tzid) - && cal_component_compare_tzid (tzid, end_datetime.tzid)) { - /* If both TZIDs are the same as the given zone's TZID, then - we know the timezones are the same so we return TRUE. */ - retval = TRUE; - } else { - /* If the TZIDs differ, we have to compare the UTC offsets - of the start and end times, using their own timezones and - the given timezone. */ - status = cal_client_get_timezone (client, - start_datetime.tzid, - &start_zone); - if (status != CAL_CLIENT_GET_SUCCESS) - goto out; - - if (start_datetime.value) { - offset1 = icaltimezone_get_utc_offset (start_zone, - start_datetime.value, - NULL); - offset2 = icaltimezone_get_utc_offset (zone, - start_datetime.value, - NULL); - if (offset1 != offset2) - goto out; - } - - status = cal_client_get_timezone (client, - end_datetime.tzid, - &end_zone); - if (status != CAL_CLIENT_GET_SUCCESS) - goto out; - - if (end_datetime.value) { - offset1 = icaltimezone_get_utc_offset (end_zone, - end_datetime.value, - NULL); - offset2 = icaltimezone_get_utc_offset (zone, - end_datetime.value, - NULL); - if (offset1 != offset2) - goto out; - } - - retval = TRUE; - } - - out: - - cal_component_free_datetime (&start_datetime); - cal_component_free_datetime (&end_datetime); - - return retval; -} - -/** - * cal_comp_confirm_delete_empty_comp: - * @comp: A calendar component. - * @client: Calendar client where the component purportedly lives. - * @widget: Widget to be used as the basis for UTF8 conversion. - * - * Assumming a calendar component with an empty SUMMARY property (as per - * string_is_empty()), asks whether the user wants to delete it based on - * whether the appointment is on the calendar server or not. If the - * component is on the server, this function will present a confirmation - * dialog and delete the component if the user tells it to. If the component - * is not on the server it will just return TRUE. - * - * Return value: A result code indicating whether the component - * was not on the server and is to be deleted locally, whether it - * was on the server and the user deleted it, or whether the - * user cancelled the deletion. - **/ -ConfirmDeleteEmptyCompResult -cal_comp_confirm_delete_empty_comp (CalComponent *comp, CalClient *client, GtkWidget *widget) -{ - const char *uid; - CalClientGetStatus status; - CalComponent *server_comp; - - g_return_val_if_fail (comp != NULL, EMPTY_COMP_DO_NOT_REMOVE); - g_return_val_if_fail (IS_CAL_COMPONENT (comp), EMPTY_COMP_DO_NOT_REMOVE); - g_return_val_if_fail (client != NULL, EMPTY_COMP_DO_NOT_REMOVE); - g_return_val_if_fail (IS_CAL_CLIENT (client), EMPTY_COMP_DO_NOT_REMOVE); - g_return_val_if_fail (widget != NULL, EMPTY_COMP_DO_NOT_REMOVE); - g_return_val_if_fail (GTK_IS_WIDGET (widget), EMPTY_COMP_DO_NOT_REMOVE); - - /* See if the component is on the server. If it is not, then it likely - * means that the appointment is new, only in the day view, and we - * haven't added it yet to the server. In that case, we don't need to - * confirm and we can just delete the event. Otherwise, we ask - * the user. - */ - cal_component_get_uid (comp, &uid); - - status = cal_client_get_object (client, uid, &server_comp); - - switch (status) { - case CAL_CLIENT_GET_SUCCESS: - gtk_object_unref (GTK_OBJECT (server_comp)); - /* Will handle confirmation below */ - break; - - case CAL_CLIENT_GET_SYNTAX_ERROR: - g_message ("confirm_delete_empty_appointment(): Syntax error when getting " - "object `%s'", - uid); - /* However, the object *is* in the server, so confirm */ - break; - - case CAL_CLIENT_GET_NOT_FOUND: - return EMPTY_COMP_REMOVE_LOCALLY; - - default: - g_assert_not_reached (); - } - - /* The event exists in the server, so confirm whether to delete it */ - - if (delete_component_dialog (comp, TRUE, 1, CAL_COMPONENT_EVENT, widget)) { - cal_client_remove_object (client, uid); - return EMPTY_COMP_REMOVED_FROM_SERVER; - } else - return EMPTY_COMP_DO_NOT_REMOVE; -} - -/** - * cal_comp_event_new_with_defaults: - * - * Creates a new VEVENT component and adds any default alarms to it as set in - * the program's configuration values. - * - * Return value: A newly-created calendar component. - **/ -CalComponent * -cal_comp_event_new_with_defaults (void) -{ - CalComponent *comp; - int interval; - CalUnits units; - CalComponentAlarm *alarm; - CalAlarmTrigger trigger; - - comp = cal_component_new (); - - cal_component_set_new_vtype (comp, CAL_COMPONENT_EVENT); - - if (!calendar_config_get_use_default_reminder ()) - return comp; - - interval = calendar_config_get_default_reminder_interval (); - units = calendar_config_get_default_reminder_units (); - - alarm = cal_component_alarm_new (); - - /* We don't set the description of the alarm; we'll copy it from the - * summary when it gets committed to the server. - */ - - cal_component_alarm_set_action (alarm, CAL_ALARM_DISPLAY); - - trigger.type = CAL_ALARM_TRIGGER_RELATIVE_START; - - memset (&trigger.u.rel_duration, 0, sizeof (trigger.u.rel_duration)); - - trigger.u.rel_duration.is_neg = TRUE; - - switch (units) { - case CAL_MINUTES: - trigger.u.rel_duration.minutes = interval; - break; - - case CAL_HOURS: - trigger.u.rel_duration.hours = interval; - break; - - case CAL_DAYS: - trigger.u.rel_duration.days = interval; - break; - - default: - g_assert_not_reached (); - } - - cal_component_alarm_set_trigger (alarm, trigger); - - cal_component_add_alarm (comp, alarm); - cal_component_alarm_free (alarm); - - return comp; -} diff --git a/calendar/gui/comp-util.h b/calendar/gui/comp-util.h deleted file mode 100644 index a4a55c0a2d..0000000000 --- a/calendar/gui/comp-util.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Evolution calendar - Utilities for manipulating CalComponent objects - * - * Copyright (C) 2000 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef COMP_UTIL_H -#define COMP_UTIL_H - -#include <gtk/gtkwidget.h> -#include <cal-util/cal-component.h> -#include <cal-client/cal-client.h> - -void cal_comp_util_add_exdate (CalComponent *comp, time_t t, icaltimezone *zone); - - -/* Returns TRUE if the component uses the given timezone for both DTSTART - and DTEND, or if the UTC offsets of the start and end times are the same - as in the given zone. */ -gboolean cal_comp_util_compare_event_timezones (CalComponent *comp, - CalClient *client, - icaltimezone *zone); - -typedef enum { - EMPTY_COMP_REMOVE_LOCALLY, - EMPTY_COMP_REMOVED_FROM_SERVER, - EMPTY_COMP_DO_NOT_REMOVE -} ConfirmDeleteEmptyCompResult; - -ConfirmDeleteEmptyCompResult cal_comp_confirm_delete_empty_comp (CalComponent *comp, - CalClient *client, - GtkWidget *widget); - -CalComponent *cal_comp_event_new_with_defaults (void); - -#endif diff --git a/calendar/gui/component-factory.c b/calendar/gui/component-factory.c deleted file mode 100644 index b4a2b3ab89..0000000000 --- a/calendar/gui/component-factory.c +++ /dev/null @@ -1,729 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* component-factory.c - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Ettore Perazzoli <ettore@ximian.com> - */ - -#include <config.h> - -#include <errno.h> -#include <libgnomevfs/gnome-vfs-types.h> -#include <libgnomevfs/gnome-vfs-uri.h> -#include <libgnomevfs/gnome-vfs-ops.h> -#include <libgnomevfs/gnome-vfs-directory.h> -#include <libgnomevfs/gnome-vfs-file-info.h> - -#include <bonobo/bonobo-generic-factory.h> -#include <bonobo/bonobo-context.h> -#include <bonobo/bonobo-exception.h> -#include "evolution-shell-component.h" -#include "calendar-offline-handler.h" -#include "component-factory.h" -#include "tasks-control-factory.h" -#include "config-control-factory.h" -#include "control-factory.h" -#include "calendar-config.h" -#include "tasks-control.h" -#include "tasks-migrate.h" - - - -/* OAFIID for the component. */ -#define COMPONENT_ID "OAFIID:GNOME_Evolution_Calendar_ShellComponent" - -/* Folder type IDs */ -#define FOLDER_CALENDAR "calendar" -#define FOLDER_TASKS "tasks" - -/* IDs for user creatable items */ -#define CREATE_EVENT_ID "event" -#define CREATE_ALLDAY_EVENT_ID "allday-event" -#define CREATE_MEETING_ID "meeting" -#define CREATE_TASK_ID "task" - -char *evolution_dir; -EvolutionShellClient *global_shell_client = NULL; - -static const EvolutionShellComponentFolderType folder_types[] = { - { FOLDER_CALENDAR, - "evolution-calendar.png", - N_("Calendar"), - N_("Folder containing appointments and events"), - TRUE, NULL, NULL }, - { FOLDER_TASKS, - "evolution-tasks.png", - N_("Tasks"), - N_("Folder containing to-do items"), - TRUE, NULL, NULL }, - { NULL, NULL } -}; - - - -/* EvolutionShellComponent methods and signals. */ - -static EvolutionShellComponentResult -create_view (EvolutionShellComponent *shell_component, - const char *physical_uri, - const char *type, - const char *view_info, - BonoboControl **control_return, - void *closure) -{ - BonoboControl *control; - - if (!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); - if (!g_strcasecmp (type, "calendar") && *view_info) - bonobo_control_set_property (control, "view", view_info, 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; - GnomeVFSURI *uri; - - CORBA_exception_init (&ev); - - if (strcmp (type, FOLDER_CALENDAR) && strcmp (type, FOLDER_TASKS)) { - GNOME_Evolution_ShellComponentListener_notifyResult ( - listener, - GNOME_Evolution_ShellComponentListener_UNSUPPORTED_TYPE, - &ev); - CORBA_exception_free (&ev); - return; - } - - uri = gnome_vfs_uri_new (physical_uri); - if (uri) { - /* we don't need to do anything */ - GNOME_Evolution_ShellComponentListener_notifyResult ( - listener, - GNOME_Evolution_ShellComponentListener_OK, &ev); - gnome_vfs_uri_unref (uri); - } - else { - GNOME_Evolution_ShellComponentListener_notifyResult ( - listener, - GNOME_Evolution_ShellComponentListener_INVALID_URI, - &ev); - } - - CORBA_exception_free (&ev); -} - -/* Asks the alarm daemon to stop monitoring the specified URI */ -static void -stop_alarms (GnomeVFSURI *uri) -{ - char *str_uri; - CORBA_Environment ev; - GNOME_Evolution_Calendar_AlarmNotify an; - - /* Activate the alarm notification service */ - - CORBA_exception_init (&ev); - an = oaf_activate_from_id ("OAFIID:GNOME_Evolution_Calendar_AlarmNotify", 0, NULL, &ev); - - if (BONOBO_EX (&ev)) { - g_message ("stop_alarms(): Could not activate the alarm notification service"); - CORBA_exception_free (&ev); - return; - } - CORBA_exception_free (&ev); - - /* Ask the service to remove the URI from its list of calendars */ - - str_uri = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE); - g_assert (str_uri != NULL); - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_AlarmNotify_removeCalendar (an, str_uri, &ev); - g_free (str_uri); - - if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_AlarmNotify_InvalidURI)) { - g_message ("stop_alarms(): Invalid URI reported from the alarm notification service"); - } else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_AlarmNotify_NotFound)) { - /* This is OK; the service may not have loaded that calendar */ - } else if (BONOBO_EX (&ev)) { - g_message ("stop_alarms(): Could not issue the removeCalendar request"); - } - - CORBA_exception_free (&ev); - - /* Get rid of the service */ - - CORBA_exception_init (&ev); - bonobo_object_release_unref (an, &ev); - if (BONOBO_EX (&ev)) - g_message ("stop_alarms(): Could not unref the alarm notification service"); - CORBA_exception_free (&ev); -} - -static void -remove_folder (EvolutionShellComponent *shell_component, - const char *physical_uri, - const char *type, - const GNOME_Evolution_ShellComponentListener listener, - void *closure) -{ - GnomeVFSURI *dir_uri, *data_uri, *backup_uri; - GnomeVFSResult data_result, backup_result; - - /* check type */ - if (strcmp (type, FOLDER_CALENDAR) && strcmp (type, FOLDER_TASKS)) { - CORBA_Environment ev; - - CORBA_exception_init (&ev); - GNOME_Evolution_ShellComponentListener_notifyResult ( - listener, - GNOME_Evolution_ShellComponentListener_UNSUPPORTED_TYPE, - &ev); - - if (BONOBO_EX (&ev)) - g_message ("remove_folder(): Could not notify the listener of " - "an unsupported folder type"); - - CORBA_exception_free (&ev); - return; - } - - /* check URI */ - dir_uri = gnome_vfs_uri_new (physical_uri); - if (!dir_uri) { - CORBA_Environment ev; - - CORBA_exception_init (&ev); - GNOME_Evolution_ShellComponentListener_notifyResult ( - listener, - GNOME_Evolution_ShellComponentListener_INVALID_URI, - &ev); - CORBA_exception_free (&ev); - return; - } - - /* Compute the URIs of the appropriate files */ - - if (strcmp (type, FOLDER_CALENDAR) == 0) { - data_uri = gnome_vfs_uri_append_file_name (dir_uri, "calendar.ics"); - backup_uri = gnome_vfs_uri_append_file_name (dir_uri, "calendar.ics~"); - } else if (strcmp (type, FOLDER_TASKS) == 0) { - data_uri = gnome_vfs_uri_append_file_name (dir_uri, "tasks.ics"); - backup_uri = gnome_vfs_uri_append_file_name (dir_uri, "tasks.ics~"); - } else { - g_assert_not_reached (); - return; - } - - if (!data_uri || !backup_uri) { - CORBA_Environment ev; - - g_message ("remove_folder(): Could not generate the data/backup URIs"); - - CORBA_exception_init (&ev); - GNOME_Evolution_ShellComponentListener_notifyResult ( - listener, - GNOME_Evolution_ShellComponentListener_INVALID_URI, - &ev); - - if (BONOBO_EX (&ev)) - g_message ("remove_folder(): Could not notify the listener " - "of an invalid URI"); - - CORBA_exception_free (&ev); - - goto out; - } - - /* Ask the alarm daemon to stop monitoring this URI */ - - stop_alarms (data_uri); - - /* Delete the data and backup files; the shell will take care of the rest */ - - data_result = gnome_vfs_unlink_from_uri (data_uri); - backup_result = gnome_vfs_unlink_from_uri (backup_uri); - - if ((data_result == GNOME_VFS_OK || data_result == GNOME_VFS_ERROR_NOT_FOUND) - && (backup_result == GNOME_VFS_OK || backup_result == GNOME_VFS_ERROR_NOT_FOUND)) { - CORBA_Environment ev; - - CORBA_exception_init (&ev); - GNOME_Evolution_ShellComponentListener_notifyResult ( - listener, - GNOME_Evolution_ShellComponentListener_OK, - &ev); - - if (BONOBO_EX (&ev)) - g_message ("remove_folder(): Could not notify the listener about success"); - - CORBA_exception_free (&ev); - } else { - CORBA_Environment ev; - - CORBA_exception_init (&ev); - GNOME_Evolution_ShellComponentListener_notifyResult ( - listener, - GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED, - &ev); - - if (BONOBO_EX (&ev)) - g_message ("remove_folder(): Could not notify the listener about failure"); - - CORBA_exception_free (&ev); - } - - out: - - gnome_vfs_uri_unref (dir_uri); - - if (data_uri) - gnome_vfs_uri_unref (data_uri); - - if (backup_uri) - gnome_vfs_uri_unref (backup_uri); -} - -static GNOME_Evolution_ShellComponentListener_Result -xfer_file (GnomeVFSURI *base_src_uri, - GnomeVFSURI *base_dest_uri, - const char *file_name, - int remove_source) -{ - GnomeVFSURI *src_uri, *dest_uri; - GnomeVFSHandle *hin, *hout; - GnomeVFSResult result; - GnomeVFSFileInfo file_info; - GnomeVFSFileSize size; - char *buffer; - - src_uri = gnome_vfs_uri_append_file_name (base_src_uri, file_name); - - result = gnome_vfs_open_uri (&hin, src_uri, GNOME_VFS_OPEN_READ); - if (result == GNOME_VFS_ERROR_NOT_FOUND) { - gnome_vfs_uri_unref (src_uri); - return GNOME_Evolution_ShellComponentListener_OK; /* No need to xfer anything. */ - } - if (result != GNOME_VFS_OK) { - gnome_vfs_uri_unref (src_uri); - return GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED; - } - - result = gnome_vfs_get_file_info_uri (src_uri, &file_info, GNOME_VFS_FILE_INFO_DEFAULT); - if (result != GNOME_VFS_OK) { - gnome_vfs_uri_unref (src_uri); - return GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED; - } - - dest_uri = gnome_vfs_uri_append_file_name (base_dest_uri, file_name); - - result = gnome_vfs_create_uri (&hout, dest_uri, GNOME_VFS_OPEN_WRITE, FALSE, 0600); - if (result != GNOME_VFS_OK) { - gnome_vfs_close (hin); - gnome_vfs_uri_unref (src_uri); - gnome_vfs_uri_unref (dest_uri); - return GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED; - } - - /* write source file to destination file */ - buffer = g_malloc (file_info.size); - result = gnome_vfs_read (hin, buffer, file_info.size, &size); - if (result != GNOME_VFS_OK) { - gnome_vfs_close (hin); - gnome_vfs_close (hout); - gnome_vfs_uri_unref (src_uri); - gnome_vfs_uri_unref (dest_uri); - g_free (buffer); - return GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED; - } - - result = gnome_vfs_write (hout, buffer, file_info.size, &size); - if (result != GNOME_VFS_OK) { - gnome_vfs_close (hin); - gnome_vfs_close (hout); - gnome_vfs_uri_unref (src_uri); - gnome_vfs_uri_unref (dest_uri); - g_free (buffer); - return GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED; - } - - if (remove_source) { - char *text_uri; - - /* Sigh, we have to do this as there is no gnome_vfs_unlink_uri(). :-( */ - - text_uri = gnome_vfs_uri_to_string (src_uri, GNOME_VFS_URI_HIDE_NONE); - result = gnome_vfs_unlink (text_uri); - g_free (text_uri); - } - - gnome_vfs_close (hin); - gnome_vfs_close (hout); - gnome_vfs_uri_unref (src_uri); - gnome_vfs_uri_unref (dest_uri); - g_free (buffer); - - return GNOME_Evolution_ShellComponentListener_OK; -} - -static void -xfer_folder (EvolutionShellComponent *shell_component, - const char *source_physical_uri, - const char *destination_physical_uri, - const char *type, - gboolean remove_source, - const GNOME_Evolution_ShellComponentListener listener, - void *closure) -{ - CORBA_Environment ev; - GnomeVFSURI *src_uri; - GnomeVFSURI *dest_uri; - GnomeVFSResult result; - char *filename, *backup_filename; - - CORBA_exception_init (&ev); - - /* check type */ - if (strcmp (type, FOLDER_CALENDAR) && strcmp (type, FOLDER_TASKS)) { - GNOME_Evolution_ShellComponentListener_notifyResult ( - listener, - GNOME_Evolution_ShellComponentListener_UNSUPPORTED_TYPE, - &ev); - CORBA_exception_free (&ev); - return; - } - - /* check URIs */ - src_uri = gnome_vfs_uri_new (source_physical_uri); - dest_uri = gnome_vfs_uri_new (destination_physical_uri); - if (!src_uri || ! dest_uri) { - GNOME_Evolution_ShellComponentListener_notifyResult ( - listener, - GNOME_Evolution_ShellComponentListener_INVALID_URI, - &ev); - gnome_vfs_uri_unref (src_uri); - gnome_vfs_uri_unref (dest_uri); - CORBA_exception_free (&ev); - return; - } - - if (strcmp (type, FOLDER_CALENDAR) == 0) { - filename = "calendar.ics"; - backup_filename = "calendar.ics~"; - } else if (strcmp (type, FOLDER_TASKS) == 0) { - filename = "tasks.ics"; - backup_filename = "tasks.ics~"; - } else { - g_assert_not_reached (); - return; - } - - result = xfer_file (src_uri, dest_uri, filename, remove_source); - if (result == GNOME_Evolution_ShellComponentListener_OK) - result = xfer_file (src_uri, dest_uri, backup_filename, remove_source); - - GNOME_Evolution_ShellComponentListener_notifyResult (listener, result, &ev); - - gnome_vfs_uri_unref (src_uri); - gnome_vfs_uri_unref (dest_uri); - - CORBA_exception_free (&ev); -} - -static GList *shells = NULL; - -static void -owner_set_cb (EvolutionShellComponent *shell_component, - EvolutionShellClient *shell_client, - const char *evolution_homedir, - gpointer user_data) -{ - static gboolean migrated = FALSE; - - evolution_dir = g_strdup (evolution_homedir); - - if (!migrated) { - tasks_migrate (); - migrated = TRUE; - } - - shells = g_list_append (shells, shell_component); - - global_shell_client = shell_client; - - config_control_factory_register (bonobo_object_corba_objref (BONOBO_OBJECT (shell_client))); -} - -static void -owner_unset_cb (EvolutionShellComponent *shell_component, - gpointer user_data) -{ - shells = g_list_remove (shells, shell_component); - - if (g_list_length (shells) == 0) - gtk_main_quit (); -} - -/* Computes the final URI for a calendar component */ -static char * -get_data_uri (const char *uri, CalComponentVType vtype) -{ - if (uri) { - if (*uri != '/' && strncmp (uri, "file:", 5) != 0) - return g_strdup (uri); - if (vtype == CAL_COMPONENT_EVENT) - return g_concat_dir_and_file (uri, "calendar.ics"); - else if (vtype == CAL_COMPONENT_TODO) - return g_concat_dir_and_file (uri, "tasks.ics"); - else - g_assert_not_reached (); - } else { - if (vtype == CAL_COMPONENT_EVENT) - return g_concat_dir_and_file (g_get_home_dir (), - "evolution/local/Calendar/calendar.ics"); - else if (vtype == CAL_COMPONENT_TODO) - return g_concat_dir_and_file (g_get_home_dir (), - "evolution/local/Tasks/tasks.ics"); - else - g_assert_not_reached (); - } - - return NULL; -} - -/* Creates a calendar component at a specified URI. If the URI is NULL then it - * uses the default folder for that type of component. - */ -static void -create_component (const char *uri, GNOME_Evolution_Calendar_CompEditorFactory_CompEditorMode type) -{ - char *real_uri; - CORBA_Environment ev; - GNOME_Evolution_Calendar_CompEditorFactory factory; - CalComponentVType vtype; - - switch (type) { - case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_EVENT: - case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_ALLDAY_EVENT: - case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_MEETING: - vtype = CAL_COMPONENT_EVENT; - break; - case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_TODO: - vtype = CAL_COMPONENT_TODO; - break; - default: - g_assert_not_reached (); - return; - } - - real_uri = get_data_uri (uri, vtype); - - /* Get the factory */ - - CORBA_exception_init (&ev); - factory = oaf_activate_from_id ("OAFIID:GNOME_Evolution_Calendar_CompEditorFactory", - 0, NULL, &ev); - - if (BONOBO_EX (&ev)) { - g_message ("create_component(): Could not activate the component editor factory"); - CORBA_exception_free (&ev); - g_free (real_uri); - return; - } - CORBA_exception_free (&ev); - - /* Create the item */ - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_CompEditorFactory_editNew (factory, real_uri, type, &ev); - - if (BONOBO_EX (&ev)) - g_message ("create_component(): Exception while creating the component"); - - CORBA_exception_free (&ev); - g_free (real_uri); - - /* Get rid of the factory */ - - CORBA_exception_init (&ev); - bonobo_object_release_unref (factory, &ev); - if (BONOBO_EX (&ev)) - g_message ("create_component(): Could not unref the calendar component factory"); - - CORBA_exception_free (&ev); -} - -/* Callback used when we must create a user-creatable item */ -static void -sc_user_create_new_item_cb (EvolutionShellComponent *shell_component, - const char *id, - const char *parent_folder_physical_uri, - const char *parent_folder_type) -{ - if (strcmp (id, CREATE_EVENT_ID) == 0) { - if (strcmp (parent_folder_type, FOLDER_CALENDAR) == 0) - create_component (parent_folder_physical_uri, - GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_EVENT); - else - create_component (NULL, - GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_EVENT); - } else if (strcmp (id, CREATE_ALLDAY_EVENT_ID) == 0) { - if (strcmp (parent_folder_type, FOLDER_CALENDAR) == 0) - create_component (parent_folder_physical_uri, - GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_ALLDAY_EVENT); - else - create_component (NULL, - GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_ALLDAY_EVENT); - } else if (strcmp (id, CREATE_MEETING_ID) == 0) { - if (strcmp (parent_folder_type, FOLDER_CALENDAR) == 0) - create_component (parent_folder_physical_uri, - GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_MEETING); - else - create_component (NULL, - GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_MEETING); - } else if (strcmp (id, CREATE_TASK_ID) == 0) { - if (strcmp (parent_folder_type, FOLDER_TASKS) == 0) - create_component (parent_folder_physical_uri, - GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_TODO); - else - create_component (NULL, - GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_TODO); - } else - g_assert_not_reached (); -} - - -/* The factory function. */ - -static void -add_creatable_item (EvolutionShellComponent *shell_component, - const char *id, - const char *description, - const char *menu_description, - char menu_shortcut, - const char *icon_name) -{ - char *icon_path; - GdkPixbuf *icon; - - if (icon_name == NULL) { - icon_path = NULL; - icon = NULL; - } else { - icon_path = g_concat_dir_and_file (EVOLUTION_ICONSDIR, icon_name); - icon = gdk_pixbuf_new_from_file (icon_path); - } - - evolution_shell_component_add_user_creatable_item (shell_component, - id, - description, - menu_description, - menu_shortcut, - icon); - - if (icon != NULL) - gdk_pixbuf_unref (icon); - g_free (icon_path); -} - -static BonoboObject * -create_object (void) -{ - EvolutionShellComponent *shell_component; - CalendarOfflineHandler *offline_handler; - - shell_component = evolution_shell_component_new (folder_types, - NULL, - create_view, - create_folder, - remove_folder, - xfer_folder, - NULL, /* populate_folder_context_menu_fn */ - NULL, /* get_dnd_selection_fn */ - NULL /* closure */); - - /* Offline handler */ - offline_handler = calendar_offline_handler_new (); - bonobo_object_add_interface (BONOBO_OBJECT (shell_component), - BONOBO_OBJECT (offline_handler)); - - 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); - - /* User creatable items */ - - add_creatable_item (shell_component, CREATE_MEETING_ID, - _("New meeting"), _("_Meeting"), - 's', "meeting-request.png"); - - add_creatable_item (shell_component, CREATE_TASK_ID, - _("New task"), _("_Task"), - 't', "new_task-16.png"); - - add_creatable_item (shell_component, CREATE_ALLDAY_EVENT_ID, - _("New All Day Appointment"), _("All _Day Appointment"), - 'd', "new_all_day_event.png"); - - add_creatable_item (shell_component, CREATE_EVENT_ID, - _("New appointment"), _("_Appointment"), - 'a', "new_appointment.xpm"); - - gtk_signal_connect (GTK_OBJECT (shell_component), "user_create_new_item", - GTK_SIGNAL_FUNC (sc_user_create_new_item_cb), NULL); - - return BONOBO_OBJECT (shell_component); -} - - -void -component_factory_init (void) -{ - BonoboObject *object; - int result; - - object = create_object (); - - result = oaf_active_server_register (COMPONENT_ID, bonobo_object_corba_objref (object)); - - if (result == OAF_REG_ERROR) - g_error ("Cannot initialize Evolution's calendar component."); -} diff --git a/calendar/gui/component-factory.h b/calendar/gui/component-factory.h deleted file mode 100644 index 576255cb6d..0000000000 --- a/calendar/gui/component-factory.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* component-factory.h - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: 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/config-control-factory.c b/calendar/gui/config-control-factory.c deleted file mode 100644 index f2a9b48383..0000000000 --- a/calendar/gui/config-control-factory.c +++ /dev/null @@ -1,61 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* config-control-factory.c - * - * Copyright (C) 2002 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Ettore Perazzoli - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "config-control-factory.h" - -#include "dialogs/cal-prefs-dialog.h" - -#include <bonobo/bonobo-generic-factory.h> - - -#define CONFIG_CONTROL_FACTORY_ID "OAFIID:GNOME_Evolution_Calendar_ConfigControlFactory" -static BonoboGenericFactory *generic_factory = NULL; - - -static BonoboObject * -factory_fn (BonoboGenericFactory *generic_factory, - void *data) -{ - EvolutionConfigControl *config_control; - - config_control = cal_prefs_dialog_new (); - - return BONOBO_OBJECT (config_control); -} - -gboolean -config_control_factory_register (GNOME_Evolution_Shell shell) -{ - generic_factory = bonobo_generic_factory_new (CONFIG_CONTROL_FACTORY_ID, - factory_fn, shell); - - if (generic_factory == NULL) { - g_warning ("Cannot register %s", CONFIG_CONTROL_FACTORY_ID); - return FALSE; - } - - return TRUE; -} diff --git a/calendar/gui/config-control-factory.h b/calendar/gui/config-control-factory.h deleted file mode 100644 index b0ff927fa9..0000000000 --- a/calendar/gui/config-control-factory.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* config-control-factory.h - * - * Copyright (C) 2002 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Ettore Perazzoli - */ - -#ifndef CONFIG_CONTROL_FACTORY_H -#define CONFIG_CONTROL_FACTORY_H - -#include "Evolution.h" - -gboolean config_control_factory_register (GNOME_Evolution_Shell shell); - -#endif diff --git a/calendar/gui/control-factory.c b/calendar/gui/control-factory.c deleted file mode 100644 index a17790f197..0000000000 --- a/calendar/gui/control-factory.c +++ /dev/null @@ -1,267 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* control-factory.c - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Ettore Perazzoli <ettore@ximian.com> - */ - -#include <config.h> -#include <glade/glade.h> -#include <bonobo/bonobo-control.h> -#include <bonobo/bonobo-generic-factory.h> -#include <bonobo/bonobo-persist-file.h> -#include <bonobo/bonobo-context.h> -#include <glade/glade.h> - -#include <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 PROPERTY_CALENDAR_VIEW "view" -#define PROPERTY_CALENDAR_VIEW_IDX 2 - -#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 data) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - if (activate) - calendar_control_activate (control, gcal); - else - calendar_control_deactivate (control, gcal); -} - -static void -get_prop (BonoboPropertyBag *bag, - BonoboArg *arg, - guint arg_id, - CORBA_Environment *ev, - gpointer user_data) -{ - GnomeCalendar *gcal = user_data; - const char *uri; - - switch (arg_id) { - - case PROPERTY_CALENDAR_URI_IDX: - uri = cal_client_get_uri (gnome_calendar_get_cal_client (gcal)); - BONOBO_ARG_SET_STRING (arg, uri); - break; - - case PROPERTY_CALENDAR_VIEW_IDX: - switch (gnome_calendar_get_view (gcal)) { - case GNOME_CAL_DAY_VIEW: - BONOBO_ARG_SET_STRING (arg, "day"); - break; - case GNOME_CAL_WEEK_VIEW: - BONOBO_ARG_SET_STRING (arg, "week"); - break; - case GNOME_CAL_WORK_WEEK_VIEW: - BONOBO_ARG_SET_STRING (arg, "workweek"); - break; - case GNOME_CAL_MONTH_VIEW: - BONOBO_ARG_SET_STRING (arg, "month"); - break; - } - 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 *string; - GnomeCalendarViewType view; - - switch (arg_id) { - case PROPERTY_CALENDAR_URI_IDX: - string = BONOBO_ARG_GET_STRING (arg); - if (!gnome_calendar_open (gcal, string)) { - char *msg; - - msg = g_strdup_printf (_("Could not open the folder in '%s'"), string); - gnome_error_dialog_parented ( - msg, - GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (gcal)))); - g_free (msg); - } - break; - - case PROPERTY_CALENDAR_VIEW_IDX: - string = BONOBO_ARG_GET_STRING (arg); - if (!g_strcasecmp (string, "week")) - view = GNOME_CAL_WEEK_VIEW; - else if (!g_strcasecmp (string, "workweek")) - view = GNOME_CAL_WORK_WEEK_VIEW; - else if (!g_strcasecmp (string, "month")) - view = GNOME_CAL_MONTH_VIEW; - else - view = GNOME_CAL_DAY_VIEW; - - /* This doesn't actually work, because the GalView - * comes along and resets the view. FIXME. - */ - gnome_calendar_set_view (gcal, view, FALSE, TRUE); - 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_property_bag_add (pbag, - PROPERTY_CALENDAR_VIEW, - PROPERTY_CALENDAR_VIEW_IDX, - BONOBO_ARG_STRING, - NULL, - _("The type of view to show"), - 0); - - bonobo_control_set_properties (control, pbag); - bonobo_object_unref (BONOBO_OBJECT (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); - bonobo_running_context_auto_exit_unref (BONOBO_OBJECT (factory)); - - if (factory == NULL) - g_error ("I could not register a Calendar control factory."); -} - -#if 0 -static int -load_calendar (BonoboPersistFile *pf, const CORBA_char *filename, CORBA_Environment *ev, void *closure) -{ - GnomeCalendar *gcal = closure; - - return gnome_calendar_open (gcal, filename); -} - -static int -save_calendar (BonoboPersistFile *pf, const CORBA_char *filename, - CORBA_Environment *ev, - void *closure) -{ - /* Do not know how to save stuff yet */ - return -1; -} - -static void -calendar_persist_init (GnomeCalendar *gcal, BonoboControl *control) -{ - BonoboPersistFile *f; - - f = bonobo_persist_file_new (load_calendar, save_calendar, gcal); - bonobo_object_add_interface (BONOBO_OBJECT (control), BONOBO_OBJECT (f)); -} -#endif - -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; - } - gtk_object_set_data (GTK_OBJECT (gcal), "control", control); - - calendar_properties_init (gcal, control); -#if 0 - calendar_persist_init (gcal, control); -#endif - - 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 322b5a4a4e..0000000000 --- a/calendar/gui/control-factory.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* control-factory.c - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: 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 64968755b7..0000000000 --- a/calendar/gui/dialogs/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -.deps -.pure -Makefile -Makefile.in -Evolution-Addressbook-SelectNames.h -Evolution-Addressbook-SelectNames-stubs.c -Evolution-Addressbook-SelectNames-skels.c -Evolution-Addressbook-SelectNames-common.c diff --git a/calendar/gui/dialogs/Makefile.am b/calendar/gui/dialogs/Makefile.am deleted file mode 100644 index aa107d84e0..0000000000 --- a/calendar/gui/dialogs/Makefile.am +++ /dev/null @@ -1,105 +0,0 @@ -IDLS = $(top_srcdir)/addressbook/gui/component/select-names/Evolution-Addressbook-SelectNames.idl - -IDL_GENERATED = \ - Evolution-Addressbook-SelectNames.h \ - Evolution-Addressbook-SelectNames-common.c \ - Evolution-Addressbook-SelectNames-skels.c \ - Evolution-Addressbook-SelectNames-stubs.c - -$(IDL_GENERATED): $(IDLS) - $(ORBIT_IDL) -I $(srcdir) -I $(datadir)/idl `$(GNOME_CONFIG) --cflags idl` \ - $(top_srcdir)/addressbook/gui/component/select-names/Evolution-Addressbook-SelectNames.idl - -BUILT_SOURCES = $(IDL_GENERATED) - -INCLUDES = \ - -DG_LOG_DOMAIN=\"calendar-gui\" \ - -I$(top_srcdir) \ - -I$(top_srcdir)/calendar \ - -I$(top_srcdir)/calendar/cal-client \ - -I$(top_builddir)/calendar/cal-client \ - -I$(top_srcdir)/libical/src/libical \ - -I$(top_builddir)/libical/src/libical \ - -I$(top_builddir)/shell \ - -I$(top_srcdir)/shell \ - -I$(top_srcdir)/addressbook/backend/ebook \ - -I$(top_builddir)/addressbook/backend/ebook \ - -I$(includedir) \ - -DEVOLUTION_DATADIR=\""$(datadir)"\" \ - -DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \ - -DEVOLUTION_ICONSDIR=\""$(iconsdir)"\" \ - -DEVOLUTION_ETSPECDIR=\""$(etspecdir)"\" \ - -DGNOMELOCALEDIR=\""$(localedir)"\" \ - $(EVOLUTION_CALENDAR_CFLAGS) - -noinst_LIBRARIES = libcal-dialogs.a - -libcal_dialogs_a_SOURCES = \ - $(IDL_GENERATED) \ - alarm-options.c \ - alarm-options.h \ - alarm-page.c \ - alarm-page.h \ - cal-prefs-dialog.c \ - cal-prefs-dialog.h \ - cancel-comp.c \ - cancel-comp.h \ - changed-comp.c \ - changed-comp.h \ - comp-editor.c \ - comp-editor.h \ - comp-editor-page.c \ - comp-editor-page.h \ - comp-editor-util.c \ - comp-editor-util.h \ - delete-comp.c \ - delete-comp.h \ - e-delegate-dialog.c \ - e-delegate-dialog.h \ - event-editor.c \ - event-editor.h \ - event-page.c \ - event-page.h \ - meeting-page.c \ - meeting-page.h \ - recurrence-page.c \ - recurrence-page.h \ - save-comp.c \ - save-comp.h \ - schedule-page.c \ - schedule-page.h \ - send-comp.c \ - send-comp.h \ - task-editor.c \ - task-editor.h \ - task-details-page.c \ - task-details-page.h \ - task-page.c \ - task-page.h - -iconsdir = $(datadir)/images/evolution - -gladedir = $(datadir)/evolution/glade -glade_DATA = \ - alarm-options.glade \ - alarm-page.glade \ - cal-prefs-dialog.glade \ - e-delegate-dialog.glade \ - event-page.glade \ - meeting-page.glade \ - recurrence-page.glade \ - schedule-page.glade \ - task-details-page.glade \ - task-page.glade - -etspecdir = $(datadir)/evolution/etspec/ -etspec_DATA = meeting-page.etspec - -CLEANFILES = $(BUILT_SOURCES) - -dist-hook: - cd $(distdir); rm -f $(BUILT_SOURCES) - -EXTRA_DIST = \ - $(glade_DATA) \ - $(etspec_DATA) diff --git a/calendar/gui/dialogs/alarm-options.c b/calendar/gui/dialogs/alarm-options.c deleted file mode 100644 index 2ea6938633..0000000000 --- a/calendar/gui/dialogs/alarm-options.c +++ /dev/null @@ -1,585 +0,0 @@ -/* Evolution calendar - Alarm options dialog - * - * 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <glib.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <gtk/gtkmain.h> -#include <gtk/gtkcheckbutton.h> -#include <gtk/gtksignal.h> -#include <gtk/gtkwindow.h> -#include <glade/glade.h> -#include "e-util/e-dialog-widgets.h" -#include "alarm-options.h" - - - -typedef struct { - /* Whether the dialog was accepted or canceled */ - gboolean canceled; - - /* Glade XML data */ - GladeXML *xml; - - /* Toplevel */ - GtkWidget *toplevel; - - /* Buttons */ - GtkWidget *button_ok; - GtkWidget *button_cancel; - - /* Alarm repeat widgets */ - GtkWidget *repeat_toggle; - GtkWidget *repeat_group; - GtkWidget *repeat_quantity; - GtkWidget *repeat_value; - GtkWidget *repeat_unit; - - /* Display alarm widgets */ - GtkWidget *dalarm_group; - GtkWidget *dalarm_description; - - /* Audio alarm widgets */ - GtkWidget *aalarm_group; - GtkWidget *aalarm_attach; - - /* FIXME: Mail alarm widgets */ - GtkWidget *malarm_group; - - /* Procedure alarm widgets */ - GtkWidget *palarm_group; - GtkWidget *palarm_program; - GtkWidget *palarm_args; -} Dialog; - - - -/* Gets the widgets from the XML file and returns if they are all available. */ -static gboolean -get_widgets (Dialog *dialog) -{ -#define GW(name) glade_xml_get_widget (dialog->xml, name) - - dialog->toplevel = GW ("alarm-options-toplevel"); - - dialog->button_ok = GW ("button-ok"); - dialog->button_cancel = GW ("button-cancel"); - - dialog->repeat_toggle = GW ("repeat-toggle"); - dialog->repeat_group = GW ("repeat-group"); - dialog->repeat_quantity = GW ("repeat-quantity"); - dialog->repeat_value = GW ("repeat-value"); - dialog->repeat_unit = GW ("repeat-unit"); - - dialog->dalarm_group = GW ("dalarm-group"); - dialog->dalarm_description = GW ("dalarm-description"); - - dialog->aalarm_group = GW ("aalarm-group"); - dialog->aalarm_attach = GW ("aalarm-attach"); - - dialog->malarm_group = GW ("malarm-group"); - - dialog->palarm_group = GW ("palarm-group"); - dialog->palarm_program = GW ("palarm-program"); - dialog->palarm_args = GW ("palarm-args"); - - return (dialog->toplevel - && dialog->button_ok - && dialog->button_cancel - && dialog->repeat_toggle - && dialog->repeat_group - && dialog->repeat_quantity - && dialog->repeat_value - && dialog->repeat_unit - && dialog->dalarm_group - && dialog->dalarm_description - && dialog->aalarm_group - && dialog->aalarm_attach - && dialog->malarm_group - && dialog->palarm_group - && dialog->palarm_program - && dialog->palarm_args); -} - -/* Closes the dialog by terminating its main loop */ -static void -close_dialog (Dialog *dialog, gboolean canceled) -{ - dialog->canceled = canceled; - gtk_main_quit (); -} - -/* Callback used when the toplevel window is deleted */ -static guint -toplevel_delete_event_cb (GtkWidget *widget, GdkEventAny *event, gpointer data) -{ - Dialog *dialog; - - dialog = data; - close_dialog (dialog, TRUE); - return TRUE; -} - -/* Callback used when the OK button is clicked */ -static void -button_ok_clicked_cb (GtkWidget *button, gpointer data) -{ - Dialog *dialog; - - dialog = data; - close_dialog (dialog, FALSE); -} - -/* Callback used when the Cancel button is clicked */ -static void -button_cancel_clicked_cb (GtkWidget *button, gpointer data) -{ - Dialog *dialog; - - dialog = data; - close_dialog (dialog, TRUE); -} - -/* Callback used when the repeat toggle button is toggled. We sensitize the - * repeat group options as appropriate. - */ -static void -repeat_toggle_toggled_cb (GtkToggleButton *toggle, gpointer data) -{ - Dialog *dialog; - gboolean active; - - dialog = data; - - active = gtk_toggle_button_get_active (toggle); - - gtk_widget_set_sensitive (dialog->repeat_group, active); -} - -/* Hooks the widget signals */ -static void -init_widgets (Dialog *dialog) -{ - /* Toplevel, buttons */ - - dialog->canceled = TRUE; - - gtk_signal_connect (GTK_OBJECT (dialog->toplevel), "delete_event", - GTK_SIGNAL_FUNC (toplevel_delete_event_cb), dialog); - - gtk_signal_connect (GTK_OBJECT (dialog->button_ok), "clicked", - GTK_SIGNAL_FUNC (button_ok_clicked_cb), dialog); - - gtk_signal_connect (GTK_OBJECT (dialog->button_cancel), "clicked", - GTK_SIGNAL_FUNC (button_cancel_clicked_cb), dialog); - - /* Alarm repeat */ - - gtk_signal_connect (GTK_OBJECT (dialog->repeat_toggle), "toggled", - GTK_SIGNAL_FUNC (repeat_toggle_toggled_cb), dialog); -} - -/* Fills the audio alarm widgets with the values from the alarm component */ -static void -alarm_to_aalarm_widgets (Dialog *dialog, CalComponentAlarm *alarm) -{ - icalattach *attach; - const char *url; - - cal_component_alarm_get_attach (alarm, &attach); - - if (!attach) { - e_dialog_editable_set (dialog->aalarm_attach, NULL); - return; - } - - /* FIXME: this does not support inline data */ - - url = NULL; - - if (icalattach_get_is_url (attach)) - url = icalattach_get_url (attach); - else - g_message ("alarm_to_aalarm_widgets(): FIXME: we don't support inline data yet"); - - e_dialog_editable_set (dialog->aalarm_attach, url); - - icalattach_unref (attach); -} - -/* Fills the display alarm widgets with the values from the alarm component */ -static void -alarm_to_dalarm_widgets (Dialog *dialog, CalComponentAlarm *alarm) -{ - CalComponentText description; - - cal_component_alarm_get_description (alarm, &description); - - e_dialog_editable_set (dialog->dalarm_description, description.value); -} - -/* Fills the mail alarm widgets with the values from the alarm component */ -static void -alarm_to_malarm_widgets (Dialog *dialog, CalComponentAlarm *alarm) -{ - /* FIXME: nothing for now; we don't support mail alarms */ -} - -/* Fills the procedure alarm widgets with the values from the alarm component */ -static void -alarm_to_palarm_widgets (Dialog *dialog, CalComponentAlarm *alarm) -{ - icalattach *attach; - CalComponentText description; - - cal_component_alarm_get_attach (alarm, &attach); - cal_component_alarm_get_description (alarm, &description); - - if (attach) { - const char *url; - - if (icalattach_get_is_url (attach)) { - url = icalattach_get_url (attach); - e_dialog_editable_set (dialog->palarm_program, url); - } else - g_message ("alarm_to_palarm_widgets(): Don't know what to do with non-URL " - "attachments"); - - icalattach_unref (attach); - } - - e_dialog_editable_set (dialog->palarm_args, description.value); -} - -enum duration_units { - DUR_MINUTES, - DUR_HOURS, - DUR_DAYS -}; - -static const int duration_units_map[] = { - DUR_MINUTES, - DUR_HOURS, - DUR_DAYS, - -1 -}; - -/* Sigh. Takes an overcomplicated duration value and reduces it to its lowest - * common denominator. - */ -static void -normalize_duration (struct icaldurationtype dur, int *value, enum duration_units *units) -{ - if (dur.seconds != 0 || dur.minutes != 0) { - *value = ((((dur.weeks * 7 + dur.days) * 24 + dur.hours) * 60) + dur.minutes - + dur.seconds / 60 + ((dur.seconds % 60) >= 30 ? 1 : 0)); - *units = DUR_MINUTES; - } else if (dur.hours) { - *value = ((dur.weeks * 7) + dur.days) * 24 + dur.hours; - *units = DUR_HOURS; - } else if (dur.days != 0 || dur.weeks != 0) { - *value = dur.weeks * 7 + dur.days; - *units = DUR_DAYS; - } else { - *value = 0; - *units = DUR_MINUTES; - } -} - -/* Fills the repeat widgets with the values from the alarm component */ -static void -alarm_to_repeat_widgets (Dialog *dialog, CalComponentAlarm *alarm) -{ - CalAlarmRepeat repeat; - int value; - enum duration_units units; - - cal_component_alarm_get_repeat (alarm, &repeat); - - /* Sensitivity */ - - if (repeat.repetitions == 0) { - gtk_widget_set_sensitive (dialog->repeat_group, FALSE); - e_dialog_toggle_set (dialog->repeat_toggle, FALSE); - return; - } - - gtk_widget_set_sensitive (dialog->repeat_group, TRUE); - e_dialog_toggle_set (dialog->repeat_toggle, TRUE); - - /* Repetitions */ - e_dialog_spin_set (dialog->repeat_quantity, repeat.repetitions); - - /* Duration */ - - normalize_duration (repeat.duration, &value, &units); - - e_dialog_spin_set (dialog->repeat_value, value); - e_dialog_option_menu_set (dialog->repeat_unit, units, duration_units_map); -} - -/* Fills the widgets with the values from the alarm component */ -static void -alarm_to_dialog (Dialog *dialog, CalComponentAlarm *alarm) -{ - CalAlarmAction action; - - alarm_to_repeat_widgets (dialog, alarm); - - cal_component_alarm_get_action (alarm, &action); - - switch (action) { - case CAL_ALARM_NONE: - g_assert_not_reached (); - return; - - case CAL_ALARM_AUDIO: - gtk_window_set_title (GTK_WINDOW (dialog->toplevel), _("Audio Alarm Options")); - gtk_widget_show (dialog->aalarm_group); - gtk_widget_hide (dialog->dalarm_group); - gtk_widget_hide (dialog->malarm_group); - gtk_widget_hide (dialog->palarm_group); - alarm_to_aalarm_widgets (dialog, alarm); - break; - - case CAL_ALARM_DISPLAY: - gtk_window_set_title (GTK_WINDOW (dialog->toplevel), _("Message Alarm Options")); - gtk_widget_hide (dialog->aalarm_group); - gtk_widget_show (dialog->dalarm_group); - gtk_widget_hide (dialog->malarm_group); - gtk_widget_hide (dialog->palarm_group); - alarm_to_dalarm_widgets (dialog, alarm); - break; - - case CAL_ALARM_EMAIL: - gtk_window_set_title (GTK_WINDOW (dialog->toplevel), _("Mail Alarm Options")); - gtk_widget_hide (dialog->aalarm_group); - gtk_widget_hide (dialog->dalarm_group); - gtk_widget_show (dialog->malarm_group); - gtk_widget_hide (dialog->palarm_group); - alarm_to_malarm_widgets (dialog, alarm); - break; - - case CAL_ALARM_PROCEDURE: - gtk_window_set_title (GTK_WINDOW (dialog->toplevel), _("Program Alarm Options")); - gtk_widget_hide (dialog->aalarm_group); - gtk_widget_hide (dialog->dalarm_group); - gtk_widget_hide (dialog->malarm_group); - gtk_widget_show (dialog->palarm_group); - alarm_to_palarm_widgets (dialog, alarm); - break; - - case CAL_ALARM_UNKNOWN: - gtk_window_set_title (GTK_WINDOW (dialog->toplevel), _("Unknown Alarm Options")); - break; - - default: - g_assert_not_reached (); - return; - } -} - - - -/* Fills the alarm data with the values from the repeat/duration widgets */ -static void -repeat_widgets_to_alarm (Dialog *dialog, CalComponentAlarm *alarm) -{ - CalAlarmRepeat repeat; - - if (!e_dialog_toggle_get (dialog->repeat_toggle)) { - repeat.repetitions = 0; - - cal_component_alarm_set_repeat (alarm, repeat); - return; - } - - repeat.repetitions = e_dialog_spin_get_int (dialog->repeat_quantity); - - memset (&repeat.duration, 0, sizeof (repeat.duration)); - switch (e_dialog_option_menu_get (dialog->repeat_unit, duration_units_map)) { - case DUR_MINUTES: - repeat.duration.minutes = e_dialog_spin_get_int (dialog->repeat_value); - break; - - case DUR_HOURS: - repeat.duration.hours = e_dialog_spin_get_int (dialog->repeat_value); - break; - - case DUR_DAYS: - repeat.duration.days = e_dialog_spin_get_int (dialog->repeat_value); - break; - - default: - g_assert_not_reached (); - } - - cal_component_alarm_set_repeat (alarm, repeat); - -} - -/* Fills the audio alarm data with the values from the widgets */ -static void -aalarm_widgets_to_alarm (Dialog *dialog, CalComponentAlarm *alarm) -{ - char *url; - icalattach *attach; - - url = e_dialog_editable_get (dialog->aalarm_attach); - attach = icalattach_new_from_url (url ? url : ""); - g_free (url); - - cal_component_alarm_set_attach (alarm, attach); - icalattach_unref (attach); -} - -/* Fills the display alarm data with the values from the widgets */ -static void -dalarm_widgets_to_alarm (Dialog *dialog, CalComponentAlarm *alarm) -{ - char *str; - CalComponentText description; - - str = e_dialog_editable_get (dialog->dalarm_description); - description.value = str; - description.altrep = NULL; - - cal_component_alarm_set_description (alarm, &description); - g_free (str); -} - -/* Fills the mail alarm data with the values from the widgets */ -static void -malarm_widgets_to_alarm (Dialog *dialog, CalComponentAlarm *alarm) -{ - /* FIXME: nothing for now; we don't support mail alarms */ -} - -/* Fills the procedure alarm data with the values from the widgets */ -static void -palarm_widgets_to_alarm (Dialog *dialog, CalComponentAlarm *alarm) -{ - char *program; - icalattach *attach; - char *str; - CalComponentText description; - - program = e_dialog_editable_get (dialog->palarm_program); - attach = icalattach_new_from_url (program ? program : ""); - g_free (program); - - cal_component_alarm_set_attach (alarm, attach); - icalattach_unref (attach); - - str = e_dialog_editable_get (dialog->palarm_args); - description.value = str; - description.altrep = NULL; - - cal_component_alarm_set_description (alarm, &description); - g_free (str); -} - -/* Fills the alarm data with the values from the widgets */ -static void -dialog_to_alarm (Dialog *dialog, CalComponentAlarm *alarm) -{ - CalAlarmAction action; - - repeat_widgets_to_alarm (dialog, alarm); - - cal_component_alarm_get_action (alarm, &action); - - switch (action) { - case CAL_ALARM_NONE: - g_assert_not_reached (); - break; - - case CAL_ALARM_AUDIO: - aalarm_widgets_to_alarm (dialog, alarm); - break; - - case CAL_ALARM_DISPLAY: - dalarm_widgets_to_alarm (dialog, alarm); - break; - - case CAL_ALARM_EMAIL: - malarm_widgets_to_alarm (dialog, alarm); - break; - - case CAL_ALARM_PROCEDURE: - palarm_widgets_to_alarm (dialog, alarm); - break; - - case CAL_ALARM_UNKNOWN: - break; - - default: - g_assert_not_reached (); - } -} - - - -/** - * alarm_options_dialog_run: - * @alarm: Alarm that is to be edited. - * - * Runs an alarm options dialog modally. - * - * Return value: TRUE if the dialog could be created, FALSE otherwise. - **/ -gboolean -alarm_options_dialog_run (CalComponentAlarm *alarm) -{ - Dialog dialog; - - g_return_val_if_fail (alarm != NULL, FALSE); - - dialog.xml = glade_xml_new (EVOLUTION_GLADEDIR "/alarm-options.glade", NULL); - if (!dialog.xml) { - g_message ("alarm_options_dialog_new(): Could not load the Glade XML file!"); - return FALSE; - } - - if (!get_widgets (&dialog)) { - gtk_object_unref (GTK_OBJECT (dialog.xml)); - return FALSE; - } - - init_widgets (&dialog); - - alarm_to_dialog (&dialog, alarm); - - gtk_widget_show (dialog.toplevel); - gtk_main (); - - if (!dialog.canceled) - dialog_to_alarm (&dialog, alarm); - - gtk_widget_destroy (dialog.toplevel); - gtk_object_unref (GTK_OBJECT (dialog.xml)); - - return TRUE; -} diff --git a/calendar/gui/dialogs/alarm-options.glade b/calendar/gui/dialogs/alarm-options.glade deleted file mode 100644 index 00c38b9390..0000000000 --- a/calendar/gui/dialogs/alarm-options.glade +++ /dev/null @@ -1,398 +0,0 @@ -<?xml version="1.0"?> -<GTK-Interface> - -<project> - <name>Dialogs</name> - <program_name>dialogs</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>alarm-options-toplevel</name> - <title></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>True</auto_shrink> - - <widget> - <class>GtkVBox</class> - <name>vbox1</name> - <border_width>4</border_width> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - - <widget> - <class>GtkFrame</class> - <name>frame1</name> - <label>Alarm Repeat</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>hbox1</name> - <border_width>4</border_width> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - - <widget> - <class>GtkCheckButton</class> - <name>repeat-toggle</name> - <can_focus>True</can_focus> - <has_focus>True</has_focus> - <label>Repeat the alarm</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkHBox</class> - <name>repeat-group</name> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkSpinButton</class> - <name>repeat-quantity</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>1</lower> - <upper>999</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>label1</name> - <label>extra times every</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>GtkSpinButton</class> - <name>repeat-value</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>999</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>GtkOptionMenu</class> - <name>repeat-unit</name> - <can_focus>True</can_focus> - <items>minutes -hours -days -</items> - <initial_choice>0</initial_choice> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> - </widget> - </widget> - - <widget> - <class>GtkVBox</class> - <name>dalarm-group</name> - <visible>False</visible> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label2</name> - <label>Message to Display</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>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>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkText</class> - <name>dalarm-description</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text></text> - </widget> - </widget> - </widget> - - <widget> - <class>GtkHBox</class> - <name>aalarm-group</name> - <visible>False</visible> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label3</name> - <label>Play sound:</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>GnomeFileEntry</class> - <name>file-entry1</name> - <max_saved>10</max_saved> - <directory>False</directory> - <modal>False</modal> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkEntry</class> - <child_name>GnomeEntry:entry</child_name> - <name>aalarm-attach</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - </widget> - </widget> - </widget> - - <widget> - <class>GtkLabel</class> - <name>malarm-group</name> - <visible>False</visible> - <label>This is an email reminder, but Evolution does not yet support this kind of reminders. You will not be able to edit the options for this reminder.</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>True</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>GtkHBox</class> - <name>palarm-group</name> - <visible>False</visible> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label5</name> - <label>Run program:</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>GtkEntry</class> - <name>palarm-program</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>GtkLabel</class> - <name>label6</name> - <label>With these arguments:</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>GtkEntry</class> - <name>palarm-args</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>GtkHButtonBox</class> - <name>hbuttonbox1</name> - <layout_style>GTK_BUTTONBOX_END</layout_style> - <spacing>30</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>button-ok</name> - <can_default>True</can_default> - <has_default>True</has_default> - <can_focus>True</can_focus> - <stock_button>GNOME_STOCK_BUTTON_OK</stock_button> - <relief>GTK_RELIEF_NORMAL</relief> - </widget> - - <widget> - <class>GtkButton</class> - <name>button-cancel</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button> - <relief>GTK_RELIEF_NORMAL</relief> - </widget> - </widget> - </widget> -</widget> - -</GTK-Interface> diff --git a/calendar/gui/dialogs/alarm-options.h b/calendar/gui/dialogs/alarm-options.h deleted file mode 100644 index 388b737541..0000000000 --- a/calendar/gui/dialogs/alarm-options.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Evolution calendar - Alarm options dialog - * - * 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef ALARM_OPTIONS_H -#define ALARM_OPTIONS_H - -#include <cal-util/cal-component.h> - -gboolean alarm_options_dialog_run (CalComponentAlarm *alarm); - -#endif diff --git a/calendar/gui/dialogs/alarm-page.c b/calendar/gui/dialogs/alarm-page.c deleted file mode 100644 index c06e975ed7..0000000000 --- a/calendar/gui/dialogs/alarm-page.c +++ /dev/null @@ -1,869 +0,0 @@ -/* Evolution calendar - Alarm page of the calendar component dialogs - * - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * Miguel de Icaza <miguel@ximian.com> - * Seth Alves <alves@hungry.com> - * JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <gtk/gtksignal.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <glade/glade.h> -#include <gal/widgets/e-unicode.h> -#include "e-util/e-dialog-widgets.h" -#include "e-util/e-time-utils.h" -#include "cal-util/cal-util.h" -#include "cal-util/timeutil.h" -#include "../calendar-config.h" -#include "comp-editor-util.h" -#include "alarm-options.h" -#include "alarm-page.h" - - - -/* Private part of the AlarmPage structure */ -struct _AlarmPagePrivate { - /* Glade XML data */ - GladeXML *xml; - - /* Widgets from the Glade file */ - - GtkWidget *main; - - GtkWidget *summary; - GtkWidget *date_time; - - GtkWidget *list; - GtkWidget *add; - GtkWidget *delete; - - GtkWidget *action; - GtkWidget *interval_value; - GtkWidget *value_units; - GtkWidget *relative; - GtkWidget *time; - - GtkWidget *button_options; - - /* Alarm options dialog and the alarm we maintain */ - CalComponentAlarm *alarm; - - gboolean updating; -}; - -/* "relative" types */ -enum { - BEFORE, - AFTER -}; - -/* Time units */ -enum { - MINUTES, - HOURS, - DAYS -}; - -/* Option menu maps */ -static const int action_map[] = { - CAL_ALARM_DISPLAY, - CAL_ALARM_AUDIO, - CAL_ALARM_PROCEDURE, - -1 -}; - -static const int value_map[] = { - MINUTES, - HOURS, - DAYS, - -1 -}; - -static const int relative_map[] = { - BEFORE, - AFTER, - -1 -}; - -static const int time_map[] = { - CAL_ALARM_TRIGGER_RELATIVE_START, - CAL_ALARM_TRIGGER_RELATIVE_END, - -1 -}; - - - -static void alarm_page_class_init (AlarmPageClass *class); -static void alarm_page_init (AlarmPage *apage); -static void alarm_page_destroy (GtkObject *object); - -static GtkWidget *alarm_page_get_widget (CompEditorPage *page); -static void alarm_page_focus_main_widget (CompEditorPage *page); -static void alarm_page_fill_widgets (CompEditorPage *page, CalComponent *comp); -static gboolean alarm_page_fill_component (CompEditorPage *page, CalComponent *comp); -static void alarm_page_set_summary (CompEditorPage *page, const char *summary); -static void alarm_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates); - -static CompEditorPageClass *parent_class = NULL; - - - -/** - * alarm_page_get_type: - * - * Registers the #AlarmPage class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the #AlarmPage class. - **/ -GtkType -alarm_page_get_type (void) -{ - static GtkType alarm_page_type; - - if (!alarm_page_type) { - static const GtkTypeInfo alarm_page_info = { - "AlarmPage", - sizeof (AlarmPage), - sizeof (AlarmPageClass), - (GtkClassInitFunc) alarm_page_class_init, - (GtkObjectInitFunc) alarm_page_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - alarm_page_type = gtk_type_unique (TYPE_COMP_EDITOR_PAGE, - &alarm_page_info); - } - - return alarm_page_type; -} - -/* Class initialization function for the alarm page */ -static void -alarm_page_class_init (AlarmPageClass *class) -{ - CompEditorPageClass *editor_page_class; - GtkObjectClass *object_class; - - editor_page_class = (CompEditorPageClass *) class; - object_class = (GtkObjectClass *) class; - - parent_class = gtk_type_class (TYPE_COMP_EDITOR_PAGE); - - editor_page_class->get_widget = alarm_page_get_widget; - editor_page_class->focus_main_widget = alarm_page_focus_main_widget; - editor_page_class->fill_widgets = alarm_page_fill_widgets; - editor_page_class->fill_component = alarm_page_fill_component; - editor_page_class->set_summary = alarm_page_set_summary; - editor_page_class->set_dates = alarm_page_set_dates; - - object_class->destroy = alarm_page_destroy; -} - -/* Object initialization function for the alarm page */ -static void -alarm_page_init (AlarmPage *apage) -{ - AlarmPagePrivate *priv; - - priv = g_new0 (AlarmPagePrivate, 1); - apage->priv = priv; - - priv->xml = NULL; - - priv->main = NULL; - priv->summary = NULL; - priv->date_time = NULL; - priv->list = NULL; - priv->add = NULL; - priv->delete = NULL; - priv->action = NULL; - priv->interval_value = NULL; - priv->value_units = NULL; - priv->relative = NULL; - priv->time = NULL; - priv->button_options = NULL; - - priv->alarm = cal_component_alarm_new (); - - priv->updating = FALSE; -} - -/* Destroy handler for the alarm page */ -static void -alarm_page_destroy (GtkObject *object) -{ - AlarmPage *apage; - AlarmPagePrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_ALARM_PAGE (object)); - - apage = ALARM_PAGE (object); - priv = apage->priv; - - if (priv->xml) { - gtk_object_unref (GTK_OBJECT (priv->xml)); - priv->xml = NULL; - } - - if (priv->alarm) { - cal_component_alarm_free (priv->alarm); - priv->alarm = NULL; - } - - g_free (priv); - apage->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - - -/* get_widget handler for the alarm page */ -static GtkWidget * -alarm_page_get_widget (CompEditorPage *page) -{ - AlarmPage *apage; - AlarmPagePrivate *priv; - - apage = ALARM_PAGE (page); - priv = apage->priv; - - return priv->main; -} - -/* focus_main_widget handler for the alarm page */ -static void -alarm_page_focus_main_widget (CompEditorPage *page) -{ - AlarmPage *apage; - AlarmPagePrivate *priv; - - apage = ALARM_PAGE (page); - priv = apage->priv; - - gtk_widget_grab_focus (priv->action); -} - -/* Fills the widgets with default values */ -static void -clear_widgets (AlarmPage *apage) -{ - AlarmPagePrivate *priv; - - priv = apage->priv; - - /* Summary */ - gtk_label_set_text (GTK_LABEL (priv->summary), ""); - - /* Start date */ - gtk_label_set_text (GTK_LABEL (priv->date_time), ""); - - /* Sane defaults */ - e_dialog_option_menu_set (priv->action, CAL_ALARM_DISPLAY, action_map); - e_dialog_spin_set (priv->interval_value, 15); - e_dialog_option_menu_set (priv->value_units, MINUTES, value_map); - e_dialog_option_menu_set (priv->relative, BEFORE, relative_map); - e_dialog_option_menu_set (priv->time, CAL_ALARM_TRIGGER_RELATIVE_START, time_map); - - /* List data */ - gtk_clist_clear (GTK_CLIST (priv->list)); -} - -/* Builds a string for the duration of the alarm. If the duration is zero, returns NULL. */ -static char * -get_alarm_duration_string (struct icaldurationtype *duration) -{ - GString *string = g_string_new (NULL); - char *ret; - gboolean have_something; - - have_something = FALSE; - - if (duration->days > 1) { - g_string_sprintf (string, _("%d days"), duration->days); - have_something = TRUE; - } else if (duration->days == 1) { - g_string_append (string, _("1 day")); - have_something = TRUE; - } - - if (duration->weeks > 1) { - g_string_sprintf (string, _("%d weeks"), duration->weeks); - have_something = TRUE; - } else if (duration->weeks == 1) { - g_string_append (string, _("1 week")); - have_something = TRUE; - } - - if (duration->hours > 1) { - g_string_sprintf (string, _("%d hours"), duration->hours); - have_something = TRUE; - } else if (duration->hours == 1) { - g_string_append (string, _("1 hour")); - have_something = TRUE; - } - - if (duration->minutes > 1) { - g_string_sprintf (string, _("%d minutes"), duration->minutes); - have_something = TRUE; - } else if (duration->minutes == 1) { - g_string_append (string, _("1 minute")); - have_something = TRUE; - } - - if (duration->seconds > 1) { - g_string_sprintf (string, _("%d seconds"), duration->seconds); - have_something = TRUE; - } else if (duration->seconds == 1) { - g_string_append (string, _("1 second")); - have_something = TRUE; - } - - if (have_something) { - ret = string->str; - g_string_free (string, FALSE); - return ret; - } else { - g_string_free (string, TRUE); - return NULL; - } -} - -static char * -get_alarm_string (CalComponentAlarm *alarm) -{ - CalAlarmAction action; - CalAlarmTrigger trigger; - char string[256]; - char *base, *str = NULL, *dur; - - string [0] = '\0'; - - cal_component_alarm_get_action (alarm, &action); - cal_component_alarm_get_trigger (alarm, &trigger); - - switch (action) { - case CAL_ALARM_AUDIO: - base = _("Play a sound"); - break; - - case CAL_ALARM_DISPLAY: - base = _("Display a message"); - break; - - case CAL_ALARM_EMAIL: - base = _("Send an email"); - break; - - case CAL_ALARM_PROCEDURE: - base = _("Run a program"); - break; - - case CAL_ALARM_NONE: - case CAL_ALARM_UNKNOWN: - default: - base = _("Unknown action to be performed"); - break; - } - - /* FIXME: This does not look like it will localize correctly. */ - - switch (trigger.type) { - case CAL_ALARM_TRIGGER_RELATIVE_START: - dur = get_alarm_duration_string (&trigger.u.rel_duration); - - if (dur) { - if (trigger.u.rel_duration.is_neg) - str = g_strdup_printf (_("%s %s before the start of the appointment"), - base, dur); - else - str = g_strdup_printf (_("%s %s after the start of the appointment"), - base, dur); - - g_free (dur); - } else - str = g_strdup_printf (_("%s at the start of the appointment"), base); - - break; - - case CAL_ALARM_TRIGGER_RELATIVE_END: - dur = get_alarm_duration_string (&trigger.u.rel_duration); - - if (dur) { - if (trigger.u.rel_duration.is_neg) - str = g_strdup_printf (_("%s %s before the end of the appointment"), - base, dur); - else - str = g_strdup_printf (_("%s %s after the end of the appointment"), - base, dur); - - g_free (dur); - } else - str = g_strdup_printf (_("%s at the end of the appointment"), base); - - break; - - case CAL_ALARM_TRIGGER_ABSOLUTE: { - struct icaltimetype itt; - icaltimezone *utc_zone, *current_zone; - char *location; - struct tm tm; - char buf[256]; - - /* Absolute triggers come in UTC, so convert them to the local timezone */ - - itt = trigger.u.abs_time; - - utc_zone = icaltimezone_get_utc_timezone (); - location = calendar_config_get_timezone (); - current_zone = icaltimezone_get_builtin_timezone (location); - - tm = icaltimetype_to_tm_with_zone (&itt, utc_zone, current_zone); - - e_time_format_date_and_time (&tm, calendar_config_get_24_hour_format (), - FALSE, FALSE, buf, sizeof (buf)); - - str = g_strdup_printf (_("%s at %s"), base, buf); - - break; } - - case CAL_ALARM_TRIGGER_NONE: - default: - str = g_strdup_printf (_("%s for an unknown trigger type"), base); - break; - } - - return str; -} - -/* Appends an alarm to the list */ -static void -append_reminder (AlarmPage *apage, CalComponentAlarm *alarm) -{ - AlarmPagePrivate *priv; - GtkCList *clist; - char *c[1]; - int i; - - priv = apage->priv; - - clist = GTK_CLIST (priv->list); - - c[0] = get_alarm_string (alarm); - i = gtk_clist_append (clist, c); - - gtk_clist_set_row_data_full (clist, i, alarm, (GtkDestroyNotify) cal_component_alarm_free); - gtk_clist_select_row (clist, i, 0); - g_free (c[0]); - - gtk_widget_set_sensitive (priv->delete, TRUE); -} - -/* fill_widgets handler for the alarm page */ -static void -alarm_page_fill_widgets (CompEditorPage *page, CalComponent *comp) -{ - AlarmPage *apage; - AlarmPagePrivate *priv; - CalComponentText text; - GList *alarms, *l; - GtkCList *clist; - CompEditorPageDates dates; - - apage = ALARM_PAGE (page); - priv = apage->priv; - - /* Don't send off changes during this time */ - priv->updating = TRUE; - - /* Clean the page */ - clear_widgets (apage); - - /* Summary */ - cal_component_get_summary (comp, &text); - alarm_page_set_summary (page, text.value); - - /* Dates */ - comp_editor_dates (&dates, comp); - alarm_page_set_dates (page, &dates); - comp_editor_free_dates (&dates); - - /* List */ - if (!cal_component_has_alarms (comp)) - goto out; - - alarms = cal_component_get_alarm_uids (comp); - - clist = GTK_CLIST (priv->list); - for (l = alarms; l != NULL; l = l->next) { - CalComponentAlarm *ca, *ca_copy; - const char *auid; - - auid = l->data; - ca = cal_component_get_alarm (comp, auid); - g_assert (ca != NULL); - - ca_copy = cal_component_alarm_clone (ca); - cal_component_alarm_free (ca); - - append_reminder (apage, ca_copy); - } - cal_obj_uid_list_free (alarms); - - out: - - priv->updating = FALSE; -} - -/* fill_component handler for the alarm page */ -static gboolean -alarm_page_fill_component (CompEditorPage *page, CalComponent *comp) -{ - AlarmPage *apage; - AlarmPagePrivate *priv; - GList *list, *l; - GtkCList *clist; - int i; - - apage = ALARM_PAGE (page); - priv = apage->priv; - - /* Remove all the alarms from the component */ - - list = cal_component_get_alarm_uids (comp); - for (l = list; l; l = l->next) { - const char *auid; - - auid = l->data; - cal_component_remove_alarm (comp, auid); - } - cal_obj_uid_list_free (list); - - /* Add the new alarms */ - - clist = GTK_CLIST (priv->list); - for (i = 0; i < clist->rows; i++) { - CalComponentAlarm *alarm, *alarm_copy; - - alarm = gtk_clist_get_row_data (clist, i); - g_assert (alarm != NULL); - - /* We clone the alarm to maintain the invariant that the alarm - * structures in the list did *not* come from the component. - */ - - alarm_copy = cal_component_alarm_clone (alarm); - cal_component_add_alarm (comp, alarm_copy); - cal_component_alarm_free (alarm_copy); - } - - return TRUE; -} - -/* set_summary handler for the alarm page */ -static void -alarm_page_set_summary (CompEditorPage *page, const char *summary) -{ - AlarmPage *apage; - AlarmPagePrivate *priv; - gchar *s; - - apage = ALARM_PAGE (page); - priv = apage->priv; - - s = e_utf8_to_gtk_string (priv->summary, summary); - gtk_label_set_text (GTK_LABEL (priv->summary), s); - g_free (s); -} - -/* set_dates handler for the alarm page */ -static void -alarm_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates) -{ - AlarmPage *apage; - AlarmPagePrivate *priv; - - apage = ALARM_PAGE (page); - priv = apage->priv; - - comp_editor_date_label (dates, priv->date_time); -} - - - -/* Gets the widgets from the XML file and returns if they are all available. */ -static gboolean -get_widgets (AlarmPage *apage) -{ - CompEditorPage *page = COMP_EDITOR_PAGE (apage); - AlarmPagePrivate *priv; - GSList *accel_groups; - GtkWidget *toplevel; - - priv = apage->priv; - -#define GW(name) glade_xml_get_widget (priv->xml, name) - - priv->main = GW ("alarm-page"); - if (!priv->main) - return FALSE; - - /* Get the GtkAccelGroup from the toplevel window, so we can install - it when the notebook page is mapped. */ - toplevel = gtk_widget_get_toplevel (priv->main); - accel_groups = gtk_accel_groups_from_object (GTK_OBJECT (toplevel)); - if (accel_groups) { - page->accel_group = accel_groups->data; - gtk_accel_group_ref (page->accel_group); - } - - gtk_widget_ref (priv->main); - gtk_widget_unparent (priv->main); - - priv->summary = GW ("summary"); - priv->date_time = GW ("date-time"); - - priv->list = GW ("list"); - priv->add = GW ("add"); - priv->delete = GW ("delete"); - - priv->action = GW ("action"); - priv->interval_value = GW ("interval-value"); - priv->value_units = GW ("value-units"); - priv->relative = GW ("relative"); - priv->time = GW ("time"); - - priv->button_options = GW ("button-options"); - -#undef GW - - return (priv->summary - && priv->date_time - && priv->list - && priv->add - && priv->delete - && priv->action - && priv->interval_value - && priv->value_units - && priv->relative - && priv->time - && priv->button_options); -} - -/* This is called when any field is changed; it notifies upstream. */ -static void -field_changed_cb (GtkWidget *widget, gpointer data) -{ - AlarmPage *apage; - AlarmPagePrivate *priv; - - apage = ALARM_PAGE (data); - priv = apage->priv; - - if (!priv->updating) - comp_editor_page_notify_changed (COMP_EDITOR_PAGE (apage)); -} - -/* Callback used for the "add reminder" button */ -static void -add_clicked_cb (GtkButton *button, gpointer data) -{ - AlarmPage *apage; - AlarmPagePrivate *priv; - CalComponentAlarm *alarm; - CalAlarmTrigger trigger; - - apage = ALARM_PAGE (data); - priv = apage->priv; - - alarm = cal_component_alarm_clone (priv->alarm); - - memset (&trigger, 0, sizeof (CalAlarmTrigger)); - trigger.type = e_dialog_option_menu_get (priv->time, time_map); - if (e_dialog_option_menu_get (priv->relative, 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->value_units, value_map)) { - case MINUTES: - trigger.u.rel_duration.minutes = - e_dialog_spin_get_int (priv->interval_value); - break; - - case HOURS: - trigger.u.rel_duration.hours = - e_dialog_spin_get_int (priv->interval_value); - break; - - case DAYS: - trigger.u.rel_duration.days = - e_dialog_spin_get_int (priv->interval_value); - break; - - default: - g_assert_not_reached (); - } - cal_component_alarm_set_trigger (alarm, trigger); - - cal_component_alarm_set_action (alarm, e_dialog_option_menu_get (priv->action, action_map)); - - append_reminder (apage, alarm); -} - -/* Callback used for the "delete reminder" button */ -static void -delete_clicked_cb (GtkButton *button, gpointer data) -{ - AlarmPage *apage; - AlarmPagePrivate *priv; - GtkCList *clist; - int sel; - - apage = ALARM_PAGE (data); - priv = apage->priv; - - clist = GTK_CLIST (priv->list); - if (!clist->selection) - return; - - sel = GPOINTER_TO_INT (clist->selection->data); - - 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->delete, FALSE); -} - -/* Callback used when the alarm options button is clicked */ -static void -button_options_clicked_cb (GtkWidget *widget, gpointer data) -{ - AlarmPage *apage; - AlarmPagePrivate *priv; - - apage = ALARM_PAGE (data); - priv = apage->priv; - - cal_component_alarm_set_action (priv->alarm, - e_dialog_option_menu_get (priv->action, action_map)); - - if (!alarm_options_dialog_run (priv->alarm)) - g_message ("button_options_clicked_cb(): Could not create the alarm options dialog"); -} - -/* Hooks the widget signals */ -static void -init_widgets (AlarmPage *apage) -{ - AlarmPagePrivate *priv; - - priv = apage->priv; - - /* Reminder buttons */ - gtk_signal_connect (GTK_OBJECT (priv->add), "clicked", - GTK_SIGNAL_FUNC (add_clicked_cb), apage); - gtk_signal_connect (GTK_OBJECT (priv->delete), "clicked", - GTK_SIGNAL_FUNC (delete_clicked_cb), apage); - - /* Connect the default signal handler to use to make sure we notify - * upstream of changes to the widget values. - */ - gtk_signal_connect (GTK_OBJECT (priv->add), "clicked", - GTK_SIGNAL_FUNC (field_changed_cb), apage); - gtk_signal_connect (GTK_OBJECT (priv->delete), "clicked", - GTK_SIGNAL_FUNC (field_changed_cb), apage); - - /* Options button */ - gtk_signal_connect (GTK_OBJECT (priv->button_options), "clicked", - GTK_SIGNAL_FUNC (button_options_clicked_cb), apage); -} - - - -/** - * alarm_page_construct: - * @apage: An alarm page. - * - * Constructs an alarm page by loading its Glade data. - * - * Return value: The same object as @apage, or NULL if the widgets could not be - * created. - **/ -AlarmPage * -alarm_page_construct (AlarmPage *apage) -{ - AlarmPagePrivate *priv; - - priv = apage->priv; - - priv->xml = glade_xml_new (EVOLUTION_GLADEDIR "/alarm-page.glade", - NULL); - if (!priv->xml) { - g_message ("alarm_page_construct(): " - "Could not load the Glade XML file!"); - return NULL; - } - - if (!get_widgets (apage)) { - g_message ("alarm_page_construct(): " - "Could not find all widgets in the XML file!"); - return NULL; - } - - init_widgets (apage); - - return apage; -} - -/** - * alarm_page_new: - * - * Creates a new alarm page. - * - * Return value: A newly-created alarm page, or NULL if the page could not be - * created. - **/ -AlarmPage * -alarm_page_new (void) -{ - AlarmPage *apage; - - apage = gtk_type_new (TYPE_ALARM_PAGE); - if (!alarm_page_construct (apage)) { - gtk_object_unref (GTK_OBJECT (apage)); - return NULL; - } - - return apage; -} diff --git a/calendar/gui/dialogs/alarm-page.glade b/calendar/gui/dialogs/alarm-page.glade deleted file mode 100644 index 56c6f6ada1..0000000000 --- a/calendar/gui/dialogs/alarm-page.glade +++ /dev/null @@ -1,381 +0,0 @@ -<?xml version="1.0"?> -<GTK-Interface> - -<project> - <name>alarm-page</name> - <program_name>alarm-page</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>GtkWindow</class> - <name>alarm-toplevel</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>GtkVBox</class> - <name>alarm-page</name> - <border_width>4</border_width> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - - <widget> - <class>GtkFrame</class> - <name>frame33</name> - <label>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>Summary:</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>label63</name> - <label>Date/Time:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</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>summary</name> - <width>10</width> - <label></label> - <justify>GTK_JUSTIFY_LEFT</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>4</xpad> - <ypad>0</ypad> - <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>GtkLabel</class> - <name>date-time</name> - <width>10</width> - <label></label> - <justify>GTK_JUSTIFY_LEFT</justify> - <wrap>False</wrap> - <xalign>7.45058e-09</xalign> - <yalign>0.5</yalign> - <xpad>4</xpad> - <ypad>0</ypad> - <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> - </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>action</name> - <can_focus>True</can_focus> - <items>Display a message -Play a sound -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>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>999</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>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>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>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>button-options</name> - <can_focus>True</can_focus> - <label>_Options...</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>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>add</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <label>_Add</label> - </widget> - - <widget> - <class>GtkButton</class> - <name>delete</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <label>_Delete</label> - </widget> - </widget> - </widget> - </widget> - </widget> - </widget> -</widget> - -</GTK-Interface> diff --git a/calendar/gui/dialogs/alarm-page.h b/calendar/gui/dialogs/alarm-page.h deleted file mode 100644 index aa1a6be26b..0000000000 --- a/calendar/gui/dialogs/alarm-page.h +++ /dev/null @@ -1,61 +0,0 @@ -/* Evolution calendar - Alarm page of the calendar component dialogs - * - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * Miguel de Icaza <miguel@ximian.com> - * Seth Alves <alves@hungry.com> - * JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef ALARM_PAGE_H -#define ALARM_PAGE_H - -#include "comp-editor-page.h" - -BEGIN_GNOME_DECLS - - - -#define TYPE_ALARM_PAGE (alarm_page_get_type ()) -#define ALARM_PAGE(obj) (GTK_CHECK_CAST ((obj), TYPE_ALARM_PAGE, AlarmPage)) -#define ALARM_PAGE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_ALARM_PAGE, AlarmPageClass)) -#define IS_ALARM_PAGE(obj) (GTK_CHECK_TYPE ((obj), TYPE_ALARM_PAGE)) -#define IS_ALARM_PAGE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), TYPE_ALARM_PAGE)) - -typedef struct _AlarmPagePrivate AlarmPagePrivate; - -typedef struct { - CompEditorPage page; - - /* Private data */ - AlarmPagePrivate *priv; -} AlarmPage; - -typedef struct { - CompEditorPageClass parent_class; -} AlarmPageClass; - - -GtkType alarm_page_get_type (void); -AlarmPage *alarm_page_construct (AlarmPage *apage); -AlarmPage *alarm_page_new (void); - - - -END_GNOME_DECLS - -#endif diff --git a/calendar/gui/dialogs/cal-prefs-dialog.c b/calendar/gui/dialogs/cal-prefs-dialog.c deleted file mode 100644 index 639738c3bc..0000000000 --- a/calendar/gui/dialogs/cal-prefs-dialog.c +++ /dev/null @@ -1,629 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Authors : - * Damon Chaplin <damon@ximian.com> - * Ettore Perazzoli <ettore@ximian.com> - * - * Copyright 2000, 2001, 2002 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -/* - * CalPrefsDialog - a GtkObject which handles a libglade-loaded dialog - * to edit the calendar preference settings. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "../e-timezone-entry.h" -#include "cal-prefs-dialog.h" -#include "../calendar-config.h" -#include "../calendar-commands.h" -#include "../e-tasks.h" - -#include <libgnomeui/gnome-color-picker.h> -#include <glade/glade.h> -#include <gal/util/e-util.h> -#include <e-util/e-dialog-widgets.h> -#include <widgets/misc/e-dateedit.h> - - -struct _DialogData { - /* Glade XML data */ - GladeXML *xml; - - GtkWidget *page; - - GtkWidget *timezone; - 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; - - /* Widgets for the task list options */ - GtkWidget *tasks_due_today_color; - GtkWidget *tasks_overdue_color; - - GtkWidget *tasks_hide_completed_checkbutton; - GtkWidget *tasks_hide_completed_spinbutton; - GtkWidget *tasks_hide_completed_optionmenu; - - /* Other page options */ - GtkWidget *confirm_delete; - GtkWidget *default_reminder; - GtkWidget *default_reminder_interval; - GtkWidget *default_reminder_units; -}; -typedef struct _DialogData DialogData; - -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 -}; - -/* The following two are kept separate in case we need to re-order each menu individually */ -static const int hide_completed_units_map[] = { - CAL_MINUTES, CAL_HOURS, CAL_DAYS, -1 -}; - -static const int default_reminder_units_map[] = { - CAL_MINUTES, CAL_HOURS, CAL_DAYS, -1 -}; - - -static gboolean get_widgets (DialogData *data); - -static void widget_changed_callback (GtkWidget *, void *data); -static void connect_changed (GtkWidget *widget, const char *signal_name, EvolutionConfigControl *config_control); -static void setup_changes (DialogData *data, EvolutionConfigControl *config_control); - -static void init_widgets (DialogData *data); -static void show_config (DialogData *data); -static void update_config (DialogData *dialog_data); - -static void config_control_apply_callback (EvolutionConfigControl *config_control, void *data); -static void config_control_destroy_callback (GtkObject *object, void *data); - -static void cal_prefs_dialog_use_24_hour_toggled(GtkWidget *button, void *data); -static void cal_prefs_dialog_hide_completed_tasks_toggled (GtkWidget *button, void *data); - -GtkWidget *cal_prefs_dialog_create_time_edit (void); - - -/** - * cal_prefs_dialog_new: - * - * Creates a new #CalPrefsDialog. - * - * Return value: a new #CalPrefsDialog. - **/ -EvolutionConfigControl * -cal_prefs_dialog_new (void) -{ - DialogData *dialog_data; - EvolutionConfigControl *config_control; - - dialog_data = g_new0 (DialogData, 1); - - /* Load the content widgets */ - - dialog_data->xml = glade_xml_new (EVOLUTION_GLADEDIR "/cal-prefs-dialog.glade", NULL); - if (!dialog_data->xml) { - g_message ("cal_prefs_dialog_construct(): Could not load the Glade XML file!"); - return NULL; - } - - if (!get_widgets (dialog_data)) { - g_message ("cal_prefs_dialog_construct(): Could not find all widgets in the XML file!"); - return NULL; - } - - init_widgets (dialog_data); - show_config (dialog_data); - - gtk_widget_ref (dialog_data->page); - gtk_container_remove (GTK_CONTAINER (dialog_data->page->parent), dialog_data->page); - config_control = evolution_config_control_new (dialog_data->page); - gtk_widget_unref (dialog_data->page); - - gtk_signal_connect (GTK_OBJECT (config_control), "apply", - GTK_SIGNAL_FUNC (config_control_apply_callback), dialog_data); - gtk_signal_connect (GTK_OBJECT (config_control), "destroy", - GTK_SIGNAL_FUNC (config_control_destroy_callback), dialog_data); - - setup_changes (dialog_data, config_control); - - return config_control; -} - -static void -widget_changed_callback (GtkWidget *widget, - void *data) -{ - EvolutionConfigControl *config_control; - - config_control = EVOLUTION_CONFIG_CONTROL (data); - - evolution_config_control_changed (config_control); -} - -/* ^*&%!!#! GnomeColorPicker. */ -static void -color_set_callback (GnomeColorPicker *cp, - guint r, - guint g, - guint b, - guint a, - void *data) -{ - EvolutionConfigControl *config_control; - - config_control = EVOLUTION_CONFIG_CONTROL (data); - - evolution_config_control_changed (config_control); -} - -static void -connect_changed (GtkWidget *widget, - const char *signal_name, - EvolutionConfigControl *config_control) -{ - gtk_signal_connect (GTK_OBJECT (widget), signal_name, - GTK_SIGNAL_FUNC (widget_changed_callback), config_control); -} - -static void -setup_changes (DialogData *dialog_data, - EvolutionConfigControl *config_control) -{ - int i; - - for (i = 0; i < 7; i ++) - connect_changed (dialog_data->working_days[i], "toggled", config_control); - - connect_changed (dialog_data->timezone, "changed", config_control); - - connect_changed (dialog_data->start_of_day, "changed", config_control); - connect_changed (dialog_data->end_of_day, "changed", config_control); - - connect_changed (GTK_OPTION_MENU (dialog_data->week_start_day)->menu, "selection_done", config_control); - - connect_changed (dialog_data->use_12_hour, "toggled", config_control); - - connect_changed (GTK_OPTION_MENU (dialog_data->time_divisions)->menu, "selection_done", config_control); - - connect_changed (dialog_data->show_end_times, "toggled", config_control); - connect_changed (dialog_data->compress_weekend, "toggled", config_control); - connect_changed (dialog_data->dnav_show_week_no, "toggled", config_control); - - connect_changed (dialog_data->tasks_hide_completed_checkbutton, "toggled", config_control); - connect_changed (dialog_data->tasks_hide_completed_spinbutton, "changed", config_control); - connect_changed (GTK_OPTION_MENU (dialog_data->tasks_hide_completed_spinbutton)->menu, "selection_done", config_control); - - connect_changed (dialog_data->confirm_delete, "toggled", config_control); - connect_changed (dialog_data->default_reminder, "toggled", config_control); - connect_changed (dialog_data->default_reminder_interval, "changed", config_control); - connect_changed (GTK_OPTION_MENU (dialog_data->default_reminder_units)->menu, "selection_done", config_control); - - /* These use GnomeColorPicker so we have to use a different signal. */ - gtk_signal_connect (GTK_OBJECT (dialog_data->tasks_due_today_color), "color_set", - GTK_SIGNAL_FUNC (color_set_callback), config_control); - gtk_signal_connect (GTK_OBJECT (dialog_data->tasks_overdue_color), "color_set", - GTK_SIGNAL_FUNC (color_set_callback), config_control); -} - -/* Gets the widgets from the XML file and returns if they are all available. - */ -static gboolean -get_widgets (DialogData *data) -{ -#define GW(name) glade_xml_get_widget (data->xml, name) - - data->page = GW ("toplevel-notebook"); - - /* The indices must be 0 (Sun) to 6 (Sat). */ - data->working_days[0] = GW ("sun_button"); - data->working_days[1] = GW ("mon_button"); - data->working_days[2] = GW ("tue_button"); - data->working_days[3] = GW ("wed_button"); - data->working_days[4] = GW ("thu_button"); - data->working_days[5] = GW ("fri_button"); - data->working_days[6] = GW ("sat_button"); - - data->timezone = GW ("timezone"); - data->week_start_day = GW ("first_day_of_week"); - data->start_of_day = GW ("start_of_day"); - data->end_of_day = GW ("end_of_day"); - data->use_12_hour = GW ("use_12_hour"); - data->use_24_hour = GW ("use_24_hour"); - data->time_divisions = GW ("time_divisions"); - data->show_end_times = GW ("show_end_times"); - data->compress_weekend = GW ("compress_weekend"); - data->dnav_show_week_no = GW ("dnav_show_week_no"); - - data->tasks_due_today_color = GW ("tasks_due_today_color"); - data->tasks_overdue_color = GW ("tasks_overdue_color"); - - data->tasks_hide_completed_checkbutton = GW ("tasks-hide-completed-checkbutton"); - data->tasks_hide_completed_spinbutton = GW ("tasks-hide-completed-spinbutton"); - data->tasks_hide_completed_optionmenu = GW ("tasks-hide-completed-optionmenu"); - - data->confirm_delete = GW ("confirm-delete"); - data->default_reminder = GW ("default-reminder"); - data->default_reminder_interval = GW ("default-reminder-interval"); - data->default_reminder_units = GW ("default-reminder-units"); - -#undef GW - - return (data->page - && data->timezone - && data->working_days[0] - && data->working_days[1] - && data->working_days[2] - && data->working_days[3] - && data->working_days[4] - && data->working_days[5] - && data->working_days[6] - && data->week_start_day - && data->start_of_day - && data->end_of_day - && data->use_12_hour - && data->use_24_hour - && data->time_divisions - && data->show_end_times - && data->compress_weekend - && data->dnav_show_week_no - && data->tasks_due_today_color - && data->tasks_overdue_color - && data->tasks_hide_completed_checkbutton - && data->tasks_hide_completed_spinbutton - && data->tasks_hide_completed_optionmenu - && data->confirm_delete - && data->default_reminder - && data->default_reminder_interval - && data->default_reminder_units); -} - - -static void -config_control_destroy_callback (GtkObject *object, - void *data) -{ - DialogData *dialog_data; - - dialog_data = (DialogData *) data; - - gtk_object_unref (GTK_OBJECT (dialog_data->xml)); - - g_free (dialog_data); -} - - -static void -config_control_apply_callback (EvolutionConfigControl *control, - void *data) -{ - DialogData *dialog_data; - - dialog_data = (DialogData *) data; - - update_config (dialog_data); -} - - -/* 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; -} - - -/* Connects any necessary signal handlers. */ -static void -init_widgets (DialogData *dialog_data) -{ - gtk_signal_connect (GTK_OBJECT (dialog_data->use_24_hour), "toggled", - GTK_SIGNAL_FUNC (cal_prefs_dialog_use_24_hour_toggled), - dialog_data); - - gtk_signal_connect (GTK_OBJECT (dialog_data->tasks_hide_completed_checkbutton), - "toggled", - GTK_SIGNAL_FUNC (cal_prefs_dialog_hide_completed_tasks_toggled), - dialog_data); -} - - -static void -cal_prefs_dialog_use_24_hour_toggled (GtkWidget *button, - void *data) -{ - DialogData *dialog_data; - gboolean use_24_hour; - - dialog_data = (DialogData *) data; - - use_24_hour = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog_data->use_24_hour)); - - e_date_edit_set_use_24_hour_format (E_DATE_EDIT (dialog_data->start_of_day), use_24_hour); - e_date_edit_set_use_24_hour_format (E_DATE_EDIT (dialog_data->end_of_day), use_24_hour); -} - -static void -cal_prefs_dialog_hide_completed_tasks_toggled (GtkWidget *button, - void *data) -{ - DialogData *dialog_data; - gboolean hide_completed_tasks; - - dialog_data = (DialogData *) data; - - hide_completed_tasks = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog_data->tasks_hide_completed_checkbutton)); - - gtk_widget_set_sensitive (dialog_data->tasks_hide_completed_spinbutton, hide_completed_tasks); - gtk_widget_set_sensitive (dialog_data->tasks_hide_completed_optionmenu, hide_completed_tasks); -} - -/* Sets the color in a color picker from an X color spec */ -static void -set_color_picker (GtkWidget *picker, const char *spec) -{ - GdkColor color; - - g_assert (spec != NULL); - - if (!gdk_color_parse (spec, &color)) { - color.red = color.green = color.blue = 0; - return; - } - - gnome_color_picker_set_i16 (GNOME_COLOR_PICKER (picker), - color.red, - color.green, - color.blue, - 65535); -} - -/* Shows the current task list settings in the dialog */ -static void -show_task_list_config (DialogData *dialog_data) -{ - CalUnits units; - gboolean hide_completed_tasks; - - set_color_picker (dialog_data->tasks_due_today_color, calendar_config_get_tasks_due_today_color ()); - set_color_picker (dialog_data->tasks_overdue_color, calendar_config_get_tasks_overdue_color ()); - - /* Hide Completed Tasks. */ - hide_completed_tasks = calendar_config_get_hide_completed_tasks (); - e_dialog_toggle_set (dialog_data->tasks_hide_completed_checkbutton, - hide_completed_tasks); - - /* Hide Completed Tasks Units. */ - units = calendar_config_get_hide_completed_tasks_units (); - e_dialog_option_menu_set (dialog_data->tasks_hide_completed_optionmenu, - units, hide_completed_units_map); - - /* Hide Completed Tasks Value. */ - e_dialog_spin_set (dialog_data->tasks_hide_completed_spinbutton, - calendar_config_get_hide_completed_tasks_value ()); - - gtk_widget_set_sensitive (dialog_data->tasks_hide_completed_spinbutton, - hide_completed_tasks); - gtk_widget_set_sensitive (dialog_data->tasks_hide_completed_optionmenu, - hide_completed_tasks); -} - -/* Shows the current config settings in the dialog. */ -static void -show_config (DialogData *dialog_data) -{ - CalWeekdays working_days; - gint mask, day, week_start_day, time_divisions; - char *zone_name; - icaltimezone *zone; - gboolean sensitive; - - /* Timezone. */ - zone_name = calendar_config_get_timezone (); - zone = icaltimezone_get_builtin_timezone (zone_name); - e_timezone_entry_set_timezone (E_TIMEZONE_ENTRY (dialog_data->timezone), - zone); - - /* Working Days. */ - working_days = calendar_config_get_working_days (); - mask = 1 << 0; - for (day = 0; day < 7; day++) { - e_dialog_toggle_set (dialog_data->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 (dialog_data->week_start_day, week_start_day, - week_start_day_map); - - /* Start of Day. */ - e_date_edit_set_time_of_day (E_DATE_EDIT (dialog_data->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 (dialog_data->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 ()) - e_dialog_toggle_set (dialog_data->use_24_hour, TRUE); - else - e_dialog_toggle_set (dialog_data->use_12_hour, TRUE); - - sensitive = calendar_config_locale_supports_12_hour_format (); - gtk_widget_set_sensitive (dialog_data->use_12_hour, sensitive); - gtk_widget_set_sensitive (dialog_data->use_24_hour, sensitive); - - - /* Time Divisions. */ - time_divisions = calendar_config_get_time_divisions (); - e_dialog_option_menu_set (dialog_data->time_divisions, time_divisions, - time_division_map); - - /* Show Appointment End Times. */ - e_dialog_toggle_set (dialog_data->show_end_times, calendar_config_get_show_event_end ()); - - /* Compress Weekend. */ - e_dialog_toggle_set (dialog_data->compress_weekend, calendar_config_get_compress_weekend ()); - - /* Date Navigator - Show Week Numbers. */ - e_dialog_toggle_set (dialog_data->dnav_show_week_no, calendar_config_get_dnav_show_week_no ()); - - /* Task list */ - - show_task_list_config (dialog_data); - - /* Other page */ - - e_dialog_toggle_set (dialog_data->confirm_delete, calendar_config_get_confirm_delete ()); - - e_dialog_toggle_set (dialog_data->default_reminder, - calendar_config_get_use_default_reminder ()); - e_dialog_spin_set (dialog_data->default_reminder_interval, - calendar_config_get_default_reminder_interval ()); - e_dialog_option_menu_set (dialog_data->default_reminder_units, - calendar_config_get_default_reminder_units (), - default_reminder_units_map); -} - -/* Returns a pointer to a static string with an X color spec for the current - * value of a color picker. - */ -static const char * -spec_from_picker (GtkWidget *picker) -{ - static char spec[8]; - guint8 r, g, b; - - gnome_color_picker_get_i8 (GNOME_COLOR_PICKER (picker), &r, &g, &b, NULL); - g_snprintf (spec, sizeof (spec), "#%02x%02x%02x", r, g, b); - - return spec; -} - -/* Updates the task list config values from the settings in the dialog */ -static void -update_task_list_config (DialogData *dialog_data) -{ - calendar_config_set_tasks_due_today_color (spec_from_picker (dialog_data->tasks_due_today_color)); - calendar_config_set_tasks_overdue_color (spec_from_picker (dialog_data->tasks_overdue_color)); - - calendar_config_set_hide_completed_tasks (e_dialog_toggle_get (dialog_data->tasks_hide_completed_checkbutton)); - calendar_config_set_hide_completed_tasks_units (e_dialog_option_menu_get (dialog_data->tasks_hide_completed_optionmenu, hide_completed_units_map)); - calendar_config_set_hide_completed_tasks_value (e_dialog_spin_get_int (dialog_data->tasks_hide_completed_spinbutton)); -} - -/* Updates the config values based on the settings in the dialog. */ -static void -update_config (DialogData *dialog_data) -{ - CalWeekdays working_days; - gint mask, day, week_start_day, time_divisions, hour, minute; - icaltimezone *zone; - - /* Timezone. */ - zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (dialog_data->timezone)); - calendar_config_set_timezone (icaltimezone_get_location (zone)); - - /* Working Days. */ - working_days = 0; - mask = 1 << 0; - for (day = 0; day < 7; day++) { - if (e_dialog_toggle_get (dialog_data->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 (dialog_data->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 (dialog_data->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 (dialog_data->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 (e_dialog_toggle_get (dialog_data->use_24_hour)); - - /* Time Divisions. */ - time_divisions = e_dialog_option_menu_get (dialog_data->time_divisions, time_division_map); - calendar_config_set_time_divisions (time_divisions); - - /* Show Appointment End Times. */ - calendar_config_set_show_event_end (e_dialog_toggle_get (dialog_data->show_end_times)); - - /* Compress Weekend. */ - calendar_config_set_compress_weekend (e_dialog_toggle_get (dialog_data->compress_weekend)); - - /* Date Navigator - Show Week Numbers. */ - calendar_config_set_dnav_show_week_no (e_dialog_toggle_get (dialog_data->dnav_show_week_no)); - - /* Task list */ - update_task_list_config (dialog_data); - - /* Other page */ - - calendar_config_set_confirm_delete (e_dialog_toggle_get (dialog_data->confirm_delete)); - - calendar_config_set_use_default_reminder (e_dialog_toggle_get (dialog_data->default_reminder)); - - calendar_config_set_default_reminder_interval ( - e_dialog_spin_get_int (dialog_data->default_reminder_interval)); - - calendar_config_set_default_reminder_units ( - e_dialog_option_menu_get (dialog_data->default_reminder_units, default_reminder_units_map)); - - /* Done */ - - calendar_config_write (); - update_all_config_settings (); - e_tasks_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 311e378826..0000000000 --- a/calendar/gui/dialogs/cal-prefs-dialog.glade +++ /dev/null @@ -1,949 +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> - <visible>False</visible> - <title>Calendar and Tasks Settings</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> - <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>toplevel-notebook</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>vbox10</name> - <border_width>4</border_width> - <homogeneous>False</homogeneous> - <spacing>6</spacing> - - <widget> - <class>GtkFrame</class> - <name>frame12</name> - <border_width>3</border_width> - <label>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>GtkTable</class> - <name>table5</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>label22</name> - <label>Time _zone:</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>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>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>GtkHBox</class> - <name>hbox10</name> - <homogeneous>True</homogeneous> - <spacing>4</spacing> - <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>GtkAlignment</class> - <name>alignment2</name> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xscale>3.35276e-08</xscale> - <yscale>1</yscale> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </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> - </widget> - </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>True</expand> - <fill>True</fill> - </child> - </widget> - </widget> - - <widget> - <class>Custom</class> - <name>timezone</name> - <creation_function>make_timezone_entry</creation_function> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Wed, 20 Jun 2001 02:22:46 GMT</last_modification_time> - <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>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - </widget> - </widget> - - <widget> - <class>GtkFrame</class> - <name>frame9</name> - <border_width>3</border_width> - <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>T_ue</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>T_hu</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>Su_n</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></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>Sta_rt 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>GtkCheckButton</class> - <name>confirm-delete</name> - <border_width>3</border_width> - <can_focus>True</can_focus> - <label>_Ask for confirmation when deleting items</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkHBox</class> - <name>hbox16</name> - <border_width>3</border_width> - <homogeneous>False</homogeneous> - <spacing>3</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkCheckButton</class> - <name>default-reminder</name> - <can_focus>True</can_focus> - <label>Sh_ow a default reminder</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>default-reminder-interval</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>0</value> - <lower>0</lower> - <upper>9999</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>default-reminder-units</name> - <can_focus>True</can_focus> - <items>Minutes -Hours -Days -</items> - <initial_choice>0</initial_choice> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label30</name> - <label>before the start of the appointment</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> - <child_name>Notebook:tab</child_name> - <name>label21</name> - <label>_General</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>vbox8</name> - <border_width>4</border_width> - <homogeneous>False</homogeneous> - <spacing>6</spacing> - - <widget> - <class>GtkHBox</class> - <name>hbox12</name> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label25</name> - <label>_Time divisions:</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>time_divisions</default_focus_target> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <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> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> - - <widget> - <class>GtkCheckButton</class> - <name>show_end_times</name> - <can_focus>True</can_focus> - <label>_Show appointment end times in week and month views</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>compress_weekend</name> - <can_focus>True</can_focus> - <label>_Compress weekends in month view</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>dnav_show_week_no</name> - <can_focus>True</can_focus> - <label>Show week _numbers in date navigator</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkFrame</class> - <name>frame13</name> - <label>Task List</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>vbox12</name> - <border_width>4</border_width> - <homogeneous>False</homogeneous> - <spacing>3</spacing> - - <widget> - <class>GtkTable</class> - <name>table7</name> - <rows>2</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>False</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label28</name> - <label>T_asks due today:</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>tasks_due_today_color</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>label29</name> - <label>_Overdue tasks:</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>tasks_overdue_color</default_focus_target> - <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>GnomeColorPicker</class> - <name>tasks_overdue_color</name> - <can_focus>True</can_focus> - <dither>True</dither> - <use_alpha>False</use_alpha> - <title>Color for overdue tasks</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>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GnomeColorPicker</class> - <name>tasks_due_today_color</name> - <can_focus>True</can_focus> - <dither>True</dither> - <use_alpha>False</use_alpha> - <title>Color for tasks due today</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>True</xfill> - <yfill>False</yfill> - </child> - </widget> - </widget> - - <widget> - <class>GtkHBox</class> - <name>hbox15</name> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkCheckButton</class> - <name>tasks-hide-completed-checkbutton</name> - <can_focus>True</can_focus> - <label>_Hide completed tasks 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>tasks-hide-completed-spinbutton</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>9999</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>tasks-hide-completed-optionmenu</name> - <can_focus>True</can_focus> - <items>Minutes -Hours -Days -</items> - <initial_choice>0</initial_choice> - <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>label7</name> - <label>_Display</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 ce3f46736c..0000000000 --- a/calendar/gui/dialogs/cal-prefs-dialog.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 2000, Ximian, Inc. - * Copyright 2000, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -/* - * 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 "evolution-config-control.h" - -EvolutionConfigControl *cal_prefs_dialog_new (void); - -END_GNOME_DECLS - -#endif /* _CAL_PREFS_DIALOG_H_ */ diff --git a/calendar/gui/dialogs/cancel-comp.c b/calendar/gui/dialogs/cancel-comp.c deleted file mode 100644 index 92590cfa40..0000000000 --- a/calendar/gui/dialogs/cancel-comp.c +++ /dev/null @@ -1,83 +0,0 @@ -/* Evolution calendar - Send calendar component dialog - * - * Copyright (C) 2001 Ximian, Inc. - * - * Author: JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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 "cancel-comp.h" - - - -/** - * cancel_component_dialog: - * - * Pops up a dialog box asking the user whether he wants to send a - * cancel and delete an iTip/iMip message - * - * Return value: TRUE if the user clicked Yes, FALSE otherwise. - **/ -gboolean -cancel_component_dialog (CalComponent *comp) -{ - GtkWidget *dialog; - CalComponentVType vtype; - char *str; - - str = _("The meeting status has changed. Send an updated version?"); - - vtype = cal_component_get_vtype (comp); - - switch (vtype) { - case CAL_COMPONENT_EVENT: - str = g_strdup_printf (_("Are you sure you want to cancel " - "and delete this meeting?")); - break; - - case CAL_COMPONENT_TODO: - str = g_strdup_printf (_("Are you sure you want to cancel " - "and delete this task?")); - break; - - case CAL_COMPONENT_JOURNAL: - str = g_strdup_printf (_("Are you sure you want to cancel " - "and delete this journal entry?")); - break; - - default: - g_message ("send_component_dialog(): " - "Cannot handle object of type %d", vtype); - return FALSE; - } - - dialog = gnome_question_dialog_modal (str, NULL, NULL); - - if (gnome_dialog_run (GNOME_DIALOG (dialog)) == GNOME_YES) - return TRUE; - else - return FALSE; -} diff --git a/calendar/gui/dialogs/cancel-comp.h b/calendar/gui/dialogs/cancel-comp.h deleted file mode 100644 index d12466ffa1..0000000000 --- a/calendar/gui/dialogs/cancel-comp.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Evolution calendar - Send calendar component dialog - * - * Copyright (C) 2001 Ximian, Inc. - * - * Author: JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef CANCEL_COMP_H -#define CANCEL_COMP_H - -#include <glib.h> -#include <cal-util/cal-component.h> - -gboolean cancel_component_dialog (CalComponent *comp); - -#endif diff --git a/calendar/gui/dialogs/changed-comp.c b/calendar/gui/dialogs/changed-comp.c deleted file mode 100644 index 4282307859..0000000000 --- a/calendar/gui/dialogs/changed-comp.c +++ /dev/null @@ -1,111 +0,0 @@ -/* Evolution calendar - Send calendar component dialog - * - * Copyright (C) 2001 Ximian, Inc. - * - * Author: JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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 "changed-comp.h" - - - -/** - * changed_component_dialog: - * @comp: A calendar component - * @deleted: Whether the object is being deleted or updated - * @changed: Whether or not the user has made changes - * - * Pops up a dialog box asking the user whether changes made (if any) - * should be thrown away because the item has been updated elsewhere - * - * Return value: TRUE if the user clicked Yes, FALSE otherwise. - **/ -gboolean -changed_component_dialog (CalComponent *comp, gboolean deleted, gboolean changed) -{ - GtkWidget *dialog; - CalComponentVType vtype; - char *str; - - vtype = cal_component_get_vtype (comp); - - if (deleted) { - switch (vtype) { - case CAL_COMPONENT_EVENT: - str = _("This event has been deleted."); - break; - - case CAL_COMPONENT_TODO: - str = _("This task has been deleted."); - break; - - case CAL_COMPONENT_JOURNAL: - str = _("This journal entry has been deleted."); - break; - - default: - g_message ("changed_component_dialog(): " - "Cannot handle object of type %d", vtype); - return FALSE; - } - if (changed) - str = g_strdup_printf (_("%s You have made changes. Forget those changes and close the editor?"), str); - else - str = g_strdup_printf (_("%s You have made no changes, close the editor?"), str); - - } else { - switch (vtype) { - case CAL_COMPONENT_EVENT: - str = _("This event has been changed."); - break; - - case CAL_COMPONENT_TODO: - str = _("This task has been changed."); - break; - - case CAL_COMPONENT_JOURNAL: - str = _("This journal entry has been changed."); - break; - - default: - g_message ("changed_component_dialog(): " - "Cannot handle object of type %d", vtype); - return FALSE; - } - if (changed) - str = g_strdup_printf (_("%s You have made changes. Forget those changes and update the editor?"), str); - else - str = g_strdup_printf (_("%s You have made no changes, update the editor?"), str); - } - - dialog = gnome_question_dialog_modal (str, NULL, NULL); - - if (gnome_dialog_run (GNOME_DIALOG (dialog)) == GNOME_YES) - return TRUE; - else - return FALSE; -} diff --git a/calendar/gui/dialogs/changed-comp.h b/calendar/gui/dialogs/changed-comp.h deleted file mode 100644 index 915d7a5372..0000000000 --- a/calendar/gui/dialogs/changed-comp.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Evolution calendar - Changed calendar component dialog - * - * Copyright (C) 2001 Ximian, Inc. - * - * Author: JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef CHANGED_COMP_H -#define CHANGED_COMP_H - -#include <glib.h> -#include <cal-util/cal-component.h> - -gboolean changed_component_dialog (CalComponent *comp, gboolean deleted, gboolean changed); - -#endif diff --git a/calendar/gui/dialogs/comp-editor-page.c b/calendar/gui/dialogs/comp-editor-page.c deleted file mode 100644 index 0d7f315837..0000000000 --- a/calendar/gui/dialogs/comp-editor-page.c +++ /dev/null @@ -1,361 +0,0 @@ -/* Evolution calendar - Base class for calendar component editor pages - * - * 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtksignal.h> -#include "comp-editor-page.h" - - - -static void comp_editor_page_class_init (CompEditorPageClass *class); -static void comp_editor_page_init (CompEditorPage *page); -static void comp_editor_page_destroy (GtkObject *object); - -static GtkObjectClass *parent_class = NULL; - -/* Signal IDs */ - -enum { - CHANGED, - SUMMARY_CHANGED, - DATES_CHANGED, - LAST_SIGNAL -}; - -static guint comp_editor_page_signals[LAST_SIGNAL]; - -#define CLASS(page) (COMP_EDITOR_PAGE_CLASS (GTK_OBJECT (page)->klass)) - - - -/** - * comp_editor_page_get_type: - * - * Registers the #CompEditorPage class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the #CompEditorPage class. - **/ -GtkType -comp_editor_page_get_type (void) -{ - static GtkType comp_editor_page_type = 0; - - if (!comp_editor_page_type) { - static const GtkTypeInfo comp_editor_page_info = { - "CompEditorPage", - sizeof (CompEditorPage), - sizeof (CompEditorPageClass), - (GtkClassInitFunc) comp_editor_page_class_init, - (GtkObjectInitFunc) comp_editor_page_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - comp_editor_page_type = - gtk_type_unique (GTK_TYPE_OBJECT, - &comp_editor_page_info); - } - - return comp_editor_page_type; -} - -/* Class initialization function for the abstract editor page */ -static void -comp_editor_page_class_init (CompEditorPageClass *class) -{ - GtkObjectClass *object_class; - - object_class = (GtkObjectClass *) class; - - parent_class = gtk_type_class (GTK_TYPE_OBJECT); - - comp_editor_page_signals[CHANGED] = - gtk_signal_new ("changed", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (CompEditorPageClass, - changed), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - comp_editor_page_signals[SUMMARY_CHANGED] = - gtk_signal_new ("summary_changed", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (CompEditorPageClass, - summary_changed), - gtk_marshal_NONE__POINTER, - GTK_TYPE_NONE, 1, GTK_TYPE_POINTER); - - comp_editor_page_signals[DATES_CHANGED] = - gtk_signal_new ("dates_changed", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (CompEditorPageClass, - dates_changed), - gtk_marshal_NONE__POINTER, - GTK_TYPE_NONE, 1, GTK_TYPE_POINTER); - - gtk_object_class_add_signals (object_class, - comp_editor_page_signals, - LAST_SIGNAL); - - class->changed = NULL; - class->summary_changed = NULL; - class->dates_changed = NULL; - - class->get_widget = NULL; - class->focus_main_widget = NULL; - class->fill_widgets = NULL; - class->fill_component = NULL; - class->set_summary = NULL; - class->set_dates = NULL; - - object_class->destroy = comp_editor_page_destroy; -} - - - -static void -comp_editor_page_init (CompEditorPage *page) -{ - page->client = NULL; - page->accel_group = NULL; -} - - -static void -comp_editor_page_destroy (GtkObject *object) -{ - CompEditorPage *page; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_COMP_EDITOR_PAGE (object)); - - page = COMP_EDITOR_PAGE (object); - - if (page->client) { - gtk_object_ref (GTK_OBJECT (page->client)); - page->client = NULL; - } - - if (page->accel_group) { - gtk_accel_group_unref (page->accel_group); - page->accel_group = NULL; - } - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - -/** - * comp_editor_page_get_widget: - * @page: An editor page. - * - * Queries the main widget of an editor page. - * - * Return value: The widget that is the page's upper container. It should - * normally be inserted in a notebook widget. - **/ -GtkWidget * -comp_editor_page_get_widget (CompEditorPage *page) -{ - g_return_val_if_fail (page != NULL, NULL); - g_return_val_if_fail (IS_COMP_EDITOR_PAGE (page), NULL); - - g_assert (CLASS (page)->get_widget != NULL); - return (* CLASS (page)->get_widget) (page); -} - -/** - * comp_editor_page_focus_main_widget: - * @page: An editor page. - * - * Makes an editor page focus its main widget. This is used by the component - * editor when it first pops up so that it can focus the main widget in the - * first page. - **/ -void -comp_editor_page_focus_main_widget (CompEditorPage *page) -{ - g_return_if_fail (page != NULL); - g_return_if_fail (IS_COMP_EDITOR_PAGE (page)); - - g_assert (CLASS (page)->focus_main_widget != NULL); - (* CLASS (page)->focus_main_widget) (page); -} - -/** - * comp_editor_page_fill_widgets: - * @page: An editor page. - * @comp: A calendar component. - * - * Fills the widgets of an editor page with the data from a calendar component. - **/ -void -comp_editor_page_fill_widgets (CompEditorPage *page, CalComponent *comp) -{ - g_return_if_fail (page != NULL); - g_return_if_fail (IS_COMP_EDITOR_PAGE (page)); - g_return_if_fail (comp != NULL); - - g_assert (CLASS (page)->fill_widgets != NULL); - (* CLASS (page)->fill_widgets) (page, comp); -} - -/** - * comp_editor_page_fill_component: - * @page: An editor page. - * @comp: A calendar component. - * - * Takes the data from the widgets of an editor page and sets it on a calendar - * component, replacing the contents of the properties that the editor page - * knows how to manipulate. - * - * Returns: TRUE if the component could be filled, FALSE otherwise - **/ -gboolean -comp_editor_page_fill_component (CompEditorPage *page, CalComponent *comp) -{ - g_return_val_if_fail (page != NULL, FALSE); - g_return_val_if_fail (IS_COMP_EDITOR_PAGE (page), FALSE); - g_return_val_if_fail (comp != NULL, FALSE); - - if (CLASS (page)->fill_component != NULL) - return (* CLASS (page)->fill_component) (page, comp); - - return TRUE; -} - -/** - * comp_editor_page_set_cal_client: - * @page: An editor page - * @client: A #CalClient object - * - * Sets the #CalClient for the dialog page to use. - **/ -void -comp_editor_page_set_cal_client (CompEditorPage *page, CalClient *client) -{ - g_return_if_fail (page != NULL); - g_return_if_fail (IS_COMP_EDITOR_PAGE (page)); - - if (page->client) - gtk_object_unref (GTK_OBJECT (client)); - - page->client = client; - if (page->client) - gtk_object_ref (GTK_OBJECT (client)); -} - -/** - * comp_editor_page_set_summary: - * @page: An editor page - * @summary: The text of the new summary value - * - * Sets the summary value for this group of widgets - **/ -void -comp_editor_page_set_summary (CompEditorPage *page, const char *summary) -{ - g_return_if_fail (page != NULL); - g_return_if_fail (IS_COMP_EDITOR_PAGE (page)); - - if (CLASS (page)->set_summary != NULL) - (* CLASS (page)->set_summary) (page, summary); -} - -/** - * comp_editor_page_set_dates: - * @page: An editor page - * @dates: A collection of various dates in time_t format - * - * Sets the date values for this group of widgets - **/ -void -comp_editor_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates) -{ - g_return_if_fail (page != NULL); - g_return_if_fail (IS_COMP_EDITOR_PAGE (page)); - - if (CLASS (page)->set_dates != NULL) - (* CLASS (page)->set_dates) (page, dates); -} - -/** - * comp_editor_page_notify_changed: - * @page: An editor page. - * - * Makes an editor page emit the "changed" signal. This is meant to be - * used only by page implementations. - **/ -void -comp_editor_page_notify_changed (CompEditorPage *page) -{ - g_return_if_fail (page != NULL); - g_return_if_fail (IS_COMP_EDITOR_PAGE (page)); - - gtk_signal_emit (GTK_OBJECT (page), comp_editor_page_signals[CHANGED]); -} - -/** - * comp_editor_page_notify_summary_changed: - * @page: An editor page. - * - * Makes an editor page emit the "summary_changed" signal. This is meant to be - * used only by page implementations. - **/ -void -comp_editor_page_notify_summary_changed (CompEditorPage *page, - const char *summary) -{ - g_return_if_fail (page != NULL); - g_return_if_fail (IS_COMP_EDITOR_PAGE (page)); - - - gtk_signal_emit (GTK_OBJECT (page), - comp_editor_page_signals[SUMMARY_CHANGED], - summary); -} - -/** - * comp_editor_page_notify_dates_changed: - * @page: An editor page. - * - * Makes an editor page emit the "dates_changed" signal. This is meant to be - * used only by page implementations. - **/ -void -comp_editor_page_notify_dates_changed (CompEditorPage *page, - CompEditorPageDates *dates) -{ - g_return_if_fail (page != NULL); - g_return_if_fail (IS_COMP_EDITOR_PAGE (page)); - - gtk_signal_emit (GTK_OBJECT (page), - comp_editor_page_signals[DATES_CHANGED], - dates); -} diff --git a/calendar/gui/dialogs/comp-editor-page.h b/calendar/gui/dialogs/comp-editor-page.h deleted file mode 100644 index 6ef5549219..0000000000 --- a/calendar/gui/dialogs/comp-editor-page.h +++ /dev/null @@ -1,108 +0,0 @@ -/* Evolution calendar - Base class for calendar component editor pages - * - * 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef COMP_EDITOR_PAGE_H -#define COMP_EDITOR_PAGE_H - -#include <time.h> -#include <libgnome/gnome-defs.h> -#include <gtk/gtkwidget.h> -#include <cal-util/cal-component.h> -#include "cal-client.h" - -BEGIN_GNOME_DECLS - - - -#define TYPE_COMP_EDITOR_PAGE (comp_editor_page_get_type ()) -#define COMP_EDITOR_PAGE(obj) (GTK_CHECK_CAST ((obj), TYPE_COMP_EDITOR_PAGE, CompEditorPage)) -#define COMP_EDITOR_PAGE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_COMP_EDITOR_PAGE, CompEditorPageClass)) -#define IS_COMP_EDITOR_PAGE(obj) (GTK_CHECK_TYPE ((obj), TYPE_COMP_EDITOR_PAGE)) -#define IS_COMP_EDITOR_PAGE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), TYPE_COMP_EDITOR_PAGE)) - -typedef struct { - CalComponentDateTime *start; - CalComponentDateTime *end; - CalComponentDateTime *due; - struct icaltimetype *complete; -} CompEditorPageDates; - -typedef struct { - GtkObject object; - - /* Some of the pages need the CalClient to access timezone data. */ - CalClient *client; - - /* The GtkAccelGroup for the page. We install this when the page is - mapped, and uninstall when it is unmapped. libglade would do this - normally, but we create our pages individually so have to do it - ourselves. */ - GtkAccelGroup *accel_group; -} CompEditorPage; - -typedef struct { - GtkObjectClass parent_class; - - /* Notification signals */ - - void (* changed) (CompEditorPage *page); - void (* needs_send) (CompEditorPage *page); - - void (* summary_changed) (CompEditorPage *page, const char *summary); - void (* dates_changed) (CompEditorPage *page, const char *dates); - - /* Virtual methods */ - - GtkWidget *(* get_widget) (CompEditorPage *page); - void (* focus_main_widget) (CompEditorPage *page); - - void (* fill_widgets) (CompEditorPage *page, CalComponent *comp); - gboolean (* fill_component) (CompEditorPage *page, CalComponent *comp); - - void (* set_summary) (CompEditorPage *page, const char *summary); - void (* set_dates) (CompEditorPage *page, CompEditorPageDates *dates); -} CompEditorPageClass; - - -GtkType comp_editor_page_get_type (void); -GtkWidget *comp_editor_page_get_widget (CompEditorPage *page); -void comp_editor_page_focus_main_widget (CompEditorPage *page); -void comp_editor_page_fill_widgets (CompEditorPage *page, - CalComponent *comp); -gboolean comp_editor_page_fill_component (CompEditorPage *page, - CalComponent *comp); -void comp_editor_page_set_cal_client (CompEditorPage *page, - CalClient *client); -void comp_editor_page_set_summary (CompEditorPage *page, - const char *summary); -void comp_editor_page_set_dates (CompEditorPage *page, - CompEditorPageDates *dates); -void comp_editor_page_notify_changed (CompEditorPage *page); -void comp_editor_page_notify_summary_changed (CompEditorPage *page, - const char *summary); -void comp_editor_page_notify_dates_changed (CompEditorPage *page, - CompEditorPageDates *dates); - - - - -END_GNOME_DECLS - -#endif diff --git a/calendar/gui/dialogs/comp-editor-util.c b/calendar/gui/dialogs/comp-editor-util.c deleted file mode 100644 index 34d4e71e81..0000000000 --- a/calendar/gui/dialogs/comp-editor-util.c +++ /dev/null @@ -1,590 +0,0 @@ -/* Evolution calendar - Widget utilities - * - * 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <ctype.h> -#include <string.h> -#include <ical.h> -#include <glib.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <liboaf/liboaf.h> -#include <bonobo/bonobo-control.h> -#include <bonobo/bonobo-widget.h> -#include <gal/unicode/gunicode.h> -#include <e-destination.h> -#include <e-util/e-time-utils.h> -#include <cal-util/timeutil.h> -#include "../calendar-config.h" -#include "comp-editor-util.h" - - - -/** - * comp_editor_dates: - * @dates: A structure to be filled out with dates of a component - * @comp: The component to extract the dates from - * - * Extracts the dates from the calendar component into the - * CompEditorPageDates structure. Call comp_editor_free_dates() to free the - * results. - **/ -void -comp_editor_dates (CompEditorPageDates *dates, CalComponent *comp) -{ - CalComponentDateTime dt; - - dates->start = NULL; - dates->end = NULL; - dates->due = NULL; - dates->complete = NULL; - - /* Note that the CalComponentDateTime's returned contain allocated - icaltimetype and tzid values, so we just take over ownership of - those. */ - cal_component_get_dtstart (comp, &dt); - if (dt.value) { - dates->start = g_new (CalComponentDateTime, 1); - *dates->start = dt; - } - - cal_component_get_dtend (comp, &dt); - if (dt.value) { - dates->end = g_new (CalComponentDateTime, 1); - *dates->end = dt; - } - - cal_component_get_due (comp, &dt); - if (dt.value) { - dates->due = g_new (CalComponentDateTime, 1); - *dates->due = dt; - } - - cal_component_get_completed (comp, &dates->complete); -} - - -/* This frees the dates in the CompEditorPageDates struct. But it doesn't free - * the struct (as that is usually static). - */ -void -comp_editor_free_dates (CompEditorPageDates *dates) -{ - /* Note that cal_component_free_datetime() only frees the fields in - the struct. It doesn't free the struct itself, so we do that. */ - if (dates->start) { - cal_component_free_datetime (dates->start); - g_free (dates->start); - } - - if (dates->end) { - cal_component_free_datetime (dates->end); - g_free (dates->end); - } - - if (dates->due) { - cal_component_free_datetime (dates->due); - g_free (dates->due); - } - - if (dates->complete) - cal_component_free_icaltimetype (dates->complete); -} - - -/* dtstart is only passed in if tt is the dtend. */ -static void -write_label_piece (struct icaltimetype *tt, char *buffer, int size, - char *stext, char *etext, struct icaltimetype *dtstart) -{ - struct tm tmp_tm = { 0 }; - struct icaltimetype tt_copy = *tt; - int len; - - /* FIXME: May want to convert the time to an appropriate zone. */ - - if (stext != NULL) - strcat (buffer, stext); - - /* If we are writing the DTEND (i.e. DTSTART is set), and - DTEND > DTSTART, subtract 1 day. The DTEND date is not inclusive. */ - if (tt_copy.is_date && dtstart - && icaltime_compare_date_only (tt_copy, *dtstart) > 0) { - icaltime_adjust (&tt_copy, -1, 0, 0, 0); - } - - tmp_tm.tm_year = tt_copy.year - 1900; - tmp_tm.tm_mon = tt_copy.month - 1; - tmp_tm.tm_mday = tt_copy.day; - tmp_tm.tm_hour = tt_copy.hour; - tmp_tm.tm_min = tt_copy.minute; - tmp_tm.tm_sec = tt_copy.second; - tmp_tm.tm_isdst = -1; - - tmp_tm.tm_wday = time_day_of_week (tt_copy.day, tt_copy.month - 1, - tt_copy.year); - - len = strlen (buffer); - e_time_format_date_and_time (&tmp_tm, - calendar_config_get_24_hour_format (), - !tt_copy.is_date, FALSE, - &buffer[len], size - len); - if (etext != NULL) - strcat (buffer, etext); -} - -/** - * comp_editor_date_label: - * @dates: The dates to use in constructing a label - * @label: The label whose text is to be set - * - * Set the text of a label based on the dates available and the user's - * formatting preferences - **/ -void -comp_editor_date_label (CompEditorPageDates *dates, GtkWidget *label) -{ - char buffer[1024]; - gboolean start_set = FALSE, end_set = FALSE; - gboolean complete_set = FALSE, due_set = FALSE; - - buffer[0] = '\0'; - - if (dates->start && !icaltime_is_null_time (*dates->start->value)) - start_set = TRUE; - if (dates->end && !icaltime_is_null_time (*dates->end->value)) - end_set = TRUE; - if (dates->complete && !icaltime_is_null_time (*dates->complete)) - complete_set = TRUE; - if (dates->due && !icaltime_is_null_time (*dates->due->value)) - due_set = TRUE; - - if (start_set) - write_label_piece (dates->start->value, buffer, 1024, - NULL, NULL, NULL); - - if (start_set && end_set) - write_label_piece (dates->end->value, buffer, 1024, - _(" to "), NULL, dates->start->value); - - if (complete_set) { - if (start_set) - write_label_piece (dates->complete, buffer, 1024, _(" (Completed "), ")", NULL); - else - write_label_piece (dates->complete, buffer, 1024, _("Completed "), NULL, NULL); - } - - if (due_set && dates->complete == NULL) { - if (start_set) - write_label_piece (dates->due->value, buffer, 1024, _(" (Due "), ")", NULL); - else - write_label_piece (dates->due->value, buffer, 1024, _("Due "), NULL, NULL); - } - - gtk_label_set_text (GTK_LABEL (label), buffer); -} - -/** - * comp_editor_new_date_edit: - * @show_date: Whether to show a date picker in the widget. - * @show_time: Whether to show a time picker in the widget. - * @make_time_insensitive: Whether the time field is made insensitive rather - * than hiding it. This is useful if you want to preserve the layout of the - * widgets. - * - * Creates a new #EDateEdit widget, configured using the calendar's preferences. - * - * Return value: A newly-created #EDateEdit widget. - **/ -GtkWidget * -comp_editor_new_date_edit (gboolean show_date, gboolean show_time, - gboolean make_time_insensitive) -{ - 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); -#if 0 - e_date_edit_set_make_time_insensitive (dedit, make_time_insensitive); -#else - e_date_edit_set_make_time_insensitive (dedit, FALSE); -#endif - calendar_config_configure_e_date_edit (dedit); - - return GTK_WIDGET (dedit); -} - - -/* Returns the current time, for EDateEdit widgets and ECalendar items in the - dialogs. - FIXME: Should probably use the timezone from somewhere in the component - rather than the current timezone. */ -struct tm -comp_editor_get_current_time (GtkObject *object, gpointer data) -{ - char *location; - icaltimezone *zone; - struct icaltimetype tt; - struct tm tmp_tm = { 0 }; - - /* Get the current timezone. */ - location = calendar_config_get_timezone (); - zone = icaltimezone_get_builtin_timezone (location); - - tt = icaltime_from_timet_with_zone (time (NULL), FALSE, zone); - - /* Now copy it to the struct tm and return it. */ - tmp_tm.tm_year = tt.year - 1900; - tmp_tm.tm_mon = tt.month - 1; - tmp_tm.tm_mday = tt.day; - tmp_tm.tm_hour = tt.hour; - tmp_tm.tm_min = tt.minute; - tmp_tm.tm_sec = tt.second; - tmp_tm.tm_isdst = -1; - - return tmp_tm; -} - - - -/* - * These are utility functions to handle the SelectNames control we use - * for the contacts field, and its related dialog. - */ - -#define SELECT_NAMES_OAFID "OAFIID:GNOME_Evolution_Addressbook_SelectNames" - -GNOME_Evolution_Addressbook_SelectNames -comp_editor_create_contacts_component (void) -{ - GNOME_Evolution_Addressbook_SelectNames corba_select_names; - CORBA_Environment ev; - - CORBA_exception_init (&ev); - corba_select_names = oaf_activate_from_id (SELECT_NAMES_OAFID, 0, - NULL, &ev); - - /* OAF seems to be broken -- it can return a CORBA_OBJECT_NIL without - raising an exception in `ev'. */ - if (ev._major != CORBA_NO_EXCEPTION - || corba_select_names == CORBA_OBJECT_NIL) { - g_warning ("Cannot activate -- %s", SELECT_NAMES_OAFID); - CORBA_exception_free (&ev); - return CORBA_OBJECT_NIL; - } - - CORBA_exception_free (&ev); - - return corba_select_names; -} - - -GtkWidget * -comp_editor_create_contacts_control (GNOME_Evolution_Addressbook_SelectNames corba_select_names) -{ - Bonobo_Control corba_control; - GtkWidget *control_widget; - CORBA_Environment ev; - char *name = _("Contacts"); - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_SelectNames_addSection ( - corba_select_names, name, name, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - CORBA_exception_free (&ev); - return NULL; - } - - corba_control = - GNOME_Evolution_Addressbook_SelectNames_getEntryBySection ( - corba_select_names, name, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - CORBA_exception_free (&ev); - return NULL; - } - - CORBA_exception_free (&ev); - - control_widget = bonobo_widget_new_control_from_objref ( - corba_control, CORBA_OBJECT_NIL); - - gtk_widget_show (control_widget); - - return control_widget; -} - - -Bonobo_EventSource_ListenerId -comp_editor_connect_contacts_changed (GtkWidget *contacts_entry, - BonoboListenerCallbackFn changed_cb, - gpointer changed_cb_data) -{ - BonoboControlFrame *cf; - Bonobo_PropertyBag pb = CORBA_OBJECT_NIL; - - cf = bonobo_widget_get_control_frame (BONOBO_WIDGET (contacts_entry)); - pb = bonobo_control_frame_get_control_property_bag (cf, NULL); - - return bonobo_event_source_client_add_listener ( - pb, changed_cb, - "Bonobo/Property:change:entry_changed", - NULL, changed_cb_data); -} - - -void -comp_editor_show_contacts_dialog (GNOME_Evolution_Addressbook_SelectNames corba_select_names) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - GNOME_Evolution_Addressbook_SelectNames_activateDialog ( - corba_select_names, _("Contacts"), &ev); - CORBA_exception_free (&ev); -} - - -/* A simple 'name <email>' parser. Input should be UTF8. - FIXME: Should probably use camel functions or something. */ -static void -parse_contact_string (const char *value, char **name, char **email) -{ - char *lbracket, *rbracket, *name_end, *tmp_name, *tmp_email; - - if (!value) { - *name = g_strdup (""); - *email = g_strdup (""); - return; - } - - lbracket = g_utf8_strchr (value, '<'); - rbracket = g_utf8_strchr (value, '>'); - - if (!lbracket || !rbracket || rbracket < lbracket) { - *name = g_strdup (value); - *email = g_strdup (""); - return; - } - - name_end = g_utf8_prev_char (lbracket); - while (name_end > value && g_unichar_isspace (g_utf8_get_char (name_end))) - name_end = g_utf8_prev_char (name_end); - - tmp_name = g_malloc (name_end - value + 2); - strncpy (tmp_name, value, name_end - value + 1); - tmp_name[name_end - value + 1] = '\0'; - *name = tmp_name; - - tmp_email = g_malloc (rbracket - lbracket); - strncpy (tmp_email, lbracket + 1, rbracket - lbracket - 1); - tmp_email[rbracket - lbracket - 1] = '\0'; - *email = tmp_email; - -#if 0 - g_print ("Parsed: %s\n Name:'%s'\nEmail:'%s'\n", - value, *name, *email); -#endif -} - - -void -comp_editor_contacts_to_widget (GtkWidget *contacts_entry, - CalComponent *comp) -{ - GPtrArray *dest_array; - EDestination *dest; - GSList *contact_list, *elem; - char *contacts_string; - int i; - - cal_component_get_contact_list (comp, &contact_list); - dest_array = g_ptr_array_new (); - for (elem = contact_list; elem; elem = elem->next) { - CalComponentText *t = elem->data; - char *name, *email; - - parse_contact_string (t->value, &name, &email); - - dest = e_destination_new (); - e_destination_set_name (dest, name); - e_destination_set_email (dest, email); - g_ptr_array_add (dest_array, dest); - g_free (name); - g_free (email); - } - cal_component_free_text_list (contact_list); - - /* we need destv to be NULL terminated */ - g_ptr_array_add (dest_array, NULL); - - contacts_string = e_destination_exportv ((EDestination**) dest_array->pdata); -#if 0 - g_print ("Destinations: %s\n", contacts_string ? contacts_string : ""); -#endif - - bonobo_widget_set_property (BONOBO_WIDGET (contacts_entry), - "destinations", contacts_string, NULL); - - g_free (contacts_string); - - /* We free all dest_array except the last NULL we added. */ - for (i = 0; i < dest_array->len - 1; i++) { - dest = g_ptr_array_index (dest_array, i); - gtk_object_unref (GTK_OBJECT (dest)); - } - g_ptr_array_free (dest_array, TRUE); -} - - -void -comp_editor_contacts_to_component (GtkWidget *contacts_entry, - CalComponent *comp) -{ - EDestination **contact_destv; - GSList *contact_list = NULL, *elem; - char *contacts_string = NULL; - CalComponentText *t; - const char *name, *email; - int i; - - bonobo_widget_get_property (BONOBO_WIDGET (contacts_entry), - "destinations", &contacts_string, NULL); -#if 0 - g_print ("Contacts string: %s\n", contacts_string ? contacts_string : ""); -#endif - - contact_destv = e_destination_importv (contacts_string); - if (contact_destv) { - for (i = 0; contact_destv[i] != NULL; i++) { - name = e_destination_get_name (contact_destv[i]); - email = e_destination_get_email (contact_destv[i]); - - t = g_new0 (CalComponentText, 1); - t->altrep = NULL; - - /* If both name and email are given, use the standard - '"name" <email>' form, otherwise use just the name - or the email address. - FIXME: I'm not sure this is correct syntax etc. */ - if (name && name[0] && email && email[0]) - t->value = g_strdup_printf ("\"%s\" <%s>", - name, email); - else if (name && name[0]) - t->value = g_strdup_printf ("\"%s\"", - name); - else - t->value = g_strdup_printf ("<%s>", - email); - - contact_list = g_slist_prepend (contact_list, t); - - gtk_object_unref (GTK_OBJECT (contact_destv[i])); - } - } - g_free (contact_destv); - - contact_list = g_slist_reverse (contact_list); - cal_component_set_contact_list (comp, contact_list); - - for (elem = contact_list; elem; elem = elem->next) { - t = elem->data; - g_free ((char*)t->value); - g_free (t); - } - g_slist_free (contact_list); -} - -/** - * comp_editor_strip_categories: - * @categories: A string of category names entered by the user. - * - * Takes a string of the form "categ, categ, categ, ..." and removes the - * whitespace between categories to result in "categ,categ,categ,..." - * - * Return value: The category names stripped of surrounding whitespace - * and separated with commas. - **/ -char * -comp_editor_strip_categories (const char *categories) -{ - char *new_categories; - const char *start, *end; - const char *p; - char *new_p; - - if (!categories) - return NULL; - - new_categories = g_new (char, strlen (categories) + 1); - - start = end = NULL; - new_p = new_categories; - - for (p = categories; *p; p++) { - int c; - - c = *p; - - if (isspace (c)) - continue; - else if (c == ',') { - int len; - - if (!start) - continue; - - g_assert (start <= end); - - len = end - start + 1; - strncpy (new_p, start, len); - new_p[len] = ','; - new_p += len + 1; - - start = end = NULL; - } else { - if (!start) { - start = p; - end = p; - } else - end = p; - } - } - - if (start) { - int len; - - g_assert (start <= end); - - len = end - start + 1; - strncpy (new_p, start, len); - new_p += len; - } - - *new_p = '\0'; - - return new_categories; -} diff --git a/calendar/gui/dialogs/comp-editor-util.h b/calendar/gui/dialogs/comp-editor-util.h deleted file mode 100644 index 948b34221c..0000000000 --- a/calendar/gui/dialogs/comp-editor-util.h +++ /dev/null @@ -1,54 +0,0 @@ -/* Evolution calendar - Widget utilities - * - * Copyright (C) 2000 Ximian, Inc. - * - * Author: JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _COMP_EDITOR_UTIL_H_ -#define _COMP_EDITOR_UTIL_H_ - -#include <gtk/gtkwidget.h> -#include <bonobo/bonobo-control.h> -#include "Evolution-Addressbook-SelectNames.h" -#include "comp-editor-page.h" - -void comp_editor_dates (CompEditorPageDates *date, CalComponent *comp); -void comp_editor_free_dates (CompEditorPageDates *dates); - -void comp_editor_date_label (CompEditorPageDates *dates, GtkWidget *label); - -GtkWidget *comp_editor_new_date_edit (gboolean show_date, gboolean show_time, - gboolean make_time_insensitive); - -struct tm comp_editor_get_current_time (GtkObject *object, gpointer data); - - -GNOME_Evolution_Addressbook_SelectNames comp_editor_create_contacts_component (void); -GtkWidget * comp_editor_create_contacts_control (GNOME_Evolution_Addressbook_SelectNames corba_select_names); -Bonobo_EventSource_ListenerId comp_editor_connect_contacts_changed (GtkWidget *contacts_entry, - BonoboListenerCallbackFn changed_cb, - gpointer changed_cb_data); -void comp_editor_show_contacts_dialog (GNOME_Evolution_Addressbook_SelectNames corba_select_names); - -void comp_editor_contacts_to_widget (GtkWidget *contacts_entry, - CalComponent *comp); -void comp_editor_contacts_to_component (GtkWidget *contacts_entry, - CalComponent *comp); - -char *comp_editor_strip_categories (const char *categories); - -#endif diff --git a/calendar/gui/dialogs/comp-editor.c b/calendar/gui/dialogs/comp-editor.c deleted file mode 100644 index cad55ebf08..0000000000 --- a/calendar/gui/dialogs/comp-editor.c +++ /dev/null @@ -1,1259 +0,0 @@ -/* Evolution calendar - Framework for a calendar component editor dialog - * - * Copyright (C) 2001 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <glib.h> -#include <gdk/gdkkeysyms.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <libgnomeui/gnome-uidefs.h> -#include <libgnomeui/gnome-dialog.h> -#include <libgnomeui/gnome-dialog-util.h> -#include <libgnomeui/gnome-stock.h> -#include <libgnomeui/gnome-window-icon.h> -#include <bonobo/bonobo-ui-container.h> -#include <bonobo/bonobo-ui-util.h> -#include <gal/widgets/e-unicode.h> -#include <e-util/e-dialog-utils.h> -#include <evolution-shell-component-utils.h> -#include "../print.h" -#include "save-comp.h" -#include "delete-comp.h" -#include "send-comp.h" -#include "changed-comp.h" -#include "comp-editor.h" - - - -/* Private part of the CompEditor structure */ -struct _CompEditorPrivate { - /* Client to use */ - CalClient *client; - - /* Calendar object/uid we are editing; this is an internal copy */ - CalComponent *comp; - - /* The pages we have */ - GList *pages; - - /* UI Component for the dialog */ - BonoboUIComponent *uic; - - /* Notebook to hold the pages */ - GtkNotebook *notebook; - - GtkWidget *filesel; - - gboolean changed; - gboolean needs_send; - gboolean needs_send_new; - gboolean updating; -}; - - - -static void comp_editor_class_init (CompEditorClass *class); -static void comp_editor_init (CompEditor *editor); -static gint comp_editor_key_press_event (GtkWidget *d, GdkEventKey *e); -static void comp_editor_destroy (GtkObject *object); - -static void real_set_cal_client (CompEditor *editor, CalClient *client); -static void real_edit_comp (CompEditor *editor, CalComponent *comp); -static void real_send_comp (CompEditor *editor, CalComponentItipMethod method); -static gboolean prompt_to_save_changes (CompEditor *editor, gboolean send); -static void delete_comp (CompEditor *editor); -static void close_dialog (CompEditor *editor); - -static void page_changed_cb (GtkObject *obj, gpointer data); -static void page_summary_changed_cb (GtkObject *obj, const char *summary, gpointer data); -static void page_dates_changed_cb (GtkObject *obj, CompEditorPageDates *dates, 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 void save_cmd (GtkWidget *widget, gpointer data); -static void save_close_cmd (GtkWidget *widget, gpointer data); -static void save_as_cmd (GtkWidget *widget, gpointer data); -static void delete_cmd (GtkWidget *widget, gpointer data); -static void print_cmd (GtkWidget *widget, gpointer data); -static void print_preview_cmd (GtkWidget *widget, gpointer data); -static void print_setup_cmd (GtkWidget *widget, gpointer data); -static void close_cmd (GtkWidget *widget, gpointer data); - -static gint delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data); - -static EPixmap pixmaps [] = -{ - E_PIXMAP ("/menu/File/FileSave", "save-16.png"), - E_PIXMAP ("/menu/File/FileSaveAndClose", "save-16.png"), - E_PIXMAP ("/menu/File/FileSaveAs", "save-as-16.png"), - - E_PIXMAP ("/menu/File/FileDelete", "evolution-trash-mini.png"), - - E_PIXMAP ("/menu/File/FilePrint", "print.xpm"), - E_PIXMAP ("/menu/File/FilePrintPreview", "print-preview.xpm"), - - E_PIXMAP ("/Toolbar/FileSaveAndClose", "buttons/save-24.png"), - E_PIXMAP ("/Toolbar/FilePrint", "buttons/print.png"), - E_PIXMAP ("/Toolbar/FileDelete", "buttons/delete-message.png"), - - E_PIXMAP_END -}; - -static BonoboUIVerb verbs [] = { - BONOBO_UI_UNSAFE_VERB ("FileSave", save_cmd), - BONOBO_UI_UNSAFE_VERB ("FileSaveAndClose", save_close_cmd), - BONOBO_UI_UNSAFE_VERB ("FileSaveAs", save_as_cmd), - BONOBO_UI_UNSAFE_VERB ("FileDelete", delete_cmd), - BONOBO_UI_UNSAFE_VERB ("FilePrint", print_cmd), - BONOBO_UI_UNSAFE_VERB ("FilePrintPreview", print_preview_cmd), - BONOBO_UI_UNSAFE_VERB ("FilePrintSetup", print_setup_cmd), - BONOBO_UI_UNSAFE_VERB ("FileClose", close_cmd), - - BONOBO_UI_VERB_END -}; - -static GtkObjectClass *parent_class; - - - -GtkType -comp_editor_get_type (void) -{ - static GtkType comp_editor_type = 0; - - if (!comp_editor_type) { - static const GtkTypeInfo comp_editor_info = { - "CompEditor", - sizeof (CompEditor), - sizeof (CompEditorClass), - (GtkClassInitFunc) comp_editor_class_init, - (GtkObjectInitFunc) comp_editor_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - comp_editor_type = gtk_type_unique (BONOBO_TYPE_WINDOW, - &comp_editor_info); - } - - return comp_editor_type; -} - -/* Class initialization function for the calendar component editor */ -static void -comp_editor_class_init (CompEditorClass *klass) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - - object_class = GTK_OBJECT_CLASS (klass); - widget_class = GTK_WIDGET_CLASS (klass); - - parent_class = gtk_type_class (BONOBO_TYPE_WINDOW); - - klass->set_cal_client = real_set_cal_client; - klass->edit_comp = real_edit_comp; - klass->send_comp = real_send_comp; - - widget_class->key_press_event = comp_editor_key_press_event; - object_class->destroy = comp_editor_destroy; -} - -/* Creates the basic in the editor */ -static void -setup_widgets (CompEditor *editor) -{ - CompEditorPrivate *priv; - BonoboUIContainer *container; - GtkWidget *vbox; - - priv = editor->priv; - - /* Window and basic vbox */ - bonobo_window_construct (BONOBO_WINDOW (editor), - "event-editor", "iCalendar Editor"); - gtk_signal_connect (GTK_OBJECT (editor), "delete_event", - GTK_SIGNAL_FUNC (delete_event_cb), editor); - - priv->uic = bonobo_ui_component_new_default (); - container = bonobo_ui_container_new (); - bonobo_ui_container_set_win (container, BONOBO_WINDOW (editor)); - bonobo_ui_component_set_container (priv->uic, BONOBO_OBJREF (container)); - bonobo_ui_engine_config_set_path (bonobo_window_get_ui_engine (BONOBO_WINDOW (editor)), - "/evolution/UIConf/kvps"); - - bonobo_ui_component_add_verb_list_with_data (priv->uic, verbs, editor); - bonobo_ui_util_set_ui (priv->uic, EVOLUTION_DATADIR, - "evolution-comp-editor.xml", - "evolution-calendar"); - e_pixmaps_update (priv->uic, pixmaps); - - vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL); - gtk_widget_show (vbox); - gtk_container_set_border_width (GTK_CONTAINER (vbox), GNOME_PAD_SMALL); - bonobo_window_set_contents (BONOBO_WINDOW (editor), vbox); - - /* Notebook */ - priv->notebook = GTK_NOTEBOOK (gtk_notebook_new ()); - gtk_widget_show (GTK_WIDGET (priv->notebook)); - gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (priv->notebook), - TRUE, TRUE, 0); -} - -/* Object initialization function for the calendar component editor */ -static void -comp_editor_init (CompEditor *editor) -{ - CompEditorPrivate *priv; - - priv = g_new0 (CompEditorPrivate, 1); - editor->priv = priv; - - setup_widgets (editor); - - priv->pages = NULL; - priv->changed = FALSE; - priv->needs_send = FALSE; - priv->needs_send_new = FALSE; -} - - -static gint -comp_editor_key_press_event (GtkWidget *d, GdkEventKey *e) -{ - if (e->keyval == GDK_Escape) { - if (prompt_to_save_changes (COMP_EDITOR (d), TRUE)) - close_dialog (COMP_EDITOR (d)); - return TRUE; - } - - if (GTK_WIDGET_CLASS (parent_class)->key_press_event) - return (* GTK_WIDGET_CLASS (parent_class)->key_press_event) (d, e); - - return FALSE; -} - -/* Destroy handler for the calendar component editor */ -static void -comp_editor_destroy (GtkObject *object) -{ - CompEditor *editor; - CompEditorPrivate *priv; - GList *l; - - editor = COMP_EDITOR (object); - priv = editor->priv; - - gtk_signal_disconnect_by_data (GTK_OBJECT (priv->client), editor); - - /* We want to destroy the pages after the widgets get destroyed, - since they have lots of signal handlers connected to the widgets - with the pages as the data. */ - for (l = priv->pages; l != NULL; l = l->next) - gtk_object_unref (GTK_OBJECT (l->data)); - - if (priv->comp) { - gtk_object_unref (GTK_OBJECT (priv->comp)); - priv->comp = NULL; - } - - g_free (priv); - editor->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - -static gboolean -save_comp (CompEditor *editor) -{ - CompEditorPrivate *priv; - CalComponent *clone; - GList *l; - - priv = editor->priv; - - if (!priv->changed) - return TRUE; - - clone = cal_component_clone (priv->comp); - for (l = priv->pages; l != NULL; l = l->next) { - if (!comp_editor_page_fill_component (l->data, clone)) { - gtk_object_unref (GTK_OBJECT (clone)); - return FALSE; - } - } - cal_component_commit_sequence (clone); - gtk_object_unref (GTK_OBJECT (priv->comp)); - priv->comp = clone; - - priv->updating = TRUE; - - if (!cal_client_update_object (priv->client, priv->comp)) { - GtkWidget *dlg; - - dlg = gnome_error_dialog (_("Could not update object!")); - gnome_dialog_run_and_close (GNOME_DIALOG (dlg)); - - return FALSE; - } else { - priv->changed = FALSE; - } - - priv->updating = FALSE; - - return TRUE; -} - -static gboolean -save_comp_with_send (CompEditor *editor) -{ - CompEditorPrivate *priv; - gboolean send; - - priv = editor->priv; - - send = priv->changed && priv->needs_send; - - if (!save_comp (editor)) - return FALSE; - - if (send && send_component_dialog (priv->comp, priv->needs_send_new)) - comp_editor_send_comp (editor, CAL_COMPONENT_METHOD_REQUEST); - - return TRUE; -} - -static void -delete_comp (CompEditor *editor) -{ - CompEditorPrivate *priv; - const char *uid; - - priv = editor->priv; - - cal_component_get_uid (priv->comp, &uid); - priv->updating = TRUE; - cal_client_remove_object (priv->client, uid); - priv->updating = FALSE; - close_dialog (editor); -} - -static gboolean -prompt_to_save_changes (CompEditor *editor, gboolean send) -{ - CompEditorPrivate *priv; - - priv = editor->priv; - - if (!priv->changed) - return TRUE; - - switch (save_component_dialog (GTK_WINDOW (editor))) { - case 0: /* Save */ - if (send && save_comp_with_send (editor)) - return TRUE; - else if (!send && save_comp (editor)) - return TRUE; - else - return FALSE; - case 1: /* Discard */ - return TRUE; - case 2: /* Cancel */ - default: - return FALSE; - } -} - -/* Closes the dialog box and emits the appropriate signals */ -static void -close_dialog (CompEditor *editor) -{ - CompEditorPrivate *priv; - - priv = editor->priv; - - gtk_object_destroy (GTK_OBJECT (editor)); -} - - - -/** - * comp_editor_set_changed: - * @editor: A component editor - * @changed: Value to set the changed state to - * - * Set the dialog changed state to the given value - **/ -void -comp_editor_set_changed (CompEditor *editor, gboolean changed) -{ - CompEditorPrivate *priv; - - priv = editor->priv; - - priv->changed = changed; -} - -/** - * comp_editor_get_changed: - * @editor: A component editor - * - * Gets the changed state of the dialog - * - * Return value: A boolean indicating if the dialog is in a changed - * state - **/ -gboolean -comp_editor_get_changed (CompEditor *editor) -{ - CompEditorPrivate *priv; - - priv = editor->priv; - - return priv->changed; -} - -/** - * comp_editor_set_needs_send: - * @editor: A component editor - * @needs_send: Value to set the needs send state to - * - * Set the dialog needs send state to the given value - **/ -void -comp_editor_set_needs_send (CompEditor *editor, gboolean needs_send) -{ - CompEditorPrivate *priv; - - priv = editor->priv; - - priv->needs_send = needs_send; -} - -/** - * comp_editor_get_needs_send: - * @editor: A component editor - * - * Gets the needs send state of the dialog - * - * Return value: A boolean indicating if the dialog is in a needs send - * state - **/ -gboolean -comp_editor_get_needs_send (CompEditor *editor) -{ - CompEditorPrivate *priv; - - priv = editor->priv; - - return priv->needs_send; -} - -static void page_mapped_cb (GtkWidget *page_widget, - CompEditorPage *page) -{ - GtkWidget *toplevel; - - toplevel = gtk_widget_get_toplevel (page_widget); - if (!GTK_IS_WINDOW (toplevel)) - return; - - if (page->accel_group) { - gtk_window_add_accel_group (GTK_WINDOW (toplevel), - page->accel_group); - } -} - -static void page_unmapped_cb (GtkWidget *page_widget, - CompEditorPage *page) -{ - GtkWidget *toplevel; - - toplevel = gtk_widget_get_toplevel (page_widget); - if (!GTK_IS_WINDOW (toplevel)) - return; - - if (page->accel_group) { - gtk_window_remove_accel_group (GTK_WINDOW (toplevel), - page->accel_group); - } -} - -/** - * comp_editor_append_page: - * @editor: A component editor - * @page: A component editor page - * @label: Label of the page - * - * Appends a page to the editor notebook with the given label - **/ -void -comp_editor_append_page (CompEditor *editor, - CompEditorPage *page, - const char *label) -{ - CompEditorPrivate *priv; - GtkWidget *page_widget; - GtkWidget *label_widget; - gboolean is_first_page; - - g_return_if_fail (editor != NULL); - g_return_if_fail (IS_COMP_EDITOR (editor)); - g_return_if_fail (page != NULL); - g_return_if_fail (IS_COMP_EDITOR_PAGE (page)); - g_return_if_fail (label != NULL); - - priv = editor->priv; - - gtk_object_ref (GTK_OBJECT (page)); - - /* If we are editing something, fill the widgets with current info */ - if (priv->comp != NULL) { - CalComponent *comp; - - comp = comp_editor_get_current_comp (editor); - comp_editor_page_fill_widgets (page, comp); - gtk_object_unref (GTK_OBJECT (comp)); - } - - page_widget = comp_editor_page_get_widget (page); - g_assert (page_widget != NULL); - - label_widget = gtk_label_new (label); - - is_first_page = (priv->pages == NULL); - - priv->pages = g_list_append (priv->pages, page); - gtk_notebook_append_page (priv->notebook, page_widget, label_widget); - - /* Listen for things happening on the page */ - gtk_signal_connect (GTK_OBJECT (page), "changed", - GTK_SIGNAL_FUNC (page_changed_cb), editor); - gtk_signal_connect (GTK_OBJECT (page), "summary_changed", - GTK_SIGNAL_FUNC (page_summary_changed_cb), editor); - gtk_signal_connect (GTK_OBJECT (page), "dates_changed", - GTK_SIGNAL_FUNC (page_dates_changed_cb), editor); - - /* Listen for when the page is mapped/unmapped so we can - install/uninstall the appropriate GtkAccelGroup. */ - gtk_signal_connect (GTK_OBJECT (page_widget), "map", - GTK_SIGNAL_FUNC (page_mapped_cb), page); - gtk_signal_connect (GTK_OBJECT (page_widget), "unmap", - GTK_SIGNAL_FUNC (page_unmapped_cb), page); - - /* The first page is the main page of the editor, so we ask it to focus - * its main widget. - */ - if (is_first_page) - comp_editor_page_focus_main_widget (page); -} - -/** - * comp_editor_remove_page: - * @editor: A component editor - * @page: A component editor page - * - * Removes the page from the component editor - **/ -void -comp_editor_remove_page (CompEditor *editor, CompEditorPage *page) -{ - CompEditorPrivate *priv; - GtkWidget *page_widget; - gint page_num; - - g_return_if_fail (editor != NULL); - g_return_if_fail (IS_COMP_EDITOR (editor)); - g_return_if_fail (page != NULL); - g_return_if_fail (IS_COMP_EDITOR_PAGE (page)); - - priv = editor->priv; - - page_widget = comp_editor_page_get_widget (page); - page_num = gtk_notebook_page_num (priv->notebook, page_widget); - if (page_num == -1) - return; - - /* Disconnect all the signals added in append_page(). */ - gtk_signal_disconnect_by_data (GTK_OBJECT (page), editor); - gtk_signal_disconnect_by_data (GTK_OBJECT (page_widget), page); - - gtk_notebook_remove_page (priv->notebook, page_num); - - priv->pages = g_list_remove (priv->pages, page); - gtk_object_unref (GTK_OBJECT (page)); -} - -/** - * comp_editor_show_page: - * @editor: - * @page: - * - * - **/ -void -comp_editor_show_page (CompEditor *editor, CompEditorPage *page) -{ - CompEditorPrivate *priv; - GtkWidget *page_widget; - gint page_num; - - g_return_if_fail (editor != NULL); - g_return_if_fail (IS_COMP_EDITOR (editor)); - g_return_if_fail (page != NULL); - g_return_if_fail (IS_COMP_EDITOR_PAGE (page)); - - priv = editor->priv; - - page_widget = comp_editor_page_get_widget (page); - page_num = gtk_notebook_page_num (priv->notebook, page_widget); - gtk_notebook_set_page (priv->notebook, page_num); -} - -/** - * comp_editor_set_cal_client: - * @editor: A component editor - * @client: The calendar client to use - * - * Sets the calendar client used by the editor to update components - **/ -void -comp_editor_set_cal_client (CompEditor *editor, CalClient *client) -{ - CompEditorClass *klass; - - g_return_if_fail (editor != NULL); - g_return_if_fail (IS_COMP_EDITOR (editor)); - - klass = COMP_EDITOR_CLASS (GTK_OBJECT (editor)->klass); - - if (klass->set_cal_client) - klass->set_cal_client (editor, client); -} - -/** - * comp_editor_get_cal_client: - * @editor: A component editor - * - * Returns the calendar client of the editor - * - * Return value: The calendar client of the editor - **/ -CalClient * -comp_editor_get_cal_client (CompEditor *editor) -{ - CompEditorPrivate *priv; - - g_return_val_if_fail (editor != NULL, NULL); - g_return_val_if_fail (IS_COMP_EDITOR (editor), NULL); - - priv = editor->priv; - - return priv->client; -} - -/* Creates an appropriate title for the event editor dialog */ -static char * -make_title_from_comp (CalComponent *comp) -{ - char *title; - const char *type_string; - CalComponentVType type; - CalComponentText text; - - if (!comp) - return g_strdup (_("Edit Appointment")); - - type = cal_component_get_vtype (comp); - switch (type) { - case CAL_COMPONENT_EVENT: - type_string = _("Appointment - %s"); - break; - case CAL_COMPONENT_TODO: - type_string = _("Task - %s"); - break; - case CAL_COMPONENT_JOURNAL: - type_string = _("Journal entry - %s"); - break; - default: - g_message ("make_title_from_comp(): Cannot handle object of type %d", type); - return NULL; - } - - cal_component_get_summary (comp, &text); - if (text.value) { - char *summary; - summary = e_utf8_to_locale_string (text.value); - title = g_strdup_printf (type_string, summary); - g_free (summary); - } else - title = g_strdup_printf (type_string, _("No summary")); - - return title; -} - -static const char * -make_icon_from_comp (CalComponent *comp) -{ - CalComponentVType type; - - if (!comp) - return EVOLUTION_ICONSDIR "/evolution-calendar-mini.png"; - - type = cal_component_get_vtype (comp); - switch (type) { - case CAL_COMPONENT_EVENT: - return EVOLUTION_ICONSDIR "/buttons/new_appointment.png"; - break; - case CAL_COMPONENT_TODO: - return EVOLUTION_ICONSDIR "/buttons/new_task.png"; - break; - default: - return EVOLUTION_ICONSDIR "/evolution-calendar-mini.png"; - } -} - -/* Sets the event editor's window title from a calendar component */ -static void -set_title_from_comp (CompEditor *editor) -{ - CompEditorPrivate *priv; - char *title; - - priv = editor->priv; - title = make_title_from_comp (priv->comp); - gtk_window_set_title (GTK_WINDOW (editor), title); - g_free (title); -} - -static void -set_icon_from_comp (CompEditor *editor) -{ - CompEditorPrivate *priv; - const char *file; - - priv = editor->priv; - file = make_icon_from_comp (priv->comp); - gnome_window_icon_set_from_file (GTK_WINDOW (editor), file); -} - -static void -fill_widgets (CompEditor *editor) -{ - CompEditorPrivate *priv; - GList *l; - - priv = editor->priv; - - for (l = priv->pages; l != NULL; l = l->next) - comp_editor_page_fill_widgets (l->data, priv->comp); -} - -static void -real_set_cal_client (CompEditor *editor, CalClient *client) -{ - CompEditorPrivate *priv; - GList *elem; - - g_return_if_fail (editor != NULL); - g_return_if_fail (IS_COMP_EDITOR (editor)); - - priv = editor->priv; - - if (client == priv->client) - return; - - if (client) { - g_return_if_fail (IS_CAL_CLIENT (client)); - g_return_if_fail (cal_client_get_load_state (client) == - CAL_CLIENT_LOAD_LOADED); - gtk_object_ref (GTK_OBJECT (client)); - } - - if (priv->client) { - gtk_signal_disconnect_by_data (GTK_OBJECT (priv->client), - editor); - gtk_object_unref (GTK_OBJECT (priv->client)); - } - - priv->client = client; - - /* Pass the client to any pages that need it. */ - for (elem = priv->pages; elem; elem = elem->next) - comp_editor_page_set_cal_client (elem->data, client); - - gtk_signal_connect (GTK_OBJECT (priv->client), "obj_updated", - GTK_SIGNAL_FUNC (obj_updated_cb), editor); - - gtk_signal_connect (GTK_OBJECT (priv->client), "obj_removed", - GTK_SIGNAL_FUNC (obj_removed_cb), editor); -} - -static void -real_edit_comp (CompEditor *editor, CalComponent *comp) -{ - CompEditorPrivate *priv; - - g_return_if_fail (editor != NULL); - g_return_if_fail (IS_COMP_EDITOR (editor)); - - priv = editor->priv; - - if (priv->comp) { - gtk_object_unref (GTK_OBJECT (priv->comp)); - priv->comp = NULL; - } - - if (comp) - priv->comp = cal_component_clone (comp); - - priv->needs_send_new = !priv->needs_send; - - set_title_from_comp (editor); - set_icon_from_comp (editor); - fill_widgets (editor); -} - - -static void -real_send_comp (CompEditor *editor, CalComponentItipMethod method) -{ - CompEditorPrivate *priv; - - g_return_if_fail (editor != NULL); - g_return_if_fail (IS_COMP_EDITOR (editor)); - - priv = editor->priv; - - itip_send_comp (method, priv->comp, priv->client, NULL); -} - - -/** - * comp_editor_edit_comp: - * @editor: A component editor - * @comp: A calendar component - * - * Starts the editor editing the given component - **/ -void -comp_editor_edit_comp (CompEditor *editor, CalComponent *comp) -{ - CompEditorClass *klass; - - g_return_if_fail (editor != NULL); - g_return_if_fail (IS_COMP_EDITOR (editor)); - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - - klass = COMP_EDITOR_CLASS (GTK_OBJECT (editor)->klass); - - if (klass->edit_comp) - klass->edit_comp (editor, comp); -} - -CalComponent * -comp_editor_get_current_comp (CompEditor *editor) -{ - CompEditorPrivate *priv; - CalComponent *comp; - GList *l; - - g_return_val_if_fail (editor != NULL, NULL); - g_return_val_if_fail (IS_COMP_EDITOR (editor), NULL); - - priv = editor->priv; - - comp = cal_component_clone (priv->comp); - if (priv->changed) { - for (l = priv->pages; l != NULL; l = l->next) - comp_editor_page_fill_component (l->data, comp); - } - - return comp; -} - -/** - * comp_editor_save_comp: - * @editor: - * - * - **/ -gboolean -comp_editor_save_comp (CompEditor *editor, gboolean send) -{ - return prompt_to_save_changes (editor, send); -} - -/** - * comp_editor_delete_comp: - * @editor: - * - * - **/ -void -comp_editor_delete_comp (CompEditor *editor) -{ - delete_comp (editor); -} - -/** - * comp_editor_send_comp: - * @editor: - * @method: - * - * - **/ -void -comp_editor_send_comp (CompEditor *editor, CalComponentItipMethod method) -{ - CompEditorClass *klass; - - g_return_if_fail (editor != NULL); - g_return_if_fail (IS_COMP_EDITOR (editor)); - - klass = COMP_EDITOR_CLASS (GTK_OBJECT (editor)->klass); - - if (klass->send_comp) - klass->send_comp (editor, method); -} - -/** - * comp_editor_merge_ui: - * @editor: - * @filename: - * @verbs: - * - * - **/ -void -comp_editor_merge_ui (CompEditor *editor, const char *filename, BonoboUIVerb *verbs) -{ - CompEditorPrivate *priv; - - g_return_if_fail (editor != NULL); - g_return_if_fail (IS_COMP_EDITOR (editor)); - - priv = editor->priv; - - bonobo_ui_util_set_ui (priv->uic, EVOLUTION_DATADIR, filename, "evolution-calendar"); - bonobo_ui_component_add_verb_list_with_data (priv->uic, verbs, editor); -} - -/** - * comp_editor_set_ui_prop: - * @editor: - * @path: - * @attr: - * @val: - * - * - **/ -void -comp_editor_set_ui_prop (CompEditor *editor, - const char *path, - const char *attr, - const char *val) -{ - CompEditorPrivate *priv; - - g_return_if_fail (editor != NULL); - g_return_if_fail (IS_COMP_EDITOR (editor)); - - priv = editor->priv; - - bonobo_ui_component_set_prop (priv->uic, path, attr, val, NULL); -} - - -/* 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); -} - -/** - * comp_editor_focus: - * @editor: A component editor - * - * Brings the editor window to the front and gives it focus - **/ -void -comp_editor_focus (CompEditor *editor) -{ - CompEditorPrivate *priv; - - g_return_if_fail (editor != NULL); - g_return_if_fail (IS_COMP_EDITOR (editor)); - - priv = editor->priv; - - gtk_widget_show (GTK_WIDGET (editor)); - raise_and_focus (GTK_WIDGET (editor)); -} - -/* This sets the focus to the toplevel, so any field being edited is committed. - FIXME: In future we may also want to check some of the fields are valid, - e.g. the EDateEdit fields. */ -static void -commit_all_fields (CompEditor *editor) -{ - CompEditorPrivate *priv; - - priv = editor->priv; - - gtk_window_set_focus (GTK_WINDOW (editor), NULL); -} - -/* Menu Commands */ -static void -save_cmd (GtkWidget *widget, gpointer data) -{ - CompEditor *editor = COMP_EDITOR (data); - - commit_all_fields (editor); - - save_comp_with_send (editor); -} - -static void -save_close_cmd (GtkWidget *widget, gpointer data) -{ - CompEditor *editor = COMP_EDITOR (data); - - commit_all_fields (editor); - - if (save_comp_with_send (editor)) - close_dialog (editor); -} - -static void -save_as_cmd (GtkWidget *widget, gpointer data) -{ - CompEditor *editor = COMP_EDITOR (data); - CompEditorPrivate *priv; - char *filename; - char *ical_string; - FILE *file; - - priv = editor->priv; - - commit_all_fields (editor); - - filename = e_file_dialog_save (_("Save as...")); - if (filename == NULL) - return; - - ical_string = cal_client_get_component_as_string (priv->client, priv->comp); - if (ical_string == NULL) { - g_warning ("Couldn't convert item to a string"); - return; - } - - file = fopen (filename, "w"); - if (file == NULL) { - g_warning ("Couldn't save item"); - return; - } - - fprintf (file, ical_string); - g_free (ical_string); - fclose (file); -} - -static void -delete_cmd (GtkWidget *widget, gpointer data) -{ - CompEditor *editor = COMP_EDITOR (data); - CompEditorPrivate *priv; - CalComponentVType vtype; - - priv = editor->priv; - - vtype = cal_component_get_vtype (priv->comp); - - if (delete_component_dialog (priv->comp, FALSE, 1, vtype, GTK_WIDGET (editor))) - delete_comp (editor); -} - -static void -print_cmd (GtkWidget *widget, gpointer data) -{ - CompEditor *editor = COMP_EDITOR (data); - CalComponent *comp; - - commit_all_fields (editor); - - comp = comp_editor_get_current_comp (editor); - print_comp (comp, editor->priv->client, FALSE); - gtk_object_unref (GTK_OBJECT (comp)); -} - -static void -print_preview_cmd (GtkWidget *widget, gpointer data) -{ - CompEditor *editor = COMP_EDITOR (data); - CalComponent *comp; - - commit_all_fields (editor); - - comp = comp_editor_get_current_comp (editor); - print_comp (comp, editor->priv->client, TRUE); - gtk_object_unref (GTK_OBJECT (comp)); -} - -static void -print_setup_cmd (GtkWidget *widget, gpointer data) -{ - CompEditor *editor = COMP_EDITOR (data); - CompEditorPrivate *priv; - - priv = editor->priv; - - print_setup (); -} - -static void -close_cmd (GtkWidget *widget, gpointer data) -{ - CompEditor *editor = COMP_EDITOR (data); - - commit_all_fields (editor); - - if (prompt_to_save_changes (editor, TRUE)) - close_dialog (editor); -} - -static void -page_changed_cb (GtkObject *obj, gpointer data) -{ - CompEditor *editor = COMP_EDITOR (data); - CompEditorPrivate *priv; - - priv = editor->priv; - - priv->changed = TRUE; -} - -/* Page signal callbacks */ -static void -page_summary_changed_cb (GtkObject *obj, const char *summary, gpointer data) -{ - CompEditor *editor = COMP_EDITOR (data); - CompEditorPrivate *priv; - GList *l; - - priv = editor->priv; - - for (l = priv->pages; l != NULL; l = l->next) - if (obj != l->data) - comp_editor_page_set_summary (l->data, summary); - - priv->changed = TRUE; -} - -static void -page_dates_changed_cb (GtkObject *obj, - CompEditorPageDates *dates, - gpointer data) -{ - CompEditor *editor = COMP_EDITOR (data); - CompEditorPrivate *priv; - GList *l; - - priv = editor->priv; - - for (l = priv->pages; l != NULL; l = l->next) - if (obj != l->data) - comp_editor_page_set_dates (l->data, dates); - - priv->changed = TRUE; -} - -static void -obj_updated_cb (CalClient *client, const char *uid, gpointer data) -{ - CompEditor *editor = COMP_EDITOR (data); - CompEditorPrivate *priv; - CalComponent *comp = NULL; - CalClientGetStatus status; - const char *edit_uid; - - priv = editor->priv; - - cal_component_get_uid (priv->comp, &edit_uid); - - if (!strcmp (uid, edit_uid) && !priv->updating) { - if (changed_component_dialog (priv->comp, FALSE, priv->changed)) { - status = cal_client_get_object (priv->client, uid, &comp); - if (status == CAL_CLIENT_GET_SUCCESS) { - comp_editor_edit_comp (editor, comp); - gtk_object_unref (GTK_OBJECT (comp)); - } else { - GtkWidget *dlg; - - dlg = gnome_error_dialog (_("Unable to obtain current version!")); - gnome_dialog_run_and_close (GNOME_DIALOG (dlg)); - } - } - } -} - -static void -obj_removed_cb (CalClient *client, const char *uid, gpointer data) -{ - CompEditor *editor = COMP_EDITOR (data); - CompEditorPrivate *priv; - const char *edit_uid; - - priv = editor->priv; - - cal_component_get_uid (priv->comp, &edit_uid); - - if (!strcmp (uid, edit_uid) && !priv->updating) { - if (changed_component_dialog (priv->comp, TRUE, priv->changed)) - close_dialog (editor); - } -} - -static gint -delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data) -{ - CompEditor *editor = COMP_EDITOR (data); - - if (prompt_to_save_changes (editor, TRUE)) - close_dialog (editor); - - return TRUE; -} diff --git a/calendar/gui/dialogs/comp-editor.h b/calendar/gui/dialogs/comp-editor.h deleted file mode 100644 index f789515ab1..0000000000 --- a/calendar/gui/dialogs/comp-editor.h +++ /dev/null @@ -1,99 +0,0 @@ -/* Evolution calendar - Framework for a calendar component editor dialog - * - * Copyright (C) 2001 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef COMP_EDITOR_H -#define COMP_EDITOR_H - -#include <gtk/gtk.h> -#include <bonobo/bonobo-win.h> -#include <bonobo/bonobo-ui-engine.h> -#include <bonobo/bonobo-ui-component.h> -#include "cal-client.h" -#include "../itip-utils.h" -#include "comp-editor-page.h" - -BEGIN_GNOME_DECLS - - - -#define TYPE_COMP_EDITOR (comp_editor_get_type ()) -#define COMP_EDITOR(obj) (GTK_CHECK_CAST ((obj), TYPE_COMP_EDITOR, CompEditor)) -#define COMP_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_COMP_EDITOR, CompEditorClass)) -#define IS_COMP_EDITOR(obj) (GTK_CHECK_TYPE ((obj), TYPE_COMP_EDITOR)) -#define IS_COMP_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), TYPE_COMP_EDITOR)) - -typedef struct _CompEditorPrivate CompEditorPrivate; - -typedef struct { - BonoboWindow object; - - /* Private data */ - CompEditorPrivate *priv; -} CompEditor; - -typedef struct { - BonoboWindowClass parent_class; - - /* Virtual functions */ - void (* set_cal_client) (CompEditor *page, CalClient *client); - void (* edit_comp) (CompEditor *page, CalComponent *comp); - void (* send_comp) (CompEditor *page, CalComponentItipMethod method); -} CompEditorClass; - -GtkType comp_editor_get_type (void); -void comp_editor_set_changed (CompEditor *editor, - gboolean changed); -gboolean comp_editor_get_changed (CompEditor *editor); -void comp_editor_set_needs_send (CompEditor *editor, - gboolean needs_send); -gboolean comp_editor_get_needs_send (CompEditor *editor); -void comp_editor_append_page (CompEditor *editor, - CompEditorPage *page, - const char *label); -void comp_editor_remove_page (CompEditor *editor, - CompEditorPage *page); -void comp_editor_show_page (CompEditor *editor, - CompEditorPage *page); -void comp_editor_set_cal_client (CompEditor *editor, - CalClient *client); -CalClient *comp_editor_get_cal_client (CompEditor *editor); -void comp_editor_edit_comp (CompEditor *ee, - CalComponent *comp); -CalComponent *comp_editor_get_current_comp (CompEditor *editor); -gboolean comp_editor_save_comp (CompEditor *editor, - gboolean send); -void comp_editor_delete_comp (CompEditor *editor); -void comp_editor_send_comp (CompEditor *editor, - CalComponentItipMethod method); -void comp_editor_merge_ui (CompEditor *editor, - const char *filename, - BonoboUIVerb *verbs); -void comp_editor_set_ui_prop (CompEditor *editor, - const char *path, - const char *attr, - const char *val); -void comp_editor_focus (CompEditor *editor); - - - - -END_GNOME_DECLS - -#endif diff --git a/calendar/gui/dialogs/delete-comp.c b/calendar/gui/dialogs/delete-comp.c deleted file mode 100644 index 405a9445b4..0000000000 --- a/calendar/gui/dialogs/delete-comp.c +++ /dev/null @@ -1,165 +0,0 @@ -/* Evolution calendar - Delete calendar component dialog - * - * Copyright (C) 2001 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <glib.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <libgnomeui/gnome-stock.h> -#include <gal/widgets/e-unicode.h> -#include "widgets/misc/e-messagebox.h" -#include "../calendar-config.h" -#include "delete-comp.h" - - - -/** - * delete_component_dialog: - * @comp: A calendar component if a single component is to be deleted, or NULL - * if more that one component is to be deleted. - * @consider_as_untitled: If deleting more than one component, this is ignored. - * Otherwise, whether to consider the component as not having a summary; if - * FALSE then the component's summary string will be used. - * @n_comps: Number of components that are to be deleted. - * @vtype: Type of the components that are to be deleted. This is ignored - * if only one component is to be deleted, and the vtype is extracted from - * the component instead. - * @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 number of - * calendar components. The dialog will not appear, however, if the - * configuration option for confirmation is turned off. - * - * Return value: TRUE if the user clicked Yes, FALSE otherwise. If the - * configuration option for confirmation is turned off, this function will - * unconditionally return TRUE. - **/ -gboolean -delete_component_dialog (CalComponent *comp, - gboolean consider_as_untitled, - int n_comps, CalComponentVType vtype, - GtkWidget *widget) -{ - char *str; - GtkWidget *dialog; - - if (comp) { - g_return_val_if_fail (IS_CAL_COMPONENT (comp), FALSE); - g_return_val_if_fail (n_comps == 1, FALSE); - } else { - g_return_val_if_fail (n_comps > 1, FALSE); - g_return_val_if_fail (vtype != CAL_COMPONENT_NO_TYPE, FALSE); - } - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); - - if (!calendar_config_get_confirm_delete ()) - return TRUE; - - if (comp) { - CalComponentText summary; - char *tmp; - - vtype = cal_component_get_vtype (comp); - - if (!consider_as_untitled) { - cal_component_get_summary (comp, &summary); - tmp = e_utf8_to_gtk_string (widget, summary.value); - } else - tmp = NULL; - - switch (vtype) { - case CAL_COMPONENT_EVENT: - if (tmp) - str = g_strdup_printf (_("Are you sure you want to delete " - "the appointment `%s'?"), tmp); - else - str = g_strdup (_("Are you sure you want to delete this " - "untitled appointment?")); - break; - - case CAL_COMPONENT_TODO: - if (tmp) - str = g_strdup_printf (_("Are you sure you want to delete " - "the task `%s'?"), tmp); - else - str = g_strdup (_("Are you sure you want to delete this " - "untitled task?")); - break; - - case CAL_COMPONENT_JOURNAL: - if (tmp) - str = g_strdup_printf (_("Are you sure you want to delete " - "the journal entry `%s'?"), tmp); - 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); - g_free (tmp); - return FALSE; - } - - g_free (tmp); - } else { - switch (vtype) { - case CAL_COMPONENT_EVENT: - str = g_strdup_printf (_("Are you sure you want to delete " - "%d appointments?"), n_comps); - break; - - case CAL_COMPONENT_TODO: - str = g_strdup_printf (_("Are you sure you want to delete " - "%d tasks?"), n_comps); - break; - - case CAL_COMPONENT_JOURNAL: - str = g_strdup_printf (_("Are you sure you want to delete " - "%d journal entries?"), n_comps); - break; - - default: - g_message ("delete_component_dialog(): Cannot handle objects of type %d", - vtype); - return FALSE; - } - } - - dialog = e_message_box_new (str, E_MESSAGE_BOX_QUESTION, - GNOME_STOCK_BUTTON_YES, - GNOME_STOCK_BUTTON_NO, - NULL); - g_free (str); - - gtk_widget_hide (e_message_box_get_checkbox (E_MESSAGE_BOX (dialog))); - - if (gnome_dialog_run_and_close (GNOME_DIALOG (dialog)) == 0) - return TRUE; - else - return FALSE; -} diff --git a/calendar/gui/dialogs/delete-comp.h b/calendar/gui/dialogs/delete-comp.h deleted file mode 100644 index 64945b5bee..0000000000 --- a/calendar/gui/dialogs/delete-comp.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Evolution calendar - Delete calendar component dialog - * - * Copyright (C) 2001 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef DELETE_COMP_H -#define DELETE_COMP_H - -#include <gtk/gtkwidget.h> -#include <cal-util/cal-component.h> - -gboolean delete_component_dialog (CalComponent *comp, - gboolean consider_as_untitled, - int n_comps, CalComponentVType vtype, - GtkWidget *widget); - -#endif diff --git a/calendar/gui/dialogs/e-delegate-dialog.c b/calendar/gui/dialogs/e-delegate-dialog.c deleted file mode 100644 index 159d27e6a3..0000000000 --- a/calendar/gui/dialogs/e-delegate-dialog.c +++ /dev/null @@ -1,340 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Evolution calendar - Delegate selector dialog - * - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: Damon Chaplin <damon@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#include <config.h> -#include <liboaf/liboaf.h> -#include <bonobo/bonobo-control.h> -#include <bonobo/bonobo-exception.h> -#include <bonobo/bonobo-widget.h> -#include <gtk/gtksignal.h> -#include <gtk/gtkcombo.h> -#include <gtk/gtkentry.h> -#include <gtk/gtklabel.h> -#include <gnome.h> -#include <ical.h> -#include <glade/glade.h> -#include <widgets/misc/e-map.h> -#include <e-destination.h> -#include "Evolution-Addressbook-SelectNames.h" -#include "e-delegate-dialog.h" - -struct _EDelegateDialogPrivate { - char *name; - char *address; - - /* Glade XML data */ - GladeXML *xml; - - /* Widgets from the Glade file */ - GtkWidget *app; - GtkWidget *hbox; - GtkWidget *addressbook; - - GNOME_Evolution_Addressbook_SelectNames corba_select_names; - GtkWidget *entry; -}; - -#define SELECT_NAMES_OAFID "OAFIID:GNOME_Evolution_Addressbook_SelectNames" -static const char *section_name = "Delegate To"; - -static void e_delegate_dialog_class_init (EDelegateDialogClass *class); -static void e_delegate_dialog_init (EDelegateDialog *edd); -static void e_delegate_dialog_destroy (GtkObject *object); - -static gboolean get_widgets (EDelegateDialog *edd); -static void addressbook_clicked_cb (GtkWidget *widget, gpointer data); - -static GtkObjectClass *parent_class; - - -GtkType -e_delegate_dialog_get_type (void) -{ - static GtkType e_delegate_dialog_type = 0; - - if (!e_delegate_dialog_type) { - static const GtkTypeInfo e_delegate_dialog_info = { - "EDelegateDialog", - sizeof (EDelegateDialog), - sizeof (EDelegateDialogClass), - (GtkClassInitFunc) e_delegate_dialog_class_init, - (GtkObjectInitFunc) e_delegate_dialog_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - e_delegate_dialog_type = gtk_type_unique (GTK_TYPE_OBJECT, - &e_delegate_dialog_info); - } - - return e_delegate_dialog_type; -} - -/* Class initialization function for the event editor */ -static void -e_delegate_dialog_class_init (EDelegateDialogClass *class) -{ - GtkObjectClass *object_class; - - object_class = (GtkObjectClass *) class; - - parent_class = gtk_type_class (GTK_TYPE_OBJECT); - - object_class->destroy = e_delegate_dialog_destroy; -} - -/* Object initialization function for the event editor */ -static void -e_delegate_dialog_init (EDelegateDialog *edd) -{ - EDelegateDialogPrivate *priv; - - priv = g_new0 (EDelegateDialogPrivate, 1); - edd->priv = priv; - - priv->address = NULL; -} - -/* Destroy handler for the event editor */ -static void -e_delegate_dialog_destroy (GtkObject *object) -{ - EDelegateDialog *edd; - EDelegateDialogPrivate *priv; - GtkWidget *dialog; - - g_return_if_fail (object != NULL); - g_return_if_fail (E_IS_DELEGATE_DIALOG (object)); - - edd = E_DELEGATE_DIALOG (object); - priv = edd->priv; - - /* Destroy the actual dialog. */ - dialog = e_delegate_dialog_get_toplevel (edd); - gtk_widget_destroy (dialog); - - g_free (priv->address); - priv->address = NULL; - - g_free (priv); - edd->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - -EDelegateDialog * -e_delegate_dialog_construct (EDelegateDialog *edd, const char *name, const char *address) -{ - EDelegateDialogPrivate *priv; - EDestination *dest; - EDestination *destv[2] = {NULL, NULL}; - Bonobo_Control corba_control; - CORBA_Environment ev; - - g_return_val_if_fail (edd != NULL, NULL); - g_return_val_if_fail (E_IS_DELEGATE_DIALOG (edd), NULL); - - priv = edd->priv; - - /* Load the content widgets */ - - priv->xml = glade_xml_new (EVOLUTION_GLADEDIR "/e-delegate-dialog.glade", - NULL); - if (!priv->xml) { - g_message ("e_delegate_dialog_construct(): Could not load the Glade XML file!"); - goto error; - } - - if (!get_widgets (edd)) { - g_message ("e_delegate_dialog_construct(): Could not find all widgets in the XML file!"); - goto error; - } - - CORBA_exception_init (&ev); - - priv->corba_select_names = oaf_activate_from_id (SELECT_NAMES_OAFID, 0, NULL, &ev); - GNOME_Evolution_Addressbook_SelectNames_addSectionWithLimit (priv->corba_select_names, - section_name, - section_name, - 1, &ev); - - if (BONOBO_EX (&ev)) { - g_message ("e_delegate_dialog_construct(): Unable to add section!"); - goto error; - } - - corba_control = GNOME_Evolution_Addressbook_SelectNames_getEntryBySection (priv->corba_select_names, - section_name, &ev); - - if (BONOBO_EX (&ev)) { - g_message ("e_delegate_dialog_construct(): Unable to get addressbook entry!"); - goto error; - } - - CORBA_exception_free (&ev); - - priv->entry = bonobo_widget_new_control_from_objref (corba_control, CORBA_OBJECT_NIL); - gtk_widget_show (priv->entry); - gtk_box_pack_start (GTK_BOX (priv->hbox), priv->entry, TRUE, TRUE, 0); - - dest = e_destination_new (); - destv[0] = dest; - if (name != NULL && *name) - e_destination_set_name (dest, name); - if (address != NULL && *address) - e_destination_set_email (dest, address); - bonobo_widget_set_property (BONOBO_WIDGET (priv->entry), "destinations", e_destination_exportv (destv), NULL); - gtk_object_unref (GTK_OBJECT (dest)); - - gtk_signal_connect (GTK_OBJECT (priv->addressbook), "clicked", - GTK_SIGNAL_FUNC (addressbook_clicked_cb), edd); - - return edd; - - error: - - gtk_object_unref (GTK_OBJECT (edd)); - return NULL; -} - -static gboolean -get_widgets (EDelegateDialog *edd) -{ - EDelegateDialogPrivate *priv; - - priv = edd->priv; - -#define GW(name) glade_xml_get_widget (priv->xml, name) - - priv->app = GW ("delegate-dialog"); - priv->hbox = GW ("delegate-hbox"); - priv->addressbook = GW ("addressbook"); - - return (priv->app - && priv->hbox - && priv->addressbook); -} - -static void -addressbook_clicked_cb (GtkWidget *widget, gpointer data) -{ - EDelegateDialog *edd = data; - EDelegateDialogPrivate *priv; - CORBA_Environment ev; - - priv = edd->priv; - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_SelectNames_activateDialog (priv->corba_select_names, section_name, &ev); - - CORBA_exception_free (&ev); -} - - -/** - * e_delegate_dialog_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. - **/ -EDelegateDialog * -e_delegate_dialog_new (const char *name, const char *address) -{ - EDelegateDialog *edd; - - edd = E_DELEGATE_DIALOG (gtk_type_new (E_TYPE_DELEGATE_DIALOG)); - return e_delegate_dialog_construct (E_DELEGATE_DIALOG (edd), name, address); -} - -char * -e_delegate_dialog_get_delegate (EDelegateDialog *edd) -{ - EDelegateDialogPrivate *priv; - EDestination **destv; - char *string = NULL; - - g_return_val_if_fail (edd != NULL, NULL); - g_return_val_if_fail (E_IS_DELEGATE_DIALOG (edd), NULL); - - priv = edd->priv; - - bonobo_widget_get_property (BONOBO_WIDGET (priv->entry), "destinations", &string, NULL); - destv = e_destination_importv (string); - - if (destv && destv[0] != NULL) { - g_free (priv->address); - priv->address = g_strdup (e_destination_get_email (destv[0])); - g_free (destv); - } - - g_free (string); - - return g_strdup (priv->address); -} - - -char * -e_delegate_dialog_get_delegate_name (EDelegateDialog *edd) -{ - EDelegateDialogPrivate *priv; - EDestination **destv; - char *string = NULL; - - g_return_val_if_fail (edd != NULL, NULL); - g_return_val_if_fail (E_IS_DELEGATE_DIALOG (edd), NULL); - - priv = edd->priv; - - bonobo_widget_get_property (BONOBO_WIDGET (priv->entry), "destinations", &string, NULL); - destv = e_destination_importv (string); - - g_message ("importv: [%s]", string); - - if (destv && destv[0] != NULL) { - g_free (priv->name); - priv->name = g_strdup (e_destination_get_name (destv[0])); - g_free (destv); - } - - g_free (string); - - return g_strdup (priv->name); -} - -GtkWidget* -e_delegate_dialog_get_toplevel (EDelegateDialog *edd) -{ - EDelegateDialogPrivate *priv; - - g_return_val_if_fail (edd != NULL, NULL); - g_return_val_if_fail (E_IS_DELEGATE_DIALOG (edd), NULL); - - priv = edd->priv; - - return priv->app; -} - diff --git a/calendar/gui/dialogs/e-delegate-dialog.glade b/calendar/gui/dialogs/e-delegate-dialog.glade deleted file mode 100644 index 394c191682..0000000000 --- a/calendar/gui/dialogs/e-delegate-dialog.glade +++ /dev/null @@ -1,120 +0,0 @@ -<?xml version="1.0"?> -<GTK-Interface> - -<project> - <name>timezone-dialog</name> - <program_name>timezone-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>GnomeDialog</class> - <name>delegate-dialog</name> - <visible>False</visible> - <title>Enter Delegate</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> - <auto_close>True</auto_close> - <hide_on_close>True</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>ok-button</name> - <can_default>True</can_default> - <has_default>True</has_default> - <can_focus>True</can_focus> - <stock_button>GNOME_STOCK_BUTTON_OK</stock_button> - </widget> - - <widget> - <class>GtkButton</class> - <name>cancel-button</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>delegate-hbox</name> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label3</name> - <label>Delegate To:</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>GtkButton</class> - <name>addressbook</name> - <can_focus>True</can_focus> - <label>Addressbook...</label> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - <pack>GTK_PACK_END</pack> - </child> - </widget> - </widget> - </widget> -</widget> - -</GTK-Interface> diff --git a/calendar/gui/dialogs/e-delegate-dialog.h b/calendar/gui/dialogs/e-delegate-dialog.h deleted file mode 100644 index 311d22b4c7..0000000000 --- a/calendar/gui/dialogs/e-delegate-dialog.h +++ /dev/null @@ -1,73 +0,0 @@ -/* Evolution calendar - Delegate selector dialog - * - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef __E_DELEGATE_DIALOG_H__ -#define __E_DELEGATE_DIALOG_H__ - -#include <libgnome/gnome-defs.h> -#include <gtk/gtkwidget.h> - - - -#define E_TYPE_DELEGATE_DIALOG (e_delegate_dialog_get_type ()) -#define E_DELEGATE_DIALOG(obj) (GTK_CHECK_CAST ((obj), E_TYPE_DELEGATE_DIALOG, EDelegateDialog)) -#define E_DELEGATE_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_DELEGATE_DIALOG, \ - EDelegateDialogClass)) -#define E_IS_DELEGATE_DIALOG(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_DELEGATE_DIALOG)) -#define E_IS_DELEGATE_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), E_TYPE_DELEGATE_DIALOG)) - - -typedef struct _EDelegateDialog EDelegateDialog; -typedef struct _EDelegateDialogClass EDelegateDialogClass; -typedef struct _EDelegateDialogPrivate EDelegateDialogPrivate; - -struct _EDelegateDialog { - GtkObject object; - - /* Private data */ - EDelegateDialogPrivate *priv; -}; - -struct _EDelegateDialogClass { - GtkObjectClass parent_class; -}; - -GtkType e_delegate_dialog_get_type (void); - -EDelegateDialog* e_delegate_dialog_construct (EDelegateDialog *etd, - const char *name, - const char *address); - -EDelegateDialog* e_delegate_dialog_new (const char *name, - const char *address); - -char* e_delegate_dialog_get_delegate (EDelegateDialog *etd); - -char* e_delegate_dialog_get_delegate_name (EDelegateDialog *etd); - -void e_delegate_dialog_set_delegate (EDelegateDialog *etd, - const char *address); - -GtkWidget* e_delegate_dialog_get_toplevel (EDelegateDialog *etd); - - - - -#endif /* __E_DELEGATE_DIALOG_H__ */ diff --git a/calendar/gui/dialogs/event-editor.c b/calendar/gui/dialogs/event-editor.c deleted file mode 100644 index 4c0862c9f7..0000000000 --- a/calendar/gui/dialogs/event-editor.c +++ /dev/null @@ -1,450 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* Evolution calendar - Event editor dialog - * - * Copyright (C) 2000 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#include <config.h> -#include <string.h> -#include <glade/glade.h> -#include <gal/widgets/e-unicode.h> -#include <libgnome/gnome-i18n.h> -#include <widgets/misc/e-dateedit.h> - -#include "event-page.h" -#include "alarm-page.h" -#include "recurrence-page.h" -#include "meeting-page.h" -#include "schedule-page.h" -#include "cancel-comp.h" -#include "event-editor.h" - -struct _EventEditorPrivate { - EventPage *event_page; - AlarmPage *alarm_page; - RecurrencePage *recur_page; - MeetingPage *meet_page; - SchedulePage *sched_page; - - EMeetingModel *model; - - gboolean meeting_shown; - gboolean existing_org; - gboolean updating; -}; - - - -static void event_editor_class_init (EventEditorClass *class); -static void event_editor_init (EventEditor *ee); -static void event_editor_set_cal_client (CompEditor *editor, CalClient *client); -static void event_editor_edit_comp (CompEditor *editor, CalComponent *comp); -static void event_editor_send_comp (CompEditor *editor, CalComponentItipMethod method); -static void event_editor_destroy (GtkObject *object); - -static void schedule_meeting_cmd (GtkWidget *widget, gpointer data); -static void refresh_meeting_cmd (GtkWidget *widget, gpointer data); -static void cancel_meeting_cmd (GtkWidget *widget, gpointer data); -static void forward_cmd (GtkWidget *widget, gpointer data); - -static void model_row_changed_cb (ETableModel *etm, int row, gpointer data); -static void row_count_changed_cb (ETableModel *etm, int row, int count, gpointer data); - -static BonoboUIVerb verbs [] = { - BONOBO_UI_UNSAFE_VERB ("ActionScheduleMeeting", schedule_meeting_cmd), - BONOBO_UI_UNSAFE_VERB ("ActionRefreshMeeting", refresh_meeting_cmd), - BONOBO_UI_UNSAFE_VERB ("ActionCancelMeeting", cancel_meeting_cmd), - BONOBO_UI_UNSAFE_VERB ("ActionForward", forward_cmd), - - BONOBO_UI_VERB_END -}; - -static CompEditorClass *parent_class; - - - -/** - * 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 (TYPE_COMP_EDITOR, - &event_editor_info); - } - - return event_editor_type; -} - -/* Class initialization function for the event editor */ -static void -event_editor_class_init (EventEditorClass *klass) -{ - GtkObjectClass *object_class; - CompEditorClass *editor_class; - - object_class = (GtkObjectClass *) klass; - editor_class = (CompEditorClass *) klass; - - parent_class = gtk_type_class (TYPE_COMP_EDITOR); - - editor_class->set_cal_client = event_editor_set_cal_client; - editor_class->edit_comp = event_editor_edit_comp; - editor_class->send_comp = event_editor_send_comp; - - object_class->destroy = event_editor_destroy; -} - -static void -set_menu_sens (EventEditor *ee) -{ - EventEditorPrivate *priv; - gboolean sens; - - priv = ee->priv; - - sens = priv->meeting_shown; - comp_editor_set_ui_prop (COMP_EDITOR (ee), - "/commands/ActionScheduleMeeting", - "sensitive", sens ? "0" : "1"); - - sens = sens && priv->existing_org; - comp_editor_set_ui_prop (COMP_EDITOR (ee), - "/commands/ActionRefreshMeeting", - "sensitive", sens ? "1" : "0"); - comp_editor_set_ui_prop (COMP_EDITOR (ee), - "/commands/ActionCancelMeeting", - "sensitive", sens ? "1" : "0"); -} - -static void -init_widgets (EventEditor *ee) -{ - EventEditorPrivate *priv; - - priv = ee->priv; - - gtk_signal_connect (GTK_OBJECT (priv->model), "model_row_changed", - GTK_SIGNAL_FUNC (model_row_changed_cb), ee); - gtk_signal_connect (GTK_OBJECT (priv->model), "model_rows_inserted", - GTK_SIGNAL_FUNC (row_count_changed_cb), ee); - gtk_signal_connect (GTK_OBJECT (priv->model), "model_rows_deleted", - GTK_SIGNAL_FUNC (row_count_changed_cb), ee); -} - -/* Object initialization function for the event editor */ -static void -event_editor_init (EventEditor *ee) -{ - EventEditorPrivate *priv; - - priv = g_new0 (EventEditorPrivate, 1); - ee->priv = priv; - - priv->event_page = event_page_new (); - comp_editor_append_page (COMP_EDITOR (ee), - COMP_EDITOR_PAGE (priv->event_page), - _("Appointment")); - - priv->alarm_page = alarm_page_new (); - comp_editor_append_page (COMP_EDITOR (ee), - COMP_EDITOR_PAGE (priv->alarm_page), - _("Reminder")); - - priv->recur_page = recurrence_page_new (); - comp_editor_append_page (COMP_EDITOR (ee), - COMP_EDITOR_PAGE (priv->recur_page), - _("Recurrence")); - - priv->model = E_MEETING_MODEL (e_meeting_model_new ()); - - priv->sched_page = schedule_page_new (priv->model); - comp_editor_append_page (COMP_EDITOR (ee), - COMP_EDITOR_PAGE (priv->sched_page), - _("Scheduling")); - - priv->meet_page = meeting_page_new (priv->model); - comp_editor_append_page (COMP_EDITOR (ee), - COMP_EDITOR_PAGE (priv->meet_page), - _("Meeting")); - - comp_editor_merge_ui (COMP_EDITOR (ee), "evolution-event-editor.xml", verbs); - - priv->meeting_shown = TRUE; - priv->existing_org = FALSE; - priv->updating = FALSE; - - init_widgets (ee); - set_menu_sens (ee); -} - -static void -event_editor_set_cal_client (CompEditor *editor, CalClient *client) -{ - EventEditor *ee; - EventEditorPrivate *priv; - - ee = EVENT_EDITOR (editor); - priv = ee->priv; - - e_meeting_model_set_cal_client (priv->model, client); - - if (parent_class->set_cal_client) - parent_class->set_cal_client (editor, client); -} - -static void -event_editor_edit_comp (CompEditor *editor, CalComponent *comp) -{ - EventEditor *ee; - EventEditorPrivate *priv; - GSList *attendees = NULL; - - ee = EVENT_EDITOR (editor); - priv = ee->priv; - - priv->updating = TRUE; - - priv->existing_org = cal_component_has_organizer (comp); - cal_component_get_attendee_list (comp, &attendees); - - e_meeting_model_remove_all_attendees (priv->model); - if (attendees == NULL) { - comp_editor_remove_page (editor, COMP_EDITOR_PAGE (priv->meet_page)); - comp_editor_remove_page (editor, COMP_EDITOR_PAGE (priv->sched_page)); - priv->meeting_shown = FALSE; - } else { - GSList *l; - - if (!priv->meeting_shown) { - comp_editor_append_page (COMP_EDITOR (ee), - COMP_EDITOR_PAGE (priv->sched_page), - _("Scheduling")); - comp_editor_append_page (COMP_EDITOR (ee), - COMP_EDITOR_PAGE (priv->meet_page), - _("Meeting")); - } - - for (l = attendees; l != NULL; l = l->next) { - CalComponentAttendee *ca = l->data; - EMeetingAttendee *ia; - - ia = E_MEETING_ATTENDEE (e_meeting_attendee_new_from_cal_component_attendee (ca)); - e_meeting_model_add_attendee (priv->model, ia); - gtk_object_unref (GTK_OBJECT (ia)); - } - priv->meeting_shown = TRUE; - } - cal_component_free_attendee_list (attendees); - - set_menu_sens (ee); - comp_editor_set_needs_send (COMP_EDITOR (ee), priv->meeting_shown); - - priv->updating = FALSE; - - if (parent_class->edit_comp) - parent_class->edit_comp (editor, comp); -} - -static void -event_editor_send_comp (CompEditor *editor, CalComponentItipMethod method) -{ - EventEditor *ee = EVENT_EDITOR (editor); - EventEditorPrivate *priv; - CalComponent *comp = NULL; - - priv = ee->priv; - - /* Don't cancel more than once or when just publishing */ - if (method == CAL_COMPONENT_METHOD_PUBLISH || - method == CAL_COMPONENT_METHOD_CANCEL) - goto parent; - - comp = meeting_page_get_cancel_comp (priv->meet_page); - if (comp != NULL) { - CalClient *client; - - client = e_meeting_model_get_cal_client (priv->model); - itip_send_comp (CAL_COMPONENT_METHOD_CANCEL, comp, client, NULL); - gtk_object_unref (GTK_OBJECT (comp)); - } - - parent: - if (parent_class->send_comp) - parent_class->send_comp (editor, method); -} - -/* 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; - - gtk_object_unref (GTK_OBJECT (priv->event_page)); - gtk_object_unref (GTK_OBJECT (priv->alarm_page)); - gtk_object_unref (GTK_OBJECT (priv->recur_page)); - gtk_object_unref (GTK_OBJECT (priv->meet_page)); - gtk_object_unref (GTK_OBJECT (priv->sched_page)); - - gtk_object_destroy (GTK_OBJECT (priv->model)); - gtk_object_unref (GTK_OBJECT (priv->model)); - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - -/** - * 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) -{ - return EVENT_EDITOR (gtk_type_new (TYPE_EVENT_EDITOR)); -} - -static void -show_meeting (EventEditor *ee) -{ - EventEditorPrivate *priv; - - priv = ee->priv; - - if (!priv->meeting_shown) { - comp_editor_append_page (COMP_EDITOR (ee), - COMP_EDITOR_PAGE (priv->sched_page), - _("Scheduling")); - comp_editor_append_page (COMP_EDITOR (ee), - COMP_EDITOR_PAGE (priv->meet_page), - _("Meeting")); - priv->meeting_shown = TRUE; - - set_menu_sens (ee); - comp_editor_set_changed (COMP_EDITOR (ee), priv->meeting_shown); - comp_editor_set_needs_send (COMP_EDITOR (ee), priv->meeting_shown); - } - - comp_editor_show_page (COMP_EDITOR (ee), - COMP_EDITOR_PAGE (priv->meet_page)); -} - -void -event_editor_show_meeting (EventEditor *ee) -{ - g_return_if_fail (ee != NULL); - g_return_if_fail (IS_EVENT_EDITOR (ee)); - - - show_meeting (ee); -} - -static void -schedule_meeting_cmd (GtkWidget *widget, gpointer data) -{ - EventEditor *ee = EVENT_EDITOR (data); - - show_meeting (ee); -} - -static void -refresh_meeting_cmd (GtkWidget *widget, gpointer data) -{ - EventEditor *ee = EVENT_EDITOR (data); - - comp_editor_send_comp (COMP_EDITOR (ee), CAL_COMPONENT_METHOD_REFRESH); -} - -static void -cancel_meeting_cmd (GtkWidget *widget, gpointer data) -{ - EventEditor *ee = EVENT_EDITOR (data); - CalComponent *comp; - - comp = comp_editor_get_current_comp (COMP_EDITOR (ee)); - if (cancel_component_dialog (comp)) { - comp_editor_send_comp (COMP_EDITOR (ee), CAL_COMPONENT_METHOD_CANCEL); - comp_editor_delete_comp (COMP_EDITOR (ee)); - } -} - -static void -forward_cmd (GtkWidget *widget, gpointer data) -{ - EventEditor *ee = EVENT_EDITOR (data); - - if (comp_editor_save_comp (COMP_EDITOR (ee), TRUE)) - comp_editor_send_comp (COMP_EDITOR (ee), CAL_COMPONENT_METHOD_PUBLISH); -} - -static void -model_row_changed_cb (ETableModel *etm, int row, gpointer data) -{ - EventEditor *ee = EVENT_EDITOR (data); - EventEditorPrivate *priv; - - priv = ee->priv; - - if (!priv->updating) - comp_editor_set_changed (COMP_EDITOR (ee), TRUE); -} - -static void -row_count_changed_cb (ETableModel *etm, int row, int count, gpointer data) -{ - EventEditor *ee = EVENT_EDITOR (data); - EventEditorPrivate *priv; - - priv = ee->priv; - - if (!priv->updating) - comp_editor_set_changed (COMP_EDITOR (ee), TRUE); -} diff --git a/calendar/gui/dialogs/event-editor.h b/calendar/gui/dialogs/event-editor.h deleted file mode 100644 index d27bb8e52d..0000000000 --- a/calendar/gui/dialogs/event-editor.h +++ /dev/null @@ -1,61 +0,0 @@ -/* Evolution calendar - Event editor dialog - * - * Copyright (C) 2000 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef __EVENT_EDITOR_H__ -#define __EVENT_EDITOR_H__ - -#include <libgnome/gnome-defs.h> -#include <gtk/gtkobject.h> -#include "comp-editor.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 { - CompEditor parent; - - /* Private data */ - EventEditorPrivate *priv; -}; - -struct _EventEditorClass { - CompEditorClass parent_class; -}; - -GtkType event_editor_get_type (void); -EventEditor *event_editor_construct (EventEditor *ee); -EventEditor *event_editor_new (void); -void event_editor_show_meeting (EventEditor *ee); - - - -#endif /* __EVENT_EDITOR_H__ */ diff --git a/calendar/gui/dialogs/event-page.c b/calendar/gui/dialogs/event-page.c deleted file mode 100644 index a12bce2c47..0000000000 --- a/calendar/gui/dialogs/event-page.c +++ /dev/null @@ -1,1439 +0,0 @@ -/* Evolution calendar - Main page of the event editor dialog - * - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * Miguel de Icaza <miguel@ximian.com> - * Seth Alves <alves@hungry.com> - * JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtksignal.h> -#include <gtk/gtktogglebutton.h> -#include <glade/glade.h> -#include <gal/widgets/e-unicode.h> -#include <gal/widgets/e-categories.h> -#include "e-util/e-categories-config.h" -#include "e-util/e-dialog-widgets.h" -#include "widgets/misc/e-dateedit.h" -#include "cal-util/timeutil.h" -#include "../calendar-config.h" -#include "../e-timezone-entry.h" -#include "comp-editor-util.h" -#include "event-page.h" - - - -/* Private part of the EventPage structure */ -struct _EventPagePrivate { - /* Glade XML data */ - GladeXML *xml; - - /* Widgets from the Glade file */ - - GtkWidget *main; - - GtkWidget *summary; - GtkWidget *location; - - GtkWidget *start_time; - GtkWidget *end_time; - GtkWidget *start_timezone; - GtkWidget *end_timezone; - GtkWidget *all_day_event; - - GtkWidget *description; - - GtkWidget *classification_public; - GtkWidget *classification_private; - GtkWidget *classification_confidential; - - GtkWidget *show_time_as_free; - GtkWidget *show_time_as_busy; - - GtkWidget *contacts_btn; - GtkWidget *contacts_box; - - GtkWidget *categories_btn; - GtkWidget *categories; - - gboolean updating; - - /* This is TRUE if both the start & end timezone are the same. If the - start timezone is then changed, we updated the end timezone to the - same value, since 99% of events start and end in one timezone. */ - gboolean sync_timezones; - - /* The Corba component for selecting contacts, and the entry field - which we place in the dialog. */ - GNOME_Evolution_Addressbook_SelectNames corba_select_names; - GtkWidget *contacts_entry; -}; - - - -static void event_page_class_init (EventPageClass *class); -static void event_page_init (EventPage *epage); -static void event_page_destroy (GtkObject *object); - -static GtkWidget *event_page_get_widget (CompEditorPage *page); -static void event_page_focus_main_widget (CompEditorPage *page); -static void event_page_fill_widgets (CompEditorPage *page, CalComponent *comp); -static gboolean event_page_fill_component (CompEditorPage *page, CalComponent *comp); -static void event_page_set_summary (CompEditorPage *page, const char *summary); -static void event_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates); - -static CompEditorPageClass *parent_class = NULL; - - - -/** - * event_page_get_type: - * - * Registers the #EventPage class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the #EventPage class. - **/ -GtkType -event_page_get_type (void) -{ - static GtkType event_page_type; - - if (!event_page_type) { - static const GtkTypeInfo event_page_info = { - "EventPage", - sizeof (EventPage), - sizeof (EventPageClass), - (GtkClassInitFunc) event_page_class_init, - (GtkObjectInitFunc) event_page_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - event_page_type = gtk_type_unique (TYPE_COMP_EDITOR_PAGE, - &event_page_info); - } - - return event_page_type; -} - -/* Class initialization function for the event page */ -static void -event_page_class_init (EventPageClass *class) -{ - CompEditorPageClass *editor_page_class; - GtkObjectClass *object_class; - - editor_page_class = (CompEditorPageClass *) class; - object_class = (GtkObjectClass *) class; - - parent_class = gtk_type_class (TYPE_COMP_EDITOR_PAGE); - - editor_page_class->get_widget = event_page_get_widget; - editor_page_class->focus_main_widget = event_page_focus_main_widget; - editor_page_class->fill_widgets = event_page_fill_widgets; - editor_page_class->fill_component = event_page_fill_component; - editor_page_class->set_summary = event_page_set_summary; - editor_page_class->set_dates = event_page_set_dates; - - object_class->destroy = event_page_destroy; -} - -/* Object initialization function for the event page */ -static void -event_page_init (EventPage *epage) -{ - EventPagePrivate *priv; - - priv = g_new0 (EventPagePrivate, 1); - epage->priv = priv; - - priv->xml = NULL; - - priv->main = NULL; - priv->summary = NULL; - priv->location = NULL; - priv->start_time = NULL; - priv->end_time = NULL; - priv->start_timezone = NULL; - priv->end_timezone = NULL; - priv->all_day_event = NULL; - priv->description = NULL; - priv->classification_public = NULL; - priv->classification_private = NULL; - priv->classification_confidential = NULL; - priv->show_time_as_free = NULL; - priv->show_time_as_busy = NULL; - priv->contacts_btn = NULL; - priv->contacts_box = NULL; - priv->categories_btn = NULL; - priv->categories = NULL; - - priv->updating = FALSE; - priv->sync_timezones = FALSE; - - priv->corba_select_names = CORBA_OBJECT_NIL; - priv->contacts_entry = NULL; -} - -/* Destroy handler for the event page */ -static void -event_page_destroy (GtkObject *object) -{ - EventPage *epage; - EventPagePrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_EVENT_PAGE (object)); - - epage = EVENT_PAGE (object); - priv = epage->priv; - - if (priv->corba_select_names != CORBA_OBJECT_NIL) { - CORBA_Environment ev; - - CORBA_exception_init (&ev); - CORBA_Object_release (priv->corba_select_names, &ev); - CORBA_exception_free (&ev); - } - - if (priv->xml) { - gtk_object_unref (GTK_OBJECT (priv->xml)); - priv->xml = NULL; - } - - g_free (priv); - epage->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - - -static const int classification_map[] = { - CAL_COMPONENT_CLASS_PUBLIC, - CAL_COMPONENT_CLASS_PRIVATE, - CAL_COMPONENT_CLASS_CONFIDENTIAL, - -1 -}; - -static const int transparency_map[] = { - CAL_COMPONENT_TRANSP_TRANSPARENT, - CAL_COMPONENT_TRANSP_OPAQUE, - -1 -}; - -/* get_widget handler for the event page */ -static GtkWidget * -event_page_get_widget (CompEditorPage *page) -{ - EventPage *epage; - EventPagePrivate *priv; - - epage = EVENT_PAGE (page); - priv = epage->priv; - - return priv->main; -} - -/* focus_main_widget handler for the event page */ -static void -event_page_focus_main_widget (CompEditorPage *page) -{ - EventPage *epage; - EventPagePrivate *priv; - - epage = EVENT_PAGE (page); - priv = epage->priv; - - gtk_widget_grab_focus (priv->summary); -} - -/* Sets the 'All Day Event' flag to the given value (without emitting signals), - * and shows or hides the widgets as appropriate. */ -static void -set_all_day (EventPage *epage, gboolean all_day) -{ - EventPagePrivate *priv; - - priv = epage->priv; - - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->all_day_event), - epage); - e_dialog_toggle_set (priv->all_day_event, all_day); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->all_day_event), - epage); - - 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); - - /* DATE values do not have timezones, so we hide the fields. */ - if (all_day) { - gtk_widget_hide (priv->start_timezone); - gtk_widget_hide (priv->end_timezone); - } else { - gtk_widget_show (priv->start_timezone); - gtk_widget_show (priv->end_timezone); - } -} - -static void -update_time (EventPage *epage, CalComponentDateTime *start_date, CalComponentDateTime *end_date) -{ - EventPagePrivate *priv; - struct icaltimetype *start_tt, *end_tt; - icaltimezone *start_zone = NULL, *end_zone = NULL; - CalClientGetStatus status; - gboolean all_day_event; - - priv = epage->priv; - - /* Note that if we are creating a new event, the timezones may not be - on the server, so we try to get the builtin timezone with the TZID - first. */ - start_zone = icaltimezone_get_builtin_timezone_from_tzid (start_date->tzid); - if (!start_zone) { - status = cal_client_get_timezone (COMP_EDITOR_PAGE (epage)->client, - start_date->tzid, - &start_zone); - /* FIXME: Handle error better. */ - if (status != CAL_CLIENT_GET_SUCCESS) - g_warning ("Couldn't get timezone from server: %s", - start_date->tzid ? start_date->tzid : ""); - } - - end_zone = icaltimezone_get_builtin_timezone_from_tzid (end_date->tzid); - if (!end_zone) { - status = cal_client_get_timezone (COMP_EDITOR_PAGE (epage)->client, - end_date->tzid, - &end_zone); - /* FIXME: Handle error better. */ - if (status != CAL_CLIENT_GET_SUCCESS) - g_warning ("Couldn't get timezone from server: %s", - end_date->tzid ? end_date->tzid : ""); - } - - /* If both times are DATE values, we set the 'All Day Event' checkbox. - Also, if DTEND is after DTSTART, we subtract 1 day from it. */ - all_day_event = FALSE; - start_tt = start_date->value; - end_tt = end_date->value; - if (start_tt->is_date && end_tt->is_date) { - all_day_event = TRUE; - if (icaltime_compare_date_only (*end_tt, *start_tt) > 0) { - icaltime_adjust (end_tt, -1, 0, 0, 0); - } - } - - set_all_day (epage, all_day_event); - - /* If it is an all day event, we set both timezones to the current - timezone, so that if the user toggles the 'All Day Event' checkbox - the event uses the current timezone rather than none at all. */ - if (all_day_event) { - char *location = calendar_config_get_timezone (); - start_zone = end_zone = icaltimezone_get_builtin_timezone (location); - } - - - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_time), - epage); - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->end_time), epage); - - e_date_edit_set_date (E_DATE_EDIT (priv->start_time), start_tt->year, - start_tt->month, start_tt->day); - e_date_edit_set_time_of_day (E_DATE_EDIT (priv->start_time), - start_tt->hour, start_tt->minute); - - e_date_edit_set_date (E_DATE_EDIT (priv->end_time), end_tt->year, - end_tt->month, end_tt->day); - e_date_edit_set_time_of_day (E_DATE_EDIT (priv->end_time), - end_tt->hour, end_tt->minute); - - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->start_time), - epage); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->end_time), - epage); - - /* Set the timezones, and set sync_timezones to TRUE if both timezones - are the same. */ - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_timezone), - epage); - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->end_timezone), epage); - - e_timezone_entry_set_timezone (E_TIMEZONE_ENTRY (priv->start_timezone), - start_zone); - e_timezone_entry_set_timezone (E_TIMEZONE_ENTRY (priv->end_timezone), - end_zone); - - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->start_timezone), - epage); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->end_timezone), - epage); - - priv->sync_timezones = (start_zone == end_zone) ? TRUE : FALSE; - -} - -/* Fills the widgets with default values */ -static void -clear_widgets (EventPage *epage) -{ - EventPagePrivate *priv; - - priv = epage->priv; - - /* Summary, description */ - e_dialog_editable_set (priv->summary, NULL); - e_dialog_editable_set (priv->location, NULL); - e_dialog_editable_set (priv->description, NULL); - - /* Start and end times */ - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_time), - epage); - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->end_time), epage); - - e_date_edit_set_time (E_DATE_EDIT (priv->start_time), 0); - e_date_edit_set_time (E_DATE_EDIT (priv->end_time), 0); - - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->start_time), - epage); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->end_time), - epage); - - set_all_day (epage, FALSE); - - /* Classification */ - e_dialog_radio_set (priv->classification_public, - CAL_COMPONENT_CLASS_PRIVATE, classification_map); - - /* Show Time As (Transparency) */ - e_dialog_radio_set (priv->show_time_as_free, - CAL_COMPONENT_TRANSP_OPAQUE, transparency_map); - - /* Categories */ - e_dialog_editable_set (priv->categories, NULL); -} - - -static void -contacts_changed_cb (BonoboListener *listener, - char *event_name, - CORBA_any *arg, - CORBA_Environment *ev, - gpointer data) -{ - EventPage *epage; - EventPagePrivate *priv; - - epage = EVENT_PAGE (data); - priv = epage->priv; - -#if 0 - g_print ("In contacts_changed_cb\n"); -#endif - - if (!priv->updating) - comp_editor_page_notify_changed (COMP_EDITOR_PAGE (epage)); -} - - -/* fill_widgets handler for the event page */ -static void -event_page_fill_widgets (CompEditorPage *page, CalComponent *comp) -{ - EventPage *epage; - EventPagePrivate *priv; - CalComponentText text; - CalComponentClassification cl; - CalComponentTransparency transparency; - CalComponentDateTime start_date, end_date; - const char *location; - const char *categories; - GSList *l; - - g_return_if_fail (page->client != NULL); - - epage = EVENT_PAGE (page); - priv = epage->priv; - - /* Don't send off changes during this time */ - priv->updating = TRUE; - - /* Clean the page */ - clear_widgets (epage); - - /* Summary, location, description(s) */ - - cal_component_get_summary (comp, &text); - e_dialog_editable_set (priv->summary, text.value); - - cal_component_get_location (comp, &location); - e_dialog_editable_set (priv->location, location); - - cal_component_get_description_list (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 */ - - cal_component_get_dtstart (comp, &start_date); - cal_component_get_dtend (comp, &end_date); - - update_time (epage, &start_date, &end_date); - - cal_component_free_datetime (&start_date); - cal_component_free_datetime (&end_date); - - /* Classification */ - - cal_component_get_classification (comp, &cl); - - switch (cl) { - case CAL_COMPONENT_CLASS_PUBLIC: - e_dialog_radio_set (priv->classification_public, - CAL_COMPONENT_CLASS_PUBLIC, - classification_map); - break; - - case CAL_COMPONENT_CLASS_PRIVATE: - e_dialog_radio_set (priv->classification_public, - CAL_COMPONENT_CLASS_PRIVATE, - classification_map); - break; - - case CAL_COMPONENT_CLASS_CONFIDENTIAL: - e_dialog_radio_set (priv->classification_public, - CAL_COMPONENT_CLASS_CONFIDENTIAL, - classification_map); - break; - - default: - /* default to PUBLIC */ - e_dialog_radio_set (priv->classification_public, - CAL_COMPONENT_CLASS_PUBLIC, - classification_map); - break; - } - - - /* Show Time As (Transparency) */ - cal_component_get_transparency (comp, &transparency); - switch (transparency) { - case CAL_COMPONENT_TRANSP_TRANSPARENT: - e_dialog_radio_set (priv->show_time_as_free, - CAL_COMPONENT_TRANSP_TRANSPARENT, - transparency_map); - break; - - default: - e_dialog_radio_set (priv->show_time_as_free, - CAL_COMPONENT_TRANSP_OPAQUE, - transparency_map); - break; - } - - - - /* Categories */ - cal_component_get_categories (comp, &categories); - e_dialog_editable_set (priv->categories, categories); - - /* Contacts */ - comp_editor_contacts_to_widget (priv->contacts_entry, comp); - - /* We connect the contacts changed signal here, as we have to be a bit - more careful with it due to the use of Corba. The priv->updating - flag won't work as we won't get the changed event immediately. - FIXME: Unfortunately this doesn't work either. We never get the - changed event now. */ - comp_editor_connect_contacts_changed (priv->contacts_entry, - contacts_changed_cb, epage); - - priv->updating = FALSE; -} - -/* fill_component handler for the event page */ -static gboolean -event_page_fill_component (CompEditorPage *page, CalComponent *comp) -{ - EventPage *epage; - EventPagePrivate *priv; - CalComponentDateTime start_date, end_date; - struct icaltimetype start_tt, end_tt; - gboolean all_day_event, start_date_set, end_date_set; - char *cat, *str; - CalComponentClassification classif; - CalComponentTransparency transparency; - - epage = EVENT_PAGE (page); - priv = epage->priv; - - /* 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); - - /* Location */ - - str = e_dialog_editable_get (priv->location); - if (!str || strlen (str) == 0) - cal_component_set_location (comp, NULL); - else - cal_component_set_location (comp, str); - - 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 */ - - start_tt = icaltime_null_time (); - start_date.value = &start_tt; - start_date.tzid = NULL; - - end_tt = icaltime_null_time (); - end_date.value = &end_tt; - end_date.tzid = NULL; - - start_date_set = e_date_edit_get_date (E_DATE_EDIT (priv->start_time), - &start_tt.year, - &start_tt.month, - &start_tt.day); - g_assert (start_date_set); - - end_date_set = e_date_edit_get_date (E_DATE_EDIT (priv->end_time), - &end_tt.year, - &end_tt.month, - &end_tt.day); - g_assert (end_date_set); - - /* If the all_day toggle is set, we use DATE values for DTSTART and - DTEND. If not, we fetch the hour & minute from the widgets. */ - all_day_event = e_dialog_toggle_get (priv->all_day_event); - - if (all_day_event) { - start_tt.is_date = TRUE; - end_tt.is_date = TRUE; - - /* We have to add 1 day to DTEND, as it is not inclusive. */ - icaltime_adjust (&end_tt, 1, 0, 0, 0); - } else { - icaltimezone *start_zone, *end_zone; - - e_date_edit_get_time_of_day (E_DATE_EDIT (priv->start_time), - &start_tt.hour, - &start_tt.minute); - e_date_edit_get_time_of_day (E_DATE_EDIT (priv->end_time), - &end_tt.hour, - &end_tt.minute); - start_zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->start_timezone)); - start_date.tzid = icaltimezone_get_tzid (start_zone); - end_zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->end_timezone)); - end_date.tzid = icaltimezone_get_tzid (end_zone); - } - - cal_component_set_dtstart (comp, &start_date); - cal_component_set_dtend (comp, &end_date); - - - /* Categories */ - - cat = e_dialog_editable_get (priv->categories); - str = comp_editor_strip_categories (cat); - if (cat) - g_free (cat); - - cal_component_set_categories (comp, str); - - if (str) - g_free (str); - - /* Classification */ - - classif = e_dialog_radio_get (priv->classification_public, - classification_map); - cal_component_set_classification (comp, classif); - - /* Show Time As (Transparency) */ - - transparency = e_dialog_radio_get (priv->show_time_as_free, - transparency_map); - cal_component_set_transparency (comp, transparency); - - /* Contacts */ - - comp_editor_contacts_to_component (priv->contacts_entry, comp); - - return TRUE; -} - -/* set_summary handler for the event page */ -static void -event_page_set_summary (CompEditorPage *page, const char *summary) -{ - /* nothing */ -} - -static void -event_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates) -{ - update_time (EVENT_PAGE (page), dates->start, dates->end); -} - - - -/* Gets the widgets from the XML file and returns if they are all available. */ -static gboolean -get_widgets (EventPage *epage) -{ - CompEditorPage *page = COMP_EDITOR_PAGE (epage); - EventPagePrivate *priv; - GSList *accel_groups; - GtkWidget *toplevel; - - priv = epage->priv; - -#define GW(name) glade_xml_get_widget (priv->xml, name) - - priv->main = GW ("event-page"); - if (!priv->main) - return FALSE; - - /* Get the GtkAccelGroup from the toplevel window, so we can install - it when the notebook page is mapped. */ - toplevel = gtk_widget_get_toplevel (priv->main); - accel_groups = gtk_accel_groups_from_object (GTK_OBJECT (toplevel)); - if (accel_groups) { - page->accel_group = accel_groups->data; - gtk_accel_group_ref (page->accel_group); - } - - gtk_widget_ref (priv->main); - gtk_widget_unparent (priv->main); - - priv->summary = GW ("general-summary"); - priv->location = GW ("location"); - - priv->start_time = GW ("start-time"); - priv->end_time = GW ("end-time"); - priv->start_timezone = GW ("start-timezone"); - priv->end_timezone = GW ("end-timezone"); - 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->show_time_as_free = GW ("show-time-as-free"); - priv->show_time_as_busy = GW ("show-time-as-busy"); - - priv->contacts_btn = GW ("contacts-button"); - priv->contacts_box = GW ("contacts-box"); - - priv->categories_btn = GW ("categories-button"); - priv->categories = GW ("categories"); - -#undef GW - - return (priv->summary - && priv->location - && priv->start_time - && priv->end_time - && priv->start_timezone - && priv->end_timezone - && priv->all_day_event - && priv->description - && priv->classification_public - && priv->classification_private - && priv->classification_confidential - && priv->show_time_as_free - && priv->show_time_as_busy - && priv->contacts_btn - && priv->contacts_box - && priv->categories_btn - && priv->categories); -} - -/* Callback used when the summary changes; we emit the notification signal. */ -static void -summary_changed_cb (GtkEditable *editable, gpointer data) -{ - EventPage *epage; - EventPagePrivate *priv; - gchar *summary; - - epage = EVENT_PAGE (data); - priv = epage->priv; - - if (priv->updating) - return; - - summary = e_dialog_editable_get (GTK_WIDGET (editable)); - comp_editor_page_notify_summary_changed (COMP_EDITOR_PAGE (epage), - summary); - g_free (summary); -} - - -/* Note that this assumes that the start_tt and end_tt passed to it are the - dates visible to the user. For DATE values, we have to add 1 day to the - end_tt before emitting the signal. */ -static void -notify_dates_changed (EventPage *epage, struct icaltimetype *start_tt, - struct icaltimetype *end_tt) -{ - EventPagePrivate *priv; - CompEditorPageDates dates; - CalComponentDateTime start_dt, end_dt; - gboolean all_day_event; - icaltimezone *start_zone = NULL, *end_zone = NULL; - - priv = epage->priv; - - all_day_event = e_dialog_toggle_get (priv->all_day_event); - - start_dt.value = start_tt; - end_dt.value = end_tt; - - if (all_day_event) { - /* The actual DTEND is 1 day after the displayed date for - DATE values. */ - icaltime_adjust (end_tt, 1, 0, 0, 0); - } else { - start_zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->start_timezone)); - end_zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->end_timezone)); - } - - start_dt.tzid = start_zone ? icaltimezone_get_tzid (start_zone) : NULL; - end_dt.tzid = end_zone ? icaltimezone_get_tzid (end_zone) : NULL; - - dates.start = &start_dt; - dates.end = &end_dt; - - dates.due = NULL; - dates.complete = NULL; - - comp_editor_page_notify_dates_changed (COMP_EDITOR_PAGE (epage), - &dates); -} - - -static gboolean -check_start_before_end (struct icaltimetype *start_tt, - icaltimezone *start_zone, - struct icaltimetype *end_tt, - icaltimezone *end_zone, - gboolean adjust_end_time) -{ - struct icaltimetype end_tt_copy; - int cmp; - - /* Convert the end time to the same timezone as the start time. */ - end_tt_copy = *end_tt; - icaltimezone_convert_time (&end_tt_copy, end_zone, start_zone); - - /* Now check if the start time is after the end time. If it is, - we need to modify one of the times. */ - cmp = icaltime_compare (*start_tt, end_tt_copy); - if (cmp > 0) { - if (adjust_end_time) { - /* Modify the end time, to be the start + 1 hour. */ - *end_tt = *start_tt; - icaltime_adjust (end_tt, 0, 1, 0, 0); - icaltimezone_convert_time (end_tt, start_zone, - end_zone); - } else { - /* Modify the start time, to be the end - 1 hour. */ - *start_tt = *end_tt; - icaltime_adjust (start_tt, 0, -1, 0, 0); - icaltimezone_convert_time (start_tt, end_zone, - start_zone); - } - return TRUE; - } - - return FALSE; -} - - -/* - * This is called whenever the start or end dates or timezones is changed. - * It makes sure that the start date < end date. It also emits the notification - * signals so the other event editor pages update their labels etc. - * - * If adjust_end_time is TRUE, if the start time < end time it will adjust - * the end time. If FALSE it will adjust the start time. If the user sets the - * start or end time, the other time is adjusted to make it valid. - */ -static void -times_updated (EventPage *epage, gboolean adjust_end_time) -{ - EventPagePrivate *priv; - struct icaltimetype start_tt = icaltime_null_time(); - struct icaltimetype end_tt = icaltime_null_time(); - gboolean date_set, all_day_event; - gboolean set_start_date = FALSE, set_end_date = FALSE; - icaltimezone *start_zone, *end_zone; - - priv = epage->priv; - - if (priv->updating) - return; - - /* Fetch the start and end times and timezones from the widgets. */ - all_day_event = e_dialog_toggle_get (priv->all_day_event); - - date_set = e_date_edit_get_date (E_DATE_EDIT (priv->start_time), - &start_tt.year, - &start_tt.month, - &start_tt.day); - g_assert (date_set); - - date_set = e_date_edit_get_date (E_DATE_EDIT (priv->end_time), - &end_tt.year, - &end_tt.month, - &end_tt.day); - g_assert (date_set); - - if (all_day_event) { - /* All Day Events are simple. We just compare the dates and if - start > end we copy one of them to the other. */ - int cmp = icaltime_compare_date_only (start_tt, end_tt); - if (cmp > 0) { - if (adjust_end_time) { - end_tt = start_tt; - set_end_date = TRUE; - } else { - start_tt = end_tt; - set_start_date = TRUE; - } - } - - start_tt.is_date = TRUE; - end_tt.is_date = TRUE; - } else { - /* For DATE-TIME events, we have to convert to the same - timezone before comparing. */ - e_date_edit_get_time_of_day (E_DATE_EDIT (priv->start_time), - &start_tt.hour, - &start_tt.minute); - e_date_edit_get_time_of_day (E_DATE_EDIT (priv->end_time), - &end_tt.hour, - &end_tt.minute); - - start_zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->start_timezone)); - end_zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->end_timezone)); - - if (check_start_before_end (&start_tt, start_zone, - &end_tt, end_zone, - adjust_end_time)) { - if (adjust_end_time) - set_end_date = TRUE; - else - set_start_date = TRUE; - } - } - - - if (set_start_date) { - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_time), epage); - e_date_edit_set_date (E_DATE_EDIT (priv->start_time), - start_tt.year, start_tt.month, - start_tt.day); - e_date_edit_set_time_of_day (E_DATE_EDIT (priv->start_time), - start_tt.hour, start_tt.minute); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->start_time), epage); - } - - if (set_end_date) { - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->end_time), epage); - e_date_edit_set_date (E_DATE_EDIT (priv->end_time), - end_tt.year, end_tt.month, end_tt.day); - e_date_edit_set_time_of_day (E_DATE_EDIT (priv->end_time), - end_tt.hour, end_tt.minute); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->end_time), epage); - } - - /* Notify upstream */ - notify_dates_changed (epage, &start_tt, &end_tt); -} - -/* 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 (GtkWidget *dedit, gpointer data) -{ - EventPage *epage; - - epage = EVENT_PAGE (data); - - times_updated (epage, dedit == epage->priv->start_time); -} - - -/* Callback used when the start timezone is changed. If sync_timezones is set, - * we set the end timezone to the same value. It also updates the start time - * labels on the other notebook pages. - */ -static void -start_timezone_changed_cb (GtkWidget *widget, gpointer data) -{ - EventPage *epage; - EventPagePrivate *priv; - icaltimezone *zone; - - epage = EVENT_PAGE (data); - priv = epage->priv; - - if (priv->sync_timezones) { - zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->start_timezone)); - priv->updating = TRUE; - e_timezone_entry_set_timezone (E_TIMEZONE_ENTRY (priv->end_timezone), zone); - priv->updating = FALSE; - } - - times_updated (epage, TRUE); -} - - -/* Callback used when the end timezone is changed. It checks if the end - * timezone is the same as the start timezone and sets sync_timezones if so. - */ -static void -end_timezone_changed_cb (GtkWidget *widget, gpointer data) -{ - EventPage *epage; - EventPagePrivate *priv; - icaltimezone *start_zone, *end_zone; - - epage = EVENT_PAGE (data); - priv = epage->priv; - - start_zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->start_timezone)); - end_zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->end_timezone)); - - priv->sync_timezones = (start_zone == end_zone) ? TRUE : FALSE; - - times_updated (epage, TRUE); -} - -/* 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 -all_day_event_toggled_cb (GtkWidget *toggle, gpointer data) -{ - EventPage *epage; - EventPagePrivate *priv; - gboolean all_day; - struct icaltimetype start_tt = icaltime_null_time(); - struct icaltimetype end_tt = icaltime_null_time(); - gboolean date_set; - - epage = EVENT_PAGE (data); - priv = epage->priv; - - /* 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 round it down to the previous day, so the - * event times stay the same. - * - * When the all_day_toggle is turned off, then if the event is within - * one day, we set the event start to the start of the working day, - * and set the event end to one hour after it. If the event is longer - * than one day, we set the event end to the end of the day it is on, - * so that the actual event times remain the same. - * - * This may need tweaking to work well with different timezones used - * in the event start & end. - */ - all_day = GTK_TOGGLE_BUTTON (toggle)->active; - - set_all_day (epage, all_day); - - date_set = e_date_edit_get_date (E_DATE_EDIT (priv->start_time), - &start_tt.year, - &start_tt.month, - &start_tt.day); - e_date_edit_get_time_of_day (E_DATE_EDIT (priv->start_time), - &start_tt.hour, - &start_tt.minute); - g_assert (date_set); - - date_set = e_date_edit_get_date (E_DATE_EDIT (priv->end_time), - &end_tt.year, - &end_tt.month, - &end_tt.day); - e_date_edit_get_time_of_day (E_DATE_EDIT (priv->end_time), - &end_tt.hour, - &end_tt.minute); - g_assert (date_set); - - if (all_day) { - /* Round down to the start of the day. */ - start_tt.hour = 0; - start_tt.minute = 0; - start_tt.second = 0; - start_tt.is_date = TRUE; - - /* Round down to the start of the day, or the start of the - previous day if it is midnight. */ - icaltime_adjust (&end_tt, 0, 0, 0, -1); - end_tt.hour = 0; - end_tt.minute = 0; - end_tt.second = 0; - end_tt.is_date = TRUE; - } else { - icaltimezone *start_zone, *end_zone; - - if (end_tt.year == start_tt.year - && end_tt.month == start_tt.month - && end_tt.day == start_tt.day) { - /* The event is within one day, so we set the event - start to the start of the working day, and the end - to one hour later. */ - start_tt.hour = calendar_config_get_day_start_hour (); - start_tt.minute = calendar_config_get_day_start_minute (); - start_tt.second = 0; - - end_tt = start_tt; - icaltime_adjust (&end_tt, 0, 1, 0, 0); - } else { - /* The event is longer than 1 day, so we keep exactly - the same times, just using DATE-TIME rather than - DATE. */ - icaltime_adjust (&end_tt, 1, 0, 0, 0); - } - - /* Make sure that end > start using the timezones. */ - start_zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->start_timezone)); - end_zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->end_timezone)); - check_start_before_end (&start_tt, start_zone, - &end_tt, end_zone, - TRUE); - } - - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_time), - epage); - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->end_time), - epage); - - e_date_edit_set_date (E_DATE_EDIT (priv->start_time), start_tt.year, - start_tt.month, start_tt.day); - e_date_edit_set_time_of_day (E_DATE_EDIT (priv->start_time), - start_tt.hour, start_tt.minute); - - e_date_edit_set_date (E_DATE_EDIT (priv->end_time), end_tt.year, - end_tt.month, end_tt.day); - e_date_edit_set_time_of_day (E_DATE_EDIT (priv->end_time), - end_tt.hour, end_tt.minute); - - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->start_time), - epage); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->end_time), - epage); - - /* Notify upstream */ - notify_dates_changed (epage, &start_tt, &end_tt); -} - -/* Callback used when the contacts button is clicked; we must bring up the - * contact list dialog. - */ -static void -contacts_clicked_cb (GtkWidget *button, gpointer data) -{ - EventPage *epage; - EventPagePrivate *priv; - - epage = EVENT_PAGE (data); - priv = epage->priv; - - comp_editor_show_contacts_dialog (priv->corba_select_names); - - /* FIXME: Currently we aren't getting the changed event from the - SelectNames component correctly, so we aren't saving the event - if just the contacts are changed. To work around that, we assume - that if the contacts button is clicked it is changed. */ - comp_editor_page_notify_changed (COMP_EDITOR_PAGE (epage)); -} - -/* Callback used when the categories button is clicked; we must bring up the - * category list dialog. - */ -static void -categories_clicked_cb (GtkWidget *button, gpointer data) -{ - EventPage *epage; - EventPagePrivate *priv; - GtkWidget *entry; - - epage = EVENT_PAGE (data); - priv = epage->priv; - - entry = priv->categories; - e_categories_config_open_dialog_for_entry (GTK_ENTRY (entry)); -} - -/* This is called when any field is changed; it notifies upstream. */ -static void -field_changed_cb (GtkWidget *widget, gpointer data) -{ - EventPage *epage; - EventPagePrivate *priv; - - epage = EVENT_PAGE (data); - priv = epage->priv; - - if (!priv->updating) - comp_editor_page_notify_changed (COMP_EDITOR_PAGE (epage)); -} - -/* Hooks the widget signals */ -static gboolean -init_widgets (EventPage *epage) -{ - EventPagePrivate *priv; - char *location; - icaltimezone *zone; - - priv = epage->priv; - - /* Make sure the EDateEdit widgets use our timezones to get the - current time. */ - e_date_edit_set_get_time_callback (E_DATE_EDIT (priv->start_time), - (EDateEditGetTimeCallback) comp_editor_get_current_time, - epage, NULL); - e_date_edit_set_get_time_callback (E_DATE_EDIT (priv->end_time), - (EDateEditGetTimeCallback) comp_editor_get_current_time, - epage, NULL); - - /* Summary */ - gtk_signal_connect (GTK_OBJECT (priv->summary), "changed", - GTK_SIGNAL_FUNC (summary_changed_cb), epage); - - /* Description - turn on word wrap. */ - gtk_text_set_word_wrap (GTK_TEXT (priv->description), TRUE); - - /* Start and end times */ - gtk_signal_connect (GTK_OBJECT (priv->start_time), "changed", - GTK_SIGNAL_FUNC (date_changed_cb), epage); - gtk_signal_connect (GTK_OBJECT (priv->end_time), "changed", - GTK_SIGNAL_FUNC (date_changed_cb), epage); - - gtk_signal_connect (GTK_OBJECT (priv->start_timezone), "changed", - GTK_SIGNAL_FUNC (start_timezone_changed_cb), epage); - gtk_signal_connect (GTK_OBJECT (priv->end_timezone), "changed", - GTK_SIGNAL_FUNC (end_timezone_changed_cb), epage); - - gtk_signal_connect (GTK_OBJECT (priv->all_day_event), "toggled", - GTK_SIGNAL_FUNC (all_day_event_toggled_cb), epage); - - /* Contacts button */ - gtk_signal_connect (GTK_OBJECT (priv->contacts_btn), "clicked", - GTK_SIGNAL_FUNC (contacts_clicked_cb), epage); - - /* Categories button */ - gtk_signal_connect (GTK_OBJECT (priv->categories_btn), "clicked", - GTK_SIGNAL_FUNC (categories_clicked_cb), epage); - - /* Connect the default signal handler to use to make sure we notify - * upstream of changes to the widget values. - */ - - gtk_signal_connect (GTK_OBJECT (priv->summary), "changed", - GTK_SIGNAL_FUNC (field_changed_cb), epage); - gtk_signal_connect (GTK_OBJECT (priv->location), "changed", - GTK_SIGNAL_FUNC (field_changed_cb), epage); - gtk_signal_connect (GTK_OBJECT (priv->start_time), "changed", - GTK_SIGNAL_FUNC (field_changed_cb), epage); - gtk_signal_connect (GTK_OBJECT (priv->end_time), "changed", - GTK_SIGNAL_FUNC (field_changed_cb), epage); - gtk_signal_connect (GTK_OBJECT (priv->start_timezone), "changed", - GTK_SIGNAL_FUNC (field_changed_cb), epage); - gtk_signal_connect (GTK_OBJECT (priv->end_timezone), "changed", - GTK_SIGNAL_FUNC (field_changed_cb), epage); - gtk_signal_connect (GTK_OBJECT (priv->all_day_event), "toggled", - GTK_SIGNAL_FUNC (field_changed_cb), epage); - gtk_signal_connect (GTK_OBJECT (priv->description), "changed", - GTK_SIGNAL_FUNC (field_changed_cb), epage); - gtk_signal_connect (GTK_OBJECT (priv->classification_public), - "toggled", GTK_SIGNAL_FUNC (field_changed_cb), - epage); - gtk_signal_connect (GTK_OBJECT (priv->classification_private), - "toggled", GTK_SIGNAL_FUNC (field_changed_cb), - epage); - gtk_signal_connect (GTK_OBJECT (priv->classification_confidential), - "toggled", GTK_SIGNAL_FUNC (field_changed_cb), - epage); - gtk_signal_connect (GTK_OBJECT (priv->show_time_as_free), - "toggled", GTK_SIGNAL_FUNC (field_changed_cb), - epage); - gtk_signal_connect (GTK_OBJECT (priv->show_time_as_busy), - "toggled", GTK_SIGNAL_FUNC (field_changed_cb), - epage); - gtk_signal_connect (GTK_OBJECT (priv->categories), "changed", - GTK_SIGNAL_FUNC (field_changed_cb), epage); - - /* Create the contacts entry, a corba control from the address book. */ - priv->corba_select_names = comp_editor_create_contacts_component (); - if (priv->corba_select_names == CORBA_OBJECT_NIL) - return FALSE; - - priv->contacts_entry = comp_editor_create_contacts_control (priv->corba_select_names); - if (priv->contacts_entry == NULL) - return FALSE; - - gtk_container_add (GTK_CONTAINER (priv->contacts_box), - priv->contacts_entry); - - /* Set the default timezone, so the timezone entry may be hidden. */ - location = calendar_config_get_timezone (); - zone = icaltimezone_get_builtin_timezone (location); - e_timezone_entry_set_default_timezone (E_TIMEZONE_ENTRY (priv->start_timezone), zone); - e_timezone_entry_set_default_timezone (E_TIMEZONE_ENTRY (priv->end_timezone), zone); - - return TRUE; -} - - - -/** - * event_page_construct: - * @epage: An event page. - * - * Constructs an event page by loading its Glade data. - * - * Return value: The same object as @epage, or NULL if the widgets could not be - * created. - **/ -EventPage * -event_page_construct (EventPage *epage) -{ - EventPagePrivate *priv; - - priv = epage->priv; - - priv->xml = glade_xml_new (EVOLUTION_GLADEDIR "/event-page.glade", - NULL); - if (!priv->xml) { - g_message ("event_page_construct(): " - "Could not load the Glade XML file!"); - return NULL; - } - - if (!get_widgets (epage)) { - g_message ("event_page_construct(): " - "Could not find all widgets in the XML file!"); - return NULL; - } - - if (!init_widgets (epage)) { - g_message ("event_page_construct(): " - "Could not initialize the widgets!"); - return NULL; - } - - return epage; -} - -/** - * event_page_new: - * - * Creates a new event page. - * - * Return value: A newly-created event page, or NULL if the page could - * not be created. - **/ -EventPage * -event_page_new (void) -{ - EventPage *epage; - - epage = gtk_type_new (TYPE_EVENT_PAGE); - if (!event_page_construct (epage)) { - gtk_object_unref (GTK_OBJECT (epage)); - return NULL; - } - - return epage; -} - -GtkWidget *make_date_edit (void); - -GtkWidget * -make_date_edit (void) -{ - return comp_editor_new_date_edit (TRUE, TRUE, TRUE); -} - -GtkWidget *make_timezone_entry (void); - -GtkWidget * -make_timezone_entry (void) -{ - return e_timezone_entry_new (); -} diff --git a/calendar/gui/dialogs/event-page.glade b/calendar/gui/dialogs/event-page.glade deleted file mode 100644 index 6be310448a..0000000000 --- a/calendar/gui/dialogs/event-page.glade +++ /dev/null @@ -1,601 +0,0 @@ -<?xml version="1.0"?> -<GTK-Interface> - -<project> - <name>event-page</name> - <program_name>event-page</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>GtkWindow</class> - <name>event-toplevel</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>GtkVBox</class> - <name>event-page</name> - <border_width>4</border_width> - <homogeneous>False</homogeneous> - <spacing>6</spacing> - - <widget> - <class>GtkTable</class> - <name>table11</name> - <rows>2</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> - <class>GtkLabel</class> - <name>label61</name> - <label>L_ocation:</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>location</default_focus_target> - <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>location</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> - - <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>4</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> - <focus_target>start-time</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>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> - <focus_target>end-time</focus_target> - <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>Custom</class> - <name>start-time</name> - <can_focus>True</can_focus> - <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> - <can_focus>True</can_focus> - <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> - <class>Custom</class> - <name>end-timezone</name> - <creation_function>make_timezone_entry</creation_function> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Mon, 18 Jun 2001 23:51:40 GMT</last_modification_time> - <child> - <left_attach>2</left_attach> - <right_attach>3</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>True</yfill> - </child> - </widget> - - <widget> - <class>Custom</class> - <name>start-timezone</name> - <creation_function>make_timezone_entry</creation_function> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Mon, 18 Jun 2001 23:51:34 GMT</last_modification_time> - <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>True</yfill> - </child> - </widget> - - <widget> - <class>GtkAlignment</class> - <name>alignment1</name> - <xalign>1</xalign> - <yalign>7.45058e-09</yalign> - <xscale>0</xscale> - <yscale>0</yscale> - <child> - <left_attach>3</left_attach> - <right_attach>4</right_attach> - <top_attach>0</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>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> - </widget> - </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>GtkHBox</class> - <name>hbox54</name> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <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>True</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>True</expand> - <fill>True</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>True</expand> - <fill>True</fill> - </child> - </widget> - - <widget> - <class>GtkRadioButton</class> - <name>classification-confidential</name> - <can_focus>True</can_focus> - <label>Con_fidential</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <group>classification_radio_group</group> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - </widget> - </widget> - </widget> - - <widget> - <class>GtkFrame</class> - <name>frame33</name> - <label>Show Time As</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>hbox55</name> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - - <widget> - <class>GtkRadioButton</class> - <name>show-time-as-free</name> - <can_focus>True</can_focus> - <label>F_ree</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <group>show_time_as_radio_group</group> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - </widget> - - <widget> - <class>GtkRadioButton</class> - <name>show-time-as-busy</name> - <can_focus>True</can_focus> - <label>B_usy</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - <group>show_time_as_radio_group</group> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - </widget> - </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> - <relief>GTK_RELIEF_NORMAL</relief> - <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>GtkEventBox</class> - <name>contacts-box</name> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>Placeholder</class> - </widget> - </widget> - - <widget> - <class>GtkButton</class> - <name>categories-button</name> - <can_focus>True</can_focus> - <relief>GTK_RELIEF_NORMAL</relief> - <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> - -</GTK-Interface> diff --git a/calendar/gui/dialogs/event-page.h b/calendar/gui/dialogs/event-page.h deleted file mode 100644 index 3da59f4ada..0000000000 --- a/calendar/gui/dialogs/event-page.h +++ /dev/null @@ -1,61 +0,0 @@ -/* Evolution calendar - Main page of the event editor dialog - * - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * Miguel de Icaza <miguel@ximian.com> - * Seth Alves <alves@hungry.com> - * JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef EVENT_PAGE_H -#define EVENT_PAGE_H - -#include "comp-editor-page.h" - -BEGIN_GNOME_DECLS - - - -#define TYPE_EVENT_PAGE (event_page_get_type ()) -#define EVENT_PAGE(obj) (GTK_CHECK_CAST ((obj), TYPE_EVENT_PAGE, EventPage)) -#define EVENT_PAGE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_EVENT_PAGE, EventPageClass)) -#define IS_EVENT_PAGE(obj) (GTK_CHECK_TYPE ((obj), TYPE_EVENT_PAGE)) -#define IS_EVENT_PAGE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), TYPE_EVENT_PAGE)) - -typedef struct _EventPagePrivate EventPagePrivate; - -typedef struct { - CompEditorPage page; - - /* Private data */ - EventPagePrivate *priv; -} EventPage; - -typedef struct { - CompEditorPageClass parent_class; -} EventPageClass; - - -GtkType event_page_get_type (void); -EventPage *event_page_construct (EventPage *epage); -EventPage *event_page_new (void); - - - -END_GNOME_DECLS - -#endif diff --git a/calendar/gui/dialogs/meeting-page.c b/calendar/gui/dialogs/meeting-page.c deleted file mode 100644 index 2504ed3993..0000000000 --- a/calendar/gui/dialogs/meeting-page.c +++ /dev/null @@ -1,862 +0,0 @@ -/* Evolution calendar - Main page of the task editor dialog - * - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * Miguel de Icaza <miguel@ximian.com> - * Seth Alves <alves@hungry.com> - * JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <glib.h> -#include <gtk/gtksignal.h> -#include <gtk/gtktogglebutton.h> -#include <gtk/gtkvbox.h> -#include <gtk/gtkwindow.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <glade/glade.h> -#include <libgnomeui/gnome-stock.h> -#include <gal/e-table/e-cell-combo.h> -#include <gal/e-table/e-cell-text.h> -#include <gal/e-table/e-table-simple.h> -#include <gal/e-table/e-table-scrolled.h> -#include <gal/widgets/e-unicode.h> -#include <gal/widgets/e-popup-menu.h> -#include <gal/widgets/e-gui-utils.h> -#include <widgets/misc/e-dateedit.h> -#include <e-util/e-dialog-widgets.h> -#include "../component-factory.h" -#include "../e-meeting-attendee.h" -#include "../e-meeting-model.h" -#include "../itip-utils.h" -#include "comp-editor-util.h" -#include "e-delegate-dialog.h" -#include "meeting-page.h" - - - -enum columns { - MEETING_ATTENDEE_COL, - MEETING_MEMBER_COL, - MEETING_TYPE_COL, - MEETING_ROLE_COL, - MEETING_RSVP_COL, - MEETING_DELTO_COL, - MEETING_DELFROM_COL, - MEETING_STATUS_COL, - MEETING_CN_COL, - MEETING_LANG_COL, - MEETING_COLUMN_COUNT -}; - -/* Private part of the MeetingPage structure */ -struct _MeetingPagePrivate { - /* Lists of attendees */ - GPtrArray *deleted_attendees; - - /* To use in case of cancellation */ - CalComponent *comp; - - /* List of identities */ - GList *addresses; - GList *address_strings; - gchar *default_address; - - /* Glade XML data */ - GladeXML *xml; - - /* Widgets from the Glade file */ - GtkWidget *main; - GtkWidget *organizer_table; - GtkWidget *organizer; - GtkWidget *organizer_lbl; - GtkWidget *other_organizer; - GtkWidget *other_organizer_lbl; - GtkWidget *other_organizer_btn; - GtkWidget *existing_organizer_table; - GtkWidget *existing_organizer; - GtkWidget *existing_organizer_btn; - GtkWidget *invite; - - /* E Table stuff */ - EMeetingModel *model; - ETableScrolled *etable; - gint row; - - /* For handling who the organizer is */ - gboolean other; - gboolean existing; - gboolean updating; -}; - - - -static void meeting_page_class_init (MeetingPageClass *class); -static void meeting_page_init (MeetingPage *mpage); -static void meeting_page_destroy (GtkObject *object); - -static GtkWidget *meeting_page_get_widget (CompEditorPage *page); -static void meeting_page_focus_main_widget (CompEditorPage *page); -static void meeting_page_fill_widgets (CompEditorPage *page, CalComponent *comp); -static gboolean meeting_page_fill_component (CompEditorPage *page, CalComponent *comp); - -static gint right_click_cb (ETable *etable, gint row, gint col, GdkEvent *event, gpointer data); - -static CompEditorPageClass *parent_class = NULL; - - - -/** - * meeting_page_get_type: - * - * Registers the #MeetingPage class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the #MeetingPage class. - **/ -GtkType -meeting_page_get_type (void) -{ - static GtkType meeting_page_type; - - if (!meeting_page_type) { - static const GtkTypeInfo meeting_page_info = { - "MeetingPage", - sizeof (MeetingPage), - sizeof (MeetingPageClass), - (GtkClassInitFunc) meeting_page_class_init, - (GtkObjectInitFunc) meeting_page_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - meeting_page_type = - gtk_type_unique (TYPE_COMP_EDITOR_PAGE, - &meeting_page_info); - } - - return meeting_page_type; -} - -/* Class initialization function for the task page */ -static void -meeting_page_class_init (MeetingPageClass *class) -{ - CompEditorPageClass *editor_page_class; - GtkObjectClass *object_class; - - editor_page_class = (CompEditorPageClass *) class; - object_class = (GtkObjectClass *) class; - - parent_class = gtk_type_class (TYPE_COMP_EDITOR_PAGE); - - editor_page_class->get_widget = meeting_page_get_widget; - editor_page_class->focus_main_widget = meeting_page_focus_main_widget; - editor_page_class->fill_widgets = meeting_page_fill_widgets; - editor_page_class->fill_component = meeting_page_fill_component; - editor_page_class->set_summary = NULL; - editor_page_class->set_dates = NULL; - - object_class->destroy = meeting_page_destroy; -} - -/* Object initialization function for the task page */ -static void -meeting_page_init (MeetingPage *mpage) -{ - MeetingPagePrivate *priv; - - priv = g_new0 (MeetingPagePrivate, 1); - mpage->priv = priv; - - priv->deleted_attendees = g_ptr_array_new (); - - priv->comp = NULL; - - priv->xml = NULL; - priv->main = NULL; - priv->invite = NULL; - - priv->model = NULL; - priv->etable = NULL; - - priv->updating = FALSE; -} - -static void -set_attendees (CalComponent *comp, const GPtrArray *attendees) -{ - GSList *comp_attendees = NULL, *l; - int i; - - for (i = 0; i < attendees->len; i++) { - EMeetingAttendee *ia = g_ptr_array_index (attendees, i); - CalComponentAttendee *ca; - - ca = e_meeting_attendee_as_cal_component_attendee (ia); - - comp_attendees = g_slist_prepend (comp_attendees, ca); - - } - comp_attendees = g_slist_reverse (comp_attendees); - cal_component_set_attendee_list (comp, comp_attendees); - - for (l = comp_attendees; l != NULL; l = l->next) - g_free (l->data); - g_slist_free (comp_attendees); -} - -static void -cleanup_attendees (GPtrArray *attendees) -{ - int i; - - for (i = 0; i < attendees->len; i++) - gtk_object_unref (GTK_OBJECT (g_ptr_array_index (attendees, i))); -} - -/* Destroy handler for the task page */ -static void -meeting_page_destroy (GtkObject *object) -{ - MeetingPage *mpage; - MeetingPagePrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_MEETING_PAGE (object)); - - mpage = MEETING_PAGE (object); - priv = mpage->priv; - - if (priv->comp != NULL) - gtk_object_unref (GTK_OBJECT (priv->comp)); - - cleanup_attendees (priv->deleted_attendees); - g_ptr_array_free (priv->deleted_attendees, FALSE); - - itip_addresses_free (priv->addresses); - g_list_foreach (priv->address_strings, (GFunc) g_free, NULL); - g_list_free (priv->address_strings); - - gtk_object_unref (GTK_OBJECT (priv->model)); - - if (priv->xml) { - gtk_object_unref (GTK_OBJECT (priv->xml)); - priv->xml = NULL; - } - - g_free (priv); - mpage->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - - -/* get_widget handler for the task page */ -static GtkWidget * -meeting_page_get_widget (CompEditorPage *page) -{ - MeetingPage *mpage; - MeetingPagePrivate *priv; - - mpage = MEETING_PAGE (page); - priv = mpage->priv; - - return priv->main; -} - -/* focus_main_widget handler for the task page */ -static void -meeting_page_focus_main_widget (CompEditorPage *page) -{ - MeetingPage *mpage; - MeetingPagePrivate *priv; - - mpage = MEETING_PAGE (page); - priv = mpage->priv; - - gtk_widget_grab_focus (priv->organizer); -} - -/* Fills the widgets with default values */ -static void -clear_widgets (MeetingPage *mpage) -{ - MeetingPagePrivate *priv; - - priv = mpage->priv; - - gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (priv->organizer)->entry), ""); - gtk_entry_set_text (GTK_ENTRY (priv->other_organizer), ""); - gtk_label_set_text (GTK_LABEL (priv->existing_organizer), _("None")); - - gtk_widget_show (priv->organizer_table); - gtk_widget_hide (priv->existing_organizer_table); - - gtk_widget_hide (priv->other_organizer_lbl); - gtk_widget_hide (priv->other_organizer); - - priv->existing = FALSE; - priv->other = FALSE; -} - -/* fill_widgets handler for the meeting page */ -static void -meeting_page_fill_widgets (CompEditorPage *page, CalComponent *comp) -{ - MeetingPage *mpage; - MeetingPagePrivate *priv; - CalComponentOrganizer organizer; - GList *l; - - mpage = MEETING_PAGE (page); - priv = mpage->priv; - - priv->updating = TRUE; - - /* Clean out old data */ - if (priv->comp != NULL) - gtk_object_unref (GTK_OBJECT (priv->comp)); - priv->comp = NULL; - - cleanup_attendees (priv->deleted_attendees); - - /* Clean the screen */ - clear_widgets (mpage); - - /* Component for cancellation */ - priv->comp = cal_component_clone (comp); - - /* Organizer */ - cal_component_get_organizer (comp, &organizer); - priv->addresses = itip_addresses_get (); - for (l = priv->addresses; l != NULL; l = l->next) { - ItipAddress *a = l->data; - char *s; - - s = e_utf8_to_gtk_string (GTK_COMBO (priv->organizer)->entry, a->full); - priv->address_strings = g_list_append (priv->address_strings, s); - if (a->default_address) - priv->default_address = s; - } - gtk_combo_set_popdown_strings (GTK_COMBO (priv->organizer), priv->address_strings); - - if (organizer.value != NULL) { - const gchar *strip = itip_strip_mailto (organizer.value); - gchar *s, *string; - - gtk_widget_hide (priv->organizer_table); - gtk_widget_show (priv->existing_organizer_table); - gtk_widget_hide (priv->invite); - - if (organizer.cn != NULL) - string = g_strdup_printf ("%s <%s>", organizer.cn, strip); - else - string = g_strdup (strip); - s = e_utf8_to_gtk_string (priv->existing_organizer, string); - gtk_label_set_text (GTK_LABEL (priv->existing_organizer), s); - g_free (s); - g_free (string); - - priv->existing = TRUE; - } else { - gtk_widget_hide (priv->other_organizer_lbl); - gtk_widget_hide (priv->other_organizer); - - e_dialog_editable_set (GTK_COMBO (priv->organizer)->entry, priv->default_address); - } - - priv->updating = FALSE; -} - -/* fill_component handler for the meeting page */ -static gboolean -meeting_page_fill_component (CompEditorPage *page, CalComponent *comp) -{ - MeetingPage *mpage; - MeetingPagePrivate *priv; - CalComponentOrganizer organizer = {NULL, NULL, NULL, NULL}; - - mpage = MEETING_PAGE (page); - priv = mpage->priv; - - if (!priv->existing) { - gchar *addr = NULL, *cn = NULL; - GList *l; - - if (priv->other) { - addr = e_dialog_editable_get (priv->other_organizer); - } else { - gchar *str = e_dialog_editable_get (GTK_COMBO (priv->organizer)->entry); - for (l = priv->addresses; l != NULL; l = l->next) { - ItipAddress *a = l->data; - - if (!strcmp (a->full, str)) { - addr = g_strdup (a->address); - cn = g_strdup (a->name); - } - } - g_free (str); - } - - if (addr == NULL || strlen (addr) == 0) { - e_notice (NULL, GNOME_MESSAGE_BOX_ERROR, - _("An organizer is required.")); - g_free (addr); - g_free (cn); - return FALSE; - } else { - gchar *tmp; - - tmp = addr; - addr = g_strdup_printf ("MAILTO:%s", addr); - g_free (tmp); - } - - organizer.value = addr; - organizer.cn = cn; - cal_component_set_organizer (comp, &organizer); - g_free (addr); - g_free (cn); - } - - if (e_meeting_model_count_actual_attendees (priv->model) < 1) { - e_notice (NULL, GNOME_MESSAGE_BOX_ERROR, - _("At least one attendee is required.")); - return FALSE; - } - set_attendees (comp, e_meeting_model_get_attendees (priv->model)); - - return TRUE; -} - - - -/* Gets the widgets from the XML file and returns if they are all available. */ -static gboolean -get_widgets (MeetingPage *mpage) -{ - CompEditorPage *page = COMP_EDITOR_PAGE (mpage); - MeetingPagePrivate *priv; - GSList *accel_groups; - GtkWidget *toplevel; - - priv = mpage->priv; - -#define GW(name) glade_xml_get_widget (priv->xml, name) - - priv->main = GW ("meeting-page"); - if (!priv->main) - return FALSE; - - /* Get the GtkAccelGroup from the toplevel window, so we can install - it when the notebook page is mapped. */ - toplevel = gtk_widget_get_toplevel (priv->main); - accel_groups = gtk_accel_groups_from_object (GTK_OBJECT (toplevel)); - if (accel_groups) { - page->accel_group = accel_groups->data; - gtk_accel_group_ref (page->accel_group); - } - - gtk_widget_ref (priv->main); - gtk_widget_unparent (priv->main); - - priv->organizer_table = GW ("organizer-table"); - priv->organizer = GW ("organizer"); - priv->organizer_lbl = GW ("organizer-label"); - priv->other_organizer = GW ("other-organizer"); - priv->other_organizer_lbl = GW ("other-organizer-label"); - priv->other_organizer_btn = GW ("other-organizer-button"); - priv->existing_organizer_table = GW ("existing-organizer-table"); - priv->existing_organizer = GW ("existing-organizer"); - priv->existing_organizer_btn = GW ("existing-organizer-button"); - priv->invite = GW ("invite"); - -#undef GW - - return (priv->invite - && priv->organizer_table - && priv->organizer - && priv->organizer_lbl - && priv->other_organizer - && priv->other_organizer_lbl - && priv->other_organizer_btn - && priv->existing_organizer_table - && priv->existing_organizer - && priv->existing_organizer_btn); -} - -/* This is called when any field is changed; it notifies upstream. */ -static void -field_changed_cb (GtkWidget *widget, gpointer data) -{ - MeetingPage *mpage; - MeetingPagePrivate *priv; - - mpage = MEETING_PAGE (data); - priv = mpage->priv; - - if (!priv->updating) - comp_editor_page_notify_changed (COMP_EDITOR_PAGE (mpage)); -} - -/* Function called to make the organizer other than the user */ -static void -other_clicked_cb (GtkWidget *widget, gpointer data) -{ - MeetingPage *mpage; - MeetingPagePrivate *priv; - - mpage = MEETING_PAGE (data); - priv = mpage->priv; - - gtk_widget_hide (priv->organizer_lbl); - gtk_widget_hide (priv->organizer); - gtk_widget_hide (priv->other_organizer_btn); - gtk_widget_show (priv->other_organizer_lbl); - gtk_widget_show (priv->other_organizer); - - priv->other = TRUE; -} - -/* Function called to change the organizer */ -static void -change_clicked_cb (GtkWidget *widget, gpointer data) -{ - MeetingPage *mpage; - MeetingPagePrivate *priv; - - mpage = MEETING_PAGE (data); - priv = mpage->priv; - - gtk_widget_show (priv->organizer_table); - gtk_widget_hide (priv->existing_organizer_table); - gtk_widget_show (priv->invite); - - gtk_combo_set_popdown_strings (GTK_COMBO (priv->organizer), priv->address_strings); - e_dialog_editable_set (GTK_COMBO (priv->organizer)->entry, priv->default_address); - - priv->existing = FALSE; -} - -/* Function called to invite more people */ -static void -invite_cb (GtkWidget *widget, gpointer data) -{ - MeetingPage *mpage; - MeetingPagePrivate *priv; - - mpage = MEETING_PAGE (data); - priv = mpage->priv; - - e_meeting_model_invite_others_dialog (priv->model); -} - -/* Hooks the widget signals */ -static void -init_widgets (MeetingPage *mpage) -{ - MeetingPagePrivate *priv; - - priv = mpage->priv; - - /* Organizer */ - gtk_signal_connect (GTK_OBJECT (GTK_COMBO (priv->organizer)->entry), "changed", - GTK_SIGNAL_FUNC (field_changed_cb), mpage); - - gtk_signal_connect (GTK_OBJECT (priv->other_organizer_btn), "clicked", - GTK_SIGNAL_FUNC (other_clicked_cb), mpage); - gtk_signal_connect (GTK_OBJECT (priv->existing_organizer_btn), "clicked", - GTK_SIGNAL_FUNC (change_clicked_cb), mpage); - - /* Invite button */ - gtk_signal_connect (GTK_OBJECT (priv->invite), "clicked", - GTK_SIGNAL_FUNC (invite_cb), mpage); -} - -#if 0 -static void -popup_delegate_cb (GtkWidget *widget, gpointer data) -{ - MeetingPage *mpage = MEETING_PAGE (data); - MeetingPagePrivate *priv; - EDelegateDialog *edd; - GtkWidget *dialog; - EMeetingAttendee *ia; - char *address = NULL, *name = NULL; - - priv = mpage->priv; - - ia = e_meeting_model_find_attendee_at_row (priv->model, priv->row); - - /* Show dialog. */ - edd = e_delegate_dialog_new (NULL, itip_strip_mailto (e_meeting_attendee_get_delto (ia))); - dialog = e_delegate_dialog_get_toplevel (edd); - - if (gnome_dialog_run_and_close (GNOME_DIALOG (dialog)) == 0){ - EMeetingAttendee *ic; - - name = e_delegate_dialog_get_delegate_name (edd); - address = e_delegate_dialog_get_delegate (edd); - - /* Make sure we can add the new delegatee person */ - if (e_meeting_model_find_attendee (priv->model, address, NULL) != NULL) { - e_notice (NULL, GNOME_MESSAGE_BOX_ERROR, - _("That person is already attending the meeting!")); - goto cleanup; - } - - /* Update information for attendee */ - if (e_meeting_attendee_is_set_delto (ia)) { - EMeetingAttendee *ib; - - ib = e_meeting_model_find_attendee (priv->model, itip_strip_mailto (e_meeting_attendee_get_delto (ia)), NULL); - if (ib != NULL) { - gtk_object_ref (GTK_OBJECT (ib)); - g_ptr_array_add (priv->deleted_attendees, ib); - - e_meeting_model_remove_attendee (priv->model, ib); - } - } - e_meeting_attendee_set_delto (ia, g_strdup_printf ("MAILTO:%s", address)); - - /* Construct delegatee information */ - ic = e_meeting_model_add_attendee_with_defaults (priv->model); - - e_meeting_attendee_set_address (ic, g_strdup_printf ("MAILTO:%s", address)); - e_meeting_attendee_set_delfrom (ic, g_strdup (e_meeting_attendee_get_address (ia))); - e_meeting_attendee_set_cn (ic, g_strdup (name)); - } - - cleanup: - g_free (name); - g_free (address); - gtk_object_unref (GTK_OBJECT (edd)); -} -#endif - -static void -popup_delete_cb (GtkWidget *widget, gpointer data) -{ - MeetingPage *mpage = MEETING_PAGE (data); - MeetingPagePrivate *priv; - EMeetingAttendee *ia; - int pos = 0; - - priv = mpage->priv; - - ia = e_meeting_model_find_attendee_at_row (priv->model, priv->row); - - /* If this was a delegatee, no longer delegate */ - if (e_meeting_attendee_is_set_delfrom (ia)) { - EMeetingAttendee *ib; - - ib = e_meeting_model_find_attendee (priv->model, e_meeting_attendee_get_delfrom (ia), &pos); - if (ib != NULL) - e_meeting_attendee_set_delto (ib, NULL); - } - - /* Handle deleting all attendees in the delegation chain */ - while (ia != NULL) { - EMeetingAttendee *ib = NULL; - - gtk_object_ref (GTK_OBJECT (ia)); - g_ptr_array_add (priv->deleted_attendees, ia); - e_meeting_model_remove_attendee (priv->model, ia); - - if (e_meeting_attendee_get_delto (ia) != NULL) - ib = e_meeting_model_find_attendee (priv->model, e_meeting_attendee_get_delto (ia), NULL); - ia = ib; - } -} - -enum { - CAN_DELEGATE = 2, - CAN_DELETE = 4 -}; - -static EPopupMenu context_menu[] = { -#if 0 - E_POPUP_ITEM (N_("_Delegate To..."), GTK_SIGNAL_FUNC (popup_delegate_cb), CAN_DELEGATE), - - E_POPUP_SEPARATOR, -#endif - - E_POPUP_ITEM (N_("_Delete"), GTK_SIGNAL_FUNC (popup_delete_cb), CAN_DELETE), - - E_POPUP_TERMINATOR -}; - -/* handle context menu over message-list */ -static gint -right_click_cb (ETable *etable, gint row, gint col, GdkEvent *event, gpointer data) -{ - MeetingPage *mpage = MEETING_PAGE (data); - MeetingPagePrivate *priv; - GtkMenu *menu; - int enable_mask = 0, hide_mask = 0, view_row; - - priv = mpage->priv; - - view_row = e_table_model_to_view_row (etable, row); - priv->row = e_meeting_model_etable_view_to_model_row (etable, priv->model, view_row); - - /* FIXME: if you enable Delegate, then change index to '1' */ - context_menu[0].pixmap_widget = gnome_stock_new_with_icon (GNOME_STOCK_MENU_TRASH); - - menu = e_popup_menu_create (context_menu, enable_mask, hide_mask, data); - e_auto_kill_popup_menu_on_hide (menu); - - gtk_menu_popup (menu, NULL, NULL, NULL, NULL, - event->button.button, event->button.time); - - return TRUE; -} - - - -/* Callback used when the ETable gets a focus-out event. We have to commit any - * pending click-to-add state for if the event editor is being destroyed. - */ -static gint -table_canvas_focus_out_cb (GtkWidget *widget, GdkEventFocus *event, gpointer data) -{ - MeetingPage *mpage; - MeetingPagePrivate *priv; - ETable *etable; - - mpage = MEETING_PAGE (data); - priv = mpage->priv; - - etable = e_table_scrolled_get_table (priv->etable); - - e_table_commit_click_to_add (etable); - return TRUE; -} - -/** - * meeting_page_construct: - * @mpage: An task details page. - * - * Constructs an task page by loading its Glade data. - * - * Return value: The same object as @mpage, or NULL if the widgets could not - * be created. - **/ -MeetingPage * -meeting_page_construct (MeetingPage *mpage, EMeetingModel *emm) -{ - MeetingPagePrivate *priv; - ETable *real_table; - gchar *filename; - - priv = mpage->priv; - - priv->xml = glade_xml_new (EVOLUTION_GLADEDIR - "/meeting-page.glade", NULL); - if (!priv->xml) { - g_message ("meeting_page_construct(): " - "Could not load the Glade XML file!"); - return NULL; - } - - if (!get_widgets (mpage)) { - g_message ("meeting_page_construct(): " - "Could not find all widgets in the XML file!"); - return NULL; - } - - /* The etable displaying attendees and their status */ - gtk_object_ref (GTK_OBJECT (emm)); - priv->model = emm; - - filename = g_strdup_printf ("%s/config/et-header-meeting-page", evolution_dir); - priv->etable = e_meeting_model_etable_from_model (priv->model, - EVOLUTION_ETSPECDIR "/meeting-page.etspec", - filename); - g_free (filename); - - real_table = e_table_scrolled_get_table (priv->etable); - gtk_signal_connect (GTK_OBJECT (real_table), - "right_click", GTK_SIGNAL_FUNC (right_click_cb), mpage); - - gtk_signal_connect (GTK_OBJECT (real_table->table_canvas), "focus_out_event", - GTK_SIGNAL_FUNC (table_canvas_focus_out_cb), mpage); - - gtk_widget_show (GTK_WIDGET (priv->etable)); - gtk_box_pack_start (GTK_BOX (priv->main), GTK_WIDGET (priv->etable), TRUE, TRUE, 2); - - /* Init the widget signals */ - init_widgets (mpage); - - return mpage; -} - -/** - * meeting_page_new: - * - * Creates a new task details page. - * - * Return value: A newly-created task details page, or NULL if the page could - * not be created. - **/ -MeetingPage * -meeting_page_new (EMeetingModel *emm) -{ - MeetingPage *mpage; - - mpage = gtk_type_new (TYPE_MEETING_PAGE); - if (!meeting_page_construct (mpage, emm)) { - gtk_object_unref (GTK_OBJECT (mpage)); - return NULL; - } - - return mpage; -} - -/** - * meeting_page_get_cancel_comp: - * @mpage: - * - * - * - * Return value: - **/ -CalComponent * -meeting_page_get_cancel_comp (MeetingPage *mpage) -{ - MeetingPagePrivate *priv; - - g_return_val_if_fail (mpage != NULL, NULL); - g_return_val_if_fail (IS_MEETING_PAGE (mpage), NULL); - - priv = mpage->priv; - - if (priv->deleted_attendees->len == 0) - return NULL; - - set_attendees (priv->comp, priv->deleted_attendees); - - return cal_component_clone (priv->comp); -} diff --git a/calendar/gui/dialogs/meeting-page.etspec b/calendar/gui/dialogs/meeting-page.etspec deleted file mode 100644 index 96bc480fe9..0000000000 --- a/calendar/gui/dialogs/meeting-page.etspec +++ /dev/null @@ -1,21 +0,0 @@ -<ETableSpecification click-to-add="true" click-to-add-end="true" _click-to-add-message="Click here to add an attendee" draw-grid="true"> - <ETableColumn model_col= "0" _title="Attendee" expansion="2.0" minimum_width="10" resizable="true" cell="string" compare="string"/> - <ETableColumn model_col= "1" _title="Member" expansion="2.0" minimum_width="10" resizable="true" cell="string" compare="string"/> - <ETableColumn model_col= "2" _title="Type" expansion="1.0" minimum_width="10" resizable="true" cell="typeedit" compare="string"/> - <ETableColumn model_col= "3" _title="Role" expansion="1.0" minimum_width="10" resizable="true" cell="roleedit" compare="string"/> - <ETableColumn model_col= "4" _title="RSVP" expansion="1.0" minimum_width="10" resizable="true" cell="rsvpedit" compare="string"/> - <ETableColumn model_col= "5" _title="Delegated To" expansion="2.0" minimum_width="10" resizable="true" cell="string" compare="string"/> - <ETableColumn model_col= "6" _title="Delegated From" expansion="2.0" minimum_width="10" resizable="true" cell="string" compare="string"/> - <ETableColumn model_col= "7" _title="Status" expansion="1.0" minimum_width="10" resizable="true" cell="statusedit" compare="string"/> - <ETableColumn model_col= "8" _title="Common Name" expansion="2.0" minimum_width="10" resizable="true" cell="string" compare="string"/> - <ETableColumn model_col= "9" _title="Language" expansion="2.0" minimum_width="10" resizable="true" cell="string" compare="string"/> - - <ETableState> - <column source="0"/> - <column source="2"/> - <column source="3"/> - <column source="4"/> - <column source="7"/> - <grouping></grouping> - </ETableState> -</ETableSpecification> diff --git a/calendar/gui/dialogs/meeting-page.glade b/calendar/gui/dialogs/meeting-page.glade deleted file mode 100644 index f06f457d16..0000000000 --- a/calendar/gui/dialogs/meeting-page.glade +++ /dev/null @@ -1,306 +0,0 @@ -<?xml version="1.0"?> -<GTK-Interface> - -<project> - <name>task-details-page</name> - <program_name>task-details-page</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-toplevel</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>GtkVBox</class> - <name>meeting-page</name> - <border_width>4</border_width> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - - <widget> - <class>GtkVBox</class> - <name>vbox1</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - - <widget> - <class>GtkTable</class> - <name>organizer-table</name> - <border_width>4</border_width> - <rows>2</rows> - <columns>3</columns> - <homogeneous>False</homogeneous> - <row_spacing>0</row_spacing> - <column_spacing>4</column_spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkCombo</class> - <name>organizer</name> - <value_in_list>True</value_in_list> - <ok_if_empty>False</ok_if_empty> - <case_sensitive>False</case_sensitive> - <use_arrows>True</use_arrows> - <use_arrows_always>False</use_arrows_always> - <items></items> - <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> - <class>GtkEntry</class> - <child_name>GtkCombo:entry</child_name> - <name>entry2</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - </widget> - </widget> - - <widget> - <class>GtkButton</class> - <name>other-organizer-button</name> - <can_focus>True</can_focus> - <label>_Other Organizer</label> - <relief>GTK_RELIEF_NORMAL</relief> - <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>False</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>other-organizer</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>GtkLabel</class> - <name>organizer-label</name> - <label>Organizer:</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>other-organizer-label</name> - <label>Organizer:</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> - - <widget> - <class>GtkTable</class> - <name>existing-organizer-table</name> - <border_width>4</border_width> - <rows>1</rows> - <columns>3</columns> - <homogeneous>False</homogeneous> - <row_spacing>0</row_spacing> - <column_spacing>4</column_spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label1</name> - <label>Organizer:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</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>False</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkButton</class> - <name>existing-organizer-button</name> - <can_focus>True</can_focus> - <label>_Change Organizer</label> - <relief>GTK_RELIEF_NORMAL</relief> - <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>False</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>existing-organizer</name> - <label>None</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>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> - - <widget> - <class>Placeholder</class> - </widget> - - <widget> - <class>GtkButton</class> - <name>invite</name> - <can_focus>True</can_focus> - <label>_Invite Others...</label> - <relief>GTK_RELIEF_NORMAL</relief> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - <pack>GTK_PACK_END</pack> - </child> - </widget> - </widget> -</widget> - -</GTK-Interface> diff --git a/calendar/gui/dialogs/meeting-page.h b/calendar/gui/dialogs/meeting-page.h deleted file mode 100644 index b7c8571b44..0000000000 --- a/calendar/gui/dialogs/meeting-page.h +++ /dev/null @@ -1,64 +0,0 @@ -/* Evolution calendar - Main page of the task editor dialog - * - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * Miguel de Icaza <miguel@ximian.com> - * Seth Alves <alves@hungry.com> - * JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef MEETING_PAGE_H -#define MEETING_PAGE_H - -#include "../e-meeting-model.h" -#include "comp-editor-page.h" - -BEGIN_GNOME_DECLS - - - -#define TYPE_MEETING_PAGE (meeting_page_get_type ()) -#define MEETING_PAGE(obj) (GTK_CHECK_CAST ((obj), TYPE_MEETING_PAGE, MeetingPage)) -#define MEETING_PAGE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_MEETING_PAGE, MeetingPageClass)) -#define IS_MEETING_PAGE(obj) (GTK_CHECK_TYPE ((obj), TYPE_MEETING_PAGE)) -#define IS_MEETING_PAGE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), TYPE_MEETING_PAGE)) - -typedef struct _MeetingPagePrivate MeetingPagePrivate; - -typedef struct { - CompEditorPage page; - - /* Private data */ - MeetingPagePrivate *priv; -} MeetingPage; - -typedef struct { - CompEditorPageClass parent_class; -} MeetingPageClass; - - -GtkType meeting_page_get_type (void); -MeetingPage *meeting_page_construct (MeetingPage *mpage, - EMeetingModel *emm); -MeetingPage *meeting_page_new (EMeetingModel *emm); -CalComponent *meeting_page_get_cancel_comp (MeetingPage *mpage); - - - -END_GNOME_DECLS - -#endif diff --git a/calendar/gui/dialogs/recurrence-page.c b/calendar/gui/dialogs/recurrence-page.c deleted file mode 100644 index a096e403a8..0000000000 --- a/calendar/gui/dialogs/recurrence-page.c +++ /dev/null @@ -1,2446 +0,0 @@ -/* Evolution calendar - Recurrence page of the calendar component dialogs - * - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * Miguel de Icaza <miguel@ximian.com> - * Seth Alves <alves@hungry.com> - * JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtkoptionmenu.h> -#include <gtk/gtksignal.h> -#include <gtk/gtkspinbutton.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <glade/glade.h> -#include <gal/widgets/e-unicode.h> -#include <e-util/e-dialog-widgets.h> -#include <e-util/e-time-utils.h> -#include <widgets/misc/e-dateedit.h> -#include <cal-util/timeutil.h> -#include "../calendar-config.h" -#include "../tag-calendar.h" -#include "../weekday-picker.h" -#include "comp-editor-util.h" -#include "recurrence-page.h" - - - -enum month_num_options { - MONTH_NUM_FIRST, - MONTH_NUM_SECOND, - MONTH_NUM_THIRD, - MONTH_NUM_FOURTH, - MONTH_NUM_LAST, - MONTH_NUM_DAY, - MONTH_NUM_OTHER -}; - -static const int month_num_options_map[] = { - MONTH_NUM_FIRST, - MONTH_NUM_SECOND, - MONTH_NUM_THIRD, - MONTH_NUM_FOURTH, - MONTH_NUM_LAST, - MONTH_NUM_DAY, - MONTH_NUM_OTHER, - -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 -}; - -enum recur_type { - RECUR_NONE, - RECUR_SIMPLE, - RECUR_CUSTOM -}; - -static const int type_map[] = { - RECUR_NONE, - RECUR_SIMPLE, - RECUR_CUSTOM, - -1 -}; - -static const int freq_map[] = { - ICAL_DAILY_RECURRENCE, - ICAL_WEEKLY_RECURRENCE, - ICAL_MONTHLY_RECURRENCE, - ICAL_YEARLY_RECURRENCE, - -1 -}; - -enum ending_type { - ENDING_FOR, - ENDING_UNTIL, - ENDING_FOREVER -}; - -static const int ending_types_map[] = { - ENDING_FOR, - ENDING_UNTIL, - ENDING_FOREVER, - -1 -}; - -static const char *date_suffix[] = { - N_("st"), - N_("nd"), - N_("rd"), - N_("th"), - N_("th"), - N_("th"), - N_("th"), - N_("th"), - N_("th"), - N_("th"), - N_("th"), - N_("th"), - N_("th"), - N_("th"), - N_("th"), - N_("th"), - N_("th"), - N_("th"), - N_("th"), - N_("th"), - N_("st"), - N_("nd"), - N_("rd"), - N_("th"), - N_("th"), - N_("th"), - N_("th"), - N_("th"), - N_("th"), - N_("th"), - N_("st") -}; - -/* Private part of the RecurrencePage structure */ -struct _RecurrencePagePrivate { - /* Component we use to expand the recurrence rules for the preview */ - CalComponent *comp; - - /* Glade XML data */ - GladeXML *xml; - - /* Widgets from the Glade file */ - - GtkWidget *main; - - GtkWidget *summary; - GtkWidget *date_time; - - GtkWidget *none; - GtkWidget *simple; - GtkWidget *custom; - - GtkWidget *params; - GtkWidget *interval_value; - GtkWidget *interval_unit; - GtkWidget *special; - GtkWidget *ending_menu; - GtkWidget *ending_special; - GtkWidget *custom_warning_bin; - - /* For weekly recurrences, created by hand */ - GtkWidget *weekday_picker; - guint8 weekday_day_mask; - guint8 weekday_blocked_day_mask; - - /* For monthly recurrences, created by hand */ - int month_index; - - GtkWidget *month_day_menu; - enum month_day_options month_day; - - GtkWidget *month_num_menu; - enum month_num_options month_num; - - /* For ending date, created by hand */ - GtkWidget *ending_date_edit; - struct icaltimetype ending_date_tt; - - /* For ending count of occurrences, created by hand */ - GtkWidget *ending_count_spin; - int ending_count; - - /* More widgets from the Glade file */ - - GtkWidget *exception_date; - GtkWidget *exception_list; - GtkWidget *exception_add; - GtkWidget *exception_modify; - GtkWidget *exception_delete; - - GtkWidget *preview_bin; - - /* For the recurrence preview, the actual widget */ - GtkWidget *preview_calendar; - - gboolean updating; -}; - - - -static void recurrence_page_class_init (RecurrencePageClass *class); -static void recurrence_page_init (RecurrencePage *rpage); -static void recurrence_page_destroy (GtkObject *object); - -static GtkWidget *recurrence_page_get_widget (CompEditorPage *page); -static void recurrence_page_focus_main_widget (CompEditorPage *page); -static void recurrence_page_fill_widgets (CompEditorPage *page, CalComponent *comp); -static gboolean recurrence_page_fill_component (CompEditorPage *page, CalComponent *comp); -static void recurrence_page_set_summary (CompEditorPage *page, const char *summary); -static void recurrence_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates); - -static void field_changed (RecurrencePage *apage); - -static CompEditorPageClass *parent_class = NULL; - - - -/** - * recurrence_page_get_type: - * - * Registers the #RecurrencePage class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the #RecurrencePage class. - **/ -GtkType -recurrence_page_get_type (void) -{ - static GtkType recurrence_page_type; - - if (!recurrence_page_type) { - static const GtkTypeInfo recurrence_page_info = { - "RecurrencePage", - sizeof (RecurrencePage), - sizeof (RecurrencePageClass), - (GtkClassInitFunc) recurrence_page_class_init, - (GtkObjectInitFunc) recurrence_page_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - recurrence_page_type = gtk_type_unique (TYPE_COMP_EDITOR_PAGE, - &recurrence_page_info); - } - - return recurrence_page_type; -} - -/* Class initialization function for the recurrence page */ -static void -recurrence_page_class_init (RecurrencePageClass *class) -{ - CompEditorPageClass *editor_page_class; - GtkObjectClass *object_class; - - editor_page_class = (CompEditorPageClass *) class; - object_class = (GtkObjectClass *) class; - - parent_class = gtk_type_class (TYPE_COMP_EDITOR_PAGE); - - editor_page_class->get_widget = recurrence_page_get_widget; - editor_page_class->focus_main_widget = recurrence_page_focus_main_widget; - editor_page_class->fill_widgets = recurrence_page_fill_widgets; - editor_page_class->fill_component = recurrence_page_fill_component; - editor_page_class->set_summary = recurrence_page_set_summary; - editor_page_class->set_dates = recurrence_page_set_dates; - - object_class->destroy = recurrence_page_destroy; -} - -/* Object initialization function for the recurrence page */ -static void -recurrence_page_init (RecurrencePage *rpage) -{ - RecurrencePagePrivate *priv; - - priv = g_new0 (RecurrencePagePrivate, 1); - rpage->priv = priv; - - priv->xml = NULL; - - priv->main = NULL; - priv->summary = NULL; - priv->date_time = NULL; - priv->none = NULL; - priv->simple = NULL; - priv->custom = NULL; - priv->params = NULL; - priv->interval_value = NULL; - priv->interval_unit = NULL; - priv->special = NULL; - priv->ending_menu = NULL; - priv->ending_special = NULL; - priv->custom_warning_bin = NULL; - priv->weekday_picker = NULL; - priv->month_day_menu = NULL; - priv->month_num_menu = NULL; - priv->ending_date_edit = NULL; - priv->ending_count_spin = NULL; - priv->exception_date = NULL; - priv->exception_list = NULL; - priv->exception_add = NULL; - priv->exception_modify = NULL; - priv->exception_delete = NULL; - priv->preview_bin = NULL; - priv->preview_calendar = NULL; - - priv->comp = NULL; -} - -/* Frees the CalComponentDateTime stored in the GtkCList */ -static void -free_exception_date_time (CalComponentDateTime *dt) -{ - g_free (dt->value); - g_free ((char*)dt->tzid); - g_free (dt); -} - -/* Destroy handler for the recurrence page */ -static void -recurrence_page_destroy (GtkObject *object) -{ - RecurrencePage *rpage; - RecurrencePagePrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_RECURRENCE_PAGE (object)); - - rpage = RECURRENCE_PAGE (object); - priv = rpage->priv; - - if (priv->xml) { - gtk_object_unref (GTK_OBJECT (priv->xml)); - priv->xml = NULL; - } - - if (priv->comp) { - gtk_object_unref (GTK_OBJECT (priv->comp)); - priv->comp = NULL; - } - - g_free (priv); - rpage->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - - -/* get_widget handler for the recurrence page */ -static GtkWidget * -recurrence_page_get_widget (CompEditorPage *page) -{ - RecurrencePage *rpage; - RecurrencePagePrivate *priv; - - rpage = RECURRENCE_PAGE (page); - priv = rpage->priv; - - return priv->main; -} - -/* focus_main_widget handler for the recurrence page */ -static void -recurrence_page_focus_main_widget (CompEditorPage *page) -{ - RecurrencePage *rpage; - RecurrencePagePrivate *priv; - - rpage = RECURRENCE_PAGE (page); - priv = rpage->priv; - - if (e_dialog_toggle_get (priv->none)) - gtk_widget_grab_focus (priv->none); - else if (e_dialog_toggle_get (priv->simple)) - gtk_widget_grab_focus (priv->simple); - else if (e_dialog_toggle_get (priv->custom)) - gtk_widget_grab_focus (priv->custom); - else - g_assert_not_reached (); -} - -/* Fills the widgets with default values */ -static void -clear_widgets (RecurrencePage *rpage) -{ - RecurrencePagePrivate *priv; - GtkAdjustment *adj; - GtkWidget *menu; - - priv = rpage->priv; - - priv->weekday_day_mask = 0; - - priv->month_index = 1; - priv->month_num = MONTH_NUM_DAY; - priv->month_day = MONTH_DAY_NTH; - - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->none), rpage); - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->simple), rpage); - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->custom), rpage); - e_dialog_radio_set (priv->none, RECUR_NONE, type_map); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->none), rpage); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->simple), rpage); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->custom), rpage); - - adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->interval_value)); - gtk_signal_handler_block_by_data (GTK_OBJECT (adj), rpage); - e_dialog_spin_set (priv->interval_value, 1); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (adj), rpage); - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->interval_unit)); - gtk_signal_handler_block_by_data (GTK_OBJECT (menu), rpage); - e_dialog_option_menu_set (priv->interval_unit, - ICAL_DAILY_RECURRENCE, - freq_map); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), rpage); - - priv->ending_date_tt = icaltime_today (); - priv->ending_count = 1; - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->ending_menu)); - gtk_signal_handler_block_by_data (GTK_OBJECT (menu), rpage); - e_dialog_option_menu_set (priv->ending_menu, - ENDING_FOREVER, - ending_types_map); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), rpage); - - /* Exceptions list */ - gtk_clist_clear (GTK_CLIST (priv->exception_list)); -} - -/* Builds a static string out of an exception date */ -static char * -get_exception_string (CalComponentDateTime *dt) -{ - static char buf[256]; - struct tm tmp_tm; - - tmp_tm.tm_year = dt->value->year - 1900; - tmp_tm.tm_mon = dt->value->month - 1; - tmp_tm.tm_mday = dt->value->day; - tmp_tm.tm_hour = dt->value->hour; - tmp_tm.tm_min = dt->value->minute; - tmp_tm.tm_sec = dt->value->second; - tmp_tm.tm_isdst = -1; - - tmp_tm.tm_wday = time_day_of_week (dt->value->day, - dt->value->month - 1, - dt->value->year); - - e_time_format_date_and_time (&tmp_tm, calendar_config_get_24_hour_format(), FALSE, FALSE, buf, sizeof (buf)); - - return buf; -} - -/* Appends an exception date to the list */ -static void -append_exception (RecurrencePage *rpage, CalComponentDateTime *datetime) -{ - RecurrencePagePrivate *priv; - CalComponentDateTime *dt; - char *c[1]; - int i; - GtkCList *clist; - struct icaltimetype *tt; - - priv = rpage->priv; - - dt = g_new (CalComponentDateTime, 1); - dt->value = g_new (struct icaltimetype, 1); - *dt->value = *datetime->value; - dt->tzid = g_strdup (datetime->tzid); - - clist = GTK_CLIST (priv->exception_list); - - gtk_signal_handler_block_by_data (GTK_OBJECT (clist), rpage); - - c[0] = get_exception_string (dt); - i = gtk_clist_append (clist, c); - - gtk_clist_set_row_data_full (clist, i, dt, (GtkDestroyNotify) free_exception_date_time); - - gtk_clist_select_row (clist, i, 0); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (clist), rpage); - - tt = dt->value; - e_date_edit_set_date (E_DATE_EDIT (priv->exception_date), - tt->year, tt->month, tt->day); - e_date_edit_set_time_of_day (E_DATE_EDIT (priv->exception_date), - tt->hour, tt->minute); - - gtk_widget_set_sensitive (priv->exception_modify, TRUE); - gtk_widget_set_sensitive (priv->exception_delete, TRUE); -} - -/* Fills in the exception widgets with the data from the calendar component */ -static void -fill_exception_widgets (RecurrencePage *rpage, CalComponent *comp) -{ - RecurrencePagePrivate *priv; - GSList *list, *l; - gboolean added; - - priv = rpage->priv; - - cal_component_get_exdate_list (comp, &list); - - added = FALSE; - - for (l = list; l; l = l->next) { - CalComponentDateTime *cdt; - - added = TRUE; - - cdt = l->data; - append_exception (rpage, cdt); - } - - cal_component_free_exdate_list (list); - - if (added) - gtk_clist_select_row (GTK_CLIST (priv->exception_list), 0, 0); -} - -/* 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) { - short weekday; - - weekday = icaltime_day_of_week (*dt.value); - retval = 0x1 << (weekday - 1); - } 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_special_defaults (RecurrencePage *rpage) -{ - RecurrencePagePrivate *priv; - guint8 mask; - - priv = rpage->priv; - - mask = get_start_weekday_mask (priv->comp); - - priv->weekday_day_mask = mask; - priv->weekday_blocked_day_mask = mask; -} - -/* Sensitizes the recurrence widgets based on the state of the recurrence type - * radio group. - */ -static void -sensitize_recur_widgets (RecurrencePage *rpage) -{ - RecurrencePagePrivate *priv; - enum recur_type type; - GtkWidget *label; - - priv = rpage->priv; - - type = e_dialog_radio_get (priv->none, type_map); - - if (GTK_BIN (priv->custom_warning_bin)->child) - gtk_widget_destroy (GTK_BIN (priv->custom_warning_bin)->child); - - switch (type) { - case RECUR_NONE: - gtk_widget_set_sensitive (priv->params, FALSE); - gtk_widget_show (priv->params); - gtk_widget_hide (priv->custom_warning_bin); - break; - - case RECUR_SIMPLE: - gtk_widget_set_sensitive (priv->params, TRUE); - gtk_widget_show (priv->params); - gtk_widget_hide (priv->custom_warning_bin); - break; - - case RECUR_CUSTOM: - gtk_widget_set_sensitive (priv->params, FALSE); - gtk_widget_hide (priv->params); - - label = gtk_label_new (_("This appointment contains " - "recurrences that Evolution " - "cannot edit.")); - gtk_container_add (GTK_CONTAINER (priv->custom_warning_bin), - label); - gtk_widget_show_all (priv->custom_warning_bin); - break; - - default: - g_assert_not_reached (); - } -} - -#if 0 -/* Encondes a position/weekday pair into the proper format for - * icalrecurrencetype.by_day. Not needed at present. - */ -static short -nth_weekday (int pos, icalrecurrencetype_weekday weekday) -{ - g_assert (pos > 0 && pos <= 5); - - return (pos << 3) | (int) weekday; -} -#endif - -/* Gets the simple recurrence data from the recurrence widgets and stores it in - * the calendar component. - */ -static void -simple_recur_to_comp (RecurrencePage *rpage, CalComponent *comp) -{ - RecurrencePagePrivate *priv; - struct icalrecurrencetype r; - GSList l; - enum ending_type ending_type; - gboolean date_set; - - priv = rpage->priv; - - icalrecurrencetype_clear (&r); - - /* Frequency, interval, week start */ - - r.freq = e_dialog_option_menu_get (priv->interval_unit, freq_map); - r.interval = e_dialog_spin_get_int (priv->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->special)->child != NULL); - g_assert (priv->weekday_picker != NULL); - g_assert (IS_WEEKDAY_PICKER (priv->weekday_picker)); - - day_mask = weekday_picker_get_days (WEEKDAY_PICKER (priv->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: { - enum month_num_options month_num; - enum month_day_options month_day; - - g_assert (GTK_BIN (priv->special)->child != NULL); - g_assert (priv->month_day_menu != NULL); - g_assert (GTK_IS_OPTION_MENU (priv->month_day_menu)); - g_assert (priv->month_num_menu != NULL); - g_assert (GTK_IS_OPTION_MENU (priv->month_num_menu)); - - month_num = e_dialog_option_menu_get (priv->month_num_menu, - month_num_options_map ); - month_day = e_dialog_option_menu_get (priv->month_day_menu, - month_day_options_map); - - if (month_num == MONTH_NUM_LAST) - month_num = -1; - - switch (month_day) { - case MONTH_DAY_NTH: - if (month_num == -1) - r.by_month_day[0] = -1; - else - r.by_month_day[0] = priv->month_index; - break; - - /* Outlook 2000 uses BYDAY=TU;BYSETPOS=2, and will not - accept BYDAY=2TU. So we now use the same as Outlook - by default. */ - case MONTH_DAY_MON: - r.by_day[0] = ICAL_MONDAY_WEEKDAY; - r.by_set_pos[0] = month_num; - break; - - case MONTH_DAY_TUE: - r.by_day[0] = ICAL_TUESDAY_WEEKDAY; - r.by_set_pos[0] = month_num; - break; - - case MONTH_DAY_WED: - r.by_day[0] = ICAL_WEDNESDAY_WEEKDAY; - r.by_set_pos[0] = month_num; - break; - - case MONTH_DAY_THU: - r.by_day[0] = ICAL_THURSDAY_WEEKDAY; - r.by_set_pos[0] = month_num; - break; - - case MONTH_DAY_FRI: - r.by_day[0] = ICAL_FRIDAY_WEEKDAY; - r.by_set_pos[0] = month_num; - break; - - case MONTH_DAY_SAT: - r.by_day[0] = ICAL_SATURDAY_WEEKDAY; - r.by_set_pos[0] = month_num; - break; - - case MONTH_DAY_SUN: - r.by_day[0] = ICAL_SUNDAY_WEEKDAY; - r.by_set_pos[0] = month_num; - 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->ending_menu, - ending_types_map); - - switch (ending_type) { - case ENDING_FOR: - g_assert (priv->ending_count_spin != NULL); - g_assert (GTK_IS_SPIN_BUTTON (priv->ending_count_spin)); - - r.count = e_dialog_spin_get_int (priv->ending_count_spin); - break; - - case ENDING_UNTIL: - g_assert (priv->ending_date_edit != NULL); - g_assert (E_IS_DATE_EDIT (priv->ending_date_edit)); - - /* We only allow a DATE value to be set for the UNTIL property, - since we don't support sub-day recurrences. */ - date_set = e_date_edit_get_date (E_DATE_EDIT (priv->ending_date_edit), - &r.until.year, - &r.until.month, - &r.until.day); - g_assert (date_set); - - r.until.is_date = 1; - - 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); -} - -/* Fills a component with the data from the recurrence page; in the case of a - * custom recurrence, it leaves it intact. - */ -static void -fill_component (RecurrencePage *rpage, CalComponent *comp) -{ - RecurrencePagePrivate *priv; - enum recur_type recur_type; - GtkCList *exception_list; - GSList *list; - int i; - - priv = rpage->priv; - - recur_type = e_dialog_radio_get (priv->none, 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 (rpage, 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->exception_list); - for (i = 0; i < exception_list->rows; i++) { - CalComponentDateTime *cdt, *dt; - - cdt = g_new (CalComponentDateTime, 1); - cdt->value = g_new (struct icaltimetype, 1); - - dt = gtk_clist_get_row_data (exception_list, i); - g_assert (dt != NULL); - - *cdt->value = *dt->value; - cdt->tzid = g_strdup (dt->tzid); - -#if 0 - g_print ("Adding exception is_date: %i\n", cdt->value->is_date); -#endif - - list = g_slist_prepend (list, cdt); - } - - cal_component_set_exdate_list (comp, list); - cal_component_free_exdate_list (list); -} - -/* Re-tags the recurrence preview calendar based on the current information of - * the widgets in the recurrence page. - */ -static void -preview_recur (RecurrencePage *rpage) -{ - RecurrencePagePrivate *priv; - CalComponent *comp; - CalComponentDateTime cdt; - GSList *l; - - priv = rpage->priv; - - /* If our component has not been set yet through ::fill_widgets(), we - * cannot preview the recurrence. - */ - if (!priv->comp) - return; - - /* Create a scratch component with the start/end and - * recurrence/exception 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); - - fill_component (rpage, comp); - - tag_calendar_by_comp (E_CALENDAR (priv->preview_calendar), comp, - COMP_EDITOR_PAGE (rpage)->client, TRUE, FALSE); - gtk_object_unref (GTK_OBJECT (comp)); -} - -/* Callback used when the recurrence weekday picker changes */ -static void -weekday_picker_changed_cb (WeekdayPicker *wp, gpointer data) -{ - RecurrencePage *rpage; - - rpage = RECURRENCE_PAGE (data); - - field_changed (rpage); - preview_recur (rpage); -} - -/* Creates the special contents for weekly recurrences */ -static void -make_weekly_special (RecurrencePage *rpage) -{ - RecurrencePagePrivate *priv; - GtkWidget *hbox; - GtkWidget *label; - WeekdayPicker *wp; - - priv = rpage->priv; - - g_assert (GTK_BIN (priv->special)->child == NULL); - g_assert (priv->weekday_picker == NULL); - - /* Create the widgets */ - - hbox = gtk_hbox_new (FALSE, 2); - gtk_container_add (GTK_CONTAINER (priv->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->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->weekday_day_mask); - weekday_picker_set_blocked_days (wp, priv->weekday_blocked_day_mask); - - gtk_signal_connect (GTK_OBJECT (wp), "changed", - GTK_SIGNAL_FUNC (weekday_picker_changed_cb), - rpage); -} - - -static void -month_num_submenu_selection_done_cb (GtkMenuShell *menu_shell, gpointer data) -{ - GtkWidget *item; - int month_index; - - item = gtk_menu_get_active (GTK_MENU (menu_shell)); - item = gtk_menu_get_active (GTK_MENU (GTK_MENU_ITEM (item)->submenu)); - - month_index = GPOINTER_TO_INT (gtk_object_get_user_data (GTK_OBJECT (item))); - gtk_object_set_user_data (GTK_OBJECT (data), GINT_TO_POINTER (month_index)); -} - -/* Creates the option menu for the monthly recurrence number */ -static GtkWidget * -make_recur_month_num_submenu (const char *title, int start, int end) -{ - GtkWidget *submenu, *item; - int i; - - submenu = gtk_menu_new (); - for (i = start; i < end; i++) { - char *date; - - date = g_strdup_printf ("%d%s", i + 1, _(date_suffix[i])); - item = gtk_menu_item_new_with_label (date); - g_free (date); - gtk_menu_append (GTK_MENU (submenu), item); - gtk_object_set_user_data (GTK_OBJECT (item), GINT_TO_POINTER (i + 1)); - gtk_widget_show (item); - } - - item = gtk_menu_item_new_with_label (_(title)); - gtk_widget_show (item); - gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu); - - return item; -} - -static GtkWidget * -make_recur_month_num_menu (int month_index) -{ - static const char *options[] = { - N_("first"), - N_("second"), - N_("third"), - N_("fourth"), - N_("last") - }; - - GtkWidget *menu, *submenu, *item, *submenu_item; - GtkWidget *omenu; - char *date; - int i; - - menu = gtk_menu_new (); - - /* Relation */ - for (i = 0; i < sizeof (options) / sizeof (options[0]); i++) { - item = gtk_menu_item_new_with_label (_(options[i])); - gtk_menu_append (GTK_MENU (menu), item); - gtk_widget_show (item); - } - - /* Current date */ - date = g_strdup_printf ("%d%s", month_index, _(date_suffix[month_index - 1])); - item = gtk_menu_item_new_with_label (date); - g_free (date); - gtk_menu_append (GTK_MENU (menu), item); - gtk_widget_show (item); - - /* Other Submenu */ - submenu = gtk_menu_new (); - submenu_item = gtk_menu_item_new_with_label (_("Other Date")); - gtk_menu_append (GTK_MENU (menu), submenu_item); - gtk_widget_show (submenu_item); - - item = make_recur_month_num_submenu ("1st to 10th", 0, 10); - gtk_menu_append (GTK_MENU (submenu), item); - item = make_recur_month_num_submenu ("11th to 20th", 10, 20); - gtk_menu_append (GTK_MENU (submenu), item); - item = make_recur_month_num_submenu ("21st to 31st", 20, 31); - gtk_menu_append (GTK_MENU (submenu), item); - - gtk_menu_item_set_submenu (GTK_MENU_ITEM (submenu_item), submenu); - gtk_object_set_user_data (GTK_OBJECT (submenu_item), GINT_TO_POINTER (month_index)); - gtk_signal_connect (GTK_OBJECT (submenu), "selection_done", - GTK_SIGNAL_FUNC (month_num_submenu_selection_done_cb), - submenu_item); - - omenu = gtk_option_menu_new (); - gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu); - - return omenu; -} - -/* 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; -} - -static void -month_num_menu_selection_done_cb (GtkMenuShell *menu_shell, gpointer data) -{ - RecurrencePage *rpage; - RecurrencePagePrivate *priv; - enum month_num_options month_num; - enum month_day_options month_day; - - rpage = RECURRENCE_PAGE (data); - priv = rpage->priv; - - month_num = e_dialog_option_menu_get (priv->month_num_menu, - month_num_options_map); - month_day = e_dialog_option_menu_get (priv->month_day_menu, - month_day_options_map); - - if (month_num == MONTH_NUM_OTHER) { - GtkWidget *label, *item; - char *date; - - item = gtk_menu_get_active (GTK_MENU (menu_shell)); - priv->month_index = GPOINTER_TO_INT (gtk_object_get_user_data (GTK_OBJECT (item))); - - month_num = MONTH_NUM_DAY; - e_dialog_option_menu_set (priv->month_num_menu, month_num, month_num_options_map); - - label = GTK_BIN (priv->month_num_menu)->child; - date = g_strdup_printf ("%d%s", priv->month_index, _(date_suffix[priv->month_index - 1])); - gtk_label_set_text (GTK_LABEL (label), date); - g_free (date); - - e_dialog_option_menu_set (priv->month_num_menu, 0, month_num_options_map); - e_dialog_option_menu_set (priv->month_num_menu, month_num, month_num_options_map); - } - - if (month_num == MONTH_NUM_DAY && month_day != MONTH_DAY_NTH) - e_dialog_option_menu_set (priv->month_day_menu, - MONTH_DAY_NTH, - month_day_options_map); - else if (month_num != MONTH_NUM_DAY && month_num != MONTH_NUM_LAST && month_day == MONTH_DAY_NTH) - e_dialog_option_menu_set (priv->month_day_menu, - MONTH_DAY_MON, - month_num_options_map); - field_changed (rpage); - preview_recur (rpage); -} - -/* 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) -{ - RecurrencePage *rpage; - RecurrencePagePrivate *priv; - enum month_num_options month_num; - enum month_day_options month_day; - - rpage = RECURRENCE_PAGE (data); - priv = rpage->priv; - - month_num = e_dialog_option_menu_get (priv->month_num_menu, - month_num_options_map); - month_day = e_dialog_option_menu_get (priv->month_day_menu, - month_day_options_map); - if (month_day == MONTH_DAY_NTH && month_num != MONTH_NUM_LAST && month_num != MONTH_NUM_DAY) - e_dialog_option_menu_set (priv->month_num_menu, - MONTH_NUM_DAY, - month_num_options_map); - else if (month_day != MONTH_DAY_NTH && month_num == MONTH_NUM_DAY) - e_dialog_option_menu_set (priv->month_num_menu, - MONTH_NUM_FIRST, - month_num_options_map); - field_changed (rpage); - preview_recur (rpage); -} - -/* Callback used when the month index value changes. */ -static void -month_index_value_changed_cb (GtkAdjustment *adj, gpointer data) -{ - RecurrencePage *rpage; - - rpage = RECURRENCE_PAGE (data); - - field_changed (rpage); - preview_recur (rpage); -} - -/* Creates the special contents for monthly recurrences */ -static void -make_monthly_special (RecurrencePage *rpage) -{ - RecurrencePagePrivate *priv; - GtkWidget *hbox; - GtkWidget *label; - GtkAdjustment *adj; - GtkWidget *menu; - - priv = rpage->priv; - - g_assert (GTK_BIN (priv->special)->child == NULL); - g_assert (priv->month_day_menu == NULL); - - /* Create the widgets */ - - hbox = gtk_hbox_new (FALSE, 2); - gtk_container_add (GTK_CONTAINER (priv->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->month_num_menu = make_recur_month_num_menu (priv->month_index); - gtk_box_pack_start (GTK_BOX (hbox), priv->month_num_menu, - FALSE, FALSE, 0); - - priv->month_day_menu = make_recur_month_menu (); - gtk_box_pack_start (GTK_BOX (hbox), priv->month_day_menu, - FALSE, FALSE, 0); - - gtk_widget_show_all (hbox); - - /* Set the options */ - e_dialog_option_menu_set (priv->month_num_menu, - priv->month_num, - month_num_options_map); - e_dialog_option_menu_set (priv->month_day_menu, - priv->month_day, - month_day_options_map); - - gtk_signal_connect (GTK_OBJECT (adj), "value_changed", GTK_SIGNAL_FUNC (month_index_value_changed_cb), - rpage); - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->month_num_menu)); - gtk_signal_connect (GTK_OBJECT (menu), "selection_done", - GTK_SIGNAL_FUNC (month_num_menu_selection_done_cb), - rpage); - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->month_day_menu)); - gtk_signal_connect (GTK_OBJECT (menu), "selection_done", - GTK_SIGNAL_FUNC (month_day_menu_selection_done_cb), - rpage); -} - -/* 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 (RecurrencePage *rpage) -{ - RecurrencePagePrivate *priv; - icalrecurrencetype_frequency frequency; - - priv = rpage->priv; - - if (GTK_BIN (priv->special)->child != NULL) { - gtk_widget_destroy (GTK_BIN (priv->special)->child); - - priv->weekday_picker = NULL; - priv->month_day_menu = NULL; - } - if (priv->month_num_menu != NULL) { - gtk_widget_destroy (priv->month_num_menu); - priv->month_num_menu = NULL; - } - - frequency = e_dialog_option_menu_get (priv->interval_unit, freq_map); - - switch (frequency) { - case ICAL_DAILY_RECURRENCE: - gtk_widget_hide (priv->special); - break; - - case ICAL_WEEKLY_RECURRENCE: - make_weekly_special (rpage); - gtk_widget_show (priv->special); - break; - - case ICAL_MONTHLY_RECURRENCE: - make_monthly_special (rpage); - gtk_widget_show (priv->special); - break; - - case ICAL_YEARLY_RECURRENCE: - gtk_widget_hide (priv->special); - break; - - default: - g_assert_not_reached (); - } -} - -/* Counts the 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; -} - -/* Callback used when the ending-until date editor changes */ -static void -ending_until_changed_cb (EDateEdit *de, gpointer data) -{ - RecurrencePage *rpage; - - rpage = RECURRENCE_PAGE (data); - field_changed (rpage); - preview_recur (rpage); -} - -/* Creates the special contents for "ending until" (end date) recurrences */ -static void -make_ending_until_special (RecurrencePage *rpage) -{ - RecurrencePagePrivate *priv; - EDateEdit *de; - - priv = rpage->priv; - - g_assert (GTK_BIN (priv->ending_special)->child == NULL); - g_assert (priv->ending_date_edit == NULL); - - /* Create the widget */ - - priv->ending_date_edit = comp_editor_new_date_edit (TRUE, FALSE, - FALSE); - de = E_DATE_EDIT (priv->ending_date_edit); - - gtk_container_add (GTK_CONTAINER (priv->ending_special), - GTK_WIDGET (de)); - gtk_widget_show_all (GTK_WIDGET (de)); - - /* Set the value */ - - e_date_edit_set_date (de, priv->ending_date_tt.year, - priv->ending_date_tt.month, - priv->ending_date_tt.day); - - gtk_signal_connect (GTK_OBJECT (de), "changed", - GTK_SIGNAL_FUNC (ending_until_changed_cb), rpage); - - /* Make sure the EDateEdit widget uses our timezones to get the - current time. */ - e_date_edit_set_get_time_callback (de, - (EDateEditGetTimeCallback) comp_editor_get_current_time, - rpage, NULL); -} - -/* Callback used when the ending-count value changes */ -static void -ending_count_value_changed_cb (GtkAdjustment *adj, gpointer data) -{ - RecurrencePage *rpage; - - rpage = RECURRENCE_PAGE (data); - field_changed (rpage); - preview_recur (rpage); -} - -/* Creates the special contents for the occurrence count case */ -static void -make_ending_count_special (RecurrencePage *rpage) -{ - RecurrencePagePrivate *priv; - GtkWidget *hbox; - GtkWidget *label; - GtkAdjustment *adj; - - priv = rpage->priv; - - g_assert (GTK_BIN (priv->ending_special)->child == NULL); - g_assert (priv->ending_count_spin == NULL); - - /* Create the widgets */ - - hbox = gtk_hbox_new (FALSE, 2); - gtk_container_add (GTK_CONTAINER (priv->ending_special), hbox); - - adj = GTK_ADJUSTMENT (gtk_adjustment_new (1, 1, 10000, 1, 10, 10)); - priv->ending_count_spin = gtk_spin_button_new (adj, 1, 0); - gtk_box_pack_start (GTK_BOX (hbox), priv->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->ending_count_spin, priv->ending_count); - - gtk_signal_connect (GTK_OBJECT (adj), "value_changed", - GTK_SIGNAL_FUNC (ending_count_value_changed_cb), - rpage); -} - -/* 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_ending_special (RecurrencePage *rpage) -{ - RecurrencePagePrivate *priv; - enum ending_type ending_type; - - priv = rpage->priv; - - if (GTK_BIN (priv->ending_special)->child != NULL) { - gtk_widget_destroy (GTK_BIN (priv->ending_special)->child); - - priv->ending_date_edit = NULL; - priv->ending_count_spin = NULL; - } - - ending_type = e_dialog_option_menu_get (priv->ending_menu, - ending_types_map); - - switch (ending_type) { - case ENDING_FOR: - make_ending_count_special (rpage); - gtk_widget_show (priv->ending_special); - break; - - case ENDING_UNTIL: - make_ending_until_special (rpage); - gtk_widget_show (priv->ending_special); - break; - - case ENDING_FOREVER: - gtk_widget_hide (priv->ending_special); - break; - - default: - g_assert_not_reached (); - } -} - -/* Fills the recurrence ending date widgets with the values from the calendar - * component. - */ -static void -fill_ending_date (RecurrencePage *rpage, struct icalrecurrencetype *r) -{ - RecurrencePagePrivate *priv; - GtkWidget *menu; - - priv = rpage->priv; - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->ending_menu)); - gtk_signal_handler_block_by_data (GTK_OBJECT (menu), rpage); - - if (r->count == 0) { - if (r->until.year == 0) { - /* Forever */ - - e_dialog_option_menu_set (priv->ending_menu, - ENDING_FOREVER, - ending_types_map); - } else { - /* Ending date */ - - priv->ending_date_tt = r->until; - e_dialog_option_menu_set (priv->ending_menu, - ENDING_UNTIL, - ending_types_map); - } - } else { - /* Count of occurrences */ - - priv->ending_count = r->count; - e_dialog_option_menu_set (priv->ending_menu, - ENDING_FOR, - ending_types_map); - } - - gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), rpage); - - make_ending_special (rpage); -} - -/* fill_widgets handler for the recurrence page. 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 -recurrence_page_fill_widgets (CompEditorPage *page, CalComponent *comp) -{ - RecurrencePage *rpage; - RecurrencePagePrivate *priv; - CalComponentText text; - CompEditorPageDates dates; - 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; - - rpage = RECURRENCE_PAGE (page); - priv = rpage->priv; - - /* Keep a copy of the component so that we can expand the recurrence - * set for the preview. - */ - - if (priv->comp) - gtk_object_unref (GTK_OBJECT (priv->comp)); - - priv->comp = cal_component_clone (comp); - - /* Don't send off changes during this time */ - priv->updating = TRUE; - - /* Clean the page */ - clear_widgets (rpage); - - /* Summary */ - cal_component_get_summary (comp, &text); - recurrence_page_set_summary (page, text.value); - - /* Dates */ - comp_editor_dates (&dates, comp); - recurrence_page_set_dates (page, &dates); - comp_editor_free_dates (&dates); - - /* Exceptions */ - fill_exception_widgets (rpage, comp); - - /* Set up defaults for the special widgets */ - set_special_defaults (rpage); - - /* No recurrences? */ - - if (!cal_component_has_rdates (comp) - && !cal_component_has_rrules (comp) - && !cal_component_has_exrules (comp)) { - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->none), - rpage); - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->simple), - rpage); - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->custom), - rpage); - e_dialog_radio_set (priv->none, RECUR_NONE, type_map); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->none), - rpage); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->simple), - rpage); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->custom), - rpage); - - gtk_widget_set_sensitive (priv->custom, FALSE); - - sensitize_recur_widgets (rpage); - preview_recur (rpage); - - priv->updating = FALSE; - return; - } - - /* See if it is a custom set we don't support */ - - cal_component_get_rrule_list (comp, &rrule_list); - len = g_slist_length (rrule_list); - if (len > 1 - || cal_component_has_rdates (comp) - || cal_component_has_exrules (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->interval_unit)); - gtk_signal_handler_block_by_data (GTK_OBJECT (menu), rpage); - e_dialog_option_menu_set (priv->interval_unit, - ICAL_DAILY_RECURRENCE, - freq_map); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), rpage); - 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->weekday_day_mask = day_mask; - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->interval_unit)); - gtk_signal_handler_block_by_data (GTK_OBJECT (menu), rpage); - e_dialog_option_menu_set (priv->interval_unit, - ICAL_WEEKLY_RECURRENCE, - freq_map); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), rpage); - break; - } - - case ICAL_MONTHLY_RECURRENCE: - if (n_by_year_day != 0 - || n_by_week_no != 0 - || n_by_month != 0 - || n_by_set_pos > 1) - goto custom; - - if (n_by_month_day == 1) { - int nth; - - if (n_by_set_pos != 0) - goto custom; - - nth = r->by_month_day[0]; - if (nth < 1 && nth != -1) - goto custom; - - if (nth == -1) { - CalComponentDateTime dt; - - cal_component_get_dtstart (comp, &dt); - priv->month_index = dt.value->day; - priv->month_num = MONTH_NUM_LAST; - } else { - priv->month_index = nth; - priv->month_num = MONTH_NUM_DAY; - } - priv->month_day = MONTH_DAY_NTH; - - } else if (n_by_day == 1) { - enum icalrecurrencetype_weekday weekday; - int pos; - enum month_day_options month_day; - - /* Outlook 2000 uses BYDAY=TU;BYSETPOS=2, and will not - accept BYDAY=2TU. So we now use the same as Outlook - by default. */ - - weekday = icalrecurrencetype_day_day_of_week (r->by_day[0]); - pos = icalrecurrencetype_day_position (r->by_day[0]); - - if (pos == 0) { - if (n_by_set_pos != 1) - goto custom; - pos = r->by_set_pos[0]; - } else if (pos < 0) { - 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; - } - - if (pos == -1) - priv->month_num = MONTH_NUM_LAST; - else - priv->month_num = pos; - priv->month_day = month_day; - } else - goto custom; - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->interval_unit)); - gtk_signal_handler_block_by_data (GTK_OBJECT (menu), rpage); - e_dialog_option_menu_set (priv->interval_unit, - ICAL_MONTHLY_RECURRENCE, - freq_map); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), rpage); - 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->interval_unit)); - gtk_signal_handler_block_by_data (GTK_OBJECT (menu), rpage); - e_dialog_option_menu_set (priv->interval_unit, - ICAL_YEARLY_RECURRENCE, - freq_map); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), rpage); - break; - - default: - goto custom; - } - - /* If we got here it means it is a simple recurrence */ - - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->none), rpage); - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->simple), rpage); - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->custom), rpage); - e_dialog_radio_set (priv->simple, RECUR_SIMPLE, type_map); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->none), rpage); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->simple), rpage); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->custom), rpage); - - gtk_widget_set_sensitive (priv->custom, FALSE); - - sensitize_recur_widgets (rpage); - make_recurrence_special (rpage); - - adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->interval_value)); - gtk_signal_handler_block_by_data (GTK_OBJECT (adj), rpage); - e_dialog_spin_set (priv->interval_value, r->interval); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (adj), rpage); - - fill_ending_date (rpage, r); - - goto out; - - custom: - - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->none), rpage); - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->simple), rpage); - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->custom), rpage); - e_dialog_radio_set (priv->custom, RECUR_CUSTOM, type_map); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->none), rpage); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->simple), rpage); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->custom), rpage); - - gtk_widget_set_sensitive (priv->custom, TRUE); - sensitize_recur_widgets (rpage); - - out: - - cal_component_free_recur_list (rrule_list); - preview_recur (rpage); - - priv->updating = FALSE; -} - -/* fill_component handler for the recurrence page */ -static gboolean -recurrence_page_fill_component (CompEditorPage *page, CalComponent *comp) -{ - RecurrencePage *rpage; - - rpage = RECURRENCE_PAGE (page); - fill_component (rpage, comp); - - return TRUE; -} - -/* set_summary handler for the recurrence page */ -static void -recurrence_page_set_summary (CompEditorPage *page, const char *summary) -{ - RecurrencePage *rpage; - RecurrencePagePrivate *priv; - gchar *s; - - rpage = RECURRENCE_PAGE (page); - priv = rpage->priv; - - s = e_utf8_to_gtk_string (priv->summary, summary); - gtk_label_set_text (GTK_LABEL (priv->summary), s); - g_free (s); -} - -/* set_dates handler for the recurrence page */ -static void -recurrence_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates) -{ - RecurrencePage *rpage; - RecurrencePagePrivate *priv; - CalComponentDateTime dt; - struct icaltimetype icaltime; - guint8 mask; - - rpage = RECURRENCE_PAGE (page); - priv = rpage->priv; - - comp_editor_date_label (dates, priv->date_time); - - /* Copy the dates to our component */ - - if (!priv->comp) - return; - - dt.value = &icaltime; - - if (dates->start) { - icaltime = *dates->start->value; - dt.tzid = dates->start->tzid; - cal_component_set_dtstart (priv->comp, &dt); - } - - if (dates->end) { - icaltime = *dates->end->value; - dt.tzid = dates->end->tzid; - cal_component_set_dtend (priv->comp, &dt); - } - - /* Update the weekday picker if necessary */ - mask = get_start_weekday_mask (priv->comp); - if (mask == priv->weekday_blocked_day_mask) - return; - - priv->weekday_day_mask = priv->weekday_day_mask | mask; - priv->weekday_blocked_day_mask = mask; - - if (priv->weekday_picker != NULL) { - weekday_picker_set_days (WEEKDAY_PICKER (priv->weekday_picker), - priv->weekday_day_mask); - weekday_picker_set_blocked_days (WEEKDAY_PICKER (priv->weekday_picker), - priv->weekday_blocked_day_mask); - } - - /* Make sure the preview gets updated. */ - preview_recur (rpage); -} - - - -/* Gets the widgets from the XML file and returns if they are all available. */ -static gboolean -get_widgets (RecurrencePage *rpage) -{ - CompEditorPage *page = COMP_EDITOR_PAGE (rpage); - RecurrencePagePrivate *priv; - GSList *accel_groups; - GtkWidget *toplevel; - - priv = rpage->priv; - -#define GW(name) glade_xml_get_widget (priv->xml, name) - - priv->main = GW ("recurrence-page"); - if (!priv->main) - return FALSE; - - /* Get the GtkAccelGroup from the toplevel window, so we can install - it when the notebook page is mapped. */ - toplevel = gtk_widget_get_toplevel (priv->main); - accel_groups = gtk_accel_groups_from_object (GTK_OBJECT (toplevel)); - if (accel_groups) { - page->accel_group = accel_groups->data; - gtk_accel_group_ref (page->accel_group); - } - - gtk_widget_ref (priv->main); - gtk_widget_unparent (priv->main); - - priv->summary = GW ("summary"); - priv->date_time = GW ("date-time"); - - priv->none = GW ("none"); - priv->simple = GW ("simple"); - priv->custom = GW ("custom"); - priv->params = GW ("params"); - - priv->interval_value = GW ("interval-value"); - priv->interval_unit = GW ("interval-unit"); - priv->special = GW ("special"); - priv->ending_menu = GW ("ending-menu"); - priv->ending_special = GW ("ending-special"); - priv->custom_warning_bin = GW ("custom-warning-bin"); - - priv->exception_date = GW ("exception-date"); - priv->exception_list = GW ("exception-list"); - priv->exception_add = GW ("exception-add"); - priv->exception_modify = GW ("exception-modify"); - priv->exception_delete = GW ("exception-delete"); - - priv->preview_bin = GW ("preview-bin"); - -#undef GW - - return (priv->summary - && priv->date_time - && priv->none - && priv->simple - && priv->custom - && priv->params - && priv->interval_value - && priv->interval_unit - && priv->special - && priv->ending_menu - && priv->ending_special - && priv->custom_warning_bin - && priv->exception_date - && priv->exception_list - && priv->exception_add - && priv->exception_modify - && priv->exception_delete - && priv->preview_bin); -} - -/* Callback used when the displayed date range in the recurrence preview - * calendar changes. - */ -static void -preview_date_range_changed_cb (ECalendarItem *item, gpointer data) -{ - RecurrencePage *rpage; - - rpage = RECURRENCE_PAGE (data); - preview_recur (rpage); -} - -/* Callback used when one of the recurrence type radio buttons is toggled. We - * enable or disable the recurrence parameters. - */ -static void -type_toggled_cb (GtkToggleButton *toggle, gpointer data) -{ - RecurrencePage *rpage; - - rpage = RECURRENCE_PAGE (data); - - field_changed (rpage); - - if (toggle->active) { - sensitize_recur_widgets (rpage); - preview_recur (rpage); - } -} - -/* Callback used when the recurrence interval value spin button changes. */ -static void -interval_value_changed_cb (GtkAdjustment *adj, gpointer data) -{ - RecurrencePage *rpage; - - rpage = RECURRENCE_PAGE (data); - - field_changed (rpage); - preview_recur (rpage); -} - -/* Callback used when the recurrence interval option menu changes. We need to - * change the contents of the recurrence special widget. - */ -static void -interval_selection_done_cb (GtkMenuShell *menu_shell, gpointer data) -{ - RecurrencePage *rpage; - - rpage = RECURRENCE_PAGE (data); - - field_changed (rpage); - make_recurrence_special (rpage); - preview_recur (rpage); -} - -/* Callback used when the recurrence ending option menu changes. We need to - * change the contents of the ending special widget. - */ -static void -ending_selection_done_cb (GtkMenuShell *menu_shell, gpointer data) -{ - RecurrencePage *rpage; - - rpage = RECURRENCE_PAGE (data); - - field_changed (rpage); - make_ending_special (rpage); - preview_recur (rpage); -} - -/* Callback for the "add exception" button */ -static void -exception_add_cb (GtkWidget *widget, gpointer data) -{ - RecurrencePage *rpage; - RecurrencePagePrivate *priv; - CalComponentDateTime dt; - struct icaltimetype icaltime = icaltime_null_time (); - gboolean date_set; - - rpage = RECURRENCE_PAGE (data); - priv = rpage->priv; - - field_changed (rpage); - - dt.value = &icaltime; - - /* We use DATE values for exceptions, so we don't need a TZID. */ - dt.tzid = NULL; - icaltime.is_date = 1; - - date_set = e_date_edit_get_date (E_DATE_EDIT (priv->exception_date), - &icaltime.year, - &icaltime.month, - &icaltime.day); - g_assert (date_set); - - append_exception (rpage, &dt); - preview_recur (rpage); -} - -/* Callback for the "modify exception" button */ -static void -exception_modify_cb (GtkWidget *widget, gpointer data) -{ - RecurrencePage *rpage; - RecurrencePagePrivate *priv; - GtkCList *clist; - CalComponentDateTime *dt; - struct icaltimetype *tt; - int sel; - - rpage = RECURRENCE_PAGE (data); - priv = rpage->priv; - - clist = GTK_CLIST (priv->exception_list); - if (!clist->selection) - return; - - field_changed (rpage); - - sel = GPOINTER_TO_INT (clist->selection->data); - - dt = gtk_clist_get_row_data (clist, sel); - tt = dt->value; - e_date_edit_get_date (E_DATE_EDIT (priv->exception_date), - &tt->year, &tt->month, &tt->day); - tt->hour = 0; - tt->minute = 0; - tt->second = 0; - tt->is_date = 1; - - /* We get rid of any old TZID, since we are using a DATE value now. */ - g_free ((char*)dt->tzid); - dt->tzid = NULL; - - gtk_clist_set_text (clist, sel, 0, get_exception_string (dt)); - - preview_recur (rpage); -} - -/* Callback for the "delete exception" button */ -static void -exception_delete_cb (GtkWidget *widget, gpointer data) -{ - RecurrencePage *rpage; - RecurrencePagePrivate *priv; - GtkCList *clist; - int sel; - - rpage = RECURRENCE_PAGE (data); - priv = rpage->priv; - - clist = GTK_CLIST (priv->exception_list); - if (!clist->selection) - return; - - field_changed (rpage); - - sel = GPOINTER_TO_INT (clist->selection->data); - - 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->exception_modify, FALSE); - gtk_widget_set_sensitive (priv->exception_delete, FALSE); - } - - preview_recur (rpage); -} - -/* Callback used when a row is selected in the list of exception - * dates. We must update the date/time widgets to reflect the - * exception's value. - */ -static void -exception_select_row_cb (GtkCList *clist, gint row, gint col, - GdkEvent *event, gpointer data) -{ - RecurrencePage *rpage; - RecurrencePagePrivate *priv; - CalComponentDateTime *dt; - struct icaltimetype *t; - - rpage = RECURRENCE_PAGE (data); - priv = rpage->priv; - - /* Sometimes GtkCList emits a 'row-selected' signal for row 0 when - there are 0 rows in the list (after you delete the last row). - So we check that the row is valid here. */ - if (row >= clist->rows) - return; - - dt = gtk_clist_get_row_data (clist, row); - g_assert (dt != NULL); - - t = dt->value; - - e_date_edit_set_date (E_DATE_EDIT (priv->exception_date), - t->year, t->month, t->day); - e_date_edit_set_time_of_day (E_DATE_EDIT (priv->exception_date), - t->hour, t->minute); -} - -/* This is called when any field is changed; it notifies upstream. */ -static void -field_changed (RecurrencePage *rpage) -{ - RecurrencePagePrivate *priv; - - priv = rpage->priv; - - if (!priv->updating) - comp_editor_page_notify_changed (COMP_EDITOR_PAGE (rpage)); -} - -/* Hooks the widget signals */ -static void -init_widgets (RecurrencePage *rpage) -{ - RecurrencePagePrivate *priv; - ECalendar *ecal; - GtkAdjustment *adj; - GtkWidget *menu; - - priv = rpage->priv; - - /* Recurrence preview */ - - priv->preview_calendar = e_calendar_new (); - ecal = E_CALENDAR (priv->preview_calendar); - gtk_signal_connect (GTK_OBJECT (ecal->calitem), "date_range_changed", - GTK_SIGNAL_FUNC (preview_date_range_changed_cb), - rpage); - calendar_config_configure_e_calendar (ecal); - e_calendar_item_set_max_days_sel (ecal->calitem, 0); - gtk_container_add (GTK_CONTAINER (priv->preview_bin), - priv->preview_calendar); - gtk_widget_show (priv->preview_calendar); - - /* Make sure the EDateEdit widgets and ECalendarItem use our timezones - to get the current time. */ - e_date_edit_set_show_time (E_DATE_EDIT (priv->exception_date), FALSE); - e_date_edit_set_get_time_callback (E_DATE_EDIT (priv->exception_date), - (EDateEditGetTimeCallback) comp_editor_get_current_time, - rpage, NULL); - e_calendar_item_set_get_time_callback (ecal->calitem, - (ECalendarItemGetTimeCallback) comp_editor_get_current_time, - rpage, NULL); - - /* Recurrence types */ - - gtk_signal_connect (GTK_OBJECT (priv->none), "toggled", - GTK_SIGNAL_FUNC (type_toggled_cb), rpage); - gtk_signal_connect (GTK_OBJECT (priv->simple), "toggled", - GTK_SIGNAL_FUNC (type_toggled_cb), rpage); - gtk_signal_connect (GTK_OBJECT (priv->custom), "toggled", - GTK_SIGNAL_FUNC (type_toggled_cb), rpage); - - /* Recurrence interval */ - - adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->interval_value)); - gtk_signal_connect (GTK_OBJECT (adj), "value_changed", - GTK_SIGNAL_FUNC (interval_value_changed_cb), - rpage); - - /* Recurrence units */ - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->interval_unit)); - gtk_signal_connect (GTK_OBJECT (menu), "selection_done", - GTK_SIGNAL_FUNC (interval_selection_done_cb), - rpage); - - /* Recurrence ending */ - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->ending_menu)); - gtk_signal_connect (GTK_OBJECT (menu), "selection_done", - GTK_SIGNAL_FUNC (ending_selection_done_cb), rpage); - - /* Exception buttons */ - - gtk_signal_connect (GTK_OBJECT (priv->exception_add), "clicked", - GTK_SIGNAL_FUNC (exception_add_cb), rpage); - gtk_signal_connect (GTK_OBJECT (priv->exception_modify), "clicked", - GTK_SIGNAL_FUNC (exception_modify_cb), rpage); - gtk_signal_connect (GTK_OBJECT (priv->exception_delete), "clicked", - GTK_SIGNAL_FUNC (exception_delete_cb), rpage); - - /* Selections in the exceptions list */ - - gtk_signal_connect (GTK_OBJECT (priv->exception_list), "select_row", - GTK_SIGNAL_FUNC (exception_select_row_cb), rpage); -} - - - -/** - * recurrence_page_construct: - * @rpage: A recurrence page. - * - * Constructs a recurrence page by loading its Glade data. - * - * Return value: The same object as @rpage, or NULL if the widgets could not be - * created. - **/ -RecurrencePage * -recurrence_page_construct (RecurrencePage *rpage) -{ - RecurrencePagePrivate *priv; - - priv = rpage->priv; - - priv->xml = glade_xml_new (EVOLUTION_GLADEDIR - "/recurrence-page.glade", NULL); - if (!priv->xml) { - g_message ("recurrence_page_construct(): " - "Could not load the Glade XML file!"); - return NULL; - } - - if (!get_widgets (rpage)) { - g_message ("recurrence_page_construct(): " - "Could not find all widgets in the XML file!"); - return NULL; - } - - init_widgets (rpage); - - return rpage; -} - -/** - * recurrence_page_new: - * - * Creates a new recurrence page. - * - * Return value: A newly-created recurrence page, or NULL if the page could not - * be created. - **/ -RecurrencePage * -recurrence_page_new (void) -{ - RecurrencePage *rpage; - - rpage = gtk_type_new (TYPE_RECURRENCE_PAGE); - if (!recurrence_page_construct (rpage)) { - gtk_object_unref (GTK_OBJECT (rpage)); - return NULL; - } - - return rpage; -} - - -GtkWidget *make_exdate_date_edit (void); - -GtkWidget * -make_exdate_date_edit (void) -{ - return comp_editor_new_date_edit (TRUE, TRUE, FALSE); -} - diff --git a/calendar/gui/dialogs/recurrence-page.glade b/calendar/gui/dialogs/recurrence-page.glade deleted file mode 100644 index a044a771aa..0000000000 --- a/calendar/gui/dialogs/recurrence-page.glade +++ /dev/null @@ -1,602 +0,0 @@ -<?xml version="1.0"?> -<GTK-Interface> - -<project> - <name>recurrence-page</name> - <program_name>recurrence-page</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>GtkWindow</class> - <name>recurrence-toplevel</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>GtkVBox</class> - <name>recurrence-page</name> - <border_width>4</border_width> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - - <widget> - <class>GtkFrame</class> - <name>frame35</name> - <label>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>Summary:</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>label67</name> - <label>Date/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>GtkLabel</class> - <name>summary</name> - <width>10</width> - <label></label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>4</xpad> - <ypad>0</ypad> - <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>GtkLabel</class> - <name>date-time</name> - <width>10</width> - <label></label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>4</xpad> - <ypad>0</ypad> - <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> - <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>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>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>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>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>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>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>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>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>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>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>exception-add</name> - <can_focus>True</can_focus> - <label>A_dd</label> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkButton</class> - <name>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>exception-delete</name> - <can_focus>True</can_focus> - <label>_Remove</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>exception-date</name> - <creation_function>make_exdate_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>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>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> - -</GTK-Interface> diff --git a/calendar/gui/dialogs/recurrence-page.h b/calendar/gui/dialogs/recurrence-page.h deleted file mode 100644 index 29395f586f..0000000000 --- a/calendar/gui/dialogs/recurrence-page.h +++ /dev/null @@ -1,61 +0,0 @@ -/* Evolution calendar - Recurrence page of the calendar component dialogs - * - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * Miguel de Icaza <miguel@ximian.com> - * Seth Alves <alves@hungry.com> - * JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef RECURRENCE_PAGE_H -#define RECURRENCE_PAGE_H - -#include "comp-editor-page.h" - -BEGIN_GNOME_DECLS - - - -#define TYPE_RECURRENCE_PAGE (recurrence_page_get_type ()) -#define RECURRENCE_PAGE(obj) (GTK_CHECK_CAST ((obj), TYPE_RECURRENCE_PAGE, RecurrencePage)) -#define RECURRENCE_PAGE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_RECURRENCE_PAGE, RecurrencePageClass)) -#define IS_RECURRENCE_PAGE(obj) (GTK_CHECK_TYPE ((obj), TYPE_RECURRENCE_PAGE)) -#define IS_RECURRENCE_PAGE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), TYPE_RECURRENCE_PAGE)) - -typedef struct _RecurrencePagePrivate RecurrencePagePrivate; - -typedef struct { - CompEditorPage page; - - /* Private data */ - RecurrencePagePrivate *priv; -} RecurrencePage; - -typedef struct { - CompEditorPageClass parent_class; -} RecurrencePageClass; - - -GtkType recurrence_page_get_type (void); -RecurrencePage *recurrence_page_construct (RecurrencePage *rpage); -RecurrencePage *recurrence_page_new (void); - - - -END_GNOME_DECLS - -#endif diff --git a/calendar/gui/dialogs/save-comp.c b/calendar/gui/dialogs/save-comp.c deleted file mode 100644 index 67a43a7320..0000000000 --- a/calendar/gui/dialogs/save-comp.c +++ /dev/null @@ -1,62 +0,0 @@ -/* Evolution calendar - Delete calendar component dialog - * - * Copyright (C) 2000 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#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 7090464a4e..0000000000 --- a/calendar/gui/dialogs/save-comp.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Evolution calendar - Delete calendar component dialog - * - * Copyright (C) 2000 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef SAVE_COMP_H -#define SAVE_COMP_H - -#include <gtk/gtkwindow.h> - -gint save_component_dialog (GtkWindow *parent); - -#endif diff --git a/calendar/gui/dialogs/schedule-page.c b/calendar/gui/dialogs/schedule-page.c deleted file mode 100644 index 6ae7924355..0000000000 --- a/calendar/gui/dialogs/schedule-page.c +++ /dev/null @@ -1,542 +0,0 @@ -/* Evolution calendar - Scheduling page - * - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * Miguel de Icaza <miguel@ximian.com> - * Seth Alves <alves@hungry.com> - * JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <glib.h> -#include <gtk/gtksignal.h> -#include <gtk/gtktogglebutton.h> -#include <gtk/gtkvbox.h> -#include <gtk/gtkwindow.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <libgnomeui/gnome-stock.h> -#include <libgnomeui/gnome-dialog-util.h> -#include <glade/glade.h> -#include <gal/e-table/e-cell-combo.h> -#include <gal/e-table/e-cell-text.h> -#include <gal/e-table/e-table-simple.h> -#include <gal/e-table/e-table-scrolled.h> -#include <gal/widgets/e-unicode.h> -#include <gal/widgets/e-popup-menu.h> -#include <gal/widgets/e-gui-utils.h> -#include <widgets/misc/e-dateedit.h> -#include <e-util/e-dialog-widgets.h> -#include "../calendar-config.h" -#include "../e-meeting-time-sel.h" -#include "../itip-utils.h" -#include "comp-editor-util.h" -#include "e-delegate-dialog.h" -#include "schedule-page.h" - - - -/* Private part of the SchedulePage structure */ -struct _SchedulePagePrivate { - /* Glade XML data */ - GladeXML *xml; - - /* Widgets from the Glade file */ - GtkWidget *main; - - /* Model */ - EMeetingModel *model; - - /* Selector */ - EMeetingTimeSelector *sel; - - /* The timezone we use. Note that we use the same timezone for the - start and end date. We convert the end date if it is passed in in - another timezone. */ - icaltimezone *zone; - - gboolean updating; -}; - - - -static void schedule_page_class_init (SchedulePageClass *class); -static void schedule_page_init (SchedulePage *spage); -static void schedule_page_destroy (GtkObject *object); - -static GtkWidget *schedule_page_get_widget (CompEditorPage *page); -static void schedule_page_focus_main_widget (CompEditorPage *page); -static void schedule_page_fill_widgets (CompEditorPage *page, CalComponent *comp); -static gboolean schedule_page_fill_component (CompEditorPage *page, CalComponent *comp); -static void schedule_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates); - -static void times_changed_cb (GtkWidget *widget, gpointer data); - -static CompEditorPageClass *parent_class = NULL; - - - -/** - * schedule_page_get_type: - * - * Registers the #SchedulePage class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the #SchedulePage class. - **/ -GtkType -schedule_page_get_type (void) -{ - static GtkType schedule_page_type; - - if (!schedule_page_type) { - static const GtkTypeInfo schedule_page_info = { - "SchedulePage", - sizeof (SchedulePage), - sizeof (SchedulePageClass), - (GtkClassInitFunc) schedule_page_class_init, - (GtkObjectInitFunc) schedule_page_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - schedule_page_type = - gtk_type_unique (TYPE_COMP_EDITOR_PAGE, - &schedule_page_info); - } - - return schedule_page_type; -} - -/* Class initialization function for the schedule page */ -static void -schedule_page_class_init (SchedulePageClass *class) -{ - CompEditorPageClass *editor_page_class; - GtkObjectClass *object_class; - - editor_page_class = (CompEditorPageClass *) class; - object_class = (GtkObjectClass *) class; - - parent_class = gtk_type_class (TYPE_COMP_EDITOR_PAGE); - - editor_page_class->get_widget = schedule_page_get_widget; - editor_page_class->focus_main_widget = schedule_page_focus_main_widget; - editor_page_class->fill_widgets = schedule_page_fill_widgets; - editor_page_class->fill_component = schedule_page_fill_component; - editor_page_class->set_summary = NULL; - editor_page_class->set_dates = schedule_page_set_dates; - - object_class->destroy = schedule_page_destroy; -} - -/* Object initialization function for the schedule page */ -static void -schedule_page_init (SchedulePage *spage) -{ - SchedulePagePrivate *priv; - - priv = g_new0 (SchedulePagePrivate, 1); - spage->priv = priv; - - priv->xml = NULL; - - priv->main = NULL; - - priv->zone = NULL; - - priv->updating = FALSE; -} - -/* Destroy handler for the schedule page */ -static void -schedule_page_destroy (GtkObject *object) -{ - SchedulePage *spage; - SchedulePagePrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_SCHEDULE_PAGE (object)); - - spage = SCHEDULE_PAGE (object); - priv = spage->priv; - - if (priv->xml) { - gtk_object_unref (GTK_OBJECT (priv->xml)); - priv->xml = NULL; - } - - gtk_object_unref (GTK_OBJECT (priv->model)); - - g_free (priv); - spage->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - - -/* get_widget handler for the schedule page */ -static GtkWidget * -schedule_page_get_widget (CompEditorPage *page) -{ - SchedulePage *spage; - SchedulePagePrivate *priv; - - spage = SCHEDULE_PAGE (page); - priv = spage->priv; - - return priv->main; -} - -/* focus_main_widget handler for the schedule page */ -static void -schedule_page_focus_main_widget (CompEditorPage *page) -{ - SchedulePage *spage; - SchedulePagePrivate *priv; - - spage = SCHEDULE_PAGE (page); - priv = spage->priv; - - gtk_widget_grab_focus (GTK_WIDGET (priv->sel)); -} - -/* Set date/time */ -static void -update_time (SchedulePage *spage, CalComponentDateTime *start_date, CalComponentDateTime *end_date) -{ - SchedulePagePrivate *priv; - struct icaltimetype start_tt, end_tt; - icaltimezone *start_zone = NULL, *end_zone = NULL; - CalClientGetStatus status; - gboolean all_day; - - priv = spage->priv; - - /* Note that if we are creating a new event, the timezones may not be - on the server, so we try to get the builtin timezone with the TZID - first. */ - start_zone = icaltimezone_get_builtin_timezone_from_tzid (start_date->tzid); - if (!start_zone) { - status = cal_client_get_timezone (COMP_EDITOR_PAGE (spage)->client, - start_date->tzid, - &start_zone); - /* FIXME: Handle error better. */ - if (status != CAL_CLIENT_GET_SUCCESS) - g_warning ("Couldn't get timezone from server: %s", - start_date->tzid ? start_date->tzid : ""); - } - - end_zone = icaltimezone_get_builtin_timezone_from_tzid (end_date->tzid); - if (!end_zone) { - status = cal_client_get_timezone (COMP_EDITOR_PAGE (spage)->client, - end_date->tzid, - &end_zone); - /* FIXME: Handle error better. */ - if (status != CAL_CLIENT_GET_SUCCESS) - g_warning ("Couldn't get timezone from server: %s", - end_date->tzid ? end_date->tzid : ""); - } - - start_tt = *start_date->value; - end_tt = *end_date->value; - - /* If the end zone is not the same as the start zone, we convert it. */ - priv->zone = start_zone; - if (start_zone != end_zone) { - icaltimezone_convert_time (&end_tt, end_zone, start_zone); - } - e_meeting_model_set_zone (priv->model, priv->zone); - - all_day = (start_tt.is_date && end_tt.is_date) ? TRUE : FALSE; - - /* For All Day Events, if DTEND is after DTSTART, we subtract 1 day - from it. */ - if (all_day) { - if (icaltime_compare_date_only (end_tt, start_tt) > 0) { - icaltime_adjust (&end_tt, -1, 0, 0, 0); - } - } - - e_meeting_time_selector_set_all_day (priv->sel, all_day); - - e_date_edit_set_date (E_DATE_EDIT (priv->sel->start_date_edit), start_tt.year, - start_tt.month, start_tt.day); - e_date_edit_set_time_of_day (E_DATE_EDIT (priv->sel->start_date_edit), - start_tt.hour, start_tt.minute); - - e_date_edit_set_date (E_DATE_EDIT (priv->sel->end_date_edit), end_tt.year, - end_tt.month, end_tt.day); - e_date_edit_set_time_of_day (E_DATE_EDIT (priv->sel->end_date_edit), - end_tt.hour, end_tt.minute); - -} - - -/* Fills the widgets with default values */ -static void -clear_widgets (SchedulePage *spage) -{ - SchedulePagePrivate *priv; - - priv = spage->priv; -} - -/* fill_widgets handler for the schedule page */ -static void -schedule_page_fill_widgets (CompEditorPage *page, CalComponent *comp) -{ - SchedulePage *spage; - SchedulePagePrivate *priv; - CalComponentDateTime start_date, end_date; - - spage = SCHEDULE_PAGE (page); - priv = spage->priv; - - priv->updating = TRUE; - - /* Clean the screen */ - clear_widgets (spage); - - /* Start and end times */ - cal_component_get_dtstart (comp, &start_date); - cal_component_get_dtend (comp, &end_date); - update_time (spage, &start_date, &end_date); - - cal_component_free_datetime (&start_date); - cal_component_free_datetime (&end_date); - - priv->updating = FALSE; -} - -/* fill_component handler for the schedule page */ -static gboolean -schedule_page_fill_component (CompEditorPage *page, CalComponent *comp) -{ - SchedulePage *spage; - SchedulePagePrivate *priv; - - spage = SCHEDULE_PAGE (page); - priv = spage->priv; - - return TRUE; -} - -static void -schedule_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates) -{ - SchedulePage *spage; - SchedulePagePrivate *priv; - - spage = SCHEDULE_PAGE (page); - priv = spage->priv; - - priv->updating = TRUE; - - update_time (spage, dates->start, dates->end); - - priv->updating = FALSE; -} - - - -/* Gets the widgets from the XML file and returns if they are all available. */ -static gboolean -get_widgets (SchedulePage *spage) -{ - CompEditorPage *page = COMP_EDITOR_PAGE (spage); - SchedulePagePrivate *priv; - GSList *accel_groups; - GtkWidget *toplevel; - - priv = spage->priv; - -#define GW(name) glade_xml_get_widget (priv->xml, name) - - priv->main = GW ("schedule-page"); - if (!priv->main) - return FALSE; - - /* Get the GtkAccelGroup from the toplevel window, so we can install - it when the notebook page is mapped. */ - toplevel = gtk_widget_get_toplevel (priv->main); - accel_groups = gtk_accel_groups_from_object (GTK_OBJECT (toplevel)); - if (accel_groups) { - page->accel_group = accel_groups->data; - gtk_accel_group_ref (page->accel_group); - } - - gtk_widget_ref (priv->main); - gtk_widget_unparent (priv->main); - -#undef GW - - return TRUE; -} - -static gboolean -init_widgets (SchedulePage *spage) -{ - SchedulePagePrivate *priv; - - priv = spage->priv; - - gtk_signal_connect (GTK_OBJECT (priv->sel), - "changed", times_changed_cb, spage); - - return TRUE; - -} - - - -/** - * schedule_page_construct: - * @spage: An schedule page. - * - * Constructs an schedule page by loading its Glade data. - * - * Return value: The same object as @spage, or NULL if the widgets could not - * be created. - **/ -SchedulePage * -schedule_page_construct (SchedulePage *spage, EMeetingModel *emm) -{ - SchedulePagePrivate *priv; - - priv = spage->priv; - - priv->xml = glade_xml_new (EVOLUTION_GLADEDIR - "/schedule-page.glade", NULL); - if (!priv->xml) { - g_message ("schedule_page_construct(): " - "Could not load the Glade XML file!"); - return NULL; - } - - if (!get_widgets (spage)) { - g_message ("schedule_page_construct(): " - "Could not find all widgets in the XML file!"); - return NULL; - } - - /* Model */ - gtk_object_ref (GTK_OBJECT (emm)); - priv->model = emm; - - /* Selector */ - priv->sel = E_MEETING_TIME_SELECTOR (e_meeting_time_selector_new (emm)); - e_meeting_time_selector_set_working_hours (priv->sel, - calendar_config_get_day_start_hour (), - calendar_config_get_day_start_minute (), - calendar_config_get_day_end_hour (), - calendar_config_get_day_end_minute ()); - gtk_widget_show (GTK_WIDGET (priv->sel)); - gtk_box_pack_start (GTK_BOX (priv->main), GTK_WIDGET (priv->sel), TRUE, TRUE, 2); - - if (!init_widgets (spage)) { - g_message ("schedule_page_construct(): " - "Could not initialize the widgets!"); - return NULL; - } - - return spage; -} - -/** - * schedule_page_new: - * - * Creates a new schedule page. - * - * Return value: A newly-created schedule page, or NULL if the page could - * not be created. - **/ -SchedulePage * -schedule_page_new (EMeetingModel *emm) -{ - SchedulePage *spage; - - spage = gtk_type_new (TYPE_SCHEDULE_PAGE); - if (!schedule_page_construct (spage, emm)) { - gtk_object_unref (GTK_OBJECT (spage)); - return NULL; - } - - return spage; -} - -static void -times_changed_cb (GtkWidget *widget, gpointer data) -{ - SchedulePage *spage = data; - SchedulePagePrivate *priv; - CompEditorPageDates dates; - CalComponentDateTime start_dt, end_dt; - struct icaltimetype start_tt = icaltime_null_time (); - struct icaltimetype end_tt = icaltime_null_time (); - - priv = spage->priv; - - if (priv->updating) - return; - - e_date_edit_get_date (E_DATE_EDIT (priv->sel->start_date_edit), - &start_tt.year, - &start_tt.month, - &start_tt.day); - e_date_edit_get_time_of_day (E_DATE_EDIT (priv->sel->start_date_edit), - &start_tt.hour, - &start_tt.minute); - e_date_edit_get_date (E_DATE_EDIT (priv->sel->end_date_edit), - &end_tt.year, - &end_tt.month, - &end_tt.day); - e_date_edit_get_time_of_day (E_DATE_EDIT (priv->sel->end_date_edit), - &end_tt.hour, - &end_tt.minute); - - start_dt.value = &start_tt; - end_dt.value = &end_tt; - - if (e_date_edit_get_show_time (E_DATE_EDIT (priv->sel->start_date_edit))) { - /* We set the start and end to the same timezone. */ - start_dt.tzid = icaltimezone_get_tzid (priv->zone); - end_dt.tzid = start_dt.tzid; - } else { - /* For All-Day Events, we set the timezone to NULL, and add - 1 day to DTEND. */ - start_dt.value->is_date = TRUE; - start_dt.tzid = NULL; - end_dt.value->is_date = TRUE; - icaltime_adjust (&end_tt, 1, 0, 0, 0); - end_dt.tzid = NULL; - } - - dates.start = &start_dt; - dates.end = &end_dt; - dates.due = NULL; - dates.complete = NULL; - - comp_editor_page_notify_dates_changed (COMP_EDITOR_PAGE (spage), - &dates); -} diff --git a/calendar/gui/dialogs/schedule-page.glade b/calendar/gui/dialogs/schedule-page.glade deleted file mode 100644 index 95a2147659..0000000000 --- a/calendar/gui/dialogs/schedule-page.glade +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.0"?> -<GTK-Interface> - -<project> - <name>task-details-page</name> - <program_name>task-details-page</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>schedule-toplevel</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>GtkVBox</class> - <name>schedule-page</name> - <border_width>4</border_width> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - </widget> -</widget> - -</GTK-Interface> diff --git a/calendar/gui/dialogs/schedule-page.h b/calendar/gui/dialogs/schedule-page.h deleted file mode 100644 index c485ba0f9e..0000000000 --- a/calendar/gui/dialogs/schedule-page.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Evolution calendar - Scheduling page - * - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef SCHEDULE_PAGE_H -#define SCHEDULE_PAGE_H - -#include "../e-meeting-model.h" -#include "comp-editor-page.h" - -BEGIN_GNOME_DECLS - - - -#define TYPE_SCHEDULE_PAGE (schedule_page_get_type ()) -#define SCHEDULE_PAGE(obj) (GTK_CHECK_CAST ((obj), TYPE_SCHEDULE_PAGE, SchedulePage)) -#define SCHEDULE_PAGE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_SCHEDULE_PAGE, SchedulePageClass)) -#define IS_SCHEDULE_PAGE(obj) (GTK_CHECK_TYPE ((obj), TYPE_SCHEDULE_PAGE)) -#define IS_SCHEDULE_PAGE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), TYPE_SCHEDULE_PAGE)) - -typedef struct _SchedulePagePrivate SchedulePagePrivate; - -typedef struct { - CompEditorPage page; - - /* Private data */ - SchedulePagePrivate *priv; -} SchedulePage; - -typedef struct { - CompEditorPageClass parent_class; -} SchedulePageClass; - - -GtkType schedule_page_get_type (void); -SchedulePage *schedule_page_construct (SchedulePage *mpage, EMeetingModel *emm); -SchedulePage *schedule_page_new (EMeetingModel *emm); - - - -END_GNOME_DECLS - -#endif diff --git a/calendar/gui/dialogs/send-comp.c b/calendar/gui/dialogs/send-comp.c deleted file mode 100644 index 2afd92320e..0000000000 --- a/calendar/gui/dialogs/send-comp.c +++ /dev/null @@ -1,87 +0,0 @@ -/* Evolution calendar - Send calendar component dialog - * - * Copyright (C) 2001 Ximian, Inc. - * - * Author: JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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 "send-comp.h" - - - -/** - * send_component_dialog: - * - * Pops up a dialog box asking the user whether he wants to send a - * iTip/iMip message - * - * Return value: TRUE if the user clicked Yes, FALSE otherwise. - **/ -gboolean -send_component_dialog (CalComponent *comp, gboolean new) -{ - GtkWidget *dialog; - CalComponentVType vtype; - char *str; - - vtype = cal_component_get_vtype (comp); - - switch (vtype) { - case CAL_COMPONENT_EVENT: - if (new) - str = g_strdup_printf (_("The meeting information has " - "been created. Send it?")); - else - str = g_strdup_printf (_("The meeting information has " - "changed. Send an updated " - "version?")); - break; - - case CAL_COMPONENT_TODO: - if (new) - str = g_strdup_printf (_("The task assignment " - "information has been " - "created. Send it?")); - else - str = g_strdup_printf (_("The task information has " - "changed. Send an updated " - "version?")); - break; - - default: - g_message ("send_component_dialog(): " - "Cannot handle object of type %d", vtype); - return FALSE; - } - - dialog = gnome_question_dialog_modal (str, NULL, NULL); - - if (gnome_dialog_run (GNOME_DIALOG (dialog)) == GNOME_YES) - return TRUE; - else - return FALSE; -} diff --git a/calendar/gui/dialogs/send-comp.h b/calendar/gui/dialogs/send-comp.h deleted file mode 100644 index 9a77d8bd4e..0000000000 --- a/calendar/gui/dialogs/send-comp.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Evolution calendar - Send calendar component dialog - * - * Copyright (C) 2001 Ximian, Inc. - * - * Author: JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef SEND_COMP_H -#define SEND_COMP_H - -#include <glib.h> -#include <cal-util/cal-component.h> - -gboolean send_component_dialog (CalComponent *comp, gboolean new); - -#endif diff --git a/calendar/gui/dialogs/task-details-page.c b/calendar/gui/dialogs/task-details-page.c deleted file mode 100644 index 84070ff541..0000000000 --- a/calendar/gui/dialogs/task-details-page.c +++ /dev/null @@ -1,772 +0,0 @@ -/* Evolution calendar - task details page - * - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * Miguel de Icaza <miguel@ximian.com> - * Seth Alves <alves@hungry.com> - * JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtksignal.h> -#include <gtk/gtktogglebutton.h> -#include <glade/glade.h> -#include <gal/widgets/e-unicode.h> -#include <widgets/misc/e-dateedit.h> -#include <widgets/misc/e-url-entry.h> -#include "e-util/e-dialog-widgets.h" -#include "../calendar-config.h" -#include "../e-timezone-entry.h" -#include "comp-editor-util.h" -#include "task-details-page.h" - - - -/* Private part of the TaskDetailsPage structure */ -struct _TaskDetailsPagePrivate { - /* Glade XML data */ - GladeXML *xml; - - /* Widgets from the Glade file */ - GtkWidget *main; - - GtkWidget *status; - GtkWidget *priority; - GtkWidget *percent_complete; - - GtkWidget *completed_date; - - GtkWidget *url_entry; - GtkWidget *url; - - gboolean updating; -}; - -/* 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 void task_details_page_class_init (TaskDetailsPageClass *class); -static void task_details_page_init (TaskDetailsPage *tdpage); -static void task_details_page_destroy (GtkObject *object); - -static GtkWidget *task_details_page_get_widget (CompEditorPage *page); -static void task_details_page_focus_main_widget (CompEditorPage *page); -static void task_details_page_fill_widgets (CompEditorPage *page, CalComponent *comp); -static gboolean task_details_page_fill_component (CompEditorPage *page, CalComponent *comp); - -static CompEditorPageClass *parent_class = NULL; - - - -/** - * task_details_page_get_type: - * - * Registers the #TaskDetailsPage class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the #TaskDetailsPage class. - **/ -GtkType -task_details_page_get_type (void) -{ - static GtkType task_details_page_type; - - if (!task_details_page_type) { - static const GtkTypeInfo task_details_page_info = { - "TaskDetailsPage", - sizeof (TaskDetailsPage), - sizeof (TaskDetailsPageClass), - (GtkClassInitFunc) task_details_page_class_init, - (GtkObjectInitFunc) task_details_page_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - task_details_page_type = - gtk_type_unique (TYPE_COMP_EDITOR_PAGE, - &task_details_page_info); - } - - return task_details_page_type; -} - -/* Class initialization function for the task page */ -static void -task_details_page_class_init (TaskDetailsPageClass *class) -{ - CompEditorPageClass *editor_page_class; - GtkObjectClass *object_class; - - editor_page_class = (CompEditorPageClass *) class; - object_class = (GtkObjectClass *) class; - - parent_class = gtk_type_class (TYPE_COMP_EDITOR_PAGE); - - editor_page_class->get_widget = task_details_page_get_widget; - editor_page_class->focus_main_widget = task_details_page_focus_main_widget; - editor_page_class->fill_widgets = task_details_page_fill_widgets; - editor_page_class->fill_component = task_details_page_fill_component; - - object_class->destroy = task_details_page_destroy; -} - -/* Object initialization function for the task page */ -static void -task_details_page_init (TaskDetailsPage *tdpage) -{ - TaskDetailsPagePrivate *priv; - - priv = g_new0 (TaskDetailsPagePrivate, 1); - tdpage->priv = priv; - - priv->xml = NULL; - - priv->main = NULL; - - priv->status = NULL; - priv->priority = NULL; - priv->percent_complete = NULL; - - priv->completed_date = NULL; - - priv->url_entry = NULL; - priv->url = NULL; - - priv->updating = FALSE; -} - -/* Destroy handler for the task page */ -static void -task_details_page_destroy (GtkObject *object) -{ - TaskDetailsPage *tdpage; - TaskDetailsPagePrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_TASK_DETAILS_PAGE (object)); - - tdpage = TASK_DETAILS_PAGE (object); - priv = tdpage->priv; - - if (priv->xml) { - gtk_object_unref (GTK_OBJECT (priv->xml)); - priv->xml = NULL; - } - - g_free (priv); - tdpage->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - - -/* get_widget handler for the task page */ -static GtkWidget * -task_details_page_get_widget (CompEditorPage *page) -{ - TaskDetailsPage *tdpage; - TaskDetailsPagePrivate *priv; - - tdpage = TASK_DETAILS_PAGE (page); - priv = tdpage->priv; - - return priv->main; -} - -/* focus_main_widget handler for the task page */ -static void -task_details_page_focus_main_widget (CompEditorPage *page) -{ - TaskDetailsPage *tdpage; - TaskDetailsPagePrivate *priv; - - tdpage = TASK_DETAILS_PAGE (page); - priv = tdpage->priv; - - gtk_widget_grab_focus (priv->status); -} - - -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; -} - -/* Fills the widgets with default values */ -static void -clear_widgets (TaskDetailsPage *tdpage) -{ - TaskDetailsPagePrivate *priv; - - priv = tdpage->priv; - - /* Date completed */ - e_date_edit_set_time (E_DATE_EDIT (priv->completed_date), -1); - - /* URL */ - e_dialog_editable_set (priv->url, NULL); -} - -/* fill_widgets handler for the task page */ -static void -task_details_page_fill_widgets (CompEditorPage *page, CalComponent *comp) -{ - TaskDetailsPage *tdpage; - TaskDetailsPagePrivate *priv; - int *priority_value, *percent; - TaskEditorPriority priority; - icalproperty_status status; - const char *url; - struct icaltimetype *completed = NULL; - - tdpage = TASK_DETAILS_PAGE (page); - priv = tdpage->priv; - - priv->updating = TRUE; - - /* Clean the screen */ - clear_widgets (tdpage); - - /* Percent Complete. */ - cal_component_get_percent (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 (comp, &status); - if (status == ICAL_STATUS_NONE) { - /* Try to use 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); - - /* Completed Date. */ - cal_component_get_completed (comp, &completed); - if (completed) { - icaltimezone *utc_zone, *zone; - char *location; - - /* Completed is in UTC, but that would confuse the user, so - we convert it to local time. */ - utc_zone = icaltimezone_get_utc_timezone (); - location = calendar_config_get_timezone (); - zone = icaltimezone_get_builtin_timezone (location); - - icaltimezone_convert_time (completed, utc_zone, zone); - - e_date_edit_set_date (E_DATE_EDIT (priv->completed_date), - completed->year, completed->month, - completed->day); - e_date_edit_set_time_of_day (E_DATE_EDIT (priv->completed_date), - completed->hour, - completed->minute); - - cal_component_free_icaltimetype (completed); - } - - /* Priority. */ - cal_component_get_priority (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); - - /* URL */ - cal_component_get_url (comp, &url); - e_dialog_editable_set (priv->url, url); - - priv->updating = FALSE; -} - -/* fill_component handler for the task page */ -static gboolean -task_details_page_fill_component (CompEditorPage *page, CalComponent *comp) -{ - TaskDetailsPage *tdpage; - TaskDetailsPagePrivate *priv; - struct icaltimetype icaltime; - icalproperty_status status; - TaskEditorPriority priority; - int priority_value, percent; - char *url; - gboolean date_set; - - tdpage = TASK_DETAILS_PAGE (page); - priv = tdpage->priv; - - /* 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); - - icaltime = icaltime_null_time (); - - /* COMPLETED must be in UTC. */ - icaltime.is_utc = 1; - - /* Completed Date. */ - date_set = e_date_edit_get_date (E_DATE_EDIT (priv->completed_date), - &icaltime.year, - &icaltime.month, - &icaltime.day); - e_date_edit_get_time_of_day (E_DATE_EDIT (priv->completed_date), - &icaltime.hour, - &icaltime.minute); - if (date_set) { - /* COMPLETED must be in UTC, so we assume that the date in the - dialog is in the current timezone, and we now convert it - to UTC. FIXME: We should really use one timezone for the - entire time the dialog is shown. Otherwise if the user - changes the timezone, the COMPLETED date may get changed - as well. */ - char *location = calendar_config_get_timezone (); - icaltimezone *zone = icaltimezone_get_builtin_timezone (location); - icaltimezone_convert_time (&icaltime, zone, - icaltimezone_get_utc_timezone ()); - cal_component_set_completed (comp, &icaltime); - } else { - cal_component_set_completed (comp, NULL); - } - - /* URL. */ - url = e_dialog_editable_get (priv->url); - cal_component_set_url (comp, url); - if (url) - g_free (url); - - return TRUE; -} - - - -/* Gets the widgets from the XML file and returns if they are all available. */ -static gboolean -get_widgets (TaskDetailsPage *tdpage) -{ - CompEditorPage *page = COMP_EDITOR_PAGE (tdpage); - TaskDetailsPagePrivate *priv; - GSList *accel_groups; - GtkWidget *toplevel; - - priv = tdpage->priv; - -#define GW(name) glade_xml_get_widget (priv->xml, name) - - priv->main = GW ("task-details-page"); - if (!priv->main) - return FALSE; - - /* Get the GtkAccelGroup from the toplevel window, so we can install - it when the notebook page is mapped. */ - toplevel = gtk_widget_get_toplevel (priv->main); - accel_groups = gtk_accel_groups_from_object (GTK_OBJECT (toplevel)); - if (accel_groups) { - page->accel_group = accel_groups->data; - gtk_accel_group_ref (page->accel_group); - } - - gtk_widget_ref (priv->main); - gtk_widget_unparent (priv->main); - - priv->status = GW ("status"); - priv->priority = GW ("priority"); - priv->percent_complete = GW ("percent-complete"); - - priv->completed_date = GW ("completed-date"); - - priv->url_entry = GW ("url_entry"); - priv->url = e_url_entry_get_entry (E_URL_ENTRY (priv->url_entry)); - -#undef GW - - return (priv->status - && priv->priority - && priv->percent_complete - && priv->completed_date - && priv->url); -} - - -static void -complete_date_changed (TaskDetailsPage *tdpage, time_t ctime, gboolean complete) -{ - TaskDetailsPagePrivate *priv; - CompEditorPageDates dates = {NULL, NULL, NULL, NULL}; - icaltimezone *zone; - struct icaltimetype completed_tt = icaltime_null_time(); - - priv = tdpage->priv; - - /* Get the current time in UTC. */ - zone = icaltimezone_get_utc_timezone (); - completed_tt = icaltime_from_timet_with_zone (ctime, FALSE, zone); - completed_tt.is_utc = TRUE; - - dates.start = NULL; - dates.end = NULL; - dates.due = NULL; - if (complete) - dates.complete = &completed_tt; - - /* Notify upstream */ - comp_editor_page_notify_dates_changed (COMP_EDITOR_PAGE (tdpage), - &dates); -} - -static void -date_changed_cb (EDateEdit *dedit, gpointer data) -{ - TaskDetailsPage *tdpage; - TaskDetailsPagePrivate *priv; - CompEditorPageDates dates = {NULL, NULL, NULL, NULL}; - struct icaltimetype completed_tt = icaltime_null_time (); - icalproperty_status status; - gboolean date_set; - - tdpage = TASK_DETAILS_PAGE (data); - priv = tdpage->priv; - - if (priv->updating) - return; - - priv->updating = TRUE; - - date_set = e_date_edit_get_date (E_DATE_EDIT (priv->completed_date), - &completed_tt.year, - &completed_tt.month, - &completed_tt.day); - e_date_edit_get_time_of_day (E_DATE_EDIT (priv->completed_date), - &completed_tt.hour, - &completed_tt.minute); - - status = e_dialog_option_menu_get (priv->status, status_map); - - if (!date_set) { - completed_tt = icaltime_null_time (); - if (status == ICAL_STATUS_COMPLETED) { - e_dialog_option_menu_set (priv->status, - ICAL_STATUS_NEEDSACTION, - status_map); - e_dialog_spin_set (priv->percent_complete, 0); - } - } else { - if (status != ICAL_STATUS_COMPLETED) { - e_dialog_option_menu_set (priv->status, - ICAL_STATUS_COMPLETED, - status_map); - } - e_dialog_spin_set (priv->percent_complete, 100); - } - - priv->updating = FALSE; - - /* Notify upstream */ - dates.complete = &completed_tt; - comp_editor_page_notify_dates_changed (COMP_EDITOR_PAGE (tdpage), &dates); -} - -static void -status_changed (GtkMenu *menu, TaskDetailsPage *tdpage) -{ - TaskDetailsPagePrivate *priv; - icalproperty_status status; - time_t ctime = -1; - - priv = tdpage->priv; - - if (priv->updating) - return; - - priv->updating = TRUE; - - status = e_dialog_option_menu_get (priv->status, status_map); - if (status == ICAL_STATUS_NEEDSACTION) { - e_dialog_spin_set (priv->percent_complete, 0); - e_date_edit_set_time (E_DATE_EDIT (priv->completed_date), ctime); - complete_date_changed (tdpage, 0, FALSE); - } else if (status == ICAL_STATUS_INPROCESS) { - e_dialog_spin_set (priv->percent_complete, 50); - e_date_edit_set_time (E_DATE_EDIT (priv->completed_date), ctime); - complete_date_changed (tdpage, 0, FALSE); - } else if (status == ICAL_STATUS_COMPLETED) { - e_dialog_spin_set (priv->percent_complete, 100); - ctime = time (NULL); - e_date_edit_set_time (E_DATE_EDIT (priv->completed_date), ctime); - complete_date_changed (tdpage, ctime, TRUE); - } - - priv->updating = FALSE; - - comp_editor_page_notify_changed (COMP_EDITOR_PAGE (tdpage)); -} - -static void -percent_complete_changed (GtkAdjustment *adj, TaskDetailsPage *tdpage) -{ - TaskDetailsPagePrivate *priv; - gint percent; - icalproperty_status status; - gboolean complete; - time_t ctime = -1; - - priv = tdpage->priv; - - if (priv->updating) - return; - - priv->updating = TRUE; - - percent = e_dialog_spin_get_int (priv->percent_complete); - if (percent == 100) { - complete = TRUE; - ctime = time (NULL); - status = ICAL_STATUS_COMPLETED; - } else { - complete = FALSE; - - if (percent == 0) - status = ICAL_STATUS_NEEDSACTION; - else - status = ICAL_STATUS_INPROCESS; - } - - e_dialog_option_menu_set (priv->status, status, status_map); - e_date_edit_set_time (E_DATE_EDIT (priv->completed_date), ctime); - complete_date_changed (tdpage, ctime, complete); - - priv->updating = FALSE; - - comp_editor_page_notify_changed (COMP_EDITOR_PAGE (tdpage)); -} - -/* This is called when any field is changed; it notifies upstream. */ -static void -field_changed_cb (GtkWidget *widget, gpointer data) -{ - TaskDetailsPage *tdpage; - TaskDetailsPagePrivate *priv; - - tdpage = TASK_DETAILS_PAGE (data); - priv = tdpage->priv; - - if (!priv->updating) - comp_editor_page_notify_changed (COMP_EDITOR_PAGE (tdpage)); -} - -/* Hooks the widget signals */ -static void -init_widgets (TaskDetailsPage *tdpage) -{ - TaskDetailsPagePrivate *priv; - - priv = tdpage->priv; - - /* Make sure the EDateEdit widgets use our timezones to get the - current time. */ - e_date_edit_set_get_time_callback (E_DATE_EDIT (priv->completed_date), - (EDateEditGetTimeCallback) comp_editor_get_current_time, - tdpage, NULL); - - /* 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 (GTK_OPTION_MENU (priv->status)->menu), - "deactivate", - GTK_SIGNAL_FUNC (status_changed), tdpage); - - gtk_signal_connect (GTK_OBJECT (GTK_SPIN_BUTTON (priv->percent_complete)->adjustment), - "value_changed", - GTK_SIGNAL_FUNC (percent_complete_changed), tdpage); - - /* Priority */ - gtk_signal_connect (GTK_OBJECT (GTK_OPTION_MENU (priv->priority)->menu), - "deactivate", - GTK_SIGNAL_FUNC (field_changed_cb), tdpage); - - /* Completed Date */ - gtk_signal_connect (GTK_OBJECT (priv->completed_date), "changed", - GTK_SIGNAL_FUNC (date_changed_cb), tdpage); - - /* URL */ - gtk_signal_connect (GTK_OBJECT (priv->url), "changed", - GTK_SIGNAL_FUNC (field_changed_cb), tdpage); -} - - - -/** - * task_details_page_construct: - * @tdpage: An task details page. - * - * Constructs an task page by loading its Glade data. - * - * Return value: The same object as @tdpage, or NULL if the widgets could not - * be created. - **/ -TaskDetailsPage * -task_details_page_construct (TaskDetailsPage *tdpage) -{ - TaskDetailsPagePrivate *priv; - - priv = tdpage->priv; - - priv->xml = glade_xml_new (EVOLUTION_GLADEDIR - "/task-details-page.glade", NULL); - if (!priv->xml) { - g_message ("task_details_page_construct(): " - "Could not load the Glade XML file!"); - return NULL; - } - - if (!get_widgets (tdpage)) { - g_message ("task_details_page_construct(): " - "Could not find all widgets in the XML file!"); - return NULL; - } - - init_widgets (tdpage); - - return tdpage; -} - -/** - * task_details_page_new: - * - * Creates a new task details page. - * - * Return value: A newly-created task details page, or NULL if the page could - * not be created. - **/ -TaskDetailsPage * -task_details_page_new (void) -{ - TaskDetailsPage *tdpage; - - tdpage = gtk_type_new (TYPE_TASK_DETAILS_PAGE); - if (!task_details_page_construct (tdpage)) { - gtk_object_unref (GTK_OBJECT (tdpage)); - return NULL; - } - - return tdpage; -} - -GtkWidget *task_details_page_create_date_edit (void); - -GtkWidget * -task_details_page_create_date_edit (void) -{ - GtkWidget *dedit; - - dedit = comp_editor_new_date_edit (TRUE, TRUE, FALSE); - e_date_edit_set_allow_no_date_set (E_DATE_EDIT (dedit), TRUE); - - return dedit; -} - diff --git a/calendar/gui/dialogs/task-details-page.glade b/calendar/gui/dialogs/task-details-page.glade deleted file mode 100644 index 28bf6a3bcc..0000000000 --- a/calendar/gui/dialogs/task-details-page.glade +++ /dev/null @@ -1,309 +0,0 @@ -<?xml version="1.0"?> -<GTK-Interface> - -<project> - <name>task-details-page</name> - <program_name>task-details-page</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>task-details-toplevel</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>GtkVBox</class> - <name>task-details-page</name> - <border_width>4</border_width> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - - <widget> - <class>GtkFrame</class> - <name>frame2</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>False</fill> - </child> - - <widget> - <class>GtkVBox</class> - <name>vbox1</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - - <widget> - <class>GtkHBox</class> - <name>hbox1</name> - <border_width>4</border_width> - <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>_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>label18</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>label19</name> - <label>% Complete</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>GtkSpinButton</class> - <name>percent-complete</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> - - <widget> - <class>GtkTable</class> - <name>table1</name> - <border_width>4</border_width> - <rows>1</rows> - <columns>2</columns> - <homogeneous>False</homogeneous> - <row_spacing>2</row_spacing> - <column_spacing>4</column_spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <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>Custom</class> - <name>completed-date</name> - <creation_function>task_details_page_create_date_edit</creation_function> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Fri, 01 Jun 2001 18:58:51 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>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - </widget> - </widget> - </widget> - - <widget> - <class>GtkTable</class> - <name>table2</name> - <border_width>4</border_width> - <rows>1</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>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>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>url_entry</name> - <creation_function>e_url_entry_new</creation_function> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Fri, 08 Feb 2002 21:02:37 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>True</yfill> - </child> - </widget> - </widget> - </widget> -</widget> - -</GTK-Interface> diff --git a/calendar/gui/dialogs/task-details-page.h b/calendar/gui/dialogs/task-details-page.h deleted file mode 100644 index 580388cb8d..0000000000 --- a/calendar/gui/dialogs/task-details-page.h +++ /dev/null @@ -1,61 +0,0 @@ -/* Evolution calendar - Main page of the task editor dialog - * - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * Miguel de Icaza <miguel@ximian.com> - * Seth Alves <alves@hungry.com> - * JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef TASK_DETAILS_PAGE_H -#define TASK_DETAILS_PAGE_H - -#include "comp-editor-page.h" - -BEGIN_GNOME_DECLS - - - -#define TYPE_TASK_DETAILS_PAGE (task_details_page_get_type ()) -#define TASK_DETAILS_PAGE(obj) (GTK_CHECK_CAST ((obj), TYPE_TASK_DETAILS_PAGE, TaskDetailsPage)) -#define TASK_DETAILS_PAGE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_TASK_DETAILS_PAGE, TaskDetailsPageClass)) -#define IS_TASK_DETAILS_PAGE(obj) (GTK_CHECK_TYPE ((obj), TYPE_TASK_DETAILS_PAGE)) -#define IS_TASK_DETAILS_PAGE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), TYPE_TASK_DETAILS_PAGE)) - -typedef struct _TaskDetailsPagePrivate TaskDetailsPagePrivate; - -typedef struct { - CompEditorPage page; - - /* Private data */ - TaskDetailsPagePrivate *priv; -} TaskDetailsPage; - -typedef struct { - CompEditorPageClass parent_class; -} TaskDetailsPageClass; - - -GtkType task_details_page_get_type (void); -TaskDetailsPage *task_details_page_construct (TaskDetailsPage *tdpage); -TaskDetailsPage *task_details_page_new (void); - - - -END_GNOME_DECLS - -#endif diff --git a/calendar/gui/dialogs/task-editor.c b/calendar/gui/dialogs/task-editor.c deleted file mode 100644 index 1ede12fff3..0000000000 --- a/calendar/gui/dialogs/task-editor.c +++ /dev/null @@ -1,405 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Evolution calendar - Task editor dialog - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: Miguel de Icaza <miguel@ximian.com> - * Federico Mena-Quintero <federico@ximian.com> - * Seth Alves <alves@hungry.com> - * JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#include <config.h> -#include <string.h> -#include <glade/glade.h> -#include <gal/widgets/e-unicode.h> -#include <libgnome/gnome-i18n.h> - -#include "task-page.h" -#include "task-details-page.h" -#include "meeting-page.h" -#include "cancel-comp.h" -#include "task-editor.h" - -struct _TaskEditorPrivate { - TaskPage *task_page; - TaskDetailsPage *task_details_page; - MeetingPage *meet_page; - - EMeetingModel *model; - - gboolean assignment_shown; - gboolean existing_org; - gboolean updating; -}; - - - -static void task_editor_class_init (TaskEditorClass *class); -static void task_editor_init (TaskEditor *te); -static void task_editor_edit_comp (CompEditor *editor, CalComponent *comp); -static void task_editor_send_comp (CompEditor *editor, CalComponentItipMethod method); -static void task_editor_destroy (GtkObject *object); - -static void assign_task_cmd (GtkWidget *widget, gpointer data); -static void refresh_task_cmd (GtkWidget *widget, gpointer data); -static void cancel_task_cmd (GtkWidget *widget, gpointer data); -static void forward_cmd (GtkWidget *widget, gpointer data); - -static void model_row_changed_cb (ETableModel *etm, int row, gpointer data); -static void row_count_changed_cb (ETableModel *etm, int row, int count, gpointer data); - -static BonoboUIVerb verbs [] = { - BONOBO_UI_UNSAFE_VERB ("ActionAssignTask", assign_task_cmd), - BONOBO_UI_UNSAFE_VERB ("ActionRefreshTask", refresh_task_cmd), - BONOBO_UI_UNSAFE_VERB ("ActionCancelTask", cancel_task_cmd), - BONOBO_UI_UNSAFE_VERB ("ActionForward", forward_cmd), - - BONOBO_UI_VERB_END -}; - -static CompEditorClass *parent_class; - - - -/** - * task_editor_get_type: - * - * Registers the #TaskEditor class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the #TaskEditor class. - **/ -GtkType -task_editor_get_type (void) -{ - static GtkType task_editor_type = 0; - - if (!task_editor_type) { - static const GtkTypeInfo task_editor_info = { - "TaskEditor", - sizeof (TaskEditor), - sizeof (TaskEditorClass), - (GtkClassInitFunc) task_editor_class_init, - (GtkObjectInitFunc) task_editor_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - task_editor_type = gtk_type_unique (TYPE_COMP_EDITOR, - &task_editor_info); - } - - return task_editor_type; -} - -/* Class initialization function for the event editor */ -static void -task_editor_class_init (TaskEditorClass *klass) -{ - GtkObjectClass *object_class; - CompEditorClass *editor_class; - - object_class = (GtkObjectClass *) klass; - editor_class = (CompEditorClass *) klass; - - parent_class = gtk_type_class (TYPE_COMP_EDITOR); - - editor_class->edit_comp = task_editor_edit_comp; - editor_class->send_comp = task_editor_send_comp; - - object_class->destroy = task_editor_destroy; -} - -static void -set_menu_sens (TaskEditor *te) -{ - TaskEditorPrivate *priv; - gboolean sens; - - priv = te->priv; - - sens = priv->assignment_shown; - comp_editor_set_ui_prop (COMP_EDITOR (te), - "/commands/ActionAssignTask", - "sensitive", sens ? "0" : "1"); - - sens = sens && priv->existing_org; - comp_editor_set_ui_prop (COMP_EDITOR (te), - "/commands/ActionRefreshTask", - "sensitive", sens ? "1" : "0"); - comp_editor_set_ui_prop (COMP_EDITOR (te), - "/commands/ActionCancelTask", - "sensitive", sens ? "1" : "0"); -} - -static void -init_widgets (TaskEditor *te) -{ - TaskEditorPrivate *priv; - - priv = te->priv; - - gtk_signal_connect (GTK_OBJECT (priv->model), "model_row_changed", - GTK_SIGNAL_FUNC (model_row_changed_cb), te); - gtk_signal_connect (GTK_OBJECT (priv->model), "model_rows_inserted", - GTK_SIGNAL_FUNC (row_count_changed_cb), te); - gtk_signal_connect (GTK_OBJECT (priv->model), "model_rows_deleted", - GTK_SIGNAL_FUNC (row_count_changed_cb), te); -} - -/* Object initialization function for the task editor */ -static void -task_editor_init (TaskEditor *te) -{ - TaskEditorPrivate *priv; - - priv = g_new0 (TaskEditorPrivate, 1); - te->priv = priv; - - priv->task_page = task_page_new (); - comp_editor_append_page (COMP_EDITOR (te), - COMP_EDITOR_PAGE (priv->task_page), - _("Basic")); - - priv->task_details_page = task_details_page_new (); - comp_editor_append_page (COMP_EDITOR (te), - COMP_EDITOR_PAGE (priv->task_details_page), - _("Details")); - - priv->model = E_MEETING_MODEL (e_meeting_model_new ()); - - priv->meet_page = meeting_page_new (priv->model); - comp_editor_append_page (COMP_EDITOR (te), - COMP_EDITOR_PAGE (priv->meet_page), - _("Assignment")); - - comp_editor_merge_ui (COMP_EDITOR (te), "evolution-task-editor.xml", verbs); - - priv->assignment_shown = TRUE; - priv->existing_org = FALSE; - priv->updating = FALSE; - - init_widgets (te); - set_menu_sens (te); -} - -static void -task_editor_edit_comp (CompEditor *editor, CalComponent *comp) -{ - TaskEditor *te; - TaskEditorPrivate *priv; - GSList *attendees = NULL; - - te = TASK_EDITOR (editor); - priv = te->priv; - - priv->updating = TRUE; - - priv->existing_org = cal_component_has_organizer (comp); - cal_component_get_attendee_list (comp, &attendees); - - e_meeting_model_remove_all_attendees (priv->model); - if (attendees == NULL) { - comp_editor_remove_page (editor, COMP_EDITOR_PAGE (priv->meet_page)); - priv->assignment_shown = FALSE; - } else { - GSList *l; - - if (!priv->assignment_shown) - comp_editor_append_page (COMP_EDITOR (te), - COMP_EDITOR_PAGE (priv->meet_page), - _("Assignment")); - - for (l = attendees; l != NULL; l = l->next) { - CalComponentAttendee *ca = l->data; - EMeetingAttendee *ia = E_MEETING_ATTENDEE (e_meeting_attendee_new_from_cal_component_attendee (ca)); - - e_meeting_model_add_attendee (priv->model, ia); - gtk_object_unref (GTK_OBJECT (ia)); - } - priv->assignment_shown = TRUE; - } - cal_component_free_attendee_list (attendees); - - set_menu_sens (te); - comp_editor_set_needs_send (COMP_EDITOR (te), priv->assignment_shown); - - priv->updating = FALSE; - - if (parent_class->edit_comp) - parent_class->edit_comp (editor, comp); -} - -static void -task_editor_send_comp (CompEditor *editor, CalComponentItipMethod method) -{ - TaskEditor *te = TASK_EDITOR (editor); - TaskEditorPrivate *priv; - CalComponent *comp = NULL; - - priv = te->priv; - - /* Don't cancel more than once or when just publishing */ - if (method == CAL_COMPONENT_METHOD_PUBLISH || - method == CAL_COMPONENT_METHOD_CANCEL) - goto parent; - - comp = meeting_page_get_cancel_comp (priv->meet_page); - if (comp != NULL) { - CalClient *client; - - client = e_meeting_model_get_cal_client (priv->model); - itip_send_comp (CAL_COMPONENT_METHOD_CANCEL, comp, client, NULL); - gtk_object_unref (GTK_OBJECT (comp)); - } - - parent: - if (parent_class->send_comp) - parent_class->send_comp (editor, method); -} - -/* Destroy handler for the event editor */ -static void -task_editor_destroy (GtkObject *object) -{ - TaskEditor *te; - TaskEditorPrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_TASK_EDITOR (object)); - - te = TASK_EDITOR (object); - priv = te->priv; - - gtk_object_unref (GTK_OBJECT (priv->task_page)); - gtk_object_unref (GTK_OBJECT (priv->task_details_page)); - gtk_object_unref (GTK_OBJECT (priv->meet_page)); - - gtk_object_unref (GTK_OBJECT (priv->model)); - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - -/** - * task_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. - **/ -TaskEditor * -task_editor_new (void) -{ - return TASK_EDITOR (gtk_type_new (TYPE_TASK_EDITOR)); -} - -static void -show_assignment (TaskEditor *te) -{ - TaskEditorPrivate *priv; - - priv = te->priv; - - if (!priv->assignment_shown) { - comp_editor_append_page (COMP_EDITOR (te), - COMP_EDITOR_PAGE (priv->meet_page), - _("Assignment")); - priv->assignment_shown = TRUE; - - set_menu_sens (te); - comp_editor_set_needs_send (COMP_EDITOR (te), priv->assignment_shown); - comp_editor_set_changed (COMP_EDITOR (te), TRUE); - } - - comp_editor_show_page (COMP_EDITOR (te), - COMP_EDITOR_PAGE (priv->meet_page)); -} - -void -task_editor_show_assignment (TaskEditor *te) -{ - g_return_if_fail (te != NULL); - g_return_if_fail (IS_TASK_EDITOR (te)); - - show_assignment (te); -} - -static void -assign_task_cmd (GtkWidget *widget, gpointer data) -{ - TaskEditor *te = TASK_EDITOR (data); - - show_assignment (te); -} - -static void -refresh_task_cmd (GtkWidget *widget, gpointer data) -{ - TaskEditor *te = TASK_EDITOR (data); - - comp_editor_send_comp (COMP_EDITOR (te), CAL_COMPONENT_METHOD_REFRESH); -} - -static void -cancel_task_cmd (GtkWidget *widget, gpointer data) -{ - TaskEditor *te = TASK_EDITOR (data); - CalComponent *comp; - - comp = comp_editor_get_current_comp (COMP_EDITOR (te)); - if (cancel_component_dialog (comp)) { - comp_editor_send_comp (COMP_EDITOR (te), CAL_COMPONENT_METHOD_CANCEL); - comp_editor_delete_comp (COMP_EDITOR (te)); - } -} - -static void -forward_cmd (GtkWidget *widget, gpointer data) -{ - TaskEditor *te = TASK_EDITOR (data); - - if (comp_editor_save_comp (COMP_EDITOR (te), TRUE)) - comp_editor_send_comp (COMP_EDITOR (te), CAL_COMPONENT_METHOD_PUBLISH); -} - -static void -model_row_changed_cb (ETableModel *etm, int row, gpointer data) -{ - TaskEditor *te = TASK_EDITOR (data); - TaskEditorPrivate *priv; - - priv = te->priv; - - if (!priv->updating) - comp_editor_set_changed (COMP_EDITOR (te), TRUE); -} - -static void -row_count_changed_cb (ETableModel *etm, int row, int count, gpointer data) -{ - TaskEditor *te = TASK_EDITOR (data); - TaskEditorPrivate *priv; - - priv = te->priv; - - if (!priv->updating) - comp_editor_set_changed (COMP_EDITOR (te), TRUE); -} diff --git a/calendar/gui/dialogs/task-editor.h b/calendar/gui/dialogs/task-editor.h deleted file mode 100644 index e9888f446a..0000000000 --- a/calendar/gui/dialogs/task-editor.h +++ /dev/null @@ -1,61 +0,0 @@ -/* Evolution calendar - Task editor dialog - * - * Copyright (C) 2000 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef __TASK_EDITOR_H__ -#define __TASK_EDITOR_H__ - -#include <libgnome/gnome-defs.h> -#include <gtk/gtkobject.h> -#include "comp-editor.h" - - - -#define TYPE_TASK_EDITOR (task_editor_get_type ()) -#define TASK_EDITOR(obj) (GTK_CHECK_CAST ((obj), TYPE_TASK_EDITOR, TaskEditor)) -#define TASK_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_TASK_EDITOR, \ - TaskEditorClass)) -#define IS_TASK_EDITOR(obj) (GTK_CHECK_TYPE ((obj), TYPE_TASK_EDITOR)) -#define IS_TASK_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), TYPE_TASK_EDITOR)) - -typedef struct _TaskEditor TaskEditor; -typedef struct _TaskEditorClass TaskEditorClass; -typedef struct _TaskEditorPrivate TaskEditorPrivate; - -struct _TaskEditor { - CompEditor parent; - - /* Private data */ - TaskEditorPrivate *priv; -}; - -struct _TaskEditorClass { - CompEditorClass parent_class; -}; - -GtkType task_editor_get_type (void); -TaskEditor *task_editor_construct (TaskEditor *te); -TaskEditor *task_editor_new (void); -void task_editor_show_assignment(TaskEditor *te); - - -#endif /* __TASK_EDITOR_H__ */ diff --git a/calendar/gui/dialogs/task-page.c b/calendar/gui/dialogs/task-page.c deleted file mode 100644 index 6b55b58c84..0000000000 --- a/calendar/gui/dialogs/task-page.c +++ /dev/null @@ -1,992 +0,0 @@ -/* Evolution calendar - Main page of the task editor dialog - * - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * Miguel de Icaza <miguel@ximian.com> - * Seth Alves <alves@hungry.com> - * JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <gtk/gtksignal.h> -#include <gtk/gtktext.h> -#include <gtk/gtktogglebutton.h> -#include <gtk/gtkspinbutton.h> -#include <gtk/gtkoptionmenu.h> -#include <glade/glade.h> -#include <gal/widgets/e-unicode.h> -#include <gal/widgets/e-categories.h> -#include <widgets/misc/e-dateedit.h> -#include "e-util/e-dialog-widgets.h" -#include "e-util/e-categories-config.h" -#include "../e-timezone-entry.h" -#include "../calendar-config.h" -#include "comp-editor-util.h" -#include "task-page.h" - - - -/* Private part of the TaskPage structure */ -struct _TaskPagePrivate { - /* Glade XML data */ - GladeXML *xml; - - /* Widgets from the Glade file */ - GtkWidget *main; - - GtkWidget *summary; - - GtkWidget *due_date; - GtkWidget *start_date; - GtkWidget *due_timezone; - GtkWidget *start_timezone; - - GtkWidget *description; - - GtkWidget *classification_public; - GtkWidget *classification_private; - GtkWidget *classification_confidential; - - GtkWidget *contacts_btn; - GtkWidget *contacts_box; - - GtkWidget *categories_btn; - GtkWidget *categories; - - gboolean updating; - - /* The Corba component for selecting contacts, and the entry field - which we place in the dialog. */ - GNOME_Evolution_Addressbook_SelectNames corba_select_names; - GtkWidget *contacts_entry; -}; - -static const int classification_map[] = { - CAL_COMPONENT_CLASS_PUBLIC, - CAL_COMPONENT_CLASS_PRIVATE, - CAL_COMPONENT_CLASS_CONFIDENTIAL, - -1 -}; - - - -static void task_page_class_init (TaskPageClass *class); -static void task_page_init (TaskPage *tpage); -static void task_page_destroy (GtkObject *object); - -static GtkWidget *task_page_get_widget (CompEditorPage *page); -static void task_page_focus_main_widget (CompEditorPage *page); -static void task_page_fill_widgets (CompEditorPage *page, CalComponent *comp); -static gboolean task_page_fill_component (CompEditorPage *page, CalComponent *comp); -static void task_page_set_summary (CompEditorPage *page, const char *summary); -static void task_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates); - -static CompEditorPageClass *parent_class = NULL; - - - -/** - * task_page_get_type: - * - * Registers the #TaskPage class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the #TaskPage class. - **/ -GtkType -task_page_get_type (void) -{ - static GtkType task_page_type; - - if (!task_page_type) { - static const GtkTypeInfo task_page_info = { - "TaskPage", - sizeof (TaskPage), - sizeof (TaskPageClass), - (GtkClassInitFunc) task_page_class_init, - (GtkObjectInitFunc) task_page_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - task_page_type = gtk_type_unique (TYPE_COMP_EDITOR_PAGE, - &task_page_info); - } - - return task_page_type; -} - -/* Class initialization function for the task page */ -static void -task_page_class_init (TaskPageClass *class) -{ - CompEditorPageClass *editor_page_class; - GtkObjectClass *object_class; - - editor_page_class = (CompEditorPageClass *) class; - object_class = (GtkObjectClass *) class; - - parent_class = gtk_type_class (TYPE_COMP_EDITOR_PAGE); - - editor_page_class->get_widget = task_page_get_widget; - editor_page_class->focus_main_widget = task_page_focus_main_widget; - editor_page_class->fill_widgets = task_page_fill_widgets; - editor_page_class->fill_component = task_page_fill_component; - editor_page_class->set_summary = task_page_set_summary; - editor_page_class->set_dates = task_page_set_dates; - - object_class->destroy = task_page_destroy; -} - -/* Object initialization function for the task page */ -static void -task_page_init (TaskPage *tpage) -{ - TaskPagePrivate *priv; - - priv = g_new0 (TaskPagePrivate, 1); - tpage->priv = priv; - - priv->xml = NULL; - - priv->main = NULL; - priv->summary = NULL; - priv->due_date = NULL; - priv->start_date = NULL; - priv->due_timezone = NULL; - priv->start_timezone = NULL; - priv->description = NULL; - priv->classification_public = NULL; - priv->classification_private = NULL; - priv->classification_confidential = NULL; - priv->contacts_btn = NULL; - priv->contacts_box = NULL; - priv->categories_btn = NULL; - priv->categories = NULL; - - priv->updating = FALSE; - - priv->corba_select_names = CORBA_OBJECT_NIL; - priv->contacts_entry = NULL; -} - -/* Destroy handler for the task page */ -static void -task_page_destroy (GtkObject *object) -{ - TaskPage *tpage; - TaskPagePrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_TASK_PAGE (object)); - - tpage = TASK_PAGE (object); - priv = tpage->priv; - - if (priv->corba_select_names != CORBA_OBJECT_NIL) { - CORBA_Environment ev; - - CORBA_exception_init (&ev); - CORBA_Object_release (priv->corba_select_names, &ev); - CORBA_exception_free (&ev); - } - - if (priv->xml) { - gtk_object_unref (GTK_OBJECT (priv->xml)); - priv->xml = NULL; - } - - g_free (priv); - tpage->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - - -/* get_widget handler for the task page */ -static GtkWidget * -task_page_get_widget (CompEditorPage *page) -{ - TaskPage *tpage; - TaskPagePrivate *priv; - - tpage = TASK_PAGE (page); - priv = tpage->priv; - - return priv->main; -} - -/* focus_main_widget handler for the task page */ -static void -task_page_focus_main_widget (CompEditorPage *page) -{ - TaskPage *tpage; - TaskPagePrivate *priv; - - tpage = TASK_PAGE (page); - priv = tpage->priv; - - gtk_widget_grab_focus (priv->summary); -} - -/* Fills the widgets with default values */ -static void -clear_widgets (TaskPage *tpage) -{ - TaskPagePrivate *priv; - - priv = tpage->priv; - - /* Summary, description */ - e_dialog_editable_set (priv->summary, NULL); - e_dialog_editable_set (priv->description, NULL); - - /* Start, due times */ - e_date_edit_set_time (E_DATE_EDIT (priv->start_date), 0); - e_date_edit_set_time (E_DATE_EDIT (priv->due_date), 0); - - /* Classification */ - e_dialog_radio_set (priv->classification_public, - CAL_COMPONENT_CLASS_PRIVATE, classification_map); - - /* Categories */ - e_dialog_editable_set (priv->categories, NULL); -} - -/* Decode the radio button group for classifications */ -static CalComponentClassification -classification_get (GtkWidget *widget) -{ - return e_dialog_radio_get (widget, classification_map); -} - -static void -contacts_changed_cb (BonoboListener *listener, - char *event_name, - CORBA_any *arg, - CORBA_Environment *ev, - gpointer data) -{ - TaskPage *tpage; - TaskPagePrivate *priv; - - tpage = TASK_PAGE (data); - priv = tpage->priv; - - if (!priv->updating) - comp_editor_page_notify_changed (COMP_EDITOR_PAGE (tpage)); -} - -/* fill_widgets handler for the task page */ -static void -task_page_fill_widgets (CompEditorPage *page, CalComponent *comp) -{ - TaskPage *tpage; - TaskPagePrivate *priv; - CalComponentText text; - CalComponentDateTime d; - CalComponentClassification cl; - CalClientGetStatus get_tz_status; - GSList *l; - const char *categories; - icaltimezone *zone, *default_zone; - char *location; - - tpage = TASK_PAGE (page); - priv = tpage->priv; - - priv->updating = TRUE; - - /* Clean the screen */ - clear_widgets (tpage); - - /* Summary, description(s) */ - cal_component_get_summary (comp, &text); - e_dialog_editable_set (priv->summary, text.value); - - cal_component_get_description_list (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); - - location = calendar_config_get_timezone (); - default_zone = icaltimezone_get_builtin_timezone (location); - - /* Due Date. */ - cal_component_get_due (comp, &d); - zone = NULL; - if (d.value) { - struct icaltimetype *due_tt = d.value; - e_date_edit_set_date (E_DATE_EDIT (priv->due_date), - due_tt->year, due_tt->month, - due_tt->day); - if (due_tt->is_date) { - e_date_edit_set_time_of_day (E_DATE_EDIT (priv->due_date), - -1, -1); - zone = default_zone; - } else { - e_date_edit_set_time_of_day (E_DATE_EDIT (priv->due_date), - due_tt->hour, - due_tt->minute); - } - } else { - e_date_edit_set_time (E_DATE_EDIT (priv->due_date), -1); - - /* If no time is set, we use the default timezone, so the - user usually doesn't have to set this when they set the - date. */ - zone = default_zone; - } - - /* Note that if we are creating a new task, the timezones may not be - on the server, so we try to get the builtin timezone with the TZID - first. */ - if (!zone) - zone = icaltimezone_get_builtin_timezone_from_tzid (d.tzid); - if (!zone) { - get_tz_status = cal_client_get_timezone (page->client, d.tzid, - &zone); - /* FIXME: Handle error better. */ - if (get_tz_status != CAL_CLIENT_GET_SUCCESS) - g_warning ("Couldn't get timezone from server: %s", - d.tzid ? d.tzid : ""); - } - e_timezone_entry_set_timezone (E_TIMEZONE_ENTRY (priv->due_timezone), - zone); - - cal_component_free_datetime (&d); - - - /* Start Date. */ - cal_component_get_dtstart (comp, &d); - zone = NULL; - if (d.value) { - struct icaltimetype *start_tt = d.value; - e_date_edit_set_date (E_DATE_EDIT (priv->start_date), - start_tt->year, start_tt->month, - start_tt->day); - if (start_tt->is_date) { - e_date_edit_set_time_of_day (E_DATE_EDIT (priv->start_date), - -1, -1); - zone = default_zone; - } else { - e_date_edit_set_time_of_day (E_DATE_EDIT (priv->start_date), - start_tt->hour, - start_tt->minute); - } - } else { - e_date_edit_set_time (E_DATE_EDIT (priv->start_date), -1); - - /* If no time is set, we use the default timezone, so the - user usually doesn't have to set this when they set the - date. */ - zone = default_zone; - } - - if (!zone) - zone = icaltimezone_get_builtin_timezone_from_tzid (d.tzid); - if (!zone) { - get_tz_status = cal_client_get_timezone (page->client, d.tzid, - &zone); - /* FIXME: Handle error better. */ - if (get_tz_status != CAL_CLIENT_GET_SUCCESS) - g_warning ("Couldn't get timezone from server: %s", - d.tzid ? d.tzid : ""); - } - e_timezone_entry_set_timezone (E_TIMEZONE_ENTRY (priv->start_timezone), - zone); - - cal_component_free_datetime (&d); - - /* Classification. */ - cal_component_get_classification (comp, &cl); - - switch (cl) { - case CAL_COMPONENT_CLASS_PUBLIC: - e_dialog_radio_set (priv->classification_public, - CAL_COMPONENT_CLASS_PUBLIC, - classification_map); - break; - - case CAL_COMPONENT_CLASS_PRIVATE: - e_dialog_radio_set (priv->classification_public, - CAL_COMPONENT_CLASS_PRIVATE, - classification_map); - break; - - case CAL_COMPONENT_CLASS_CONFIDENTIAL: - e_dialog_radio_set (priv->classification_public, - CAL_COMPONENT_CLASS_CONFIDENTIAL, - classification_map); - break; - - default: - /* default to PUBLIC */ - e_dialog_radio_set (priv->classification_public, - CAL_COMPONENT_CLASS_PUBLIC, - classification_map); - break; - } - - /* Categories */ - cal_component_get_categories (comp, &categories); - e_dialog_editable_set (priv->categories, categories); - - - /* Contacts */ - comp_editor_contacts_to_widget (priv->contacts_entry, comp); - - /* We connect the contacts changed signal here, as we have to be a bit - more careful with it due to the use or Corba. The priv->updating - flag won't work as we won't get the changed event immediately. - FIXME: Unfortunately this doesn't work either. We never get the - changed event now. */ - comp_editor_connect_contacts_changed (priv->contacts_entry, - contacts_changed_cb, tpage); - - - priv->updating = FALSE; -} - -/* fill_component handler for the task page */ -static gboolean -task_page_fill_component (CompEditorPage *page, CalComponent *comp) -{ - TaskPage *tpage; - TaskPagePrivate *priv; - CalComponentDateTime date; - struct icaltimetype icaltime; - char *cat, *str; - gboolean date_set, time_set; - icaltimezone *zone; - - tpage = TASK_PAGE (page); - priv = tpage->priv; - - /* 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 */ - - icaltime = icaltime_null_time (); - - date.value = &icaltime; - date.tzid = NULL; - - /* Due Date. */ - date_set = e_date_edit_get_date (E_DATE_EDIT (priv->due_date), - &icaltime.year, - &icaltime.month, - &icaltime.day); - time_set = e_date_edit_get_time_of_day (E_DATE_EDIT (priv->due_date), - &icaltime.hour, - &icaltime.minute); - if (date_set) { - if (time_set) { - zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->due_timezone)); - date.tzid = icaltimezone_get_tzid (zone); - } else { - icaltime.is_date = TRUE; - date.tzid = NULL; - } - cal_component_set_due (comp, &date); - } else { - cal_component_set_due (comp, NULL); - } - - /* Start Date. */ - icaltime = icaltime_null_time (); - date_set = e_date_edit_get_date (E_DATE_EDIT (priv->start_date), - &icaltime.year, - &icaltime.month, - &icaltime.day); - time_set = e_date_edit_get_time_of_day (E_DATE_EDIT (priv->start_date), - &icaltime.hour, - &icaltime.minute); - if (date_set) { - if (time_set) { - zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->start_timezone)); - date.tzid = icaltimezone_get_tzid (zone); - } else { - icaltime.is_date = TRUE; - date.tzid = NULL; - } - cal_component_set_dtstart (comp, &date); - } else { - cal_component_set_dtstart (comp, NULL); - } - - /* Classification. */ - cal_component_set_classification (comp, classification_get (priv->classification_public)); - - /* Categories */ - cat = e_dialog_editable_get (priv->categories); - str = comp_editor_strip_categories (cat); - if (cat) - g_free (cat); - - cal_component_set_categories (comp, str); - - if (str) - g_free (str); - - /* Contacts */ - comp_editor_contacts_to_component (priv->contacts_entry, comp); - - return TRUE; -} - -/* set_summary handler for the task page */ -static void -task_page_set_summary (CompEditorPage *page, const char *summary) -{ - /* nothing */ -} - -static void -task_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates) -{ - TaskPage *tpage; - TaskPagePrivate *priv; - - tpage = TASK_PAGE (page); - priv = tpage->priv; - - if (priv->updating) - return; - - priv->updating = TRUE; - - priv->updating = FALSE; -} - - - -/* Gets the widgets from the XML file and returns if they are all available. */ -static gboolean -get_widgets (TaskPage *tpage) -{ - CompEditorPage *page = COMP_EDITOR_PAGE (tpage); - TaskPagePrivate *priv; - GSList *accel_groups; - GtkWidget *toplevel; - - priv = tpage->priv; - -#define GW(name) glade_xml_get_widget (priv->xml, name) - - priv->main = GW ("task-page"); - if (!priv->main) - return FALSE; - - /* Get the GtkAccelGroup from the toplevel window, so we can install - it when the notebook page is mapped. */ - toplevel = gtk_widget_get_toplevel (priv->main); - accel_groups = gtk_accel_groups_from_object (GTK_OBJECT (toplevel)); - if (accel_groups) { - page->accel_group = accel_groups->data; - gtk_accel_group_ref (page->accel_group); - } - - gtk_widget_ref (priv->main); - gtk_widget_unparent (priv->main); - - priv->summary = GW ("summary"); - - priv->due_date = GW ("due-date"); - priv->start_date = GW ("start-date"); - priv->due_timezone = GW ("due-timezone"); - priv->start_timezone = GW ("start-timezone"); - - priv->description = GW ("description"); - - priv->classification_public = GW ("classification-public"); - priv->classification_private = GW ("classification-private"); - priv->classification_confidential = GW ("classification-confidential"); - - priv->contacts_btn = GW ("contacts-button"); - priv->contacts_box = GW ("contacts-box"); - - priv->categories_btn = GW ("categories-button"); - priv->categories = GW ("categories"); - -#undef GW - - return (priv->summary - && priv->due_date - && priv->start_date - && priv->due_timezone - && priv->start_timezone - && priv->classification_public - && priv->classification_private - && priv->classification_confidential - && priv->description - && priv->contacts_btn - && priv->contacts_box - && priv->categories_btn - && priv->categories); -} - -/* Callback used when the summary changes; we emit the notification signal. */ -static void -summary_changed_cb (GtkEditable *editable, gpointer data) -{ - TaskPage *tpage; - TaskPagePrivate *priv; - gchar *summary; - - tpage = TASK_PAGE (data); - priv = tpage->priv; - - if (priv->updating) - return; - - summary = e_dialog_editable_get (GTK_WIDGET (editable)); - comp_editor_page_notify_summary_changed (COMP_EDITOR_PAGE (tpage), - summary); - g_free (summary); -} - -/* Callback used when the start or due date widgets change. We notify the - * other pages in the task editor, so they can update any labels. - */ -static void -date_changed_cb (EDateEdit *dedit, gpointer data) -{ - TaskPage *tpage; - TaskPagePrivate *priv; - CompEditorPageDates dates; - gboolean date_set, time_set; - CalComponentDateTime start_dt, due_dt; - struct icaltimetype start_tt = icaltime_null_time(); - struct icaltimetype due_tt = icaltime_null_time(); - - tpage = TASK_PAGE (data); - priv = tpage->priv; - - if (priv->updating) - return; - - date_set = e_date_edit_get_date (E_DATE_EDIT (priv->start_date), - &start_tt.year, - &start_tt.month, - &start_tt.day); - time_set = e_date_edit_get_time_of_day (E_DATE_EDIT (priv->start_date), - &start_tt.hour, - &start_tt.minute); - if (date_set) { - if (time_set) { - icaltimezone *zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->start_timezone)); - start_dt.tzid = icaltimezone_get_tzid (zone); - } else { - start_tt.is_date = TRUE; - start_dt.tzid = NULL; - } - } else { - start_tt = icaltime_null_time (); - start_dt.tzid = NULL; - } - - date_set = e_date_edit_get_date (E_DATE_EDIT (priv->due_date), - &due_tt.year, - &due_tt.month, - &due_tt.day); - time_set = e_date_edit_get_time_of_day (E_DATE_EDIT (priv->due_date), - &due_tt.hour, - &due_tt.minute); - if (date_set) { - if (time_set) { - icaltimezone *zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->due_timezone)); - due_dt.tzid = icaltimezone_get_tzid (zone); - } else { - due_tt.is_date = TRUE; - due_dt.tzid = NULL; - } - } else { - due_tt = icaltime_null_time (); - due_dt.tzid = NULL; - } - - start_dt.value = &start_tt; - dates.start = &start_dt; - dates.end = NULL; - due_dt.value = &due_tt; - dates.due = &due_dt; - dates.complete = NULL; - - /* Notify upstream */ - comp_editor_page_notify_dates_changed (COMP_EDITOR_PAGE (tpage), - &dates); -} - -/* Callback used when the contacts button is clicked; we must bring up the - * contact list dialog. - */ -static void -contacts_clicked_cb (GtkWidget *button, gpointer data) -{ - TaskPage *tpage; - TaskPagePrivate *priv; - - tpage = TASK_PAGE (data); - priv = tpage->priv; - - comp_editor_show_contacts_dialog (priv->corba_select_names); - - /* FIXME: Currently we aren't getting the changed event from the - SelectNames component correctly, so we aren't saving the event - if just the contacts are changed. To work around that, we assume - that if the contacts button is clicked it is changed. */ - comp_editor_page_notify_changed (COMP_EDITOR_PAGE (tpage)); -} - -/* Callback used when the categories button is clicked; we must bring up the - * category list dialog. - */ -static void -categories_clicked_cb (GtkWidget *button, gpointer data) -{ - TaskPage *tpage; - TaskPagePrivate *priv; - GtkWidget *entry; - - tpage = TASK_PAGE (data); - priv = tpage->priv; - - entry = priv->categories; - e_categories_config_open_dialog_for_entry (GTK_ENTRY (entry)); -} - -/* This is called when any field is changed; it notifies upstream. */ -static void -field_changed_cb (GtkWidget *widget, gpointer data) -{ - TaskPage *tpage; - TaskPagePrivate *priv; - - tpage = TASK_PAGE (data); - priv = tpage->priv; - - if (!priv->updating) - comp_editor_page_notify_changed (COMP_EDITOR_PAGE (tpage)); -} - -/* Hooks the widget signals */ -static gboolean -init_widgets (TaskPage *tpage) -{ - TaskPagePrivate *priv; - char *location; - icaltimezone *zone; - - priv = tpage->priv; - - /* Make sure the EDateEdit widgets use our timezones to get the - current time. */ - e_date_edit_set_get_time_callback (E_DATE_EDIT (priv->start_date), - (EDateEditGetTimeCallback) comp_editor_get_current_time, - tpage, NULL); - e_date_edit_set_get_time_callback (E_DATE_EDIT (priv->due_date), - (EDateEditGetTimeCallback) comp_editor_get_current_time, - tpage, NULL); - - /* Summary */ - gtk_signal_connect (GTK_OBJECT (priv->summary), "changed", - GTK_SIGNAL_FUNC (summary_changed_cb), tpage); - - /* Description - turn on word wrap. */ - gtk_text_set_word_wrap (GTK_TEXT (priv->description), TRUE); - - /* Dates */ - gtk_signal_connect (GTK_OBJECT (priv->start_date), "changed", - GTK_SIGNAL_FUNC (date_changed_cb), tpage); - gtk_signal_connect (GTK_OBJECT (priv->due_date), "changed", - GTK_SIGNAL_FUNC (date_changed_cb), tpage); - - gtk_signal_connect (GTK_OBJECT (priv->due_timezone), "changed", - GTK_SIGNAL_FUNC (field_changed_cb), tpage); - gtk_signal_connect (GTK_OBJECT (priv->start_timezone), "changed", - GTK_SIGNAL_FUNC (field_changed_cb), tpage); - - /* Classification */ - gtk_signal_connect (GTK_OBJECT (priv->classification_public), - "toggled", - GTK_SIGNAL_FUNC (field_changed_cb), tpage); - gtk_signal_connect (GTK_OBJECT (priv->classification_private), - "toggled", - GTK_SIGNAL_FUNC (field_changed_cb), tpage); - gtk_signal_connect (GTK_OBJECT (priv->classification_confidential), - "toggled", - GTK_SIGNAL_FUNC (field_changed_cb), tpage); - - /* 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->description), "changed", - GTK_SIGNAL_FUNC (field_changed_cb), tpage); - gtk_signal_connect (GTK_OBJECT (priv->categories), "changed", - GTK_SIGNAL_FUNC (field_changed_cb), tpage); - - /* Contacts button */ - gtk_signal_connect (GTK_OBJECT (priv->contacts_btn), "clicked", - GTK_SIGNAL_FUNC (contacts_clicked_cb), tpage); - - /* Categories button */ - gtk_signal_connect (GTK_OBJECT (priv->categories_btn), "clicked", - GTK_SIGNAL_FUNC (categories_clicked_cb), tpage); - - - /* Create the contacts entry, a corba control from the address book. */ - priv->corba_select_names = comp_editor_create_contacts_component (); - if (priv->corba_select_names == CORBA_OBJECT_NIL) - return FALSE; - - priv->contacts_entry = comp_editor_create_contacts_control (priv->corba_select_names); - if (priv->contacts_entry == NULL) - return FALSE; - - gtk_container_add (GTK_CONTAINER (priv->contacts_box), - priv->contacts_entry); - - /* Set the default timezone, so the timezone entry may be hidden. */ - location = calendar_config_get_timezone (); - zone = icaltimezone_get_builtin_timezone (location); - e_timezone_entry_set_default_timezone (E_TIMEZONE_ENTRY (priv->start_timezone), zone); - e_timezone_entry_set_default_timezone (E_TIMEZONE_ENTRY (priv->due_timezone), zone); - - return TRUE; -} - - - -/** - * task_page_construct: - * @tpage: An task page. - * - * Constructs an task page by loading its Glade data. - * - * Return value: The same object as @tpage, or NULL if the widgets could not be - * created. - **/ -TaskPage * -task_page_construct (TaskPage *tpage) -{ - TaskPagePrivate *priv; - - priv = tpage->priv; - - priv->xml = glade_xml_new (EVOLUTION_GLADEDIR "/task-page.glade", - NULL); - if (!priv->xml) { - g_message ("task_page_construct(): " - "Could not load the Glade XML file!"); - return NULL; - } - - if (!get_widgets (tpage)) { - g_message ("task_page_construct(): " - "Could not find all widgets in the XML file!"); - return NULL; - } - - if (!init_widgets (tpage)) { - g_message ("event_page_construct(): " - "Could not initialize the widgets!"); - return NULL; - } - - return tpage; -} - -/** - * task_page_new: - * - * Creates a new task page. - * - * Return value: A newly-created task page, or NULL if the page could - * not be created. - **/ -TaskPage * -task_page_new (void) -{ - TaskPage *tpage; - - tpage = gtk_type_new (TYPE_TASK_PAGE); - if (!task_page_construct (tpage)) { - gtk_object_unref (GTK_OBJECT (tpage)); - return NULL; - } - - return tpage; -} - -GtkWidget *task_page_create_date_edit (void); - -GtkWidget * -task_page_create_date_edit (void) -{ - GtkWidget *dedit; - - dedit = comp_editor_new_date_edit (TRUE, TRUE, TRUE); - e_date_edit_set_allow_no_date_set (E_DATE_EDIT (dedit), TRUE); - - return dedit; -} diff --git a/calendar/gui/dialogs/task-page.glade b/calendar/gui/dialogs/task-page.glade deleted file mode 100644 index 31a7ba2cbe..0000000000 --- a/calendar/gui/dialogs/task-page.glade +++ /dev/null @@ -1,493 +0,0 @@ -<?xml version="1.0"?> -<GTK-Interface> - -<project> - <name>task-page</name> - <program_name>task-page</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>task-toplevel</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>GtkVBox</class> - <name>task-page</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>3</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> - <focus_target>start-date</focus_target> - <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> - <focus_target>due-date</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>Custom</class> - <name>due-date</name> - <can_focus>True</can_focus> - <creation_function>task_page_create_date_edit</creation_function> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Fri, 01 Jun 2001 18:59:52 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> - <can_focus>True</can_focus> - <creation_function>task_page_create_date_edit</creation_function> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Fri, 01 Jun 2001 18:59:57 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> - <class>Custom</class> - <name>due-timezone</name> - <creation_function>make_timezone_entry</creation_function> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Tue, 19 Jun 2001 04:43:54 GMT</last_modification_time> - <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>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>Custom</class> - <name>start-timezone</name> - <creation_function>make_timezone_entry</creation_function> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Tue, 19 Jun 2001 04:43:46 GMT</last_modification_time> - <child> - <left_attach>2</left_attach> - <right_attach>3</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> - </widget> - </widget> - - <widget> - <class>GtkVBox</class> - <name>vbox1</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label18</name> - <label>Description:</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>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>True</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> - - <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>Con_fidential</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>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkButton</class> - <name>contacts-button</name> - <can_focus>True</can_focus> - <relief>GTK_RELIEF_NORMAL</relief> - <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>GtkEventBox</class> - <name>contacts-box</name> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>Placeholder</class> - </widget> - </widget> - - <widget> - <class>GtkButton</class> - <name>categories-button</name> - <can_focus>True</can_focus> - <relief>GTK_RELIEF_NORMAL</relief> - <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> - -</GTK-Interface> diff --git a/calendar/gui/dialogs/task-page.h b/calendar/gui/dialogs/task-page.h deleted file mode 100644 index 55c8ebc923..0000000000 --- a/calendar/gui/dialogs/task-page.h +++ /dev/null @@ -1,60 +0,0 @@ -/* Evolution calendar - Main page of the task editor dialog - * - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * Miguel de Icaza <miguel@ximian.com> - * Seth Alves <alves@hungry.com> - * JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef TASK_PAGE_H -#define TASK_PAGE_H - -#include "comp-editor-page.h" - -BEGIN_GNOME_DECLS - - - -#define TYPE_TASK_PAGE (task_page_get_type ()) -#define TASK_PAGE(obj) (GTK_CHECK_CAST ((obj), TYPE_TASK_PAGE, TaskPage)) -#define TASK_PAGE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_TASK_PAGE, TaskPageClass)) -#define IS_TASK_PAGE(obj) (GTK_CHECK_TYPE ((obj), TYPE_TASK_PAGE)) -#define IS_TASK_PAGE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), TYPE_TASK_PAGE)) - -typedef struct _TaskPagePrivate TaskPagePrivate; - -typedef struct { - CompEditorPage page; - - /* Private data */ - TaskPagePrivate *priv; -} TaskPage; - -typedef struct { - CompEditorPageClass parent_class; -} TaskPageClass; - -GtkType task_page_get_type (void); -TaskPage *task_page_construct (TaskPage *epage); -TaskPage *task_page_new (void); - - - -END_GNOME_DECLS - -#endif diff --git a/calendar/gui/e-calendar-table.c b/calendar/gui/e-calendar-table.c deleted file mode 100644 index 8a7d3dd631..0000000000 --- a/calendar/gui/e-calendar-table.c +++ /dev/null @@ -1,1345 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Authors : - * Damon Chaplin <damon@ximian.com> - * Rodrigo Moya <rodrigo@ximian.com> - * - * Copyright 2000, Ximian, Inc. - * Copyright 2000, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -/* - * 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 <gtk/gtkinvisible.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 <gal/e-table/e-cell-combo.h> -#include <gal/util/e-unicode-i18n.h> -#include <gal/widgets/e-popup-menu.h> -#include <e-util/e-dialog-utils.h> -#include <widgets/misc/e-cell-date-edit.h> -#include <widgets/misc/e-cell-percent.h> -#include "e-calendar-table.h" -#include "e-cell-date-edit-text.h" -#include "calendar-config.h" -#include "calendar-model.h" -#include "print.h" -#include "dialogs/delete-comp.h" -#include "dialogs/task-editor.h" - -/* Pixmaps. */ -#include "art/task.xpm" -#include "art/task-recurring.xpm" -#include "art/task-assigned.xpm" -#include "art/task-assigned-to.xpm" - -#include "art/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_save_as (GtkWidget *menuitem, - gpointer data); -static void e_calendar_table_on_print_task (GtkWidget *menuitem, - gpointer data); -static void e_calendar_table_on_cut (GtkWidget *menuitem, - gpointer data); -static void e_calendar_table_on_copy (GtkWidget *menuitem, - gpointer data); -static void e_calendar_table_on_paste (GtkWidget *menuitem, - gpointer data); -static void e_calendar_table_on_assign (GtkWidget *menuitem, - gpointer data); -static void e_calendar_table_on_forward (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 selection_clear_event (GtkWidget *invisible, - GdkEventSelection *event, - ECalendarTable *cal_table); -static void selection_received (GtkWidget *invisible, - GtkSelectionData *selection_data, - guint time, - ECalendarTable *cal_table); -static void selection_get (GtkWidget *invisible, - GtkSelectionData *selection_data, - guint info, - guint time_stamp, - ECalendarTable *cal_table); -static void invisible_destroyed (GtkWidget *invisible, - ECalendarTable *cal_table); -static struct tm e_calendar_table_get_current_time (ECellDateEdit *ecde, - gpointer data); -static void mark_row_complete_cb (int model_row, gpointer data); - - -/* 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; -static GdkAtom clipboard_atom = GDK_NONE; - - -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 - - /* clipboard atom */ - if (!clipboard_atom) - clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE); -} - -/* Compares two priority values, which may not exist */ -static int -compare_priorities (int *a, int *b) -{ - if (a && b) { - if (*a < *b) - return -1; - else if (*a > *b) - return 1; - else - return 0; - } else if (a) - return -1; - else if (b) - return 1; - else - return 0; -} - -/* Comparison function for the task-sort column. Sorts by due date and then by - * priority. - * - * FIXME: Does this ever get called?? It doesn't seem to. - * I specified that the table should be sorted by this column, but it still - * never calls this function. - * Also, this assumes it is passed pointers to CalComponents, but I think it - * may just be passed pointers to the 2 cell values. - */ -static gint -task_compare_cb (gconstpointer a, gconstpointer b) -{ - CalComponent *ca, *cb; - CalComponentDateTime due_a, due_b; - int *prio_a, *prio_b; - int retval; - - ca = CAL_COMPONENT (a); - cb = CAL_COMPONENT (b); - - cal_component_get_due (ca, &due_a); - cal_component_get_due (cb, &due_b); - cal_component_get_priority (ca, &prio_a); - cal_component_get_priority (cb, &prio_b); - - if (due_a.value && due_b.value) { - int v; - - /* FIXME: TIMEZONES. But currently we have no way to get the - CalClient, so we can't get the timezone. */ - v = icaltime_compare (*due_a.value, *due_b.value); - - if (v == 0) - retval = compare_priorities (prio_a, prio_b); - else - retval = v; - } else if (due_a.value) - retval = -1; - else if (due_b.value) - retval = 1; - else - retval = compare_priorities (prio_a, prio_b); - - cal_component_free_datetime (&due_a); - cal_component_free_datetime (&due_b); - - if (prio_a) - cal_component_free_priority (prio_a); - - if (prio_b) - cal_component_free_priority (prio_b); - - return retval; -} - -static gint -date_compare_cb (gconstpointer a, gconstpointer b) -{ - ECellDateEditValue *dv1 = (ECellDateEditValue *) a; - ECellDateEditValue *dv2 = (ECellDateEditValue *) b; - struct icaltimetype tt; - - /* First check if either is NULL. NULL dates sort last. */ - if (!dv1 || !dv2) { - if (dv1 == dv2) - return 0; - else if (dv1) - return -1; - else - return 1; - } - - /* Copy the 2nd value and convert it to the same timezone as the - first. */ - tt = dv2->tt; - - icaltimezone_convert_time (&tt, dv2->zone, dv1->zone); - - /* Now we can compare them. */ - - return icaltime_compare (dv1->tt, tt); -} - -static gint -percent_compare_cb (gconstpointer a, gconstpointer b) -{ - int percent1 = GPOINTER_TO_INT (a); - int percent2 = GPOINTER_TO_INT (b); - int retval; - - if (percent1 > percent2) - retval = 1; - else if (percent1 < percent2) - retval = -1; - else - retval = 0; - - return retval; -} - -static gint -priority_compare_cb (gconstpointer a, gconstpointer b) -{ - int priority1, priority2; - - priority1 = cal_util_priority_from_string ((const char*) a); - priority2 = cal_util_priority_from_string ((const char*) b); - - /* We change undefined priorities so they appear after 'Low'. */ - if (priority1 <= 0) - priority1 = 10; - if (priority2 <= 0) - priority2 = 10; - - /* We'll just use the ordering of the priority values. */ - if (priority1 < priority2) - return -1; - else if (priority1 > priority2) - return 1; - else - return 0; -} - -static void -e_calendar_table_init (ECalendarTable *cal_table) -{ - GtkWidget *table; - ETable *e_table; - ECell *cell, *popup_cell; - ETableExtras *extras; - gint i; - GdkPixbuf *pixbuf; - GList *strings; - - /* Create the model */ - - cal_table->model = calendar_model_new (); - - /* Create the header columns */ - - extras = e_table_extras_new(); - - /* - * Normal string fields. - */ - 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); - - - /* - * Date fields. - */ - cell = e_cell_date_edit_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); - - popup_cell = e_cell_date_edit_new (); - e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell); - gtk_object_unref (GTK_OBJECT (cell)); - e_table_extras_add_cell (extras, "dateedit", popup_cell); - cal_table->dates_cell = E_CELL_DATE_EDIT (popup_cell); - - e_cell_date_edit_set_get_time_callback (E_CELL_DATE_EDIT (popup_cell), - e_calendar_table_get_current_time, - cal_table, NULL); - - - /* - * Combo fields. - */ - - /* Classification field. */ - 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, - "editable", FALSE, - NULL); - - popup_cell = e_cell_combo_new (); - e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell); - gtk_object_unref (GTK_OBJECT (cell)); - - strings = NULL; - strings = g_list_append (strings, (char*) U_("Public")); - strings = g_list_append (strings, (char*) U_("Private")); - strings = g_list_append (strings, (char*) U_("Confidential")); - e_cell_combo_set_popdown_strings (E_CELL_COMBO (popup_cell), - strings); - - e_table_extras_add_cell (extras, "classification", popup_cell); - - /* Priority field. */ - 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, - "editable", FALSE, - NULL); - - popup_cell = e_cell_combo_new (); - e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell); - gtk_object_unref (GTK_OBJECT (cell)); - - strings = NULL; - strings = g_list_append (strings, (char*) U_("High")); - strings = g_list_append (strings, (char*) U_("Normal")); - strings = g_list_append (strings, (char*) U_("Low")); - strings = g_list_append (strings, (char*) U_("Undefined")); - e_cell_combo_set_popdown_strings (E_CELL_COMBO (popup_cell), - strings); - - e_table_extras_add_cell (extras, "priority", popup_cell); - - /* Percent field. */ - cell = e_cell_percent_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); - - popup_cell = e_cell_combo_new (); - e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell); - gtk_object_unref (GTK_OBJECT (cell)); - - strings = NULL; - strings = g_list_append (strings, (char*) U_("0%")); - strings = g_list_append (strings, (char*) U_("10%")); - strings = g_list_append (strings, (char*) U_("20%")); - strings = g_list_append (strings, (char*) U_("30%")); - strings = g_list_append (strings, (char*) U_("40%")); - strings = g_list_append (strings, (char*) U_("50%")); - strings = g_list_append (strings, (char*) U_("60%")); - strings = g_list_append (strings, (char*) U_("70%")); - strings = g_list_append (strings, (char*) U_("80%")); - strings = g_list_append (strings, (char*) U_("90%")); - strings = g_list_append (strings, (char*) U_("100%")); - e_cell_combo_set_popdown_strings (E_CELL_COMBO (popup_cell), - strings); - - e_table_extras_add_cell (extras, "percent", popup_cell); - - /* Transparency field. */ - 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, - "editable", FALSE, - NULL); - - popup_cell = e_cell_combo_new (); - e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell); - gtk_object_unref (GTK_OBJECT (cell)); - - strings = NULL; - strings = g_list_append (strings, (char*) U_("Free")); - strings = g_list_append (strings, (char*) U_("Busy")); - e_cell_combo_set_popdown_strings (E_CELL_COMBO (popup_cell), - strings); - - e_table_extras_add_cell (extras, "transparency", popup_cell); - - /* Status field. */ - 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, - "editable", FALSE, - NULL); - - popup_cell = e_cell_combo_new (); - e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell); - gtk_object_unref (GTK_OBJECT (cell)); - - strings = NULL; - strings = g_list_append (strings, (char*) U_("Not Started")); - strings = g_list_append (strings, (char*) U_("In Progress")); - strings = g_list_append (strings, (char*) U_("Completed")); - strings = g_list_append (strings, (char*) U_("Cancelled")); - e_cell_combo_set_popdown_strings (E_CELL_COMBO (popup_cell), - strings); - - e_table_extras_add_cell (extras, "calstatus", popup_cell); - - /* Task sorting field */ - /* FIXME: This column should not be displayed, but ETableExtras requires - * its shit to be visible columns listed in the XML spec. - */ - e_table_extras_add_compare (extras, "task-sort", task_compare_cb); - - e_table_extras_add_compare (extras, "date-compare", - date_compare_cb); - e_table_extras_add_compare (extras, "percent-compare", - percent_compare_cb); - e_table_extras_add_compare (extras, "priority-compare", - priority_compare_cb); - - /* 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_from_spec_file (E_TABLE_MODEL (cal_table->model), - extras, - EVOLUTION_ETSPECDIR "/e-calendar-table.etspec", - 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); - - /* Set up the invisible widget for the clipboard selections */ - cal_table->invisible = gtk_invisible_new (); - gtk_selection_add_target (cal_table->invisible, - clipboard_atom, - GDK_SELECTION_TYPE_STRING, - 0); - gtk_signal_connect (GTK_OBJECT (cal_table->invisible), - "selection_get", - GTK_SIGNAL_FUNC (selection_get), - (gpointer) cal_table); - gtk_signal_connect (GTK_OBJECT (cal_table->invisible), - "selection_clear_event", - GTK_SIGNAL_FUNC (selection_clear_event), - (gpointer) cal_table); - gtk_signal_connect (GTK_OBJECT (cal_table->invisible), - "selection_received", - GTK_SIGNAL_FUNC (selection_received), - (gpointer) cal_table); - gtk_signal_connect (GTK_OBJECT (cal_table->invisible), - "destroy", - GTK_SIGNAL_FUNC (invisible_destroyed), - (gpointer) cal_table); - cal_table->clipboard_selection = NULL; -} - - -/** - * 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; - - if (cal_table->invisible) - gtk_widget_destroy (cal_table->invisible); - if (cal_table->clipboard_selection) { - g_free (cal_table->clipboard_selection); - cal_table->clipboard_selection = NULL; - } - - GTK_OBJECT_CLASS (parent_class)->destroy (object); -} - -/** - * e_calendar_table_get_table: - * @cal_table: A calendar table. - * - * Queries the #ETable widget that the calendar table is using. - * - * Return value: The #ETable widget that the calendar table uses to display its - * data. - **/ -ETable * -e_calendar_table_get_table (ECalendarTable *cal_table) -{ - g_return_val_if_fail (cal_table != NULL, NULL); - g_return_val_if_fail (E_IS_CALENDAR_TABLE (cal_table), NULL); - - return e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable)); -} - -/** - * e_calendar_table_complete_selected: - * @cal_table: A calendar table - * - * Marks the selected items as completed - **/ -void -e_calendar_table_complete_selected (ECalendarTable *cal_table) -{ - ETable *etable; - - g_return_if_fail (cal_table != NULL); - g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table)); - - etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable)); - e_table_selected_row_foreach (etable, mark_row_complete_cb, cal_table); -} - -/* Used from e_table_selected_row_foreach(); puts the selected row number in an - * int pointed to by the closure data. - */ -static void -get_selected_row_cb (int model_row, gpointer data) -{ - int *row; - - row = data; - *row = model_row; -} - -/* Returns the component that is selected in the table; only works if there is - * one and only one selected row. - */ -static CalComponent * -get_selected_comp (ECalendarTable *cal_table) -{ - ETable *etable; - int row; - - etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable)); - if (e_table_selected_count (etable) != 1) - return NULL; - - row = -1; - e_table_selected_row_foreach (etable, - get_selected_row_cb, - &row); - g_assert (row != -1); - - return calendar_model_get_component (cal_table->model, row); -} - -struct get_selected_uids_closure { - ECalendarTable *cal_table; - GSList *uids; -}; - -/* Used from e_table_selected_row_foreach(), builds a list of the selected UIDs */ -static void -add_uid_cb (int model_row, gpointer data) -{ - struct get_selected_uids_closure *closure; - CalComponent *comp; - const char *uid; - - closure = data; - - comp = calendar_model_get_component (closure->cal_table->model, model_row); - cal_component_get_uid (comp, &uid); - - closure->uids = g_slist_prepend (closure->uids, (char *) uid); -} - -static GSList * -get_selected_uids (ECalendarTable *cal_table) -{ - struct get_selected_uids_closure closure; - ETable *etable; - - closure.cal_table = cal_table; - closure.uids = NULL; - - etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable)); - e_table_selected_row_foreach (etable, add_uid_cb, &closure); - - return closure.uids; -} - -/* Deletes all of the selected components in the table */ -static void -delete_selected_components (ECalendarTable *cal_table) -{ - CalClient *client; - GSList *uids, *l; - - uids = get_selected_uids (cal_table); - - client = calendar_model_get_cal_client (cal_table->model); - - calendar_model_set_status_message (e_calendar_table_get_model (cal_table), - _("Deleting selected objects")); - - for (l = uids; l; l = l->next) { - const char *uid; - - uid = l->data; - - /* We don't check the return value; FALSE can mean the object - * was not in the server anyways. - */ - cal_client_remove_object (client, uid); - } - - calendar_model_set_status_message (e_calendar_table_get_model (cal_table), NULL); - - g_slist_free (uids); -} - -/** - * e_calendar_table_delete_selected: - * @cal_table: A calendar table. - * - * Deletes the selected components in the table; asks the user first. - **/ -void -e_calendar_table_delete_selected (ECalendarTable *cal_table) -{ - ETable *etable; - int n_selected; - CalComponent *comp; - - g_return_if_fail (cal_table != NULL); - g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table)); - - etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable)); - - n_selected = e_table_selected_count (etable); - if (n_selected <= 0) - return; - - if (n_selected == 1) - comp = get_selected_comp (cal_table); - else - comp = NULL; - - /* FIXME: this may be something other than a TODO component */ - - if (delete_component_dialog (comp, FALSE, n_selected, CAL_COMPONENT_TODO, - GTK_WIDGET (cal_table))) - delete_selected_components (cal_table); -} - -/** - * e_calendar_table_cut_clipboard: - * @cal_table: A calendar table. - * - * Cuts selected tasks in the given calendar table - */ -void -e_calendar_table_cut_clipboard (ECalendarTable *cal_table) -{ - g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table)); - - e_calendar_table_copy_clipboard (cal_table); - delete_selected_components (cal_table); -} - -/* callback for e_table_selected_row_foreach */ -static void -copy_row_cb (int model_row, gpointer data) -{ - ECalendarTable *cal_table; - CalComponent *comp; - gchar *comp_str; - icalcomponent *child; - - cal_table = E_CALENDAR_TABLE (data); - - g_return_if_fail (cal_table->tmp_vcal != NULL); - - comp = calendar_model_get_component (cal_table->model, model_row); - if (!comp) - return; - - /* add the new component to the VCALENDAR component */ - comp_str = cal_component_get_as_string (comp); - child = icalparser_parse_string (comp_str); - if (child) { - icalcomponent_add_component (cal_table->tmp_vcal, - icalcomponent_new_clone (child)); - icalcomponent_free (child); - } - - g_free (comp_str); -} - -/** - * e_calendar_table_copy_clipboard: - * @cal_table: A calendar table. - * - * Copies selected tasks into the clipboard - */ -void -e_calendar_table_copy_clipboard (ECalendarTable *cal_table) -{ - ETable *etable; - char *comp_str; - - g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table)); - - if (cal_table->clipboard_selection) { - g_free (cal_table->clipboard_selection); - cal_table->clipboard_selection = NULL; - } - - /* create temporary VCALENDAR object */ - cal_table->tmp_vcal = cal_util_new_top_level (); - - etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable)); - e_table_selected_row_foreach (etable, copy_row_cb, cal_table); - - comp_str = icalcomponent_as_ical_string (cal_table->tmp_vcal); - cal_table->clipboard_selection = g_strdup (comp_str); - icalcomponent_free (cal_table->tmp_vcal); - cal_table->tmp_vcal = NULL; - - gtk_selection_owner_set (cal_table->invisible, clipboard_atom, GDK_CURRENT_TIME); -} - -/** - * e_calendar_table_paste_clipboard: - * @cal_table: A calendar table. - * - * Pastes tasks currently in the clipboard into the given calendar table - */ -void -e_calendar_table_paste_clipboard (ECalendarTable *cal_table) -{ - g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table)); - - gtk_selection_convert (cal_table->invisible, - clipboard_atom, - GDK_SELECTION_TYPE_STRING, - GDK_CURRENT_TIME); -} - -/* Opens a task in the task editor */ -static void -open_task (ECalendarTable *cal_table, CalComponent *comp, gboolean assign) -{ - TaskEditor *tedit; - - tedit = task_editor_new (); - comp_editor_set_cal_client (COMP_EDITOR (tedit), calendar_model_get_cal_client (cal_table->model)); - comp_editor_edit_comp (COMP_EDITOR (tedit), comp); - if (assign) - task_editor_show_assignment (TASK_EDITOR (tedit)); - comp_editor_focus (COMP_EDITOR (tedit)); -} - -/* Opens the task in the specified row */ -static void -open_task_by_row (ECalendarTable *cal_table, int row) -{ - CalComponent *comp; - - comp = calendar_model_get_component (cal_table->model, row); - open_task (cal_table, comp, FALSE); -} - -static void -e_calendar_table_on_double_click (ETable *table, - gint row, - gint col, - GdkEvent *event, - ECalendarTable *cal_table) -{ - open_task_by_row (cal_table, row); -} - -/* Used from e_table_selected_row_foreach() */ -static void -mark_row_complete_cb (int model_row, gpointer data) -{ - ECalendarTable *cal_table; - - cal_table = E_CALENDAR_TABLE (data); - calendar_model_mark_task_complete (cal_table->model, model_row); -} - -/* Callback used for the "mark tasks as complete" menu item */ -static void -mark_as_complete_cb (GtkWidget *menuitem, gpointer data) -{ - ECalendarTable *cal_table; - ETable *etable; - - cal_table = E_CALENDAR_TABLE (data); - - etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable)); - e_table_selected_row_foreach (etable, mark_row_complete_cb, cal_table); -} - -/* Callback for the "delete tasks" menu item */ -static void -delete_cb (GtkWidget *menuitem, gpointer data) -{ - ECalendarTable *cal_table; - - cal_table = E_CALENDAR_TABLE (data); - e_calendar_table_delete_selected (cal_table); -} - - -enum { - MASK_SINGLE = 1 << 0, /* For commands that work on 1 task. */ - MASK_MULTIPLE = 1 << 1, /* For commands for multiple tasks. */ -}; - - -static EPopupMenu tasks_popup_menu [] = { - E_POPUP_ITEM (N_("_Open"), e_calendar_table_on_open_task, MASK_SINGLE), - E_POPUP_ITEM (N_("_Save as..."), e_calendar_table_on_save_as, MASK_SINGLE), - E_POPUP_ITEM (N_("_Print..."), e_calendar_table_on_print_task, MASK_SINGLE), - - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("C_ut"), e_calendar_table_on_cut, 0), - E_POPUP_ITEM (N_("_Copy"), e_calendar_table_on_copy, 0), - E_POPUP_ITEM (N_("_Paste"), e_calendar_table_on_paste, 0), - - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("_Assign Task"), e_calendar_table_on_assign, MASK_SINGLE), - E_POPUP_ITEM (N_("_Forward as iCalendar"), e_calendar_table_on_forward, MASK_SINGLE), - E_POPUP_ITEM (N_("_Mark as Complete"), mark_as_complete_cb, MASK_SINGLE), - E_POPUP_ITEM (N_("_Mark Selected Tasks as Complete"), mark_as_complete_cb, MASK_MULTIPLE), - - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("_Delete"), delete_cb, MASK_SINGLE), - E_POPUP_ITEM (N_("_Delete Selected Tasks"), delete_cb, MASK_MULTIPLE), - - E_POPUP_TERMINATOR -}; - -static gint -e_calendar_table_on_right_click (ETable *table, - gint row, - gint col, - GdkEventButton *event, - ECalendarTable *cal_table) -{ - int n_selected; - int hide_mask = 0; - int disable_mask = 0; - - n_selected = e_table_selected_count (table); - if (n_selected <= 0) - return TRUE; - - if (n_selected == 1) - hide_mask = MASK_MULTIPLE; - else - hide_mask = MASK_SINGLE; - - e_popup_menu_run (tasks_popup_menu, (GdkEvent *) event, - disable_mask, hide_mask, cal_table); - - return TRUE; -} - - -static void -e_calendar_table_on_open_task (GtkWidget *menuitem, - gpointer data) -{ - ECalendarTable *cal_table; - CalComponent *comp; - - cal_table = E_CALENDAR_TABLE (data); - - comp = get_selected_comp (cal_table); - if (comp) - open_task (cal_table, comp, FALSE); -} - -static void -e_calendar_table_on_save_as (GtkWidget *widget, gpointer data) -{ - ECalendarTable *cal_table; - CalClient *client; - CalComponent *comp; - char *filename; - char *ical_string; - FILE *file; - - cal_table = E_CALENDAR_TABLE (data); - - client = calendar_model_get_cal_client (cal_table->model); - comp = get_selected_comp (cal_table); - if (comp == NULL) - return; - - filename = e_file_dialog_save (_("Save as...")); - if (filename == NULL) - return; - - ical_string = cal_client_get_component_as_string (client, comp); - if (ical_string == NULL) { - g_warning ("Couldn't convert item to a string"); - return; - } - - file = fopen (filename, "w"); - if (file == NULL) { - g_warning ("Couldn't save item"); - return; - } - - fprintf (file, ical_string); - g_free (ical_string); - fclose (file); -} - -static void -e_calendar_table_on_print_task (GtkWidget *widget, gpointer data) -{ - ECalendarTable *cal_table; - CalClient *client; - CalComponent *comp; - - cal_table = E_CALENDAR_TABLE (data); - - client = calendar_model_get_cal_client (cal_table->model); - comp = get_selected_comp (cal_table); - if (comp == NULL) - return; - - print_comp (comp, client, FALSE); -} - -static void -e_calendar_table_on_cut (GtkWidget *menuitem, gpointer data) -{ - ECalendarTable *cal_table; - - cal_table = E_CALENDAR_TABLE (data); - e_calendar_table_cut_clipboard (cal_table); -} - -static void -e_calendar_table_on_copy (GtkWidget *menuitem, gpointer data) -{ - ECalendarTable *cal_table; - - cal_table = E_CALENDAR_TABLE (data); - e_calendar_table_copy_clipboard (cal_table); -} - -static void -e_calendar_table_on_paste (GtkWidget *menuitem, gpointer data) -{ - ECalendarTable *cal_table; - - cal_table = E_CALENDAR_TABLE (data); - e_calendar_table_paste_clipboard (cal_table); -} - -static void -e_calendar_table_on_assign (GtkWidget *widget, gpointer data) -{ - ECalendarTable *cal_table; - CalComponent *comp; - - cal_table = E_CALENDAR_TABLE (data); - - comp = get_selected_comp (cal_table); - if (comp) - open_task (cal_table, comp, TRUE); -} - -static void -e_calendar_table_on_forward (GtkWidget *widget, gpointer data) -{ - ECalendarTable *cal_table; - CalClient *client; - CalComponent *comp; - - cal_table = E_CALENDAR_TABLE (data); - - client = calendar_model_get_cal_client (cal_table->model); - comp = get_selected_comp (cal_table); - if (comp) - itip_send_comp (CAL_COMPONENT_METHOD_PUBLISH, comp, - client, NULL); -} - -static gint -e_calendar_table_on_key_press (ETable *table, - gint row, - gint col, - GdkEventKey *event, - ECalendarTable *cal_table) -{ - if (event->keyval == GDK_Delete) { - delete_cb (NULL, cal_table); - return TRUE; - } - - return FALSE; -} - -/* 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); -} - - -static void -invisible_destroyed (GtkWidget *invisible, ECalendarTable *cal_table) -{ - cal_table->invisible = NULL; -} - -static void -selection_get (GtkWidget *invisible, - GtkSelectionData *selection_data, - guint info, - guint time_stamp, - ECalendarTable *cal_table) -{ - if (cal_table->clipboard_selection != NULL) { - gtk_selection_data_set (selection_data, - GDK_SELECTION_TYPE_STRING, - 8, - cal_table->clipboard_selection, - strlen (cal_table->clipboard_selection)); - } -} - -static void -selection_clear_event (GtkWidget *invisible, - GdkEventSelection *event, - ECalendarTable *cal_table) -{ - if (cal_table->clipboard_selection != NULL) { - g_free (cal_table->clipboard_selection); - cal_table->clipboard_selection = NULL; - } -} - -static void -selection_received (GtkWidget *invisible, - GtkSelectionData *selection_data, - guint time, - ECalendarTable *cal_table) -{ - char *comp_str; - icalcomponent *icalcomp; - char *uid; - CalComponent *comp; - icalcomponent_kind kind; - - g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table)); - - if (selection_data->length < 0 || - selection_data->type != GDK_SELECTION_TYPE_STRING) { - return; - } - - comp_str = (char *) selection_data->data; - icalcomp = icalparser_parse_string ((const char *) comp_str); - if (!icalcomp) - return; - - /* check the type of the component */ - kind = icalcomponent_isa (icalcomp); - if (kind != ICAL_VCALENDAR_COMPONENT && - kind != ICAL_VEVENT_COMPONENT && - kind != ICAL_VTODO_COMPONENT && - kind != ICAL_VJOURNAL_COMPONENT) { - return; - } - - calendar_model_set_status_message (e_calendar_table_get_model (cal_table), - _("Updating objects")); - - if (kind == ICAL_VCALENDAR_COMPONENT) { - icalcomponent_kind child_kind; - icalcomponent *subcomp; - icalcomponent *vcal_comp; - - vcal_comp = icalcomp; - subcomp = icalcomponent_get_first_component ( - vcal_comp, ICAL_ANY_COMPONENT); - while (subcomp) { - child_kind = icalcomponent_isa (subcomp); - if (child_kind == ICAL_VEVENT_COMPONENT || - child_kind == ICAL_VTODO_COMPONENT || - child_kind == ICAL_VJOURNAL_COMPONENT) { - CalComponent *tmp_comp; - - uid = cal_component_gen_uid (); - tmp_comp = cal_component_new (); - cal_component_set_icalcomponent ( - tmp_comp, icalcomponent_new_clone (subcomp)); - cal_component_set_uid (tmp_comp, uid); - - cal_client_update_object ( - calendar_model_get_cal_client (cal_table->model), - tmp_comp); - free (uid); - gtk_object_unref (GTK_OBJECT (tmp_comp)); - } - subcomp = icalcomponent_get_next_component ( - vcal_comp, ICAL_ANY_COMPONENT); - } - } - else { - comp = cal_component_new (); - cal_component_set_icalcomponent (comp, icalcomp); - uid = cal_component_gen_uid (); - cal_component_set_uid (comp, (const char *) uid); - free (uid); - - cal_client_update_object ( - calendar_model_get_cal_client (cal_table->model), - comp); - gtk_object_unref (GTK_OBJECT (comp)); - } - - calendar_model_set_status_message (e_calendar_table_get_model (cal_table), NULL); -} - - -/* Returns the current time, for the ECellDateEdit items. - FIXME: Should probably use the timezone of the item rather than the - current timezone, though that may be difficult to get from here. */ -static struct tm -e_calendar_table_get_current_time (ECellDateEdit *ecde, gpointer data) -{ - char *location; - icaltimezone *zone; - struct tm tmp_tm = { 0 }; - struct icaltimetype tt; - - /* Get the current timezone. */ - location = calendar_config_get_timezone (); - zone = icaltimezone_get_builtin_timezone (location); - - tt = icaltime_from_timet_with_zone (time (NULL), FALSE, zone); - - /* Now copy it to the struct tm and return it. */ - tmp_tm.tm_year = tt.year - 1900; - tmp_tm.tm_mon = tt.month - 1; - tmp_tm.tm_mday = tt.day; - tmp_tm.tm_hour = tt.hour; - tmp_tm.tm_min = tt.minute; - tmp_tm.tm_sec = tt.second; - tmp_tm.tm_isdst = -1; - - return tmp_tm; -} - - -#ifdef TRANSLATORS_ONLY - -static char *test[] = { - N_("Click to add a task") -}; - -#endif diff --git a/calendar/gui/e-calendar-table.etspec b/calendar/gui/e-calendar-table.etspec deleted file mode 100644 index 2e47b817d2..0000000000 --- a/calendar/gui/e-calendar-table.etspec +++ /dev/null @@ -1,26 +0,0 @@ -<ETableSpecification click-to-add="true" _click-to-add-message="Click 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="classification" compare="string" priority="-1"/> - <ETableColumn model_col= "2" _title="Completion Date" expansion="2.0" minimum_width="10" resizable="true" cell="dateedit" compare="date-compare" priority="-2"/> - <ETableColumn model_col= "3" _title="End Date" expansion="2.0" minimum_width="10" resizable="true" cell="dateedit" compare="date-compare" priority="-2" disabled="true"/> - <ETableColumn model_col= "4" _title="Start Date" expansion="2.0" minimum_width="10" resizable="true" cell="dateedit" compare="date-compare" priority="-2"/> - <ETableColumn model_col= "5" _title="Due Date" expansion="2.0" minimum_width="10" resizable="true" cell="dateedit" compare="date-compare" priority="-2"/> - <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="percent" compare="percent-compare" priority="-3"/> - <ETableColumn model_col= "8" _title="Priority" expansion="1.0" minimum_width="10" resizable="true" cell="priority" compare="priority-compare" priority="-3"/> - <ETableColumn model_col= "9" _title="Summary" expansion="3.0" minimum_width="10" resizable="true" cell="calstring" compare="string" priority="10"/> - <ETableColumn model_col="10" _title="Show Time As" expansion="1.0" minimum_width="10" resizable="true" cell="transparency" compare="string" priority="-1" disabled="true"/> - <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" disabled="true"/> - <ETableColumn model_col="13" pixbuf="icon" _title="Type" expansion="1.0" minimum_width="16" resizable="false" cell="icon" compare="integer" priority="-4"/> - <ETableColumn model_col="14" pixbuf="complete" _title="Complete" expansion="1.0" minimum_width="16" resizable="false" cell="checkbox" compare="integer" priority="-4"/> - <ETableColumn model_col="18" _title="Status" expansion="1.0" minimum_width="10" resizable="true" cell="calstatus" compare="string" priority="-1"/> - <ETableColumn model_col="19" _title="Task sort" cell="task-sort" compare="task-sort" priority="-4"/> - - <ETableState> - <column source="13"/> - <column source="14"/> - <column source= "9"/> - <grouping></grouping> - </ETableState> -</ETableSpecification> diff --git a/calendar/gui/e-calendar-table.h b/calendar/gui/e-calendar-table.h deleted file mode 100644 index fab3afd85d..0000000000 --- a/calendar/gui/e-calendar-table.h +++ /dev/null @@ -1,102 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 2000, Ximian, Inc. - * Copyright 2000, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ -#ifndef _E_CALENDAR_TABLE_H_ -#define _E_CALENDAR_TABLE_H_ - -#include <gtk/gtktable.h> -#include <gal/e-table/e-table-scrolled.h> -#include <widgets/misc/e-cell-date-edit.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. - */ - - -#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; - - -struct _ECalendarTable -{ - GtkTable table; - - /* The model that we use */ - CalendarModel *model; - - GtkWidget *etable; - - /* The ECell used to view & edit dates. */ - ECellDateEdit *dates_cell; - - /* The invisible widget used for cut/copy/paste */ - GtkWidget *invisible; - gchar *clipboard_selection; - icalcomponent *tmp_vcal; -}; - -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); - -ETable *e_calendar_table_get_table (ECalendarTable *cal_table); - -void e_calendar_table_complete_selected (ECalendarTable *cal_table); -void e_calendar_table_delete_selected (ECalendarTable *cal_table); - -/* Clipboard related functions */ -void e_calendar_table_cut_clipboard (ECalendarTable *cal_table); -void e_calendar_table_copy_clipboard (ECalendarTable *cal_table); -void e_calendar_table_paste_clipboard (ECalendarTable *cal_table); - -/* 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); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_CALENDAR_TABLE_H_ */ diff --git a/calendar/gui/e-cell-date-edit-text.c b/calendar/gui/e-cell-date-edit-text.c deleted file mode 100644 index 96cf911a1a..0000000000 --- a/calendar/gui/e-cell-date-edit-text.c +++ /dev/null @@ -1,235 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 2001, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -/* - * ECellDateEditText - a subclass of ECellText used to show and edit the text - * representation of the date, from a CalComponentDateTime* model value. - */ - -#include <config.h> - -#include <sys/time.h> -#include <time.h> -#include <unistd.h> -#include <string.h> -#include <libgnomeui/gnome-messagebox.h> -#include <libgnomeui/gnome-stock.h> -#include <libgnome/gnome-i18n.h> -#include <gal/util/e-util.h> -#include <gal/widgets/e-unicode.h> -#include <e-util/e-time-utils.h> -#include <cal-util/timeutil.h> - -#include "e-cell-date-edit-text.h" - - -#define PARENT_TYPE e_cell_text_get_type () - -static ECellTextClass *parent_class; - - -void -e_cell_date_edit_text_set_timezone (ECellDateEditText *ecd, - icaltimezone *zone) -{ - g_return_if_fail (E_IS_CELL_DATE_EDIT_TEXT (ecd)); - - ecd->zone = zone; -} - - -void -e_cell_date_edit_text_set_use_24_hour_format (ECellDateEditText *ecd, - gboolean use_24_hour) -{ - g_return_if_fail (E_IS_CELL_DATE_EDIT_TEXT (ecd)); - - ecd->use_24_hour_format = use_24_hour; -} - - -static char * -ecd_get_text (ECellText *cell, ETableModel *model, int col, int row) -{ - ECellDateEditText *ecd = E_CELL_DATE_EDIT_TEXT (cell); - ECellDateEditValue *dv = e_table_model_value_at (model, col, row); - struct tm tmp_tm; - char buffer[64]; - - if (!dv) - return g_strdup (""); - - /* Note that although the property may be in a different - timezone, we convert it to the current timezone to display - it in the table. If the user actually edits the value, - it will be set to the current timezone. See set_value(). */ - tmp_tm = icaltimetype_to_tm_with_zone (&dv->tt, dv->zone, ecd->zone); - - e_time_format_date_and_time (&tmp_tm, ecd->use_24_hour_format, - !dv->tt.is_date, FALSE, - buffer, sizeof (buffer)); - return e_utf8_from_locale_string (buffer); -} - - -static void -ecd_free_text (ECellText *cell, char *text) -{ - g_free (text); -} - - -/* FIXME: We need to set the "transient_for" property for the dialog. */ -static void -show_date_warning (ECellDateEditText *ecd) -{ - GtkWidget *dialog; - char buffer[64], message[256], *format; - time_t t; - struct tm *tmp_tm; - - t = time (NULL); - /* We are only using this as an example, so the timezone doesn't - matter. */ - tmp_tm = localtime (&t); - - if (ecd->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); -} - - -static void -ecd_set_value (ECellText *cell, ETableModel *model, int col, int row, - const char *text) -{ - ECellDateEditText *ecd = E_CELL_DATE_EDIT_TEXT (cell); - ETimeParseStatus status; - struct tm tmp_tm; - ECellDateEditValue *value; - gboolean is_date = TRUE; - - /* Try to parse just a date first. If the value is only a date, we - use a DATE value. */ - status = e_time_parse_date (text, &tmp_tm); - if (status == E_TIME_PARSE_INVALID) { - is_date = FALSE; - status = e_time_parse_date_and_time (text, &tmp_tm); - - if (status == E_TIME_PARSE_INVALID) { - show_date_warning (ecd); - return; - } - } - - if (status == E_TIME_PARSE_NONE) { - value = NULL; - } else { - ECellDateEditValue dv; - - dv.tt = icaltime_null_time (); - - dv.tt.year = tmp_tm.tm_year + 1900; - dv.tt.month = tmp_tm.tm_mon + 1; - dv.tt.day = tmp_tm.tm_mday; - dv.tt.hour = tmp_tm.tm_hour; - dv.tt.minute = tmp_tm.tm_min; - dv.tt.second = tmp_tm.tm_sec; - dv.tt.is_date = is_date; - - /* FIXME: We assume it is being set to the current timezone. - Is that OK? */ - if (is_date) { - dv.zone = NULL; - } else { - dv.zone = ecd->zone; - } - - value = &dv; - } - - e_table_model_set_value_at (model, col, row, value); -} - - -static void -e_cell_date_edit_text_class_init (GtkObjectClass *object_class) -{ - ECellTextClass *ectc = (ECellTextClass *) object_class; - - parent_class = gtk_type_class (PARENT_TYPE); - - ectc->get_text = ecd_get_text; - ectc->free_text = ecd_free_text; - ectc->set_value = ecd_set_value; -} - - -static void -e_cell_date_edit_text_init (GtkObject *object) -{ - ECellDateEditText *ecd = E_CELL_DATE_EDIT_TEXT (object); - - ecd->zone = icaltimezone_get_utc_timezone (); - ecd->use_24_hour_format = TRUE; -} - - -/** - * e_cell_date_edit_text_new: - * - * Creates a new ECell renderer that can be used to render and edit dates that - * that come from the model. The value returned from the model is - * interpreted as being a CalComponentDateTime*. - * - * Returns: an ECell object that can be used to render dates. - */ -ECell * -e_cell_date_edit_text_new (const char *fontname, - GtkJustification justify) -{ - ECellDateEditText *ecd = gtk_type_new (e_cell_date_edit_text_get_type ()); - - e_cell_text_construct (E_CELL_TEXT (ecd), fontname, justify); - - return (ECell *) ecd; -} - - -E_MAKE_TYPE (e_cell_date_edit_text, "ECellDateEditText", ECellDateEditText, - e_cell_date_edit_text_class_init, e_cell_date_edit_text_init, - PARENT_TYPE); diff --git a/calendar/gui/e-cell-date-edit-text.h b/calendar/gui/e-cell-date-edit-text.h deleted file mode 100644 index bb00590622..0000000000 --- a/calendar/gui/e-cell-date-edit-text.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 2001, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -/* - * ECellDateEditText - a subclass of ECellText used to show and edit the text - * representation of the date, from a CalComponentDateTime* model value. - */ - -#ifndef _E_CELL_DATE_EDIT_TEXT_H_ -#define _E_CELL_DATE_EDIT_TEXT_H_ - -#include <ical.h> -#include <gal/e-table/e-cell-text.h> - -BEGIN_GNOME_DECLS - -#define E_CELL_DATE_EDIT_TEXT_TYPE (e_cell_date_edit_text_get_type ()) -#define E_CELL_DATE_EDIT_TEXT(o) (GTK_CHECK_CAST ((o), E_CELL_DATE_EDIT_TEXT_TYPE, ECellDateEditText)) -#define E_CELL_DATE_EDIT_TEXT_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_CELL_DATE_EDIT_TEXT_TYPE, ECellDateEditTextClass)) -#define E_IS_CELL_DATE_EDIT_TEXT(o) (GTK_CHECK_TYPE ((o), E_CELL_DATE_EDIT_TEXT_TYPE)) -#define E_IS_CELL_DATE_EDIT_TEXT_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_CELL_DATE_EDIT_TEXT_TYPE)) - -typedef struct _ECellDateEditValue ECellDateEditValue; -struct _ECellDateEditValue { - struct icaltimetype tt; - icaltimezone *zone; -}; - -typedef struct { - ECellText base; - - /* The timezone to display the date in. */ - icaltimezone *zone; - - /* Whether to display in 24-hour format. */ - gboolean use_24_hour_format; -} ECellDateEditText; - -typedef struct { - ECellTextClass parent_class; -} ECellDateEditTextClass; - -GtkType e_cell_date_edit_text_get_type (void); -ECell *e_cell_date_edit_text_new (const char *fontname, - GtkJustification justify); - - -void e_cell_date_edit_text_set_timezone (ECellDateEditText *ecd, - icaltimezone *zone); -void e_cell_date_edit_text_set_use_24_hour_format (ECellDateEditText *ecd, - gboolean use_24_hour); -END_GNOME_DECLS - -#endif /* _E_CELL_DATE_EDIT_TEXT_H_ */ diff --git a/calendar/gui/e-day-view-layout.c b/calendar/gui/e-day-view-layout.c deleted file mode 100644 index ba843b828c..0000000000 --- a/calendar/gui/e-day-view-layout.c +++ /dev/null @@ -1,352 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 2001, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -/* - * Lays out events for the Day & Work-Week views of the calendar. It is also - * used for printing. - */ - -#include <config.h> - -#include "e-day-view-layout.h" - -static void e_day_view_layout_long_event (EDayViewEvent *event, - guint8 *grid, - gint days_shown, - time_t *day_starts, - gint *rows_in_top_display); - -static void e_day_view_layout_day_event (EDayViewEvent *event, - guint8 *grid, - guint16 *group_starts, - gint8 *cols_per_row, - gint rows, - gint mins_per_row); -static void e_day_view_expand_day_event (EDayViewEvent *event, - guint8 *grid, - gint8 *cols_per_row, - gint mins_per_row); -static void e_day_view_recalc_cols_per_row (gint rows, - gint8 *cols_per_row, - guint16 *group_starts); - - -void -e_day_view_layout_long_events (GArray *events, - gint days_shown, - time_t *day_starts, - gint *rows_in_top_display) -{ - EDayViewEvent *event; - gint event_num; - 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, 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. */ - *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 < events->len; event_num++) { - event = &g_array_index (events, EDayViewEvent, event_num); - e_day_view_layout_long_event (event, grid, - days_shown, day_starts, - rows_in_top_display); - } - - /* Free the grid. */ - g_free (grid); -} - - -static void -e_day_view_layout_long_event (EDayViewEvent *event, - guint8 *grid, - gint days_shown, - time_t *day_starts, - gint *rows_in_top_display) -{ - gint start_day, end_day, free_row, day, row; - - event->num_columns = 0; - - if (!e_day_view_find_long_event_days (event, - days_shown, day_starts, - &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. */ - *rows_in_top_display = MAX (*rows_in_top_display, free_row + 1); -} - - -void -e_day_view_layout_day_events (GArray *events, - gint rows, - gint mins_per_row, - gint8 *cols_per_row) -{ - 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 < rows; row++) { - cols_per_row[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, 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 < events->len; event_num++) { - event = &g_array_index (events, EDayViewEvent, event_num); - - e_day_view_layout_day_event (event, grid, group_starts, - cols_per_row, rows, mins_per_row); - } - - /* Recalculate the number of columns needed in each row. */ - e_day_view_recalc_cols_per_row (rows, cols_per_row, group_starts); - - /* Iterate over the events again, trying to expand events horizontally - if there is enough space. */ - for (event_num = 0; event_num < events->len; event_num++) { - event = &g_array_index (events, EDayViewEvent, event_num); - e_day_view_expand_day_event (event, grid, cols_per_row, - mins_per_row); - } - - /* 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 (EDayViewEvent *event, - guint8 *grid, - guint16 *group_starts, - gint8 *cols_per_row, - gint rows, - gint mins_per_row) -{ - gint start_row, end_row, free_col, col, row, group_start; - - start_row = event->start_minute / mins_per_row; - end_row = (event->end_minute - 1) / mins_per_row; - if (end_row < start_row) - end_row = start_row; - - event->num_columns = 0; - - /* If the event can't currently be seen, just return. */ - if (start_row >= rows || end_row < 0) - return; - - /* Make sure we don't go outside the visible times. */ - start_row = CLAMP (start_row, 0, rows - 1); - end_row = CLAMP (end_row, 0, 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; - cols_per_row[row]++; - group_starts[row] = group_start; - } - - /* If any following rows should be in the same group, add them. */ - for (row = end_row + 1; row < 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 (gint rows, - gint8 *cols_per_row, - guint16 *group_starts) -{ - gint start_row = 0, row, next_start_row, max_events; - - while (start_row < rows) { - max_events = 0; - for (row = start_row; row < rows && group_starts[row] == start_row; row++) - max_events = MAX (max_events, cols_per_row[row]); - - next_start_row = row; - - for (row = start_row; row < next_start_row; row++) - cols_per_row[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 (EDayViewEvent *event, - guint8 *grid, - gint8 *cols_per_row, - gint mins_per_row) -{ - gint start_row, end_row, col, row; - gboolean clashed; - - start_row = event->start_minute / mins_per_row; - end_row = (event->end_minute - 1) / mins_per_row; - if (end_row < start_row) - end_row = start_row; - - /* Try each column until we find a free one. */ - clashed = FALSE; - for (col = event->start_row_or_col + 1; col < cols_per_row[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++; - } -} - - -/* Find the start and end days for the event. */ -gboolean -e_day_view_find_long_event_days (EDayViewEvent *event, - gint days_shown, - time_t *day_starts, - gint *start_day_return, - gint *end_day_return) -{ - gint day, start_day, end_day; - - start_day = -1; - end_day = -1; - - for (day = 0; day < days_shown; day++) { - if (start_day == -1 - && event->start < day_starts[day + 1]) - start_day = day; - if (event->end > day_starts[day]) - end_day = day; - } - - /* Sanity check. */ - if (start_day < 0 || start_day >= days_shown - || end_day < 0 || end_day >= 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; -} - - diff --git a/calendar/gui/e-day-view-layout.h b/calendar/gui/e-day-view-layout.h deleted file mode 100644 index 70d0dd6394..0000000000 --- a/calendar/gui/e-day-view-layout.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 2001, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ -#ifndef _E_DAY_VIEW_LAYOUT_H_ -#define _E_DAY_VIEW_LAYOUT_H_ - -#include "e-day-view.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* I've split these functions away from EDayView so we can use them for - printing. */ - -void e_day_view_layout_long_events (GArray *events, - gint days_shown, - time_t *day_starts, - gint *rows_in_top_display); - - -void e_day_view_layout_day_events (GArray *events, - gint rows, - gint mins_per_row, - gint8 *cols_per_row); - -gboolean e_day_view_find_long_event_days (EDayViewEvent *event, - gint days_shown, - time_t *day_starts, - gint *start_day, - gint *end_day); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_DAY_VIEW_LAYOUT_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 f7f86c6660..0000000000 --- a/calendar/gui/e-day-view-main-item.c +++ /dev/null @@ -1,756 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 1999, Ximian, Inc. - * Copyright 1999, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -/* - * EDayViewMainItem - canvas item which displays most of the appointment - * data in the main Day/Work Week display. - */ - -#include <config.h> -#include "e-util/e-categories-config.h" -#include "e-day-view-layout.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 icaltimetype day_start_tt; - gint weekday; - -#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_tt = icaltime_from_timet_with_zone (day_view->day_starts[day], FALSE, day_view->zone); - weekday = icaltime_day_of_week (day_start_tt) - 1; - - work_day = day_view->working_days & (1 << weekday); - - 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; - CalComponentTransparency transparency; - - 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); - - /* If the event is TRANSPARENT, skip it. */ - cal_component_get_transparency (event->comp, &transparency); - if (transparency == CAL_COMPONENT_TRANSP_TRANSPARENT) - continue; - - /* 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; - CalComponentTransparency transparency; - - 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 the event is TRANSPARENT, skip it. */ - cal_component_get_transparency (event->comp, &transparency); - if (transparency == CAL_COMPONENT_TRANSP_TRANSPARENT) - continue; - - if (!e_day_view_find_long_event_days (event, - day_view->days_shown, - day_view->day_starts, - &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, draw_timezone_icon; - GSList *categories_list, *elem; - CalComponentTransparency transparency; - - 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 1 - 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; - } - - /* Only fill it in if the event isn't TRANSPARENT. */ - cal_component_get_transparency (event->comp, &transparency); - if (transparency != CAL_COMPONENT_TRANSP_TRANSPARENT) { - 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; - draw_timezone_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 the DTSTART or DTEND are in a different timezone to our current - timezone, we display the timezone icon. */ - if (event->different_timezone) { - draw_timezone_icon = TRUE; - num_icons++; - } - - - cal_component_get_categories_list (comp, &categories_list); - num_icons += g_slist_length (categories_list); - - 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)); - - icon_x += icon_x_inc; - icon_y += icon_y_inc; - } - - if (draw_timezone_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->timezone_mask); - gdk_draw_pixmap (drawable, gc, - day_view->timezone_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; - } - - /* draw categories icons */ - for (elem = categories_list; elem; elem = elem->next) { - char *category; - GdkPixmap *pixmap = NULL; - GdkBitmap *mask = NULL; - - category = (char *) elem->data; - e_categories_config_get_icon_for (category, &pixmap, &mask); - if (pixmap == NULL) - continue; - - 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); - if (mask != NULL) - gdk_gc_set_clip_mask (gc, mask); - gdk_draw_pixmap (drawable, gc, - pixmap, - 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_pixmap_unref (pixmap); - if (mask != NULL) - gdk_bitmap_unref (mask); - - icon_x += icon_x_inc; - icon_y += icon_y_inc; - } - - gdk_gc_set_clip_mask (gc, NULL); - } - - /* free memory */ - cal_component_free_categories_list (categories_list); -} - - -/* 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 be7f130606..0000000000 --- a/calendar/gui/e-day-view-main-item.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 1999, Ximian, Inc. - * Copyright 1999, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ -#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 94af4ee00c..0000000000 --- a/calendar/gui/e-day-view-time-item.c +++ /dev/null @@ -1,659 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 1999, Ximian, Inc. - * Copyright 1999, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -/* - * EDayViewTimeItem - canvas item which displays the times down the left of - * the EDayView. - */ - -#include <config.h> -#include <glib.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.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 f425363c98..0000000000 --- a/calendar/gui/e-day-view-time-item.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 1999, Ximian, Inc. - * Copyright 1999, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ -#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 c2fd76f86a..0000000000 --- a/calendar/gui/e-day-view-top-item.c +++ /dev/null @@ -1,695 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 1999, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -/* - * EDayViewTopItem - displays the top part of the Day/Work Week calendar view. - */ - -#include <config.h> -#include <glib.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include "e-util/e-categories-config.h" -#include "cal-util/timeutil.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 = { 0 }; - struct icaltimetype day_start_tt; - -#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 - x, 1 - y, - canvas_width - 2 - x, 1 - y); - gdk_draw_line (drawable, light_gc, - left_edge - x, 2 - y, - left_edge - x, item_height - 2 - y); - gdk_draw_line (drawable, dark_gc, - left_edge - 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_tt = icaltime_from_timet_with_zone (day_view->day_starts[day], FALSE, day_view->zone); - day_start.tm_year = day_start_tt.year - 1900; - day_start.tm_mon = day_start_tt.month - 1; - day_start.tm_mday = day_start_tt.day; - day_start.tm_isdst = -1; - - day_start.tm_wday = time_day_of_week (day_start_tt.day, - day_start_tt.month - 1, - day_start_tt.year); - - 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; - GSList *categories_list, *elem; - - 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 - E_DAY_VIEW_LONG_EVENT_ICON_R_PAD - - 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; - } - - /* draw categories icons */ - cal_component_get_categories_list (comp, &categories_list); - for (elem = categories_list; elem; elem = elem->next) { - char *category; - GdkPixmap *pixmap = NULL; - GdkBitmap *mask = NULL; - - category = (char *) elem->data; - e_categories_config_get_icon_for (category, &pixmap, &mask); - if (pixmap == NULL) - continue; - - if (icon_x <= max_icon_x) { - gdk_gc_set_clip_origin (gc, icon_x, icon_y); - if (mask != NULL) - gdk_gc_set_clip_mask (gc, mask); - gdk_draw_pixmap (drawable, gc, - pixmap, - 0, 0, icon_x, icon_y, - E_DAY_VIEW_ICON_WIDTH, - E_DAY_VIEW_ICON_HEIGHT); - icon_x -= icon_x_inc; - } - - gdk_pixmap_unref (pixmap); - if (mask != NULL) - gdk_bitmap_unref (mask); - } - - cal_component_free_categories_list (categories_list); - - 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 daeb37aca7..0000000000 --- a/calendar/gui/e-day-view-top-item.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 1999, Ximian, Inc. - * Copyright 1999, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ -#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 2a346cdbf9..0000000000 --- a/calendar/gui/e-day-view.c +++ /dev/null @@ -1,7570 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Authors : - * Damon Chaplin <damon@ximian.com> - * Rodrigo Moya <rodrigo@ximian.com> - * - * Copyright 1999, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -/* - * EDayView - displays the Day & Work-Week views of the calendar. - */ - -#include <config.h> - -#include "e-day-view.h" - -#include <math.h> -#include <time.h> -#include <gdk/gdkkeysyms.h> -#include <gdk/gdkx.h> -#include <gtk/gtkdnd.h> -#include <gtk/gtkinvisible.h> -#include <gtk/gtkmain.h> -#include <gtk/gtksignal.h> -#include <gtk/gtkvscrollbar.h> -#include <gtk/gtkwindow.h> -#include <gal/e-text/e-text.h> -#include <gal/widgets/e-canvas-utils.h> -#include <gal/widgets/e-gui-utils.h> -#include <gal/widgets/e-unicode.h> -#include <libgnomeui/gnome-canvas-rect-ellipse.h> -#include <libgnome/gnome-i18n.h> -#include <libgnome/gnome-exec.h> -#include <libgnome/gnome-util.h> -#include <e-util/e-dialog-utils.h> - -#include "cal-util/timeutil.h" -#include "dialogs/delete-comp.h" -#include "dialogs/send-comp.h" -#include "print.h" -#include "comp-util.h" -#include "itip-utils.h" -#include "calendar-commands.h" -#include "calendar-config.h" -#include "goto.h" -#include "e-day-view-time-item.h" -#include "e-day-view-top-item.h" -#include "e-day-view-layout.h" -#include "e-day-view-main-item.h" -#include "misc.h" - -/* Images */ -#include "art/bell.xpm" -#include "art/recur.xpm" -#include "art/timezone-16.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 - -/* The timeout before we do a layout, so we don't do a layout for each event - we get from the server. */ -#define E_DAY_VIEW_LAYOUT_TIMEOUT 100 - -/* Used for the status bar messages */ -#define EVOLUTION_CALENDAR_PROGRESS_IMAGE "evolution-calendar-mini.png" -static GdkPixbuf *progress_icon[2] = { NULL, NULL }; - -/* Signal IDs */ -enum { - SELECTION_CHANGED, - LAST_SIGNAL -}; -static guint e_day_view_signals[LAST_SIGNAL] = { 0 }; - - -/* 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_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_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_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 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_new_event (GtkWidget *widget, - gpointer data); -static void e_day_view_on_new_meeting (GtkWidget *widget, - gpointer data); -static void e_day_view_on_new_task (GtkWidget *widget, - gpointer data); -static void e_day_view_on_goto_today (GtkWidget *widget, - gpointer data); -static void e_day_view_on_goto_date (GtkWidget *widget, - gpointer data); -static void e_day_view_on_edit_appointment (GtkWidget *widget, - gpointer data); -static void e_day_view_on_save_as (GtkWidget *widget, - gpointer data); -static void e_day_view_on_print (GtkWidget *widget, - gpointer data); -static void e_day_view_on_print_event (GtkWidget *widget, - gpointer data); -static void e_day_view_on_meeting (GtkWidget *widget, - gpointer data); -static void e_day_view_on_forward (GtkWidget *widget, - gpointer data); -static void e_day_view_on_publish (GtkWidget *widget, - gpointer data); -static void e_day_view_on_settings (GtkWidget *widget, - gpointer data); -static void e_day_view_on_pilot_settings (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_cut (GtkWidget *widget, gpointer data); -static void e_day_view_on_copy (GtkWidget *widget, gpointer data); -static void e_day_view_on_paste (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 void selection_clear_event (GtkWidget *invisible, - GdkEventSelection *event, - EDayView *day_view); -static void selection_received (GtkWidget *invisible, - GtkSelectionData *selection_data, - guint time, - EDayView *day_view); -static void selection_get (GtkWidget *invisible, - GtkSelectionData *selection_data, - guint info, - guint time_stamp, - EDayView *day_view); -static void invisible_destroyed (GtkWidget *invisible, EDayView *day_view); - -static void e_day_view_queue_layout (EDayView *day_view); -static void e_day_view_cancel_layout (EDayView *day_view); -static gboolean e_day_view_layout_timeout_cb (gpointer data); - - -static GtkTableClass *parent_class; -static GdkAtom clipboard_atom = GDK_NONE; - - -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; - - e_day_view_signals[SELECTION_CHANGED] = - gtk_signal_new ("selection_changed", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (EDayViewClass, selection_changed), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - gtk_object_class_add_signals (object_class, e_day_view_signals, LAST_SIGNAL); - - /* 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; - - class->selection_changed = NULL; - - /* clipboard atom */ - if (!clipboard_atom) - clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE); -} - - -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->sexp = g_strdup ("#t"); /* match all by default */ - day_view->query = 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->layout_timeout_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->zone = NULL; - - 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; - - day_view->default_category = NULL; - - /* 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_LEFT_PTR); - 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 | GDK_ACTION_ASK); - gtk_drag_dest_set (day_view->main_canvas, - GTK_DEST_DEFAULT_ALL, - target_table, n_targets, - GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_ASK); - - /* Set up the invisible widget for the clipboard selections */ - day_view->invisible = gtk_invisible_new (); - gtk_selection_add_target (day_view->invisible, - clipboard_atom, - GDK_SELECTION_TYPE_STRING, - 0); - gtk_signal_connect (GTK_OBJECT (day_view->invisible), - "selection_get", - GTK_SIGNAL_FUNC (selection_get), - (gpointer) day_view); - gtk_signal_connect (GTK_OBJECT (day_view->invisible), - "selection_clear_event", - GTK_SIGNAL_FUNC (selection_clear_event), - (gpointer) day_view); - gtk_signal_connect (GTK_OBJECT (day_view->invisible), - "selection_received", - GTK_SIGNAL_FUNC (selection_received), - (gpointer) day_view); - gtk_signal_connect (GTK_OBJECT (day_view->invisible), - "destroy", - GTK_SIGNAL_FUNC (invisible_destroyed), - (gpointer) day_view); - day_view->clipboard_selection = NULL; - - day_view->activity = NULL; -} - - -/* 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_cancel_layout (day_view); - - e_day_view_stop_auto_scroll (day_view); - - 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->sexp) { - g_free (day_view->sexp); - day_view->sexp = NULL; - } - - if (day_view->query) { - gtk_signal_disconnect_by_data (GTK_OBJECT (day_view->query), day_view); - gtk_object_unref (GTK_OBJECT (day_view->query)); - day_view->query = NULL; - } - - if (day_view->large_font) { - gdk_font_unref (day_view->large_font); - day_view->large_font = NULL; - } - - if (day_view->default_category) { - g_free (day_view->default_category); - day_view->default_category = NULL; - } - - 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); - day_view->long_events = NULL; - for (day = 0; day < E_DAY_VIEW_MAX_DAYS; day++) { - g_array_free (day_view->events[day], TRUE); - day_view->events[day] = NULL; - } - - if (day_view->invisible) - gtk_widget_destroy (day_view->invisible); - if (day_view->clipboard_selection) { - g_free (day_view->clipboard_selection); - day_view->clipboard_selection = NULL; - } - - if (day_view->activity) { - gtk_object_unref (GTK_OBJECT (day_view->activity)); - day_view->activity = NULL; - } - - 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 = 0x8000; - day_view->colors[E_DAY_VIEW_COLOR_BG_GRID].green = 0x8000; - day_view->colors[E_DAY_VIEW_COLOR_BG_GRID].blue = 0x8000; - - day_view->colors[E_DAY_VIEW_COLOR_BG_TOP_CANVAS].red = 0x8000; - day_view->colors[E_DAY_VIEW_COLOR_BG_TOP_CANVAS].green = 0x8000; - day_view->colors[E_DAY_VIEW_COLOR_BG_TOP_CANVAS].blue = 0x8000; - - 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); - day_view->timezone_icon = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &day_view->timezone_mask, NULL, timezone_16_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); - - g_assert (GTK_WIDGET_REALIZED (day_view->main_canvas)); - if (E_CANVAS (day_view->main_canvas)->ic) - gdk_im_begin (E_CANVAS (day_view->main_canvas)->ic, - GTK_LAYOUT (day_view->main_canvas)->bin_window); - - 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); - - g_assert (GTK_WIDGET_REALIZED (day_view->main_canvas)); - if (E_CANVAS (day_view->main_canvas)->ic) - gdk_im_end (); - - 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 a component is updated in the live query */ -static void -query_obj_updated_cb (CalQuery *query, const char *uid, - gboolean query_in_progress, int n_scanned, int total, - gpointer data) -{ - EDayView *day_view; - EDayViewEvent *event; - CalComponent *comp; - CalClientGetStatus status; - gint day, event_num; - - day_view = E_DAY_VIEW (data); - - /* 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 ("query_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; - } - - /* 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, - cal_client_resolve_tzid_cb, day_view->client, - day_view->zone); - gtk_object_unref (GTK_OBJECT (comp)); - - e_day_view_queue_layout (day_view); -} - -/* Callback used when a component is removed from the live query */ -static void -query_obj_removed_cb (CalQuery *query, 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); -} - -/* Callback used when a query ends */ -static void -query_query_done_cb (CalQuery *query, CalQueryDoneStatus status, const char *error_str, gpointer data) -{ - EDayView *day_view; - - day_view = E_DAY_VIEW (data); - - /* FIXME */ - - e_day_view_set_status_message (day_view, NULL); - - if (status != CAL_QUERY_DONE_SUCCESS) - fprintf (stderr, "query done: %s\n", error_str); -} - -/* Callback used when an evaluation error occurs when running a query */ -static void -query_eval_error_cb (CalQuery *query, const char *error_str, gpointer data) -{ - EDayView *day_view; - - day_view = E_DAY_VIEW (data); - - /* FIXME */ - - e_day_view_set_status_message (day_view, NULL); - - fprintf (stderr, "eval error: %s\n", error_str); -} - - -/* Builds a complete query sexp for the day view by adding the predicates to - * filter only for VEVENTS that fit in the day view's time range. - */ -static char * -adjust_query_sexp (EDayView *day_view, const char *sexp) -{ - char *start, *end; - char *new_sexp; - - /* If the dates have not been set yet, we just want an empty query. */ - if (day_view->lower == 0 || day_view->upper == 0) - return NULL; - - start = isodate_from_time_t (day_view->lower); - end = isodate_from_time_t (day_view->upper); - - new_sexp = g_strdup_printf ("(and (= (get-vtype) \"VEVENT\")" - " (occur-in-time-range? (make-time \"%s\")" - " (make-time \"%s\"))" - " %s)", - start, end, - sexp); - - g_free (start); - g_free (end); - - return new_sexp; -} - - -/* Restarts a query for the day view */ -static void -update_query (EDayView *day_view) -{ - CalQuery *old_query; - char *real_sexp; - - e_day_view_stop_editing_event (day_view); - - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); - e_day_view_free_events (day_view); - e_day_view_queue_layout (day_view); - - if (!(day_view->client - && cal_client_get_load_state (day_view->client) == CAL_CLIENT_LOAD_LOADED)) - return; - - old_query = day_view->query; - day_view->query = NULL; - - if (old_query) { - gtk_signal_disconnect_by_data (GTK_OBJECT (old_query), day_view); - gtk_object_unref (GTK_OBJECT (old_query)); - } - - g_assert (day_view->sexp != NULL); - - real_sexp = adjust_query_sexp (day_view, day_view->sexp); - if (!real_sexp) - return; /* No time range is set, so don't start a query */ - - e_day_view_set_status_message (day_view, _("Searching")); - day_view->query = cal_client_get_query (day_view->client, real_sexp); - g_free (real_sexp); - - if (!day_view->query) { - g_message ("update_query(): Could not create the query"); - return; - } - - gtk_signal_connect (GTK_OBJECT (day_view->query), "obj_updated", - GTK_SIGNAL_FUNC (query_obj_updated_cb), day_view); - gtk_signal_connect (GTK_OBJECT (day_view->query), "obj_removed", - GTK_SIGNAL_FUNC (query_obj_removed_cb), day_view); - gtk_signal_connect (GTK_OBJECT (day_view->query), "query_done", - GTK_SIGNAL_FUNC (query_query_done_cb), day_view); - gtk_signal_connect (GTK_OBJECT (day_view->query), "eval_error", - GTK_SIGNAL_FUNC (query_eval_error_cb), day_view); -} - -/* 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; - - update_query (day_view); -} - -/** - * 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) - update_query (day_view); - else - gtk_signal_connect (GTK_OBJECT (day_view->client), "cal_opened", - GTK_SIGNAL_FUNC (cal_opened_cb), day_view); - } -} - -/** - * e_day_view_set_query: - * @day_view: A day view. - * @sexp: S-expression that defines the query. - * - * Sets the query sexp that the day view will use for filtering the displayed - * events. - **/ -void -e_day_view_set_query (EDayView *day_view, const char *sexp) -{ - g_return_if_fail (day_view != NULL); - g_return_if_fail (E_IS_DAY_VIEW (day_view)); - g_return_if_fail (sexp != NULL); - - if (day_view->sexp) - g_free (day_view->sexp); - - day_view->sexp = g_strdup (sexp); - - update_query (day_view); -} - - -/** - * e_day_view_set_default_category: - * @day_view: A day view. - * @category: Default category name or NULL for no category. - * - * Sets the default category that will be used when creating new calendar - * components from the day view. - **/ -void -e_day_view_set_default_category (EDayView *day_view, const char *category) -{ - g_return_if_fail (day_view != NULL); - g_return_if_fail (E_IS_DAY_VIEW (day_view)); - - if (day_view->default_category) - g_free (day_view->default_category); - - day_view->default_category = g_strdup (category); -} - -static gboolean -e_day_view_update_event_cb (EDayView *day_view, - gint day, - 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_day 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_with_zone (start_time, day_view->zone); - } 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); - update_query (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; - struct icaltimetype tt = icaltime_null_time (); - - time_to_gdate_with_zone (&date, start_time, day_view->zone); - - /* 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); - - tt.year = g_date_year (&date); - tt.month = g_date_month (&date); - tt.day = g_date_day (&date); - - return icaltime_as_timet_with_zone (tt, day_view->zone); -} - - -/* 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_with_zone (day_view->day_starts[day - 1], 1, day_view->zone); - } - -#if 0 - for (day = 0; day <= day_view->days_shown; day++) - g_print ("Day Starts %i: %s", day, ctime (&day_view->day_starts[day])); -#endif - - 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); - - update_query (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); - } -} - - -/* The current timezone. */ -icaltimezone* -e_day_view_get_timezone (EDayView *day_view) -{ - g_return_val_if_fail (E_IS_DAY_VIEW (day_view), NULL); - - return day_view->zone; -} - - -void -e_day_view_set_timezone (EDayView *day_view, - icaltimezone *zone) -{ - icaltimezone *old_zone; - struct icaltimetype tt; - time_t lower; - - g_return_if_fail (E_IS_DAY_VIEW (day_view)); - - old_zone = day_view->zone; - if (old_zone == zone) - return; - - day_view->zone = zone; - - /* If our time hasn't been set yet, just return. */ - if (day_view->lower == 0 && day_view->upper == 0) - return; - - /* Recalculate the new start of the first day. We just use exactly - the same time, but with the new timezone. */ - tt = icaltime_from_timet_with_zone (day_view->lower, FALSE, - old_zone); - - lower = icaltime_as_timet_with_zone (tt, zone); - - e_day_view_recalc_day_starts (day_view, lower); - update_query (day_view); -} - - -/* 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 EDayViewEvent * -get_current_event (EDayView *day_view) -{ - g_return_val_if_fail (E_IS_DAY_VIEW (day_view), NULL); - - if (day_view->editing_event_day == -1) - return NULL; - - if (day_view->editing_event_day == E_DAY_VIEW_LONG_EVENT) - return &g_array_index (day_view->long_events, - EDayViewEvent, - day_view->editing_event_num); - else - return &g_array_index (day_view->events[day_view->editing_event_day], - EDayViewEvent, - day_view->editing_event_num); -} - -void -e_day_view_cut_clipboard (EDayView *day_view) -{ - EDayViewEvent *event; - const char *uid; - - g_return_if_fail (E_IS_DAY_VIEW (day_view)); - - event = get_current_event (day_view); - if (event == NULL) - return; - - e_day_view_set_status_message (day_view, _("Deleting selected objects")); - - e_day_view_copy_clipboard (day_view); - cal_component_get_uid (event->comp, &uid); - cal_client_remove_object (day_view->client, uid); - - e_day_view_set_status_message (day_view, NULL); -} - -void -e_day_view_copy_clipboard (EDayView *day_view) -{ - EDayViewEvent *event; - char *comp_str; - - g_return_if_fail (E_IS_DAY_VIEW (day_view)); - - event = get_current_event (day_view); - if (event == NULL) - return; - - comp_str = cal_component_get_as_string (event->comp); - if (day_view->clipboard_selection != NULL) - g_free (day_view->clipboard_selection); - day_view->clipboard_selection = comp_str; - gtk_selection_owner_set (day_view->invisible, clipboard_atom, GDK_CURRENT_TIME); -} - -void -e_day_view_paste_clipboard (EDayView *day_view) -{ - g_return_if_fail (E_IS_DAY_VIEW (day_view)); - - gtk_selection_convert (day_view->invisible, - clipboard_atom, - GDK_SELECTION_TYPE_STRING, - GDK_CURRENT_TIME); -} - -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); - update_query (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 (event->type == GDK_2BUTTON_PRESS) { - time_t dtstart, dtend; - - e_day_view_get_selected_time_range (day_view, &dtstart, - &dtend); - gnome_calendar_new_appointment_for (day_view->calendar, - dtstart, dtend, - TRUE, FALSE); - return TRUE; - } - - 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; - -#if 0 - g_print ("In e_day_view_on_main_canvas_button_press\n"); -#endif - - /* 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 (event->type == GDK_2BUTTON_PRESS) { - time_t dtstart, dtend; - - e_day_view_get_selected_time_range (day_view, &dtstart, - &dtend); - gnome_calendar_new_appointment_for (day_view->calendar, - dtstart, dtend, - FALSE, FALSE); - return TRUE; - } - - 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; -} - - -/* Callback used when a component is destroyed. Expects the closure data to be - * a pointer to a boolean; will set it to TRUE. - */ -static void -comp_destroy_cb (GtkObject *object, gpointer data) -{ - gboolean *destroyed; - - destroyed = data; - *destroyed = TRUE; -} - - -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); - gtk_signal_emit_stop_by_name (GTK_OBJECT (day_view->top_canvas), - "button_press_event"); - return TRUE; - } - } else if (event->button == 3) { - EDayViewEvent *e; - gboolean destroyed; - guint id; - - e = &g_array_index (day_view->long_events, EDayViewEvent, event_num); - destroyed = FALSE; - id = gtk_signal_connect (GTK_OBJECT (e->comp), "destroy", - GTK_SIGNAL_FUNC (comp_destroy_cb), &destroyed); - - if (!GTK_WIDGET_HAS_FOCUS (day_view)) - gtk_widget_grab_focus (GTK_WIDGET (day_view)); - - if (!destroyed) { - gtk_signal_disconnect (GTK_OBJECT (e->comp), id); - - 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); - gtk_signal_emit_stop_by_name (GTK_OBJECT (day_view->main_canvas), - "button_press_event"); - return TRUE; - } - } else if (event->button == 3) { - EDayViewEvent *e; - gboolean destroyed; - guint id; - - e = &g_array_index (day_view->events[day], EDayViewEvent, event_num); - - destroyed = FALSE; - id = gtk_signal_connect (GTK_OBJECT (e->comp), "destroy", - GTK_SIGNAL_FUNC (comp_destroy_cb), &destroyed); - - if (!GTK_WIDGET_HAS_FOCUS (day_view)) - gtk_widget_grab_focus (GTK_WIDGET (day_view)); - - if (!destroyed) { - gtk_signal_disconnect (GTK_OBJECT (e->comp), id); - - 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)) { - gboolean destroyed; - guint id; - - if (!e_day_view_find_long_event_days (event, - day_view->days_shown, - day_view->day_starts, - &start_day, &end_day)) - return; - - destroyed = FALSE; - id = gtk_signal_connect (GTK_OBJECT (event->comp), "destroy", - GTK_SIGNAL_FUNC (comp_destroy_cb), &destroyed); - - /* 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 (destroyed) - return; - - gtk_signal_disconnect (GTK_OBJECT (event->comp), id); - - 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)) { - gboolean destroyed; - guint id; - - destroyed = FALSE; - id = gtk_signal_connect (GTK_OBJECT (event->comp), "destroy", - GTK_SIGNAL_FUNC (comp_destroy_cb), &destroyed); - - /* 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 (destroyed) - return; - - gtk_signal_disconnect (GTK_OBJECT (event->comp), id); - - 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; - if (day_view->resize_end_row < day_view->resize_start_row) - day_view->resize_end_row = day_view->resize_start_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) -{ - EDayViewEvent *event; - gboolean destroyed; - guint id; - - if (day == -1) - event = &g_array_index (day_view->long_events, EDayViewEvent, - event_num); - else - event = &g_array_index (day_view->events[day], EDayViewEvent, - event_num); - - destroyed = FALSE; - id = gtk_signal_connect (GTK_OBJECT (event->comp), "destroy", - GTK_SIGNAL_FUNC (comp_destroy_cb), &destroyed); - - e_day_view_stop_editing_event (day_view); - - if (!destroyed) { - gtk_signal_disconnect (GTK_OBJECT (event->comp), id); - - if (day_view->calendar) - gnome_calendar_edit_object (day_view->calendar, event->comp, FALSE); - else - g_warning ("Calendar not set"); - } -} - -enum { - /* - * This is used to "flag" events that can not be edited - */ - MASK_EDITABLE = 1, - - /* - * To disable recurring actions to be displayed - */ - MASK_RECURRING = 2, - - /* - * To disable actions for non-recurring items to be displayed - */ - MASK_SINGLE = 4, - - /* - * This is used to when an event is currently being edited - * in another window and we want to disable the event - * from being edited twice - */ - MASK_EDITING = 8 -}; - -static EPopupMenu main_items [] = { - E_POPUP_ITEM (N_("New _Appointment"), - e_day_view_on_new_appointment, 0), - E_POPUP_ITEM (N_("New All Day _Event"), - e_day_view_on_new_event, 0), - E_POPUP_ITEM (N_("New Meeting"), - e_day_view_on_new_meeting, 0), - E_POPUP_ITEM (N_("New Task"), - e_day_view_on_new_task, 0), - - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("Print..."), - e_day_view_on_print, 0), - - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("_Paste"), - e_day_view_on_paste, 0), - - E_POPUP_SEPARATOR, - - E_POPUP_SUBMENU (N_("Current View"), NULL, 0), - - E_POPUP_ITEM (N_("Go to _Today"), - e_day_view_on_goto_today, 0), - E_POPUP_ITEM (N_("_Go to Date..."), - e_day_view_on_goto_date, 0), - - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("_Publish Free/Busy Information"), - e_day_view_on_publish, 0), - - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("_Configure..."), - e_day_view_on_settings, 0), - E_POPUP_ITEM (N_("_Configure Pilot..."), - e_day_view_on_pilot_settings, 0), - - E_POPUP_TERMINATOR -}; - -static EPopupMenu child_items [] = { - - E_POPUP_ITEM (N_("_Open"), e_day_view_on_edit_appointment, MASK_EDITABLE | MASK_EDITING), - E_POPUP_ITEM (N_("_Save As..."), e_day_view_on_save_as, MASK_EDITABLE | MASK_EDITING), - E_POPUP_ITEM (N_("_Print..."), e_day_view_on_print_event, MASK_EDITABLE | MASK_EDITING), - - /* Only show this separator if one of the above is shown. */ - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("C_ut"), e_day_view_on_cut, MASK_EDITABLE | MASK_EDITING), - E_POPUP_ITEM (N_("_Copy"), e_day_view_on_copy, 0), - E_POPUP_ITEM (N_("_Paste"), e_day_view_on_paste, 0), - - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("_Schedule Meeting..."), e_day_view_on_meeting, MASK_EDITABLE | MASK_EDITING), - E_POPUP_ITEM (N_("_Forward as iCalendar..."), e_day_view_on_forward, MASK_EDITABLE | MASK_EDITING), - - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("_Delete"), e_day_view_on_delete_appointment, MASK_EDITABLE | MASK_SINGLE | MASK_EDITING), - E_POPUP_ITEM (N_("Make this Occurrence _Movable"), e_day_view_on_unrecur_appointment, MASK_RECURRING | MASK_EDITING), - E_POPUP_ITEM (N_("Delete this _Occurrence"), e_day_view_on_delete_occurrence, MASK_RECURRING | MASK_EDITING), - E_POPUP_ITEM (N_("Delete _All Occurrences"), e_day_view_on_delete_appointment, MASK_RECURRING | MASK_EDITING), - - E_POPUP_TERMINATOR -}; - -static void -free_view_popup (GtkWidget *widget, gpointer data) -{ - EDayView *day_view = E_DAY_VIEW (data); - - if (day_view->view_menu == NULL) - return; - - gnome_calendar_discard_view_popup (day_view->calendar, day_view->view_menu); - day_view->view_menu = NULL; -} - -static void -e_day_view_on_event_right_click (EDayView *day_view, - GdkEventButton *bevent, - gint day, - gint event_num) -{ - EDayViewEvent *event; - int have_selection; - gboolean being_edited; - EPopupMenu *context_menu; - GtkMenu *popup; - int hide_mask = 0; - int disable_mask = 0; - - /* - * FIXME: - * 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. - */ - - being_edited = FALSE; - - have_selection = GTK_WIDGET_HAS_FOCUS (day_view) - && day_view->selection_start_day != -1; - - if (event_num == -1) { - day_view->view_menu = gnome_calendar_setup_view_popup (day_view->calendar); - main_items[9].submenu = day_view->view_menu; - context_menu = main_items; - } else { - context_menu = child_items; - - 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 (event->comp)) - hide_mask |= MASK_SINGLE; - else - hide_mask |= MASK_RECURRING; - } - - if (being_edited) - disable_mask |= MASK_EDITING; - - day_view->popup_event_day = day; - day_view->popup_event_num = event_num; - - popup = e_popup_menu_create (context_menu, disable_mask, hide_mask, day_view); - gtk_signal_connect (GTK_OBJECT (popup), "selection-done", - GTK_SIGNAL_FUNC (free_view_popup), day_view); - e_popup_menu (popup, (GdkEvent *) bevent); -} - -static void -e_day_view_on_new_appointment (GtkWidget *widget, gpointer data) -{ - EDayView *day_view = E_DAY_VIEW (data); - time_t dtstart, dtend; - struct icaltimetype itt; - - /* Edit a new event. If only one day is selected in the top canvas, - we set the time to the first 1/2-hour of the working day. */ - if (day_view->selection_in_top_canvas - && day_view->selection_start_day != -1 - && day_view->selection_start_day == day_view->selection_end_day) { - dtstart = day_view->day_starts[day_view->selection_start_day]; - itt = icaltime_from_timet_with_zone (dtstart, FALSE, - day_view->zone); - itt.hour = calendar_config_get_day_start_hour (); - itt.minute = calendar_config_get_day_start_minute (); - dtstart = icaltime_as_timet_with_zone (itt, day_view->zone); - - icaltime_adjust (&itt, 0, 0, 30, 0); - dtend = icaltime_as_timet_with_zone (itt, day_view->zone); - } else { - e_day_view_get_selected_time_range (day_view, &dtstart, - &dtend); - } - - gnome_calendar_new_appointment_for ( - day_view->calendar, dtstart, dtend, FALSE, FALSE); -} - -static void -e_day_view_on_new_event (GtkWidget *widget, gpointer data) -{ - EDayView *day_view = E_DAY_VIEW (data); - time_t dtstart, dtend; - - e_day_view_get_selected_time_range (day_view, &dtstart, &dtend); - gnome_calendar_new_appointment_for ( - day_view->calendar, dtstart, dtend, TRUE, FALSE); -} - -static void -e_day_view_on_new_meeting (GtkWidget *widget, gpointer data) -{ - EDayView *day_view = E_DAY_VIEW (data); - time_t dtstart, dtend; - struct icaltimetype itt; - - /* Edit a new event. If only one day is selected in the top canvas, - we set the time to the first 1/2-hour of the working day. */ - if (day_view->selection_in_top_canvas - && day_view->selection_start_day != -1 - && day_view->selection_start_day == day_view->selection_end_day) { - dtstart = day_view->day_starts[day_view->selection_start_day]; - itt = icaltime_from_timet_with_zone (dtstart, FALSE, - day_view->zone); - itt.hour = calendar_config_get_day_start_hour (); - itt.minute = calendar_config_get_day_start_minute (); - dtstart = icaltime_as_timet_with_zone (itt, day_view->zone); - - icaltime_adjust (&itt, 0, 0, 30, 0); - dtend = icaltime_as_timet_with_zone (itt, day_view->zone); - } else { - e_day_view_get_selected_time_range (day_view, &dtstart, - &dtend); - } - - gnome_calendar_new_appointment_for ( - day_view->calendar, dtstart, dtend, FALSE, TRUE); -} - -static void -e_day_view_on_new_task (GtkWidget *widget, gpointer data) -{ - EDayView *day_view = E_DAY_VIEW (data); - - gnome_calendar_new_task (day_view->calendar); -} - -static void -e_day_view_on_goto_date (GtkWidget *widget, gpointer data) -{ - EDayView *day_view = E_DAY_VIEW (data); - - goto_dialog (day_view->calendar); -} - -static void -e_day_view_on_goto_today (GtkWidget *widget, gpointer data) -{ - EDayView *day_view = E_DAY_VIEW (data); - - calendar_goto_today (day_view->calendar); -} - -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, FALSE); - else - g_warning ("Calendar not set"); -} - -static void -e_day_view_on_save_as (GtkWidget *widget, gpointer data) -{ - EDayView *day_view; - EDayViewEvent *event; - char *filename; - char *ical_string; - FILE *file; - - day_view = E_DAY_VIEW (data); - - event = e_day_view_get_popup_menu_event (day_view); - if (event == NULL) - return; - - filename = e_file_dialog_save (_("Save as...")); - if (filename == NULL) - return; - - ical_string = cal_client_get_component_as_string (day_view->client, event->comp); - if (ical_string == NULL) { - g_warning ("Couldn't convert item to a string"); - return; - } - - file = fopen (filename, "w"); - if (file == NULL) { - g_warning ("Couldn't save item"); - return; - } - - fprintf (file, ical_string); - g_free (ical_string); - fclose (file); -} - -static void -e_day_view_on_print (GtkWidget *widget, gpointer data) -{ - EDayView *day_view; - time_t start; - GnomeCalendarViewType view_type; - PrintView print_view; - - day_view = E_DAY_VIEW (data); - - gnome_calendar_get_current_time_range (day_view->calendar, &start, NULL); - view_type = gnome_calendar_get_view (day_view->calendar); - - switch (view_type) { - case GNOME_CAL_DAY_VIEW: - print_view = PRINT_VIEW_DAY; - break; - - case GNOME_CAL_WORK_WEEK_VIEW: - print_view = PRINT_VIEW_WEEK; - break; - - default: - g_assert_not_reached (); - return; - } - - print_calendar (day_view->calendar, FALSE, start, print_view); -} - -static void -e_day_view_on_print_event (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; - - print_comp (event->comp, day_view->client, FALSE); -} - -static void -e_day_view_on_meeting (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, TRUE); - else - g_warning ("Calendar not set"); -} - -static void -e_day_view_on_forward (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; - - itip_send_comp (CAL_COMPONENT_METHOD_PUBLISH, event->comp, - day_view->client, NULL); -} - -static void -e_day_view_on_publish (GtkWidget *widget, gpointer data) -{ - EDayView *day_view; - icaltimezone *utc; - time_t start = time (NULL), end; - GList *comp_list; - - day_view = E_DAY_VIEW (data); - - utc = icaltimezone_get_utc_timezone (); - start = time_day_begin_with_zone (start, utc); - end = time_add_week_with_zone (start, 6, utc); - - comp_list = cal_client_get_free_busy (day_view->client, NULL, start, end); - if (comp_list) { - GList *l; - - for (l = comp_list; l; l = l->next) { - CalComponent *comp = CAL_COMPONENT (l->data); - itip_send_comp (CAL_COMPONENT_METHOD_PUBLISH, comp, - day_view->client, NULL); - - gtk_object_unref (GTK_OBJECT (comp)); - } - - g_list_free (comp_list); - } -} - -static void -e_day_view_on_settings (GtkWidget *widget, gpointer data) -{ - EDayView *day_view; - - day_view = E_DAY_VIEW (data); - - control_util_show_settings (day_view->calendar); -} - -static void -e_day_view_on_pilot_settings (GtkWidget *widget, gpointer data) -{ - char *args[] = { - "gpilotd-control-applet", - NULL - }; - int pid; - - args[0] = gnome_is_program_in_path ("gpilotd-control-applet"); - if (!args[0]) { - e_notice (NULL, GNOME_MESSAGE_BOX_ERROR, - _("The GNOME Pilot tools do not appear to be installed on this system.")); - return; - } - - pid = gnome_execute_async (NULL, 4, args); - if (pid == -1) - e_notice (NULL, GNOME_MESSAGE_BOX_ERROR, _("Error executing %s."), args[0]); - - g_free (args[0]); -} - -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, event->start, day_view->zone); - - 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_delete_event_internal (EDayView *day_view, EDayViewEvent *event) -{ - CalComponentVType vtype; - - vtype = cal_component_get_vtype (event->comp); - - if (delete_component_dialog (event->comp, FALSE, 1, vtype, - GTK_WIDGET (day_view))) { - 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_delete_appointment (GtkWidget *widget, gpointer data) -{ - EDayView *day_view; - EDayViewEvent *event; - gboolean destroyed; - guint id; - - day_view = E_DAY_VIEW (data); - - event = e_day_view_get_popup_menu_event (day_view); - if (event == NULL) - return; - - destroyed = FALSE; - id = gtk_signal_connect (GTK_OBJECT (event->comp), "destroy", - GTK_SIGNAL_FUNC (comp_destroy_cb), &destroyed); - - if (day_view->editing_event_day >= 0) - e_day_view_stop_editing_event (day_view); - - if (!destroyed) { - gtk_signal_disconnect (GTK_OBJECT (event->comp), id); - - e_day_view_delete_event_internal (day_view, event); - } -} - -void -e_day_view_delete_event (EDayView *day_view) -{ - EDayViewEvent *event; - - g_return_if_fail (E_IS_DAY_VIEW (day_view)); - - if (day_view->editing_event_day == -1) - return; - - if (day_view->editing_event_day == E_DAY_VIEW_LONG_EVENT) - event = &g_array_index (day_view->long_events, - EDayViewEvent, - day_view->editing_event_num); - else - event = &g_array_index (day_view->events[day_view->editing_event_day], - EDayViewEvent, - day_view->editing_event_num); - - e_day_view_delete_event_internal (day_view, event); -} - - -static void -e_day_view_on_cut (GtkWidget *widget, gpointer data) -{ - EDayView *day_view; - EDayViewEvent *event; - const char *uid; - - day_view = E_DAY_VIEW (data); - - event = e_day_view_get_popup_menu_event (day_view); - if (event == NULL) - return; - - e_day_view_on_copy (widget, data); - - cal_component_get_uid (event->comp, &uid); - cal_client_remove_object (day_view->client, uid); -} - -static void -e_day_view_on_copy (GtkWidget *widget, gpointer data) -{ - EDayView *day_view; - EDayViewEvent *event; - char *comp_str; - - day_view = E_DAY_VIEW (data); - - event = e_day_view_get_popup_menu_event (day_view); - if (event == NULL) - return; - - comp_str = cal_component_get_as_string (event->comp); - if (day_view->clipboard_selection) - g_free (day_view->clipboard_selection); - day_view->clipboard_selection = comp_str; - - gtk_selection_owner_set (day_view->invisible, clipboard_atom, GDK_CURRENT_TIME); -} - -static void -e_day_view_on_paste (GtkWidget *widget, gpointer data) -{ - EDayView *day_view = E_DAY_VIEW (data); - - gtk_selection_convert (day_view->invisible, - clipboard_atom, - GDK_SELECTION_TYPE_STRING, - GDK_CURRENT_TIME); -} - -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, event->start, day_view->zone); - - /* 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 = icaltimezone_get_tzid (day_view->zone); - - *date.value = icaltime_from_timet_with_zone (event->start, FALSE, - day_view->zone); - cal_component_set_dtstart (new_comp, &date); - *date.value = icaltime_from_timet_with_zone (event->end, FALSE, - day_view->zone); - 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) { - gdk_pointer_ungrab (event->time); - e_day_view_finish_long_event_resize (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 gboolean -e_day_view_on_main_canvas_button_release (GtkWidget *widget, - GdkEventButton *event, - EDayView *day_view) -{ -#if 0 - g_print ("In e_day_view_on_main_canvas_button_release\n"); -#endif - - 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) { - gdk_pointer_ungrab (event->time); - e_day_view_finish_resize (day_view); - 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; - /* FIXME: Should probably keep the timezone of the original start - and end times. */ - date.tzid = icaltimezone_get_tzid (day_view->zone); - - 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_with_zone (dt, FALSE, - day_view->zone); - cal_component_set_dtstart (comp, &date); - } else { - dt = day_view->day_starts[day_view->resize_end_row + 1]; - *date.value = icaltime_from_timet_with_zone (dt, FALSE, - day_view->zone); - 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)) { - if (cal_component_has_attendees (comp) && send_component_dialog (comp, FALSE)) - itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, day_view->client, NULL); - } else { - 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; - /* FIXME: Should probably keep the timezone of the original start - and end times. */ - date.tzid = icaltimezone_get_tzid (day_view->zone); - - 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_with_zone (dt, FALSE, - day_view->zone); - 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_with_zone (dt, FALSE, - day_view->zone); - 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)) { - if (cal_component_has_attendees (comp) && send_component_dialog (comp, FALSE)) - itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, day_view->client, NULL); - } else { - 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); - } -} - - -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 icaltimetype start_tt, end_tt; - - 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_tt = icaltime_from_timet_with_zone (start, FALSE, - day_view->zone); - end_tt = icaltime_from_timet_with_zone (end, FALSE, - day_view->zone); - - 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_tt.hour * 60 + start_tt.minute - offset; - event.end_minute = end_tt.hour * 60 + end_tt.minute - offset; - - event.start_row_or_col = 0; - event.num_columns = 0; - - event.different_timezone = FALSE; - if (!cal_comp_util_compare_event_timezones (comp, day_view->client, - day_view->zone)) - event.different_timezone = TRUE; - - /* 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, rows_in_top_display, top_canvas_height, top_rows; - - /* 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->events[day], - day_view->rows, - day_view->mins_per_row, - day_view->cols_per_row[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->long_events, - day_view->days_shown, - day_view->day_starts, - &rows_in_top_display); - - /* 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 != rows_in_top_display) { - day_view->rows_in_top_display = rows_in_top_display; - top_rows = MAX (1, 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); - } - } - - - 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_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) { - GSList *categories_list; - - if (cal_component_has_alarms (comp)) - num_icons++; - if (cal_component_has_recurrences (comp)) - num_icons++; - if (event->different_timezone) - num_icons++; - - cal_component_get_categories_list (comp, &categories_list); - num_icons += g_slist_length (categories_list); - cal_component_free_categories_list (categories_list); - } - - 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 + E_DAY_VIEW_LONG_EVENT_ICON_R_PAD; - 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); -} - - -/* 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) { - GSList *categories_list; - - if (cal_component_has_alarms (comp)) - num_icons++; - if (cal_component_has_recurrences (comp)) - num_icons++; - if (event->different_timezone) - num_icons++; - - cal_component_get_categories_list (comp, &categories_list); - num_icons += g_slist_length (categories_list); - cal_component_free_categories_list (categories_list); - } - - 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; - } - } -} - - -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 start_dt, end_dt; - struct icaltimetype start_tt, end_tt; - 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->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK))) - || (event->length == 0) - || (keyval == GDK_Tab)) { - return FALSE; - } else - initial_text = e_utf8_from_gtk_event_key (widget, event->keyval, event->string); - - /* Add a new event covering the selected range */ - - comp = cal_comp_event_new_with_defaults (); - - e_day_view_get_selected_time_range (day_view, &dtstart, &dtend); - - start_tt = icaltime_from_timet_with_zone (dtstart, FALSE, - day_view->zone); - - end_tt = icaltime_from_timet_with_zone (dtend, FALSE, - day_view->zone); - - if (day_view->selection_in_top_canvas) { - start_dt.tzid = NULL; - start_tt.is_date = 1; - end_tt.is_date = 1; - } else { - start_dt.tzid = icaltimezone_get_tzid (day_view->zone); - } - - start_dt.value = &start_tt; - end_dt.value = &end_tt; - end_dt.tzid = start_dt.tzid; - cal_component_set_dtstart (comp, &start_dt); - cal_component_set_dtend (comp, &end_dt); - - cal_component_set_categories (comp, day_view->default_category); - - /* We add the event locally and start editing it. We don't send it - to the server until the user finishes editing it. */ - 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"); - } - - if (initial_text) - g_free (initial_text); - - 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, TRUE); - - 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); -} - - -/* Cancels the current edition by resetting the appointment's text to its original value */ -static void -cancel_editing (EDayView *day_view) -{ - int day, event_num; - EDayViewEvent *event; - CalComponentText summary; - - day = day_view->editing_event_day; - event_num = day_view->editing_event_num; - - g_assert (day != -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); - - /* Reset the text to what was in the component */ - - cal_component_get_summary (event->comp, &summary); - gtk_object_set (GTK_OBJECT (event->canvas_item), - "text", summary.value ? summary.value : "", - NULL); - - /* Stop editing */ - e_day_view_stop_editing_event (day_view); -} - - -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; - } else if (event->key.keyval == GDK_Escape) { - cancel_editing (day_view); - gtk_signal_emit_stop_by_name (GTK_OBJECT (item), "event"); - return TRUE; - } - break; - case GDK_2BUTTON_PRESS: -#if 0 - g_print ("Item got double-click\n"); -#endif - 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); - } - - gtk_signal_emit (GTK_OBJECT (day_view), - e_day_view_signals[SELECTION_CHANGED]); -} - -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); - g_assert (text != NULL); - - if (string_is_empty (text)) { - ConfirmDeleteEmptyCompResult result; - - result = cal_comp_confirm_delete_empty_comp (event->comp, day_view->client, - GTK_WIDGET (day_view)); - - switch (result) { - case EMPTY_COMP_REMOVE_LOCALLY: { - const char *uid; - - cal_component_get_uid (event->comp, &uid); - - 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); - goto out; } - - case EMPTY_COMP_REMOVED_FROM_SERVER: - goto out; - - case EMPTY_COMP_DO_NOT_REMOVE: - /* But we cannot keep an empty summary, so make the - * canvas item refresh itself from the text that the - * component already had. - */ - - if (day == E_DAY_VIEW_LONG_EVENT) - e_day_view_reshape_long_event (day_view, event_num); - else - e_day_view_update_event_label (day_view, day, event_num); - - goto out; - - default: - g_assert_not_reached (); - } - - g_assert_not_reached (); - } - - /* Only update the summary if necessary. */ - cal_component_get_summary (event->comp, &summary); - if (summary.value && !strcmp (text, summary.value)) { - if (day == E_DAY_VIEW_LONG_EVENT) - e_day_view_reshape_long_event (day_view, event_num); - else - e_day_view_update_event_label (day_view, day, - event_num); - } else { - summary.value = text; - summary.altrep = NULL; - cal_component_set_summary (event->comp, &summary); - - if (cal_client_update_object (day_view->client, event->comp)) { - if (cal_component_has_attendees (event->comp) && send_component_dialog (event->comp, FALSE)) - itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, event->comp, - day_view->client, NULL); - } else { - g_message ("e_day_view_on_editing_stopped(): Could not update the object!"); - } - } - - out: - - g_free (text); - - gtk_signal_emit (GTK_OBJECT (day_view), - e_day_view_signals[SELECTION_CHANGED]); -} - - -/* 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 icaltimetype tt; - 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]; - - /* Create an icaltimetype and convert to a time_t. */ - tt = icaltime_from_timet_with_zone (day_view->day_starts[col], - FALSE, day_view->zone); - tt.hour = minutes / 60; - tt.minute = minutes % 60; - tt.second = 0; - - val = icaltime_as_timet_with_zone (tt, day_view->zone); - return val; -} - - -static gboolean -e_day_view_convert_time_to_grid_position (EDayView *day_view, - time_t time, - gint *col, - gint *row) -{ - struct icaltimetype tt; - 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 an icaltimetype, - calculate the offset in minutes from the top of the display and - divide it by the mins per row setting. */ - tt = icaltime_from_timet_with_zone (time, FALSE, day_view->zone); - - minutes = tt.hour * 60 + tt.minute; - 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; - if (end_row < start_row) - end_row = start_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 (event, - day_view->days_shown, - day_view->day_starts, - 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 (event, - day_view->days_shown, - day_view->day_starts, - &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; - - 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; - if (end_row < start_row) - end_row = start_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; - gboolean all_day_event; - - /* Note that we only support DnD within the EDayView at present. */ - if ((data->length >= 0) && (data->format == 8) - && (day_view->drag_event_day != -1)) { - 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 = 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); - day -= day_view->drag_event_offset; - day = MAX (day, 0); - - e_day_view_find_long_event_days (event, - day_view->days_shown, - day_view->day_starts, - &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 { - 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 clone the event 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); - - if (start_offset == 0 && end_offset == 0) - all_day_event = TRUE; - else - all_day_event = FALSE; - - date.value = &itt; - - dt = day_view->day_starts[day] + start_offset * 60; - itt = icaltime_from_timet_with_zone (dt, FALSE, - day_view->zone); - if (all_day_event) { - itt.is_date = TRUE; - date.tzid = NULL; - } else { - /* FIXME: Should probably keep the timezone of - the original start and end times. */ - date.tzid = icaltimezone_get_tzid (day_view->zone); - } - cal_component_set_dtstart (comp, &date); - - if (end_offset == 0) - dt = day_view->day_starts[day + num_days]; - else - dt = day_view->day_starts[day + num_days - 1] + end_offset * 60; - itt = icaltime_from_timet_with_zone (dt, FALSE, - day_view->zone); - if (all_day_event) { - itt.is_date = TRUE; - date.tzid = NULL; - } else { - /* FIXME: Should probably keep the timezone of - the original start and end times. */ - date.tzid = icaltimezone_get_tzid (day_view->zone); - } - 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)) { - if (cal_component_has_attendees (comp) && send_component_dialog (comp, FALSE)) - itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, - day_view->client, NULL); - } else { - 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; - - /* Note that we only support DnD within the EDayView at present. */ - if ((data->length >= 0) && (data->format == 8) - && (day_view->drag_event_day != -1)) { - 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 { - 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; - if (end_row < start_row) - end_row = start_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 = icaltimezone_get_tzid (day_view->zone); - - dt = e_day_view_convert_grid_position_to_time (day_view, day, row) + start_offset * 60; - *date.value = icaltime_from_timet_with_zone (dt, FALSE, - day_view->zone); - 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_with_zone (dt, FALSE, - day_view->zone); - 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)) { - if (cal_component_has_attendees (comp) && send_component_dialog (comp, FALSE)) - itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, - day_view->client, NULL); - } else { - 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; -} - -static void -invisible_destroyed (GtkWidget *invisible, EDayView *day_view) -{ - day_view->invisible = NULL; -} - -static void -selection_get (GtkWidget *invisible, - GtkSelectionData *selection_data, - guint info, - guint time_stamp, - EDayView *day_view) -{ - if (day_view->clipboard_selection != NULL) { - gtk_selection_data_set (selection_data, - GDK_SELECTION_TYPE_STRING, - 8, - day_view->clipboard_selection, - strlen (day_view->clipboard_selection)); - } -} - -static void -selection_clear_event (GtkWidget *invisible, - GdkEventSelection *event, - EDayView *day_view) -{ - if (day_view->clipboard_selection != NULL) { - g_free (day_view->clipboard_selection); - day_view->clipboard_selection = NULL; - } -} - -static void -selection_received (GtkWidget *invisible, - GtkSelectionData *selection_data, - guint time, - EDayView *day_view) -{ - char *comp_str; - icalcomponent *icalcomp; - time_t dtstart, dtend; - struct icaltimetype itime; - icalcomponent_kind kind; - CalComponent *comp; - char *uid; - time_t tt_start, tt_end; - struct icaldurationtype ic_dur; - - g_return_if_fail (E_IS_DAY_VIEW (day_view)); - - if (selection_data->length < 0 || - selection_data->type != GDK_SELECTION_TYPE_STRING) { - return; - } - - comp_str = (char *) selection_data->data; - icalcomp = icalparser_parse_string ((const char *) comp_str); - if (!icalcomp) - return; - - /* check the type of the component */ - kind = icalcomponent_isa (icalcomp); - if (kind != ICAL_VCALENDAR_COMPONENT && - kind != ICAL_VEVENT_COMPONENT && - kind != ICAL_VTODO_COMPONENT && - kind != ICAL_VJOURNAL_COMPONENT) { - return; - } - - e_day_view_set_status_message (day_view, _("Updating objects")); - e_day_view_get_selected_time_range (day_view, &dtstart, &dtend); - - if (kind == ICAL_VCALENDAR_COMPONENT) { - icalcomponent_kind child_kind; - icalcomponent *subcomp; - - subcomp = icalcomponent_get_first_component ( - icalcomp, ICAL_ANY_COMPONENT); - while (subcomp) { - child_kind = icalcomponent_isa (subcomp); - if (child_kind == ICAL_VEVENT_COMPONENT || - child_kind == ICAL_VTODO_COMPONENT || - child_kind == ICAL_VJOURNAL_COMPONENT) { - tt_start = icaltime_as_timet (icalcomponent_get_dtstart (subcomp)); - tt_end = icaltime_as_timet (icalcomponent_get_dtend (subcomp)); - ic_dur = icaldurationtype_from_int (tt_end - tt_start); - itime = icaltime_from_timet_with_zone (dtstart, FALSE, day_view->zone); - - icalcomponent_set_dtstart (subcomp, itime); - itime = icaltime_add (itime, ic_dur); - icalcomponent_set_dtend (subcomp, itime); - - uid = cal_component_gen_uid (); - comp = cal_component_new (); - cal_component_set_icalcomponent ( - comp, icalcomponent_new_clone (subcomp)); - cal_component_set_uid (comp, uid); - - cal_client_update_object (day_view->client, comp); - - free (uid); - gtk_object_unref (GTK_OBJECT (comp)); - - } - subcomp = icalcomponent_get_next_component ( - icalcomp, ICAL_ANY_COMPONENT); - } - } - else { - tt_start = icaltime_as_timet (icalcomponent_get_dtstart (icalcomp)); - tt_end = icaltime_as_timet (icalcomponent_get_dtend (icalcomp)); - ic_dur = icaldurationtype_from_int (tt_end - tt_start); - itime = icaltime_from_timet_with_zone (dtstart, FALSE, day_view->zone); - - icalcomponent_set_dtstart (icalcomp, itime); - itime = icaltime_add (itime, ic_dur); - icalcomponent_set_dtend (icalcomp, itime); - - comp = cal_component_new (); - cal_component_set_icalcomponent (comp, icalcomp); - - uid = cal_component_gen_uid (); - cal_component_set_uid (comp, (const char *) uid); - free (uid); - - cal_client_update_object (day_view->client, comp); - - gtk_object_unref (GTK_OBJECT (comp)); - } - - e_day_view_set_status_message (day_view, NULL); -} - - -/* Gets the visible time range. Returns FALSE if no time range has been set. */ -gboolean -e_day_view_get_visible_time_range (EDayView *day_view, - time_t *start_time, - time_t *end_time) -{ - /* If the date isn't set, return FALSE. */ - if (day_view->lower == 0 && day_view->upper == 0) - return FALSE; - - *start_time = day_view->day_starts[0]; - *end_time = day_view->day_starts[day_view->days_shown]; - - return TRUE; -} - - -/* Queues a layout, unless one is already queued. */ -static void -e_day_view_queue_layout (EDayView *day_view) -{ - if (day_view->layout_timeout_id == 0) { - day_view->layout_timeout_id = g_timeout_add (E_DAY_VIEW_LAYOUT_TIMEOUT, e_day_view_layout_timeout_cb, day_view); - } -} - - -/* Removes any queued layout. */ -static void -e_day_view_cancel_layout (EDayView *day_view) -{ - if (day_view->layout_timeout_id != 0) { - gtk_timeout_remove (day_view->layout_timeout_id); - day_view->layout_timeout_id = 0; - } -} - - -static gboolean -e_day_view_layout_timeout_cb (gpointer data) -{ - EDayView *day_view = E_DAY_VIEW (data); - - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); - e_day_view_check_layout (day_view); - - day_view->layout_timeout_id = 0; - return FALSE; -} - - -/* Returns the number of selected events (0 or 1 at present). */ -gint -e_day_view_get_num_events_selected (EDayView *day_view) -{ - g_return_val_if_fail (E_IS_DAY_VIEW (day_view), 0); - - return (day_view->editing_event_day != -1) ? 1 : 0; -} - -/* Displays messages on the status bar. */ -void -e_day_view_set_status_message (EDayView *day_view, const char *message) -{ - extern EvolutionShellClient *global_shell_client; /* ugly */ - - g_return_if_fail (E_IS_DAY_VIEW (day_view)); - - if (!message || !*message) { - if (day_view->activity) { - gtk_object_unref (GTK_OBJECT (day_view->activity)); - day_view->activity = NULL; - } - } - else if (!day_view->activity) { - int display; - char *client_id = g_strdup_printf ("%p", day_view); - - if (progress_icon[0] == NULL) - progress_icon[0] = gdk_pixbuf_new_from_file (EVOLUTION_IMAGESDIR "/" EVOLUTION_CALENDAR_PROGRESS_IMAGE); - day_view->activity = evolution_activity_client_new ( - global_shell_client, client_id, - progress_icon, message, TRUE, &display); - - g_free (client_id); - } - else - evolution_activity_client_update (day_view->activity, message, -1.0); -} diff --git a/calendar/gui/e-day-view.h b/calendar/gui/e-day-view.h deleted file mode 100644 index 25f9181218..0000000000 --- a/calendar/gui/e-day-view.h +++ /dev/null @@ -1,672 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 1999, Ximian, Inc. - * Copyright 1999, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ -#ifndef _E_DAY_VIEW_H_ -#define _E_DAY_VIEW_H_ - -#include <time.h> -#include <gtk/gtktable.h> -#include <libgnomeui/gnome-canvas.h> -#include <gal/widgets/e-popup-menu.h> - -#include "gnome-cal.h" -#include "evolution-activity-client.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 1 -#define E_DAY_VIEW_ICON_Y_PAD 1 - -/* The space between the icons and the long event text. */ -#define E_DAY_VIEW_LONG_EVENT_ICON_R_PAD 1 - -/* 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; - - /* TRUE if the event is at a different UTC offset than our current - timezone, i.e. it is in a different timezone. */ - guint different_timezone : 1; - - /* 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; - - /* S-expression for query and the query object */ - char *sexp; - CalQuery *query; - - /* 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]; - - /* The timezone. */ - icaltimezone *zone; - - /* 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 the timeout function for doing a new layout. */ - gint layout_timeout_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; - GdkPixmap *timezone_icon; - GdkBitmap *timezone_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; - EPopupMenu *view_menu; - - /* 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; - - /* the invisible widget to manage the clipboard selections */ - GtkWidget *invisible; - gchar *clipboard_selection; - - /* The default category for new events */ - char *default_category; - - /* The activity client used to show messages on the status bar. */ - EvolutionActivityClient *activity; -}; - -struct _EDayViewClass -{ - GtkTableClass parent_class; - - /* Notification signals */ - void (* selection_changed) (EDayView *day_view); -}; - - -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); - -void e_day_view_set_query (EDayView *day_view, - const char *sexp); - -void e_day_view_set_default_category (EDayView *day_view, - const char *category); - -/* 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); - -/* Gets the visible time range. Returns FALSE if no time range has been set. */ -gboolean e_day_view_get_visible_time_range (EDayView *day_view, - time_t *start_time, - time_t *end_time); - -/* 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); - -/* The current timezone. */ -icaltimezone* e_day_view_get_timezone (EDayView *day_view); -void e_day_view_set_timezone (EDayView *day_view, - icaltimezone *zone); - - -/* Clipboard-related functions */ -void e_day_view_cut_clipboard (EDayView *day_view); -void e_day_view_copy_clipboard (EDayView *day_view); -void e_day_view_paste_clipboard (EDayView *day_view); - -void e_day_view_delete_event (EDayView *day_view); - - -/* Returns the number of selected events (0 or 1 at present). */ -gint e_day_view_get_num_events_selected (EDayView *day_view); - - -/* - * 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); - -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); - - -gint e_day_view_event_sort_func (const void *arg1, - const void *arg2); - -void e_day_view_set_status_message (EDayView *day_view, - const char *message); - -#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 f8cfe2fea3..0000000000 --- a/calendar/gui/e-itip-control.c +++ /dev/null @@ -1,2020 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-itip-control.c - * - * Copyright (C) 2001 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: JP Rosevear - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <glib.h> -#include <gtk/gtkmisc.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <libgnome/gnome-util.h> -#include <libgnomeui/gnome-stock.h> -#include <libgnomeui/gnome-uidefs.h> -#include <libgnomeui/gnome-dialog.h> -#include <libgnomeui/gnome-dialog-util.h> -#include <bonobo/bonobo-exception.h> -#include <gal/util/e-unicode-i18n.h> -#include <gal/widgets/e-unicode.h> -#include <gtkhtml/gtkhtml.h> -#include <gtkhtml/gtkhtml-stream.h> -#include <ical.h> -#include <cal-util/cal-component.h> -#include <cal-util/timeutil.h> -#include <cal-client/cal-client.h> -#include <e-util/e-time-utils.h> -#include <e-util/e-dialog-widgets.h> -#include <evolution-shell-client.h> -#include <evolution-folder-selector-button.h> -#include "calendar-config.h" -#include "itip-utils.h" -#include "e-itip-control.h" - -struct _EItipControlPrivate { - GtkWidget *html; - -#if 0 - GtkWidget *count; - GtkWidget *next; - GtkWidget *prev; -#endif - - GPtrArray *event_clients; - CalClient *event_client; - GPtrArray *task_clients; - CalClient *task_client; - - char *vcalendar; - CalComponent *comp; - icalcomponent *main_comp; - icalcomponent *ical_comp; - icalcomponent *top_level; - icalcompiter iter; - icalproperty_method method; - - int current; - int total; - - GList *addresses; - gchar *from_address; - gchar *my_address; -}; - -/* HTML Strings */ -#define HTML_BODY_START "<body bgcolor=\"#ffffff\" text=\"#000000\" link=\"#336699\">" -#define HTML_SEP "<hr color=#336699 align=\"left\" width=450>" -#define HTML_BODY_END "</body>" -#define HTML_FOOTER "</html>" - -/* We don't use these now, as we need to be able to translate the text. - But I've left these here, in case there are problems with the new code. */ -#if 0 -#define PUBLISH_OPTIONS "<form><b>Choose an action:</b> <select NAME=\"action\" SIZE=\"1\"> \ -<option VALUE=\"U\">Update</option></select>    \ -<input TYPE=Submit name=\"ok\" value=\"OK\"></form>" - -#define REQUEST_OPTIONS "<form><b>Choose an action:</b> <select NAME=\"action\" SIZE=\"1\"> \ -<option VALUE=\"A\">Accept</option> \ -<option VALUE=\"T\">Tentatively accept</option> \ -<option VALUE=\"D\">Decline</option></select>  \ -<input TYPE=\"checkbox\" name=\"rsvp\" value=\"1\" checked>RSVP  \ -<input TYPE=\"submit\" name=\"ok\" value=\"OK\"><br> \ -</form>" - -#define REQUEST_FB_OPTIONS "<form><b>Choose an action:</b><select NAME=\"action\" SIZE=\"1\"> \ -<option VALUE=\"F\">Send Free/Busy Information</option></select>    \ -<input TYPE=Submit name=\"ok\" value=\"OK\"></form>" - -#define REPLY_OPTIONS "<form><b>Choose an action:</b><select NAME=\"action\" SIZE=\"1\"> \ -<option VALUE=\"R\">Update respondent status</option></select>    \ -<input TYPE=Submit name=\"ok\" value=\"OK\"></form>" - -#define REFRESH_OPTIONS "<form><b>Choose an action:</b><select NAME=\"action\" SIZE=\"1\"> \ -<option VALUE=\"S\">Send Latest Information</option></select>    \ -<input TYPE=Submit name=\"ok\" value=\"OK\"></form>" - -#define CANCEL_OPTIONS "<form><b>Choose an action:</b><select NAME=\"action\" SIZE=\"1\"> \ -<option VALUE=\"C\">Cancel</option></select>    \ -<input TYPE=Submit name=\"ok\" value=\"OK\"></form>" -#endif - -extern EvolutionShellClient *global_shell_client; - -static const char *calendar_types[] = { "calendar", NULL }; -static const char *tasks_types[] = { "tasks", NULL }; - -static void class_init (EItipControlClass *klass); -static void init (EItipControl *itip); -static void destroy (GtkObject *obj); - -#if 0 -static void prev_clicked_cb (GtkWidget *widget, gpointer data); -static void next_clicked_cb (GtkWidget *widget, gpointer data); -#endif -static void url_requested_cb (GtkHTML *html, const gchar *url, GtkHTMLStream *handle, gpointer data); -static gboolean object_requested_cb (GtkHTML *html, GtkHTMLEmbedded *eb, gpointer data); -static void ok_clicked_cb (GtkHTML *html, const gchar *method, const gchar *url, const gchar *encoding, gpointer data); - -static GtkVBoxClass *parent_class = NULL; - - -GtkType -e_itip_control_get_type (void) -{ - static GtkType type = 0; - - if (type == 0) { - static const GtkTypeInfo info = - { - "EItipControl", - sizeof (EItipControl), - sizeof (EItipControlClass), - (GtkClassInitFunc) class_init, - (GtkObjectInitFunc) init, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - type = gtk_type_unique (gtk_vbox_get_type (), &info); - } - - return type; -} - -static void -class_init (EItipControlClass *klass) -{ - GtkObjectClass *object_class; - - object_class = GTK_OBJECT_CLASS (klass); - - parent_class = gtk_type_class (gtk_vbox_get_type ()); - - object_class->destroy = destroy; -} - - -/* Calendar Server routines */ -static void -start_calendar_server_cb (CalClient *cal_client, - CalClientOpenStatus status, - gpointer data) -{ - gboolean *success = data; - - if (status == CAL_CLIENT_OPEN_SUCCESS) - *success = TRUE; - else - *success = FALSE; - - gtk_main_quit (); /* end the sub event loop */ -} - -static CalClient * -start_calendar_server (char *uri) -{ - CalClient *client; - gboolean success = FALSE; - - client = cal_client_new (); - - gtk_signal_connect (GTK_OBJECT (client), "cal_opened", - start_calendar_server_cb, &success); - - cal_client_open_calendar (client, uri, TRUE); - - /* run a sub event loop to turn cal-client's async load - notification into a synchronous call */ - gtk_main (); - - if (success) - return client; - - gtk_object_unref (GTK_OBJECT (client)); - - return NULL; -} - -static CalClient * -start_default_server (gboolean tasks) -{ - CalClient *client; - gboolean success = FALSE; - - client = cal_client_new (); - - gtk_signal_connect (GTK_OBJECT (client), "cal_opened", - start_calendar_server_cb, &success); - - if (tasks) { - if (!cal_client_open_default_tasks (client, FALSE)) - goto error; - } else { - if (!cal_client_open_default_calendar (client, FALSE)) - goto error; - } - - /* run a sub event loop to turn cal-client's async load - notification into a synchronous call */ - gtk_main (); - - if (success) - return client; - - error: - gtk_object_unref (GTK_OBJECT (client)); - - return NULL; -} - -static GPtrArray * -get_servers (EvolutionShellClient *shell_client, const char *possible_types[], gboolean tasks) -{ - GNOME_Evolution_StorageRegistry registry; - GNOME_Evolution_StorageRegistry_StorageList *storage_list; - GPtrArray *servers; - int i, j, k; - CORBA_Environment ev; - - servers = g_ptr_array_new (); - - bonobo_object_ref (BONOBO_OBJECT (shell_client)); - registry = evolution_shell_client_get_storage_registry_interface (shell_client); - - CORBA_exception_init (&ev); - storage_list = GNOME_Evolution_StorageRegistry_getStorageList (registry, &ev); - if (BONOBO_EX (&ev)) { - CORBA_exception_free (&ev); - return servers; - } - - for (i = 0; i < storage_list->_length; i++) { - GNOME_Evolution_Storage storage; - GNOME_Evolution_FolderList *folder_list; - - storage = storage_list->_buffer[i]; - folder_list = GNOME_Evolution_Storage__get_folderList (storage, &ev); - - for (j = 0; j < folder_list->_length; j++) { - GNOME_Evolution_Folder folder; - - folder = folder_list->_buffer[j]; - for (k = 0; possible_types[k] != NULL; k++) { - CalClient *client; - char *uri; - - if (strcmp (possible_types[k], folder.type)) - continue; - - uri = cal_util_expand_uri (folder.physicalUri, tasks); - client = start_calendar_server (uri); - if (client != NULL) - g_ptr_array_add (servers, client); - g_free (uri); - - break; - } - } - - CORBA_free (folder_list); - } - - bonobo_object_unref (BONOBO_OBJECT (shell_client)); - - return servers; -} - -static CalClient * -find_server (GPtrArray *servers, CalComponent *comp) -{ - const char *uid; - int i; - - cal_component_get_uid (comp, &uid); - for (i = 0; i < servers->len; i++) { - CalClient *client; - CalComponent *found_comp; - CalClientGetStatus status; - - client = g_ptr_array_index (servers, i); - status = cal_client_get_object (client, uid, &found_comp); - if (status == CAL_CLIENT_GET_SUCCESS) { - gtk_object_unref (GTK_OBJECT (found_comp)); - gtk_object_ref (GTK_OBJECT (client)); - - return client; - } - } - - return NULL; -} - -static void -init (EItipControl *itip) -{ - EItipControlPrivate *priv; - GtkWidget *scrolled_window; - - priv = g_new0 (EItipControlPrivate, 1); - - itip->priv = priv; - - /* Addresses */ - priv->addresses = itip_addresses_get (); - - /* Header */ -#if 0 - priv->prev = gnome_stock_button (GNOME_STOCK_BUTTON_PREV); - gtk_widget_show (priv->prev); - priv->next = gnome_stock_button (GNOME_STOCK_BUTTON_NEXT); - gtk_widget_show (priv->next); - - hbox = gtk_hbox_new (FALSE, 0); - gtk_box_pack_start (GTK_BOX (hbox), priv->prev, FALSE, FALSE, 4); - gtk_box_pack_start (GTK_BOX (hbox), priv->count, TRUE, TRUE, 4); - gtk_box_pack_start (GTK_BOX (hbox), priv->next, FALSE, FALSE, 4); - gtk_widget_show (hbox); - - gtk_signal_connect (GTK_OBJECT (priv->prev), "clicked", - GTK_SIGNAL_FUNC (prev_clicked_cb), itip); - gtk_signal_connect (GTK_OBJECT (priv->next), "clicked", - GTK_SIGNAL_FUNC (next_clicked_cb), itip); -#endif - - /* Get the cal clients */ - priv->event_clients = get_servers (global_shell_client, calendar_types, FALSE); - priv->event_client = NULL; - priv->task_clients = get_servers (global_shell_client, tasks_types, TRUE); - priv->task_client = NULL; - - /* Html Widget */ - priv->html = gtk_html_new (); - gtk_html_set_default_content_type (GTK_HTML (priv->html), - "text/html; charset=utf-8"); - gtk_widget_show (priv->html); - - scrolled_window = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - gtk_widget_show (scrolled_window); - - gtk_container_add (GTK_CONTAINER (scrolled_window), priv->html); - gtk_widget_set_usize (scrolled_window, 600, 400); - gtk_box_pack_start (GTK_BOX (itip), scrolled_window, FALSE, FALSE, 4); - - gtk_signal_connect (GTK_OBJECT (priv->html), "url_requested", - url_requested_cb, itip); - gtk_signal_connect (GTK_OBJECT (priv->html), "object_requested", - GTK_SIGNAL_FUNC (object_requested_cb), - itip); - gtk_signal_connect (GTK_OBJECT (priv->html), "submit", - ok_clicked_cb, itip); - -} - -static void -clean_up (EItipControl *itip) -{ - EItipControlPrivate *priv; - - priv = itip->priv; - - g_free (priv->vcalendar); - priv->vcalendar = NULL; - - if (priv->comp) - gtk_object_unref (GTK_OBJECT (priv->comp)); - priv->comp = NULL; - - icalcomponent_free (priv->top_level); - priv->top_level = NULL; - icalcomponent_free (priv->main_comp); - priv->main_comp = NULL; - priv->ical_comp = NULL; - - priv->current = 0; - priv->total = 0; - - g_free (priv->my_address); - priv->my_address = NULL; - g_free (priv->from_address); - priv->from_address = NULL; -} - -static void -destroy (GtkObject *obj) -{ - EItipControl *itip = E_ITIP_CONTROL (obj); - EItipControlPrivate *priv; - int i; - - priv = itip->priv; - - clean_up (itip); - - itip_addresses_free (priv->addresses); - priv->addresses = NULL; - - for (i = 0; i < priv->event_clients->len; i++) - gtk_object_unref (GTK_OBJECT (g_ptr_array_index (priv->event_clients, i))); - g_ptr_array_free (priv->event_clients, TRUE); - for (i = 0; i < priv->task_clients->len; i++) - gtk_object_unref (GTK_OBJECT (g_ptr_array_index (priv->task_clients, i))); - g_ptr_array_free (priv->task_clients, TRUE); - - g_free (priv); - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (obj); -} - -GtkWidget * -e_itip_control_new (void) -{ - return gtk_type_new (E_TYPE_ITIP_CONTROL); -} - -static void -find_my_address (EItipControl *itip, icalcomponent *ical_comp) -{ - EItipControlPrivate *priv; - icalproperty *prop; - char *my_alt_address = NULL; - - priv = itip->priv; - - for (prop = icalcomponent_get_first_property (ical_comp, ICAL_ATTENDEE_PROPERTY); - prop != NULL; - prop = icalcomponent_get_next_property (ical_comp, ICAL_ATTENDEE_PROPERTY)) - { - icalvalue *value; - icalparameter *param; - const char *attendee, *name; - char *attendee_clean, *name_clean; - GList *l; - - value = icalproperty_get_value (prop); - if (value != NULL) { - attendee = icalvalue_get_string (value); - attendee_clean = g_strdup (itip_strip_mailto (attendee)); - attendee_clean = g_strstrip (attendee_clean); - } else { - attendee = NULL; - attendee_clean = NULL; - } - - param = icalproperty_get_first_parameter (prop, ICAL_CN_PARAMETER); - if (param != NULL) { - name = icalparameter_get_cn (param); - name_clean = g_strdup (name); - name_clean = g_strstrip (name_clean); - } else { - name = NULL; - name_clean = NULL; - } - - for (l = priv->addresses; l != NULL; l = l->next) { - ItipAddress *a = l->data; - - /* Check for a matching address */ - if (attendee_clean != NULL - && !g_strcasecmp (a->address, attendee_clean)) { - priv->my_address = g_strdup (a->address); - g_free (attendee_clean); - g_free (name_clean); - return; - } - - /* Check for a matching cname to fall back on */ - if (name_clean != NULL - && !g_strcasecmp (a->name, name_clean)) - my_alt_address = g_strdup (attendee_clean); - } - g_free (attendee_clean); - g_free (name_clean); - } - - priv->my_address = my_alt_address; -} - -static icalproperty * -find_attendee (icalcomponent *ical_comp, const char *address) -{ - icalproperty *prop; - - if (address == NULL) - return NULL; - - for (prop = icalcomponent_get_first_property (ical_comp, ICAL_ATTENDEE_PROPERTY); - prop != NULL; - prop = icalcomponent_get_next_property (ical_comp, ICAL_ATTENDEE_PROPERTY)) - { - icalvalue *value; - const char *attendee; - char *text; - - value = icalproperty_get_value (prop); - if (!value) - continue; - - attendee = icalvalue_get_string (value); - - text = g_strdup (itip_strip_mailto (attendee)); - text = g_strstrip (text); - if (!g_strcasecmp (address, text)) { - g_free (text); - break; - } - g_free (text); - } - - return prop; -} - -#if 0 -static void -set_label (EItipControl *itip) -{ - EItipControlPrivate *priv; - gchar *text; - - priv = itip->priv; - - text = g_strdup_printf ("%d of %d", priv->current, priv->total); - gtk_label_set_text (GTK_LABEL (priv->count), text); - -} - -static void -set_button_status (EItipControl *itip) -{ - EItipControlPrivate *priv; - - priv = itip->priv; - - if (priv->current == priv->total) - gtk_widget_set_sensitive (priv->next, FALSE); - else - gtk_widget_set_sensitive (priv->next, TRUE); - - if (priv->current == 1) - gtk_widget_set_sensitive (priv->prev, FALSE); - else - gtk_widget_set_sensitive (priv->prev, TRUE); -} -#endif - -static void -write_label_piece (EItipControl *itip, CalComponentDateTime *dt, - char *buffer, int size, - const char *stext, const char *etext) -{ - EItipControlPrivate *priv; - struct tm tmp_tm; - char time_buf[64], *time_utf8; - icaltimezone *zone = NULL; - char *display_name; - - priv = itip->priv; - - /* UTC times get converted to the current timezone. This is done for - the COMPLETED property, which is always in UTC, and also because - Outlook sends simple events as UTC times. */ - if (dt->value->is_utc) { - char *location = calendar_config_get_timezone (); - zone = icaltimezone_get_builtin_timezone (location); - icaltimezone_convert_time (dt->value, icaltimezone_get_utc_timezone (), zone); - } - - tmp_tm = icaltimetype_to_tm (dt->value); - - if (stext != NULL) - strcat (buffer, stext); - - e_time_format_date_and_time (&tmp_tm, - calendar_config_get_24_hour_format (), - FALSE, FALSE, - time_buf, sizeof (time_buf)); - - time_utf8 = e_utf8_from_locale_string (time_buf); - strcat (buffer, time_utf8); - g_free (time_utf8); - - if (!dt->value->is_utc && dt->tzid) { - zone = icalcomponent_get_timezone (priv->top_level, dt->tzid); - } - - /* Output timezone after time, e.g. " America/New_York". */ - if (zone) { - /* Note that this returns UTF-8, since all iCalendar data is - UTF-8. But it probably is not translated. */ - display_name = icaltimezone_get_display_name (zone); - if (display_name && *display_name) { - strcat (buffer, " "); - - /* We check if it is one of our builtin timezone names, - in which case we call gettext to translate it, and - we need to convert to UTF-8. If it isn't a builtin - timezone name, we use it as-is, as it is already - UTF-8. */ - if (icaltimezone_get_builtin_timezone (display_name)) { - strcat (buffer, U_(display_name)); - } else { - strcat (buffer, display_name); - } - } - } - - if (etext != NULL) - strcat (buffer, etext); -} - -static void -set_date_label (EItipControl *itip, GtkHTML *html, GtkHTMLStream *html_stream, - CalComponent *comp) -{ - EItipControlPrivate *priv; - CalComponentDateTime datetime; - static char buffer[1024]; - gboolean wrote = FALSE, task_completed = FALSE; - CalComponentVType type; - - priv = itip->priv; - - type = cal_component_get_vtype (comp); - - buffer[0] = '\0'; - cal_component_get_dtstart (comp, &datetime); - if (datetime.value) { - switch (type) { - case CAL_COMPONENT_EVENT: - write_label_piece (itip, &datetime, buffer, 1024, - U_("Meeting begins: <b>"), - "</b><br>"); - break; - case CAL_COMPONENT_TODO: - write_label_piece (itip, &datetime, buffer, 1024, - U_("Task begins: <b>"), - "</b><br>"); - break; - case CAL_COMPONENT_FREEBUSY: - write_label_piece (itip, &datetime, buffer, 1024, - U_("Free/Busy info begins: <b>"), - "</b><br>"); - break; - default: - write_label_piece (itip, &datetime, buffer, 1024, U_("Begins: <b>"), "</b><br>"); - } - gtk_html_write (html, html_stream, buffer, strlen(buffer)); - wrote = TRUE; - } - cal_component_free_datetime (&datetime); - - buffer[0] = '\0'; - cal_component_get_dtend (comp, &datetime); - if (datetime.value){ - switch (type) { - case CAL_COMPONENT_EVENT: - write_label_piece (itip, &datetime, buffer, 1024, U_("Meeting ends: <b>"), "</b><br>"); - break; - case CAL_COMPONENT_FREEBUSY: - write_label_piece (itip, &datetime, buffer, 1024, U_("Free/Busy info ends: <b>"), - "</b><br>"); - break; - default: - write_label_piece (itip, &datetime, buffer, 1024, U_("Ends: <b>"), "</b><br>"); - } - gtk_html_write (html, html_stream, buffer, strlen (buffer)); - wrote = TRUE; - } - cal_component_free_datetime (&datetime); - - buffer[0] = '\0'; - datetime.tzid = NULL; - cal_component_get_completed (comp, &datetime.value); - if (type == CAL_COMPONENT_TODO && datetime.value) { - /* Pass TRUE as is_utc, so it gets converted to the current - timezone. */ - datetime.value->is_utc = TRUE; - write_label_piece (itip, &datetime, buffer, 1024, U_("Task Completed: <b>"), "</b><br>"); - gtk_html_write (html, html_stream, buffer, strlen (buffer)); - wrote = TRUE; - task_completed = TRUE; - } - cal_component_free_datetime (&datetime); - - buffer[0] = '\0'; - cal_component_get_due (comp, &datetime); - if (type == CAL_COMPONENT_TODO && !task_completed && datetime.value) { - write_label_piece (itip, &datetime, buffer, 1024, U_("Task Due: <b>"), "</b><br>"); - gtk_html_write (html, html_stream, buffer, strlen (buffer)); - wrote = TRUE; - } - - cal_component_free_datetime (&datetime); - - if (wrote) - gtk_html_stream_printf (html_stream, "<br>"); -} - -static void -set_message (GtkHTML *html, GtkHTMLStream *html_stream, const gchar *message, gboolean err) -{ - if (message == NULL) - return; - - - if (err) { - gtk_html_stream_printf (html_stream, "<b><font color=\"#ff0000\">%s</font></b><br><br>", message); - } else { - gtk_html_stream_printf (html_stream, "<b>%s</b><br><br>", message); - } -} - -static void -write_error_html (EItipControl *itip, const gchar *itip_err) -{ - EItipControlPrivate *priv; - GtkHTMLStream *html_stream; - - priv = itip->priv; - - /* Html widget */ - html_stream = gtk_html_begin (GTK_HTML (priv->html)); - gtk_html_stream_printf (html_stream, - "<html><head><title>%s</title></head>", - U_("iCalendar Information")); - - gtk_html_write (GTK_HTML (priv->html), html_stream, - HTML_BODY_START, strlen(HTML_BODY_START)); - - /* The table */ - gtk_html_stream_printf (html_stream, "<table width=450 cellspacing=\"0\" cellpadding=\"4\" border=\"0\">"); - /* The column for the image */ - gtk_html_stream_printf (html_stream, "<tr><td width=48 align=\"center\" valign=\"top\" rowspan=\"8\">"); - /* The image */ - gtk_html_stream_printf (html_stream, "<img src=\"/meeting-request.png\"></td>"); - - gtk_html_stream_printf (html_stream, "<td align=\"left\" valign=\"top\">"); - - /* Title */ - set_message (GTK_HTML (priv->html), html_stream, U_("iCalendar Error"), TRUE); - - /* Error */ - gtk_html_write (GTK_HTML (priv->html), html_stream, itip_err, strlen(itip_err)); - - /* Clean up */ - gtk_html_stream_printf (html_stream, "</td></tr></table>"); - - gtk_html_write (GTK_HTML (priv->html), html_stream, - HTML_BODY_END, strlen(HTML_BODY_END)); - gtk_html_write (GTK_HTML (priv->html), html_stream, - HTML_FOOTER, strlen(HTML_FOOTER)); - - gtk_html_end (GTK_HTML (priv->html), html_stream, GTK_HTML_STREAM_OK); -} - -static void -write_html (EItipControl *itip, const gchar *itip_desc, const gchar *itip_title, const gchar *options) -{ - EItipControlPrivate *priv; - GtkHTMLStream *html_stream; - CalComponentText text; - CalComponentOrganizer organizer; - CalComponentAttendee *attendee; - GSList *attendees, *l = NULL; - gchar *html; - const gchar *const_html; - - priv = itip->priv; - - /* Html widget */ - html_stream = gtk_html_begin (GTK_HTML (priv->html)); - gtk_html_stream_printf (html_stream, - "<html><head><title>%s</title></head>", - U_("iCalendar Information")); - gtk_html_write (GTK_HTML (priv->html), html_stream, - HTML_BODY_START, strlen(HTML_BODY_START)); - - /* The table */ - const_html = "<table width=450 cellspacing=\"0\" cellpadding=\"4\" border=\"0\">"; - gtk_html_write (GTK_HTML (priv->html), html_stream, const_html, strlen(const_html)); - - /* The column for the image */ - const_html = "<tr><td width=48 align=\"center\" valign=\"top\" rowspan=\"8\">"; - gtk_html_write (GTK_HTML (priv->html), html_stream, const_html, strlen(const_html)); - - /* The image */ - const_html = "<img src=\"/meeting-request.png\"></td>"; - gtk_html_write (GTK_HTML (priv->html), html_stream, const_html, strlen(const_html)); - - const_html = "<td align=\"left\" valign=\"top\">"; - gtk_html_write (GTK_HTML (priv->html), html_stream, const_html, strlen(const_html)); - - switch (priv->method) { - case ICAL_METHOD_REFRESH: - case ICAL_METHOD_REPLY: - /* An attendee sent this */ - cal_component_get_attendee_list (priv->comp, &attendees); - if (attendees != NULL) { - attendee = attendees->data; - html = g_strdup_printf (itip_desc, - attendee->cn ? - attendee->cn : - itip_strip_mailto (attendee->value)); - } else { - html = g_strdup_printf (itip_desc, U_("An unknown person")); - } - break; - case ICAL_METHOD_PUBLISH: - case ICAL_METHOD_REQUEST: - case ICAL_METHOD_ADD: - case ICAL_METHOD_CANCEL: - default: - /* The organizer sent this */ - cal_component_get_organizer (priv->comp, &organizer); - if (organizer.value != NULL) - html = g_strdup_printf (itip_desc, - organizer.cn ? - organizer.cn : - itip_strip_mailto (organizer.value)); - else - html = g_strdup_printf (itip_desc, U_("An unknown person")); - break; - } - gtk_html_write (GTK_HTML (priv->html), html_stream, html, strlen(html)); - g_free (html); - - /* Describe what the user can do */ - const_html = U_("<br> Please review the following information, " - "and then select an action from the menu below."); - gtk_html_write (GTK_HTML (priv->html), html_stream, const_html, strlen(const_html)); - - /* Separator */ - gtk_html_write (GTK_HTML (priv->html), html_stream, HTML_SEP, strlen (HTML_SEP)); - - /* Title */ - set_message (GTK_HTML (priv->html), html_stream, itip_title, FALSE); - - /* Date information */ - set_date_label (itip, GTK_HTML (priv->html), html_stream, priv->comp); - - /* Summary */ - cal_component_get_summary (priv->comp, &text); - gtk_html_stream_printf (html_stream, "<b>%s</b> %s<br><br>", - U_("Summary:"), text.value ? text.value : U_("<i>None</i>")); - - /* Status */ - if (priv->method == ICAL_METHOD_REPLY) { - GSList *alist; - - cal_component_get_attendee_list (priv->comp, &alist); - - if (alist != NULL) { - CalComponentAttendee *a = alist->data; - - gtk_html_stream_printf (html_stream, "<b>%s</b> ", - U_("Status:")); - - switch (a->status) { - case ICAL_PARTSTAT_ACCEPTED: - gtk_html_stream_printf (html_stream, "%s<br><br>", - U_("Accepted")); - break; - case ICAL_PARTSTAT_TENTATIVE: - gtk_html_stream_printf (html_stream, "%s<br><br>", - U_("Tentatively Accepted")); - break; - case ICAL_PARTSTAT_DECLINED: - gtk_html_stream_printf (html_stream, "%s<br><br>", - U_("Declined")); - break; - default: - gtk_html_stream_printf (html_stream, "%s<br><br>", - U_("Unknown")); - } - } - - cal_component_free_attendee_list (alist); - } - - /* Description */ - cal_component_get_description_list (priv->comp, &l); - if (l) - text = *((CalComponentText *)l->data); - - if (l && text.value) { - gtk_html_stream_printf (html_stream, "<b>%s</b> %s", - U_("Description:"), text.value); - } - cal_component_free_text_list (l); - - /* Separator */ - gtk_html_write (GTK_HTML (priv->html), html_stream, HTML_SEP, strlen (HTML_SEP)); - - /* Options */ - if (options != NULL) { - const_html = "</td></tr><tr><td valign=\"center\">"; - gtk_html_write (GTK_HTML (priv->html), html_stream, const_html, strlen (const_html)); - gtk_html_write (GTK_HTML (priv->html), html_stream, options, strlen (options)); - } - - const_html = "</td></tr></table>"; - gtk_html_write (GTK_HTML (priv->html), html_stream, const_html, strlen(const_html)); - - gtk_html_write (GTK_HTML (priv->html), html_stream, - HTML_BODY_END, strlen(HTML_BODY_END)); - gtk_html_write (GTK_HTML (priv->html), html_stream, - HTML_FOOTER, strlen(HTML_FOOTER)); - - gtk_html_end (GTK_HTML (priv->html), html_stream, GTK_HTML_STREAM_OK); -} - - -static char* -get_publish_options (gboolean selector) -{ - char *html; - - html = g_strdup_printf ("<form><b>%s</b> " - "<select NAME=\"action\" SIZE=\"1\"> " - "<option VALUE=\"U\">%s</option>" - "</select>    " - "<input TYPE=Submit name=\"ok\" value=\"%s\">" - "</form>", - U_("Choose an action:"), - U_("Update"), - U_("OK")); - - if (selector) { - char *sel; - - sel = g_strconcat (html, "<object classid=\"gtk:label\">", NULL); - g_free (html); - html = sel; - } - - return html; -} - -static char* -get_request_options (gboolean selector) -{ - char *html; - - html = g_strdup_printf ("<form><b>%s</b> " - "<select NAME=\"action\" SIZE=\"1\"> " - "<option VALUE=\"A\">%s</option> " - "<option VALUE=\"T\">%s</option> " - "<option VALUE=\"D\">%s</option></select>  " - "<input TYPE=\"checkbox\" name=\"rsvp\" value=\"1\" checked>%s  " - "<input TYPE=\"submit\" name=\"ok\" value=\"%s\"><br> " - "</form>", - U_("Choose an action:"), - U_("Accept"), - U_("Tentatively accept"), - U_("Decline"), - U_("RSVP"), - U_("OK")); - - if (selector) { - char *sel; - - sel = g_strconcat (html, "<object classid=\"gtk:label\">", NULL); - g_free (html); - html = sel; - } - - return html; -} - -static char* -get_request_fb_options () -{ - return g_strdup_printf ("<form><b>%s</b> " - "<select NAME=\"action\" SIZE=\"1\"> " - "<option VALUE=\"F\">%s</option></select>    " - "<input TYPE=Submit name=\"ok\" value=\"%s\">" - "</form>", - U_("Choose an action:"), - U_("Send Free/Busy Information"), - U_("OK")); -} - -static char* -get_reply_options () -{ - return g_strdup_printf ("<form><b>%s</b> " - "<select NAME=\"action\" SIZE=\"1\"> " - "<option VALUE=\"R\">%s</option></select>    " - "<input TYPE=Submit name=\"ok\" value=\"%s\">" - "</form>", - U_("Choose an action:"), - U_("Update respondent status"), - U_("OK")); -} - -static char* -get_refresh_options () -{ - return g_strdup_printf ("<form><b>%s</b> " - "<select NAME=\"action\" SIZE=\"1\"> " - "<option VALUE=\"S\">%s</option></select>    " - "<input TYPE=Submit name=\"ok\" value=\"%s\">" - "</form>", - U_("Choose an action:"), - U_("Send Latest Information"), - U_("OK")); -} - -static char* -get_cancel_options () -{ - return g_strdup_printf ("<form><b>%s</b> " - "<select NAME=\"action\" SIZE=\"1\"> " - "<option VALUE=\"C\">%s</option></select>    " - "<input TYPE=Submit name=\"ok\" value=\"%s\">" - "</form>", - U_("Choose an action:"), - U_("Cancel"), - U_("OK")); -} - - -static CalComponent * -get_real_item (EItipControl *itip) -{ - EItipControlPrivate *priv; - CalComponent *comp; - CalComponentVType type; - CalClientGetStatus status = CAL_CLIENT_GET_NOT_FOUND; - const char *uid; - - priv = itip->priv; - - type = cal_component_get_vtype (priv->comp); - cal_component_get_uid (priv->comp, &uid); - - switch (type) { - case CAL_COMPONENT_EVENT: - if (priv->event_client != NULL) - status = cal_client_get_object (priv->event_client, uid, &comp); - break; - case CAL_COMPONENT_TODO: - if (priv->task_client != NULL) - status = cal_client_get_object (priv->task_client, uid, &comp); - break; - default: - status = CAL_CLIENT_GET_NOT_FOUND; - } - - if (status != CAL_CLIENT_GET_SUCCESS) - return NULL; - - return comp; -} - -static void -show_current_event (EItipControl *itip) -{ - EItipControlPrivate *priv; - CalComponent *comp; - const gchar *itip_title, *itip_desc; - char *options; - - priv = itip->priv; - - priv->event_client = find_server (priv->event_clients, priv->comp); - - switch (priv->method) { - case ICAL_METHOD_PUBLISH: - itip_desc = U_("<b>%s</b> has published meeting information."); - itip_title = U_("Meeting Information"); - options = get_publish_options (priv->event_client ? FALSE : TRUE); - break; - case ICAL_METHOD_REQUEST: - itip_desc = U_("<b>%s</b> requests your presence at a meeting."); - itip_title = U_("Meeting Proposal"); - options = get_request_options (priv->event_client ? FALSE : TRUE); - break; - case ICAL_METHOD_ADD: - itip_desc = U_("<b>%s</b> wishes to add to an existing meeting."); - itip_title = U_("Meeting Update"); - options = get_publish_options (priv->event_client ? FALSE : TRUE); - break; - case ICAL_METHOD_REFRESH: - itip_desc = U_("<b>%s</b> wishes to receive the latest meeting information."); - itip_title = U_("Meeting Update Request"); - options = get_refresh_options (); - - /* Provide extra info, since its not in the component */ - comp = get_real_item (itip); - if (comp != NULL) { - CalComponentText text; - GSList *l; - - cal_component_get_summary (comp, &text); - cal_component_set_summary (priv->comp, &text); - cal_component_get_description_list (comp, &l); - cal_component_set_description_list (priv->comp, l); - cal_component_free_text_list (l); - - gtk_object_unref (GTK_OBJECT (comp)); - } else { - CalComponentText text = {_("Unknown"), NULL}; - - cal_component_set_summary (priv->comp, &text); - } - break; - case ICAL_METHOD_REPLY: - itip_desc = U_("<b>%s</b> has replied to a meeting request."); - itip_title = U_("Meeting Reply"); - options = get_reply_options (); - break; - case ICAL_METHOD_CANCEL: - itip_desc = U_("<b>%s</b> has cancelled a meeting."); - itip_title = U_("Meeting Cancellation"); - options = get_cancel_options (); - break; - default: - itip_desc = U_("<b>%s</b> has sent an unintelligible message."); - itip_title = U_("Bad Meeting Message"); - options = NULL; - } - - write_html (itip, itip_desc, itip_title, options); - g_free (options); -} - -static void -show_current_todo (EItipControl *itip) -{ - EItipControlPrivate *priv; - CalComponent *comp; - const gchar *itip_title, *itip_desc; - char *options; - - priv = itip->priv; - - priv->task_client = find_server (priv->task_clients, priv->comp); - - switch (priv->method) { - case ICAL_METHOD_PUBLISH: - itip_desc = U_("<b>%s</b> has published task information."); - itip_title = U_("Task Information"); - options = get_publish_options (priv->task_client ? FALSE : TRUE); - break; - case ICAL_METHOD_REQUEST: - itip_desc = U_("<b>%s</b> requests you perform a task."); - itip_title = U_("Task Proposal"); - options = get_request_options (priv->task_client ? FALSE : TRUE); - break; - case ICAL_METHOD_ADD: - itip_desc = U_("<b>%s</b> wishes to add to an existing task."); - itip_title = U_("Task Update"); - options = get_publish_options (priv->task_client ? FALSE : TRUE); - break; - case ICAL_METHOD_REFRESH: - itip_desc = U_("<b>%s</b> wishes to receive the latest task information."); - itip_title = U_("Task Update Request"); - options = get_refresh_options (); - - - /* Provide extra info, since its not in the component */ - comp = get_real_item (itip); - if (comp != NULL) { - CalComponentText text; - GSList *l; - - cal_component_get_summary (comp, &text); - cal_component_set_summary (priv->comp, &text); - cal_component_get_description_list (comp, &l); - cal_component_set_description_list (priv->comp, l); - cal_component_free_text_list (l); - - gtk_object_unref (GTK_OBJECT (comp)); - } else { - CalComponentText text = {_("Unknown"), NULL}; - - cal_component_set_summary (priv->comp, &text); - } - break; - case ICAL_METHOD_REPLY: - itip_desc = U_("<b>%s</b> has replied to a task assignment."); - itip_title = U_("Task Reply"); - options = get_reply_options (); - break; - case ICAL_METHOD_CANCEL: - itip_desc = U_("<b>%s</b> has cancelled a task."); - itip_title = U_("Task Cancellation"); - options = get_cancel_options (); - break; - default: - itip_desc = U_("<b>%s</b> has sent an unintelligible message."); - itip_title = U_("Bad Task Message"); - options = NULL; - } - - write_html (itip, itip_desc, itip_title, options); - g_free (options); -} - -static void -show_current_freebusy (EItipControl *itip) -{ - EItipControlPrivate *priv; - const gchar *itip_title, *itip_desc; - char *options; - - priv = itip->priv; - - switch (priv->method) { - case ICAL_METHOD_PUBLISH: - itip_desc = U_("<b>%s</b> has published free/busy information."); - itip_title = U_("Free/Busy Information"); - options = NULL; - break; - case ICAL_METHOD_REQUEST: - itip_desc = U_("<b>%s</b> requests your free/busy information."); - itip_title = U_("Free/Busy Request"); - options = get_request_fb_options (); - break; - case ICAL_METHOD_REPLY: - itip_desc = U_("<b>%s</b> has replied to a free/busy request."); - itip_title = U_("Free/Busy Reply"); - options = NULL; - break; - default: - itip_desc = U_("<b>%s</b> has sent an unintelligible message."); - itip_title = U_("Bad Free/Busy Message"); - options = NULL; - } - - write_html (itip, itip_desc, itip_title, options); - g_free (options); -} - -static icalcomponent * -get_next (icalcompiter *iter) -{ - icalcomponent *ret = NULL; - icalcomponent_kind kind; - - do { - icalcompiter_next (iter); - ret = icalcompiter_deref (iter); - kind = icalcomponent_isa (ret); - } while (ret != NULL - && kind != ICAL_VEVENT_COMPONENT - && kind != ICAL_VTODO_COMPONENT - && kind != ICAL_VFREEBUSY_COMPONENT); - - return ret; -} - -#if 0 -static icalcomponent * -get_prev (icalcompiter *iter) -{ - icalcomponent *ret = NULL; - icalcomponent_kind kind = ICAL_NO_COMPONENT; - - while (kind != ICAL_VEVENT_COMPONENT - && kind != ICAL_VTODO_COMPONENT - && kind != ICAL_VFREEBUSY_COMPONENT) { - icalcompiter_prior (iter); - ret = icalcompiter_deref (iter); - kind = icalcomponent_isa (ret); - } - - return ret; -} -#endif - -static void -show_current (EItipControl *itip) -{ - EItipControlPrivate *priv; - CalComponentVType type; - icalcomponent *alarm_comp; - icalcompiter alarm_iter; - - priv = itip->priv; - -#if 0 - set_label (itip); - set_button_status (itip); -#endif - - if (priv->comp) - gtk_object_unref (GTK_OBJECT (priv->comp)); - if (priv->event_client != NULL) - gtk_object_unref (GTK_OBJECT (priv->event_client)); - priv->event_client = NULL; - if (priv->task_client != NULL) - gtk_object_unref (GTK_OBJECT (priv->task_client)); - priv->task_client = NULL; - - /* Strip out alarms for security purposes */ - alarm_iter = icalcomponent_begin_component (priv->ical_comp, ICAL_VALARM_COMPONENT); - while ((alarm_comp = icalcompiter_deref (&alarm_iter)) != NULL) { - icalcomponent_remove_component (priv->ical_comp, alarm_comp); - - icalcompiter_next (&alarm_iter); - } - - priv->comp = cal_component_new (); - if (!cal_component_set_icalcomponent (priv->comp, priv->ical_comp)) { - write_error_html (itip, U_("The message does not appear to be properly formed")); - gtk_object_unref (GTK_OBJECT (priv->comp)); - priv->comp = NULL; - return; - }; - - type = cal_component_get_vtype (priv->comp); - - switch (type) { - case CAL_COMPONENT_EVENT: - show_current_event (itip); - break; - case CAL_COMPONENT_TODO: - show_current_todo (itip); - break; - case CAL_COMPONENT_FREEBUSY: - show_current_freebusy (itip); - break; - default: - write_error_html (itip, U_("The message contains only unsupported requests.")); - } - - find_my_address (itip, priv->ical_comp); -} - -void -e_itip_control_set_data (EItipControl *itip, const gchar *text) -{ - EItipControlPrivate *priv; - icalproperty *prop; - icalcomponent_kind kind = ICAL_NO_COMPONENT; - icalcomponent *tz_comp; - icalcompiter tz_iter; - - priv = itip->priv; - - clean_up (itip); - - priv->comp = NULL; - priv->total = 0; - priv->current = 0; - - priv->vcalendar = g_strdup (text); - priv->top_level = cal_util_new_top_level (); - - priv->main_comp = icalparser_parse_string (priv->vcalendar); - if (priv->main_comp == NULL) { - write_error_html (itip, U_("The attachment does not contain a valid calendar message")); - return; - } - - prop = icalcomponent_get_first_property (priv->main_comp, ICAL_METHOD_PROPERTY); - if (prop == NULL) { - write_error_html (itip, U_("The attachment does not contain a valid calendar message")); - return; - } - - priv->method = icalproperty_get_method (prop); - - tz_iter = icalcomponent_begin_component (priv->main_comp, ICAL_VTIMEZONE_COMPONENT); - while ((tz_comp = icalcompiter_deref (&tz_iter)) != NULL) { - icalcomponent *clone; - - clone = icalcomponent_new_clone (tz_comp); - icalcomponent_add_component (priv->top_level, clone); - - icalcompiter_next (&tz_iter); - } - - priv->iter = icalcomponent_begin_component (priv->main_comp, ICAL_ANY_COMPONENT); - priv->ical_comp = icalcompiter_deref (&priv->iter); - kind = icalcomponent_isa (priv->ical_comp); - if (kind != ICAL_VEVENT_COMPONENT - && kind != ICAL_VTODO_COMPONENT - && kind != ICAL_VFREEBUSY_COMPONENT) - priv->ical_comp = get_next (&priv->iter); - - if (priv->ical_comp == NULL) { - write_error_html (itip, U_("The attachment has no viewable calendar items")); - return; - } - - priv->total = icalcomponent_count_components (priv->main_comp, ICAL_VEVENT_COMPONENT); - priv->total += icalcomponent_count_components (priv->main_comp, ICAL_VTODO_COMPONENT); - priv->total += icalcomponent_count_components (priv->main_comp, ICAL_VFREEBUSY_COMPONENT); - - if (priv->total > 0) - priv->current = 1; - else - priv->current = 0; - - show_current (itip); -} - -gchar * -e_itip_control_get_data (EItipControl *itip) -{ - EItipControlPrivate *priv; - - priv = itip->priv; - - return g_strdup (priv->vcalendar); -} - -gint -e_itip_control_get_data_size (EItipControl *itip) -{ - EItipControlPrivate *priv; - - priv = itip->priv; - - if (priv->vcalendar == NULL) - return 0; - - return strlen (priv->vcalendar); -} - -void -e_itip_control_set_from_address (EItipControl *itip, const gchar *address) -{ - EItipControlPrivate *priv; - - priv = itip->priv; - - if (priv->from_address) - g_free (priv->from_address); - - priv->from_address = g_strdup (address); -} - -const gchar * -e_itip_control_get_from_address (EItipControl *itip) -{ - EItipControlPrivate *priv; - - priv = itip->priv; - - return priv->from_address; -} - - -static gboolean -change_status (icalcomponent *ical_comp, const char *address, icalparameter_partstat status) -{ - icalproperty *prop; - - prop = find_attendee (ical_comp, address); - if (prop) { - icalparameter *param; - - icalproperty_remove_parameter (prop, ICAL_PARTSTAT_PARAMETER); - param = icalparameter_new_partstat (status); - icalproperty_add_parameter (prop, param); - } else { - icalparameter *param; - - if (address != NULL) { - prop = icalproperty_new_attendee (address); - icalcomponent_add_property (ical_comp, prop); - - param = icalparameter_new_role (ICAL_ROLE_OPTPARTICIPANT); - icalproperty_add_parameter (prop, param); - - param = icalparameter_new_partstat (status); - icalproperty_add_parameter (prop, param); - } else { - ItipAddress *a; - - a = itip_addresses_get_default (); - - prop = icalproperty_new_attendee (a->address); - icalcomponent_add_property (ical_comp, prop); - - param = icalparameter_new_cn (a->name); - icalproperty_add_parameter (prop, param); - - param = icalparameter_new_role (ICAL_ROLE_REQPARTICIPANT); - icalproperty_add_parameter (prop, param); - - param = icalparameter_new_partstat (status); - icalproperty_add_parameter (prop, param); - - itip_address_free (a); - } - } - - return TRUE; -} - -static void -update_item (EItipControl *itip) -{ - EItipControlPrivate *priv; - icalcomponent *clone; - CalClient *client; - CalComponentVType type; - GtkWidget *dialog; - - priv = itip->priv; - - type = cal_component_get_vtype (priv->comp); - if (type == CAL_COMPONENT_TODO) - client = priv->task_client; - else - client = priv->event_client; - - clone = icalcomponent_new_clone (priv->ical_comp); - icalcomponent_add_component (priv->top_level, clone); - - if (!cal_client_update_objects (client, priv->top_level)) - dialog = gnome_warning_dialog (_("Calendar file could not be updated!\n")); - else - dialog = gnome_ok_dialog (_("Update complete\n")); - gnome_dialog_run_and_close (GNOME_DIALOG (dialog)); - - icalcomponent_remove_component (priv->top_level, clone); -} - -static void -update_attendee_status (EItipControl *itip) -{ - EItipControlPrivate *priv; - CalClient *client; - CalClientGetStatus status; - CalComponent *comp = NULL; - CalComponentVType type; - const char *uid; - GtkWidget *dialog; - - priv = itip->priv; - - type = cal_component_get_vtype (priv->comp); - if (type == CAL_COMPONENT_TODO) - client = priv->task_client; - else - client = priv->event_client; - - if (client == NULL) { - dialog = gnome_warning_dialog (_("Attendee status can not be updated " - "because the item no longer exists")); - goto cleanup; - } - - /* Obtain our version */ - cal_component_get_uid (priv->comp, &uid); - status = cal_client_get_object (client, uid, &comp); - - if (status == CAL_CLIENT_GET_SUCCESS) { - GSList *attendees; - - cal_component_get_attendee_list (priv->comp, &attendees); - if (attendees != NULL) { - CalComponentAttendee *a = attendees->data; - icalproperty *prop; - - prop = find_attendee (cal_component_get_icalcomponent (comp), - itip_strip_mailto (a->value)); - - if (prop == NULL) { - dialog = gnome_question_dialog_modal (_("This response is not from a current " - "attendee. Add as an attendee?"), - NULL, NULL); - if (gnome_dialog_run_and_close (GNOME_DIALOG (dialog)) == GNOME_YES) { - change_status (cal_component_get_icalcomponent (comp), - itip_strip_mailto (a->value), - a->status); - cal_component_rescan (comp); - } else { - goto cleanup; - } - } else if (a->status == ICAL_PARTSTAT_NONE || a->status == ICAL_PARTSTAT_X) { - dialog = gnome_warning_dialog (_("Attendee status could " - "not be updated because " - "of an invalid status!\n")); - goto cleanup; - } else { - change_status (cal_component_get_icalcomponent (comp), - itip_strip_mailto (a->value), - a->status); - cal_component_rescan (comp); - } - } - - if (!cal_client_update_object (client, comp)) - dialog = gnome_warning_dialog (_("Attendee status could not be updated!\n")); - else - dialog = gnome_ok_dialog (_("Attendee status updated\n")); - } else { - dialog = gnome_warning_dialog (_("Attendee status can not be updated " - "because the item no longer exists")); - } - - cleanup: - if (comp != NULL) - gtk_object_unref (GTK_OBJECT (comp)); - gnome_dialog_run_and_close (GNOME_DIALOG (dialog)); -} - -static void -remove_item (EItipControl *itip) -{ - EItipControlPrivate *priv; - CalClient *client; - CalComponentVType type; - const char *uid; - GtkWidget *dialog; - - priv = itip->priv; - - type = cal_component_get_vtype (priv->comp); - if (type == CAL_COMPONENT_TODO) - client = priv->task_client; - else - client = priv->event_client; - - if (client == NULL) - return; - - cal_component_get_uid (priv->comp, &uid); - if (cal_client_remove_object (client, uid)) { - dialog = gnome_ok_dialog (_("Removal Complete")); - gnome_dialog_run_and_close (GNOME_DIALOG (dialog)); - } -} - -static void -send_item (EItipControl *itip) -{ - EItipControlPrivate *priv; - CalComponent *comp; - CalComponentVType vtype; - GtkWidget *dialog; - - priv = itip->priv; - - comp = get_real_item (itip); - vtype = cal_component_get_vtype (comp); - - if (comp != NULL) { - switch (vtype) { - case CAL_COMPONENT_EVENT: - itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, priv->event_client, NULL); - break; - case CAL_COMPONENT_TODO: - itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, priv->task_client, NULL); - break; - default: - itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, comp, NULL, NULL); - } - gtk_object_unref (GTK_OBJECT (comp)); - dialog = gnome_ok_dialog (_("Item sent!\n")); - } else { - dialog = gnome_warning_dialog (_("The item could not be sent!\n")); - } - gnome_dialog_run_and_close (GNOME_DIALOG (dialog)); -} - -static void -send_freebusy (EItipControl *itip) -{ - EItipControlPrivate *priv; - CalComponentDateTime datetime; - time_t start, end; - GtkWidget *dialog; - GList *comp_list; - icaltimezone *zone; - - priv = itip->priv; - - cal_component_get_dtstart (priv->comp, &datetime); - if (datetime.tzid) { - zone = icalcomponent_get_timezone (priv->top_level, - datetime.tzid); - } else { - zone = NULL; - } - start = icaltime_as_timet_with_zone (*datetime.value, zone); - cal_component_free_datetime (&datetime); - - cal_component_get_dtend (priv->comp, &datetime); - if (datetime.tzid) { - zone = icalcomponent_get_timezone (priv->top_level, - datetime.tzid); - } else { - zone = NULL; - } - end = icaltime_as_timet_with_zone (*datetime.value, zone); - cal_component_free_datetime (&datetime); - - comp_list = cal_client_get_free_busy (priv->event_client, NULL, start, end); - - if (comp_list) { - GList *l; - - for (l = comp_list; l; l = l->next) { - CalComponent *comp = CAL_COMPONENT (l->data); - itip_send_comp (CAL_COMPONENT_METHOD_REPLY, comp, priv->event_client, NULL); - - gtk_object_unref (GTK_OBJECT (comp)); - } - dialog = gnome_ok_dialog (_("Item sent!\n")); - - g_list_free (comp_list); - } else { - dialog = gnome_warning_dialog (_("The item could not be sent!\n")); - } - gnome_dialog_run_and_close (GNOME_DIALOG (dialog)); -} - -#if 0 -static void -prev_clicked_cb (GtkWidget *widget, gpointer data) -{ - EItipControl *itip = E_ITIP_CONTROL (data); - EItipControlPrivate *priv; - - priv = itip->priv; - - priv->current--; - priv->ical_comp = get_prev (&priv->iter); - - show_current (itip); -} - -static void -next_clicked_cb (GtkWidget *widget, gpointer data) -{ - EItipControl *itip = E_ITIP_CONTROL (data); - EItipControlPrivate *priv; - - priv = itip->priv; - - priv->current++; - priv->ical_comp = get_next (&priv->iter); - - show_current (itip); -} -#endif - -static void -button_selected_cb (EvolutionFolderSelectorButton *button, GNOME_Evolution_Folder *folder, gpointer data) -{ - EItipControl *itip = E_ITIP_CONTROL (data); - EItipControlPrivate *priv; - CalComponentVType type; - char *uri; - - priv = itip->priv; - - type = cal_component_get_vtype (priv->comp); - if (type == CAL_COMPONENT_TODO) - uri = cal_util_expand_uri (folder->physicalUri, TRUE); - else - uri = cal_util_expand_uri (folder->physicalUri, FALSE); - - gtk_object_unref (GTK_OBJECT (priv->event_client)); - priv->event_client = start_calendar_server (uri); - - g_free (uri); -} - -static void -url_requested_cb (GtkHTML *html, const gchar *url, GtkHTMLStream *handle, gpointer data) -{ unsigned char buffer[4096]; - int len, fd; - char *path; - - path = g_strdup_printf ("%s/%s", EVOLUTION_ICONSDIR, url); - - if ((fd = open (path, O_RDONLY)) == -1) { - g_warning ("%s", g_strerror (errno)); - goto cleanup; - } - - while ((len = read (fd, buffer, 4096)) > 0) { - gtk_html_write (html, handle, buffer, len); - } - - if (len < 0) { - /* check to see if we stopped because of an error */ - gtk_html_end (html, handle, GTK_HTML_STREAM_ERROR); - g_warning ("%s", g_strerror (errno)); - goto cleanup; - } - /* done with no errors */ - gtk_html_end (html, handle, GTK_HTML_STREAM_OK); - close (fd); - - cleanup: - g_free (path); -} - -static gboolean -object_requested_cb (GtkHTML *html, GtkHTMLEmbedded *eb, gpointer data) -{ - EItipControl *itip = E_ITIP_CONTROL (data); - EItipControlPrivate *priv; - GtkWidget *button; - CalComponentVType vtype; - - priv = itip->priv; - - vtype = cal_component_get_vtype (priv->comp); - - switch (vtype) { - case CAL_COMPONENT_EVENT: - button = evolution_folder_selector_button_new ( - global_shell_client, _("Select Calendar Folder"), - calendar_config_default_calendar_folder (), - calendar_types); - priv->event_client = start_default_server (FALSE); - break; - case CAL_COMPONENT_TODO: - button = evolution_folder_selector_button_new ( - global_shell_client, _("Select Tasks Folder"), - calendar_config_default_tasks_folder (), - tasks_types); - priv->task_client = start_default_server (TRUE); - break; - default: - button = NULL; - } - - gtk_signal_connect (GTK_OBJECT (button), "selected", - button_selected_cb, itip); - - gtk_container_add (GTK_CONTAINER (eb), button); - gtk_widget_show (button); - - return TRUE; -} - -static void -ok_clicked_cb (GtkHTML *html, const gchar *method, const gchar *url, const gchar *encoding, gpointer data) -{ - EItipControl *itip = E_ITIP_CONTROL (data); - EItipControlPrivate *priv; - gchar **fields; - gboolean rsvp = FALSE, status = FALSE; - int i; - - priv = itip->priv; - - fields = g_strsplit (encoding, "&", -1); - for (i = 0; fields[i] != NULL; i++) { - gchar **key_value; - - key_value = g_strsplit (fields[i], "=", 2); - - if (key_value[0] != NULL && !strcmp (key_value[0], "action")) { - if (key_value[1] == NULL) - break; - - switch (key_value[1][0]) { - case 'U': - update_item (itip); - break; - case 'A': - status = change_status (priv->ical_comp, priv->my_address, - ICAL_PARTSTAT_ACCEPTED); - if (status) { - cal_component_rescan (priv->comp); - update_item (itip); - } - break; - case 'T': - status = change_status (priv->ical_comp, priv->my_address, - ICAL_PARTSTAT_TENTATIVE); - if (status) { - cal_component_rescan (priv->comp); - update_item (itip); - } - break; - case 'D': - status = change_status (priv->ical_comp, priv->my_address, - ICAL_PARTSTAT_DECLINED); - if (status) { - cal_component_rescan (priv->comp); - remove_item (itip); - } - break; - case 'F': - send_freebusy (itip); - break; - case 'R': - update_attendee_status (itip); - break; - case 'S': - send_item (itip); - break; - case 'C': - remove_item (itip); - break; - } - } - - if (key_value[0] != NULL && !strcmp (key_value[0], "rsvp")) - if (*key_value[1] == '1') - rsvp = TRUE; - - g_strfreev (key_value); - - } - g_strfreev (fields); - - if (rsvp && status) { - CalComponent *comp = NULL; - CalComponentVType vtype; - icalcomponent *ical_comp; - icalproperty *prop; - icalvalue *value; - const char *attendee; - GSList *l, *list = NULL; - - comp = cal_component_clone (priv->comp); - if (comp == NULL) - return; - vtype = cal_component_get_vtype (comp); - - if (priv->my_address == NULL) - find_my_address (itip, priv->ical_comp); - g_assert (priv->my_address != NULL); - - ical_comp = cal_component_get_icalcomponent (comp); - - for (prop = icalcomponent_get_first_property (ical_comp, ICAL_ATTENDEE_PROPERTY); - prop != NULL; - prop = icalcomponent_get_next_property (ical_comp, ICAL_ATTENDEE_PROPERTY)) - { - char *text; - - value = icalproperty_get_value (prop); - if (!value) - continue; - - attendee = icalvalue_get_string (value); - - text = g_strdup (itip_strip_mailto (attendee)); - text = g_strstrip (text); - if (g_strcasecmp (priv->my_address, text)) - list = g_slist_prepend (list, prop); - g_free (text); - } - - for (l = list; l; l = l->next) { - prop = l->data; - icalcomponent_remove_property (ical_comp, prop); - icalproperty_free (prop); - } - g_slist_free (list); - - cal_component_rescan (comp); - switch (vtype) { - case CAL_COMPONENT_EVENT: - itip_send_comp (CAL_COMPONENT_METHOD_REPLY, comp, - priv->event_client, priv->top_level); - break; - case CAL_COMPONENT_TODO: - itip_send_comp (CAL_COMPONENT_METHOD_REPLY, comp, - priv->task_client, priv->top_level); - break; - default: - itip_send_comp (CAL_COMPONENT_METHOD_REPLY, comp, NULL, NULL); - } - gtk_object_unref (GTK_OBJECT (comp)); - } -} diff --git a/calendar/gui/e-itip-control.glade b/calendar/gui/e-itip-control.glade deleted file mode 100644 index 68e15d6989..0000000000 --- a/calendar/gui/e-itip-control.glade +++ /dev/null @@ -1,478 +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</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_NONE</shadow_type> - - <widget> - <class>GtkVBox</class> - <name>vbox1</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - - <widget> - <class>GtkTable</class> - <name>table1</name> - <border_width>3</border_width> - <rows>4</rows> - <columns>2</columns> - <homogeneous>False</homogeneous> - <row_spacing>3</row_spacing> - <column_spacing>3</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>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>label6</name> - <label>Organizer:</label> - <justify>GTK_JUSTIFY_LEFT</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>label7</name> - <label>Date:</label> - <justify>GTK_JUSTIFY_LEFT</justify> - <wrap>False</wrap> - <xalign>0</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>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label8</name> - <label>Summary:</label> - <justify>GTK_JUSTIFY_LEFT</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>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>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label9</name> - <label>Description:</label> - <justify>GTK_JUSTIFY_LEFT</justify> - <wrap>False</wrap> - <xalign>0</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> - - <widget> - <class>GtkLabel</class> - <name>label12</name> - <label>Server Message:</label> - <justify>GTK_JUSTIFY_LEFT</justify> - <wrap>False</wrap> - <xalign>7.45058e-09</xalign> - <yalign>0.5</yalign> - <xpad>3</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </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>0</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 30917fb13d..0000000000 --- a/calendar/gui/e-itip-control.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-itip-control.h - * - * Copyright (C) 2001 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: JP Rosevear - */ - -#ifndef _E_ITIP_CONTROL_H_ -#define _E_ITIP_CONTROL_H_ - -#include <gtk/gtk.h> - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -#define E_TYPE_ITIP_CONTROL (e_itip_control_get_type ()) -#define E_ITIP_CONTROL(obj) (GTK_CHECK_CAST ((obj), E_TYPE_ITIP_CONTROL, EItipControl)) -#define E_ITIP_CONTROL_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_ITIP_CONTROL, EItipControlClass)) -#define E_IS_ITIP_CONTROL(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_ITIP_CONTROL)) -#define E_IS_ITIP_CONTROL_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_ITIP_CONTROL)) - - -typedef struct _EItipControl EItipControl; -typedef struct _EItipControlPrivate EItipControlPrivate; -typedef struct _EItipControlClass EItipControlClass; - -struct _EItipControl { - GtkVBox parent; - - EItipControlPrivate *priv; -}; - -struct _EItipControlClass { - GtkVBoxClass parent_class; -}; - - - -GtkType e_itip_control_get_type (void); -GtkWidget * e_itip_control_new (void); -void e_itip_control_set_data (EItipControl *itip, - const gchar *text); -gchar * e_itip_control_get_data (EItipControl *itip); -gint e_itip_control_get_data_size (EItipControl *itip); -void e_itip_control_set_from_address (EItipControl *itip, - const gchar *address); -const gchar *e_itip_control_get_from_address (EItipControl *itip); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_ITIP_CONTROL_H_ */ diff --git a/calendar/gui/e-meeting-attendee.c b/calendar/gui/e-meeting-attendee.c deleted file mode 100644 index 3d4a8a4f48..0000000000 --- a/calendar/gui/e-meeting-attendee.c +++ /dev/null @@ -1,990 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-attendee.c - * - * Copyright (C) 2001 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: JP Rosevear - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <gtk/gtk.h> -#include "e-meeting-attendee.h" - -struct _EMeetingAttendeePrivate { - gchar *address; - gchar *member; - - icalparameter_cutype cutype; - icalparameter_role role; - - gboolean rsvp; - - gchar *delto; - gchar *delfrom; - - icalparameter_partstat status; - - gchar *sentby; - gchar *cn; - gchar *language; - - gboolean has_calendar_info; - - GArray *busy_periods; - gboolean busy_periods_sorted; - - EMeetingTime busy_periods_start; - EMeetingTime busy_periods_end; - gboolean start_busy_range_set; - gboolean end_busy_range_set; - - gint longest_period_in_days; -}; - -enum { - CHANGED, - LAST_SIGNAL -}; -static guint signals[LAST_SIGNAL]; - -static void class_init (EMeetingAttendeeClass *klass); -static void init (EMeetingAttendee *ia); -static void destroy (GtkObject *obj); - - -static GtkObjectClass *parent_class = NULL; - - -GtkType -e_meeting_attendee_get_type (void) -{ - static GtkType type = 0; - - if (type == 0) - { - static const GtkTypeInfo info = - { - "EMeetingAttendee", - sizeof (EMeetingAttendee), - sizeof (EMeetingAttendeeClass), - (GtkClassInitFunc) class_init, - (GtkObjectInitFunc) init, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - type = gtk_type_unique (gtk_object_get_type (), &info); - } - - return type; -} - -static void -class_init (EMeetingAttendeeClass *klass) -{ - GtkObjectClass *object_class; - - object_class = GTK_OBJECT_CLASS (klass); - - parent_class = gtk_type_class (gtk_object_get_type ()); - - signals[CHANGED] = - gtk_signal_new ("changed", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (EMeetingAttendeeClass, changed), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); - - object_class->destroy = destroy; -} - -static gchar * -string_test (gchar *string) -{ - return string != NULL ? string : g_strdup (""); -} - -static gboolean -string_is_set (gchar *string) -{ - if (string != NULL && *string != '\0') - return TRUE; - - return FALSE; -} - -static void -notify_changed (EMeetingAttendee *ia) -{ - gtk_signal_emit (GTK_OBJECT (ia), signals[CHANGED]); -} - -static void -init (EMeetingAttendee *ia) -{ - EMeetingAttendeePrivate *priv; - - priv = g_new0 (EMeetingAttendeePrivate, 1); - - ia->priv = priv; - - priv->address = string_test (NULL); - priv->member = string_test (NULL); - - priv->cutype = ICAL_CUTYPE_NONE; - priv->role = ICAL_ROLE_NONE; - - priv->rsvp = FALSE; - - priv->delto = string_test (NULL); - priv->delfrom = string_test (NULL); - - priv->status = ICAL_PARTSTAT_NONE; - - priv->sentby = string_test (NULL); - priv->cn = string_test (NULL); - priv->language = string_test (NULL); - - priv->has_calendar_info = FALSE; - - priv->busy_periods = g_array_new (FALSE, FALSE, sizeof (EMeetingFreeBusyPeriod)); - priv->busy_periods_sorted = FALSE; - - g_date_clear (&priv->busy_periods_start.date, 1); - priv->busy_periods_start.hour = 0; - priv->busy_periods_start.minute = 0; - - g_date_clear (&priv->busy_periods_end.date, 1); - priv->busy_periods_end.hour = 0; - priv->busy_periods_end.minute = 0; - - priv->start_busy_range_set = FALSE; - priv->end_busy_range_set = FALSE; - - priv->longest_period_in_days = 0; -} - - -static void -destroy (GtkObject *obj) -{ - EMeetingAttendee *ia = E_MEETING_ATTENDEE (obj); - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - g_free (priv->address); - g_free (priv->member); - - g_free (priv->delto); - g_free (priv->delfrom); - - g_free (priv->sentby); - g_free (priv->cn); - g_free (priv->language); - - g_array_free (priv->busy_periods, TRUE); - - g_free (priv); -} - -GtkObject * -e_meeting_attendee_new (void) -{ - return gtk_type_new (E_TYPE_MEETING_ATTENDEE); -} - -GtkObject * -e_meeting_attendee_new_from_cal_component_attendee (CalComponentAttendee *ca) -{ - EMeetingAttendee *ia; - - ia = E_MEETING_ATTENDEE (gtk_type_new (E_TYPE_MEETING_ATTENDEE)); - - e_meeting_attendee_set_address (ia, g_strdup (ca->value)); - e_meeting_attendee_set_member (ia, g_strdup (ca->member)); - e_meeting_attendee_set_cutype (ia, ca->cutype); - e_meeting_attendee_set_role (ia, ca->role); - e_meeting_attendee_set_status (ia, ca->status); - e_meeting_attendee_set_rsvp (ia, ca->rsvp); - e_meeting_attendee_set_delto (ia, g_strdup (ca->delto)); - e_meeting_attendee_set_delfrom (ia, g_strdup (ca->delfrom)); - e_meeting_attendee_set_sentby (ia, g_strdup (ca->sentby)); - e_meeting_attendee_set_cn (ia, g_strdup (ca->cn)); - e_meeting_attendee_set_language (ia, g_strdup (ca->language)); - - return GTK_OBJECT (ia); -} - -CalComponentAttendee * -e_meeting_attendee_as_cal_component_attendee (EMeetingAttendee *ia) -{ - EMeetingAttendeePrivate *priv; - CalComponentAttendee *ca; - - priv = ia->priv; - - ca = g_new0 (CalComponentAttendee, 1); - - ca->value = priv->address; - ca->member = string_is_set (priv->member) ? priv->member : NULL; - ca->cutype= priv->cutype; - ca->role = priv->role; - ca->status = priv->status; - ca->rsvp = priv->rsvp; - ca->delto = string_is_set (priv->delto) ? priv->delto : NULL; - ca->delfrom = string_is_set (priv->delfrom) ? priv->delfrom : NULL; - ca->sentby = string_is_set (priv->sentby) ? priv->sentby : NULL; - ca->cn = string_is_set (priv->cn) ? priv->cn : NULL; - ca->language = string_is_set (priv->language) ? priv->language : NULL; - - return ca; -} - - -const gchar * -e_meeting_attendee_get_address (EMeetingAttendee *ia) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - return priv->address; -} - -void -e_meeting_attendee_set_address (EMeetingAttendee *ia, gchar *address) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - if (priv->address != NULL) - g_free (priv->address); - - priv->address = string_test (address); - - notify_changed (ia); -} - -gboolean -e_meeting_attendee_is_set_address (EMeetingAttendee *ia) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - return string_is_set (priv->address); -} - -const gchar * -e_meeting_attendee_get_member (EMeetingAttendee *ia) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - return priv->member; -} - -void -e_meeting_attendee_set_member (EMeetingAttendee *ia, gchar *member) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - if (priv->member != NULL) - g_free (priv->member); - - priv->member = string_test (member); - - notify_changed (ia); -} - -gboolean -e_meeting_attendee_is_set_member (EMeetingAttendee *ia) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - return string_is_set (priv->member); -} - -icalparameter_cutype -e_meeting_attendee_get_cutype (EMeetingAttendee *ia) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - return priv->cutype; -} - -void -e_meeting_attendee_set_cutype (EMeetingAttendee *ia, icalparameter_cutype cutype) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - priv->cutype = cutype; - - notify_changed (ia); -} - -icalparameter_role -e_meeting_attendee_get_role (EMeetingAttendee *ia) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - return priv->role; -} - -void -e_meeting_attendee_set_role (EMeetingAttendee *ia, icalparameter_role role) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - priv->role = role; - - notify_changed (ia); -} - -gboolean -e_meeting_attendee_get_rsvp (EMeetingAttendee *ia) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - return priv->rsvp; -} - -void -e_meeting_attendee_set_rsvp (EMeetingAttendee *ia, gboolean rsvp) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - priv->rsvp = rsvp; - - notify_changed (ia); -} - -const gchar * -e_meeting_attendee_get_delto (EMeetingAttendee *ia) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - return priv->delto; -} - -void -e_meeting_attendee_set_delto (EMeetingAttendee *ia, gchar *delto) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - if (priv->delto != NULL) - g_free (priv->delto); - - priv->delto = string_test (delto); - - notify_changed (ia); -} - -gboolean -e_meeting_attendee_is_set_delto (EMeetingAttendee *ia) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - return string_is_set (priv->delto); -} - -const gchar * -e_meeting_attendee_get_delfrom (EMeetingAttendee *ia) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - return priv->delfrom; -} - -void -e_meeting_attendee_set_delfrom (EMeetingAttendee *ia, gchar *delfrom) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - if (priv->delfrom != NULL) - g_free (priv->delfrom); - - priv->delfrom = string_test (delfrom); - - notify_changed (ia); -} - -gboolean -e_meeting_attendee_is_set_delfrom (EMeetingAttendee *ia) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - return string_is_set (priv->delfrom); -} - -icalparameter_partstat -e_meeting_attendee_get_status (EMeetingAttendee *ia) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - return priv->status; -} - -void -e_meeting_attendee_set_status (EMeetingAttendee *ia, icalparameter_partstat status) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - priv->status = status; - - notify_changed (ia); -} - -const gchar * -e_meeting_attendee_get_sentby (EMeetingAttendee *ia) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - return priv->sentby; -} - -void -e_meeting_attendee_set_sentby (EMeetingAttendee *ia, gchar *sentby) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - if (priv->sentby != NULL) - g_free (priv->sentby); - - priv->sentby = string_test (sentby); - - notify_changed (ia); -} - -gboolean -e_meeting_attendee_is_set_sentby (EMeetingAttendee *ia) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - return string_is_set (priv->sentby); -} - -const gchar * -e_meeting_attendee_get_cn (EMeetingAttendee *ia) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - return priv->cn; -} - -void -e_meeting_attendee_set_cn (EMeetingAttendee *ia, gchar *cn) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - if (priv->cn != NULL) - g_free (priv->cn); - - priv->cn = string_test (cn); - - notify_changed (ia); -} - -gboolean -e_meeting_attendee_is_set_cn (EMeetingAttendee *ia) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - return string_is_set (priv->cn); -} - -const gchar * -e_meeting_attendee_get_language (EMeetingAttendee *ia) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - return priv->language; -} - -void -e_meeting_attendee_set_language (EMeetingAttendee *ia, gchar *language) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - if (priv->language != NULL) - g_free (priv->language); - - priv->language = string_test (language); - - notify_changed (ia); -} - -gboolean -e_meeting_attendee_is_set_language (EMeetingAttendee *ia) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - return string_is_set (priv->language); -} - -EMeetingAttendeeType -e_meeting_attendee_get_atype (EMeetingAttendee *ia) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - if (priv->cutype == ICAL_CUTYPE_ROOM - || priv->cutype == ICAL_CUTYPE_RESOURCE) - return E_MEETING_ATTENDEE_RESOURCE; - - if (priv->role == ICAL_ROLE_CHAIR - || priv->role == ICAL_ROLE_REQPARTICIPANT) - return E_MEETING_ATTENDEE_REQUIRED_PERSON; - - return E_MEETING_ATTENDEE_OPTIONAL_PERSON; -} - -static gint -compare_times (EMeetingTime *time1, - EMeetingTime *time2) -{ - gint day_comparison; - - day_comparison = g_date_compare (&time1->date, - &time2->date); - if (day_comparison != 0) - return day_comparison; - - if (time1->hour < time2->hour) - return -1; - if (time1->hour > time2->hour) - return 1; - - if (time1->minute < time2->minute) - return -1; - if (time1->minute > time2->minute) - return 1; - - /* The start times are exactly the same. */ - return 0; -} - -static gint -compare_period_starts (const void *arg1, - const void *arg2) -{ - EMeetingFreeBusyPeriod *period1, *period2; - - period1 = (EMeetingFreeBusyPeriod *) arg1; - period2 = (EMeetingFreeBusyPeriod *) arg2; - - return compare_times (&period1->start, &period2->start); -} - -static void -ensure_periods_sorted (EMeetingAttendee *ia) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - if (priv->busy_periods_sorted) - return; - - qsort (priv->busy_periods->data, priv->busy_periods->len, - sizeof (EMeetingFreeBusyPeriod), - compare_period_starts); - - priv->busy_periods_sorted = TRUE; -} - -gboolean -e_meeting_attendee_get_has_calendar_info (EMeetingAttendee *ia) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - return priv->has_calendar_info; -} - -void -e_meeting_attendee_set_has_calendar_info (EMeetingAttendee *ia, gboolean has_calendar_info) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - priv->has_calendar_info = has_calendar_info; -} - -const GArray * -e_meeting_attendee_get_busy_periods (EMeetingAttendee *ia) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - ensure_periods_sorted (ia); - - return priv->busy_periods; -} - -gint -e_meeting_attendee_find_first_busy_period (EMeetingAttendee *ia, GDate *date) -{ - EMeetingAttendeePrivate *priv; - EMeetingFreeBusyPeriod *period; - gint lower, upper, middle = 0, cmp = 0; - GDate tmp_date; - - priv = ia->priv; - - /* Make sure the busy periods have been sorted. */ - ensure_periods_sorted (ia); - - /* Calculate the first day which could have a busy period which - continues onto our given date. */ - tmp_date = *date; - g_date_subtract_days (&tmp_date, priv->longest_period_in_days); - - /* We want the first busy period which starts on tmp_date. */ - lower = 0; - upper = priv->busy_periods->len; - - if (upper == 0) - return -1; - - while (lower < upper) { - middle = (lower + upper) >> 1; - - period = &g_array_index (priv->busy_periods, - EMeetingFreeBusyPeriod, middle); - - cmp = g_date_compare (&tmp_date, &period->start.date); - - if (cmp == 0) - break; - else if (cmp < 0) - upper = middle; - else - lower = middle + 1; - } - - /* There may be several busy periods on the same day so we step - backwards to the first one. */ - if (cmp == 0) { - while (middle > 0) { - period = &g_array_index (priv->busy_periods, - EMeetingFreeBusyPeriod, middle - 1); - if (g_date_compare (&tmp_date, &period->start.date) != 0) - break; - middle--; - } - } else if (cmp > 0) { - /* This means we couldn't find a period on the given day, and - the last one we looked at was before it, so if there are - any more periods after this one we return it. */ - middle++; - if (priv->busy_periods->len <= middle) - return -1; - } - - return middle; -} - -gboolean -e_meeting_attendee_add_busy_period (EMeetingAttendee *ia, - gint start_year, - gint start_month, - gint start_day, - gint start_hour, - gint start_minute, - gint end_year, - gint end_month, - gint end_day, - gint end_hour, - gint end_minute, - EMeetingFreeBusyType busy_type) -{ - EMeetingAttendeePrivate *priv; - EMeetingFreeBusyPeriod period; - gint period_in_days; - - g_return_val_if_fail (ia != NULL, FALSE); - g_return_val_if_fail (E_IS_MEETING_ATTENDEE (ia), FALSE); - g_return_val_if_fail (busy_type >= 0, FALSE); - g_return_val_if_fail (busy_type < E_MEETING_FREE_BUSY_LAST, FALSE); - - priv = ia->priv; - - /* Check the dates are valid. */ - if (!g_date_valid_dmy (start_day, start_month, start_year)) - return FALSE; - if (!g_date_valid_dmy (end_day, end_month, end_year)) - return FALSE; - if (start_hour < 0 || start_hour > 23) - return FALSE; - if (end_hour < 0 || end_hour > 23) - return FALSE; - if (start_minute < 0 || start_minute > 59) - return FALSE; - if (end_minute < 0 || end_minute > 59) - return FALSE; - - g_date_clear (&period.start.date, 1); - g_date_clear (&period.end.date, 1); - g_date_set_dmy (&period.start.date, start_day, start_month, start_year); - g_date_set_dmy (&period.end.date, end_day, end_month, end_year); - period.start.hour = start_hour; - period.start.minute = start_minute; - period.end.hour = end_hour; - period.end.minute = end_minute; - period.busy_type = busy_type; - - /* Check that the start time is before or equal to the end time. */ - if (compare_times (&period.start, &period.end) > 0) - return FALSE; - - /* If the busy range is not set elsewhere, track it as best we can */ - if (!priv->start_busy_range_set) { - if (!g_date_valid (&priv->busy_periods_start.date)) { - priv->busy_periods_start.date = period.start.date; - priv->busy_periods_start.hour = period.start.hour; - priv->busy_periods_start.minute = period.start.minute; - } else { - switch (g_date_compare (&period.start.date, &priv->busy_periods_start.date)) { - case -1: - priv->busy_periods_start.date = period.start.date; - priv->busy_periods_start.hour = period.start.hour; - priv->busy_periods_start.minute = period.start.minute; - break; - case 0: - if (period.start.hour < priv->busy_periods_start.hour - || (period.start.hour == priv->busy_periods_start.hour - && period.start.minute < priv->busy_periods_start.minute)) { - priv->busy_periods_start.date = period.start.date; - priv->busy_periods_start.hour = period.start.hour; - priv->busy_periods_start.minute = period.start.minute; - break; - } - break; - } - } - } - if (!priv->end_busy_range_set) { - if (!g_date_valid (&priv->busy_periods_end.date)) { - priv->busy_periods_end.date = period.end.date; - priv->busy_periods_end.hour = period.end.hour; - priv->busy_periods_end.minute = period.end.minute; - } else { - switch (g_date_compare (&period.end.date, &priv->busy_periods_end.date)) { - case 0: - if (period.end.hour > priv->busy_periods_end.hour - || (period.end.hour == priv->busy_periods_end.hour - && period.end.minute > priv->busy_periods_end.minute)) { - priv->busy_periods_end.date = period.end.date; - priv->busy_periods_end.hour = period.end.hour; - priv->busy_periods_end.minute = period.end.minute; - break; - } - break; - case 1: - priv->busy_periods_end.date = period.end.date; - priv->busy_periods_end.hour = period.end.hour; - priv->busy_periods_end.minute = period.end.minute; - break; - } - } - } - - g_array_append_val (priv->busy_periods, period); - priv->has_calendar_info = TRUE; - priv->busy_periods_sorted = FALSE; - - period_in_days = g_date_julian (&period.end.date) - g_date_julian (&period.start.date) + 1; - priv->longest_period_in_days = MAX (priv->longest_period_in_days, period_in_days); - - return TRUE; -} - -EMeetingTime -e_meeting_attendee_get_start_busy_range (EMeetingAttendee *ia) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - return priv->busy_periods_start; -} - -EMeetingTime -e_meeting_attendee_get_end_busy_range (EMeetingAttendee *ia) -{ - EMeetingAttendeePrivate *priv; - - priv = ia->priv; - - return priv->busy_periods_end; -} - -gboolean -e_meeting_attendee_set_start_busy_range (EMeetingAttendee *ia, - gint start_year, - gint start_month, - gint start_day, - gint start_hour, - gint start_minute) -{ - EMeetingAttendeePrivate *priv; - - g_return_val_if_fail (E_IS_MEETING_ATTENDEE (ia), FALSE); - - priv = ia->priv; - - /* Check the dates are valid. */ - if (!g_date_valid_dmy (start_day, start_month, start_year)) - return FALSE; - if (start_hour < 0 || start_hour > 23) - return FALSE; - if (start_minute < 0 || start_minute > 59) - return FALSE; - - g_date_clear (&priv->busy_periods_start.date, 1); - g_date_set_dmy (&priv->busy_periods_start.date, - start_day, start_month, start_year); - priv->busy_periods_start.hour = start_hour; - priv->busy_periods_start.minute = start_minute; - - priv->start_busy_range_set = TRUE; - - return TRUE; -} - -gboolean -e_meeting_attendee_set_end_busy_range (EMeetingAttendee *ia, - gint end_year, - gint end_month, - gint end_day, - gint end_hour, - gint end_minute) -{ - EMeetingAttendeePrivate *priv; - - g_return_val_if_fail (E_IS_MEETING_ATTENDEE (ia), FALSE); - - priv = ia->priv; - - /* Check the dates are valid. */ - if (!g_date_valid_dmy (end_day, end_month, end_year)) - return FALSE; - if (end_hour < 0 || end_hour > 23) - return FALSE; - if (end_minute < 0 || end_minute > 59) - return FALSE; - - g_date_clear (&priv->busy_periods_end.date, 1); - g_date_set_dmy (&priv->busy_periods_end.date, - end_day, end_month, end_year); - priv->busy_periods_end.hour = end_hour; - priv->busy_periods_end.minute = end_minute; - - priv->end_busy_range_set = TRUE; - - return TRUE; -} - -/* Clears all busy times for the given attendee. */ -void -e_meeting_attendee_clear_busy_periods (EMeetingAttendee *ia) -{ - EMeetingAttendeePrivate *priv; - - g_return_if_fail (E_IS_MEETING_ATTENDEE (ia)); - - priv = ia->priv; - - g_array_set_size (priv->busy_periods, 0); - priv->busy_periods_sorted = TRUE; - - g_date_clear (&priv->busy_periods_start.date, 1); - priv->busy_periods_start.hour = 0; - priv->busy_periods_start.minute = 0; - - g_date_clear (&priv->busy_periods_end.date, 1); - priv->busy_periods_end.hour = 0; - priv->busy_periods_end.minute = 0; - - priv->longest_period_in_days = 0; -} diff --git a/calendar/gui/e-meeting-attendee.h b/calendar/gui/e-meeting-attendee.h deleted file mode 100644 index 69f2ced837..0000000000 --- a/calendar/gui/e-meeting-attendee.h +++ /dev/null @@ -1,162 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-meeting_attendee.h - * - * Copyright (C) 2001 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: JP Rosevear - */ - -#ifndef _E_MEETING_ATTENDEE_H_ -#define _E_MEETING_ATTENDEE_H_ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtk.h> -#include <cal-util/cal-component.h> -#include "e-meeting-types.h" - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -#define E_TYPE_MEETING_ATTENDEE (e_meeting_attendee_get_type ()) -#define E_MEETING_ATTENDEE(obj) (GTK_CHECK_CAST ((obj), E_TYPE_MEETING_ATTENDEE, EMeetingAttendee)) -#define E_MEETING_ATTENDEE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_MEETING_ATTENDEE, EMeetingAttendeeClass)) -#define E_IS_MEETING_ATTENDEE(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_MEETING_ATTENDEE)) -#define E_IS_MEETING_ATTENDEE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_MEETING_ATTENDEE)) - - -typedef struct _EMeetingAttendee EMeetingAttendee; -typedef struct _EMeetingAttendeePrivate EMeetingAttendeePrivate; -typedef struct _EMeetingAttendeeClass EMeetingAttendeeClass; - -/* These specify the type of attendee. Either a person or a resource (e.g. a - meeting room). These are used for the Autopick options, where the user can - ask for a time when, for example, all people and one resource are free. - The default is E_MEETING_ATTENDEE_REQUIRED_PERSON. */ -typedef enum -{ - E_MEETING_ATTENDEE_REQUIRED_PERSON, - E_MEETING_ATTENDEE_OPTIONAL_PERSON, - E_MEETING_ATTENDEE_RESOURCE -} EMeetingAttendeeType; - -struct _EMeetingAttendee { - GtkObject parent; - - EMeetingAttendeePrivate *priv; -}; - -struct _EMeetingAttendeeClass { - GtkObjectClass parent_class; - - void (* changed) (EMeetingAttendee *ia); -}; - - -GtkType e_meeting_attendee_get_type (void); -GtkObject *e_meeting_attendee_new (void); -GtkObject *e_meeting_attendee_new_from_cal_component_attendee (CalComponentAttendee *ca); - -CalComponentAttendee *e_meeting_attendee_as_cal_component_attendee (EMeetingAttendee *ia); - -const gchar *e_meeting_attendee_get_address (EMeetingAttendee *ia); -void e_meeting_attendee_set_address (EMeetingAttendee *ia, gchar *address); -gboolean e_meeting_attendee_is_set_address (EMeetingAttendee *ia); - -const gchar *e_meeting_attendee_get_member (EMeetingAttendee *ia); -void e_meeting_attendee_set_member (EMeetingAttendee *ia, gchar *member); -gboolean e_meeting_attendee_is_set_member (EMeetingAttendee *ia); - -icalparameter_cutype e_meeting_attendee_get_cutype (EMeetingAttendee *ia); -void e_meeting_attendee_set_cutype (EMeetingAttendee *ia, icalparameter_cutype cutype); - -icalparameter_role e_meeting_attendee_get_role (EMeetingAttendee *ia); -void e_meeting_attendee_set_role (EMeetingAttendee *ia, icalparameter_role role); - -gboolean e_meeting_attendee_get_rsvp (EMeetingAttendee *ia); -void e_meeting_attendee_set_rsvp (EMeetingAttendee *ia, gboolean rsvp); - -const gchar *e_meeting_attendee_get_delto (EMeetingAttendee *ia); -void e_meeting_attendee_set_delto (EMeetingAttendee *ia, gchar *delto); -gboolean e_meeting_attendee_is_set_delto (EMeetingAttendee *ia); - -const gchar *e_meeting_attendee_get_delfrom (EMeetingAttendee *ia); -void e_meeting_attendee_set_delfrom (EMeetingAttendee *ia, gchar *delfrom); -gboolean e_meeting_attendee_is_set_delfrom (EMeetingAttendee *ia); - -icalparameter_partstat e_meeting_attendee_get_status (EMeetingAttendee *ia); -void e_meeting_attendee_set_status (EMeetingAttendee *ia, icalparameter_partstat status); - -const gchar *e_meeting_attendee_get_sentby (EMeetingAttendee *ia); -void e_meeting_attendee_set_sentby (EMeetingAttendee *ia, gchar *sentby); -gboolean e_meeting_attendee_is_set_sentby (EMeetingAttendee *ia); - -const gchar *e_meeting_attendee_get_cn (EMeetingAttendee *ia); -void e_meeting_attendee_set_cn (EMeetingAttendee *ia, gchar *cn); -gboolean e_meeting_attendee_is_set_cn (EMeetingAttendee *ia); - -const gchar *e_meeting_attendee_get_language (EMeetingAttendee *ia); -void e_meeting_attendee_set_language (EMeetingAttendee *ia, gchar *language); -gboolean e_meeting_attendee_is_set_language (EMeetingAttendee *ia); - -EMeetingAttendeeType e_meeting_attendee_get_atype (EMeetingAttendee *ia); - -gboolean e_meeting_attendee_get_has_calendar_info (EMeetingAttendee *ia); -void e_meeting_attendee_set_has_calendar_info (EMeetingAttendee *ia, gboolean has_calendar_info); - -const GArray *e_meeting_attendee_get_busy_periods (EMeetingAttendee *ia); -gint e_meeting_attendee_find_first_busy_period (EMeetingAttendee *ia, GDate *date); -gboolean e_meeting_attendee_add_busy_period (EMeetingAttendee *ia, - gint start_year, - gint start_month, - gint start_day, - gint start_hour, - gint start_minute, - gint end_year, - gint end_month, - gint end_day, - gint end_hour, - gint end_minute, - EMeetingFreeBusyType busy_type); - -EMeetingTime e_meeting_attendee_get_start_busy_range (EMeetingAttendee *ia); -EMeetingTime e_meeting_attendee_get_end_busy_range (EMeetingAttendee *ia); - -gboolean e_meeting_attendee_set_start_busy_range (EMeetingAttendee *ia, - gint start_year, - gint start_month, - gint start_day, - gint start_hour, - gint start_minute); -gboolean e_meeting_attendee_set_end_busy_range (EMeetingAttendee *ia, - gint end_year, - gint end_month, - gint end_day, - gint end_hour, - gint end_minute); - -void e_meeting_attendee_clear_busy_periods (EMeetingAttendee *ia); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_MEETING_ATTENDEE_H_ */ diff --git a/calendar/gui/e-meeting-model.c b/calendar/gui/e-meeting-model.c deleted file mode 100644 index 6adfb9c1c9..0000000000 --- a/calendar/gui/e-meeting-model.c +++ /dev/null @@ -1,1748 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* itip-model.c - * - * Copyright (C) 2001 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: JP Rosevear - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <glib.h> -#include <liboaf/liboaf.h> -#include <bonobo/bonobo-control.h> -#include <bonobo/bonobo-widget.h> -#include <bonobo/bonobo-exception.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <libgnome/gnome-util.h> -#include <libgnomevfs/gnome-vfs.h> -#include <gal/e-table/e-table-without.h> -#include <gal/e-table/e-cell-text.h> -#include <gal/e-table/e-cell-popup.h> -#include <gal/e-table/e-cell-combo.h> -#include <gal/util/e-unicode-i18n.h> -#include <e-book.h> -#include <e-card-types.h> -#include <e-card-cursor.h> -#include <e-card.h> -#include <e-card-simple.h> -#include <e-destination.h> -#include <cal-util/cal-component.h> -#include <cal-util/cal-util.h> -#include <cal-util/timeutil.h> -#include "Evolution-Addressbook-SelectNames.h" -#include "calendar-config.h" -#include "itip-utils.h" -#include "e-meeting-utils.h" -#include "e-meeting-attendee.h" -#include "e-meeting-model.h" - -#define SELECT_NAMES_OAFID "OAFIID:GNOME_Evolution_Addressbook_SelectNames" - -struct _EMeetingModelPrivate -{ - GPtrArray *attendees; - ETableWithout *without; - - CalClient *client; - icaltimezone *zone; - - EBook *ebook; - gboolean book_loaded; - gboolean book_load_wait; - - GPtrArray *refresh_queue; - GHashTable *refresh_data; - gint refresh_idle_id; - - /* For invite others dialogs */ - GNOME_Evolution_Addressbook_SelectNames corba_select_names; -}; - -#define BUF_SIZE 1024 - -static char *sections[] = {N_("Chair Persons"), - N_("Required Participants"), - N_("Optional Participants"), - N_("Non-Participants"), - NULL}; -static icalparameter_role roles[] = {ICAL_ROLE_CHAIR, - ICAL_ROLE_REQPARTICIPANT, - ICAL_ROLE_OPTPARTICIPANT, - ICAL_ROLE_NONPARTICIPANT, - ICAL_ROLE_NONE}; - -typedef struct _EMeetingModelQueueData EMeetingModelQueueData; -struct _EMeetingModelQueueData { - EMeetingModel *im; - EMeetingAttendee *ia; - - gboolean refreshing; - - EMeetingTime start; - EMeetingTime end; - - char buffer[BUF_SIZE]; - GString *string; - - GPtrArray *call_backs; - GPtrArray *data; -}; - - -static void class_init (EMeetingModelClass *klass); -static void init (EMeetingModel *model); -static void destroy (GtkObject *obj); - -static void refresh_queue_add (EMeetingModel *im, int row, - EMeetingTime *start, - EMeetingTime *end, - EMeetingModelRefreshCallback call_back, - gpointer data); -static void refresh_queue_remove (EMeetingModel *im, - EMeetingAttendee *ia); -static gboolean refresh_busy_periods (gpointer data); - -static void attendee_changed_cb (EMeetingAttendee *ia, gpointer data); -static void select_names_ok_cb (BonoboListener *listener, - char *event_name, - CORBA_any *arg, - CORBA_Environment *ev, - gpointer data); - -static void table_destroy_cb (ETableScrolled *etable, gpointer data); - -static ETableModelClass *parent_class = NULL; - -GtkType -e_meeting_model_get_type (void) -{ - static GtkType type = 0; - - if (type == 0) - { - static const GtkTypeInfo info = - { - "EMeetingModel", - sizeof (EMeetingModel), - sizeof (EMeetingModelClass), - (GtkClassInitFunc) class_init, - (GtkObjectInitFunc) init, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - type = gtk_type_unique (e_table_model_get_type (), &info); - } - - return type; -} - -static void -book_open_cb (EBook *book, EBookStatus status, gpointer data) -{ - EMeetingModel *im = E_MEETING_MODEL (data); - EMeetingModelPrivate *priv; - - priv = im->priv; - - if (status == E_BOOK_STATUS_SUCCESS) - priv->book_loaded = TRUE; - else - g_warning ("Book not loaded"); - - if (priv->book_load_wait) { - priv->book_load_wait = FALSE; - gtk_main_quit (); - } -} - -static void -start_addressbook_server (EMeetingModel *im) -{ - EMeetingModelPrivate *priv; - gchar *uri, *path; - - priv = im->priv; - - priv->ebook = e_book_new (); - - path = g_concat_dir_and_file (g_get_home_dir (), - "evolution/local/Contacts/addressbook.db"); - uri = g_strdup_printf ("file://%s", path); - g_free (path); - - e_book_load_uri (priv->ebook, uri, book_open_cb, im); - - g_free (uri); -} - -static EMeetingAttendee * -find_match (EMeetingModel *im, const char *address, int *pos) -{ - EMeetingModelPrivate *priv; - EMeetingAttendee *ia; - const gchar *ia_address; - int i; - - priv = im->priv; - - if (address == NULL) - return NULL; - - /* Make sure we can add the new delegatee person */ - for (i = 0; i < priv->attendees->len; i++) { - ia = g_ptr_array_index (priv->attendees, i); - - ia_address = e_meeting_attendee_get_address (ia); - if (ia_address != NULL && !g_strcasecmp (itip_strip_mailto (ia_address), itip_strip_mailto (address))) { - if (pos != NULL) - *pos = i; - return ia; - } - } - - return NULL; -} - -static icalparameter_cutype -text_to_type (const char *type) -{ - if (!g_strcasecmp (type, _("Individual"))) - return ICAL_CUTYPE_INDIVIDUAL; - else if (!g_strcasecmp (type, _("Group"))) - return ICAL_CUTYPE_GROUP; - else if (!g_strcasecmp (type, _("Resource"))) - return ICAL_CUTYPE_RESOURCE; - else if (!g_strcasecmp (type, _("Room"))) - return ICAL_CUTYPE_ROOM; - else - return ICAL_CUTYPE_NONE; -} - -static char * -type_to_text (icalparameter_cutype type) -{ - switch (type) { - case ICAL_CUTYPE_INDIVIDUAL: - return _("Individual"); - case ICAL_CUTYPE_GROUP: - return _("Group"); - case ICAL_CUTYPE_RESOURCE: - return _("Resource"); - case ICAL_CUTYPE_ROOM: - return _("Room"); - default: - return _("Unknown"); - } - - return NULL; - -} - -static icalparameter_role -text_to_role (const char *role) -{ - if (!g_strcasecmp (role, _("Chair"))) - return ICAL_ROLE_CHAIR; - else if (!g_strcasecmp (role, _("Required Participant"))) - return ICAL_ROLE_REQPARTICIPANT; - else if (!g_strcasecmp (role, _("Optional Participant"))) - return ICAL_ROLE_OPTPARTICIPANT; - else if (!g_strcasecmp (role, _("Non-Participant"))) - return ICAL_ROLE_NONPARTICIPANT; - else - return ICAL_ROLE_NONE; -} - -static char * -role_to_text (icalparameter_role role) -{ - switch (role) { - case ICAL_ROLE_CHAIR: - return _("Chair"); - case ICAL_ROLE_REQPARTICIPANT: - return _("Required Participant"); - case ICAL_ROLE_OPTPARTICIPANT: - return _("Optional Participant"); - case ICAL_ROLE_NONPARTICIPANT: - return _("Non-Participant"); - default: - return _("Unknown"); - } - - return NULL; -} - -static gboolean -text_to_boolean (const char *role) -{ - if (!g_strcasecmp (role, _("Yes"))) - return TRUE; - else - return FALSE; -} - -static char * -boolean_to_text (gboolean b) -{ - if (b) - return _("Yes"); - else - return _("No"); -} - -static icalparameter_partstat -text_to_partstat (const char *partstat) -{ - if (!g_strcasecmp (partstat, _("Needs Action"))) - return ICAL_PARTSTAT_NEEDSACTION; - else if (!g_strcasecmp (partstat, _("Accepted"))) - return ICAL_PARTSTAT_ACCEPTED; - else if (!g_strcasecmp (partstat, _("Declined"))) - return ICAL_PARTSTAT_DECLINED; - else if (!g_strcasecmp (partstat, _("Tentative"))) - return ICAL_PARTSTAT_TENTATIVE; - else if (!g_strcasecmp (partstat, _("Delegated"))) - return ICAL_PARTSTAT_DELEGATED; - else if (!g_strcasecmp (partstat, _("Completed"))) - return ICAL_PARTSTAT_COMPLETED; - else if (!g_strcasecmp (partstat, _("In Process"))) - return ICAL_PARTSTAT_INPROCESS; - else - return ICAL_PARTSTAT_NONE; -} - -static char * -partstat_to_text (icalparameter_partstat partstat) -{ - switch (partstat) { - case ICAL_PARTSTAT_NEEDSACTION: - return _("Needs Action"); - case ICAL_PARTSTAT_ACCEPTED: - return _("Accepted"); - case ICAL_PARTSTAT_DECLINED: - return _("Declined"); - case ICAL_PARTSTAT_TENTATIVE: - return _("Tentative"); - case ICAL_PARTSTAT_DELEGATED: - return _("Delegated"); - case ICAL_PARTSTAT_COMPLETED: - return _("Completed"); - case ICAL_PARTSTAT_INPROCESS: - return _("In Process"); - case ICAL_PARTSTAT_NONE: - default: - return _("Unknown"); - } - - return NULL; -} - -static int -column_count (ETableModel *etm) -{ - return E_MEETING_MODEL_COLUMN_COUNT; -} - -static int -row_count (ETableModel *etm) -{ - EMeetingModel *im; - EMeetingModelPrivate *priv; - - im = E_MEETING_MODEL (etm); - priv = im->priv; - - return (priv->attendees->len); -} - -static void -append_row (ETableModel *etm, ETableModel *source, int row) -{ - EMeetingModel *im; - EMeetingModelPrivate *priv; - EMeetingAttendee *ia; - char *address; - - im = E_MEETING_MODEL (etm); - priv = im->priv; - - address = (char *) e_table_model_value_at (source, E_MEETING_MODEL_ADDRESS_COL, row); - if (find_match (im, address, NULL) != NULL) { - return; - } - - ia = E_MEETING_ATTENDEE (e_meeting_attendee_new ()); - - e_meeting_attendee_set_address (ia, g_strdup_printf ("MAILTO:%s", address)); - e_meeting_attendee_set_member (ia, g_strdup (e_table_model_value_at (source, E_MEETING_MODEL_MEMBER_COL, row))); - e_meeting_attendee_set_cutype (ia, text_to_type (e_table_model_value_at (source, E_MEETING_MODEL_TYPE_COL, row))); - e_meeting_attendee_set_role (ia, text_to_role (e_table_model_value_at (source, E_MEETING_MODEL_ROLE_COL, row))); - e_meeting_attendee_set_rsvp (ia, text_to_boolean (e_table_model_value_at (source, E_MEETING_MODEL_RSVP_COL, row))); - e_meeting_attendee_set_delto (ia, g_strdup (e_table_model_value_at (source, E_MEETING_MODEL_DELTO_COL, row))); - e_meeting_attendee_set_delfrom (ia, g_strdup (e_table_model_value_at (source, E_MEETING_MODEL_DELFROM_COL, row))); - e_meeting_attendee_set_status (ia, text_to_partstat (e_table_model_value_at (source, E_MEETING_MODEL_STATUS_COL, row))); - e_meeting_attendee_set_cn (ia, g_strdup (e_table_model_value_at (source, E_MEETING_MODEL_CN_COL, row))); - e_meeting_attendee_set_language (ia, g_strdup (e_table_model_value_at (source, E_MEETING_MODEL_LANGUAGE_COL, row))); - - e_meeting_model_add_attendee (E_MEETING_MODEL (etm), ia); -} - -static void * -value_at (ETableModel *etm, int col, int row) -{ - EMeetingModel *im; - EMeetingModelPrivate *priv; - EMeetingAttendee *ia; - - im = E_MEETING_MODEL (etm); - priv = im->priv; - - ia = g_ptr_array_index (priv->attendees, row); - - switch (col) { - case E_MEETING_MODEL_ADDRESS_COL: - return (void *)itip_strip_mailto (e_meeting_attendee_get_address (ia)); - case E_MEETING_MODEL_MEMBER_COL: - return (void *)e_meeting_attendee_get_member (ia); - case E_MEETING_MODEL_TYPE_COL: - return type_to_text (e_meeting_attendee_get_cutype (ia)); - case E_MEETING_MODEL_ROLE_COL: - return role_to_text (e_meeting_attendee_get_role (ia)); - case E_MEETING_MODEL_RSVP_COL: - return boolean_to_text (e_meeting_attendee_get_rsvp (ia)); - case E_MEETING_MODEL_DELTO_COL: - return (void *)itip_strip_mailto (e_meeting_attendee_get_delto (ia)); - case E_MEETING_MODEL_DELFROM_COL: - return (void *)itip_strip_mailto (e_meeting_attendee_get_delfrom (ia)); - case E_MEETING_MODEL_STATUS_COL: - return partstat_to_text (e_meeting_attendee_get_status (ia)); - case E_MEETING_MODEL_CN_COL: - return (void *)e_meeting_attendee_get_cn (ia); - case E_MEETING_MODEL_LANGUAGE_COL: - return (void *)e_meeting_attendee_get_language (ia); - } - - return NULL; -} - -static void -set_value_at (ETableModel *etm, int col, int row, const void *val) -{ - EMeetingModel *im; - EMeetingModelPrivate *priv; - EMeetingAttendee *ia; - - im = E_MEETING_MODEL (etm); - priv = im->priv; - - ia = g_ptr_array_index (priv->attendees, row); - - e_table_model_pre_change (etm); - - switch (col) { - case E_MEETING_MODEL_ADDRESS_COL: - e_meeting_attendee_set_address (ia, g_strdup_printf ("MAILTO:%s", (char *) val)); - break; - case E_MEETING_MODEL_MEMBER_COL: - e_meeting_attendee_set_member (ia, g_strdup (val)); - break; - case E_MEETING_MODEL_TYPE_COL: - e_meeting_attendee_set_cutype (ia, text_to_type (val)); - break; - case E_MEETING_MODEL_ROLE_COL: - e_meeting_attendee_set_role (ia, text_to_role (val)); - break; - case E_MEETING_MODEL_RSVP_COL: - e_meeting_attendee_set_rsvp (ia, text_to_boolean (val)); - break; - case E_MEETING_MODEL_DELTO_COL: - e_meeting_attendee_set_delto (ia, g_strdup (val)); - break; - case E_MEETING_MODEL_DELFROM_COL: - e_meeting_attendee_set_delfrom (ia, g_strdup (val)); - break; - case E_MEETING_MODEL_STATUS_COL: - e_meeting_attendee_set_status (ia, text_to_partstat (val)); - break; - case E_MEETING_MODEL_CN_COL: - e_meeting_attendee_set_cn (ia, g_strdup (val)); - break; - case E_MEETING_MODEL_LANGUAGE_COL: - e_meeting_attendee_set_language (ia, g_strdup (val)); - break; - } - - e_table_model_cell_changed (etm, col, row); -} - -static gboolean -is_cell_editable (ETableModel *etm, int col, int row) -{ - switch (col) { - case E_MEETING_MODEL_DELTO_COL: - case E_MEETING_MODEL_DELFROM_COL: - return FALSE; - - default: - } - - return TRUE; -} - -static void * -duplicate_value (ETableModel *etm, int col, const void *val) -{ - return g_strdup (val); -} - -static void -free_value (ETableModel *etm, int col, void *val) -{ - g_free (val); -} - -static void * -init_value (ETableModel *etm, int col) -{ - switch (col) { - case E_MEETING_MODEL_ADDRESS_COL: - return g_strdup (""); - case E_MEETING_MODEL_MEMBER_COL: - return g_strdup (""); - case E_MEETING_MODEL_TYPE_COL: - return g_strdup (_("Individual")); - case E_MEETING_MODEL_ROLE_COL: - return g_strdup (_("Required Participant")); - case E_MEETING_MODEL_RSVP_COL: - return g_strdup (_("Yes")); - case E_MEETING_MODEL_DELTO_COL: - return g_strdup (""); - case E_MEETING_MODEL_DELFROM_COL: - return g_strdup (""); - case E_MEETING_MODEL_STATUS_COL: - return g_strdup (_("Needs Action")); - case E_MEETING_MODEL_CN_COL: - return g_strdup (""); - case E_MEETING_MODEL_LANGUAGE_COL: - return g_strdup ("en"); - } - - return g_strdup (""); -} - -static gboolean -value_is_empty (ETableModel *etm, int col, const void *val) -{ - - switch (col) { - case E_MEETING_MODEL_ADDRESS_COL: - case E_MEETING_MODEL_MEMBER_COL: - case E_MEETING_MODEL_DELTO_COL: - case E_MEETING_MODEL_DELFROM_COL: - case E_MEETING_MODEL_CN_COL: - if (val && !g_strcasecmp (val, "")) - return TRUE; - else - return FALSE; - default: - } - - return TRUE; -} - -static char * -value_to_string (ETableModel *etm, int col, const void *val) -{ - return g_strdup (val); -} - -static void * -get_key (ETableModel *source, int row, gpointer data) -{ - EMeetingModel *im; - EMeetingModelPrivate *priv; - char *str; - - im = E_MEETING_MODEL (source); - priv = im->priv; - - str = value_at (source, E_MEETING_MODEL_DELTO_COL, row); - if (str && *str) - return g_strdup ("delegator"); - - return g_strdup ("none"); -} - -static void * -duplicate_key (const void *key, gpointer data) -{ - return g_strdup (key); -} - -static void -free_gotten_key (void *key, gpointer data) -{ - g_free (key); -} - -static void -free_duplicated_key (void *key, gpointer data) -{ - g_free (key); -} - -static void -class_init (EMeetingModelClass *klass) -{ - GtkObjectClass *object_class; - ETableModelClass *etm_class; - - object_class = GTK_OBJECT_CLASS (klass); - etm_class = E_TABLE_MODEL_CLASS (klass); - - parent_class = gtk_type_class (E_TABLE_MODEL_TYPE); - - object_class->destroy = destroy; - - etm_class->column_count = column_count; - etm_class->row_count = row_count; - etm_class->value_at = value_at; - etm_class->set_value_at = set_value_at; - etm_class->is_cell_editable = is_cell_editable; - etm_class->append_row = append_row; - etm_class->duplicate_value = duplicate_value; - etm_class->free_value = free_value; - etm_class->initialize_value = init_value; - etm_class->value_is_empty = value_is_empty; - etm_class->value_to_string = value_to_string; -} - - -static void -init (EMeetingModel *im) -{ - EMeetingModelPrivate *priv; - - priv = g_new0 (EMeetingModelPrivate, 1); - - im->priv = priv; - - priv->attendees = g_ptr_array_new (); - - priv->without = E_TABLE_WITHOUT (e_table_without_new (E_TABLE_MODEL (im), - g_str_hash, - g_str_equal, - get_key, - duplicate_key, - free_gotten_key, - free_duplicated_key, - NULL)); - e_table_without_hide (priv->without, g_strdup ("delegator")); - - priv->client = NULL; - priv->zone = icaltimezone_get_builtin_timezone (calendar_config_get_timezone ()); - - priv->ebook = NULL; - priv->book_loaded = FALSE; - priv->book_load_wait = FALSE; - - priv->refresh_queue = g_ptr_array_new (); - priv->refresh_data = g_hash_table_new (g_direct_hash, g_direct_equal); - priv->refresh_idle_id = -1; - - start_addressbook_server (im); -} - -static void -destroy (GtkObject *obj) -{ - EMeetingModel *im = E_MEETING_MODEL (obj); - EMeetingModelPrivate *priv; - int i; - - priv = im->priv; - - for (i = 0; i < priv->attendees->len; i++) - gtk_object_unref (GTK_OBJECT (g_ptr_array_index (priv->attendees, i))); - g_ptr_array_free (priv->attendees, TRUE); - - if (priv->client != NULL) - gtk_object_unref (GTK_OBJECT (priv->client)); - - if (priv->ebook != NULL) - gtk_object_unref (GTK_OBJECT (priv->ebook)); - - if (priv->corba_select_names != CORBA_OBJECT_NIL) { - CORBA_Environment ev; - CORBA_exception_init (&ev); - bonobo_object_release_unref (priv->corba_select_names, &ev); - CORBA_exception_free (&ev); - } - - while (priv->refresh_queue->len > 0) - refresh_queue_remove (im, g_ptr_array_index (priv->refresh_queue, 0)); - g_ptr_array_free (priv->refresh_queue, TRUE); - g_hash_table_destroy (priv->refresh_data); - - if (priv->refresh_idle_id) - g_source_remove (priv->refresh_idle_id); - - g_free (priv); -} - -GtkObject * -e_meeting_model_new (void) -{ - return gtk_type_new (E_TYPE_MEETING_MODEL); -} - - -CalClient * -e_meeting_model_get_cal_client (EMeetingModel *im) -{ - EMeetingModelPrivate *priv; - - priv = im->priv; - - return priv->client; -} - -void -e_meeting_model_set_cal_client (EMeetingModel *im, CalClient *client) -{ - EMeetingModelPrivate *priv; - - priv = im->priv; - - if (priv->client != NULL) - gtk_object_unref (GTK_OBJECT (priv->client)); - - if (client != NULL) - gtk_object_ref (GTK_OBJECT (client)); - priv->client = client; -} - -icaltimezone * -e_meeting_model_get_zone (EMeetingModel *im) -{ - EMeetingModelPrivate *priv; - - g_return_val_if_fail (im != NULL, NULL); - g_return_val_if_fail (E_IS_MEETING_MODEL (im), NULL); - - priv = im->priv; - - return priv->zone; -} - -void -e_meeting_model_set_zone (EMeetingModel *im, icaltimezone *zone) -{ - EMeetingModelPrivate *priv; - - g_return_if_fail (im != NULL); - g_return_if_fail (E_IS_MEETING_MODEL (im)); - - priv = im->priv; - - priv->zone = zone; -} - -static ETableScrolled * -build_etable (ETableModel *model, const gchar *spec_file, const gchar *state_file) -{ - GtkWidget *etable; - ETable *real_table; - ETableExtras *extras; - GList *strings; - ECell *popup_cell, *cell; - - extras = e_table_extras_new (); - - /* For type */ - cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT); - popup_cell = e_cell_combo_new (); - e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell); - gtk_object_unref (GTK_OBJECT (cell)); - - strings = NULL; - strings = g_list_append (strings, (char*) U_("Individual")); - strings = g_list_append (strings, (char*) U_("Group")); - strings = g_list_append (strings, (char*) U_("Resource")); - strings = g_list_append (strings, (char*) U_("Room")); - strings = g_list_append (strings, (char*) U_("Unknown")); - - e_cell_combo_set_popdown_strings (E_CELL_COMBO (popup_cell), strings); - e_table_extras_add_cell (extras, "typeedit", popup_cell); - - /* For role */ - cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT); - popup_cell = e_cell_combo_new (); - e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell); - gtk_object_unref (GTK_OBJECT (cell)); - - strings = NULL; - strings = g_list_append (strings, (char*) U_("Chair")); - strings = g_list_append (strings, (char*) U_("Required Participant")); - strings = g_list_append (strings, (char*) U_("Optional Participant")); - strings = g_list_append (strings, (char*) U_("Non-Participant")); - strings = g_list_append (strings, (char*) U_("Unknown")); - - e_cell_combo_set_popdown_strings (E_CELL_COMBO (popup_cell), strings); - e_table_extras_add_cell (extras, "roleedit", popup_cell); - - /* For rsvp */ - cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT); - popup_cell = e_cell_combo_new (); - e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell); - gtk_object_unref (GTK_OBJECT (cell)); - - strings = NULL; - strings = g_list_append (strings, (char*) U_("Yes")); - strings = g_list_append (strings, (char*) U_("No")); - - e_cell_combo_set_popdown_strings (E_CELL_COMBO (popup_cell), strings); - e_table_extras_add_cell (extras, "rsvpedit", popup_cell); - - /* For status */ - cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT); - popup_cell = e_cell_combo_new (); - e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell); - gtk_object_unref (GTK_OBJECT (cell)); - - strings = NULL; - strings = g_list_append (strings, (char*) U_("Needs Action")); - strings = g_list_append (strings, (char*) U_("Accepted")); - strings = g_list_append (strings, (char*) U_("Declined")); - strings = g_list_append (strings, (char*) U_("Tentative")); - strings = g_list_append (strings, (char*) U_("Delegated")); - - e_cell_combo_set_popdown_strings (E_CELL_COMBO (popup_cell), strings); - e_table_extras_add_cell (extras, "statusedit", popup_cell); - - etable = e_table_scrolled_new_from_spec_file (model, extras, spec_file, NULL); - real_table = e_table_scrolled_get_table (E_TABLE_SCROLLED (etable)); - gtk_object_set (GTK_OBJECT (real_table), "uniform_row_height", TRUE, NULL); - e_table_load_state (real_table, state_file); - -#if 0 - gtk_signal_connect (GTK_OBJECT (real_table), - "right_click", GTK_SIGNAL_FUNC (right_click_cb), mpage); -#endif - - gtk_signal_connect (GTK_OBJECT (etable), "destroy", - GTK_SIGNAL_FUNC (table_destroy_cb), g_strdup (state_file)); - - gtk_object_unref (GTK_OBJECT (extras)); - - return E_TABLE_SCROLLED (etable); -} - -void -e_meeting_model_add_attendee (EMeetingModel *im, EMeetingAttendee *ia) -{ - EMeetingModelPrivate *priv; - - priv = im->priv; - - e_table_model_pre_change (E_TABLE_MODEL (im)); - - gtk_object_ref (GTK_OBJECT (ia)); - g_ptr_array_add (priv->attendees, ia); - - gtk_signal_connect (GTK_OBJECT (ia), "changed", - GTK_SIGNAL_FUNC (attendee_changed_cb), im); - - e_table_model_row_inserted (E_TABLE_MODEL (im), row_count (E_TABLE_MODEL (im)) - 1); -} - -EMeetingAttendee * -e_meeting_model_add_attendee_with_defaults (EMeetingModel *im) -{ - EMeetingAttendee *ia; - char *str; - - ia = E_MEETING_ATTENDEE (e_meeting_attendee_new ()); - - e_meeting_attendee_set_address (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_ADDRESS_COL)); - e_meeting_attendee_set_member (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_MEMBER_COL)); - - str = init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_TYPE_COL); - e_meeting_attendee_set_cutype (ia, text_to_type (str)); - g_free (str); - str = init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_ROLE_COL); - e_meeting_attendee_set_role (ia, text_to_role (str)); - g_free (str); - str = init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_RSVP_COL); - e_meeting_attendee_set_role (ia, text_to_boolean (str)); - g_free (str); - - e_meeting_attendee_set_delto (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_DELTO_COL)); - e_meeting_attendee_set_delfrom (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_DELFROM_COL)); - - str = init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_STATUS_COL); - e_meeting_attendee_set_status (ia, text_to_partstat (str)); - g_free (str); - - e_meeting_attendee_set_cn (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_CN_COL)); - e_meeting_attendee_set_language (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_LANGUAGE_COL)); - - e_meeting_model_add_attendee (im, ia); - - return ia; -} - -void -e_meeting_model_remove_attendee (EMeetingModel *im, EMeetingAttendee *ia) -{ - EMeetingModelPrivate *priv; - gint i, row = -1; - - priv = im->priv; - - for (i = 0; i < priv->attendees->len; i++) { - if (ia == g_ptr_array_index (priv->attendees, i)) { - row = i; - break; - } - } - - if (row != -1) { - e_table_model_pre_change (E_TABLE_MODEL (im)); - - g_ptr_array_remove_index (priv->attendees, row); - gtk_object_unref (GTK_OBJECT (ia)); - - e_table_model_row_deleted (E_TABLE_MODEL (im), row); - } -} - -void -e_meeting_model_remove_all_attendees (EMeetingModel *im) -{ - EMeetingModelPrivate *priv; - gint i, len; - - priv = im->priv; - - e_table_model_pre_change (E_TABLE_MODEL (im)); - - len = priv->attendees->len; - - for (i = 0; i < len; i++) { - EMeetingAttendee *ia = g_ptr_array_index (priv->attendees, i); - gtk_object_unref (GTK_OBJECT (ia)); - } - - g_ptr_array_set_size (priv->attendees, 0); - e_table_model_rows_deleted (E_TABLE_MODEL (im), 0, len); -} - -EMeetingAttendee * -e_meeting_model_find_attendee (EMeetingModel *im, const gchar *address, gint *row) -{ - EMeetingModelPrivate *priv; - EMeetingAttendee *ia; - int i; - - priv = im->priv; - - if (address == NULL) - return NULL; - - for (i = 0; i < priv->attendees->len; i++) { - const gchar *ia_address; - - ia = g_ptr_array_index (priv->attendees, i); - - ia_address = e_meeting_attendee_get_address (ia); - if (ia_address && !g_strcasecmp (itip_strip_mailto (ia_address), itip_strip_mailto (address))) { - if (row != NULL) - *row = i; - - return ia; - } - } - - return NULL; -} - -EMeetingAttendee * -e_meeting_model_find_attendee_at_row (EMeetingModel *im, gint row) -{ - EMeetingModelPrivate *priv; - - g_return_val_if_fail (im != NULL, NULL); - g_return_val_if_fail (E_IS_MEETING_MODEL (im), NULL); - g_return_val_if_fail (row >= 0, NULL); - - priv = im->priv; - g_return_val_if_fail (row < priv->attendees->len, NULL); - - return g_ptr_array_index (priv->attendees, row); -} - -gint -e_meeting_model_count_actual_attendees (EMeetingModel *im) -{ - EMeetingModelPrivate *priv; - - priv = im->priv; - - return e_table_model_row_count (E_TABLE_MODEL (priv->without)); -} - -const GPtrArray * -e_meeting_model_get_attendees (EMeetingModel *im) -{ - EMeetingModelPrivate *priv; - - priv = im->priv; - - return priv->attendees; -} - -static icaltimezone * -find_zone (icalproperty *ip, icalcomponent *tz_top_level) -{ - icalparameter *param; - icalcomponent *sub_comp; - const char *tzid; - icalcompiter iter; - - if (tz_top_level == NULL) - return NULL; - - param = icalproperty_get_first_parameter (ip, ICAL_TZID_PARAMETER); - if (param == NULL) - return NULL; - tzid = icalparameter_get_tzid (param); - - iter = icalcomponent_begin_component (tz_top_level, ICAL_VTIMEZONE_COMPONENT); - while ((sub_comp = icalcompiter_deref (&iter)) != NULL) { - icalcomponent *clone; - const char *tz_tzid; - - tz_tzid = icalproperty_get_tzid (sub_comp); - if (!strcmp (tzid, tz_tzid)) { - icaltimezone *zone; - - zone = icaltimezone_new (); - clone = icalcomponent_new_clone (sub_comp); - icaltimezone_set_component (zone, clone); - - return zone; - } - - icalcompiter_next (&iter); - } - - return NULL; -} - - -static void -refresh_queue_add (EMeetingModel *im, int row, - EMeetingTime *start, - EMeetingTime *end, - EMeetingModelRefreshCallback call_back, - gpointer data) -{ - EMeetingModelPrivate *priv; - EMeetingAttendee *ia; - EMeetingModelQueueData *qdata; - - priv = im->priv; - - ia = g_ptr_array_index (priv->attendees, row); - if (ia == NULL) - return; - - qdata = g_hash_table_lookup (priv->refresh_data, ia); - if (qdata == NULL) { - qdata = g_new0 (EMeetingModelQueueData, 1); - - qdata->im = im; - qdata->ia = ia; - e_meeting_attendee_clear_busy_periods (ia); - e_meeting_attendee_set_has_calendar_info (ia, FALSE); - - qdata->start = *start; - qdata->end = *end; - qdata->string = g_string_new (NULL); - qdata->call_backs = g_ptr_array_new (); - qdata->data = g_ptr_array_new (); - g_ptr_array_add (qdata->call_backs, call_back); - g_ptr_array_add (qdata->data, data); - - g_hash_table_insert (priv->refresh_data, ia, qdata); - } else { - if (e_meeting_time_compare_times (start, &qdata->start) == -1) - qdata->start = *start; - if (e_meeting_time_compare_times (end, &qdata->end) == 1) - qdata->end = *end; - g_ptr_array_add (qdata->call_backs, call_back); - g_ptr_array_add (qdata->data, data); - } - - gtk_object_ref (GTK_OBJECT (ia)); - g_ptr_array_add (priv->refresh_queue, ia); - - if (priv->refresh_idle_id == -1) - priv->refresh_idle_id = g_idle_add (refresh_busy_periods, im); -} - -static void -refresh_queue_remove (EMeetingModel *im, EMeetingAttendee *ia) -{ - EMeetingModelPrivate *priv; - EMeetingModelQueueData *qdata; - - priv = im->priv; - - /* Free the queue data */ - qdata = g_hash_table_lookup (priv->refresh_data, ia); - g_assert (qdata != NULL); - - g_hash_table_remove (priv->refresh_data, ia); - g_ptr_array_free (qdata->call_backs, TRUE); - g_ptr_array_free (qdata->data, TRUE); - g_free (qdata); - - /* Unref the attendee */ - g_ptr_array_remove (priv->refresh_queue, ia); - gtk_object_unref (GTK_OBJECT (ia)); -} - -static void -process_callbacks (EMeetingModelQueueData *qdata) -{ - int i; - - for (i = 0; i < qdata->call_backs->len; i++) { - EMeetingModelRefreshCallback call_back; - gpointer *data; - - call_back = g_ptr_array_index (qdata->call_backs, i); - data = g_ptr_array_index (qdata->data, i); - - call_back (data); - } - - refresh_queue_remove (qdata->im, qdata->ia); -} - -static void -process_free_busy_comp (EMeetingAttendee *ia, - icalcomponent *fb_comp, - icaltimezone *zone, - icalcomponent *tz_top_level) -{ - icalproperty *ip; - - ip = icalcomponent_get_first_property (fb_comp, ICAL_DTSTART_PROPERTY); - if (ip != NULL) { - struct icaltimetype dtstart; - icaltimezone *ds_zone; - - dtstart = icalproperty_get_dtstart (ip); - if (!dtstart.is_utc) - ds_zone = find_zone (ip, tz_top_level); - else - ds_zone = icaltimezone_get_utc_timezone (); - icaltimezone_convert_time (&dtstart, ds_zone, zone); - e_meeting_attendee_set_start_busy_range (ia, - dtstart.year, - dtstart.month, - dtstart.day, - dtstart.hour, - dtstart.minute); - } - - ip = icalcomponent_get_first_property (fb_comp, ICAL_DTEND_PROPERTY); - if (ip != NULL) { - struct icaltimetype dtend; - icaltimezone *de_zone; - - dtend = icalproperty_get_dtend (ip); - if (!dtend.is_utc) - de_zone = find_zone (ip, tz_top_level); - else - de_zone = icaltimezone_get_utc_timezone (); - icaltimezone_convert_time (&dtend, de_zone, zone); - e_meeting_attendee_set_end_busy_range (ia, - dtend.year, - dtend.month, - dtend.day, - dtend.hour, - dtend.minute); - } - - ip = icalcomponent_get_first_property (fb_comp, ICAL_FREEBUSY_PROPERTY); - while (ip != NULL) { - icalparameter *param; - struct icalperiodtype fb; - EMeetingFreeBusyType busy_type = E_MEETING_FREE_BUSY_LAST; - icalparameter_fbtype fbtype = ICAL_FBTYPE_BUSY; - - fb = icalproperty_get_freebusy (ip); - param = icalproperty_get_first_parameter (ip, ICAL_FBTYPE_PARAMETER); - if (param != NULL) - fbtype = icalparameter_get_fbtype (param); - - switch (fbtype) { - case ICAL_FBTYPE_BUSY: - busy_type = E_MEETING_FREE_BUSY_BUSY; - break; - - case ICAL_FBTYPE_BUSYUNAVAILABLE: - busy_type = E_MEETING_FREE_BUSY_OUT_OF_OFFICE; - break; - - case ICAL_FBTYPE_BUSYTENTATIVE: - busy_type = E_MEETING_FREE_BUSY_TENTATIVE; - break; - - default: - } - - if (busy_type != E_MEETING_FREE_BUSY_LAST) { - icaltimezone *utc_zone = icaltimezone_get_utc_timezone (); - - icaltimezone_convert_time (&fb.start, utc_zone, zone); - icaltimezone_convert_time (&fb.end, utc_zone, zone); - e_meeting_attendee_add_busy_period (ia, - fb.start.year, - fb.start.month, - fb.start.day, - fb.start.hour, - fb.start.minute, - fb.end.year, - fb.end.month, - fb.end.day, - fb.end.hour, - fb.end.minute, - busy_type); - } - - ip = icalcomponent_get_next_property (fb_comp, ICAL_FREEBUSY_PROPERTY); - } -} - -static void -process_free_busy (EMeetingModelQueueData *qdata, char *text) -{ - EMeetingModel *im = qdata->im; - EMeetingModelPrivate *priv; - EMeetingAttendee *ia = qdata->ia; - icalcomponent *main_comp; - icalcomponent_kind kind = ICAL_NO_COMPONENT; - - priv = im->priv; - - main_comp = icalparser_parse_string (text); - if (main_comp == NULL) { - process_callbacks (qdata); - return; - } - - kind = icalcomponent_isa (main_comp); - if (kind == ICAL_VCALENDAR_COMPONENT) { - icalcompiter iter; - icalcomponent *tz_top_level, *sub_comp; - - tz_top_level = cal_util_new_top_level (); - - iter = icalcomponent_begin_component (main_comp, ICAL_VTIMEZONE_COMPONENT); - while ((sub_comp = icalcompiter_deref (&iter)) != NULL) { - icalcomponent *clone; - - clone = icalcomponent_new_clone (sub_comp); - icalcomponent_add_component (tz_top_level, clone); - - icalcompiter_next (&iter); - } - - iter = icalcomponent_begin_component (main_comp, ICAL_VFREEBUSY_COMPONENT); - while ((sub_comp = icalcompiter_deref (&iter)) != NULL) { - process_free_busy_comp (ia, sub_comp, priv->zone, tz_top_level); - - icalcompiter_next (&iter); - } - icalcomponent_free (tz_top_level); - } else if (kind == ICAL_VFREEBUSY_COMPONENT) { - process_free_busy_comp (ia, main_comp, priv->zone, NULL); - } else { - return; - } - - icalcomponent_free (main_comp); - - process_callbacks (qdata); -} - -static void -async_close (GnomeVFSAsyncHandle *handle, - GnomeVFSResult result, - gpointer data) -{ - EMeetingModelQueueData *qdata = data; - - process_free_busy (qdata, qdata->string->str); -} - -static void -async_read (GnomeVFSAsyncHandle *handle, - GnomeVFSResult result, - gpointer buffer, - GnomeVFSFileSize requested, - GnomeVFSFileSize read, - gpointer data) -{ - EMeetingModelQueueData *qdata = data; - GnomeVFSFileSize buf_size = BUF_SIZE - 1; - - if (result != GNOME_VFS_OK) { - gnome_vfs_async_close (handle, async_close, qdata); - return; - } - - ((char *)buffer)[read] = '\0'; - qdata->string = g_string_append (qdata->string, buffer); - - if (read < requested) { - gnome_vfs_async_close (handle, async_close, qdata); - return; - } - - gnome_vfs_async_read (handle, qdata->buffer, buf_size, async_read, qdata); -} - -static void -async_open (GnomeVFSAsyncHandle *handle, - GnomeVFSResult result, - gpointer data) -{ - EMeetingModelQueueData *qdata = data; - GnomeVFSFileSize buf_size = BUF_SIZE - 1; - - if (result != GNOME_VFS_OK) { - gnome_vfs_async_close (handle, async_close, qdata); - return; - } - - gnome_vfs_async_read (handle, qdata->buffer, buf_size, async_read, qdata); -} - -static void -cursor_cb (EBook *book, EBookStatus status, ECardCursor *cursor, gpointer data) -{ - EMeetingModelQueueData *qdata = data; - int length, i; - - if (status != E_BOOK_STATUS_SUCCESS) - return; - - length = e_card_cursor_get_length (cursor); - for (i = 0; i < length; i ++) { - GnomeVFSAsyncHandle *handle; - ECard *card = e_card_cursor_get_nth (cursor, i); - const char *addr; - - if (card->fburl == NULL) - continue; - - addr = itip_strip_mailto (e_meeting_attendee_get_address (qdata->ia)); - if (!e_card_email_match_string (card, addr)) - continue; - - /* Read in free/busy data from the url */ - gnome_vfs_async_open (&handle, card->fburl, GNOME_VFS_OPEN_READ, async_open, qdata); - return; - } - - process_callbacks (qdata); -} - -static gboolean -refresh_busy_periods (gpointer data) -{ - EMeetingModel *im = E_MEETING_MODEL (data); - EMeetingModelPrivate *priv; - EMeetingAttendee *ia = NULL; - EMeetingModelQueueData *qdata = NULL; - char *query; - int i; - - priv = im->priv; - - /* Check to see if there are any remaining attendees in the queue */ - for (i = 0; i < priv->refresh_queue->len; i++) { - ia = g_ptr_array_index (priv->refresh_queue, i); - g_assert (ia != NULL); - - qdata = g_hash_table_lookup (priv->refresh_data, ia); - g_assert (qdata != NULL); - - if (!qdata->refreshing) - break; - } - - /* The everything in the queue is being refreshed */ - if (i >= priv->refresh_queue->len) { - priv->refresh_idle_id = -1; - return FALSE; - } - - /* Indicate we are trying to refresh it */ - qdata->refreshing = TRUE; - - /* Check the server for free busy data */ - if (priv->client) { - GList *fb_data, *users = NULL; - struct icaltimetype itt; - time_t startt, endt; - const char *user; - - itt = icaltime_null_time (); - itt.year = g_date_year (&qdata->start.date); - itt.month = g_date_month (&qdata->start.date); - itt.day = g_date_day (&qdata->start.date); - itt.hour = qdata->start.hour; - itt.minute = qdata->start.minute; - startt = icaltime_as_timet_with_zone (itt, priv->zone); - - itt = icaltime_null_time (); - itt.year = g_date_year (&qdata->end.date); - itt.month = g_date_month (&qdata->end.date); - itt.day = g_date_day (&qdata->end.date); - itt.hour = qdata->end.hour; - itt.minute = qdata->end.minute; - endt = icaltime_as_timet_with_zone (itt, priv->zone); - - user = itip_strip_mailto (e_meeting_attendee_get_address (ia)); - users = g_list_append (users, g_strdup (user)); - fb_data = cal_client_get_free_busy (priv->client, users, startt, endt); - - g_list_foreach (users, (GFunc)g_free, NULL); - g_list_free (users); - - if (fb_data != NULL) { - CalComponent *comp = fb_data->data; - char *comp_str; - - comp_str = cal_component_get_as_string (comp); - process_free_busy (qdata, comp_str); - g_free (comp_str); - return TRUE; - } - } - - /* Look for fburl's of attendee with no free busy info on server */ - if (!priv->book_loaded) { - priv->book_load_wait = TRUE; - gtk_main (); - } - - if (!e_meeting_attendee_is_set_address (ia)) { - process_callbacks (qdata); - return TRUE; - } - - query = g_strdup_printf ("(contains \"email\" \"%s\")", - itip_strip_mailto (e_meeting_attendee_get_address (ia))); - e_book_get_cursor (priv->ebook, query, cursor_cb, qdata); - g_free (query); - - return TRUE; -} - -void -e_meeting_model_refresh_all_busy_periods (EMeetingModel *im, - EMeetingTime *start, - EMeetingTime *end, - EMeetingModelRefreshCallback call_back, - gpointer data) -{ - EMeetingModelPrivate *priv; - int i; - - g_return_if_fail (im != NULL); - g_return_if_fail (E_IS_MEETING_MODEL (im)); - - priv = im->priv; - - for (i = 0; i < priv->attendees->len; i++) - refresh_queue_add (im, i, start, end, call_back, data); -} - -void -e_meeting_model_refresh_busy_periods (EMeetingModel *im, - int row, - EMeetingTime *start, - EMeetingTime *end, - EMeetingModelRefreshCallback call_back, - gpointer data) -{ - EMeetingModelPrivate *priv; - - g_return_if_fail (im != NULL); - g_return_if_fail (E_IS_MEETING_MODEL (im)); - - priv = im->priv; - - refresh_queue_add (im, row, start, end, call_back, data); -} - -ETableScrolled * -e_meeting_model_etable_from_model (EMeetingModel *im, const gchar *spec_file, const gchar *state_file) -{ - EMeetingModelPrivate *priv; - - g_return_val_if_fail (im != NULL, NULL); - g_return_val_if_fail (E_IS_MEETING_MODEL (im), NULL); - - priv = im->priv; - - return build_etable (E_TABLE_MODEL (priv->without), spec_file, state_file); -} - -int -e_meeting_model_etable_model_to_view_row (ETable *et, EMeetingModel *im, int model_row) -{ - EMeetingModelPrivate *priv; - int row; - - g_return_val_if_fail (im != NULL, -1); - g_return_val_if_fail (E_IS_MEETING_MODEL (im), -1); - - priv = im->priv; - - row = e_table_model_to_view_row (et, model_row); - if (row == -1) - return -1; - - return e_table_subset_model_to_view_row (E_TABLE_SUBSET (priv->without), row); -} - -int -e_meeting_model_etable_view_to_model_row (ETable *et, EMeetingModel *im, int view_row) -{ - EMeetingModelPrivate *priv; - int row; - - g_return_val_if_fail (im != NULL, -1); - g_return_val_if_fail (E_IS_MEETING_MODEL (im), -1); - - priv = im->priv; - - row = e_table_view_to_model_row (et, view_row); - if (row == -1) - return -1; - - return e_table_subset_view_to_model_row (E_TABLE_SUBSET (priv->without), row); -} - - -static void -add_section (GNOME_Evolution_Addressbook_SelectNames corba_select_names, const char *name) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_SelectNames_addSection (corba_select_names, - name, - gettext (name), - &ev); - - CORBA_exception_free (&ev); -} - -static gboolean -get_select_name_dialog (EMeetingModel *im) -{ - EMeetingModelPrivate *priv; - CORBA_Environment ev; - int i; - - priv = im->priv; - - if (priv->corba_select_names != CORBA_OBJECT_NIL) { - Bonobo_Control corba_control; - GtkWidget *control_widget; - int i; - - CORBA_exception_init (&ev); - for (i = 0; sections[i] != NULL; i++) { - corba_control = GNOME_Evolution_Addressbook_SelectNames_getEntryBySection - (priv->corba_select_names, sections[i], &ev); - if (BONOBO_EX (&ev)) { - CORBA_exception_free (&ev); - return FALSE; - } - - control_widget = bonobo_widget_new_control_from_objref (corba_control, CORBA_OBJECT_NIL); - - bonobo_widget_set_property (BONOBO_WIDGET (control_widget), "text", "", NULL); - } - CORBA_exception_free (&ev); - - return TRUE; - } - - CORBA_exception_init (&ev); - - priv->corba_select_names = oaf_activate_from_id (SELECT_NAMES_OAFID, 0, NULL, &ev); - - for (i = 0; sections[i] != NULL; i++) - add_section (priv->corba_select_names, sections[i]); - - bonobo_event_source_client_add_listener (priv->corba_select_names, - select_names_ok_cb, - "GNOME/Evolution:ok:dialog", - NULL, im); - - if (BONOBO_EX (&ev)) { - CORBA_exception_free (&ev); - return FALSE; - } - - CORBA_exception_free (&ev); - - return TRUE; -} - -void -e_meeting_model_invite_others_dialog (EMeetingModel *im) -{ - EMeetingModelPrivate *priv; - CORBA_Environment ev; - - priv = im->priv; - - if (!get_select_name_dialog (im)) - return; - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_SelectNames_activateDialog ( - priv->corba_select_names, _("Required Participants"), &ev); - - CORBA_exception_free (&ev); -} - -static void -process_section (EMeetingModel *im, EDestination **destv, icalparameter_role role) -{ - int i; - - for (i = 0; destv[i] != NULL; i++) { - EMeetingAttendee *ia; - const char *name, *address; - - name = e_destination_get_name (destv[i]); - address = e_destination_get_email (destv[i]); - - if (address == NULL || *address == '\0') - continue; - - if (e_meeting_model_find_attendee (im, address, NULL) == NULL) { - ia = e_meeting_model_add_attendee_with_defaults (im); - - e_meeting_attendee_set_address (ia, g_strdup_printf ("MAILTO:%s", address)); - e_meeting_attendee_set_role (ia, role); - e_meeting_attendee_set_cn (ia, g_strdup (name)); - } - } -} - -static void -select_names_ok_cb (BonoboListener *listener, - char *event_name, - CORBA_any *arg, - CORBA_Environment *ev, - gpointer data) -{ - EMeetingModel *im = data; - EMeetingModelPrivate *priv; - Bonobo_Control corba_control; - GtkWidget *control_widget; - EDestination **destv; - char *string = NULL; - int i; - - priv = im->priv; - - for (i = 0; sections[i] != NULL; i++) { - corba_control = GNOME_Evolution_Addressbook_SelectNames_getEntryBySection - (priv->corba_select_names, sections[i], ev); - control_widget = bonobo_widget_new_control_from_objref - (corba_control, CORBA_OBJECT_NIL); - - bonobo_widget_get_property (BONOBO_WIDGET (control_widget), "destinations", &string, NULL); - destv = e_destination_importv (string); - if (destv != NULL) { - process_section (im, destv, roles[i]); - e_destination_freev (destv); - } - } -} - -static void -attendee_changed_cb (EMeetingAttendee *ia, gpointer data) -{ - EMeetingModel *im = E_MEETING_MODEL (data); - EMeetingModelPrivate *priv; - gint row = -1, i; - - priv = im->priv; - - for (i = 0; i < priv->attendees->len; i++) { - if (ia == g_ptr_array_index (priv->attendees, i)) { - row = 1; - break; - } - } - - if (row == -1) - return; - - /* FIXME: Ideally I think you are supposed to call pre_change() before - the data structures are changed. */ - e_table_model_pre_change (E_TABLE_MODEL (im)); - e_table_model_row_changed (E_TABLE_MODEL (im), row); -} - -static void -table_destroy_cb (ETableScrolled *etable, gpointer data) -{ - ETable *real_table; - char *filename = data; - - real_table = e_table_scrolled_get_table (etable); - e_table_save_state (real_table, filename); - - g_free (data); -} - diff --git a/calendar/gui/e-meeting-model.h b/calendar/gui/e-meeting-model.h deleted file mode 100644 index 7e1aa0758b..0000000000 --- a/calendar/gui/e-meeting-model.h +++ /dev/null @@ -1,124 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-model.h - * - * Copyright (C) 2001 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: JP Rosevear - */ - -#ifndef _E_MODEL_H_ -#define _E_MODEL_H_ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtk.h> -#include <gal/e-table/e-table-scrolled.h> -#include <gal/e-table/e-table-model.h> -#include <cal-client/cal-client.h> -#include "e-meeting-attendee.h" - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -#define E_TYPE_MEETING_MODEL (e_meeting_model_get_type ()) -#define E_MEETING_MODEL(obj) (GTK_CHECK_CAST ((obj), E_TYPE_MEETING_MODEL, EMeetingModel)) -#define E_MEETING_MODEL_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_MEETING_MODEL, EMeetingModelClass)) -#define E_IS_MEETING_MODEL(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_MEETING_MODEL)) -#define E_IS_MEETING_MODEL_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_MEETING_MODEL)) - - -typedef struct _EMeetingModel EMeetingModel; -typedef struct _EMeetingModelPrivate EMeetingModelPrivate; -typedef struct _EMeetingModelClass EMeetingModelClass; - -typedef enum { - E_MEETING_MODEL_ADDRESS_COL, - E_MEETING_MODEL_MEMBER_COL, - E_MEETING_MODEL_TYPE_COL, - E_MEETING_MODEL_ROLE_COL, - E_MEETING_MODEL_RSVP_COL, - E_MEETING_MODEL_DELTO_COL, - E_MEETING_MODEL_DELFROM_COL, - E_MEETING_MODEL_STATUS_COL, - E_MEETING_MODEL_CN_COL, - E_MEETING_MODEL_LANGUAGE_COL, - E_MEETING_MODEL_COLUMN_COUNT -} EMeetingModelColumns; - -struct _EMeetingModel { - ETableModel parent; - - EMeetingModelPrivate *priv; -}; - -struct _EMeetingModelClass { - ETableModelClass parent_class; -}; - -typedef void (* EMeetingModelRefreshCallback) (gpointer data); - - -GtkType e_meeting_model_get_type (void); -GtkObject *e_meeting_model_new (void); - -CalClient *e_meeting_model_get_cal_client (EMeetingModel *im); -void e_meeting_model_set_cal_client (EMeetingModel *im, CalClient *client); - -icaltimezone *e_meeting_model_get_zone (EMeetingModel *im); -void e_meeting_model_set_zone (EMeetingModel *im, icaltimezone *zone); - -void e_meeting_model_add_attendee (EMeetingModel *im, EMeetingAttendee *ia); -EMeetingAttendee *e_meeting_model_add_attendee_with_defaults (EMeetingModel *im); - -void e_meeting_model_remove_attendee (EMeetingModel *im, EMeetingAttendee *ia); -void e_meeting_model_remove_all_attendees (EMeetingModel *im); - -EMeetingAttendee *e_meeting_model_find_attendee (EMeetingModel *im, const gchar *address, gint *row); -EMeetingAttendee *e_meeting_model_find_attendee_at_row (EMeetingModel *im, gint row); - -gint e_meeting_model_count_actual_attendees (EMeetingModel *im); -const GPtrArray *e_meeting_model_get_attendees (EMeetingModel *im); - -void e_meeting_model_refresh_all_busy_periods (EMeetingModel *im, - EMeetingTime *start, - EMeetingTime *end, - EMeetingModelRefreshCallback call_back, - gpointer data); -void e_meeting_model_refresh_busy_periods (EMeetingModel *im, - int row, - EMeetingTime *start, - EMeetingTime *end, - EMeetingModelRefreshCallback call_back, - gpointer data); - - -/* Helpful functions */ -ETableScrolled *e_meeting_model_etable_from_model (EMeetingModel *im, const gchar *spec_file, const gchar *state_file); -int e_meeting_model_etable_model_to_view_row (ETable *et, EMeetingModel *im, int model_row); -int e_meeting_model_etable_view_to_model_row (ETable *et, EMeetingModel *im, int view_row); - -void e_meeting_model_invite_others_dialog (EMeetingModel *im); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_MEETING_MODEL_H_ */ diff --git a/calendar/gui/e-meeting-time-sel-item.c b/calendar/gui/e-meeting-time-sel-item.c deleted file mode 100644 index d44a1f436d..0000000000 --- a/calendar/gui/e-meeting-time-sel-item.c +++ /dev/null @@ -1,1020 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@gtk.org> - * - * Copyright 1999, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -/* - * EMeetingTimeSelectorItem - A GnomeCanvasItem which is used for both the main - * display canvas and the top display (with the dates, times & All Attendees). - * I didn't make these separate GnomeCanvasItems since they share a lot of - * code. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <time.h> -#include <glib.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include "calendar-config.h" -#include "e-meeting-time-sel-item.h" -#include "e-meeting-time-sel.h" - -/* Initially the grid lines were drawn at the bottom of cells, but this didn't - line up well with the GtkEntry widgets, which in the default theme draw a - black shadow line across the top. So I've switched our code to draw the - lines across the top of cells. */ -#define E_MEETING_TIME_SELECTOR_DRAW_GRID_LINES_AT_BOTTOM 0 - -static void e_meeting_time_selector_item_class_init (EMeetingTimeSelectorItemClass *mts_item_class); -static void e_meeting_time_selector_item_init (EMeetingTimeSelectorItem *mts_item); -static void e_meeting_time_selector_item_destroy (GtkObject *object); - -static void e_meeting_time_selector_item_set_arg (GtkObject *o, GtkArg *arg, - guint arg_id); -static void e_meeting_time_selector_item_realize (GnomeCanvasItem *item); -static void e_meeting_time_selector_item_unrealize (GnomeCanvasItem *item); -static void e_meeting_time_selector_item_update (GnomeCanvasItem *item, - double *affine, - ArtSVP *clip_path, int flags); -static void e_meeting_time_selector_item_draw (GnomeCanvasItem *item, - GdkDrawable *drawable, - int x, int y, - int width, int height); -static double e_meeting_time_selector_item_point (GnomeCanvasItem *item, - double x, double y, - int cx, int cy, - GnomeCanvasItem **actual_item); -static gint e_meeting_time_selector_item_event (GnomeCanvasItem *item, - GdkEvent *event); -static gint e_meeting_time_selector_item_button_press (EMeetingTimeSelectorItem *mts_item, - GdkEvent *event); -static gint e_meeting_time_selector_item_button_release (EMeetingTimeSelectorItem *mts_item, - GdkEvent *event); -static gint e_meeting_time_selector_item_motion_notify (EMeetingTimeSelectorItem *mts_item, - GdkEvent *event); - -static void e_meeting_time_selector_item_paint_day_top (EMeetingTimeSelectorItem *mts_item, - GdkDrawable *drawable, - GDate *date, - int x, int scroll_y, - int width, int height); -static void e_meeting_time_selector_item_paint_all_attendees_busy_periods (EMeetingTimeSelectorItem *mts_item, GdkDrawable *drawable, GDate *date, int x, int y, int width, int height); -static void e_meeting_time_selector_item_paint_day (EMeetingTimeSelectorItem *mts_item, - GdkDrawable *drawable, - GDate *date, - int x, int scroll_y, - int width, int height); -static void e_meeting_time_selector_item_paint_busy_periods (EMeetingTimeSelectorItem *mts_item, GdkDrawable *drawable, GDate *date, int x, int scroll_y, int width, int height); -static gint e_meeting_time_selector_item_find_first_busy_period (EMeetingTimeSelectorItem *mts_item, GDate *date, gint row); -static void e_meeting_time_selector_item_paint_attendee_busy_periods (EMeetingTimeSelectorItem *mts_item, GdkDrawable *drawable, int row, int x, int y, int width, int first_period, EMeetingFreeBusyType busy_type); - -static EMeetingTimeSelectorPosition e_meeting_time_selector_item_get_drag_position (EMeetingTimeSelectorItem *mts_item, gint x, gint y); -static gboolean e_meeting_time_selector_item_calculate_busy_range (EMeetingTimeSelector *mts, - gint row, - gint x, - gint width, - gint *start_x, - gint *end_x); - -static GnomeCanvasItemClass *parent_class; - -/* The arguments we take */ -enum { - ARG_0, - ARG_MEETING_TIME_SELECTOR -}; - - -GtkType -e_meeting_time_selector_item_get_type (void) -{ - static GtkType e_meeting_time_selector_item_type = 0; - - if (!e_meeting_time_selector_item_type) { - GtkTypeInfo e_meeting_time_selector_item_info = { - "EMeetingTimeSelectorItem", - sizeof (EMeetingTimeSelectorItem), - sizeof (EMeetingTimeSelectorItemClass), - (GtkClassInitFunc) e_meeting_time_selector_item_class_init, - (GtkObjectInitFunc) e_meeting_time_selector_item_init, - NULL, /* reserved_1 */ - NULL, /* reserved_2 */ - (GtkClassInitFunc) NULL - }; - - e_meeting_time_selector_item_type = gtk_type_unique (gnome_canvas_item_get_type (), &e_meeting_time_selector_item_info); - } - - return e_meeting_time_selector_item_type; -} - - -static void -e_meeting_time_selector_item_class_init (EMeetingTimeSelectorItemClass *mts_item_class) -{ - GtkObjectClass *object_class; - GnomeCanvasItemClass *item_class; - - parent_class = gtk_type_class (gnome_canvas_item_get_type()); - - object_class = (GtkObjectClass *) mts_item_class; - item_class = (GnomeCanvasItemClass *) mts_item_class; - - gtk_object_add_arg_type ("EMeetingTimeSelectorItem::meeting_time_selector", - GTK_TYPE_POINTER, GTK_ARG_WRITABLE, - ARG_MEETING_TIME_SELECTOR); - - object_class->destroy = e_meeting_time_selector_item_destroy; - object_class->set_arg = e_meeting_time_selector_item_set_arg; - - /* GnomeCanvasItem method overrides */ - item_class->realize = e_meeting_time_selector_item_realize; - item_class->unrealize = e_meeting_time_selector_item_unrealize; - item_class->update = e_meeting_time_selector_item_update; - item_class->draw = e_meeting_time_selector_item_draw; - item_class->point = e_meeting_time_selector_item_point; - item_class->event = e_meeting_time_selector_item_event; -} - - -static void -e_meeting_time_selector_item_init (EMeetingTimeSelectorItem *mts_item) -{ - GnomeCanvasItem *item = GNOME_CANVAS_ITEM (mts_item); - - mts_item->mts = NULL; - - mts_item->main_gc = NULL; - mts_item->stipple_gc = NULL; - - /* Create the cursors. */ - mts_item->normal_cursor = gdk_cursor_new (GDK_LEFT_PTR); - mts_item->resize_cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW); - mts_item->last_cursor_set = NULL; - - item->x1 = 0; - item->y1 = 0; - item->x2 = 0; - item->y2 = 0; -} - - -static void -e_meeting_time_selector_item_destroy (GtkObject *object) -{ - EMeetingTimeSelectorItem *mts_item; - - mts_item = E_MEETING_TIME_SELECTOR_ITEM (object); - - gdk_cursor_destroy (mts_item->normal_cursor); - gdk_cursor_destroy (mts_item->resize_cursor); - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (*GTK_OBJECT_CLASS (parent_class)->destroy)(object); -} - - -static void -e_meeting_time_selector_item_set_arg (GtkObject *o, GtkArg *arg, guint arg_id) -{ - GnomeCanvasItem *item; - EMeetingTimeSelectorItem *mts_item; - - item = GNOME_CANVAS_ITEM (o); - mts_item = E_MEETING_TIME_SELECTOR_ITEM (o); - - switch (arg_id){ - case ARG_MEETING_TIME_SELECTOR: - mts_item->mts = GTK_VALUE_POINTER (*arg); - break; - } -} - - -static void -e_meeting_time_selector_item_realize (GnomeCanvasItem *item) -{ - GnomeCanvas *canvas; - GdkWindow *window; - EMeetingTimeSelectorItem *mts_item; - - if (GNOME_CANVAS_ITEM_CLASS (parent_class)->realize) - (*GNOME_CANVAS_ITEM_CLASS (parent_class)->realize)(item); - - mts_item = E_MEETING_TIME_SELECTOR_ITEM (item); - - canvas = item->canvas; - window = GTK_WIDGET (canvas)->window; - - mts_item->main_gc = gdk_gc_new (window); - mts_item->stipple_gc = gdk_gc_new (window); -} - - -static void -e_meeting_time_selector_item_unrealize (GnomeCanvasItem *item) -{ - EMeetingTimeSelectorItem *mts_item; - - mts_item = E_MEETING_TIME_SELECTOR_ITEM (item); - - gdk_gc_unref (mts_item->main_gc); - mts_item->main_gc = NULL; - gdk_gc_unref (mts_item->stipple_gc); - mts_item->stipple_gc = NULL; - - if (GNOME_CANVAS_ITEM_CLASS (parent_class)->unrealize) - (*GNOME_CANVAS_ITEM_CLASS (parent_class)->unrealize)(item); -} - - -static void -e_meeting_time_selector_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 grid 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_meeting_time_selector_item_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, int height) -{ - EMeetingTimeSelector *mts; - EMeetingTimeSelectorItem *mts_item; - ETable *real_table; - EMeetingAttendee *ia; - gint day_x, meeting_start_x, meeting_end_x, bar_y, bar_height; - gint row, row_y, start_x, end_x; - GDate date, last_date, current_date; - gboolean is_display_top, show_meeting_time; - GdkGC *gc, *stipple_gc; - - mts_item = E_MEETING_TIME_SELECTOR_ITEM (item); - mts = mts_item->mts; - g_return_if_fail (mts != NULL); - gc = mts_item->main_gc; - stipple_gc = mts_item->stipple_gc; - - real_table = e_table_scrolled_get_table (E_TABLE_SCROLLED (mts->etable)); - - is_display_top = (GTK_WIDGET (item->canvas) == mts->display_top) - ? TRUE : FALSE; - - /* Calculate the first and last visible days and positions. */ - e_meeting_time_selector_calculate_day_and_position (mts, x, - &date, &day_x); - e_meeting_time_selector_calculate_day_and_position (mts, x + width, - &last_date, NULL); - - /* For the top display draw the 'All Attendees' row background. */ - if (is_display_top) { - gdk_gc_set_foreground (gc, &mts->all_attendees_bg_color); - gdk_draw_rectangle (drawable, gc, TRUE, - 0, mts->row_height * 2 - y, - width, mts->row_height); - } else { - gdk_gc_set_foreground (gc, &mts->bg_color); - gdk_draw_rectangle (drawable, gc, TRUE, 0, 0, width, height); - } - - /* Calculate the x coordinates of the meeting time. */ - show_meeting_time = e_meeting_time_selector_get_meeting_time_positions (mts, &meeting_start_x, &meeting_end_x); - - /* Draw the meeting time background. */ - if (show_meeting_time - && (meeting_end_x - 1 >= x) && (meeting_start_x + 1 < x + width) - && (meeting_end_x - meeting_start_x > 2)) { - gdk_gc_set_foreground (gc, &mts->meeting_time_bg_color); - if (is_display_top) - gdk_draw_rectangle (drawable, gc, TRUE, - meeting_start_x + 1 - x, mts->row_height * 2 - y, - meeting_end_x - meeting_start_x - 2, mts->row_height); - else - gdk_draw_rectangle (drawable, gc, TRUE, - meeting_start_x + 1 - x, 0, - meeting_end_x - meeting_start_x - 2, height); - } - - /* For the main display draw the stipple background for attendee's - that have no calendar information. */ - if (!is_display_top) { - gdk_gc_set_foreground (gc, &mts->grid_color); - gdk_gc_set_foreground (stipple_gc, &mts->grid_color); - gdk_gc_set_background (stipple_gc, &mts->stipple_bg_color); - gdk_gc_set_stipple (stipple_gc, mts->stipple); - gnome_canvas_set_stipple_origin (item->canvas, stipple_gc); - gdk_gc_set_fill (stipple_gc, GDK_OPAQUE_STIPPLED); - row = y / mts->row_height; - row_y = row * mts->row_height - y; - while (row < e_meeting_model_count_actual_attendees (mts->model) && row_y < height) { - gint model_row = e_meeting_model_etable_view_to_model_row (real_table, - mts->model, row); - - ia = e_meeting_model_find_attendee_at_row (mts->model, model_row); - - if (e_meeting_attendee_get_has_calendar_info (ia)) { - if (e_meeting_time_selector_item_calculate_busy_range (mts, model_row, x, width, &start_x, &end_x)) { - if (start_x >= width || end_x <= 0) { - gdk_draw_rectangle (drawable, stipple_gc, TRUE, 0, row_y, width, mts->row_height); - } else { - if (start_x >= 0) { - gdk_draw_rectangle (drawable, stipple_gc, TRUE, 0, row_y, start_x, mts->row_height); - gdk_draw_line (drawable, gc, start_x, row_y, start_x, row_y + mts->row_height); - } - if (end_x <= width) { - gdk_draw_rectangle (drawable, stipple_gc, TRUE, end_x, row_y, width - end_x, mts->row_height); - gdk_draw_line (drawable, gc, end_x, row_y, end_x, row_y + mts->row_height); - } - } - } - } else { - gdk_draw_rectangle (drawable, stipple_gc, TRUE, - 0, row_y, - width, mts->row_height); - } - row++; - row_y += mts->row_height; - } - gdk_gc_set_fill (gc, GDK_SOLID); - } - - /* Now paint the visible days one by one. */ - current_date = date; - for (;;) { - /* Currently we use the same GnomeCanvasItem class for the - top display and the main display. We may use separate - classes in future if necessary. */ - if (is_display_top) - e_meeting_time_selector_item_paint_day_top (mts_item, drawable, ¤t_date, day_x, y, width, height); - else - e_meeting_time_selector_item_paint_day (mts_item, drawable, ¤t_date, day_x, y, width, height); - - day_x += mts_item->mts->day_width; - if (g_date_compare (¤t_date, &last_date) == 0) - break; - g_date_add_days (¤t_date, 1); - } - - /* Draw the busy periods. */ - if (is_display_top) - e_meeting_time_selector_item_paint_all_attendees_busy_periods (mts_item, drawable, &date, x, y, width, height); - else - e_meeting_time_selector_item_paint_busy_periods (mts_item, drawable, &date, x, y, width, height); - - - /* Draw the currently-selected meeting time vertical bars. */ - if (show_meeting_time) { - if (is_display_top) { - bar_y = mts->row_height * 2 - y; - bar_height = mts->row_height; - } else { - bar_y = 0; - bar_height = height; - } - - gdk_gc_set_foreground (gc, &mts->grid_color); - - if ((meeting_start_x + 2 >= x) - && (meeting_start_x - 2 < x + width)) { - gdk_draw_rectangle (drawable, gc, TRUE, - meeting_start_x - 2 - x, bar_y, - 5, bar_height); - } - - if ((meeting_end_x + 2 >= x) - && (meeting_end_x - 2 < x + width)) { - gdk_draw_rectangle (drawable, gc, TRUE, - meeting_end_x - 2 - x, bar_y, - 5, bar_height); - } - } -} - - -static void -e_meeting_time_selector_item_paint_day_top (EMeetingTimeSelectorItem *mts_item, - GdkDrawable *drawable, GDate *date, - int x, int scroll_y, - int width, int height) -{ - EMeetingTimeSelector *mts; - GdkGC *gc; - GdkFont *font; - gint y, grid_x; - gchar buffer[128], *format; - gint hour, hour_x, hour_y; - GdkRectangle clip_rect; - - mts = mts_item->mts; - gc = mts_item->main_gc; - - gdk_gc_set_foreground (gc, &mts->grid_color); - - /* Draw the horizontal lines. */ - y = mts->row_height - 1 - scroll_y; - gdk_draw_line (drawable, gc, x, y, x + mts->day_width - 1, y); - gdk_gc_set_foreground (gc, &mts->grid_shadow_color); - gdk_draw_line (drawable, gc, x, y + 1, x + mts->day_width - 1, y + 1); - gdk_gc_set_foreground (gc, &mts->grid_color); - y += mts->row_height; - gdk_draw_line (drawable, gc, x, y, x + mts->day_width - 1, y); - y += mts->row_height; - gdk_draw_line (drawable, gc, x, y, x + mts->day_width - 1, y); - - - /* Draw the vertical grid lines. */ - for (grid_x = mts->col_width - 1; - grid_x < mts->day_width - mts->col_width; - grid_x += mts->col_width) { - gdk_draw_line (drawable, gc, - x + grid_x, mts->row_height * 2 - 4 - scroll_y, - x + grid_x, height); - } - grid_x = mts->day_width - 2; - gdk_draw_line (drawable, gc, x + grid_x, 0, x + grid_x, height); - grid_x++; - gdk_draw_line (drawable, gc, x + grid_x, 0, x + grid_x, height); - - /* Draw the date. Set a clipping rectangle so we don't draw over the - next day. */ - font = GTK_WIDGET (mts)->style->font; - if (mts->date_format == E_MEETING_TIME_SELECTOR_DATE_FULL) - /* This is a strftime() format string %A = full weekday name, - %B = full month name, %d = month day, %Y = full year. */ - format = _("%A, %B %d, %Y"); - else if (mts->date_format == E_MEETING_TIME_SELECTOR_DATE_ABBREVIATED_DAY) - /* This is a strftime() format string %a = abbreviated weekday - name, %m = month number, %d = month day, %Y = full year. */ - format = _("%a %m/%d/%Y"); - else - /* This is a strftime() format string %m = month number, - %d = month day, %Y = full year. */ - format = _("%m/%d/%Y"); - - g_date_strftime (buffer, sizeof (buffer), format, date); - - clip_rect.x = x; - clip_rect.y = -scroll_y; - clip_rect.width = mts->day_width - 2; - clip_rect.height = mts->row_height - 2; - gdk_gc_set_clip_rectangle (gc, &clip_rect); - gdk_draw_string (drawable, font, gc, - x + 2, 4 + font->ascent - scroll_y, buffer); - gdk_gc_set_clip_rectangle (gc, NULL); - - /* Draw the hours. */ - hour = mts->first_hour_shown; - hour_x = x + 2; - hour_y = mts->row_height + 4 + font->ascent - scroll_y; - while (hour < mts->last_hour_shown) { - if (calendar_config_get_24_hour_format ()) - gdk_draw_string (drawable, font, gc, - hour_x, hour_y, - EMeetingTimeSelectorHours[hour]); - else - gdk_draw_string (drawable, font, gc, - hour_x, hour_y, - EMeetingTimeSelectorHours12[hour]); - - hour += mts->zoomed_out ? 3 : 1; - hour_x += mts->col_width; - } -} - - -/* This paints the colored bars representing busy periods for the combined - list of attendees. For now we just paint the bars for each attendee of - each other. If we want to speed it up we could optimise it later. */ -static void -e_meeting_time_selector_item_paint_all_attendees_busy_periods (EMeetingTimeSelectorItem *mts_item, GdkDrawable *drawable, GDate *date, int x, int scroll_y, int width, int height) -{ - EMeetingTimeSelector *mts; - EMeetingAttendee *ia; - EMeetingFreeBusyType busy_type; - gint row, y; - GdkGC *gc; - gint *first_periods; - - mts = mts_item->mts; - gc = mts_item->main_gc; - - /* Calculate the y coordinate to paint the row at in the drawable. */ - y = 2 * mts->row_height - scroll_y - 1; - - /* Get the first visible busy periods for all the attendees. */ - first_periods = g_new (gint, e_meeting_model_count_actual_attendees (mts->model)); - for (row = 0; row < e_meeting_model_count_actual_attendees (mts->model); row++) { - ia = e_meeting_model_find_attendee_at_row (mts->model, row); - first_periods[row] = e_meeting_time_selector_item_find_first_busy_period (mts_item, date, row); - } - - for (busy_type = 0; - busy_type < E_MEETING_FREE_BUSY_LAST; - busy_type++) { - gdk_gc_set_foreground (gc, &mts->busy_colors[busy_type]); - for (row = 0; row < e_meeting_model_count_actual_attendees (mts->model); row++) { - if (first_periods[row] == -1) - continue; - e_meeting_time_selector_item_paint_attendee_busy_periods (mts_item, drawable, x, y, width, row, first_periods[row], busy_type); - } - } - - g_free (first_periods); -} - - -static void -e_meeting_time_selector_item_paint_day (EMeetingTimeSelectorItem *mts_item, - GdkDrawable *drawable, GDate *date, - int x, int scroll_y, - int width, int height) -{ - EMeetingTimeSelector *mts; - GdkGC *gc; - gint grid_x, grid_y, attendee_index, unused_y; - - mts = mts_item->mts; - gc = mts_item->main_gc; - - /* Draw the grid lines. The grid lines around unused rows are drawn in - a different color. */ - - /* Draw the horizontal grid lines. */ - attendee_index = scroll_y / mts->row_height; -#if E_MEETING_TIME_SELECTOR_DRAW_GRID_LINES_AT_BOTTOM - for (grid_y = mts->row_height - 1 - (scroll_y % mts->row_height); -#else - for (grid_y = - (scroll_y % mts->row_height); -#endif - grid_y < height; - grid_y += mts->row_height) - { - if (attendee_index <= e_meeting_model_count_actual_attendees (mts->model)) { - gdk_gc_set_foreground (gc, &mts->grid_color); - gdk_draw_line (drawable, gc, 0, grid_y, - width, grid_y); - } else { - gdk_gc_set_foreground (gc, &mts->grid_unused_color); - gdk_draw_line (drawable, gc, 0, grid_y, - width, grid_y); - } - attendee_index++; - } - - /* Draw the vertical grid lines. */ - unused_y = (e_meeting_model_count_actual_attendees (mts->model) * mts->row_height) - scroll_y; - if (unused_y >= 0) { - gdk_gc_set_foreground (gc, &mts->grid_color); - for (grid_x = mts->col_width - 1; - grid_x < mts->day_width - mts->col_width; - grid_x += mts->col_width) - { - gdk_draw_line (drawable, gc, - x + grid_x, 0, - x + grid_x, unused_y - 1); - } - gdk_draw_rectangle (drawable, gc, TRUE, - x + mts->day_width - 2, 0, - 2, unused_y); - } - - if (unused_y < height) { - gdk_gc_set_foreground (gc, &mts->grid_unused_color); - for (grid_x = mts->col_width - 1; - grid_x < mts->day_width - mts->col_width; - grid_x += mts->col_width) - { - gdk_draw_line (drawable, gc, - x + grid_x, unused_y, - x + grid_x, height); - } - gdk_draw_rectangle (drawable, gc, TRUE, - x + mts->day_width - 2, unused_y, - 2, height - unused_y); - } - - -} - - -/* This paints the colored bars representing busy periods for the individual - attendees. */ -static void -e_meeting_time_selector_item_paint_busy_periods (EMeetingTimeSelectorItem *mts_item, GdkDrawable *drawable, GDate *date, int x, int scroll_y, int width, int height) -{ - EMeetingTimeSelector *mts; - EMeetingFreeBusyType busy_type; - ETable *real_table; - gint row, model_row, y, first_period; - GdkGC *gc; - - mts = mts_item->mts; - gc = mts_item->main_gc; - - real_table = e_table_scrolled_get_table (E_TABLE_SCROLLED (mts->etable)); - - /* Calculate the first visible attendee row. */ - row = scroll_y / mts->row_height; - - /* Calculate the y coordinate to paint the row at in the drawable. */ - y = row * mts->row_height - scroll_y; - - /* Step through the attendees painting the busy periods. */ - while (y < height && row < e_meeting_model_count_actual_attendees (mts->model)) { - model_row = e_meeting_model_etable_view_to_model_row (real_table, mts->model, row); - - /* Find the first visible busy period. */ - first_period = e_meeting_time_selector_item_find_first_busy_period (mts_item, date, model_row); - if (first_period != -1) { - /* Paint the different types of busy periods, in - reverse order of precedence, so the highest - precedences are displayed. */ - for (busy_type = 0; - busy_type < E_MEETING_FREE_BUSY_LAST; - busy_type++) { - gdk_gc_set_foreground (gc, &mts->busy_colors[busy_type]); - e_meeting_time_selector_item_paint_attendee_busy_periods (mts_item, drawable, x, y, width, model_row, first_period, busy_type); - } - } - y += mts->row_height; - row++; - } -} - - -/* This subtracts the attendees longest_period_in_days from the given date, - and does a binary search of the attendee's busy periods array to find the - first one which could possible end on the given day or later. - If none are found it returns -1. */ -static gint -e_meeting_time_selector_item_find_first_busy_period (EMeetingTimeSelectorItem *mts_item, GDate *date, gint row) -{ - EMeetingTimeSelector *mts; - EMeetingAttendee *ia; - const GArray *busy_periods; - EMeetingFreeBusyPeriod *period; - gint period_num; - - mts = mts_item->mts; - - ia = e_meeting_model_find_attendee_at_row (mts->model, row); - - period_num = e_meeting_attendee_find_first_busy_period (ia, date); - if (period_num == -1) - return -1; - - /* Check if the period starts after the end of the current canvas - scroll area. */ - busy_periods = e_meeting_attendee_get_busy_periods (ia); - period = &g_array_index (busy_periods, EMeetingFreeBusyPeriod, period_num); - if (g_date_compare (&mts->last_date_shown, &period->start.date) < 0) - return -1; - - return period_num; -} - - -/* This paints the visible busy periods for one attendee which are of a certain - busy type, e.g out of office. It is passed the index of the first visible - busy period of the attendee and continues until it runs off the screen. */ -static void -e_meeting_time_selector_item_paint_attendee_busy_periods (EMeetingTimeSelectorItem *mts_item, GdkDrawable *drawable, int x, int y, int width, int row, int first_period, EMeetingFreeBusyType busy_type) -{ - EMeetingTimeSelector *mts; - EMeetingAttendee *ia; - const GArray *busy_periods; - EMeetingFreeBusyPeriod *period; - GdkGC *gc; - gint period_num, x1, x2, x2_within_day, x2_within_col; - - mts = mts_item->mts; - gc = mts_item->main_gc; - - ia = e_meeting_model_find_attendee_at_row (mts->model, row); - - busy_periods = e_meeting_attendee_get_busy_periods (ia); - for (period_num = first_period; - period_num < busy_periods->len; - period_num++) { - period = &g_array_index (busy_periods, EMeetingFreeBusyPeriod, period_num); - - if (period->busy_type != busy_type) - continue; - - /* Convert the period start and end times to x coordinates. */ - x1 = e_meeting_time_selector_calculate_time_position (mts, &period->start); - /* If the period is off the right of the area being drawn, we - are finished. */ - if (x1 >= x + width) - return; - - x2 = e_meeting_time_selector_calculate_time_position (mts, &period->end); - /* If the period is off the left edge of the area skip it. */ - if (x2 <= x) - continue; - - /* We paint from x1 to x2 - 1, so that for example a time - from 5:00-6:00 is distinct from 6:00-7:00. - We never finish on a grid line separating days, and we only - ever paint on a normal vertical grid line if the period is - only 1 pixel wide. */ - x2_within_day = x2 % mts->day_width; - if (x2_within_day == 0) { - x2 -= 2; - } else if (x2_within_day == mts->day_width - 1) { - x2 -= 1; - } else { - x2_within_col = x2_within_day % mts->col_width; - if (x2_within_col == 0 && x2 > x1 + 1) - x2 -= 1; - } - - /* Paint the rectangle. We leave a gap of 2 pixels at the - top and bottom, remembering that the grid is painted along - the top/bottom line of each row. */ - if (x2 - x1 > 0) { -#if E_MEETING_TIME_SELECTOR_DRAW_GRID_LINES_AT_BOTTOM - gdk_draw_rectangle (drawable, gc, TRUE, - x1 - x, y + 2, - x2 - x1, mts->row_height - 5); -#else - gdk_draw_rectangle (drawable, gc, TRUE, - x1 - x, y + 3, - x2 - x1, mts->row_height - 5); -#endif - } - } -} - - -/* - * CANVAS ITEM ROUTINES - functions to be a GnomeCanvasItem. - */ - -/* 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_meeting_time_selector_item_point (GnomeCanvasItem *item, double x, double y, - int cx, int cy, - GnomeCanvasItem **actual_item) -{ - *actual_item = item; - return 0.0; -} - - -static gint -e_meeting_time_selector_item_event (GnomeCanvasItem *item, GdkEvent *event) -{ - EMeetingTimeSelectorItem *mts_item; - - mts_item = E_MEETING_TIME_SELECTOR_ITEM (item); - - switch (event->type) { - case GDK_BUTTON_PRESS: - return e_meeting_time_selector_item_button_press (mts_item, - event); - case GDK_BUTTON_RELEASE: - return e_meeting_time_selector_item_button_release (mts_item, - event); - case GDK_MOTION_NOTIFY: - return e_meeting_time_selector_item_motion_notify (mts_item, - event); - default: - break; - } - - return FALSE; -} - - -/* This handles all button press events for the item. If the cursor is over - one of the meeting time vertical bars we start a drag. If not we set the - meeting time to the nearest half-hour interval. - Note that GnomeCanvas converts the event coords to world coords, - i.e. relative to the entire canvas scroll area. */ -static gint -e_meeting_time_selector_item_button_press (EMeetingTimeSelectorItem *mts_item, - GdkEvent *event) -{ - EMeetingTimeSelector *mts; - EMeetingTime start_time, end_time; - EMeetingTimeSelectorPosition position; - GDate *start_date, *end_date; - gint x, y; - - mts = mts_item->mts; - x = (gint) event->button.x; - y = (gint) event->button.y; - - /* Check if we are starting a drag of the vertical meeting time bars.*/ - position = e_meeting_time_selector_item_get_drag_position (mts_item, - x, y); - if (position != E_MEETING_TIME_SELECTOR_POS_NONE) { - if (gnome_canvas_item_grab (GNOME_CANVAS_ITEM (mts_item), - GDK_POINTER_MOTION_MASK - | GDK_BUTTON_RELEASE_MASK, - mts_item->resize_cursor, - event->button.time) == 0 /*Success*/) { - mts->dragging_position = position; - return TRUE; - } - } - - /* Convert the x coordinate into a EMeetingTimeSelectorTime. */ - e_meeting_time_selector_calculate_time (mts, x, &start_time); - start_date = &start_time.date; - end_date = &end_time.date; - - /* Find the nearest half-hour or hour interval, depending on whether - zoomed_out is set. */ - if (!mts->all_day) { - if (mts->zoomed_out) { - start_time.minute = 0; - end_time = start_time; - end_time.hour += 1; - } else { - start_time.minute -= start_time.minute % 30; - end_time = start_time; - end_time.minute += 30; - } - } else { - start_time.hour = 0; - start_time.minute = 0; - end_time = start_time; - g_date_add_days (&end_time.date, 1); - } - - /* Fix any overflows. */ - e_meeting_time_selector_fix_time_overflows (&end_time); - - /* Set the new meeting time. */ - e_meeting_time_selector_set_meeting_time (mts_item->mts, - g_date_year (start_date), - g_date_month (start_date), - g_date_day (start_date), - start_time.hour, - start_time.minute, - g_date_year (end_date), - g_date_month (end_date), - g_date_day (end_date), - end_time.hour, - end_time.minute); - - - return FALSE; -} - - -/* This handles all button release events for the item. If we were dragging, - we finish the drag. */ -static gint -e_meeting_time_selector_item_button_release (EMeetingTimeSelectorItem *mts_item, - GdkEvent *event) -{ - EMeetingTimeSelector *mts; - - mts = mts_item->mts; - - /* Reset any drag. */ - if (mts->dragging_position != E_MEETING_TIME_SELECTOR_POS_NONE) { - mts->dragging_position = E_MEETING_TIME_SELECTOR_POS_NONE; - e_meeting_time_selector_remove_timeout (mts); - gnome_canvas_item_ungrab (GNOME_CANVAS_ITEM (mts_item), - event->button.time); - } - - return FALSE; -} - - -/* This handles all motion notify events for the item. If button1 is pressed - we check if a drag is in progress. If not, we set the cursor if we are over - the meeting time vertical bars. Note that GnomeCanvas doesn't use motion - hints, which may affect performance. */ -static gint -e_meeting_time_selector_item_motion_notify (EMeetingTimeSelectorItem *mts_item, - GdkEvent *event) -{ - EMeetingTimeSelector *mts; - EMeetingTimeSelectorPosition position; - GdkCursor *cursor; - gint x, y; - - mts = mts_item->mts; - x = (gint) event->motion.x; - y = (gint) event->motion.y; - - if (mts->dragging_position != E_MEETING_TIME_SELECTOR_POS_NONE) { - e_meeting_time_selector_drag_meeting_time (mts, x); - return TRUE; - } - - position = e_meeting_time_selector_item_get_drag_position (mts_item, - x, y); - - /* Determine which cursor should be used. */ - if (position == E_MEETING_TIME_SELECTOR_POS_NONE) - cursor = mts_item->normal_cursor; - else - cursor = mts_item->resize_cursor; - - /* Only set the cursor if it is different to the last one we set. */ - if (mts_item->last_cursor_set != cursor) { - mts_item->last_cursor_set = cursor; - gdk_window_set_cursor (GTK_WIDGET (GNOME_CANVAS_ITEM (mts_item)->canvas)->window, cursor); - } - - return FALSE; -} - - -static EMeetingTimeSelectorPosition -e_meeting_time_selector_item_get_drag_position (EMeetingTimeSelectorItem *mts_item, - gint x, gint y) -{ - EMeetingTimeSelector *mts; - gboolean is_display_top; - gint meeting_start_x, meeting_end_x; - - mts = mts_item->mts; - - is_display_top = (GTK_WIDGET (GNOME_CANVAS_ITEM (mts_item)->canvas) == mts->display_top) ? TRUE : FALSE; - - if (is_display_top && y < mts->row_height * 2) - return E_MEETING_TIME_SELECTOR_POS_NONE; - - if (!e_meeting_time_selector_get_meeting_time_positions (mts, &meeting_start_x, &meeting_end_x)) - return E_MEETING_TIME_SELECTOR_POS_NONE; - - if (x >= meeting_end_x - 2 && x <= meeting_end_x + 2) - return E_MEETING_TIME_SELECTOR_POS_END; - - if (x >= meeting_start_x - 2 && x <= meeting_start_x + 2) - return E_MEETING_TIME_SELECTOR_POS_START; - - return E_MEETING_TIME_SELECTOR_POS_NONE; -} - - -static gboolean -e_meeting_time_selector_item_calculate_busy_range (EMeetingTimeSelector *mts, - gint row, - gint x, - gint width, - gint *start_x, - gint *end_x) -{ - EMeetingAttendee *ia; - EMeetingTime busy_periods_start; - EMeetingTime busy_periods_end; - - ia = e_meeting_model_find_attendee_at_row (mts->model, row); - busy_periods_start = e_meeting_attendee_get_start_busy_range (ia); - busy_periods_end = e_meeting_attendee_get_end_busy_range (ia); - - *start_x = -1; - *end_x = -1; - - if (!g_date_valid (&busy_periods_start.date) - || !g_date_valid (&busy_periods_end.date)) - return FALSE; - - *start_x = e_meeting_time_selector_calculate_time_position (mts, &busy_periods_start) - x - 1; - - *end_x = e_meeting_time_selector_calculate_time_position (mts, &busy_periods_end) - x; - - return TRUE; -} diff --git a/calendar/gui/e-meeting-time-sel-item.h b/calendar/gui/e-meeting-time-sel-item.h deleted file mode 100644 index 11b355dfa0..0000000000 --- a/calendar/gui/e-meeting-time-sel-item.h +++ /dev/null @@ -1,78 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@gtk.org> - * - * Copyright 1999, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -/* - * MeetingTimeSelectorItem - A GnomeCanvasItem which is used for both the main - * display canvas and the top display (with the dates, times & All Attendees). - * I didn't make these separate GnomeCanvasItems since they share a lot of - * code. - */ - -#ifndef _E_MEETING_TIME_SELECTOR_ITEM_H_ -#define _E_MEETING_TIME_SELECTOR_ITEM_H_ - -#include "e-meeting-time-sel.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -#define E_MEETING_TIME_SELECTOR_ITEM(obj) (GTK_CHECK_CAST((obj), e_meeting_time_selector_item_get_type (), EMeetingTimeSelectorItem)) -#define E_MEETING_TIME_SELECTOR_ITEM_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), e_meeting_time_selector_item_get_type (), EMeetingTimeSelectorItemClass)) -#define IS_E_MEETING_TIME_SELECTOR_ITEM(o) (GTK_CHECK_TYPE((o), e_meeting_time_selector_item_get_type ())) - - -typedef struct _EMeetingTimeSelectorItem EMeetingTimeSelectorItem; -typedef struct _EMeetingTimeSelectorItemClass EMeetingTimeSelectorItemClass; - -struct _EMeetingTimeSelectorItem -{ - GnomeCanvasItem canvas_item; - - /* The parent EMeetingTimeSelector widget. */ - EMeetingTimeSelector *mts; - - /* This GC is used for most of the drawing. The fg/bg colors are - changed for each bit. */ - GdkGC *main_gc; - GdkGC *stipple_gc; - - /* The normal & resize cursors. */ - GdkCursor *normal_cursor; - GdkCursor *resize_cursor; - - /* This remembers the last cursor set on the window. */ - GdkCursor *last_cursor_set; -}; - - -struct _EMeetingTimeSelectorItemClass -{ - GnomeCanvasItemClass parent_class; -}; - -GtkType e_meeting_time_selector_item_get_type (void); - - -#endif /* _E_MEETING_TIME_SELECTOR_ITEM_H_ */ diff --git a/calendar/gui/e-meeting-time-sel.c b/calendar/gui/e-meeting-time-sel.c deleted file mode 100644 index 50ba2af777..0000000000 --- a/calendar/gui/e-meeting-time-sel.c +++ /dev/null @@ -1,2884 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@gtk.org> - * - * Copyright 1999, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-meeting-time-sel.h" - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <time.h> -#include <glib.h> -#include <gdk/gdkkeysyms.h> -#include <gtk/gtkalignment.h> -#include <gtk/gtkarrow.h> -#include <gtk/gtkbutton.h> -#include <gtk/gtkdrawingarea.h> -#include <gtk/gtkentry.h> -#include <gtk/gtkfixed.h> -#include <gtk/gtkhbox.h> -#include <gtk/gtkhscrollbar.h> -#include <gtk/gtkhseparator.h> -#include <gtk/gtklabel.h> -#include <gtk/gtkmenu.h> -#include <gtk/gtkradiomenuitem.h> -#include <gtk/gtksignal.h> -#include <gtk/gtkvbox.h> -#include <gtk/gtkvscrollbar.h> -#include <libgnomeui/gnome-dateedit.h> -#include <libgnome/gnome-i18n.h> -#include <libgnomeui/gnome-canvas-widget.h> - -#include <gal/widgets/e-canvas.h> -#include <gal/widgets/e-canvas-utils.h> -#include <gal/widgets/e-font.h> -#include <gal/e-table/e-cell-combo.h> -#include <gal/e-table/e-cell-text.h> -#include <gal/e-table/e-table-simple.h> -#include <gal/e-table/e-table-scrolled.h> -#include <gal/e-table/e-table-header-item.h> -#include <gal/e-table/e-table-header-utils.h> - -#include <widgets/misc/e-dateedit.h> -#include "component-factory.h" -#include "calendar-config.h" -#include "e-meeting-utils.h" -#include "e-meeting-time-sel-item.h" - -/* An array of hour strings for 24 hour time, "0:00" .. "23:00". */ -const gchar *EMeetingTimeSelectorHours[24] = { - "0:00", "1:00", "2:00", "3:00", "4:00", "5:00", "6:00", "7:00", - "8:00", "9:00", "10:00", "11:00", "12:00", "13:00", "14:00", "15:00", - "16:00", "17:00", "18:00", "19:00", "20:00", "21:00", "22:00", "23:00" -}; - -/* An array of hour strings for 12 hour time, "12:00am" .. "11:00pm". */ -const gchar *EMeetingTimeSelectorHours12[24] = { - "12:00am", "1:00am", "2:00am", "3:00am", "4:00am", "5:00am", "6:00am", - "7:00am", "8:00am", "9:00am", "10:00am", "11:00am", "12:00pm", - "1:00pm", "2:00pm", "3:00pm", "4:00pm", "5:00pm", "6:00pm", "7:00pm", - "8:00pm", "9:00pm", "10:00pm", "11:00pm" -}; - -/* The number of days shown in the entire canvas. */ -#define E_MEETING_TIME_SELECTOR_DAYS_SHOWN 365 -#define E_MEETING_TIME_SELECTOR_DAYS_START_BEFORE 60 -#define E_MEETING_TIME_SELECTOR_FB_DAYS_BEFORE 7 -#define E_MEETING_TIME_SELECTOR_FB_DAYS_AFTER 28 - -/* This is the number of pixels between the mouse has to move before the - scroll speed is incremented. */ -#define E_MEETING_TIME_SELECTOR_SCROLL_INCREMENT_WIDTH 10 - -/* This is the maximum scrolling speed. */ -#define E_MEETING_TIME_SELECTOR_MAX_SCROLL_SPEED 4 - -/* Signals */ -enum { - CHANGED, - LAST_SIGNAL -}; - - -static gint mts_signals [LAST_SIGNAL] = { 0 }; - -static void e_meeting_time_selector_class_init (EMeetingTimeSelectorClass * klass); -static void e_meeting_time_selector_init (EMeetingTimeSelector * mts); -static void e_meeting_time_selector_destroy (GtkObject *object); -static void e_meeting_time_selector_alloc_named_color (EMeetingTimeSelector * mts, - const char *name, GdkColor *c); -static void e_meeting_time_selector_add_key_color (EMeetingTimeSelector * mts, - GtkWidget *hbox, - gchar *label_text, - GdkColor *color); -static gint e_meeting_time_selector_expose_key_color (GtkWidget *darea, - GdkEventExpose *event, - GdkColor *color); -static void e_meeting_time_selector_options_menu_detacher (GtkWidget *widget, - GtkMenu *menu); -static void e_meeting_time_selector_autopick_menu_detacher (GtkWidget *widget, - GtkMenu *menu); -static void e_meeting_time_selector_realize (GtkWidget *widget); -static void e_meeting_time_selector_unrealize (GtkWidget *widget); -static void e_meeting_time_selector_style_set (GtkWidget *widget, - GtkStyle *previous_style); -static gint e_meeting_time_selector_expose_event (GtkWidget *widget, - GdkEventExpose *event); -static void e_meeting_time_selector_draw (GtkWidget *widget, - GdkRectangle *area); -static void e_meeting_time_selector_draw_shadow (EMeetingTimeSelector *mts); -static void e_meeting_time_selector_hadjustment_changed (GtkAdjustment *adjustment, - EMeetingTimeSelector *mts); -static void e_meeting_time_selector_vadjustment_changed (GtkAdjustment *adjustment, - EMeetingTimeSelector *mts); -static void e_meeting_time_selector_table_vadjustment_changed (GtkAdjustment *adjustment, - EMeetingTimeSelector *mts); - -static void e_meeting_time_selector_on_canvas_realized (GtkWidget *widget, - EMeetingTimeSelector *mts); - -static void e_meeting_time_selector_on_options_button_clicked (GtkWidget *button, - EMeetingTimeSelector *mts); -static void e_meeting_time_selector_options_menu_position_callback (GtkMenu *menu, - gint *x, - gint *y, - gpointer user_data); -static void e_meeting_time_selector_on_zoomed_out_toggled (GtkWidget *button, - EMeetingTimeSelector *mts); -static void e_meeting_time_selector_on_working_hours_toggled (GtkWidget *button, - EMeetingTimeSelector *mts); -static void e_meeting_time_selector_on_invite_others_button_clicked (GtkWidget *button, - EMeetingTimeSelector *mts); -static void e_meeting_time_selector_on_update_free_busy (GtkWidget *button, - EMeetingTimeSelector *mts); -static void e_meeting_time_selector_on_autopick_button_clicked (GtkWidget *button, - EMeetingTimeSelector *mts); -static void e_meeting_time_selector_autopick_menu_position_callback (GtkMenu *menu, - gint *x, - gint *y, - gpointer user_data); -static void e_meeting_time_selector_on_autopick_option_toggled (GtkWidget *button, - EMeetingTimeSelector *mts); -static void e_meeting_time_selector_on_prev_button_clicked (GtkWidget *button, - EMeetingTimeSelector *mts); -static void e_meeting_time_selector_on_next_button_clicked (GtkWidget *button, - EMeetingTimeSelector *mts); -static void e_meeting_time_selector_autopick (EMeetingTimeSelector *mts, - gboolean forward); -static void e_meeting_time_selector_calculate_time_difference (EMeetingTime*start, - EMeetingTime*end, - gint *days, - gint *hours, - gint *minutes); -static void e_meeting_time_selector_find_nearest_interval (EMeetingTimeSelector *mts, - EMeetingTime*start_time, - EMeetingTime*end_time, - gint days, gint hours, gint mins); -static void e_meeting_time_selector_find_nearest_interval_backward (EMeetingTimeSelector *mts, - EMeetingTime *start_time, - EMeetingTime *end_time, - gint days, gint hours, gint mins); -static void e_meeting_time_selector_adjust_time (EMeetingTime*mtstime, - gint days, gint hours, gint minutes); -static EMeetingFreeBusyPeriod* e_meeting_time_selector_find_time_clash (EMeetingTimeSelector *mts, - EMeetingAttendee *attendee, - EMeetingTime *start_time, - EMeetingTime *end_time); - - -static void e_meeting_time_selector_recalc_grid (EMeetingTimeSelector *mts); -static void e_meeting_time_selector_recalc_date_format (EMeetingTimeSelector *mts); -static void e_meeting_time_selector_save_position (EMeetingTimeSelector *mts, - EMeetingTime *mtstime); -static void e_meeting_time_selector_restore_position (EMeetingTimeSelector *mts, - EMeetingTime*mtstime); -static void e_meeting_time_selector_on_start_time_changed (GtkWidget *widget, - EMeetingTimeSelector *mts); -static void e_meeting_time_selector_on_end_time_changed (GtkWidget *widget, - EMeetingTimeSelector *mts); -static void e_meeting_time_selector_update_date_popup_menus (EMeetingTimeSelector *mts); -static void e_meeting_time_selector_on_canvas_size_allocate (GtkWidget *widget, - GtkAllocation *allocation, - EMeetingTimeSelector *mts); -static void e_meeting_time_selector_update_main_canvas_scroll_region (EMeetingTimeSelector *mts); -static gboolean e_meeting_time_selector_timeout_handler (gpointer data); -static void e_meeting_time_selector_update_start_date_edit (EMeetingTimeSelector *mts); -static void e_meeting_time_selector_update_end_date_edit (EMeetingTimeSelector *mts); -static void e_meeting_time_selector_ensure_meeting_time_shown (EMeetingTimeSelector *mts); -static void e_meeting_time_selector_update_dates_shown (EMeetingTimeSelector *mts); - -static void rows_inserted_cb (ETableModel *etm, int row, int count, gpointer data); -static void cell_changed_cb (ETableModel *etm, int row, int col, gpointer data); -static void rows_deleted_cb (ETableModel *etm, int row, int count, gpointer data); -static void sort_info_changed_cb (ETableSortInfo *info, gpointer data); - -static GtkTableClass *parent_class; - - -GtkType -e_meeting_time_selector_get_type (void) -{ - static guint e_meeting_time_selector_type = 0; - - if (!e_meeting_time_selector_type) { - GtkTypeInfo e_meeting_time_selector_info = - { - "EMeetingTimeSelector", - sizeof (EMeetingTimeSelector), - sizeof (EMeetingTimeSelectorClass), - (GtkClassInitFunc) e_meeting_time_selector_class_init, - (GtkObjectInitFunc) e_meeting_time_selector_init, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - e_meeting_time_selector_type = gtk_type_unique (GTK_TYPE_TABLE, - &e_meeting_time_selector_info); - } - return e_meeting_time_selector_type; -} - - -static void -e_meeting_time_selector_class_init (EMeetingTimeSelectorClass * klass) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - - parent_class = gtk_type_class (gtk_table_get_type()); - object_class = (GtkObjectClass *) klass; - widget_class = (GtkWidgetClass *) klass; - - mts_signals [CHANGED] = - gtk_signal_new ("changed", GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (EMeetingTimeSelectorClass, - changed), - gtk_signal_default_marshaller, - GTK_TYPE_NONE, 0); - - gtk_object_class_add_signals (object_class, mts_signals, - LAST_SIGNAL); - - object_class->destroy = e_meeting_time_selector_destroy; - - widget_class->realize = e_meeting_time_selector_realize; - widget_class->unrealize = e_meeting_time_selector_unrealize; - widget_class->style_set = e_meeting_time_selector_style_set; - widget_class->expose_event = e_meeting_time_selector_expose_event; - widget_class->draw = e_meeting_time_selector_draw; -} - - -static void -e_meeting_time_selector_init (EMeetingTimeSelector * mts) -{ - /* The shadow is drawn in the border so it must be >= 2 pixels. */ - gtk_container_set_border_width (GTK_CONTAINER (mts), 2); - - mts->accel_group = gtk_accel_group_new (); - - mts->working_hours_only = TRUE; - mts->day_start_hour = 9; - mts->day_start_minute = 0; - mts->day_end_hour = 18; - mts->day_end_minute = 0; - mts->zoomed_out = TRUE; - mts->dragging_position = E_MEETING_TIME_SELECTOR_POS_NONE; - - mts->etable = NULL; -} - - -void -e_meeting_time_selector_construct (EMeetingTimeSelector * mts, EMeetingModel *emm) -{ - GtkWidget *hbox, *vbox, *separator, *button, *label, *table; - GtkWidget *alignment, *child_hbox, *arrow, *menuitem; - GSList *group; - GdkVisual *visual; - GdkColormap *colormap; - guint accel_key; - GtkAccelGroup *menu_accel_group; - time_t meeting_start_time; - struct tm *meeting_start_tm; - char *filename; - ETable *real_table; - guchar stipple_bits[] = { - 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, - }; - - /* The default meeting time is the nearest half-hour interval in the - future, in working hours. */ - meeting_start_time = time (NULL); - g_date_clear (&mts->meeting_start_time.date, 1); - g_date_set_time (&mts->meeting_start_time.date, meeting_start_time); - meeting_start_tm = localtime (&meeting_start_time); - mts->meeting_start_time.hour = meeting_start_tm->tm_hour; - mts->meeting_start_time.minute = meeting_start_tm->tm_min; - - e_meeting_time_selector_find_nearest_interval (mts, &mts->meeting_start_time, - &mts->meeting_end_time, - 0, 0, 30); - - e_meeting_time_selector_update_dates_shown (mts); - - mts->meeting_positions_valid = FALSE; - - mts->row_height = 19; - mts->col_width = 55; - mts->day_width = 55 * 24 + 1; - - mts->auto_scroll_timeout_id = 0; - - vbox = gtk_vbox_new (FALSE, 0); - gtk_table_attach (GTK_TABLE (mts), - vbox, 0, 1, 0, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); - gtk_widget_show (vbox); - - mts->attendees_vbox_spacer = gtk_vbox_new (FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), mts->attendees_vbox_spacer, FALSE, FALSE, 0); - gtk_widget_show (mts->attendees_vbox_spacer); - - mts->attendees_vbox = gtk_vbox_new (FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), mts->attendees_vbox, TRUE, TRUE, 0); - gtk_widget_show (mts->attendees_vbox); - - /* build the etable */ - filename = g_strdup_printf ("%s/config/et-header-meeting-time-sel", evolution_dir); - mts->model = emm; - if (mts->model) - gtk_object_ref (GTK_OBJECT (mts->model)); - - gtk_signal_connect (GTK_OBJECT (mts->model), "model_rows_inserted", - GTK_SIGNAL_FUNC (rows_inserted_cb), mts); - gtk_signal_connect (GTK_OBJECT (mts->model), "model_cell_changed", - GTK_SIGNAL_FUNC (cell_changed_cb), mts); - gtk_signal_connect (GTK_OBJECT (mts->model), "model_rows_deleted", - GTK_SIGNAL_FUNC (rows_deleted_cb), mts); - - mts->etable = GTK_WIDGET (e_meeting_model_etable_from_model (mts->model, - EVOLUTION_ETSPECDIR "/e-meeting-time-sel.etspec", - filename)); - e_scroll_frame_set_policy (E_SCROLL_FRAME (mts->etable), GTK_POLICY_NEVER, GTK_POLICY_NEVER); - e_scroll_frame_set_scrollbar_spacing (E_SCROLL_FRAME (mts->etable), 0); - - real_table = e_table_scrolled_get_table (E_TABLE_SCROLLED (mts->etable)); - gtk_signal_connect (GTK_OBJECT (real_table->sort_info), "sort_info_changed", - GTK_SIGNAL_FUNC (sort_info_changed_cb), mts); - - gtk_box_pack_start (GTK_BOX (mts->attendees_vbox), mts->etable, TRUE, TRUE, 2); - gtk_widget_show (mts->etable); - g_free (filename); - - /* The free/busy information */ - mts->display_top = gnome_canvas_new (); - gtk_widget_set_usize (mts->display_top, -1, mts->row_height * 3); - gnome_canvas_set_scroll_region (GNOME_CANVAS (mts->display_top), - 0, 0, - mts->day_width * E_MEETING_TIME_SELECTOR_DAYS_SHOWN, - mts->row_height * 3); - /* Add some horizontal padding for the shadow around the display. */ - gtk_table_attach (GTK_TABLE (mts), mts->display_top, - 1, 4, 0, 1, GTK_EXPAND | GTK_FILL, 0, 0, 0); - gtk_widget_show (mts->display_top); - gtk_signal_connect (GTK_OBJECT (mts->display_top), "realize", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_canvas_realized), mts); - - mts->display_main = gnome_canvas_new (); - e_meeting_time_selector_update_main_canvas_scroll_region (mts); - /* Add some horizontal padding for the shadow around the display. */ - gtk_table_attach (GTK_TABLE (mts), mts->display_main, - 1, 4, 1, 2, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - gtk_widget_show (mts->display_main); - gtk_signal_connect (GTK_OBJECT (mts->display_main), "realize", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_canvas_realized), mts); - gtk_signal_connect (GTK_OBJECT (mts->display_main), "size_allocate", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_canvas_size_allocate), mts); - - mts->hscrollbar = gtk_hscrollbar_new (GTK_LAYOUT (mts->display_main)->hadjustment); - GTK_LAYOUT (mts->display_main)->hadjustment->step_increment = mts->col_width; - gtk_table_attach (GTK_TABLE (mts), mts->hscrollbar, - 1, 4, 2, 3, GTK_EXPAND | GTK_FILL, 0, 0, 0); - gtk_widget_show (mts->hscrollbar); - - mts->vscrollbar = gtk_vscrollbar_new (GTK_LAYOUT (mts->display_main)->vadjustment); - GTK_LAYOUT (mts->display_main)->vadjustment->step_increment = mts->row_height; - gtk_table_attach (GTK_TABLE (mts), mts->vscrollbar, - 4, 5, 1, 2, 0, GTK_EXPAND | GTK_FILL, 0, 0); - gtk_widget_show (mts->vscrollbar); - - /* Create the item in the top canvas. */ - gnome_canvas_item_new (GNOME_CANVAS_GROUP (GNOME_CANVAS (mts->display_top)->root), - e_meeting_time_selector_item_get_type (), - "EMeetingTimeSelectorItem::meeting_time_selector", mts, - NULL); - - /* Create the item in the main canvas. */ - gnome_canvas_item_new (GNOME_CANVAS_GROUP (GNOME_CANVAS (mts->display_main)->root), - e_meeting_time_selector_item_get_type (), - "EMeetingTimeSelectorItem::meeting_time_selector", mts, - NULL); - - /* Create the hbox containing the color key. */ - hbox = gtk_hbox_new (FALSE, 2); - gtk_table_attach (GTK_TABLE (mts), hbox, - 1, 4, 3, 4, GTK_FILL, 0, 0, 8); - gtk_widget_show (hbox); - - e_meeting_time_selector_add_key_color (mts, hbox, _("Tentative"), &mts->busy_colors[E_MEETING_FREE_BUSY_TENTATIVE]); - e_meeting_time_selector_add_key_color (mts, hbox, _("Busy"), &mts->busy_colors[E_MEETING_FREE_BUSY_BUSY]); - e_meeting_time_selector_add_key_color (mts, hbox, _("Out of Office"), &mts->busy_colors[E_MEETING_FREE_BUSY_OUT_OF_OFFICE]); - e_meeting_time_selector_add_key_color (mts, hbox, _("No Information"), - NULL); - - separator = gtk_hseparator_new (); - gtk_table_attach (GTK_TABLE (mts), separator, - 0, 5, 4, 5, GTK_FILL, 0, 0, 0); - gtk_widget_show (separator); - - /* Create the Invite Others & Options buttons on the left. */ - hbox = gtk_hbox_new (FALSE, 4); - gtk_table_attach (GTK_TABLE (mts), hbox, - 0, 1, 3, 4, GTK_FILL, 0, 0, 0); - gtk_widget_show (hbox); - - button = gtk_button_new_with_label (""); - accel_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (button)->child), - _("_Invite Others...")); - gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); - gtk_widget_show (button); - gtk_widget_add_accelerator (button, "clicked", mts->accel_group, - accel_key, GDK_MOD1_MASK, 0); - gtk_signal_connect (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_invite_others_button_clicked), mts); - - mts->options_button = gtk_button_new (); - gtk_box_pack_start (GTK_BOX (hbox), mts->options_button, TRUE, TRUE, 0); - gtk_widget_show (mts->options_button); - - gtk_signal_connect (GTK_OBJECT (mts->options_button), "clicked", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_options_button_clicked), mts); - - child_hbox = gtk_hbox_new (FALSE, 2); - gtk_container_add (GTK_CONTAINER (mts->options_button), child_hbox); - gtk_widget_show (child_hbox); - - label = gtk_label_new (""); - accel_key = gtk_label_parse_uline (GTK_LABEL (label), _("_Options")); - gtk_box_pack_start (GTK_BOX (child_hbox), label, TRUE, TRUE, 0); - gtk_widget_show (label); - gtk_widget_add_accelerator (mts->options_button, "clicked", mts->accel_group, - accel_key, GDK_MOD1_MASK, 0); - - arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT); - gtk_box_pack_start (GTK_BOX (child_hbox), arrow, FALSE, FALSE, 2); - gtk_widget_show (arrow); - - /* Create the Options menu. */ - mts->options_menu = gtk_menu_new (); - gtk_menu_attach_to_widget (GTK_MENU (mts->options_menu), mts->options_button, - e_meeting_time_selector_options_menu_detacher); - menu_accel_group = gtk_menu_ensure_uline_accel_group (GTK_MENU (mts->options_menu)); - - menuitem = gtk_check_menu_item_new_with_label (""); - accel_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (menuitem)->child), _("Show _Only Working Hours")); - gtk_menu_append (GTK_MENU (mts->options_menu), menuitem); - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem), - mts->working_hours_only); - gtk_widget_add_accelerator (menuitem, "activate", menu_accel_group, - accel_key, 0, 0); - gtk_widget_add_accelerator (menuitem, "activate", menu_accel_group, - accel_key, GDK_MOD1_MASK, 0); - gtk_signal_connect (GTK_OBJECT (menuitem), "toggled", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_working_hours_toggled), mts); - gtk_widget_show (menuitem); - - menuitem = gtk_check_menu_item_new_with_label (""); - accel_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (menuitem)->child), _("Show _Zoomed Out")); - gtk_menu_append (GTK_MENU (mts->options_menu), menuitem); - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem), - mts->zoomed_out); - gtk_widget_add_accelerator (menuitem, "activate", menu_accel_group, - accel_key, 0, 0); - gtk_widget_add_accelerator (menuitem, "activate", menu_accel_group, - accel_key, GDK_MOD1_MASK, 0); - gtk_signal_connect (GTK_OBJECT (menuitem), "toggled", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_zoomed_out_toggled), mts); - gtk_widget_show (menuitem); - - menuitem = gtk_menu_item_new (); - gtk_menu_append (GTK_MENU (mts->options_menu), menuitem); - gtk_widget_set_sensitive (menuitem, FALSE); - gtk_widget_show (menuitem); - - menuitem = gtk_menu_item_new_with_label (""); - accel_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (menuitem)->child), _("_Update Free/Busy")); - gtk_menu_append (GTK_MENU (mts->options_menu), menuitem); - gtk_widget_add_accelerator (menuitem, "activate", menu_accel_group, - accel_key, 0, 0); - gtk_widget_add_accelerator (menuitem, "activate", menu_accel_group, - accel_key, GDK_MOD1_MASK, 0); - gtk_signal_connect (GTK_OBJECT (menuitem), "activate", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_update_free_busy), mts); - gtk_widget_show (menuitem); - - /* Create the 3 AutoPick buttons on the left. */ - hbox = gtk_hbox_new (FALSE, 0); - gtk_table_attach (GTK_TABLE (mts), hbox, - 0, 1, 5, 6, GTK_FILL, 0, 0, 0); - gtk_widget_show (hbox); - - button = gtk_button_new_with_label (""); - accel_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (button)->child), - _("_<<")); - gtk_widget_add_accelerator (button, "clicked", mts->accel_group, - accel_key, GDK_MOD1_MASK | GDK_SHIFT_MASK, 0); - gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); - gtk_widget_show (button); - gtk_signal_connect (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_prev_button_clicked), mts); - - mts->autopick_button = gtk_button_new (); - gtk_box_pack_start (GTK_BOX (hbox), mts->autopick_button, TRUE, TRUE, 0); - gtk_widget_show (mts->autopick_button); - - child_hbox = gtk_hbox_new (FALSE, 2); - gtk_container_add (GTK_CONTAINER (mts->autopick_button), child_hbox); - gtk_widget_show (child_hbox); - - label = gtk_label_new (""); - accel_key = gtk_label_parse_uline (GTK_LABEL (label), _("_Autopick")); - gtk_box_pack_start (GTK_BOX (child_hbox), label, TRUE, TRUE, 0); - gtk_widget_show (label); - gtk_widget_add_accelerator (mts->autopick_button, "clicked", mts->accel_group, - accel_key, GDK_MOD1_MASK, 0); - gtk_signal_connect (GTK_OBJECT (mts->autopick_button), "clicked", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_autopick_button_clicked), mts); - - arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT); - gtk_box_pack_start (GTK_BOX (child_hbox), arrow, FALSE, FALSE, 2); - gtk_widget_show (arrow); - - button = gtk_button_new_with_label (""); - accel_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (button)->child), - _(">_>")); - gtk_widget_add_accelerator (button, "clicked", mts->accel_group, - accel_key, GDK_MOD1_MASK | GDK_SHIFT_MASK, 0); - gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); - gtk_widget_show (button); - gtk_signal_connect (GTK_OBJECT (button), "clicked", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_next_button_clicked), mts); - - /* Create the Autopick menu. */ - mts->autopick_menu = gtk_menu_new (); - gtk_menu_attach_to_widget (GTK_MENU (mts->autopick_menu), mts->autopick_button, - e_meeting_time_selector_autopick_menu_detacher); - menu_accel_group = gtk_menu_ensure_uline_accel_group (GTK_MENU (mts->autopick_menu)); - - menuitem = gtk_radio_menu_item_new_with_label (NULL, ""); - mts->autopick_all_item = menuitem; - group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem)); - accel_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (menuitem)->child), _("_All People and Resources")); - gtk_menu_append (GTK_MENU (mts->autopick_menu), menuitem); - gtk_widget_add_accelerator (menuitem, "activate", menu_accel_group, - accel_key, 0, 0); - gtk_widget_add_accelerator (menuitem, "activate", menu_accel_group, - accel_key, GDK_MOD1_MASK, 0); - gtk_signal_connect (GTK_OBJECT (menuitem), "toggled", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_autopick_option_toggled), mts); - gtk_widget_show (menuitem); - - menuitem = gtk_radio_menu_item_new_with_label (group, ""); - mts->autopick_all_people_one_resource_item = menuitem; - group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem)); - accel_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (menuitem)->child), _("All _People and One Resource")); - gtk_menu_append (GTK_MENU (mts->autopick_menu), menuitem); - gtk_widget_add_accelerator (menuitem, "activate", menu_accel_group, - accel_key, 0, 0); - gtk_widget_add_accelerator (menuitem, "activate", menu_accel_group, - accel_key, GDK_MOD1_MASK, 0); - gtk_signal_connect (GTK_OBJECT (menuitem), "toggled", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_autopick_option_toggled), mts); - gtk_widget_show (menuitem); - - menuitem = gtk_radio_menu_item_new_with_label (group, ""); - mts->autopick_required_people_item = menuitem; - group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem)); - accel_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (menuitem)->child), _("_Required People")); - gtk_menu_append (GTK_MENU (mts->autopick_menu), menuitem); - gtk_widget_add_accelerator (menuitem, "activate", menu_accel_group, - accel_key, 0, 0); - gtk_widget_add_accelerator (menuitem, "activate", menu_accel_group, - accel_key, GDK_MOD1_MASK, 0); - gtk_signal_connect (GTK_OBJECT (menuitem), "activate", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_autopick_option_toggled), mts); - gtk_widget_show (menuitem); - - menuitem = gtk_radio_menu_item_new_with_label (group, ""); - mts->autopick_required_people_one_resource_item = menuitem; - group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem)); - accel_key = gtk_label_parse_uline (GTK_LABEL (GTK_BIN (menuitem)->child), _("Required People and _One Resource")); - gtk_menu_append (GTK_MENU (mts->autopick_menu), menuitem); - gtk_widget_add_accelerator (menuitem, "activate", menu_accel_group, - accel_key, 0, 0); - gtk_widget_add_accelerator (menuitem, "activate", menu_accel_group, - accel_key, GDK_MOD1_MASK, 0); - gtk_signal_connect (GTK_OBJECT (menuitem), "activate", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_autopick_option_toggled), mts); - gtk_widget_show (menuitem); - - /* Create the date entry fields on the right. */ - alignment = gtk_alignment_new (0.0, 0.5, 0, 0); - gtk_table_attach (GTK_TABLE (mts), alignment, - 1, 4, 5, 6, GTK_FILL, 0, 0, 0); - gtk_widget_show (alignment); - - table = gtk_table_new (2, 2, FALSE); - gtk_table_set_row_spacings (GTK_TABLE (table), 4); - gtk_container_add (GTK_CONTAINER (alignment), table); - gtk_widget_show (table); - - label = gtk_label_new (""); - accel_key = gtk_label_parse_uline (GTK_LABEL (label), - _("Meeting _start time:")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_table_attach (GTK_TABLE (table), label, - 0, 1, 0, 1, GTK_FILL, 0, 4, 0); - gtk_widget_show (label); - - mts->start_date_edit = e_date_edit_new (); - e_date_edit_set_show_time (E_DATE_EDIT (mts->start_date_edit), TRUE); - e_date_edit_set_use_24_hour_format (E_DATE_EDIT (mts->start_date_edit), - calendar_config_get_24_hour_format ()); - - gtk_table_attach (GTK_TABLE (table), mts->start_date_edit, - 1, 2, 0, 1, GTK_FILL, 0, 0, 0); - gtk_widget_show (mts->start_date_edit); - gtk_signal_connect (GTK_OBJECT (mts->start_date_edit), "changed", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_start_time_changed), mts); - - label = gtk_label_new (""); - accel_key = gtk_label_parse_uline (GTK_LABEL (label), - _("Meeting _end time:")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_table_attach (GTK_TABLE (table), label, - 0, 1, 1, 2, GTK_FILL, 0, 4, 0); - gtk_widget_show (label); - - mts->end_date_edit = e_date_edit_new (); - e_date_edit_set_show_time (E_DATE_EDIT (mts->end_date_edit), TRUE); - e_date_edit_set_use_24_hour_format (E_DATE_EDIT (mts->end_date_edit), - calendar_config_get_24_hour_format ()); - - gtk_table_attach (GTK_TABLE (table), mts->end_date_edit, - 1, 2, 1, 2, GTK_FILL, 0, 0, 0); - gtk_widget_show (mts->end_date_edit); - gtk_signal_connect (GTK_OBJECT (mts->end_date_edit), "changed", - GTK_SIGNAL_FUNC (e_meeting_time_selector_on_end_time_changed), mts); - - gtk_table_set_col_spacing (GTK_TABLE (mts), 0, 4); - gtk_table_set_row_spacing (GTK_TABLE (mts), 4, 12); - - /* Allocate the colors. */ - visual = gtk_widget_get_visual (GTK_WIDGET (mts)); - colormap = gtk_widget_get_colormap (GTK_WIDGET (mts)); - mts->color_context = gdk_color_context_new (visual, colormap); - e_meeting_time_selector_alloc_named_color (mts, "gray75", &mts->bg_color); - e_meeting_time_selector_alloc_named_color (mts, "gray50", &mts->all_attendees_bg_color); - gdk_color_black (colormap, &mts->grid_color); - gdk_color_white (colormap, &mts->grid_shadow_color); - e_meeting_time_selector_alloc_named_color (mts, "gray50", &mts->grid_unused_color); - gdk_color_white (colormap, &mts->meeting_time_bg_color); - gdk_color_white (colormap, &mts->stipple_bg_color); - gdk_color_white (colormap, &mts->attendee_list_bg_color); - - e_meeting_time_selector_alloc_named_color (mts, "LightSkyBlue2", &mts->busy_colors[E_MEETING_FREE_BUSY_TENTATIVE]); - e_meeting_time_selector_alloc_named_color (mts, "blue", &mts->busy_colors[E_MEETING_FREE_BUSY_BUSY]); - e_meeting_time_selector_alloc_named_color (mts, "HotPink3", &mts->busy_colors[E_MEETING_FREE_BUSY_OUT_OF_OFFICE]); - - /* Create the stipple, for attendees with no data. */ - mts->stipple = gdk_bitmap_create_from_data (NULL, (gchar*)stipple_bits, - 8, 8); - - /* Connect handlers to the adjustments scroll the other items. */ - gtk_signal_connect (GTK_OBJECT (GTK_LAYOUT (mts->display_main)->hadjustment), "value_changed", GTK_SIGNAL_FUNC (e_meeting_time_selector_hadjustment_changed), mts); - gtk_signal_connect (GTK_OBJECT (GTK_LAYOUT (mts->display_main)->vadjustment), "value_changed", GTK_SIGNAL_FUNC (e_meeting_time_selector_vadjustment_changed), mts); - gtk_signal_connect (GTK_OBJECT (GTK_LAYOUT (mts->display_main)->vadjustment), "changed", GTK_SIGNAL_FUNC (e_meeting_time_selector_vadjustment_changed), mts); - - gtk_signal_connect (GTK_OBJECT (e_scroll_frame_get_vadjustment (E_SCROLL_FRAME (mts->etable))), "value_changed", GTK_SIGNAL_FUNC (e_meeting_time_selector_table_vadjustment_changed), mts); - gtk_signal_connect (GTK_OBJECT (e_scroll_frame_get_vadjustment (E_SCROLL_FRAME (mts->etable))), "changed", GTK_SIGNAL_FUNC (e_meeting_time_selector_table_vadjustment_changed), mts); - - e_meeting_time_selector_recalc_grid (mts); - e_meeting_time_selector_ensure_meeting_time_shown (mts); - e_meeting_time_selector_update_start_date_edit (mts); - e_meeting_time_selector_update_end_date_edit (mts); - e_meeting_time_selector_update_date_popup_menus (mts); - - gtk_signal_emit (GTK_OBJECT (mts), mts_signals [CHANGED]); -} - - -/* This adds a color to the color key beneath the main display. If color is - NULL, it displays the No Info stipple instead. */ -static void -e_meeting_time_selector_add_key_color (EMeetingTimeSelector * mts, - GtkWidget *hbox, - gchar *label_text, GdkColor *color) -{ - GtkWidget *child_hbox, *darea, *label; - - child_hbox = gtk_hbox_new (FALSE, 4); - gtk_box_pack_start (GTK_BOX (hbox), child_hbox, TRUE, TRUE, 0); - gtk_widget_show (child_hbox); - - darea = gtk_drawing_area_new (); - gtk_box_pack_start (GTK_BOX (child_hbox), darea, FALSE, FALSE, 0); - gtk_object_set_user_data (GTK_OBJECT (darea), mts); - gtk_widget_set_usize (darea, 14, 14); - gtk_widget_show (darea); - - label = gtk_label_new (label_text); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_box_pack_start (GTK_BOX (child_hbox), label, TRUE, TRUE, 0); - gtk_widget_show (label); - - gtk_signal_connect (GTK_OBJECT (darea), "expose_event", - GTK_SIGNAL_FUNC (e_meeting_time_selector_expose_key_color), - color); -} - -static gint -e_meeting_time_selector_expose_key_color (GtkWidget *darea, - GdkEventExpose *event, - GdkColor *color) -{ - EMeetingTimeSelector * mts; - GdkGC *gc; - gint width, height; - - mts = gtk_object_get_user_data (GTK_OBJECT (darea)); - gc = mts->color_key_gc; - width = darea->allocation.width; - height = darea->allocation.height; - - gtk_draw_shadow (darea->style, darea->window, GTK_STATE_NORMAL, - GTK_SHADOW_IN, 0, 0, width, height); - - if (color) { - gdk_gc_set_foreground (gc, color); - gdk_draw_rectangle (darea->window, gc, TRUE, 1, 1, - width - 2, height - 2); - } else { - gdk_gc_set_foreground (gc, &mts->grid_color); - gdk_gc_set_background (gc, &mts->stipple_bg_color); - gdk_gc_set_stipple (gc, mts->stipple); - gdk_gc_set_fill (gc, GDK_OPAQUE_STIPPLED); - gdk_draw_rectangle (darea->window, gc, TRUE, 1, 1, - width - 2, height - 2); - gdk_gc_set_fill (gc, GDK_SOLID); - } - - return TRUE; -} - - -static void -e_meeting_time_selector_alloc_named_color (EMeetingTimeSelector * mts, - const char *name, GdkColor *c) -{ - int failed; - - g_return_if_fail (name != NULL); - g_return_if_fail (c != NULL); - - gdk_color_parse (name, c); - c->pixel = 0; - c->pixel = gdk_color_context_get_pixel (mts->color_context, - c->red, c->green, c->blue, - &failed); - if (failed) - g_warning ("Failed to allocate color: %s\n", name); -} - - -static void -e_meeting_time_selector_options_menu_detacher (GtkWidget *widget, - GtkMenu *menu) -{ - EMeetingTimeSelector *mts; - - g_return_if_fail (widget != NULL); - g_return_if_fail (IS_E_MEETING_TIME_SELECTOR (widget)); - - mts = E_MEETING_TIME_SELECTOR (widget); - g_return_if_fail (mts->options_menu == (GtkWidget*) menu); - - mts->options_menu = NULL; -} - - -static void -e_meeting_time_selector_autopick_menu_detacher (GtkWidget *widget, - GtkMenu *menu) -{ - EMeetingTimeSelector *mts; - - g_return_if_fail (widget != NULL); - g_return_if_fail (IS_E_MEETING_TIME_SELECTOR (widget)); - - mts = E_MEETING_TIME_SELECTOR (widget); - g_return_if_fail (mts->autopick_menu == (GtkWidget*) menu); - - mts->autopick_menu = NULL; -} - - -GtkWidget * -e_meeting_time_selector_new (EMeetingModel *emm) -{ - GtkWidget *mts; - - mts = GTK_WIDGET (gtk_type_new (e_meeting_time_selector_get_type ())); - - e_meeting_time_selector_construct (E_MEETING_TIME_SELECTOR (mts), emm); - - return mts; -} - - -static void -e_meeting_time_selector_destroy (GtkObject *object) -{ - EMeetingTimeSelector *mts; - - mts = E_MEETING_TIME_SELECTOR (object); - - e_meeting_time_selector_remove_timeout (mts); - - gdk_color_context_free (mts->color_context); - gdk_bitmap_unref (mts->stipple); - - if (mts->model) - gtk_object_unref (GTK_OBJECT (mts->model)); - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (*GTK_OBJECT_CLASS (parent_class)->destroy)(object); -} - - -static void -e_meeting_time_selector_realize (GtkWidget *widget) -{ - EMeetingTimeSelector *mts; - - if (GTK_WIDGET_CLASS (parent_class)->realize) - (*GTK_WIDGET_CLASS (parent_class)->realize)(widget); - - mts = E_MEETING_TIME_SELECTOR (widget); - - mts->color_key_gc = gdk_gc_new (widget->window); -} - - -static void -e_meeting_time_selector_unrealize (GtkWidget *widget) -{ - EMeetingTimeSelector *mts; - - mts = E_MEETING_TIME_SELECTOR (widget); - - gdk_gc_unref (mts->color_key_gc); - mts->color_key_gc = NULL; - - if (GTK_WIDGET_CLASS (parent_class)->unrealize) - (*GTK_WIDGET_CLASS (parent_class)->unrealize)(widget); -} - -static void -e_meeting_time_selector_style_set (GtkWidget *widget, - GtkStyle *previous_style) -{ - EMeetingTimeSelector *mts; - EMeetingTime saved_time; - ETable *real_table; - ETableHeader *eth; - GdkFont *font; - EFont *efont; - int hour, max_hour_width; - int numcols, col; - int maxheight; - - if (GTK_WIDGET_CLASS (parent_class)->style_set) - (*GTK_WIDGET_CLASS (parent_class)->style_set)(widget, previous_style); - - mts = E_MEETING_TIME_SELECTOR (widget); - font = widget->style->font; - efont = e_font_from_gdk_font (font); - - /* Calculate the widths of the hour strings in the style's font. */ - max_hour_width = 0; - for (hour = 0; hour < 24; hour++) { - if (calendar_config_get_24_hour_format ()) - mts->hour_widths[hour] = gdk_string_width (font, EMeetingTimeSelectorHours[hour]); - else - mts->hour_widths[hour] = gdk_string_width (font, EMeetingTimeSelectorHours12[hour]); - max_hour_width = MAX (max_hour_width, mts->hour_widths[hour]); - } - - /* FIXME the 5 is for the padding etable adds on */ - mts->row_height = e_font_height (efont) + 5; - mts->col_width = max_hour_width + 6; - - e_font_unref (efont); - - e_meeting_time_selector_save_position (mts, &saved_time); - e_meeting_time_selector_recalc_grid (mts); - e_meeting_time_selector_restore_position (mts, &saved_time); - - gtk_widget_set_usize (mts->display_top, -1, mts->row_height * 3); - - /* Calculate header height */ - real_table = e_table_scrolled_get_table (E_TABLE_SCROLLED (mts->etable)); - eth = real_table->full_header; - numcols = e_table_header_count (eth); - maxheight = 0; - for (col = 0; col < numcols; col++) { - ETableCol *ecol = e_table_header_get_column (eth, col); - int height; - - height = e_table_header_compute_height (ecol, widget->style, font); - - if (height > maxheight) - maxheight = height; - } - /* FIXME the 5 is for the padding etable adds on */ - gtk_widget_set_usize (mts->attendees_vbox_spacer, 1, mts->row_height * 3 - maxheight - 5); - - GTK_LAYOUT (mts->display_main)->hadjustment->step_increment = mts->col_width; - GTK_LAYOUT (mts->display_main)->vadjustment->step_increment = mts->row_height; -} - -/* This draws a shadow around the top display and main display. */ -static gint -e_meeting_time_selector_expose_event (GtkWidget *widget, - GdkEventExpose *event) -{ - EMeetingTimeSelector *mts; - - mts = E_MEETING_TIME_SELECTOR (widget); - - e_meeting_time_selector_draw_shadow (mts); - - if (GTK_WIDGET_CLASS (parent_class)->expose_event) - (*GTK_WIDGET_CLASS (parent_class)->expose_event)(widget, event); - - return FALSE; -} - - -static void -e_meeting_time_selector_draw (GtkWidget *widget, - GdkRectangle *area) -{ - EMeetingTimeSelector *mts; - - mts = E_MEETING_TIME_SELECTOR (widget); - - e_meeting_time_selector_draw_shadow (mts); - - if (GTK_WIDGET_CLASS (parent_class)->draw) - (*GTK_WIDGET_CLASS (parent_class)->draw)(widget, area); -} - - -static void -e_meeting_time_selector_draw_shadow (EMeetingTimeSelector *mts) -{ - GtkWidget *widget; - gint x, y, w, h; - - widget = GTK_WIDGET (mts); - - /* Draw the shadow around the graphical displays. */ - x = mts->display_top->allocation.x - 2; - y = mts->display_top->allocation.y - 2; - w = mts->display_top->allocation.width + 4; - h = mts->display_top->allocation.height + mts->display_main->allocation.height + 4; - - gtk_draw_shadow (widget->style, widget->window, GTK_STATE_NORMAL, - GTK_SHADOW_IN, x, y, w, h); -} - - -/* When the main canvas scrolls, we scroll the other canvases. */ -static void -e_meeting_time_selector_hadjustment_changed (GtkAdjustment *adjustment, - EMeetingTimeSelector *mts) -{ - GtkAdjustment *adj; - - adj = GTK_LAYOUT (mts->display_top)->hadjustment; - if (adj->value != adjustment->value) { - adj->value = adjustment->value; - gtk_adjustment_value_changed (adj); - } -} - - -static void -e_meeting_time_selector_vadjustment_changed (GtkAdjustment *adjustment, - EMeetingTimeSelector *mts) -{ - GtkAdjustment *adj; - - adj = e_scroll_frame_get_vadjustment (E_SCROLL_FRAME (mts->etable)); - if (adj->value != adjustment->value) { - adj->value = adjustment->value; - gtk_adjustment_value_changed (adj); - } -} - -static void -e_meeting_time_selector_table_vadjustment_changed (GtkAdjustment *adjustment, - EMeetingTimeSelector *mts) -{ - GtkAdjustment *adj; - - adj = GTK_LAYOUT (mts->display_main)->vadjustment; - if (adj->value != adjustment->value) { - adj->value = adjustment->value; - gtk_adjustment_value_changed (adj); - } -} - - -void -e_meeting_time_selector_get_meeting_time (EMeetingTimeSelector *mts, - gint *start_year, - gint *start_month, - gint *start_day, - gint *start_hour, - gint *start_minute, - gint *end_year, - gint *end_month, - gint *end_day, - gint *end_hour, - gint *end_minute) -{ - *start_year = g_date_year (&mts->meeting_start_time.date); - *start_month = g_date_month (&mts->meeting_start_time.date); - *start_day = g_date_day (&mts->meeting_start_time.date); - *start_hour = mts->meeting_start_time.hour; - *start_minute = mts->meeting_start_time.minute; - - *end_year = g_date_year (&mts->meeting_end_time.date); - *end_month = g_date_month (&mts->meeting_end_time.date); - *end_day = g_date_day (&mts->meeting_end_time.date); - *end_hour = mts->meeting_end_time.hour; - *end_minute = mts->meeting_end_time.minute; -} - - -gboolean -e_meeting_time_selector_set_meeting_time (EMeetingTimeSelector *mts, - gint start_year, - gint start_month, - gint start_day, - gint start_hour, - gint start_minute, - gint end_year, - gint end_month, - gint end_day, - gint end_hour, - gint end_minute) -{ - g_return_val_if_fail (IS_E_MEETING_TIME_SELECTOR (mts), FALSE); - - /* Check the dates are valid. */ - if (!g_date_valid_dmy (start_day, start_month, start_year) - || !g_date_valid_dmy (end_day, end_month, end_year) - || start_hour < 0 || start_hour > 23 - || end_hour < 0 || end_hour > 23 - || start_minute < 0 || start_minute > 59 - || end_minute < 0 || end_minute > 59) - return FALSE; - - g_date_set_dmy (&mts->meeting_start_time.date, start_day, start_month, - start_year); - mts->meeting_start_time.hour = start_hour; - mts->meeting_start_time.minute = start_minute; - g_date_set_dmy (&mts->meeting_end_time.date, end_day, end_month, - end_year); - mts->meeting_end_time.hour = end_hour; - mts->meeting_end_time.minute = end_minute; - - mts->meeting_positions_valid = FALSE; - - gtk_widget_queue_draw (mts->display_top); - gtk_widget_queue_draw (mts->display_main); - - /* Set the times in the EDateEdit widgets. */ - e_meeting_time_selector_update_start_date_edit (mts); - e_meeting_time_selector_update_end_date_edit (mts); - - gtk_signal_emit (GTK_OBJECT (mts), mts_signals [CHANGED]); - - return TRUE; -} - -void -e_meeting_time_selector_set_all_day (EMeetingTimeSelector *mts, - gboolean all_day) -{ - EMeetingTime saved_time; - - mts->all_day = all_day; - - e_date_edit_set_show_time (E_DATE_EDIT (mts->start_date_edit), - !all_day); - e_date_edit_set_show_time (E_DATE_EDIT (mts->end_date_edit), - !all_day); - - e_meeting_time_selector_save_position (mts, &saved_time); - e_meeting_time_selector_recalc_grid (mts); - e_meeting_time_selector_restore_position (mts, &saved_time); - - gtk_widget_queue_draw (mts->display_top); - gtk_widget_queue_draw (mts->display_main); - e_meeting_time_selector_update_date_popup_menus (mts); -} - - -void -e_meeting_time_selector_set_working_hours_only (EMeetingTimeSelector *mts, - gboolean working_hours_only) -{ - EMeetingTime saved_time; - - g_return_if_fail (IS_E_MEETING_TIME_SELECTOR (mts)); - - if (mts->working_hours_only == working_hours_only) - return; - - mts->working_hours_only = working_hours_only; - - e_meeting_time_selector_save_position (mts, &saved_time); - e_meeting_time_selector_recalc_grid (mts); - e_meeting_time_selector_restore_position (mts, &saved_time); - - gtk_widget_queue_draw (mts->display_top); - gtk_widget_queue_draw (mts->display_main); - e_meeting_time_selector_update_date_popup_menus (mts); -} - - -void -e_meeting_time_selector_set_working_hours (EMeetingTimeSelector *mts, - gint day_start_hour, - gint day_start_minute, - gint day_end_hour, - gint day_end_minute) -{ - EMeetingTime saved_time; - - g_return_if_fail (IS_E_MEETING_TIME_SELECTOR (mts)); - - if (mts->day_start_hour == day_start_hour - && mts->day_start_minute == day_start_minute - && mts->day_end_hour == day_end_hour - && mts->day_end_minute == day_end_minute) - return; - - mts->day_start_hour = day_start_hour; - mts->day_start_minute = day_start_minute; - mts->day_end_hour = day_end_hour; - mts->day_end_minute = day_end_minute; - - e_meeting_time_selector_save_position (mts, &saved_time); - e_meeting_time_selector_recalc_grid (mts); - e_meeting_time_selector_restore_position (mts, &saved_time); - - gtk_widget_queue_draw (mts->display_top); - gtk_widget_queue_draw (mts->display_main); - e_meeting_time_selector_update_date_popup_menus (mts); -} - - -void -e_meeting_time_selector_set_zoomed_out (EMeetingTimeSelector *mts, - gboolean zoomed_out) -{ - EMeetingTime saved_time; - - g_return_if_fail (IS_E_MEETING_TIME_SELECTOR (mts)); - - if (mts->zoomed_out == zoomed_out) - return; - - mts->zoomed_out = zoomed_out; - - e_meeting_time_selector_save_position (mts, &saved_time); - e_meeting_time_selector_recalc_grid (mts); - e_meeting_time_selector_restore_position (mts, &saved_time); - - gtk_widget_queue_draw (mts->display_top); - gtk_widget_queue_draw (mts->display_main); -} - -static void -e_meeting_time_selector_refresh_cb (gpointer data) -{ - EMeetingTimeSelector *mts = data; - gtk_widget_queue_draw (mts->display_top); - gtk_widget_queue_draw (mts->display_main); -} - -static void -e_meeting_time_selector_refresh_free_busy (EMeetingTimeSelector *mts, int row, gboolean all) -{ - EMeetingTime start, end; - - start = mts->meeting_start_time; - g_date_subtract_days (&start.date, E_MEETING_TIME_SELECTOR_FB_DAYS_BEFORE); - start.hour = 0; - start.minute = 0; - end = mts->meeting_end_time; - g_date_add_days (&end.date, E_MEETING_TIME_SELECTOR_FB_DAYS_AFTER); - end.hour = 0; - end.minute = 0; - - if (all) - e_meeting_model_refresh_all_busy_periods (mts->model, &start, &end, - e_meeting_time_selector_refresh_cb, mts); - else - e_meeting_model_refresh_busy_periods (mts->model, row, &start, &end, - e_meeting_time_selector_refresh_cb, mts); -} - -EMeetingTimeSelectorAutopickOption -e_meeting_time_selector_get_autopick_option (EMeetingTimeSelector *mts) -{ - if (GTK_CHECK_MENU_ITEM (mts->autopick_all_item)->active) - return E_MEETING_TIME_SELECTOR_ALL_PEOPLE_AND_RESOURCES; - if (GTK_CHECK_MENU_ITEM (mts->autopick_all_people_one_resource_item)->active) - return E_MEETING_TIME_SELECTOR_ALL_PEOPLE_AND_ONE_RESOURCE; - if (GTK_CHECK_MENU_ITEM (mts->autopick_required_people_item)->active) - return E_MEETING_TIME_SELECTOR_REQUIRED_PEOPLE; - return E_MEETING_TIME_SELECTOR_REQUIRED_PEOPLE_AND_ONE_RESOURCE; -} - - -void -e_meeting_time_selector_set_autopick_option (EMeetingTimeSelector *mts, - EMeetingTimeSelectorAutopickOption autopick_option) -{ - g_return_if_fail (IS_E_MEETING_TIME_SELECTOR (mts)); - - switch (autopick_option) { - case E_MEETING_TIME_SELECTOR_ALL_PEOPLE_AND_RESOURCES: - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mts->autopick_all_item), TRUE); - break; - case E_MEETING_TIME_SELECTOR_ALL_PEOPLE_AND_ONE_RESOURCE: - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mts->autopick_all_people_one_resource_item), TRUE); - break; - case E_MEETING_TIME_SELECTOR_REQUIRED_PEOPLE: - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mts->autopick_required_people_item), TRUE); - break; - case E_MEETING_TIME_SELECTOR_REQUIRED_PEOPLE_AND_ONE_RESOURCE: - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (mts->autopick_required_people_one_resource_item), TRUE); - break; - } -} -#if 0 -void -e_meeting_time_selector_attendee_set_send_meeting_to (EMeetingTimeSelector *mts, - gint row, - gboolean send_meeting_to) -{ - EMeetingTimeSelectorAttendee *attendee; - - g_return_if_fail (IS_E_MEETING_TIME_SELECTOR (mts)); - g_return_if_fail (row >= 0); - g_return_if_fail (row < mts->attendees->len); - - attendee = &g_array_index (mts->attendees, - EMeetingTimeSelectorAttendee, row); - attendee->send_meeting_to = send_meeting_to; -} -#endif - -/* - * DEBUGGING ROUTINES - functions to output various bits of data. - */ - -#ifdef E_MEETING_TIME_SELECTOR_DEBUG - -/* Debugging function to dump information on all attendees. */ -void -e_meeting_time_selector_dump (EMeetingTimeSelector *mts) -{ - EMeetingTimeSelectorAttendee *attendee; - EMeetingTimeSelectorPeriod *period; - gint row, period_num; - gchar buffer[128]; - - g_return_if_fail (IS_E_MEETING_TIME_SELECTOR (mts)); - - g_print ("\n\nAttendee Information:\n"); - - for (row = 0; row < mts->attendees->len; row++) { - attendee = &g_array_index (mts->attendees, - EMeetingTimeSelectorAttendee, row); - g_print ("Attendee: %s\n", attendee->name); - g_print (" Longest Busy Period: %i days\n", - attendee->longest_period_in_days); - - e_meeting_time_selector_attendee_ensure_periods_sorted (mts, attendee); -#if 1 - for (period_num = 0; - period_num < attendee->busy_periods->len; - period_num++) { - period = &g_array_index (attendee->busy_periods, - EMeetingTimeSelectorPeriod, - period_num); - - /* These are just for debugging so don't need i18n. */ - g_date_strftime (buffer, sizeof (buffer), - "%A, %B %d, %Y", &period->start.date); - g_print (" Start: %s %i:%02i\n", buffer, - period->start.hour, period->start.minute); - - g_date_strftime (buffer, sizeof (buffer), - "%A, %B %d, %Y", &period->end.date); - g_print (" End : %s %i:%02i\n", buffer, - period->end.hour, period->end.minute); - } -#endif - } - -} - - -/* This formats a EMeetingTimein a string and returns it. - Note that it uses a static buffer. */ -gchar* -e_meeting_time_selector_dump_time (EMeetingTime*mtstime) -{ - static gchar buffer[128]; - - gchar buffer2[128]; - - /* This is just for debugging so doesn't need i18n. */ - g_date_strftime (buffer, sizeof (buffer), "%A, %B %d, %Y", - &mtstime->date); - sprintf (buffer2, " at %i:%02i", (gint) mtstime->hour, - (gint) mtstime->minute); - strcat (buffer, buffer2); - - return buffer; -} - - -/* This formats a GDate in a string and returns it. - Note that it uses a static buffer. */ -gchar* -e_meeting_time_selector_dump_date (GDate *date) -{ - static gchar buffer[128]; - - /* This is just for debugging so doesn't need i18n. */ - g_date_strftime (buffer, sizeof (buffer), "%A, %B %d, %Y", date); - return buffer; -} - -#endif /* E_MEETING_TIME_SELECTOR_DEBUG */ - - -static void -e_meeting_time_selector_on_invite_others_button_clicked (GtkWidget *button, - EMeetingTimeSelector *mts) -{ - e_meeting_model_invite_others_dialog (mts->model); -} - - -static void -e_meeting_time_selector_on_options_button_clicked (GtkWidget *button, - EMeetingTimeSelector *mts) -{ - gtk_menu_popup (GTK_MENU (mts->options_menu), NULL, NULL, - e_meeting_time_selector_options_menu_position_callback, - mts, 1, GDK_CURRENT_TIME); -} - - -static void -e_meeting_time_selector_options_menu_position_callback (GtkMenu *menu, - gint *x, - gint *y, - gpointer user_data) -{ - EMeetingTimeSelector *mts; - GtkRequisition menu_requisition; - gint max_x, max_y; - - mts = E_MEETING_TIME_SELECTOR (user_data); - - /* Calculate our preferred position. */ - gdk_window_get_origin (mts->options_button->window, x, y); - *y += mts->options_button->allocation.height; - - /* Now make sure we are on the screen. */ - gtk_widget_size_request (mts->options_menu, &menu_requisition); - max_x = MAX (0, gdk_screen_width () - menu_requisition.width); - max_y = MAX (0, gdk_screen_height () - menu_requisition.height); - *x = CLAMP (*x, 0, max_x); - *y = CLAMP (*y, 0, max_y); -} - -static void -e_meeting_time_selector_on_update_free_busy (GtkWidget *button, - EMeetingTimeSelector *mts) -{ - /* Make sure the menu pops down, which doesn't happen by default if - keyboard accelerators are used. */ - if (GTK_WIDGET_VISIBLE (mts->options_menu)) - gtk_menu_popdown (GTK_MENU (mts->options_menu)); - - e_meeting_time_selector_refresh_free_busy (mts, 0, TRUE); -} - - -static void -e_meeting_time_selector_on_autopick_button_clicked (GtkWidget *button, - EMeetingTimeSelector *mts) -{ - gtk_menu_popup (GTK_MENU (mts->autopick_menu), NULL, NULL, - e_meeting_time_selector_autopick_menu_position_callback, - mts, 1, GDK_CURRENT_TIME); -} - - -static void -e_meeting_time_selector_autopick_menu_position_callback (GtkMenu *menu, - gint *x, - gint *y, - gpointer user_data) -{ - EMeetingTimeSelector *mts; - GtkRequisition menu_requisition; - gint max_x, max_y; - - mts = E_MEETING_TIME_SELECTOR (user_data); - - /* Calculate our preferred position. */ - gdk_window_get_origin (mts->autopick_button->window, x, y); - *y += mts->autopick_button->allocation.height; - - /* Now make sure we are on the screen. */ - gtk_widget_size_request (mts->autopick_menu, &menu_requisition); - max_x = MAX (0, gdk_screen_width () - menu_requisition.width); - max_y = MAX (0, gdk_screen_height () - menu_requisition.height); - *x = CLAMP (*x, 0, max_x); - *y = CLAMP (*y, 0, max_y); -} - - -static void -e_meeting_time_selector_on_autopick_option_toggled (GtkWidget *button, - EMeetingTimeSelector *mts) -{ - /* Make sure the menu pops down, which doesn't happen by default if - keyboard accelerators are used. */ - if (GTK_WIDGET_VISIBLE (mts->autopick_menu)) - gtk_menu_popdown (GTK_MENU (mts->autopick_menu)); -} - - -static void -e_meeting_time_selector_on_prev_button_clicked (GtkWidget *button, - EMeetingTimeSelector *mts) -{ - e_meeting_time_selector_autopick (mts, FALSE); -} - - -static void -e_meeting_time_selector_on_next_button_clicked (GtkWidget *button, - EMeetingTimeSelector *mts) -{ - e_meeting_time_selector_autopick (mts, TRUE); -} - - -/* This tries to find the previous or next meeting time for which all - attendees will be available. */ -static void -e_meeting_time_selector_autopick (EMeetingTimeSelector *mts, - gboolean forward) -{ - EMeetingTime start_time, end_time, *resource_free; - EMeetingAttendee *attendee; - EMeetingFreeBusyPeriod *period; - EMeetingTimeSelectorAutopickOption autopick_option; - gint duration_days, duration_hours, duration_minutes, row; - gboolean meeting_time_ok, skip_optional = FALSE; - gboolean need_one_resource = FALSE, found_resource; - - /* Get the current meeting duration in days + hours + minutes. */ - e_meeting_time_selector_calculate_time_difference (&mts->meeting_start_time, &mts->meeting_end_time, &duration_days, &duration_hours, &duration_minutes); - - /* Find the first appropriate start time. */ - start_time = mts->meeting_start_time; - if (forward) - e_meeting_time_selector_find_nearest_interval (mts, &start_time, &end_time, duration_days, duration_hours, duration_minutes); - else - e_meeting_time_selector_find_nearest_interval_backward (mts, &start_time, &end_time, duration_days, duration_hours, duration_minutes); - - /* Determine if we can skip optional people and if we only need one - resource based on the autopick option. */ - autopick_option = e_meeting_time_selector_get_autopick_option (mts); - if (autopick_option == E_MEETING_TIME_SELECTOR_REQUIRED_PEOPLE - || autopick_option == E_MEETING_TIME_SELECTOR_REQUIRED_PEOPLE_AND_ONE_RESOURCE) - skip_optional = TRUE; - if (autopick_option == E_MEETING_TIME_SELECTOR_ALL_PEOPLE_AND_ONE_RESOURCE - || autopick_option == E_MEETING_TIME_SELECTOR_REQUIRED_PEOPLE_AND_ONE_RESOURCE) - need_one_resource = TRUE; - - /* Keep moving forward or backward until we find a possible meeting - time. */ - for (;;) { - meeting_time_ok = TRUE; - found_resource = FALSE; - resource_free = NULL; - - /* Step through each attendee, checking if the meeting time - intersects one of the attendees busy periods. */ - for (row = 0; row < e_meeting_model_count_actual_attendees (mts->model); row++) { - attendee = e_meeting_model_find_attendee_at_row (mts->model, row); - - /* Skip optional people if they don't matter. */ - if (skip_optional && e_meeting_attendee_get_atype (attendee) == E_MEETING_ATTENDEE_OPTIONAL_PERSON) - continue; - - period = e_meeting_time_selector_find_time_clash (mts, attendee, &start_time, &end_time); - - if (need_one_resource && e_meeting_attendee_get_atype (attendee) == E_MEETING_ATTENDEE_RESOURCE) { - if (period) { - /* We want to remember the closest - prev/next time that one resource is - available, in case we don't find any - free resources. */ - if (forward) { - if (!resource_free || e_meeting_time_compare_times (resource_free, &period->end) > 0) - resource_free = &period->end; - } else { - if (!resource_free || e_meeting_time_compare_times (resource_free, &period->start) < 0) - resource_free = &period->start; - } - - } else { - found_resource = TRUE; - } - } else if (period) { - /* Skip the period which clashed. */ - if (forward) { - start_time = period->end; - } else { - start_time = period->start; - e_meeting_time_selector_adjust_time (&start_time, -duration_days, -duration_hours, -duration_minutes); - } - meeting_time_ok = FALSE; - break; - } - } - - /* Check that we found one resource if necessary. If not, skip - to the closest time that a resource is free. Note that if - there are no resources, resource_free will never get set, - so we assume the meeting time is OK. */ - if (meeting_time_ok && need_one_resource && !found_resource - && resource_free) { - if (forward) { - start_time = *resource_free; - } else { - start_time = *resource_free; - e_meeting_time_selector_adjust_time (&start_time, -duration_days, -duration_hours, -duration_minutes); - } - meeting_time_ok = FALSE; - } - - if (meeting_time_ok) { - mts->meeting_start_time = start_time; - mts->meeting_end_time = end_time; - mts->meeting_positions_valid = FALSE; - gtk_widget_queue_draw (mts->display_top); - gtk_widget_queue_draw (mts->display_main); - - /* Make sure the time is shown. */ - e_meeting_time_selector_ensure_meeting_time_shown (mts); - - /* Set the times in the EDateEdit widgets. */ - e_meeting_time_selector_update_start_date_edit (mts); - e_meeting_time_selector_update_end_date_edit (mts); - - gtk_signal_emit (GTK_OBJECT (mts), mts_signals [CHANGED]); - - return; - } - - /* Move forward to the next possible interval. */ - if (forward) - e_meeting_time_selector_find_nearest_interval (mts, &start_time, &end_time, duration_days, duration_hours, duration_minutes); - else - e_meeting_time_selector_find_nearest_interval_backward (mts, &start_time, &end_time, duration_days, duration_hours, duration_minutes); - } -} - - -static void -e_meeting_time_selector_calculate_time_difference (EMeetingTime*start, - EMeetingTime*end, - gint *days, - gint *hours, - gint *minutes) -{ - *days = g_date_julian (&end->date) - g_date_julian (&start->date); - *hours = end->hour - start->hour; - *minutes = end->minute - start->minute; - if (*minutes < 0) { - *minutes += 60; - *hours = *hours - 1; - } - if (*hours < 0) { - *hours += 24; - *days = *days - 1; - } -} - - -/* This moves the given time forward to the next suitable start of a meeting. - If zoomed_out is set, this means every hour. If not every half-hour. */ -static void -e_meeting_time_selector_find_nearest_interval (EMeetingTimeSelector *mts, - EMeetingTime*start_time, - EMeetingTime*end_time, - gint days, gint hours, gint mins) -{ - gint minutes_shown; - gboolean set_to_start_of_working_day = FALSE; - - if (!mts->all_day) { - if (mts->zoomed_out) { - start_time->hour++; - start_time->minute = 0; - } else { - start_time->minute += 30; - start_time->minute -= start_time->minute % 30; - } - } else { - g_date_add_days (&start_time->date, 1); - start_time->hour = 0; - start_time->minute = 0; - } - e_meeting_time_selector_fix_time_overflows (start_time); - - *end_time = *start_time; - e_meeting_time_selector_adjust_time (end_time, days, hours, mins); - - /* Check if the interval is less than a day as seen in the display. - If it isn't we don't worry about the working day. */ - if (!mts->working_hours_only || days > 0) - return; - minutes_shown = (mts->day_end_hour - mts->day_start_hour) * 60; - minutes_shown += mts->day_end_minute - mts->day_start_minute; - if (hours * 60 + mins > minutes_shown) - return; - - /* If the meeting time finishes past the end of the working day, move - onto the start of the next working day. If the meeting time starts - before the working day, move it on as well. */ - if (start_time->hour > mts->day_end_hour - || (start_time->hour == mts->day_end_hour - && start_time->minute > mts->day_end_minute) - || end_time->hour > mts->day_end_hour - || (end_time->hour == mts->day_end_hour - && end_time->minute > mts->day_end_minute)) { - g_date_add_days (&start_time->date, 1); - set_to_start_of_working_day = TRUE; - } else if (start_time->hour < mts->day_start_hour - || (start_time->hour == mts->day_start_hour - && start_time->minute < mts->day_start_minute)) { - set_to_start_of_working_day = TRUE; - } - - if (set_to_start_of_working_day) { - start_time->hour = mts->day_start_hour; - start_time->minute = mts->day_start_minute; - - if (mts->zoomed_out) { - if (start_time->minute > 0) { - start_time->hour++; - start_time->minute = 0; - } - } else { - start_time->minute += 29; - start_time->minute -= start_time->minute % 30; - } - - e_meeting_time_selector_fix_time_overflows (start_time); - - *end_time = *start_time; - e_meeting_time_selector_adjust_time (end_time, days, hours, mins); - } -} - - -/* This moves the given time backward to the next suitable start of a meeting. - If zoomed_out is set, this means every hour. If not every half-hour. */ -static void -e_meeting_time_selector_find_nearest_interval_backward (EMeetingTimeSelector *mts, - EMeetingTime*start_time, - EMeetingTime*end_time, - gint days, gint hours, gint mins) -{ - gint new_hour, minutes_shown; - gboolean set_to_end_of_working_day = FALSE; - - if (!mts->all_day) { - new_hour = start_time->hour; - if (mts->zoomed_out) { - if (start_time->minute == 0) - new_hour--; - start_time->minute = 0; - } else { - if (start_time->minute == 0) { - start_time->minute = 30; - new_hour--; - } else if (start_time->minute <= 30) - start_time->minute = 0; - else - start_time->minute = 30; - } - if (new_hour < 0) { - new_hour += 24; - g_date_subtract_days (&start_time->date, 1); - } - start_time->hour = new_hour; - } else { - g_date_subtract_days (&start_time->date, 1); - start_time->hour = 0; - start_time->minute = 0; - } - - *end_time = *start_time; - e_meeting_time_selector_adjust_time (end_time, days, hours, mins); - - /* Check if the interval is less than a day as seen in the display. - If it isn't we don't worry about the working day. */ - if (!mts->working_hours_only || days > 0) - return; - minutes_shown = (mts->day_end_hour - mts->day_start_hour) * 60; - minutes_shown += mts->day_end_minute - mts->day_start_minute; - if (hours * 60 + mins > minutes_shown) - return; - - /* If the meeting time finishes past the end of the working day, move - back to the end of the working day. If the meeting time starts - before the working day, move it back to the end of the previous - working day. */ - if (start_time->hour > mts->day_end_hour - || (start_time->hour == mts->day_end_hour - && start_time->minute > mts->day_end_minute) - || end_time->hour > mts->day_end_hour - || (end_time->hour == mts->day_end_hour - && end_time->minute > mts->day_end_minute)) { - set_to_end_of_working_day = TRUE; - } else if (start_time->hour < mts->day_start_hour - || (start_time->hour == mts->day_start_hour - && start_time->minute < mts->day_start_minute)) { - g_date_subtract_days (&end_time->date, 1); - set_to_end_of_working_day = TRUE; - } - - if (set_to_end_of_working_day) { - end_time->hour = mts->day_end_hour; - end_time->minute = mts->day_end_minute; - *start_time = *end_time; - e_meeting_time_selector_adjust_time (start_time, -days, -hours, -mins); - - if (mts->zoomed_out) { - start_time->minute = 0; - } else { - start_time->minute -= start_time->minute % 30; - } - - *end_time = *start_time; - e_meeting_time_selector_adjust_time (end_time, days, hours, mins); - } -} - - -/* This adds on the given days, hours & minutes to a EMeetingTimeSelectorTime. - It is used to calculate the end of a period given a start & duration. - Days, hours & minutes can be negative, to move backwards, but they should - be within normal ranges, e.g. hours should be between -23 and 23. */ -static void -e_meeting_time_selector_adjust_time (EMeetingTime*mtstime, - gint days, gint hours, gint minutes) -{ - gint new_hours, new_minutes; - - /* We have to handle negative values for hous and minutes here, since - EMeetingTimeuses guint8s to store them. */ - new_minutes = mtstime->minute + minutes; - if (new_minutes < 0) { - new_minutes += 60; - hours -= 1; - } - - new_hours = mtstime->hour + hours; - if (new_hours < 0) { - new_hours += 24; - days -= 1; - } - - g_date_add_days (&mtstime->date, days); - mtstime->hour = new_hours; - mtstime->minute = new_minutes; - - e_meeting_time_selector_fix_time_overflows (mtstime); -} - - -/* This looks for any busy period of the given attendee which clashes with - the start and end time. It uses a binary search. */ -static EMeetingFreeBusyPeriod * -e_meeting_time_selector_find_time_clash (EMeetingTimeSelector *mts, - EMeetingAttendee *attendee, - EMeetingTime*start_time, - EMeetingTime*end_time) -{ - EMeetingFreeBusyPeriod *period; - const GArray *busy_periods; - gint period_num; - - busy_periods = e_meeting_attendee_get_busy_periods (attendee); - period_num = e_meeting_attendee_find_first_busy_period (attendee, &start_time->date); - - if (period_num == -1) - return NULL; - - /* Step forward through the busy periods until we find a clash or we - go past the end_time. */ - while (period_num < busy_periods->len) { - period = &g_array_index (busy_periods, EMeetingFreeBusyPeriod, period_num); - - /* If the period starts at or after the end time, there is no - clash and we are finished. The busy periods are sorted by - their start times, so all the rest will be later. */ - if (e_meeting_time_compare_times (&period->start, end_time) >= 0) - return NULL; - - /* If the period ends after the start time, we have found a - clash. From the above test we already know the busy period - isn't completely after the meeting time. */ - if (e_meeting_time_compare_times (&period->end, start_time) > 0) - return period; - - period_num++; - } - - return NULL; -} - -static void -e_meeting_time_selector_on_zoomed_out_toggled (GtkWidget *menuitem, - EMeetingTimeSelector *mts) -{ - /* Make sure the menu pops down, which doesn't happen by default if - keyboard accelerators are used. */ - if (GTK_WIDGET_VISIBLE (mts->options_menu)) - gtk_menu_popdown (GTK_MENU (mts->options_menu)); - - e_meeting_time_selector_set_zoomed_out (mts, GTK_CHECK_MENU_ITEM (menuitem)->active); -} - - -static void -e_meeting_time_selector_on_working_hours_toggled (GtkWidget *menuitem, - EMeetingTimeSelector *mts) -{ - /* Make sure the menu pops down, which doesn't happen by default if - keyboard accelerators are used. */ - if (GTK_WIDGET_VISIBLE (mts->options_menu)) - gtk_menu_popdown (GTK_MENU (mts->options_menu)); - - e_meeting_time_selector_set_working_hours_only (mts, GTK_CHECK_MENU_ITEM (menuitem)->active); -} - - -/* This recalculates day_width, first_hour_shown and last_hour_shown. */ -static void -e_meeting_time_selector_recalc_grid (EMeetingTimeSelector *mts) -{ - if (mts->working_hours_only) { - mts->first_hour_shown = mts->day_start_hour; - mts->last_hour_shown = mts->day_end_hour; - if (mts->day_end_minute != 0) - mts->last_hour_shown += 1; - } else { - mts->first_hour_shown = 0; - mts->last_hour_shown = 24; - } - - /* In the brief view we use the nearest hours divisible by 3. */ - if (mts->zoomed_out) { - mts->first_hour_shown -= mts->first_hour_shown % 3; - mts->last_hour_shown += 2; - mts->last_hour_shown -= mts->last_hour_shown % 3; - } - - mts->day_width = mts->col_width * (mts->last_hour_shown - mts->first_hour_shown); - if (mts->zoomed_out) - mts->day_width /= 3; - - /* Add one pixel for the extra vertical grid line. */ - mts->day_width++; - - gnome_canvas_set_scroll_region (GNOME_CANVAS (mts->display_top), - 0, 0, - mts->day_width * E_MEETING_TIME_SELECTOR_DAYS_SHOWN, - mts->row_height * 3); - e_meeting_time_selector_update_main_canvas_scroll_region (mts); - - e_meeting_time_selector_recalc_date_format (mts); - mts->meeting_positions_valid = FALSE; -} - - -/* This saves the first visible time in the given EMeetingTimeSelectorTime. */ -static void -e_meeting_time_selector_save_position (EMeetingTimeSelector *mts, - EMeetingTime*mtstime) -{ - gint scroll_x, scroll_y; - - gnome_canvas_get_scroll_offsets (GNOME_CANVAS (mts->display_main), - &scroll_x, &scroll_y); - e_meeting_time_selector_calculate_time (mts, scroll_x, mtstime); -} - - -/* This restores a saved position. */ -static void -e_meeting_time_selector_restore_position (EMeetingTimeSelector *mts, - EMeetingTime*mtstime) -{ - gint scroll_x, scroll_y, new_scroll_x; - - new_scroll_x = e_meeting_time_selector_calculate_time_position (mts, - mtstime); - gnome_canvas_get_scroll_offsets (GNOME_CANVAS (mts->display_main), - &scroll_x, &scroll_y); - gnome_canvas_scroll_to (GNOME_CANVAS (mts->display_main), - new_scroll_x, scroll_y); -} - - -/* This returns the x pixel coords of the meeting time in the entire scroll - region. It recalculates them if they have been marked as invalid. - If it returns FALSE then no meeting time is set or the meeting time is - not visible in the current scroll area. */ -gboolean -e_meeting_time_selector_get_meeting_time_positions (EMeetingTimeSelector *mts, - gint *start_x, - gint *end_x) -{ - if (mts->meeting_positions_valid) { - if (mts->meeting_positions_in_scroll_area) { - *start_x = mts->meeting_start_x; - *end_x = mts->meeting_end_x; - return TRUE; - } else { - return FALSE; - } - } - - mts->meeting_positions_valid = TRUE; - - /* Check if the days aren't in our current range. */ - if (g_date_compare (&mts->meeting_start_time.date, &mts->last_date_shown) > 0 - || g_date_compare (&mts->meeting_end_time.date, &mts->first_date_shown) < 0) { - mts->meeting_positions_in_scroll_area = FALSE; - return FALSE; - } - - mts->meeting_positions_in_scroll_area = TRUE; - *start_x = mts->meeting_start_x = e_meeting_time_selector_calculate_time_position (mts, &mts->meeting_start_time); - *end_x = mts->meeting_end_x = e_meeting_time_selector_calculate_time_position (mts, &mts->meeting_end_time); - - return TRUE; -} - - -/* This recalculates the date format to used, by computing the width of the - longest date strings in the widget's font and seeing if they fit. */ -static void -e_meeting_time_selector_recalc_date_format (EMeetingTimeSelector *mts) -{ - /* 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 }; - GDate date; - gint max_date_width, longest_weekday_width, longest_month_width, width; - gint day, longest_weekday, month, longest_month; - gchar buffer[128]; - GdkFont *font; - - font = GTK_WIDGET (mts)->style->font; - - /* Calculate the maximum date width we can fit into the display. */ - max_date_width = mts->day_width - 2; - - /* Find the biggest full weekday name. We start on a particular - Monday and go through seven days. */ - g_date_clear (&date, 1); - g_date_set_dmy (&date, 3, 1, 2000); /* Monday 3rd Jan 2000. */ - longest_weekday_width = 0; - longest_weekday = G_DATE_MONDAY; - for (day = G_DATE_MONDAY; day <= G_DATE_SUNDAY; day++) { - g_date_strftime (buffer, sizeof (buffer), "%A", &date); - width = gdk_string_width (font, buffer); - if (width > longest_weekday_width) { - longest_weekday = day; - longest_weekday_width = width; - } - g_date_add_days (&date, 1); - } - - /* Now find the biggest month name. */ - longest_month_width = 0; - longest_month = G_DATE_JANUARY; - for (month = G_DATE_JANUARY; month <= G_DATE_DECEMBER; month++) { - g_date_set_month (&date, month); - g_date_strftime (buffer, sizeof (buffer), "%B", &date); - width = gdk_string_width (font, buffer); - if (width > longest_month_width) { - longest_month = month; - longest_month_width = width; - } - } - - /* See if we can use the full date. We want to use a date with a - month day > 20 and also the longest weekday. We use a - pre-calculated array of days for each month and add on the - weekday (which is 1 (Mon) to 7 (Sun). */ - g_date_set_dmy (&date, days[longest_month - 1] + longest_weekday, - longest_month, 2000); - /* This is a strftime() format string %A = full weekday name, - %B = full month name, %d = month day, %Y = full year. */ - g_date_strftime (buffer, sizeof (buffer), _("%A, %B %d, %Y"), &date); - -#if 0 - g_print ("longest_month: %i longest_weekday: %i date: %s\n", - longest_month, longest_weekday, buffer); -#endif - - if (gdk_string_width (font, buffer) < max_date_width) { - mts->date_format = E_MEETING_TIME_SELECTOR_DATE_FULL; - return; - } - - /* Now try it with abbreviated weekday names. */ - longest_weekday_width = 0; - longest_weekday = G_DATE_MONDAY; - g_date_set_dmy (&date, 3, 1, 2000); /* Monday 3rd Jan 2000. */ - for (day = G_DATE_MONDAY; day <= G_DATE_SUNDAY; day++) { - g_date_strftime (buffer, sizeof (buffer), "%a", &date); - width = gdk_string_width (font, buffer); - if (width > longest_weekday_width) { - longest_weekday = day; - longest_weekday_width = width; - } - g_date_add_days (&date, 1); - } - - g_date_set_dmy (&date, days[longest_month - 1] + longest_weekday, - longest_month, 2000); - /* This is a strftime() format string %a = abbreviated weekday name, - %m = month number, %d = month day, %Y = full year. */ - g_date_strftime (buffer, sizeof (buffer), _("%a %m/%d/%Y"), &date); - -#if 0 - g_print ("longest_month: %i longest_weekday: %i date: %s\n", - longest_month, longest_weekday, buffer); -#endif - - if (gdk_string_width (font, buffer) < max_date_width) - mts->date_format = E_MEETING_TIME_SELECTOR_DATE_ABBREVIATED_DAY; - else - mts->date_format = E_MEETING_TIME_SELECTOR_DATE_SHORT; -} - - -/* Turn off the background of the canvas windows. This reduces flicker - considerably when scrolling. (Why isn't it in GnomeCanvas?). */ -static void -e_meeting_time_selector_on_canvas_realized (GtkWidget *widget, - EMeetingTimeSelector *mts) -{ - gdk_window_set_back_pixmap (GTK_LAYOUT (widget)->bin_window, - NULL, FALSE); -} - - -/* This is called when the meeting start time GnomeDateEdit is changed, - either via the "date_changed". "time_changed" or "activate" signals on one - of the GtkEntry widgets. So don't use the widget parameter since it may be - one of the child GtkEntry widgets. */ -static void -e_meeting_time_selector_on_start_time_changed (GtkWidget *widget, - EMeetingTimeSelector *mts) -{ - gint duration_days, duration_hours, duration_minutes; - EMeetingTime mtstime; - gint hour = 0, minute = 0; - time_t newtime; - - /* Date */ - newtime = e_date_edit_get_time (E_DATE_EDIT (mts->start_date_edit)); - g_date_clear (&mtstime.date, 1); - g_date_set_time (&mtstime.date, newtime); - - /* Time */ - e_date_edit_get_time_of_day (E_DATE_EDIT (mts->start_date_edit), &hour, &minute); - mtstime.hour = hour; - mtstime.minute = minute; - - /* If the time hasn't changed, just return. */ - if (e_meeting_time_compare_times (&mtstime, &mts->meeting_start_time) == 0) - return; - - /* Calculate the current meeting duration. */ - e_meeting_time_selector_calculate_time_difference (&mts->meeting_start_time, &mts->meeting_end_time, &duration_days, &duration_hours, &duration_minutes); - - /* Set the new start time. */ - mts->meeting_start_time = mtstime; - - /* Update the end time so the meeting duration stays the same. */ - mts->meeting_end_time = mts->meeting_start_time; - e_meeting_time_selector_adjust_time (&mts->meeting_end_time, duration_days, duration_hours, duration_minutes); - e_meeting_time_selector_update_end_date_edit (mts); - - mts->meeting_positions_valid = FALSE; - e_meeting_time_selector_ensure_meeting_time_shown (mts); - gtk_widget_queue_draw (mts->display_top); - gtk_widget_queue_draw (mts->display_main); - - gtk_signal_emit (GTK_OBJECT (mts), mts_signals [CHANGED]); -} - - -/* This is called when the meeting end time GnomeDateEdit is changed, - either via the "date_changed", "time_changed" or "activate" signals on one - of the GtkEntry widgets. So don't use the widget parameter since it may be - one of the child GtkEntry widgets. */ -static void -e_meeting_time_selector_on_end_time_changed (GtkWidget *widget, - EMeetingTimeSelector *mts) -{ - EMeetingTime mtstime; - gint hour = 0, minute = 0; - time_t newtime; - - /* Date */ - newtime = e_date_edit_get_time (E_DATE_EDIT (mts->end_date_edit)); - g_date_clear (&mtstime.date, 1); - g_date_set_time (&mtstime.date, newtime); - if (mts->all_day) - g_date_add_days (&mtstime.date, 1); - - /* Time */ - e_date_edit_get_time_of_day (E_DATE_EDIT (mts->end_date_edit), &hour, &minute); - mtstime.hour = hour; - mtstime.minute = minute; - - /* If the time hasn't changed, just return. */ - if (e_meeting_time_compare_times (&mtstime, &mts->meeting_end_time) == 0) - return; - - /* Set the new end time. */ - mts->meeting_end_time = mtstime; - - /* If the start time is after the end time, set it to the same time. */ - if (e_meeting_time_compare_times (&mtstime, &mts->meeting_start_time) <= 0) { - /* We set it first, before updating the widget, so the signal - handler will just return. */ - mts->meeting_start_time = mtstime; - if (mts->all_day) - g_date_subtract_days (&mts->meeting_start_time.date, 1); - e_meeting_time_selector_update_start_date_edit (mts); - } - - mts->meeting_positions_valid = FALSE; - e_meeting_time_selector_ensure_meeting_time_shown (mts); - gtk_widget_queue_draw (mts->display_top); - gtk_widget_queue_draw (mts->display_main); - - gtk_signal_emit (GTK_OBJECT (mts), mts_signals [CHANGED]); -} - - -/* This updates the ranges shown in the GnomeDateEdit popup menus, according - to working_hours_only etc. */ -static void -e_meeting_time_selector_update_date_popup_menus (EMeetingTimeSelector *mts) -{ - EDateEdit *start_edit, *end_edit; - gint low_hour, high_hour; - - start_edit = E_DATE_EDIT (mts->start_date_edit); - end_edit = E_DATE_EDIT (mts->end_date_edit); - - if (mts->working_hours_only) { - low_hour = mts->day_start_hour; - high_hour = mts->day_end_hour; - } else { - low_hour = 0; - high_hour = 23; - } - - e_date_edit_set_time_popup_range (start_edit, low_hour, high_hour); - e_date_edit_set_time_popup_range (end_edit, low_hour, high_hour); -} - - -static void -e_meeting_time_selector_on_canvas_size_allocate (GtkWidget *widget, - GtkAllocation *allocation, - EMeetingTimeSelector *mts) -{ - e_meeting_time_selector_update_main_canvas_scroll_region (mts); - - e_meeting_time_selector_ensure_meeting_time_shown (mts); -} - -/* This updates the canvas scroll regions according to the number of attendees. - If the total height needed is less than the height of the canvas, we must - use the height of the canvas, or it causes problems. */ -static void -e_meeting_time_selector_update_main_canvas_scroll_region (EMeetingTimeSelector *mts) -{ - gint height, canvas_height; - - height = mts->row_height * (e_meeting_model_count_actual_attendees (mts->model) + 2); - canvas_height = GTK_WIDGET (mts->display_main)->allocation.height; - - height = MAX (height, canvas_height); - - gnome_canvas_set_scroll_region (GNOME_CANVAS (mts->display_main), - 0, 0, - mts->day_width * E_MEETING_TIME_SELECTOR_DAYS_SHOWN, - height); -} - - -/* This changes the meeting time based on the given x coordinate and whether - we are dragging the start or end bar. It returns the new position, which - will be swapped if the start bar is dragged past the end bar or vice versa. - It make sure the meeting time is never dragged outside the visible canvas - area. */ -void -e_meeting_time_selector_drag_meeting_time (EMeetingTimeSelector *mts, - gint x) -{ - EMeetingTime first_time, last_time, drag_time, *time_to_set; - gint scroll_x, scroll_y, canvas_width; - gboolean set_both_times = FALSE; - - /* Get the x coords of visible part of the canvas. */ - gnome_canvas_get_scroll_offsets (GNOME_CANVAS (mts->display_main), - &scroll_x, &scroll_y); - canvas_width = mts->display_main->allocation.width; - - /* Save the x coordinate for the timeout handler. */ - mts->last_drag_x = (x < scroll_x) ? x - scroll_x - : x - scroll_x - canvas_width + 1; - - /* Check if the mouse is off the edge of the canvas. */ - if (x < scroll_x || x > scroll_x + canvas_width) { - /* If we haven't added a timeout function, add one. */ - if (mts->auto_scroll_timeout_id == 0) { - mts->auto_scroll_timeout_id = g_timeout_add (60, e_meeting_time_selector_timeout_handler, mts); - mts->scroll_count = 0; - - /* Call the handler to start scrolling now. */ - e_meeting_time_selector_timeout_handler (mts); - return; - } - } else { - e_meeting_time_selector_remove_timeout (mts); - } - - /* Calculate the minimum & maximum times we can use, based on the - scroll offsets and whether zoomed_out is set. */ - e_meeting_time_selector_calculate_time (mts, scroll_x, &first_time); - e_meeting_time_selector_calculate_time (mts, scroll_x + canvas_width - 1, - &last_time); - if (!mts->all_day) { - if (mts->zoomed_out) { - if (first_time.minute > 30) - first_time.hour++; - first_time.minute = 0; - last_time.minute = 0; - } else { - first_time.minute += 15; - first_time.minute -= first_time.minute % 30; - last_time.minute -= last_time.minute % 30; - } - } else { - if (first_time.hour > 0 || first_time.minute > 0) - g_date_add_days (&first_time.date, 1); - first_time.hour = 0; - first_time.minute = 0; - last_time.hour = 0; - last_time.minute = 0; - } - e_meeting_time_selector_fix_time_overflows (&first_time); - e_meeting_time_selector_fix_time_overflows (&last_time); - - /* Calculate the time from x coordinate. */ - e_meeting_time_selector_calculate_time (mts, x, &drag_time); - - /* Calculate the nearest half-hour or hour, depending on whether - zoomed_out is set. */ - if (!mts->all_day) { - if (mts->zoomed_out) { - if (drag_time.minute > 30) - drag_time.hour++; - drag_time.minute = 0; - } else { - drag_time.minute += 15; - drag_time.minute -= drag_time.minute % 30; - } - } else { - if (drag_time.hour > 12) - g_date_add_days (&drag_time.date, 1); - drag_time.hour = 0; - drag_time.minute = 0; - } - e_meeting_time_selector_fix_time_overflows (&drag_time); - - /* Now make sure we are between first_time & last_time. */ - if (e_meeting_time_compare_times (&drag_time, &first_time) < 0) - drag_time = first_time; - if (e_meeting_time_compare_times (&drag_time, &last_time) > 0) - drag_time = last_time; - - /* Set the meeting start or end time to drag_time. */ - if (mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_START) - time_to_set = &mts->meeting_start_time; - else - time_to_set = &mts->meeting_end_time; - - /* If the time is unchanged, just return. */ - if (e_meeting_time_compare_times (time_to_set, &drag_time) == 0) - return; - - /* Don't let an empty occur for all day events */ - if (mts->all_day - && mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_START - && e_meeting_time_compare_times (&mts->meeting_end_time, &drag_time) == 0) - return; - else if (mts->all_day - && mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_END - && e_meeting_time_compare_times (&mts->meeting_start_time, &drag_time) == 0) - return; - - *time_to_set = drag_time; - - /* Check if the start time and end time need to be switched. */ - if (e_meeting_time_compare_times (&mts->meeting_start_time, - &mts->meeting_end_time) > 0) { - drag_time = mts->meeting_start_time; - mts->meeting_start_time = mts->meeting_end_time; - mts->meeting_end_time = drag_time; - - if (mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_START) - mts->dragging_position = E_MEETING_TIME_SELECTOR_POS_END; - else - mts->dragging_position = E_MEETING_TIME_SELECTOR_POS_START; - - set_both_times = TRUE; - } - - - /* Mark the calculated positions as invalid. */ - mts->meeting_positions_valid = FALSE; - - /* Redraw the canvases. */ - gtk_widget_queue_draw (mts->display_top); - gtk_widget_queue_draw (mts->display_main); - - /* Set the times in the GnomeDateEdit widgets. */ - if (set_both_times - || mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_START) - e_meeting_time_selector_update_start_date_edit (mts); - - if (set_both_times - || mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_END) - e_meeting_time_selector_update_end_date_edit (mts); - - if (set_both_times - || mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_END - || mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_START) - gtk_signal_emit (GTK_OBJECT (mts), mts_signals [CHANGED]); -} - - -/* This is the timeout function which handles auto-scrolling when the user is - dragging one of the meeting time vertical bars outside the left or right - edge of the canvas. */ -static gboolean -e_meeting_time_selector_timeout_handler (gpointer data) -{ - EMeetingTimeSelector *mts; - EMeetingTime drag_time, *time_to_set; - gint scroll_x, max_scroll_x, scroll_y, canvas_width; - gint scroll_speed, scroll_offset; - gboolean set_both_times = FALSE; - - mts = E_MEETING_TIME_SELECTOR (data); - - GDK_THREADS_ENTER (); - - /* Return if we don't need to scroll yet. */ - if (mts->scroll_count-- > 0) { - GDK_THREADS_LEAVE (); - return TRUE; - } - - /* Get the x coords of visible part of the canvas. */ - gnome_canvas_get_scroll_offsets (GNOME_CANVAS (mts->display_main), - &scroll_x, &scroll_y); - canvas_width = mts->display_main->allocation.width; - - /* Calculate the scroll delay, between 0 and MAX_SCROLL_SPEED. */ - scroll_speed = abs (mts->last_drag_x / E_MEETING_TIME_SELECTOR_SCROLL_INCREMENT_WIDTH); - scroll_speed = MIN (scroll_speed, - E_MEETING_TIME_SELECTOR_MAX_SCROLL_SPEED); - - /* Reset the scroll count. */ - mts->scroll_count = E_MEETING_TIME_SELECTOR_MAX_SCROLL_SPEED - scroll_speed; - - /* Calculate how much we need to scroll. */ - if (mts->last_drag_x >= 0) - scroll_offset = mts->col_width; - else - scroll_offset = -mts->col_width; - - scroll_x += scroll_offset; - max_scroll_x = (mts->day_width * E_MEETING_TIME_SELECTOR_DAYS_SHOWN) - - canvas_width; - scroll_x = CLAMP (scroll_x, 0, max_scroll_x); - - /* Calculate the minimum or maximum visible time in the canvas, which - we will now set the dragged time to. */ - if (scroll_offset > 0) { - e_meeting_time_selector_calculate_time (mts, - scroll_x + canvas_width - 1, - &drag_time); - if (!mts->all_day) { - if (mts->zoomed_out) { - drag_time.minute = 0; - } else { - drag_time.minute -= drag_time.minute % 30; - } - } else { - drag_time.hour = 0; - drag_time.minute = 0; - } - } else { - e_meeting_time_selector_calculate_time (mts, scroll_x, - &drag_time); - if (!mts->all_day) { - if (mts->zoomed_out) { - if (drag_time.minute > 30) - drag_time.hour++; - drag_time.minute = 0; - } else { - drag_time.minute += 15; - drag_time.minute -= drag_time.minute % 30; - } - } else { - if (drag_time.hour > 0 || drag_time.minute > 0) - g_date_add_days (&drag_time.date, 1); - drag_time.hour = 0; - drag_time.minute = 0; - } - } - e_meeting_time_selector_fix_time_overflows (&drag_time); - - /* Set the meeting start or end time to drag_time. */ - if (mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_START) - time_to_set = &mts->meeting_start_time; - else - time_to_set = &mts->meeting_end_time; - - /* If the time is unchanged, just return. */ - if (e_meeting_time_compare_times (time_to_set, &drag_time) == 0) { - GDK_THREADS_LEAVE (); - goto scroll; - } - - /* Don't let an empty occur for all day events */ - if (mts->all_day - && mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_START - && e_meeting_time_compare_times (&mts->meeting_end_time, &drag_time) == 0) - goto scroll; - else if (mts->all_day - && mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_END - && e_meeting_time_compare_times (&mts->meeting_start_time, &drag_time) == 0) - goto scroll; - - *time_to_set = drag_time; - - /* Check if the start time and end time need to be switched. */ - if (e_meeting_time_compare_times (&mts->meeting_start_time, &mts->meeting_end_time) > 0) { - drag_time = mts->meeting_start_time; - mts->meeting_start_time = mts->meeting_end_time; - mts->meeting_end_time = drag_time; - - if (mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_START) - mts->dragging_position = E_MEETING_TIME_SELECTOR_POS_END; - else - mts->dragging_position = E_MEETING_TIME_SELECTOR_POS_START; - - set_both_times = TRUE; - } - - /* Mark the calculated positions as invalid. */ - mts->meeting_positions_valid = FALSE; - - /* Set the times in the GnomeDateEdit widgets. */ - if (set_both_times - || mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_START) - e_meeting_time_selector_update_start_date_edit (mts); - - if (set_both_times - || mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_END) - e_meeting_time_selector_update_end_date_edit (mts); - - if (set_both_times - || mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_END - || mts->dragging_position == E_MEETING_TIME_SELECTOR_POS_START) - gtk_signal_emit (GTK_OBJECT (mts), mts_signals [CHANGED]); - - scroll: - /* Redraw the canvases. We freeze and thaw the layouts so that they - get redrawn completely. Otherwise the pixels get scrolled left or - right which is not good for us (since our vertical bars have been - moved) and causes flicker. */ - gtk_layout_freeze (GTK_LAYOUT (mts->display_main)); - gtk_layout_freeze (GTK_LAYOUT (mts->display_top)); - gnome_canvas_scroll_to (GNOME_CANVAS (mts->display_main), - scroll_x, scroll_y); - gnome_canvas_scroll_to (GNOME_CANVAS (mts->display_top), - scroll_x, scroll_y); - gtk_layout_thaw (GTK_LAYOUT (mts->display_main)); - gtk_layout_thaw (GTK_LAYOUT (mts->display_top)); - - GDK_THREADS_LEAVE (); - return TRUE; -} - - -/* This removes our auto-scroll timeout function, if we have one installed. */ -void -e_meeting_time_selector_remove_timeout (EMeetingTimeSelector *mts) -{ - if (mts->auto_scroll_timeout_id) { - g_source_remove (mts->auto_scroll_timeout_id); - mts->auto_scroll_timeout_id = 0; - } -} - - -/* This updates the GnomeDateEdit widget displaying the meeting start time. */ -static void -e_meeting_time_selector_update_start_date_edit (EMeetingTimeSelector *mts) -{ - e_date_edit_set_date_and_time_of_day (E_DATE_EDIT (mts->start_date_edit), - g_date_year (&mts->meeting_start_time.date), - g_date_month (&mts->meeting_start_time.date), - g_date_day (&mts->meeting_start_time.date), - mts->meeting_start_time.hour, - mts->meeting_start_time.minute); -} - - -/* This updates the GnomeDateEdit widget displaying the meeting end time. */ -static void -e_meeting_time_selector_update_end_date_edit (EMeetingTimeSelector *mts) -{ - GDate date; - - date = mts->meeting_end_time.date; - if (mts->all_day) - g_date_subtract_days (&date, 1); - - e_date_edit_set_date_and_time_of_day (E_DATE_EDIT (mts->end_date_edit), - g_date_year (&date), - g_date_month (&date), - g_date_day (&date), - mts->meeting_end_time.hour, - mts->meeting_end_time.minute); -} - - -/* This ensures that the meeting time is shown on screen, by scrolling the - canvas and possibly by changing the range of dates shown in the canvas. */ -static void -e_meeting_time_selector_ensure_meeting_time_shown (EMeetingTimeSelector *mts) -{ - gint start_x, end_x, scroll_x, scroll_y, canvas_width; - gint new_scroll_x; - gboolean fits_in_canvas; - - /* Check if we need to change the range of dates shown. */ - if (g_date_compare (&mts->meeting_start_time.date, - &mts->first_date_shown) < 0 - || g_date_compare (&mts->meeting_end_time.date, - &mts->last_date_shown) > 0) { - e_meeting_time_selector_update_dates_shown (mts); - gtk_widget_queue_draw (mts->display_top); - gtk_widget_queue_draw (mts->display_main); - } - - /* If all of the meeting time is visible, just return. */ - e_meeting_time_selector_get_meeting_time_positions (mts, &start_x, - &end_x); - gnome_canvas_get_scroll_offsets (GNOME_CANVAS (mts->display_main), - &scroll_x, &scroll_y); - canvas_width = mts->display_main->allocation.width; - if (start_x > scroll_x && end_x <= scroll_x + canvas_width) - return; - - fits_in_canvas = end_x - start_x < canvas_width ? TRUE : FALSE; - - /* If the meeting is not entirely visible, either center it if it is - smaller than the canvas, or show the start of it if it is big. */ - if (fits_in_canvas) { - new_scroll_x = (start_x + end_x - canvas_width) / 2; - } else { - new_scroll_x = start_x; - } - gnome_canvas_scroll_to (GNOME_CANVAS (mts->display_main), - new_scroll_x, scroll_y); -} - - -/* This updates the range of dates shown in the canvas, to make sure that the - currently selected meeting time is in the range. */ -static void -e_meeting_time_selector_update_dates_shown (EMeetingTimeSelector *mts) -{ - mts->first_date_shown = mts->meeting_start_time.date; - g_date_subtract_days (&mts->first_date_shown, - E_MEETING_TIME_SELECTOR_DAYS_START_BEFORE); - - mts->last_date_shown = mts->first_date_shown; - g_date_add_days (&mts->last_date_shown, - E_MEETING_TIME_SELECTOR_DAYS_SHOWN - 1); -} - - -/* This checks if the time's hour is over 24 or its minute is over 60 and if - so it updates the day/hour appropriately. Note that hours and minutes are - stored in guint8's so they can't overflow by much. */ -void -e_meeting_time_selector_fix_time_overflows (EMeetingTime*mtstime) -{ - gint hours_to_add, days_to_add; - - hours_to_add = mtstime->minute / 60; - if (hours_to_add > 0) { - mtstime->minute -= hours_to_add * 60; - mtstime->hour += hours_to_add; - } - - days_to_add = mtstime->hour / 24; - if (days_to_add > 0) { - mtstime->hour -= days_to_add * 24; - g_date_add_days (&mtstime->date, days_to_add); - } -} - -/* - * CONVERSION ROUTINES - functions to convert between different coordinate - * spaces and dates. - */ - -/* This takes an x pixel coordinate within the entire canvas scroll region and - returns the date in which it falls. If day_position is not NULL it also - returns the x coordinate within the date, relative to the visible part of - the canvas. It is used when painting the days in the item_draw function. - Note that it must handle negative x coordinates in case we are dragging off - the edge of the canvas. */ -void -e_meeting_time_selector_calculate_day_and_position (EMeetingTimeSelector *mts, - gint x, - GDate *date, - gint *day_position) -{ - gint days_from_first_shown; - - *date = mts->first_date_shown; - - if (x >= 0) { - days_from_first_shown = x / mts->day_width; - g_date_add_days (date, days_from_first_shown); - if (day_position) - *day_position = - x % mts->day_width; - } else { - days_from_first_shown = -x / mts->day_width + 1; - g_date_subtract_days (date, days_from_first_shown); - if (day_position) - *day_position = -mts->day_width - x % mts->day_width; - } -} - - -/* This takes an x pixel coordinate within a day, and converts it to hours - and minutes, depending on working_hours_only and zoomed_out. */ -void -e_meeting_time_selector_convert_day_position_to_hours_and_mins (EMeetingTimeSelector *mts, gint day_position, guint8 *hours, guint8 *minutes) -{ - if (mts->zoomed_out) - day_position *= 3; - - /* Calculate the hours & minutes from the first displayed. */ - *hours = day_position / mts->col_width; - *minutes = (day_position % mts->col_width) * 60 / mts->col_width; - - /* Now add on the first hour shown. */ - *hours += mts->first_hour_shown; -} - - -/* This takes an x pixel coordinate within the entire canvas scroll region and - returns the time in which it falls. Note that it won't be extremely - accurate since hours may only be a few pixels wide in the display. - With zoomed_out set each pixel may represent 5 minutes or more, depending - on how small the font is. */ -void -e_meeting_time_selector_calculate_time (EMeetingTimeSelector *mts, - gint x, - EMeetingTime*time) -{ - gint day_position; - - /* First get the day and the x position within the day. */ - e_meeting_time_selector_calculate_day_and_position (mts, x, &time->date, - NULL); - - /* Now convert the day_position into an hour and minute. */ - if (x >= 0) - day_position = x % mts->day_width; - else - day_position = mts->day_width + x % mts->day_width; - - e_meeting_time_selector_convert_day_position_to_hours_and_mins (mts, day_position, &time->hour, &time->minute); -} - - -/* This takes a EMeetingTime and calculates the x pixel coordinate - within the entire canvas scroll region. It is used to draw the selected - meeting time and all the busy periods. */ -gint -e_meeting_time_selector_calculate_time_position (EMeetingTimeSelector *mts, - EMeetingTime *mtstime) -{ - gint x, date_offset, day_offset; - - /* Calculate the number of days since the first date shown in the - entire canvas scroll region. */ - date_offset = g_date_julian (&mtstime->date) - g_date_julian (&mts->first_date_shown); - - /* Calculate the x pixel coordinate of the start of the day. */ - x = date_offset * mts->day_width; - - /* Add on the hours and minutes, depending on whether zoomed_out and - working_hours_only are set. */ - day_offset = (mtstime->hour - mts->first_hour_shown) * 60 - + mtstime->minute; - /* The day width includes an extra vertical grid line so subtract 1. */ - day_offset *= (mts->day_width - 1); - day_offset /= (mts->last_hour_shown - mts->first_hour_shown) * 60; - - /* Clamp the day_offset in case the time isn't actually visible. */ - x += CLAMP (day_offset, 0, mts->day_width); - - return x; -} - -static void -rows_inserted_cb (ETableModel *etm, int row, int count, gpointer data) -{ - EMeetingTimeSelector *mts = E_MEETING_TIME_SELECTOR (data); - int i; - - /* Update the scroll region. */ - e_meeting_time_selector_update_main_canvas_scroll_region (mts); - - /* Redraw */ - gtk_widget_queue_draw (mts->display_top); - gtk_widget_queue_draw (mts->display_main); - - /* Get the latest free/busy info */ - for (i = 0; i < count; i++) - e_meeting_time_selector_refresh_free_busy (mts, row + i, FALSE); -} - -static void -cell_changed_cb (ETableModel *etm, int col, int row, gpointer data) -{ - EMeetingTimeSelector *mts = E_MEETING_TIME_SELECTOR (data); - - if (col != E_MEETING_MODEL_ADDRESS_COL) - return; - - /* Get the latest free/busy info */ - e_meeting_time_selector_refresh_free_busy (mts, row, FALSE); -} - -static void -rows_deleted_cb (ETableModel *etm, int row, int count, gpointer data) -{ - EMeetingTimeSelector *mts = E_MEETING_TIME_SELECTOR (data); - - /* Update the scroll region. */ - e_meeting_time_selector_update_main_canvas_scroll_region (mts); - - /* Redraw */ - gtk_widget_queue_draw (mts->display_top); - gtk_widget_queue_draw (mts->display_main); -} - -static void -sort_info_changed_cb (ETableSortInfo *info, gpointer data) -{ - EMeetingTimeSelector *mts = E_MEETING_TIME_SELECTOR (data); - - /* Redraw */ - gtk_widget_queue_draw (mts->display_top); - gtk_widget_queue_draw (mts->display_main); -} diff --git a/calendar/gui/e-meeting-time-sel.etspec b/calendar/gui/e-meeting-time-sel.etspec deleted file mode 100644 index c0b5c721dd..0000000000 --- a/calendar/gui/e-meeting-time-sel.etspec +++ /dev/null @@ -1,19 +0,0 @@ -<ETableSpecification click-to-add="true" click-to-add-end="true" _click-to-add-message="Click here to add an attendee" draw-grid="true"> - <ETableColumn model_col= "0" _title="Attendee" expansion="2.0" minimum_width="10" resizable="true" cell="string" compare="string"/> - <ETableColumn model_col= "1" _title="Member" expansion="2.0" minimum_width="10" resizable="true" cell="string" compare="string"/> - <ETableColumn model_col= "2" _title="Type" expansion="1.0" minimum_width="10" resizable="true" cell="typeedit" compare="string"/> - <ETableColumn model_col= "3" _title="Role" expansion="1.0" minimum_width="10" resizable="true" cell="roleedit" compare="string"/> - <ETableColumn model_col= "4" _title="RSVP" expansion="1.0" minimum_width="10" resizable="true" cell="rsvpedit" compare="string"/> - <ETableColumn model_col= "5" _title="Delegated To" expansion="2.0" minimum_width="10" resizable="true" cell="string" compare="string"/> - <ETableColumn model_col= "6" _title="Delegated From" expansion="2.0" minimum_width="10" resizable="true" cell="string" compare="string"/> - <ETableColumn model_col= "7" _title="Status" expansion="1.0" minimum_width="10" resizable="true" cell="statusedit" compare="string"/> - <ETableColumn model_col= "8" _title="Common Name" expansion="2.0" minimum_width="10" resizable="true" cell="string" compare="string"/> - <ETableColumn model_col= "9" _title="Language" expansion="2.0" minimum_width="10" resizable="true" cell="string" compare="string"/> - - <ETableState> - <column source="0"/> - <column source="2"/> - <column source="7"/> - <grouping></grouping> - </ETableState> -</ETableSpecification> diff --git a/calendar/gui/e-meeting-time-sel.h b/calendar/gui/e-meeting-time-sel.h deleted file mode 100644 index 30c1abefa7..0000000000 --- a/calendar/gui/e-meeting-time-sel.h +++ /dev/null @@ -1,384 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@gtk.org> - * - * Copyright 1999, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ -#ifndef _E_MEETING_TIME_SELECTOR_H_ -#define _E_MEETING_TIME_SELECTOR_H_ - -#include <glib.h> -#include <gtk/gtkaccelgroup.h> -#include <gtk/gtktable.h> -#include <gtk/gtkwidget.h> -#include <libgnomeui/gnome-canvas.h> -#include <gal/e-text/e-text.h> -#include <gal/e-table/e-table-model.h> -#include <gal/e-table/e-table.h> -#include "e-meeting-model.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - * EMeetingTimeSelector displays a list of attendees for a meeting and a - * graphical summary of the times which they are free and busy, allowing the - * user to select an appropriate time for a meeting. - */ - -/* Define this to include the debugging functions. */ -#undef E_MEETING_TIME_SELECTOR_DEBUG - -/* This is the width of the icon column in the attendees list. */ -#define E_MEETING_TIME_SELECTOR_ICON_COLUMN_WIDTH 24 - -#define E_MEETING_TIME_SELECTOR_TEXT_Y_PAD 3 -#define E_MEETING_TIME_SELECTOR_TEXT_X_PAD 2 - - -/* This is used to specify the format used when displaying the dates. - The full format is like 'Sunday, September 12, 1999'. The abbreviated format - is like 'Sun 12/9/99'. The short format is like '12/9/99'. The actual - format used is determined in e_meeting_time_selector_style_set(), once we - know the font being used. */ -typedef enum -{ - E_MEETING_TIME_SELECTOR_DATE_FULL, - E_MEETING_TIME_SELECTOR_DATE_ABBREVIATED_DAY, - E_MEETING_TIME_SELECTOR_DATE_SHORT -} EMeetingTimeSelectorDateFormat; - - -/* This is used to specify a position regarding the vertical bars around the - current meeting time, so we know which one is being dragged. */ -typedef enum -{ - E_MEETING_TIME_SELECTOR_POS_NONE, - E_MEETING_TIME_SELECTOR_POS_START, - E_MEETING_TIME_SELECTOR_POS_END -} EMeetingTimeSelectorPosition; - - -/* This is used to specify the autopick option, which determines how we choose - the previous/next appropriate meeting time. */ -typedef enum -{ - E_MEETING_TIME_SELECTOR_ALL_PEOPLE_AND_RESOURCES, - E_MEETING_TIME_SELECTOR_ALL_PEOPLE_AND_ONE_RESOURCE, - E_MEETING_TIME_SELECTOR_REQUIRED_PEOPLE, - E_MEETING_TIME_SELECTOR_REQUIRED_PEOPLE_AND_ONE_RESOURCE -} EMeetingTimeSelectorAutopickOption; - -/* An array of hour strings for 24 hour time, "0:00" .. "23:00". */ -extern const gchar *EMeetingTimeSelectorHours[24]; -/* An array of hour strings for 12 hour time, "12:00am" .. "11:00pm". */ -extern const gchar *EMeetingTimeSelectorHours12[24]; - - -#define E_MEETING_TIME_SELECTOR(obj) GTK_CHECK_CAST (obj, e_meeting_time_selector_get_type (), EMeetingTimeSelector) -#define E_MEETING_TIME_SELECTOR_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, e_meeting_time_selector_get_type (), EMeetingTimeSelectorClass) -#define IS_E_MEETING_TIME_SELECTOR(obj) GTK_CHECK_TYPE (obj, e_meeting_time_selector_get_type ()) - - -typedef struct _EMeetingTimeSelector EMeetingTimeSelector; -typedef struct _EMeetingTimeSelectorClass EMeetingTimeSelectorClass; - -struct _EMeetingTimeSelector -{ - /* We subclass a GtkTable which makes it easy to add extra widgets - if neccesary. */ - GtkTable table; - - /* - * User Interface stuff - widgets, colors etc. - */ - - /* This contains our keyboard accelerators, which need to be added to - the toplevel window. */ - GtkAccelGroup *accel_group; - - /* The vbox in the top-left corner, containing the 'All Attendees' - title bar packed at the end. Extra widgets can be added here - with PACK_START if necessary. */ - GtkWidget *attendees_vbox; - GtkWidget *attendees_vbox_spacer; - - /* The etable and model */ - EMeetingModel *model; - GtkWidget *etable; - - /* The canvas displaying the dates, times, and the summary - 'All Attendees' free/busy display. */ - GtkWidget *display_top; - - /* The canvas containing the free/busy displays of individual - attendees. This is separate from display_top since it also scrolls - vertically. */ - GtkWidget *display_main; - - /* This is the 'Options' button & menu. */ - GtkWidget *options_button; - GtkWidget *options_menu; - - /* This is the 'Autopick' button, menu & radio menu items. */ - GtkWidget *autopick_button; - GtkWidget *autopick_menu; - GtkWidget *autopick_all_item; - GtkWidget *autopick_all_people_one_resource_item; - GtkWidget *autopick_required_people_item; - GtkWidget *autopick_required_people_one_resource_item; - - /* The horizontal scrollbar which scrolls display_top & display_main.*/ - GtkWidget *hscrollbar; - - /* The vertical scrollbar which scrolls attendees & display_main. */ - GtkWidget *vscrollbar; - - /* The 2 EDateEdit widgets for the meeting start & end times. */ - GtkWidget *start_date_edit; - GtkWidget *end_date_edit; - - /* Colors. */ - GdkColorContext *color_context; - GdkColor bg_color; - GdkColor all_attendees_bg_color; - GdkColor meeting_time_bg_color; - GdkColor stipple_bg_color; - GdkColor attendee_list_bg_color; - GdkColor grid_color; - GdkColor grid_shadow_color; - GdkColor grid_unused_color; - GdkColor busy_colors[E_MEETING_FREE_BUSY_LAST]; - - /* The stipple used for attendees with no data. */ - GdkPixmap *stipple; - - /* GC for drawing the color key. */ - GdkGC *color_key_gc; - - /* Width of the hours strings (e.g. "1:00") in the current font. */ - gint hour_widths[24]; - - /* Whether we are using the full, abbreviated or short date format. */ - EMeetingTimeSelectorDateFormat date_format; - - /* - * Option Settings. - */ - - /* True if we are selecting all day events */ - gboolean all_day; - - /* If this is TRUE we only show hours between day_start_hour and - day_end_hour, defaults to TRUE (9am-6pm). */ - gboolean working_hours_only; - gint day_start_hour; - gint day_start_minute; - gint day_end_hour; - gint day_end_minute; - - /* If TRUE, view is compressed, with one cell for every 3 hours rather - than every hour. Defaults to FALSE. */ - gboolean zoomed_out; - - - /* - * Internal Data. - */ - - /* These are the first & last dates shown in the current scroll area. - We show E_MEETING_TIME_SELECTOR_DAYS_SHOWN days at a time. */ - GDate first_date_shown; - GDate last_date_shown; - - /* This is the current selection of the meeting time. */ - EMeetingTime meeting_start_time; - EMeetingTime meeting_end_time; - - /* These are the x pixel coordinates in the entire scroll region of - the start and end times. Set to meeting_positions_valid to FALSE to - invalidate. They will then be recomputed when needed. Always access - with e_meeting_time_selector_get_meeting_time_positions(). */ - gint meeting_positions_valid; - gint meeting_positions_in_scroll_area; - gint meeting_start_x; - gint meeting_end_x; - - /* These are the width and height of the cells, including the grid - lines which are displayed on the right and top or bottom of cells.*/ - gint row_height; - gint col_width; - - /* This is the width of a day in the display, which depends on - col_width, working_hours_only and zoomed_out. */ - gint day_width; - - /* These are the first and last hour of each day we display, depending - on working_hours_only and zoomed_out. */ - gint first_hour_shown; - gint last_hour_shown; - - /* The id of the source function for auto-scroll timeouts. */ - guint auto_scroll_timeout_id; - - /* This specifies if we are dragging one of the vertical bars around - the meeting time. */ - EMeetingTimeSelectorPosition dragging_position; - - /* The last x coordinate of the mouse, relative to either the left or - right edge of the canvas. Used in the auto_scroll_timeout function - to determine which way to scroll and how fast. */ - gint last_drag_x; - - /* This is used to determine the delay between scrolls. */ - gint scroll_count; -}; - - -struct _EMeetingTimeSelectorClass -{ - GtkTableClass parent_class; - - void (* changed) (EMeetingTimeSelector *mts); -}; - - -/* - * PUBLIC INTERFACE - note that this interface will probably change, when I - * know where the data is coming from. This is mainly just for testing for now. - */ - -GtkType e_meeting_time_selector_get_type (void); -GtkWidget* e_meeting_time_selector_new (EMeetingModel *emm); -void e_meeting_time_selector_construct (EMeetingTimeSelector * mts, EMeetingModel *emm); - -/* This returns the currently selected meeting time. - Note that months are 1-12 and days are 1-31. The start time is guaranteed to - be before or equal to the end time. You may want to check if they are equal - if that if it is a problem. */ -void e_meeting_time_selector_get_meeting_time (EMeetingTimeSelector *mts, - gint *start_year, - gint *start_month, - gint *start_day, - gint *start_hour, - gint *start_minute, - gint *end_year, - gint *end_month, - gint *end_day, - gint *end_hour, - gint *end_minute); - -/* This sets the meeting time, returning TRUE if it is valid. */ -gboolean e_meeting_time_selector_set_meeting_time (EMeetingTimeSelector *mts, - gint start_year, - gint start_month, - gint start_day, - gint start_hour, - gint start_minute, - gint end_year, - gint end_month, - gint end_day, - gint end_hour, - gint end_minute); - -void e_meeting_time_selector_set_all_day (EMeetingTimeSelector *mts, - gboolean all_day); -void e_meeting_time_selector_set_working_hours_only (EMeetingTimeSelector *mts, - gboolean working_hours_only); -void e_meeting_time_selector_set_working_hours (EMeetingTimeSelector *mts, - gint day_start_hour, - gint day_start_minute, - gint day_end_hour, - gint day_end_minute); - -void e_meeting_time_selector_set_zoomed_out (EMeetingTimeSelector *mts, - gboolean zoomed_out); - -EMeetingTimeSelectorAutopickOption e_meeting_time_selector_get_autopick_option (EMeetingTimeSelector *mts); -void e_meeting_time_selector_set_autopick_option (EMeetingTimeSelector *mts, - EMeetingTimeSelectorAutopickOption autopick_option); - -void e_meeting_time_selector_attendee_set_send_meeting_to (EMeetingTimeSelector *mts, - gint row, - gboolean send_meeting_to); - -/* Clears all busy times for the given attendee. */ -void e_meeting_time_selector_attendee_clear_busy_periods (EMeetingTimeSelector *mts, - gint row); -/* Adds one busy time for the given attendee. */ -gboolean e_meeting_time_selector_attendee_add_busy_period (EMeetingTimeSelector *mts, - gint row, - gint start_year, - gint start_month, - gint start_day, - gint start_hour, - gint start_minute, - gint end_year, - gint end_month, - gint end_day, - gint end_hour, - gint end_minute, - EMeetingFreeBusyType busy_type); - - - -/* - * INTERNAL ROUTINES - functions to communicate with the canvas items within - * the EMeetingTimeSelector. - */ - -/* This returns the x pixel coordinates of the meeting start and end times, - in the entire canvas scroll area. If it returns FALSE, then the meeting - time isn't in the current scroll area (which shouldn't really happen). */ -gboolean e_meeting_time_selector_get_meeting_time_positions (EMeetingTimeSelector *mts, - gint *start_x, - gint *end_x); - -void e_meeting_time_selector_drag_meeting_time (EMeetingTimeSelector *mts, - gint x); - -void e_meeting_time_selector_remove_timeout (EMeetingTimeSelector *mts); - -void e_meeting_time_selector_fix_time_overflows (EMeetingTime*mtstime); - -void e_meeting_time_selector_calculate_day_and_position (EMeetingTimeSelector *mts, - gint x, - GDate *date, - gint *day_position); -void e_meeting_time_selector_convert_day_position_to_hours_and_mins (EMeetingTimeSelector *mts, gint day_position, guint8 *hours, guint8 *minutes); -void e_meeting_time_selector_calculate_time (EMeetingTimeSelector *mts, - gint x, - EMeetingTime*time); -gint e_meeting_time_selector_calculate_time_position (EMeetingTimeSelector *mts, - EMeetingTime *mtstime); - -/* Debugging function to dump information on all attendees. */ -#ifdef E_MEETING_TIME_SELECTOR_DEBUG -void e_meeting_time_selector_dump (EMeetingTimeSelector *mts); -gchar* e_meeting_time_selector_dump_time (EMeetingTime*mtstime); -gchar* e_meeting_time_selector_dump_date (GDate *date); -#endif /* E_MEETING_TIME_SELECTOR_DEBUG */ - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_MEETING_TIME_SELECTOR_H_ */ diff --git a/calendar/gui/e-meeting-types.h b/calendar/gui/e-meeting-types.h deleted file mode 100644 index ab330a6d40..0000000000 --- a/calendar/gui/e-meeting-types.h +++ /dev/null @@ -1,78 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* itip-attendee.h - * - * Copyright (C) 2001 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: JP Rosevear - */ - -#ifndef _E_MEETING_TYPES_H_ -#define _E_MEETING_TYPES_H_ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <glib.h> -#include "e-meeting-types.h" - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - - - -typedef struct _EMeetingTime EMeetingTime; -typedef struct _EMeetingFreeBusyPeriod EMeetingFreeBusyPeriod; - -/* These are used to specify whether an attendee is free or busy at a - particular time. We'll probably replace this with a global calendar type. - These should be ordered in increasing order of preference. Higher precedence - busy periods will be painted over lower precedence ones. These are also - used as for loop counters, so they should start at 0 and be ordered. */ -typedef enum -{ - E_MEETING_FREE_BUSY_TENTATIVE = 0, - E_MEETING_FREE_BUSY_OUT_OF_OFFICE = 1, - E_MEETING_FREE_BUSY_BUSY = 2, - - E_MEETING_FREE_BUSY_LAST = 3 -} EMeetingFreeBusyType; - -/* This is our representation of a time. We use a GDate to store the day, - and guint8s for the hours and minutes. */ -struct _EMeetingTime -{ - GDate date; - guint8 hour; - guint8 minute; -}; - -/* This represents a busy period. */ -struct _EMeetingFreeBusyPeriod -{ - EMeetingTime start; - EMeetingTime end; - EMeetingFreeBusyType busy_type; -}; - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_MEETING_TYPES_H_ */ diff --git a/calendar/gui/e-meeting-utils.c b/calendar/gui/e-meeting-utils.c deleted file mode 100644 index 496bb8ebaa..0000000000 --- a/calendar/gui/e-meeting-utils.c +++ /dev/null @@ -1,52 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* itip-model.c - * - * Copyright (C) 2001 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: JP Rosevear - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-meeting-utils.h" - -gint -e_meeting_time_compare_times (EMeetingTime*time1, - EMeetingTime*time2) -{ - gint day_comparison; - - day_comparison = g_date_compare (&time1->date, - &time2->date); - if (day_comparison != 0) - return day_comparison; - - if (time1->hour < time2->hour) - return -1; - if (time1->hour > time2->hour) - return 1; - - if (time1->minute < time2->minute) - return -1; - if (time1->minute > time2->minute) - return 1; - - /* The start times are exactly the same. */ - return 0; -} diff --git a/calendar/gui/e-meeting-utils.h b/calendar/gui/e-meeting-utils.h deleted file mode 100644 index 4c2798fcf0..0000000000 --- a/calendar/gui/e-meeting-utils.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* itip-attendee.h - * - * Copyright (C) 2001 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: JP Rosevear - */ - -#ifndef _E_MEETING_UTILS_H_ -#define _E_MEETING_UTILS_H_ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <glib.h> -#include "e-meeting-types.h" - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - - - -gint e_meeting_time_compare_times (EMeetingTime *time1, - EMeetingTime *time2); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_MEETING_UTILS_H_ */ - - diff --git a/calendar/gui/e-tasks.c b/calendar/gui/e-tasks.c deleted file mode 100644 index 23bd46f34f..0000000000 --- a/calendar/gui/e-tasks.c +++ /dev/null @@ -1,831 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-tasks.c - * - * Copyright (C) 2001 Ximian, Inc. - * Copyright (C) 2001 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * 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-instance.h> -#include <gal/menus/gal-view-factory-etable.h> -#include <gal/menus/gal-view-etable.h> -#include "e-util/e-url.h" -#include "widgets/menus/gal-view-menus.h" -#include "dialogs/task-editor.h" -#include "cal-search-bar.h" -#include "calendar-config.h" -#include "component-factory.h" - -#include "e-tasks.h" - -/* A list of all of the ETasks widgets in use. We use this to update the - user preference settings. This will change when we switch to GConf. */ -static GList *all_tasks = NULL; - - -/* Private part of the GnomeCalendar structure */ -struct _ETasksPrivate { - /* The calendar client object we monitor */ - CalClient *client; - CalQuery *query; - - /* The ECalendarTable showing the tasks. */ - GtkWidget *tasks_view; - - /* Calendar search bar for tasks */ - GtkWidget *search_bar; - - /* View instance and the view menus handler */ - GalViewInstance *view_instance; - GalViewMenus *view_menus; -}; - - -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 char* e_tasks_get_config_filename (ETasks *tasks); - -/* Signal IDs */ -enum { - SELECTION_CHANGED, - LAST_SIGNAL -}; - -static GtkTableClass *parent_class; -static guint e_tasks_signals[LAST_SIGNAL] = { 0 }; - - -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); - - e_tasks_signals[SELECTION_CHANGED] = - gtk_signal_new ("selection_changed", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (ETasksClass, selection_changed), - gtk_marshal_NONE__INT, - GTK_TYPE_NONE, 1, - GTK_TYPE_INT); - - gtk_object_class_add_signals (object_class, e_tasks_signals, LAST_SIGNAL); - - object_class->destroy = e_tasks_destroy; - - class->selection_changed = NULL; -} - - -/* Object initialization function for the gnome calendar */ -static void -e_tasks_init (ETasks *tasks) -{ - ETasksPrivate *priv; - - priv = g_new0 (ETasksPrivate, 1); - tasks->priv = priv; - - priv->client = NULL; - priv->query = NULL; - priv->view_instance = NULL; - priv->view_menus = NULL; -} - -/* Callback used when the selection changes in the table. */ -static void -table_selection_change_cb (ETable *etable, gpointer data) -{ - ETasks *tasks; - int n_selected; - - tasks = E_TASKS (data); - - n_selected = e_table_selected_count (etable); - gtk_signal_emit (GTK_OBJECT (tasks), e_tasks_signals[SELECTION_CHANGED], - n_selected); -} - -/* Callback used when the sexp in the search bar changes */ -static void -search_bar_sexp_changed_cb (CalSearchBar *cal_search, const char *sexp, gpointer data) -{ - ETasks *tasks; - ETasksPrivate *priv; - CalendarModel *model; - - tasks = E_TASKS (data); - priv = tasks->priv; - - model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view)); - calendar_model_set_query (model, sexp); -} - -/* Callback used when the selected category in the search bar changes */ -static void -search_bar_category_changed_cb (CalSearchBar *cal_search, const char *category, gpointer data) -{ - ETasks *tasks; - ETasksPrivate *priv; - CalendarModel *model; - - tasks = E_TASKS (data); - priv = tasks->priv; - - model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view)); - calendar_model_set_default_category (model, category); -} - -#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; - CalendarModel *model; - - priv = tasks->priv; - - priv->search_bar = cal_search_bar_new (); - gtk_signal_connect (GTK_OBJECT (priv->search_bar), "sexp_changed", - GTK_SIGNAL_FUNC (search_bar_sexp_changed_cb), tasks); - gtk_signal_connect (GTK_OBJECT (priv->search_bar), "category_changed", - GTK_SIGNAL_FUNC (search_bar_category_changed_cb), tasks); - - gtk_table_attach (GTK_TABLE (tasks), priv->search_bar, 0, 1, 0, 1, - GTK_EXPAND | GTK_FILL | GTK_SHRINK, 0, 0, 0); - gtk_widget_show (priv->search_bar); - - 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); - - calendar_config_configure_e_calendar_table (E_CALENDAR_TABLE (priv->tasks_view)); - - gtk_signal_connect (GTK_OBJECT (etable), "selection_change", - GTK_SIGNAL_FUNC (table_selection_change_cb), tasks); -} - -/* Callback used when the set of categories changes in the calendar client */ -static void -client_categories_changed_cb (CalClient *client, GPtrArray *categories, gpointer data) -{ - ETasks *tasks; - ETasksPrivate *priv; - - tasks = E_TASKS (data); - priv = tasks->priv; - - cal_search_bar_set_categories (CAL_SEARCH_BAR (priv->search_bar), categories); -} - -GtkWidget * -e_tasks_construct (ETasks *tasks) -{ - ETasksPrivate *priv; - CalendarModel *model; - - g_return_val_if_fail (tasks != NULL, NULL); - g_return_val_if_fail (E_IS_TASKS (tasks), NULL); - - priv = tasks->priv; - - setup_widgets (tasks); - - 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), "categories_changed", - GTK_SIGNAL_FUNC (client_categories_changed_cb), tasks); - - model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view)); - g_assert (model != NULL); - - calendar_model_set_cal_client (model, priv->client, CALOBJ_TYPE_TODO); - - 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; - } - - all_tasks = g_list_prepend (all_tasks, tasks); - - return GTK_WIDGET (tasks); -} - - -void -e_tasks_set_ui_component (ETasks *tasks, - BonoboUIComponent *ui_component) -{ - g_return_if_fail (E_IS_TASKS (tasks)); - g_return_if_fail (ui_component == NULL || BONOBO_IS_UI_COMPONENT (ui_component)); - - e_search_bar_set_ui_component (E_SEARCH_BAR (tasks->priv->search_bar), ui_component); -} - - -static void -e_tasks_destroy (GtkObject *object) -{ - 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) { - gtk_object_unref (GTK_OBJECT (priv->client)); - priv->client = NULL; - } - - g_free (priv); - tasks->priv = NULL; - - all_tasks = g_list_remove (all_tasks, tasks); - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - -static void -set_status_message (ETasks *tasks, const char *message) -{ - ETasksPrivate *priv; - CalendarModel *model; - - priv = tasks->priv; - - model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view)); - calendar_model_set_status_message (model, message); -} - -gboolean -e_tasks_open (ETasks *tasks, - char *file) -{ - ETasksPrivate *priv; - char *config_filename; - char *message; - EUri *uri; - char *real_uri; - - 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; - - uri = e_uri_new (file); - if (!uri || !g_strncasecmp (uri->protocol, "file", 4)) - real_uri = g_concat_dir_and_file (file, "tasks.ics"); - else - real_uri = g_strdup (file); - - message = g_strdup_printf (_("Opening tasks at %s"), real_uri); - set_status_message (tasks, message); - g_free (message); - - if (!cal_client_open_calendar (priv->client, real_uri, FALSE)) { - g_message ("e_tasks_open(): Could not issue the request"); - g_free (real_uri); - e_uri_free (uri); - - 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); - g_free (real_uri); - e_uri_free (uri); - - 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; - char *location; - icaltimezone *zone; - - tasks = E_TASKS (data); - priv = tasks->priv; - - set_status_message (tasks, NULL); - - switch (status) { - case CAL_CLIENT_OPEN_SUCCESS: - /* Everything is OK */ - - /* Set the client's default timezone, if we have one. */ - location = calendar_config_get_timezone (); - zone = icaltimezone_get_builtin_timezone (location); - if (zone) - cal_client_set_default_timezone (client, zone); - 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 (); - } -} - - -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; - const char *category; - - g_return_if_fail (E_IS_TASKS (tasks)); - - priv = tasks->priv; - - tedit = task_editor_new (); - comp_editor_set_cal_client (COMP_EDITOR (tedit), priv->client); - - comp = cal_component_new (); - cal_component_set_new_vtype (comp, CAL_COMPONENT_TODO); - - category = cal_search_bar_get_category (CAL_SEARCH_BAR (priv->search_bar)); - cal_component_set_categories (comp, category); - - comp_editor_edit_comp (COMP_EDITOR (tedit), comp); - gtk_object_unref (GTK_OBJECT (comp)); - - comp_editor_focus (COMP_EDITOR (tedit)); -} - -/** - * e_tasks_complete_selected: - * @tasks: A tasks control widget - * - * Marks the selected tasks complete - **/ -void -e_tasks_complete_selected (ETasks *tasks) -{ - ETasksPrivate *priv; - ECalendarTable *cal_table; - - g_return_if_fail (tasks != NULL); - g_return_if_fail (E_IS_TASKS (tasks)); - - priv = tasks->priv; - - cal_table = E_CALENDAR_TABLE (priv->tasks_view); - - set_status_message (tasks, _("Completing tasks...")); - e_calendar_table_complete_selected (cal_table); - set_status_message (tasks, NULL); -} - -/** - * e_tasks_delete_selected: - * @tasks: A tasks control widget. - * - * Deletes the selected tasks in the task list. - **/ -void -e_tasks_delete_selected (ETasks *tasks) -{ - ETasksPrivate *priv; - ECalendarTable *cal_table; - - g_return_if_fail (tasks != NULL); - g_return_if_fail (E_IS_TASKS (tasks)); - - priv = tasks->priv; - - cal_table = E_CALENDAR_TABLE (priv->tasks_view); - set_status_message (tasks, _("Deleting selected objects...")); - e_calendar_table_delete_selected (cal_table); - set_status_message (tasks, NULL); -} - -static char * -create_sexp (void) -{ - char *sexp; - - sexp = g_strdup ("(and (= (get-vtype) \"VTODO\") (is-completed?))"); -#if 0 - g_print ("Calendar model sexp:\n%s\n", sexp); -#endif - - return sexp; -} - -/* Callback used when a component is updated in the live query */ -static void -query_obj_updated_cb (CalQuery *query, const char *uid, - gboolean query_in_progress, int n_scanned, int total, - gpointer data) -{ - ETasks *tasks; - ETasksPrivate *priv; - - tasks = E_TASKS (data); - priv = tasks->priv; - - cal_client_remove_object (priv->client, uid); -} - -/* Callback used when an evaluation error occurs when running a query */ -static void -query_eval_error_cb (CalQuery *query, const char *error_str, gpointer data) -{ - ETasks *tasks; - ETasksPrivate *priv; - - tasks = E_TASKS (data); - priv = tasks->priv; - - g_warning ("eval error: %s\n", error_str); - - set_status_message (tasks, NULL); - - gtk_signal_disconnect_by_data (GTK_OBJECT (priv->query), tasks); - gtk_object_unref (GTK_OBJECT (priv->query)); - priv->query = NULL; -} - -static void -query_query_done_cb (CalQuery *query, CalQueryDoneStatus status, const char *error_str, gpointer data) -{ - ETasks *tasks; - ETasksPrivate *priv; - - tasks = E_TASKS (data); - priv = tasks->priv; - - if (status != CAL_QUERY_DONE_SUCCESS) - g_warning ("query done: %s\n", error_str); - - set_status_message (tasks, NULL); - - gtk_signal_disconnect_by_data (GTK_OBJECT (priv->query), tasks); - gtk_object_unref (GTK_OBJECT (priv->query)); - priv->query = NULL; -} -/** - * e_tasks_expunge: - * @tasks: A tasks control widget - * - * Removes all tasks marked as completed - **/ -void -e_tasks_delete_completed (ETasks *tasks) -{ - ETasksPrivate *priv; - char *sexp; - - g_return_if_fail (tasks != NULL); - g_return_if_fail (E_IS_TASKS (tasks)); - - priv = tasks->priv; - - /* If we have a query, we are already expunging */ - if (priv->query) - return; - - sexp = create_sexp (); - - set_status_message (tasks, _("Expunging")); - priv->query = cal_client_get_query (priv->client, sexp); - g_free (sexp); - - if (!priv->query) { - set_status_message (tasks, NULL); - g_message ("update_query(): Could not create the query"); - return; - } - - gtk_signal_connect (GTK_OBJECT (priv->query), "obj_updated", - GTK_SIGNAL_FUNC (query_obj_updated_cb), tasks); - gtk_signal_connect (GTK_OBJECT (priv->query), "query_done", - GTK_SIGNAL_FUNC (query_query_done_cb), tasks); - gtk_signal_connect (GTK_OBJECT (priv->query), "eval_error", - GTK_SIGNAL_FUNC (query_eval_error_cb), tasks); -} - -/* Callback used from the view collection when we need to display a new view */ -static void -display_view_cb (GalViewInstance *instance, GalView *view, gpointer data) -{ - ETasks *tasks; - - tasks = E_TASKS (data); - - if (GAL_IS_VIEW_ETABLE (view)) { - 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); - } -} - -/** - * e_tasks_setup_view_menus: - * @tasks: A tasks widget. - * @uic: UI controller to use for the menus. - * - * Sets up the #GalView menus for a tasks control. This function should be - * called from the Bonobo control activation callback for this tasks control. - * Also, the menus should be discarded using e_tasks_discard_view_menus(). - **/ -void -e_tasks_setup_view_menus (ETasks *tasks, BonoboUIComponent *uic) -{ - ETasksPrivate *priv; - GalViewFactory *factory; - ETableSpecification *spec; - char *dir; - static GalViewCollection *collection = NULL; - - g_return_if_fail (tasks != NULL); - g_return_if_fail (E_IS_TASKS (tasks)); - g_return_if_fail (uic != NULL); - g_return_if_fail (BONOBO_IS_UI_COMPONENT (uic)); - - priv = tasks->priv; - - g_return_if_fail (priv->view_instance == NULL); - - g_assert (priv->view_instance == NULL); - g_assert (priv->view_menus == NULL); - - /* Create the view instance */ - - if (collection == NULL) { - collection = gal_view_collection_new (); - - dir = gnome_util_prepend_user_home ("/evolution/views/tasks/"); - gal_view_collection_set_storage_directories (collection, - EVOLUTION_DATADIR "/evolution/views/tasks/", - dir); - g_free (dir); - - /* Create the views */ - - spec = e_table_specification_new (); - e_table_specification_load_from_file (spec, - EVOLUTION_ETSPECDIR "/e-calendar-table.etspec"); - - factory = gal_view_factory_etable_new (spec); - gtk_object_unref (GTK_OBJECT (spec)); - gal_view_collection_add_factory (collection, factory); - gtk_object_unref (GTK_OBJECT (factory)); - - /* Load the collection and create the menus */ - - gal_view_collection_load (collection); - } - - priv->view_instance = gal_view_instance_new (collection, cal_client_get_uri (priv->client)); - - priv->view_menus = gal_view_menus_new (priv->view_instance); - gal_view_menus_apply (priv->view_menus, uic, NULL); - gtk_signal_connect (GTK_OBJECT (priv->view_instance), "display_view", - GTK_SIGNAL_FUNC (display_view_cb), tasks); - display_view_cb (priv->view_instance, gal_view_instance_get_current_view (priv->view_instance), tasks); -} - -/** - * e_tasks_discard_view_menus: - * @tasks: A tasks widget. - * - * Discards the #GalView menus used by a tasks control. This function should be - * called from the Bonobo control deactivation callback for this tasks control. - * The menus should have been set up with e_tasks_setup_view_menus(). - **/ -void -e_tasks_discard_view_menus (ETasks *tasks) -{ - ETasksPrivate *priv; - - g_return_if_fail (tasks != NULL); - g_return_if_fail (E_IS_TASKS (tasks)); - - priv = tasks->priv; - - g_return_if_fail (priv->view_instance != NULL); - - g_assert (priv->view_instance != NULL); - g_assert (priv->view_menus != NULL); - - gtk_object_unref (GTK_OBJECT (priv->view_instance)); - priv->view_instance = NULL; - - gtk_object_unref (GTK_OBJECT (priv->view_menus)); - priv->view_menus = NULL; -} - -/** - * e_tasks_get_calendar_table: - * @tasks: A tasks widget. - * - * Queries the #ECalendarTable contained in a tasks widget. - * - * Return value: The #ECalendarTable that the tasks widget uses to display its - * information. - **/ -ECalendarTable * -e_tasks_get_calendar_table (ETasks *tasks) -{ - ETasksPrivate *priv; - - g_return_val_if_fail (tasks != NULL, NULL); - g_return_val_if_fail (E_IS_TASKS (tasks), NULL); - - priv = tasks->priv; - return E_CALENDAR_TABLE (priv->tasks_view); -} - -/* This updates all the preference settings for all the ETasks widgets in use. - */ -void -e_tasks_update_all_config_settings (void) -{ - ETasks *tasks; - ETasksPrivate *priv; - GList *elem; - char *location; - icaltimezone *zone; - - location = calendar_config_get_timezone (); - zone = icaltimezone_get_builtin_timezone (location); - - for (elem = all_tasks; elem; elem = elem->next) { - tasks = E_TASKS (elem->data); - priv = tasks->priv; - - calendar_config_configure_e_calendar_table (E_CALENDAR_TABLE (priv->tasks_view)); - - if (zone) - cal_client_set_default_timezone (priv->client, zone); - } -} diff --git a/calendar/gui/e-tasks.h b/calendar/gui/e-tasks.h deleted file mode 100644 index b88e495dcc..0000000000 --- a/calendar/gui/e-tasks.h +++ /dev/null @@ -1,86 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-tasks.h - * - * Copyright (C) 2001 Ximian, Inc. - * Copyright (C) 2001 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: Federico Mena Quintero <federico@ximian.com> - * Damon Chaplin <damon@ximian.com> - */ - -#ifndef _E_TASKS_H_ -#define _E_TASKS_H_ - -#include <gtk/gtktable.h> -#include <cal-client/cal-client.h> -#include "e-calendar-table.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; - - /* Notification signals */ - void (* selection_changed) (ETasks *tasks, int n_selected); -}; - - -GtkType e_tasks_get_type (void); -GtkWidget *e_tasks_construct (ETasks *tasks); - -GtkWidget *e_tasks_new (void); - -void e_tasks_set_ui_component (ETasks *tasks, - BonoboUIComponent *ui_component); - -gboolean e_tasks_open (ETasks *tasks, - char *file); - -CalClient *e_tasks_get_cal_client (ETasks *tasks); - -void e_tasks_new_task (ETasks *tasks); -void e_tasks_complete_selected (ETasks *tasks); -void e_tasks_delete_selected (ETasks *tasks); -void e_tasks_delete_completed (ETasks *tasks); - - -void e_tasks_setup_view_menus (ETasks *tasks, BonoboUIComponent *uic); -void e_tasks_discard_view_menus (ETasks *tasks); - -ECalendarTable *e_tasks_get_calendar_table (ETasks *tasks); - -/* This updates all the preference settings for all the ETasks widgets in use. - */ -void e_tasks_update_all_config_settings (void); - -#endif /* _E_TASKS_H_ */ diff --git a/calendar/gui/e-timezone-entry.c b/calendar/gui/e-timezone-entry.c deleted file mode 100644 index 84c512b574..0000000000 --- a/calendar/gui/e-timezone-entry.c +++ /dev/null @@ -1,387 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 2001, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -/* - * ETimezoneEntry - a field for setting a timezone. It shows the timezone in - * a GtkEntry with a '...' button beside it which shows a dialog for changing - * the timezone. The dialog contains a map of the world with a point for each - * timezone, and an option menu as an alternative way of selecting the - * timezone. - */ - -#include <config.h> -#include <gtk/gtkbutton.h> -#include <gtk/gtkentry.h> -#include <gtk/gtksignal.h> -#include <gnome.h> -#include <gal/widgets/e-unicode.h> -#include <widgets/e-timezone-dialog/e-timezone-dialog.h> -#include "e-timezone-entry.h" - -/* The timezone icon for the button. */ -#include "art/timezone-16.xpm" - -struct _ETimezoneEntryPrivate { - /* This is the timezone set in e_timezone_entry_set_timezone(). - Note that we don't copy it or use a ref count - we assume it is - never destroyed for the lifetime of this widget. */ - icaltimezone *zone; - - /* This is TRUE if the timezone has been changed since being set. - If it hasn't, we can just return zone, If it has, we return the - builtin timezone with tzid. (It can only be changed to a builtin - timezone, or to 'local time', i.e. no timezone.) */ - gboolean changed; - - GtkWidget *entry; - GtkWidget *button; - - /* This can be set to the default timezone. If the current timezone - setting in the ETimezoneEntry matches this, then the entry field - is hidden. This makes the user interface simpler. */ - icaltimezone *default_zone; -}; - - -enum { - CHANGED, - LAST_SIGNAL -}; - - -static void e_timezone_entry_class_init (ETimezoneEntryClass *class); -static void e_timezone_entry_init (ETimezoneEntry *tentry); -static void e_timezone_entry_destroy (GtkObject *object); - -static void on_entry_changed (GtkEntry *entry, - ETimezoneEntry *tentry); -static void on_button_clicked (GtkWidget *widget, - ETimezoneEntry *tentry); - -static char* e_timezone_entry_get_display_name (ETimezoneEntry *tentry, - icaltimezone *zone); - -static void e_timezone_entry_set_entry_visibility (ETimezoneEntry *tentry); - - -static GtkHBoxClass *parent_class; -static guint timezone_entry_signals[LAST_SIGNAL] = { 0 }; - - -/** - * e_timezone_entry_get_type: - * - * Returns the GtkType for the ETimezoneEntry widget - */ -guint -e_timezone_entry_get_type (void) -{ - static guint timezone_entry_type = 0; - - if (!timezone_entry_type){ - GtkTypeInfo timezone_entry_info = { - "ETimezoneEntry", - sizeof (ETimezoneEntry), - sizeof (ETimezoneEntryClass), - (GtkClassInitFunc) e_timezone_entry_class_init, - (GtkObjectInitFunc) e_timezone_entry_init, - NULL, - NULL, - }; - - timezone_entry_type = gtk_type_unique (gtk_hbox_get_type (), &timezone_entry_info); - } - - return timezone_entry_type; -} - - -static void -e_timezone_entry_class_init (ETimezoneEntryClass *class) -{ - GtkObjectClass *object_class = (GtkObjectClass *) class; - - object_class = (GtkObjectClass*) class; - - parent_class = gtk_type_class (gtk_hbox_get_type ()); - - timezone_entry_signals[CHANGED] = - gtk_signal_new ("changed", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (ETimezoneEntryClass, - changed), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - gtk_object_class_add_signals (object_class, timezone_entry_signals, - LAST_SIGNAL); - - object_class->destroy = e_timezone_entry_destroy; - - class->changed = NULL; -} - - -static void -e_timezone_entry_init (ETimezoneEntry *tentry) -{ - ETimezoneEntryPrivate *priv; - GdkColormap *colormap; - GdkPixmap *timezone_icon; - GdkBitmap *timezone_mask; - GtkWidget *pixmap; - - tentry->priv = priv = g_new0 (ETimezoneEntryPrivate, 1); - - priv->zone = NULL; - priv->changed = FALSE; - priv->default_zone = NULL; - - priv->entry = gtk_entry_new (); - gtk_entry_set_editable (GTK_ENTRY (priv->entry), FALSE); - /*gtk_widget_set_usize (priv->date_entry, 90, 0);*/ - gtk_box_pack_start (GTK_BOX (tentry), priv->entry, TRUE, TRUE, 0); - gtk_widget_show (priv->entry); - gtk_signal_connect (GTK_OBJECT (priv->entry), "changed", - GTK_SIGNAL_FUNC (on_entry_changed), tentry); - - priv->button = gtk_button_new (); - gtk_signal_connect (GTK_OBJECT (priv->button), "clicked", - GTK_SIGNAL_FUNC (on_button_clicked), tentry); - gtk_box_pack_start (GTK_BOX (tentry), priv->button, FALSE, FALSE, 0); - gtk_widget_show (priv->button); - - colormap = gtk_widget_get_colormap (priv->button); - timezone_icon = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &timezone_mask, NULL, timezone_16_xpm); - - pixmap = gtk_pixmap_new (timezone_icon, timezone_mask); - gtk_container_add (GTK_CONTAINER (priv->button), pixmap); - gtk_widget_show (pixmap); -} - - -/** - * e_timezone_entry_new: - * - * Description: Creates a new #ETimezoneEntry widget which can be used - * to provide an easy to use way for entering dates and times. - * - * Returns: a new #ETimezoneEntry widget. - */ -GtkWidget * -e_timezone_entry_new (void) -{ - ETimezoneEntry *tentry; - - tentry = gtk_type_new (e_timezone_entry_get_type ()); - - return GTK_WIDGET (tentry); -} - - -static void -e_timezone_entry_destroy (GtkObject *object) -{ - ETimezoneEntry *tentry; - ETimezoneEntryPrivate *priv; - - g_return_if_fail (E_IS_TIMEZONE_ENTRY (object)); - - tentry = E_TIMEZONE_ENTRY (object); - priv = tentry->priv; - - g_free (tentry->priv); - tentry->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - -/* The arrow button beside the date field has been clicked, so we show the - popup with the ECalendar in. */ -static void -on_button_clicked (GtkWidget *widget, - ETimezoneEntry *tentry) -{ - ETimezoneEntryPrivate *priv; - ETimezoneDialog *timezone_dialog; - GtkWidget *dialog; - char *tzid = NULL, *display_name, *old_display_name; - - priv = tentry->priv; - - display_name = gtk_entry_get_text (GTK_ENTRY (priv->entry)); - - if (priv->zone) - tzid = icaltimezone_get_tzid (priv->zone); - - timezone_dialog = e_timezone_dialog_new (); - e_timezone_dialog_set_timezone (timezone_dialog, tzid, display_name); - - dialog = e_timezone_dialog_get_toplevel (timezone_dialog); - - if (gnome_dialog_run_and_close (GNOME_DIALOG (dialog)) == 0) { - tzid = e_timezone_dialog_get_timezone (E_TIMEZONE_DIALOG (timezone_dialog), &display_name); - old_display_name = gtk_entry_get_text (GTK_ENTRY (priv->entry)); - /* See if the timezone has been changed. It can only have been - changed to a builtin timezone, in which case the returned - TZID will be NULL. */ - if (strcmp (old_display_name, display_name) - || (!tzid && priv->zone)) { - priv->changed = TRUE; - priv->zone = NULL; - } - - gtk_entry_set_text (GTK_ENTRY (priv->entry), display_name); - e_timezone_entry_set_entry_visibility (tentry); - } - - gtk_object_unref (GTK_OBJECT (timezone_dialog)); -} - - -static void -on_entry_changed (GtkEntry *entry, - ETimezoneEntry *tentry) -{ - gtk_signal_emit (GTK_OBJECT (tentry), timezone_entry_signals[CHANGED]); -} - - -icaltimezone* -e_timezone_entry_get_timezone (ETimezoneEntry *tentry) -{ - ETimezoneEntryPrivate *priv; - char *display_name; - - g_return_val_if_fail (E_IS_TIMEZONE_ENTRY (tentry), NULL); - - priv = tentry->priv; - - /* If the timezone hasn't been change, we can just return the same - zone we were passed in. */ - if (!priv->changed) - return priv->zone; - - /* If the timezone has changed, it can only have been changed to a - builtin timezone or 'local time' (i.e. no timezone). */ - display_name = gtk_entry_get_text (GTK_ENTRY (priv->entry)); - - return e_timezone_dialog_get_builtin_timezone (display_name); -} - - -void -e_timezone_entry_set_timezone (ETimezoneEntry *tentry, - icaltimezone *zone) -{ - ETimezoneEntryPrivate *priv; - gchar *display_name; - - g_return_if_fail (E_IS_TIMEZONE_ENTRY (tentry)); - - priv = tentry->priv; - - priv->zone = zone; - priv->changed = FALSE; - - display_name = e_timezone_entry_get_display_name (tentry, zone); - gtk_entry_set_text (GTK_ENTRY (priv->entry), - display_name ? display_name : ""); - g_free (display_name); - - e_timezone_entry_set_entry_visibility (tentry); -} - - -/* Returns the timezone name to display to the user, in the locale's encoding. - We prefer to use the Olson city name, but fall back on the TZNAME, or - finally the TZID. We don't want to use "" as it may be wrongly interpreted - as a 'local time'. If zone is NULL, NULL is returned. The returned string - should be freed. */ -static char* -e_timezone_entry_get_display_name (ETimezoneEntry *tentry, - icaltimezone *zone) -{ - char *display_name; - - if (!zone) - return NULL; - - /* Get the UTF-8 display name from the icaltimezone. */ - display_name = icaltimezone_get_display_name (zone); - - /* We check if it is one of our builtin timezone names, in which case - we call gettext to translate it. If it isn't a builtin timezone - name, we need to convert it to the GTK+ encoding. */ - if (icaltimezone_get_builtin_timezone (display_name)) { - return g_strdup (_(display_name)); - } else { - return e_utf8_to_gtk_string (GTK_WIDGET (tentry), - display_name); - } -} - - -/* Sets the default timezone. If the current timezone matches this, then the - entry field is hidden. This is useful since most people do not use timezones - so it makes the user interface simpler. */ -void -e_timezone_entry_set_default_timezone (ETimezoneEntry *tentry, - icaltimezone *zone) -{ - ETimezoneEntryPrivate *priv; - - g_return_if_fail (E_IS_TIMEZONE_ENTRY (tentry)); - - priv = tentry->priv; - - priv->default_zone = zone; - - e_timezone_entry_set_entry_visibility (tentry); -} - - -static void -e_timezone_entry_set_entry_visibility (ETimezoneEntry *tentry) -{ - ETimezoneEntryPrivate *priv; - icaltimezone *zone; - gboolean show_entry = TRUE; - - priv = tentry->priv; - - if (priv->default_zone) { - zone = e_timezone_entry_get_timezone (tentry); - if (zone == priv->default_zone) - show_entry = FALSE; - } - - if (show_entry) - gtk_widget_show (priv->entry); - else - gtk_widget_hide (priv->entry); -} - diff --git a/calendar/gui/e-timezone-entry.h b/calendar/gui/e-timezone-entry.h deleted file mode 100644 index 4a057f681f..0000000000 --- a/calendar/gui/e-timezone-entry.h +++ /dev/null @@ -1,81 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 2001, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -/* - * ETimezoneEntry - a field for setting a timezone. It shows the timezone in - * a GtkEntry with a '...' button beside it which shows a dialog for changing - * the timezone. The dialog contains a map of the world with a point for each - * timezone, and an option menu as an alternative way of selecting the - * timezone. - */ - -#ifndef __E_TIMEZONE_ENTRY_H_ -#define __E_TIMEZONE_ENTRY_H_ - -#include <gtk/gtkhbox.h> -#include <libgnome/gnome-defs.h> -#include <cal-client/cal-client.h> - -BEGIN_GNOME_DECLS - - -#define E_TYPE_TIMEZONE_ENTRY (e_timezone_entry_get_type ()) -#define E_TIMEZONE_ENTRY(obj) (GTK_CHECK_CAST ((obj), E_TYPE_TIMEZONE_ENTRY, ETimezoneEntry)) -#define E_TIMEZONE_ENTRY_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_TIMEZONE_ENTRY, ETimezoneEntryClass)) -#define E_IS_TIMEZONE_ENTRY(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_TIMEZONE_ENTRY)) -#define E_IS_TIMEZONE_ENTRY_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), E_TYPE_TIMEZONE_ENTRY)) - - -typedef struct _ETimezoneEntry ETimezoneEntry; -typedef struct _ETimezoneEntryPrivate ETimezoneEntryPrivate; -typedef struct _ETimezoneEntryClass ETimezoneEntryClass; - -struct _ETimezoneEntry { - GtkHBox hbox; - - /*< private >*/ - ETimezoneEntryPrivate *priv; -}; - -struct _ETimezoneEntryClass { - GtkHBoxClass parent_class; - - void (* changed) (ETimezoneEntry *tentry); -}; - -guint e_timezone_entry_get_type (void); -GtkWidget* e_timezone_entry_new (void); - -icaltimezone* e_timezone_entry_get_timezone (ETimezoneEntry *tentry); -void e_timezone_entry_set_timezone (ETimezoneEntry *tentry, - icaltimezone *zone); - -/* Sets the default timezone. If the current timezone matches this, then the - entry field is hidden. This is useful since most people do not use timezones - so it makes the user interface simpler. */ -void e_timezone_entry_set_default_timezone(ETimezoneEntry *tentry, - icaltimezone *zone); - -END_GNOME_DECLS - -#endif /* __E_TIMEZONE_ENTRY_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 4d532be5bf..0000000000 --- a/calendar/gui/e-week-view-event-item.c +++ /dev/null @@ -1,901 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 1999, Ximian, Inc. - * Copyright 2001, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -/* - * 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 "e-util/e-categories-config.h" -#include "e-week-view-event-item.h" - -#include <gtk/gtksignal.h> -#include <gal/e-text/e-text.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 gboolean e_week_view_event_item_double_click (EWeekViewEventItem *wveitem, - GdkEvent *bevent); -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 *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; - 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 - E_WEEK_VIEW_ICON_R_PAD - 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; - - gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_EVENT_TEXT]); - - 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; - gboolean draw_timezone_icon = FALSE; - GSList *categories_list, *elem; - - 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++; - } - - if (event->different_timezone) { - draw_timezone_icon = TRUE; - num_icons++; - } - - cal_component_get_categories_list (comp, &categories_list); - num_icons += g_slist_length (categories_list); - - 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; - } - - if (draw_timezone_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->timezone_mask); - gdk_draw_pixmap (drawable, gc, - week_view->timezone_icon, - 0, 0, icon_x, icon_y, - E_WEEK_VIEW_ICON_WIDTH, - E_WEEK_VIEW_ICON_HEIGHT); - icon_x += icon_x_inc; - } - - /* draw categories icons */ - for (elem = categories_list; elem; elem = elem->next) { - char *category; - GdkPixmap *pixmap = NULL; - GdkBitmap *mask = NULL; - - category = (char *) elem->data; - e_categories_config_get_icon_for (category, &pixmap, &mask); - if (pixmap == NULL) - continue; - - if (icon_x + E_WEEK_VIEW_ICON_WIDTH <= x2) { - gdk_gc_set_clip_origin (gc, icon_x, icon_y); - if (mask != NULL) - gdk_gc_set_clip_mask (gc, mask); - gdk_draw_pixmap (drawable, gc, - pixmap, - 0, 0, icon_x, icon_y, - E_WEEK_VIEW_ICON_WIDTH, - E_WEEK_VIEW_ICON_HEIGHT); - icon_x += icon_x_inc; - } - gdk_pixmap_unref (pixmap); - if (mask != NULL) - gdk_bitmap_unref (mask); - } - - cal_component_free_categories_list (categories_list); - - 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_2BUTTON_PRESS: - return e_week_view_event_item_double_click (wveitem, event); - 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; - - if (bevent->button.button == 1) { - week_view->pressed_event_num = wveitem->event_num; - week_view->pressed_span_num = wveitem->span_num; - - /* 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. - */ - - return TRUE; - } 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; - } - - return FALSE; -} - - -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 gboolean -e_week_view_event_item_double_click (EWeekViewEventItem *wveitem, - GdkEvent *bevent) -{ - EWeekView *week_view; - EWeekViewEvent *event; - 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); - - e_week_view_stop_editing_event (week_view); - - if (week_view->calendar) - gnome_calendar_edit_object (week_view->calendar, event->comp, FALSE); - else - g_warning ("Calendar not set"); - - return TRUE; -} - - -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 20cace0132..0000000000 --- a/calendar/gui/e-week-view-event-item.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 1999, Ximian, Inc. - * Copyright 2001, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ -#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-layout.c b/calendar/gui/e-week-view-layout.c deleted file mode 100644 index 4ab1cf1fd9..0000000000 --- a/calendar/gui/e-week-view-layout.c +++ /dev/null @@ -1,425 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 2001, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -/* - * Lays out events for the Week & Month views of the calendar. It is also - * used for printing. - */ - -#include <config.h> - -#include "e-week-view-layout.h" - - -static void e_week_view_layout_event (EWeekViewEvent *event, - guint8 *grid, - GArray *spans, - GArray *old_spans, - gboolean multi_week_view, - gint weeks_shown, - gboolean compress_weekend, - gint start_weekday, - time_t *day_starts, - gint *rows_per_day); -static gint e_week_view_find_day (time_t time_to_find, - gboolean include_midnight_in_prev_day, - gint days_shown, - time_t *day_starts); -static gint e_week_view_find_span_end (gboolean multi_week_view, - gboolean compress_weekend, - gint display_start_day, - gint day); - - -GArray* -e_week_view_layout_events (GArray *events, - GArray *old_spans, - gboolean multi_week_view, - gint weeks_shown, - gboolean compress_weekend, - gint start_weekday, - time_t *day_starts, - gint *rows_per_day) -{ - EWeekViewEvent *event; - EWeekViewEventSpan *span; - gint num_days, day, event_num, span_num; - guint8 *grid; - GArray *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 = multi_week_view ? weeks_shown * 7 : 7; - for (day = 0; day < num_days; day++) { - 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 < events->len; event_num++) { - event = &g_array_index (events, EWeekViewEvent, event_num); - e_week_view_layout_event (event, grid, spans, old_spans, - multi_week_view, - weeks_shown, compress_weekend, - start_weekday, day_starts, - rows_per_day); - } - - /* Free the grid. */ - g_free (grid); - - /* 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); - } - - return spans; -} - - -static void -e_week_view_layout_event (EWeekViewEvent *event, - guint8 *grid, - GArray *spans, - GArray *old_spans, - gboolean multi_week_view, - gint weeks_shown, - gboolean compress_weekend, - gint start_weekday, - time_t *day_starts, - gint *rows_per_day) -{ - 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, days_shown; - EWeekViewEventSpan span, *old_span; - - days_shown = multi_week_view ? weeks_shown * 7 : 7; - start_day = e_week_view_find_day (event->start, FALSE, days_shown, - day_starts); - end_day = e_week_view_find_day (event->end, TRUE, days_shown, - day_starts); - start_day = CLAMP (start_day, 0, days_shown - 1); - end_day = CLAMP (end_day, 0, days_shown - 1); - -#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 (multi_week_view, - compress_weekend, - start_weekday, - 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; - rows_per_day[day] = MAX (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 (old_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; -} - - -/* 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 (time_t time_to_find, - gboolean include_midnight_in_prev_day, - gint days_shown, - time_t *day_starts) -{ - gint day; - - if (time_to_find < day_starts[0]) - return -1; - if (time_to_find > day_starts[days_shown]) - return days_shown; - - for (day = 1; day <= days_shown; 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 days_shown; -} - - -/* 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 (gboolean multi_week_view, - gboolean compress_weekend, - gint display_start_day, - gint day) -{ - gint week, col, sat_col, end_col; - - if (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 (compress_weekend) { - sat_col = (5 + 7 - 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; - } -} - - -void -e_week_view_layout_get_day_position (gint day, - gboolean multi_week_view, - gint weeks_shown, - gint display_start_day, - gboolean compress_weekend, - gint *day_x, - gint *day_y, - gint *rows) -{ - gint week, day_of_week, row, col, weekend_col, box, weekend_box; - - *day_x = *day_y = *rows = 0; - g_return_if_fail (day >= 0); - - if (multi_week_view) { - g_return_if_fail (day < weeks_shown * 7); - - week = day / 7; - col = day % 7; - day_of_week = (display_start_day + day) % 7; - if (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 * 2; - *rows = 1; - } else { - *day_y = week * 2 + 1; - *rows = 1; - col--; - } - /* Both Saturday and Sunday are in the same column. */ - *day_x = col; - } else { - /* If the weekend is compressed and the day is after - the weekend we have to move back a column. */ - if (compress_weekend) { - /* Calculate where the weekend column is. - Note that 5 is Saturday. */ - weekend_col = (5 + 7 - display_start_day) % 7; - if (col > weekend_col) - col--; - } - - *day_y = week * 2; - *rows = 2; - *day_x = 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 = (display_start_day + day) % 7; - weekend_box = (5 + 7 - display_start_day) % 7; - if (box > weekend_box) - box--; - - if (box < 3) - *day_x = 0; - else - *day_x = 1; - - row = (box % 3) * 2; - if (day_of_week < 5) { - *day_y = row; - *rows = 2; - } else if (day_of_week == 5) { - /* Saturday. */ - *day_y = row; - *rows = 1; - - } else { - /* Sunday. */ - *day_y = row + 1; - *rows = 1; - } - } -} - - -/* Returns TRUE if the event span is visible or FALSE if it isn't. - It also returns the number of days of the span that are visible. - 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. */ -gboolean -e_week_view_layout_get_span_position (EWeekViewEvent *event, - EWeekViewEventSpan *span, - gint rows_per_cell, - gint rows_per_compressed_cell, - gint display_start_day, - gboolean multi_week_view, - gboolean compress_weekend, - gint *span_num_days) -{ - gint end_day_of_week; - - if (span->row >= rows_per_cell) - return FALSE; - - end_day_of_week = (display_start_day + span->start_day - + span->num_days - 1) % 7; - *span_num_days = span->num_days; - /* Check if the row will not be visible in compressed cells. */ - if (span->row >= rows_per_compressed_cell) { - if (multi_week_view) { - if (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 (*span_num_days == 1) { - return FALSE; - } else { - (*span_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; - } - } - - return TRUE; -} diff --git a/calendar/gui/e-week-view-layout.h b/calendar/gui/e-week-view-layout.h deleted file mode 100644 index 2c6d5a29d8..0000000000 --- a/calendar/gui/e-week-view-layout.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 2001, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ -#ifndef _E_WEEK_VIEW_LAYOUT_H_ -#define _E_WEEK_VIEW_LAYOUT_H_ - -#include "e-week-view.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* I've split these functions away from EWeekView so we can use them for - printing. */ - -GArray* e_week_view_layout_events (GArray *events, - GArray *old_spans, - gboolean multi_week_view, - gint weeks_shown, - gboolean compress_weekend, - gint start_weekday, - time_t *day_starts, - gint *rows_per_day); - -/* Returns which 'cell' in the table the day appears in. Note that most days - have a height of 2 rows, but Sat/Sun are sometimes compressed so they have - a height of only 1 row. */ -void e_week_view_layout_get_day_position(gint day, - gboolean multi_week_view, - gint weeks_shown, - gint display_start_day, - gboolean compress_weekend, - gint *cell_x, - gint *cell_y, - gint *rows); - -gboolean e_week_view_layout_get_span_position (EWeekViewEvent *event, - EWeekViewEventSpan *span, - gint rows_per_cell, - gint rows_per_compressed_cell, - gint display_start_day, - gboolean multi_week_view, - gboolean compress_weekend, - gint *span_num_days); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_WEEK_VIEW_LAYOUT_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 60d71f0631..0000000000 --- a/calendar/gui/e-week-view-main-item.c +++ /dev/null @@ -1,401 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 1999, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -/* - * EWeekViewMainItem - displays the background grid and dates for the Week and - * Month calendar views. - */ - -#include <config.h> - -#include <glib.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.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 if (week_view->multi_week_view) { - struct icaltimetype tt; - - /* Check if we are drawing today */ - tt = icaltime_from_timet_with_zone (time (NULL), FALSE, week_view->zone); - if (g_date_year (date) == tt.year - && g_date_month (date) == tt.month - && g_date_day (date) == tt.day) - gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_TODAY]); - else - gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_DATES]); - } 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 35740479da..0000000000 --- a/calendar/gui/e-week-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, Ximian, Inc. - * Copyright 2001, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ -#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 d201a50e35..0000000000 --- a/calendar/gui/e-week-view-titles-item.c +++ /dev/null @@ -1,310 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 1999, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -/* - * 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 77fed506c8..0000000000 --- a/calendar/gui/e-week-view-titles-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, Ximian, Inc. - * Copyright 2001, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ -#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 f0913e3e28..0000000000 --- a/calendar/gui/e-week-view.c +++ /dev/null @@ -1,4379 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Authors : - * Damon Chaplin <damon@ximian.com> - * Rodrigo Moya <rodrigo@ximian.com> - * - * Copyright 1999, Ximian, Inc. - * Copyright 2001, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -/* - * EWeekView - displays the Week & Month views of the calendar. - */ - -#include <config.h> - -#include "e-week-view.h" - -#include <math.h> -#include <gdk/gdkkeysyms.h> -#include <gtk/gtkinvisible.h> -#include <gtk/gtkselection.h> -#include <gtk/gtksignal.h> -#include <gtk/gtkvscrollbar.h> -#include <gtk/gtkwindow.h> -#include <gtk/gtkmain.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <libgnome/gnome-i18n.h> -#include <libgnome/gnome-exec.h> -#include <libgnome/gnome-util.h> -#include <gdk-pixbuf/gdk-pixbuf.h> -#include <gdk-pixbuf/gnome-canvas-pixbuf.h> -#include <gal/e-text/e-text.h> -#include <gal/widgets/e-canvas-utils.h> -#include <gal/widgets/e-gui-utils.h> -#include <gal/widgets/e-unicode.h> -#include <e-util/e-dialog-utils.h> -#include "dialogs/delete-comp.h" -#include "dialogs/send-comp.h" -#include "comp-util.h" -#include "itip-utils.h" -#include "cal-util/timeutil.h" -#include "calendar-commands.h" -#include "calendar-config.h" -#include "print.h" -#include "goto.h" -#include "e-week-view-event-item.h" -#include "e-week-view-layout.h" -#include "e-week-view-main-item.h" -#include "e-week-view-titles-item.h" -#include "misc.h" - -/* Images */ -#include "art/bell.xpm" -#include "art/recur.xpm" -#include "art/timezone-16.xpm" -#include "art/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-*" - -#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 - -/* The timeout before we do a layout, so we don't do a layout for each event - we get from the server. */ -#define E_WEEK_VIEW_LAYOUT_TIMEOUT 100 - -/* Used for the status bar messages */ -#define EVOLUTION_CALENDAR_PROGRESS_IMAGE "evolution-calendar-mini.png" -static GdkPixbuf *progress_icon[2] = { NULL, NULL }; - -/* Signal IDs */ -enum { - SELECTION_CHANGED, - LAST_SIGNAL -}; -static guint e_week_view_signals[LAST_SIGNAL] = { 0 }; - - -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_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_ensure_events_sorted (EWeekView *week_view); -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 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_new_event (GtkWidget *widget, - gpointer data); -static void e_week_view_on_new_meeting (GtkWidget *widget, - gpointer data); -static void e_week_view_on_new_task (GtkWidget *widget, - gpointer data); -static void e_week_view_on_goto_today (GtkWidget *widget, - gpointer data); -static void e_week_view_on_goto_date (GtkWidget *widget, - gpointer data); -static void e_week_view_on_edit_appointment (GtkWidget *widget, - gpointer data); -static void e_week_view_on_save_as (GtkWidget *widget, - gpointer data); -static void e_week_view_on_print (GtkWidget *widget, - gpointer data); -static void e_week_view_on_print_event (GtkWidget *widget, - gpointer data); -static void e_week_view_on_meeting (GtkWidget *widget, - gpointer data); -static void e_week_view_on_forward (GtkWidget *widget, - gpointer data); -static void e_week_view_on_publish (GtkWidget *widget, - gpointer data); -static void e_week_view_on_settings (GtkWidget *widget, - gpointer data); -static void e_week_view_on_pilot_settings (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_cut (GtkWidget *widget, gpointer data); -static void e_week_view_on_copy (GtkWidget *widget, gpointer data); -static void e_week_view_on_paste (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 void invisible_destroyed (GtkWidget *invisible, EWeekView *week_view); -static void selection_get (GtkWidget *invisible, - GtkSelectionData *selection_data, - guint info, - guint time_stamp, - EWeekView *week_view); -static void selection_clear_event (GtkWidget *invisible, - GdkEventSelection *event, - EWeekView *week_view); -static void selection_received (GtkWidget *invisible, - GtkSelectionData *selection_data, - guint time, - EWeekView *week_view); - -static void e_week_view_queue_layout (EWeekView *week_view); -static void e_week_view_cancel_layout (EWeekView *week_view); -static gboolean e_week_view_layout_timeout_cb (gpointer data); - - -static GtkTableClass *parent_class; -static GdkAtom clipboard_atom = GDK_NONE; - - -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; - - e_week_view_signals[SELECTION_CHANGED] = - gtk_signal_new ("selection_changed", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (EWeekViewClass, selection_changed), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - gtk_object_class_add_signals (object_class, e_week_view_signals, LAST_SIGNAL); - - /* 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; - - class->selection_changed = NULL; - - /* clipboard atom */ - if (!clipboard_atom) - clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE); -} - - -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->sexp = g_strdup ("#t"); /* match all by default */ - week_view->query = 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->layout_timeout_id = 0; - - week_view->spans = NULL; - - week_view->zone = 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; - - week_view->default_category = 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_LEFT_PTR); - 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; - - /* Set up the inivisible widget for the clipboard selections */ - week_view->invisible = gtk_invisible_new (); - gtk_selection_add_target (week_view->invisible, - clipboard_atom, - GDK_SELECTION_TYPE_STRING, - 0); - gtk_signal_connect (GTK_OBJECT (week_view->invisible), - "selection_get", - GTK_SIGNAL_FUNC (selection_get), - (gpointer) week_view); - gtk_signal_connect (GTK_OBJECT (week_view->invisible), - "selection_clear_event", - GTK_SIGNAL_FUNC (selection_clear_event), - (gpointer) week_view); - gtk_signal_connect (GTK_OBJECT (week_view->invisible), - "selection_received", - GTK_SIGNAL_FUNC (selection_received), - (gpointer) week_view); - gtk_signal_connect (GTK_OBJECT (week_view->invisible), - "destroy", - GTK_SIGNAL_FUNC (invisible_destroyed), - (gpointer) week_view); - week_view->clipboard_selection = NULL; - - week_view->activity = 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_cancel_layout (week_view); - - e_week_view_free_events (week_view); - g_array_free (week_view->events, TRUE); - week_view->events = NULL; - - 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->sexp) { - g_free (week_view->sexp); - week_view->sexp = NULL; - } - - if (week_view->query) { - gtk_signal_disconnect_by_data (GTK_OBJECT (week_view->query), week_view); - gtk_object_unref (GTK_OBJECT (week_view->query)); - week_view->query = NULL; - } - - if (week_view->small_font) { - gdk_font_unref (week_view->small_font); - week_view->small_font = NULL; - } - - if (week_view->default_category) { - g_free (week_view->default_category); - week_view->default_category = NULL; - } - - gdk_cursor_destroy (week_view->normal_cursor); - gdk_cursor_destroy (week_view->move_cursor); - gdk_cursor_destroy (week_view->resize_width_cursor); - - if (week_view->invisible) - gtk_widget_destroy (week_view->invisible); - if (week_view->clipboard_selection) { - g_free (week_view->clipboard_selection); - week_view->clipboard_selection = NULL; - } - - if (week_view->activity) { - gtk_object_unref (GTK_OBJECT (week_view->activity)); - week_view->activity = NULL; - } - - 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 = 0xe0e0; - week_view->colors[E_WEEK_VIEW_COLOR_EVEN_MONTHS].green = 0xe0e0; - week_view->colors[E_WEEK_VIEW_COLOR_EVEN_MONTHS].blue = 0xe0e0; - - 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 = 213 * 257; - week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND].green = 213 * 257; - week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND].blue = 213 * 257; - - 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; - - week_view->colors[E_WEEK_VIEW_COLOR_TODAY].red = 65535; - week_view->colors[E_WEEK_VIEW_COLOR_TODAY].green = 0; - week_view->colors[E_WEEK_VIEW_COLOR_TODAY].blue = 0; - - 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); - week_view->timezone_icon = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &week_view->timezone_mask, NULL, timezone_16_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); - - /* Check that the small font is smaller than the default font. - If it isn't, we won't use it. */ - if (week_view->small_font) { - if (font->ascent + font->descent <= week_view->small_font->ascent + week_view->small_font->descent) - week_view->use_small_font = FALSE; - } - - /* 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 a component is updated in the live query */ -static void -query_obj_updated_cb (CalQuery *query, const char *uid, - gboolean query_in_progress, int n_scanned, int total, - gpointer data) -{ - EWeekView *week_view; - EWeekViewEvent *event; - gint event_num, num_days; - CalComponent *comp; - CalClientGetStatus status; - - week_view = E_WEEK_VIEW (data); - - /* 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; - } - - /* 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, - cal_client_resolve_tzid_cb, week_view->client, - week_view->zone); - - gtk_object_unref (GTK_OBJECT (comp)); - - e_week_view_queue_layout (week_view); -} - -/* Callback used when a component is removed from the live query */ -static void -query_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); - - gtk_widget_queue_draw (week_view->main_canvas); - e_week_view_check_layout (week_view); -} - -/* Callback used when a query ends */ -static void -query_query_done_cb (CalQuery *query, CalQueryDoneStatus status, const char *error_str, gpointer data) -{ - EWeekView *week_view; - - week_view = E_WEEK_VIEW (data); - - /* FIXME */ - - e_week_view_set_status_message (week_view, NULL); - - if (status != CAL_QUERY_DONE_SUCCESS) - fprintf (stderr, "query done: %s\n", error_str); - - gtk_widget_queue_draw (week_view->main_canvas); -} - -/* Callback used when an evaluation error occurs when running a query */ -static void -query_eval_error_cb (CalQuery *query, const char *error_str, gpointer data) -{ - EWeekView *week_view; - - week_view = E_WEEK_VIEW (data); - - /* FIXME */ - - e_week_view_set_status_message (week_view, NULL); - - fprintf (stderr, "eval error: %s\n", error_str); - - gtk_widget_queue_draw (week_view->main_canvas); -} - -/* Builds a complete query sexp for the week view by adding the predicates to - * filter only for VEVENTS that fit in the week view's time range. - */ -static char * -adjust_query_sexp (EWeekView *week_view, const char *sexp) -{ - int num_days; - char *start, *end; - char *new_sexp; - - /* If the dates have not been set yet, we just want an empty query. */ - if (!g_date_valid (&week_view->first_day_shown)) - return NULL; - - num_days = week_view->multi_week_view ? week_view->weeks_shown * 7 : 7; - - start = isodate_from_time_t (week_view->day_starts[0]); - end = isodate_from_time_t (week_view->day_starts[num_days]); - - new_sexp = g_strdup_printf ("(and (= (get-vtype) \"VEVENT\")" - " (occur-in-time-range? (make-time \"%s\")" - " (make-time \"%s\"))" - " %s)", - start, end, - sexp); - - g_free (start); - g_free (end); - - return new_sexp; -} - -/* Restarts a query for the week view */ -static void -update_query (EWeekView *week_view) -{ - CalQuery *old_query; - char *real_sexp; - - gtk_widget_queue_draw (week_view->main_canvas); - e_week_view_free_events (week_view); - e_week_view_queue_layout (week_view); - - if (!(week_view->client - && cal_client_get_load_state (week_view->client) == CAL_CLIENT_LOAD_LOADED)) - return; - - old_query = week_view->query; - week_view->query = NULL; - - if (old_query) { - gtk_signal_disconnect_by_data (GTK_OBJECT (old_query), week_view); - gtk_object_unref (GTK_OBJECT (old_query)); - } - - g_assert (week_view->sexp != NULL); - - real_sexp = adjust_query_sexp (week_view, week_view->sexp); - if (!real_sexp) { - return; /* No time range is set, so don't start a query */ - } - - e_week_view_set_status_message (week_view, _("Searching")); - week_view->query = cal_client_get_query (week_view->client, real_sexp); - g_free (real_sexp); - - if (!week_view->query) { - g_message ("update_query(): Could not create the query"); - return; - } - - gtk_signal_connect (GTK_OBJECT (week_view->query), "obj_updated", - GTK_SIGNAL_FUNC (query_obj_updated_cb), week_view); - gtk_signal_connect (GTK_OBJECT (week_view->query), "obj_removed", - GTK_SIGNAL_FUNC (query_obj_removed_cb), week_view); - gtk_signal_connect (GTK_OBJECT (week_view->query), "query_done", - GTK_SIGNAL_FUNC (query_query_done_cb), week_view); - gtk_signal_connect (GTK_OBJECT (week_view->query), "eval_error", - GTK_SIGNAL_FUNC (query_eval_error_cb), week_view); -} - -/* 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; - - update_query (week_view); -} - -/** - * 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) - update_query (week_view); - else - gtk_signal_connect (GTK_OBJECT (week_view->client), "cal_opened", - GTK_SIGNAL_FUNC (cal_opened_cb), week_view); - } -} - -/** - * e_week_view_set_query: - * @week_view: A week view. - * @sexp: S-expression that defines the query. - * - * Sets the query sexp that the week view will use for filtering the displayed - * events. - **/ -void -e_week_view_set_query (EWeekView *week_view, const char *sexp) -{ - g_return_if_fail (week_view != NULL); - g_return_if_fail (E_IS_WEEK_VIEW (week_view)); - g_return_if_fail (sexp != NULL); - - if (week_view->sexp) - g_free (week_view->sexp); - - week_view->sexp = g_strdup (sexp); - - update_query (week_view); -} - - -/** - * e_week_view_set_default_category: - * @week_view: A week view. - * @category: Default category name or NULL for no category. - * - * Sets the default category that will be used when creating new calendar - * components from the week view. - **/ -void -e_week_view_set_default_category (EWeekView *week_view, const char *category) -{ - g_return_if_fail (week_view != NULL); - g_return_if_fail (E_IS_WEEK_VIEW (week_view)); - - if (week_view->default_category) - g_free (week_view->default_category); - - week_view->default_category = g_strdup (category); -} - - -/* This sets the selected time range. The EWeekView will show the corresponding - month and the days between start_time and end_time will be selected. - To select a single day, use the same value for start_time & end_time. */ -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)); - - time_to_gdate_with_zone (&date, start_time, week_view->zone); - - 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_with_zone (start_time, -day_offset, - week_view->zone); - start_time = time_day_begin_with_zone (start_time, - week_view->zone); - e_week_view_recalc_day_starts (week_view, start_time); - update_query (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_with_zone (start_time, 1, - week_view->zone)) - week_view->selection_end_day = week_view->selection_start_day; - else { - time_to_gdate_with_zone (&end_date, end_time - 60, week_view->zone); - 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 icaltimetype start_tt = icaltime_null_time (); - 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; - - start_tt.year = g_date_year (&base_date); - start_tt.month = g_date_month (&base_date); - start_tt.day = g_date_day (&base_date); - - start_time = icaltime_as_timet_with_zone (start_tt, - week_view->zone); - - e_week_view_recalc_day_starts (week_view, start_time); - update_query (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_with_zone (tmp_time, 1, - week_view->zone); - 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); - - update_query (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); -} - - -/* The current timezone. */ -icaltimezone* -e_week_view_get_timezone (EWeekView *week_view) -{ - g_return_val_if_fail (E_IS_WEEK_VIEW (week_view), NULL); - - return week_view->zone; -} - - -void -e_week_view_set_timezone (EWeekView *week_view, - icaltimezone *zone) -{ - icaltimezone *old_zone; - struct icaltimetype tt = icaltime_null_time (); - time_t lower; - - g_return_if_fail (E_IS_WEEK_VIEW (week_view)); - - old_zone = week_view->zone; - if (old_zone == zone) - return; - - week_view->zone = zone; - - /* If we don't have a valid date set yet, just return. */ - if (!g_date_valid (&week_view->first_day_shown)) - return; - - /* Recalculate the new start of the first week. We just use exactly - the same time, but with the new timezone. */ - tt.year = g_date_year (&week_view->first_day_shown); - tt.month = g_date_month (&week_view->first_day_shown); - tt.day = g_date_day (&week_view->first_day_shown); - - lower = icaltime_as_timet_with_zone (tt, zone); - - e_week_view_recalc_day_starts (week_view, lower); - update_query (week_view); -} - - -void -e_week_view_cut_clipboard (EWeekView *week_view) -{ - EWeekViewEvent *event; - const char *uid; - - g_return_if_fail (E_IS_WEEK_VIEW (week_view)); - - if (week_view->editing_event_num == -1) - return; - - event = &g_array_index (week_view->events, EWeekViewEvent, - week_view->editing_event_num); - if (event == NULL) - return; - - e_week_view_set_status_message (week_view, _("Deleting selected objects")); - - e_week_view_copy_clipboard (week_view); - cal_component_get_uid (event->comp, &uid); - cal_client_remove_object (week_view->client, uid); - - e_week_view_set_status_message (week_view, NULL); -} - -void -e_week_view_copy_clipboard (EWeekView *week_view) -{ - EWeekViewEvent *event; - char *comp_str; - - g_return_if_fail (E_IS_WEEK_VIEW (week_view)); - - event = &g_array_index (week_view->events, EWeekViewEvent, - week_view->editing_event_num); - if (event == NULL) - return; - - comp_str = cal_component_get_as_string (event->comp); - if (week_view->clipboard_selection != NULL) - g_free (week_view->clipboard_selection); - week_view->clipboard_selection = comp_str; - gtk_selection_owner_set (week_view->invisible, clipboard_atom, GDK_CURRENT_TIME); -} - -void -e_week_view_paste_clipboard (EWeekView *week_view) -{ - g_return_if_fail (E_IS_WEEK_VIEW (week_view)); - - gtk_selection_convert (week_view->invisible, - clipboard_atom, - GDK_SELECTION_TYPE_STRING, - GDK_CURRENT_TIME); -} - - -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 cell_x, cell_y, cell_h; - - e_week_view_layout_get_day_position (day, - week_view->multi_week_view, - week_view->weeks_shown, - week_view->display_start_day, - week_view->compress_weekend, - &cell_x, &cell_y, &cell_h); - - *day_x = week_view->col_offsets[cell_x]; - *day_y = week_view->row_offsets[cell_y]; - - *day_w = week_view->col_widths[cell_x]; - *day_h = week_view->row_heights[cell_y]; - if (cell_h == 2) - *day_h += week_view->row_heights[cell_y + 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 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 (!e_week_view_layout_get_span_position (event, span, - week_view->rows_per_cell, - week_view->rows_per_compressed_cell, - week_view->display_start_day, - week_view->multi_week_view, - week_view->compress_weekend, - &num_days)) { - 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"); - if (event->type == GDK_2BUTTON_PRESS) - g_print (" is a double-click\n"); - if (week_view->pressed_event_num != -1) - g_print (" item is pressed\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; - } - - /* 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; - - /* If an event is pressed just return. */ - if (week_view->pressed_event_num != -1) - return FALSE; - - if (event->button == 1 && event->type == GDK_2BUTTON_PRESS) { - time_t dtstart, dtend; - - dtstart = week_view->day_starts[day]; - dtend = week_view->day_starts[day + 1]; - gnome_calendar_new_appointment_for (week_view->calendar, - dtstart, dtend, - TRUE, FALSE); - return TRUE; - } - - if (event->button == 1) { - /* Start the selection drag. */ - 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); - } -} - - -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; - } - - /* Hide all the jump buttons. */ - for (day = 0; day < E_WEEK_VIEW_MAX_WEEKS * 7; day++) { - gnome_canvas_item_hide (week_view->jump_buttons[day]); - } -} - - -/* 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 icaltimetype start_tt, end_tt; - - 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_tt = icaltime_from_timet_with_zone (start, FALSE, - week_view->zone); - end_tt = icaltime_from_timet_with_zone (end, FALSE, - week_view->zone); - - 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_tt.hour * 60 + start_tt.minute; - event.end_minute = end_tt.hour * 60 + end_tt.minute; - if (event.end_minute == 0 && start != end) - event.end_minute = 24 * 60; - - event.different_timezone = FALSE; - if (!cal_comp_util_compare_event_timezones (comp, week_view->client, - week_view->zone)) - event.different_timezone = TRUE; - - 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) - week_view->spans = e_week_view_layout_events - (week_view->events, week_view->spans, - week_view->multi_week_view, - week_view->weeks_shown, - week_view->compress_weekend, - week_view->display_start_day, - week_view->day_starts, - week_view->rows_per_day); - - 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_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; - } -} - - -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) { - GSList *categories_list; - - if (cal_component_has_alarms (comp)) - num_icons++; - if (cal_component_has_recurrences (comp)) - num_icons++; - if (event->different_timezone) - num_icons++; - - cal_component_get_categories_list (comp, &categories_list); - num_icons += g_slist_length (categories_list); - - cal_component_free_categories_list (categories_list); - } - - /* 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); -} - - -static void -e_week_view_on_adjustment_changed (GtkAdjustment *adjustment, - EWeekView *week_view) -{ - GDate date; - gint week_offset; - struct icaltimetype start_tt = icaltime_null_time (); - 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. */ - start_tt.year = g_date_year (&date); - start_tt.month = g_date_month (&date); - start_tt.day = g_date_day (&date); - - lower = icaltime_as_timet_with_zone (start_tt, week_view->zone); - - e_week_view_recalc_day_starts (week_view, lower); - update_query (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); - } -} - - -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, TRUE); - - /* 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); -} - - -/* Cancels the current edition by resetting the appointment's text to its original value */ -static void -cancel_editing (EWeekView *week_view) -{ - int event_num, span_num; - EWeekViewEvent *event; - EWeekViewEventSpan *span; - CalComponentText summary; - - event_num = week_view->editing_event_num; - span_num = week_view->editing_span_num; - - g_assert (event_num != -1); - - 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 text to what was in the component */ - - cal_component_get_summary (event->comp, &summary); - gtk_object_set (GTK_OBJECT (span->text_item), - "text", summary.value ? summary.value : "", - NULL); - - /* Stop editing */ - e_week_view_stop_editing_event (week_view); -} - -/* Callback used when a component is destroyed. Expects the closure data to be - * a pointer to a boolean; will set it to TRUE. - */ -static void -comp_destroy_cb (GtkObject *object, gpointer data) -{ - gboolean *destroyed; - - destroyed = data; - *destroyed = TRUE; -} - - -static gboolean -e_week_view_on_text_item_event (GnomeCanvasItem *item, - GdkEvent *gdkevent, - EWeekView *week_view) -{ - EWeekViewEvent *event; - gint event_num, span_num; - -#if 0 - g_print ("In e_week_view_on_text_item_event\n"); -#endif - - switch (gdkevent->type) { - case GDK_KEY_PRESS: - if (gdkevent && gdkevent->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; - } else if (gdkevent->key.keyval == GDK_Escape) { - cancel_editing (week_view); - gtk_signal_emit_stop_by_name (GTK_OBJECT (item), "event"); - return TRUE; - } - break; - case GDK_2BUTTON_PRESS: - if (!e_week_view_find_event_from_item (week_view, item, - &event_num, &span_num)) - return FALSE; - - event = &g_array_index (week_view->events, EWeekViewEvent, - event_num); - - if (week_view->calendar) - gnome_calendar_edit_object (week_view->calendar, - event->comp, FALSE); - else - g_warning ("Calendar not set"); - - gtk_signal_emit_stop_by_name (GTK_OBJECT (item), "event"); - return TRUE; - case GDK_BUTTON_PRESS: - if (!e_week_view_find_event_from_item (week_view, item, - &event_num, &span_num)) - return FALSE; - - if (gdkevent->button.button == 3) { - EWeekViewEvent *e; - gboolean destroyed; - int id; - - e = &g_array_index (week_view->events, EWeekViewEvent, event_num); - - destroyed = FALSE; - id = gtk_signal_connect (GTK_OBJECT (e->comp), "destroy", - GTK_SIGNAL_FUNC (comp_destroy_cb), &destroyed); - - if (!GTK_WIDGET_HAS_FOCUS (week_view)) - gtk_widget_grab_focus (GTK_WIDGET (week_view)); - - if (!destroyed) { - gtk_signal_disconnect (GTK_OBJECT (e->comp), id); - - e_week_view_show_popup_menu (week_view, - (GdkEventButton*) gdkevent, - 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 (gdkevent) { - week_view->drag_event_x = gdkevent->button.x; - week_view->drag_event_y = gdkevent->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 (gdkevent->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); - } - - gtk_signal_emit (GTK_OBJECT (week_view), - e_week_view_signals[SELECTION_CHANGED]); -} - - -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); - g_assert (text != NULL); - - if (string_is_empty (text)) { - ConfirmDeleteEmptyCompResult result; - - result = cal_comp_confirm_delete_empty_comp (event->comp, week_view->client, - GTK_WIDGET (week_view)); - - switch (result) { - case EMPTY_COMP_REMOVE_LOCALLY: { - const char *uid; - - cal_component_get_uid (event->comp, &uid); - - e_week_view_foreach_event_with_uid (week_view, uid, - e_week_view_remove_event_cb, NULL); - gtk_widget_queue_draw (week_view->main_canvas); - e_week_view_check_layout (week_view); - goto out; } - - case EMPTY_COMP_REMOVED_FROM_SERVER: - goto out; - - case EMPTY_COMP_DO_NOT_REMOVE: - /* But we cannot keep an empty summary, so make the - * canvas item refresh itself from the text that the - * component already had. - */ - - gtk_object_ref (GTK_OBJECT (event->comp)); - e_week_view_update_event_cb (week_view, event_num, event->comp); - gtk_object_unref (GTK_OBJECT (event->comp)); - goto out; - - default: - g_assert_not_reached (); - } - - g_assert_not_reached (); - } - - /* Only update the summary if necessary. */ - cal_component_get_summary (event->comp, &summary); - if (summary.value && !strcmp (text, summary.value)) { - if (!e_week_view_is_one_day_event (week_view, event_num)) - e_week_view_reshape_event_span (week_view, event_num, - span_num); - } else { - summary.value = text; - summary.altrep = NULL; - cal_component_set_summary (event->comp, &summary); - - if (cal_client_update_object (week_view->client, event->comp)) { - if (cal_component_has_attendees (event->comp) && send_component_dialog (event->comp, FALSE)) - itip_send_comp (CAL_COMPONENT_METHOD_REQUEST, event->comp, - week_view->client, NULL); - } else { - g_message ("e_week_view_on_editing_stopped(): Could not update the object!"); - } - } - - out: - - g_free (text); - - gtk_signal_emit (GTK_OBJECT (week_view), - e_week_view_signals[SELECTION_CHANGED]); -} - - -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->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK))) - || (event->length == 0) - || (event->keyval == GDK_Tab)) { - return FALSE; - } else - initial_text = e_utf8_from_gtk_event_key (widget, event->keyval, event->string); - - /* Add a new event covering the selected range. */ - comp = cal_comp_event_new_with_defaults (); - - 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; - - /* We use DATE values now, so we don't need the timezone. */ - /*date.tzid = icaltimezone_get_tzid (week_view->zone);*/ - - *date.value = icaltime_from_timet_with_zone (dtstart, TRUE, - week_view->zone); - cal_component_set_dtstart (comp, &date); - - *date.value = icaltime_from_timet_with_zone (dtend, TRUE, - week_view->zone); - cal_component_set_dtend (comp, &date); - - cal_component_set_categories (comp, week_view->default_category); - - /* We add the event locally and start editing it. We don't send it - to the server until the user finishes editing it. */ - 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"); - } - - if (initial_text) - g_free (initial_text); - - gtk_object_unref (GTK_OBJECT (comp)); - - return TRUE; -} - -enum { - /* - * This is used to "flag" events that can not be editted - */ - MASK_EDITABLE = 1, - - /* - * To disable recurring actions to be displayed - */ - MASK_RECURRING = 2, - - /* - * To disable actions for non-recurring items to be displayed - */ - MASK_SINGLE = 4, - - /* - * This is used to when an event is currently being edited - * in another window and we want to disable the event - * from being edited twice - */ - MASK_EDITING = 8 -}; - -static EPopupMenu main_items [] = { - E_POPUP_ITEM (N_("New _Appointment..."), e_week_view_on_new_appointment, 0), - E_POPUP_ITEM (N_("New All Day _Event"), e_week_view_on_new_event, 0), - E_POPUP_ITEM (N_("New Meeting"), e_week_view_on_new_meeting, 0), - E_POPUP_ITEM (N_("New Task"), e_week_view_on_new_task, 0), - - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("_Print..."), e_week_view_on_print, 0), - - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("_Paste"), e_week_view_on_paste, 0), - - E_POPUP_SEPARATOR, - - E_POPUP_SUBMENU (N_("Current View"), NULL, 0), - - E_POPUP_ITEM (N_("Go to _Today"), e_week_view_on_goto_today, 0), - E_POPUP_ITEM (N_("_Go to Date..."), e_week_view_on_goto_date, 0), - - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("_Publish Free/Busy Information"), e_week_view_on_publish, 0), - - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("_Configure..."), e_week_view_on_settings, 0), - E_POPUP_ITEM (N_("_Configure Pilot..."), e_week_view_on_pilot_settings, 0), - - E_POPUP_TERMINATOR -}; - -static EPopupMenu child_items [] = { - E_POPUP_ITEM (N_("_Open"), e_week_view_on_edit_appointment, MASK_EDITABLE | MASK_EDITING), - E_POPUP_ITEM (N_("_Save As..."), e_week_view_on_save_as, MASK_EDITABLE | MASK_EDITING), - E_POPUP_ITEM (N_("_Print..."), e_week_view_on_print_event, MASK_EDITABLE | MASK_EDITING), - - /* Only show this separator if one of the above is shown. */ - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("C_ut"), e_week_view_on_cut, MASK_EDITING | MASK_EDITABLE), - E_POPUP_ITEM (N_("_Copy"), e_week_view_on_copy, MASK_EDITING | MASK_EDITABLE), - E_POPUP_ITEM (N_("_Paste"), e_week_view_on_paste, 0), - - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("_Schedule Meeting..."), e_week_view_on_meeting, MASK_EDITABLE | MASK_EDITING), - E_POPUP_ITEM (N_("_Forward as iCalendar..."), e_week_view_on_forward, MASK_EDITABLE | MASK_EDITING), - - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("_Delete this Appointment"), e_week_view_on_delete_appointment, MASK_EDITABLE | MASK_SINGLE | MASK_EDITING), - E_POPUP_ITEM (N_("Make this Occurrence _Movable"), e_week_view_on_unrecur_appointment, MASK_RECURRING | MASK_EDITING), - E_POPUP_ITEM (N_("Delete this _Occurrence"), e_week_view_on_delete_occurrence, MASK_RECURRING | MASK_EDITING), - E_POPUP_ITEM (N_("Delete _All Occurrences"), e_week_view_on_delete_appointment, MASK_RECURRING | MASK_EDITING), - - E_POPUP_TERMINATOR -}; - -static void -free_view_popup (GtkWidget *widget, gpointer data) -{ - EWeekView *week_view = E_WEEK_VIEW (data); - - if (week_view->view_menu == NULL) - return; - - gnome_calendar_discard_view_popup (week_view->calendar, week_view->view_menu); - week_view->view_menu = NULL; -} - -void -e_week_view_show_popup_menu (EWeekView *week_view, - GdkEventButton *bevent, - gint event_num) -{ - EWeekViewEvent *event; - int have_selection; - gboolean being_edited; - guint32 disable_mask = 0, hide_mask = 0; - EPopupMenu *context_menu; - GtkMenu *popup; - - have_selection = GTK_WIDGET_HAS_FOCUS (week_view) - && week_view->selection_start_day != -1; - - /* - * 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. - */ - being_edited = FALSE; - - if (event_num == -1) { - week_view->view_menu = gnome_calendar_setup_view_popup (week_view->calendar); - main_items[9].submenu = week_view->view_menu; - context_menu = main_items; - } else { - context_menu = child_items; - event = &g_array_index (week_view->events, - EWeekViewEvent, event_num); - if (cal_component_has_recurrences (event->comp)) - hide_mask |= MASK_SINGLE; - else - hide_mask |= MASK_RECURRING; - } - - if (being_edited) - disable_mask |= MASK_EDITING; - week_view->popup_event_num = event_num; - - popup = e_popup_menu_create (context_menu, disable_mask, hide_mask, week_view); - gtk_signal_connect (GTK_OBJECT (popup), "selection-done", - GTK_SIGNAL_FUNC (free_view_popup), week_view); - e_popup_menu (popup, (GdkEvent *) bevent); -} - -static void -e_week_view_on_new_appointment (GtkWidget *widget, gpointer data) -{ - EWeekView *week_view = E_WEEK_VIEW (data); - time_t dtstart, dtend; - struct icaltimetype itt; - - /* Edit a new event. If only one day is selected we set the time to - the first 1/2-hour of the working day. */ - if (week_view->selection_start_day == week_view->selection_end_day) { - dtstart = week_view->day_starts[week_view->selection_start_day]; - itt = icaltime_from_timet_with_zone (dtstart, FALSE, - week_view->zone); - itt.hour = calendar_config_get_day_start_hour (); - itt.minute = calendar_config_get_day_start_minute (); - dtstart = icaltime_as_timet_with_zone (itt, week_view->zone); - - icaltime_adjust (&itt, 0, 0, 30, 0); - dtend = icaltime_as_timet_with_zone (itt, week_view->zone); - } else { - dtstart = week_view->day_starts[week_view->selection_start_day]; - dtend = week_view->day_starts[week_view->selection_end_day + 1]; - } - - gnome_calendar_new_appointment_for ( - week_view->calendar, dtstart, dtend, FALSE, FALSE); -} - -static void -e_week_view_on_new_event (GtkWidget *widget, gpointer data) -{ - EWeekView *week_view = E_WEEK_VIEW (data); - time_t dtstart, dtend; - - dtstart = week_view->day_starts[week_view->selection_start_day]; - dtend = week_view->day_starts[week_view->selection_end_day + 1]; - gnome_calendar_new_appointment_for ( - week_view->calendar, dtstart, dtend, TRUE, FALSE); -} - -static void -e_week_view_on_new_meeting (GtkWidget *widget, gpointer data) -{ - EWeekView *week_view = E_WEEK_VIEW (data); - time_t dtstart, dtend; - struct icaltimetype itt; - - if (week_view->selection_start_day == week_view->selection_end_day) { - dtstart = week_view->day_starts[week_view->selection_start_day]; - itt = icaltime_from_timet_with_zone (dtstart, FALSE, - week_view->zone); - itt.hour = calendar_config_get_day_start_hour (); - itt.minute = calendar_config_get_day_start_minute (); - dtstart = icaltime_as_timet_with_zone (itt, week_view->zone); - - icaltime_adjust (&itt, 0, 0, 30, 0); - dtend = icaltime_as_timet_with_zone (itt, week_view->zone); - } else { - dtstart = week_view->day_starts[week_view->selection_start_day]; - dtend = week_view->day_starts[week_view->selection_end_day + 1]; - } - - gnome_calendar_new_appointment_for ( - week_view->calendar, dtstart, dtend, FALSE, TRUE); -} - -static void -e_week_view_on_new_task (GtkWidget *widget, gpointer data) -{ - EWeekView *week_view = E_WEEK_VIEW (data); - - gnome_calendar_new_task (week_view->calendar); -} - -static void -e_week_view_on_goto_date (GtkWidget *widget, gpointer data) -{ - EWeekView *week_view = E_WEEK_VIEW (data); - - goto_dialog (week_view->calendar); -} - -static void -e_week_view_on_goto_today (GtkWidget *widget, gpointer data) -{ - EWeekView *week_view = E_WEEK_VIEW (data); - - calendar_goto_today (week_view->calendar); -} - -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, - FALSE); - else - g_warning ("Calendar not set"); -} - -static void -e_week_view_on_print (GtkWidget *widget, gpointer data) -{ - EWeekView *week_view; - time_t start; - GnomeCalendarViewType view_type; - PrintView print_view; - - week_view = E_WEEK_VIEW (data); - - gnome_calendar_get_current_time_range (week_view->calendar, &start, NULL); - view_type = gnome_calendar_get_view (week_view->calendar); - - switch (view_type) { - case GNOME_CAL_WEEK_VIEW: - print_view = PRINT_VIEW_WEEK; - break; - - case GNOME_CAL_MONTH_VIEW: - print_view = PRINT_VIEW_MONTH; - break; - - default: - g_assert_not_reached (); - return; - } - - print_calendar (week_view->calendar, FALSE, start, print_view); -} - -static void -e_week_view_on_save_as (GtkWidget *widget, gpointer data) -{ - EWeekView *week_view; - EWeekViewEvent *event; - char *filename; - char *ical_string; - FILE *file; - - 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); - - filename = e_file_dialog_save (_("Save as...")); - if (filename == NULL) - return; - - ical_string = cal_client_get_component_as_string (week_view->client, event->comp); - if (ical_string == NULL) { - g_warning ("Couldn't convert item to a string"); - return; - } - - file = fopen (filename, "w"); - if (file == NULL) { - g_warning ("Couldn't save item"); - return; - } - - fprintf (file, ical_string); - g_free (ical_string); - fclose (file); -} - -static void -e_week_view_on_print_event (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); - - print_comp (event->comp, week_view->client, FALSE); -} - -static void -e_week_view_on_meeting (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, TRUE); - else - g_warning ("Calendar not set"); -} - -static void -e_week_view_on_forward (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); - - itip_send_comp (CAL_COMPONENT_METHOD_PUBLISH, event->comp, - week_view->client, NULL); -} - -static void -e_week_view_on_publish (GtkWidget *widget, gpointer data) -{ - EWeekView *week_view; - icaltimezone *utc; - time_t start = time (NULL), end; - GList *comp_list; - - week_view = E_WEEK_VIEW (data); - - utc = icaltimezone_get_utc_timezone (); - start = time_day_begin_with_zone (start, utc); - end = time_add_week_with_zone (start, 6, utc); - - comp_list = cal_client_get_free_busy (week_view->client, NULL, start, end); - if (comp_list) { - GList *l; - - for (l = comp_list; l; l = l->next) { - CalComponent *comp = CAL_COMPONENT (l->data); - itip_send_comp (CAL_COMPONENT_METHOD_PUBLISH, comp, - week_view->client, NULL); - - gtk_object_unref (GTK_OBJECT (comp)); - } - - g_list_free (comp_list); - } -} - -static void -e_week_view_on_settings (GtkWidget *widget, gpointer data) -{ - EWeekView *week_view; - - week_view = E_WEEK_VIEW (data); - - control_util_show_settings (week_view->calendar); -} - -static void -e_week_view_on_pilot_settings (GtkWidget *widget, gpointer data) -{ - char *args[] = { - "gpilotd-control-applet", - NULL - }; - int pid; - - args[0] = gnome_is_program_in_path ("gpilotd-control-applet"); - if (!args[0]) { - e_notice (NULL, GNOME_MESSAGE_BOX_ERROR, - _("The GNOME Pilot tools do not appear to be installed on this system.")); - return; - } - - pid = gnome_execute_async (NULL, 4, args); - if (pid == -1) - e_notice (NULL, GNOME_MESSAGE_BOX_ERROR, _("Error executing %s."), args[0]); - - g_free (args[0]); -} - -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, event->start, week_view->zone); - - 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_delete_event_internal (EWeekView *week_view, gint event_num) -{ - CalComponentVType vtype; - EWeekViewEvent *event; - - event = &g_array_index (week_view->events, EWeekViewEvent, - event_num); - - vtype = cal_component_get_vtype (event->comp); - - if (delete_component_dialog (event->comp, FALSE, 1, vtype, - GTK_WIDGET (week_view))) { - 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_delete_appointment (GtkWidget *widget, gpointer data) -{ - EWeekView *week_view; - - week_view = E_WEEK_VIEW (data); - - if (week_view->popup_event_num == -1) - return; - - e_week_view_delete_event_internal (week_view, - week_view->popup_event_num); -} - - -void -e_week_view_delete_event (EWeekView *week_view) -{ - g_return_if_fail (E_IS_WEEK_VIEW (week_view)); - - if (week_view->editing_event_num == -1) - return; - - e_week_view_delete_event_internal (week_view, - week_view->editing_event_num); -} - - -static void -e_week_view_on_cut (GtkWidget *widget, gpointer data) -{ - EWeekView *week_view; - EWeekViewEvent *event; - const char *uid; - - week_view = E_WEEK_VIEW (data); - - e_week_view_on_copy (widget, data); - - if (week_view->popup_event_num == -1) - return; - - event = &g_array_index (week_view->events, EWeekViewEvent, - week_view->popup_event_num); - - cal_component_get_uid (event->comp, &uid); - cal_client_remove_object (week_view->client, uid); -} - -static void -e_week_view_on_copy (GtkWidget *widget, gpointer data) -{ - EWeekView *week_view; - EWeekViewEvent *event; - char *comp_str; - - 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); - - comp_str = cal_component_get_as_string (event->comp); - if (week_view->clipboard_selection) - g_free (week_view->clipboard_selection); - week_view->clipboard_selection = comp_str; - - gtk_selection_owner_set (week_view->invisible, clipboard_atom, GDK_CURRENT_TIME); -} - -static void -e_week_view_on_paste (GtkWidget *widget, gpointer data) -{ - EWeekView *week_view = E_WEEK_VIEW (data); - - gtk_selection_convert (week_view->invisible, - clipboard_atom, - GDK_SELECTION_TYPE_STRING, - GDK_CURRENT_TIME); -} - -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, event->start, week_view->zone); - - /* 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 = icaltimezone_get_tzid (week_view->zone); - - *date.value = icaltime_from_timet_with_zone (event->start, FALSE, - week_view->zone); - cal_component_set_dtstart (new_comp, &date); - *date.value = icaltime_from_timet_with_zone (event->end, FALSE, - week_view->zone); - 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; -} - -static void -invisible_destroyed (GtkWidget *invisible, EWeekView *week_view) -{ - week_view->invisible = NULL; -} - -static void -selection_get (GtkWidget *invisible, - GtkSelectionData *selection_data, - guint info, - guint time_stamp, - EWeekView *week_view) -{ - if (week_view->clipboard_selection != NULL) { - gtk_selection_data_set (selection_data, - GDK_SELECTION_TYPE_STRING, - 8, - week_view->clipboard_selection, - strlen (week_view->clipboard_selection)); - } -} - -static void -selection_clear_event (GtkWidget *invisible, - GdkEventSelection *event, - EWeekView *week_view) -{ - if (week_view->clipboard_selection != NULL) { - g_free (week_view->clipboard_selection); - week_view->clipboard_selection = NULL; - } -} - -static void -selection_received (GtkWidget *invisible, - GtkSelectionData *selection_data, - guint time, - EWeekView *week_view) -{ - char *comp_str; - icalcomponent *icalcomp; - icalcomponent_kind kind; - CalComponent *comp; - time_t selected_time; - struct icaltimetype itime; - struct icaltimetype tmp_itime; - time_t tt_start, tt_end; - struct icaldurationtype ic_dur; - char *uid; - CalComponentDateTime ccdt; - - g_return_if_fail (E_IS_WEEK_VIEW (week_view)); - - if (selection_data->length < 0 || - selection_data->type != GDK_SELECTION_TYPE_STRING) { - return; - } - - comp_str = (char *) selection_data->data; - icalcomp = icalparser_parse_string ((const char *) comp_str); - if (!icalcomp) - return; - - /* check the type of the component */ - kind = icalcomponent_isa (icalcomp); - if (kind != ICAL_VCALENDAR_COMPONENT && - kind != ICAL_VEVENT_COMPONENT && - kind != ICAL_VTODO_COMPONENT && - kind != ICAL_VJOURNAL_COMPONENT) { - return; - } - - e_week_view_set_status_message (week_view, _("Updating objects")); - selected_time = week_view->day_starts[week_view->selection_start_day]; - - if (kind == ICAL_VCALENDAR_COMPONENT) { - icalcomponent_kind child_kind; - icalcomponent *subcomp; - - subcomp = icalcomponent_get_first_component ( - icalcomp, ICAL_ANY_COMPONENT); - while (subcomp) { - child_kind = icalcomponent_isa (subcomp); - if (child_kind == ICAL_VEVENT_COMPONENT || - child_kind == ICAL_VTODO_COMPONENT || - child_kind == ICAL_VJOURNAL_COMPONENT) { - icalcomponent *new_icalcomp; - - new_icalcomp = icalcomponent_new_clone (subcomp); - comp = cal_component_new (); - - /* change the day for the event */ - tt_start = icaltime_as_timet ( - icalcomponent_get_dtstart (new_icalcomp)); - tt_end = icaltime_as_timet ( - icalcomponent_get_dtend (new_icalcomp)); - ic_dur = icaldurationtype_from_int (tt_end - tt_start); - - tmp_itime = icaltime_from_timet_with_zone ( - selected_time, FALSE, week_view->zone); - itime = icalcomponent_get_dtstart (new_icalcomp); - itime.year = tmp_itime.year; - itime.month = tmp_itime.month; - itime.day = tmp_itime.day; - - cal_component_set_icalcomponent (comp, new_icalcomp); - ccdt.value = &itime; - ccdt.tzid = icaltimezone_get_tzid (week_view->zone); - cal_component_set_dtstart (comp, &ccdt); - - itime = icaltime_add (itime, ic_dur); - ccdt.value = &itime; - cal_component_set_dtend (comp, &ccdt); - - uid = cal_component_gen_uid (); - cal_component_set_uid (comp, uid); - - cal_client_update_object (week_view->client, comp); - - g_free (uid); - gtk_object_unref (GTK_OBJECT (comp)); - } - subcomp = icalcomponent_get_next_component ( - icalcomp, ICAL_ANY_COMPONENT); - } - - icalcomponent_free (icalcomp); - - } - else { - comp = cal_component_new (); - - /* change the day for the event */ - tt_start = icaltime_as_timet (icalcomponent_get_dtstart (icalcomp)); - tt_end = icaltime_as_timet (icalcomponent_get_dtend (icalcomp)); - ic_dur = icaldurationtype_from_int (tt_end - tt_start); - - tmp_itime = icaltime_from_timet_with_zone ( - selected_time, FALSE, week_view->zone); - itime = icalcomponent_get_dtstart (icalcomp); - itime.year = tmp_itime.year; - itime.month = tmp_itime.month; - itime.day = tmp_itime.day; - - cal_component_set_icalcomponent (comp, icalcomp); - ccdt.value = &itime; - ccdt.tzid = icaltimezone_get_tzid (week_view->zone); - cal_component_set_dtstart (comp, &ccdt); - - itime = icaltime_add (itime, ic_dur); - ccdt.value = &itime; - cal_component_set_dtend (comp, &ccdt); - - uid = cal_component_gen_uid (); - cal_component_set_uid (comp, (const char *) uid); - - cal_client_update_object (week_view->client, comp); - - g_free (uid); - gtk_object_unref (GTK_OBJECT (comp)); - } - - e_week_view_set_status_message (week_view, NULL); -} - - -/* Gets the visible time range. Returns FALSE if no time range has been set. */ -gboolean -e_week_view_get_visible_time_range (EWeekView *week_view, - time_t *start_time, - time_t *end_time) -{ - gint num_days; - - /* If we don't have a valid date set yet, return FALSE. */ - if (!g_date_valid (&week_view->first_day_shown)) - return FALSE; - - num_days = week_view->multi_week_view ? week_view->weeks_shown * 7 : 7; - *start_time = week_view->day_starts[0]; - *end_time = week_view->day_starts[num_days]; - - return TRUE; -} - - -/* Queues a layout, unless one is already queued. */ -static void -e_week_view_queue_layout (EWeekView *week_view) -{ - if (week_view->layout_timeout_id == 0) { - week_view->layout_timeout_id = g_timeout_add (E_WEEK_VIEW_LAYOUT_TIMEOUT, e_week_view_layout_timeout_cb, week_view); - } -} - - -/* Removes any queued layout. */ -static void -e_week_view_cancel_layout (EWeekView *week_view) -{ - if (week_view->layout_timeout_id != 0) { - gtk_timeout_remove (week_view->layout_timeout_id); - week_view->layout_timeout_id = 0; - } -} - - -static gboolean -e_week_view_layout_timeout_cb (gpointer data) -{ - EWeekView *week_view = E_WEEK_VIEW (data); - - gtk_widget_queue_draw (week_view->main_canvas); - e_week_view_check_layout (week_view); - - week_view->layout_timeout_id = 0; - return FALSE; -} - - -/* Returns the number of selected events (0 or 1 at present). */ -gint -e_week_view_get_num_events_selected (EWeekView *week_view) -{ - g_return_val_if_fail (E_IS_WEEK_VIEW (week_view), 0); - - return (week_view->editing_event_num != -1) ? 1 : 0; -} - -/* Displays a message on the activity client. */ -void -e_week_view_set_status_message (EWeekView *week_view, const char *message) -{ - extern EvolutionShellClient *global_shell_client; /* ugly */ - - g_return_if_fail (E_IS_WEEK_VIEW (week_view)); - - if (!message || !*message) { - if (week_view->activity) { - gtk_object_unref (GTK_OBJECT (week_view->activity)); - week_view->activity = NULL; - } - } - else if (!week_view->activity) { - int display; - char *client_id = g_strdup_printf ("%p", week_view); - - if (progress_icon[0] == NULL) - progress_icon[0] = gdk_pixbuf_new_from_file (EVOLUTION_IMAGESDIR "/" EVOLUTION_CALENDAR_PROGRESS_IMAGE); - week_view->activity = evolution_activity_client_new ( - global_shell_client, client_id, - progress_icon, message, TRUE, &display); - - g_free (client_id); - } - else - evolution_activity_client_update (week_view->activity, message, -1.0); -} diff --git a/calendar/gui/e-week-view.h b/calendar/gui/e-week-view.h deleted file mode 100644 index 689874cc25..0000000000 --- a/calendar/gui/e-week-view.h +++ /dev/null @@ -1,511 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 1999, Ximian, Inc. - * Copyright 2001, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ -#ifndef _E_WEEK_VIEW_H_ -#define _E_WEEK_VIEW_H_ - -#include <gtk/gtktable.h> -#include <libgnomeui/gnome-canvas.h> -#include <gal/widgets/e-popup-menu.h> - -#include "gnome-cal.h" -#include "evolution-activity-client.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 1 -#define E_WEEK_VIEW_ICON_Y_PAD 1 -#define E_WEEK_VIEW_ICON_R_PAD 1 - -/* 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 - -/* 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 - -/* 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_TODAY, - - 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; - guint8 num_spans; - - /* TRUE if the event is at a different UTC offset than our current - timezone, i.e. it is in a different timezone. */ - guint different_timezone : 1; -}; - - -#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; - - /* S-expression for query and the query object */ - char *sexp; - CalQuery *query; - - /* The array of EWeekViewEvent elements. */ - GArray *events; - gboolean events_sorted; - gboolean events_need_layout; - gboolean events_need_reshape; - - /* The ID of the timeout function for doing a new layout. */ - gint layout_timeout_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 timezone. */ - icaltimezone *zone; - - /* 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; - GdkPixmap *timezone_icon; - GdkBitmap *timezone_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; - EPopupMenu *view_menu; - - /* 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; - - /* the invisible widget to manage the clipboard selections */ - GtkWidget *invisible; - gchar *clipboard_selection; - - /* The default category for new events */ - char *default_category; - - /* The activity client used to show messages on the status bar. */ - EvolutionActivityClient *activity; -}; - -struct _EWeekViewClass -{ - GtkTableClass parent_class; - - /* Notification signals */ - void (* selection_changed) (EWeekView *week_view); -}; - - -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); - -void e_week_view_set_query (EWeekView *week_view, - const char *sexp); - -void e_week_view_set_default_category (EWeekView *week_view, - const char *category); - -/* The selected time range. The EWeekView will show the corresponding - month and the days between start_time and end_time will be selected. - To select a single day, use the same value for start_time & end_time. */ -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); - -/* Gets the visible time range. Returns FALSE if no time range has been set. */ -gboolean e_week_view_get_visible_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); - -/* The current timezone. */ -icaltimezone* e_week_view_get_timezone (EWeekView *week_view); -void e_week_view_set_timezone (EWeekView *week_view, - icaltimezone *zone); - -/* Clipboard related functions */ -void e_week_view_cut_clipboard (EWeekView *week_view); -void e_week_view_copy_clipboard (EWeekView *week_view); -void e_week_view_paste_clipboard (EWeekView *week_view); - -void e_week_view_delete_event (EWeekView *week_view); - -/* Returns the number of selected events (0 or 1 at present). */ -gint e_week_view_get_num_events_selected (EWeekView *week_view); - -/* - * 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); - -gint e_week_view_event_sort_func (const void *arg1, - const void *arg2); - -void e_week_view_set_status_message (EWeekView *week_view, - const char *message); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_WEEK_VIEW_H_ */ diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c deleted file mode 100644 index ad6b485a6c..0000000000 --- a/calendar/gui/gnome-cal.c +++ /dev/null @@ -1,2893 +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 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#include <config.h> -#include <unistd.h> -#include <signal.h> -#include <sys/wait.h> -#include <fcntl.h> -#include <glib.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <libgnome/gnome-util.h> -#include <libgnomeui/gnome-dialog.h> -#include <libgnomeui/gnome-dialog-util.h> -#include <liboaf/liboaf.h> -#include <bonobo/bonobo-exception.h> -#include <gal/e-paned/e-hpaned.h> -#include <gal/e-paned/e-vpaned.h> -#include "e-util/e-url.h" -#include <cal-util/timeutil.h> -#include "widgets/menus/gal-view-menus.h" -#include "dialogs/event-editor.h" -#include "dialogs/task-editor.h" -#include "comp-util.h" -#include "e-day-view.h" -#include "e-week-view.h" -#include "evolution-calendar.h" -#include "gnome-cal.h" -#include "component-factory.h" -#include "cal-search-bar.h" -#include "calendar-commands.h" -#include "calendar-config.h" -#include "calendar-view.h" -#include "calendar-view-factory.h" -#include "tag-calendar.h" - - - -/* Private part of the GnomeCalendar structure */ -struct _GnomeCalendarPrivate { - /* - * The Calendar Folder. - */ - - /* The calendar client object we monitor */ - CalClient *client; - - /* Set of categories from the calendar client */ - GPtrArray *cal_categories; - - /* - * The TaskPad Folder. - */ - - /* The calendar client object we monitor */ - CalClient *task_pad_client; - - /* Set of categories from the tasks client */ - GPtrArray *tasks_categories; - - /* - * 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 *search_bar; - - GtkWidget *hpane; - GtkWidget *notebook; - GtkWidget *vpane; - ECalendar *date_navigator; - GtkWidget *todo; - - GtkWidget *day_view; - GtkWidget *work_week_view; - GtkWidget *week_view; - GtkWidget *month_view; - - /* Calendar query for the date navigator */ - CalQuery *dn_query; - char *sexp; - - /* 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. */ - GnomeCalendarViewType 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; - - /* View instance and menus for the control */ - GalViewInstance *view_instance; - GalViewMenus *view_menus; - - /* Whether we are being destroyed and should not mess with the object - * editor hash table. - */ - guint in_destroy : 1; - - /* Our current timezone. */ - icaltimezone *zone; - - /* The dates currently shown. If they are -1 then we have no dates - shown. We only use these to check if we need to emit a - 'dates-shown-changed' signal.*/ - time_t visible_start; - time_t visible_end; -}; - -/* Signal IDs */ - -enum { - DATES_SHOWN_CHANGED, - CALENDAR_SELECTION_CHANGED, - TASKPAD_SELECTION_CHANGED, - CALENDAR_FOCUS_CHANGE, - TASKPAD_FOCUS_CHANGE, - LAST_SIGNAL -}; - -/* Used to indicate who has the focus within the calendar view */ -typedef enum { - FOCUS_CALENDAR, - FOCUS_TASKPAD, - FOCUS_OTHER -} FocusLocation; - -static guint gnome_calendar_signals[LAST_SIGNAL]; - - - - -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_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 void gnome_calendar_notify_dates_shown_changed (GnomeCalendar *gcal); - -static void update_query (GnomeCalendar *gcal); - - -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); - - gnome_calendar_signals[DATES_SHOWN_CHANGED] = - gtk_signal_new ("dates_shown_changed", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (GnomeCalendarClass, - dates_shown_changed), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - gnome_calendar_signals[CALENDAR_SELECTION_CHANGED] = - gtk_signal_new ("calendar_selection_changed", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (GnomeCalendarClass, calendar_selection_changed), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - gnome_calendar_signals[TASKPAD_SELECTION_CHANGED] = - gtk_signal_new ("taskpad_selection_changed", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (GnomeCalendarClass, taskpad_selection_changed), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - gnome_calendar_signals[CALENDAR_FOCUS_CHANGE] = - gtk_signal_new ("calendar_focus_change", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (GnomeCalendarClass, calendar_focus_change), - gtk_marshal_NONE__BOOL, - GTK_TYPE_NONE, 1, - GTK_TYPE_BOOL); - - gnome_calendar_signals[TASKPAD_FOCUS_CHANGE] = - gtk_signal_new ("taskpad_focus_change", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (GnomeCalendarClass, taskpad_focus_change), - gtk_marshal_NONE__BOOL, - GTK_TYPE_NONE, 1, - GTK_TYPE_BOOL); - - gtk_object_class_add_signals (object_class, - gnome_calendar_signals, - LAST_SIGNAL); - - object_class->destroy = gnome_calendar_destroy; - - class->dates_shown_changed = NULL; - class->calendar_selection_changed = NULL; - class->taskpad_selection_changed = NULL; - class->calendar_focus_change = NULL; - class->taskpad_focus_change = NULL; -} - -/* Callback used when the calendar query reports of an updated object */ -static void -dn_query_obj_updated_cb (CalQuery *query, const char *uid, - gboolean query_in_progress, int n_scanned, int total, - gpointer data) -{ - GnomeCalendar *gcal; - GnomeCalendarPrivate *priv; - CalComponent *comp; - CalClientGetStatus status; - - gcal = GNOME_CALENDAR (data); - priv = gcal->priv; - - /* If this is an update that is not part of an ongoing query, we have to - * retag the whole thing: an event may change dates and the - * tag_calendar_by_comp() below would not know how to untag the old - * dates. - */ - if (!query_in_progress) { - update_query (gcal); - return; - } - - 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 ("dn_query_obj_updated_cb(): Syntax error while getting object `%s'", uid); - break; - - case CAL_CLIENT_GET_NOT_FOUND: - /* The object is no longer in the server, so do nothing */ - break; - - default: - g_assert_not_reached (); - return; - } - - tag_calendar_by_comp (priv->date_navigator, comp, priv->client, FALSE, - TRUE); - gtk_object_unref (GTK_OBJECT (comp)); -} - -/* Callback used when the calendar query reports of a removed object */ -static void -dn_query_obj_removed_cb (CalQuery *query, const char *uid, gpointer data) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - /* Just retag the whole thing */ - update_query (gcal); -} - -/* Callback used when the calendar query is done */ -static void -dn_query_query_done_cb (CalQuery *query, CalQueryDoneStatus status, const char *error_str, - gpointer data) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - /* FIXME */ - - if (status != CAL_QUERY_DONE_SUCCESS) - fprintf (stderr, "query done: %s\n", error_str); -} - -/* Callback used when the calendar query reports an evaluation error */ -static void -dn_query_eval_error_cb (CalQuery *query, const char *error_str, gpointer data) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - /* FIXME */ - - fprintf (stderr, "eval error: %s\n", error_str); -} - -/* Returns the current view widget, a EDayView or EWeekView. */ -static GtkWidget* -gnome_calendar_get_current_view_widget (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - GtkWidget *retval = NULL; - - priv = gcal->priv; - - switch (priv->current_view_type) { - case GNOME_CAL_DAY_VIEW: - retval = priv->day_view; - break; - case GNOME_CAL_WORK_WEEK_VIEW: - retval = priv->work_week_view; - break; - case GNOME_CAL_WEEK_VIEW: - retval = priv->week_view; - break; - case GNOME_CAL_MONTH_VIEW: - retval = priv->month_view; - break; - default: - g_assert_not_reached (); - } - - return retval; -} - -/* Gets the focus location based on who is the focused widget within the - * calendar view. - */ -static FocusLocation -get_focus_location (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - ETable *etable; - - priv = gcal->priv; - - etable = e_calendar_table_get_table (E_CALENDAR_TABLE (priv->todo)); - - if (GTK_WIDGET_HAS_FOCUS (etable->table_canvas)) - return FOCUS_TASKPAD; - else { - GtkWidget *widget; - EDayView *dv; - EWeekView *wv; - - widget = gnome_calendar_get_current_view_widget (gcal); - - switch (priv->current_view_type) { - case GNOME_CAL_DAY_VIEW: - case GNOME_CAL_WORK_WEEK_VIEW: - dv = E_DAY_VIEW (widget); - - if (GTK_WIDGET_HAS_FOCUS (dv->top_canvas) - || GTK_WIDGET_HAS_FOCUS (dv->main_canvas)) - return FOCUS_CALENDAR; - else - return FOCUS_OTHER; - - case GNOME_CAL_WEEK_VIEW: - case GNOME_CAL_MONTH_VIEW: - wv = E_WEEK_VIEW (widget); - - if (GTK_WIDGET_HAS_FOCUS (wv->main_canvas)) - return FOCUS_CALENDAR; - else - return FOCUS_OTHER; - - default: - g_assert_not_reached (); - return FOCUS_OTHER; - } - } -} - -/* Computes the range of time that the date navigator is showing */ -static void -get_date_navigator_range (GnomeCalendar *gcal, time_t *start_time, time_t *end_time) -{ - GnomeCalendarPrivate *priv; - gint start_year, start_month, start_day; - gint end_year, end_month, end_day; - struct icaltimetype start_tt; - struct icaltimetype end_tt; - - priv = gcal->priv; - - start_tt = icaltime_null_time (); - end_tt = icaltime_null_time (); - - if (!e_calendar_item_get_date_range (priv->date_navigator->calitem, - &start_year, &start_month, &start_day, - &end_year, &end_month, &end_day)) { - *start_time = -1; - *end_time = -1; - return; - } - - start_tt.year = start_year; - start_tt.month = start_month + 1; - start_tt.day = start_day; - - end_tt.year = end_year; - end_tt.month = end_month + 1; - end_tt.day = end_day; - - icaltime_adjust (&end_tt, 1, 0, 0, 0); - - *start_time = icaltime_as_timet_with_zone (start_tt, priv->zone); - *end_time = icaltime_as_timet_with_zone (end_tt, priv->zone); -} - -/* Adjusts a given query sexp with the time range of the date navigator */ -static char * -adjust_query_sexp (GnomeCalendar *gcal, const char *sexp) -{ - time_t start_time, end_time; - char *start, *end; - char *new_sexp; - - get_date_navigator_range (gcal, &start_time, &end_time); - if (start_time == -1 || end_time == -1) - return NULL; - - start = isodate_from_time_t (start_time); - end = isodate_from_time_t (end_time); - - new_sexp = g_strdup_printf ("(and (= (get-vtype) \"VEVENT\")" - " (occur-in-time-range? (make-time \"%s\")" - " (make-time \"%s\"))" - " %s)", - start, end, - sexp); - - g_free (start); - g_free (end); - - return new_sexp; -} - -/* Restarts a query for the date navigator in the calendar */ -static void -update_query (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - CalQuery *old_query; - char *real_sexp; - - priv = gcal->priv; - - e_calendar_item_clear_marks (priv->date_navigator->calitem); - - if (!(priv->client - && cal_client_get_load_state (priv->client) == CAL_CLIENT_LOAD_LOADED)) - return; - - old_query = priv->dn_query; - priv->dn_query = NULL; - - if (old_query) { - gtk_signal_disconnect_by_data (GTK_OBJECT (old_query), gcal); - gtk_object_unref (GTK_OBJECT (old_query)); - } - - g_assert (priv->sexp != NULL); - - real_sexp = adjust_query_sexp (gcal, priv->sexp); - if (!real_sexp) - return; /* No time range is set, so don't start a query */ - - priv->dn_query = cal_client_get_query (priv->client, real_sexp); - g_free (real_sexp); - - if (!priv->dn_query) { - g_message ("update_query(): Could not create the query"); - return; - } - - gtk_signal_connect (GTK_OBJECT (priv->dn_query), "obj_updated", - GTK_SIGNAL_FUNC (dn_query_obj_updated_cb), gcal); - gtk_signal_connect (GTK_OBJECT (priv->dn_query), "obj_removed", - GTK_SIGNAL_FUNC (dn_query_obj_removed_cb), gcal); - gtk_signal_connect (GTK_OBJECT (priv->dn_query), "query_done", - GTK_SIGNAL_FUNC (dn_query_query_done_cb), gcal); - gtk_signal_connect (GTK_OBJECT (priv->dn_query), "eval_error", - GTK_SIGNAL_FUNC (dn_query_eval_error_cb), gcal); -} - -/** - * gnome_calendar_set_query: - * @gcal: A calendar. - * @sexp: Sexp that defines the query. - * - * Sets the query sexp for all the views in a calendar. - **/ -void -gnome_calendar_set_query (GnomeCalendar *gcal, const char *sexp) -{ - GnomeCalendarPrivate *priv; - CalendarModel *model; - - g_return_if_fail (gcal != NULL); - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - g_return_if_fail (sexp != NULL); - - priv = gcal->priv; - - /* Set the query on the date navigator */ - - if (priv->sexp) - g_free (priv->sexp); - - priv->sexp = g_strdup (sexp); - - update_query (gcal); - - /* Set the query on the main view */ - - switch (priv->current_view_type) { - case GNOME_CAL_DAY_VIEW: - e_day_view_set_query (E_DAY_VIEW (priv->day_view), sexp); - break; - - case GNOME_CAL_WORK_WEEK_VIEW: - e_day_view_set_query (E_DAY_VIEW (priv->work_week_view), sexp); - break; - - case GNOME_CAL_WEEK_VIEW: - e_week_view_set_query (E_WEEK_VIEW (priv->week_view), sexp); - break; - - case GNOME_CAL_MONTH_VIEW: - e_week_view_set_query (E_WEEK_VIEW (priv->month_view), sexp); - break; - - default: - g_warning ("A penguin bit my hand!"); - g_assert_not_reached (); - } - - /* Set the query on the task pad */ - - model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo)); - calendar_model_set_query (model, sexp); -} - -/* Returns the current time, for the ECalendarItem. */ -static struct tm -get_current_time (ECalendarItem *calitem, gpointer data) -{ - GnomeCalendar *cal = data; - struct tm tmp_tm = { 0 }; - struct icaltimetype tt; - - g_return_val_if_fail (cal != NULL, tmp_tm); - g_return_val_if_fail (GNOME_IS_CALENDAR (cal), tmp_tm); - - tt = icaltime_from_timet_with_zone (time (NULL), FALSE, - cal->priv->zone); - - /* Now copy it to the struct tm and return it. */ - tmp_tm = icaltimetype_to_tm (&tt); - - return tmp_tm; -} - -/* Callback used when the sexp changes in the calendar search bar */ -static void -search_bar_sexp_changed_cb (CalSearchBar *cal_search, const char *sexp, gpointer data) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - gnome_calendar_set_query (gcal, sexp); -} - -/* Callback used when the selected category in the search bar changes */ -static void -search_bar_category_changed_cb (CalSearchBar *cal_search, const char *category, gpointer data) -{ - GnomeCalendar *gcal; - GnomeCalendarPrivate *priv; - CalendarModel *model; - - gcal = GNOME_CALENDAR (data); - priv = gcal->priv; - - e_day_view_set_default_category (E_DAY_VIEW (priv->day_view), category); - e_day_view_set_default_category (E_DAY_VIEW (priv->work_week_view), category); - e_week_view_set_default_category (E_WEEK_VIEW (priv->week_view), category); - e_week_view_set_default_category (E_WEEK_VIEW (priv->month_view), category); - - model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo)); - calendar_model_set_default_category (model, category); -} - -static void -view_selection_changed_cb (GtkWidget *view, GnomeCalendar *gcal) -{ - gtk_signal_emit (GTK_OBJECT (gcal), - gnome_calendar_signals[CALENDAR_SELECTION_CHANGED]); -} - - -/* Callback used when the taskpad receives a focus event. We emit the - * corresponding signal so that parents can change the menus as appropriate. - */ -static gint -table_canvas_focus_change_cb (GtkWidget *widget, GdkEventFocus *event, gpointer data) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - gtk_signal_emit (GTK_OBJECT (gcal), gnome_calendar_signals [TASKPAD_FOCUS_CHANGE], - event->in ? TRUE : FALSE); - - return FALSE; -} - -static gint -calendar_focus_change_cb (GtkWidget *widget, GdkEventFocus *event, gpointer data) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - gtk_signal_emit (GTK_OBJECT (gcal), gnome_calendar_signals [CALENDAR_FOCUS_CHANGE], - event->in ? TRUE : FALSE); - - return FALSE; -} - -/* Connects to the focus change signals of a day view widget */ -static void -connect_day_view_focus (GnomeCalendar *gcal, EDayView *dv) -{ - gtk_signal_connect (GTK_OBJECT (dv->top_canvas), "focus_in_event", - GTK_SIGNAL_FUNC (calendar_focus_change_cb), gcal); - gtk_signal_connect (GTK_OBJECT (dv->top_canvas), "focus_out_event", - GTK_SIGNAL_FUNC (calendar_focus_change_cb), gcal); - - gtk_signal_connect (GTK_OBJECT (dv->main_canvas), "focus_in_event", - GTK_SIGNAL_FUNC (calendar_focus_change_cb), gcal); - gtk_signal_connect (GTK_OBJECT (dv->main_canvas), "focus_out_event", - GTK_SIGNAL_FUNC (calendar_focus_change_cb), gcal); -} - -/* Connects to the focus change signals of a week view widget */ -static void -connect_week_view_focus (GnomeCalendar *gcal, EWeekView *wv) -{ - gtk_signal_connect (GTK_OBJECT (wv->main_canvas), "focus_in_event", - GTK_SIGNAL_FUNC (calendar_focus_change_cb), gcal); - gtk_signal_connect (GTK_OBJECT (wv->main_canvas), "focus_out_event", - GTK_SIGNAL_FUNC (calendar_focus_change_cb), gcal); -} - -/* Callback used when the selection in the taskpad table changes. We just proxy - * the signal with our own one. - */ -static void -table_selection_change_cb (ETable *etable, gpointer data) -{ - GnomeCalendar *gcal; - int n_selected; - - gcal = GNOME_CALENDAR (data); - - n_selected = e_table_selected_count (etable); - gtk_signal_emit (GTK_OBJECT (gcal), gnome_calendar_signals[TASKPAD_SELECTION_CHANGED]); -} - -static void -setup_widgets (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - GtkWidget *w; - gchar *filename; - CalendarModel *model; - ETable *etable; - - priv = gcal->priv; - - priv->search_bar = cal_search_bar_new (); - gtk_signal_connect (GTK_OBJECT (priv->search_bar), "sexp_changed", - GTK_SIGNAL_FUNC (search_bar_sexp_changed_cb), gcal); - gtk_signal_connect (GTK_OBJECT (priv->search_bar), "category_changed", - GTK_SIGNAL_FUNC (search_bar_category_changed_cb), gcal); - - gtk_widget_show (priv->search_bar); - gtk_box_pack_start (GTK_BOX (gcal), priv->search_bar, FALSE, FALSE, 0); - - /* 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_calendar_item_set_get_time_callback (priv->date_navigator->calitem, - (ECalendarItemGetTimeCallback) get_current_time, - gcal, NULL); - - 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 (); - calendar_config_configure_e_calendar_table (E_CALENDAR_TABLE (priv->todo)); - 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); - - etable = e_calendar_table_get_table (E_CALENDAR_TABLE (priv->todo)); - gtk_signal_connect (GTK_OBJECT (etable->table_canvas), "focus_in_event", - GTK_SIGNAL_FUNC (table_canvas_focus_change_cb), gcal); - gtk_signal_connect (GTK_OBJECT (etable->table_canvas), "focus_out_event", - GTK_SIGNAL_FUNC (table_canvas_focus_change_cb), gcal); - - gtk_signal_connect (GTK_OBJECT (etable), "selection_change", - GTK_SIGNAL_FUNC (table_selection_change_cb), gcal); - - /* 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 ("")); - gtk_signal_connect (GTK_OBJECT (priv->day_view), "selection_changed", - GTK_SIGNAL_FUNC (view_selection_changed_cb), gcal); - - connect_day_view_focus (gcal, E_DAY_VIEW (priv->day_view)); - - /* The Work Week View. */ - priv->work_week_view = e_day_view_new (); - 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 ("")); - gtk_signal_connect (GTK_OBJECT (priv->work_week_view), "selection_changed", - GTK_SIGNAL_FUNC (view_selection_changed_cb), gcal); - - connect_day_view_focus (gcal, E_DAY_VIEW (priv->work_week_view)); - - /* 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 ("")); - gtk_signal_connect (GTK_OBJECT (priv->week_view), "selection_changed", - GTK_SIGNAL_FUNC (view_selection_changed_cb), gcal); - - connect_week_view_focus (gcal, E_WEEK_VIEW (priv->week_view)); - - /* 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 ("")); - gtk_signal_connect (GTK_OBJECT (priv->month_view), "selection_changed", - GTK_SIGNAL_FUNC (view_selection_changed_cb), gcal); - - connect_week_view_focus (gcal, E_WEEK_VIEW (priv->month_view)); - - 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->cal_categories = NULL; - priv->tasks_categories = NULL; - - priv->object_editor_hash = g_hash_table_new (g_str_hash, g_str_equal); - - priv->current_view_type = GNOME_CAL_DAY_VIEW; - priv->range_selected = FALSE; - - setup_widgets (gcal); - priv->dn_query = NULL; - priv->sexp = g_strdup ("#t"); /* Match all */ - - priv->selection_start_time = time_day_begin_with_zone (time (NULL), - priv->zone); - priv->selection_end_time = time_add_day_with_zone (priv->selection_start_time, 1, priv->zone); - - priv->view_instance = NULL; - priv->view_menus = NULL; - - priv->visible_start = -1; - priv->visible_end = -1; -} - -/* Frees a set of categories */ -static void -free_categories (GPtrArray *categories) -{ - int i; - - if (!categories) - return; - - for (i = 0; i < categories->len; i++) - g_free (categories->pdata[i]); - - g_ptr_array_free (categories, TRUE); -} - -/* 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; - - free_categories (priv->cal_categories); - priv->cal_categories = NULL; - - free_categories (priv->tasks_categories); - priv->tasks_categories = NULL; - - /* 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->dn_query) { - gtk_signal_disconnect_by_data (GTK_OBJECT (priv->dn_query), gcal); - gtk_object_unref (GTK_OBJECT (priv->dn_query)); - priv->dn_query = NULL; - } - - if (priv->sexp) { - g_free (priv->sexp); - priv->sexp = NULL; - } - - if (priv->client) { - gtk_object_unref (GTK_OBJECT (priv->client)); - priv->client = NULL; - } - - if (priv->task_pad_client) { - 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; - - if (priv->view_instance) { - gtk_object_unref (GTK_OBJECT (priv->view_instance)); - priv->view_instance = NULL; - } - - if (priv->view_menus) { - gtk_object_unref (GTK_OBJECT (priv->view_menus)); - priv->view_menus = NULL; - } - - g_free (priv); - gcal->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - -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_with_zone (new_time, - priv->zone); - priv->selection_end_time = time_add_day_with_zone (priv->selection_start_time, 1, priv->zone); - - gnome_calendar_update_view_times (gcal); - gnome_calendar_update_date_navigator (gcal); - gnome_calendar_notify_dates_shown_changed (gcal); -} - - -static void -gnome_calendar_update_view_times (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - - priv = gcal->priv; - - switch (priv->current_view_type) { - case GNOME_CAL_DAY_VIEW: - e_day_view_set_selected_time_range (E_DAY_VIEW (priv->day_view), - priv->selection_start_time, - priv->selection_end_time); - break; - - case GNOME_CAL_WORK_WEEK_VIEW: - e_day_view_set_selected_time_range (E_DAY_VIEW (priv->work_week_view), - priv->selection_start_time, - priv->selection_end_time); - break; - - case GNOME_CAL_WEEK_VIEW: - e_week_view_set_selected_time_range (E_WEEK_VIEW (priv->week_view), - priv->selection_start_time, - priv->selection_end_time); - break; - - case GNOME_CAL_MONTH_VIEW: - e_week_view_set_selected_time_range (E_WEEK_VIEW (priv->month_view), - priv->selection_start_time, - priv->selection_end_time); - break; - - default: - g_warning ("My penguin is gone!"); - g_assert_not_reached (); - } -} - -static void -gnome_calendar_direction (GnomeCalendar *gcal, int direction) -{ - GnomeCalendarPrivate *priv; - time_t start_time, end_time; - - priv = gcal->priv; - - start_time = priv->selection_start_time; - end_time = priv->selection_end_time; - - switch (priv->current_view_type) { - case GNOME_CAL_DAY_VIEW: - start_time = time_add_day_with_zone (start_time, direction, - priv->zone); - end_time = time_add_day_with_zone (end_time, direction, - priv->zone); - break; - - case GNOME_CAL_WORK_WEEK_VIEW: - start_time = time_add_week_with_zone (start_time, direction, - priv->zone); - end_time = time_add_week_with_zone (end_time, direction, - priv->zone); - break; - - case GNOME_CAL_WEEK_VIEW: - start_time = time_add_week_with_zone (start_time, direction, - priv->zone); - end_time = time_add_week_with_zone (end_time, direction, - priv->zone); - break; - - case GNOME_CAL_MONTH_VIEW: - start_time = time_add_month_with_zone (start_time, direction, - priv->zone); - end_time = time_add_month_with_zone (end_time, direction, - priv->zone); - break; - - default: - 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); - gnome_calendar_notify_dates_shown_changed (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_with_zone (time, - priv->zone); - priv->selection_end_time = time_add_day_with_zone (priv->selection_start_time, 1, priv->zone); - - gnome_calendar_set_view (gcal, GNOME_CAL_DAY_VIEW, FALSE, TRUE); -} - -static void -focus_current_view (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - - priv = gcal->priv; - - switch (priv->current_view_type) { - case GNOME_CAL_DAY_VIEW: - gtk_widget_grab_focus (priv->day_view); - break; - - case GNOME_CAL_WORK_WEEK_VIEW: - gtk_widget_grab_focus (priv->work_week_view); - break; - - case GNOME_CAL_WEEK_VIEW: - gtk_widget_grab_focus (priv->week_view); - break; - - case GNOME_CAL_MONTH_VIEW: - gtk_widget_grab_focus (priv->month_view); - break; - - default: - g_warning ("A penguin fell on its face!"); - g_assert_not_reached (); - } -} - -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)); - focus_current_view (gcal); -} - -/** - * gnome_calendar_get_view: - * @gcal: A calendar. - * - * Queries the type of the view that is being shown in a calendar. - * - * Return value: Type of the view that is currently shown. - **/ -GnomeCalendarViewType -gnome_calendar_get_view (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - - g_return_val_if_fail (gcal != NULL, GNOME_CAL_DAY_VIEW); - g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), GNOME_CAL_DAY_VIEW); - - priv = gcal->priv; - return priv->current_view_type; -} - -/* 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 -set_view (GnomeCalendar *gcal, GnomeCalendarViewType view_type, - gboolean range_selected, gboolean grab_focus) -{ - GnomeCalendarPrivate *priv; - gboolean round_selection; - GtkWidget *focus_widget; - const char *view_id; - - priv = gcal->priv; - - round_selection = FALSE; - focus_widget = NULL; - - switch (view_type) { - case GNOME_CAL_DAY_VIEW: - view_id = "Day_View"; - focus_widget = priv->day_view; - - if (!range_selected) - e_day_view_set_days_shown (E_DAY_VIEW (priv->day_view), 1); - - break; - - case GNOME_CAL_WORK_WEEK_VIEW: - view_id = "Work_Week_View"; - focus_widget = priv->work_week_view; - break; - - case GNOME_CAL_WEEK_VIEW: - view_id = "Week_View"; - focus_widget = priv->week_view; - round_selection = TRUE; - break; - - case GNOME_CAL_MONTH_VIEW: - view_id = "Month_View"; - focus_widget = priv->month_view; - - if (!range_selected) - e_week_view_set_weeks_shown (E_WEEK_VIEW (priv->month_view), 5); - - round_selection = TRUE; - break; - - default: - g_warning ("A penguin is loose!"); - g_assert_not_reached (); - return; - } - - priv->current_view_type = view_type; - priv->range_selected = range_selected; - - g_assert (focus_widget != NULL); - - calendar_config_set_default_view (view_type); - - gtk_notebook_set_page (GTK_NOTEBOOK (priv->notebook), (int) view_type); - gal_view_instance_set_current_view_id (priv->view_instance, view_id); - - if (grab_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); -} - -/** - * gnome_calendar_set_view: - * @gcal: A calendar. - * @view_type: Type of view to show. - * @range_selected: If false, the range of days/weeks shown will be reset to the - * default value (1 for day view, 5 for week view, respectively). If true, the - * currently displayed range will be kept. - * @grab_focus: Whether the view widget should grab the focus. - * - * Sets the view that should be shown in a calendar. If @reset_range is true, - * this function will automatically set the number of days or weeks shown in - * the view; otherwise the last configuration will be kept. - **/ -void -gnome_calendar_set_view (GnomeCalendar *gcal, GnomeCalendarViewType view_type, - gboolean range_selected, gboolean grab_focus) -{ - g_return_if_fail (gcal != NULL); - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - - set_view (gcal, view_type, range_selected, grab_focus); - gnome_calendar_update_view_times (gcal); - gnome_calendar_update_date_navigator (gcal); - gnome_calendar_notify_dates_shown_changed (gcal); -} - -/* Callback used when the view collection asks us to display a particular view */ -static void -display_view_cb (GalViewInstance *view_instance, GalView *view, gpointer data) -{ - GnomeCalendar *gcal; - CalendarView *cal_view; - - gcal = GNOME_CALENDAR (data); - - if (!IS_CALENDAR_VIEW (view)) - g_error ("display_view_cb(): Unknown type of view for GnomeCalendar"); - - cal_view = CALENDAR_VIEW (view); - - gnome_calendar_set_view (gcal, calendar_view_get_view_type (cal_view), FALSE, TRUE); -} - -/** - * gnome_calendar_setup_view_menus: - * @gcal: A calendar. - * @uic: UI controller to use for the menus. - * - * Sets up the #GalView menus for a calendar. This function should be called - * from the Bonobo control activation callback for this calendar. Also, the - * menus should be discarded using gnome_calendar_discard_view_menus(). - **/ -void -gnome_calendar_setup_view_menus (GnomeCalendar *gcal, BonoboUIComponent *uic) -{ - GnomeCalendarPrivate *priv; - char *path; - CalendarViewFactory *factory; - static GalViewCollection *collection = NULL; - - g_return_if_fail (gcal != NULL); - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - g_return_if_fail (uic != NULL); - g_return_if_fail (BONOBO_IS_UI_COMPONENT (uic)); - - priv = gcal->priv; - - g_return_if_fail (priv->view_instance == NULL); - - g_assert (priv->view_instance == NULL); - g_assert (priv->view_menus == NULL); - - /* Create the view instance */ - - if (collection == NULL) { - collection = gal_view_collection_new (); - - path = gnome_util_prepend_user_home ("/evolution/views/calendar/"); - gal_view_collection_set_storage_directories (collection, - EVOLUTION_DATADIR "/evolution/views/calendar/", - path); - g_free (path); - - /* Create the views */ - - factory = calendar_view_factory_new (GNOME_CAL_DAY_VIEW); - gal_view_collection_add_factory (collection, GAL_VIEW_FACTORY (factory)); - gtk_object_unref (GTK_OBJECT (factory)); - - factory = calendar_view_factory_new (GNOME_CAL_WORK_WEEK_VIEW); - gal_view_collection_add_factory (collection, GAL_VIEW_FACTORY (factory)); - gtk_object_unref (GTK_OBJECT (factory)); - - factory = calendar_view_factory_new (GNOME_CAL_WEEK_VIEW); - gal_view_collection_add_factory (collection, GAL_VIEW_FACTORY (factory)); - gtk_object_unref (GTK_OBJECT (factory)); - - factory = calendar_view_factory_new (GNOME_CAL_MONTH_VIEW); - gal_view_collection_add_factory (collection, GAL_VIEW_FACTORY (factory)); - gtk_object_unref (GTK_OBJECT (factory)); - - /* Load the collection and create the menus */ - - gal_view_collection_load (collection); - } - - priv->view_instance = gal_view_instance_new (collection, cal_client_get_uri (priv->client)); - - priv->view_menus = gal_view_menus_new (priv->view_instance); - gal_view_menus_apply (priv->view_menus, uic, NULL); - gtk_signal_connect (GTK_OBJECT (priv->view_instance), "display_view", - GTK_SIGNAL_FUNC (display_view_cb), gcal); - display_view_cb (priv->view_instance, gal_view_instance_get_current_view (priv->view_instance), gcal); -} - -/** - * gnome_calendar_discard_view_menus: - * @gcal: A calendar. - * - * Discards the #GalView menus used by a calendar. This function should be - * called from the Bonobo control deactivation callback for this calendar. The - * menus should have been set up with gnome_calendar_setup_view_menus(). - **/ -void -gnome_calendar_discard_view_menus (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - - g_return_if_fail (gcal != NULL); - - priv = gcal->priv; - - g_return_if_fail (priv->view_instance != NULL); - - g_assert (priv->view_instance != NULL); - g_assert (priv->view_menus != NULL); - - gtk_object_unref (GTK_OBJECT (priv->view_instance)); - priv->view_instance = NULL; - - gtk_object_unref (GTK_OBJECT (priv->view_menus)); - priv->view_menus = NULL; -} - -EPopupMenu * -gnome_calendar_setup_view_popup (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; - - g_return_val_if_fail (priv->view_instance != NULL, NULL); - - return gal_view_instance_get_popup_menu (priv->view_instance); -} - -void -gnome_calendar_discard_view_popup (GnomeCalendar *gcal, EPopupMenu *popup) -{ - - - GnomeCalendarPrivate *priv; - - g_return_if_fail (gcal != NULL); - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - - priv = gcal->priv; - - g_return_if_fail (priv->view_instance != NULL); - - gal_view_instance_free_popup_menu (priv->view_instance, popup); -} - -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 == GNOME_CAL_MONTH_VIEW && !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); -} - -/* 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 -client_cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data) -{ - GnomeCalendar *gcal; - GnomeCalendarPrivate *priv; - - gcal = GNOME_CALENDAR (data); - priv = gcal->priv; - - e_week_view_set_status_message (E_WEEK_VIEW (priv->week_view), NULL); - - switch (status) { - case CAL_CLIENT_OPEN_SUCCESS: - /* If this is the main CalClient, update the Date Navigator. */ - if (client == priv->client) { - update_query (gcal); - } - - /* Set the client's default timezone, if we have one. */ - if (priv->zone) { - cal_client_set_default_timezone (client, priv->zone); - } - 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; - } -} - -/* Duplicates an array of categories */ -static GPtrArray * -copy_categories (GPtrArray *categories) -{ - GPtrArray *c; - int i; - - c = g_ptr_array_new (); - g_ptr_array_set_size (c, categories->len); - - for (i = 0; i < categories->len; i++) - c->pdata[i] = g_strdup (categories->pdata[i]); - - return c; -} - -/* Adds the categories from an array to a hash table if they don't exist there - * already. - */ -static void -add_categories (GHashTable *categories, GPtrArray *c) -{ - int i; - - if (!c) - return; - - for (i = 0; i < c->len; i++) { - const char *cat; - const char *str; - - cat = c->pdata[i]; - str = g_hash_table_lookup (categories, cat); - - if (!str) - g_hash_table_insert (categories, (char *) cat, NULL); - } -} - -/* Used to append categories from a hash table to an array */ -struct append_category_closure { - GPtrArray *c; - - int i; -}; - -/* Appends a category from the hash table to the array */ -static void -append_category_cb (gpointer key, gpointer value, gpointer data) -{ - struct append_category_closure *closure; - const char *category; - - category = key; - closure = data; - - closure->c->pdata[closure->i] = g_strdup (category); - closure->i++; -} - -/* Creates the union of two sets of categories */ -static GPtrArray * -merge_categories (GPtrArray *a, GPtrArray *b) -{ - GHashTable *categories; - int n; - GPtrArray *c; - struct append_category_closure closure; - - categories = g_hash_table_new (g_str_hash, g_str_equal); - - add_categories (categories, a); - add_categories (categories, b); - - n = g_hash_table_size (categories); - - c = g_ptr_array_new (); - g_ptr_array_set_size (c, n); - - closure.c = c; - closure.i = 0; - g_hash_table_foreach (categories, append_category_cb, &closure); - g_hash_table_destroy (categories); - - return c; -} - -/* Callback from the calendar client when the set of categories changes. We - * have to merge the categories of the calendar and tasks clients. - */ -static void -client_categories_changed_cb (CalClient *client, GPtrArray *categories, gpointer data) -{ - GnomeCalendar *gcal; - GnomeCalendarPrivate *priv; - GPtrArray *merged; - - gcal = GNOME_CALENDAR (data); - priv = gcal->priv; - - if (client == priv->client) { - free_categories (priv->cal_categories); - priv->cal_categories = copy_categories (categories); - } else if (client == priv->task_pad_client) { - free_categories (priv->tasks_categories); - priv->tasks_categories = copy_categories (categories); - } else - g_assert_not_reached (); - - merged = merge_categories (priv->cal_categories, priv->tasks_categories); - cal_search_bar_set_categories (CAL_SEARCH_BAR (priv->search_bar), merged); - free_categories (merged); -} - -GtkWidget * -gnome_calendar_construct (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - GnomeCalendarViewType view_type; - CalendarModel *model; - - 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 (client_cal_opened_cb), gcal); - gtk_signal_connect (GTK_OBJECT (priv->client), "categories_changed", - GTK_SIGNAL_FUNC (client_categories_changed_cb), gcal); - - 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 (client_cal_opened_cb), gcal); - gtk_signal_connect (GTK_OBJECT (priv->task_pad_client), "categories_changed", - GTK_SIGNAL_FUNC (client_categories_changed_cb), gcal); - - model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo)); - g_assert (model != NULL); - - calendar_model_set_cal_client (model, priv->task_pad_client, CALOBJ_TYPE_TODO); - - /* Get the default view to show. */ - view_type = calendar_config_get_default_view (); - if (view_type < GNOME_CAL_DAY_VIEW || view_type > GNOME_CAL_MONTH_VIEW) - view_type = GNOME_CAL_DAY_VIEW; - - gnome_calendar_set_view (gcal, view_type, 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); -} - -void -gnome_calendar_set_ui_component (GnomeCalendar *gcal, - BonoboUIComponent *ui_component) -{ - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - g_return_if_fail (ui_component == NULL || BONOBO_IS_UI_COMPONENT (ui_component)); - - e_search_bar_set_ui_component (E_SEARCH_BAR (gcal->priv->search_bar), ui_component); -} - -/** - * gnome_calendar_get_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; -} - -/** - * gnome_calendar_get_task_pad_cal_client: - * @gcal: A calendar view. - * - * Queries the calendar client interface object that a calendar view is using - * for the Task Pad. - * - * Return value: A calendar client interface object. - **/ -CalClient * -gnome_calendar_get_task_pad_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->task_pad_client; -} - -/* Adds the specified URI to the alarm notification service */ -static void -add_alarms (const char *uri) -{ - CORBA_Environment ev; - GNOME_Evolution_Calendar_AlarmNotify an; - - /* Activate the alarm notification service */ - - CORBA_exception_init (&ev); - an = oaf_activate_from_id ("OAFIID:GNOME_Evolution_Calendar_AlarmNotify", 0, NULL, &ev); - - if (BONOBO_EX (&ev)) { - g_message ("add_alarms(): Could not activate the alarm notification service"); - CORBA_exception_free (&ev); - return; - } - CORBA_exception_free (&ev); - - /* Ask the service to load the URI */ - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_AlarmNotify_addCalendar (an, uri, &ev); - - if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_AlarmNotify_InvalidURI)) - g_message ("add_calendar(): Invalid URI reported from the " - "alarm notification service"); - else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_AlarmNotify_BackendContactError)) - g_message ("add_calendar(): The alarm notification service could " - "not contact the backend"); - else if (BONOBO_EX (&ev)) - g_message ("add_calendar(): Could not issue the addCalendar request"); - - CORBA_exception_free (&ev); - - /* Get rid of the service */ - - CORBA_exception_init (&ev); - bonobo_object_release_unref (an, &ev); - if (BONOBO_EX (&ev)) - g_message ("add_alarms(): Could not unref the alarm notification service"); - - CORBA_exception_free (&ev); -} - -gboolean -gnome_calendar_open (GnomeCalendar *gcal, const char *str_uri) -{ - GnomeCalendarPrivate *priv; - char *tasks_uri; - gboolean success; - EUri *uri; - char *message; - char *real_uri; - - 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); - - uri = e_uri_new (str_uri); - if (!uri || !g_strncasecmp (uri->protocol, "file", 4)) - real_uri = g_concat_dir_and_file (str_uri, "calendar.ics"); - else - real_uri = g_strdup (str_uri); - - message = g_strdup_printf (_("Opening calendar at %s"), real_uri); - e_week_view_set_status_message (E_WEEK_VIEW (priv->week_view), message); - g_free (message); - - if (!cal_client_open_calendar (priv->client, real_uri, FALSE)) { - g_message ("gnome_calendar_open(): Could not issue the request"); - g_free (real_uri); - e_uri_free (uri); - - return FALSE; - } - - add_alarms (real_uri); - - /* Open the appropriate Tasks folder to show in the TaskPad */ - - if (!uri) { - 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); - } - else { - if (!g_strncasecmp (uri->protocol, "file", 4)) { - 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); - } - else { - success = cal_client_open_default_tasks (priv->task_pad_client, FALSE); - } - } - - g_free (real_uri); - e_uri_free (uri); - - if (success) - add_alarms (cal_client_get_uri (priv->task_pad_client)); - else { - 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; - char *location; - - 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)); - - calendar_config_configure_e_calendar_table (E_CALENDAR_TABLE (priv->todo)); - - location = calendar_config_get_timezone (); - priv->zone = icaltimezone_get_builtin_timezone (location); - - if (priv->client - && cal_client_get_load_state (priv->client) == CAL_CLIENT_LOAD_LOADED) { - cal_client_set_default_timezone (priv->client, priv->zone); - } - if (priv->task_pad_client - && cal_client_get_load_state (priv->task_pad_client) == CAL_CLIENT_LOAD_LOADED) { - cal_client_set_default_timezone (priv->task_pad_client, - priv->zone); - } - - e_day_view_set_timezone (E_DAY_VIEW (priv->day_view), priv->zone); - e_day_view_set_timezone (E_DAY_VIEW (priv->work_week_view), priv->zone); - e_week_view_set_timezone (E_WEEK_VIEW (priv->week_view), priv->zone); - e_week_view_set_timezone (E_WEEK_VIEW (priv->month_view), priv->zone); - - 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); - gnome_calendar_notify_dates_shown_changed (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_notify_dates_shown_changed (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, - gboolean meeting) -{ - 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); - - comp_editor_set_cal_client (COMP_EDITOR (ee), priv->client); - comp_editor_edit_comp (COMP_EDITOR (ee), comp); - if (meeting) - event_editor_show_meeting (ee); - } - - comp_editor_focus (COMP_EDITOR (ee)); -} - -/** - * gnome_calendar_new_appointment_for: - * @gcal: An Evolution calendar. - * @dtstart: a Unix time_t that marks the beginning of the appointment. - * @dtend: a Unix time_t that marks the end of the appointment. - * @all_day: if true, the dtstart and dtend are expanded to cover the entire - * day, and the event is set to TRANSPARENT. - * - * Opens an event editor dialog for a new appointment. - * - **/ -void -gnome_calendar_new_appointment_for (GnomeCalendar *cal, - time_t dtstart, time_t dtend, - gboolean all_day, - gboolean meeting) -{ - GnomeCalendarPrivate *priv; - struct icaltimetype itt; - CalComponentDateTime dt; - CalComponent *comp; - CalComponentTransparency transparency; - const char *category; - - g_return_if_fail (cal != NULL); - g_return_if_fail (GNOME_IS_CALENDAR (cal)); - - priv = cal->priv; - - dt.value = &itt; - if (all_day) - dt.tzid = NULL; - else - dt.tzid = icaltimezone_get_tzid (priv->zone); - - comp = cal_comp_event_new_with_defaults (); - - /* DTSTART, DTEND */ - - itt = icaltime_from_timet_with_zone (dtstart, FALSE, priv->zone); - if (all_day) { - itt.hour = itt.minute = itt.second = 0; - itt.is_date = TRUE; - } - cal_component_set_dtstart (comp, &dt); - - itt = icaltime_from_timet_with_zone (dtend, FALSE, priv->zone); - if (all_day) { - /* We round it up to the end of the day, unless it is already - set to midnight. */ - if (itt.hour != 0 || itt.minute != 0 || itt.second != 0) { - icaltime_adjust (&itt, 1, 0, 0, 0); - } - itt.hour = itt.minute = itt.second = 0; - itt.is_date = TRUE; - } - cal_component_set_dtend (comp, &dt); - - transparency = all_day ? CAL_COMPONENT_TRANSP_TRANSPARENT - : CAL_COMPONENT_TRANSP_OPAQUE; - cal_component_set_transparency (comp, transparency); - - - /* Category */ - - category = cal_search_bar_get_category (CAL_SEARCH_BAR (priv->search_bar)); - cal_component_set_categories (comp, category); - - /* Edit! */ - - cal_component_commit_sequence (comp); - - gnome_calendar_edit_object (cal, comp, meeting); - gtk_object_unref (GTK_OBJECT (comp)); -} - -/** - * gnome_calendar_new_appointment: - * @gcal: An Evolution calendar. - * - * Opens an event editor dialog for a new appointment. The appointment's start - * and end times are set to the currently selected time range in the calendar - * views. - **/ -void -gnome_calendar_new_appointment (GnomeCalendar *gcal) -{ - time_t dtstart, dtend; - - g_return_if_fail (gcal != NULL); - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - - gnome_calendar_get_current_time_range (gcal, &dtstart, &dtend); - gnome_calendar_new_appointment_for (gcal, dtstart, dtend, FALSE, FALSE); -} - -/** - * gnome_calendar_new_task: - * @gcal: An Evolution calendar. - * - * Opens a task editor dialog for a new task. - **/ -void -gnome_calendar_new_task (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - TaskEditor *tedit; - CalComponent *comp; - const char *category; - - g_return_if_fail (gcal != NULL); - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - - priv = gcal->priv; - - tedit = task_editor_new (); - comp_editor_set_cal_client (COMP_EDITOR (tedit), priv->task_pad_client); - - comp = cal_component_new (); - cal_component_set_new_vtype (comp, CAL_COMPONENT_TODO); - - category = cal_search_bar_get_category (CAL_SEARCH_BAR (priv->search_bar)); - cal_component_set_categories (comp, category); - - comp_editor_edit_comp (COMP_EDITOR (tedit), comp); - gtk_object_unref (GTK_OBJECT (comp)); - - comp_editor_focus (COMP_EDITOR (tedit)); -} - - -/* 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; - - priv = gcal->priv; - - switch (priv->current_view_type) { - case GNOME_CAL_DAY_VIEW: - e_day_view_get_selected_time_range (E_DAY_VIEW (priv->day_view), - start_time, end_time); - break; - - case GNOME_CAL_WORK_WEEK_VIEW: - e_day_view_get_selected_time_range (E_DAY_VIEW (priv->work_week_view), - start_time, end_time); - break; - - case GNOME_CAL_WEEK_VIEW: - e_week_view_get_selected_time_range (E_WEEK_VIEW (priv->week_view), - start_time, end_time); - break; - - case GNOME_CAL_MONTH_VIEW: - e_week_view_get_selected_time_range (E_WEEK_VIEW (priv->month_view), - start_time, end_time); - break; - - default: - g_message ("My penguin is gone!"); - g_assert_not_reached (); - } -} - - -/* Gets the visible time range for the current view. Returns FALSE if no - time range has been set yet. */ -gboolean -gnome_calendar_get_visible_time_range (GnomeCalendar *gcal, - time_t *start_time, - time_t *end_time) -{ - GnomeCalendarPrivate *priv; - gboolean retval = FALSE; - - g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), FALSE); - - priv = gcal->priv; - - switch (priv->current_view_type) { - case GNOME_CAL_DAY_VIEW: - retval = e_day_view_get_visible_time_range (E_DAY_VIEW (priv->day_view), start_time, end_time); - break; - - case GNOME_CAL_WORK_WEEK_VIEW: - retval = e_day_view_get_visible_time_range (E_DAY_VIEW (priv->work_week_view), start_time, end_time); - break; - - case GNOME_CAL_WEEK_VIEW: - retval = e_week_view_get_visible_time_range (E_WEEK_VIEW (priv->week_view), start_time, end_time); - break; - - case GNOME_CAL_MONTH_VIEW: - retval = e_week_view_get_visible_time_range (E_WEEK_VIEW (priv->month_view), start_time, end_time); - break; - - default: - g_assert_not_reached (); - } - - return retval; -} - - - -static void -get_days_shown (GnomeCalendar *gcal, GDate *start_date, gint *days_shown) -{ - GnomeCalendarPrivate *priv; - - priv = gcal->priv; - - switch (priv->current_view_type) { - case GNOME_CAL_DAY_VIEW: - time_to_gdate_with_zone (start_date, - E_DAY_VIEW (priv->day_view)->lower, - priv->zone); - *days_shown = e_day_view_get_days_shown (E_DAY_VIEW (priv->day_view)); - break; - - case GNOME_CAL_WORK_WEEK_VIEW: - time_to_gdate_with_zone (start_date, - E_DAY_VIEW (priv->work_week_view)->lower, - priv->zone); - *days_shown = e_day_view_get_days_shown (E_DAY_VIEW (priv->work_week_view)); - break; - - case GNOME_CAL_WEEK_VIEW: - *start_date = E_WEEK_VIEW (priv->week_view)->first_day_shown; - if (e_week_view_get_multi_week_view (E_WEEK_VIEW (priv->week_view))) - *days_shown = e_week_view_get_weeks_shown ( - E_WEEK_VIEW (priv->week_view)) * 7; - else - *days_shown = 7; - - break; - - case GNOME_CAL_MONTH_VIEW: - *start_date = E_WEEK_VIEW (priv->month_view)->first_day_shown; - if (e_week_view_get_multi_week_view (E_WEEK_VIEW (priv->month_view))) - *days_shown = e_week_view_get_weeks_shown ( - E_WEEK_VIEW (priv->month_view)) * 7; - else - *days_shown = 7; - - break; - - default: - 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; - - 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 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; - gboolean starts_on_week_start_day; - - priv = gcal->priv; - - starts_on_week_start_day = FALSE; - - get_days_shown (gcal, &start_date, &days_shown); - - 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); - - set_view (gcal, GNOME_CAL_MONTH_VIEW, TRUE, FALSE); - gnome_calendar_update_date_navigator (gcal); - gnome_calendar_notify_dates_shown_changed (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); - - set_view (gcal, GNOME_CAL_WEEK_VIEW, TRUE, FALSE); - gnome_calendar_update_date_navigator (gcal); - gnome_calendar_notify_dates_shown_changed (gcal); - } else { - gint start_year, start_month, start_day; - gint end_year, end_month, end_day; - struct icaltimetype tt; - - start_year = g_date_year (&new_start_date); - start_month = g_date_month (&new_start_date); - start_day = g_date_day (&new_start_date); - end_year = g_date_year (&new_end_date); - end_month = g_date_month (&new_end_date); - end_day = g_date_day (&new_end_date); - - tt = icaltime_null_time (); - tt.year = start_year; - tt.month = start_month; - tt.day = start_day; - priv->selection_start_time = icaltime_as_timet_with_zone (tt, priv->zone); - - tt = icaltime_null_time (); - tt.year = end_year; - tt.month = end_month; - tt.day = end_day; - icaltime_adjust (&tt, 1, 0, 0, 0); - priv->selection_end_time = icaltime_as_timet_with_zone (tt, priv->zone); - - e_day_view_set_days_shown (E_DAY_VIEW (priv->day_view), new_days_shown); - gnome_calendar_set_view (gcal, GNOME_CAL_DAY_VIEW, TRUE, FALSE); - } - - focus_current_view (gcal); -} - - -static void -gnome_calendar_on_date_navigator_date_range_changed (ECalendarItem *calitem, - GnomeCalendar *gcal) -{ - update_query (gcal); -} - - -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; - - 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 - set_view(). */ - 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 == GNOME_CAL_MONTH_VIEW && !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_cut_clipboard (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - FocusLocation location; - - priv = gcal->priv; - - location = get_focus_location (gcal); - - if (location == FOCUS_CALENDAR) { - switch (priv->current_view_type) { - case GNOME_CAL_DAY_VIEW : - e_day_view_cut_clipboard (E_DAY_VIEW (priv->day_view)); - break; - case GNOME_CAL_WORK_WEEK_VIEW : - e_day_view_cut_clipboard (E_DAY_VIEW (priv->work_week_view)); - break; - case GNOME_CAL_WEEK_VIEW : - e_week_view_cut_clipboard (E_WEEK_VIEW (priv->week_view)); - break; - case GNOME_CAL_MONTH_VIEW : - e_week_view_cut_clipboard (E_WEEK_VIEW (priv->month_view)); - break; - default: - g_assert_not_reached (); - } - } else if (location == FOCUS_TASKPAD) - e_calendar_table_cut_clipboard (E_CALENDAR_TABLE (priv->todo)); - else - g_assert_not_reached (); -} - -void -gnome_calendar_copy_clipboard (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - FocusLocation location; - - priv = gcal->priv; - - location = get_focus_location (gcal); - - if (location == FOCUS_CALENDAR) { - switch (priv->current_view_type) { - case GNOME_CAL_DAY_VIEW : - e_day_view_copy_clipboard (E_DAY_VIEW (priv->day_view)); - break; - case GNOME_CAL_WORK_WEEK_VIEW : - e_day_view_copy_clipboard (E_DAY_VIEW (priv->work_week_view)); - break; - case GNOME_CAL_WEEK_VIEW : - e_week_view_copy_clipboard (E_WEEK_VIEW (priv->week_view)); - break; - case GNOME_CAL_MONTH_VIEW : - e_week_view_copy_clipboard (E_WEEK_VIEW (priv->month_view)); - break; - default: - g_assert_not_reached (); - } - } else if (location == FOCUS_TASKPAD) - e_calendar_table_copy_clipboard (E_CALENDAR_TABLE (priv->todo)); - else - g_assert_not_reached (); -} - -void -gnome_calendar_paste_clipboard (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - FocusLocation location; - - priv = gcal->priv; - - location = get_focus_location (gcal); - - if (location == FOCUS_CALENDAR) { - switch (priv->current_view_type) { - case GNOME_CAL_DAY_VIEW : - e_day_view_paste_clipboard (E_DAY_VIEW (priv->day_view)); - break; - case GNOME_CAL_WORK_WEEK_VIEW : - e_day_view_paste_clipboard (E_DAY_VIEW (priv->work_week_view)); - break; - case GNOME_CAL_WEEK_VIEW : - e_week_view_paste_clipboard (E_WEEK_VIEW (priv->week_view)); - break; - case GNOME_CAL_MONTH_VIEW : - e_week_view_paste_clipboard (E_WEEK_VIEW (priv->month_view)); - break; - } - } else if (location == FOCUS_TASKPAD) - e_calendar_table_paste_clipboard (E_CALENDAR_TABLE (priv->todo)); - else - g_assert_not_reached (); -} - - -/* Get the current timezone. */ -icaltimezone* -gnome_calendar_get_timezone (GnomeCalendar *gcal) -{ - g_return_val_if_fail (gcal != NULL, NULL); - g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL); - - return gcal->priv->zone; -} - - -static void -gnome_calendar_notify_dates_shown_changed (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - time_t start_time, end_time; - - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - - priv = gcal->priv; - - /* If no time range is set yet, just return. */ - if (!gnome_calendar_get_visible_time_range (gcal, &start_time, - &end_time)) - return; - - /* We check if the visible date range has changed, and only emit the - signal if it has. (This makes sure we only change the folder title - bar label in the shell when we need to.) */ - if (priv->visible_start != start_time - || priv->visible_end != end_time) { - priv->visible_start = start_time; - priv->visible_end = end_time; - - gtk_signal_emit (GTK_OBJECT (gcal), - gnome_calendar_signals[DATES_SHOWN_CHANGED]); - } -} - - -/* Returns the number of selected events (0 or 1 at present). */ -gint -gnome_calendar_get_num_events_selected (GnomeCalendar *gcal) -{ - GtkWidget *view; - gint retval = 0; - - g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), 0); - - view = gnome_calendar_get_current_view_widget (gcal); - if (E_IS_DAY_VIEW (view)) - retval = e_day_view_get_num_events_selected (E_DAY_VIEW (view)); - else - retval = e_week_view_get_num_events_selected (E_WEEK_VIEW (view)); - - return retval; -} - -/** - * gnome_calendar_get_num_tasks_selected: - * @gcal: A calendar view. - * - * Queries the number of tasks that are currently selected in the task pad of a - * calendar view. - * - * Return value: Number of selected tasks. - **/ -gint -gnome_calendar_get_num_tasks_selected (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - ETable *etable; - - g_return_val_if_fail (gcal != NULL, -1); - g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), -1); - - priv = gcal->priv; - - etable = e_calendar_table_get_table (E_CALENDAR_TABLE (priv->todo)); - return e_table_selected_count (etable); -} - - -void -gnome_calendar_delete_selection (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - FocusLocation location; - GtkWidget *view; - - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - - priv = gcal->priv; - - location = get_focus_location (gcal); - - if (location == FOCUS_CALENDAR) { - view = gnome_calendar_get_current_view_widget (gcal); - - if (E_IS_DAY_VIEW (view)) - e_day_view_delete_event (E_DAY_VIEW (view)); - else - e_week_view_delete_event (E_WEEK_VIEW (view)); - } else if (location == FOCUS_TASKPAD) - e_calendar_table_delete_selected (E_CALENDAR_TABLE (priv->todo)); - else - g_assert_not_reached (); -} - - -ECalendarTable* -gnome_calendar_get_task_pad (GnomeCalendar *gcal) -{ - g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL); - - return E_CALENDAR_TABLE (gcal->priv->todo); -} - diff --git a/calendar/gui/gnome-cal.h b/calendar/gui/gnome-cal.h deleted file mode 100644 index ebad45c99f..0000000000 --- a/calendar/gui/gnome-cal.h +++ /dev/null @@ -1,176 +0,0 @@ -/* Evolution calendar - Main calendar view widget - * - * Copyright (C) 1998 The Free Software Foundation - * Copyright (C) 2000 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef GNOME_CALENDAR_APP_H -#define GNOME_CALENDAR_APP_H - -#include <time.h> -#include <libgnome/gnome-defs.h> -#include <gtk/gtkvbox.h> -#include <bonobo/bonobo-ui-component.h> -#include <gal/widgets/e-popup-menu.h> -#include <widgets/misc/e-calendar.h> -#include <cal-client/cal-client.h> - -#include "e-calendar-table.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; - -/* View types */ -typedef enum { - GNOME_CAL_DAY_VIEW, - GNOME_CAL_WORK_WEEK_VIEW, - GNOME_CAL_WEEK_VIEW, - GNOME_CAL_MONTH_VIEW -} GnomeCalendarViewType; - -struct _GnomeCalendar { - GtkVBox vbox; - - /* Private data */ - GnomeCalendarPrivate *priv; -}; - -struct _GnomeCalendarClass { - GtkVBoxClass parent_class; - - /* Notification signals */ - void (* dates_shown_changed) (GnomeCalendar *gcal); - - void (* calendar_selection_changed) (GnomeCalendar *gcal); - void (* taskpad_selection_changed) (GnomeCalendar *gcal); - - void (* calendar_focus_change) (GnomeCalendar *gcal, gboolean in); - void (* taskpad_focus_change) (GnomeCalendar *gcal, gboolean in); -}; - - -GtkType gnome_calendar_get_type (void); -GtkWidget *gnome_calendar_construct (GnomeCalendar *gcal); - -GtkWidget *gnome_calendar_new (void); - -void gnome_calendar_set_ui_component (GnomeCalendar *cal, - BonoboUIComponent *ui_component); - -ECalendarTable *gnome_calendar_get_task_pad (GnomeCalendar *gcal); - -CalClient *gnome_calendar_get_cal_client (GnomeCalendar *gcal); -CalClient *gnome_calendar_get_task_pad_cal_client(GnomeCalendar *gcal); - -gboolean gnome_calendar_open (GnomeCalendar *gcal, const char *str_uri); - -void gnome_calendar_set_query (GnomeCalendar *gcal, const char *sexp); - -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); - -GnomeCalendarViewType gnome_calendar_get_view (GnomeCalendar *gcal); -void gnome_calendar_set_view (GnomeCalendar *gcal, GnomeCalendarViewType view_type, - gboolean range_selected, gboolean grab_focus); - -void gnome_calendar_setup_view_menus (GnomeCalendar *gcal, BonoboUIComponent *uic); -void gnome_calendar_discard_view_menus (GnomeCalendar *gcal); - -EPopupMenu *gnome_calendar_setup_view_popup (GnomeCalendar *gcal); -void gnome_calendar_discard_view_popup (GnomeCalendar *gcal, EPopupMenu *popup); - -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, - gboolean meeting); - -void gnome_calendar_new_appointment (GnomeCalendar *gcal); -void gnome_calendar_new_appointment_for (GnomeCalendar *cal, - time_t dtstart, time_t dtend, - gboolean all_day, - gboolean meeting); - -void gnome_calendar_new_task (GnomeCalendar *gcal); - -/* Returns the selected time range for the current view. Note that this may be - 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); - -/* Gets the visible time range for the current view. Returns FALSE if no - time range has been set yet. */ -gboolean gnome_calendar_get_visible_time_range (GnomeCalendar *gcal, - time_t *start_time, - time_t *end_time); - -/* Returns the number of selected events (0 or 1 at present). */ -gint gnome_calendar_get_num_events_selected (GnomeCalendar *gcal); - -/* Returns the number of selected tasks */ -gint gnome_calendar_get_num_tasks_selected (GnomeCalendar *gcal); - -/* 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); - -/* Get the current timezone. */ -icaltimezone *gnome_calendar_get_timezone (GnomeCalendar *gcal); - - -/* Clipboard operations */ -void gnome_calendar_cut_clipboard (GnomeCalendar *gcal); -void gnome_calendar_copy_clipboard (GnomeCalendar *gcal); -void gnome_calendar_paste_clipboard (GnomeCalendar *gcal); - -void gnome_calendar_delete_selection (GnomeCalendar *gcal); - - - -END_GNOME_DECLS - -#endif 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 06250a1a70..0000000000 --- a/calendar/gui/goto.c +++ /dev/null @@ -1,257 +0,0 @@ -/* Go to date dialog for Evolution - * - * Copyright (C) 1998 Red Hat, Inc. - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: Federico Mena <federico@ximian.com> - * JP Rosevear <jpr@ximian.com> - */ - -#include <config.h> -#include <gtk/gtkmenu.h> -#include <gtk/gtkoptionmenu.h> -#include <gtk/gtksignal.h> -#include <gtk/gtkspinbutton.h> -#include <gtk/gtktogglebutton.h> -#include <gtk/gtkwindow.h> -#include <libgnomeui/gnome-dialog.h> -#include <glade/glade.h> -#include "calendar-commands.h" -#include "calendar-config.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 icaltimetype tt = icaltime_null_time (); - time_t et; - - e_calendar_item_get_selection (calitem, &start_date, &end_date); - - tt.year = g_date_year (&start_date); - tt.month = g_date_month (&start_date); - tt.day = g_date_day (&start_date); - - et = icaltime_as_timet_with_zone (tt, gnome_calendar_get_timezone (dlg->gcal)); - - gnome_calendar_goto (dlg->gcal, et); - - gnome_dialog_close (GNOME_DIALOG (dlg->dialog)); -} - -/* Returns the current time, for the ECalendarItem. */ -static struct tm -get_current_time (ECalendarItem *calitem, gpointer data) -{ - char *location; - icaltimezone *zone; - struct tm tmp_tm = { 0 }; - struct icaltimetype tt; - - /* Get the current timezone. */ - location = calendar_config_get_timezone (); - zone = icaltimezone_get_builtin_timezone (location); - - tt = icaltime_from_timet_with_zone (time (NULL), FALSE, zone); - - /* Now copy it to the struct tm and return it. */ - tmp_tm.tm_year = tt.year - 1900; - tmp_tm.tm_mon = tt.month - 1; - tmp_tm.tm_mday = tt.day; - tmp_tm.tm_hour = tt.hour; - tmp_tm.tm_min = tt.minute; - tmp_tm.tm_sec = tt.second; - tmp_tm.tm_isdst = -1; - - return tmp_tm; -} - -/* 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); - e_calendar_item_set_get_time_callback (calitem, - get_current_time, - dlg, NULL); - - 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 icaltimetype tt; - 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!"); - g_free (dlg); - return; - } - - if (!get_widgets (dlg)) { - g_message ("goto_dialog(): Could not find all widgets in the XML file!"); - g_free (dlg); - return; - } - dlg->gcal = gcal; - - gnome_calendar_get_selected_time_range (dlg->gcal, &start_time, NULL); - tt = icaltime_from_timet_with_zone (start_time, FALSE, gnome_calendar_get_timezone (gcal)); - dlg->year_val = tt.year; - dlg->month_val = tt.month - 1; - dlg->day_val = tt.day; - - 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 9ecfeeeb83..0000000000 --- a/calendar/gui/goto.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Evolution calendar - Go To Date dialog - * - * Copyright (C) 1998 Red Hat, Inc. - * Copyright (C) 2000 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef GOTO_DIALOG_H -#define GOTO_DIALOG_H - -#include "gnome-cal.h" - -void goto_dialog (GnomeCalendar *gcal); - -#endif diff --git a/calendar/gui/itip-bonobo-control.c b/calendar/gui/itip-bonobo-control.c deleted file mode 100644 index d05cee6d9a..0000000000 --- a/calendar/gui/itip-bonobo-control.c +++ /dev/null @@ -1,252 +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 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#include <config.h> -#include <glib.h> -#include <gtk/gtkobject.h> -#include <gtk/gtkwidget.h> -#include <bonobo/bonobo-generic-factory.h> -#include <bonobo/bonobo-control.h> -#include <bonobo/bonobo-property-bag.h> -#include <bonobo/bonobo-persist-stream.h> -#include <bonobo/bonobo-stream-client.h> -#include <bonobo/bonobo-context.h> -#include <bonobo/bonobo-exception.h> -#include <ical.h> - -#include "e-itip-control.h" -#include "itip-control-factory.h" - -extern gchar *evolution_dir; - -enum E_ITIP_BONOBO_ARGS { - FROM_ADDRESS_ARG_ID, -}; - -/* - * Bonobo::PersistStream - * - * These two functions implement the Bonobo::PersistStream load and - * save methods which allow data to be loaded into and out of the - * BonoboObject. - */ - -static char * -stream_read (Bonobo_Stream stream) -{ - Bonobo_Stream_iobuf *buffer; - CORBA_Environment ev; - gchar *data = NULL; - gint length = 0; - - CORBA_exception_init (&ev); - do { -#define READ_CHUNK_SIZE 65536 - Bonobo_Stream_read (stream, READ_CHUNK_SIZE, - &buffer, &ev); - - if (BONOBO_EX (&ev)) { - CORBA_exception_free (&ev); - return NULL; - } - - if (buffer->_length <= 0) - break; - - data = g_realloc (data, length + buffer->_length + 1); - memcpy (data + length, buffer->_buffer, buffer->_length); - length += buffer->_length; - data[length] = '\0'; - - CORBA_free (buffer); -#undef READ_CHUNK_SIZE - } while (1); - - CORBA_free (buffer); - CORBA_exception_free (&ev); - - if (data == NULL) - data = g_strdup(""); - - return data; -} /* stream_read */ - -/* - * This function implements the Bonobo::PersistStream:load method. - */ -static void -pstream_load (BonoboPersistStream *ps, const Bonobo_Stream stream, - Bonobo_Persist_ContentType type, void *data, - CORBA_Environment *ev) -{ - EItipControl *itip = data; - gchar *text; - - if (type && g_strcasecmp (type, "text/calendar") != 0 && - g_strcasecmp (type, "text/x-calendar") != 0) { - bonobo_exception_set (ev, ex_Bonobo_Persist_WrongDataType); - return; - } - - if ((text = stream_read (stream)) == NULL) { - bonobo_exception_set (ev, ex_Bonobo_Persist_FileNotFound); - return; - } - - e_itip_control_set_data (itip, text); - g_free (text); -} -/* - * This function implements the Bonobo::PersistStream:save method. - */ -static void -pstream_save (BonoboPersistStream *ps, const Bonobo_Stream stream, - Bonobo_Persist_ContentType type, void *data, - CORBA_Environment *ev) -{ - EItipControl *itip = data; - gchar *text; - gint len; - - if (type && g_strcasecmp (type, "text/calendar") != 0 && - g_strcasecmp (type, "text/x-calendar") != 0) { - bonobo_exception_set (ev, ex_Bonobo_Persist_WrongDataType); - return; - } - - text = e_itip_control_get_data (itip); - len = e_itip_control_get_data_size (itip); - - bonobo_stream_client_write (stream, text, len, ev); - g_free (text); -} /* pstream_save */ - -static CORBA_long -pstream_get_max_size (BonoboPersistStream *ps, void *data, - CORBA_Environment *ev) -{ - EItipControl *itip = data; - gint len; - - len = e_itip_control_get_data_size (itip); - - if (len > 0) - return len; - - return 0L; -} - -static Bonobo_Persist_ContentTypeList * -pstream_get_content_types (BonoboPersistStream *ps, void *closure, - CORBA_Environment *ev) -{ - return bonobo_persist_generate_content_types (2, "text/calendar", "text/x-calendar"); -} - -static void -get_prop (BonoboPropertyBag *bag, - BonoboArg *arg, - guint arg_id, - CORBA_Environment *ev, - gpointer user_data) -{ - EItipControl *itip = user_data; - - switch (arg_id) { - case FROM_ADDRESS_ARG_ID: - BONOBO_ARG_SET_STRING (arg, e_itip_control_get_from_address (itip)); - break; - } -} - -static void -set_prop ( BonoboPropertyBag *bag, - const BonoboArg *arg, - guint arg_id, - CORBA_Environment *ev, - gpointer user_data) -{ - EItipControl *itip = user_data; - - switch (arg_id) { - case FROM_ADDRESS_ARG_ID: - e_itip_control_set_from_address (itip, BONOBO_ARG_GET_STRING (arg)); - break; - } -} - - -static BonoboObject * -itip_control_factory (BonoboGenericFactory *Factory, void *closure) -{ - BonoboControl *control; - BonoboPropertyBag *prop_bag; - BonoboPersistStream *stream; - GtkWidget *itip; - - itip = e_itip_control_new (); - gtk_widget_show (itip); - control = bonobo_control_new (itip); - - /* create a property bag */ - prop_bag = bonobo_property_bag_new (get_prop, set_prop, itip); - bonobo_property_bag_add (prop_bag, "from_address", FROM_ADDRESS_ARG_ID, BONOBO_ARG_STRING, NULL, - "from_address", 0 ); - - bonobo_control_set_properties (control, prop_bag); - bonobo_object_unref (BONOBO_OBJECT (prop_bag)); - - bonobo_control_set_automerge (control, TRUE); - - stream = bonobo_persist_stream_new (pstream_load, pstream_save, - pstream_get_max_size, - pstream_get_content_types, - itip); - - 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 -itip_control_factory_init (void) -{ - static BonoboGenericFactory *factory = NULL; - - if (factory != NULL) - return; - - factory = bonobo_generic_factory_new ( - "OAFIID:GNOME_Evolution_Calendar_iTip_ControlFactory", - itip_control_factory, NULL); - bonobo_running_context_auto_exit_unref (BONOBO_OBJECT (factory));; - - if (factory == NULL) - g_error ("I could not register an iTip control factory."); -} - diff --git a/calendar/gui/itip-bonobo-control.h b/calendar/gui/itip-bonobo-control.h deleted file mode 100644 index 6f8a95ec71..0000000000 --- a/calendar/gui/itip-bonobo-control.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Evolution calendar - Control for displaying iTIP mail messages - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: - * Jesse Pavel <jpavel@ximian.com> - * JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef __ITIP_CONTROL_FACTORY_H__ -#define __ITIP_CONTROL_FACTORY_H__ - -void itip_control_factory_init (void); - -#endif /* __ITIP_CONTROL_H__ */ diff --git a/calendar/gui/itip-control-factory.c b/calendar/gui/itip-control-factory.c deleted file mode 100644 index d05cee6d9a..0000000000 --- a/calendar/gui/itip-control-factory.c +++ /dev/null @@ -1,252 +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 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#include <config.h> -#include <glib.h> -#include <gtk/gtkobject.h> -#include <gtk/gtkwidget.h> -#include <bonobo/bonobo-generic-factory.h> -#include <bonobo/bonobo-control.h> -#include <bonobo/bonobo-property-bag.h> -#include <bonobo/bonobo-persist-stream.h> -#include <bonobo/bonobo-stream-client.h> -#include <bonobo/bonobo-context.h> -#include <bonobo/bonobo-exception.h> -#include <ical.h> - -#include "e-itip-control.h" -#include "itip-control-factory.h" - -extern gchar *evolution_dir; - -enum E_ITIP_BONOBO_ARGS { - FROM_ADDRESS_ARG_ID, -}; - -/* - * Bonobo::PersistStream - * - * These two functions implement the Bonobo::PersistStream load and - * save methods which allow data to be loaded into and out of the - * BonoboObject. - */ - -static char * -stream_read (Bonobo_Stream stream) -{ - Bonobo_Stream_iobuf *buffer; - CORBA_Environment ev; - gchar *data = NULL; - gint length = 0; - - CORBA_exception_init (&ev); - do { -#define READ_CHUNK_SIZE 65536 - Bonobo_Stream_read (stream, READ_CHUNK_SIZE, - &buffer, &ev); - - if (BONOBO_EX (&ev)) { - CORBA_exception_free (&ev); - return NULL; - } - - if (buffer->_length <= 0) - break; - - data = g_realloc (data, length + buffer->_length + 1); - memcpy (data + length, buffer->_buffer, buffer->_length); - length += buffer->_length; - data[length] = '\0'; - - CORBA_free (buffer); -#undef READ_CHUNK_SIZE - } while (1); - - CORBA_free (buffer); - CORBA_exception_free (&ev); - - if (data == NULL) - data = g_strdup(""); - - return data; -} /* stream_read */ - -/* - * This function implements the Bonobo::PersistStream:load method. - */ -static void -pstream_load (BonoboPersistStream *ps, const Bonobo_Stream stream, - Bonobo_Persist_ContentType type, void *data, - CORBA_Environment *ev) -{ - EItipControl *itip = data; - gchar *text; - - if (type && g_strcasecmp (type, "text/calendar") != 0 && - g_strcasecmp (type, "text/x-calendar") != 0) { - bonobo_exception_set (ev, ex_Bonobo_Persist_WrongDataType); - return; - } - - if ((text = stream_read (stream)) == NULL) { - bonobo_exception_set (ev, ex_Bonobo_Persist_FileNotFound); - return; - } - - e_itip_control_set_data (itip, text); - g_free (text); -} -/* - * This function implements the Bonobo::PersistStream:save method. - */ -static void -pstream_save (BonoboPersistStream *ps, const Bonobo_Stream stream, - Bonobo_Persist_ContentType type, void *data, - CORBA_Environment *ev) -{ - EItipControl *itip = data; - gchar *text; - gint len; - - if (type && g_strcasecmp (type, "text/calendar") != 0 && - g_strcasecmp (type, "text/x-calendar") != 0) { - bonobo_exception_set (ev, ex_Bonobo_Persist_WrongDataType); - return; - } - - text = e_itip_control_get_data (itip); - len = e_itip_control_get_data_size (itip); - - bonobo_stream_client_write (stream, text, len, ev); - g_free (text); -} /* pstream_save */ - -static CORBA_long -pstream_get_max_size (BonoboPersistStream *ps, void *data, - CORBA_Environment *ev) -{ - EItipControl *itip = data; - gint len; - - len = e_itip_control_get_data_size (itip); - - if (len > 0) - return len; - - return 0L; -} - -static Bonobo_Persist_ContentTypeList * -pstream_get_content_types (BonoboPersistStream *ps, void *closure, - CORBA_Environment *ev) -{ - return bonobo_persist_generate_content_types (2, "text/calendar", "text/x-calendar"); -} - -static void -get_prop (BonoboPropertyBag *bag, - BonoboArg *arg, - guint arg_id, - CORBA_Environment *ev, - gpointer user_data) -{ - EItipControl *itip = user_data; - - switch (arg_id) { - case FROM_ADDRESS_ARG_ID: - BONOBO_ARG_SET_STRING (arg, e_itip_control_get_from_address (itip)); - break; - } -} - -static void -set_prop ( BonoboPropertyBag *bag, - const BonoboArg *arg, - guint arg_id, - CORBA_Environment *ev, - gpointer user_data) -{ - EItipControl *itip = user_data; - - switch (arg_id) { - case FROM_ADDRESS_ARG_ID: - e_itip_control_set_from_address (itip, BONOBO_ARG_GET_STRING (arg)); - break; - } -} - - -static BonoboObject * -itip_control_factory (BonoboGenericFactory *Factory, void *closure) -{ - BonoboControl *control; - BonoboPropertyBag *prop_bag; - BonoboPersistStream *stream; - GtkWidget *itip; - - itip = e_itip_control_new (); - gtk_widget_show (itip); - control = bonobo_control_new (itip); - - /* create a property bag */ - prop_bag = bonobo_property_bag_new (get_prop, set_prop, itip); - bonobo_property_bag_add (prop_bag, "from_address", FROM_ADDRESS_ARG_ID, BONOBO_ARG_STRING, NULL, - "from_address", 0 ); - - bonobo_control_set_properties (control, prop_bag); - bonobo_object_unref (BONOBO_OBJECT (prop_bag)); - - bonobo_control_set_automerge (control, TRUE); - - stream = bonobo_persist_stream_new (pstream_load, pstream_save, - pstream_get_max_size, - pstream_get_content_types, - itip); - - 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 -itip_control_factory_init (void) -{ - static BonoboGenericFactory *factory = NULL; - - if (factory != NULL) - return; - - factory = bonobo_generic_factory_new ( - "OAFIID:GNOME_Evolution_Calendar_iTip_ControlFactory", - itip_control_factory, NULL); - bonobo_running_context_auto_exit_unref (BONOBO_OBJECT (factory));; - - if (factory == NULL) - g_error ("I could not register an iTip control factory."); -} - diff --git a/calendar/gui/itip-control-factory.h b/calendar/gui/itip-control-factory.h deleted file mode 100644 index 6f8a95ec71..0000000000 --- a/calendar/gui/itip-control-factory.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Evolution calendar - Control for displaying iTIP mail messages - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: - * Jesse Pavel <jpavel@ximian.com> - * JP Rosevear <jpr@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef __ITIP_CONTROL_FACTORY_H__ -#define __ITIP_CONTROL_FACTORY_H__ - -void itip_control_factory_init (void); - -#endif /* __ITIP_CONTROL_H__ */ diff --git a/calendar/gui/itip-utils.c b/calendar/gui/itip-utils.c deleted file mode 100644 index 7e9efdbb57..0000000000 --- a/calendar/gui/itip-utils.c +++ /dev/null @@ -1,820 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Authors: - * JP Rosevear <jpr@ximian.com> - * - * Copyright 2001, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <bonobo/bonobo-exception.h> -#include <bonobo/bonobo-object.h> -#include <bonobo/bonobo-object-client.h> -#include <bonobo/bonobo-moniker-util.h> -#include <bonobo-conf/bonobo-config-database.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <gtk/gtkwidget.h> -#include <gal/widgets/e-gui-utils.h> -#include <gal/widgets/e-unicode.h> -#include <gal/util/e-unicode-i18n.h> -#include <gal/util/e-util.h> -#include <ical.h> -#include <Evolution-Composer.h> -#include <e-util/e-time-utils.h> -#include <cal-util/timeutil.h> -#include <cal-util/cal-util.h> -#include "calendar-config.h" -#include "itip-utils.h" - -#define GNOME_EVOLUTION_COMPOSER_OAFIID "OAFIID:GNOME_Evolution_Mail_Composer" - -static gchar *itip_methods[] = { - "PUBLISH", - "REQUEST", - "REPLY", - "ADD", - "CANCEL", - "RERESH", - "COUNTER", - "DECLINECOUNTER" -}; - -static icalproperty_method itip_methods_enum[] = { - ICAL_METHOD_PUBLISH, - ICAL_METHOD_REQUEST, - ICAL_METHOD_REPLY, - ICAL_METHOD_ADD, - ICAL_METHOD_CANCEL, - ICAL_METHOD_REFRESH, - ICAL_METHOD_COUNTER, - ICAL_METHOD_DECLINECOUNTER, -}; - -static Bonobo_ConfigDatabase db = NULL; - -static ItipAddress * -get_address (long num) -{ - ItipAddress *a; - gchar *path; - - a = g_new0 (ItipAddress, 1); - - /* get the identity info */ - path = g_strdup_printf ("/Mail/Accounts/identity_name_%ld", num); - a->name = bonobo_config_get_string (db, path, NULL); - g_free (path); - - path = g_strdup_printf ("/Mail/Accounts/identity_address_%ld", num); - a->address = bonobo_config_get_string (db, path, NULL); - a->address = g_strstrip (a->address); - g_free (path); - - a->full = g_strdup_printf ("%s <%s>", a->name, a->address); - - return a; -} - -GList * -itip_addresses_get (void) -{ - - CORBA_Environment ev; - GList *addresses = NULL; - glong len, def, i; - - if (db == NULL) { - CORBA_exception_init (&ev); - - db = bonobo_get_object ("wombat:", - "Bonobo/ConfigDatabase", - &ev); - - if (BONOBO_EX (&ev) || db == CORBA_OBJECT_NIL) { - CORBA_exception_free (&ev); - return NULL; - } - - CORBA_exception_free (&ev); - } - - len = bonobo_config_get_long_with_default (db, "/Mail/Accounts/num", 0, NULL); - def = bonobo_config_get_long_with_default (db, "/Mail/Accounts/default_account", 0, NULL); - - for (i = 0; i < len; i++) { - ItipAddress *a; - - a = get_address (i); - if (i == def) - a->default_address = TRUE; - - addresses = g_list_append (addresses, a); - } - - return addresses; -} - -ItipAddress * -itip_addresses_get_default (void) -{ - CORBA_Environment ev; - ItipAddress *a; - glong def; - - if (db == NULL) { - CORBA_exception_init (&ev); - - db = bonobo_get_object ("wombat:", - "Bonobo/ConfigDatabase", - &ev); - - if (BONOBO_EX (&ev) || db == CORBA_OBJECT_NIL) { - CORBA_exception_free (&ev); - return NULL; - } - - CORBA_exception_free (&ev); - } - - def = bonobo_config_get_long_with_default (db, "/Mail/Accounts/default_account", 0, NULL); - a = get_address (def); - a->default_address = TRUE; - - return a; -} - -void -itip_address_free (ItipAddress *address) -{ - g_free (address->name); - g_free (address->address); - g_free (address->full); - g_free (address); -} - -void -itip_addresses_free (GList *addresses) -{ - GList *l; - - for (l = addresses; l != NULL; l = l->next) { - ItipAddress *a = l->data; - itip_address_free (a); - } - g_list_free (addresses); -} - -const gchar * -itip_strip_mailto (const gchar *address) -{ - if (address == NULL) - return NULL; - - if (!g_strncasecmp (address, "mailto:", 7)) - address += 7; - - return address; -} - -typedef struct { - GHashTable *tzids; - icalcomponent *icomp; - CalClient *client; - icalcomponent *zones; -} ItipUtilTZData; - -static GNOME_Evolution_Composer_RecipientList * -comp_to_list (CalComponentItipMethod method, CalComponent *comp) -{ - GNOME_Evolution_Composer_RecipientList *to_list; - GNOME_Evolution_Composer_Recipient *recipient; - CalComponentOrganizer organizer; - GSList *attendees, *l; - gint cntr, len; - - switch (method) { - case CAL_COMPONENT_METHOD_REQUEST: - case CAL_COMPONENT_METHOD_CANCEL: - cal_component_get_attendee_list (comp, &attendees); - len = g_slist_length (attendees); - if (len <= 0) { - e_notice (NULL, GNOME_MESSAGE_BOX_ERROR, - _("At least one attendee is necessary")); - cal_component_free_attendee_list (attendees); - return NULL; - } - - to_list = GNOME_Evolution_Composer_RecipientList__alloc (); - to_list->_maximum = len; - to_list->_length = len; - to_list->_buffer = CORBA_sequence_GNOME_Evolution_Composer_Recipient_allocbuf (len); - - for (cntr = 0, l = attendees; cntr < len; cntr++, l = l->next) { - CalComponentAttendee *att = l->data; - - recipient = &(to_list->_buffer[cntr]); - if (att->cn) - recipient->name = CORBA_string_dup (att->cn); - else - recipient->name = CORBA_string_dup (""); - recipient->address = CORBA_string_dup (itip_strip_mailto (att->value)); - } - cal_component_free_attendee_list (attendees); - break; - - case CAL_COMPONENT_METHOD_REPLY: - case CAL_COMPONENT_METHOD_ADD: - case CAL_COMPONENT_METHOD_REFRESH: - case CAL_COMPONENT_METHOD_COUNTER: - case CAL_COMPONENT_METHOD_DECLINECOUNTER: - cal_component_get_organizer (comp, &organizer); - if (organizer.value == NULL) { - e_notice (NULL, GNOME_MESSAGE_BOX_ERROR, - _("An organizer must be set.")); - return NULL; - } - - len = 1; - - to_list = GNOME_Evolution_Composer_RecipientList__alloc (); - to_list->_maximum = len; - to_list->_length = len; - to_list->_buffer = CORBA_sequence_GNOME_Evolution_Composer_Recipient_allocbuf (len); - recipient = &(to_list->_buffer[0]); - - if (organizer.cn != NULL) - recipient->name = CORBA_string_dup (organizer.cn); - else - recipient->name = CORBA_string_dup (""); - recipient->address = CORBA_string_dup (itip_strip_mailto (organizer.value)); - break; - - default: - to_list = GNOME_Evolution_Composer_RecipientList__alloc (); - to_list->_maximum = to_list->_length = 0; - break; - } - CORBA_sequence_set_release (to_list, TRUE); - - return to_list; -} - -static CORBA_char * -comp_subject (CalComponentItipMethod method, CalComponent *comp) -{ - CalComponentText caltext; - const char *description, *prefix = NULL; - GSList *alist; - int *sequence; - CORBA_char *subject; - - cal_component_get_summary (comp, &caltext); - if (caltext.value != NULL) - description = caltext.value; - else { - switch (cal_component_get_vtype (comp)) { - case CAL_COMPONENT_EVENT: - description = U_("Event information"); - case CAL_COMPONENT_TODO: - description = U_("Task information"); - case CAL_COMPONENT_JOURNAL: - description = U_("Journal information"); - case CAL_COMPONENT_FREEBUSY: - description = U_("Free/Busy information"); - default: - description = U_("Calendar information"); - } - } - - switch (method) { - case CAL_COMPONENT_METHOD_PUBLISH: - case CAL_COMPONENT_METHOD_REQUEST: - /* FIXME: If this is an update to a previous - * PUBLISH or REQUEST, then - prefix = U_("Updated"); - */ - break; - - case CAL_COMPONENT_METHOD_REPLY: - cal_component_get_attendee_list (comp, &alist); - if (alist != NULL) { - CalComponentAttendee *a = alist->data; - - switch (a->status) { - case ICAL_PARTSTAT_ACCEPTED: - prefix = U_("Accepted"); - break; - case ICAL_PARTSTAT_TENTATIVE: - prefix = U_("Tentatively Accepted"); - break; - case ICAL_PARTSTAT_DECLINED: - prefix = U_("Declined"); - break; - default: - break; - } - cal_component_free_attendee_list (alist); - } - break; - - case CAL_COMPONENT_METHOD_ADD: - prefix = U_("Updated"); - break; - - case CAL_COMPONENT_METHOD_CANCEL: - prefix = U_("Cancel"); - break; - - case CAL_COMPONENT_METHOD_REFRESH: - prefix = U_("Refresh"); - break; - - case CAL_COMPONENT_METHOD_COUNTER: - prefix = U_("Counter-proposal"); - break; - - case CAL_COMPONENT_METHOD_DECLINECOUNTER: - prefix = U_("Declined"); - break; - - default: - break; - } - - if (prefix) { - subject = CORBA_string_alloc (strlen (description) + - strlen (prefix) + 3); - sprintf (subject, "%s: %s", prefix, description); - } else - subject = CORBA_string_dup (description); - - return subject; -} - -static CORBA_char * -comp_content_type (CalComponent *comp, CalComponentItipMethod method) -{ - char tmp[256]; - - sprintf (tmp, "text/calendar; name=\"%s\"; charset=utf-8; METHOD=%s", - cal_component_get_vtype (comp) == CAL_COMPONENT_FREEBUSY ? - "freebusy.ifb" : "calendar.ics", itip_methods[method]); - return CORBA_string_dup (tmp); - -} - -static void -foreach_tzid_callback (icalparameter *param, gpointer data) -{ - ItipUtilTZData *tz_data = data; - const char *tzid; - icaltimezone *zone = NULL; - icalcomponent *vtimezone_comp; - - /* Get the TZID string from the parameter. */ - tzid = icalparameter_get_tzid (param); - if (!tzid || g_hash_table_lookup (tz_data->tzids, tzid)) - return; - - /* Look for the timezone */ - if (tz_data->zones != NULL) - zone = icalcomponent_get_timezone (tz_data->zones, tzid); - if (zone == NULL) - zone = icaltimezone_get_builtin_timezone_from_tzid (tzid); - if (zone == NULL && tz_data->client != NULL) - cal_client_get_timezone (tz_data->client, tzid, &zone); - if (zone == NULL) - return; - - /* Convert it to a string and add it to the hash. */ - vtimezone_comp = icaltimezone_get_component (zone); - if (!vtimezone_comp) - return; - - icalcomponent_add_component (tz_data->icomp, icalcomponent_new_clone (vtimezone_comp)); - g_hash_table_insert (tz_data->tzids, (char *)tzid, (char *)tzid); -} - -static char * -comp_string (CalComponentItipMethod method, CalComponent *comp, CalClient *client, icalcomponent *zones) -{ - icalcomponent *top_level, *icomp; - icalproperty *prop; - icalvalue *value; - gchar *ical_string; - ItipUtilTZData tz_data; - - top_level = cal_util_new_top_level (); - - prop = icalproperty_new (ICAL_METHOD_PROPERTY); - value = icalvalue_new_method (itip_methods_enum[method]); - icalproperty_set_value (prop, value); - icalcomponent_add_property (top_level, prop); - - icomp = cal_component_get_icalcomponent (comp); - - if (method == CAL_COMPONENT_METHOD_REPLY) { - struct icaltimetype dtstamp; - gboolean add_it = FALSE; - - /* workaround for Outlook expecting a X-MICROSOFT-CDO-REPLYTIME - on every METHOD=REPLY message. If the component has any of - the X-MICROSOFT-* properties, we add the REPLYTIME one */ - prop = icalcomponent_get_first_property (icomp, ICAL_X_PROPERTY); - while (prop) { - const char *x_name; - - x_name = icalproperty_get_x_name (prop); - if (!strncmp (x_name, "X-MICROSOFT-", strlen ("X-MICROSOFT-"))) { - add_it = TRUE; - break; - } - prop = icalcomponent_get_next_property (icomp, ICAL_X_PROPERTY); - } - - if (add_it) { - dtstamp = icaltime_from_timet_with_zone ( - time (NULL), 0, icaltimezone_get_utc_timezone ()); - prop = icalproperty_new_x (icaltime_as_ical_string (dtstamp)); - icalproperty_set_x_name (prop, "X-MICROSOFT-CDO-REPLYTIME"); - icalcomponent_add_property (icomp, prop); - } - } - - /* Add the timezones */ - tz_data.tzids = g_hash_table_new (g_str_hash, g_str_equal); - tz_data.icomp = top_level; - tz_data.client = client; - tz_data.zones = zones; - icalcomponent_foreach_tzid (icomp, foreach_tzid_callback, &tz_data); - g_hash_table_destroy (tz_data.tzids); - - icalcomponent_add_component (top_level, icomp); - ical_string = icalcomponent_as_ical_string (top_level); - icalcomponent_remove_component (top_level, icomp); - - icalcomponent_free (top_level); - - return ical_string; -} - -static gboolean -comp_limit_attendees (CalComponent *comp) -{ - icalcomponent *icomp; - GList *addresses; - icalproperty *prop; - gboolean found = FALSE, match = FALSE; - GSList *l, *list = NULL; - - icomp = cal_component_get_icalcomponent (comp); - addresses = itip_addresses_get (); - - for (prop = icalcomponent_get_first_property (icomp, ICAL_ATTENDEE_PROPERTY); - prop != NULL; - prop = icalcomponent_get_next_property (icomp, ICAL_ATTENDEE_PROPERTY)) - { - icalvalue *value; - const char *attendee; - char *text; - GList *l; - - /* If we've already found something, just erase the rest */ - if (found) { - list = g_slist_prepend (list, prop); - continue; - } - - value = icalproperty_get_value (prop); - if (!value) - continue; - - attendee = icalvalue_get_string (value); - - text = g_strdup (itip_strip_mailto (attendee)); - text = g_strstrip (text); - for (l = addresses; l != NULL; l = l->next) { - ItipAddress *a = l->data; - - if (!g_strcasecmp (a->address, text)) - found = match = TRUE; - } - g_free (text); - - if (!match) - list = g_slist_prepend (list, prop); - match = FALSE; - } - - for (l = list; l != NULL; l = l->next) { - prop = l->data; - - icalcomponent_remove_property (icomp, prop); - icalproperty_free (prop); - } - g_slist_free (list); - - itip_addresses_free (addresses); - - return found; -} - -static void -comp_sentby (CalComponent *comp) -{ - CalComponentOrganizer organizer; - GList *addresses, *l; - const char *strip; - gboolean is_user = FALSE; - - cal_component_get_organizer (comp, &organizer); - if (!organizer.value) { - ItipAddress *a = itip_addresses_get_default (); - - organizer.value = g_strdup_printf ("MAILTO:%s", a->address); - organizer.sentby = NULL; - organizer.cn = a->name; - organizer.language = NULL; - - cal_component_set_organizer (comp, &organizer); - g_free ((char *) organizer.value); - itip_address_free (a); - - return; - } - - strip = itip_strip_mailto (organizer.value); - - addresses = itip_addresses_get (); - for (l = addresses; l != NULL; l = l->next) { - ItipAddress *a = l->data; - - if (!strcmp (a->address, strip)) { - is_user = TRUE; - break; - } - } - if (!is_user) { - ItipAddress *a = itip_addresses_get_default (); - - organizer.value = g_strdup (organizer.value); - organizer.sentby = g_strdup_printf ("MAILTO:%s", a->address); - organizer.cn = g_strdup (organizer.cn); - organizer.language = g_strdup (organizer.language); - - cal_component_set_organizer (comp, &organizer); - - g_free ((char *)organizer.value); - g_free ((char *)organizer.sentby); - g_free ((char *)organizer.cn); - g_free ((char *)organizer.language); - itip_address_free (a); - } - - itip_addresses_free (addresses); -} -static CalComponent * -comp_minimal (CalComponent *comp, gboolean attendee) -{ - CalComponent *clone; - icalcomponent *icomp, *icomp_clone; - icalproperty *prop; - CalComponentOrganizer organizer; - const char *uid; - GSList *comments; - struct icaltimetype itt; - CalComponentRange recur_id; - - clone = cal_component_new (); - cal_component_set_new_vtype (clone, cal_component_get_vtype (comp)); - - if (attendee) { - GSList *attendees; - - cal_component_get_attendee_list (comp, &attendees); - cal_component_set_attendee_list (clone, attendees); - - if (!comp_limit_attendees (clone)) { - e_notice (NULL, GNOME_MESSAGE_BOX_ERROR, - _("You must be an attendee of the event.")); - goto error; - } - } - - itt = icaltime_from_timet_with_zone (time (NULL), FALSE, - icaltimezone_get_utc_timezone ()); - cal_component_set_dtstamp (clone, &itt); - - cal_component_get_organizer (comp, &organizer); - if (organizer.value == NULL) - goto error; - cal_component_set_organizer (clone, &organizer); - - cal_component_get_uid (comp, &uid); - cal_component_set_uid (clone, uid); - - cal_component_get_comment_list (comp, &comments); - if (g_slist_length (comments) <= 1) { - cal_component_set_comment_list (clone, comments); - } else { - GSList *l = comments; - - comments = g_slist_remove_link (comments, l); - cal_component_set_comment_list (clone, l); - cal_component_free_text_list (l); - } - cal_component_free_text_list (comments); - - cal_component_get_recurid (comp, &recur_id); - if (recur_id.datetime.value != NULL) - cal_component_set_recurid (clone, &recur_id); - - icomp = cal_component_get_icalcomponent (comp); - icomp_clone = cal_component_get_icalcomponent (clone); - for (prop = icalcomponent_get_first_property (icomp, ICAL_X_PROPERTY); - prop != NULL; - prop = icalcomponent_get_next_property (icomp, ICAL_X_PROPERTY)) - { - icalproperty *p; - - p = icalproperty_new_clone (prop); - icalcomponent_add_property (icomp_clone, p); - } - - cal_component_rescan (clone); - - return clone; - - error: - gtk_object_unref (GTK_OBJECT (clone)); - return NULL; -} - -static CalComponent * -comp_compliant (CalComponentItipMethod method, CalComponent *comp) -{ - CalComponent *clone, *temp_clone; - struct icaltimetype itt; - - clone = cal_component_clone (comp); - itt = icaltime_from_timet_with_zone (time (NULL), FALSE, - icaltimezone_get_utc_timezone ()); - cal_component_set_dtstamp (clone, &itt); - - /* We delete incoming alarms anyhow, and this helps with outlook */ - cal_component_remove_all_alarms (clone); - - /* Comply with itip spec */ - switch (method) { - case CAL_COMPONENT_METHOD_PUBLISH: - comp_sentby (clone); - cal_component_set_attendee_list (clone, NULL); - break; - case CAL_COMPONENT_METHOD_REQUEST: - comp_sentby (clone); - break; - case CAL_COMPONENT_METHOD_CANCEL: - comp_sentby (clone); - break; - case CAL_COMPONENT_METHOD_REPLY: - break; - case CAL_COMPONENT_METHOD_ADD: - break; - case CAL_COMPONENT_METHOD_REFRESH: - /* Need to remove almost everything */ - temp_clone = comp_minimal (clone, TRUE); - gtk_object_unref (GTK_OBJECT (clone)); - clone = temp_clone; - break; - case CAL_COMPONENT_METHOD_COUNTER: - break; - case CAL_COMPONENT_METHOD_DECLINECOUNTER: - /* Need to remove almost everything */ - temp_clone = comp_minimal (clone, FALSE); - gtk_object_unref (GTK_OBJECT (clone)); - clone = temp_clone; - break; - default: - } - - return clone; -} - -void -itip_send_comp (CalComponentItipMethod method, CalComponent *send_comp, - CalClient *client, icalcomponent *zones) -{ - BonoboObjectClient *bonobo_server; - GNOME_Evolution_Composer composer_server; - CalComponent *comp = NULL; - GNOME_Evolution_Composer_RecipientList *to_list = NULL; - GNOME_Evolution_Composer_RecipientList *cc_list = NULL; - GNOME_Evolution_Composer_RecipientList *bcc_list = NULL; - CORBA_char *subject = NULL, *body = NULL, *content_type = NULL; - CORBA_char *filename = NULL, *description = NULL; - GNOME_Evolution_Composer_AttachmentData *attach_data = NULL; - char *ical_string; - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - /* Obtain an object reference for the Composer. */ - bonobo_server = bonobo_object_activate (GNOME_EVOLUTION_COMPOSER_OAFIID, 0); - g_return_if_fail (bonobo_server != NULL); - composer_server = BONOBO_OBJREF (bonobo_server); - - comp = comp_compliant (method, send_comp); - if (comp == NULL) - goto cleanup; - - to_list = comp_to_list (method, comp); - if (to_list == NULL) - goto cleanup; - - 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; - - /* Subject information */ - subject = comp_subject (method, comp); - - /* Set recipients, subject */ - GNOME_Evolution_Composer_setHeaders (composer_server, to_list, cc_list, bcc_list, subject, &ev); - if (BONOBO_EX (&ev)) { - g_warning ("Unable to set composer headers while sending iTip message"); - goto cleanup; - } - - /* Content type */ - content_type = comp_content_type (comp, method); - - ical_string = comp_string (method, comp, client, zones); - attach_data = GNOME_Evolution_Composer_AttachmentData__alloc (); - attach_data->_length = strlen (ical_string) + 1; - attach_data->_maximum = attach_data->_length; - attach_data->_buffer = CORBA_sequence_CORBA_char_allocbuf (attach_data->_length); - strcpy (attach_data->_buffer, ical_string); - - GNOME_Evolution_Composer_setBody (composer_server, ical_string, content_type, &ev); - - if (BONOBO_EX (&ev)) { - g_warning ("Unable to attach data to the composer while sending iTip message"); - goto cleanup; - } - - if (method == CAL_COMPONENT_METHOD_PUBLISH) { - GNOME_Evolution_Composer_show (composer_server, &ev); - if (BONOBO_EX (&ev)) - g_warning ("Unable to show the composer while sending iTip message"); - } else { - GNOME_Evolution_Composer_send (composer_server, &ev); - if (BONOBO_EX (&ev)) - g_warning ("Unable to send iTip message"); - } - - cleanup: - CORBA_exception_free (&ev); - - if (comp != NULL) - gtk_object_unref (GTK_OBJECT (comp)); - - if (to_list != NULL) - CORBA_free (to_list); - if (cc_list != NULL) - CORBA_free (cc_list); - if (bcc_list != NULL) - CORBA_free (bcc_list); - - if (subject != NULL) - CORBA_free (subject); - if (body != NULL) - CORBA_free (body); - if (content_type != NULL) - CORBA_free (content_type); - if (filename != NULL) - CORBA_free (filename); - if (description != NULL) - CORBA_free (description); - if (attach_data != NULL) - CORBA_free (attach_data); -} - diff --git a/calendar/gui/itip-utils.h b/calendar/gui/itip-utils.h deleted file mode 100644 index 2863d871e2..0000000000 --- a/calendar/gui/itip-utils.h +++ /dev/null @@ -1,41 +0,0 @@ - -#ifndef ITIP_UTILS_HEADER -#define ITIP_UTILS_HEADER - -#include <ical.h> -#include <string.h> -#include <glib.h> -#include <cal-client/cal-client.h> -#include <cal-util/cal-component.h> - -typedef enum { - CAL_COMPONENT_METHOD_PUBLISH, - CAL_COMPONENT_METHOD_REQUEST, - CAL_COMPONENT_METHOD_REPLY, - CAL_COMPONENT_METHOD_ADD, - CAL_COMPONENT_METHOD_CANCEL, - CAL_COMPONENT_METHOD_REFRESH, - CAL_COMPONENT_METHOD_COUNTER, - CAL_COMPONENT_METHOD_DECLINECOUNTER -} CalComponentItipMethod; - -typedef struct { - gchar *name; - gchar *address; - gchar *full; - - gboolean default_address; -} ItipAddress; - -GList *itip_addresses_get (void); -ItipAddress *itip_addresses_get_default (void); -void itip_address_free (ItipAddress *address); -void itip_addresses_free (GList *addresses); - -const gchar *itip_strip_mailto (const gchar *address); - -void itip_send_comp (CalComponentItipMethod method, CalComponent *comp, - CalClient *client, icalcomponent *zones); - - -#endif diff --git a/calendar/gui/main.c b/calendar/gui/main.c deleted file mode 100644 index 5c7a2bc08f..0000000000 --- a/calendar/gui/main.c +++ /dev/null @@ -1,168 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* control-factory.c - * - * Copyright (C) 2000 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Ettore Perazzoli - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <glib.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <libgnomeui/gnome-init.h> -#include <libgnomevfs/gnome-vfs-init.h> -#include <glade/glade.h> - -#include <liboaf/liboaf.h> -#include <bonobo/bonobo-main.h> -#include <bonobo/bonobo-generic-factory.h> -#include <bonobo/bonobo-exception.h> - -#include <gal/widgets/e-cursors.h> - -#include "alarm-notify/alarm.h" -#include "calendar-commands.h" -#include "calendar-config.h" -#include "component-factory.h" -#include "comp-editor-factory.h" -#include "control-factory.h" -#include "itip-control-factory.h" -#include "tasks-control-factory.h" - -/* The component editor factory */ -static CompEditorFactory *comp_editor_factory = NULL; - -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")); -} - -/* Factory function for the calendar component factory; just creates and - * references a singleton service object. - */ -static BonoboObject * -comp_editor_factory_fn (BonoboGenericFactory *factory, void *data) -{ - if (!comp_editor_factory) { - comp_editor_factory = comp_editor_factory_new (); - if (!comp_editor_factory) - return NULL; - } - - bonobo_object_ref (BONOBO_OBJECT (comp_editor_factory)); - return BONOBO_OBJECT (comp_editor_factory); -} - -/* Creates and registers the component editor factory */ -static void -component_editor_factory_init (void) -{ - BonoboGenericFactory *factory; - - factory = bonobo_generic_factory_new ( - "OAFIID:GNOME_Evolution_Calendar_CompEditorFactory_Factory", - comp_editor_factory_fn, NULL); - if (!factory) - g_error (_("Could not create the component editor factory")); -} - -/* Does a simple activation and unreffing of the alarm notification service so - * that the daemon will be launched if it is not running yet. - */ -static void -launch_alarm_daemon (void) -{ - CORBA_Environment ev; - GNOME_Evolution_Calendar_AlarmNotify an; - - CORBA_exception_init (&ev); - an = oaf_activate_from_id ("OAFIID:GNOME_Evolution_Calendar_AlarmNotify", 0, NULL, &ev); - - if (BONOBO_EX (&ev)) { - g_message ("add_alarms(): Could not activate the alarm notification service"); - CORBA_exception_free (&ev); - return; - } - CORBA_exception_free (&ev); - - /* Just get rid of it; what we are interested in is that it gets launched */ - - CORBA_exception_init (&ev); - bonobo_object_release_unref (an, &ev); - if (BONOBO_EX (&ev)) - g_message ("add_alarms(): Could not unref the alarm notification service"); - - CORBA_exception_free (&ev); -} - -int -main (int argc, char **argv) -{ - free (malloc (8)); - - bindtextdomain(PACKAGE, EVOLUTION_LOCALEDIR); - textdomain(PACKAGE); - - init_bonobo (argc, argv); - - if (!gnome_vfs_init ()) - g_error (_("Could not initialize gnome-vfs")); - - glade_gnome_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 - - calendar_config_init (); - - control_factory_init (); - component_factory_init (); - itip_control_factory_init (); - tasks_control_factory_init (); - component_editor_factory_init (); - - launch_alarm_daemon (); - - gtk_widget_push_visual (gdk_rgb_get_visual ()); - gtk_widget_push_colormap (gdk_rgb_get_cmap ()); - - bonobo_main (); - - alarm_done (); - calendar_config_write_on_exit (); - - gnome_vfs_shutdown (); - - return 0; -} diff --git a/calendar/gui/misc.c b/calendar/gui/misc.c deleted file mode 100644 index 15dcf93e09..0000000000 --- a/calendar/gui/misc.c +++ /dev/null @@ -1,60 +0,0 @@ -/* Evolution calendar - Miscellaneous utility functions - * - * 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <ctype.h> -#include "misc.h" - - - -/** - * string_is_empty: - * @value: A string. - * - * Returns whether a string is NULL, the empty string, or completely made up of - * whitespace characters. - * - * Return value: TRUE if the string is empty, FALSE otherwise. - **/ -gboolean -string_is_empty (const char *value) -{ - const char *p; - gboolean empty; - - empty = TRUE; - - if (value) { - p = value; - while (*p) { - if (!isspace ((unsigned char) *p)) { - empty = FALSE; - break; - } - p++; - } - } - return empty; - -} diff --git a/calendar/gui/misc.h b/calendar/gui/misc.h deleted file mode 100644 index 81e2a13afe..0000000000 --- a/calendar/gui/misc.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Evolution calendar - Miscellaneous utility functions - * - * 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef MISC_H -#define MISC_H - -#include <glib.h> - -gboolean string_is_empty (const char *value); - -#endif diff --git a/calendar/gui/print.c b/calendar/gui/print.c deleted file mode 100644 index b353fc24fb..0000000000 --- a/calendar/gui/print.c +++ /dev/null @@ -1,2646 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* Evolution calendar - Print support - * - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Michael Zucchi <notzed@ximian.com> - * Federico Mena-Quintero <federico@ximian.com> - * Damon Chaplin <damon@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 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 <time.h> -#include <glib.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <libgnome/gnome-paper.h> -#include <libgnomeui/gnome-dialog.h> -#include <libgnomeui/gnome-uidefs.h> -#include <libgnomeui/gnome-paper-selector.h> -#include <libgnomeui/gnome-stock.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 <e-util/e-time-utils.h> -#include <gal/util/e-unicode-i18n.h> -#include <gal/widgets/e-unicode.h> -#include <cal-util/timeutil.h> -#include "calendar-commands.h" -#include "calendar-config.h" -#include "e-day-view.h" -#include "e-day-view-layout.h" -#include "e-week-view.h" -#include "e-week-view-layout.h" -#include "gnome-cal.h" -#include "print.h" - - - -/* - * Note that most dimensions are in points (1/72 of an inch) since that is - * what gnome-print uses. - */ - -/* The font to use */ -#define DEFAULT_FONT "Times" - -/* The font size to use for normal text. */ -#define DAY_NORMAL_FONT_SIZE 12 -#define WEEK_NORMAL_FONT_SIZE 12 -#define MONTH_NORMAL_FONT_SIZE 8 - -/* The height of the header bar across the top of the Day, Week & Month views, - which contains the dates shown and the 2 small calendar months. */ -#define HEADER_HEIGHT 80 - -/* The width of the small calendar months, the space from the right edge of - the header rectangle, and the space between the months. */ -#define SMALL_MONTH_WIDTH 80 -#define SMALL_MONTH_PAD 4 -#define SMALL_MONTH_SPACING 12 - -/* The minimum number of rows we leave space for for the long events in the - day view. */ -#define DAY_VIEW_MIN_ROWS_IN_TOP_DISPLAY 2 - -/* The row height for long events in the day view. */ -#define DAY_VIEW_ROW_HEIGHT 20 - -/* The minutes per row in the day view printout. */ -#define DAY_VIEW_MINS_PER_ROW 30 - -#define DAY_VIEW_ROWS ((60 / DAY_VIEW_MINS_PER_ROW) * 24) - -/* The width of the column with all the times in it. */ -#define DAY_VIEW_TIME_COLUMN_WIDTH 36 - -/* The space on the right of each event. */ -#define DAY_VIEW_EVENT_X_PAD 8 - -/* Allowance for small errors in floating point comparisons. */ -#define EPSILON 0.01 - -/* 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 SEPT_1752_START 2 /* Start day within month */ -#define SEPT_1752_END 20 /* End day within month */ - - -struct pdinfo -{ - gint days_shown; - time_t day_starts[E_DAY_VIEW_MAX_DAYS + 1]; - - GArray *long_events; - GArray *events[E_DAY_VIEW_MAX_DAYS]; - - gint start_hour; - gint end_hour; - gint start_minute_offset; - gint end_minute_offset; - gint rows; - gint mins_per_row; - gint8 cols_per_row[DAY_VIEW_ROWS]; - gboolean use_24_hour_format; -}; - -struct psinfo -{ - gint days_shown; - time_t day_starts[E_WEEK_VIEW_MAX_WEEKS * 7 + 1]; - - GArray *events; - - int rows_per_cell; - int rows_per_compressed_cell; - int display_start_weekday; - gboolean multi_week_view; - int weeks_shown; - int month; - gboolean compress_weekend; - gboolean use_24_hour_format; - double row_height; - double header_row_height; -}; - -struct ptinfo -{ - GList *todos; -}; - -struct einfo -{ - char *text; - time_t start; - time_t end; - int count; -}; - -static const GnomePaper *paper_info = NULL; - - -/* Convenience function to help the transition to timezone functions. - It returns the current timezone. */ -static icaltimezone* -get_timezone (void) -{ - char *location = calendar_config_get_timezone (); - return icaltimezone_get_builtin_timezone (location); -} - - -/* Convenience function to help the transition to timezone functions. - It converts a time_t to a struct tm. */ -static struct tm* -convert_timet_to_struct_tm (time_t time, icaltimezone *zone) -{ - static struct tm my_tm; - struct icaltimetype tt; - - /* Convert it to an icaltimetype. */ - tt = icaltime_from_timet_with_zone (time, FALSE, zone); - - /* Fill in the struct tm. */ - my_tm.tm_year = tt.year - 1900; - my_tm.tm_mon = tt.month - 1; - my_tm.tm_mday = tt.day; - my_tm.tm_hour = tt.hour; - my_tm.tm_min = tt.minute; - my_tm.tm_sec = tt.second; - my_tm.tm_isdst = tt.is_daylight; - - my_tm.tm_wday = time_day_of_week (tt.day, tt.month - 1, tt.year); - - return &my_tm; -} - - -/* 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 *days, int *start, int *end) -{ - int i; - int d_month, d_week, week_start_day; - - /* 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 = time_days_in_month (year, month); - /* Get the start weekday in the month, 0=Sun to 6=Sat. */ - d_week = time_day_of_week (1, month, year); - - /* Get the configuration setting specifying which weekday we put on - the left column, 0=Sun to 6=Sat. */ - week_start_day = calendar_config_get_week_start_day (); - - /* Figure out which square we want to put the 1 in. */ - d_week = (d_week + 7 - week_start_day) % 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; -} - -static GnomeFont * -get_font_for_size (double h, GnomeFontWeight weight, gboolean italic) -{ - GnomeFontFace *face; - GnomeFont *font; - double asc, desc, size; - - face = gnome_font_unsized_closest (DEFAULT_FONT, weight, italic); - asc = gnome_font_face_get_ascender (face); - desc = gnome_font_face_get_descender (face); - size = h * 1000 / (asc + desc); - g_print ("Print Info: %f, %f, %f\n", asc, desc, size); - - font = gnome_font_new_closest (DEFAULT_FONT, weight, italic, size); - - gtk_object_unref (GTK_OBJECT (face)); - - return font; -} - -enum align_box { - ALIGN_LEFT=1, - ALIGN_RIGHT, - ALIGN_CENTER, - ALIGN_BORDER= 1<<8 -}; - - -/* Prints a rectangle, with or without a border, filled or outline, and - possibly with triangular arrows at one or both horizontal edges. - width = width of border, -ve means no border. - fillcolor = shade of fill, -ve means no fill. - left_triangle_width, right_triangle_width = width from edge of rectangle to - point of triangle, or -ve for no triangle. */ -static void -print_border_with_triangles (GnomePrintContext *pc, - double l, double r, double t, double b, - double width, double fillcolor, - double left_triangle_width, - double right_triangle_width) -{ - gnome_print_gsave (pc); - - /* Fill in the interior of the rectangle, if desired. */ - if (fillcolor >= -EPSILON) { - gnome_print_moveto (pc, l, t); - if (left_triangle_width > 0.0) - gnome_print_lineto (pc, l - left_triangle_width, - (t + b) / 2); - gnome_print_lineto (pc, l, b); - gnome_print_lineto (pc, r, b); - if (right_triangle_width > 0.0) - gnome_print_lineto (pc, r + right_triangle_width, - (t + b) / 2); - gnome_print_lineto (pc, r, t); - gnome_print_closepath (pc); - gnome_print_setrgbcolor (pc, fillcolor, fillcolor, - fillcolor); - gnome_print_fill (pc); - } - - /* Draw the outline, if desired. */ - if (width >= -EPSILON) { - gnome_print_moveto (pc, l, t); - if (left_triangle_width > 0.0) - gnome_print_lineto (pc, l - left_triangle_width, - (t + b) / 2); - gnome_print_lineto (pc, l, b); - gnome_print_lineto (pc, r, b); - if (right_triangle_width > 0.0) - gnome_print_lineto (pc, r + right_triangle_width, - (t + b) / 2); - gnome_print_lineto (pc, r, t); - gnome_print_closepath (pc); - gnome_print_setrgbcolor (pc, 0, 0, 0); - gnome_print_setlinewidth (pc, width); - gnome_print_stroke (pc); - } - - gnome_print_grestore (pc); -} - - -/* Prints a rectangle, with or without a border, and filled or outline. - width = width of border, -ve means no border. - fillcolor = shade of fill, -ve means no fill. */ -static void -print_border (GnomePrintContext *pc, - double l, double r, double t, double b, - double width, double fillcolor) -{ - print_border_with_triangles (pc, l, r, t, b, width, fillcolor, - -1.0, -1.0); -} - - -/* Prints 1 line of aligned text in a box. It is centered vertically, and - the horizontal alignment can be either ALIGN_LEFT, ALIGN_RIGHT, or - ALIGN_CENTER. */ -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, y; - - gnome_print_gsave (pc); - - w = gnome_font_get_width_utf8 (font, text); - - switch (align & 3) { - case ALIGN_LEFT: - default: - x = l; - break; - case ALIGN_RIGHT: - x = r - w; - break; - case ALIGN_CENTER: - x = l + ((r - l) - w) / 2; - break; - } - - /* Make sure we don't go off the left edge. */ - x = MAX (l, x); - - /* Now calculate the baseline. */ - y = t - gnome_font_get_ascender (font); - - /* Set a clipping rectangle. */ - gnome_print_moveto (pc, l, t); - gnome_print_lineto (pc, r, t); - gnome_print_lineto (pc, r, b); - gnome_print_lineto (pc, l, b); - gnome_print_closepath (pc); - gnome_print_clip (pc); - - gnome_print_newpath (pc); - gnome_print_moveto (pc, x, y); - 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 book font */ -static void -print_text_size(GnomePrintContext *pc, const char *text, - enum align_box align, double l, double r, double t, double b) -{ - GnomeFont *font; - - font = get_font_for_size (t - b, GNOME_FONT_BOOK, FALSE); - print_text(pc, font, text, align, l, r, t, b); - gtk_object_unref (GTK_OBJECT (font)); -} - -/* gets/frees the font for you, as a bold font */ -static void -print_text_size_bold(GnomePrintContext *pc, const char *text, - enum align_box align, double l, double r, double t, double b) -{ - GnomeFont *font; - - font = get_font_for_size (t - b, GNOME_FONT_BOLD, FALSE); - 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) -{ - double size; - - size = gnome_font_get_size (font); - - if (align & ALIGN_BORDER) { - print_border (pc, *l, *r, *t, *t - size * 1.4, - linewidth, 0.9); - print_border (pc, *l, *r, *t - size * 1.4, *b, - linewidth, -1.0); - - *l += 2; - *r -= 2; - *b += 2; - } - - print_text (pc, font, text, align, *l, *r, *t, *t - size * 1.4); - *t -= size * 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) -{ - icaltimezone *zone = get_timezone (); - char fmt[64]; - struct tm tm; - char *utf_str; - - tm = *convert_timet_to_struct_tm (time, zone); - - 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); - utf_str = e_utf8_from_locale_string (buffer); - strncpy (buffer, utf_str, bufflen - 1); - buffer[bufflen - 1] = '\0'; - g_free (utf_str); - 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) -{ - icaltimezone *zone = get_timezone (); - CalClient *client; - GnomeFont *font, *font_bold, *font_normal; - time_t now, next; - int x, y; - int days[42]; - int day, weekday, week_start_day; - char buf[100]; - struct tm tm; - double font_size, max_font_size; - double header_size, col_width, row_height, text_xpad, w; - double cell_top, cell_bottom, cell_left, cell_right, text_right; - char *daynames[] = { N_("Su"), N_("Mo"), N_("Tu"), N_("We"), - N_("Th"), N_("Fr"), N_("Sa") }; - - /* Print the title, e.g. 'June 2001', in the top 16% of the area. */ - format_date (month, titleflags, buf, 100); - header_size = (top - bottom) * 0.16; - font = get_font_for_size (header_size, GNOME_FONT_BOLD, FALSE); - if (bordertitle) { - print_border (pc, left, right, top, top - header_size, - 1.0, 0.9); - } - print_text (pc, font, buf, ALIGN_CENTER, left, right, - top, top - header_size); - gtk_object_unref (GTK_OBJECT (font)); - - top -= header_size; - - client = gnome_calendar_get_cal_client (gcal); - - col_width = (right - left) / 7; - - /* The top row with the day abbreviations gets an extra bit of - vertical space around it. */ - row_height = (top - bottom) / 7.4; - - /* First we need to calculate a reasonable font size. We start with a - rough guess of just under the height of each row. */ - font_size = row_height; - - /* Check that it isn't going to be too wide. The characters are about - twice as high as they are wide, but we need to fit two characters - into each cell, so we don't want to go over col_width. */ - max_font_size = col_width * 0.65; - - font_size = row_height; - - /* get month days */ - tm = *convert_timet_to_struct_tm (month, zone); - build_month (tm.tm_mon, tm.tm_year + 1900, days, 0, 0); - - font_normal = get_font_for_size (font_size, GNOME_FONT_BOOK, FALSE); - font_bold = get_font_for_size (font_size, GNOME_FONT_BOLD, FALSE); - - /* Get a reasonable estimate of the largest number we will need, - and use it to calculate the offset from the right edge of the - cell that we should put the numbers. */ - w = gnome_font_get_width_utf8 (font_bold, "23"); - text_xpad = (col_width - w) / 2; - - gnome_print_setrgbcolor (pc, 0, 0, 0); - - /* Print the abbreviated day names across the top in bold. */ - week_start_day = calendar_config_get_week_start_day (); - weekday = week_start_day; - for (x = 0; x < 7; x++) { - print_text (pc, font_bold, U_(daynames[weekday]), ALIGN_CENTER, - left + x * col_width, left + (x + 1) * col_width, - top, top - row_height * 1.4); - weekday = (weekday + 1) % 7; - } - - top -= row_height * 1.4; - - now = time_month_begin_with_zone (month, zone); - for (y = 0; y < 6; y++) { - - cell_top = top - y * row_height; - cell_bottom = cell_top - row_height; - - for (x = 0; x < 7; x++) { - - cell_left = left + x * col_width; - /* We add a 0.05 to make sure the cells meet up with - each other. Otherwise you sometimes get lines - between them which looks bad. Maybe I'm not using - coords in the way gnome-print expects. */ - cell_right = cell_left + col_width + 0.05; - text_right = cell_right - text_xpad; - - 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_with_zone (now, zone)); - font = uids ? font_bold : font_normal; - cal_obj_uid_list_free (uids); - - next = time_add_day_with_zone (now, 1, zone); - if ((now >= greystart && now < greyend) - || (greystart >= now && greystart < next)) { - print_border (pc, - cell_left, cell_right, - cell_top, cell_bottom, - -1.0, 0.75); - } - print_text (pc, font, buf, ALIGN_RIGHT, - cell_left, text_right, - cell_top, cell_bottom); - - 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_utf8_sized(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; -} - - -/* Draw the borders, lines, and times down the left of the day view. */ -static void -print_day_background (GnomePrintContext *pc, GnomeCalendar *gcal, - time_t whence, struct pdinfo *pdi, - double left, double right, double top, double bottom) -{ - GnomeFont *font_hour, *font_minute; - double yinc, y; - double width = DAY_VIEW_TIME_COLUMN_WIDTH; - double font_size, max_font_size, hour_font_size, minute_font_size; - char buf[20]; - const char *minute; - gboolean use_24_hour; - int i, hour, row; - - /* Fill the time column in light-gray. */ - print_border (pc, left, left + width, top, bottom, -1.0, 0.9); - - /* Draw the border around the entire view. */ - gnome_print_setrgbcolor (pc, 0, 0, 0); - print_border (pc, left, right, top, bottom, 1.0, -1.0); - - /* Draw the vertical line on the right of the time column. */ - gnome_print_setlinewidth (pc, 0.0); - gnome_print_moveto (pc, left + width, bottom); - gnome_print_lineto (pc, left + width, top); - gnome_print_stroke (pc); - - /* Calculate the row height. */ - yinc = (top - bottom) / (pdi->end_hour - pdi->start_hour); - - /* Get the 2 fonts we need. */ - font_size = yinc * 0.6; - max_font_size = width * 0.5; - hour_font_size = MIN (font_size, max_font_size); - font_hour = get_font_for_size (hour_font_size, GNOME_FONT_BOLD, FALSE); - - font_size = yinc * 0.33; - max_font_size = width * 0.25; - minute_font_size = MIN (font_size, max_font_size); - font_minute = get_font_for_size (minute_font_size, GNOME_FONT_BOLD, FALSE); - - use_24_hour = calendar_config_get_24_hour_format (); - - row = 0; - for (i = pdi->start_hour; i < pdi->end_hour; i++) { - y = top - yinc * (row + 1); - gnome_print_setrgbcolor (pc, 0, 0, 0); - - if (use_24_hour) { - hour = i; - minute = "00"; - } else { - if (i < 12) - minute = U_("am"); - else - minute = U_("pm"); - - hour = i % 12; - if (hour == 0) - hour = 12; - } - - /* the hour label/minute */ - sprintf (buf, "%d", hour); - print_text (pc, font_hour, buf, ALIGN_RIGHT, - left, left + width * 0.58, - y + yinc - 4, y + yinc - 4 - hour_font_size); - print_text (pc, font_minute, minute, ALIGN_RIGHT, - left, left + width - 3, - y + yinc - 3, y + yinc - 3 - minute_font_size); - - /* Draw the horizontal line between hours, across the entire - width of the day view. */ - gnome_print_moveto (pc, left, y); - gnome_print_lineto (pc, right, y); - gnome_print_stroke (pc); - - /* Draw the horizontal line for the 1/2-hours, across the - entire width except for part of the time column. */ - gnome_print_moveto (pc, left + width * 0.6, y + yinc / 2); - gnome_print_lineto (pc, right, y + yinc / 2); - gnome_print_stroke (pc); - - row++; - } - - gtk_object_unref (GTK_OBJECT (font_hour)); - gtk_object_unref (GTK_OBJECT (font_minute)); -} - - -/* This adds one event to the view, adding it to the appropriate array. */ -static gint -print_day_add_event (CalComponent *comp, - time_t start, - time_t end, - gint days_shown, - time_t *day_starts, - GArray *long_events, - GArray **events) - -{ - icaltimezone *zone = get_timezone (); - EDayViewEvent event; - gint day, offset; - struct icaltimetype start_tt, end_tt; - -#if 0 - g_print ("Day view lower: %s", ctime (&day_starts[0])); - g_print ("Day view upper: %s", ctime (&day_starts[days_shown])); - 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, -1); - g_return_val_if_fail (start < day_starts[days_shown], -1); - g_return_val_if_fail (end > day_starts[0], -1); - - start_tt = icaltime_from_timet_with_zone (start, FALSE, zone); - end_tt = icaltime_from_timet_with_zone (end, FALSE, zone); - - 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;*/ - offset = 0; - event.start_minute = start_tt.hour * 60 + start_tt.minute - offset; - event.end_minute = end_tt.hour * 60 + end_tt.minute - offset; - - event.start_row_or_col = 0; - event.num_columns = 0; - - /* Find out which array to add the event to. */ - for (day = 0; day < days_shown; day++) { - if (start >= day_starts[day] && end <= day_starts[day + 1]) { - - /* Special case for when the appointment ends at - midnight, i.e. the start of the next day. */ - if (end == 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_starts[day]) - break; - - event.end_minute = 24 * 60; - } - - g_array_append_val (events[day], event); - return day; - } - } - - /* 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 (long_events, event); - return E_DAY_VIEW_LONG_EVENT; -} - - -static gboolean -print_day_details_cb (CalComponent *comp, time_t istart, time_t iend, - gpointer data) -{ - struct pdinfo *pdi = (struct pdinfo *)data; - - print_day_add_event (comp, istart, iend, - pdi->days_shown, pdi->day_starts, - pdi->long_events, pdi->events); - - return TRUE; -} - - -static void -free_event_array (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); -} - - -static void -print_day_long_event (GnomePrintContext *pc, GnomeFont *font, - double left, double right, double top, double bottom, - double row_height, EDayViewEvent *event, - struct pdinfo *pdi) -{ - CalComponentText summary; - double x1, x2, y1, y2; - double left_triangle_width = -1.0, right_triangle_width = -1.0; - char *text; - char buffer[32]; - struct tm date_tm; - - /* If the event starts before the first day being printed, draw a - triangle. (Note that I am assuming we are just showing 1 day at - the moment.) */ - if (event->start < pdi->day_starts[0]) - left_triangle_width = 4; - - /* If the event ends after the last day being printed, draw a - triangle. */ - if (event->end > pdi->day_starts[1]) - right_triangle_width = 4; - - x1 = left + 10; - x2 = right - 10; - y1 = top - event->start_row_or_col * row_height - 4; - y2 = y1 - row_height + 4; - print_border_with_triangles (pc, x1, x2, y1, y2, 0.5, 0.95, - left_triangle_width, - right_triangle_width); - - /* If the event starts after the first day being printed, we need to - print the start time. */ - if (event->start > pdi->day_starts[0]) { - date_tm.tm_year = 2001; - date_tm.tm_mon = 0; - date_tm.tm_mday = 1; - date_tm.tm_hour = event->start_minute / 60; - date_tm.tm_min = event->start_minute % 60; - date_tm.tm_sec = 0; - date_tm.tm_isdst = -1; - - e_time_format_time (&date_tm, pdi->use_24_hour_format, FALSE, - buffer, sizeof (buffer)); - - x1 += 4; - print_text (pc, font, buffer, ALIGN_LEFT, x1, x2, y1, y2); - x1 += gnome_font_get_width_utf8 (font, buffer); - } - - /* If the event ends before the end of the last day being printed, - we need to print the end time. */ - if (event->end < pdi->day_starts[1]) { - date_tm.tm_year = 2001; - date_tm.tm_mon = 0; - date_tm.tm_mday = 1; - date_tm.tm_hour = event->end_minute / 60; - date_tm.tm_min = event->end_minute % 60; - date_tm.tm_sec = 0; - date_tm.tm_isdst = -1; - - e_time_format_time (&date_tm, pdi->use_24_hour_format, FALSE, - buffer, sizeof (buffer)); - - x2 -= 4; - print_text (pc, font, buffer, ALIGN_RIGHT, x1, x2, y1, y2); - x2 -= gnome_font_get_width_utf8 (font, buffer); - } - - /* Print the text. */ - cal_component_get_summary (event->comp, &summary); - text = summary.value ? (char*) summary.value : ""; - - x1 += 4; - x2 -= 4; - print_text (pc, font, text, ALIGN_CENTER, x1, x2, y1, y2); -} - - -static void -print_day_event (GnomePrintContext *pc, GnomeFont *font, - double left, double right, double top, double bottom, - EDayViewEvent *event, struct pdinfo *pdi) -{ - CalComponentText summary; - double x1, x2, y1, y2, col_width, row_height; - int start_offset, end_offset, start_row, end_row; - char *text, start_buffer[32], end_buffer[32]; - gboolean display_times = FALSE, free_text = FALSE; - struct tm date_tm; - - if ((event->start_minute >= pdi->end_minute_offset) - || (event->end_minute <= pdi->start_minute_offset)) - return; - - start_offset = event->start_minute - pdi->start_minute_offset; - end_offset = event->end_minute - pdi->start_minute_offset; - - start_row = start_offset / pdi->mins_per_row; - start_row = MAX (0, start_row); - end_row = (end_offset - 1) / pdi->mins_per_row; - end_row = MIN (pdi->rows - 1, end_row); - col_width = (right - left) / pdi->cols_per_row[event->start_minute / pdi->mins_per_row]; - - if (start_offset != start_row * pdi->mins_per_row - || end_offset != (end_row + 1) * pdi->mins_per_row) - display_times = TRUE; - - x1 = left + event->start_row_or_col * col_width; - x2 = x1 + event->num_columns * col_width - DAY_VIEW_EVENT_X_PAD; - - row_height = (top - bottom) / pdi->rows; - y1 = top - start_row * row_height; - y2 = top - (end_row + 1) * row_height; - -#if 0 - g_print ("Event: %g,%g %g,%g\n row_height: %g start_row: %i top: %g rows: %i\n", - x1, y1, x2, y2, row_height, start_row, top, pdi->rows); -#endif - - print_border (pc, x1, x2, y1, y2, 1.0, 0.95); - - cal_component_get_summary (event->comp, &summary); - text = summary.value ? (char*) summary.value : ""; - - - if (display_times) { - date_tm.tm_year = 2001; - date_tm.tm_mon = 0; - date_tm.tm_mday = 1; - date_tm.tm_hour = event->start_minute / 60; - date_tm.tm_min = event->start_minute % 60; - date_tm.tm_sec = 0; - date_tm.tm_isdst = -1; - - e_time_format_time (&date_tm, pdi->use_24_hour_format, FALSE, - start_buffer, sizeof (start_buffer)); - - date_tm.tm_hour = event->end_minute / 60; - date_tm.tm_min = event->end_minute % 60; - - e_time_format_time (&date_tm, pdi->use_24_hour_format, FALSE, - end_buffer, sizeof (end_buffer)); - - text = g_strdup_printf ("%s - %s %s ", start_buffer, - end_buffer, text); - - free_text = TRUE; - } - - bound_text (pc, font, text, x1 + 2, x2 - 2, y1, y2, 0); - - if (free_text) - g_free (text); -} - - -static void -print_day_details (GnomePrintContext *pc, GnomeCalendar *gcal, time_t whence, - double left, double right, double top, double bottom) -{ - icaltimezone *zone = get_timezone (); - CalClient *client; - EDayViewEvent *event; - GnomeFont *font; - time_t start, end; - struct pdinfo pdi; - gint rows_in_top_display, i; - double font_size, max_font_size; - - start = time_day_begin_with_zone (whence, zone); - end = time_day_end_with_zone (start, zone); - - pdi.days_shown = 1; - pdi.day_starts[0] = start; - pdi.day_starts[1] = end; - pdi.long_events = g_array_new (FALSE, FALSE, sizeof (EDayViewEvent)); - pdi.events[0] = g_array_new (FALSE, FALSE, sizeof (EDayViewEvent)); - pdi.start_hour = calendar_config_get_day_start_hour (); - pdi.end_hour = calendar_config_get_day_end_hour (); - if (calendar_config_get_day_end_minute () != 0) - pdi.end_hour++; - pdi.rows = (pdi.end_hour - pdi.start_hour) * 2; - pdi.mins_per_row = 30; - pdi.start_minute_offset = pdi.start_hour * 60; - pdi.end_minute_offset = pdi.end_hour * 60; - pdi.use_24_hour_format = calendar_config_get_24_hour_format (); - - /* Get the events from the server. */ - client = gnome_calendar_get_cal_client (gcal); - cal_client_generate_instances (client, CALOBJ_TYPE_EVENT, start, end, - print_day_details_cb, &pdi); - qsort (pdi.long_events->data, pdi.long_events->len, - sizeof (EDayViewEvent), e_day_view_event_sort_func); - qsort (pdi.events[0]->data, pdi.events[0]->len, - sizeof (EDayViewEvent), e_day_view_event_sort_func); - - /* Also print events outside of work hours */ - if (pdi.events[0]->len > 0) { - icaltimezone *zone = get_timezone (); - struct icaltimetype tt; - - event = &g_array_index (pdi.events[0], EDayViewEvent, 0); - tt = icaltime_from_timet_with_zone (event->start, FALSE, zone); - if (tt.hour < pdi.start_hour) - pdi.start_hour = tt.hour; - pdi.start_minute_offset = pdi.start_hour * 60; - - event = &g_array_index (pdi.events[0], EDayViewEvent, pdi.events[0]->len - 1); - tt = icaltime_from_timet_with_zone (event->end, FALSE, zone); - if (tt.hour > pdi.end_hour || tt.hour == 0) { - pdi.end_hour = tt.hour ? tt.hour : 24; - if (tt.minute > 0) - pdi.end_hour++; - } - pdi.end_minute_offset = pdi.end_hour * 60; - - pdi.rows = (pdi.end_hour - pdi.start_hour) * 2; - } - - /* Lay them out the long events, across the top of the page. */ - e_day_view_layout_long_events (pdi.long_events, pdi.days_shown, - pdi.day_starts, &rows_in_top_display); - - /* Print the long events. */ - font = get_font_for_size (12, GNOME_FONT_BOOK, FALSE); - for (i = 0; i < pdi.long_events->len; i++) { - event = &g_array_index (pdi.long_events, EDayViewEvent, i); - print_day_long_event (pc, font, left, right, top, bottom, - DAY_VIEW_ROW_HEIGHT, event, &pdi); - } - gtk_object_unref (GTK_OBJECT (font)); - - /* We always leave space for DAY_VIEW_MIN_ROWS_IN_TOP_DISPLAY in the - top display, but we may have more rows than that, in which case - the main display area will be compressed. */ - rows_in_top_display = MAX (rows_in_top_display, - DAY_VIEW_MIN_ROWS_IN_TOP_DISPLAY); - - /* Draw the border around the long events. */ - gnome_print_setrgbcolor (pc, 0, 0, 0); - print_border (pc, left, right, - top, top - rows_in_top_display * DAY_VIEW_ROW_HEIGHT - 4, - 1.0, -1.0); - - /* Adjust the area containing the main display. */ - top -= rows_in_top_display * DAY_VIEW_ROW_HEIGHT + 4; - - /* Draw the borders, lines, and times down the left. */ - print_day_background (pc, gcal, whence, &pdi, - left, right, top, bottom); - - /* Now adjust to get rid of the time column. */ - left += DAY_VIEW_TIME_COLUMN_WIDTH; - - /* Lay out the short events, within the day. */ - e_day_view_layout_day_events (pdi.events[0], DAY_VIEW_ROWS, - DAY_VIEW_MINS_PER_ROW, pdi.cols_per_row); - - /* Print the short events. */ - max_font_size = ((top - bottom) / pdi.rows) - 4; - font_size = MIN (DAY_NORMAL_FONT_SIZE, max_font_size); - font = get_font_for_size (font_size, GNOME_FONT_BOOK, FALSE); - for (i = 0; i < pdi.events[0]->len; i++) { - event = &g_array_index (pdi.events[0], EDayViewEvent, i); - print_day_event (pc, font, left, right, top, bottom, - event, &pdi); - } - gtk_object_unref (GTK_OBJECT (font)); - - /* Free everything. */ - free_event_array (pdi.long_events); - g_array_free (pdi.long_events, TRUE); - free_event_array (pdi.events[0]); - g_array_free (pdi.events[0], TRUE); -} - - -/* This adds one event to the view, adding it to the appropriate array. */ -static gboolean -print_week_summary_cb (CalComponent *comp, - time_t start, - time_t end, - gpointer data) - -{ - icaltimezone *zone = get_timezone (); - EWeekViewEvent event; - struct icaltimetype start_tt, end_tt; - - struct psinfo *psi = (struct psinfo *)data; - - /* Check that the event times are valid. */ - -#if 0 - g_print ("View start:%li end:%li Event start:%li end:%li\n", - psi->day_starts[0], psi->day_starts[psi->days_shown], - start, end); -#endif - - g_return_val_if_fail (start <= end, TRUE); - g_return_val_if_fail (start < psi->day_starts[psi->days_shown], TRUE); - g_return_val_if_fail (end > psi->day_starts[0], TRUE); - - start_tt = icaltime_from_timet_with_zone (start, FALSE, zone); - end_tt = icaltime_from_timet_with_zone (end, FALSE, zone); - - 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_tt.hour * 60 + start_tt.minute; - event.end_minute = end_tt.hour * 60 + end_tt.minute; - if (event.end_minute == 0 && start != end) - event.end_minute = 24 * 60; - - g_array_append_val (psi->events, event); - - return TRUE; -} - - -/* Returns TRUE if the event is a one-day event (i.e. not a long event). */ -static gboolean -print_is_one_day_week_event (EWeekViewEvent *event, - EWeekViewEventSpan *span, - time_t *day_starts) -{ - if (event->start == day_starts[span->start_day] - && event->end == day_starts[span->start_day + 1]) - return FALSE; - - if (span->num_days == 1 - && event->start >= day_starts[span->start_day] - && event->end <= day_starts[span->start_day + 1]) - return TRUE; - - return FALSE; -} - - -static void -print_week_long_event (GnomePrintContext *pc, GnomeFont *font, - struct psinfo *psi, - double x1, double x2, double y1, double y2, - EWeekViewEvent *event, EWeekViewEventSpan *span, - char *text) -{ - double left_triangle_width = -1.0, right_triangle_width = -1.0; - struct tm date_tm; - char buffer[32]; - - /* If the event starts before the first day of the span, draw a - triangle to indicate it continues. */ - if (event->start < psi->day_starts[span->start_day]) - left_triangle_width = 4; - - /* If the event ends after the last day of the span, draw a - triangle. */ - if (event->end > psi->day_starts[span->start_day + span->num_days]) - right_triangle_width = 4; - - print_border_with_triangles (pc, x1, x2, y1, y2, 0.5, 0.9, - left_triangle_width, - right_triangle_width); - - /* If the event starts after the first day being printed, we need to - print the start time. */ - if (event->start > psi->day_starts[span->start_day]) { - date_tm.tm_year = 2001; - date_tm.tm_mon = 0; - date_tm.tm_mday = 1; - date_tm.tm_hour = event->start_minute / 60; - date_tm.tm_min = event->start_minute % 60; - date_tm.tm_sec = 0; - date_tm.tm_isdst = -1; - - e_time_format_time (&date_tm, psi->use_24_hour_format, FALSE, - buffer, sizeof (buffer)); - - x1 += 4; - print_text_size (pc, buffer, ALIGN_LEFT, x1, x2, y1, y2); - x1 += gnome_font_get_width_utf8 (font, buffer); - } - - /* If the event ends before the end of the last day being printed, - we need to print the end time. */ - if (event->end < psi->day_starts[span->start_day + span->num_days]) { - date_tm.tm_year = 2001; - date_tm.tm_mon = 0; - date_tm.tm_mday = 1; - date_tm.tm_hour = event->end_minute / 60; - date_tm.tm_min = event->end_minute % 60; - date_tm.tm_sec = 0; - date_tm.tm_isdst = -1; - - e_time_format_time (&date_tm, psi->use_24_hour_format, FALSE, - buffer, sizeof (buffer)); - - x2 -= 4; - print_text_size (pc, buffer, ALIGN_RIGHT, x1, x2, y1, y2); - x2 -= gnome_font_get_width_utf8 (font, buffer); - } - - x1 += 4; - x2 -= 4; - print_text_size (pc, text, ALIGN_CENTER, x1, x2, y1, y2); -} - - -static void -print_week_day_event (GnomePrintContext *pc, GnomeFont *font, - struct psinfo *psi, - double x1, double x2, double y1, double y2, - EWeekViewEvent *event, EWeekViewEventSpan *span, - char *text) -{ - struct tm date_tm; - char buffer[32]; - - date_tm.tm_year = 2001; - date_tm.tm_mon = 0; - date_tm.tm_mday = 1; - date_tm.tm_hour = event->start_minute / 60; - date_tm.tm_min = event->start_minute % 60; - date_tm.tm_sec = 0; - date_tm.tm_isdst = -1; - - e_time_format_time (&date_tm, psi->use_24_hour_format, FALSE, - buffer, sizeof (buffer)); - - print_text_size (pc, buffer, ALIGN_LEFT, x1, x2, y1, y2); - x1 += gnome_font_get_width_utf8 (font, buffer); - - x1 += 4; - print_text_size (pc, text, ALIGN_LEFT, x1, x2, y1, y2); -} - - -static void -print_week_event (GnomePrintContext *pc, GnomeFont *font, - struct psinfo *psi, - double left, double top, - double cell_width, double cell_height, - EWeekViewEvent *event, GArray *spans) -{ - EWeekViewEventSpan *span; - gint span_num; - CalComponentText summary; - char *text; - int num_days, start_x, start_y, start_h, end_x, end_y, end_h; - double x1, x2, y1, y2; - - cal_component_get_summary (event->comp, &summary); - text = summary.value ? (char*) summary.value : ""; - - for (span_num = 0; span_num < event->num_spans; span_num++) { - span = &g_array_index (spans, EWeekViewEventSpan, - event->spans_index + span_num); - - if (e_week_view_layout_get_span_position - (event, span, - psi->rows_per_cell, - psi->rows_per_compressed_cell, - psi->display_start_weekday, - psi->multi_week_view, - psi->compress_weekend, - &num_days)) { - - e_week_view_layout_get_day_position - (span->start_day, - psi->multi_week_view, - psi->weeks_shown, - psi->display_start_weekday, - psi->compress_weekend, - &start_x, &start_y, &start_h); - - if (num_days == 1) { - end_x = start_x; - end_y = start_y; - end_h = start_h; - } else { - e_week_view_layout_get_day_position - (span->start_day + num_days - 1, - psi->multi_week_view, - psi->weeks_shown, - psi->display_start_weekday, - psi->compress_weekend, - &end_x, &end_y, &end_h); - } - - x1 = left + start_x * cell_width + 6; - x2 = left + (end_x + 1) * cell_width - 6; - y1 = top - start_y * cell_height - - psi->header_row_height - - span->row * psi->row_height; - y2 = y1 - psi->row_height * 0.9; - - if (print_is_one_day_week_event (event, span, - psi->day_starts)) { - print_week_day_event (pc, font, psi, - x1, x2, y1, y2, - event, span, text); - } else { - print_week_long_event (pc, font, psi, - x1, x2, y1, y2, - event, span, text); - } - } - } -} - - -static void -print_week_view_background (GnomePrintContext *pc, GnomeFont *font, - struct psinfo *psi, - double left, double top, - double cell_width, double cell_height) -{ - icaltimezone *zone = get_timezone (); - int day, day_x, day_y, day_h; - double x1, x2, y1, y2, font_size, fillcolor; - struct tm tm; - char *format_string, buffer[128], *utf_str; - - font_size = gnome_font_get_size (font); - - for (day = 0; day < psi->days_shown; day++) { - e_week_view_layout_get_day_position - (day, psi->multi_week_view, psi->weeks_shown, - psi->display_start_weekday, psi->compress_weekend, - &day_x, &day_y, &day_h); - - x1 = left + day_x * cell_width; - x2 = left + (day_x + 1) * cell_width; - y1 = top - day_y * cell_height; - y2 = y1 - day_h * cell_height; - - tm = *convert_timet_to_struct_tm (psi->day_starts[day], zone); - - /* In the month view we draw a grey background for the end - of the previous month and the start of the following. */ - fillcolor = -1.0; - if (psi->multi_week_view && (tm.tm_mon != psi->month)) - fillcolor = 0.9; - - print_border (pc, x1, x2, y1, y2, 1.0, fillcolor); - - if (psi->multi_week_view) { - if (tm.tm_mday == 1) - format_string = _("%d %B"); - else - format_string = "%d"; - } else { - gnome_print_moveto (pc, x1 + 0.1 * cell_width, - y1 - psi->header_row_height + 3); - gnome_print_lineto (pc, x2, - y1 - psi->header_row_height + 3); - gnome_print_setrgbcolor (pc, 0, 0, 0); - gnome_print_setlinewidth (pc, 0.5); - gnome_print_stroke (pc); - - /* 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"); - - } - - strftime (buffer, sizeof (buffer), format_string, &tm); - utf_str = e_utf8_from_locale_string (buffer); - print_text_size (pc, utf_str, ALIGN_RIGHT, - x1, x2 - 4, y1 - 2, y1 - 2 - font_size); - g_free (utf_str); - } -} - - - -static void -print_week_summary (GnomePrintContext *pc, GnomeCalendar *gcal, - time_t whence, gboolean multi_week_view, int weeks_shown, - int month, double font_size, - double left, double right, double top, double bottom) -{ - icaltimezone *zone = get_timezone (); - CalClient *client; - EWeekViewEvent *event; - struct psinfo psi; - time_t day_start; - gint rows_per_day[E_WEEK_VIEW_MAX_WEEKS * 7], day, event_num; - GArray *spans; - GnomeFont *font; - double cell_width, cell_height; - - psi.days_shown = weeks_shown * 7; - psi.events = g_array_new (FALSE, FALSE, sizeof (EWeekViewEvent)); - psi.multi_week_view = multi_week_view; - psi.weeks_shown = weeks_shown; - psi.month = month; - - /* Get a few config settings. */ - if (multi_week_view) - psi.compress_weekend = calendar_config_get_compress_weekend (); - else - psi.compress_weekend = TRUE; - psi.use_24_hour_format = calendar_config_get_24_hour_format (); - - /* We convert this from (0 = Sun, 6 = Sat) to (0 = Mon, 6 = Sun). */ - psi.display_start_weekday = calendar_config_get_week_start_day (); - psi.display_start_weekday = (psi.display_start_weekday + 6) % 7; - - /* If weekends are compressed then we can't start on a Sunday. */ - if (psi.compress_weekend && psi.display_start_weekday == 6) - psi.display_start_weekday = 5; - - day_start = time_day_begin_with_zone (whence, zone); - for (day = 0; day <= psi.days_shown; day++) { - psi.day_starts[day] = day_start; - day_start = time_add_day_with_zone (day_start, 1, zone); - } - - /* Get the events from the server. */ - client = gnome_calendar_get_cal_client (gcal); - cal_client_generate_instances (client, CALOBJ_TYPE_EVENT, - psi.day_starts[0], - psi.day_starts[psi.days_shown], - print_week_summary_cb, &psi); - qsort (psi.events->data, psi.events->len, - sizeof (EWeekViewEvent), e_week_view_event_sort_func); - - /* Layout the events. */ - spans = e_week_view_layout_events (psi.events, NULL, - psi.multi_week_view, - psi.weeks_shown, - psi.compress_weekend, - psi.display_start_weekday, - psi.day_starts, rows_per_day); - - /* Calculate the size of the cells. */ - if (multi_week_view) { - cell_width = (right - left) / (psi.compress_weekend ? 6 : 7); - cell_height = (top - bottom) / (weeks_shown * 2); - } else { - cell_width = (right - left) / 2; - cell_height = (top - bottom) / 6; - } - - /* Calculate the row height, using the normal font and with room for - space or a rectangle around it. */ - psi.row_height = font_size * 1.2; - psi.header_row_height = font_size * 1.5; - - /* Calculate how many rows we can fit into each type of cell. */ - psi.rows_per_cell = ((cell_height * 2) - psi.header_row_height) - / psi.row_height; - psi.rows_per_compressed_cell = (cell_height - psi.header_row_height) - / psi.row_height; - - font = get_font_for_size (font_size, GNOME_FONT_BOOK, FALSE); - - /* Draw the grid and the day names/numbers. */ - print_week_view_background (pc, font, &psi, left, top, - cell_width, cell_height); - - /* Print the events. */ - for (event_num = 0; event_num < psi.events->len; event_num++) { - event = &g_array_index (psi.events, EWeekViewEvent, event_num); - print_week_event (pc, font, &psi, left, top, - cell_width, cell_height, event, spans); - } - - gtk_object_unref (GTK_OBJECT (font)); - - /* Free everything. */ - for (event_num = 0; event_num < psi.events->len; event_num++) { - event = &g_array_index (psi.events, EWeekViewEvent, event_num); - gtk_object_unref (GTK_OBJECT (event->comp)); - } - g_array_free (psi.events, TRUE); - g_array_free (spans, TRUE); -} - - -static void -print_year_summary (GnomePrintContext *pc, GnomeCalendar *gcal, time_t whence, - double left, double right, double top, double bottom, - int morerows) -{ - icaltimezone *zone = get_timezone (); - double row_height, col_width, l, r, t, b; - time_t now; - int col, row, rows, cols; - - l = left; - t = top; - - /* If morerows is set we do 4 rows and 3 columns instead of 3 rows and - 4 columns. This is useful if we switch paper orientation. */ - if (morerows) { - rows = 4; - cols = 3; - } else { - rows = 3; - cols = 4; - } - - row_height = (top - bottom) / rows; - col_width = (right - left) / cols; - r = l + col_width; - b = top - row_height; - now = time_year_begin_with_zone (whence, zone); - - for (row = 0; row < rows; row++) { - t = top - row_height * row; - b = t - row_height; - for (col = 0; col < cols; col++) { - l = left + col_width * col; - r = l + col_width; - print_month_small (pc, gcal, now, - l + 8, r - 8, t - 8, b + 8, - DATE_MONTH, 0, 0, TRUE); - now = time_add_month_with_zone (now, 1, zone); - } - } -} - -static void -print_month_summary (GnomePrintContext *pc, GnomeCalendar *gcal, time_t whence, - double left, double right, double top, double bottom) -{ - icaltimezone *zone = get_timezone (); - time_t date; - struct tm tm; - struct icaltimetype tt; - char buffer[100]; - GnomeFont *font; - gboolean compress_weekend; - int columns, col, weekday, len, month; - double font_size, cell_width, x1, x2, y1, y2; - - weekday = calendar_config_get_week_start_day (); - compress_weekend = calendar_config_get_compress_weekend (); - - /* Remember which month we want. */ - tt = icaltime_from_timet_with_zone (whence, FALSE, zone); - month = tt.month - 1; - - /* Find the start of the month, and then the start of the week on - or before that day. */ - date = time_month_begin_with_zone (whence, zone); - date = time_week_begin_with_zone (date, weekday, zone); - - /* If weekends are compressed then we can't start on a Sunday. */ - if (compress_weekend && weekday == 0) - date = time_add_day_with_zone (date, -1, zone); - - /* do day names ... */ - - /* We are only interested in outputting the weekday here, but we want - to be able to step through the week without worrying about - overflows making strftime choke, so we move near to the start of - the month. */ - tm = *convert_timet_to_struct_tm (date, zone); - tm.tm_mday = (tm.tm_mday % 7) + 7; - - font = get_font_for_size (MONTH_NORMAL_FONT_SIZE, GNOME_FONT_BOLD, FALSE); - font_size = gnome_font_get_size (font); - gnome_print_setfont (pc, font); - - columns = compress_weekend ? 6 : 7; - cell_width = (right - left) / columns; - y1 = top; - y2 = top - font_size * 1.5; - - for (col = 0; col < columns; col++) { - char *utf_str; - - if (tm.tm_wday == 6 && compress_weekend) { - strftime (buffer, sizeof (buffer), "%a/", &tm); - len = strlen (buffer); - tm.tm_mday++; - tm.tm_wday = (tm.tm_wday + 1) % 7; - strftime (buffer + len, sizeof (buffer) - len, - "%a", &tm); - } else { - strftime (buffer, sizeof (buffer), "%A", &tm); - } - - x1 = left + cell_width * col; - x2 = x1 + cell_width; - - print_border (pc, x1, x2, y1, y2, 1.0, -1.0); - utf_str = e_utf8_from_locale_string (buffer); - print_text_size (pc, utf_str, ALIGN_CENTER, x1, x2, y1, y2); - g_free (utf_str); - - tm.tm_mday++; - tm.tm_wday = (tm.tm_wday + 1) % 7; - } - gtk_object_unref (GTK_OBJECT (font)); - - top = y2; - print_week_summary (pc, gcal, date, TRUE, 6, month, - MONTH_NORMAL_FONT_SIZE, - left, right, top, bottom); -} - - -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; - GnomeFont *font_summary; - double y, yend, x, xend; - struct icaltimetype *tt; - ECalendarTable *task_pad; - ETable *table; - CalendarModel *model; - gint rows, row; - - /* We get the tasks directly from the TaskPad ETable. This means we - get them filtered & sorted for free. */ - task_pad = gnome_calendar_get_task_pad (gcal); - table = e_calendar_table_get_table (task_pad); - model = e_calendar_table_get_model (task_pad); - client = gnome_calendar_get_task_pad_cal_client (gcal); - - font_summary = get_font_for_size (10, GNOME_FONT_BOOK, FALSE); - - gnome_print_setrgbcolor (pc, 0, 0, 0); - gnome_print_setlinewidth (pc, 0.0); - - titled_box (pc, U_("Tasks"), font_summary, ALIGN_CENTER | ALIGN_BORDER, - &left, &right, &top, &bottom, 1.0); - - y = top - 3; - yend = bottom - 2; - - rows = e_table_model_row_count (E_TABLE_MODEL (model)); - for (row = 0; row < rows; row++) { - CalComponent *comp; - CalComponentText summary; - int model_row; - - model_row = e_table_view_to_model_row (table, row); - comp = calendar_model_get_component (model, model_row); - - cal_component_get_summary (comp, &summary); - - if (!summary.value) - continue; - - x = left; - xend = right - 2; - - if (y < bottom) - break; - - /* Print the box to put the tick in. */ - print_border (pc, x + 2, x + 8, y - 3, y - 11, 0.1, -1.0); - - /* If the task is complete, print a tick in the box. */ - cal_component_get_completed (comp, &tt); - if (tt) { - cal_component_free_icaltimetype (tt); - - gnome_print_setrgbcolor (pc, 0, 0, 0); - gnome_print_setlinewidth (pc, 1.0); - gnome_print_moveto (pc, x + 3, y - 8); - gnome_print_lineto (pc, x + 5, y - 10); - gnome_print_lineto (pc, x + 7, y - 3.5); - gnome_print_stroke (pc); - } - - y = bound_text (pc, font_summary, summary.value, - x + 10, xend, y, yend, 0); - y += gnome_font_get_size (font_summary) - 6; - gnome_print_moveto (pc, x, y); - gnome_print_lineto (pc, xend, y); - gnome_print_stroke (pc); - y -= 3; - } - - gtk_object_unref (GTK_OBJECT (font_summary)); -} - - -/* 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) -{ - icaltimezone *zone = get_timezone (); - 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; - gint week_start_day; - - box = gtk_vbox_new (FALSE, GNOME_PAD_SMALL); - - tm = *convert_timet_to_struct_tm (at, zone); - - /* Day */ - - strftime (text, sizeof (text), _("Selected 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_start_day = calendar_config_get_week_start_day (); - week_begin = time_week_begin_with_zone (at, week_start_day, zone); - /* If the week starts on a Sunday, we have to show the Saturday first, - since the weekend is compressed. If the original date passed in was - a Saturday, we need to move on to the next Saturday, else we move - back to the last one. */ - if (week_start_day == 0) { - if (tm.tm_wday == 6) - week_begin = time_add_day_with_zone (week_begin, 6, zone); - else - week_begin = time_add_day_with_zone (week_begin, -1, zone); - } - week_end = time_add_day_with_zone (week_begin, 6, zone); - - week_begin_tm = *convert_timet_to_struct_tm (week_begin, zone); - week_end_tm = *convert_timet_to_struct_tm (week_end, zone); - - 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), _("Selected 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), _("Selected 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), _("Selected 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; -} - - -static void -print_day_view (GnomePrintContext *pc, GnomeCalendar *gcal, time_t date, - double left, double right, double top, double bottom) -{ - icaltimezone *zone = get_timezone (); - int i, days = 1; - double todo, header, l; - char buf[100]; - - for (i = 0; i < days; i++) { - todo = (right - left) * 0.75 + left; - header = top - HEADER_HEIGHT; - - /* FIXME: What is the name supposed to be for? */ - gnome_print_beginpage (pc, "Calendar Day View"); - - /* Print the main view with all the events in. */ - print_day_details (pc, gcal, date, - left, todo - 2.0, header, bottom); - - /* Print the TaskPad down the right. */ - print_todo_details (pc, gcal, 0, INT_MAX, - todo, right, header, bottom); - - /* Print the filled border around the header. */ - print_border (pc, left, right, top, header + 2.0, 1.0, 0.9); - - /* Print the 2 mini calendar-months. */ - l = right - SMALL_MONTH_PAD - SMALL_MONTH_WIDTH * 2 - - SMALL_MONTH_SPACING; - print_month_small (pc, gcal, date, - l, l + SMALL_MONTH_WIDTH, - top - 4, header + 4, - DATE_MONTH | DATE_YEAR, date, date, FALSE); - - l += SMALL_MONTH_SPACING + SMALL_MONTH_WIDTH; - print_month_small (pc, gcal, - time_add_month_with_zone (date, 1, zone), - l, l + SMALL_MONTH_WIDTH, - top - 4, header + 4, - DATE_MONTH | DATE_YEAR, 0, 0, FALSE); - - /* Print the date, e.g. '8th May, 2001'. */ - format_date (date, DATE_DAY | DATE_MONTH | DATE_YEAR, - buf, 100); - print_text_size_bold (pc, buf, ALIGN_LEFT, - left + 4, todo, top - 4, top - 4 - 24); - - /* Print the day, e.g. 'Tuesday'. */ - format_date (date, DATE_DAYNAME, buf, 100); - print_text_size_bold (pc, buf, ALIGN_LEFT, - left + 4, todo, top - 32, top - 32 - 18); - - gnome_print_showpage (pc); - date = time_add_day_with_zone (date, 1, zone); - } -} - - -static void -print_week_view (GnomePrintContext *pc, GnomeCalendar *gcal, time_t date, - double left, double right, double top, double bottom) -{ - icaltimezone *zone = get_timezone (); - double header, l; - char buf[100]; - time_t when; - gint week_start_day; - struct tm tm; - - header = top - HEADER_HEIGHT; - - /* FIXME: What is the name supposed to be for? */ - gnome_print_beginpage (pc, "Calendar Week View"); - - tm = *convert_timet_to_struct_tm (date, zone); - week_start_day = calendar_config_get_week_start_day (); - when = time_week_begin_with_zone (date, week_start_day, zone); - /* If the week starts on a Sunday, we have to show the Saturday first, - since the weekend is compressed. */ - if (week_start_day == 0) { - if (tm.tm_wday == 6) - when = time_add_day_with_zone (when, 6, zone); - else - when = time_add_day_with_zone (when, -1, zone); - } - - /* Print the main week view. */ - print_week_summary (pc, gcal, when, FALSE, 1, 0, - WEEK_NORMAL_FONT_SIZE, - left, right, header, bottom); - - /* Print the border around the main view. */ - print_border (pc, left, right, header, bottom, 1.0, -1.0); - - /* Print the border around the header area. */ - print_border (pc, left, right, top, header + 2.0, 1.0, 0.9); - - /* Print the 2 mini calendar-months. */ - l = right - SMALL_MONTH_PAD - SMALL_MONTH_WIDTH * 2 - - SMALL_MONTH_SPACING; - print_month_small (pc, gcal, when, - l, l + SMALL_MONTH_WIDTH, - top - 4, header + 4, - DATE_MONTH | DATE_YEAR, when, - time_add_week_with_zone (when, 1, zone), FALSE); - - l += SMALL_MONTH_SPACING + SMALL_MONTH_WIDTH; - print_month_small (pc, gcal, - time_add_month_with_zone (when, 1, zone), - l, l + SMALL_MONTH_WIDTH, - top - 4, header + 4, - DATE_MONTH | DATE_YEAR, when, - time_add_week_with_zone (when, 1, zone), FALSE); - - /* Print the start day of the week, e.g. '7th May 2001'. */ - format_date (when, DATE_DAY | DATE_MONTH | DATE_YEAR, buf, 100); - print_text_size_bold (pc, buf, ALIGN_LEFT, - left + 3, right, top - 4, top - 4 - 24); - - /* Print the end day of the week, e.g. '13th May 2001'. */ - when = time_add_day_with_zone (when, 6, zone); - format_date (when, DATE_DAY | DATE_MONTH | DATE_YEAR, buf, 100); - print_text_size_bold (pc, buf, ALIGN_LEFT, - left + 3, right, top - 24 - 3, top - 24 - 3 - 24); - - gnome_print_showpage (pc); -} - - -static void -print_month_view (GnomePrintContext *pc, GnomeCalendar *gcal, time_t date, - double left, double right, double top, double bottom) -{ - icaltimezone *zone = get_timezone (); - double header; - char buf[100]; - - header = top - HEADER_HEIGHT; - - /* FIXME: What is the name supposed to be for? */ - gnome_print_beginpage (pc, "Calendar Month View"); - - /* Print the main month view. */ - print_month_summary (pc, gcal, date, left, right, header, bottom); - - /* Print the border around the header. */ - print_border (pc, left, right, top, header, 1.0, 0.9); - - /* Print the 2 mini calendar-months. */ - print_month_small (pc, gcal, - time_add_month_with_zone (date, 1, zone), - right - (right - left) / 7 + 2, right - 8, - top - 4, header, - DATE_MONTH | DATE_YEAR, 0, 0, FALSE); - print_month_small (pc, gcal, - time_add_month_with_zone (date, -1, zone), - left + 8, left + (right - left) / 7 - 2, - top - 4, header, - DATE_MONTH | DATE_YEAR, 0, 0, FALSE); - - /* Print the month, e.g. 'May 2001'. */ - format_date (date, DATE_MONTH | DATE_YEAR, buf, 100); - print_text_size_bold (pc, buf, ALIGN_CENTER, - left + 3, right - 3, top - 3, top - 3 - 24); - - gnome_print_showpage (pc); -} - - -static void -print_year_view (GnomePrintContext *pc, GnomeCalendar *gcal, time_t date, - double left, double right, double top, double bottom) -{ - char buf[100]; - - /* FIXME: What is the name supposed to be for? */ - gnome_print_beginpage (pc, "Calendar Year View"); - - print_year_summary (pc, gcal, date, left, right, top - 50, bottom, - TRUE); - - /* centered title */ - format_date (date, DATE_YEAR, buf, 100); - print_text_size_bold (pc, buf, ALIGN_CENTER, - left+3, right, top-3, top - 27); - - gnome_print_showpage (pc); -} - -static void -write_label_piece (time_t t, char *buffer, int size, char *stext, char *etext) -{ - icaltimezone *zone = get_timezone (); - struct tm *tmp_tm; - int len; - - tmp_tm = convert_timet_to_struct_tm (t, zone); - - if (stext != NULL) - strcat (buffer, stext); - - len = strlen (buffer); - e_time_format_date_and_time (tmp_tm, - calendar_config_get_24_hour_format (), - FALSE, FALSE, - &buffer[len], size - len); - if (etext != NULL) - strcat (buffer, etext); -} - -static icaltimezone* -get_zone_from_tzid (CalClient *client, const char *tzid) -{ - icaltimezone *zone; - - /* Note that the timezones may not be on the server, so we try to get - the builtin timezone with the TZID first. */ - zone = icaltimezone_get_builtin_timezone_from_tzid (tzid); - if (!zone) { - CalClientGetStatus status; - - status = cal_client_get_timezone (client, tzid, &zone); - /* FIXME: Handle error better. */ - if (status != CAL_CLIENT_GET_SUCCESS) - g_warning ("Couldn't get timezone from server: %s", - tzid ? tzid : ""); - } - - return zone; -} - -static void -print_date_label (GnomePrintContext *pc, CalComponent *comp, CalClient *client, - double left, double right, double top, double bottom) -{ - icaltimezone *start_zone, *end_zone, *due_zone, *completed_zone; - CalComponentDateTime datetime; - time_t start = 0, end = 0, complete = 0, due = 0; - static char buffer[1024], *utf_text; - - cal_component_get_dtstart (comp, &datetime); - if (datetime.value) { - start_zone = get_zone_from_tzid (client, datetime.tzid); - start = icaltime_as_timet_with_zone (*datetime.value, - start_zone); - } - cal_component_free_datetime (&datetime); - - cal_component_get_dtend (comp, &datetime); - if (datetime.value) { - end_zone = get_zone_from_tzid (client, datetime.tzid); - end = icaltime_as_timet_with_zone (*datetime.value, - end_zone); - } - cal_component_free_datetime (&datetime); - - cal_component_get_due (comp, &datetime); - if (datetime.value) { - due_zone = get_zone_from_tzid (client, datetime.tzid); - due = icaltime_as_timet_with_zone (*datetime.value, - due_zone); - } - cal_component_free_datetime (&datetime); - - cal_component_get_completed (comp, &datetime.value); - if (datetime.value) { - completed_zone = icaltimezone_get_utc_timezone (); - complete = icaltime_as_timet_with_zone (*datetime.value, - completed_zone); - cal_component_free_icaltimetype (datetime.value); - } - - buffer[0] = '\0'; - - if (start > 0) - write_label_piece (start, buffer, 1024, NULL, NULL); - - if (end > 0 && start > 0) - write_label_piece (end, buffer, 1024, _(" to "), NULL); - - if (complete > 0) { - if (start > 0) - write_label_piece (complete, buffer, 1024, _(" (Completed "), ")"); - else - write_label_piece (complete, buffer, 1024, _("Completed "), NULL); - } - - if (due > 0 && complete == 0) { - if (start > 0) - write_label_piece (due, buffer, 1024, _(" (Due "), ")"); - else - write_label_piece (due, buffer, 1024, _("Due "), NULL); - } - - utf_text = e_utf8_from_locale_string (buffer); - print_text_size_bold (pc, utf_text, ALIGN_LEFT, - left, right, top, top - 15); - g_free (utf_text); -} - -static void -print_comp_item (GnomePrintContext *pc, CalComponent *comp, CalClient *client, - double left, double right, double top, double bottom) -{ - GnomeFont *font; - CalComponentVType vtype; - CalComponentText text; - GSList *desc, *l; - const char *title, *categories; - char *categories_string; - GSList *contact_list, *elem; - gint header_size; - - vtype = cal_component_get_vtype (comp); - - /* We should only be asked to print VEVENTs or VTODOs. */ - if (vtype == CAL_COMPONENT_EVENT) - title = U_("Appointment"); - else if (vtype == CAL_COMPONENT_TODO) - title = U_("Task"); - else - return; - - /* Print the title in a box at the top of the page. */ - font = get_font_for_size (18, GNOME_FONT_BOLD, FALSE); - header_size = 50; - print_border (pc, left, right, top, top - header_size, - 1.0, 0.9); - print_text (pc, font, title, ALIGN_CENTER, left, right, - top - header_size * 0.1, top - header_size); - gtk_object_unref (GTK_OBJECT (font)); - - top -= header_size + 10; - - /* Summary */ - font = get_font_for_size (18, GNOME_FONT_BOLD, FALSE); - cal_component_get_summary (comp, &text); - top = bound_text (pc, font, text.value, left, right, - top - 3, bottom, 0); - gtk_object_unref (GTK_OBJECT (font)); - - /* Date information */ - print_date_label (pc, comp, client, left, right, top-3, top - 15); - top -= 20; - - font = get_font_for_size (12, GNOME_FONT_BOOK, FALSE); - - /* For a VTODO we print the Status, Priority, % Complete and URL. */ - if (vtype == CAL_COMPONENT_TODO) { - icalproperty_status status; - const char *status_string = NULL; - int *percent; - int *priority; - const char *url; - - /* Status */ - cal_component_get_status (comp, &status); - if (status != ICAL_STATUS_NONE) { - switch (status) { - case ICAL_STATUS_NEEDSACTION: - status_string = U_("Not Started"); - break; - case ICAL_STATUS_INPROCESS: - status_string = U_("In Progress"); - break; - case ICAL_STATUS_COMPLETED: - status_string = U_("Completed"); - break; - case ICAL_STATUS_CANCELLED: - status_string = U_("Cancelled"); - break; - default: - break; - } - - if (status_string) { - char *text = g_strdup_printf (U_("Status: %s"), - status_string); - top = bound_text (pc, font, text, - left, right, top, bottom, 0); - top += gnome_font_get_size (font) - 6; - g_free (text); - } - } - - /* Priority */ - cal_component_get_priority (comp, &priority); - if (priority && *priority >= 0) { - char *priority_string, *priority_utf8, *text; - - priority_string = cal_util_priority_to_string (*priority); - cal_component_free_priority (priority); - - priority_utf8 = e_utf8_from_locale_string (priority_string); - text = g_strdup_printf (U_("Priority: %s"), - priority_utf8); - top = bound_text (pc, font, text, - left, right, top, bottom, 0); - top += gnome_font_get_size (font) - 6; - g_free (text); - g_free (priority_utf8); - } - - /* Percent Complete */ - cal_component_get_percent (comp, &percent); - if (percent) { - char *percent_string; - - percent_string = g_strdup_printf (U_("Percent Complete: %i"), *percent); - cal_component_free_percent (percent); - - top = bound_text (pc, font, percent_string, - left, right, top, bottom, 0); - top += gnome_font_get_size (font) - 6; - } - - - /* URL */ - cal_component_get_url (comp, &url); - if (url && url[0]) { - char *url_string = g_strdup_printf (U_("URL: %s"), - url); - - top = bound_text (pc, font, url_string, - left, right, top, bottom, 0); - top += gnome_font_get_size (font) - 6; - - g_free (url_string); - } - } - - /* Categories */ - cal_component_get_categories (comp, &categories); - if (categories && categories[0]) { - categories_string = g_strdup_printf (U_("Categories: %s"), - categories); - top = bound_text (pc, font, categories_string, - left, right, top, bottom, 0); - top += gnome_font_get_size (font) - 6; - g_free (categories_string); - } - - /* Contacts */ - cal_component_get_contact_list (comp, &contact_list); - if (contact_list) { - GString *contacts = g_string_new (U_("Contacts: ")); - for (elem = contact_list; elem; elem = elem->next) { - CalComponentText *t = elem->data; - /* Put a comma between contacts. */ - if (elem != contact_list) - g_string_append (contacts, ", "); - g_string_append (contacts, t->value); - } - cal_component_free_text_list (contact_list); - - top = bound_text (pc, font, contacts->str, - left, right, top, bottom, 0); - top += gnome_font_get_size (font) - 6; - - g_string_free (contacts, TRUE); - } - - top -= 16; - - /* Description */ - cal_component_get_description_list (comp, &desc); - for (l = desc; l != NULL; l = l->next) { - CalComponentText *text = l->data; - - if (text->value != NULL) - top = bound_text (pc, font, text->value, left, right, top-3, bottom, 0); - } - cal_component_free_text_list (desc); - gtk_object_unref (GTK_OBJECT (font)); - - gnome_print_showpage (pc); -} - -void -print_calendar (GnomeCalendar *gcal, gboolean preview, time_t date, - PrintView default_view) -{ - GnomePrinter *printer; - GnomePrintMaster *gpm; - GnomePrintContext *pc; - int copies, collate; - double l, r, t, b; - - 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, date, &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 (); - - if (paper_info == NULL) - 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: - print_day_view (pc, gcal, date, l, r, t, b); - break; - case PRINT_VIEW_WEEK: - print_week_view (pc, gcal, date, l, r, t, b); - break; - case PRINT_VIEW_MONTH: - gnome_print_rotate (pc, 90); - gnome_print_translate (pc, 0, - -gnome_paper_pswidth (paper_info)); - print_month_view (pc, gcal, date, b, t, r, l); - break; - case PRINT_VIEW_YEAR: - print_year_view (pc, gcal, date, l, r, t, b); - break; - default: - g_assert_not_reached (); - } - - gnome_print_master_close (gpm); - - if (preview) { - GnomePrintMasterPreview *gpmp; - gboolean landscape = FALSE; - - if (default_view == PRINT_VIEW_MONTH) - landscape = TRUE; - - gpmp = gnome_print_master_preview_new_with_orientation (gpm, _("Print Preview"), landscape); - gtk_widget_show (GTK_WIDGET (gpmp)); - } else { - gnome_print_master_print (gpm); - } - - gtk_object_unref (GTK_OBJECT (gpm)); -} - - -void -print_comp (CalComponent *comp, CalClient *client, gboolean preview) -{ - GnomePrinter *printer; - GnomePrintMaster *gpm; - GnomePrintContext *pc; - int copies, collate; - double l, r, t, b; - - g_return_if_fail (comp != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - - printer = NULL; - copies = 1; - collate = FALSE; - - if (!preview) { - GtkWidget *gpd; - - gpd = gnome_print_dialog_new (_("Print Item"), - GNOME_PRINT_DIALOG_COPIES); - - 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); - - 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 (); - - if (paper_info == NULL) - 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); - - print_comp_item (pc, comp, client, l, r, t, b); - - 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)); -} - -void -print_setup (void) -{ - GtkWidget *dlg, *ps; - gint btn; - - ps = gnome_paper_selector_new (); - gtk_widget_show (ps); - - dlg = gnome_dialog_new (_("Print Setup"), - GNOME_STOCK_BUTTON_OK, - GNOME_STOCK_BUTTON_CANCEL, - NULL); - gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dlg)->vbox), ps, TRUE, TRUE, 2); - - btn = gnome_dialog_run (GNOME_DIALOG (dlg)); - if (btn == 0) { - gchar *name; - - name = gnome_paper_selector_get_name (GNOME_PAPER_SELECTOR (ps)); - paper_info = gnome_paper_with_name (name); - } - - gnome_dialog_close (GNOME_DIALOG (dlg)); -} diff --git a/calendar/gui/print.h b/calendar/gui/print.h deleted file mode 100644 index 4571b36976..0000000000 --- a/calendar/gui/print.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Evolution calendar - Print support - * - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Michael Zucchi <notzed@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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#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); -void print_comp (CalComponent *comp, CalClient *client, gboolean preview); - -void print_setup (void); - - - -#endif diff --git a/calendar/gui/tag-calendar.c b/calendar/gui/tag-calendar.c deleted file mode 100644 index cda93a1d64..0000000000 --- a/calendar/gui/tag-calendar.c +++ /dev/null @@ -1,227 +0,0 @@ -/* Evolution calendar - Utilities for tagging ECalendar widgets - * - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Damon Chaplin <damon@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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <cal-util/timeutil.h> -#include "calendar-config.h" -#include "tag-calendar.h" - - - -struct calendar_tag_closure { - ECalendarItem *calitem; - icaltimezone *zone; - time_t start_time; - time_t end_time; - - gboolean skip_transparent_events; -}; - -/* 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, gboolean clear_first) -{ - gint start_year, start_month, start_day; - gint end_year, end_month, end_day; - struct icaltimetype start_tt = icaltime_null_time (); - struct icaltimetype end_tt = icaltime_null_time (); - char *location; - - if (clear_first) - 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_tt.year = start_year; - start_tt.month = start_month + 1; - start_tt.day = start_day; - - end_tt.year = end_year; - end_tt.month = end_month + 1; - end_tt.day = end_day; - - icaltime_adjust (&end_tt, 1, 0, 0, 0); - - c->calitem = ecal->calitem; - - /* FIXME. It may be better if the timezone is passed in. */ - location = calendar_config_get_timezone (); - c->zone = icaltimezone_get_builtin_timezone (location); - - c->start_time = icaltime_as_timet_with_zone (start_tt, c->zone); - c->end_time = icaltime_as_timet_with_zone (end_tt, c->zone); - - 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; - struct icaltimetype start_tt, end_tt; - CalComponentTransparency transparency; - - /* If we are skipping TRANSPARENT events, return if the event is - transparent. */ - if (c->skip_transparent_events) { - cal_component_get_transparency (comp, &transparency); - if (transparency == CAL_COMPONENT_TRANSP_TRANSPARENT) - return TRUE; - } - - start_tt = icaltime_from_timet_with_zone (istart, FALSE, c->zone); - end_tt = icaltime_from_timet_with_zone (iend - 1, FALSE, c->zone); - e_calendar_item_mark_days (c->calitem, - start_tt.year, start_tt.month - 1, - start_tt.day, - end_tt.year, end_tt.month - 1, - end_tt.day, - E_CALENDAR_ITEM_MARK_BOLD); - - 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, TRUE)) - return; - - c.skip_transparent_events = TRUE; - -#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); -} - -/* Resolves TZIDs for the recurrence generator, for when the comp is not on - the server. We need to try to use builtin timezones first, as they may not - be added to the server yet. */ -static icaltimezone* -resolve_tzid_cb (const char *tzid, gpointer data) -{ - CalClient *client; - icaltimezone *zone = NULL; - CalClientGetStatus status; - - g_return_val_if_fail (data != NULL, NULL); - g_return_val_if_fail (IS_CAL_CLIENT (data), NULL); - - client = CAL_CLIENT (data); - - /* Try to find the builtin timezone first. */ - zone = icaltimezone_get_builtin_timezone_from_tzid (tzid); - - if (!zone) { - /* FIXME: Handle errors. */ - status = cal_client_get_timezone (client, tzid, &zone); - } - - return zone; -} - -/** - * tag_calendar_by_comp: - * @ecal: Calendar widget to tag. - * @comp: A calendar component object. - * @clear_first: Whether the #ECalendar should be cleared of any marks first. - * - * Tags an #ECalendar widget with any occurrences of a specific calendar - * component that occur within the calendar's current time range. - * Note that TRANSPARENT events are also tagged here. - * - * If comp_is_on_server is FALSE, it will try to resolve TZIDs using builtin - * timezones first, before querying the server, since the timezones may not - * have been added to the calendar on the server yet. - **/ -void -tag_calendar_by_comp (ECalendar *ecal, CalComponent *comp, CalClient *client, gboolean clear_first, gboolean comp_is_on_server) -{ - 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, clear_first)) - return; - - c.skip_transparent_events = FALSE; - -#if 0 - g_print ("DateNavigator generating instances\n"); -#endif - if (comp_is_on_server) { - cal_recur_generate_instances (comp, c.start_time, c.end_time, - tag_calendar_cb, &c, - cal_client_resolve_tzid_cb, - client, c.zone); - } else { - cal_recur_generate_instances (comp, c.start_time, c.end_time, - tag_calendar_cb, &c, - resolve_tzid_cb, - client, c.zone); - } -} diff --git a/calendar/gui/tag-calendar.h b/calendar/gui/tag-calendar.h deleted file mode 100644 index 32c7eb475c..0000000000 --- a/calendar/gui/tag-calendar.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Evolution calendar - Utilities for tagging ECalendar widgets - * - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Damon Chaplin <damon@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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#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, - CalClient *client, gboolean clear_first, - gboolean comp_is_on_server); - -#endif diff --git a/calendar/gui/tasks-control-factory.c b/calendar/gui/tasks-control-factory.c deleted file mode 100644 index 5fd8d61346..0000000000 --- a/calendar/gui/tasks-control-factory.c +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* tasks-control-factory.c - * - * Copyright (C) 2000 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: Ettore Perazzoli - * Damon Chaplin <damon@ximian.com> - */ - -#include <config.h> -#include <libgnomeui/gnome-dialog.h> -#include <libgnomeui/gnome-dialog-util.h> -#include <liboaf/liboaf.h> -#include <bonobo/bonobo-control.h> -#include <bonobo/bonobo-generic-factory.h> -#include <bonobo/bonobo-context.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); - bonobo_running_context_auto_exit_unref (BONOBO_OBJECT (factory)); - - 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 { - gnome_warning_dialog (_("Could not create the tasks view. Please check your " - "ORBit and OAF setup.")); - return NULL; - } -} diff --git a/calendar/gui/tasks-control-factory.h b/calendar/gui/tasks-control-factory.h deleted file mode 100644 index 468f03b9e7..0000000000 --- a/calendar/gui/tasks-control-factory.h +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* tasks-control-factory.h - * - * Copyright (C) 2000 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: Federico Mena Quintero <federico@ximian.com> - * Damon Chaplin <damon@ximian.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 53e3eb239f..0000000000 --- a/calendar/gui/tasks-control.c +++ /dev/null @@ -1,684 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* tasks-control.c - * - * Copyright (C) 2000 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: Damon Chaplin <damon@ximian.com> - * Ettore Perazzoli - */ - -#include <config.h> -#include <gtk/gtksignal.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <libgnome/gnome-paper.h> -#include <libgnome/gnome-util.h> -#include <libgnomeui/gnome-dialog.h> -#include <libgnomeui/gnome-dialog-util.h> -#include <libgnomeui/gnome-stock.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 <bonobo/bonobo-control.h> -#include <bonobo/bonobo-ui-util.h> -#include <gal/widgets/e-gui-utils.h> -#include <e-util/e-dialog-utils.h> -#include "dialogs/cal-prefs-dialog.h" -#include "calendar-config.h" -#include "calendar-commands.h" -#include "e-tasks.h" -#include "tasks-control.h" -#include "evolution-shell-component-utils.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, - ETasks *tasks); - -static void tasks_control_new_task_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path); -static void tasks_control_cut_cmd (BonoboUIComponent *uic, - gpointer data, - const gchar *path); -static void tasks_control_copy_cmd (BonoboUIComponent *uic, - gpointer data, - const gchar *path); -static void tasks_control_paste_cmd (BonoboUIComponent *uic, - gpointer data, - const gchar *path); -static void tasks_control_delete_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path); -static void tasks_control_complete_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path); -static void tasks_control_expunge_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path); -static void tasks_control_print_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path); -static void tasks_control_print_preview_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path); - - -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) { - gtk_widget_destroy (tasks); - 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); - bonobo_object_unref (BONOBO_OBJECT (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) -{ - ETasks *tasks = user_data; - char *uri; - - switch (arg_id) { - - case TASKS_CONTROL_PROPERTY_URI_IDX: - uri = cal_client_get_uri (e_tasks_get_cal_client (tasks)); - BONOBO_ARG_SET_STRING (arg, uri); - 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 *uri; - - switch (arg_id) { - - case TASKS_CONTROL_PROPERTY_URI_IDX: - uri = BONOBO_ARG_GET_STRING (arg); - if (!e_tasks_open (tasks, 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); - } - break; - - default: - g_warning ("Unhandled arg %d\n", arg_id); - break; - } -} - - -static void -tasks_control_activate_cb (BonoboControl *control, - gboolean activate, - gpointer user_data) -{ - ETasks *tasks; - - tasks = E_TASKS (user_data); - - if (activate) - tasks_control_activate (control, tasks); - else - tasks_control_deactivate (control, tasks); -} - -/* Sensitizes the UI Component menu/toolbar commands based on the number of - * selected tasks. - */ -static void -sensitize_commands (ETasks *tasks, BonoboControl *control, int n_selected) -{ - BonoboUIComponent *uic; - - uic = bonobo_control_get_ui_component (control); - g_assert (uic != NULL); - - bonobo_ui_component_set_prop (uic, "/commands/TasksCut", "sensitive", - n_selected == 0 ? "0" : "1", - NULL); - bonobo_ui_component_set_prop (uic, "/commands/TasksCopy", "sensitive", - n_selected == 0 ? "0" : "1", - NULL); - bonobo_ui_component_set_prop (uic, "/commands/TasksDelete", "sensitive", - n_selected == 0 ? "0" : "1", - NULL); - bonobo_ui_component_set_prop (uic, "/commands/TasksMarkComplete", "sensitive", - n_selected == 0 ? "0" : "1", - NULL); -} - -/* Callback used when the selection in the table changes */ -static void -selection_changed_cb (ETasks *tasks, int n_selected, gpointer data) -{ - BonoboControl *control; - - control = BONOBO_CONTROL (data); - - sensitize_commands (tasks, control, n_selected); -} - -static BonoboUIVerb verbs [] = { - BONOBO_UI_VERB ("TasksNewTask", tasks_control_new_task_cmd), - BONOBO_UI_VERB ("TasksCut", tasks_control_cut_cmd), - BONOBO_UI_VERB ("TasksCopy", tasks_control_copy_cmd), - BONOBO_UI_VERB ("TasksPaste", tasks_control_paste_cmd), - BONOBO_UI_VERB ("TasksDelete", tasks_control_delete_cmd), - BONOBO_UI_VERB ("TasksMarkComplete", tasks_control_complete_cmd), - BONOBO_UI_VERB ("TasksExpunge", tasks_control_expunge_cmd), - BONOBO_UI_VERB ("TasksPrint", tasks_control_print_cmd), - BONOBO_UI_VERB ("TasksPrintPreview", tasks_control_print_preview_cmd), - - BONOBO_UI_VERB_END -}; - -static EPixmap pixmaps [] = { - E_PIXMAP ("/menu/File/New/NewFirstItem/NewTask", "new_task-16.png"), - E_PIXMAP ("/menu/File/Print/Print", "print.xpm"), - E_PIXMAP ("/menu/File/Print/PrintPreview", "print-preview.xpm"), - E_PIXMAP ("/menu/EditPlaceholder/Edit/TasksCut", "16_cut.png"), - E_PIXMAP ("/menu/EditPlaceholder/Edit/TasksCopy", "16_copy.png"), - E_PIXMAP ("/menu/EditPlaceholder/Edit/TasksPaste", "16_paste.png"), - E_PIXMAP ("/menu/EditPlaceholder/Edit/TasksDelete", "evolution-trash-mini.png"), - E_PIXMAP ("/menu/Tools/ComponentPlaceholder/TasksSettings", "configure_16_calendar.xpm"), - E_PIXMAP ("/Toolbar/New", "buttons/new_task.png"), - E_PIXMAP ("/Toolbar/Cut", "buttons/cut.png"), - E_PIXMAP ("/Toolbar/Copy", "buttons/copy.png"), - E_PIXMAP ("/Toolbar/Paste", "buttons/paste.png"), - E_PIXMAP ("/Toolbar/Delete", "buttons/delete-message.png"), - E_PIXMAP ("/Toolbar/Print", "buttons/print.png"), - E_PIXMAP_END -}; - -static void -tasks_control_activate (BonoboControl *control, ETasks *tasks) -{ - Bonobo_UIContainer remote_uih; - BonoboUIComponent *uic; - int n_selected; - ECalendarTable *cal_table; - ETable *etable; - - uic = bonobo_control_get_ui_component (control); - g_assert (uic != NULL); - - e_tasks_set_ui_component (tasks, uic); - - 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_pixmaps_update (uic, pixmaps); - - e_tasks_setup_view_menus (tasks, uic); - - /* Signals from the tasks widget; also sensitize the menu items as appropriate */ - - gtk_signal_connect (GTK_OBJECT (tasks), "selection_changed", - GTK_SIGNAL_FUNC (selection_changed_cb), control); - - cal_table = e_tasks_get_calendar_table (tasks); - etable = e_calendar_table_get_table (cal_table); - n_selected = e_table_selected_count (etable); - - sensitize_commands (tasks, control, n_selected); - - bonobo_ui_component_thaw (uic, NULL); - - /* Show the dialog for setting the timezone if the user hasn't chosen - a default timezone already. This is done in the startup wizard now, - so we don't do it here. */ -#if 0 - calendar_config_check_timezone_set (); -#endif - - control_util_set_folder_bar_label (control, ""); -} - - -static void -tasks_control_deactivate (BonoboControl *control, ETasks *tasks) -{ - BonoboUIComponent *uic = bonobo_control_get_ui_component (control); - - g_assert (uic != NULL); - - e_tasks_set_ui_component (tasks, NULL); - - e_tasks_discard_view_menus (tasks); - - /* Stop monitoring the "selection_changed" signal */ - gtk_signal_disconnect_by_data (GTK_OBJECT (tasks), control); - - 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; - - tasks = E_TASKS (data); - e_tasks_new_task (tasks); -} - -static void -tasks_control_cut_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path) -{ - ETasks *tasks; - ECalendarTable *cal_table; - - tasks = E_TASKS (data); - cal_table = e_tasks_get_calendar_table (tasks); - e_calendar_table_cut_clipboard (cal_table); -} - -static void -tasks_control_copy_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path) -{ - ETasks *tasks; - ECalendarTable *cal_table; - - tasks = E_TASKS (data); - cal_table = e_tasks_get_calendar_table (tasks); - e_calendar_table_copy_clipboard (cal_table); -} - -static void -tasks_control_paste_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path) -{ - ETasks *tasks; - ECalendarTable *cal_table; - - tasks = E_TASKS (data); - cal_table = e_tasks_get_calendar_table (tasks); - e_calendar_table_paste_clipboard (cal_table); -} - -static void -tasks_control_delete_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path) -{ - ETasks *tasks; - - tasks = E_TASKS (data); - e_tasks_delete_selected (tasks); -} - -static void -tasks_control_complete_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path) -{ - ETasks *tasks; - - tasks = E_TASKS (data); - e_tasks_complete_selected (tasks); -} - -static gboolean -confirm_expunge (ETasks *tasks) -{ - GtkWidget *dialog, *label, *checkbox; - int button; - - if (!calendar_config_get_confirm_expunge ()) - return TRUE; - - dialog = gnome_dialog_new (_("Warning"), - GNOME_STOCK_BUTTON_YES, - GNOME_STOCK_BUTTON_NO, - NULL); - e_gnome_dialog_set_parent (GNOME_DIALOG (dialog), - GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (tasks), - GTK_TYPE_WINDOW))); - - label = gtk_label_new (_("This operation will permanently erase all tasks marked as completed. If you continue, you will not be able to recover these tasks.\n\nReally erase these tasks?")); - - gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); - gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT); - gtk_widget_show (label); - gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), label, TRUE, TRUE, 4); - - checkbox = gtk_check_button_new_with_label (_("Do not ask me again.")); - gtk_widget_show (checkbox); - gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), checkbox, TRUE, TRUE, 4); - - button = gnome_dialog_run (GNOME_DIALOG (dialog)); - if (button == 0 && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbox))) - calendar_config_set_confirm_expunge (FALSE); - gnome_dialog_close (GNOME_DIALOG (dialog)); - - if (button == 0) - return TRUE; - else - return FALSE; -} - -static void -tasks_control_expunge_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path) -{ - ETasks *tasks; - - tasks = E_TASKS (data); - - if (confirm_expunge (tasks)) - e_tasks_delete_completed (tasks); -} - - -static void -print_title (GnomePrintContext *pc, - double page_width, double page_height) -{ - GnomeFont *font; - char *text; - double w, x, y; - - font = gnome_font_new_closest ("Times", GNOME_FONT_BOLD, 0, 18); - - text = _("Tasks"); - w = gnome_font_get_width_utf8 (font, text); - - x = (page_width - w) / 2; - y = page_height - gnome_font_get_ascender (font); - - gnome_print_moveto (pc, x, y); - gnome_print_setfont (pc, font); - gnome_print_setrgbcolor (pc, 0, 0, 0); - gnome_print_show (pc, text); - - gtk_object_unref (GTK_OBJECT (font)); -} - - -static void -print_tasks (ETasks *tasks, gboolean preview, gboolean landscape, - int copies, gboolean collate) -{ - ECalendarTable *cal_table; - EPrintable *printable; - ETable *etable; - GnomePrintMaster *master; - GnomePrintContext *pc; - const GnomePaper *paper_info; - double l, r, t, b, page_width, page_height, left_margin, bottom_margin; - - cal_table = e_tasks_get_calendar_table (tasks); - etable = e_calendar_table_get_table (E_CALENDAR_TABLE (cal_table)); - printable = e_table_get_printable (etable); - - master = gnome_print_master_new (); - - paper_info = gnome_paper_with_name (gnome_paper_name_default ()); - gnome_print_master_set_paper (master, paper_info); - - gnome_print_master_set_copies (master, copies, collate); - pc = gnome_print_master_get_context (master); - e_printable_reset (printable); - - 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); - - if (landscape) { - page_width = t - b; - page_height = r - l; - left_margin = b; - bottom_margin = gnome_paper_rmargin (paper_info); - } else { - page_width = r - l; - page_height = t - b; - left_margin = l; - bottom_margin = b; - } - - while (e_printable_data_left (printable)) { - gnome_print_beginpage (pc, "Tasks"); - gnome_print_gsave (pc); - if (landscape) { - gnome_print_rotate (pc, 90); - gnome_print_translate (pc, 0, -gnome_paper_pswidth (paper_info)); - } - - gnome_print_translate (pc, left_margin, bottom_margin); - - print_title (pc, page_width, page_height); - - e_printable_print_page (printable, pc, - page_width, page_height - 24, TRUE); - - gnome_print_grestore (pc); - gnome_print_showpage (pc); - } - gnome_print_master_close (master); - - if (preview) { - GnomePrintMasterPreview *gpmp; - gpmp = gnome_print_master_preview_new_with_orientation (master, _("Print Preview"), landscape); - gtk_widget_show (GTK_WIDGET (gpmp)); - } else { - gnome_print_master_print (master); - } - - gtk_object_unref (GTK_OBJECT (master)); - gtk_object_unref (GTK_OBJECT (printable)); -} - - -/* File/Print callback */ -static void -tasks_control_print_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path) -{ - ETasks *tasks; - GtkWidget *gpd, *mode_box, *portrait_radio, *landscape_radio; - GtkWidget *dialog_vbox, *dialog_hbox, *mode_frame; - GList *children; - GSList *group; - gboolean preview = FALSE, landscape = FALSE; - GnomePrinter *printer; - int copies; - gboolean collate; - - tasks = E_TASKS (data); - - gpd = gnome_print_dialog_new (_("Print Tasks"), - GNOME_PRINT_DIALOG_COPIES); - - mode_frame = gtk_frame_new (_("Orientation")); - - mode_box = gtk_vbox_new (FALSE, 4); - gtk_container_add (GTK_CONTAINER (mode_frame), mode_box); - - /* Portrait */ - portrait_radio = gtk_radio_button_new_with_label (NULL, _("Portrait")); - group = gtk_radio_button_group (GTK_RADIO_BUTTON (portrait_radio)); - gtk_box_pack_start (GTK_BOX (mode_box), portrait_radio, - FALSE, FALSE, 0); - - /* Landscape */ - landscape_radio = gtk_radio_button_new_with_label (group, - _("Landscape")); - gtk_box_pack_start (GTK_BOX (mode_box), landscape_radio, - FALSE, FALSE, 0); - - gtk_widget_show_all (mode_frame); - - /* A bit of a hack to insert our own Orientation option. */ - dialog_vbox = GNOME_DIALOG (gpd)->vbox; - children = gtk_container_children (GTK_CONTAINER (dialog_vbox)); - dialog_hbox = children->next->data; - g_list_free (children); - gtk_box_pack_start (GTK_BOX (dialog_hbox), mode_frame, - FALSE, FALSE, 3); - - 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; - } - - gnome_print_dialog_get_copies (GNOME_PRINT_DIALOG (gpd), - &copies, &collate); - if (GTK_TOGGLE_BUTTON (landscape_radio)->active) - landscape = TRUE; - - printer = gnome_print_dialog_get_printer (GNOME_PRINT_DIALOG (gpd)); - - gnome_dialog_close (GNOME_DIALOG (gpd)); - - print_tasks (tasks, preview, landscape, copies, collate); -} - -static void -tasks_control_print_preview_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path) -{ - ETasks *tasks; - - tasks = E_TASKS (data); - - print_tasks (tasks, TRUE, FALSE, 1, FALSE); -} - diff --git a/calendar/gui/tasks-control.h b/calendar/gui/tasks-control.h deleted file mode 100644 index 2d701f0c85..0000000000 --- a/calendar/gui/tasks-control.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* tasks-control.h - * - * Copyright (C) 2000 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: Federico Mena Quintero <federico@ximian.com> - * Damon Chaplin <damon@ximian.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 5c9a4fa7c5..0000000000 --- a/calendar/gui/tasks-migrate.c +++ /dev/null @@ -1,307 +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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#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 0307d533b9..0000000000 --- a/calendar/gui/tasks-migrate.h +++ /dev/null @@ -1,28 +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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef TASKS_MIGRATE_H -#define TASKS_MIGRATE_H - - -void tasks_migrate (void); - - -#endif diff --git a/calendar/gui/weekday-picker.c b/calendar/gui/weekday-picker.c deleted file mode 100644 index 890d46f92e..0000000000 --- a/calendar/gui/weekday-picker.c +++ /dev/null @@ -1,574 +0,0 @@ -/* Evolution calendar - Week day picker widget - * - * 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <gtk/gtksignal.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <libgnomeui/gnome-canvas-rect-ellipse.h> -#include <libgnomeui/gnome-canvas-text.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 928dcac353..0000000000 --- a/calendar/gui/weekday-picker.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Evolution calendar - Week day picker widget - * - * 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#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/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 7ad011aecf..0000000000 --- a/calendar/idl/evolution-calendar.idl +++ /dev/null @@ -1,350 +0,0 @@ -/* Evolution calendar interface - * - * Copyright (C) 2000 Eskil Heyn Olsen - * Copyright (C) 2000 Ximian, 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; - typedef sequence<CalObj> CalObjSeq; - - /* A unique identifier for a calendar component */ - typedef string CalObjUID; - - /* Simple sequence of strings */ - typedef sequence<string> StringSeq; - - /* Sequence of unique identifiers */ - typedef sequence<CalObjUID> CalObjUIDSeq; - - /* A VTIMEZONE component, represented as an iCalendar string. */ - typedef string CalTimezoneObj; - - /* A unique identifier for a VTIMEZONE component, i.e. its TZID. */ - typedef string CalTimezoneObjUID; - - /* 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; - - /* Flags for getting URI sequences */ - typedef long CalMode; - const CalMode MODE_LOCAL = 1 << 0; - const CalMode MODE_REMOTE = 1 << 1; - const CalMode MODE_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_start; - Time_t occur_end; - }; - - /* 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; - - /* Used to represent users and lists of users */ - typedef string User; - typedef sequence<User> UserList; - - interface Query; - - interface Listener; - - interface QueryListener; - - /* Calendar client interface */ - interface Cal : Bonobo::Unknown { - exception NotFound {}; - exception InvalidRange {}; - exception InvalidObject {}; - exception CouldNotCreate {}; - - /* A calendar is identified by its URI */ - readonly attribute string uri; - - /* For going online/offline */ - void setMode (in CalMode mode); - - /* 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); - - /* Sets the default timezone to be used for resolving DATE - and floating DATE-TIME values. */ - void setDefaultTimezone (in CalTimezoneObjUID tzid) - raises (NotFound); - - /* Gets a VTIMEZONE component based on its TZID */ - CalTimezoneObj getTimezoneObject (in CalTimezoneObjUID tzid) - 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); - - /* Returns free/busy objects for the given interval */ - CalObjSeq getFreeBusy (in UserList users, in Time_t start, in Time_t end) - raises (NotFound, 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); - - - /* Adds or updates one or more VEVENT/VTODO/VTIMEZONE - * components. The calobj should be a string representation of - * a complete VCALENDAR object (we also support single - * VEVENT/VTODO strings, but that is deprecated). - * - * The VTIMEZONE data will be merged into the calendar, - * possibly by renaming TZIDs (though not for builtin - * VTIMEZONEs, which have unique TZIDs), so don't rely on the - * TZIDs being the same in the new object on the server. - * - * The client should probably immediately free its copy of the - * object after this call, and call getObject to get the - * updated version. - */ - void updateObjects (in CalObj calobj) - raises (InvalidObject); - - /* Removes a component */ - void removeObject (in CalObjUID uid) - raises (NotFound); - - /* Initiates a live query of the calendar. Returns a handle - * to the live query itself; changes to components that are - * present in the query are notified to the listener. - */ - Query getQuery (in string sexp, in QueryListener ql) - raises (CouldNotCreate); - }; - - /* 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 */ - }; - - /* Return status when setting calendar mode */ - enum SetModeStatus { - MODE_SET, /* All OK */ - MODE_NOT_SET, /* Generic error */ - MODE_NOT_SUPPORTED /* Mode not supported */ - }; - - /* 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 the mode is changed */ - void notifyCalSetMode (in SetModeStatus status, in CalMode mode); - - /* 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); - - /* Called from a Calendar when the list of categories changes */ - void notifyCategoriesChanged (in StringSeq categories); - }; - - /* Handle to a live query on a calendar */ - interface Query : Bonobo::Unknown { - }; - - /* Listener for changes in a query of a calendar */ - interface QueryListener : Bonobo::Unknown { - /* Called when a component is added or changed. If - * query_in_progress is true, then the initial query results are - * being populated and the other arguments indicate the - * percentage of completion Otherwise, the percent value is - * unspecified. */ - void notifyObjUpdated (in CalObjUID uid, - in boolean query_in_progress, - in long n_scanned, - in long total); - - /* Called when a component is removed */ - void notifyObjRemoved (in CalObjUID uid); - - /* Reported when a query ends */ - enum QueryDoneStatus { - SUCCESS, - PARSE_ERROR - }; - - /* Called when the query finishes populating itself some time - * after it is created. Before this is called, - * notifyObjUpdated() may have been called several times to - * indicate which objects are actually in the query, unless the - * status result is a parse error. - */ - void notifyQueryDone (in QueryDoneStatus status, in string error_str); - - /* Called when an evaluation error occurs while performing a query */ - void notifyEvalError (in string error_str); - }; - - /* A calendar factory, can load and create calendars */ - interface CalFactory : Bonobo::Unknown { - exception NilListener {}; - exception InvalidURI {}; - exception UnsupportedMethod {}; - - /* Open a calendar from an URI */ - void open (in string uri, in boolean only_if_exists, in Listener listener) - raises (NilListener, InvalidURI, UnsupportedMethod); - - /* List of open URI's */ - StringSeq uriList (in CalMode mode); - }; - - /* Interface to the alarm notification service */ - interface AlarmNotify : Bonobo::Unknown { - exception InvalidURI {}; - exception BackendContactError {}; - exception NotFound {}; - - /* Adds a calendar to the alarm notification system so that - * alarms will be triggered for it. The calendar will be loaded - * automatically whenever the alarm daemon starts up. - */ - void addCalendar (in string uri) - raises (InvalidURI, BackendContactError); - - /* Removes a calendar from the alarm notification system and - * alarms will no longer be triggered for it. The calendar will - * no longer be loaded when the alarm daemon starts up. - */ - void removeCalendar (in string uri) - raises (InvalidURI, NotFound); - }; - - /* Factory to centralize calendar component editor dialogs */ - interface CompEditorFactory : Bonobo::Unknown { - exception InvalidURI {}; - exception BackendContactError {}; - exception UnsupportedType {}; - - typedef long CompEditorMode; - const CompEditorMode EDITOR_MODE_EVENT = 1 << 0; - const CompEditorMode EDITOR_MODE_ALLDAY_EVENT = 1 << 1; - const CompEditorMode EDITOR_MODE_MEETING = 1 << 2; - const CompEditorMode EDITOR_MODE_TODO = 1 << 3; - - /* Loads a calendar and opens an editor for the specified object */ - void editExisting (in string uri, in CalObjUID uid) - raises (InvalidURI, BackendContactError); - - /* Loads a calendar and creates a new component of the specified type */ - void editNew (in string uri, in CompEditorMode mode) - raises (InvalidURI, BackendContactError, UnsupportedType); - }; -}; - -}; -}; - -#endif diff --git a/calendar/importers/.cvsignore b/calendar/importers/.cvsignore deleted file mode 100644 index dfa0930c53..0000000000 --- a/calendar/importers/.cvsignore +++ /dev/null @@ -1,6 +0,0 @@ -.deps -.libs -Makefile -Makefile.in -evolution-calendar-importer -GNOME_Evolution_Calendar_Importer.oaf diff --git a/calendar/importers/GNOME_Evolution_Calendar_Importer.oaf.in b/calendar/importers/GNOME_Evolution_Calendar_Importer.oaf.in deleted file mode 100644 index 710567dbc0..0000000000 --- a/calendar/importers/GNOME_Evolution_Calendar_Importer.oaf.in +++ /dev/null @@ -1,51 +0,0 @@ -<oaf_info> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_ImporterFactory" - type="exe" - location="evolution-calendar-importer"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/ObjectFactory:1.0"/> - </oaf_attribute> - <oaf_attribute name="description" type="string" - _value="Factory to import iCalendar files into Evolution"/> -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_iCalendar_Importer" - type="factory" - location="OAFIID:GNOME_Evolution_Calendar_ImporterFactory"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution/Importer:1.0"/> - </oaf_attribute> - <oaf_attribute name="evolution:menu-name" type="string" - value="iCalendar files (.ics)"/> - <oaf_attribute name="description" type="string" - _value="Imports iCalendar files into Evolution"/> - -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_vCalendar_Importer" - type="factory" - location="OAFIID:GNOME_Evolution_Calendar_ImporterFactory"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution/Importer:1.0"/> - </oaf_attribute> - <oaf_attribute name="evolution:menu-name" type="string" - value="vCalendar files (.vcf)"/> - <oaf_attribute name="description" type="string" - _value="Imports vCalendar files into Evolution"/> - -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Gnome_Calendar_Intelligent_Importer" - type="factory" - location="OAFIID:GNOME_Evolution_Calendar_ImporterFactory"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution/IntelligentImporter:1.0"/> - </oaf_attribute> - -</oaf_server> -</oaf_info> diff --git a/calendar/importers/Makefile.am b/calendar/importers/Makefile.am deleted file mode 100644 index 4015e12f86..0000000000 --- a/calendar/importers/Makefile.am +++ /dev/null @@ -1,42 +0,0 @@ -bin_PROGRAMS = evolution-calendar-importer - -sounddir = $(datadir)/evolution/sounds - -INCLUDES = \ - -DEVOLUTION_LOCALEDIR=\""$(localedir)"\" \ - -DEVOLUTION_SOUNDDIR=\""$(sounddir)"\" \ - -DG_LOG_DOMAIN=\"Evolution-Importer\" \ - -I$(top_srcdir) \ - -I$(top_builddir)/shell \ - -I$(top_srcdir)/shell \ - -I$(top_srcdir)/calendar/cal-client \ - -I$(top_builddir)/calendar/cal-client \ - -I$(top_srcdir)/calendar \ - -I$(top_builddir)/calendar \ - -I$(top_srcdir)/libical/src/libical \ - -I$(top_builddir)/libical/src/libical \ - -I$(top_srcdir)/libical/src/libicalvcal \ - $(EVOLUTION_CALENDAR_CFLAGS) - -evolution_calendar_importer_SOURCES = \ - evolution-calendar-importer.h \ - icalendar-importer.c \ - main.c - -evolution_calendar_importer_LDADD = \ - $(top_builddir)/shell/importer/libevolution-importer.la \ - $(top_builddir)/calendar/cal-util/libcal-util.la \ - $(top_builddir)/calendar/cal-client/libcal-client.la \ - $(top_builddir)/libwombat/libwombat.la \ - $(top_builddir)/libical/src/libical/libical-evolution.la \ - $(top_builddir)/libical/src/libicalvcal/libicalvcal-evolution.la \ - $(EVOLUTION_CALENDAR_LIBS) - -oafdir = $(datadir)/oaf -oaf_in_files = GNOME_Evolution_Calendar_Importer.oaf.in - -oaf_DATA = $(oaf_in_files:.oaf.in=.oaf) - -EXTRA_DIST = $(oaf_in_files) $(oaf_DATA) - -@XML_I18N_MERGE_OAF_RULE@ diff --git a/calendar/importers/evolution-calendar-importer.h b/calendar/importers/evolution-calendar-importer.h deleted file mode 100644 index b4c59da340..0000000000 --- a/calendar/importers/evolution-calendar-importer.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Evolution calendar importer component - * - * Authors: Rodrigo Moya <rodrigo@ximian.com> - * - * Copyright (C) 2001 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef EVOLUTION_CALENDAR_IMPORTER_H -#define EVOLUTION_CALENDAR_IMPORTER_H - -#include <bonobo/bonobo-object.h> - -BEGIN_GNOME_DECLS - -BonoboObject *ical_importer_new (void); -BonoboObject *vcal_importer_new (void); - -BonoboObject *gnome_calendar_importer_new (void); - -END_GNOME_DECLS - -#endif diff --git a/calendar/importers/icalendar-importer.c b/calendar/importers/icalendar-importer.c deleted file mode 100644 index 6a7a6f363f..0000000000 --- a/calendar/importers/icalendar-importer.c +++ /dev/null @@ -1,683 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Evolution calendar importer component - * - * Authors: Rodrigo Moya <rodrigo@ximian.com> - * - * Copyright (C) 2001 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include <sys/types.h> -#include <fcntl.h> -#include <gtk/gtksignal.h> -#include <gtk/gtkcheckbutton.h> -#include <gtk/gtkhbox.h> -#include <gtk/gtkmain.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-util.h> -#include <bonobo/bonobo-control.h> -#include <gal/util/e-unicode-i18n.h> -#include <cal-client.h> -#include <importer/evolution-importer.h> -#include <importer/evolution-intelligent-importer.h> -#include <importer/GNOME_Evolution_Importer.h> -#include "icalvcal.h" -#include "evolution-calendar-importer.h" - -/* We timeout after 2 minutes, when opening the folders. */ -#define IMPORTER_TIMEOUT_SECONDS 120 - - -typedef struct { - CalClient *client; - CalClient *tasks_client; - EvolutionImporter *importer; - icalcomponent *icalcomp; - gboolean folder_contains_events; - gboolean folder_contains_tasks; -} ICalImporter; - -typedef struct { - gboolean do_calendar; - gboolean do_tasks; -} ICalIntelligentImporter; - -/* - * Functions shared by iCalendar & vCalendar importer. - */ - -static void -importer_destroy_cb (GtkObject *object, gpointer user_data) -{ - ICalImporter *ici = (ICalImporter *) user_data; - - g_return_if_fail (ici != NULL); - - gtk_object_unref (GTK_OBJECT (ici->client)); - gtk_object_unref (GTK_OBJECT (ici->tasks_client)); - if (ici->icalcomp != NULL) - icalcomponent_free (ici->icalcomp); - g_free (ici); -} - - -/* This reads in an entire file and returns it. It returns NULL on error. - The returned string should be freed. */ -static char* -read_file (const char *filename) -{ - int fd, n; - GString *str; - char buffer[2049]; - gboolean error = FALSE; - - /* read file contents */ - fd = open (filename, O_RDONLY); - if (fd == -1) - return NULL; - - str = g_string_new (""); - while (1) { - memset (buffer, 0, sizeof(buffer)); - n = read (fd, buffer, sizeof (buffer) - 1); - if (n > 0) { - str = g_string_append (str, buffer); - } else if (n == 0) { - break; - } else { - error = TRUE; - break; - } - } - - close (fd); - - if (error) { - g_string_free (str, FALSE); - return NULL; - } else { - gchar *retval = str->str; - g_string_free (str, FALSE); - return retval; - } -} - - -/* Returns the URI to load given a folder path. Currently this is just a full - pathname. The returned string should be freed. */ -static char* -get_uri_from_folder_path (const char *folderpath) -{ - const char *name; - char *parent; - - if (folderpath == NULL || *folderpath == '\0') { - return g_strdup_printf ("%s/evolution/local/Calendar/calendar.ics", - g_get_home_dir ()); - } - - name = strrchr (folderpath, '/'); - if (name == NULL || name == folderpath) { - parent = "evolution/local/"; - if (folderpath[0] == '/') - name = folderpath + 1; - else - name = folderpath; - } else { - name += 1; - parent = "evolution/local/Calendar/subfolders/"; - } - - return g_strdup_printf ("%s/%s%s/calendar.ics", g_get_home_dir (), - parent, name); -} - - -/* Determine whether it is a calendar or tasks folder, or both. If it starts - with 'file:' we know it is a local folder so we see if it ends with - calendar.ics or tasks.ics. For remote folders (i.e. Exchange folders at - present), we import both calendar events and tasks into it. */ -static void -check_folder_type (ICalImporter *ici, - const char *folderpath) -{ - ici->folder_contains_events = TRUE; - ici->folder_contains_tasks = TRUE; - - /* FIXME: Finish. */ -} - - -/* This removes all components except VEVENTs and VTIMEZONEs from the toplevel - icalcomponent, and returns a GList of the VTODO components. */ -static GList* -prepare_events (icalcomponent *icalcomp) -{ - icalcomponent *subcomp, *next_subcomp; - GList *vtodos = NULL; - - subcomp = icalcomponent_get_first_component (icalcomp, - ICAL_ANY_COMPONENT); - while (subcomp) { - icalcomponent_kind child_kind = icalcomponent_isa (subcomp); - next_subcomp = icalcomponent_get_next_component (icalcomp, ICAL_ANY_COMPONENT); - if (child_kind != ICAL_VEVENT_COMPONENT - && child_kind != ICAL_VTIMEZONE_COMPONENT) { - - icalcomponent_remove_component (icalcomp, - subcomp); - if (child_kind == ICAL_VTODO_COMPONENT) - vtodos = g_list_prepend (vtodos, subcomp); - else - icalcomponent_free (subcomp); - } - subcomp = next_subcomp; - } - - return vtodos; -} - - -/* This removes all components except VTODOs and VTIMEZONEs from the toplevel - icalcomponent, and adds the given list of VTODO components. The list is - freed afterwards. */ -static void -prepare_tasks (icalcomponent *icalcomp, GList *vtodos) -{ - icalcomponent *subcomp, *next_subcomp; - GList *elem; - - subcomp = icalcomponent_get_first_component (icalcomp, - ICAL_ANY_COMPONENT); - while (subcomp) { - icalcomponent_kind child_kind = icalcomponent_isa (subcomp); - next_subcomp = icalcomponent_get_next_component (icalcomp, ICAL_ANY_COMPONENT); - if (child_kind != ICAL_VTODO_COMPONENT - && child_kind != ICAL_VTIMEZONE_COMPONENT) { - icalcomponent_remove_component (icalcomp, subcomp); - icalcomponent_free (subcomp); - } - subcomp = next_subcomp; - } - - for (elem = vtodos; elem; elem = elem->next) { - icalcomponent_add_component (icalcomp, elem->data); - } - g_list_free (vtodos); -} - - -static void -process_item_fn (EvolutionImporter *importer, - CORBA_Object listener, - void *closure, - CORBA_Environment *ev) -{ - CalClientLoadState state, tasks_state; - ICalImporter *ici = (ICalImporter *) closure; - GNOME_Evolution_ImporterListener_ImporterResult result; - - result = GNOME_Evolution_ImporterListener_OK; - - g_return_if_fail (ici != NULL); - g_return_if_fail (IS_CAL_CLIENT (ici->client)); - g_return_if_fail (ici->icalcomp != NULL); - - state = cal_client_get_load_state (ici->client); - tasks_state = cal_client_get_load_state (ici->tasks_client); - if (state == CAL_CLIENT_LOAD_LOADING - || tasks_state == CAL_CLIENT_LOAD_LOADING) { - GNOME_Evolution_ImporterListener_notifyResult ( - listener, - GNOME_Evolution_ImporterListener_NOT_READY, - TRUE, ev); - return; - } - else if (state != CAL_CLIENT_LOAD_LOADED - || tasks_state != CAL_CLIENT_LOAD_LOADED) { - GNOME_Evolution_ImporterListener_notifyResult ( - listener, - GNOME_Evolution_ImporterListener_UNSUPPORTED_OPERATION, - FALSE, ev); - return; - } - - /* If the folder contains events & tasks we can just import everything - into it. If it contains just events, we have to strip out the - VTODOs and import them into the default tasks folder. If the folder - contains just tasks, we strip out the VEVENTs, which do not get - imported at all. */ - if (ici->folder_contains_events && ici->folder_contains_tasks) { - if (!cal_client_update_objects (ici->client, ici->icalcomp)) - result = GNOME_Evolution_ImporterListener_BAD_DATA; - } else if (ici->folder_contains_events) { - GList *vtodos = prepare_events (ici->icalcomp); - if (!cal_client_update_objects (ici->client, ici->icalcomp)) - result = GNOME_Evolution_ImporterListener_BAD_DATA; - - prepare_tasks (ici->icalcomp, vtodos); - if (!cal_client_update_objects (ici->tasks_client, - ici->icalcomp)) - result = GNOME_Evolution_ImporterListener_BAD_DATA; - } else { - prepare_tasks (ici->icalcomp, NULL); - if (!cal_client_update_objects (ici->client, ici->icalcomp)) - result = GNOME_Evolution_ImporterListener_BAD_DATA; - } - - GNOME_Evolution_ImporterListener_notifyResult (listener, result, FALSE, - ev); -} - - -/* - * iCalendar importer functions. - */ - -static gboolean -support_format_fn (EvolutionImporter *importer, - const char *filename, - void *closure) -{ - char *contents; - icalcomponent *icalcomp; - gboolean ret = FALSE; - - contents = read_file (filename); - - /* parse the file */ - if (contents) { - icalcomp = icalparser_parse_string (contents); - if (icalcomp) { - icalcomponent_free (icalcomp); - ret = TRUE; - } - } - - g_free (contents); - - return ret; -} - -static gboolean -load_file_fn (EvolutionImporter *importer, - const char *filename, - const char *folderpath, - void *closure) -{ - char *uri_str, *contents; - gboolean ret = FALSE; - ICalImporter *ici = (ICalImporter *) closure; - - g_return_val_if_fail (ici != NULL, FALSE); - - uri_str = get_uri_from_folder_path (folderpath); - check_folder_type (ici, folderpath); - - contents = read_file (filename); - - /* parse the file */ - if (contents) { - icalcomponent *icalcomp; - - icalcomp = icalparser_parse_string (contents); - if (icalcomp) { - if (cal_client_open_calendar (ici->client, uri_str, TRUE) - && cal_client_open_default_tasks (ici->tasks_client, FALSE)) { - ici->icalcomp = icalcomp; - ret = TRUE; - } - } - } - - g_free (contents); - g_free (uri_str); - - return ret; -} - -BonoboObject * -ical_importer_new (void) -{ - ICalImporter *ici; - - ici = g_new0 (ICalImporter, 1); - ici->client = cal_client_new (); - ici->tasks_client = cal_client_new (); - ici->icalcomp = NULL; - ici->importer = evolution_importer_new (support_format_fn, - load_file_fn, - process_item_fn, - NULL, - ici); - gtk_signal_connect (GTK_OBJECT (ici->importer), "destroy", - GTK_SIGNAL_FUNC (importer_destroy_cb), ici); - - return BONOBO_OBJECT (ici->importer); -} - - - -/* - * vCalendar importer functions. - */ - -static gboolean -vcal_support_format_fn (EvolutionImporter *importer, - const char *filename, - void *closure) -{ - char *contents; - gboolean ret = FALSE; - - contents = read_file (filename); - - /* parse the file */ - if (contents) { - VObject *vcal; - - vcal = Parse_MIME (contents, strlen (contents)); - - if (vcal) { - icalcomponent *icalcomp; - - icalcomp = icalvcal_convert (vcal); - - if (icalcomp) { - icalcomponent_free (icalcomp); - ret = TRUE; - } - - cleanVObject (vcal); - } - } - - g_free (contents); - - return ret; -} - -/* This tries to load in a vCalendar file and convert it to an icalcomponent. - It returns NULL on failure. */ -static icalcomponent* -load_vcalendar_file (const char *filename) -{ - icalvcal_defaults defaults = { 0 }; - icalcomponent *icalcomp = NULL; - char *contents; - - defaults.alarm_audio_url = "file://" EVOLUTION_SOUNDDIR "/default_alarm.wav"; - defaults.alarm_audio_fmttype = "audio/x-wav"; - defaults.alarm_description = (char*) U_("Reminder!!"); - - contents = read_file (filename); - - /* parse the file */ - if (contents) { - VObject *vcal; - - vcal = Parse_MIME (contents, strlen (contents)); - - if (vcal) { - icalcomp = icalvcal_convert_with_defaults (vcal, - &defaults); - cleanVObject (vcal); - } - } - - g_free (contents); - - return icalcomp; -} - -static gboolean -vcal_load_file_fn (EvolutionImporter *importer, - const char *filename, - const char *folderpath, - void *closure) -{ - char *uri_str; - gboolean ret = FALSE; - ICalImporter *ici = (ICalImporter *) closure; - icalcomponent *icalcomp; - - g_return_val_if_fail (ici != NULL, FALSE); - - uri_str = get_uri_from_folder_path (folderpath); - check_folder_type (ici, folderpath); - - icalcomp = load_vcalendar_file (filename); - if (icalcomp) { - if (cal_client_open_calendar (ici->client, uri_str, TRUE) - && cal_client_open_default_tasks (ici->tasks_client, FALSE)) { - ici->icalcomp = icalcomp; - ret = TRUE; - } - } - - g_free (uri_str); - - return ret; -} - -BonoboObject * -vcal_importer_new (void) -{ - ICalImporter *ici; - - ici = g_new0 (ICalImporter, 1); - ici->client = cal_client_new (); - ici->tasks_client = cal_client_new (); - ici->icalcomp = NULL; - ici->importer = evolution_importer_new (vcal_support_format_fn, - vcal_load_file_fn, - process_item_fn, - NULL, - ici); - gtk_signal_connect (GTK_OBJECT (ici->importer), "destroy", - GTK_SIGNAL_FUNC (importer_destroy_cb), ici); - - return BONOBO_OBJECT (ici->importer); -} - - - - - - -static void -gnome_calendar_importer_destroy_cb (GtkObject *object, gpointer user_data) -{ - ICalIntelligentImporter *ici = (ICalIntelligentImporter *) user_data; - - g_return_if_fail (ici != NULL); - - g_free (ici); -} - - - -static gboolean -gnome_calendar_can_import_fn (EvolutionIntelligentImporter *ii, - void *closure) -{ - char *filename; - gboolean gnome_calendar_exists; - - filename = gnome_util_home_file ("user-cal.vcf"); - gnome_calendar_exists = g_file_exists (filename); - g_free (filename); - - return gnome_calendar_exists; -} - - -static void -gnome_calendar_import_data_fn (EvolutionIntelligentImporter *ii, - void *closure) -{ - ICalIntelligentImporter *ici = closure; - icalcomponent *icalcomp = NULL; - char *filename; - GList *vtodos; - CalClient *calendar_client = NULL, *tasks_client = NULL; - int t; - - /* If neither is selected, just return. */ - if (!ici->do_calendar && !ici->do_tasks) { - return; - } - - /* Try to open the default calendar & tasks folders. */ - if (ici->do_calendar) { - calendar_client = cal_client_new (); - if (!cal_client_open_default_calendar (calendar_client, FALSE)) - goto out; - } - - if (ici->do_tasks) { - tasks_client = cal_client_new (); - if (!cal_client_open_default_tasks (tasks_client, FALSE)) - goto out; - } - - /* Load the Gnome Calendar file and convert to iCalendar. */ - filename = gnome_util_home_file ("user-cal.vcf"); - icalcomp = load_vcalendar_file (filename); - g_free (filename); - - /* If we couldn't load the file, just return. FIXME: Error message? */ - if (!icalcomp) - goto out; - - /* - * Import the calendar events into the default calendar folder. - */ - vtodos = prepare_events (icalcomp); - - /* Wait for client to finish opening the calendar & tasks folders. */ - for (t = 0; t < IMPORTER_TIMEOUT_SECONDS; t++) { - CalClientLoadState calendar_state, tasks_state; - - calendar_state = tasks_state = CAL_CLIENT_LOAD_LOADED; - - /* We need this so the CalClient gets notified that the - folder is opened, via Corba. */ - while (gtk_events_pending ()) - gtk_main_iteration (); - - if (ici->do_calendar) - calendar_state = cal_client_get_load_state (calendar_client); - - if (ici->do_tasks) - tasks_state = cal_client_get_load_state (tasks_client); - - if (calendar_state == CAL_CLIENT_LOAD_LOADED - && tasks_state == CAL_CLIENT_LOAD_LOADED) - break; - - sleep (1); - } - - /* If we timed out, just return. */ - if (t == IMPORTER_TIMEOUT_SECONDS) - goto out; - - /* Import the calendar events. */ - /* FIXME: What do intelligent importers do about errors? */ - if (ici->do_calendar) - cal_client_update_objects (calendar_client, icalcomp); - - - /* - * Import the tasks into the default tasks folder. - */ - prepare_tasks (icalcomp, vtodos); - if (ici->do_tasks) - cal_client_update_objects (tasks_client, icalcomp); - - out: - if (icalcomp) - icalcomponent_free (icalcomp); - if (calendar_client) - gtk_object_unref (GTK_OBJECT (calendar_client)); - if (tasks_client) - gtk_object_unref (GTK_OBJECT (tasks_client)); -} - - -/* Fun with aggregation */ -static void -checkbox_toggle_cb (GtkToggleButton *tb, - gboolean *do_item) -{ - *do_item = gtk_toggle_button_get_active (tb); -} - -static BonoboControl * -create_checkboxes_control (ICalIntelligentImporter *ici) -{ - GtkWidget *hbox, *calendar_checkbox, *tasks_checkbox; - BonoboControl *control; - - hbox = gtk_hbox_new (FALSE, 2); - - calendar_checkbox = gtk_check_button_new_with_label (_("Calendar Events")); - gtk_signal_connect (GTK_OBJECT (calendar_checkbox), "toggled", - GTK_SIGNAL_FUNC (checkbox_toggle_cb), - &ici->do_calendar); - gtk_box_pack_start (GTK_BOX (hbox), calendar_checkbox, - FALSE, FALSE, 0); - - tasks_checkbox = gtk_check_button_new_with_label (_("Tasks")); - gtk_signal_connect (GTK_OBJECT (tasks_checkbox), "toggled", - GTK_SIGNAL_FUNC (checkbox_toggle_cb), - &ici->do_tasks); - gtk_box_pack_start (GTK_BOX (hbox), tasks_checkbox, - FALSE, FALSE, 0); - - gtk_widget_show_all (hbox); - control = bonobo_control_new (hbox); - return control; -} - -BonoboObject * -gnome_calendar_importer_new (void) -{ - EvolutionIntelligentImporter *importer; - ICalIntelligentImporter *ici; - BonoboControl *control; - char *message = N_("Evolution has found Gnome Calendar files.\n" - "Would you like to import them into Evolution?"); - - ici = g_new0 (ICalIntelligentImporter, 1); - - importer = evolution_intelligent_importer_new (gnome_calendar_can_import_fn, - gnome_calendar_import_data_fn, - _("Gnome Calendar"), - _(message), - ici); - - - gtk_signal_connect (GTK_OBJECT (importer), "destroy", - GTK_SIGNAL_FUNC (gnome_calendar_importer_destroy_cb), ici); - - control = create_checkboxes_control (ici); - bonobo_object_add_interface (BONOBO_OBJECT (importer), - BONOBO_OBJECT (control)); - - return BONOBO_OBJECT (importer); -} diff --git a/calendar/importers/main.c b/calendar/importers/main.c deleted file mode 100644 index f6d5788d93..0000000000 --- a/calendar/importers/main.c +++ /dev/null @@ -1,91 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Evolution calendar importer component - * - * Authors: Rodrigo Moya <rodrigo@ximian.com> - * - * Copyright (C) 2001 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <bonobo/bonobo-generic-factory.h> -#include <bonobo/bonobo-context.h> -#include <bonobo/bonobo-main.h> -#include "evolution-calendar-importer.h" - -#define IMPORTER_FACTORY_ID "OAFIID:GNOME_Evolution_Calendar_ImporterFactory" -#define ICALENDAR_IMPORTER_ID "OAFIID:GNOME_Evolution_Calendar_iCalendar_Importer" -#define VCALENDAR_IMPORTER_ID "OAFIID:GNOME_Evolution_Calendar_vCalendar_Importer" -#define GNOME_CALENDAR_IMPORTER_ID "OAFIID:GNOME_Evolution_Gnome_Calendar_Intelligent_Importer" - -static BonoboObject * -importer_factory_fn (BonoboGenericFactory *factory, const char *id, void *closure) -{ - BonoboObject *object = NULL; - - g_return_val_if_fail (id != NULL, NULL); - - if (!strcmp (id, ICALENDAR_IMPORTER_ID)) - object = ical_importer_new (); - else if (!strcmp (id, VCALENDAR_IMPORTER_ID)) - object = vcal_importer_new (); - else if (!strcmp (id, GNOME_CALENDAR_IMPORTER_ID)) - object = gnome_calendar_importer_new (); - else - g_warning ("Component not supporte by this factory"); - - return object; -} - -static void -init_importer (void) -{ - BonoboGenericFactory *factory; - - factory = bonobo_generic_factory_new_multi (IMPORTER_FACTORY_ID, - importer_factory_fn, NULL); - if (factory == NULL) { - g_error ("Unable to create factory"); - exit (0); - } - - bonobo_running_context_auto_exit_unref (BONOBO_OBJECT (factory)); -} - -int -main (int argc, char *argv[]) -{ - CORBA_ORB orb; - - bindtextdomain(PACKAGE, EVOLUTION_LOCALEDIR); - textdomain(PACKAGE); - - gnome_init_with_popt_table ("evolution-calendar-importer", - VERSION, argc, argv, oaf_popt_options, 0, - NULL); - orb = oaf_init (argc, argv); - if (bonobo_init (orb, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL) == FALSE) { - g_error ("Could not initialize Bonobo."); - exit (0); - } - - init_importer (); - bonobo_main (); - - return 0; -} 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 57c24d3130..0000000000 --- a/calendar/pcs/Makefile.am +++ /dev/null @@ -1,52 +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 \ - -I$(top_srcdir)/libwombat \ - -I$(top_builddir)/libwombat \ - -DGNOMELOCALEDIR=\""$(localedir)"\" \ - $(EVOLUTION_CALENDAR_CFLAGS) - -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-backend-util.c \ - cal-backend-util.h \ - cal-common.h \ - cal-factory.c \ - cal-factory.h \ - job.c \ - job.h \ - query.c \ - query.h - - -BUILT_SOURCES = $(CORBA_GENERATED) -CLEANFILES = $(BUILT_SOURCES) - -dist-hook: - cd $(distdir); rm -f $(BUILT_SOURCES) - diff --git a/calendar/pcs/cal-backend-file.c b/calendar/pcs/cal-backend-file.c deleted file mode 100644 index 5ca5a06f0e..0000000000 --- a/calendar/pcs/cal-backend-file.c +++ /dev/null @@ -1,1949 +0,0 @@ -/* Evolution calendar - iCalendar file backend - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * Rodrigo Moya <rodrigo@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#include <config.h> -#include <gtk/gtksignal.h> -#include <bonobo/bonobo-exception.h> -#include <bonobo/bonobo-moniker-util.h> -#include <libgnomevfs/gnome-vfs.h> -#include "e-util/e-dbhash.h" -#include "cal-util/cal-recur.h" -#include "cal-util/cal-util.h" -#include "cal-backend-file.h" -#include "cal-backend-util.h" - - - -/* A category that exists in some of the objects of the calendar */ -typedef struct { - /* Category name, also used as the key in the categories hash table */ - char *name; - - /* Number of objects that have this category */ - int refcount; -} Category; - -/* Private part of the CalBackendFile structure */ -struct _CalBackendFilePrivate { - /* URI where the calendar data is stored */ - char *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; - - /* Hash table of live categories, and a temporary hash of removed categories */ - GHashTable *categories; - GHashTable *removed_categories; - - /* Config database handle for free/busy organizer information */ - Bonobo_ConfigDatabase db; - - /* Idle handler for saving the calendar when it is dirty */ - guint idle_id; - - /* The calendar's default timezone, used for resolving DATE and - floating DATE-TIME values. */ - icaltimezone *default_zone; -}; - - - -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 const char *cal_backend_file_get_uri (CalBackend *backend); -static CalBackendOpenStatus cal_backend_file_open (CalBackend *backend, - const char *uristr, - gboolean only_if_exists); -static gboolean cal_backend_file_is_loaded (CalBackend *backend); -static Query *cal_backend_file_get_query (CalBackend *backend, - GNOME_Evolution_Calendar_QueryListener ql, - const char *sexp); - -static CalMode cal_backend_file_get_mode (CalBackend *backend); -static void cal_backend_file_set_mode (CalBackend *backend, CalMode mode); - -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 CalComponent *cal_backend_file_get_object_component (CalBackend *backend, const char *uid); -static char *cal_backend_file_get_timezone_object (CalBackend *backend, const char *tzid); -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 GList *cal_backend_file_get_free_busy (CalBackend *backend, GList *users, 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_objects (CalBackend *backend, const char *calobj); -static gboolean cal_backend_file_remove_object (CalBackend *backend, const char *uid); - -static icaltimezone* cal_backend_file_get_timezone (CalBackend *backend, const char *tzid); -static icaltimezone* cal_backend_file_get_default_timezone (CalBackend *backend); -static gboolean cal_backend_file_set_default_timezone (CalBackend *backend, - const char *tzid); - -static void notify_categories_changed (CalBackendFile *cbfile); - -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->open = cal_backend_file_open; - backend_class->is_loaded = cal_backend_file_is_loaded; - backend_class->get_query = cal_backend_file_get_query; - backend_class->get_mode = cal_backend_file_get_mode; - backend_class->set_mode = cal_backend_file_set_mode; - backend_class->get_n_objects = cal_backend_file_get_n_objects; - backend_class->get_object = cal_backend_file_get_object; - backend_class->get_object_component = cal_backend_file_get_object_component; - backend_class->get_timezone_object = cal_backend_file_get_timezone_object; - 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_free_busy = cal_backend_file_get_free_busy; - 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_objects = cal_backend_file_update_objects; - backend_class->remove_object = cal_backend_file_remove_object; - - backend_class->get_timezone = cal_backend_file_get_timezone; - backend_class->get_default_timezone = cal_backend_file_get_default_timezone; - backend_class->set_default_timezone = cal_backend_file_set_default_timezone; -} - -static Bonobo_ConfigDatabase -load_db (void) -{ - Bonobo_ConfigDatabase db = CORBA_OBJECT_NIL; - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - db = bonobo_get_object ("wombat:", "Bonobo/ConfigDatabase", &ev); - - if (BONOBO_EX (&ev)) - db = CORBA_OBJECT_NIL; - - CORBA_exception_free (&ev); - - return db; -} - -static void -cal_added_cb (CalBackend *backend, gpointer user_data) -{ - notify_categories_changed (CAL_BACKEND_FILE (backend)); -} - -/* 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; - - priv->uri = NULL; - priv->icalcomp = NULL; - priv->comp_uid_hash = NULL; - priv->events = NULL; - priv->todos = NULL; - priv->journals = NULL; - - priv->categories = g_hash_table_new (g_str_hash, g_str_equal); - priv->removed_categories = g_hash_table_new (g_str_hash, g_str_equal); - - /* The timezone defaults to UTC. */ - priv->default_zone = icaltimezone_get_utc_timezone (); - - priv->db = load_db (); - - gtk_signal_connect (GTK_OBJECT (cbfile), "cal_added", - GTK_SIGNAL_FUNC (cal_added_cb), NULL); -} - -/* 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; - GnomeVFSURI *uri; - GnomeVFSHandle *handle = NULL; - GnomeVFSResult result; - GnomeVFSFileSize out; - gchar *tmp; - char *buf; - - priv = cbfile->priv; - g_assert (priv->uri != NULL); - g_assert (priv->icalcomp != NULL); - - uri = gnome_vfs_uri_new (priv->uri); - - /* Make a backup copy of the file if it exists */ - tmp = gnome_vfs_uri_to_string (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 (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, 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); - gnome_vfs_uri_unref (uri); - - return; - - error: - g_warning ("Error writing calendar file."); - return; -} - -/* Used from g_hash_table_foreach(), frees a Category structure */ -static void -free_category_cb (gpointer key, gpointer value, gpointer data) -{ - Category *c; - - c = value; - g_free (c->name); - g_free (c); -} - -/* Destroy handler for the file backend */ -static void -cal_backend_file_destroy (GtkObject *object) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - GList *clients; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_CAL_BACKEND_FILE (object)); - - cbfile = CAL_BACKEND_FILE (object); - priv = cbfile->priv; - - clients = CAL_BACKEND (cbfile)->clients; - g_assert (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) { - g_free (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; - - g_hash_table_foreach (priv->categories, free_category_cb, NULL); - g_hash_table_destroy (priv->categories); - priv->categories = NULL; - - g_hash_table_foreach (priv->removed_categories, free_category_cb, NULL); - g_hash_table_destroy (priv->removed_categories); - priv->removed_categories = NULL; - - if (priv->icalcomp) { - icalcomponent_free (priv->icalcomp); - priv->icalcomp = NULL; - } - - bonobo_object_release_unref (priv->db, NULL); - priv->db = CORBA_OBJECT_NIL; - - 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 const char * -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 (const char *) priv->uri; -} - -/* Used from g_hash_table_foreach(), adds a category name to the sequence */ -static void -add_category_cb (gpointer key, gpointer value, gpointer data) -{ - Category *c; - GNOME_Evolution_Calendar_StringSeq *seq; - - c = value; - seq = data; - - seq->_buffer[seq->_length] = CORBA_string_dup (c->name); - seq->_length++; -} - -/* Notifies the clients with the current list of categories */ -static void -notify_categories_changed (CalBackendFile *cbfile) -{ - CalBackendFilePrivate *priv; - GNOME_Evolution_Calendar_StringSeq *seq; - GList *l; - - priv = cbfile->priv; - - /* Build the sequence of category names */ - - seq = GNOME_Evolution_Calendar_StringSeq__alloc (); - seq->_length = 0; - seq->_maximum = g_hash_table_size (priv->categories); - seq->_buffer = CORBA_sequence_CORBA_string_allocbuf (seq->_maximum); - CORBA_sequence_set_release (seq, TRUE); - - g_hash_table_foreach (priv->categories, add_category_cb, seq); - g_assert (seq->_length == seq->_maximum); - - /* Notify the clients */ - - for (l = CAL_BACKEND (cbfile)->clients; l; l = l->next) { - Cal *cal; - - cal = CAL (l->data); - cal_notify_categories_changed (cal, seq); - } - - CORBA_free (seq); -} - -/* 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); -} - -/* Updates the hash table of categories by adding or removing those in the - * component. - */ -static void -update_categories_from_comp (CalBackendFile *cbfile, CalComponent *comp, gboolean add) -{ - CalBackendFilePrivate *priv; - GSList *categories, *l; - - priv = cbfile->priv; - - cal_component_get_categories_list (comp, &categories); - - for (l = categories; l; l = l->next) { - const char *name; - Category *c; - - name = l->data; - c = g_hash_table_lookup (priv->categories, name); - - if (add) { - /* Add the category to the set */ - if (c) - c->refcount++; - else { - /* See if it was in the removed categories */ - - c = g_hash_table_lookup (priv->removed_categories, name); - if (c) { - /* Move it to the set of live categories */ - g_assert (c->refcount == 0); - g_hash_table_remove (priv->removed_categories, c->name); - - c->refcount = 1; - g_hash_table_insert (priv->categories, c->name, c); - } else { - /* Create a new category */ - c = g_new (Category, 1); - c->name = g_strdup (name); - c->refcount = 1; - - g_hash_table_insert (priv->categories, c->name, c); - } - } - } else { - /* Remove the category from the set --- it *must* have existed */ - - g_assert (c != NULL); - g_assert (c->refcount > 0); - - c->refcount--; - - if (c->refcount == 0) { - g_hash_table_remove (priv->categories, c->name); - g_hash_table_insert (priv->removed_categories, c->name, c); - } - } - } - - cal_component_free_categories_list (categories); -} - -/* 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); - } - - /* Update the set of categories */ - - update_categories_from_comp (cbfile, comp, TRUE); -} - -/* 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); - - /* Update the set of categories */ - - update_categories_from_comp (cbfile, comp, FALSE); - - 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, const char *uristr, 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) { - icalcomponent_free (icalcomp); - 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); - - priv->uri = g_strdup (uristr); - - return CAL_BACKEND_OPEN_SUCCESS; -} - -static CalBackendOpenStatus -create_cal (CalBackendFile *cbfile, const char *uristr) -{ - CalBackendFilePrivate *priv; - - priv = cbfile->priv; - - /* Create the new calendar information */ - priv->icalcomp = cal_util_new_top_level (); - - /* Create our internal data */ - priv->comp_uid_hash = g_hash_table_new (g_str_hash, g_str_equal); - - priv->uri = g_strdup (uristr); - - mark_dirty (cbfile); - - return CAL_BACKEND_OPEN_SUCCESS; -} - -/* Open handler for the file backend */ -static CalBackendOpenStatus -cal_backend_file_open (CalBackend *backend, const char *uristr, gboolean only_if_exists) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - FILE *file; - char *str_uri; - GnomeVFSURI *uri; - CalBackendOpenStatus status; - - 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 (uristr != NULL, CAL_BACKEND_OPEN_ERROR); - - g_assert (priv->uri == NULL); - g_assert (priv->comp_uid_hash == NULL); - - uri = gnome_vfs_uri_new (uristr); - if (!uri) - return CAL_BACKEND_OPEN_ERROR; - - if (!gnome_vfs_uri_is_local (uri)) { - gnome_vfs_uri_unref (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"); - - if (file) - status = open_cal (cbfile, str_uri, file); - else { - if (only_if_exists) - status = CAL_BACKEND_OPEN_NOT_FOUND; - else - status = create_cal (cbfile, str_uri); - } - - g_free (str_uri); - gnome_vfs_uri_unref (uri); - - return status; -} - -/* is_loaded handler for the file backend */ -static gboolean -cal_backend_file_is_loaded (CalBackend *backend) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - return (priv->icalcomp != NULL); -} - -/* get_query handler for the file backend */ -static Query * -cal_backend_file_get_query (CalBackend *backend, - GNOME_Evolution_Calendar_QueryListener ql, - const char *sexp) -{ - CalBackendFile *cbfile; - - cbfile = CAL_BACKEND_FILE (backend); - - return query_new (backend, ql, sexp); -} - -/* is_remote handler for the file backend */ -static CalMode -cal_backend_file_get_mode (CalBackend *backend) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - return CAL_MODE_LOCAL; -} - -static void -notify_mode (CalBackendFile *cbfile, - GNOME_Evolution_Calendar_Listener_SetModeStatus status, - GNOME_Evolution_Calendar_CalMode mode) -{ - CalBackendFilePrivate *priv; - GList *l; - - priv = cbfile->priv; - - for (l = CAL_BACKEND (cbfile)->clients; l; l = l->next) { - Cal *cal; - - cal = CAL (l->data); - cal_notify_mode (cal, status, mode); - } -} - -/* Set_mode handler for the file backend */ -static void -cal_backend_file_set_mode (CalBackend *backend, CalMode mode) -{ - notify_mode (CAL_BACKEND_FILE (backend), - GNOME_Evolution_Calendar_Listener_MODE_NOT_SUPPORTED, - GNOME_Evolution_Calendar_MODE_LOCAL); - -} - -/* 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); -} - -/* Get_object handler for the file backend */ -static CalComponent * -cal_backend_file_get_object_component (CalBackend *backend, const char *uid) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - - 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); - - return lookup_component (cbfile, uid); -} - -/* Get_object handler for the file backend */ -static char * -cal_backend_file_get_timezone_object (CalBackend *backend, const char *tzid) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - icaltimezone *zone; - icalcomponent *icalcomp; - char *ical_string; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (tzid != NULL, NULL); - - g_return_val_if_fail (priv->icalcomp != NULL, NULL); - g_assert (priv->comp_uid_hash != NULL); - - zone = icalcomponent_get_timezone (priv->icalcomp, tzid); - if (!zone) - return NULL; - - icalcomp = icaltimezone_get_component (zone); - if (!icalcomp) - return NULL; - - ical_string = icalcomponent_as_ical_string (icalcomp); - /* We dup the string; libical owns that memory. */ - if (ical_string) - return g_strdup (ical_string); - else - return NULL; -} - -/* 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; -} - -/* function to resolve timezones */ -static icaltimezone * -resolve_tzid (const char *tzid, gpointer user_data) -{ - icalcomponent *vcalendar_comp = user_data; - - if (!tzid || !tzid[0]) - return NULL; - else if (!strcmp (tzid, "UTC")) - return icaltimezone_get_utc_timezone (); - - return icalcomponent_get_timezone (vcalendar_comp, tzid); -} - -/* 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, icaltimezone *default_zone) -{ - GList *l; - - for (l = components; l; l = l->next) { - CalComponent *comp; - icalcomponent *icalcomp, *vcalendar_comp; - - comp = CAL_COMPONENT (l->data); - - /* Get the parent VCALENDAR component, so we can resolve - TZIDs. */ - icalcomp = cal_component_get_icalcomponent (comp); - vcalendar_comp = icalcomponent_get_parent (icalcomp); - g_assert (vcalendar_comp != NULL); - - cal_recur_generate_instances (comp, start, end, add_instance, uid_hash, resolve_tzid, vcalendar_comp, default_zone); - } -} - -/* 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, - priv->default_zone); - - if (type & CALOBJ_TYPE_TODO) - get_instances_in_range (uid_hash, priv->todos, start, end, - priv->default_zone); - - if (type & CALOBJ_TYPE_JOURNAL) - get_instances_in_range (uid_hash, priv->journals, start, end, - priv->default_zone); - - event_list = NULL; - g_hash_table_foreach (uid_hash, add_uid_to_list, &event_list); - g_hash_table_destroy (uid_hash); - - return event_list; -} - -static gboolean -free_busy_instance (CalComponent *comp, - time_t instance_start, - time_t instance_end, - gpointer data) -{ - icalcomponent *vfb = data; - icalproperty *prop; - icalparameter *param; - struct icalperiodtype ipt; - icaltimezone *utc_zone; - - utc_zone = icaltimezone_get_utc_timezone (); - - ipt.start = icaltime_from_timet_with_zone (instance_start, FALSE, utc_zone); - ipt.end = icaltime_from_timet_with_zone (instance_end, FALSE, utc_zone); - ipt.duration = icaldurationtype_null_duration (); - - /* add busy information to the vfb component */ - prop = icalproperty_new (ICAL_FREEBUSY_PROPERTY); - icalproperty_set_freebusy (prop, ipt); - - param = icalparameter_new_fbtype (ICAL_FBTYPE_BUSY); - icalproperty_add_parameter (prop, param); - - icalcomponent_add_property (vfb, prop); - - return TRUE; -} - -static icalcomponent * -create_user_free_busy (CalBackendFile *cbfile, const char *address, const char *cn, - time_t start, time_t end) -{ - CalBackendFilePrivate *priv; - GList *uids; - GList *l; - icalcomponent *vfb; - icaltimezone *utc_zone; - - priv = cbfile->priv; - - /* create the (unique) VFREEBUSY object that we'll return */ - vfb = icalcomponent_new_vfreebusy (); - if (address != NULL) { - icalproperty *prop; - icalparameter *param; - - prop = icalproperty_new_organizer (address); - if (prop != NULL && cn != NULL) { - param = icalparameter_new_cn (cn); - icalproperty_add_parameter (prop, param); - } - if (prop != NULL) - icalcomponent_add_property (vfb, prop); - } - utc_zone = icaltimezone_get_utc_timezone (); - icalcomponent_set_dtstart (vfb, icaltime_from_timet_with_zone (start, FALSE, utc_zone)); - icalcomponent_set_dtend (vfb, icaltime_from_timet_with_zone (end, FALSE, utc_zone)); - - /* add all objects in the given interval */ - - uids = cal_backend_get_objects_in_range (CAL_BACKEND (cbfile), - CALOBJ_TYPE_ANY, start, end); - for (l = uids; l != NULL; l = l->next) { - CalComponent *comp; - icalcomponent *icalcomp, *vcalendar_comp; - icalproperty *prop; - char *uid = (char *) l->data; - - /* get the component from our internal list */ - comp = lookup_component (cbfile, uid); - if (!comp) - continue; - - icalcomp = cal_component_get_icalcomponent (comp); - if (!icalcomp) - continue; - - /* If the event is TRANSPARENT, skip it. */ - prop = icalcomponent_get_first_property (icalcomp, - ICAL_TRANSP_PROPERTY); - if (prop) { - const char *transp_val = icalproperty_get_transp (prop); - if (transp_val - && !strcasecmp (transp_val, "TRANSPARENT")) - continue; - } - - vcalendar_comp = icalcomponent_get_parent (icalcomp); - cal_recur_generate_instances (comp, start, end, - free_busy_instance, - vfb, - resolve_tzid, - vcalendar_comp, - priv->default_zone); - - } - cal_obj_uid_list_free (uids); - - return vfb; -} - -/* Get_free_busy handler for the file backend */ -static GList * -cal_backend_file_get_free_busy (CalBackend *backend, GList *users, time_t start, time_t end) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - gchar *address, *name; - icalcomponent *vfb; - char *calobj; - GList *obj_list = NULL; - GList *l; - - 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); - - if (users == NULL) { - if (cal_backend_mail_account_get_default (priv->db, &address, &name)) { - vfb = create_user_free_busy (cbfile, address, name, start, end); - calobj = icalcomponent_as_ical_string (vfb); - obj_list = g_list_append (obj_list, g_strdup (calobj)); - icalcomponent_free (vfb); - g_free (address); - g_free (name); - } - } else { - for (l = users; l != NULL; l = l->next ) { - address = l->data; - if (cal_backend_mail_account_is_valid (priv->db, address, &name)) { - vfb = create_user_free_busy (cbfile, address, name, start, end); - calobj = icalcomponent_as_ical_string (vfb); - obj_list = g_list_append (obj_list, g_strdup (calobj)); - icalcomponent_free (vfb); - g_free (name); - } - } - } - - return obj_list; -} - -typedef struct -{ - CalBackend *backend; - CalObjType type; - 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; - char *calobj; - - comp = cal_component_new (); - if (be_data->type == GNOME_Evolution_Calendar_TYPE_TODO) - cal_component_set_new_vtype (comp, CAL_COMPONENT_TODO); - else - cal_component_set_new_vtype (comp, CAL_COMPONENT_EVENT); - - cal_component_set_uid (comp, key); - calobj = cal_component_get_as_string (comp); - - coc = GNOME_Evolution_Calendar_CalObjChange__alloc (); - coc->calobj = CORBA_string_dup (calobj); - 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, g_strdup (key)); - - g_free (calobj); - gtk_object_unref (GTK_OBJECT (comp)); - } -} - -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, g_strdup (uid)); - break; - case E_DBHASH_STATUS_DIFFERENT: - coc = GNOME_Evolution_Calendar_CalObjChange__alloc (); - coc->calobj = CORBA_string_dup (calobj); - coc->type = GNOME_Evolution_Calendar_MODIFIED; - changes = g_list_prepend (changes, coc); - change_ids = g_list_prepend (change_ids, g_strdup (uid)); - break; - } - } - - /* Calculate deletions */ - be_data.backend = backend; - be_data.type = type; - 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); - g_free (uid); - } - 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); -} - -/* 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 += cal_util_generate_alarms_for_list (priv->events, start, end, - &comp_alarms, resolve_tzid, - priv->icalcomp, - priv->default_zone); - n_comp_alarms += cal_util_generate_alarms_for_list (priv->todos, start, end, - &comp_alarms, resolve_tzid, - priv->icalcomp, - priv->default_zone); - - 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); - - cal_backend_util_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 = cal_util_generate_alarms_for_comp (comp, start, end, resolve_tzid, priv->icalcomp, priv->default_zone); - if (alarms) { - cal_backend_util_fill_alarm_instances_seq (&corba_alarms->alarms, alarms->alarms); - cal_component_alarms_free (alarms); - } else - cal_backend_util_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; - - cal_backend_obj_updated (CAL_BACKEND (cbfile), uid); - - for (l = CAL_BACKEND (cbfile)->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; - - cal_backend_obj_removed (CAL_BACKEND (cbfile), uid); - - for (l = CAL_BACKEND (cbfile)->clients; l; l = l->next) { - Cal *cal; - - cal = CAL (l->data); - cal_notify_remove (cal, uid); - } -} - -/* Used from g_hash_table_foreach_remove(); removes and frees a category */ -static gboolean -remove_category_cb (gpointer key, gpointer value, gpointer data) -{ - Category *c; - - c = value; - g_free (c->name); - g_free (c); - - return TRUE; -} - -/* Clears the table of removed categories */ -static void -clean_removed_categories (CalBackendFile *cbfile) -{ - CalBackendFilePrivate *priv; - - priv = cbfile->priv; - - g_hash_table_foreach_remove (priv->removed_categories, - remove_category_cb, - NULL); -} - - -/* Creates a CalComponent for the given icalcomponent and adds it to our - cache. Note that the icalcomponent is not added to the toplevel - icalcomponent here. That needs to be done elsewhere. It returns the uid - of the added component, or NULL if it failed. */ -static const char* -cal_backend_file_update_object (CalBackendFile *cbfile, - icalcomponent *icalcomp) -{ - CalComponent *old_comp; - CalComponent *comp; - const char *comp_uid; - - /* Create a CalComponent wrapper for the icalcomponent. */ - comp = cal_component_new (); - if (!cal_component_set_icalcomponent (comp, icalcomp)) { - gtk_object_unref (GTK_OBJECT (comp)); - return NULL; - } - - /* Get the UID, and check it isn't empty. */ - cal_component_get_uid (comp, &comp_uid); - if (!comp_uid || !comp_uid[0]) { - gtk_object_unref (GTK_OBJECT (comp)); - return NULL; - } - - /* Remove any old version of the component. */ - old_comp = lookup_component (cbfile, comp_uid); - if (old_comp) - remove_component (cbfile, old_comp); - - /* Now add the component to our local cache, but we pass FALSE as - the last argument, since the libical component is assumed to have - been added already. */ - add_component (cbfile, comp, FALSE); - - return comp_uid; -} - - - -/* Update_objects handler for the file backend. */ -static gboolean -cal_backend_file_update_objects (CalBackend *backend, const char *calobj) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - icalcomponent *toplevel_comp, *icalcomp = NULL; - icalcomponent_kind kind; - int old_n_categories, new_n_categories; - icalcomponent *subcomp; - gboolean retval = TRUE; - GList *comp_uid_list = NULL, *elem; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (priv->icalcomp != NULL, FALSE); - - g_return_val_if_fail (calobj != NULL, FALSE); - - /* Pull the component from the string and ensure that it is sane */ - - toplevel_comp = icalparser_parse_string ((char *) calobj); - - if (!toplevel_comp) - return FALSE; - - kind = icalcomponent_isa (toplevel_comp); - - if (kind == ICAL_VEVENT_COMPONENT - || kind == ICAL_VTODO_COMPONENT - || kind == ICAL_VJOURNAL_COMPONENT) { - /* Create a temporary toplevel component and put the VEVENT - or VTODO in it, to simplify the code below. */ - icalcomp = toplevel_comp; - toplevel_comp = cal_util_new_top_level (); - icalcomponent_add_component (toplevel_comp, icalcomp); - } else if (kind != ICAL_VCALENDAR_COMPONENT) { - /* We don't support this type of component */ - icalcomponent_free (toplevel_comp); - return FALSE; - } - - /* The list of removed categories must be empty because we are about to - * start a new scanning process. - */ - g_assert (g_hash_table_size (priv->removed_categories) == 0); - - old_n_categories = g_hash_table_size (priv->categories); - - /* Step throught the VEVENT/VTODOs being added, create CalComponents - for them, and add them to our cache. */ - subcomp = icalcomponent_get_first_component (toplevel_comp, - ICAL_ANY_COMPONENT); - while (subcomp) { - /* We ignore anything except VEVENT, VTODO and VJOURNAL - components. */ - icalcomponent_kind child_kind = icalcomponent_isa (subcomp); - if (child_kind == ICAL_VEVENT_COMPONENT - || child_kind == ICAL_VTODO_COMPONENT - || child_kind == ICAL_VJOURNAL_COMPONENT) { - const char *comp_uid; - - comp_uid = cal_backend_file_update_object (cbfile, - subcomp); - if (comp_uid) { - /* We add a copy of the UID to a list, so we - can emit notification signals later. We do - a g_strdup() in case any of the components - get removed while we are emitting - notification signals. */ - comp_uid_list = g_list_prepend (comp_uid_list, - g_strdup (comp_uid)); - } else { - retval = FALSE; - } - } - subcomp = icalcomponent_get_next_component (toplevel_comp, - ICAL_ANY_COMPONENT); - } - - /* Merge the iCalendar components with our existing VCALENDAR, - resolving any conflicting TZIDs. */ - icalcomponent_merge_component (priv->icalcomp, toplevel_comp); - - new_n_categories = g_hash_table_size (priv->categories); - - mark_dirty (cbfile); - - /* Now emit notification signals for all of the added components. - We do this after adding them all to make sure the calendar is in a - stable state before emitting signals. */ - for (elem = comp_uid_list; elem; elem = elem->next) { - char *comp_uid = elem->data; - notify_update (cbfile, comp_uid); - g_free (comp_uid); - } - g_list_free (comp_uid_list); - - if (old_n_categories != new_n_categories || - g_hash_table_size (priv->removed_categories) != 0) { - clean_removed_categories (cbfile); - notify_categories_changed (cbfile); - } - - return retval; -} - - -/* 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; - - /* The list of removed categories must be empty because we are about to - * start a new scanning process. - */ - g_assert (g_hash_table_size (priv->removed_categories) == 0); - - remove_component (cbfile, comp); - - mark_dirty (cbfile); - - notify_remove (cbfile, uid); - - if (g_hash_table_size (priv->removed_categories) != 0) { - clean_removed_categories (cbfile); - notify_categories_changed (cbfile); - } - - return TRUE; -} - - -static icaltimezone* -cal_backend_file_get_timezone (CalBackend *backend, const char *tzid) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (priv->icalcomp != NULL, NULL); - - if (!strcmp (tzid, "UTC")) - return icaltimezone_get_utc_timezone (); - else - return icalcomponent_get_timezone (priv->icalcomp, tzid); -} - - -static icaltimezone* -cal_backend_file_get_default_timezone (CalBackend *backend) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (priv->icalcomp != NULL, NULL); - - return priv->default_zone; -} - - -static gboolean -cal_backend_file_set_default_timezone (CalBackend *backend, - const char *tzid) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - icaltimezone *zone; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (priv->icalcomp != NULL, FALSE); - - /* Look up the VTIMEZONE in our icalcomponent. */ - zone = icalcomponent_get_timezone (priv->icalcomp, tzid); - if (!zone) - return FALSE; - - /* Set the default timezone to it. */ - priv->default_zone = zone; - - return TRUE; -} - diff --git a/calendar/pcs/cal-backend-file.h b/calendar/pcs/cal-backend-file.h deleted file mode 100644 index c90feddea3..0000000000 --- a/calendar/pcs/cal-backend-file.h +++ /dev/null @@ -1,62 +0,0 @@ -/* Evolution calendar - iCalendar file backend - * - * Copyright (C) 2000 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#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-util.c b/calendar/pcs/cal-backend-util.c deleted file mode 100644 index 6ae480e30b..0000000000 --- a/calendar/pcs/cal-backend-util.c +++ /dev/null @@ -1,116 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Evolution calendar - generic backend class - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: Rodrigo Moya <rodrigo@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "cal-backend-util.h" - -void -cal_backend_util_fill_alarm_instances_seq (GNOME_Evolution_Calendar_CalAlarmInstanceSeq *seq, - GSList *alarms) -{ - int n_alarms; - GSList *l; - int i; - - g_return_if_fail (seq != NULL); - - 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_start = (long) instance->occur_start; - corba_instance->occur_end = (long) instance->occur_end; - } -} - -void -cal_backend_mail_account_get (Bonobo_ConfigDatabase db, - gint def, - char **address, - char **name) -{ - gchar *path; - - *address = NULL; - *name = NULL; - - /* get the identity info */ - path = g_strdup_printf ("/Mail/Accounts/identity_name_%d", def); - *name = bonobo_config_get_string (db, path, NULL); - g_free (path); - - path = g_strdup_printf ("/Mail/Accounts/identity_address_%d", def); - *address = bonobo_config_get_string (db, path, NULL); - g_free (path); -} - -gboolean -cal_backend_mail_account_get_default (Bonobo_ConfigDatabase db, - char **address, - char **name) -{ - glong def, len; - - *address = NULL; - *name = NULL; - - len = bonobo_config_get_long_with_default (db, "/Mail/Accounts/num", 0, NULL); - def = bonobo_config_get_long_with_default (db, "/Mail/Accounts/default_account", 0, NULL); - - if (def < len) - cal_backend_mail_account_get (db, def, address, name); - else - return FALSE; - - return TRUE; -} - -gboolean -cal_backend_mail_account_is_valid (Bonobo_ConfigDatabase db, char *user, char **name) -{ - gchar *address; - glong len, i; - - len = bonobo_config_get_long_with_default (db, "/Mail/Accounts/num", 0, NULL); - - for (i = 0; i < len; i++) { - cal_backend_mail_account_get (db, i, &address, name); - if (address != NULL && !strcmp (address, user)) { - g_free (address); - return TRUE; - } - g_free (address); - g_free (*name); - } - - return FALSE; -} diff --git a/calendar/pcs/cal-backend-util.h b/calendar/pcs/cal-backend-util.h deleted file mode 100644 index f10267453a..0000000000 --- a/calendar/pcs/cal-backend-util.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Evolution calendar - generic backend class - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: Rodrigo Moya <rodrigo@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef CAL_BACKEND_UTIL_H -#define CAL_BACKEND_UTIL_H - -#include <bonobo-conf/bonobo-config-database.h> -#include <cal-backend.h> - -BEGIN_GNOME_DECLS - -/* - * CORBA utility functions - */ - -void cal_backend_util_fill_alarm_instances_seq ( - GNOME_Evolution_Calendar_CalAlarmInstanceSeq *seq, GSList *alarms); - -/* - * Functions for accessing mail configuration - */ - -void cal_backend_mail_account_get (Bonobo_ConfigDatabase db, gint def, - char **address, char **name); -gboolean cal_backend_mail_account_get_default (Bonobo_ConfigDatabase db, - char **address, char **name); -gboolean cal_backend_mail_account_is_valid (Bonobo_ConfigDatabase db, - char *user, char **name); - -END_GNOME_DECLS - -#endif diff --git a/calendar/pcs/cal-backend.c b/calendar/pcs/cal-backend.c deleted file mode 100644 index 95dc9957e6..0000000000 --- a/calendar/pcs/cal-backend.c +++ /dev/null @@ -1,849 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Evolution calendar - generic backend class - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * JP Rosevear <jpr@ximian.com> - * Rodrigo Moya <rodrigo@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#include <config.h> -#include <gtk/gtkobject.h> -#include <gtk/gtksignal.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, - CAL_ADDED, - OPENED, - OBJ_UPDATED, - OBJ_REMOVED, - 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); - cal_backend_signals[CAL_ADDED] = - gtk_signal_new ("cal_added", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (CalBackendClass, cal_added), - gtk_marshal_NONE__POINTER, - GTK_TYPE_NONE, 1, - GTK_TYPE_POINTER); - cal_backend_signals[OPENED] = - gtk_signal_new ("opened", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (CalBackendClass, opened), - gtk_marshal_NONE__ENUM, - GTK_TYPE_NONE, 1, - GTK_TYPE_ENUM); - cal_backend_signals[OBJ_UPDATED] = - gtk_signal_new ("obj_updated", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (CalBackendClass, obj_updated), - gtk_marshal_NONE__STRING, - GTK_TYPE_NONE, 1, - GTK_TYPE_STRING); - cal_backend_signals[OBJ_REMOVED] = - gtk_signal_new ("obj_removed", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (CalBackendClass, obj_removed), - gtk_marshal_NONE__STRING, - GTK_TYPE_NONE, 1, - GTK_TYPE_STRING); - - gtk_object_class_add_signals (object_class, cal_backend_signals, LAST_SIGNAL); - - class->last_client_gone = NULL; - class->opened = NULL; - class->obj_updated = NULL; - class->obj_removed = NULL; - - class->get_uri = NULL; - class->open = NULL; - class->is_loaded = NULL; - class->get_query = NULL; - class->get_mode = NULL; - class->set_mode = NULL; - class->get_n_objects = NULL; - class->get_object = NULL; - class->get_object_component = NULL; - class->get_timezone_object = NULL; - class->get_uids = NULL; - class->get_objects_in_range = NULL; - class->get_free_busy = NULL; - class->get_changes = NULL; - class->get_alarms_in_range = NULL; - class->get_alarms_for_object = NULL; - class->update_objects = NULL; - class->remove_object = NULL; -} - - - -/** - * 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. - **/ -const char * -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); -} - -/* Callback used when a Cal is destroyed */ -static void -cal_destroy_cb (GtkObject *object, gpointer data) -{ - Cal *cal; - Cal *lcal; - CalBackend *backend; - GList *l; - - cal = CAL (object); - - backend = CAL_BACKEND (data); - - /* Find the cal in the list of clients */ - - for (l = backend->clients; l; l = l->next) { - lcal = CAL (l->data); - - if (lcal == cal) - break; - } - - g_assert (l != NULL); - - /* Disconnect */ - - backend->clients = g_list_remove_link (backend->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 (!backend->clients) - cal_backend_last_client_gone (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_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); - - backend->clients = g_list_prepend (backend->clients, cal); - - /* notify backend that a new Cal has been added */ - gtk_signal_emit (GTK_OBJECT (backend), - cal_backend_signals[CAL_ADDED], - cal); -} - -/** - * cal_backend_open: - * @backend: A calendar backend. - * @uristr: 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, const char *uristr, 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 (uristr != NULL, CAL_BACKEND_OPEN_ERROR); - - g_assert (CLASS (backend)->open != NULL); - result = (* CLASS (backend)->open) (backend, uristr, only_if_exists); - - return result; -} - -/** - * cal_backend_is_loaded: - * @backend: A calendar backend. - * - * Queries whether a calendar backend has been loaded yet. - * - * Return value: TRUE if the backend has been loaded with data, FALSE - * otherwise. - **/ -gboolean -cal_backend_is_loaded (CalBackend *backend) -{ - gboolean result; - - g_return_val_if_fail (backend != NULL, FALSE); - g_return_val_if_fail (IS_CAL_BACKEND (backend), FALSE); - - g_assert (CLASS (backend)->is_loaded != NULL); - result = (* CLASS (backend)->is_loaded) (backend); - - return result; -} - -/** - * cal_backend_get_query: - * @backend: A calendar backend. - * @ql: The query listener. - * @sexp: Search expression. - * - * Create a query object for this backend. - */ -Query * -cal_backend_get_query (CalBackend *backend, - GNOME_Evolution_Calendar_QueryListener ql, - const char *sexp) -{ - Query *result; - - g_return_val_if_fail (backend != NULL, FALSE); - g_return_val_if_fail (IS_CAL_BACKEND (backend), FALSE); - - if (CLASS (backend)->get_query != NULL) - result = (* CLASS (backend)->get_query) (backend, ql, sexp); - else - result = query_new (backend, ql, sexp); - - return result; -} - -/** - * cal_backend_get_mode: - * @backend: A calendar backend. - * - * Queries whether a calendar backend is connected remotely. - * - * Return value: The current mode the calendar is in - **/ -CalMode -cal_backend_get_mode (CalBackend *backend) -{ - CalMode result; - - g_return_val_if_fail (backend != NULL, FALSE); - g_return_val_if_fail (IS_CAL_BACKEND (backend), FALSE); - - g_assert (CLASS (backend)->get_mode != NULL); - result = (* CLASS (backend)->get_mode) (backend); - - return result; -} - - -/** - * cal_backend_set_mode: - * @backend: A calendar backend - * @mode: Mode to change to - * - * Sets the mode of the calendar - * - **/ -void -cal_backend_set_mode (CalBackend *backend, CalMode mode) -{ - g_return_if_fail (backend != NULL); - g_return_if_fail (IS_CAL_BACKEND (backend)); - - g_assert (CLASS (backend)->set_mode != NULL); - (* CLASS (backend)->set_mode) (backend, mode); -} - -/** - * 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. - **/ -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_object_component: - * @backend: A calendar backend. - * @uid: Unique identifier for a calendar object. - * - * Queries a calendar backend for a calendar object based on its unique - * identifier. It returns the CalComponent rather than the string - * representation. - * - * Return value: The CalComponent of the sought object, or NULL if no object - * had the specified UID. - **/ -CalComponent * -cal_backend_get_object_component (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_component != NULL); - return (* CLASS (backend)->get_object_component) (backend, uid); -} - -/** - * cal_backend_get_timezone_object: - * @backend: A calendar backend. - * @tzid: Unique identifier for a calendar VTIMEZONE object. - * - * Queries a calendar backend for a VTIMEZONE calendar object based on its - * unique TZID identifier. - * - * Return value: The string representation of a VTIMEZONE component, or NULL - * if no VTIMEZONE object had the specified TZID. - **/ -char * -cal_backend_get_timezone_object (CalBackend *backend, const char *tzid) -{ - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - g_return_val_if_fail (tzid != NULL, NULL); - - g_assert (CLASS (backend)->get_timezone_object != NULL); - return (* CLASS (backend)->get_timezone_object) (backend, tzid); -} - -/** - * cal_backend_get_type_by_uid - * @backend: A calendar backend. - * @uid: Unique identifier for a Calendar object. - * - * Returns the type of the object identified by the @uid argument - */ -CalObjType -cal_backend_get_type_by_uid (CalBackend *backend, const char *uid) -{ - icalcomponent *icalcomp; - char *comp_str; - CalObjType type = CAL_COMPONENT_NO_TYPE; - - g_return_val_if_fail (IS_CAL_BACKEND (backend), CAL_COMPONENT_NO_TYPE); - g_return_val_if_fail (uid != NULL, CAL_COMPONENT_NO_TYPE); - - comp_str = cal_backend_get_object (backend, uid); - if (!comp_str) - return CAL_COMPONENT_NO_TYPE; - - icalcomp = icalparser_parse_string (comp_str); - if (icalcomp) { - 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); - } - - g_free (comp_str); - - return type; -} - -/** - * 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_free_busy: - * @backend: A calendar backend. - * @users: List of users to get free/busy information for. - * @start: Start time for query. - * @end: End time for query. - * - * Gets a free/busy object for the given time interval - * - * Return value: a list of CalObj's - **/ -GList * -cal_backend_get_free_busy (CalBackend *backend, GList *users, 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_free_busy != NULL); - return (* CLASS (backend)->get_free_busy) (backend, users, 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_objects: - * @backend: A calendar backend. - * @calobj: String representation of the new calendar object(s). - * - * 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_objects (CalBackend *backend, 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 (calobj != NULL, FALSE); - - g_assert (CLASS (backend)->update_objects != NULL); - return (* CLASS (backend)->update_objects) (backend, 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]); -} - -/** - * cal_backend_opened: - * @backend: A calendar backend. - * @status: Open status code. - * - * Emits the "opened" signal of a calendar backend. This function is to be used - * only by backend implementations. - **/ -void -cal_backend_opened (CalBackend *backend, CalBackendOpenStatus status) -{ - g_return_if_fail (backend != NULL); - g_return_if_fail (IS_CAL_BACKEND (backend)); - - gtk_signal_emit (GTK_OBJECT (backend), cal_backend_signals[OPENED], - status); -} - -/** - * cal_backend_obj_updated: - * @backend: A calendar backend. - * @uid: Unique identifier of the component that was updated. - * - * Emits the "obj_updated" signal of a calendar backend. This function is to be - * used only by backend implementations. - **/ -void -cal_backend_obj_updated (CalBackend *backend, const char *uid) -{ - g_return_if_fail (backend != NULL); - g_return_if_fail (IS_CAL_BACKEND (backend)); - g_return_if_fail (uid != NULL); - - gtk_signal_emit (GTK_OBJECT (backend), cal_backend_signals[OBJ_UPDATED], - uid); -} - -/** - * cal_backend_obj_removed: - * @backend: A calendar backend. - * @uid: Unique identifier of the component that was removed. - * - * Emits the "obj_removed" signal of a calendar backend. This function is to be - * used only by backend implementations. - **/ -void -cal_backend_obj_removed (CalBackend *backend, const char *uid) -{ - g_return_if_fail (backend != NULL); - g_return_if_fail (IS_CAL_BACKEND (backend)); - g_return_if_fail (uid != NULL); - - gtk_signal_emit (GTK_OBJECT (backend), cal_backend_signals[OBJ_REMOVED], - uid); -} - - -/** - * cal_backend_get_timezone: - * @backend: A calendar backend. - * @tzid: Unique identifier of a VTIMEZONE object. Note that this must not be - * NULL. - * - * Returns the icaltimezone* corresponding to the TZID, or NULL if the TZID - * can't be found. - * - * Returns: The icaltimezone* corresponding to the given TZID, or NULL. - **/ -icaltimezone* -cal_backend_get_timezone (CalBackend *backend, const char *tzid) -{ - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - g_return_val_if_fail (tzid != NULL, NULL); - - g_assert (CLASS (backend)->get_timezone != NULL); - return (* CLASS (backend)->get_timezone) (backend, tzid); -} - - -/** - * cal_backend_get_default_timezone: - * @backend: A calendar backend. - * - * Returns the default timezone for the calendar, which is used to resolve - * DATE and floating DATE-TIME values. - * - * Returns: The default icaltimezone* for the calendar. - **/ -icaltimezone* -cal_backend_get_default_timezone (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_default_timezone != NULL); - return (* CLASS (backend)->get_default_timezone) (backend); -} - - -/** - * cal_backend_set_default_timezone: - * @backend: A calendar backend. - * @tzid: The TZID identifying the timezone. - * - * Sets the default timezone for the calendar, which is used to resolve - * DATE and floating DATE-TIME values. - * - * Returns: TRUE if the VTIMEZONE data for the timezone was found, or FALSE if - * not. - **/ -gboolean -cal_backend_set_default_timezone (CalBackend *backend, const char *tzid) -{ - g_return_val_if_fail (backend != NULL, FALSE); - g_return_val_if_fail (IS_CAL_BACKEND (backend), FALSE); - g_return_val_if_fail (tzid != NULL, FALSE); - - g_assert (CLASS (backend)->set_default_timezone != NULL); - return (* CLASS (backend)->set_default_timezone) (backend, tzid); -} - diff --git a/calendar/pcs/cal-backend.h b/calendar/pcs/cal-backend.h deleted file mode 100644 index 4fd0a42bd0..0000000000 --- a/calendar/pcs/cal-backend.h +++ /dev/null @@ -1,189 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Evolution calendar - generic backend class - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * Rodrigo Moya <rodrigo@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef CAL_BACKEND_H -#define CAL_BACKEND_H - -#include <libgnome/gnome-defs.h> -#include <cal-util/cal-util.h> -#include <cal-util/cal-component.h> -#include "evolution-calendar.h" -#include "cal-common.h" -#include "cal.h" -#include "query.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)) - -/* Open 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; - GList *clients; -}; - -struct _CalBackendClass { - GtkObjectClass parent_class; - - /* Notification signals */ - void (* last_client_gone) (CalBackend *backend); - void (* cal_added) (CalBackend *backend, Cal *cal); - - void (* opened) (CalBackend *backend, CalBackendOpenStatus status); - void (* obj_updated) (CalBackend *backend, const char *uid); - void (* obj_removed) (CalBackend *backend, const char *uid); - - /* Virtual methods */ - const char *(* get_uri) (CalBackend *backend); - - CalBackendOpenStatus (* open) (CalBackend *backend, const char *uristr, - gboolean only_if_exists); - - gboolean (* is_loaded) (CalBackend *backend); - - Query *(* get_query) (CalBackend *backend, - GNOME_Evolution_Calendar_QueryListener ql, - const char *sexp); - - /* Mode relate virtual methods */ - CalMode (* get_mode) (CalBackend *backend); - void (* set_mode) (CalBackend *backend, CalMode mode); - - /* General object acquirement and information related virtual methods */ - int (* get_n_objects) (CalBackend *backend, CalObjType type); - char *(* get_object) (CalBackend *backend, const char *uid); - CalComponent *(* get_object_component) (CalBackend *backend, const char *uid); - char *(* get_timezone_object) (CalBackend *backend, const char *tzid); - GList *(* get_uids) (CalBackend *backend, CalObjType type); - - GList *(* get_objects_in_range) (CalBackend *backend, CalObjType type, - time_t start, time_t end); - GList *(* get_free_busy) (CalBackend *backend, GList *users, 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_objects) (CalBackend *backend, const char *calobj); - gboolean (* remove_object) (CalBackend *backend, const char *uid); - - /* Timezone related virtual methods */ - icaltimezone *(* get_timezone) (CalBackend *backend, const char *tzid); - icaltimezone *(* get_default_timezone) (CalBackend *backend); - gboolean (* set_default_timezone) (CalBackend *backend, const char *tzid); -}; - -GtkType cal_backend_get_type (void); - -const char *cal_backend_get_uri (CalBackend *backend); - -void cal_backend_add_cal (CalBackend *backend, Cal *cal); - -CalBackendOpenStatus cal_backend_open (CalBackend *backend, const char *uristr, - gboolean only_if_exists); - -gboolean cal_backend_is_loaded (CalBackend *backend); - -Query *cal_backend_get_query (CalBackend *backend, - GNOME_Evolution_Calendar_QueryListener ql, - const char *sexp); - -CalMode cal_backend_get_mode (CalBackend *backend); -void cal_backend_set_mode (CalBackend *backend, CalMode mode); - -int cal_backend_get_n_objects (CalBackend *backend, CalObjType type); - -char *cal_backend_get_object (CalBackend *backend, const char *uid); - -CalComponent *cal_backend_get_object_component (CalBackend *backend, const char *uid); - -gboolean cal_backend_set_default_timezone (CalBackend *backend, const char *tzid); - -char *cal_backend_get_timezone_object (CalBackend *backend, const char *tzid); - -CalObjType cal_backend_get_type_by_uid (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); - -GList *cal_backend_get_free_busy (CalBackend *backend, GList *users, 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_objects (CalBackend *backend, const char *calobj); - -gboolean cal_backend_remove_object (CalBackend *backend, const char *uid); - -icaltimezone* cal_backend_get_timezone (CalBackend *backend, const char *tzid); -icaltimezone* cal_backend_get_default_timezone (CalBackend *backend); - -void cal_backend_last_client_gone (CalBackend *backend); -void cal_backend_opened (CalBackend *backend, CalBackendOpenStatus status); -void cal_backend_obj_updated (CalBackend *backend, const char *uid); -void cal_backend_obj_removed (CalBackend *backend, const char *uid); - - - -END_GNOME_DECLS - -#endif diff --git a/calendar/pcs/cal-common.h b/calendar/pcs/cal-common.h deleted file mode 100644 index 228a67fcfe..0000000000 --- a/calendar/pcs/cal-common.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Evolution calendar server - common declarations - * - * Copyright (C) 2000 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#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 1df133ea90..0000000000 --- a/calendar/pcs/cal-factory.c +++ /dev/null @@ -1,820 +0,0 @@ -/* Evolution calendar factory - * - * Copyright (C) 2000 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#include <config.h> -#include <ctype.h> -#include <stdio.h> -#include <gtk/gtksignal.h> -#include <liboaf/liboaf.h> -#include "e-util/e-url.h" -#include "evolution-calendar.h" -#include "cal.h" -#include "cal-backend.h" -#include "cal-factory.h" -#include "job.h" - -#define PARENT_TYPE BONOBO_X_OBJECT_TYPE -#define DEFAULT_CAL_FACTORY_OAF_ID "OAFIID:GNOME_Evolution_Wombat_CalendarFactory" - -static BonoboXObjectClass *parent_class; - -/* 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; - - /* OAFIID of the factory */ - char *iid; - - /* Whether we have been registered with OAF yet */ - guint registered : 1; -}; - -typedef struct -{ - CalFactory *factory; - GNOME_Evolution_Calendar_CalMode mode; - GNOME_Evolution_Calendar_StringSeq *list; -} CalFactoryUriData; - -/* Signal IDs */ -enum SIGNALS { - LAST_CALENDAR_GONE, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL]; - -/* 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) -{ - char *uri; - CalBackend *backend; - - uri = key; - backend = value; - - g_free (uri); - gtk_object_unref (GTK_OBJECT (backend)); -} - -/* Opening calendars */ - -/* Looks up a calendar backend in a factory's hash table of uri->cal. If - * *non-NULL, orig_uri_return will be set to point to the original key in the - * *hash table. - */ -static CalBackend * -lookup_backend (CalFactory *factory, const char *uristr, char **orig_uri_return) -{ - CalFactoryPrivate *priv; - EUri *uri; - char *tmp; - gboolean found; - gpointer orig_key; - gpointer data; - - priv = factory->priv; - - uri = e_uri_new (uristr); - if (!uri) { - if (orig_uri_return) - *orig_uri_return = NULL; - - return NULL; - } - - tmp = e_uri_to_string (uri, FALSE); - found = g_hash_table_lookup_extended (priv->backends, tmp, &orig_key, &data); - g_free (tmp); - e_uri_free (uri); - - if (found) { - if (orig_uri_return) - *orig_uri_return = orig_key; - - return CAL_BACKEND (data); - } else { - if (orig_uri_return) - *orig_uri_return = FALSE; - - return NULL; - } -} - -/* 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; - CalBackend *ret_backend; - const char *uristr; - char *orig_uristr; - - fprintf (stderr, "backend_last_client_gone_cb() called!\n"); - - factory = CAL_FACTORY (data); - priv = factory->priv; - - /* Remove the backend from the hash table */ - - uristr = cal_backend_get_uri (backend); - g_assert (uristr != NULL); - - ret_backend = lookup_backend (factory, uristr, &orig_uristr); - g_assert (ret_backend != NULL); - g_assert (ret_backend == backend); - - g_hash_table_remove (priv->backends, orig_uristr); - g_free (orig_uristr); - - 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), signals[LAST_CALENDAR_GONE]); -} - -/* Adds a backend to the calendar factory's hash table */ -static void -add_backend (CalFactory *factory, const char *uristr, CalBackend *backend) -{ - CalFactoryPrivate *priv; - EUri *uri; - char *tmp; - - priv = factory->priv; - - uri = e_uri_new (uristr); - if (!uri) - return; - - tmp = e_uri_to_string (uri, FALSE); - g_hash_table_insert (priv->backends, tmp, backend); - e_uri_free (uri); - - 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, - const char *uristr, - GNOME_Evolution_Calendar_Listener listener) -{ - CalFactoryPrivate *priv; - const char *method; - GtkType *type; - CalBackend *backend; - EUri *uri; - - priv = factory->priv; - - uri = e_uri_new (uristr); - if (!uri) - return NULL; - - method = uri->protocol; - type = g_hash_table_lookup (priv->methods, method); - e_uri_free (uri); - - 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, const char *uristr, 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, uristr, listener); - if (!backend) - return NULL; - - status = cal_backend_open (backend, uristr, only_if_exists); - - switch (status) { - case CAL_BACKEND_OPEN_SUCCESS: - add_backend (factory, uristr, 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_OBJREF (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); -} - -/* Add a uri to a string list */ -static void -add_uri (gpointer key, gpointer value, gpointer data) -{ - CalFactoryUriData *cfud = data; - CalFactory *factory = cfud->factory; - GNOME_Evolution_Calendar_StringSeq *list = cfud->list; - GNOME_Evolution_Calendar_CalMode mode = cfud->mode; - char *uri_string = key; - CalBackend *backend; - - switch (mode) { - case GNOME_Evolution_Calendar_MODE_LOCAL: - backend = lookup_backend (factory, uri_string, NULL); - if (backend == NULL || cal_backend_get_mode (backend) != CAL_MODE_LOCAL) - return; - break; - case GNOME_Evolution_Calendar_MODE_REMOTE: - backend = lookup_backend (factory, uri_string, NULL); - if (backend == NULL || cal_backend_get_mode (backend) != CAL_MODE_REMOTE) - return; - break; - case GNOME_Evolution_Calendar_MODE_ANY: - break; - } - - list->_buffer[list->_length] = CORBA_string_dup (uri_string); - list->_length++; -} - -/* 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; - gboolean only_if_exists; - GNOME_Evolution_Calendar_Listener listener; - CalBackend *backend; - CORBA_Environment ev; - char *uri_string; - - jd = data; - g_assert (jd->uri != NULL); - - /* Check the URI */ - uri_string = g_strdup (jd->uri); - g_free (jd->uri); - - only_if_exists = jd->only_if_exists; - factory = jd->factory; - listener = jd->listener; - g_free (jd); - - if (!uri_string) { - 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_string, NULL); - - if (!backend) - backend = open_backend (factory, uri_string, only_if_exists, listener); - - 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); -} - - - -static void -impl_CalFactory_open (PortableServer_Servant servant, - const CORBA_char *str_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; - GtkType *type; - EUri *uri; - - factory = CAL_FACTORY (bonobo_object_from_servant (servant)); - priv = factory->priv; - - /* check URI to see if we support it */ - - uri = e_uri_new (str_uri); - if (!uri) { - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_GNOME_Evolution_Calendar_CalFactory_InvalidURI, - NULL); - return; - } - - type = g_hash_table_lookup (priv->methods, uri->protocol); - - e_uri_free (uri); - if (!type) { - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_GNOME_Evolution_Calendar_CalFactory_UnsupportedMethod, - NULL); - return; - } - - /* duplicate the listener object */ - 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); - - /* add new asynchronous job */ - jd = g_new (OpenJobData, 1); - jd->factory = factory; - jd->uri = g_strdup (str_uri); - jd->only_if_exists = only_if_exists; - jd->listener = listener_copy; - - job_add (open_fn, jd); -} - -static GNOME_Evolution_Calendar_StringSeq * -impl_CalFactory_uriList (PortableServer_Servant servant, - GNOME_Evolution_Calendar_CalMode mode, - CORBA_Environment *ev) -{ - CalFactory *factory; - CalFactoryPrivate *priv; - CalFactoryUriData cfud; - GNOME_Evolution_Calendar_StringSeq *list; - - factory = CAL_FACTORY (bonobo_object_from_servant (servant)); - priv = factory->priv; - - list = GNOME_Evolution_Calendar_StringSeq__alloc (); - list->_length = 0; - list->_maximum = g_hash_table_size (priv->backends); - list->_buffer = CORBA_sequence_CORBA_string_allocbuf (list->_maximum); - - cfud.factory = factory; - cfud.mode = mode; - cfud.list = list; - g_hash_table_foreach (priv->backends, add_uri, &cfud); - - return list; - -} - - - -/** - * 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; - - factory = gtk_type_new (CAL_FACTORY_TYPE); - - return factory; -} - -/* 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) { - oaf_active_server_unregister (priv->iid, BONOBO_OBJREF (factory)); - priv->registered = FALSE; - } - g_free (priv->iid); - - g_free (priv); - factory->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - -/* Class initialization function for the calendar factory */ -static void -cal_factory_class_init (CalFactoryClass *klass) -{ - GtkObjectClass *object_class = (GtkObjectClass *) klass; - POA_GNOME_Evolution_Calendar_CalFactory__epv *epv = &klass->epv; - - parent_class = gtk_type_class (bonobo_object_get_type ()); - - 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, signals, LAST_SIGNAL); - - /* Class method overrides */ - object_class->destroy = cal_factory_destroy; - - /* Epv methods */ - epv->open = impl_CalFactory_open; - epv->uriList = impl_CalFactory_uriList; -} - -/* 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 (g_str_hash, g_str_equal); - priv->registered = FALSE; -} - -BONOBO_X_TYPE_FUNC_FULL (CalFactory, - GNOME_Evolution_Calendar_CalFactory, - PARENT_TYPE, - cal_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. - * @iid: OAFIID for the factory to be registered. - * - * 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, const char *iid) -{ - CalFactoryPrivate *priv; - OAF_RegistrationResult result; - char *tmp_iid; - - 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); - - /* if iid is NULL, use the default factory OAFIID */ - if (iid) - tmp_iid = g_strdup (iid); - else - tmp_iid = g_strdup (DEFAULT_CAL_FACTORY_OAF_ID); - - result = oaf_active_server_register (tmp_iid, BONOBO_OBJREF (factory)); - - switch (result) { - case OAF_REG_SUCCESS: - priv->registered = TRUE; - priv->iid = tmp_iid; - 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; - } - - g_free (tmp_iid); - - 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); -} - -/* Frees a uri/backend pair from the backends hash table */ -static void -dump_backend (gpointer key, gpointer value, gpointer data) -{ - char *uri; - CalBackend *backend; - - uri = key; - backend = value; - - g_message (" %s: %p", uri, backend); -} - -void -cal_factory_dump_active_backends (CalFactory *factory) -{ - CalFactoryPrivate *priv; - - g_message ("Active PCS backends"); - - priv = factory->priv; - g_hash_table_foreach (priv->backends, dump_backend, NULL); -} diff --git a/calendar/pcs/cal-factory.h b/calendar/pcs/cal-factory.h deleted file mode 100644 index 46a66ed9a0..0000000000 --- a/calendar/pcs/cal-factory.h +++ /dev/null @@ -1,73 +0,0 @@ -/* Evolution calendar factory - * - * 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef CAL_FACTORY_H -#define CAL_FACTORY_H - -#include <libgnome/gnome-defs.h> -#include <bonobo/bonobo-xobject.h> - -#include "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 { - BonoboXObject object; - - /* Private data */ - CalFactoryPrivate *priv; -}; - -struct _CalFactoryClass { - BonoboXObjectClass parent_class; - - POA_GNOME_Evolution_Calendar_CalFactory__epv epv; - - /* Notification signals */ - void (* last_calendar_gone) (CalFactory *factory); -}; - -GtkType cal_factory_get_type (void); -CalFactory *cal_factory_new (void); - -gboolean cal_factory_oaf_register (CalFactory *factory, const char *iid); -void cal_factory_register_method (CalFactory *factory, - const char *method, - GtkType backend_type); -int cal_factory_get_n_backends (CalFactory *factory); -void cal_factory_dump_active_backends (CalFactory *factory); - -END_GNOME_DECLS - -#endif diff --git a/calendar/pcs/cal.c b/calendar/pcs/cal.c deleted file mode 100644 index 5225b5680e..0000000000 --- a/calendar/pcs/cal.c +++ /dev/null @@ -1,871 +0,0 @@ -/* Evolution calendar client interface object - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * Rodrigo Moya <rodrigo@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#include <config.h> -#include <ical.h> -#include <bonobo/bonobo-exception.h> -#include "cal.h" -#include "cal-backend.h" -#include "query.h" -#include "wombat.h" - -#define PARENT_TYPE BONOBO_X_OBJECT_TYPE - -static BonoboXObjectClass *parent_class; - -/* Private part of the Cal structure */ -struct _CalPrivate { - /* Our backend */ - CalBackend *backend; - - /* Listener on the client we notify */ - GNOME_Evolution_Calendar_Listener listener; - - /* A reference to the WombatClient interface */ - GNOME_Evolution_WombatClient wombat_client; -}; - - -/* Cal::get_uri method */ -static CORBA_char * -impl_Cal_get_uri (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - const char *str_uri; - CORBA_char *str_uri_copy; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - str_uri = cal_backend_get_uri (priv->backend); - str_uri_copy = CORBA_string_dup (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)); -} - -static void -impl_Cal_set_mode (PortableServer_Servant servant, - GNOME_Evolution_Calendar_CalMode mode, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - cal_backend_set_mode (priv->backend, mode); -} - -/* Cal::get_n_objects method */ -static CORBA_long -impl_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 -impl_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 { - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_NotFound); - - 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 * -impl_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 * -impl_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 * -impl_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) { - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_InvalidRange); - 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; -} - -static GNOME_Evolution_Calendar_CalObjSeq * -build_fb_seq (GList *obj_list) -{ - GNOME_Evolution_Calendar_CalObjSeq *seq; - GList *l; - int n, i; - - n = g_list_length (obj_list); - - seq = GNOME_Evolution_Calendar_CalObjSeq__alloc (); - CORBA_sequence_set_release (seq, TRUE); - seq->_length = n; - seq->_buffer = CORBA_sequence_GNOME_Evolution_Calendar_CalObj_allocbuf (n); - - /* Fill the sequence */ - - for (i = 0, l = obj_list; l; i++, l = l->next) { - char *calobj; - - calobj = l->data; - seq->_buffer[i] = CORBA_string_dup (calobj); - } - - return seq; -} - -/* Cal::get_free_busy method */ -static GNOME_Evolution_Calendar_CalObjSeq * -impl_Cal_get_free_busy (PortableServer_Servant servant, - const GNOME_Evolution_Calendar_UserList *user_list, - const GNOME_Evolution_Calendar_Time_t start, - const GNOME_Evolution_Calendar_Time_t end, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - time_t t_start, t_end; - GList *users = NULL; - GList *obj_list; - GNOME_Evolution_Calendar_CalObjSeq *seq; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - t_start = (time_t) start; - t_end = (time_t) end; - - if (t_start > t_end || t_start == -1 || t_end == -1) { - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_InvalidRange); - return build_fb_seq (NULL); - } - - /* convert the CORBA user list to a GList */ - if (user_list) { - int i; - - for (i = 0; i < user_list->_length; i++) - users = g_list_append (users, user_list->_buffer[i]); - } - - /* call the backend's get_free_busy method */ - obj_list = cal_backend_get_free_busy (priv->backend, users, t_start, t_end); - seq = build_fb_seq (obj_list); - g_list_free (users); - - if (obj_list == NULL) - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_NotFound); - - return seq; -} - -/* Cal::get_alarms_in_range method */ -static GNOME_Evolution_Calendar_CalComponentAlarmsSeq * -impl_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) { - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_InvalidRange); - return NULL; - } - - if (!seq) { - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_NotFound); - return NULL; - } - - return seq; -} - -/* Cal::get_alarms_for_object method */ -static GNOME_Evolution_Calendar_CalComponentAlarms * -impl_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: - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_NotFound); - return NULL; - - case CAL_BACKEND_GET_ALARMS_INVALID_RANGE: - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_InvalidRange); - return NULL; - - default: - g_assert_not_reached (); - return NULL; - } -} - -/* Cal::update_objects method */ -static void -impl_Cal_update_objects (PortableServer_Servant servant, - 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_objects (priv->backend, calobj)) - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_InvalidObject); -} - -/* Cal::remove_object method */ -static void -impl_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)) - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_NotFound); -} - -/* Cal::getQuery implementation */ -static GNOME_Evolution_Calendar_Query -impl_Cal_get_query (PortableServer_Servant servant, - const CORBA_char *sexp, - GNOME_Evolution_Calendar_QueryListener ql, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - Query *query; - CORBA_Environment ev2; - GNOME_Evolution_Calendar_Query query_copy; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - query = cal_backend_get_query (priv->backend, ql, sexp); - if (!query) { - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_CouldNotCreate); - return CORBA_OBJECT_NIL; - } - - CORBA_exception_init (&ev2); - query_copy = CORBA_Object_duplicate (BONOBO_OBJREF (query), &ev2); - if (BONOBO_EX (&ev2)) { - CORBA_exception_free (&ev2); - g_message ("Cal_get_query(): Could not duplicate the query reference"); - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_CouldNotCreate); - return CORBA_OBJECT_NIL; - } - - CORBA_exception_free (&ev2); - - return query_copy; -} - -/* Cal::set_default_timezone method */ -static void -impl_Cal_set_default_timezone (PortableServer_Servant servant, - const GNOME_Evolution_Calendar_CalTimezoneObjUID tzid, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - gboolean zone_set; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - zone_set = cal_backend_set_default_timezone (priv->backend, tzid); - - if (!zone_set) { - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_NotFound); - } -} - -/* Cal::get_timezone_object method */ -static GNOME_Evolution_Calendar_CalObj -impl_Cal_get_timezone_object (PortableServer_Servant servant, - const GNOME_Evolution_Calendar_CalTimezoneObjUID tzid, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - char *calobj; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - calobj = cal_backend_get_timezone_object (priv->backend, tzid); - - if (calobj) { - CORBA_char *calobj_copy; - - calobj_copy = CORBA_string_dup (calobj); - g_free (calobj); - return calobj_copy; - } else { - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_NotFound); - return NULL; - } -} - -/** - * 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, - 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 (BONOBO_EX (&ev)) { - g_message ("cal_construct: could not duplicate the listener"); - priv->listener = CORBA_OBJECT_NIL; - CORBA_exception_free (&ev); - return NULL; - } - - CORBA_exception_free (&ev); - - /* obtain the WombatClient interface */ - CORBA_exception_init (&ev); - priv->wombat_client = Bonobo_Unknown_queryInterface ( - priv->listener, - "IDL:GNOME/Evolution/WombatClient:1.0", - &ev); - if (BONOBO_EX (&ev)) { - g_message ("cal_construct: could not get the WombatClient interface"); - priv->wombat_client = CORBA_OBJECT_NIL; - } - - CORBA_exception_free (&ev); - - priv->backend = backend; - - return cal; -} - -/** - * 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; - - 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)); - - retval = cal_construct (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; -} - -/* 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); - bonobo_object_release_unref (priv->listener, &ev); - if (BONOBO_EX (&ev)) - g_message ("cal_destroy(): could not release the listener"); - - priv->listener = NULL; - CORBA_exception_free (&ev); - - g_free (priv); - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - - -/* Class initialization function for the calendar */ -static void -cal_class_init (CalClass *klass) -{ - GtkObjectClass *object_class = (GtkObjectClass *) klass; - POA_GNOME_Evolution_Calendar_Cal__epv *epv = &klass->epv; - - parent_class = gtk_type_class (PARENT_TYPE); - - /* Class method overrides */ - object_class->destroy = cal_destroy; - - /* Epv methods */ - epv->_get_uri = impl_Cal_get_uri; - epv->setMode = impl_Cal_set_mode; - epv->countObjects = impl_Cal_get_n_objects; - epv->getObject = impl_Cal_get_object; - epv->setDefaultTimezone = impl_Cal_set_default_timezone; - epv->getTimezoneObject = impl_Cal_get_timezone_object; - epv->getUIDs = impl_Cal_get_uids; - epv->getChanges = impl_Cal_get_changes; - epv->getObjectsInRange = impl_Cal_get_objects_in_range; - epv->getFreeBusy = impl_Cal_get_free_busy; - epv->getAlarmsInRange = impl_Cal_get_alarms_in_range; - epv->getAlarmsForObject = impl_Cal_get_alarms_for_object; - epv->updateObjects = impl_Cal_update_objects; - epv->removeObject = impl_Cal_remove_object; - epv->getQuery = impl_Cal_get_query; -} - - -/* 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; -} - -BONOBO_X_TYPE_FUNC_FULL (Cal, GNOME_Evolution_Calendar_Cal, PARENT_TYPE, cal); - -/** - * cal_notify_mode: - * @cal: A calendar client interface. - * @status: Status of the mode set. - * @mode: The current mode. - * - * Notifys the listener of the results of a setMode call. - **/ -void -cal_notify_mode (Cal *cal, - GNOME_Evolution_Calendar_Listener_SetModeStatus status, - GNOME_Evolution_Calendar_CalMode mode) -{ - CalPrivate *priv; - CORBA_Environment ev; - - g_return_if_fail (cal != NULL); - g_return_if_fail (IS_CAL (cal)); - - priv = cal->priv; - g_return_if_fail (priv->listener != CORBA_OBJECT_NIL); - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_Listener_notifyCalSetMode (priv->listener, status, mode, &ev); - - if (BONOBO_EX (&ev)) - g_message ("cal_notify_mode(): could not notify the listener " - "about a mode change"); - - CORBA_exception_free (&ev); -} - -/** - * 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 (BONOBO_EX (&ev)) - 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 (BONOBO_EX (&ev)) - g_message ("cal_notify_remove(): could not notify the listener " - "about a removed object"); - - CORBA_exception_free (&ev); -} - -/** - * cal_notify_categories_changed: - * @cal: A calendar client interface. - * @categories: List of categories. - * - * Notifies a listener attached to a calendar client interface object about the - * current set of categories in a calendar backend. - **/ -void -cal_notify_categories_changed (Cal *cal, GNOME_Evolution_Calendar_StringSeq *categories) -{ - CalPrivate *priv; - CORBA_Environment ev; - - g_return_if_fail (cal != NULL); - g_return_if_fail (IS_CAL (cal)); - g_return_if_fail (categories != NULL); - - priv = cal->priv; - g_return_if_fail (priv->listener != CORBA_OBJECT_NIL); - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_Listener_notifyCategoriesChanged (priv->listener, categories, &ev); - - if (BONOBO_EX (&ev)) - g_message ("cal_notify_categories_changed(): Could not notify the listener " - "about the current set of categories"); - - CORBA_exception_free (&ev); -} - -/** - * cal_get_password: - * @cal: A calendar client interface. - * @prompt: The message to show to the user when asking for the password. - * @key: A key associated with the password being asked. - * - * Gets a password from the calendar client this Cal knows about. It does - * so by using the WombatClient interface being used by the corresponding - * CalClient. - * - * Returns: a password entered by the user. - */ -char * -cal_get_password (Cal *cal, const char *prompt, const char *key) -{ - CalPrivate *priv; - CORBA_Environment ev; - CORBA_char *pwd; - - g_return_val_if_fail (cal != NULL, NULL); - g_return_val_if_fail (IS_CAL (cal), NULL); - - priv = cal->priv; - g_return_val_if_fail (priv->wombat_client != CORBA_OBJECT_NIL, NULL); - - CORBA_exception_init (&ev); - pwd = GNOME_Evolution_WombatClient_getPassword ( - priv->wombat_client, - (const CORBA_char *) prompt, - (const CORBA_char *) key, - &ev); - if (BONOBO_EX (&ev)) { - g_message ("cal_get_password: could not get password from associated WombatClient"); - CORBA_exception_free (&ev); - return NULL; - } - - CORBA_exception_free (&ev); - - return pwd; -} - -/** - * cal_forget_password: - * @cal: A calendar client interface. - * @key: A key associated with the password to be forgotten. - * - * Notifies the associated calendar client that it should forget - * about the password identified by @key, so that next time the backend - * asks the client about it, the client would ask again the user for it. - * This is done in cases where the password supplied the first time - * was not a valid password and the backend needs the user to enter - * a new one. - */ -void -cal_forget_password (Cal *cal, const char *key) -{ - CalPrivate *priv; - CORBA_Environment ev; - - g_return_if_fail (cal != NULL); - g_return_if_fail (IS_CAL (cal)); - - priv = cal->priv; - g_return_if_fail (priv->wombat_client != CORBA_OBJECT_NIL); - - CORBA_exception_init (&ev); - GNOME_Evolution_WombatClient_forgetPassword ( - priv->wombat_client, - (const CORBA_char *) key, - &ev); - - if (BONOBO_EX (&ev)) { - g_message ("cal_forget_password: could not notify WombatClient about " - "password to be forgotten"); - } - - CORBA_exception_free (&ev); -} diff --git a/calendar/pcs/cal.h b/calendar/pcs/cal.h deleted file mode 100644 index 81c3e55154..0000000000 --- a/calendar/pcs/cal.h +++ /dev/null @@ -1,79 +0,0 @@ -/* Evolution calendar client interface object - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * Rodrigo Moya <rodrigo@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef CAL_H -#define CAL_H - -#include <libgnome/gnome-defs.h> -#include <bonobo/bonobo-xobject.h> -#include "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 { - BonoboXObject object; - - /* Private data */ - CalPrivate *priv; -}; - -struct _CalClass { - BonoboXObjectClass parent_class; - - POA_GNOME_Evolution_Calendar_Cal__epv epv; -}; - -GtkType cal_get_type (void); - -Cal *cal_construct (Cal *cal, - CalBackend *backend, - GNOME_Evolution_Calendar_Listener listener); - -Cal *cal_new (CalBackend *backend, GNOME_Evolution_Calendar_Listener listener); - -void cal_notify_mode (Cal *cal, - GNOME_Evolution_Calendar_Listener_SetModeStatus status, - GNOME_Evolution_Calendar_CalMode mode); -void cal_notify_update (Cal *cal, const char *uid); -void cal_notify_remove (Cal *cal, const char *uid); - -void cal_notify_categories_changed (Cal *cal, GNOME_Evolution_Calendar_StringSeq *categories); - -char *cal_get_password (Cal *cal, const char *prompt, const char *key); -void cal_forget_password (Cal *cal, const char *key); - - - -END_GNOME_DECLS - -#endif diff --git a/calendar/pcs/job.c b/calendar/pcs/job.c deleted file mode 100644 index 584f1a6f38..0000000000 --- a/calendar/pcs/job.c +++ /dev/null @@ -1,98 +0,0 @@ -/* GNOME personal calendar server - job manager - * - * Copyright (C) 2000 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#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 07e3371f89..0000000000 --- a/calendar/pcs/job.h +++ /dev/null @@ -1,35 +0,0 @@ -/* GNOME personal calendar server - job manager - * - * Copyright (C) 2000 Ximian, 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef JOB_H -#define JOB_H - -#include <glib.h> - - - -typedef void (* JobFunc) (gpointer data); - -void job_add (JobFunc func, gpointer data); - - - -#endif diff --git a/calendar/pcs/query.c b/calendar/pcs/query.c deleted file mode 100644 index 2006157e58..0000000000 --- a/calendar/pcs/query.c +++ /dev/null @@ -1,1449 +0,0 @@ -/* Evolution calendar - Live search query implementation - * - * Copyright (C) 2001 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <glib.h> -#include <gtk/gtkmain.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <gtk/gtksignal.h> -#include <bonobo/bonobo-exception.h> -#include <gal/widgets/e-unicode.h> -#include <e-util/e-sexp.h> -#include <cal-util/cal-recur.h> -#include <cal-util/timeutil.h> -#include "cal-backend.h" -#include "query.h" - - - -/* States of a query */ -typedef enum { - QUERY_WAIT_FOR_BACKEND, /* the query is not populated and the backend is not loaded */ - QUERY_START_PENDING, /* the query is not populated yet, but the backend is loaded */ - QUERY_IN_PROGRESS, /* the query is populated; components are still being processed */ - QUERY_DONE, /* the query is done, but still accepts object changes */ - QUERY_PARSE_ERROR /* a parse error occurred when initially creating the ESexp */ -} QueryState; - -/* Private part of the Query structure */ -struct _QueryPrivate { - /* The backend we are monitoring */ - CalBackend *backend; - - /* The default timezone for the calendar. */ - icaltimezone *default_zone; - - /* Listener to which we report changes in the live query */ - GNOME_Evolution_Calendar_QueryListener ql; - - /* Sexp that defines the query */ - char *sexp; - ESExp *esexp; - - /* Timeout handler ID for asynchronous queries and current state of the query */ - guint timeout_id; - QueryState state; - - /* List of UIDs that we still have to process */ - GList *pending_uids; - int n_pending; - int pending_total; - - /* Table of the UIDs we know do match the query */ - GHashTable *uids; - - /* The next component that will be handled in e_sexp_eval(); put here - * just because the query object itself is the esexp context. - */ - CalComponent *next_comp; -}; - - - -static void query_class_init (QueryClass *class); -static void query_init (Query *query); -static void query_destroy (GtkObject *object); - -static BonoboXObjectClass *parent_class; - - - -BONOBO_X_TYPE_FUNC_FULL (Query, - GNOME_Evolution_Calendar_Query, - BONOBO_X_OBJECT_TYPE, - query); - -/* Class initialization function for the live search query */ -static void -query_class_init (QueryClass *class) -{ - GtkObjectClass *object_class; - - object_class = (GtkObjectClass *) class; - - parent_class = gtk_type_class (BONOBO_X_OBJECT_TYPE); - - object_class->destroy = query_destroy; - - /* The Query interface (ha ha! query interface!) has no methods, so we - * don't need to fiddle with the epv. - */ -} - -/* Object initialization function for the live search query */ -static void -query_init (Query *query) -{ - QueryPrivate *priv; - - priv = g_new0 (QueryPrivate, 1); - query->priv = priv; - - priv->backend = NULL; - priv->default_zone = NULL; - priv->ql = CORBA_OBJECT_NIL; - priv->sexp = NULL; - - priv->timeout_id = 0; - priv->state = QUERY_WAIT_FOR_BACKEND; - - priv->pending_uids = NULL; - priv->uids = g_hash_table_new (g_str_hash, g_str_equal); - - priv->next_comp = NULL; -} - -/* Used from g_hash_table_foreach(); frees a UID */ -static void -free_uid_cb (gpointer key, gpointer value, gpointer data) -{ - char *uid; - - uid = key; - g_free (uid); -} - -/* Destroy handler for the live search query */ -static void -query_destroy (GtkObject *object) -{ - Query *query; - QueryPrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_QUERY (object)); - - query = QUERY (object); - priv = query->priv; - - if (priv->backend) { - /* If we are waiting for the backend to be opened, we'll be - * connected to its "opened" signal. If we are in the middle of - * a query or if we are just waiting for object update - * notifications, we'll have the "obj_removed" and "obj_updated" - * connections. Otherwise, we are either in a parse error state - * or waiting for the query to be populated, and in both cases - * we have no signal connections. - */ - if (priv->state == QUERY_WAIT_FOR_BACKEND - || priv->state == QUERY_IN_PROGRESS || priv->state == QUERY_DONE) - gtk_signal_disconnect_by_data (GTK_OBJECT (priv->backend), query); - - gtk_object_unref (GTK_OBJECT (priv->backend)); - priv->backend = NULL; - } - - if (priv->ql != CORBA_OBJECT_NIL) { - CORBA_Environment ev; - - CORBA_exception_init (&ev); - bonobo_object_release_unref (priv->ql, &ev); - - if (BONOBO_EX (&ev)) - g_message ("query_destroy(): Could not unref the listener\n"); - - CORBA_exception_free (&ev); - - priv->ql = CORBA_OBJECT_NIL; - } - - if (priv->sexp) { - g_free (priv->sexp); - priv->sexp = NULL; - } - - if (priv->esexp) { - e_sexp_unref (priv->esexp); - priv->esexp = NULL; - } - - if (priv->timeout_id) { - g_source_remove (priv->timeout_id); - priv->timeout_id = 0; - } - - if (priv->pending_uids) { - GList *l; - - for (l = priv->pending_uids; l; l = l->next) { - char *uid; - - uid = l->data; - g_assert (uid != NULL); - g_free (uid); - } - - g_list_free (priv->pending_uids); - priv->pending_uids = NULL; - priv->n_pending = 0; - } - - g_hash_table_foreach (priv->uids, free_uid_cb, NULL); - g_hash_table_destroy (priv->uids); - priv->uids = NULL; - - g_free (priv); - query->priv = NULL; - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); -} - - - -/* E-Sexp functions */ - -/* (time-now) - * - * Returns a time_t of time (NULL). - */ -static ESExpResult * -func_time_now (ESExp *esexp, int argc, ESExpResult **argv, void *data) -{ - ESExpResult *result; - - if (argc != 0) { - e_sexp_fatal_error (esexp, _("time-now expects 0 arguments")); - return NULL; - } - - result = e_sexp_result_new (esexp, ESEXP_RES_TIME); - result->value.time = time (NULL); - - return result; -} - -/* (make-time ISODATE) - * - * ISODATE - string, ISO 8601 date/time representation - * - * Constructs a time_t value for the specified date. - */ -static ESExpResult * -func_make_time (ESExp *esexp, int argc, ESExpResult **argv, void *data) -{ - const char *str; - time_t t; - ESExpResult *result; - - if (argc != 1) { - e_sexp_fatal_error (esexp, _("make-time expects 1 argument")); - return NULL; - } - - if (argv[0]->type != ESEXP_RES_STRING) { - e_sexp_fatal_error (esexp, _("make-time expects argument 1 " - "to be a string")); - return NULL; - } - str = argv[0]->value.string; - - t = time_from_isodate (str); - if (t == -1) { - e_sexp_fatal_error (esexp, _("make-time argument 1 must be an " - "ISO 8601 date/time string")); - return NULL; - } - - result = e_sexp_result_new (esexp, ESEXP_RES_TIME); - result->value.time = t; - - return result; -} - -/* (time-add-day TIME N) - * - * TIME - time_t, base time - * N - int, number of days to add - * - * Adds the specified number of days to a time value. - * - * FIXME: TIMEZONES - need to use a timezone or daylight saving changes will - * make the result incorrect. - */ -static ESExpResult * -func_time_add_day (ESExp *esexp, int argc, ESExpResult **argv, void *data) -{ - ESExpResult *result; - time_t t; - int n; - - if (argc != 2) { - e_sexp_fatal_error (esexp, _("time-add-day expects 2 arguments")); - return NULL; - } - - if (argv[0]->type != ESEXP_RES_TIME) { - e_sexp_fatal_error (esexp, _("time-add-day expects argument 1 " - "to be a time_t")); - return NULL; - } - t = argv[0]->value.time; - - if (argv[1]->type != ESEXP_RES_INT) { - e_sexp_fatal_error (esexp, _("time-add-day expects argument 2 " - "to be an integer")); - return NULL; - } - n = argv[1]->value.number; - - result = e_sexp_result_new (esexp, ESEXP_RES_TIME); - result->value.time = time_add_day (t, n); - - return result; -} - -/* (time-day-begin TIME) - * - * TIME - time_t, base time - * - * Returns the start of the day, according to the local time. - * - * FIXME: TIMEZONES - this uses the current Unix timezone. - */ -static ESExpResult * -func_time_day_begin (ESExp *esexp, int argc, ESExpResult **argv, void *data) -{ - time_t t; - ESExpResult *result; - - if (argc != 1) { - e_sexp_fatal_error (esexp, _("time-day-begin expects 1 argument")); - return NULL; - } - - if (argv[0]->type != ESEXP_RES_TIME) { - e_sexp_fatal_error (esexp, _("time-day-begin expects argument 1 " - "to be a time_t")); - return NULL; - } - t = argv[0]->value.time; - - result = e_sexp_result_new (esexp, ESEXP_RES_TIME); - result->value.time = time_day_begin (t); - - return result; -} - -/* (time-day-end TIME) - * - * TIME - time_t, base time - * - * Returns the end of the day, according to the local time. - * - * FIXME: TIMEZONES - this uses the current Unix timezone. - */ -static ESExpResult * -func_time_day_end (ESExp *esexp, int argc, ESExpResult **argv, void *data) -{ - time_t t; - ESExpResult *result; - - if (argc != 1) { - e_sexp_fatal_error (esexp, _("time-day-end expects 1 argument")); - return NULL; - } - - if (argv[0]->type != ESEXP_RES_TIME) { - e_sexp_fatal_error (esexp, _("time-day-end expects argument 1 " - "to be a time_t")); - return NULL; - } - t = argv[0]->value.time; - - result = e_sexp_result_new (esexp, ESEXP_RES_TIME); - result->value.time = time_day_end (t); - - return result; -} - -/* (get-vtype) - * - * Returns a string indicating the type of component (VEVENT, VTODO, VJOURNAL, - * VFREEBUSY, VTIMEZONE, UNKNOWN). - */ -static ESExpResult * -func_get_vtype (ESExp *esexp, int argc, ESExpResult **argv, void *data) -{ - Query *query; - QueryPrivate *priv; - CalComponent *comp; - CalComponentVType vtype; - char *str; - ESExpResult *result; - - query = QUERY (data); - priv = query->priv; - - g_assert (priv->next_comp != NULL); - comp = priv->next_comp; - - /* Check argument types */ - - if (argc != 0) { - e_sexp_fatal_error (esexp, _("get-vtype expects 0 arguments")); - return NULL; - } - - /* Get the type */ - - vtype = cal_component_get_vtype (comp); - - switch (vtype) { - case CAL_COMPONENT_EVENT: - str = g_strdup ("VEVENT"); - break; - - case CAL_COMPONENT_TODO: - str = g_strdup ("VTODO"); - break; - - case CAL_COMPONENT_JOURNAL: - str = g_strdup ("VJOURNAL"); - break; - - case CAL_COMPONENT_FREEBUSY: - str = g_strdup ("VFREEBUSY"); - break; - - case CAL_COMPONENT_TIMEZONE: - str = g_strdup ("VTIMEZONE"); - break; - - default: - str = g_strdup ("UNKNOWN"); - break; - } - - result = e_sexp_result_new (esexp, ESEXP_RES_STRING); - result->value.string = str; - - return result; -} - -/* Sets a boolean value in the data to TRUE; called from - * cal_recur_generate_instances() to indicate that at least one instance occurs - * in the sought time range. We always return FALSE because we want the - * recurrence engine to finish as soon as possible. - */ -static gboolean -instance_occur_cb (CalComponent *comp, time_t start, time_t end, gpointer data) -{ - gboolean *occurs; - - occurs = data; - *occurs = TRUE; - - return FALSE; -} - -/* Call the backend function to get a timezone from a TZID. */ -static icaltimezone* -resolve_tzid (const char *tzid, gpointer data) -{ - Query *query = data; - - if (!tzid || !tzid[0]) - return NULL; - else - return cal_backend_get_timezone (query->priv->backend, tzid); -} - - -/* (occur-in-time-range? START END) - * - * START - time_t, start of the time range - * END - time_t, end of the time range - * - * Returns a boolean indicating whether the component has any occurrences in the - * specified time range. - */ -static ESExpResult * -func_occur_in_time_range (ESExp *esexp, int argc, ESExpResult **argv, void *data) -{ - Query *query; - QueryPrivate *priv; - CalComponent *comp; - time_t start, end; - gboolean occurs; - ESExpResult *result; - - query = QUERY (data); - priv = query->priv; - - g_assert (priv->next_comp != NULL); - comp = priv->next_comp; - - /* Check argument types */ - - if (argc != 2) { - e_sexp_fatal_error (esexp, _("occur-in-time-range? expects 2 arguments")); - return NULL; - } - - if (argv[0]->type != ESEXP_RES_TIME) { - e_sexp_fatal_error (esexp, _("occur-in-time-range? expects argument 1 " - "to be a time_t")); - return NULL; - } - start = argv[0]->value.time; - - if (argv[1]->type != ESEXP_RES_TIME) { - e_sexp_fatal_error (esexp, _("occur-in-time-range? expects argument 2 " - "to be a time_t")); - return NULL; - } - end = argv[1]->value.time; - - /* See if there is at least one instance in that range */ - - occurs = FALSE; - - cal_recur_generate_instances (comp, start, end, - instance_occur_cb, &occurs, - resolve_tzid, query, priv->default_zone); - - result = e_sexp_result_new (esexp, ESEXP_RES_BOOL); - result->value.bool = occurs; - - return result; -} - -/* Returns whether a list of CalComponentText items matches the specified string */ -static gboolean -matches_text_list (GSList *text_list, const char *str) -{ - GSList *l; - gboolean matches; - - matches = FALSE; - - for (l = text_list; l; l = l->next) { - CalComponentText *text; - - text = l->data; - g_assert (text->value != NULL); - - if (e_utf8_strstrcasedecomp (text->value, str) != NULL) { - matches = TRUE; - break; - } - } - - return matches; -} - -/* Returns whether the comments in a component matches the specified string */ -static gboolean -matches_comment (CalComponent *comp, const char *str) -{ - GSList *list; - gboolean matches; - - cal_component_get_comment_list (comp, &list); - matches = matches_text_list (list, str); - cal_component_free_text_list (list); - - return matches; -} - -/* Returns whether the description in a component matches the specified string */ -static gboolean -matches_description (CalComponent *comp, const char *str) -{ - GSList *list; - gboolean matches; - - cal_component_get_description_list (comp, &list); - matches = matches_text_list (list, str); - cal_component_free_text_list (list); - - return matches; -} - -/* Returns whether the summary in a component matches the specified string */ -static gboolean -matches_summary (CalComponent *comp, const char *str) -{ - CalComponentText text; - - cal_component_get_summary (comp, &text); - - if (!text.value) - return FALSE; - - return e_utf8_strstrcasedecomp (text.value, str) != NULL; -} - -/* Returns whether any text field in a component matches the specified string */ -static gboolean -matches_any (CalComponent *comp, const char *str) -{ - /* As an optimization, and to make life easier for the individual - * predicate functions, see if we are looking for the empty string right - * away. - */ - if (strlen (str) == 0) - return TRUE; - - return (matches_comment (comp, str) - || matches_description (comp, str) - || matches_summary (comp, str)); -} - -/* (contains? FIELD STR) - * - * FIELD - string, name of field to match (any, comment, description, summary) - * STR - string, match string - * - * Returns a boolean indicating whether the specified field contains the - * specified string. - */ -static ESExpResult * -func_contains (ESExp *esexp, int argc, ESExpResult **argv, void *data) -{ - Query *query; - QueryPrivate *priv; - CalComponent *comp; - const char *field; - const char *str; - gboolean matches; - ESExpResult *result; - - query = QUERY (data); - priv = query->priv; - - g_assert (priv->next_comp != NULL); - comp = priv->next_comp; - - /* Check argument types */ - - if (argc != 2) { - e_sexp_fatal_error (esexp, _("contains? expects 2 arguments")); - return NULL; - } - - if (argv[0]->type != ESEXP_RES_STRING) { - e_sexp_fatal_error (esexp, _("contains? expects argument 1 " - "to be a string")); - return NULL; - } - field = argv[0]->value.string; - - if (argv[1]->type != ESEXP_RES_STRING) { - e_sexp_fatal_error (esexp, _("contains? expects argument 2 " - "to be a string")); - return NULL; - } - str = argv[1]->value.string; - - /* See if it matches */ - - if (strcmp (field, "any") == 0) - matches = matches_any (comp, str); - else if (strcmp (field, "comment") == 0) - matches = matches_comment (comp, str); - else if (strcmp (field, "description") == 0) - matches = matches_description (comp, str); - else if (strcmp (field, "summary") == 0) - matches = matches_summary (comp, str); - else { - e_sexp_fatal_error (esexp, _("contains? expects argument 1 to " - "be one of \"any\", \"summary\", \"description\"")); - return NULL; - } - - result = e_sexp_result_new (esexp, ESEXP_RES_BOOL); - result->value.bool = matches; - - return result; -} - -/* (has-categories? STR+) - * (has-categories? #f) - * - * STR - At least one string specifying a category - * Or you can specify a single #f (boolean false) value for components - * that have no categories assigned to them ("unfiled"). - * - * Returns a boolean indicating whether the component has all the specified - * categories. - */ -static ESExpResult * -func_has_categories (ESExp *esexp, int argc, ESExpResult **argv, void *data) -{ - Query *query; - QueryPrivate *priv; - CalComponent *comp; - gboolean unfiled; - int i; - GSList *categories; - gboolean matches; - ESExpResult *result; - - query = QUERY (data); - priv = query->priv; - - g_assert (priv->next_comp != NULL); - comp = priv->next_comp; - - /* Check argument types */ - - if (argc < 1) { - e_sexp_fatal_error (esexp, _("has-categories? expects at least 1 argument")); - return NULL; - } - - if (argc == 1 && argv[0]->type == ESEXP_RES_BOOL) - unfiled = TRUE; - else - unfiled = FALSE; - - if (!unfiled) - for (i = 0; i < argc; i++) - if (argv[i]->type != ESEXP_RES_STRING) { - e_sexp_fatal_error (esexp, _("has-categories? expects all arguments " - "to be strings or one and only one " - "argument to be a boolean false (#f)")); - return NULL; - } - - /* Search categories. First, if there are no categories we return - * whether unfiled components are supposed to match. - */ - - cal_component_get_categories_list (comp, &categories); - if (!categories) { - result = e_sexp_result_new (esexp, ESEXP_RES_BOOL); - result->value.bool = unfiled; - - return result; - } - - /* Otherwise, we *do* have categories but unfiled components were - * requested, so this component does not match. - */ - if (unfiled) { - result = e_sexp_result_new (esexp, ESEXP_RES_BOOL); - result->value.bool = FALSE; - - return result; - } - - matches = TRUE; - - for (i = 0; i < argc; i++) { - const char *sought; - GSList *l; - gboolean has_category; - - sought = argv[i]->value.string; - - has_category = FALSE; - - for (l = categories; l; l = l->next) { - const char *category; - - category = l->data; - - if (strcmp (category, sought) == 0) { - has_category = TRUE; - break; - } - } - - if (!has_category) { - matches = FALSE; - break; - } - } - - cal_component_free_categories_list (categories); - - result = e_sexp_result_new (esexp, ESEXP_RES_BOOL); - result->value.bool = matches; - - return result; -} - -/* (is-completed?) - * - * Returns a boolean indicating whether the component is completed (i.e. has - * a COMPLETED property. This is really only useful for TODO components. - */ -static ESExpResult * -func_is_completed (ESExp *esexp, int argc, ESExpResult **argv, void *data) -{ - Query *query; - QueryPrivate *priv; - CalComponent *comp; - ESExpResult *result; - struct icaltimetype *t; - gboolean complete = FALSE; - - query = QUERY (data); - priv = query->priv; - - g_assert (priv->next_comp != NULL); - comp = priv->next_comp; - - /* Check argument types */ - - if (argc != 0) { - e_sexp_fatal_error (esexp, _("is-completed? expects 0 arguments")); - return NULL; - } - - cal_component_get_completed (comp, &t); - if (t) { - complete = TRUE; - cal_component_free_icaltimetype (t); - } - - result = e_sexp_result_new (esexp, ESEXP_RES_BOOL); - result->value.bool = complete; - - return result; -} - -/* (completed-before? TIME) - * - * TIME - time_t - * - * Returns a boolean indicating whether the component was completed on or - * before the given time (i.e. it checks the COMPLETED property). - * This is really only useful for TODO components. - */ -static ESExpResult * -func_completed_before (ESExp *esexp, int argc, ESExpResult **argv, void *data) -{ - Query *query; - QueryPrivate *priv; - CalComponent *comp; - ESExpResult *result; - struct icaltimetype *tt; - icaltimezone *zone; - gboolean retval = FALSE; - time_t before_time, completed_time; - - query = QUERY (data); - priv = query->priv; - - g_assert (priv->next_comp != NULL); - comp = priv->next_comp; - - /* Check argument types */ - - if (argc != 1) { - e_sexp_fatal_error (esexp, _("completed-before? expects 1 argument")); - return NULL; - } - - if (argv[0]->type != ESEXP_RES_TIME) { - e_sexp_fatal_error (esexp, _("completed-before? expects argument 1 " - "to be a time_t")); - return NULL; - } - before_time = argv[0]->value.time; - - cal_component_get_completed (comp, &tt); - if (tt) { - /* COMPLETED must be in UTC. */ - zone = icaltimezone_get_utc_timezone (); - completed_time = icaltime_as_timet_with_zone (*tt, zone); - -#if 0 - g_print ("Query Time : %s", ctime (&before_time)); - g_print ("Completed Time: %s", ctime (&completed_time)); -#endif - - /* We want to return TRUE if before_time is after - completed_time. */ - if (difftime (before_time, completed_time) > 0) { -#if 0 - g_print (" Returning TRUE\n"); -#endif - retval = TRUE; - } - - cal_component_free_icaltimetype (tt); - } - - result = e_sexp_result_new (esexp, ESEXP_RES_BOOL); - result->value.bool = retval; - - return result; -} - - - -/* Adds a component to our the UIDs hash table and notifies the client */ -static void -add_component (Query *query, const char *uid, gboolean query_in_progress, int n_scanned, int total) -{ - QueryPrivate *priv; - char *old_uid; - CORBA_Environment ev; - - if (query_in_progress) - g_assert (n_scanned > 0 || n_scanned <= total); - - priv = query->priv; - - if (g_hash_table_lookup_extended (priv->uids, uid, (gpointer *) &old_uid, NULL)) { - g_hash_table_remove (priv->uids, old_uid); - g_free (old_uid); - } - - g_hash_table_insert (priv->uids, g_strdup (uid), NULL); - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_QueryListener_notifyObjUpdated ( - priv->ql, - (char *) uid, - query_in_progress, - n_scanned, - total, - &ev); - - if (BONOBO_EX (&ev)) - g_message ("add_component(): Could not notify the listener of an " - "updated component"); - - CORBA_exception_free (&ev); -} - -/* Removes a component from our the UIDs hash table and notifies the client */ -static void -remove_component (Query *query, const char *uid) -{ - QueryPrivate *priv; - char *old_uid; - CORBA_Environment ev; - - priv = query->priv; - - if (!g_hash_table_lookup_extended (priv->uids, uid, (gpointer *) &old_uid, NULL)) - return; - - /* The component did match the query before but it no longer does, so we - * have to notify the client. - */ - - g_hash_table_remove (priv->uids, old_uid); - g_free (old_uid); - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_QueryListener_notifyObjRemoved ( - priv->ql, - (char *) uid, - &ev); - - if (BONOBO_EX (&ev)) - g_message ("remove_component(): Could not notify the listener of a " - "removed component"); - - CORBA_exception_free (&ev); -} - -/* Removes a component from the list of pending UIDs */ -static void -remove_from_pending (Query *query, const char *remove_uid) -{ - QueryPrivate *priv; - GList *l; - - priv = query->priv; - - for (l = priv->pending_uids; l; l = l->next) { - char *uid; - - g_assert (priv->n_pending > 0); - - uid = l->data; - if (strcmp (remove_uid, uid)) - continue; - - g_free (uid); - - priv->pending_uids = g_list_remove_link (priv->pending_uids, l); - g_list_free_1 (l); - priv->n_pending--; - - g_assert ((priv->pending_uids && priv->n_pending != 0) - || (!priv->pending_uids && priv->n_pending == 0)); - - break; - } -} - -static struct { - char *name; - ESExpFunc *func; -} functions[] = { - /* Time-related functions */ - { "time-now", func_time_now }, - { "make-time", func_make_time }, - { "time-add-day", func_time_add_day }, - { "time-day-begin", func_time_day_begin }, - { "time-day-end", func_time_day_end }, - - /* Component-related functions */ - { "get-vtype", func_get_vtype }, - { "occur-in-time-range?", func_occur_in_time_range }, - { "contains?", func_contains }, - { "has-categories?", func_has_categories }, - { "is-completed?", func_is_completed }, - { "completed-before?", func_completed_before } -}; - -/* Initializes a sexp by interning our own symbols */ -static ESExp * -create_sexp (Query *query) -{ - ESExp *esexp; - int i; - - esexp = e_sexp_new (); - - for (i = 0; i < (sizeof (functions) / sizeof (functions[0])); i++) - e_sexp_add_function (esexp, 0, functions[i].name, functions[i].func, query); - - return esexp; -} - -/* Creates the ESexp and parses the esexp. If a parse error occurs, it sets the - * query state to QUERY_PARSE_ERROR and returns FALSE. - */ -static gboolean -parse_sexp (Query *query) -{ - QueryPrivate *priv; - - priv = query->priv; - - /* Compile the query string */ - - priv->esexp = create_sexp (query); - - g_assert (priv->sexp != NULL); - e_sexp_input_text (priv->esexp, priv->sexp, strlen (priv->sexp)); - - if (e_sexp_parse (priv->esexp) == -1) { - const char *error_str; - CORBA_Environment ev; - - priv->state = QUERY_PARSE_ERROR; - - /* Report the error to the listener */ - - error_str = e_sexp_error (priv->esexp); - g_assert (error_str != NULL); - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_QueryListener_notifyQueryDone ( - priv->ql, - GNOME_Evolution_Calendar_QueryListener_PARSE_ERROR, - error_str, - &ev); - - if (BONOBO_EX (&ev)) - g_message ("parse_sexp(): Could not notify the listener of " - "a parse error"); - - CORBA_exception_free (&ev); - - e_sexp_unref (priv->esexp); - priv->esexp = NULL; - - return FALSE; - } - - return TRUE; -} - -/* Evaluates the query sexp on the specified component and notifies the listener - * as appropriate. - */ -static void -match_component (Query *query, const char *uid, - gboolean query_in_progress, int n_scanned, int total) -{ - QueryPrivate *priv; - CalComponent *comp; - ESExpResult *result; - - priv = query->priv; - - g_assert (priv->state == QUERY_IN_PROGRESS || priv->state == QUERY_DONE); - g_assert (priv->esexp != NULL); - - comp = cal_backend_get_object_component (priv->backend, uid); - if (!comp) - return; - - /* Eval the sexp */ - - g_assert (priv->next_comp == NULL); - - priv->next_comp = comp; - result = e_sexp_eval (priv->esexp); - priv->next_comp = NULL; - - if (!result) { - const char *error_str; - CORBA_Environment ev; - - error_str = e_sexp_error (priv->esexp); - g_assert (error_str != NULL); - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_QueryListener_notifyEvalError ( - priv->ql, - error_str, - &ev); - - if (BONOBO_EX (&ev)) - g_message ("match_component(): Could not notify the listener of " - "an evaluation error"); - - CORBA_exception_free (&ev); - return; - } else if (result->type != ESEXP_RES_BOOL) { - CORBA_Environment ev; - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_QueryListener_notifyEvalError ( - priv->ql, - _("Evaluation of the search expression did not yield a boolean value"), - &ev); - - if (BONOBO_EX (&ev)) - g_message ("match_component(): Could not notify the listener of " - "an unexpected result value type when evaluating the " - "search expression"); - - CORBA_exception_free (&ev); - } else { - /* Success; process the component accordingly */ - - if (result->value.bool) - add_component (query, uid, query_in_progress, n_scanned, total); - else - remove_component (query, uid); - } - - e_sexp_result_free (priv->esexp, result); -} - -/* Processes all components that are queued in the list */ -static gboolean -process_components_cb (gpointer data) -{ - Query *query; - QueryPrivate *priv; - char *uid; - GList *l; - CORBA_Environment ev; - - query = QUERY (data); - priv = query->priv; - - g_source_remove (priv->timeout_id); - priv->timeout_id = 0; - - while (priv->pending_uids) { - g_assert (priv->n_pending > 0); - - /* Fetch the component */ - - l = priv->pending_uids; - priv->pending_uids = g_list_remove_link (priv->pending_uids, l); - priv->n_pending--; - - g_assert ((priv->pending_uids && priv->n_pending != 0) - || (!priv->pending_uids && priv->n_pending == 0)); - - uid = l->data; - g_assert (uid != NULL); - - g_list_free_1 (l); - - bonobo_object_ref (BONOBO_OBJECT (query)); - - match_component (query, uid, - TRUE, - priv->pending_total - priv->n_pending, - priv->pending_total); - - bonobo_object_unref (BONOBO_OBJECT (query)); - - g_free (uid); - - /* run the main loop, for not blocking */ - if (gtk_events_pending ()) - gtk_main_iteration (); - } - - /* notify listener that the query ended */ - priv->state = QUERY_DONE; - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_QueryListener_notifyQueryDone ( - priv->ql, - GNOME_Evolution_Calendar_QueryListener_SUCCESS, - "", - &ev); - - if (BONOBO_EX (&ev)) - g_message ("start_query(): Could not notify the listener of " - "a finished query"); - - CORBA_exception_free (&ev); - - return FALSE; -} - -/* Callback used when a component changes in the backend */ -static void -backend_obj_updated_cb (CalBackend *backend, const char *uid, gpointer data) -{ - Query *query; - QueryPrivate *priv; - - query = QUERY (data); - priv = query->priv; - - g_assert (priv->state == QUERY_IN_PROGRESS || priv->state == QUERY_DONE); - - bonobo_object_ref (BONOBO_OBJECT (query)); - - match_component (query, uid, FALSE, 0, 0); - remove_from_pending (query, uid); - - bonobo_object_unref (BONOBO_OBJECT (query)); -} - -/* Callback used when a component is removed from the backend */ -static void -backend_obj_removed_cb (CalBackend *backend, const char *uid, gpointer data) -{ - Query *query; - QueryPrivate *priv; - - query = QUERY (data); - priv = query->priv; - - g_assert (priv->state == QUERY_IN_PROGRESS || priv->state == QUERY_DONE); - - bonobo_object_ref (BONOBO_OBJECT (query)); - - remove_component (query, uid); - remove_from_pending (query, uid); - - bonobo_object_unref (BONOBO_OBJECT (query)); -} - -/* Actually starts the query */ -static void -start_query (Query *query) -{ - QueryPrivate *priv; - - priv = query->priv; - - if (!parse_sexp (query)) - return; - - /* Populate the query with UIDs so that we can process them asynchronously */ - - priv->state = QUERY_IN_PROGRESS; - priv->pending_uids = cal_backend_get_uids (priv->backend, CALOBJ_TYPE_ANY); - priv->pending_total = g_list_length (priv->pending_uids); - priv->n_pending = priv->pending_total; - - gtk_signal_connect (GTK_OBJECT (priv->backend), "obj_updated", - GTK_SIGNAL_FUNC (backend_obj_updated_cb), - query); - gtk_signal_connect (GTK_OBJECT (priv->backend), "obj_removed", - GTK_SIGNAL_FUNC (backend_obj_removed_cb), - query); - - priv->timeout_id = g_timeout_add (100, (GSourceFunc) process_components_cb, query); -} - -/* Idle handler for starting a query */ -static gboolean -start_query_cb (gpointer data) -{ - Query *query; - QueryPrivate *priv; - - query = QUERY (data); - priv = query->priv; - - g_source_remove (priv->timeout_id); - priv->timeout_id = 0; - - if (priv->state == QUERY_START_PENDING) { - priv->state = QUERY_IN_PROGRESS; - start_query (query); - } - - return FALSE; -} - -/* Callback used when the backend gets loaded; we just queue the query to be - * started later. - */ -static void -backend_opened_cb (CalBackend *backend, CalBackendOpenStatus status, gpointer data) -{ - Query *query; - QueryPrivate *priv; - - query = QUERY (data); - priv = query->priv; - - g_assert (priv->state == QUERY_WAIT_FOR_BACKEND); - - gtk_signal_disconnect_by_data (GTK_OBJECT (priv->backend), query); - priv->state = QUERY_START_PENDING; - - if (status == CAL_BACKEND_OPEN_SUCCESS) { - g_assert (cal_backend_is_loaded (backend)); - - priv->timeout_id = g_timeout_add (100, (GSourceFunc) start_query_cb, query); - } -} - -/** - * query_construct: - * @query: A live search query. - * @backend: Calendar backend that the query object will monitor. - * @ql: Listener for query results. - * @sexp: Sexp that defines the query. - * - * Constructs a #Query object by binding it to a calendar backend and a query - * listener. The @query object will start to populate itself asynchronously and - * call the listener as appropriate. - * - * Return value: The same value as @query, or NULL if the query could not - * be constructed. - **/ -Query * -query_construct (Query *query, - CalBackend *backend, - GNOME_Evolution_Calendar_QueryListener ql, - const char *sexp) -{ - QueryPrivate *priv; - CORBA_Environment ev; - - g_return_val_if_fail (query != NULL, NULL); - g_return_val_if_fail (IS_QUERY (query), NULL); - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - g_return_val_if_fail (ql != CORBA_OBJECT_NIL, NULL); - g_return_val_if_fail (sexp != NULL, NULL); - - priv = query->priv; - - CORBA_exception_init (&ev); - priv->ql = CORBA_Object_duplicate (ql, &ev); - if (BONOBO_EX (&ev)) { - g_message ("query_construct(): Could not duplicate the listener"); - priv->ql = CORBA_OBJECT_NIL; - CORBA_exception_free (&ev); - return NULL; - } - CORBA_exception_free (&ev); - - priv->backend = backend; - gtk_object_ref (GTK_OBJECT (priv->backend)); - - priv->default_zone = cal_backend_get_default_timezone (backend); - - priv->sexp = g_strdup (sexp); - - /* Queue the query to be started asynchronously */ - - if (cal_backend_is_loaded (priv->backend)) { - priv->state = QUERY_START_PENDING; - - priv->timeout_id = g_timeout_add (100, (GSourceFunc) start_query_cb, query); - } else - gtk_signal_connect (GTK_OBJECT (priv->backend), "opened", - GTK_SIGNAL_FUNC (backend_opened_cb), - query); - - return query; -} - -/** - * query_new: - * @backend: Calendar backend that the query object will monitor. - * @ql: Listener for query results. - * @sexp: Sexp that defines the query. - * - * Creates a new query engine object that monitors a calendar backend. - * - * Return value: A newly-created query object, or NULL on failure. - **/ -Query * -query_new (CalBackend *backend, - GNOME_Evolution_Calendar_QueryListener ql, - const char *sexp) -{ - Query *query; - - query = QUERY (gtk_type_new (QUERY_TYPE)); - if (!query_construct (query, backend, ql, sexp)) { - bonobo_object_unref (BONOBO_OBJECT (query)); - return NULL; - } - - return query; -} diff --git a/calendar/pcs/query.h b/calendar/pcs/query.h deleted file mode 100644 index 80b17983a6..0000000000 --- a/calendar/pcs/query.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Evolution calendar - Live search query implementation - * - * Copyright (C) 2001 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 version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef QUERY_H -#define QUERY_H - -#include <libgnome/gnome-defs.h> -#include <bonobo/bonobo-xobject.h> -#include "cal-common.h" -#include "evolution-calendar.h" - -BEGIN_GNOME_DECLS - - - -#define QUERY_TYPE (query_get_type ()) -#define QUERY(obj) (GTK_CHECK_CAST ((obj), QUERY_TYPE, Query)) -#define QUERY_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), QUERY_TYPE, QueryClass)) -#define IS_QUERY(obj) (GTK_CHECK_TYPE ((obj), QUERY_TYPE)) -#define IS_QUERY_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), QUERY_TYPE)) - -typedef struct _QueryPrivate QueryPrivate; - -typedef struct { - BonoboXObject xobject; - - /* Private data */ - QueryPrivate *priv; -} Query; - -typedef struct { - BonoboXObjectClass parent_class; - - POA_GNOME_Evolution_Calendar_Query__epv epv; -} QueryClass; - -GtkType query_get_type (void); - -Query *query_construct (Query *query, - CalBackend *backend, - GNOME_Evolution_Calendar_QueryListener ql, - const char *sexp); - -Query *query_new (CalBackend *backend, - GNOME_Evolution_Calendar_QueryListener ql, - const char *sexp); - - - -END_GNOME_DECLS - -#endif diff --git a/calendar/zones.h b/calendar/zones.h deleted file mode 100644 index 06f10b749a..0000000000 --- a/calendar/zones.h +++ /dev/null @@ -1,383 +0,0 @@ -/* - * These are the timezone names from the Olson timezone data. - * We only place them here so gettext picks them up for translation. - * Don't include in any C files. - */ - -N_("Africa/Abidjan"); -N_("Africa/Accra"); -N_("Africa/Addis_Ababa"); -N_("Africa/Algiers"); -N_("Africa/Asmera"); -N_("Africa/Bamako"); -N_("Africa/Bangui"); -N_("Africa/Banjul"); -N_("Africa/Bissau"); -N_("Africa/Blantyre"); -N_("Africa/Brazzaville"); -N_("Africa/Bujumbura"); -N_("Africa/Cairo"); -N_("Africa/Casablanca"); -N_("Africa/Ceuta"); -N_("Africa/Conakry"); -N_("Africa/Dakar"); -N_("Africa/Dar_es_Salaam"); -N_("Africa/Djibouti"); -N_("Africa/Douala"); -N_("Africa/El_Aaiun"); -N_("Africa/Freetown"); -N_("Africa/Gaborone"); -N_("Africa/Harare"); -N_("Africa/Johannesburg"); -N_("Africa/Kampala"); -N_("Africa/Khartoum"); -N_("Africa/Kigali"); -N_("Africa/Kinshasa"); -N_("Africa/Lagos"); -N_("Africa/Libreville"); -N_("Africa/Lome"); -N_("Africa/Luanda"); -N_("Africa/Lubumbashi"); -N_("Africa/Lusaka"); -N_("Africa/Malabo"); -N_("Africa/Maputo"); -N_("Africa/Maseru"); -N_("Africa/Mbabane"); -N_("Africa/Mogadishu"); -N_("Africa/Monrovia"); -N_("Africa/Nairobi"); -N_("Africa/Ndjamena"); -N_("Africa/Niamey"); -N_("Africa/Nouakchott"); -N_("Africa/Ouagadougou"); -N_("Africa/Porto-Novo"); -N_("Africa/Sao_Tome"); -N_("Africa/Timbuktu"); -N_("Africa/Tripoli"); -N_("Africa/Tunis"); -N_("Africa/Windhoek"); -N_("America/Adak"); -N_("America/Anchorage"); -N_("America/Anguilla"); -N_("America/Antigua"); -N_("America/Araguaina"); -N_("America/Aruba"); -N_("America/Asuncion"); -N_("America/Barbados"); -N_("America/Belem"); -N_("America/Belize"); -N_("America/Boa_Vista"); -N_("America/Bogota"); -N_("America/Boise"); -N_("America/Buenos_Aires"); -N_("America/Cambridge_Bay"); -N_("America/Cancun"); -N_("America/Caracas"); -N_("America/Catamarca"); -N_("America/Cayenne"); -N_("America/Cayman"); -N_("America/Chicago"); -N_("America/Chihuahua"); -N_("America/Cordoba"); -N_("America/Costa_Rica"); -N_("America/Cuiaba"); -N_("America/Curacao"); -N_("America/Danmarkshavn"); -N_("America/Dawson"); -N_("America/Dawson_Creek"); -N_("America/Denver"); -N_("America/Detroit"); -N_("America/Dominica"); -N_("America/Edmonton"); -N_("America/Eirunepe"); -N_("America/El_Salvador"); -N_("America/Fortaleza"); -N_("America/Glace_Bay"); -N_("America/Godthab"); -N_("America/Goose_Bay"); -N_("America/Grand_Turk"); -N_("America/Grenada"); -N_("America/Guadeloupe"); -N_("America/Guatemala"); -N_("America/Guayaquil"); -N_("America/Guyana"); -N_("America/Halifax"); -N_("America/Havana"); -N_("America/Hermosillo"); -N_("America/Indiana/Indianapolis"); -N_("America/Indiana/Knox"); -N_("America/Indiana/Marengo"); -N_("America/Indiana/Vevay"); -N_("America/Indianapolis"); -N_("America/Inuvik"); -N_("America/Iqaluit"); -N_("America/Jamaica"); -N_("America/Jujuy"); -N_("America/Juneau"); -N_("America/Kentucky/Louisville"); -N_("America/Kentucky/Monticello"); -N_("America/La_Paz"); -N_("America/Lima"); -N_("America/Los_Angeles"); -N_("America/Louisville"); -N_("America/Maceio"); -N_("America/Managua"); -N_("America/Manaus"); -N_("America/Martinique"); -N_("America/Mazatlan"); -N_("America/Mendoza"); -N_("America/Menominee"); -N_("America/Merida"); -N_("America/Mexico_City"); -N_("America/Miquelon"); -N_("America/Monterrey"); -N_("America/Montevideo"); -N_("America/Montreal"); -N_("America/Montserrat"); -N_("America/Nassau"); -N_("America/New_York"); -N_("America/Nipigon"); -N_("America/Nome"); -N_("America/Noronha"); -N_("America/North_Dakota/Center"); -N_("America/Panama"); -N_("America/Pangnirtung"); -N_("America/Paramaribo"); -N_("America/Phoenix"); -N_("America/Port-au-Prince"); -N_("America/Port_of_Spain"); -N_("America/Porto_Velho"); -N_("America/Puerto_Rico"); -N_("America/Rainy_River"); -N_("America/Rankin_Inlet"); -N_("America/Recife"); -N_("America/Regina"); -N_("America/Rio_Branco"); -N_("America/Rosario"); -N_("America/Santiago"); -N_("America/Santo_Domingo"); -N_("America/Sao_Paulo"); -N_("America/Scoresbysund"); -N_("America/Shiprock"); -N_("America/St_Johns"); -N_("America/St_Kitts"); -N_("America/St_Lucia"); -N_("America/St_Thomas"); -N_("America/St_Vincent"); -N_("America/Swift_Current"); -N_("America/Tegucigalpa"); -N_("America/Thule"); -N_("America/Thunder_Bay"); -N_("America/Tijuana"); -N_("America/Tortola"); -N_("America/Vancouver"); -N_("America/Whitehorse"); -N_("America/Winnipeg"); -N_("America/Yakutat"); -N_("America/Yellowknife"); -N_("Antarctica/Casey"); -N_("Antarctica/Davis"); -N_("Antarctica/DumontDUrville"); -N_("Antarctica/Mawson"); -N_("Antarctica/McMurdo"); -N_("Antarctica/Palmer"); -N_("Antarctica/South_Pole"); -N_("Antarctica/Syowa"); -N_("Antarctica/Vostok"); -N_("Arctic/Longyearbyen"); -N_("Asia/Aden"); -N_("Asia/Almaty"); -N_("Asia/Amman"); -N_("Asia/Anadyr"); -N_("Asia/Aqtau"); -N_("Asia/Aqtobe"); -N_("Asia/Ashgabat"); -N_("Asia/Baghdad"); -N_("Asia/Bahrain"); -N_("Asia/Baku"); -N_("Asia/Bangkok"); -N_("Asia/Beirut"); -N_("Asia/Bishkek"); -N_("Asia/Brunei"); -N_("Asia/Calcutta"); -N_("Asia/Choibalsan"); -N_("Asia/Chongqing"); -N_("Asia/Colombo"); -N_("Asia/Damascus"); -N_("Asia/Dhaka"); -N_("Asia/Dili"); -N_("Asia/Dubai"); -N_("Asia/Dushanbe"); -N_("Asia/Gaza"); -N_("Asia/Harbin"); -N_("Asia/Hong_Kong"); -N_("Asia/Hovd"); -N_("Asia/Irkutsk"); -N_("Asia/Istanbul"); -N_("Asia/Jakarta"); -N_("Asia/Jayapura"); -N_("Asia/Jerusalem"); -N_("Asia/Kabul"); -N_("Asia/Kamchatka"); -N_("Asia/Karachi"); -N_("Asia/Kashgar"); -N_("Asia/Katmandu"); -N_("Asia/Krasnoyarsk"); -N_("Asia/Kuala_Lumpur"); -N_("Asia/Kuching"); -N_("Asia/Kuwait"); -N_("Asia/Macao"); -N_("Asia/Magadan"); -N_("Asia/Manila"); -N_("Asia/Muscat"); -N_("Asia/Nicosia"); -N_("Asia/Novosibirsk"); -N_("Asia/Omsk"); -N_("Asia/Phnom_Penh"); -N_("Asia/Pontianak"); -N_("Asia/Pyongyang"); -N_("Asia/Qatar"); -N_("Asia/Rangoon"); -N_("Asia/Riyadh"); -N_("Asia/Saigon"); -N_("Asia/Sakhalin"); -N_("Asia/Samarkand"); -N_("Asia/Seoul"); -N_("Asia/Shanghai"); -N_("Asia/Singapore"); -N_("Asia/Taipei"); -N_("Asia/Tashkent"); -N_("Asia/Tbilisi"); -N_("Asia/Tehran"); -N_("Asia/Thimphu"); -N_("Asia/Tokyo"); -N_("Asia/Ujung_Pandang"); -N_("Asia/Ulaanbaatar"); -N_("Asia/Urumqi"); -N_("Asia/Vientiane"); -N_("Asia/Vladivostok"); -N_("Asia/Yakutsk"); -N_("Asia/Yekaterinburg"); -N_("Asia/Yerevan"); -N_("Atlantic/Azores"); -N_("Atlantic/Bermuda"); -N_("Atlantic/Canary"); -N_("Atlantic/Cape_Verde"); -N_("Atlantic/Faeroe"); -N_("Atlantic/Jan_Mayen"); -N_("Atlantic/Madeira"); -N_("Atlantic/Reykjavik"); -N_("Atlantic/South_Georgia"); -N_("Atlantic/St_Helena"); -N_("Atlantic/Stanley"); -N_("Australia/Adelaide"); -N_("Australia/Brisbane"); -N_("Australia/Broken_Hill"); -N_("Australia/Darwin"); -N_("Australia/Hobart"); -N_("Australia/Lindeman"); -N_("Australia/Lord_Howe"); -N_("Australia/Melbourne"); -N_("Australia/Perth"); -N_("Australia/Sydney"); -N_("Europe/Amsterdam"); -N_("Europe/Andorra"); -N_("Europe/Athens"); -N_("Europe/Belfast"); -N_("Europe/Belgrade"); -N_("Europe/Berlin"); -N_("Europe/Bratislava"); -N_("Europe/Brussels"); -N_("Europe/Bucharest"); -N_("Europe/Budapest"); -N_("Europe/Chisinau"); -N_("Europe/Copenhagen"); -N_("Europe/Dublin"); -N_("Europe/Gibraltar"); -N_("Europe/Helsinki"); -N_("Europe/Istanbul"); -N_("Europe/Kaliningrad"); -N_("Europe/Kiev"); -N_("Europe/Lisbon"); -N_("Europe/Ljubljana"); -N_("Europe/London"); -N_("Europe/Luxembourg"); -N_("Europe/Madrid"); -N_("Europe/Malta"); -N_("Europe/Minsk"); -N_("Europe/Monaco"); -N_("Europe/Moscow"); -N_("Europe/Nicosia"); -N_("Europe/Oslo"); -N_("Europe/Paris"); -N_("Europe/Prague"); -N_("Europe/Riga"); -N_("Europe/Rome"); -N_("Europe/Samara"); -N_("Europe/San_Marino"); -N_("Europe/Sarajevo"); -N_("Europe/Simferopol"); -N_("Europe/Skopje"); -N_("Europe/Sofia"); -N_("Europe/Stockholm"); -N_("Europe/Tallinn"); -N_("Europe/Tirane"); -N_("Europe/Uzhgorod"); -N_("Europe/Vaduz"); -N_("Europe/Vatican"); -N_("Europe/Vienna"); -N_("Europe/Vilnius"); -N_("Europe/Warsaw"); -N_("Europe/Zagreb"); -N_("Europe/Zaporozhye"); -N_("Europe/Zurich"); -N_("Indian/Antananarivo"); -N_("Indian/Chagos"); -N_("Indian/Christmas"); -N_("Indian/Cocos"); -N_("Indian/Comoro"); -N_("Indian/Kerguelen"); -N_("Indian/Mahe"); -N_("Indian/Maldives"); -N_("Indian/Mauritius"); -N_("Indian/Mayotte"); -N_("Indian/Reunion"); -N_("Pacific/Apia"); -N_("Pacific/Auckland"); -N_("Pacific/Chatham"); -N_("Pacific/Easter"); -N_("Pacific/Efate"); -N_("Pacific/Enderbury"); -N_("Pacific/Fakaofo"); -N_("Pacific/Fiji"); -N_("Pacific/Funafuti"); -N_("Pacific/Galapagos"); -N_("Pacific/Gambier"); -N_("Pacific/Guadalcanal"); -N_("Pacific/Guam"); -N_("Pacific/Honolulu"); -N_("Pacific/Johnston"); -N_("Pacific/Kiritimati"); -N_("Pacific/Kosrae"); -N_("Pacific/Kwajalein"); -N_("Pacific/Majuro"); -N_("Pacific/Marquesas"); -N_("Pacific/Midway"); -N_("Pacific/Nauru"); -N_("Pacific/Niue"); -N_("Pacific/Norfolk"); -N_("Pacific/Noumea"); -N_("Pacific/Pago_Pago"); -N_("Pacific/Palau"); -N_("Pacific/Pitcairn"); -N_("Pacific/Ponape"); -N_("Pacific/Port_Moresby"); -N_("Pacific/Rarotonga"); -N_("Pacific/Saipan"); -N_("Pacific/Tahiti"); -N_("Pacific/Tarawa"); -N_("Pacific/Tongatapu"); -N_("Pacific/Truk"); -N_("Pacific/Wake"); -N_("Pacific/Wallis"); -N_("Pacific/Yap"); |