diff options
author | nobody <nobody@localhost> | 2003-12-09 09:57:09 +0800 |
---|---|---|
committer | nobody <nobody@localhost> | 2003-12-09 09:57:09 +0800 |
commit | 56f2d7b21f78ef90bd59bc2b88e312a8480a5b4c (patch) | |
tree | 75bb0caf9afd4b94842023406d6a7938c5d8b2b7 /calendar/gui | |
parent | 0031a7166cd0f3fc0cec0b60c468ca22a8c45b0b (diff) | |
download | gsoc2013-evolution-GEDIT_2_5_92.tar gsoc2013-evolution-GEDIT_2_5_92.tar.gz gsoc2013-evolution-GEDIT_2_5_92.tar.bz2 gsoc2013-evolution-GEDIT_2_5_92.tar.lz gsoc2013-evolution-GEDIT_2_5_92.tar.xz gsoc2013-evolution-GEDIT_2_5_92.tar.zst gsoc2013-evolution-GEDIT_2_5_92.zip |
This commit was manufactured by cvs2svn to create tag 'GEDIT_2_5_92'.GEDIT_2_5_92
svn path=/tags/GEDIT_2_5_92/; revision=23726
Diffstat (limited to 'calendar/gui')
220 files changed, 0 insertions, 86761 deletions
diff --git a/calendar/gui/.cvsignore b/calendar/gui/.cvsignore deleted file mode 100644 index a2cee3711f..0000000000 --- a/calendar/gui/.cvsignore +++ /dev/null @@ -1,25 +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 -e-calendar-marshal.h -e-calendar-marshal.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*.server -GNOME_Evolution_Calendar*.server.in diff --git a/calendar/gui/GNOME_Evolution_Calendar.server.in.in b/calendar/gui/GNOME_Evolution_Calendar.server.in.in deleted file mode 100644 index cee3a6a103..0000000000 --- a/calendar/gui/GNOME_Evolution_Calendar.server.in.in +++ /dev/null @@ -1,146 +0,0 @@ -<oaf_info> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_Factory:@VERSION@" - type="shlib" - location="@COMPONENTDIR@/libevolution-calendar.so"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/ObjectFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="name" type="string" - _value="Evolution Calendar and Tasks"/> - -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_iTip_Control:@VERSION@" - type="factory" - location="OAFIID:GNOME_Evolution_Calendar_Factory:@VERSION@"> - - <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 scheduling message viewer"/> -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_Component:@VERSION@" - type="factory" - location="OAFIID:GNOME_Evolution_Calendar_Factory:@VERSION@"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution/Component:@VERSION@"/> - </oaf_attribute> - - <oaf_attribute name="evolution:component_alias" type="string" value="calendar"/> - - <oaf_attribute name="name" type="string" _value="Evolution's Calendar component"/> - - <oaf_attribute name="evolution:button_label" type="string" _value="Calendars"/> - <oaf_attribute name="evolution:button_icon" type="string" value="evolution-calendar.png"/> - <oaf_attribute name="evolution:button_sort_order" type="string" value="-8"/> -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_Control:@VERSION@" - type="factory" - location="OAFIID:GNOME_Evolution_Calendar_Factory:@VERSION@"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:BonoboControl/calendar-control:@VERSION@"/> - <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="name" type="string" - _value="Evolution Calendar viewer"/> -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Tasks_Component:@VERSION@" - type="factory" - location="OAFIID:GNOME_Evolution_Calendar_Factory:@VERSION@"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution/Component:@VERSION@"/> - </oaf_attribute> - - <oaf_attribute name="evolution:component_alias" type="string" value="tasks"/> - - <oaf_attribute name="name" type="string" _value="Evolution's Tasks component"/> - - <oaf_attribute name="evolution:button_label" type="string" _value="Tasks"/> - <oaf_attribute name="evolution:button_icon" type="string" value="evolution-tasks.png"/> - <oaf_attribute name="evolution:button_sort_order" type="string" value="-8"/> -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Tasks_Control:@VERSION@" - type="factory" - location="OAFIID:GNOME_Evolution_Calendar_Factory:@VERSION@"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:BonoboControl/tasks-control:@VERSION@"/> - <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="name" type="string" - _value="Evolution Tasks viewer"/> -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_CompEditorFactory:@VERSION@" - type="factory" - location="OAFIID:GNOME_Evolution_Calendar_Factory:@VERSION@"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution/Calendar/CompEditorFactory:@VERSION@"/> - <item value="IDL:Bonobo/Unknown:1.0"/> - </oaf_attribute> - - <oaf_attribute name="name" type="string" - _value="Evolution Calendar/Task editor"/> -</oaf_server> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_ConfigControl:@VERSION@" - type="factory" - location="OAFIID:GNOME_Evolution_Calendar_Factory:@VERSION@"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/Evolution/ConfigControl:@VERSION@"/> - </oaf_attribute> - - <oaf_attribute name="evolution2:config_item:title" type="string" - _value="Calendar and Tasks"/> - - <oaf_attribute name="evolution2:config_item:description" type="string" - _value="Configure your timezone, Calendar and Task List here "/> - - <oaf_attribute name="evolution2:config_item:icon_name" type="string" - value="evolution-calendar.png"/> - - <oaf_attribute name="evolution2:config_item:type" type="stringv"> - <item value="calendar"/> - <item value="tasks"/> - </oaf_attribute> - - <oaf_attribute name="evolution2:config_item:priority" type="string" value="-7"/> - - <oaf_attribute name="name" type="string" - _value="Evolution Calendar configuration control"/> - -</oaf_server> - -</oaf_info> diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am deleted file mode 100644 index bdb5f454fa..0000000000 --- a/calendar/gui/Makefile.am +++ /dev/null @@ -1,261 +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 - -CALENDAR_IDL_GENERATED_H = \ - evolution-calendar.h -CALENDAR_IDL_GENERATED_C = \ - evolution-calendar-common.c \ - evolution-calendar-skels.c \ - evolution-calendar-stubs.c -CALENDAR_IDL_GENERATED = $(CALENDAR_IDL_GENERATED_C) $(CALENDAR_IDL_GENERATED_H) - -$(CALENDAR_IDL_GENERATED_H): $(IDLS) - $(ORBIT_IDL) -I $(srcdir) $(IDL_INCLUDES) \ - $(top_srcdir)/calendar/idl/evolution-calendar.idl -$(CALENDAR_IDL_GENERATED_C): $(CALENDAR_IDL_GENERATED_H) - -# Message composer IDL files - -COMPOSER_IDL_GENERATED_H = \ - Evolution-Composer.h -COMPOSER_IDL_GENERATED_C = \ - Evolution-Composer-common.c \ - Evolution-Composer-skels.c \ - Evolution-Composer-stubs.c -COMPOSER_IDL_GENERATED = $(COMPOSER_IDL_GENERATED_C) $(COMPOSER_IDL_GENERATED_H) - -$(COMPOSER_IDL_GENERATED_H): $(IDLS) - $(ORBIT_IDL) -I $(srcdir) $(IDL_INCLUDES) \ - $(srcdir)/../../composer/Evolution-Composer.idl -$(COMPOSER_IDL_GENERATED_C): $(COMPOSER_IDL_GENERATED_H) - -# SelectNames IDL files - -SELECT_NAMES_IDL_GENERATED_H = \ - Evolution-Addressbook-SelectNames.h -SELECT_NAMES_IDL_GENERATED_C = \ - Evolution-Addressbook-SelectNames-common.c \ - Evolution-Addressbook-SelectNames-skels.c \ - Evolution-Addressbook-SelectNames-stubs.c -SELECT_NAMES_IDL_GENERATED = $(SELECT_NAMES_IDL_GENERATED_C) $(SELECT_NAMES_IDL_GENERATED_H) - -$(SELECT_NAMES_IDL_GENERATED_H): $(IDLS) - $(ORBIT_IDL) -I $(srcdir) $(IDL_INCLUDES) \ - $(top_srcdir)/addressbook/gui/component/select-names/Evolution-Addressbook-SelectNames.idl -$(SELECT_NAMES_IDL_GENERATED_C): $(SELECT_NAMES_IDL_GENERATED_H) - - -IDL_GENERATED = $(CALENDAR_IDL_GENERATED) $(COMPOSER_IDL_GENERATED) $(SELECT_NAMES_IDL_GENERATED) - -# The marshallers -MARSHAL_GENERATED = e-calendar-marshal.c e-calendar-marshal.h -@EVO_MARSHAL_RULE@ - -SUBDIRS = alarm-notify dialogs - -component_LTLIBRARIES = libevolution-calendar.la - -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)/widgets \ - -I$(top_srcdir)/a11y/calendar \ - -DEVOLUTION_DATADIR=\""$(datadir)"\" \ - -DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \ - -DEVOLUTION_ETSPECDIR=\""$(etspecdir)"\" \ - -DEVOLUTION_IMAGESDIR=\""$(imagesdir)"\" \ - -DEVOLUTION_GALVIEWSDIR=\""$(viewsdir)"\" \ - -DEVOLUTION_UIDIR=\""$(evolutionuidir)"\" \ - -DPREFIX=\""$(prefix)"\" \ - $(EVOLUTION_CALENDAR_CFLAGS) - -glade_DATA = \ - e-itip-control.glade \ - goto-dialog.glade - -etspec_DATA = \ - e-calendar-table.etspec \ - e-meeting-time-sel.etspec \ - e-cal-list-view.etspec - -libevolution_calendar_la_SOURCES = \ - $(IDL_GENERATED) \ - $(MARSHAL_GENERATED) \ - cal-search-bar.c \ - cal-search-bar.h \ - calendar-config.c \ - calendar-config.h \ - calendar-config-keys.h \ - calendar-commands.c \ - calendar-commands.h \ - calendar-component.c \ - calendar-component.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 \ - control-factory.c \ - control-factory.h \ - e-alarm-list.c \ - e-alarm-list.h \ - e-cal-model-calendar.c \ - e-cal-model-calendar.h \ - e-cal-model-tasks.c \ - e-cal-model-tasks.h \ - e-cal-model.c \ - e-cal-model.h \ - e-cal-view.c \ - e-cal-view.h \ - e-cal-list-view.c \ - e-cal-list-view.h \ - e-cal-list-view-config.c \ - e-cal-list-view-config.h \ - e-calendar-table.c \ - e-calendar-table.h \ - e-calendar-table-config.c \ - e-calendar-table-config.h \ - e-cell-date-edit-config.c \ - e-cell-date-edit-config.h \ - e-cell-date-edit-text.h \ - e-cell-date-edit-text.c \ - e-comp-editor-registry.c \ - e-comp-editor-registry.h \ - e-date-edit-config.c \ - e-date-edit-config.h \ - e-date-time-list.c \ - e-date-time-list.h \ - e-day-view-config.c \ - e-day-view-config.h \ - 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-list-view.c \ - e-meeting-list-view.h \ - e-meeting-store.c \ - e-meeting-store.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-mini-calendar-config.c \ - e-mini-calendar-config.h \ - e-select-names-editable.c \ - e-select-names-editable.h \ - e-select-names-renderer.c \ - e-select-names-renderer.h \ - e-week-view-config.c \ - e-week-view-config.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-bonobo-control.c \ - itip-bonobo-control.h \ - itip-utils.c \ - itip-utils.h \ - main.c \ - migration.c \ - migration.h \ - misc.c \ - misc.h \ - print.c \ - print.h \ - tag-calendar.c \ - tag-calendar.h \ - tasks-component.c \ - tasks-component.h \ - tasks-control.c \ - tasks-control.h \ - weekday-picker.c \ - weekday-picker.h - -libevolution_calendar_la_LIBADD = \ - $(top_builddir)/widgets/menus/libmenus.la \ - $(top_builddir)/shell/libeshell.la \ - $(top_builddir)/calendar/gui/dialogs/libcal-dialogs.la \ - $(top_builddir)/widgets/e-timezone-dialog/libetimezonedialog.la \ - $(top_builddir)/widgets/misc/libemiscwidgets.la \ - $(top_builddir)/e-util/libeutil.la \ - $(top_builddir)/a11y/calendar/libevolution-calendar-a11y.la \ - $(EVOLUTION_CALENDAR_LIBS) - -libevolution_calendar_la_LDFLAGS = -avoid-version -module - -server_in_files = GNOME_Evolution_Calendar.server.in.in -server_DATA = $(server_in_files:.server.in.in=_$(BASE_VERSION).server) -@EVO_SERVER_RULE@ -@INTLTOOL_SERVER_RULE@ - -# GConf schemas - -schemadir = $(GCONF_SCHEMA_FILE_DIR) -schema_in_files = apps_evolution_calendar.schemas.in.in -schema_DATA = $(schema_in_files:.schemas.in.in=-$(BASE_VERSION).schemas) -%-$(BASE_VERSION).schemas.in: %.schemas.in.in - cp $< $@ - -@INTLTOOL_SCHEMAS_RULE@ - -EXTRA_DIST = \ - e-calendar-marshal.list \ - $(glade_DATA) \ - $(schema_DATA) \ - $(etspec_DATA) \ - $(server_in_files) - -BUILT_SOURCES = $(IDL_GENERATED) $(server_DATA) -CLEANFILES = $(BUILT_SOURCES) - -install-data-local: - $(mkinstalldirs) $(Conduitsdir); \ - if test -z "$(DESTDIR)"; then \ - for p in $(schema_DATA); do \ - GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) $(GCONFTOOL) --makefile-install-rule $(srcdir)/$$p; \ - done; \ - fi - -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 d940a07146..0000000000 --- a/calendar/gui/alarm-notify/.cvsignore +++ /dev/null @@ -1,12 +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*.server -GNOME_Evolution_Calendar_AlarmNotify*.server.in diff --git a/calendar/gui/alarm-notify/GNOME_Evolution_Calendar_AlarmNotify.server.in.in b/calendar/gui/alarm-notify/GNOME_Evolution_Calendar_AlarmNotify.server.in.in deleted file mode 100644 index 3c43c4ca54..0000000000 --- a/calendar/gui/alarm-notify/GNOME_Evolution_Calendar_AlarmNotify.server.in.in +++ /dev/null @@ -1,16 +0,0 @@ -<oaf_info> - -<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_AlarmNotify:@VERSION@" - type="exe" - location="@LIBEXECDIR@/evolution-alarm-notify"> - - <oaf_attribute name="repo_ids" type="stringv"> - <item value="IDL:GNOME/ObjectFactory:1.0"/> - </oaf_attribute> - - <oaf_attribute name="name" type="string" - _value="Evolution Calendar 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 e5653e4433..0000000000 --- a/calendar/gui/alarm-notify/Makefile.am +++ /dev/null @@ -1,67 +0,0 @@ -CORBA_GENERATED_H = \ - evolution-calendar.h -CORBA_GENERATED_C = \ - evolution-calendar-common.c \ - evolution-calendar-skels.c \ - evolution-calendar-stubs.c -CORBA_GENERATED = $(CORBA_GENERATED_C) $(CORBA_GENERATED_H) - -idls = $(top_srcdir)/calendar/idl/evolution-calendar.idl -idl_flags = $(IDL_INCLUDES) - -$(CORBA_GENERATED_H): $(idls) - $(ORBIT_IDL) $(idl_flags) $(top_srcdir)/calendar/idl/evolution-calendar.idl -$(CORBA_GENERATED_C): $(CORBA_GENERATED_H) - - -privlibexec_PROGRAMS = evolution-alarm-notify - - -INCLUDES = \ - -DG_LOG_DOMAIN=\"evolution-alarm-notify\" \ - -I$(top_srcdir) \ - -I$(top_srcdir)/widgets \ - -DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \ - -DEVOLUTION_IMAGESDIR=\""$(imagesdir)"\" \ - -DEVOLUTION_LOCALEDIR=\""$(localedir)"\" \ - $(EVOLUTION_CALENDAR_CFLAGS) - -glade_DATA = \ - alarm-notify.glade - -evolution_alarm_notify_SOURCES = \ - $(CORBA_GENERATED) \ - alarm.c \ - alarm.h \ - 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 \ - util.c \ - util.h - -evolution_alarm_notify_LDADD = \ - $(top_builddir)/e-util/libeutil.la \ - $(EVOLUTION_CALENDAR_LIBS) - -server_in_files = GNOME_Evolution_Calendar_AlarmNotify.server.in.in -server_DATA = $(server_in_files:.server.in.in=_$(BASE_VERSION).server) -@EVO_SERVER_RULE@ -@INTLTOOL_SERVER_RULE@ - -EXTRA_DIST = \ - $(server_in_files) \ - $(glade_DATA) - -BUILT_SOURCES = $(CORBA_GENERATED) $(server_DATA) -CLEANFILES = $(BUILT_SOURCES) - -dist-hook: - cd $(distdir); rm -f $(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 e7c87c2156..0000000000 --- a/calendar/gui/alarm-notify/alarm-notify-dialog.c +++ /dev/null @@ -1,394 +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/gtkscrolledwindow.h> -#include <gtk/gtkwindow.h> -#include <libgnome/gnome-i18n.h> -#if 0 -# include <libgnomeui/gnome-winhints.h> -#endif -#include <libgnomeui/gnome-window-icon.h> -#include <glade/glade.h> -#include <e-util/e-time-utils.h> -#include <gtkhtml/gtkhtml.h> -#include <gtkhtml/gtkhtml-stream.h> -#include <libecal/e-cal-time-util.h> -#include "alarm-notify-dialog.h" -#include "config-data.h" -#include "util.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 *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; - g_object_unref (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, *scrolled_window; - - gtk_widget_push_colormap (gdk_rgb_get_colormap ()); - - html = gtk_html_new(); - - gtk_html_set_default_content_type (GTK_HTML (html), - "charset=utf-8"); - gtk_html_load_empty (GTK_HTML (html)); - - g_signal_connect (html, "url_requested", - G_CALLBACK (url_requested_cb), - NULL); - - gtk_widget_pop_colormap(); - - 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_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), - GTK_SHADOW_IN); - - gtk_widget_set_size_request (scrolled_window, 300, 200); - - gtk_container_add(GTK_CONTAINER (scrolled_window), html); - - gtk_widget_show_all(scrolled_window); - - g_object_set_data (G_OBJECT (scrolled_window), "html", html); - return scrolled_window; -} - -static void -write_times (GtkHTMLStream *stream, char *start, char *end) -{ - if (start) - gtk_html_stream_printf (stream, "<b>%s</b> %s<br>", _("Starting:"), start); - if (end) - gtk_html_stream_printf (stream, "<b>%s</b> %s<br>", _("Ending:"), end); - -} - -/* Creates a heading for the alarm notification dialog */ -static void -write_html_heading (GtkHTMLStream *stream, const char *message, - ECalComponentVType vtype, time_t occur_start, time_t occur_end) -{ - char *buf; - char *start, *end; - char *bg_path = "file://" EVOLUTION_IMAGESDIR "/bcg.png"; - char *image_path = "file://" EVOLUTION_IMAGESDIR "/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 = g_locale_to_utf8 (buf, -1, NULL, NULL, NULL); - g_free (buf); - - buf = timet_to_str_with_zone (occur_end, current_zone); - end = g_locale_to_utf8 (buf, -1, NULL, NULL, NULL); - 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, - _("Evolution Alarm")); - - gtk_html_stream_printf (stream, "<br><br><font size=\"+2\">%s</font><br><br>", message); - - /* Write the times */ - - switch (vtype) { - case E_CAL_COMPONENT_EVENT: - write_times (stream, start, end); - break; - - case E_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: a pointer to the dialog structure if successful or NULL if an error occurs. - **/ -gpointer -alarm_notify_dialog (time_t trigger, time_t occur_start, time_t occur_end, - ECalComponentVType 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, NULL); - - /* Only VEVENTs or VTODOs can have alarms */ - g_return_val_if_fail (vtype == E_CAL_COMPONENT_EVENT || vtype == E_CAL_COMPONENT_TODO, NULL); - g_return_val_if_fail (message != NULL, NULL); - g_return_val_if_fail (func != NULL, NULL); - - an = g_new0 (AlarmNotify, 1); - - an->func = func; - an->func_data = func_data; - - an->xml = glade_xml_new (EVOLUTION_GLADEDIR "/alarm-notify.glade", NULL, NULL); - if (!an->xml) { - g_message ("alarm_notify_dialog(): Could not load the Glade XML file!"); - g_free (an); - return NULL; - } - - 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->snooze_time = glade_xml_get_widget (an->xml, "snooze-time"); - an->html = g_object_get_data (G_OBJECT (glade_xml_get_widget (an->xml, "frame")), "html"); - - if (!(an->dialog && an->close && an->snooze && an->edit - && an->snooze_time)) { - g_message ("alarm_notify_dialog(): Could not find all widgets in Glade file!"); - g_object_unref (an->xml); - g_free (an); - return NULL; - } - - g_signal_connect (G_OBJECT (an->dialog), "destroy", - G_CALLBACK (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 */ - - g_signal_connect (an->dialog, "delete_event", - G_CALLBACK (delete_event_cb), - an); - - g_signal_connect (an->close, "clicked", - G_CALLBACK (close_clicked_cb), - an); - - g_signal_connect (an->snooze, "clicked", - G_CALLBACK (snooze_clicked_cb), - an); - - g_signal_connect (an->edit, "clicked", - G_CALLBACK (edit_clicked_cb), - an); - - /* Run! */ - - if (!GTK_WIDGET_REALIZED (an->dialog)) - gtk_widget_realize (an->dialog); - - gtk_window_stick (GTK_WINDOW (an->dialog)); - gtk_window_set_icon_from_file (GTK_WINDOW (an->dialog), EVOLUTION_IMAGESDIR "/alarm.png", NULL); - - gtk_widget_show (an->dialog); - return an; -} - -void -alarm_notify_dialog_disable_buttons (gpointer dialog) -{ - AlarmNotify *an = dialog; - - gtk_widget_set_sensitive (an->snooze, FALSE); - gtk_widget_set_sensitive (an->edit, FALSE); -} 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 9bebce0a08..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 <libecal/e-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); - -gpointer alarm_notify_dialog (time_t trigger, time_t occur_start, time_t occur_end, - ECalComponentVType vtype, const char *message, - AlarmNotifyFunc func, gpointer func_data); -void alarm_notify_dialog_disable_buttons (gpointer dialog); - - -#endif diff --git a/calendar/gui/alarm-notify/alarm-notify.c b/calendar/gui/alarm-notify/alarm-notify.c deleted file mode 100644 index 9e7f1335a8..0000000000 --- a/calendar/gui/alarm-notify/alarm-notify.c +++ /dev/null @@ -1,200 +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 <string.h> -#include <libecal/e-cal.h> -#include "alarm-notify.h" -#include "alarm-queue.h" -#include "save.h" -#include "e-util/e-url.h" - - - -/* 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 *klass); -static void alarm_notify_init (AlarmNotify *an, AlarmNotifyClass *klass); -static void alarm_notify_finalize (GObject *object); - - -static BonoboObjectClass *parent_class; - - - -GType -alarm_notify_get_type (void) -{ - static GType type = 0; - - if (!type) { - static GTypeInfo info = { - sizeof (AlarmNotifyClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) alarm_notify_class_init, - NULL, NULL, - sizeof (AlarmNotify), - 0, - (GInstanceInitFunc) alarm_notify_init - }; - type = g_type_register_static (G_TYPE_OBJECT, "AlarmNotify", &info, 0); - } - - return type; -} - -/* Class initialization function for the alarm notify service */ -static void -alarm_notify_class_init (AlarmNotifyClass *klass) -{ - GObjectClass *object_class; - - object_class = (GObjectClass *) klass; - - parent_class = g_type_class_peek_parent (klass); - - object_class->finalize = alarm_notify_finalize; -} - -/* Object initialization function for the alarm notify system */ -static void -alarm_notify_init (AlarmNotify *an, AlarmNotifyClass *klass) -{ - AlarmNotifyPrivate *priv; - - priv = g_new0 (AlarmNotifyPrivate, 1); - an->priv = priv; - - priv->uri_client_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); -} - -static void -free_client_hash (gpointer key, gpointer value, gpointer user_data) -{ - char *uri = key; - ECal *client = value; - - g_free (uri); - g_object_unref (client); -} - -/* Finalize handler for the alarm notify system */ -static void -alarm_notify_finalize (GObject *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, (GHFunc) free_client_hash, NULL); - g_hash_table_destroy (priv->uri_client_hash); - - g_free (priv); - - if (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (object); -} - - - -/** - * 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 = g_object_new (TYPE_ALARM_NOTIFY, NULL); - 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. - * - * 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) -{ - AlarmNotifyPrivate *priv; - ECal *client; - - g_return_if_fail (an != NULL); - g_return_if_fail (IS_ALARM_NOTIFY (an)); - g_return_if_fail (str_uri != NULL); - - priv = an->priv; - - /* See if we already know about this uri */ - if (g_hash_table_lookup (priv->uri_client_hash, str_uri)) - return; - - client = e_cal_new_from_uri (str_uri, CALOBJ_TYPE_EVENT); - - if (client) { - if (e_cal_open (client, FALSE, NULL)) { - g_hash_table_insert (priv->uri_client_hash, - g_strdup (str_uri), client); - } - } -} - -void -alarm_notify_remove_calendar (AlarmNotify *an, const char *str_uri) -{ - AlarmNotifyPrivate *priv; - ECal *client; - - priv = an->priv; - - client = g_hash_table_lookup (priv->uri_client_hash, str_uri); - if (client) { - alarm_queue_remove_client (client); - - g_hash_table_remove (priv->uri_client_hash, str_uri); - } -} diff --git a/calendar/gui/alarm-notify/alarm-notify.glade b/calendar/gui/alarm-notify/alarm-notify.glade deleted file mode 100644 index bc0da43f22..0000000000 --- a/calendar/gui/alarm-notify/alarm-notify.glade +++ /dev/null @@ -1,189 +0,0 @@ -<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> -<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> - -<glade-interface> - -<widget class="GtkWindow" id="alarm-notify"> - <property name="border_width">12</property> - <property name="visible">True</property> - <property name="title" translatable="yes"></property> - <property name="type">GTK_WINDOW_TOPLEVEL</property> - <property name="window_position">GTK_WIN_POS_NONE</property> - <property name="modal">False</property> - <property name="resizable">True</property> - <property name="destroy_with_parent">False</property> - - <child> - <widget class="GtkVBox" id="vbox2"> - <property name="border_width">4</property> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkHBox" id="hbox3"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkVBox" id="vbox5"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="Custom" id="frame"> - <property name="visible">True</property> - <property name="creation_function">make_html_display</property> - <property name="int1">0</property> - <property name="int2">0</property> - <property name="last_modification_time">Thu, 11 Oct 2001 08:19:04 GMT</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkVBox" id="vbox4"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkButton" id="close"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">C_lose</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkButton" id="snooze"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Snoo_ze</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkButton" id="edit"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">_Edit appointment</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkHSeparator" id="hseparator1"> - <property name="visible">True</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkHBox" id="hbox4"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkLabel" id="label4"> - <property name="visible">True</property> - <property name="label" translatable="yes">Snooze time (minutes)</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkSpinButton" id="snooze-time"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="climb_rate">1</property> - <property name="digits">0</property> - <property name="numeric">False</property> - <property name="update_policy">GTK_UPDATE_ALWAYS</property> - <property name="snap_to_ticks">False</property> - <property name="wrap">False</property> - <property name="adjustment">5 1 1440 1 5 5</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - </child> -</widget> - -</glade-interface> diff --git a/calendar/gui/alarm-notify/alarm-notify.h b/calendar/gui/alarm-notify/alarm-notify.h deleted file mode 100644 index 418ae23878..0000000000 --- a/calendar/gui/alarm-notify/alarm-notify.h +++ /dev/null @@ -1,62 +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 <glib-object.h> - - - -#define TYPE_ALARM_NOTIFY (alarm_notify_get_type ()) -#define ALARM_NOTIFY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_ALARM_NOTIFY, AlarmNotify)) -#define ALARM_NOTIFY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_ALARM_NOTIFY, \ - AlarmNotifyClass)) -#define IS_ALARM_NOTIFY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_ALARM_NOTIFY)) -#define IS_ALARM_NOTIFY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_ALARM_NOTIFY)) - -typedef struct _AlarmNotify AlarmNotify; -typedef struct _AlarmNotifyClass AlarmNotifyClass; - -typedef struct _AlarmNotifyPrivate AlarmNotifyPrivate; - -struct _AlarmNotify { - GObject object; - - /* Private data */ - AlarmNotifyPrivate *priv; -}; - -struct _AlarmNotifyClass { - GObjectClass parent_class; -}; - -GType alarm_notify_get_type (void); - -AlarmNotify *alarm_notify_new (void); - -void alarm_notify_add_calendar (AlarmNotify *an, const char *str_uri, gboolean load_afterwards); -void alarm_notify_remove_calendar (AlarmNotify *an, const char *str_uri); - - - - -#endif diff --git a/calendar/gui/alarm-notify/alarm-queue.c b/calendar/gui/alarm-notify/alarm-queue.c deleted file mode 100644 index 2cf95f47b7..0000000000 --- a/calendar/gui/alarm-notify/alarm-queue.c +++ /dev/null @@ -1,1301 +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 <string.h> -#include <glib.h> -#include <bonobo-activation/bonobo-activation.h> -#include <bonobo/bonobo-object.h> -#include <gtk/gtksignal.h> -#include <gtk/gtkbox.h> -#include <gtk/gtkdialog.h> -#include <gtk/gtkeventbox.h> -#include <gtk/gtkimage.h> -#include <gtk/gtklabel.h> -#include <gtk/gtkcheckbutton.h> -#include <gtk/gtkstock.h> -#include <gtk/gtktooltips.h> -#include <libgnome/gnome-i18n.h> -#include <libgnome/gnome-exec.h> -#include <libgnome/gnome-sound.h> -#include <libgnomeui/gnome-dialog-util.h> -#include <libgnomeui/gnome-uidefs.h> -#include <e-util/eggtrayicon.h> -#include <libecal/e-cal-time-util.h> -#include "evolution-calendar.h" -#include "alarm.h" -#include "alarm-notify-dialog.h" -#include "alarm-queue.h" -#include "config-data.h" -#include "save.h" -#include "util.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 */ - ECal *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 ECalComponentAlarms and the mapping from queued alarm IDs to the - * actual alarm instance structures. - */ -typedef struct { - /* The parent client alarms structure */ - ClientAlarms *parent_client; - - /* The component's UID */ - char *uid; - - /* The actual component and its alarm instances */ - ECalComponentAlarms *alarms; - - /* List of QueuedAlarm structures */ - GSList *queued_alarms; - - /* Flags */ - gboolean expecting_update; -} 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 */ - ECalComponentAlarmInstance *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 (ECal *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) - return qa; - } - - /* not found, might have been updated/removed */ - return NULL; -} - -/* 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, - gboolean free_object, gboolean remove_alarm) -{ - QueuedAlarm *qa; - GSList *l; - - qa = NULL; - - for (l = cqa->queued_alarms; l; l = l->next) { - qa = l->data; - if (qa->alarm_id == alarm_id) - break; - } - - if (!l) - return; - - cqa->queued_alarms = g_slist_remove_link (cqa->queued_alarms, l); - g_slist_free_1 (l); - - if (remove_alarm) { - cqa->expecting_update = TRUE; - e_cal_discard_alarm (cqa->parent_client->client, cqa->alarms->comp, - qa->instance->auid, NULL); - cqa->expecting_update = FALSE; - } - - g_free (qa); - - /* If this was the last queued alarm for this component, remove the - * component itself. - */ - - if (cqa->queued_alarms != NULL) - return; - - if (free_object) { - g_hash_table_remove (cqa->parent_client->uid_alarms_hash, cqa->uid); - g_free (cqa->uid); - cqa->uid = NULL; - cqa->parent_client = NULL; - e_cal_component_alarms_free (cqa->alarms); - g_free (cqa); - } else { - e_cal_component_alarms_free (cqa->alarms); - cqa->alarms = NULL; - } -} - -/* Callback used when an alarm triggers */ -static void -alarm_trigger_cb (gpointer alarm_id, time_t trigger, gpointer data) -{ - CompQueuedAlarms *cqa; - ECalComponent *comp; - QueuedAlarm *qa; - ECalComponentAlarm *alarm; - ECalComponentAlarmAction action; - - cqa = data; - comp = cqa->alarms->comp; - - save_notification_time (trigger); - saved_notification_time = trigger; - - qa = lookup_queued_alarm (cqa, alarm_id); - if (!qa) - return; - - /* 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 = e_cal_component_get_alarm (comp, qa->instance->auid); - g_assert (alarm != NULL); - - e_cal_component_alarm_get_action (alarm, &action); - e_cal_component_alarm_free (alarm); - - switch (action) { - case E_CAL_COMPONENT_ALARM_AUDIO: - audio_notification (trigger, cqa, alarm_id); - break; - - case E_CAL_COMPONENT_ALARM_DISPLAY: - display_notification (trigger, cqa, alarm_id, TRUE); - break; - - case E_CAL_COMPONENT_ALARM_EMAIL: - mail_notification (trigger, cqa, alarm_id); - break; - - case E_CAL_COMPONENT_ALARM_PROCEDURE: - procedure_notification (trigger, cqa, alarm_id); - break; - - default: - g_assert_not_reached (); - break; - } -} - -/* Adds the alarms in a ECalComponentAlarms 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, ECalComponentAlarms *alarms) -{ - const char *uid; - CompQueuedAlarms *cqa; - GSList *l; - - /* No alarms? */ - if (alarms->alarms == NULL) { - e_cal_component_alarms_free (alarms); - return; - } - - cqa = g_new (CompQueuedAlarms, 1); - cqa->parent_client = ca; - cqa->alarms = alarms; - cqa->expecting_update = FALSE; - - cqa->queued_alarms = NULL; - - for (l = alarms->alarms; l; l = l->next) { - ECalComponentAlarmInstance *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); - } - - e_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); - - e_cal_component_alarms_free (cqa->alarms); - cqa->alarms = NULL; - - g_free (cqa); - return; - } - - cqa->queued_alarms = g_slist_reverse (cqa->queued_alarms); - cqa->uid = g_strdup (uid); - g_hash_table_insert (ca->uid_alarms_hash, cqa->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 = e_cal_get_alarms_in_range (ca->client, start, end); - - for (l = comp_alarms; l; l = l->next) { - ECalComponentAlarms *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 (ECal *client, ECalendarStatus status, gpointer data) -{ - ClientAlarms *ca; - - ca = data; - - if (status != E_CALENDAR_STATUS_OK) - 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); -} - -static void -remove_alarms (CompQueuedAlarms *cqa, gboolean free_object) -{ - GSList *l; - - 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, free_object, FALSE); - } - -} - -/* Removes a component an its alarms */ -static void -remove_comp (ClientAlarms *ca, const char *uid) -{ - CompQueuedAlarms *cqa; - - 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); - - remove_alarms (cqa, TRUE); - - /* 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 (ECal *client, const char *uid, gpointer data) -{ - ClientAlarms *ca; - time_t now, day_end; - ECalComponentAlarms *alarms; - gboolean found; - icaltimezone *zone; - CompQueuedAlarms *cqa; - - ca = data; - - now = time (NULL); - - zone = config_data_get_timezone (); - - day_end = time_day_end_with_zone (now, zone); - - found = e_cal_get_alarms_for_object (ca->client, uid, now, day_end, &alarms); - - if (!found) { - remove_comp (ca, uid); - return; - } - - cqa = lookup_comp_queued_alarms (ca, uid); - if (!cqa) - add_component_alarms (ca, alarms); - else { - GSList *l; - - /* if already in the list, just update it */ - remove_alarms (cqa, FALSE); - cqa->alarms = alarms; - cqa->queued_alarms = NULL; - - /* add the new alarms */ - for (l = cqa->alarms->alarms; l; l = l->next) { - ECalComponentAlarmInstance *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 ("obj_updated_cb(): 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); - } - - if (cqa->queued_alarms == NULL) { - if (!cqa->expecting_update) - remove_comp (ca, uid); - } else - cqa->queued_alarms = g_slist_reverse (cqa->queued_alarms); - } -} - -/* Called when a calendar component is removed; we must delete its corresponding - * alarms. - */ -static void -obj_removed_cb (ECal *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; - time_t t; - gpointer new_id; - - orig_qa = lookup_queued_alarm (cqa, alarm_id); - if (!orig_qa) - return; - - 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; - } - - orig_qa->instance->trigger = t; - orig_qa->alarm_id = new_id; - orig_qa->snooze = TRUE; -} - -/* Launches a component editor for a component */ -static void -edit_component (ECal *client, ECalComponent *comp) -{ - const char *uid; - const char *uri; - CORBA_Environment ev; - GNOME_Evolution_Calendar_CompEditorFactory factory; - - e_cal_component_get_uid (comp, &uid); - - uri = e_cal_get_uri (client); - - /* Get the factory */ - - CORBA_exception_init (&ev); - factory = bonobo_activation_activate_from_id ("OAFIID:GNOME_Evolution_Calendar_CompEditorFactory:" BASE_VERSION, - 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); -} - - -/* /\* Callback used from the alarm notify dialog *\/ */ -/* static void */ -/* notify_dialog_cb (AlarmNotifyResult result, int snooze_mins, gpointer data) */ -/* { */ - -/* switch (result) { */ -/* case ALARM_NOTIFY_SNOOZE: */ -/* create_snooze (c->cqa, c->alarm_id, snooze_mins); */ - -/* g_object_unref (c->comp); */ -/* g_object_unref (c->client); */ -/* g_free (c); */ -/* return; */ - -/* case ALARM_NOTIFY_EDIT: */ -/* edit_component (c->client, c->comp); */ -/* break; */ - -/* case ALARM_NOTIFY_CLOSE: */ -/* /\* Do nothing *\/ */ -/* break; */ - -/* default: */ -/* g_assert_not_reached (); */ -/* } */ - -/* if (c->cqa != NULL) */ -/* remove_queued_alarm (c->cqa, c->alarm_id, TRUE, TRUE); */ -/* g_object_unref (c->comp); */ -/* g_object_unref (c->client); */ -/* g_free (c); */ -/* } */ - -typedef struct { - char *message; - gboolean blink_state; - gint blink_id; - time_t trigger; - CompQueuedAlarms *cqa; - gpointer alarm_id; - ECalComponent *comp; - ECal *client; - GtkWidget *tray_icon; - GtkWidget *image; - GtkWidget *alarm_dialog; -} TrayIconData; - -static void -on_dialog_obj_updated_cb (ECal *client, const char *uid, gpointer data) -{ -/* commented out so gcc won't complain about the unused variable - struct notify_dialog_closure *c = data; -*/ -} - -static void -on_dialog_obj_removed_cb (ECal *client, const char *uid, gpointer data) -{ - const char *our_uid; - TrayIconData *tray_data = data; - - e_cal_component_get_uid (tray_data->comp, &our_uid); - g_return_if_fail (our_uid && *our_uid); - - if (!strcmp (uid, our_uid)) { - alarm_notify_dialog_disable_buttons (tray_data->alarm_dialog); - tray_data->cqa = NULL; - tray_data->alarm_id = NULL; - } -} - -/* Callback used from the alarm notify dialog */ -static void -notify_dialog_cb (AlarmNotifyResult result, int snooze_mins, gpointer data) -{ - TrayIconData *tray_data = data; - - g_signal_handlers_disconnect_matched (tray_data->client, G_SIGNAL_MATCH_FUNC, - 0, 0, NULL, on_dialog_obj_removed_cb, NULL); - - switch (result) { - case ALARM_NOTIFY_SNOOZE: - create_snooze (tray_data->cqa, tray_data->alarm_id, snooze_mins); - tray_data->cqa = NULL; - return; - - case ALARM_NOTIFY_EDIT: - edit_component (tray_data->client, tray_data->comp); - break; - - case ALARM_NOTIFY_CLOSE: - /* Do nothing */ - break; - - default: - g_assert_not_reached (); - } - - tray_data->alarm_dialog = NULL; - gtk_widget_destroy (tray_data->tray_icon); -} - -static gint -tray_icon_destroyed_cb (GtkWidget *tray, gpointer user_data) -{ - TrayIconData *tray_data = user_data; - - if (tray_data->cqa != NULL) - remove_queued_alarm (tray_data->cqa, tray_data->alarm_id, TRUE, TRUE); - - if (tray_data->message != NULL) { - g_free (tray_data->message); - tray_data->message = NULL; - } - - g_source_remove (tray_data->blink_id); - - g_object_unref (tray_data->comp); - g_object_unref (tray_data->client); - g_free (tray_data); - - return TRUE; -} - -static gint -tray_icon_clicked_cb (GtkWidget *widget, GdkEventButton *event, gpointer user_data) -{ - TrayIconData *tray_data = user_data; - - if (event->type == GDK_BUTTON_PRESS) { - if (event->button == 1) { - QueuedAlarm *qa; - - if (tray_data->alarm_dialog != NULL) - return FALSE; - - qa = lookup_queued_alarm (tray_data->cqa, tray_data->alarm_id); - if (qa) { - gtk_widget_hide (tray_data->tray_icon); - tray_data->alarm_dialog = alarm_notify_dialog ( - tray_data->trigger, - qa->instance->occur_start, - qa->instance->occur_end, - e_cal_component_get_vtype (tray_data->comp), - tray_data->message, - notify_dialog_cb, tray_data); - if (tray_data->alarm_dialog) { - g_signal_connect (G_OBJECT (tray_data->client), "obj_removed", - G_CALLBACK (on_dialog_obj_removed_cb), tray_data); - } - } - - return TRUE; - } else if (event->button == 2) { - return TRUE; - } - } - - return FALSE; -} - -static gboolean -tray_icon_blink_cb (gpointer data) -{ - TrayIconData *tray_data = data; - - /* FIXME: Use stock image equivalents when they become available */ - - tray_data->blink_state = tray_data->blink_state == TRUE ? FALSE : TRUE; - gtk_image_set_from_file (GTK_IMAGE (tray_data->image), - tray_data->blink_state == TRUE ? - EVOLUTION_IMAGESDIR "/appointment-reminder-excl.png" : - EVOLUTION_IMAGESDIR "/appointment-reminder.png"); - - return TRUE; -} - -/* Performs notification of a display alarm */ -static void -display_notification (time_t trigger, CompQueuedAlarms *cqa, - gpointer alarm_id, gboolean use_description) -{ - QueuedAlarm *qa; - ECalComponent *comp; - ECal *client; - ECalComponentVType vtype; - const char *message; - ECalComponentAlarm *alarm; - GtkWidget *tray_icon, *image, *ebox; - GtkTooltips *tooltips; - TrayIconData *tray_data; - ECalComponentText text; - char *str, *start_str, *end_str, *alarm_str; - icaltimezone *current_zone; - - comp = cqa->alarms->comp; - qa = lookup_queued_alarm (cqa, alarm_id); - if (!qa) - return; - - vtype = e_cal_component_get_vtype (comp); - - /* get a sensible description for the event */ - alarm = e_cal_component_get_alarm (comp, qa->instance->auid); - g_assert (alarm != NULL); - - e_cal_component_alarm_get_description (alarm, &text); - e_cal_component_alarm_free (alarm); - - if (text.value) - message = text.value; - else { - e_cal_component_get_summary (comp, &text); - if (text.value) - message = text.value; - else - message = _("No description available."); - } - - /* create the tray icon */ - tooltips = gtk_tooltips_new (); - - /* FIXME: Use stock image equivalent when it becomes available */ - tray_icon = egg_tray_icon_new (qa->instance->auid); - image = gtk_image_new_from_file (EVOLUTION_IMAGESDIR "/appointment-reminder.png"); - ebox = gtk_event_box_new (); - - gtk_widget_show (image); - gtk_widget_show (ebox); - - current_zone = config_data_get_timezone (); - alarm_str = timet_to_str_with_zone (trigger, current_zone); - start_str = timet_to_str_with_zone (qa->instance->occur_start, current_zone); - end_str = timet_to_str_with_zone (qa->instance->occur_end, current_zone); - str = g_strdup_printf (_("Alarm on %s\n%s\nStarting at %s\nEnding at %s"), - alarm_str, message, start_str, end_str); - gtk_tooltips_set_tip (GTK_TOOLTIPS (tooltips), ebox, str, str); - g_free (start_str); - g_free (end_str); - g_free (alarm_str); - g_free (str); - - g_object_set_data (G_OBJECT (tray_icon), "image", image); - g_object_set_data (G_OBJECT (tray_icon), "available", GINT_TO_POINTER (1)); - - gtk_container_add (GTK_CONTAINER (ebox), image); - gtk_container_add (GTK_CONTAINER (tray_icon), ebox); - - /* create the private structure */ - tray_data = g_new0 (TrayIconData, 1); - tray_data->message = g_strdup (message); - tray_data->trigger = trigger; - tray_data->cqa = cqa; - tray_data->alarm_id = alarm_id; - tray_data->comp = e_cal_component_clone (comp); - tray_data->client = cqa->parent_client->client; - tray_data->image = image; - tray_data->blink_state = FALSE; - g_object_ref (tray_data->client); - tray_data->tray_icon = tray_icon; - - g_signal_connect (G_OBJECT (tray_icon), "destroy", - G_CALLBACK (tray_icon_destroyed_cb), tray_data); - g_signal_connect (G_OBJECT (ebox), "button_press_event", - G_CALLBACK (tray_icon_clicked_cb), tray_data); - - tray_data->blink_id = g_timeout_add (500, tray_icon_blink_cb, tray_data); - - gtk_widget_show (tray_icon); -} - -/* Performs notification of an audio alarm */ -static void -audio_notification (time_t trigger, CompQueuedAlarms *cqa, - gpointer alarm_id) -{ - QueuedAlarm *qa; - ECalComponent *comp; - ECalComponentAlarm *alarm; - icalattach *attach; - - comp = cqa->alarms->comp; - qa = lookup_queued_alarm (cqa, alarm_id); - if (!qa) - return; - - alarm = e_cal_component_get_alarm (comp, qa->instance->auid); - g_assert (alarm != NULL); - - e_cal_component_alarm_get_attach (alarm, &attach); - e_cal_component_alarm_free (alarm); - - if (attach && icalattach_get_is_url (attach)) { - const char *url; - - url = icalattach_get_url (attach); - - if (url && *url && g_file_test (url, G_FILE_TEST_EXISTS)) - gnome_sound_play (url); /* this sucks */ - else - gdk_beep (); - } - - 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; - GtkWidget *label; - - /* FIXME */ - - display_notification (trigger, cqa, alarm_id, FALSE); - - dialog = gtk_dialog_new_with_buttons (_("Warning"), - NULL, 0, - GTK_STOCK_OK, GTK_RESPONSE_CANCEL, - NULL); - label = gtk_label_new (_("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.")); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), label, TRUE, TRUE, 4); - - gtk_dialog_run (GTK_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 = gtk_dialog_new_with_buttons (_("Warning"), - NULL, 0, - GTK_STOCK_NO, GTK_RESPONSE_CANCEL, - GTK_STOCK_YES, GTK_RESPONSE_OK, - 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 (GTK_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 (GTK_DIALOG (dialog)->vbox), - checkbox, TRUE, TRUE, 4); - - /* Run the dialog */ - btn = gtk_dialog_run (GTK_DIALOG (dialog)); - if (btn == GTK_RESPONSE_OK && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbox))) - save_blessed_program (url); - gtk_widget_destroy (dialog); - - return (btn == GTK_RESPONSE_OK); -} - -static void -procedure_notification (time_t trigger, CompQueuedAlarms *cqa, gpointer alarm_id) -{ - QueuedAlarm *qa; - ECalComponent *comp; - ECalComponentAlarm *alarm; - ECalComponentText description; - icalattach *attach; - const char *url; - char *cmd; - int result; - - comp = cqa->alarms->comp; - qa = lookup_queued_alarm (cqa, alarm_id); - if (!qa) - return; - - alarm = e_cal_component_get_alarm (comp, qa->instance->auid); - g_assert (alarm != NULL); - - e_cal_component_alarm_get_attach (alarm, &attach); - e_cal_component_alarm_get_description (alarm, &description); - e_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, TRUE, TRUE); - 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; -} - -static void -free_client_alarms_cb (gpointer key, gpointer value, gpointer user_data) -{ - ECal *client = key; - ClientAlarms *ca = value; - - if (ca) { - g_object_unref (ca->client); - g_free (ca); - } -} - -/** - * 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_foreach (client_alarms_hash, (GHFunc) free_client_alarms_cb, NULL); - 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 (ECal *client) -{ - ClientAlarms *ca; - - g_return_if_fail (alarm_queue_inited); - g_return_if_fail (client != NULL); - g_return_if_fail (E_IS_CAL (client)); - - ca = lookup_client (client); - if (ca) { - ca->refcount++; - return; - } - - ca = g_new (ClientAlarms, 1); - - ca->client = client; - g_object_ref (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 (e_cal_get_load_state (client) != E_CAL_LOAD_LOADED) - g_signal_connect (client, "cal_opened", - G_CALLBACK (cal_opened_cb), - ca); - - g_signal_connect (client, "obj_updated", - G_CALLBACK (obj_updated_cb), - ca); - g_signal_connect (client, "obj_removed", - G_CALLBACK (obj_removed_cb), - ca); - - if (e_cal_get_load_state (client) == E_CAL_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 (ECal *client) -{ - ClientAlarms *ca; - - g_return_if_fail (alarm_queue_inited); - g_return_if_fail (client != NULL); - g_return_if_fail (E_IS_CAL (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 */ - - g_signal_handlers_disconnect_matched (ca->client, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, ca); - - g_object_unref (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 12802750ec..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 <libecal/e-cal.h> - - -void alarm_queue_init (void); -void alarm_queue_done (void); - -void alarm_queue_add_client (ECal *client); -void alarm_queue_remove_client (ECal *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 3cad23d5cd..0000000000 --- a/calendar/gui/alarm-notify/config-data.c +++ /dev/null @@ -1,168 +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_CONFIOH -#include <config.h> -#endif - -#include <libedataserver/e-source-list.h> -#include "config-data.h" -#include "save.h" - - - -/* Whether we have initied ourselves by reading the data from the configuration engine */ -static gboolean inited = FALSE; -static GConfClient *conf_client = NULL; -static ESourceList *calendar_source_list = NULL, *tasks_source_list = NULL; - - - -/* 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'; -} - -static void -do_cleanup (void) -{ - if (calendar_source_list) { - g_object_unref (calendar_source_list); - calendar_source_list = NULL; - } - - if (tasks_source_list) { - g_object_unref (tasks_source_list); - tasks_source_list = NULL; - } - - g_object_unref (conf_client); - conf_client = NULL; - - inited = FALSE; -} - -/* Ensures that the configuration values have been read */ -static void -ensure_inited (void) -{ - if (inited) - return; - - inited = TRUE; - - conf_client = gconf_client_get_default (); - if (!GCONF_IS_CLIENT (conf_client)) { - inited = FALSE; - return; - } - - g_atexit ((GVoidFunc) do_cleanup); - - /* load the sources for calendars and tasks */ - calendar_source_list = e_source_list_new_for_gconf (conf_client, - "/apps/evolution/calendar/sources"); - tasks_source_list = e_source_list_new_for_gconf (conf_client, - "/apps/evolution/tasks/sources"); - -} - -GConfClient * -config_data_get_conf_client (void) -{ - ensure_inited (); - return conf_client; -} - -icaltimezone * -config_data_get_timezone (void) -{ - char *location; - icaltimezone *local_timezone; - - ensure_inited (); - - location = gconf_client_get_string (conf_client, - "/apps/evolution/calendar/display/timezone", - NULL); - if (location && location[0]) { - local_timezone = icaltimezone_get_builtin_timezone (location); - } else { - local_timezone = icaltimezone_get_utc_timezone (); - } - - g_free (location); - - return local_timezone; -} - -gboolean -config_data_get_24_hour_format (void) -{ - ensure_inited (); - - if (locale_supports_12_hour_format ()) { - return gconf_client_get_bool (conf_client, - "/apps/evolution/calendar/display/use_24hour_format", - NULL); - } - - return TRUE; -} - -GPtrArray * -config_data_get_calendars_to_load (void) -{ - GPtrArray *cals; - GSList *groups, *gl, *sources, *sl; - - ensure_inited (); - - /* create the array to be returned */ - cals = g_ptr_array_new (); - - /* process calendar sources */ - groups = e_source_list_peek_groups (calendar_source_list); - for (gl = groups; gl != NULL; gl = gl->next) { - sources = e_source_group_peek_sources (E_SOURCE_GROUP (gl->data)); - for (sl = sources; sl != NULL; sl = sl->next) { - g_ptr_array_add (cals, sl->data); - } - } - - /* process tasks sources */ - groups = e_source_list_peek_groups (tasks_source_list); - for (gl = groups; gl != NULL; gl = gl->next) { - sources = e_source_group_peek_sources (E_SOURCE_GROUP (gl->data)); - for (sl = sources; sl != NULL; sl = sl->next) { - g_ptr_array_add (cals, sl->data); - } - } - - return cals; -} diff --git a/calendar/gui/alarm-notify/config-data.h b/calendar/gui/alarm-notify/config-data.h deleted file mode 100644 index 26b5dc111f..0000000000 --- a/calendar/gui/alarm-notify/config-data.h +++ /dev/null @@ -1,34 +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 <libical/ical.h> -#include <gconf/gconf-client.h> - -GConfClient *config_data_get_conf_client (void); - -icaltimezone *config_data_get_timezone (void); -gboolean config_data_get_24_hour_format (void); -GPtrArray *config_data_get_calendars_to_load (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 6897d00857..0000000000 --- a/calendar/gui/alarm-notify/notify-main.c +++ /dev/null @@ -1,192 +0,0 @@ -/* Evolution calendar - Alarm notification service main file - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2003 Novell, 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. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <string.h> -#include <glib.h> -#include <libgnome/gnome-i18n.h> -#include <libgnome/gnome-init.h> -#include <libgnome/gnome-sound.h> -#include <libgnomeui/gnome-client.h> -#include <libgnomeui/gnome-ui-init.h> -#include <libgnomevfs/gnome-vfs-init.h> -#include <glade/glade.h> -#include <bonobo/bonobo-main.h> -#include <bonobo/bonobo-generic-factory.h> -#include <bonobo-activation/bonobo-activation.h> -#include <libedataserver/e-source.h> -#include "alarm.h" -#include "alarm-queue.h" -#include "alarm-notify.h" -#include "config-data.h" -#include "save.h" - - - -static GnomeClient *master_client = NULL; - -static BonoboGenericFactory *factory; - -static AlarmNotify *alarm_notify_service = NULL; - - -/* 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) -{ - bonobo_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); - - g_signal_connect (G_OBJECT (master_client), "die", - G_CALLBACK (client_die_cb), NULL); -} - -/* Factory function for the alarm notify service; just creates and references a - * singleton service object. - */ -static BonoboObject * -alarm_notify_factory_fn (BonoboGenericFactory *factory, const char *component_id, void *data) -{ - if (!alarm_notify_service) { - alarm_notify_service = alarm_notify_new (); - g_assert (alarm_notify_service != NULL); - } - - return NULL; -} - -/* Loads the calendars that the alarm daemon has been told to load in the past */ -static gboolean -load_calendars (gpointer user_data) -{ - GPtrArray *cals; - int i; - - alarm_queue_init (); - - /* create the alarm notification service */ - if (!alarm_notify_service) { - alarm_notify_service = alarm_notify_new (); - g_assert (alarm_notify_service != NULL); - } - - cals = config_data_get_calendars_to_load (); - if (!cals) { - g_message ("load_calendars(): Could not get the list of calendars to load"); - return TRUE; /* should we continue retrying? */; - } - - for (i = 0; i < cals->len; i++) { - ESource *source; - char *uri; - - source = cals->pdata[i]; - - uri = e_source_get_uri (source); - alarm_notify_add_calendar (alarm_notify_service, uri, FALSE); - g_free (uri); - } - - g_ptr_array_free (cals, TRUE); - - return FALSE; -} - -int -main (int argc, char **argv) -{ - bindtextdomain (GETTEXT_PACKAGE, EVOLUTION_LOCALEDIR); - bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - textdomain (GETTEXT_PACKAGE); - - gnome_program_init ("evolution-alarm-notify", VERSION, LIBGNOMEUI_MODULE, argc, argv, NULL); - gtk_init (&argc, &argv); - - if (bonobo_init (&argc, argv) == FALSE) - g_error (_("Could not initialize Bonobo")); - - if (!gnome_vfs_init ()) - g_error (_("Could not initialize gnome-vfs")); - - glade_init (); - - gnome_sound_init ("localhost"); - - factory = bonobo_generic_factory_new ("OAFIID:GNOME_Evolution_Calendar_AlarmNotify:" BASE_VERSION, - (BonoboFactoryCallback) alarm_notify_factory_fn, NULL); - if (!factory) - g_error (_("Could not create the alarm notify service factory")); - - set_session_parameters (argv); - - g_idle_add ((GSourceFunc) load_calendars, NULL); - - bonobo_main (); - - bonobo_object_unref (BONOBO_OBJECT (factory)); - factory = NULL; - - bonobo_object_unref (BONOBO_OBJECT (alarm_notify_service)); - - alarm_queue_done (); - alarm_done (); - - if (alarm_notify_service) - bonobo_object_unref (BONOBO_OBJECT (alarm_notify_service)); - - gnome_sound_shutdown (); - 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 d0b127fb99..0000000000 --- a/calendar/gui/alarm-notify/save.c +++ /dev/null @@ -1,142 +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 <string.h> -#include <bonobo/bonobo-arg.h> -#include <bonobo/bonobo-exception.h> -#include <bonobo/bonobo-moniker-util.h> -#include "evolution-calendar.h" -#include "config-data.h" -#include "save.h" -#include <gconf/gconf-client.h> - - - -/* Key names for the configuration values */ - -#define KEY_LAST_NOTIFICATION_TIME "/apps/evolution/calendar/notify/last_notification_time" -#define KEY_CALENDARS "/apps/evolution/calendar/notify/calendars" -#define KEY_PROGRAMS "/apps/evolution/calendar/notify/programs" - - - -/** - * 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) -{ - GConfClient *conf_client; - time_t current_t; - - g_return_if_fail (t != -1); - - if (!(conf_client = config_data_get_conf_client ())) - return; - - /* we only store the new notification time if it is bigger - than the already stored one */ - current_t = gconf_client_get_int (conf_client, KEY_LAST_NOTIFICATION_TIME, NULL); - if (t > current_t) - gconf_client_set_int (conf_client, KEY_LAST_NOTIFICATION_TIME, t, NULL); -} - -/** - * 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) -{ - GConfClient *conf_client; - long t; - - if (!(conf_client = config_data_get_conf_client ())) - return -1; - - t = gconf_client_get_int (conf_client, KEY_LAST_NOTIFICATION_TIME, NULL); - - return (time_t) t; -} - -/** - * save_blessed_program: - * @program: a program name - * - * Saves a program name as "blessed" - **/ -void -save_blessed_program (const char *program) -{ - GConfClient *conf_client; - GSList *l; - - if (!(conf_client = config_data_get_conf_client ())) - return; - - l = gconf_client_get_list (conf_client, KEY_PROGRAMS, GCONF_VALUE_STRING, NULL); - l = g_slist_append (l, g_strdup (program)); - gconf_client_set_list (conf_client, KEY_PROGRAMS, GCONF_VALUE_STRING, l, NULL); - g_slist_foreach (l, (GFunc) g_free, NULL); - g_slist_free (l); -} - -/** - * 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) -{ - GConfClient *conf_client; - GSList *l, *n; - gboolean found = FALSE; - - if (!(conf_client = config_data_get_conf_client ())) - return FALSE; - - l = gconf_client_get_list (conf_client, KEY_PROGRAMS, GCONF_VALUE_STRING, NULL); - while (l) { - n = l->next; - if (!found) - found = strcmp ((char *) l->data, program) == 0; - g_free (l->data); - g_slist_free_1 (l); - l = n; - } - - return found; -} diff --git a/calendar/gui/alarm-notify/save.h b/calendar/gui/alarm-notify/save.h deleted file mode 100644 index f7cc75955c..0000000000 --- a/calendar/gui/alarm-notify/save.h +++ /dev/null @@ -1,35 +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> - -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/alarm-notify/util.c b/calendar/gui/alarm-notify/util.c deleted file mode 100644 index 4bc91810a5..0000000000 --- a/calendar/gui/alarm-notify/util.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Evolution calendar - utility functions - * - * 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 <libgnome/gnome-i18n.h> -#include <e-util/e-time-utils.h> -#include <libecal/e-cal-time-util.h> -#include "config-data.h" -#include "util.h" - -/* Converts a time_t to a string, relative to the specified timezone */ -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); -} diff --git a/calendar/gui/alarm-notify/util.h b/calendar/gui/alarm-notify/util.h deleted file mode 100644 index 7dae3dd7fe..0000000000 --- a/calendar/gui/alarm-notify/util.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Evolution calendar - utility functions - * - * 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. - */ - -#ifndef UTIL_H -#define UTIL_H - -#include <libecal/e-cal-component.h> - -char *timet_to_str_with_zone (time_t t, icaltimezone *zone); - -#endif diff --git a/calendar/gui/apps_evolution_calendar.schemas.in.in b/calendar/gui/apps_evolution_calendar.schemas.in.in deleted file mode 100644 index 27e9aa44e2..0000000000 --- a/calendar/gui/apps_evolution_calendar.schemas.in.in +++ /dev/null @@ -1,359 +0,0 @@ -<gconfschemafile> - <schemalist> - - <!-- Display --> - - <schema> - <key>/schemas/apps/evolution/calendar/display/timezone</key> - <applyto>/apps/evolution/calendar/display/timezone</applyto> - <owner>evolution-calendar</owner> - <type>string</type> - <default>UTC</default> - <locale name="C"> - <short>Default timezone for meetings</short> - </locale> - </schema> - - <schema> - <key>/schemas/apps/evolution/calendar/display/use_24hour_format</key> - <applyto>/apps/evolution/calendar/display/use_24hour_format</applyto> - <owner>evolution-calendar</owner> - <type>bool</type> - <default>false</default> - <locale name="C"> - <short>Whether to show times in 24h format instead of using am/pm</short> - </locale> - </schema> - - <schema> - <key>/schemas/apps/evolution/calendar/display/week_start_day</key> - <applyto>/apps/evolution/calendar/display/week_start_day</applyto> - <owner>evolution-calendar</owner> - <type>int</type> - <default>1</default> - <locale name="C"> - <short>Weekday the week starts on</short> - </locale> - </schema> - - <schema> - <key>/schemas/apps/evolution/calendar/display/day_start_hour</key> - <applyto>/apps/evolution/calendar/display/day_start_hour</applyto> - <owner>evolution-calendar</owner> - <type>int</type> - <default>9</default> - <locale name="C"> - <short>Hour the workday starts on</short> - </locale> - </schema> - - <schema> - <key>/schemas/apps/evolution/calendar/display/day_start_minute</key> - <applyto>/apps/evolution/calendar/display/day_start_minute</applyto> - <owner>evolution-calendar</owner> - <type>int</type> - <default>0</default> - <locale name="C"> - <short>Minute the workday starts on</short> - </locale> - </schema> - - <schema> - <key>/schemas/apps/evolution/calendar/display/day_end_hour</key> - <applyto>/apps/evolution/calendar/display/day_end_hour</applyto> - <owner>evolution-calendar</owner> - <type>int</type> - <default>17</default> - <locale name="C"> - <short>Hour the workday ends on</short> - </locale> - </schema> - - <schema> - <key>/schemas/apps/evolution/calendar/display/day_end_minute</key> - <applyto>/apps/evolution/calendar/display/day_end_minute</applyto> - <owner>evolution-calendar</owner> - <type>int</type> - <default>0</default> - <locale name="C"> - <short>Minute the workday ends on</short> - </locale> - </schema> - - <schema> - <key>/schemas/apps/evolution/calendar/display/time_divisions</key> - <applyto>/apps/evolution/calendar/display/time_divisions</applyto> - <owner>evolution-calendar</owner> - <type>int</type> - <default>30</default> - <locale name="C"> - <short>Intervals shown in Day and Work Week views</short> - </locale> - </schema> - - <schema> - <key>/schemas/apps/evolution/calendar/display/default_view</key> - <applyto>/apps/evolution/calendar/display/default_view</applyto> - <owner>evolution-calendar</owner> - <type>int</type> - <default>0</default> - <locale name="C"> - <short>The view showing when the calendar starts</short> - </locale> - </schema> - - <schema> - <key>/schemas/apps/evolution/calendar/display/hpane_position</key> - <applyto>/apps/evolution/calendar/display/hpane_position</applyto> - <owner>evolution-calendar</owner> - <type>int</type> - <default>400</default> - <locale name="C"> - <short>Position of the horizontal pane</short> - </locale> - </schema> - - <schema> - <key>/schemas/apps/evolution/calendar/display/vpane_position</key> - <applyto>/apps/evolution/calendar/display/vpane_position</applyto> - <owner>evolution-calendar</owner> - <type>int</type> - <default>150</default> - <locale name="C"> - <short>Position of the vertical pane</short> - </locale> - </schema> - - <schema> - <key>/schemas/apps/evolution/calendar/display/month_hpane_position</key> - <applyto>/apps/evolution/calendar/display/month_hpane_position</applyto> - <owner>evolution-calendar</owner> - <type>int</type> - <default>32000</default> - <locale name="C"> - <short>Position of the horizontal pane in the month view</short> - </locale> - </schema> - - <schema> - <key>/schemas/apps/evolution/calendar/display/month_vpane_position</key> - <applyto>/apps/evolution/calendar/display/month_vpane_position</applyto> - <owner>evolution-calendar</owner> - <type>int</type> - <default>150</default> - <locale name="C"> - <short>Position of the vertical pane in the month view</short> - </locale> - </schema> - - <schema> - <key>/schemas/apps/evolution/calendar/display/task_vpane_position</key> - <applyto>/apps/evolution/calendar/display/task_vpane_position</applyto> - <owner>evolution-calendar</owner> - <type>int</type> - <default>400</default> - <locale name="C"> - <short>Position of the vertical pane in the task view</short> - </locale> - </schema> - - <schema> - <key>/schemas/apps/evolution/calendar/display/compress_weekend</key> - <applyto>/apps/evolution/calendar/display/compress_weekend</applyto> - <owner>evolution-calendar</owner> - <type>bool</type> - <default>true</default> - <locale name="C"> - <short>Allocate less space to weekend appointments</short> - </locale> - </schema> - - <schema> - <key>/schemas/apps/evolution/calendar/display/show_event_end</key> - <applyto>/apps/evolution/calendar/display/show_event_end</applyto> - <owner>evolution-calendar</owner> - <type>bool</type> - <default>true</default> - <locale name="C"> - <short>Show where events end in week and month views</short> - </locale> - </schema> - - <schema> - <key>/schemas/apps/evolution/calendar/display/working_days</key> - <applyto>/apps/evolution/calendar/display/working_days</applyto> - <owner>evolution-calendar</owner> - <type>int</type> - <default>62</default> - <locale name="C"> - <short>Days that are work days</short> - </locale> - </schema> - - <!-- Tasks --> - - <schema> - <key>/schemas/apps/evolution/calendar/tasks/hide_completed</key> - <applyto>/apps/evolution/calendar/tasks/hide_completed</applyto> - <owner>evolution-calendar</owner> - <type>bool</type> - <default>false</default> - <locale name="C"> - <short>Whether to hide completed tasks</short> - </locale> - </schema> - - <schema> - <key>/schemas/apps/evolution/calendar/tasks/hide_completed_units</key> - <applyto>/apps/evolution/calendar/tasks/hide_completed_units</applyto> - <owner>evolution-calendar</owner> - <type>string</type> - <default>days</default> - <locale name="C"> - <short>Units for determining when to hide tasks</short> - </locale> - </schema> - - <schema> - <key>/schemas/apps/evolution/calendar/tasks/hide_completed_value</key> - <applyto>/apps/evolution/calendar/tasks/hide_completed_value</applyto> - <owner>evolution-calendar</owner> - <type>int</type> - <default>1</default> - <locale name="C"> - <short>Number of units for determining when to hide tasks</short> - </locale> - </schema> - - <!-- Tasks: Colors --> - - <schema> - <key>/schemas/apps/evolution/calendar/tasks/colors/due_today</key> - <applyto>/apps/evolution/calendar/tasks/colors/due_today</applyto> - <owner>evolution-calendar</owner> - <type>string</type> - <default>blue</default> - <locale name="C"> - <short>Color of tasks that are due today</short> - </locale> - </schema> - - <schema> - <key>/schemas/apps/evolution/calendar/tasks/colors/overdue</key> - <applyto>/apps/evolution/calendar/tasks/colors/overdue</applyto> - <owner>evolution-calendar</owner> - <type>string</type> - <default>red</default> - <locale name="C"> - <short>Color of tasks that are overdue</short> - </locale> - </schema> - - <!-- Miscellaneous --> - - <schema> - <key>/schemas/apps/evolution/calendar/prompts/confirm_delete</key> - <applyto>/apps/evolution/calendar/prompts/confirm_delete</applyto> - <owner>evolution-calendar</owner> - <type>bool</type> - <default>true</default> - <locale name="C"> - <short>Whether to ask for confirmation on appointment deletion</short> - </locale> - </schema> - - <schema> - <key>/schemas/apps/evolution/calendar/prompts/confirm_expunge</key> - <applyto>/apps/evolution/calendar/prompts/confirm_expunge</applyto> - <owner>evolution-calendar</owner> - <type>bool</type> - <default>true</default> - <locale name="C"> - <short>Whether to ask for confirmation when folder is expunged</short> - </locale> - </schema> - - <schema> - <key>/schemas/apps/evolution/calendar/other/use_default_reminder</key> - <applyto>/apps/evolution/calendar/other/use_default_reminder</applyto> - <owner>evolution-calendar</owner> - <type>bool</type> - <default>false</default> - <locale name="C"> - <short>Whether to set a default reminder for events</short> - </locale> - </schema> - - <schema> - <key>/schemas/apps/evolution/calendar/other/default_reminder_interval</key> - <applyto>/apps/evolution/calendar/other/default_reminder_interval</applyto> - <owner>evolution-calendar</owner> - <type>int</type> - <default>15</default> - <locale name="C"> - <short>Number of units for default reminder</short> - </locale> - </schema> - - <schema> - <key>/schemas/apps/evolution/calendar/other/default_reminder_units</key> - <applyto>/apps/evolution/calendar/other/default_reminder_units</applyto> - <owner>evolution-calendar</owner> - <type>string</type> - <default></default> - <locale name="C"> - <short>Units of default reminder</short> - </locale> - </schema> - - <!-- Date navigator --> - - <schema> - <key>/schemas/apps/evolution/calendar/date_navigator/show_week_numbers</key> - <applyto>/apps/evolution/calendar/date_navigator/show_week_numbers</applyto> - <owner>evolution-calendar</owner> - <type>bool</type> - <default>false</default> - <locale name="C"> - <short>Whether to show week numbers in date navigator</short> - </locale> - </schema> - - <!-- Alarm notification --> - - <schema> - <key>/schemas/apps/evolution/calendar/notify/last_notification_time</key> - <applyto>/apps/evolution/calendar/notify/last_notification_time</applyto> - <owner>evolution-calendar</owner> - <type>int</type> - <default>-1</default> - <locale name="C"> - <short>Time last alarm ran</short> - </locale> - </schema> - - <schema> - <key>/schemas/apps/evolution/calendar/notify/calendars</key> - <applyto>/apps/evolution/calendar/notify/calendars</applyto> - <owner>evolution-calendar</owner> - <type>list</type> - <list_type>string</list_type> - <default>[]</default> - <locale name="C"> - <short>Calendars to run alarms for</short> - </locale> - </schema> - - <schema> - <key>/schemas/apps/evolution/calendar/notify/programs</key> - <applyto>/apps/evolution/calendar/notify/programs</applyto> - <owner>evolution-calendar</owner> - <type>list</type> - <list_type>string</list_type> - <default>[]</default> - <locale name="C"> - <short>Programs that can run as part of alarms</short> - </locale> - </schema> - </schemalist> -</gconfschemafile> diff --git a/calendar/gui/cal-search-bar.c b/calendar/gui/cal-search-bar.c deleted file mode 100644 index 477a6d91a7..0000000000 --- a/calendar/gui/cal-search-bar.c +++ /dev/null @@ -1,513 +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-i18n.h> -#include <gal/util/e-util.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 }; - - - -E_MAKE_TYPE (cal_search_bar, "CalSearchBar", CalSearchBar, cal_search_bar_class_init, - cal_search_bar_init, E_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 = g_type_class_peek_parent (class); - - cal_search_bar_signals[SEXP_CHANGED] = - gtk_signal_new ("sexp_changed", - GTK_RUN_FIRST, - G_TYPE_FROM_CLASS (object_class), - 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, - G_TYPE_FROM_CLASS (object_class), - GTK_SIGNAL_OFFSET (CalSearchBarClass, category_changed), - gtk_marshal_NONE__STRING, - GTK_TYPE_NONE, 1, - GTK_TYPE_STRING); - - 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) { - 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_e_cal_view_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_e_cal_view_contains (cal_search, "any"); - break; - - case SEARCH_SUMMARY_CONTAINS: - notify_e_cal_view_contains (cal_search, "summary"); - break; - - case SEARCH_DESCRIPTION_CONTAINS: - notify_e_cal_view_contains (cal_search, "description"); - break; - - case SEARCH_COMMENT_CONTAINS: - notify_e_cal_view_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 = g_strdup (category ? category : ""); - - 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 = g_object_new (TYPE_CAL_SEARCH_BAR, NULL); - 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 a8910ba7b4..0000000000 --- a/calendar/gui/cal-search-bar.h +++ /dev/null @@ -1,70 +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 "widgets/misc/e-search-bar.h" -#include "widgets/misc/e-filter-bar.h" - -G_BEGIN_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); - - - -G_END_DECLS - -#endif diff --git a/calendar/gui/calendar-commands.c b/calendar/gui/calendar-commands.c deleted file mode 100644 index 3ed09c3bc7..0000000000 --- a/calendar/gui/calendar-commands.c +++ /dev/null @@ -1,810 +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> - * 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 <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/gtklabel.h> -#include <gtk/gtkmain.h> -#include <gtk/gtksignal.h> -#include <gtk/gtkspinbutton.h> -#include <gtk/gtkmessagedialog.h> -#include <libgnome/gnome-util.h> -#include <libgnomeui/gnome-dialog-util.h> -#include <libgnomeui/gnome-messagebox.h> -#include <libgnomeui/gnome-stock-icons.h> -#include <libgnome/gnome-util.h> -#include <libgnome/gnome-i18n.h> -#include <bonobo/bonobo-ui-util.h> -#include <bonobo/bonobo-exception.h> -#include <gal/util/e-util.h> -#include <libecal/e-cal-time-util.h> -#include "shell/Evolution.h" -#include "calendar-commands.h" -#include "calendar-config.h" -#include "e-day-view.h" -#include "e-week-view.h" -#include "gnome-cal.h" -#include "goto.h" -#include "print.h" -#include "dialogs/cal-prefs-dialog.h" -#include "dialogs/new-calendar.h" -#include "itip-utils.h" -#include "evolution-shell-component-utils.h" - -/* 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; - -static void -file_new_calendar_cb (BonoboUIComponent *uic, gpointer data, const char *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - new_calendar_dialog (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (gcal)))); -} - -/* 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); -} - -/* 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 -show_list_view_clicked (BonoboUIComponent *uic, gpointer data, const char *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - gnome_calendar_set_view (gcal, GNOME_CAL_LIST_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 -delete_occurrence_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - set_clock_cursor (gcal); - gnome_calendar_delete_selected_occurrence (gcal); - set_normal_cursor (gcal); -} - -static void -publish_freebusy_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path) -{ - GnomeCalendar *gcal; - GList *client_list, *cl; - GList *comp_list = NULL; - 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); - - /* FIXME Should we aggregate the data? */ - client_list = e_cal_model_get_client_list (gnome_calendar_get_calendar_model (gcal)); - for (cl = client_list; cl != NULL; cl = cl->next) { - if (e_cal_get_free_busy ((ECal *) cl->data, NULL, start, end, &comp_list, NULL)) { - GList *l; - - for (l = comp_list; l; l = l->next) { - ECalComponent *comp = E_CAL_COMPONENT (l->data); - itip_send_comp (E_CAL_COMPONENT_METHOD_PUBLISH, comp, (ECal *) cl->data, NULL); - - g_object_unref (comp); - } - - g_list_free (comp_list); - } - } - - g_list_free (client_list); -} - -static void -purge_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path) -{ - GnomeCalendar *gcal; - GtkWidget *dialog, *parent, *box, *label, *spin; - int response; - - gcal = GNOME_CALENDAR (data); - - /* create the dialog */ - parent = gtk_widget_get_toplevel (GTK_WIDGET (gcal)); - dialog = gtk_message_dialog_new ( - (GtkWindow *)parent, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_WARNING, - GTK_BUTTONS_OK_CANCEL, - _("This operation will permanently erase all events older than the selected amount of time. If you continue, you will not be able to recover these events.")); - gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL); - - box = gtk_hbox_new (FALSE, 6); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), box, TRUE, FALSE, 6); - - label = gtk_label_new (_("Purge events older than")); - gtk_box_pack_start (GTK_BOX (box), label, TRUE, FALSE, 6); - spin = gtk_spin_button_new_with_range (0.0, 1000.0, 1.0); - gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), 60.0); - gtk_box_pack_start (GTK_BOX (box), spin, FALSE, FALSE, 6); - label = gtk_label_new (_("days")); - gtk_box_pack_start (GTK_BOX (box), label, TRUE, FALSE, 6); - - gtk_widget_show_all (box); - - /* run the dialog */ - response = gtk_dialog_run (GTK_DIALOG (dialog)); - if (response == GTK_RESPONSE_OK) { - gint days; - time_t tt; - - days = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin)); - tt = time (NULL); - tt -= (days * (24 * 3600)); - - gnome_calendar_purge (gcal, tt); - } - - gtk_widget_destroy (dialog); -} - - -const gchar * -calendar_get_text_for_folder_bar_label (GnomeCalendar *gcal) -{ - icaltimezone *zone; - struct icaltimetype start_tt, end_tt; - time_t start_time, end_time; - struct tm start_tm, end_tm; - static char buffer[512]; - char 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) { - e_utf8_strftime (buffer, sizeof (buffer), - _("%A %d %B %Y"), &start_tm); - } else if (start_tm.tm_year == end_tm.tm_year) { - e_utf8_strftime (buffer, sizeof (buffer), - _("%a %d %b"), &start_tm); - e_utf8_strftime (end_buffer, sizeof (end_buffer), - _("%a %d %b %Y"), &end_tm); - strcat (buffer, " - "); - strcat (buffer, end_buffer); - } else { - e_utf8_strftime (buffer, sizeof (buffer), - _("%a %d %b %Y"), &start_tm); - e_utf8_strftime (end_buffer, sizeof (end_buffer), - _("%a %d %b %Y"), &end_tm); - strcat (buffer, " - "); - strcat (buffer, end_buffer); - } - break; - case GNOME_CAL_MONTH_VIEW: - case GNOME_CAL_LIST_VIEW: - if (start_tm.tm_year == end_tm.tm_year) { - if (start_tm.tm_mon == end_tm.tm_mon) { - if (start_tm.tm_mday == end_tm.tm_mday) { - buffer [0] = '\0'; - } else { - e_utf8_strftime (buffer, sizeof (buffer), - "%d", &start_tm); - strcat (buffer, " - "); - } - e_utf8_strftime (end_buffer, sizeof (end_buffer), - _("%d %B %Y"), &end_tm); - strcat (buffer, end_buffer); - } else { - e_utf8_strftime (buffer, sizeof (buffer), - _("%d %B"), &start_tm); - e_utf8_strftime (end_buffer, sizeof (end_buffer), - _("%d %B %Y"), &end_tm); - strcat (buffer, " - "); - strcat (buffer, end_buffer); - } - } else { - e_utf8_strftime (buffer, sizeof (buffer), - _("%d %B %Y"), &start_tm); - e_utf8_strftime (end_buffer, sizeof (end_buffer), - _("%d %B %Y"), &end_tm); - strcat (buffer, " - "); - strcat (buffer, end_buffer); - } - break; - default: - g_assert_not_reached (); - return NULL; - } - return buffer; -} - - -/* Sensitizes the UI Component menu/toolbar calendar commands based on the - * number of selected events. (This will always be 0 or 1 currently.) If enable - * is FALSE, all will be disabled. Otherwise, the currently-selected number of - * events will be used. - */ -void -calendar_control_sensitize_calendar_commands (BonoboControl *control, GnomeCalendar *gcal, gboolean enable) -{ - BonoboUIComponent *uic; - ECalendarViewEvent *event; - GList *list; - int n_selected; - GtkWidget *view; - ECal *e_cal; - gboolean read_only = FALSE, has_recurrences; - - uic = bonobo_control_get_ui_component (control); - g_assert (uic != NULL); - - view = gnome_calendar_get_current_view_widget (gcal); - list = e_calendar_view_get_selected_events (E_CALENDAR_VIEW (view)); - - n_selected = enable ? g_list_length (list) : 0; - - event = (ECalendarViewEvent *) list ? list->data : NULL; - if (event) { - e_cal_is_read_only (event->comp_data->client, &read_only, NULL); - } else { - e_cal = e_cal_model_get_default_client (gnome_calendar_get_calendar_model (gcal)); - if (e_cal) - e_cal_is_read_only (e_cal, &read_only, NULL); - else - read_only = TRUE; - } - - bonobo_ui_component_set_prop (uic, "/commands/Cut", "sensitive", - n_selected == 0 || read_only ? "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 && !read_only ? "1" : "0", - NULL); - bonobo_ui_component_set_prop (uic, "/commands/Delete", "sensitive", - n_selected == 0 || read_only ? "0" : "1", - NULL); - - /* occurrence-related menu items */ - has_recurrences = FALSE; - if (n_selected > 0 && !read_only) { - if (list) { - event = (ECalendarViewEvent *) list->data; - if (e_cal_util_component_has_recurrences (event->comp_data->icalcomp)) - has_recurrences = TRUE; - } - } - - bonobo_ui_component_set_prop (uic, "/commands/DeleteOccurrence", "sensitive", - has_recurrences ? "1" : "0", - NULL); - bonobo_ui_component_set_prop (uic, "/commands/DeleteAllOccurrences", "sensitive", - has_recurrences ? "1" : "0", - NULL); - - /* free memory */ - if (list) - g_list_free (list); -} - -/* Sensitizes the UI Component menu/toolbar tasks commands based on the number - * 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; - ECal *e_cal; - gboolean read_only = TRUE; - - uic = bonobo_control_get_ui_component (control); - g_assert (uic != NULL); - - n_selected = enable ? gnome_calendar_get_num_tasks_selected (gcal) : 0; - e_cal = gnome_calendar_get_task_pad_e_cal (gcal); - if (e_cal) - e_cal_is_read_only (e_cal, &read_only, NULL); - else - read_only = TRUE; - - bonobo_ui_component_set_prop (uic, "/commands/Cut", "sensitive", - n_selected == 0 || read_only ? "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 && !read_only ? "1" : "0", - NULL); - bonobo_ui_component_set_prop (uic, "/commands/Delete", "sensitive", - n_selected == 0 || read_only ? "0" : "1", - NULL); -} - -/* 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); - - calendar_control_sensitize_calendar_commands (control, gcal, 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 = g_object_get_data (G_OBJECT (control), "focus_data"); - g_assert (focus != NULL); - - if (in) { - g_signal_connect (gcal, "calendar_selection_changed", - G_CALLBACK (gcal_calendar_selection_changed_cb), control); - calendar_control_sensitize_calendar_commands (control, gcal, TRUE); - focus->calendar_focused = TRUE; - } else if (focus->calendar_focused) { - gtk_signal_disconnect_by_func (GTK_OBJECT (gcal), - G_CALLBACK (gcal_calendar_selection_changed_cb), - control); - calendar_control_sensitize_calendar_commands (control, gcal, 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 = g_object_get_data (G_OBJECT (control), "focus_data"); - g_assert (focus != NULL); - - if (in) { - g_signal_connect (gcal, "taskpad_selection_changed", - G_CALLBACK (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), - G_CALLBACK (gcal_taskpad_selection_changed_cb), - control); - sensitize_taskpad_commands (gcal, control, FALSE); - focus->taskpad_focused = FALSE; - } - -} - - -static BonoboUIVerb verbs [] = { - BONOBO_UI_VERB ("NewCalendar", file_new_calendar_cb), - BONOBO_UI_VERB ("CalendarPrint", file_print_cb), - BONOBO_UI_VERB ("CalendarPrintPreview", file_print_preview_cb), - - BONOBO_UI_VERB ("Cut", cut_cmd), - BONOBO_UI_VERB ("Copy", copy_cmd), - BONOBO_UI_VERB ("Paste", paste_cmd), - BONOBO_UI_VERB ("Delete", delete_cmd), - BONOBO_UI_VERB ("DeleteOccurrence", delete_occurrence_cmd), - BONOBO_UI_VERB ("DeleteAllOccurrences", delete_cmd), - - BONOBO_UI_VERB ("CalendarPrev", previous_clicked), - BONOBO_UI_VERB ("CalendarToday", today_clicked), - BONOBO_UI_VERB ("CalendarNext", next_clicked), - BONOBO_UI_VERB ("CalendarGoto", goto_clicked), - - BONOBO_UI_VERB ("ShowDayView", show_day_view_clicked), - BONOBO_UI_VERB ("ShowWorkWeekView", show_work_week_view_clicked), - BONOBO_UI_VERB ("ShowWeekView", show_week_view_clicked), - BONOBO_UI_VERB ("ShowMonthView", show_month_view_clicked), - BONOBO_UI_VERB ("ShowListView", show_list_view_clicked), - - BONOBO_UI_VERB ("PublishFreeBusy", publish_freebusy_cmd), - BONOBO_UI_VERB ("CalendarPurge", purge_cmd), - - BONOBO_UI_VERB_END -}; - -static EPixmap pixmaps [] = -{ - E_PIXMAP ("/Toolbar/DayView", "buttons/dayview.xpm"), - E_PIXMAP ("/Toolbar/WorkWeekView", "buttons/workweekview.xpm"), - E_PIXMAP ("/Toolbar/WeekView", "buttons/weekview.xpm"), - E_PIXMAP ("/Toolbar/MonthView", "buttons/monthview.xpm"), - E_PIXMAP ("/Toolbar/ListView", "buttons/listview.xpm"), - - E_PIXMAP_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, NULL); - bonobo_ui_component_set_container (uic, remote_uih, NULL); - 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, PREFIX, - EVOLUTION_UIDIR "/evolution-calendar.xml", - "evolution-calendar", - NULL); - - e_pixmaps_update (uic, pixmaps); - - gnome_calendar_setup_view_menus (gcal, uic); - - g_signal_connect (gcal, "calendar_focus_change", - G_CALLBACK (gcal_calendar_focus_change_cb), control); - g_signal_connect (gcal, "taskpad_focus_change", - G_CALLBACK (gcal_taskpad_focus_change_cb), control); - - calendar_control_sensitize_calendar_commands (control, gcal, 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 - - focus = g_new (FocusData, 1); - focus->calendar_focused = FALSE; - focus->taskpad_focused = FALSE; - - g_object_set_data (G_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 = g_object_get_data (G_OBJECT (control), "focus_data"); - g_assert (focus != NULL); - - g_object_set_data (G_OBJECT (control), "focus_data", NULL); - g_free (focus); - - gnome_calendar_discard_view_menus (gcal); - - g_signal_handlers_disconnect_matched (gcal, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, control); - - bonobo_ui_component_rm (uic, "/", NULL); - bonobo_ui_component_unset_container (uic, NULL); -} diff --git a/calendar/gui/calendar-commands.h b/calendar/gui/calendar-commands.h deleted file mode 100644 index 901d01d845..0000000000 --- a/calendar/gui/calendar-commands.h +++ /dev/null @@ -1,42 +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> - -void calendar_control_activate (BonoboControl *control, GnomeCalendar *gcal); -void calendar_control_deactivate (BonoboControl *control, GnomeCalendar *gcal); - -void calendar_control_sensitize_calendar_commands (BonoboControl *control, GnomeCalendar *gcal, gboolean enable); - -void calendar_goto_today (GnomeCalendar *gcal); - -const gchar * calendar_get_text_for_folder_bar_label (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 455ede19ba..0000000000 --- a/calendar/gui/calendar-component.c +++ /dev/null @@ -1,902 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* calendar-component.c - * - * Copyright (C) 2003 Ettore Perazzoli - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * 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> - * Rodrigo Moya <rodrigo@ximian.com> - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <errno.h> -#include <bonobo/bonobo-control.h> -#include <bonobo/bonobo-i18n.h> -#include <bonobo/bonobo-exception.h> -#include "calendar-config.h" -#include "calendar-component.h" -#include "calendar-commands.h" -#include "gnome-cal.h" -#include "migration.h" -#include "e-comp-editor-registry.h" -#include "comp-util.h" -#include "dialogs/new-calendar.h" -#include "dialogs/comp-editor.h" -#include "dialogs/copy-source-dialog.h" -#include "dialogs/event-editor.h" -#include "widgets/misc/e-source-selector.h" - - -/* IDs for user creatable items */ -#define CREATE_EVENT_ID "event" -#define CREATE_MEETING_ID "meeting" -#define CREATE_ALLDAY_EVENT_ID "allday-event" - -#define PARENT_TYPE bonobo_object_get_type () -static BonoboObjectClass *parent_class = NULL; - -struct _CalendarComponentPrivate { - char *config_directory; - - GConfClient *gconf_client; - ESourceList *source_list; - GSList *source_selection; - - GnomeCalendar *calendar; - GtkWidget *source_selector; - - ECal *create_ecal; - - GList *notifications; - - EActivityHandler *activity_handler; -}; - -/* FIXME This should be gnome cal likely */ -extern ECompEditorRegistry *comp_editor_registry; - -/* Utility functions. */ - -static void -add_uri_for_source (ESource *source, GnomeCalendar *calendar) -{ - char *uri = e_source_get_uri (source); - - gnome_calendar_add_event_uri (calendar, uri); - g_free (uri); -} - -static void -remove_uri_for_source (ESource *source, GnomeCalendar *calendar) -{ - char *uri = e_source_get_uri (source); - - gnome_calendar_remove_event_uri (calendar, uri); - g_free (uri); -} - -static gboolean -is_in_selection (GSList *selection, ESource *source) -{ - GSList *l; - - for (l = selection; l; l = l->next) { - ESource *selected_source = l->data; - - if (!strcmp (e_source_peek_uid (selected_source), e_source_peek_uid (source))) - return TRUE; - } - - return FALSE; -} - -static gboolean -is_in_uids (GSList *uids, ESource *source) -{ - GSList *l; - - for (l = uids; l; l = l->next) { - const char *uid = l->data; - - if (!strcmp (uid, e_source_peek_uid (source))) - return TRUE; - } - - return FALSE; -} - -static ESource * -find_first_source (ESourceList *source_list) -{ - GSList *groups, *sources, *l, *m; - - groups = e_source_list_peek_groups (source_list); - for (l = groups; l; l = l->next) { - ESourceGroup *group = l->data; - - sources = e_source_group_peek_sources (group); - for (m = sources; m; m = m->next) { - ESource *source = m->data; - - return source; - } - } - - return NULL; -} - -static void -update_uris_for_selection (CalendarComponent *calendar_component) -{ - CalendarComponentPrivate *priv; - GSList *selection, *l, *uids_selected = NULL; - - priv = calendar_component->priv; - - selection = e_source_selector_get_selection (E_SOURCE_SELECTOR (priv->source_selector)); - - for (l = priv->source_selection; l; l = l->next) { - ESource *old_selected_source = l->data; - - if (!is_in_selection (selection, old_selected_source)) - remove_uri_for_source (old_selected_source, priv->calendar); - } - - for (l = selection; l; l = l->next) { - ESource *selected_source = l->data; - - add_uri_for_source (selected_source, priv->calendar); - uids_selected = g_slist_append (uids_selected, (char *)e_source_peek_uid (selected_source)); - } - - e_source_selector_free_selection (priv->source_selection); - priv->source_selection = selection; - - /* Save the selection for next time we start up */ - calendar_config_set_calendars_selected (uids_selected); - g_slist_free (uids_selected); -} - -static void -update_uri_for_primary_selection (CalendarComponent *calendar_component) -{ - CalendarComponentPrivate *priv; - ESource *source; - char *uri; - - priv = calendar_component->priv; - - source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (priv->source_selector)); - if (!source) - return; - - /* Set the default */ - uri = e_source_get_uri (source); - gnome_calendar_set_default_uri (priv->calendar, uri); - g_free (uri); - - /* Save the selection for next time we start up */ - calendar_config_set_primary_calendar (e_source_peek_uid (source)); -} - -static void -update_selection (CalendarComponent *calendar_component) -{ - CalendarComponentPrivate *priv; - GSList *selection, *uids_selected, *l; - - priv = calendar_component->priv; - - /* Get the selection in gconf */ - uids_selected = calendar_config_get_calendars_selected (); - - /* Remove any that aren't there any more */ - selection = e_source_selector_get_selection (E_SOURCE_SELECTOR (priv->source_selector)); - - for (l = selection; l; l = l->next) { - ESource *source = l->data; - - if (!is_in_uids (uids_selected, source)) - e_source_selector_unselect_source (E_SOURCE_SELECTOR (priv->source_selector), source); - } - - e_source_selector_free_selection (selection); - - /* Make sure the whole selection is there */ - for (l = uids_selected; l; l = l->next) { - char *uid = l->data; - ESource *source; - - source = e_source_list_peek_source_by_uid (priv->source_list, uid); - if (source) - e_source_selector_select_source (E_SOURCE_SELECTOR (priv->source_selector), source); - - g_free (uid); - } - g_slist_free (uids_selected); -} - -static void -update_primary_selection (CalendarComponent *calendar_component) -{ - CalendarComponentPrivate *priv; - ESource *source; - char *uid; - - priv = calendar_component->priv; - - uid = calendar_config_get_primary_calendar (); - if (uid) { - source = e_source_list_peek_source_by_uid (priv->source_list, uid); - g_free (uid); - - e_source_selector_set_primary_selection (E_SOURCE_SELECTOR (priv->source_selector), source); - } else { - ESource *source; - - /* Try to create a default if there isn't one */ - source = find_first_source (priv->source_list); - if (source) - e_source_selector_set_primary_selection (E_SOURCE_SELECTOR (priv->source_selector), source); - } -} - -/* FIXME This is duplicated from comp-editor-factory.c, should it go in comp-util? */ -static ECalComponent * -get_default_event (ECal *client, gboolean all_day) -{ - ECalComponent *comp; - struct icaltimetype itt; - ECalComponentDateTime dt; - char *location; - icaltimezone *zone; - - comp = cal_comp_event_new_with_defaults (client); - - location = calendar_config_get_timezone (); - zone = icaltimezone_get_builtin_timezone (location); - - if (all_day) { - itt = icaltime_from_timet_with_zone (time (NULL), 1, zone); - - dt.value = &itt; - dt.tzid = icaltimezone_get_tzid (zone); - - e_cal_component_set_dtstart (comp, &dt); - e_cal_component_set_dtend (comp, &dt); - } else { - itt = icaltime_current_time_with_zone (zone); - icaltime_adjust (&itt, 0, 1, -itt.minute, -itt.second); - - dt.value = &itt; - dt.tzid = icaltimezone_get_tzid (zone); - - e_cal_component_set_dtstart (comp, &dt); - icaltime_adjust (&itt, 0, 1, 0, 0); - e_cal_component_set_dtend (comp, &dt); - } - - e_cal_component_commit_sequence (comp); - - return comp; -} - -/* Callbacks. */ -static void -add_popup_menu_item (GtkMenu *menu, const char *label, const char *pixmap, - GCallback callback, gpointer user_data, gboolean sensitive) -{ - GtkWidget *item, *image; - - if (pixmap) { - item = gtk_image_menu_item_new_with_label (label); - - /* load the image */ - image = gtk_image_new_from_stock (pixmap, GTK_ICON_SIZE_MENU); - if (!image) - image = gtk_image_new_from_file (pixmap); - - if (image) { - gtk_widget_show (image); - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); - } - } else { - item = gtk_menu_item_new_with_label (label); - } - - if (callback) - g_signal_connect (G_OBJECT (item), "activate", callback, user_data); - - if (!sensitive) - gtk_widget_set_sensitive (item, FALSE); - - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - gtk_widget_show (item); -} - -static void -copy_calendar_cb (GtkWidget *widget, CalendarComponent *comp) -{ - ESource *selected_source; - CalendarComponentPrivate *priv; - - priv = comp->priv; - - selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (priv->source_selector)); - if (!selected_source) - return; - - copy_source_dialog (GTK_WINDOW (gtk_widget_get_toplevel (widget)), selected_source, CALOBJ_TYPE_EVENT); -} - -static void -delete_calendar_cb (GtkWidget *widget, CalendarComponent *comp) -{ - ESource *selected_source; - CalendarComponentPrivate *priv; - GtkWidget *dialog; - - priv = comp->priv; - - selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (priv->source_selector)); - if (!selected_source) - return; - - /* create the confirmation dialog */ - dialog = gtk_message_dialog_new ( - GTK_WINDOW (gtk_widget_get_toplevel (widget)), - GTK_DIALOG_MODAL, - GTK_MESSAGE_QUESTION, - GTK_BUTTONS_YES_NO, - _("Calendar '%s' will be removed. Are you sure you want to continue?"), - e_source_peek_name (selected_source)); - if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_YES) { - if (e_source_selector_source_is_selected (E_SOURCE_SELECTOR (priv->source_selector), - selected_source)) - e_source_selector_unselect_source (E_SOURCE_SELECTOR (priv->source_selector), - selected_source); - - e_source_group_remove_source (e_source_peek_group (selected_source), selected_source); - - /* FIXME: remove the calendar.ics file and the directory */ - } - - gtk_widget_destroy (dialog); -} - -static void -new_calendar_cb (GtkWidget *widget, CalendarComponent *comp) -{ - new_calendar_dialog (GTK_WINDOW (gtk_widget_get_toplevel (widget))); -} - -static void -rename_calendar_cb (GtkWidget *widget, CalendarComponent *comp) -{ - CalendarComponentPrivate *priv; - ESource *selected_source; - GtkWidget *dialog, *entry; - - priv = comp->priv; - - selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (priv->source_selector)); - if (!selected_source) - return; - - /* create the dialog to prompt the user for the new name */ - dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (widget)), - GTK_DIALOG_MODAL, - GTK_MESSAGE_QUESTION, - GTK_BUTTONS_OK_CANCEL, - _("Rename this calendar to")); - entry = gtk_entry_new (); - gtk_entry_set_text (GTK_ENTRY (entry), e_source_peek_name (selected_source)); - gtk_widget_show (entry); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), entry, TRUE, FALSE, 6); - - if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) - e_source_set_name (selected_source, gtk_entry_get_text (GTK_ENTRY (entry))); - - gtk_widget_destroy (dialog); -} - -static void -fill_popup_menu_cb (ESourceSelector *selector, GtkMenu *menu, CalendarComponent *comp) -{ - gboolean sensitive; - - sensitive = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (comp->priv->source_selector)) ? - TRUE : FALSE; - - add_popup_menu_item (menu, _("New Calendar"), GTK_STOCK_NEW, G_CALLBACK (new_calendar_cb), comp, TRUE); - add_popup_menu_item (menu, _("Copy"), NULL, G_CALLBACK (copy_calendar_cb), comp, sensitive); - add_popup_menu_item (menu, _("Rename"), NULL, G_CALLBACK (rename_calendar_cb), comp, sensitive); - add_popup_menu_item (menu, _("Delete"), GTK_STOCK_DELETE, G_CALLBACK (delete_calendar_cb), comp, sensitive); -} - -static void -source_selection_changed_cb (ESourceSelector *selector, - CalendarComponent *calendar_component) -{ - update_uris_for_selection (calendar_component); -} - -static void -primary_source_selection_changed_cb (ESourceSelector *selector, - CalendarComponent *calendar_component) -{ - update_uri_for_primary_selection (calendar_component); -} - -static void -config_selection_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - update_selection (data); -} - - -static void -config_primary_selection_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - update_primary_selection (data); -} - -/* GObject methods. */ - -static void -impl_dispose (GObject *object) -{ - CalendarComponentPrivate *priv = CALENDAR_COMPONENT (object)->priv; - GList *l; - - if (priv->source_list != NULL) { - g_object_unref (priv->source_list); - priv->source_list = NULL; - } - - if (priv->source_selection != NULL) { - e_source_selector_free_selection (priv->source_selection); - priv->source_selection = NULL; - } - - if (priv->gconf_client != NULL) { - g_object_unref (priv->gconf_client); - priv->gconf_client = NULL; - } - - if (priv->create_ecal) { - g_object_unref (priv->create_ecal); - priv->create_ecal = NULL; - } - - for (l = priv->notifications; l; l = l->next) - calendar_config_remove_notification (GPOINTER_TO_UINT (l->data)); - g_list_free (priv->notifications); - priv->notifications = NULL; - - if (priv->activity_handler != NULL) { - g_object_unref (priv->activity_handler); - priv->activity_handler = NULL; - } - - (* G_OBJECT_CLASS (parent_class)->dispose) (object); -} - -static void -impl_finalize (GObject *object) -{ - CalendarComponentPrivate *priv = CALENDAR_COMPONENT (object)->priv; - - g_free (priv->config_directory); - - g_free (priv); - - (* G_OBJECT_CLASS (parent_class)->finalize) (object); -} - - -/* Evolution::Component CORBA methods. */ - -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 -impl_createControls (PortableServer_Servant servant, - Bonobo_Control *corba_sidebar_control, - Bonobo_Control *corba_view_control, - Bonobo_Control *corba_statusbar_control, - CORBA_Environment *ev) -{ - CalendarComponent *calendar_component = CALENDAR_COMPONENT (bonobo_object_from_servant (servant)); - CalendarComponentPrivate *priv; - GtkWidget *selector_scrolled_window; - GtkWidget *statusbar_widget; - BonoboControl *sidebar_control; - BonoboControl *view_control; - BonoboControl *statusbar_control; - guint not; - - priv = calendar_component->priv; - - /* Create sidebar selector */ - priv->source_selector = e_source_selector_new (calendar_component->priv->source_list); - gtk_widget_show (priv->source_selector); - - selector_scrolled_window = gtk_scrolled_window_new (NULL, NULL); - gtk_container_add (GTK_CONTAINER (selector_scrolled_window), priv->source_selector); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (selector_scrolled_window), - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (selector_scrolled_window), - GTK_SHADOW_IN); - gtk_widget_show (selector_scrolled_window); - - sidebar_control = bonobo_control_new (selector_scrolled_window); - - /* Create main calendar view */ - /* FIXME Instead of returning, we should make a control with a - * label describing the problem */ - priv->calendar = GNOME_CALENDAR (gnome_calendar_new ()); - if (!priv->calendar) { - g_warning (G_STRLOC ": could not create the calendar widget!"); - bonobo_exception_set (ev, ex_GNOME_Evolution_Component_Failed); - return; - } - - gtk_widget_show (GTK_WIDGET (priv->calendar)); - - view_control = bonobo_control_new (GTK_WIDGET (priv->calendar)); - if (!view_control) { - g_warning (G_STRLOC ": could not create the control!"); - bonobo_exception_set (ev, ex_GNOME_Evolution_Component_Failed); - return; - } - g_object_set_data (G_OBJECT (priv->calendar), "control", view_control); - - g_signal_connect (view_control, "activate", G_CALLBACK (control_activate_cb), priv->calendar); - - g_signal_connect_object (priv->source_selector, "selection_changed", - G_CALLBACK (source_selection_changed_cb), - G_OBJECT (calendar_component), 0); - g_signal_connect_object (priv->source_selector, "primary_selection_changed", - G_CALLBACK (primary_source_selection_changed_cb), - G_OBJECT (calendar_component), 0); - g_signal_connect_object (priv->source_selector, "fill_popup_menu", - G_CALLBACK (fill_popup_menu_cb), - G_OBJECT (calendar_component), 0); - - statusbar_widget = e_task_bar_new (); - gtk_widget_show (statusbar_widget); - e_activity_handler_attach_task_bar (priv->activity_handler, E_TASK_BAR (statusbar_widget)); - statusbar_control = bonobo_control_new (statusbar_widget); - - /* Load the selection from the last run */ - update_selection (calendar_component); - update_primary_selection (calendar_component); - - /* If it gets fiddled with update */ - not = calendar_config_add_notification_calendars_selected (config_selection_changed_cb, - calendar_component); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - not = calendar_config_add_notification_primary_calendar (config_primary_selection_changed_cb, - calendar_component); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - /* Return the controls */ - *corba_sidebar_control = CORBA_Object_duplicate (BONOBO_OBJREF (sidebar_control), ev); - *corba_view_control = CORBA_Object_duplicate (BONOBO_OBJREF (view_control), ev); - *corba_statusbar_control = CORBA_Object_duplicate (BONOBO_OBJREF (statusbar_control), ev); -} - - -static GNOME_Evolution_CreatableItemTypeList * -impl__get_userCreatableItems (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - GNOME_Evolution_CreatableItemTypeList *list = GNOME_Evolution_CreatableItemTypeList__alloc (); - - list->_length = 3; - list->_maximum = list->_length; - list->_buffer = GNOME_Evolution_CreatableItemTypeList_allocbuf (list->_length); - - CORBA_sequence_set_release (list, FALSE); - - list->_buffer[0].id = CREATE_EVENT_ID; - list->_buffer[0].description = _("New appointment"); - list->_buffer[0].menuDescription = _("_Appointment"); - list->_buffer[0].tooltip = _("Create a new appointment"); - list->_buffer[0].menuShortcut = 'a'; - list->_buffer[0].iconName = "new_appointment.xpm"; - - list->_buffer[1].id = CREATE_MEETING_ID; - list->_buffer[1].description = _("New meeting"); - list->_buffer[1].menuDescription = _("M_eeting"); - list->_buffer[1].tooltip = _("Create a new meeting request"); - list->_buffer[1].menuShortcut = 'e'; - list->_buffer[1].iconName = "meeting-request-16.png"; - - list->_buffer[2].id = CREATE_ALLDAY_EVENT_ID; - list->_buffer[2].description = _("New all day appointment"); - list->_buffer[2].menuDescription = _("All _Day Appointment"); - list->_buffer[2].tooltip = _("Create a new all-day appointment"); - list->_buffer[2].menuShortcut = 'd'; - list->_buffer[2].iconName = "new_all_day_event.png"; - - return list; -} - -static void -config_create_ecal_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - CalendarComponent *calendar_component = data; - CalendarComponentPrivate *priv; - - priv = calendar_component->priv; - - g_object_unref (priv->create_ecal); - priv->create_ecal = NULL; - - priv->notifications = g_list_remove (priv->notifications, GUINT_TO_POINTER (id)); -} - -static gboolean -setup_create_ecal (CalendarComponent *calendar_component) -{ - CalendarComponentPrivate *priv; - ESource *source = NULL; - char *uid; - guint not; - - priv = calendar_component->priv; - - if (priv->create_ecal) - return TRUE; - - /* Try to use the client from the calendar first to avoid re-opening things */ - if (priv->calendar) { - ECal *default_ecal; - - default_ecal = gnome_calendar_get_default_client (priv->calendar); - if (default_ecal) { - priv->create_ecal = g_object_ref (default_ecal); - return TRUE; - } - } - - /* Get the current primary calendar, or try to set one if it doesn't already exist */ - uid = calendar_config_get_primary_calendar (); - if (uid) { - source = e_source_list_peek_source_by_uid (priv->source_list, uid); - g_free (uid); - - priv->create_ecal = e_cal_new (source, CALOBJ_TYPE_EVENT); - } - - if (!priv->create_ecal) { - /* Try to create a default if there isn't one */ - source = find_first_source (priv->source_list); - if (source) - priv->create_ecal = e_cal_new (source, CALOBJ_TYPE_EVENT); - } - - if (priv->create_ecal) { - if (!e_cal_open (priv->create_ecal, FALSE, NULL)) { - GtkWidget *dialog; - - dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, - GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, - _("Unable to open the calendar '%s' for creating events and meetings"), - e_source_peek_name (source)); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - - return FALSE; - } - } else { - GtkWidget *dialog; - - dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, - GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, - _("There is no calendar available for creating events and meetings")); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - - return FALSE; - } - - /* Handle the fact it may change on us */ - not = calendar_config_add_notification_primary_calendar (config_create_ecal_changed_cb, - calendar_component); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - /* Save the primary source for use elsewhere */ - calendar_config_set_primary_calendar (e_source_peek_uid (source)); - - return TRUE; -} - -static void -impl_requestCreateItem (PortableServer_Servant servant, - const CORBA_char *item_type_name, - CORBA_Environment *ev) -{ - CalendarComponent *calendar_component = CALENDAR_COMPONENT (bonobo_object_from_servant (servant)); - CalendarComponentPrivate *priv; - ECalComponent *comp; - EventEditor *editor; - gboolean is_meeting = FALSE; - - priv = calendar_component->priv; - - if (!setup_create_ecal (calendar_component)) - return; - - editor = event_editor_new (priv->create_ecal); - - if (strcmp (item_type_name, CREATE_EVENT_ID) == 0) { - comp = get_default_event (priv->create_ecal, FALSE); - } else if (strcmp (item_type_name, CREATE_ALLDAY_EVENT_ID) == 0) { - comp = get_default_event (priv->create_ecal, TRUE); - } else if (strcmp (item_type_name, CREATE_MEETING_ID) == 0) { - comp = get_default_event (priv->create_ecal, FALSE); - is_meeting = TRUE; - } else { - bonobo_exception_set (ev, ex_GNOME_Evolution_Component_UnknownType); - return; - } - - comp_editor_edit_comp (COMP_EDITOR (editor), comp); - if (is_meeting) - event_editor_show_meeting (editor); - comp_editor_focus (COMP_EDITOR (editor)); - - e_comp_editor_registry_add (comp_editor_registry, COMP_EDITOR (editor), TRUE); -} - - -/* Initialization. */ - -static void -calendar_component_class_init (CalendarComponentClass *class) -{ - POA_GNOME_Evolution_Component__epv *epv = &class->epv; - GObjectClass *object_class = G_OBJECT_CLASS (class); - - parent_class = g_type_class_peek_parent (class); - - epv->createControls = impl_createControls; - epv->_get_userCreatableItems = impl__get_userCreatableItems; - epv->requestCreateItem = impl_requestCreateItem; - - object_class->dispose = impl_dispose; - object_class->finalize = impl_finalize; -} - -static void -calendar_component_init (CalendarComponent *component) -{ - CalendarComponentPrivate *priv; - GSList *groups; - - priv = g_new0 (CalendarComponentPrivate, 1); - - priv->config_directory = g_build_filename (g_get_home_dir (), - ".evolution", "calendar", "config", - NULL); - - /* EPFIXME: Should use a custom one instead? Also we should add - * calendar_component_peek_gconf_client(). */ - priv->gconf_client = gconf_client_get_default (); - - priv->source_list = e_source_list_new_for_gconf (priv->gconf_client, - "/apps/evolution/calendar/sources"); - - priv->activity_handler = e_activity_handler_new (); - - /* create default calendars if there are no groups */ - groups = e_source_list_peek_groups (priv->source_list); - if (!groups) { - ESourceGroup *group; - ESource *source; - char *base_uri, *new_dir; - - /* create the local source group */ - base_uri = g_build_filename (g_get_home_dir (), - "/.evolution/calendar/local/OnThisComputer/", - NULL); - group = e_source_group_new (_("On This Computer"), base_uri); - e_source_list_add_group (priv->source_list, group, -1); - - /* migrate calendars from older setup */ - if (!migrate_old_calendars (group)) { - /* create default calendars */ - new_dir = g_build_filename (base_uri, "Personal/", NULL); - if (!e_mkdir_hier (new_dir, 0700)) { - source = e_source_new (_("Personal"), "Personal"); - e_source_group_add_source (group, source, -1); - } - g_free (new_dir); - - new_dir = g_build_filename (base_uri, "Work/", NULL); - if (!e_mkdir_hier (new_dir, 0700)) { - source = e_source_new (_("Work"), "Work"); - e_source_group_add_source (group, source, -1); - } - g_free (new_dir); - } - - g_free (base_uri); - - /* create the remote source group */ - group = e_source_group_new (_("On The Web"), "webcal://"); - e_source_list_add_group (priv->source_list, group, -1); - } - - component->priv = priv; -} - - -/* Public API. */ - -CalendarComponent * -calendar_component_peek (void) -{ - static CalendarComponent *component = NULL; - - if (component == NULL) { - component = g_object_new (calendar_component_get_type (), NULL); - - if (e_mkdir_hier (calendar_component_peek_config_directory (component), 0777) != 0) { - g_warning (G_STRLOC ": Cannot create directory %s: %s", - calendar_component_peek_config_directory (component), - g_strerror (errno)); - g_object_unref (component); - component = NULL; - } - } - - return component; -} - -const char * -calendar_component_peek_config_directory (CalendarComponent *component) -{ - return component->priv->config_directory; -} - - -EActivityHandler * -calendar_component_peek_activity_handler (CalendarComponent *component) -{ - return component->priv->activity_handler; -} - - -BONOBO_TYPE_FUNC_FULL (CalendarComponent, GNOME_Evolution_Component, PARENT_TYPE, calendar_component) diff --git a/calendar/gui/calendar-component.h b/calendar/gui/calendar-component.h deleted file mode 100644 index 77d2fe9879..0000000000 --- a/calendar/gui/calendar-component.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* calendar-component.h - * - * Copyright (C) 2003 Ettore Perazzoli - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * 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_COMPONENT_H_ -#define _CALENDAR_COMPONENT_H_ - - -#include <bonobo/bonobo-object.h> -#include <libedataserver/e-source-list.h> - -#include "e-activity-handler.h" -#include "Evolution.h" - - -#define CALENDAR_TYPE_COMPONENT (calendar_component_get_type ()) -#define CALENDAR_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CALENDAR_TYPE_COMPONENT, CalendarComponent)) -#define CALENDAR_COMPONENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CALENDAR_TYPE_COMPONENT, CalendarComponentClass)) -#define CALENDAR_IS_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CALENDAR_TYPE_COMPONENT)) -#define CALENDAR_IS_COMPONENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), CALENDAR_TYPE_COMPONENT)) - - -typedef struct _CalendarComponent CalendarComponent; -typedef struct _CalendarComponentPrivate CalendarComponentPrivate; -typedef struct _CalendarComponentClass CalendarComponentClass; - -struct _CalendarComponent { - BonoboObject parent; - - CalendarComponentPrivate *priv; -}; - -struct _CalendarComponentClass { - BonoboObjectClass parent_class; - - POA_GNOME_Evolution_Component__epv epv; -}; - - -GType calendar_component_get_type (void); - -CalendarComponent *calendar_component_peek (void); - -const char *calendar_component_peek_config_directory (CalendarComponent *component); -ESourceList *calendar_component_peek_source_list (CalendarComponent *component); -EActivityHandler *calendar_component_peek_activity_handler (CalendarComponent *component); - - -#endif /* _CALENDAR_COMPONENT_H_ */ diff --git a/calendar/gui/calendar-config-keys.h b/calendar/gui/calendar-config-keys.h deleted file mode 100644 index ebe16b6539..0000000000 --- a/calendar/gui/calendar-config-keys.h +++ /dev/null @@ -1,75 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Authors : - * JP Rosevear <jpr@ximian.com> - * - * Copyright 2003, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef _CALENDAR_CONFIG_KEYS_H_ -#define _CALENDAR_CONFIG_KEYS_H_ - -G_BEGIN_DECLS - -#define CALENDAR_CONFIG_PREFIX "/apps/evolution/calendar" - -/* Display settings */ -#define CALENDAR_CONFIG_TIMEZONE CALENDAR_CONFIG_PREFIX "/display/timezone" -#define CALENDAR_CONFIG_SELECTED_CALENDARS CALENDAR_CONFIG_PREFIX "/display/selected_calendars" -#define CALENDAR_CONFIG_PRIMARY_CALENDAR CALENDAR_CONFIG_PREFIX "/display/primary_calendar" -#define CALENDAR_CONFIG_24HOUR CALENDAR_CONFIG_PREFIX "/display/use_24hour_format" -#define CALENDAR_CONFIG_WEEK_START CALENDAR_CONFIG_PREFIX "/display/week_start_day" -#define CALENDAR_CONFIG_DAY_START_HOUR CALENDAR_CONFIG_PREFIX "/display/day_start_hour" -#define CALENDAR_CONFIG_DAY_START_MINUTE CALENDAR_CONFIG_PREFIX "/display/day_start_minute" -#define CALENDAR_CONFIG_DAY_END_HOUR CALENDAR_CONFIG_PREFIX "/display/day_end_hour" -#define CALENDAR_CONFIG_DAY_END_MINUTE CALENDAR_CONFIG_PREFIX "/display/day_end_minute" -#define CALENDAR_CONFIG_TIME_DIVISIONS CALENDAR_CONFIG_PREFIX "/display/time_divisions" -#define CALENDAR_CONFIG_TIME_DIVISIONS CALENDAR_CONFIG_PREFIX "/display/time_divisions" -#define CALENDAR_CONFIG_DEFAULT_VIEW CALENDAR_CONFIG_PREFIX "/display/default_view" -#define CALENDAR_CONFIG_HPANE_POS CALENDAR_CONFIG_PREFIX "/display/hpane_position" -#define CALENDAR_CONFIG_VPANE_POS CALENDAR_CONFIG_PREFIX "/display/vpane_position" -#define CALENDAR_CONFIG_MONTH_HPANE_POS CALENDAR_CONFIG_PREFIX "/display/month_hpane_position" -#define CALENDAR_CONFIG_MONTH_VPANE_POS CALENDAR_CONFIG_PREFIX "/display/month_vpane_position" -#define CALENDAR_CONFIG_TASK_VPANE_POS CALENDAR_CONFIG_PREFIX "/display/task_vpane_position" -#define CALENDAR_CONFIG_COMPRESS_WEEKEND CALENDAR_CONFIG_PREFIX "/display/compress_weekend" -#define CALENDAR_CONFIG_SHOW_EVENT_END CALENDAR_CONFIG_PREFIX "/display/show_event_end" -#define CALENDAR_CONFIG_WORKING_DAYS CALENDAR_CONFIG_PREFIX "/display/working_days" - -/* Date navigator settings */ -#define CALENDAR_CONFIG_DN_SHOW_WEEK_NUMBERS CALENDAR_CONFIG_PREFIX "/date_navigator/show_week_numbers" - -/* Task display settings */ -#define CALENDAR_CONFIG_TASKS_SELECTED_TASKS CALENDAR_CONFIG_PREFIX "/tasks/selected_tasks" -#define CALENDAR_CONFIG_PRIMARY_TASKS CALENDAR_CONFIG_PREFIX "/tasks/primary_tasks" -#define CALENDAR_CONFIG_TASKS_HIDE_COMPLETED CALENDAR_CONFIG_PREFIX "/tasks/hide_completed" -#define CALENDAR_CONFIG_TASKS_HIDE_COMPLETED_UNITS CALENDAR_CONFIG_PREFIX "/tasks/hide_completed_units" -#define CALENDAR_CONFIG_TASKS_HIDE_COMPLETED_VALUE CALENDAR_CONFIG_PREFIX "/tasks/hide_completed_value" -#define CALENDAR_CONFIG_TASKS_DUE_TODAY_COLOR CALENDAR_CONFIG_PREFIX "/tasks/colors/due_today" -#define CALENDAR_CONFIG_TASKS_OVERDUE_COLOR CALENDAR_CONFIG_PREFIX "/tasks/colors/overdue" - -/* Prompt settings */ -#define CALENDAR_CONFIG_PROMPT_DELETE CALENDAR_CONFIG_PREFIX "/prompts/confirm_delete" -#define CALENDAR_CONFIG_PROMPT_PURGE CALENDAR_CONFIG_PREFIX "/prompts/confirm_purge" - -/* Default reminder */ -#define CALENDAR_CONFIG_DEFAULT_REMINDER CALENDAR_CONFIG_PREFIX "/other/use_default_reminder" -#define CALENDAR_CONFIG_DEFAULT_REMINDER_INTERVAL CALENDAR_CONFIG_PREFIX "/other/default_reminder_interval" -#define CALENDAR_CONFIG_DEFAULT_REMINDER_UNITS CALENDAR_CONFIG_PREFIX "/other/default_reminder_units" - -G_END_DECLS - -#endif diff --git a/calendar/gui/calendar-config.c b/calendar/gui/calendar-config.c deleted file mode 100644 index 3c12c381ac..0000000000 --- a/calendar/gui/calendar-config.c +++ /dev/null @@ -1,1027 +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. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <time.h> -#include <gtk/gtksignal.h> -#include <libgnome/gnome-config.h> -#include <libgnomeui/gnome-dialog.h> -#include <gal/util/e-util.h> -#include <widgets/e-timezone-dialog/e-timezone-dialog.h> -#include <libecal/e-cal-time-util.h> - -#include "calendar-component.h" -#include "calendar-commands.h" -#include "e-tasks.h" -#include "e-cell-date-edit-text.h" -#include "calendar-config-keys.h" -#include "calendar-config.h" - - - -static GConfClient *config = NULL; - -static void on_timezone_set (GnomeDialog *dialog, - int button, - ETimezoneDialog *etd); -static gboolean on_timezone_dialog_delete_event (GnomeDialog *dialog, - GdkEvent *event, - ETimezoneDialog *etd); - -static void -do_cleanup (void) -{ - g_object_unref (config); - config = NULL; -} - -void -calendar_config_init (void) -{ - if (config) - return; - - config = gconf_client_get_default (); - g_atexit ((GVoidFunc) do_cleanup); - - gconf_client_add_dir (config, CALENDAR_CONFIG_PREFIX, GCONF_CLIENT_PRELOAD_RECURSIVE, NULL); -} - -void -calendar_config_remove_notification (guint id) -{ - gconf_client_notify_remove (config, id); -} - -/* 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; - - e_utf8_strftime (s, sizeof s, "%p", gmtime (&t)); - return s[0] != '\0'; -} - -/* 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; - } -} - -/* - * Calendar Settings. - */ - -/* The current list of calendars selected */ -GSList * -calendar_config_get_calendars_selected (void) -{ - return gconf_client_get_list (config, CALENDAR_CONFIG_SELECTED_CALENDARS, GCONF_VALUE_STRING, NULL); -} - -void -calendar_config_set_calendars_selected (GSList *selected) -{ - gconf_client_set_list (config, CALENDAR_CONFIG_SELECTED_CALENDARS, GCONF_VALUE_STRING, selected, NULL); -} - -guint -calendar_config_add_notification_calendars_selected (GConfClientNotifyFunc func, gpointer data) -{ - guint id; - - id = gconf_client_notify_add (config, CALENDAR_CONFIG_SELECTED_CALENDARS, func, data, NULL, NULL); - - return id; -} - -/* The primary calendar */ -char * -calendar_config_get_primary_calendar (void) -{ - return gconf_client_get_string (config, CALENDAR_CONFIG_PRIMARY_CALENDAR, NULL); -} - -void -calendar_config_set_primary_calendar (const char *primary_uid) -{ - gconf_client_set_string (config, CALENDAR_CONFIG_PRIMARY_CALENDAR, primary_uid, NULL); -} - - -guint -calendar_config_add_notification_primary_calendar (GConfClientNotifyFunc func, gpointer data) -{ - guint id; - - id = gconf_client_notify_add (config, CALENDAR_CONFIG_PRIMARY_CALENDAR, func, data, NULL, NULL); - - return id; -} - - -/* 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) -{ - /* FIXME Guard against NULL? */ - return gconf_client_get_string (config, CALENDAR_CONFIG_TIMEZONE, NULL); -} - - -/* 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) -{ - if (timezone && timezone[0]) - gconf_client_set_string (config, CALENDAR_CONFIG_TIMEZONE, timezone, NULL); - else - gconf_client_set_string (config, CALENDAR_CONFIG_TIMEZONE, "UTC", NULL); -} - -guint -calendar_config_add_notification_timezone (GConfClientNotifyFunc func, gpointer data) -{ - guint id; - - id = gconf_client_notify_add (config, CALENDAR_CONFIG_TIMEZONE, func, data, NULL, NULL); - - return id; -} - -/* Whether we use 24-hour format or 12-hour format (AM/PM). */ -gboolean -calendar_config_get_24_hour_format (void) -{ - /* 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 ()) - return gconf_client_get_bool (config, CALENDAR_CONFIG_24HOUR, NULL); - - return TRUE; -} - - -void -calendar_config_set_24_hour_format (gboolean use_24_hour) -{ - gconf_client_set_bool (config, CALENDAR_CONFIG_24HOUR, use_24_hour, NULL); -} - -guint -calendar_config_add_notification_24_hour_format (GConfClientNotifyFunc func, gpointer data) -{ - guint id; - - id = gconf_client_notify_add (config, CALENDAR_CONFIG_24HOUR, func, data, NULL, NULL); - - return id; -} - -/* The start day of the week (0 = Sun to 6 = Mon). */ -gint -calendar_config_get_week_start_day (void) -{ - return gconf_client_get_int (config, CALENDAR_CONFIG_WEEK_START, NULL); -} - - -void -calendar_config_set_week_start_day (gint week_start_day) -{ - gconf_client_set_int (config, CALENDAR_CONFIG_WEEK_START, week_start_day, NULL); -} - -guint -calendar_config_add_notification_week_start_day (GConfClientNotifyFunc func, gpointer data) -{ - guint id; - - id = gconf_client_notify_add (config, CALENDAR_CONFIG_WEEK_START, func, data, NULL, NULL); - - return id; -} - -/* The start and end times of the work-day. */ -gint -calendar_config_get_day_start_hour (void) -{ - return gconf_client_get_int (config, CALENDAR_CONFIG_DAY_START_HOUR, NULL); -} - - -void -calendar_config_set_day_start_hour (gint day_start_hour) -{ - gconf_client_set_int (config, CALENDAR_CONFIG_DAY_START_HOUR, day_start_hour, NULL); -} - -guint -calendar_config_add_notification_day_start_hour (GConfClientNotifyFunc func, gpointer data) -{ - guint id; - - id = gconf_client_notify_add (config, CALENDAR_CONFIG_DAY_START_HOUR, func, data, NULL, NULL); - - return id; -} - -gint -calendar_config_get_day_start_minute (void) -{ - return gconf_client_get_int (config, CALENDAR_CONFIG_DAY_START_MINUTE, NULL); -} - - -void -calendar_config_set_day_start_minute (gint day_start_min) -{ - gconf_client_set_int (config, CALENDAR_CONFIG_DAY_START_MINUTE, day_start_min, NULL); -} - -guint -calendar_config_add_notification_day_start_minute (GConfClientNotifyFunc func, gpointer data) -{ - guint id; - - id = gconf_client_notify_add (config, CALENDAR_CONFIG_DAY_START_MINUTE, func, data, NULL, NULL); - - return id; -} - -gint -calendar_config_get_day_end_hour (void) -{ - return gconf_client_get_int (config, CALENDAR_CONFIG_DAY_END_HOUR, NULL); -} - - -void -calendar_config_set_day_end_hour (gint day_end_hour) -{ - gconf_client_set_int (config, CALENDAR_CONFIG_DAY_END_HOUR, day_end_hour, NULL); -} - -guint -calendar_config_add_notification_day_end_hour (GConfClientNotifyFunc func, gpointer data) -{ - guint id; - - id = gconf_client_notify_add (config, CALENDAR_CONFIG_DAY_END_HOUR, func, data, NULL, NULL); - - return id; -} - -gint -calendar_config_get_day_end_minute (void) -{ - return gconf_client_get_int (config, CALENDAR_CONFIG_DAY_END_MINUTE, NULL); -} - - -void -calendar_config_set_day_end_minute (gint day_end_min) -{ - gconf_client_set_int (config, CALENDAR_CONFIG_DAY_END_MINUTE, day_end_min, NULL); -} - -guint -calendar_config_add_notification_day_end_minute (GConfClientNotifyFunc func, gpointer data) -{ - guint id; - - id = gconf_client_notify_add (config, CALENDAR_CONFIG_DAY_END_MINUTE, func, data, NULL, NULL); - - return id; -} - -/* The time divisions in the Day/Work-Week view in minutes (5/10/15/30/60). */ -gint -calendar_config_get_time_divisions (void) -{ - return gconf_client_get_int (config, CALENDAR_CONFIG_TIME_DIVISIONS, NULL); -} - - -void -calendar_config_set_time_divisions (gint divisions) -{ - gconf_client_set_int (config, CALENDAR_CONFIG_TIME_DIVISIONS, divisions, NULL); -} - -guint -calendar_config_add_notification_time_divisions (GConfClientNotifyFunc func, gpointer data) -{ - guint id; - - id = gconf_client_notify_add (config, CALENDAR_CONFIG_TIME_DIVISIONS, func, data, NULL, NULL); - - return id; -} - -/* Whether we show week numbers in the Date Navigator. */ -gboolean -calendar_config_get_dnav_show_week_no (void) -{ - return gconf_client_get_bool (config, CALENDAR_CONFIG_DN_SHOW_WEEK_NUMBERS, NULL); -} - - -void -calendar_config_set_dnav_show_week_no (gboolean show_week_no) -{ - gconf_client_set_bool (config, CALENDAR_CONFIG_DN_SHOW_WEEK_NUMBERS, show_week_no, NULL); -} - -guint -calendar_config_add_notification_dnav_show_week_no (GConfClientNotifyFunc func, gpointer data) -{ - guint id; - - id = gconf_client_notify_add (config, CALENDAR_CONFIG_DN_SHOW_WEEK_NUMBERS, func, data, NULL, NULL); - - return id; -} - -/* The view to show on start-up, 0 = Day, 1 = WorkWeek, 2 = Week, 3 = Month. */ -gint -calendar_config_get_default_view (void) -{ - return gconf_client_get_int (config, CALENDAR_CONFIG_DEFAULT_VIEW, NULL); -} - - -void -calendar_config_set_default_view (gint view) -{ - gconf_client_set_int (config, CALENDAR_CONFIG_DEFAULT_VIEW, view, NULL); -} - - -/* The positions of the panes in the normal and month views. */ -gint -calendar_config_get_hpane_pos (void) -{ - return gconf_client_get_int (config, CALENDAR_CONFIG_HPANE_POS, NULL); -} - - -void -calendar_config_set_hpane_pos (gint hpane_pos) -{ - gconf_client_set_int (config, CALENDAR_CONFIG_HPANE_POS, hpane_pos, NULL); -} - - -gint -calendar_config_get_vpane_pos (void) -{ - return gconf_client_get_int (config, CALENDAR_CONFIG_VPANE_POS, NULL); -} - - -void -calendar_config_set_vpane_pos (gint vpane_pos) -{ - gconf_client_set_int (config, CALENDAR_CONFIG_VPANE_POS, vpane_pos, NULL); -} - - -gint -calendar_config_get_month_hpane_pos (void) -{ - return gconf_client_get_int (config, CALENDAR_CONFIG_MONTH_HPANE_POS, NULL); -} - - -void -calendar_config_set_month_hpane_pos (gint hpane_pos) -{ - gconf_client_set_int (config, CALENDAR_CONFIG_MONTH_HPANE_POS, hpane_pos, NULL); -} - - -gint -calendar_config_get_month_vpane_pos (void) -{ - return gconf_client_get_int (config, CALENDAR_CONFIG_MONTH_VPANE_POS, NULL); -} - - -void -calendar_config_set_month_vpane_pos (gint vpane_pos) -{ - gconf_client_set_int (config, CALENDAR_CONFIG_MONTH_VPANE_POS, vpane_pos, NULL); -} - -/* The current list of task lists selected */ -GSList * -calendar_config_get_tasks_selected (void) -{ - return gconf_client_get_list (config, CALENDAR_CONFIG_TASKS_SELECTED_TASKS, GCONF_VALUE_STRING, NULL); -} - -void -calendar_config_set_tasks_selected (GSList *selected) -{ - gconf_client_set_list (config, CALENDAR_CONFIG_TASKS_SELECTED_TASKS, GCONF_VALUE_STRING, selected, NULL); -} - -guint -calendar_config_add_notification_tasks_selected (GConfClientNotifyFunc func, gpointer data) -{ - guint id; - - id = gconf_client_notify_add (config, CALENDAR_CONFIG_TASKS_SELECTED_TASKS, func, data, NULL, NULL); - - return id; -} - -/* The primary task list */ -char * -calendar_config_get_primary_tasks (void) -{ - return gconf_client_get_string (config, CALENDAR_CONFIG_PRIMARY_TASKS, NULL); -} - -void -calendar_config_set_primary_tasks (const char *primary_uid) -{ - gconf_client_set_string (config, CALENDAR_CONFIG_PRIMARY_TASKS, primary_uid, NULL); -} - - -guint -calendar_config_add_notification_primary_tasks (GConfClientNotifyFunc func, gpointer data) -{ - guint id; - - id = gconf_client_notify_add (config, CALENDAR_CONFIG_PRIMARY_TASKS, func, data, NULL, NULL); - - return id; -} - -gint -calendar_config_get_task_vpane_pos (void) -{ - return gconf_client_get_int (config, CALENDAR_CONFIG_TASK_VPANE_POS, NULL); -} - - -void -calendar_config_set_task_vpane_pos (gint vpane_pos) -{ - gconf_client_set_int (config, CALENDAR_CONFIG_TASK_VPANE_POS, vpane_pos, NULL); -} - - -/* Whether we compress the weekend in the week/month views. */ -gboolean -calendar_config_get_compress_weekend (void) -{ - return gconf_client_get_bool (config, CALENDAR_CONFIG_COMPRESS_WEEKEND, NULL); -} - - -void -calendar_config_set_compress_weekend (gboolean compress) -{ - gconf_client_set_bool (config, CALENDAR_CONFIG_COMPRESS_WEEKEND, compress, NULL); -} - -guint -calendar_config_add_notification_compress_weekend (GConfClientNotifyFunc func, gpointer data) -{ - guint id; - - id = gconf_client_notify_add (config, CALENDAR_CONFIG_COMPRESS_WEEKEND, func, data, NULL, NULL); - - return id; -} - -/* Whether we show event end times. */ -gboolean -calendar_config_get_show_event_end (void) -{ - return gconf_client_get_bool (config, CALENDAR_CONFIG_SHOW_EVENT_END, NULL); -} - - -void -calendar_config_set_show_event_end (gboolean show_end) -{ - gconf_client_set_bool (config, CALENDAR_CONFIG_SHOW_EVENT_END, show_end, NULL); -} - -guint -calendar_config_add_notification_show_event_end (GConfClientNotifyFunc func, gpointer data) -{ - guint id; - - id = gconf_client_notify_add (config, CALENDAR_CONFIG_SHOW_EVENT_END, func, data, NULL, NULL); - - return id; -} - -/* The working days of the week, a bit-wise combination of flags. */ -CalWeekdays -calendar_config_get_working_days (void) -{ - return gconf_client_get_int (config, CALENDAR_CONFIG_WORKING_DAYS, NULL); -} - - -void -calendar_config_set_working_days (CalWeekdays days) -{ - gconf_client_set_int (config, CALENDAR_CONFIG_WORKING_DAYS, days, NULL); -} - -guint -calendar_config_add_notification_working_days (GConfClientNotifyFunc func, gpointer data) -{ - guint id; - - id = gconf_client_notify_add (config, CALENDAR_CONFIG_WORKING_DAYS , func, data, NULL, NULL); - - return id; -} - -/* Settings to hide completed tasks. */ -gboolean -calendar_config_get_hide_completed_tasks (void) -{ - return gconf_client_get_bool (config, CALENDAR_CONFIG_TASKS_HIDE_COMPLETED, NULL); -} - - -void -calendar_config_set_hide_completed_tasks (gboolean hide) -{ - gconf_client_set_bool (config, CALENDAR_CONFIG_TASKS_HIDE_COMPLETED, hide, NULL); -} - - -CalUnits -calendar_config_get_hide_completed_tasks_units (void) -{ - char *units; - CalUnits cu; - - units = gconf_client_get_string (config, CALENDAR_CONFIG_TASKS_HIDE_COMPLETED_UNITS, NULL); - - if (!strcmp (units, "minutes")) - cu = CAL_MINUTES; - else if (!strcmp (units, "hours")) - cu = CAL_HOURS; - else - cu = CAL_DAYS; - - g_free (units); - - return cu; -} - - -void -calendar_config_set_hide_completed_tasks_units (CalUnits cu) -{ - char *units; - - switch (cu) { - case CAL_MINUTES : - units = g_strdup ("minutes"); - break; - case CAL_HOURS : - units = g_strdup ("hours"); - break; - default : - units = g_strdup ("days"); - } - - gconf_client_set_string (config, CALENDAR_CONFIG_TASKS_HIDE_COMPLETED_UNITS, units, NULL); - - g_free (units); -} - - -gint -calendar_config_get_hide_completed_tasks_value (void) -{ - return gconf_client_get_int (config, CALENDAR_CONFIG_TASKS_HIDE_COMPLETED_VALUE, NULL); -} - - -void -calendar_config_set_hide_completed_tasks_value (gint value) -{ - gconf_client_set_int (config, CALENDAR_CONFIG_TASKS_HIDE_COMPLETED_VALUE, value, NULL); -} - -/** - * 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 gconf_client_get_bool (config, CALENDAR_CONFIG_PROMPT_DELETE, NULL); -} - -/** - * 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) -{ - gconf_client_set_bool (config, CALENDAR_CONFIG_PROMPT_DELETE, confirm, NULL); -} - -/** - * calendar_config_get_confirm_purge: - * - * Queries the configuration value for whether a confirmation dialog is - * presented when purging calendar/tasks items. - * - * Return value: Whether confirmation is required when purging items. - **/ -gboolean -calendar_config_get_confirm_purge (void) -{ - return gconf_client_get_bool (config, CALENDAR_CONFIG_PROMPT_PURGE, NULL); -} - -/** - * calendar_config_set_confirm_purge: - * @confirm: Whether confirmation is required when purging items. - * - * Sets the configuration value for whether a confirmation dialog is presented - * when purging calendar/tasks items. - **/ -void -calendar_config_set_confirm_purge (gboolean confirm) -{ - gconf_client_set_bool (config, CALENDAR_CONFIG_PROMPT_PURGE, confirm, 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); -} - -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); - - g_signal_connect (dialog, "clicked", - G_CALLBACK (on_timezone_set), timezone_dialog); - g_signal_connect (dialog, "delete-event", - G_CALLBACK (on_timezone_dialog_delete_event), timezone_dialog); - - gtk_widget_show (dialog); -} - - -static void -on_timezone_set (GnomeDialog *dialog, - int button, - ETimezoneDialog *etd) -{ - icaltimezone *zone; - - zone = e_timezone_dialog_get_timezone (etd); - if (zone) - calendar_config_set_timezone (icaltimezone_get_location (zone)); - - g_object_unref (etd); -} - - -static gboolean -on_timezone_dialog_delete_event (GnomeDialog *dialog, - GdkEvent *event, - ETimezoneDialog *etd) -{ - g_object_unref (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) -{ - static char *color = NULL; - - if (color) - g_free (color); - - color = gconf_client_get_string (config, CALENDAR_CONFIG_TASKS_DUE_TODAY_COLOR, NULL); - return 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); - - gconf_client_set_string (config, CALENDAR_CONFIG_TASKS_DUE_TODAY_COLOR, color, NULL); -} - -/** - * 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) -{ - static char *color = NULL; - - if (color) - g_free (color); - - color = gconf_client_get_string (config, CALENDAR_CONFIG_TASKS_OVERDUE_COLOR, NULL); - return 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); - - gconf_client_set_string (config, CALENDAR_CONFIG_TASKS_OVERDUE_COLOR, color, NULL); -} - -/** - * 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 gconf_client_get_bool (config, CALENDAR_CONFIG_DEFAULT_REMINDER, NULL); -} - -/** - * 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) -{ - gconf_client_set_bool (config, CALENDAR_CONFIG_DEFAULT_REMINDER, value, NULL); -} - -/** - * 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 gconf_client_get_int (config, CALENDAR_CONFIG_DEFAULT_REMINDER_INTERVAL, NULL); -} - -/** - * 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) -{ - gconf_client_set_int (config, CALENDAR_CONFIG_DEFAULT_REMINDER_INTERVAL, interval, NULL); -} - -/** - * 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) -{ - char *units; - CalUnits cu; - - units = gconf_client_get_string (config, CALENDAR_CONFIG_DEFAULT_REMINDER_UNITS, NULL); - - if (units && !strcmp (units, "days")) - cu = CAL_DAYS; - else if (units && !strcmp (units, "hours")) - cu = CAL_HOURS; - else - cu = CAL_MINUTES; - g_free (units); - - return cu; -} - -/** - * 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) -{ - gconf_client_set_string (config, CALENDAR_CONFIG_DEFAULT_REMINDER_UNITS, units_to_string(units), NULL); -} - -/** - * 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; -} - diff --git a/calendar/gui/calendar-config.h b/calendar/gui/calendar-config.h deleted file mode 100644 index ff34febd91..0000000000 --- a/calendar/gui/calendar-config.h +++ /dev/null @@ -1,220 +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 <gconf/gconf-client.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_remove_notification (guint id); - -/* - * Calendar Settings. - */ - -/* The current list of calendars selected */ -GSList *calendar_config_get_calendars_selected (void); -void calendar_config_set_calendars_selected (GSList *selected); -guint calendar_config_add_notification_calendars_selected (GConfClientNotifyFunc func, gpointer data); - -/* The primary calendar */ -char *calendar_config_get_primary_calendar (void); -void calendar_config_set_primary_calendar (const char *primary_uid); -guint calendar_config_add_notification_primary_calendar (GConfClientNotifyFunc func, gpointer data); - -/* The current timezone, e.g. "Europe/London". */ -gchar* calendar_config_get_timezone (void); -void calendar_config_set_timezone (gchar *timezone); -guint calendar_config_add_notification_timezone (GConfClientNotifyFunc func, gpointer data); - -/* 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); -guint calendar_config_add_notification_working_days (GConfClientNotifyFunc func, gpointer data); - -/* 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); -guint calendar_config_add_notification_week_start_day (GConfClientNotifyFunc func, gpointer data); - -/* 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); -guint calendar_config_add_notification_day_start_hour (GConfClientNotifyFunc func, gpointer data); - -gint calendar_config_get_day_start_minute (void); -void calendar_config_set_day_start_minute (gint day_start_min); -guint calendar_config_add_notification_day_start_minute (GConfClientNotifyFunc func, gpointer data); - -gint calendar_config_get_day_end_hour (void); -void calendar_config_set_day_end_hour (gint day_end_hour); -guint calendar_config_add_notification_day_end_hour (GConfClientNotifyFunc func, gpointer data); - -gint calendar_config_get_day_end_minute (void); -void calendar_config_set_day_end_minute (gint day_end_min); -guint calendar_config_add_notification_day_end_minute (GConfClientNotifyFunc func, gpointer data); - -/* 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); -guint calendar_config_add_notification_24_hour_format (GConfClientNotifyFunc func, gpointer data); - -/* 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); -guint calendar_config_add_notification_time_divisions (GConfClientNotifyFunc func, gpointer data); - -/* Whether we show event end times. */ -gboolean calendar_config_get_show_event_end (void); -void calendar_config_set_show_event_end (gboolean show_end); -guint calendar_config_add_notification_show_event_end (GConfClientNotifyFunc func, gpointer data); - -/* 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); -guint calendar_config_add_notification_compress_weekend (GConfClientNotifyFunc func, gpointer data); - -/* 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); -guint calendar_config_add_notification_dnav_show_week_no (GConfClientNotifyFunc func, gpointer data); - -/* 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. */ -gint calendar_config_get_hpane_pos (void); -void calendar_config_set_hpane_pos (gint hpane_pos); - -gint calendar_config_get_vpane_pos (void); -void calendar_config_set_vpane_pos (gint vpane_pos); - -gint calendar_config_get_month_hpane_pos (void); -void calendar_config_set_month_hpane_pos (gint hpane_pos); - -gint calendar_config_get_month_vpane_pos (void); -void calendar_config_set_month_vpane_pos (gint vpane_pos); - -/* The current list of task lists selected */ -GSList *calendar_config_get_tasks_selected (void); -void calendar_config_set_tasks_selected (GSList *selected); -guint calendar_config_add_notification_tasks_selected (GConfClientNotifyFunc func, gpointer data); - -/* The primary calendar */ -char *calendar_config_get_primary_tasks (void); -void calendar_config_set_primary_tasks (const char *primary_uid); -guint calendar_config_add_notification_primary_tasks (GConfClientNotifyFunc func, gpointer data); - -/* The pane position */ -gint calendar_config_get_task_vpane_pos (void); -void calendar_config_set_task_vpane_pos (gint 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_purge (void); -void calendar_config_set_confirm_purge (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); - -#endif /* _CALENDAR_CONFIG_H_ */ diff --git a/calendar/gui/calendar-offline-handler.c b/calendar/gui/calendar-offline-handler.c deleted file mode 100644 index 89a7aab36e..0000000000 --- a/calendar/gui/calendar-offline-handler.c +++ /dev/null @@ -1,345 +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 <bonobo/bonobo-i18n.h> -#include <gal/util/e-util.h> -#include "e-util/e-url.h" -#include <libecal/e-cal.h> -#include "calendar-offline-handler.h" - -#define PARENT_TYPE bonobo_object_get_type () -static BonoboObjectClass *parent_class = NULL; - -struct _CalendarOfflineHandlerPrivate { - ECal *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 = e_cal_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 (ECal *client, ECalSetModeStatus status, CalMode mode, gpointer data) -{ - CalendarOfflineHandler *offline_handler = data; - - update_offline (offline_handler); - g_object_unref (client); -} - -static void -backend_cal_opened_offline (ECal *client, ECalendarStatus status, gpointer data) -{ - CalendarOfflineHandler *offline_handler = data; - - if (status != E_CALENDAR_STATUS_OK) { - update_offline (offline_handler); - g_object_unref (client); - return; - } - - g_signal_connect (client, "cal_set_mode", G_CALLBACK (backend_cal_set_mode), offline_handler); - e_cal_set_mode (client, CAL_MODE_LOCAL); -} - -static void -backend_cal_opened_online (ECal *client, ECalendarStatus status, gpointer data) -{ - if (status != E_CALENDAR_STATUS_OK) { - g_object_unref (client); - return; - } - - e_cal_set_mode (client, CAL_MODE_REMOTE); - g_object_unref (client); -} - -static void -backend_go_offline (gpointer data, gpointer user_data) -{ - CalendarOfflineHandler *offline_handler = user_data; - char *uri = data; - ECal *client; - gboolean success; - GError *error = NULL; - - client = e_cal_new_from_uri (uri, CALOBJ_TYPE_ANY); - g_signal_connect (client, "cal_opened", G_CALLBACK (backend_cal_opened_offline), offline_handler); - success = e_cal_open (client, TRUE, &error); - if (!success) { - g_warning (_("backend_go_offline(): %s"), error->message); - update_offline (offline_handler); - g_object_unref (client); - g_error_free (error); - return; - } -} - -static void -backend_go_online (gpointer data, gpointer user_data) -{ - CalendarOfflineHandler *offline_handler = user_data; - char *uri = data; - ECal *client; - gboolean success; - GError *error = NULL; - - client = e_cal_new_from_uri (uri, CALOBJ_TYPE_ANY); - g_signal_connect (G_OBJECT (client), "cal_opened", - G_CALLBACK (backend_cal_opened_online), offline_handler); - success = e_cal_open (client, TRUE, &error); - if (!success) { - g_warning (_("backend_go_online(): %s"), error->message); - g_object_unref (client); - g_error_free (error); - 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 = e_cal_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; - GList *uris; - - offline_handler = CALENDAR_OFFLINE_HANDLER (bonobo_object_from_servant (servant)); - priv = offline_handler->priv; - - uris = e_cal_uri_list (priv->client, CAL_MODE_LOCAL); - - g_list_foreach (uris, backend_go_online, offline_handler); -} - -/* GObject methods. */ - -static void -impl_dispose (GObject *object) -{ - CalendarOfflineHandler *offline_handler; - CalendarOfflineHandlerPrivate *priv; - - offline_handler = CALENDAR_OFFLINE_HANDLER (object); - priv = offline_handler->priv; - - if (priv->client) { - g_object_unref (priv->client); - priv->client = NULL; - } - - 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); - - priv->listener_interface = CORBA_OBJECT_NIL; - } - - if (G_OBJECT_CLASS (parent_class)->dispose) - (* G_OBJECT_CLASS (parent_class)->dispose) (object); -} - -static void -impl_finalize (GObject *object) -{ - CalendarOfflineHandler *offline_handler; - CalendarOfflineHandlerPrivate *priv; - - offline_handler = CALENDAR_OFFLINE_HANDLER (object); - priv = offline_handler->priv; - - g_free (priv); - - if (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (object); -} - -/* GTK+ type initialization. */ - -static void -calendar_offline_handler_class_init (CalendarOfflineHandlerClass *klass) -{ - GObjectClass *object_class; - POA_GNOME_Evolution_Offline__epv *epv; - - object_class = G_OBJECT_CLASS (klass); - object_class->dispose = impl_dispose; - object_class->finalize = impl_finalize; - - 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; - - /* FIXME: what URI to use? */ - priv->client = e_cal_new_from_uri ("", CALOBJ_TYPE_ANY); - priv->listener_interface = CORBA_OBJECT_NIL; - priv->is_offline = FALSE; -} - -CalendarOfflineHandler * -calendar_offline_handler_new (void) -{ - CalendarOfflineHandler *new; - - new = g_object_new (calendar_offline_handler_get_type (), NULL); - - return new; -} - -BONOBO_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 3cc61b4f25..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-object.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 { - BonoboObject parent; - - CalendarOfflineHandlerPrivate *priv; -}; - -struct _CalendarOfflineHandlerClass { - BonoboObjectClass 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 a90e8a46d4..0000000000 --- a/calendar/gui/calendar-view-factory.c +++ /dev/null @@ -1,228 +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-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_finalize (GObject *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; - - - -E_MAKE_TYPE (calendar_view_factory, "CalendarViewFactory", CalendarViewFactory, - calendar_view_factory_class_init, calendar_view_factory_init, GAL_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; - GObjectClass *gobject_class; - - parent_class = g_type_class_peek_parent (class); - - gal_view_factory_class = (GalViewFactoryClass *) class; - gobject_class = (GObjectClass *) 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; - - gobject_class->finalize = calendar_view_factory_finalize; -} - -/* 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; -} - -/* Finalize method for the calendar view factory */ -static void -calendar_view_factory_finalize (GObject *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 (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (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"); - - case GNOME_CAL_LIST_VIEW: - return _("List 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"; - - case GNOME_CAL_LIST_VIEW: - return "list_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 = g_object_new (TYPE_CALENDAR_VIEW_FACTORY, NULL); - 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 6d1de25590..0000000000 --- a/calendar/gui/calendar-view-factory.h +++ /dev/null @@ -1,64 +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 <gal/menus/gal-view-factory.h> -#include "gnome-cal.h" - -G_BEGIN_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); - - - -G_END_DECLS - -#endif diff --git a/calendar/gui/calendar-view.c b/calendar/gui/calendar-view.c deleted file mode 100644 index 1aec23ef36..0000000000 --- a/calendar/gui/calendar-view.c +++ /dev/null @@ -1,288 +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_finalize (GObject *object); - -static void calendar_view_edit (GalView *view, GtkWindow *parent_window); -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; - - - -E_MAKE_TYPE (calendar_view, "CalendarView", CalendarView, calendar_view_class_init, - calendar_view_init, GAL_VIEW_TYPE); - -/* Class initialization function for the calendar view */ -static void -calendar_view_class_init (CalendarViewClass *class) -{ - GalViewClass *gal_view_class; - GObjectClass *object_class; - - parent_class = g_type_class_peek_parent (class); - - gal_view_class = (GalViewClass *) class; - object_class = (GObjectClass *) 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->finalize = calendar_view_finalize; -} - -/* 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_finalize (GObject *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 (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (object); -} - - - -/* edit method of the calendar view */ -static void -calendar_view_edit (GalView *view, GtkWindow *parent_window) -{ - /* 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 = g_object_new (TYPE_CALENDAR_VIEW, NULL); - 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 = g_object_new (TYPE_CALENDAR_VIEW, NULL); - 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 8b85966a90..0000000000 --- a/calendar/gui/calendar-view.h +++ /dev/null @@ -1,66 +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 <gal/menus/gal-view.h> -#include "gnome-cal.h" - -G_BEGIN_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); - - - -G_END_DECLS - -#endif diff --git a/calendar/gui/comp-editor-factory.c b/calendar/gui/comp-editor-factory.c deleted file mode 100644 index a50b135f90..0000000000 --- a/calendar/gui/comp-editor-factory.c +++ /dev/null @@ -1,663 +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 <gtk/gtkmessagedialog.h> -#include <bonobo/bonobo-exception.h> -#include <bonobo/bonobo-i18n.h> -#include <evolution-calendar.h> -#include <e-util/e-url.h> -#include <libecal/e-cal.h> -#include "calendar-config.h" -#include "e-comp-editor-registry.h" -#include "comp-editor-factory.h" -#include "comp-util.h" -#include "dialogs/event-editor.h" -#include "dialogs/task-editor.h" - -extern ECompEditorRegistry *comp_editor_registry; - - - -/* A pending request */ - -typedef enum { - REQUEST_EXISTING, - REQUEST_NEW -} RequestType; - -typedef struct { - RequestType type; - - union { - struct { - char *uid; - } existing; - - struct { - GNOME_Evolution_Calendar_CompEditorFactory_CompEditorMode type; - } new; - } u; -} Request; - -/* A client we have open */ -typedef struct { - /* Our parent CompEditorFactory */ - CompEditorFactory *factory; - - /* Uri of the calendar, used as key in the clients hash table */ - char *uri; - - /* Client of the calendar */ - ECal *client; - - /* Count editors using this client */ - int editor_count; - - /* Pending requests; they are pending if the client is still being opened */ - GSList *pending; - - /* Whether this is open or still waiting */ - guint open : 1; -} OpenClient; - -/* Private part of the CompEditorFactory structure */ -struct CompEditorFactoryPrivate { - /* Hash table of URI->OpenClient */ - GHashTable *uri_client_hash; -}; - - - -static void comp_editor_factory_class_init (CompEditorFactoryClass *class); -static void comp_editor_factory_init (CompEditorFactory *factory); -static void comp_editor_factory_finalize (GObject *object); - -static void impl_editExisting (PortableServer_Servant servant, - const CORBA_char *str_uri, - const CORBA_char *uid, - CORBA_Environment *ev); -static void impl_editNew (PortableServer_Servant servant, - const CORBA_char *str_uri, - const GNOME_Evolution_Calendar_CalObjType type, - CORBA_Environment *ev); - -static BonoboObjectClass *parent_class = NULL; - - - -BONOBO_TYPE_FUNC_FULL (CompEditorFactory, - GNOME_Evolution_Calendar_CompEditorFactory, - BONOBO_OBJECT_TYPE, - comp_editor_factory); - -/* Class initialization function for the component editor factory */ -static void -comp_editor_factory_class_init (CompEditorFactoryClass *class) -{ - GObjectClass *object_class; - - object_class = (GObjectClass *) class; - - parent_class = g_type_class_peek_parent (class); - - class->epv.editExisting = impl_editExisting; - class->epv.editNew = impl_editNew; - - object_class->finalize = comp_editor_factory_finalize; -} - -/* 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); -} - -/* 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; - - g_object_unref (oc->client); - oc->client = NULL; - - for (l = oc->pending; l; l = l->next) { - Request *r; - - r = l->data; - free_request (r); - } - g_slist_free (oc->pending); - oc->pending = NULL; - - g_free (oc); -} - -/* 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_finalize (GObject *object) -{ - CompEditorFactory *factory; - CompEditorFactoryPrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_COMP_EDITOR_FACTORY (object)); - - factory = COMP_EDITOR_FACTORY (object); - priv = factory->priv; - - g_hash_table_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 (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (object); -} - - - -/* Callback used when a component editor gets destroyed */ -static void -editor_destroy_cb (GtkObject *object, gpointer data) -{ - OpenClient *oc; - CompEditorFactory *factory; - CompEditorFactoryPrivate *priv; - - oc = data; - factory = oc->factory; - priv = factory->priv; - - oc->editor_count--; - - /* See if we need to free the client */ - g_assert (oc->pending == NULL); - - if (oc->editor_count != 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) -{ - ECalComponent *comp; - icalcomponent *icalcomp; - CompEditor *editor; - ECalComponentVType vtype; - - g_assert (oc->open); - - /* Get the object */ - if (!e_cal_get_object (oc->client, uid, NULL, &icalcomp, NULL)) { - /* FIXME Better error handling */ - g_warning (G_STRLOC ": Syntax error while getting component `%s'", uid); - - return; - } - - comp = e_cal_component_new (); - if (!e_cal_component_set_icalcomponent (comp, icalcomp)) { - g_object_unref (comp); - icalcomponent_free (icalcomp); - return; - } - - /* Create the appropriate type of editor */ - - vtype = e_cal_component_get_vtype (comp); - - switch (vtype) { - case E_CAL_COMPONENT_EVENT: - editor = COMP_EDITOR (event_editor_new (oc->client)); - break; - - case E_CAL_COMPONENT_TODO: - editor = COMP_EDITOR (task_editor_new (oc->client)); - break; - - default: - g_message ("edit_exiting(): Unsupported object type %d", (int) vtype); - g_object_unref (comp); - return; - } - - /* Set the object on the editor */ - comp_editor_edit_comp (editor, comp); - comp_editor_focus (editor); - - oc->editor_count++; - g_signal_connect (editor, "destroy", G_CALLBACK (editor_destroy_cb), oc); - - e_comp_editor_registry_add (comp_editor_registry, editor, TRUE); -} - -/* Creates a component with the appropriate defaults for the specified component - * type. - */ -static ECalComponent * -get_default_event (ECal *client, gboolean all_day) -{ - ECalComponent *comp; - struct icaltimetype itt; - ECalComponentDateTime dt; - char *location; - icaltimezone *zone; - - comp = cal_comp_event_new_with_defaults (client); - - location = calendar_config_get_timezone (); - zone = icaltimezone_get_builtin_timezone (location); - - if (all_day) { - itt = icaltime_from_timet_with_zone (time (NULL), 1, zone); - - dt.value = &itt; - dt.tzid = icaltimezone_get_tzid (zone); - - e_cal_component_set_dtstart (comp, &dt); - e_cal_component_set_dtend (comp, &dt); - } else { - itt = icaltime_current_time_with_zone (zone); - icaltime_adjust (&itt, 0, 1, -itt.minute, -itt.second); - - dt.value = &itt; - dt.tzid = icaltimezone_get_tzid (zone); - - e_cal_component_set_dtstart (comp, &dt); - icaltime_adjust (&itt, 0, 1, 0, 0); - e_cal_component_set_dtend (comp, &dt); - } - - e_cal_component_commit_sequence (comp); - - return comp; -} - -static ECalComponent * -get_default_task (ECal *client) -{ - ECalComponent *comp; - - comp = cal_comp_task_new_with_defaults (client); - - return comp; -} - -/* Edits a new object in the context of a client */ -static void -edit_new (OpenClient *oc, const GNOME_Evolution_Calendar_CompEditorFactory_CompEditorMode type) -{ - ECalComponent *comp; - CompEditor *editor; - - switch (type) { - case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_EVENT: - case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_MEETING: - editor = COMP_EDITOR (event_editor_new (oc->client)); - comp = get_default_event (oc->client, FALSE); - break; - case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_ALLDAY_EVENT: - editor = COMP_EDITOR (event_editor_new (oc->client)); - comp = get_default_event (oc->client, TRUE); - break; - case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_TODO: - editor = COMP_EDITOR (task_editor_new (oc->client)); - comp = get_default_task (oc->client); - break; - default: - g_assert_not_reached (); - return; - } - - 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); - - oc->editor_count++; - g_signal_connect (editor, "destroy", G_CALLBACK (editor_destroy_cb), oc); - - e_comp_editor_registry_add (comp_editor_registry, editor, TRUE); -} - -/* Resolves all the pending requests for a client */ -static void -resolve_pending_requests (OpenClient *oc) -{ - CompEditorFactory *factory; - CompEditorFactoryPrivate *priv; - GSList *l; - char *location; - icaltimezone *zone; - - factory = oc->factory; - priv = factory->priv; - - if (!oc->pending) - return; - - /* Set the default timezone in the backend. */ - location = calendar_config_get_timezone (); - zone = icaltimezone_get_builtin_timezone (location); - if (zone) - /* FIXME Error handling? */ - e_cal_set_default_timezone (oc->client, zone, NULL); - - for (l = oc->pending; l; l = l->next) { - Request *request; - - request = l->data; - - switch (request->type) { - case REQUEST_EXISTING: - edit_existing (oc, request->u.existing.uid); - break; - - case REQUEST_NEW: - edit_new (oc, request->u.new.type); - break; - } - - free_request (request); - } - - g_slist_free (oc->pending); - oc->pending = NULL; -} - -/* Callback used when a client is finished opening. We resolve all the pending - * requests. - */ -static void -cal_opened_cb (ECal *client, ECalendarStatus status, gpointer data) -{ - OpenClient *oc; - CompEditorFactory *factory; - CompEditorFactoryPrivate *priv; - GtkWidget *dialog = NULL; - - oc = data; - factory = oc->factory; - priv = factory->priv; - - switch (status) { - case E_CALENDAR_STATUS_OK: - oc->open = TRUE; - resolve_pending_requests (oc); - return; - - case E_CALENDAR_STATUS_OTHER_ERROR: - dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, - GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, - _("Error while opening the calendar")); - break; - - case E_CALENDAR_STATUS_NO_SUCH_CALENDAR: - /* oops - we specified only_if_exists = FALSE */ - g_assert_not_reached (); - return; - - case E_CALENDAR_STATUS_PROTOCOL_NOT_SUPPORTED: - dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, - GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, - _("Method not supported when opening the calendar")); - break; - - case E_CALENDAR_STATUS_PERMISSION_DENIED : - dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, - GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, - _("Permission denied to open the calendar")); - break; - - default: - g_assert_not_reached (); - return; - } - - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - - 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; - ECal *client; - OpenClient *oc; - GError *error = NULL; - - priv = factory->priv; - - client = e_cal_new_from_uri (uristr, CALOBJ_TYPE_ANY); - if (!client) - return NULL; - - oc = g_new (OpenClient, 1); - oc->factory = factory; - - oc->uri = g_strdup (uristr); - - oc->client = client; - oc->editor_count = 0; - oc->pending = NULL; - oc->open = FALSE; - - g_signal_connect (oc->client, "cal_opened", G_CALLBACK (cal_opened_cb), oc); - - g_hash_table_insert (priv->uri_client_hash, oc->uri, oc); - - if (!e_cal_open (oc->client, FALSE, &error)) { - g_warning (_("open_client(): %s"), error->message); - g_free (oc->uri); - g_object_unref (oc->client); - g_free (oc); - g_error_free (error); - - return NULL; - } - - return oc; -} - -/* Looks up an open client or queues it for being opened. Returns the client or - * NULL on failure; in the latter case it sets the ev exception. - */ -static OpenClient * -lookup_open_client (CompEditorFactory *factory, 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 CORBA_char *uid, - CORBA_Environment *ev) -{ - CompEditorFactory *factory; - CompEditorFactoryPrivate *priv; - OpenClient *oc; - CompEditor *editor; - - 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 */ - editor = e_comp_editor_registry_find (comp_editor_registry, uid); - if (editor == NULL) { - edit_existing (oc, uid); - } else { - comp_editor_focus (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 g_object_new (TYPE_COMP_EDITOR_FACTORY, NULL); -} - - diff --git a/calendar/gui/comp-editor-factory.h b/calendar/gui/comp-editor-factory.h deleted file mode 100644 index fca4573497..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-object.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 { - BonoboObject object; - - /* Private data */ - CompEditorFactoryPrivate *priv; -} CompEditorFactory; - -typedef struct { - BonoboObjectClass 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 170adb0cf5..0000000000 --- a/calendar/gui/comp-util.c +++ /dev/null @@ -1,342 +0,0 @@ -/* Evolution calendar - Utilities for manipulating ECalComponent 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 <string.h> -#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 (ECalComponent *comp, time_t t, icaltimezone *zone) -{ - GSList *list; - ECalComponentDateTime *cdt; - - g_return_if_fail (comp != NULL); - g_return_if_fail (E_IS_CAL_COMPONENT (comp)); - - e_cal_component_get_exdate_list (comp, &list); - - cdt = g_new (ECalComponentDateTime, 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); - e_cal_component_set_exdate_list (comp, list); - e_cal_component_free_exdate_list (list); -} - - - -/* Returns TRUE if the TZIDs are equivalent, i.e. both NULL or the same. */ -static gboolean -e_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 #ECal. - * - * 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 (ECalComponent *comp, - ECal *client, - icaltimezone *zone) -{ - ECalComponentDateTime start_datetime, end_datetime; - const char *tzid; - gboolean retval = FALSE; - icaltimezone *start_zone, *end_zone; - int offset1, offset2; - - tzid = icaltimezone_get_tzid (zone); - - e_cal_component_get_dtstart (comp, &start_datetime); - e_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 (e_cal_component_compare_tzid (tzid, start_datetime.tzid) - && e_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. */ - if (!e_cal_get_timezone (client, start_datetime.tzid, - &start_zone, NULL)) - 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; - } - - if (!e_cal_get_timezone (client, end_datetime.tzid, - &end_zone, NULL)) - 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: - - e_cal_component_free_datetime (&start_datetime); - e_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. - **/ -gboolean -cal_comp_is_on_server (ECalComponent *comp, ECal *client) -{ - const char *uid; - icalcomponent *icalcomp; - GError *error = NULL; - - g_return_val_if_fail (comp != NULL, FALSE); - g_return_val_if_fail (E_IS_CAL_COMPONENT (comp), FALSE); - g_return_val_if_fail (client != NULL, FALSE); - g_return_val_if_fail (E_IS_CAL (client), FALSE); - - /* 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. - */ - e_cal_component_get_uid (comp, &uid); - - if (e_cal_get_object (client, uid, NULL, &icalcomp, &error)) { - icalcomponent_free (icalcomp); - - return TRUE; - } - - if (error->code != E_CALENDAR_STATUS_OBJECT_NOT_FOUND) - g_warning (G_STRLOC ": %s", error->message); - - g_clear_error (&error); - - return FALSE; -} - -/** - * 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. - **/ -ECalComponent * -cal_comp_event_new_with_defaults (ECal *client) -{ - icalcomponent *icalcomp; - ECalComponent *comp; - int interval; - CalUnits units; - ECalComponentAlarm *alarm; - icalproperty *icalprop; - ECalComponentAlarmTrigger trigger; - - if (!e_cal_get_default_object (client, &icalcomp, NULL)) - return NULL; - - comp = e_cal_component_new (); - if (!e_cal_component_set_icalcomponent (comp, icalcomp)) { - g_object_unref (comp); - icalcomponent_free (icalcomp); - return NULL; - } - - if (!calendar_config_get_use_default_reminder ()) - return comp; - - interval = calendar_config_get_default_reminder_interval (); - units = calendar_config_get_default_reminder_units (); - - alarm = e_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. For that, we add a - * X-EVOLUTION-NEEDS-DESCRIPTION property to the alarm's component. - */ - icalcomp = e_cal_component_alarm_get_icalcomponent (alarm); - icalprop = icalproperty_new_x ("1"); - icalproperty_set_x_name (icalprop, "X-EVOLUTION-NEEDS-DESCRIPTION"); - icalcomponent_add_property (icalcomp, icalprop); - - e_cal_component_alarm_set_action (alarm, E_CAL_COMPONENT_ALARM_DISPLAY); - - trigger.type = E_CAL_COMPONENT_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 (); - } - - e_cal_component_alarm_set_trigger (alarm, trigger); - - e_cal_component_add_alarm (comp, alarm); - e_cal_component_alarm_free (alarm); - - return comp; -} - -ECalComponent * -cal_comp_task_new_with_defaults (ECal *client) -{ - ECalComponent *comp; - icalcomponent *icalcomp; - - if (!e_cal_get_default_object (client, &icalcomp, NULL)) - return NULL; - - comp = e_cal_component_new (); - if (!e_cal_component_set_icalcomponent (comp, icalcomp)) { - g_object_unref (comp); - icalcomponent_free (icalcomp); - - return NULL; - } - - comp = e_cal_component_new (); - if (!e_cal_component_set_icalcomponent (comp, icalcomp)) { - g_object_unref (comp); - icalcomponent_free (icalcomp); - return NULL; - } - - return comp; -} diff --git a/calendar/gui/comp-util.h b/calendar/gui/comp-util.h deleted file mode 100644 index 0f4542aba1..0000000000 --- a/calendar/gui/comp-util.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Evolution calendar - Utilities for manipulating ECalComponent 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 <libecal/e-cal-component.h> -#include <libecal/e-cal.h> - -void cal_comp_util_add_exdate (ECalComponent *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 (ECalComponent *comp, - ECal *client, - icaltimezone *zone); - -gboolean cal_comp_is_on_server (ECalComponent *comp, - ECal *client); - -ECalComponent *cal_comp_event_new_with_defaults (ECal *client); -ECalComponent *cal_comp_task_new_with_defaults (ECal *client); - -#endif diff --git a/calendar/gui/control-factory.c b/calendar/gui/control-factory.c deleted file mode 100644 index 58436ec841..0000000000 --- a/calendar/gui/control-factory.c +++ /dev/null @@ -1,217 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* control-factory.c - * - * Copyright (C) 2000, 2001, 2002, 2003 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Ettore Perazzoli <ettore@ximian.com> - */ - -#include <config.h> -#include <string.h> -#include <gtk/gtksignal.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 <bonobo/bonobo-property-bag.h> -#include <glade/glade.h> -#include <libgnomeui/gnome-dialog-util.h> - -#include <libecal/e-cal-time-util.h> -#include <gui/gnome-cal.h> -#include <gui/calendar-commands.h> -#include <gui/calendar-config.h> - -#include "control-factory.h" - -#define PROPERTY_CALENDAR_URI "folder_uri" -#define PROPERTY_CALENDAR_URI_IDX 1 - -#define PROPERTY_CALENDAR_VIEW "view" -#define PROPERTY_CALENDAR_VIEW_IDX 2 - - -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; - const char *uri; - BonoboControl *control = user_data; - - gcal = (GnomeCalendar *) bonobo_control_get_widget (control); - - switch (arg_id) { - - case PROPERTY_CALENDAR_URI_IDX: - uri = e_cal_get_uri (e_cal_model_get_default_client (gnome_calendar_get_calendar_model (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; - case GNOME_CAL_LIST_VIEW: - BONOBO_ARG_SET_STRING (arg, "list"); - break; - default: - } - 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; - char *string; - GnomeCalendarViewType view; - BonoboControl *control = user_data; - - gcal = (GnomeCalendar *) bonobo_control_get_widget (control); - - switch (arg_id) { - case PROPERTY_CALENDAR_URI_IDX: - string = BONOBO_ARG_GET_STRING (arg); - if (gnome_calendar_add_event_uri (gcal, string)) { - calendar_control_sensitize_calendar_commands (control, gcal, TRUE); - } else { - char *msg; - - msg = g_strdup_printf (_("Could not open the folder in '%s'"), string); - 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 (!strcmp (string, "week")) - view = GNOME_CAL_WEEK_VIEW; - else if (!strcmp (string, "workweek")) - view = GNOME_CAL_WORK_WEEK_VIEW; - else if (!strcmp (string, "month")) - view = GNOME_CAL_MONTH_VIEW; - else if (!strcmp (string, "day")) - view = GNOME_CAL_DAY_VIEW; - else - view = calendar_config_get_default_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, control); - - 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, bonobo_object_corba_objref (BONOBO_OBJECT (pbag)), NULL); - bonobo_object_unref (BONOBO_OBJECT (pbag)); -} - -BonoboControl * -control_factory_new_control (void) -{ - BonoboControl *control; - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (gnome_calendar_new ()); - if (!gcal) - return NULL; - - gtk_widget_show (GTK_WIDGET (gcal)); - - control = bonobo_control_new (GTK_WIDGET (gcal)); - if (!control) { - g_message ("control_factory_fn(): could not create the control!"); - return NULL; - } - g_object_set_data (G_OBJECT (gcal), "control", control); - - calendar_properties_init (gcal, control); - - g_signal_connect (control, "activate", G_CALLBACK (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 bab1611c03..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, 2001, 2002, 2003 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Ettore Perazzoli <ettore@ximian.com> - */ - -#ifndef _CONTROL_FACTORY_H_ -#define _CONTROL_FACTORY_H_ - -#include <bonobo/bonobo-control.h> - -BonoboControl *control_factory_new_control (void); - -#endif /* _CONTROL_FACTORY_H_ */ diff --git a/calendar/gui/dialogs/.cvsignore b/calendar/gui/dialogs/.cvsignore deleted file mode 100644 index 182657d5ac..0000000000 --- a/calendar/gui/dialogs/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -.deps -.pure -Makefile -Makefile.in -Evolution-Addressbook-SelectNames-common.c -Evolution-Addressbook-SelectNames-skels.c -Evolution-Addressbook-SelectNames-stubs.c -Evolution-Addressbook-SelectNames.h diff --git a/calendar/gui/dialogs/Makefile.am b/calendar/gui/dialogs/Makefile.am deleted file mode 100644 index 7e3b76fd97..0000000000 --- a/calendar/gui/dialogs/Makefile.am +++ /dev/null @@ -1,106 +0,0 @@ -IDLS = $(top_srcdir)/addressbook/gui/component/select-names/Evolution-Addressbook-SelectNames.idl - -IDL_GENERATED_H = \ - Evolution-Addressbook-SelectNames.h -IDL_GENERATED = $(IDL_GENERATED_H) - -$(IDL_GENERATED_H): $(IDLS) - $(ORBIT_IDL) -I $(srcdir) $(IDL_INCLUDES) \ - --nostubs --noskels --nocommon \ - $(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_builddir) \ - -I$(top_srcdir)/calendar \ - -I$(top_srcdir)/calendar/cal-client \ - -I$(top_builddir)/calendar/cal-client \ - -I$(top_builddir)/shell \ - -I$(top_srcdir)/shell \ - -DEVOLUTION_DATADIR=\""$(datadir)"\" \ - -DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \ - -DEVOLUTION_IMAGESDIR=\""$(imagesdir)"\" \ - -DEVOLUTION_UIDIR=\""$(evolutionuidir)"\" \ - -DPREFIX=\""$(prefix)"\" \ - $(EVOLUTION_CALENDAR_CFLAGS) - -noinst_LTLIBRARIES = libcal-dialogs.la - -libcal_dialogs_la_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 \ - copy-source-dialog.c \ - copy-source-dialog.h \ - delete-comp.c \ - delete-comp.h \ - delete-error.c \ - delete-error.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 \ - new-calendar.c \ - new-calendar.h \ - new-task-list.c \ - new-task-list.h \ - recurrence-page.c \ - recurrence-page.h \ - recur-comp.c \ - recur-comp.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 - -glade_DATA = \ - alarm-options.glade \ - alarm-page.glade \ - cal-prefs-dialog.glade \ - e-delegate-dialog.glade \ - event-page.glade \ - meeting-page.glade \ - new-calendar.glade \ - new-task-list.glade \ - recurrence-page.glade \ - schedule-page.glade \ - task-details-page.glade \ - task-page.glade - - -CLEANFILES = $(BUILT_SOURCES) - -dist-hook: - cd $(distdir); rm -f $(BUILT_SOURCES) - -EXTRA_DIST = \ - $(glade_DATA) diff --git a/calendar/gui/dialogs/alarm-options.c b/calendar/gui/dialogs/alarm-options.c deleted file mode 100644 index 512020d4d6..0000000000 --- a/calendar/gui/dialogs/alarm-options.c +++ /dev/null @@ -1,811 +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-i18n.h> -#include <gtk/gtkmain.h> -#include <gtk/gtkcheckbutton.h> -#include <gtk/gtkdialog.h> -#include <gtk/gtkentry.h> -#include <gtk/gtksignal.h> -#include <gtk/gtkwindow.h> -#include <gtk/gtkhbox.h> -#include <gtk/gtktextbuffer.h> -#include <gtk/gtktextview.h> -#include <bonobo/bonobo-control.h> -#include <bonobo/bonobo-exception.h> -#include <bonobo/bonobo-widget.h> -#include <libgnomeui/gnome-file-entry.h> -#include <glade/glade.h> -#include <addressbook/util/eab-destination.h> -#include "Evolution-Addressbook-SelectNames.h" -#include "e-util/e-dialog-widgets.h" -#include "alarm-options.h" - - - -typedef struct { - /* Glade XML data */ - GladeXML *xml; - - /* The alarm action selected */ - ECalComponentAlarmAction action; - - /* Toplevel */ - GtkWidget *toplevel; - - /* Alarm repeat widgets */ - gboolean repeat; - 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; - - /* Mail alarm widgets */ - const char *email; - GtkWidget *malarm_group; - GtkWidget *malarm_address_group; - GtkWidget *malarm_addresses; - GtkWidget *malarm_addressbook; - GtkWidget *malarm_description; - GNOME_Evolution_Addressbook_SelectNames corba_select_names; - - /* Procedure alarm widgets */ - GtkWidget *palarm_group; - GtkWidget *palarm_program; - GtkWidget *palarm_args; -} Dialog; - -#define SELECT_NAMES_OAFID "OAFIID:GNOME_Evolution_Addressbook_SelectNames:" BASE_VERSION -static const char *section_name = "Send To"; - - - -/* 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->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->malarm_address_group = GW ("malarm-address-group"); - dialog->malarm_addressbook = GW ("malarm-addressbook"); - dialog->malarm_description = GW ("malarm-description"); - - dialog->palarm_group = GW ("palarm-group"); - dialog->palarm_program = GW ("palarm-program"); - dialog->palarm_args = GW ("palarm-args"); - - return (dialog->toplevel - && 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->malarm_address_group - && dialog->malarm_addressbook - && dialog->malarm_description - && dialog->palarm_group - && dialog->palarm_program - && dialog->palarm_args); -} - -static void -addressbook_clicked_cb (GtkWidget *widget, gpointer data) -{ - Dialog *dialog = data; - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_SelectNames_activateDialog (dialog->corba_select_names, - section_name, &ev); - - CORBA_exception_free (&ev); -} - -static gboolean -setup_select_names (Dialog *dialog) -{ - Bonobo_Control corba_control; - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - dialog->corba_select_names = bonobo_activation_activate_from_id (SELECT_NAMES_OAFID, 0, NULL, &ev); - if (BONOBO_EX (&ev)) - return FALSE; - - GNOME_Evolution_Addressbook_SelectNames_addSection (dialog->corba_select_names, - section_name, section_name, &ev); - if (BONOBO_EX (&ev)) - return FALSE; - - corba_control = GNOME_Evolution_Addressbook_SelectNames_getEntryBySection (dialog->corba_select_names, - section_name, &ev); - - if (BONOBO_EX (&ev)) - return FALSE; - - CORBA_exception_free (&ev); - - dialog->malarm_addresses = bonobo_widget_new_control_from_objref (corba_control, CORBA_OBJECT_NIL); - gtk_widget_show (dialog->malarm_addresses); - gtk_box_pack_end_defaults (GTK_BOX (dialog->malarm_address_group), dialog->malarm_addresses); - - gtk_signal_connect (GTK_OBJECT (dialog->malarm_addressbook), "clicked", - GTK_SIGNAL_FUNC (addressbook_clicked_cb), dialog); - - return TRUE; -} - -static void -palarm_options_changed_cb (GtkEditable *entry, gpointer user_data) -{ - const gchar *text; - Dialog *dialog = user_data; - - text = gtk_entry_get_text (GTK_ENTRY (dialog->palarm_program)); - if (text && *text) - gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog->toplevel), GTK_RESPONSE_OK, TRUE); - else - gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog->toplevel), GTK_RESPONSE_OK, FALSE); -} - -/* 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); - - /* activate the 'OK' button */ - if (dialog->action == E_CAL_COMPONENT_ALARM_PROCEDURE) - palarm_options_changed_cb (GTK_EDITABLE (dialog->palarm_program), dialog); -} - -static void -repeat_spin_button_changed_cb (GtkWidget *spin, gpointer user_data) -{ - Dialog *dialog = user_data; - - if (dialog->action == E_CAL_COMPONENT_ALARM_PROCEDURE) - palarm_options_changed_cb (GTK_EDITABLE (dialog->palarm_program), dialog); -} - - -static void -repeat_unit_changed_cb (GtkWidget *option_menu, gpointer user_data) -{ - Dialog *dialog = user_data; - - if (dialog->action == E_CAL_COMPONENT_ALARM_PROCEDURE) - palarm_options_changed_cb (GTK_EDITABLE (dialog->palarm_program), dialog); -} - -/* Hooks the widget signals */ -static void -init_widgets (Dialog *dialog) -{ - /* Alarm repeat */ - - g_signal_connect (G_OBJECT (dialog->repeat_toggle), "toggled", - G_CALLBACK (repeat_toggle_toggled_cb), dialog); - - g_signal_connect (G_OBJECT (dialog->repeat_quantity), "value_changed", - G_CALLBACK (repeat_spin_button_changed_cb), dialog); - g_signal_connect (G_OBJECT (dialog->repeat_value), "value_changed", - G_CALLBACK (repeat_spin_button_changed_cb), dialog); - - g_signal_connect (G_OBJECT (dialog->repeat_unit), "changed", - G_CALLBACK (repeat_unit_changed_cb), dialog); -} - -/* Fills the audio alarm widgets with the values from the alarm component */ -static void -alarm_to_aalarm_widgets (Dialog *dialog, ECalComponentAlarm *alarm) -{ - icalattach *attach; - const char *url; - - e_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, ECalComponentAlarm *alarm) -{ - ECalComponentText description; - GtkTextBuffer *text_buffer; - - e_cal_component_alarm_get_description (alarm, &description); - - text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (dialog->dalarm_description)); - gtk_text_buffer_set_text (text_buffer, description.value ? description.value : "", -1); -} - -/* Fills the mail alarm widgets with the values from the alarm component */ -static void -alarm_to_malarm_widgets (Dialog *dialog, ECalComponentAlarm *alarm) -{ - ECalComponentText description; - GtkTextBuffer *text_buffer; - GSList *attendee_list, *l; - EABDestination **destv; - int len, i; - - /* Recipients */ - e_cal_component_alarm_get_attendee_list (alarm, &attendee_list); - len = g_slist_length (attendee_list); - - if (len <= 0) { - destv = g_new0 (EABDestination *, 2); - destv[0] = eab_destination_new (); - eab_destination_set_email (destv[0], dialog->email); - destv[1] = NULL; - len = 1; - } else { - destv = g_new0 (EABDestination *, len + 1); - for (l = attendee_list, i = 0; l != NULL; l = l->next, i++) { - ECalComponentAttendee *a = l->data; - EABDestination *dest; - - dest = eab_destination_new (); - if (a->cn != NULL && *a->cn) - eab_destination_set_name (dest, a->cn); - if (a->value != NULL && *a->value) - eab_destination_set_email (dest, a->value); - - destv[i] = dest; - } - destv[i] = NULL; - } - - bonobo_widget_set_property (BONOBO_WIDGET (dialog->malarm_addresses), - "destinations", eab_destination_exportv (destv), NULL); - - for (i = 0; i < len; i++) - g_object_unref (GTK_OBJECT (destv[i])); - g_free (destv); - - e_cal_component_free_attendee_list (attendee_list); - - /* Description */ - e_cal_component_alarm_get_description (alarm, &description); - - text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (dialog->malarm_description)); - gtk_text_buffer_set_text (text_buffer, description.value ? description.value : "", -1); -} - -/* Fills the procedure alarm widgets with the values from the alarm component */ -static void -alarm_to_palarm_widgets (Dialog *dialog, ECalComponentAlarm *alarm) -{ - icalattach *attach; - ECalComponentText description; - - e_cal_component_alarm_get_attach (alarm, &attach); - e_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, ECalComponentAlarm *alarm) -{ - ECalComponentAlarmRepeat repeat; - int value; - enum duration_units units; - - e_cal_component_alarm_get_repeat (alarm, &repeat); - - /* Sensitivity */ - - if (!dialog->repeat || repeat.repetitions == 0) { - gtk_widget_set_sensitive (dialog->repeat_toggle, dialog->repeat); - 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, ECalComponentAlarm *alarm) -{ - ECalComponentAlarmAction action; - - alarm_to_repeat_widgets (dialog, alarm); - - e_cal_component_alarm_get_action (alarm, &action); - - switch (action) { - case E_CAL_COMPONENT_ALARM_NONE: - g_assert_not_reached (); - return; - - case E_CAL_COMPONENT_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 E_CAL_COMPONENT_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 E_CAL_COMPONENT_ALARM_EMAIL: - gtk_window_set_title (GTK_WINDOW (dialog->toplevel), _("Email 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 E_CAL_COMPONENT_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); - - /* make sure the 'OK' button is disabled while the program entry is empty */ - gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog->toplevel), GTK_RESPONSE_OK, FALSE); - g_signal_connect (G_OBJECT (dialog->palarm_program), "changed", - G_CALLBACK (palarm_options_changed_cb), dialog); - g_signal_connect (G_OBJECT (dialog->palarm_args), "changed", - G_CALLBACK (palarm_options_changed_cb), dialog); - break; - - case E_CAL_COMPONENT_ALARM_UNKNOWN: - gtk_window_set_title (GTK_WINDOW (dialog->toplevel), _("Unknown Alarm Options")); - break; - - default: - g_assert_not_reached (); - return; - } - - dialog->action = action; -} - - - -/* Fills the alarm data with the values from the repeat/duration widgets */ -static void -repeat_widgets_to_alarm (Dialog *dialog, ECalComponentAlarm *alarm) -{ - ECalComponentAlarmRepeat repeat; - - if (!e_dialog_toggle_get (dialog->repeat_toggle)) { - repeat.repetitions = 0; - - e_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 (); - } - - e_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, ECalComponentAlarm *alarm) -{ - char *url; - icalattach *attach; - - url = e_dialog_editable_get (dialog->aalarm_attach); - attach = icalattach_new_from_url (url ? url : ""); - g_free (url); - - e_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, ECalComponentAlarm *alarm) -{ - char *str; - ECalComponentText description; - GtkTextBuffer *text_buffer; - GtkTextIter text_iter_start, text_iter_end; - icalcomponent *icalcomp; - icalproperty *icalprop; - - text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (dialog->dalarm_description)); - gtk_text_buffer_get_start_iter (text_buffer, &text_iter_start); - gtk_text_buffer_get_end_iter (text_buffer, &text_iter_end); - str = gtk_text_buffer_get_text (text_buffer, &text_iter_start, &text_iter_end, FALSE); - - description.value = str; - description.altrep = NULL; - - e_cal_component_alarm_set_description (alarm, &description); - g_free (str); - - /* remove the X-EVOLUTION-NEEDS-DESCRIPTION property, so that - * we don't re-set the alarm's description */ - icalcomp = e_cal_component_alarm_get_icalcomponent (alarm); - icalprop = icalcomponent_get_first_property (icalcomp, ICAL_X_PROPERTY); - while (icalprop) { - const char *x_name; - - x_name = icalproperty_get_x_name (icalprop); - if (!strcmp (x_name, "X-EVOLUTION-NEEDS-DESCRIPTION")) { - icalcomponent_remove_property (icalcomp, icalprop); - break; - } - - icalprop = icalcomponent_get_next_property (icalcomp, ICAL_X_PROPERTY); - } -} - -/* Fills the mail alarm data with the values from the widgets */ -static void -malarm_widgets_to_alarm (Dialog *dialog, ECalComponentAlarm *alarm) -{ - char *str; - ECalComponentText description; - GSList *attendee_list = NULL; - EABDestination **destv; - GtkTextBuffer *text_buffer; - GtkTextIter text_iter_start, text_iter_end; - icalcomponent *icalcomp; - icalproperty *icalprop; - int i; - - /* Attendees */ - bonobo_widget_get_property (BONOBO_WIDGET (dialog->malarm_addresses), "destinations", - TC_CORBA_string, &str, NULL); - destv = eab_destination_importv (str); - g_free (str); - - for (i = 0; destv[i] != NULL; i++) { - EABDestination *dest; - ECalComponentAttendee *a; - - dest = destv[i]; - - a = g_new0 (ECalComponentAttendee, 1); - a->value = eab_destination_get_email (dest); - a->cn = eab_destination_get_name (dest); - - attendee_list = g_slist_append (attendee_list, a); - } - - e_cal_component_alarm_set_attendee_list (alarm, attendee_list); - - e_cal_component_free_attendee_list (attendee_list); - eab_destination_freev (destv); - - /* Description */ - text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (dialog->dalarm_description)); - gtk_text_buffer_get_start_iter (text_buffer, &text_iter_start); - gtk_text_buffer_get_end_iter (text_buffer, &text_iter_end); - str = gtk_text_buffer_get_text (text_buffer, &text_iter_start, &text_iter_end, FALSE); - - description.value = str; - description.altrep = NULL; - - e_cal_component_alarm_set_description (alarm, &description); - g_free (str); - - /* remove the X-EVOLUTION-NEEDS-DESCRIPTION property, so that - * we don't re-set the alarm's description */ - icalcomp = e_cal_component_alarm_get_icalcomponent (alarm); - icalprop = icalcomponent_get_first_property(icalcomp, ICAL_X_PROPERTY); - while (icalprop) { - const char *x_name; - - x_name = icalproperty_get_x_name (icalprop); - if (!strcmp (x_name, "X-EVOLUTION-NEEDS-DESCRIPTION")) { - icalcomponent_remove_property (icalcomp, icalprop); - break; - } - - icalprop = icalcomponent_get_next_property (icalcomp, ICAL_X_PROPERTY); - } -} - -/* Fills the procedure alarm data with the values from the widgets */ -static void -palarm_widgets_to_alarm (Dialog *dialog, ECalComponentAlarm *alarm) -{ - char *program; - icalattach *attach; - char *str; - ECalComponentText description; - icalcomponent *icalcomp; - icalproperty *icalprop; - - program = e_dialog_editable_get (dialog->palarm_program); - attach = icalattach_new_from_url (program ? program : ""); - g_free (program); - - e_cal_component_alarm_set_attach (alarm, attach); - icalattach_unref (attach); - - str = e_dialog_editable_get (dialog->palarm_args); - description.value = str; - description.altrep = NULL; - - e_cal_component_alarm_set_description (alarm, &description); - g_free (str); - - /* remove the X-EVOLUTION-NEEDS-DESCRIPTION property, so that - * we don't re-set the alarm's description */ - icalcomp = e_cal_component_alarm_get_icalcomponent (alarm); - icalprop = icalcomponent_get_first_property (icalcomp, ICAL_X_PROPERTY); - while (icalprop) { - const char *x_name; - - x_name = icalproperty_get_x_name (icalprop); - if (!strcmp (x_name, "X-EVOLUTION-NEEDS-DESCRIPTION")) { - icalcomponent_remove_property (icalcomp, icalprop); - break; - } - - icalprop = icalcomponent_get_next_property (icalcomp, ICAL_X_PROPERTY); - } -} - -/* Fills the alarm data with the values from the widgets */ -static void -dialog_to_alarm (Dialog *dialog, ECalComponentAlarm *alarm) -{ - ECalComponentAlarmAction action; - - repeat_widgets_to_alarm (dialog, alarm); - - e_cal_component_alarm_get_action (alarm, &action); - - switch (action) { - case E_CAL_COMPONENT_ALARM_NONE: - g_assert_not_reached (); - break; - - case E_CAL_COMPONENT_ALARM_AUDIO: - aalarm_widgets_to_alarm (dialog, alarm); - break; - - case E_CAL_COMPONENT_ALARM_DISPLAY: - dalarm_widgets_to_alarm (dialog, alarm); - break; - - case E_CAL_COMPONENT_ALARM_EMAIL: - malarm_widgets_to_alarm (dialog, alarm); - break; - - case E_CAL_COMPONENT_ALARM_PROCEDURE: - palarm_widgets_to_alarm (dialog, alarm); - break; - - case E_CAL_COMPONENT_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 (ECalComponentAlarm *alarm, const char *email, gboolean repeat) -{ - Dialog dialog; - int response_id; - - g_return_val_if_fail (alarm != NULL, FALSE); - - dialog.repeat = repeat; - dialog.email = email; - dialog.xml = glade_xml_new (EVOLUTION_GLADEDIR "/alarm-options.glade", NULL, NULL); - if (!dialog.xml) { - g_message ("alarm_options_dialog_new(): Could not load the Glade XML file!"); - return FALSE; - } - - if (!get_widgets (&dialog)) { - g_object_unref(dialog.xml); - return FALSE; - } - - if (!setup_select_names (&dialog)) { - g_object_unref (dialog.xml); - return FALSE; - } - - init_widgets (&dialog); - - alarm_to_dialog (&dialog, alarm); - - response_id = gtk_dialog_run (GTK_DIALOG (dialog.toplevel)); - gtk_widget_hide (dialog.toplevel); - - if (response_id == GTK_RESPONSE_OK) - dialog_to_alarm (&dialog, alarm); - - gtk_widget_destroy (dialog.toplevel); - g_object_unref(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 d58e817ba3..0000000000 --- a/calendar/gui/dialogs/alarm-options.glade +++ /dev/null @@ -1,573 +0,0 @@ -<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> -<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> - -<glade-interface> -<requires lib="gnome"/> - -<widget class="GtkDialog" id="alarm-options-toplevel"> - <property name="border_width">12</property> - <property name="visible">True</property> - <property name="title" translatable="yes">dialog1</property> - <property name="type">GTK_WINDOW_TOPLEVEL</property> - <property name="window_position">GTK_WIN_POS_NONE</property> - <property name="modal">True</property> - <property name="resizable">True</property> - <property name="destroy_with_parent">True</property> - <property name="has_separator">True</property> - - <child internal-child="vbox"> - <widget class="GtkVBox" id="dialog-vbox1"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child internal-child="action_area"> - <widget class="GtkHButtonBox" id="dialog-action_area1"> - <property name="visible">True</property> - <property name="layout_style">GTK_BUTTONBOX_END</property> - - <child> - <widget class="GtkButton" id="cancelbutton1"> - <property name="visible">True</property> - <property name="can_default">True</property> - <property name="can_focus">True</property> - <property name="label">gtk-cancel</property> - <property name="use_stock">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="response_id">-6</property> - </widget> - </child> - - <child> - <widget class="GtkButton" id="okbutton1"> - <property name="visible">True</property> - <property name="can_default">True</property> - <property name="can_focus">True</property> - <property name="label">gtk-ok</property> - <property name="use_stock">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="response_id">-5</property> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="pack_type">GTK_PACK_END</property> - </packing> - </child> - - <child> - <widget class="GtkVBox" id="vbox1"> - <property name="border_width">4</property> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkFrame" id="frame1"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <property name="label_yalign">0.5</property> - <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property> - - <child> - <widget class="GtkHBox" id="hbox1"> - <property name="border_width">6</property> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkCheckButton" id="repeat-toggle"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="has_focus">True</property> - <property name="label" translatable="yes">Repeat the alarm</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkHBox" id="repeat-group"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">4</property> - - <child> - <widget class="GtkSpinButton" id="repeat-quantity"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="climb_rate">1</property> - <property name="digits">0</property> - <property name="numeric">True</property> - <property name="update_policy">GTK_UPDATE_ALWAYS</property> - <property name="snap_to_ticks">False</property> - <property name="wrap">False</property> - <property name="adjustment">1 1 999 1 10 10</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label1"> - <property name="visible">True</property> - <property name="label" translatable="yes">extra times every</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkSpinButton" id="repeat-value"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="climb_rate">1</property> - <property name="digits">0</property> - <property name="numeric">True</property> - <property name="update_policy">GTK_UPDATE_ALWAYS</property> - <property name="snap_to_ticks">False</property> - <property name="wrap">False</property> - <property name="adjustment">1 0 999 1 10 10</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkOptionMenu" id="repeat-unit"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="history">0</property> - - <child internal-child="menu"> - <widget class="GtkMenu" id="convertwidget1"> - <property name="visible">True</property> - - <child> - <widget class="GtkMenuItem" id="convertwidget2"> - <property name="visible">True</property> - <property name="label" translatable="yes">minutes</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget3"> - <property name="visible">True</property> - <property name="label" translatable="yes">hours</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget4"> - <property name="visible">True</property> - <property name="label" translatable="yes">days</property> - <property name="use_underline">True</property> - </widget> - </child> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - </child> - - <child> - <widget class="GtkLabel" id="label1"> - <property name="visible">True</property> - <property name="label" translatable="yes">Alarm Repeat</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkVBox" id="dalarm-group"> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkLabel" id="label2"> - <property name="visible">True</property> - <property name="label" translatable="yes">Message to Display:</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkScrolledWindow" id="scrolledwindow1"> - <property name="visible">True</property> - <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> - <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="shadow_type">GTK_SHADOW_IN</property> - <property name="window_placement">GTK_CORNER_TOP_LEFT</property> - - <child> - <widget class="GtkTextView" id="dalarm-description"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="editable">True</property> - <property name="justification">GTK_JUSTIFY_LEFT</property> - <property name="wrap_mode">GTK_WRAP_WORD</property> - <property name="cursor_visible">True</property> - <property name="pixels_above_lines">0</property> - <property name="pixels_below_lines">0</property> - <property name="pixels_inside_wrap">0</property> - <property name="left_margin">0</property> - <property name="right_margin">0</property> - <property name="indent">0</property> - <property name="text" translatable="yes"></property> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkHBox" id="aalarm-group"> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkLabel" id="label3"> - <property name="visible">True</property> - <property name="label" translatable="yes">Play sound:</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GnomeFileEntry" id="file-entry1"> - <property name="visible">True</property> - <property name="max_saved">10</property> - <property name="directory_entry">False</property> - <property name="modal">True</property> - - <child internal-child="entry"> - <widget class="GtkEntry" id="aalarm-attach"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="editable">True</property> - <property name="visibility">True</property> - <property name="max_length">0</property> - <property name="text" translatable="yes"></property> - <property name="has_frame">True</property> - <property name="invisible_char" translatable="yes">*</property> - <property name="activates_default">False</property> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkVBox" id="malarm-group"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkHBox" id="malarm-address-group"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkButton" id="malarm-addressbook"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Send To:</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <placeholder/> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label7"> - <property name="visible">True</property> - <property name="label" translatable="yes">Message to Send</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkScrolledWindow" id="scrolledwindow2"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> - <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="shadow_type">GTK_SHADOW_NONE</property> - <property name="window_placement">GTK_CORNER_TOP_LEFT</property> - - <child> - <widget class="GtkTextView" id="malarm-description"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="editable">True</property> - <property name="justification">GTK_JUSTIFY_LEFT</property> - <property name="wrap_mode">GTK_WRAP_WORD</property> - <property name="cursor_visible">True</property> - <property name="pixels_above_lines">0</property> - <property name="pixels_below_lines">0</property> - <property name="pixels_inside_wrap">0</property> - <property name="left_margin">0</property> - <property name="right_margin">0</property> - <property name="indent">0</property> - <property name="text" translatable="yes"></property> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkHBox" id="palarm-group"> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkLabel" id="label5"> - <property name="visible">True</property> - <property name="label" translatable="yes">Run program:</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkEntry" id="palarm-program"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="editable">True</property> - <property name="visibility">True</property> - <property name="max_length">0</property> - <property name="text" translatable="yes"></property> - <property name="has_frame">True</property> - <property name="invisible_char" translatable="yes">*</property> - <property name="activates_default">False</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label6"> - <property name="visible">True</property> - <property name="label" translatable="yes">With these arguments:</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkEntry" id="palarm-args"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="editable">True</property> - <property name="visibility">True</property> - <property name="max_length">0</property> - <property name="text" translatable="yes"></property> - <property name="has_frame">True</property> - <property name="invisible_char" translatable="yes">*</property> - <property name="activates_default">False</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - </child> -</widget> - -</glade-interface> diff --git a/calendar/gui/dialogs/alarm-options.h b/calendar/gui/dialogs/alarm-options.h deleted file mode 100644 index 5a07935810..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 <libecal/e-cal-component.h> - -gboolean alarm_options_dialog_run (ECalComponentAlarm *alarm, const char *email, gboolean repeat); - -#endif diff --git a/calendar/gui/dialogs/alarm-page.c b/calendar/gui/dialogs/alarm-page.c deleted file mode 100644 index 603cd5c8b6..0000000000 --- a/calendar/gui/dialogs/alarm-page.c +++ /dev/null @@ -1,869 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* Evolution calendar - Alarm page of the calendar component dialogs - * - * Copyright (C) 2001-2003 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> - * Hans Petter Jansson <hpj@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/gtklabel.h> -#include <gtk/gtkcellrenderertext.h> -#include <gtk/gtksignal.h> -#include <gtk/gtktreeview.h> -#include <gtk/gtktreeselection.h> -#include <gtk/gtkoptionmenu.h> -#include <libgnome/gnome-i18n.h> -#include <glade/glade.h> -#include "e-util/e-dialog-widgets.h" -#include "e-util/e-time-utils.h" -#include <libecal/e-cal-util.h> -#include <libecal/e-cal-time-util.h> -#include "../calendar-config.h" -#include "comp-editor-util.h" -#include "alarm-options.h" -#include "../e-alarm-list.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 */ - ECalComponentAlarm *alarm; - - /* Alarm store for the GtkTreeView list widget */ - EAlarmList *list_store; - - gboolean updating; - - /* Old summary, to detect changes */ - gchar *old_summary; -}; - -/* "relative" types */ -enum { - BEFORE, - AFTER -}; - -/* Time units */ -enum { - MINUTES, - HOURS, - DAYS -}; - -/* Option menu maps */ -static const int action_map[] = { - E_CAL_COMPONENT_ALARM_DISPLAY, - E_CAL_COMPONENT_ALARM_AUDIO, - E_CAL_COMPONENT_ALARM_PROCEDURE, - E_CAL_COMPONENT_ALARM_EMAIL, - -1 -}; - -static const char *action_map_cap[] = { - CAL_STATIC_CAPABILITY_NO_DISPLAY_ALARMS, - CAL_STATIC_CAPABILITY_NO_AUDIO_ALARMS, - CAL_STATIC_CAPABILITY_NO_PROCEDURE_ALARMS, - CAL_STATIC_CAPABILITY_NO_EMAIL_ALARMS -}; - -static const int value_map[] = { - MINUTES, - HOURS, - DAYS, - -1 -}; - -static const int relative_map[] = { - BEFORE, - AFTER, - -1 -}; - -static const int time_map[] = { - E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START, - E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_END, - -1 -}; - - - -static void alarm_page_class_init (AlarmPageClass *class); -static void alarm_page_init (AlarmPage *apage); -static void alarm_page_finalize (GObject *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, ECalComponent *comp); -static gboolean alarm_page_fill_component (CompEditorPage *page, ECalComponent *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. - **/ - -E_MAKE_TYPE (alarm_page, "AlarmPage", AlarmPage, alarm_page_class_init, - alarm_page_init, TYPE_COMP_EDITOR_PAGE); - -/* Class initialization function for the alarm page */ -static void -alarm_page_class_init (AlarmPageClass *class) -{ - CompEditorPageClass *editor_page_class; - GObjectClass *gobject_class; - - editor_page_class = (CompEditorPageClass *) class; - gobject_class = (GObjectClass *) class; - - parent_class = g_type_class_ref (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; - - gobject_class->finalize = alarm_page_finalize; -} - -/* Object initialization function for the alarm page */ -static void -alarm_page_init (AlarmPage *apage) -{ - AlarmPagePrivate *priv; - icalcomponent *icalcomp; - icalproperty *icalprop; - - 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; - - /* create the default alarm, which will contain the - * X-EVOLUTION-NEEDS-DESCRIPTION property, so that we - * set a correct description if none is set */ - priv->alarm = e_cal_component_alarm_new (); - - icalcomp = e_cal_component_alarm_get_icalcomponent (priv->alarm); - icalprop = icalproperty_new_x ("1"); - icalproperty_set_x_name (icalprop, "X-EVOLUTION-NEEDS-DESCRIPTION"); - icalcomponent_add_property (icalcomp, icalprop); - - priv->updating = FALSE; - priv->old_summary = NULL; -} - -/* Destroy handler for the alarm page */ -static void -alarm_page_finalize (GObject *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->main) - gtk_widget_unref (priv->main); - - if (priv->xml) { - g_object_unref (priv->xml); - priv->xml = NULL; - } - - if (priv->alarm) { - e_cal_component_alarm_free (priv->alarm); - priv->alarm = NULL; - } - - if (priv->list_store) { - g_object_unref (priv->list_store); - priv->list_store = NULL; - } - - if (priv->old_summary) { - g_free (priv->old_summary); - priv->old_summary = NULL; - } - - g_free (priv); - apage->priv = NULL; - - if (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (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, E_CAL_COMPONENT_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, E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START, time_map); - - /* List data */ - e_alarm_list_clear (priv->list_store); -} - -static void -sensitize_buttons (AlarmPage *apage) -{ - AlarmPagePrivate *priv; - ECal *client; - GtkTreeSelection *selection; - GtkTreeIter iter; - gboolean have_selected; - - priv = apage->priv; - - client = COMP_EDITOR_PAGE (apage)->client; - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->list)); - have_selected = gtk_tree_selection_get_selected (selection, NULL, &iter); - - gtk_widget_set_sensitive (priv->add, - e_cal_get_one_alarm_only (client) && have_selected ? FALSE : TRUE); - gtk_widget_set_sensitive (priv->delete, have_selected); -} - -/* Appends an alarm to the list */ -static void -append_reminder (AlarmPage *apage, ECalComponentAlarm *alarm) -{ - AlarmPagePrivate *priv; - GtkTreeView *view; - GtkTreeIter iter; - - priv = apage->priv; - view = GTK_TREE_VIEW (priv->list); - - e_alarm_list_append (priv->list_store, &iter, alarm); - gtk_tree_selection_select_iter (gtk_tree_view_get_selection (view), &iter); - - sensitize_buttons (apage); -} - -/* fill_widgets handler for the alarm page */ -static void -alarm_page_fill_widgets (CompEditorPage *page, ECalComponent *comp) -{ - AlarmPage *apage; - AlarmPagePrivate *priv; - GtkWidget *menu; - ECalComponentText text; - GList *alarms, *l; - CompEditorPageDates dates; - int i; - - 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 */ - e_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 (!e_cal_component_has_alarms (comp)) - goto out; - - alarms = e_cal_component_get_alarm_uids (comp); - - for (l = alarms; l != NULL; l = l->next) { - ECalComponentAlarm *ca, *ca_copy; - const char *auid; - - auid = l->data; - ca = e_cal_component_get_alarm (comp, auid); - g_assert (ca != NULL); - - ca_copy = e_cal_component_alarm_clone (ca); - e_cal_component_alarm_free (ca); - - append_reminder (apage, ca_copy); - } - cal_obj_uid_list_free (alarms); - - out: - - /* Alarm types */ - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->action)); - for (i = 0, l = GTK_MENU_SHELL (menu)->children; action_map[i] != -1; i++, l = l->next) { - if (e_cal_get_static_capability (page->client, action_map_cap[i])) - gtk_widget_set_sensitive (l->data, FALSE); - else - gtk_widget_set_sensitive (l->data, TRUE); - } - - sensitize_buttons (apage); - - priv->updating = FALSE; -} - -/* fill_component handler for the alarm page */ -static gboolean -alarm_page_fill_component (CompEditorPage *page, ECalComponent *comp) -{ - AlarmPage *apage; - AlarmPagePrivate *priv; - GtkTreeView *view; - GtkTreeModel *model; - GtkTreeIter iter; - gboolean valid_iter; - GList *list, *l; - - apage = ALARM_PAGE (page); - priv = apage->priv; - - /* Remove all the alarms from the component */ - - list = e_cal_component_get_alarm_uids (comp); - for (l = list; l; l = l->next) { - const char *auid; - - auid = l->data; - e_cal_component_remove_alarm (comp, auid); - } - cal_obj_uid_list_free (list); - - /* Add the new alarms */ - - view = GTK_TREE_VIEW (priv->list); - model = GTK_TREE_MODEL (priv->list_store); - - for (valid_iter = gtk_tree_model_get_iter_first (model, &iter); valid_iter; - valid_iter = gtk_tree_model_iter_next (model, &iter)) { - ECalComponentAlarm *alarm, *alarm_copy; - icalcomponent *icalcomp; - icalproperty *icalprop; - - alarm = (ECalComponentAlarm *) e_alarm_list_get_alarm (priv->list_store, &iter); - g_assert (alarm != NULL); - - /* We set the description of the alarm if it's got - * the X-EVOLUTION-NEEDS-DESCRIPTION property. - */ - icalcomp = e_cal_component_alarm_get_icalcomponent (alarm); - icalprop = icalcomponent_get_first_property (icalcomp, ICAL_X_PROPERTY); - while (icalprop) { - const char *x_name; - ECalComponentText summary; - - x_name = icalproperty_get_x_name (icalprop); - if (!strcmp (x_name, "X-EVOLUTION-NEEDS-DESCRIPTION")) { - e_cal_component_get_summary (comp, &summary); - e_cal_component_alarm_set_description (alarm, &summary); - - icalcomponent_remove_property (icalcomp, icalprop); - break; - } - - icalprop = icalcomponent_get_next_property (icalcomp, ICAL_X_PROPERTY); - } - - /* We clone the alarm to maintain the invariant that the alarm - * structures in the list did *not* come from the component. - */ - - alarm_copy = e_cal_component_alarm_clone (alarm); - e_cal_component_add_alarm (comp, alarm_copy); - e_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; - - apage = ALARM_PAGE (page); - priv = apage->priv; - - gtk_label_set_text (GTK_LABEL (priv->summary), summary); - - /* iterate over all alarms */ - if (priv->old_summary) { - GtkTreeView *view; - GtkTreeModel *model; - GtkTreeIter iter; - gboolean valid_iter; - - view = GTK_TREE_VIEW (priv->list); - model = GTK_TREE_MODEL (priv->list_store); - - for (valid_iter = gtk_tree_model_get_iter_first (model, &iter); valid_iter; - valid_iter = gtk_tree_model_iter_next (model, &iter)) { - ECalComponentAlarm *alarm; - ECalComponentText desc; - - alarm = (ECalComponentAlarm *) e_alarm_list_get_alarm (priv->list_store, &iter); - g_assert (alarm != NULL); - - e_cal_component_alarm_get_description (alarm, &desc); - if (desc.value && *desc.value) { - if (!strcmp (desc.value, priv->old_summary)) { - desc.value = summary; - e_cal_component_alarm_set_description (alarm, &desc); - } - } - } - - g_free (priv->old_summary); - } - - /* update old summary */ - priv->old_summary = g_strdup (summary); -} - -/* 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 TRUE 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 (G_OBJECT (toplevel)); - if (accel_groups) { - page->accel_group = accel_groups->data; - gtk_accel_group_ref (page->accel_group); - } - - gtk_widget_ref (priv->main); - gtk_container_remove (GTK_CONTAINER (priv->main->parent), 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; - ECalComponentAlarm *alarm; - ECalComponentAlarmTrigger trigger; - ECalComponentAlarmAction action; - - apage = ALARM_PAGE (data); - priv = apage->priv; - - alarm = e_cal_component_alarm_clone (priv->alarm); - - memset (&trigger, 0, sizeof (ECalComponentAlarmTrigger)); - 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 (); - } - e_cal_component_alarm_set_trigger (alarm, trigger); - - action = e_dialog_option_menu_get (priv->action, action_map); - e_cal_component_alarm_set_action (alarm, action); - if (action == E_CAL_COMPONENT_ALARM_EMAIL && !e_cal_component_alarm_has_attendees (alarm)) { - char *email; - - if (!e_cal_get_alarm_email_address (COMP_EDITOR_PAGE (apage)->client, &email, NULL)) { - ECalComponentAttendee *a; - GSList attendee_list; - - a = g_new0 (ECalComponentAttendee, 1); - a->value = email; - attendee_list.data = a; - attendee_list.next = NULL; - e_cal_component_alarm_set_attendee_list (alarm, &attendee_list); - g_free (email); - g_free (a); - } - } - - append_reminder (apage, alarm); -} - -/* Callback used for the "delete reminder" button */ -static void -delete_clicked_cb (GtkButton *button, gpointer data) -{ - AlarmPage *apage; - AlarmPagePrivate *priv; - GtkTreeSelection *selection; - GtkTreeIter iter; - GtkTreePath *path; - gboolean valid_iter; - - apage = ALARM_PAGE (data); - priv = apage->priv; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->list)); - if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) { - g_warning ("Could not get a selection to delete."); - return; - } - - path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->list_store), &iter); - e_alarm_list_remove (priv->list_store, &iter); - - /* Select closest item after removal */ - valid_iter = gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->list_store), &iter, path); - if (!valid_iter) { - gtk_tree_path_prev (path); - valid_iter = gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->list_store), &iter, path); - } - - if (valid_iter) - gtk_tree_selection_select_iter (selection, &iter); - - sensitize_buttons (apage); - - gtk_tree_path_free (path); -} - -/* Callback used when the alarm options button is clicked */ -static void -button_options_clicked_cb (GtkWidget *widget, gpointer data) -{ - AlarmPage *apage; - AlarmPagePrivate *priv; - gboolean repeat; - char *email; - - apage = ALARM_PAGE (data); - priv = apage->priv; - - e_cal_component_alarm_set_action (priv->alarm, - e_dialog_option_menu_get (priv->action, action_map)); - - repeat = !e_cal_get_static_capability (COMP_EDITOR_PAGE (apage)->client, - CAL_STATIC_CAPABILITY_NO_ALARM_REPEAT); - - if (e_cal_get_alarm_email_address (COMP_EDITOR_PAGE (apage)->client, &email, NULL)) { - if (!alarm_options_dialog_run (priv->alarm, email, repeat)) - 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; - GtkTreeViewColumn *column; - GtkCellRenderer *cell_renderer; - - priv = apage->priv; - - /* Reminder buttons */ - g_signal_connect ((priv->add), "clicked", - G_CALLBACK (add_clicked_cb), apage); - g_signal_connect ((priv->delete), "clicked", - G_CALLBACK (delete_clicked_cb), apage); - - /* Connect the default signal handler to use to make sure we notify - * upstream of changes to the widget values. - */ - g_signal_connect ((priv->add), "clicked", - G_CALLBACK (field_changed_cb), apage); - g_signal_connect ((priv->delete), "clicked", - G_CALLBACK (field_changed_cb), apage); - - /* Options button */ - g_signal_connect ((priv->button_options), "clicked", - G_CALLBACK (button_options_clicked_cb), apage); - - /* Alarm list */ - - /* Model */ - priv->list_store = e_alarm_list_new (); - gtk_tree_view_set_model (GTK_TREE_VIEW (priv->list), - GTK_TREE_MODEL (priv->list_store)); - - /* View */ - column = gtk_tree_view_column_new (); - gtk_tree_view_column_set_title (column, _("Action/Trigger")); - cell_renderer = GTK_CELL_RENDERER (gtk_cell_renderer_text_new ()); - gtk_tree_view_column_pack_start (column, cell_renderer, TRUE); - gtk_tree_view_column_add_attribute (column, cell_renderer, "text", E_ALARM_LIST_COLUMN_DESCRIPTION); - gtk_tree_view_append_column (GTK_TREE_VIEW (priv->list), column); - -#if 0 - /* If we want the alarm setup widgets to reflect the currently selected alarm, we - * need to do something like this */ - g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->list)), "changed", - G_CALLBACK (alarm_selection_changed_cb), apage); -#endif -} - - - -/** - * 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, 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 = g_object_new (TYPE_ALARM_PAGE, NULL); - if (!alarm_page_construct (apage)) { - g_object_unref (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 7c2f06bae3..0000000000 --- a/calendar/gui/dialogs/alarm-page.glade +++ /dev/null @@ -1,490 +0,0 @@ -<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> -<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> - -<glade-interface> - -<widget class="GtkWindow" id="alarm-toplevel"> - <property name="title" translatable="yes">window1</property> - <property name="type">GTK_WINDOW_TOPLEVEL</property> - <property name="window_position">GTK_WIN_POS_NONE</property> - <property name="modal">False</property> - <property name="resizable">True</property> - <property name="destroy_with_parent">False</property> - - <child> - <widget class="GtkVBox" id="alarm-page"> - <property name="border_width">12</property> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkFrame" id="frame33"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <property name="label_yalign">0.5</property> - <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property> - - <child> - <widget class="GtkTable" id="table13"> - <property name="border_width">6</property> - <property name="visible">True</property> - <property name="n_rows">2</property> - <property name="n_columns">2</property> - <property name="homogeneous">False</property> - <property name="row_spacing">6</property> - <property name="column_spacing">6</property> - - <child> - <widget class="GtkLabel" id="label62"> - <property name="visible">True</property> - <property name="label" translatable="yes">Summary:</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label63"> - <property name="visible">True</property> - <property name="label" translatable="yes">Date/Time:</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">fill</property> - <property name="y_options">fill</property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="summary"> - <property name="visible">True</property> - <property name="label" translatable="yes"></property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">4</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="date-time"> - <property name="visible">True</property> - <property name="label" translatable="yes"></property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">7.45058e-09</property> - <property name="yalign">0.5</property> - <property name="xpad">4</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="y_options">fill</property> - </packing> - </child> - </widget> - </child> - - <child> - <widget class="GtkLabel" id="label1"> - <property name="visible">True</property> - <property name="label" translatable="yes">Basics</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkFrame" id="frame34"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <property name="label_yalign">0.5</property> - <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property> - - <child> - <widget class="GtkVBox" id="vbox53"> - <property name="border_width">6</property> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkHBox" id="hbox54"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkOptionMenu" id="action"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="history">0</property> - - <child internal-child="menu"> - <widget class="GtkMenu" id="convertwidget1"> - <property name="visible">True</property> - - <child> - <widget class="GtkMenuItem" id="convertwidget2"> - <property name="visible">True</property> - <property name="label" translatable="yes">Display a message</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget3"> - <property name="visible">True</property> - <property name="label" translatable="yes">Play a sound</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget4"> - <property name="visible">True</property> - <property name="label" translatable="yes">Run a program</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="send_an_email1"> - <property name="visible">True</property> - <property name="label" translatable="yes">Send an Email</property> - <property name="use_underline">True</property> - </widget> - </child> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkSpinButton" id="interval-value"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="climb_rate">1</property> - <property name="digits">0</property> - <property name="numeric">True</property> - <property name="update_policy">GTK_UPDATE_ALWAYS</property> - <property name="snap_to_ticks">False</property> - <property name="wrap">False</property> - <property name="adjustment">1 0 999 1 10 10</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkOptionMenu" id="value-units"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="history">0</property> - - <child internal-child="menu"> - <widget class="GtkMenu" id="convertwidget5"> - <property name="visible">True</property> - - <child> - <widget class="GtkMenuItem" id="convertwidget6"> - <property name="visible">True</property> - <property name="label" translatable="yes">minute(s)</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget7"> - <property name="visible">True</property> - <property name="label" translatable="yes">hour(s)</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget8"> - <property name="visible">True</property> - <property name="label" translatable="yes">day(s)</property> - <property name="use_underline">True</property> - </widget> - </child> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkOptionMenu" id="relative"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="history">0</property> - - <child internal-child="menu"> - <widget class="GtkMenu" id="convertwidget9"> - <property name="visible">True</property> - - <child> - <widget class="GtkMenuItem" id="convertwidget10"> - <property name="visible">True</property> - <property name="label" translatable="yes">before</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget11"> - <property name="visible">True</property> - <property name="label" translatable="yes">after</property> - <property name="use_underline">True</property> - </widget> - </child> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkOptionMenu" id="time"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="history">0</property> - - <child internal-child="menu"> - <widget class="GtkMenu" id="convertwidget12"> - <property name="visible">True</property> - - <child> - <widget class="GtkMenuItem" id="convertwidget13"> - <property name="visible">True</property> - <property name="label" translatable="yes">start of appointment</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget14"> - <property name="visible">True</property> - <property name="label" translatable="yes">end of appointment</property> - <property name="use_underline">True</property> - </widget> - </child> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkButton" id="button-options"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">_Options...</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkHBox" id="hbox55"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkScrolledWindow" id="scrolledwindow13"> - <property name="visible">True</property> - <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> - <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="shadow_type">GTK_SHADOW_IN</property> - <property name="window_placement">GTK_CORNER_TOP_LEFT</property> - - <child> - <widget class="GtkTreeView" id="list"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="headers_visible">True</property> - <property name="rules_hint">False</property> - <property name="reorderable">False</property> - <property name="enable_search">True</property> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkVButtonBox" id="vbuttonbox2"> - <property name="visible">True</property> - <property name="layout_style">GTK_BUTTONBOX_START</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkButton" id="add"> - <property name="visible">True</property> - <property name="can_default">True</property> - <property name="can_focus">True</property> - <property name="label">gtk-add</property> - <property name="use_stock">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - </widget> - </child> - - <child> - <widget class="GtkButton" id="delete"> - <property name="visible">True</property> - <property name="can_default">True</property> - <property name="can_focus">True</property> - <property name="label">gtk-remove</property> - <property name="use_stock">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - </child> - - <child> - <widget class="GtkLabel" id="label64"> - <property name="visible">True</property> - <property name="label" translatable="yes">Reminders</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - </child> -</widget> - -</glade-interface> diff --git a/calendar/gui/dialogs/alarm-page.h b/calendar/gui/dialogs/alarm-page.h deleted file mode 100644 index d814e850b3..0000000000 --- a/calendar/gui/dialogs/alarm-page.h +++ /dev/null @@ -1,62 +0,0 @@ -/* Evolution calendar - Alarm page of the calendar component dialogs - * - * Copyright (C) 2001-2003 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> - * Hans Petter Jansson <hpj@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" - -G_BEGIN_DECLS - - - -#define TYPE_ALARM_PAGE (alarm_page_get_type ()) -#define ALARM_PAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_ALARM_PAGE, AlarmPage)) -#define ALARM_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_ALARM_PAGE, AlarmPageClass)) -#define IS_ALARM_PAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_ALARM_PAGE)) -#define IS_ALARM_PAGE_CLASS(klass) (G_TYPE_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); - - - -G_END_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 83363a3ac0..0000000000 --- a/calendar/gui/dialogs/cal-prefs-dialog.c +++ /dev/null @@ -1,686 +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 <gtk/gtksignal.h> -#include <gtk/gtkoptionmenu.h> -#include <gtk/gtktogglebutton.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_end_of_day_changed (GtkWidget *button, void *data); -static void cal_prefs_dialog_start_of_day_changed (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, 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); - - g_signal_connect((config_control), "apply", - G_CALLBACK (config_control_apply_callback), dialog_data); - g_signal_connect((config_control), "destroy", - G_CALLBACK (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) -{ - g_signal_connect((widget), signal_name, - G_CALLBACK (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_optionmenu)->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. */ - g_signal_connect((dialog_data->tasks_due_today_color), "color_set", - G_CALLBACK (color_set_callback), config_control); - g_signal_connect((dialog_data->tasks_overdue_color), "color_set", - G_CALLBACK (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"); - gtk_widget_show (data->start_of_day); - data->end_of_day = GW ("end_of_day"); - gtk_widget_show (data->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; - - g_object_unref (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_use_24_hour_format (E_DATE_EDIT (dedit), calendar_config_get_24_hour_format ()); - 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) -{ - g_signal_connect((dialog_data->use_24_hour), "toggled", - G_CALLBACK (cal_prefs_dialog_use_24_hour_toggled), - dialog_data); - - g_signal_connect((dialog_data->start_of_day), "changed", - G_CALLBACK (cal_prefs_dialog_start_of_day_changed), - dialog_data); - - g_signal_connect((dialog_data->end_of_day), "changed", - G_CALLBACK (cal_prefs_dialog_end_of_day_changed), - dialog_data); - - g_signal_connect((dialog_data->tasks_hide_completed_checkbutton), - "toggled", - G_CALLBACK (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_start_of_day_changed (GtkWidget *button, void *data) -{ - DialogData *dialog_data; - EDateEdit *start, *end; - int start_hour, start_minute, end_hour, end_minute; - - dialog_data = (DialogData *) data; - - start = E_DATE_EDIT (dialog_data->start_of_day); - end = E_DATE_EDIT (dialog_data->end_of_day); - - e_date_edit_get_time_of_day (start, &start_hour, &start_minute); - e_date_edit_get_time_of_day (end, &end_hour, &end_minute); - - if ((start_hour > end_hour) - || (start_hour == end_hour && start_minute > end_minute)) { - - if (start_hour < 23) - e_date_edit_set_time_of_day (end, start_hour + 1, start_minute); - else - e_date_edit_set_time_of_day (end, 23, 59); - } -} - -static void -cal_prefs_dialog_end_of_day_changed (GtkWidget *button, void *data) -{ - DialogData *dialog_data; - EDateEdit *start, *end; - int start_hour, start_minute, end_hour, end_minute; - - dialog_data = (DialogData *) data; - - start = E_DATE_EDIT (dialog_data->start_of_day); - end = E_DATE_EDIT (dialog_data->end_of_day); - - e_date_edit_get_time_of_day (start, &start_hour, &start_minute); - e_date_edit_get_time_of_day (end, &end_hour, &end_minute); - - if ((end_hour < start_hour) - || (end_hour == start_hour && end_minute < start_minute)) { - if (end_hour < 1) - e_date_edit_set_time_of_day (start, 0, 0); - else - e_date_edit_set_time_of_day (start, end_hour - 1, end_minute); - } -} - -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)); -} diff --git a/calendar/gui/dialogs/cal-prefs-dialog.glade b/calendar/gui/dialogs/cal-prefs-dialog.glade deleted file mode 100644 index d566368611..0000000000 --- a/calendar/gui/dialogs/cal-prefs-dialog.glade +++ /dev/null @@ -1,1319 +0,0 @@ -<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> -<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> - -<glade-interface> -<requires lib="gnome"/> - -<widget class="GtkDialog" id="cal-prefs-dialog"> - <property name="title" translatable="yes">Calendar and Tasks Settings</property> - <property name="type">GTK_WINDOW_TOPLEVEL</property> - <property name="window_position">GTK_WIN_POS_NONE</property> - <property name="modal">False</property> - <property name="resizable">True</property> - <property name="destroy_with_parent">False</property> - <property name="has_separator">True</property> - - <child internal-child="vbox"> - <widget class="GtkVBox" id="vbox1"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child internal-child="action_area"> - <widget class="GtkHButtonBox" id="hbuttonbox1"> - <property name="visible">True</property> - <property name="layout_style">GTK_BUTTONBOX_END</property> - - <child> - <widget class="GtkButton" id="button1"> - <property name="visible">True</property> - <property name="can_default">True</property> - <property name="can_focus">True</property> - <property name="label">gtk-ok</property> - <property name="use_stock">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="response_id">0</property> - </widget> - </child> - - <child> - <widget class="GtkButton" id="button2"> - <property name="visible">True</property> - <property name="can_default">True</property> - <property name="can_focus">True</property> - <property name="label">gtk-apply</property> - <property name="use_stock">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="response_id">0</property> - </widget> - </child> - - <child> - <widget class="GtkButton" id="button3"> - <property name="visible">True</property> - <property name="can_default">True</property> - <property name="can_focus">True</property> - <property name="label">gtk-close</property> - <property name="use_stock">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="response_id">0</property> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="pack_type">GTK_PACK_END</property> - </packing> - </child> - - <child> - <widget class="GtkNotebook" id="toplevel-notebook"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="show_tabs">True</property> - <property name="show_border">True</property> - <property name="tab_pos">GTK_POS_TOP</property> - <property name="scrollable">False</property> - <property name="enable_popup">False</property> - - <child> - <widget class="GtkVBox" id="vbox10"> - <property name="border_width">6</property> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkFrame" id="frame12"> - <property name="border_width">3</property> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <property name="label_yalign">0.5</property> - <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property> - - <child> - <widget class="GtkTable" id="table5"> - <property name="border_width">6</property> - <property name="visible">True</property> - <property name="n_rows">2</property> - <property name="n_columns">3</property> - <property name="homogeneous">False</property> - <property name="row_spacing">6</property> - <property name="column_spacing">6</property> - - <child> - <widget class="GtkLabel" id="label22"> - <property name="visible">True</property> - <property name="label" translatable="yes">Time _zone:</property> - <property name="use_underline">True</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="mnemonic_widget">timezone</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label20"> - <property name="visible">True</property> - <property name="label" translatable="yes">Time format:</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkHBox" id="hbox10"> - <property name="visible">True</property> - <property name="homogeneous">True</property> - <property name="spacing">4</property> - - <child> - <widget class="GtkAlignment" id="alignment2"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xscale">3.35276e-08</property> - <property name="yscale">1</property> - - <child> - <widget class="GtkRadioButton" id="use_12_hour"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">_12 hour (AM/PM)</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkRadioButton" id="use_24_hour"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">_24 hour</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - <property name="group">use_12_hour</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">fill</property> - <property name="y_options">fill</property> - </packing> - </child> - - <child> - <widget class="Custom" id="timezone"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="creation_function">make_timezone_entry</property> - <property name="int1">0</property> - <property name="int2">0</property> - <property name="last_modification_time">Wed, 20 Jun 2001 02:22:46 GMT</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">3</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="x_options">fill</property> - <property name="y_options">fill</property> - </packing> - </child> - </widget> - </child> - - <child> - <widget class="GtkLabel" id="label1"> - <property name="visible">True</property> - <property name="label" translatable="yes">Time</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkFrame" id="frame9"> - <property name="border_width">3</property> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <property name="label_yalign">0.5</property> - <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property> - - <child> - <widget class="GtkTable" id="table8"> - <property name="border_width">6</property> - <property name="visible">True</property> - <property name="n_rows">3</property> - <property name="n_columns">4</property> - <property name="homogeneous">False</property> - <property name="row_spacing">6</property> - <property name="column_spacing">6</property> - - <child> - <widget class="GtkLabel" id="label33"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Day begins:</property> - <property name="use_underline">True</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkHBox" id="hbox18"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">3</property> - - <child> - <widget class="Custom" id="start_of_day"> - <property name="visible">True</property> - <property name="creation_function">cal_prefs_dialog_create_time_edit</property> - <property name="int1">0</property> - <property name="int2">0</property> - <property name="last_modification_time">Thu, 30 May 2002 19:26:53 GMT</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label34"> - <property name="visible">True</property> - <property name="label" translatable="yes">Day _ends:</property> - <property name="use_underline">True</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_RIGHT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">1</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="Custom" id="end_of_day"> - <property name="visible">True</property> - <property name="creation_function">cal_prefs_dialog_create_time_edit</property> - <property name="int1">0</property> - <property name="int2">0</property> - <property name="last_modification_time">Thu, 30 May 2002 19:27:35 GMT</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">4</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_options">fill</property> - <property name="y_options">fill</property> - </packing> - </child> - - <child> - <widget class="GtkHBox" id="hbox17"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkCheckButton" id="mon_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">_Mon</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkCheckButton" id="tue_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">_Tue</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkCheckButton" id="wed_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">_Wed</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkCheckButton" id="thu_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">T_hu</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkCheckButton" id="fri_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">_Fri</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkCheckButton" id="sat_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">_Sat</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkCheckButton" id="sun_button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">S_un</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">4</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="y_options">fill</property> - </packing> - </child> - - <child> - <widget class="GtkAlignment" id="alignment3"> - <property name="visible">True</property> - <property name="xalign">7.45058e-09</property> - <property name="yalign">0.5</property> - <property name="xscale">0</property> - <property name="yscale">1</property> - - <child> - <widget class="GtkOptionMenu" id="first_day_of_week"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="history">0</property> - - <child internal-child="menu"> - <widget class="GtkMenu" id="convertwidget1"> - <property name="visible">True</property> - - <child> - <widget class="GtkMenuItem" id="convertwidget2"> - <property name="visible">True</property> - <property name="label" translatable="yes">Monday</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget3"> - <property name="visible">True</property> - <property name="label" translatable="yes">Tuesday</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget4"> - <property name="visible">True</property> - <property name="label" translatable="yes">Wednesday</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget5"> - <property name="visible">True</property> - <property name="label" translatable="yes">Thursday</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget6"> - <property name="visible">True</property> - <property name="label" translatable="yes">Friday</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget7"> - <property name="visible">True</property> - <property name="label" translatable="yes">Saturday</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget8"> - <property name="visible">True</property> - <property name="label" translatable="yes">Sunday</property> - <property name="use_underline">True</property> - </widget> - </child> - </widget> - </child> - </widget> - </child> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label32"> - <property name="visible">True</property> - <property name="label" translatable="yes">W_eek starts:</property> - <property name="use_underline">True</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="mnemonic_widget">first_day_of_week</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label31"> - <property name="visible">True</property> - <property name="label" translatable="yes">Work days:</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - </widget> - </child> - - <child> - <widget class="GtkLabel" id="label23"> - <property name="visible">True</property> - <property name="label" translatable="yes">Work Week</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkFrame" id="frame14"> - <property name="border_width">3</property> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <property name="label_yalign">0.5</property> - <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property> - - <child> - <widget class="GtkVBox" id="vbox13"> - <property name="border_width">6</property> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkCheckButton" id="confirm-delete"> - <property name="border_width">3</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">_Ask for confirmation when deleting items</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkHBox" id="hbox19"> - <property name="border_width">3</property> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">3</property> - - <child> - <widget class="GtkCheckButton" id="default-reminder"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Sh_ow a reminder</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkSpinButton" id="default-reminder-interval"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="climb_rate">1</property> - <property name="digits">0</property> - <property name="numeric">False</property> - <property name="update_policy">GTK_UPDATE_ALWAYS</property> - <property name="snap_to_ticks">False</property> - <property name="wrap">False</property> - <property name="adjustment">0 0 9999 1 10 10</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkAlignment" id="alignment4"> - <property name="visible">True</property> - <property name="xalign">7.45058e-09</property> - <property name="yalign">0.5</property> - <property name="xscale">0</property> - <property name="yscale">0</property> - - <child> - <widget class="GtkOptionMenu" id="default-reminder-units"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="history">0</property> - - <child internal-child="menu"> - <widget class="GtkMenu" id="convertwidget9"> - <property name="visible">True</property> - - <child> - <widget class="GtkMenuItem" id="convertwidget10"> - <property name="visible">True</property> - <property name="label" translatable="yes">Minutes</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget11"> - <property name="visible">True</property> - <property name="label" translatable="yes">Hours</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget12"> - <property name="visible">True</property> - <property name="label" translatable="yes">Days</property> - <property name="use_underline">True</property> - </widget> - </child> - </widget> - </child> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label35"> - <property name="visible">True</property> - <property name="label" translatable="yes">before every appointment</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - </child> - - <child> - <widget class="GtkLabel" id="label35"> - <property name="visible">True</property> - <property name="label" translatable="yes">Alerts</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - <packing> - <property name="tab_expand">False</property> - <property name="tab_fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label21"> - <property name="visible">True</property> - <property name="label" translatable="yes">_General</property> - <property name="use_underline">True</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="type">tab</property> - </packing> - </child> - - <child> - <widget class="GtkVBox" id="vbox8"> - <property name="border_width">6</property> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkHBox" id="hbox12"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkLabel" id="label25"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Time divisions:</property> - <property name="use_underline">True</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="mnemonic_widget">time_divisions</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkOptionMenu" id="time_divisions"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="history">0</property> - - <child internal-child="menu"> - <widget class="GtkMenu" id="convertwidget13"> - <property name="visible">True</property> - - <child> - <widget class="GtkMenuItem" id="convertwidget14"> - <property name="visible">True</property> - <property name="label" translatable="yes">60 minutes</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget15"> - <property name="visible">True</property> - <property name="label" translatable="yes">30 minutes</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget16"> - <property name="visible">True</property> - <property name="label" translatable="yes">15 minutes</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget17"> - <property name="visible">True</property> - <property name="label" translatable="yes">10 minutes</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget18"> - <property name="visible">True</property> - <property name="label" translatable="yes">05 minutes</property> - <property name="use_underline">True</property> - </widget> - </child> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkCheckButton" id="show_end_times"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">_Show appointment end times in week and month views</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkCheckButton" id="compress_weekend"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">_Compress weekends in month view</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkCheckButton" id="dnav_show_week_no"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Show week _numbers in date navigator</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkFrame" id="frame13"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <property name="label_yalign">0.5</property> - <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property> - - <child> - <widget class="GtkVBox" id="vbox12"> - <property name="border_width">6</property> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkTable" id="table7"> - <property name="visible">True</property> - <property name="n_rows">2</property> - <property name="n_columns">2</property> - <property name="homogeneous">False</property> - <property name="row_spacing">6</property> - <property name="column_spacing">6</property> - - <child> - <widget class="GtkLabel" id="label28"> - <property name="visible">True</property> - <property name="label" translatable="yes">T_asks due today:</property> - <property name="use_underline">True</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="mnemonic_widget">tasks_due_today_color</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label29"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Overdue tasks:</property> - <property name="use_underline">True</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="mnemonic_widget">tasks_overdue_color</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GnomeColorPicker" id="tasks_overdue_color"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="dither">True</property> - <property name="use_alpha">False</property> - <property name="title" translatable="yes">Color for overdue tasks</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GnomeColorPicker" id="tasks_due_today_color"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="dither">True</property> - <property name="use_alpha">False</property> - <property name="title" translatable="yes">Color for tasks due today</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkHBox" id="hbox15"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkCheckButton" id="tasks-hide-completed-checkbutton"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">_Hide completed tasks after</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkSpinButton" id="tasks-hide-completed-spinbutton"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="climb_rate">1</property> - <property name="digits">0</property> - <property name="numeric">False</property> - <property name="update_policy">GTK_UPDATE_ALWAYS</property> - <property name="snap_to_ticks">False</property> - <property name="wrap">False</property> - <property name="adjustment">1 0 9999 1 10 10</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkOptionMenu" id="tasks-hide-completed-optionmenu"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="history">0</property> - - <child internal-child="menu"> - <widget class="GtkMenu" id="convertwidget19"> - <property name="visible">True</property> - - <child> - <widget class="GtkMenuItem" id="convertwidget20"> - <property name="visible">True</property> - <property name="label" translatable="yes">Minutes</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget21"> - <property name="visible">True</property> - <property name="label" translatable="yes">Hours</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget22"> - <property name="visible">True</property> - <property name="label" translatable="yes">Days</property> - <property name="use_underline">True</property> - </widget> - </child> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - </child> - - <child> - <widget class="GtkLabel" id="label36"> - <property name="visible">True</property> - <property name="label" translatable="yes">Task List</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - <packing> - <property name="tab_expand">False</property> - <property name="tab_fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label7"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Display</property> - <property name="use_underline">True</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="type">tab</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - </child> -</widget> - -</glade-interface> diff --git a/calendar/gui/dialogs/cal-prefs-dialog.h b/calendar/gui/dialogs/cal-prefs-dialog.h deleted file mode 100644 index db6f5a75fa..0000000000 --- a/calendar/gui/dialogs/cal-prefs-dialog.h +++ /dev/null @@ -1,41 +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" - -G_BEGIN_DECLS - -EvolutionConfigControl *cal_prefs_dialog_new (void); - -G_END_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 27f9b9b91e..0000000000 --- a/calendar/gui/dialogs/cancel-comp.c +++ /dev/null @@ -1,99 +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 <gtk/gtkmessagedialog.h> -#include <libgnome/gnome-i18n.h> -#include <libgnomeui/gnome-uidefs.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 (GtkWindow *parent, ECal *client, ECalComponent *comp, gboolean deleting) -{ - GtkWidget *dialog; - ECalComponentVType vtype; - char *str; - gint response; - - if (deleting && e_cal_get_save_schedules (client)) - return TRUE; - - vtype = e_cal_component_get_vtype (comp); - - switch (vtype) { - case E_CAL_COMPONENT_EVENT: - if (deleting) - str = g_strdup_printf (_("The event being deleted is a meeting, " - "would you like to send a cancellation notice?")); - else - str = g_strdup_printf (_("Are you sure you want to cancel " - "and delete this meeting?")); - break; - - case E_CAL_COMPONENT_TODO: - if (deleting) - str = g_strdup_printf (_("The task being deleted is assigned, " - "would you like to send a cancellation notice?")); - else - str = g_strdup_printf (_("Are you sure you want to cancel " - "and delete this task?")); - break; - - case E_CAL_COMPONENT_JOURNAL: - if (deleting) - str = g_strdup_printf (_("The journal entry being deleted is published, " - "would you like to send a cancellation notice?")); - else - str = g_strdup_printf (_("Are you sure you want to cancel " - "and delete this journal entry?")); - break; - - default: - g_message ("cancel_component_dialog(): " - "Cannot handle object of type %d", vtype); - return FALSE; - } - - dialog = gtk_message_dialog_new (parent, GTK_DIALOG_MODAL, - GTK_MESSAGE_QUESTION, - GTK_BUTTONS_YES_NO, str); - - response = gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - - if (response == GTK_RESPONSE_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 a43f24f2fe..0000000000 --- a/calendar/gui/dialogs/cancel-comp.h +++ /dev/null @@ -1,30 +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 <libecal/e-cal.h> -#include <libecal/e-cal-component.h> - -gboolean cancel_component_dialog (GtkWindow *parent, ECal *client, ECalComponent *comp, gboolean deleting); - -#endif diff --git a/calendar/gui/dialogs/changed-comp.c b/calendar/gui/dialogs/changed-comp.c deleted file mode 100644 index af595fe1df..0000000000 --- a/calendar/gui/dialogs/changed-comp.c +++ /dev/null @@ -1,115 +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 <gtk/gtkmessagedialog.h> -#include <libgnome/gnome-i18n.h> -#include <libgnomeui/gnome-uidefs.h> -#include "changed-comp.h" - - - -/** - * changed_component_dialog: - * @parent: Parent window for the 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 (GtkWindow *parent, ECalComponent *comp, gboolean deleted, gboolean changed) -{ - GtkWidget *dialog; - ECalComponentVType vtype; - char *str; - gint response; - - vtype = e_cal_component_get_vtype (comp); - - if (deleted) { - switch (vtype) { - case E_CAL_COMPONENT_EVENT: - str = _("This event has been deleted."); - break; - - case E_CAL_COMPONENT_TODO: - str = _("This task has been deleted."); - break; - - case E_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 E_CAL_COMPONENT_EVENT: - str = _("This event has been changed."); - break; - - case E_CAL_COMPONENT_TODO: - str = _("This task has been changed."); - break; - - case E_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 = gtk_message_dialog_new (parent, GTK_DIALOG_MODAL, - GTK_MESSAGE_QUESTION, - GTK_BUTTONS_YES_NO, str); - - response = gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - - if (response == GTK_RESPONSE_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 f029f3388e..0000000000 --- a/calendar/gui/dialogs/changed-comp.h +++ /dev/null @@ -1,30 +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 <gtk/gtkwindow.h> -#include <libecal/e-cal-component.h> - -gboolean changed_component_dialog (GtkWindow *window, ECalComponent *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 64771bebed..0000000000 --- a/calendar/gui/dialogs/comp-editor-page.c +++ /dev/null @@ -1,416 +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 <libgnome/gnome-i18n.h> -#include <libgnomeui/gnome-dialog.h> -#include <libgnomeui/gnome-dialog-util.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, - NEEDS_SEND, - SUMMARY_CHANGED, - DATES_CHANGED, - LAST_SIGNAL -}; - -static guint comp_editor_page_signals[LAST_SIGNAL]; - -#define CLASS(page) (COMP_EDITOR_PAGE_CLASS (G_OBJECT_GET_CLASS (page))) - - - -/** - * 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 = g_type_class_ref(GTK_TYPE_OBJECT); - - comp_editor_page_signals[CHANGED] = - g_signal_new ("changed", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (CompEditorPageClass, changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - comp_editor_page_signals[NEEDS_SEND] = - g_signal_new ("needs_send", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (CompEditorPageClass, needs_send), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - comp_editor_page_signals[SUMMARY_CHANGED] = - g_signal_new ("summary_changed", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (CompEditorPageClass, summary_changed), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, G_TYPE_POINTER); - - comp_editor_page_signals[DATES_CHANGED] = - g_signal_new ("dates_changed", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (CompEditorPageClass, dates_changed), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, G_TYPE_POINTER); - - 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) { - g_object_unref (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, ECalComponent *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, ECalComponent *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_e_cal: - * @page: An editor page - * @client: A #ECal object - * - * Sets the #ECal for the dialog page to use. - **/ -void -comp_editor_page_set_e_cal (CompEditorPage *page, ECal *client) -{ - g_return_if_fail (page != NULL); - g_return_if_fail (IS_COMP_EDITOR_PAGE (page)); - - if (page->client) - g_object_unref (client); - - page->client = client; - if (page->client) - g_object_ref (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_needs_send: - * @page: - * - * - **/ -void -comp_editor_page_notify_needs_send (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[NEEDS_SEND]); -} - -/** - * 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); -} - -/** - * comp_editor_page_display_validation_error: - * @page: An editor page. - * @msg: Error message to display. - * @field: Widget that caused the validation error. - * - * Displays an error message about a validation problem in the - * given field. Once the error message has been displayed, the - * focus is set to the widget that caused the validation error. - */ -void -comp_editor_page_display_validation_error (CompEditorPage *page, - const char *msg, - GtkWidget *field) -{ - GtkWidget *dialog; - char *real_msg; - - g_return_if_fail (IS_COMP_EDITOR_PAGE (page)); - g_return_if_fail (msg != NULL); - g_return_if_fail (GTK_IS_WIDGET (field)); - - real_msg = g_strdup_printf (_("Validation error: %s"), msg); - dialog = gnome_error_dialog (real_msg); - gnome_dialog_run_and_close (GNOME_DIALOG (dialog)); - - gtk_widget_grab_focus (field); - - g_free (real_msg); -} diff --git a/calendar/gui/dialogs/comp-editor-page.h b/calendar/gui/dialogs/comp-editor-page.h deleted file mode 100644 index 6046a7c039..0000000000 --- a/calendar/gui/dialogs/comp-editor-page.h +++ /dev/null @@ -1,111 +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 <gtk/gtkwidget.h> -#include <libecal/e-cal-component.h> -#include <libecal/e-cal.h> - -G_BEGIN_DECLS - - - -#define TYPE_COMP_EDITOR_PAGE (comp_editor_page_get_type ()) -#define COMP_EDITOR_PAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_COMP_EDITOR_PAGE, CompEditorPage)) -#define COMP_EDITOR_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_COMP_EDITOR_PAGE, CompEditorPageClass)) -#define IS_COMP_EDITOR_PAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_COMP_EDITOR_PAGE)) -#define IS_COMP_EDITOR_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), TYPE_COMP_EDITOR_PAGE)) - -typedef struct { - ECalComponentDateTime *start; - ECalComponentDateTime *end; - ECalComponentDateTime *due; - struct icaltimetype *complete; -} CompEditorPageDates; - -typedef struct { - GtkObject object; - - /* Some of the pages need the ECal to access timezone data. */ - ECal *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, ECalComponent *comp); - gboolean (* fill_component) (CompEditorPage *page, ECalComponent *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, - ECalComponent *comp); -gboolean comp_editor_page_fill_component (CompEditorPage *page, - ECalComponent *comp); -void comp_editor_page_set_e_cal (CompEditorPage *page, - ECal *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_needs_send (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); -void comp_editor_page_display_validation_error (CompEditorPage *page, - const char *msg, - GtkWidget *field); - - - - -G_END_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 bdb66c6c92..0000000000 --- a/calendar/gui/dialogs/comp-editor-util.c +++ /dev/null @@ -1,351 +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 <libical/ical.h> -#include <glib.h> -#include <gtk/gtklabel.h> -#include <libgnome/gnome-i18n.h> -#include <bonobo-activation/bonobo-activation.h> -#include <bonobo/bonobo-control.h> -#include <bonobo/bonobo-widget.h> -#include <e-util/e-time-utils.h> -#include <libecal/e-cal-time-util.h> -#include "../calendar-config.h" -#include "../e-date-edit-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, ECalComponent *comp) -{ - ECalComponentDateTime dt; - - dates->start = NULL; - dates->end = NULL; - dates->due = NULL; - dates->complete = NULL; - - /* Note that the ECalComponentDateTime's returned contain allocated - icaltimetype and tzid values, so we just take over ownership of - those. */ - e_cal_component_get_dtstart (comp, &dt); - if (dt.value) { - dates->start = g_new (ECalComponentDateTime, 1); - *dates->start = dt; - } - - e_cal_component_get_dtend (comp, &dt); - if (dt.value) { - dates->end = g_new (ECalComponentDateTime, 1); - *dates->end = dt; - } - - e_cal_component_get_due (comp, &dt); - if (dt.value) { - dates->due = g_new (ECalComponentDateTime, 1); - *dates->due = dt; - } - - e_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 e_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) { - e_cal_component_free_datetime (dates->start); - g_free (dates->start); - } - - if (dates->end) { - e_cal_component_free_datetime (dates->end); - g_free (dates->end); - } - - if (dates->due) { - e_cal_component_free_datetime (dates->due); - g_free (dates->due); - } - - if (dates->complete) - e_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); -} - -static void -date_edit_destroy_cb (EDateEdit *date_edit, gpointer data) -{ - EDateEditConfig *config = data; - - g_object_unref (config); -} - -/** - * 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; - EDateEditConfig *config; - - 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 - - config = e_date_edit_config_new (dedit); - g_signal_connect (G_OBJECT (dedit), "destroy", G_CALLBACK (date_edit_destroy_cb), config); - - 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; -} - - - -/** - * 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 078cd6508c..0000000000 --- a/calendar/gui/dialogs/comp-editor-util.h +++ /dev/null @@ -1,40 +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 "comp-editor-page.h" - -void comp_editor_dates (CompEditorPageDates *date, ECalComponent *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); - - -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 cd270eb423..0000000000 --- a/calendar/gui/dialogs/comp-editor.c +++ /dev/null @@ -1,1497 +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 <gtk/gtkstock.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-window-icon.h> -#include <libgnomeui/gnome-messagebox.h> -#include <bonobo/bonobo-ui-container.h> -#include <bonobo/bonobo-ui-util.h> -#include <e-util/e-dialog-utils.h> -#include <evolution-shell-component-utils.h> -#include "../print.h" -#include "../comp-util.h" -#include "save-comp.h" -#include "delete-comp.h" -#include "send-comp.h" -#include "changed-comp.h" -#include "cancel-comp.h" -#include "recur-comp.h" -#include "comp-editor.h" - - - -/* Private part of the CompEditor structure */ -struct _CompEditorPrivate { - /* Client to use */ - ECal *client; - - /* Calendar object/uid we are editing; this is an internal copy */ - ECalComponent *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; - - CalObjModType mod; - - gboolean existing_org; - gboolean user_org; - - gboolean warned; - - 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_finalize (GObject *object); - -static void real_set_e_cal (CompEditor *editor, ECal *client); -static void real_edit_comp (CompEditor *editor, ECalComponent *comp); -static gboolean real_send_comp (CompEditor *editor, ECalComponentItipMethod 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 (ECal *client, const char *uid, gpointer data); -static void obj_removed_cb (ECal *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; - - - -E_MAKE_TYPE (comp_editor, "CompEditor", CompEditor, comp_editor_class_init, comp_editor_init, - BONOBO_TYPE_WINDOW); - -/* Class initialization function for the calendar component editor */ -static void -comp_editor_class_init (CompEditorClass *klass) -{ - GObjectClass *object_class; - GtkWidgetClass *widget_class; - - object_class = G_OBJECT_CLASS (klass); - widget_class = GTK_WIDGET_CLASS (klass); - - parent_class = g_type_class_ref(BONOBO_TYPE_WINDOW); - - klass->set_e_cal = real_set_e_cal; - klass->edit_comp = real_edit_comp; - klass->send_comp = real_send_comp; - - widget_class->key_press_event = comp_editor_key_press_event; - object_class->finalize = comp_editor_finalize; -} - -/* 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 */ - container = bonobo_ui_container_new (); - editor = (CompEditor *) bonobo_window_construct (BONOBO_WINDOW (editor), container, - "event-editor", "iCalendar Editor"); - g_signal_connect((editor), "delete_event", - G_CALLBACK (delete_event_cb), editor); - - priv->uic = bonobo_ui_component_new_default (); - bonobo_ui_component_set_container (priv->uic, - bonobo_object_corba_objref (BONOBO_OBJECT (container)), - NULL); - 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, PREFIX, - EVOLUTION_UIDIR "/evolution-comp-editor.xml", - "evolution-calendar", NULL); - 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, 6); -} - -/* 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->mod = CALOBJ_MOD_ALL; - priv->existing_org = FALSE; - priv->user_org = FALSE; - priv->warned = 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_finalize (GObject *object) -{ - CompEditor *editor; - CompEditorPrivate *priv; - GList *l; - - editor = COMP_EDITOR (object); - priv = editor->priv; - - if (priv->client) { - g_signal_handlers_disconnect_matched (priv->client, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, editor); - g_object_unref (priv->client); - priv->client = NULL; - } - - /* 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) - g_object_unref (l->data); - - if (priv->comp) { - g_object_unref (priv->comp); - priv->comp = NULL; - } - - bonobo_object_unref (priv->uic); - - g_free (priv); - editor->priv = NULL; - - if (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (object); -} - -static gboolean -save_comp (CompEditor *editor) -{ - CompEditorPrivate *priv; - ECalComponent *clone; - GList *l; - gboolean result; - GError *error = NULL; - - priv = editor->priv; - - if (!priv->changed) - return TRUE; - - clone = e_cal_component_clone (priv->comp); - for (l = priv->pages; l != NULL; l = l->next) { - if (!comp_editor_page_fill_component (l->data, clone)) { - g_object_unref (clone); - comp_editor_show_page (editor, COMP_EDITOR_PAGE (l->data)); - return FALSE; - } - } - - /* If we are not the organizer, we don't update the sequence number */ - if (!e_cal_component_has_organizer (clone) || itip_organizer_is_user (clone, priv->client)) - e_cal_component_commit_sequence (clone); - else - e_cal_component_abort_sequence (clone); - - g_object_unref (priv->comp); - priv->comp = clone; - - priv->updating = TRUE; - - if (!cal_comp_is_on_server (priv->comp, priv->client)) { - result = e_cal_create_object (priv->client, e_cal_component_get_icalcomponent (priv->comp), NULL, &error); - } else { - result = e_cal_modify_object (priv->client, e_cal_component_get_icalcomponent (priv->comp), priv->mod, &error); - } - - if (!result) { - GtkWidget *dlg; - char *msg; - - msg = g_strdup (error ? error->message : _("Could not update object")); - - dlg = gnome_error_dialog (msg); - gnome_dialog_run_and_close (GNOME_DIALOG (dlg)); - - g_free (msg); - if (error) - g_error_free (error); - - 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 ((GtkWindow *) editor, priv->client, priv->comp, !priv->existing_org)) { - if (itip_organizer_is_user (priv->comp, priv->client)) - return comp_editor_send_comp (editor, E_CAL_COMPONENT_METHOD_REQUEST); - else - return comp_editor_send_comp (editor, E_CAL_COMPONENT_METHOD_REPLY); - } - - return TRUE; -} - -static void -delete_comp (CompEditor *editor) -{ - CompEditorPrivate *priv; - const char *uid; - - priv = editor->priv; - - e_cal_component_get_uid (priv->comp, &uid); - priv->updating = TRUE; - e_cal_remove_object (priv->client, uid, NULL); - 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 GTK_RESPONSE_YES: /* Save */ - if (e_cal_component_is_instance (priv->comp)) - if (!recur_component_dialog (priv->client, priv->comp, &priv->mod, GTK_WINDOW (editor))) - return FALSE; - - if (send && save_comp_with_send (editor)) - return TRUE; - else if (!send && save_comp (editor)) - return TRUE; - else - return FALSE; - case GTK_RESPONSE_NO: /* Discard */ - return TRUE; - case GTK_RESPONSE_CANCEL: /* Cancel */ - default: - return FALSE; - } -} - -/* 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); -} - -/* Closes the dialog box and emits the appropriate signals */ -static void -close_dialog (CompEditor *editor) -{ - CompEditorPrivate *priv; - - priv = editor->priv; - - gtk_widget_destroy (GTK_WIDGET (editor)); -} - - - -void -comp_editor_set_existing_org (CompEditor *editor, gboolean existing_org) -{ - CompEditorPrivate *priv; - - g_return_if_fail (editor != NULL); - g_return_if_fail (IS_COMP_EDITOR (editor)); - - priv = editor->priv; - - priv->existing_org = existing_org; -} - -gboolean -comp_editor_get_existing_org (CompEditor *editor) -{ - CompEditorPrivate *priv; - - g_return_val_if_fail (editor != NULL, FALSE); - g_return_val_if_fail (IS_COMP_EDITOR (editor), FALSE); - - priv = editor->priv; - - return priv->existing_org; -} - -void -comp_editor_set_user_org (CompEditor *editor, gboolean user_org) -{ - CompEditorPrivate *priv; - - g_return_if_fail (editor != NULL); - g_return_if_fail (IS_COMP_EDITOR (editor)); - - priv = editor->priv; - - priv->user_org = user_org; -} - -gboolean -comp_editor_get_user_org (CompEditor *editor) -{ - CompEditorPrivate *priv; - - g_return_val_if_fail (editor != NULL, FALSE); - g_return_val_if_fail (IS_COMP_EDITOR (editor), FALSE); - - priv = editor->priv; - - return priv->user_org; -} - - -/** - * 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; - - g_object_ref (page); - - /* If we are editing something, fill the widgets with current info */ - if (priv->comp != NULL) { - ECalComponent *comp; - - comp = comp_editor_get_current_comp (editor); - comp_editor_page_fill_widgets (page, comp); - g_object_unref (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 */ - g_signal_connect(page, "changed", - G_CALLBACK (page_changed_cb), editor); - g_signal_connect(page, "summary_changed", - G_CALLBACK (page_summary_changed_cb), editor); - g_signal_connect(page, "dates_changed", - G_CALLBACK (page_dates_changed_cb), editor); - - /* Listen for when the page is mapped/unmapped so we can - install/uninstall the appropriate GtkAccelGroup. */ - g_signal_connect((page_widget), "map", - G_CALLBACK (page_mapped_cb), page); - g_signal_connect((page_widget), "unmap", - G_CALLBACK (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(). */ - g_signal_handlers_disconnect_matched (page, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, editor); - g_signal_handlers_disconnect_matched (page_widget, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, page); - - gtk_notebook_remove_page (priv->notebook, page_num); - - priv->pages = g_list_remove (priv->pages, page); - g_object_unref (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_e_cal: - * @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_e_cal (CompEditor *editor, ECal *client) -{ - CompEditorClass *klass; - - g_return_if_fail (editor != NULL); - g_return_if_fail (IS_COMP_EDITOR (editor)); - - klass = COMP_EDITOR_CLASS (G_OBJECT_GET_CLASS (editor)); - - if (klass->set_e_cal) - klass->set_e_cal (editor, client); -} - -/** - * comp_editor_get_e_cal: - * @editor: A component editor - * - * Returns the calendar client of the editor - * - * Return value: The calendar client of the editor - **/ -ECal * -comp_editor_get_e_cal (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 (ECalComponent *comp) -{ - char *title; - const char *type_string; - ECalComponentVType type; - ECalComponentText text; - - if (!comp) - return g_strdup (_("Edit Appointment")); - - type = e_cal_component_get_vtype (comp); - switch (type) { - case E_CAL_COMPONENT_EVENT: - type_string = _("Appointment - %s"); - break; - case E_CAL_COMPONENT_TODO: - type_string = _("Task - %s"); - break; - case E_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; - } - - e_cal_component_get_summary (comp, &text); - if (text.value) { - title = g_strdup_printf (type_string, text.value); - } else { - title = g_strdup_printf (type_string, _("No summary")); - } - - return title; -} - -/* Creates an appropriate title for the event editor dialog */ -static char * -make_title_from_string (ECalComponent *comp, const char *str) -{ - char *title; - const char *type_string; - ECalComponentVType type; - - if (!comp) - return g_strdup (_("Edit Appointment")); - - type = e_cal_component_get_vtype (comp); - switch (type) { - case E_CAL_COMPONENT_EVENT: - type_string = _("Appointment - %s"); - break; - case E_CAL_COMPONENT_TODO: - type_string = _("Task - %s"); - break; - case E_CAL_COMPONENT_JOURNAL: - type_string = _("Journal entry - %s"); - break; - default: - g_message ("make_title_from_string(): Cannot handle object of type %d", type); - return NULL; - } - - if (str) { - title = g_strdup_printf (type_string, str); - } else { - title = g_strdup_printf (type_string, _("No summary")); - } - - return title; -} - -static const char * -make_icon_from_comp (ECalComponent *comp) -{ - ECalComponentVType type; - - if (!comp) - return EVOLUTION_IMAGESDIR "/evolution-calendar-mini.png"; - - type = e_cal_component_get_vtype (comp); - switch (type) { - case E_CAL_COMPONENT_EVENT: - return EVOLUTION_IMAGESDIR "/buttons/new_appointment.png"; - break; - case E_CAL_COMPONENT_TODO: - return EVOLUTION_IMAGESDIR "/buttons/new_task.png"; - break; - default: - return EVOLUTION_IMAGESDIR "/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_title_from_string (CompEditor *editor, const char *str) -{ - CompEditorPrivate *priv; - char *title; - - priv = editor->priv; - title = make_title_from_string (priv->comp, str); - 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_e_cal (CompEditor *editor, ECal *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 (E_IS_CAL (client)); - g_return_if_fail (e_cal_get_load_state (client) == - E_CAL_LOAD_LOADED); - g_object_ref (client); - } - - if (priv->client) { - gtk_signal_disconnect_by_data (GTK_OBJECT (priv->client), - editor); - g_object_unref (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_e_cal (elem->data, client); - - g_signal_connect((priv->client), "obj_updated", - G_CALLBACK (obj_updated_cb), editor); - - g_signal_connect((priv->client), "obj_removed", - G_CALLBACK (obj_removed_cb), editor); -} - -static void -real_edit_comp (CompEditor *editor, ECalComponent *comp) -{ - CompEditorPrivate *priv; - - g_return_if_fail (editor != NULL); - g_return_if_fail (IS_COMP_EDITOR (editor)); - - priv = editor->priv; - - if (priv->comp) { - g_object_unref (priv->comp); - priv->comp = NULL; - } - - if (comp) - priv->comp = e_cal_component_clone (comp); - - priv->existing_org = e_cal_component_has_organizer (comp); - priv->user_org = itip_organizer_is_user (comp, priv->client); - priv->warned = FALSE; - - set_title_from_comp (editor); - set_icon_from_comp (editor); - fill_widgets (editor); -} - - -static gboolean -real_send_comp (CompEditor *editor, ECalComponentItipMethod method) -{ - CompEditorPrivate *priv; - ECalComponent *tmp_comp; - - g_return_val_if_fail (editor != NULL, FALSE); - g_return_val_if_fail (IS_COMP_EDITOR (editor), FALSE); - - priv = editor->priv; - - if (itip_send_comp (method, priv->comp, priv->client, NULL)) { - tmp_comp = priv->comp; - g_object_ref (tmp_comp); - comp_editor_edit_comp (editor, tmp_comp); - g_object_unref (tmp_comp); - - comp_editor_set_changed (editor, TRUE); - save_comp (editor); - - return TRUE; - } - - comp_editor_set_changed (editor, TRUE); - - return FALSE; -} - - -/** - * 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, ECalComponent *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 (E_IS_CAL_COMPONENT (comp)); - - klass = COMP_EDITOR_CLASS (G_OBJECT_GET_CLASS (editor)); - - if (klass->edit_comp) - klass->edit_comp (editor, comp); -} - -ECalComponent * -comp_editor_get_comp (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->comp; -} - -ECalComponent * -comp_editor_get_current_comp (CompEditor *editor) -{ - CompEditorPrivate *priv; - ECalComponent *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 = e_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: - * - * - **/ -gboolean -comp_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method) -{ - CompEditorClass *klass; - - g_return_val_if_fail (editor != NULL, FALSE); - g_return_val_if_fail (IS_COMP_EDITOR (editor), FALSE); - - klass = COMP_EDITOR_CLASS (G_OBJECT_GET_CLASS (editor)); - - if (klass->send_comp) - return klass->send_comp (editor, method); - - return FALSE; -} - -gboolean -comp_editor_close (CompEditor *editor) -{ - gboolean close; - - g_return_val_if_fail (editor != NULL, FALSE); - g_return_val_if_fail (IS_COMP_EDITOR (editor), FALSE); - - commit_all_fields (editor); - - close = prompt_to_save_changes (editor, TRUE); - if (close) - close_dialog (editor); - - return close; -} - -/** - * comp_editor_merge_ui: - * @editor: - * @filename: - * @verbs: - * - * - **/ -void -comp_editor_merge_ui (CompEditor *editor, - const char *filename, - BonoboUIVerb *verbs, - EPixmap *component_pixmaps) -{ - CompEditorPrivate *priv; - char *path; - - g_return_if_fail (editor != NULL); - g_return_if_fail (IS_COMP_EDITOR (editor)); - - priv = editor->priv; - - path = g_strconcat (EVOLUTION_UIDIR "/", filename, NULL); - - bonobo_ui_util_set_ui (priv->uic, EVOLUTION_DATADIR, path, "evolution-calendar", NULL); - bonobo_ui_component_add_verb_list_with_data (priv->uic, verbs, editor); - - g_free (path); - - if (component_pixmaps != NULL) - e_pixmaps_update (priv->uic, component_pixmaps); -} - -/** - * 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)); -} - -/* Menu Commands */ -static void -save_cmd (GtkWidget *widget, gpointer data) -{ - CompEditor *editor = COMP_EDITOR (data); - CompEditorPrivate *priv; - - priv = editor->priv; - - commit_all_fields (editor); - - if (e_cal_component_is_instance (priv->comp)) - if (!recur_component_dialog (priv->client, priv->comp, &priv->mod, GTK_WINDOW (editor))) - return; - - save_comp_with_send (editor); -} - -static void -save_close_cmd (GtkWidget *widget, gpointer data) -{ - CompEditor *editor = COMP_EDITOR (data); - CompEditorPrivate *priv; - - priv = editor->priv; - - commit_all_fields (editor); - - if (e_cal_component_is_instance (priv->comp)) - if (!recur_component_dialog (priv->client, priv->comp, &priv->mod, GTK_WINDOW (editor))) - return; - - 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 = e_cal_get_component_as_string (priv->client, - e_cal_component_get_icalcomponent (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; - ECalComponentVType vtype; - - priv = editor->priv; - - vtype = e_cal_component_get_vtype (priv->comp); - - if (delete_component_dialog (priv->comp, FALSE, 1, vtype, GTK_WIDGET (editor))) { - if (itip_organizer_is_user (priv->comp, priv->client) - && cancel_component_dialog ((GtkWindow *) editor, - priv->client, priv->comp, TRUE)) - itip_send_comp (E_CAL_COMPONENT_METHOD_CANCEL, priv->comp, priv->client, NULL); - - delete_comp (editor); - } -} - -static void -print_cmd (GtkWidget *widget, gpointer data) -{ - CompEditor *editor = COMP_EDITOR (data); - ECalComponent *comp; - - commit_all_fields (editor); - - comp = comp_editor_get_current_comp (editor); - print_comp (comp, editor->priv->client, FALSE); - g_object_unref (comp); -} - -static void -print_preview_cmd (GtkWidget *widget, gpointer data) -{ - CompEditor *editor = COMP_EDITOR (data); - ECalComponent *comp; - - commit_all_fields (editor); - - comp = comp_editor_get_current_comp (editor); - print_comp (comp, editor->priv->client, TRUE); - g_object_unref (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; - - if (!priv->warned && priv->existing_org && !priv->user_org) { - e_notice (editor, GTK_MESSAGE_INFO, - _("Changes made to this item may be discarded if an update arrives")); - priv->warned = 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; - - if (!priv->warned && priv->existing_org && !priv->user_org) { - e_notice (editor, GTK_MESSAGE_INFO, - _("Changes made to this item may be discarded if an update arrives")); - priv->warned = TRUE; - } - - set_title_from_string (editor, summary); -} - -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; - - if (!priv->warned && priv->existing_org && !priv->user_org) { - e_notice (editor, GTK_MESSAGE_INFO, - _("Changes made to this item may be discarded if an update arrives")); - priv->warned = TRUE; - } -} - -static void -obj_updated_cb (ECal *client, const char *uid, gpointer data) -{ - CompEditor *editor = COMP_EDITOR (data); - CompEditorPrivate *priv; - ECalComponent *comp = NULL; - const char *edit_uid; - - priv = editor->priv; - - e_cal_component_get_uid (priv->comp, &edit_uid); - - if (!strcmp (uid, edit_uid) && !priv->updating) { - if (changed_component_dialog ((GtkWindow *) editor, priv->comp, FALSE, priv->changed)) { - icalcomponent *icalcomp; - - if (!e_cal_get_object (priv->client, uid, NULL, &icalcomp, NULL)) { - comp = e_cal_component_new (); - if (e_cal_component_set_icalcomponent (comp, icalcomp)) - comp_editor_edit_comp (editor, comp); - else { - GtkWidget *dlg; - - dlg = gnome_error_dialog (_("Unable to obtain current version!")); - gnome_dialog_run_and_close (GNOME_DIALOG (dlg)); - icalcomponent_free (icalcomp); - } - - g_object_unref (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 (ECal *client, const char *uid, gpointer data) -{ - CompEditor *editor = COMP_EDITOR (data); - CompEditorPrivate *priv; - const char *edit_uid; - - priv = editor->priv; - - e_cal_component_get_uid (priv->comp, &edit_uid); - - if (!strcmp (uid, edit_uid) && !priv->updating) { - if (changed_component_dialog ((GtkWindow *) editor, 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 48b332ce4b..0000000000 --- a/calendar/gui/dialogs/comp-editor.h +++ /dev/null @@ -1,109 +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-window.h> -#include <bonobo/bonobo-ui-engine.h> -#include <bonobo/bonobo-ui-component.h> -#include <libecal/e-cal.h> -#include "../itip-utils.h" -#include "comp-editor-page.h" -#include "evolution-shell-component-utils.h" - -G_BEGIN_DECLS - - - -#define TYPE_COMP_EDITOR (comp_editor_get_type ()) -#define COMP_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_COMP_EDITOR, CompEditor)) -#define COMP_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_COMP_EDITOR, CompEditorClass)) -#define IS_COMP_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_COMP_EDITOR)) -#define IS_COMP_EDITOR_CLASS(klass) (G_TYPE_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_e_cal) (CompEditor *page, ECal *client); - void (* edit_comp) (CompEditor *page, ECalComponent *comp); - gboolean (* send_comp) (CompEditor *page, ECalComponentItipMethod 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_set_existing_org (CompEditor *editor, - gboolean existing_org); -gboolean comp_editor_get_existing_org (CompEditor *editor); -void comp_editor_set_user_org (CompEditor *editor, - gboolean user_org); -gboolean comp_editor_get_user_org (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_e_cal (CompEditor *editor, - ECal *client); -ECal *comp_editor_get_e_cal (CompEditor *editor); -void comp_editor_edit_comp (CompEditor *ee, - ECalComponent *comp); -ECalComponent *comp_editor_get_comp (CompEditor *editor); -ECalComponent *comp_editor_get_current_comp (CompEditor *editor); -gboolean comp_editor_save_comp (CompEditor *editor, - gboolean send); -void comp_editor_delete_comp (CompEditor *editor); -gboolean comp_editor_send_comp (CompEditor *editor, - ECalComponentItipMethod method); -gboolean comp_editor_close (CompEditor *editor); -void comp_editor_merge_ui (CompEditor *editor, - const char *filename, - BonoboUIVerb *verbs, - EPixmap *pixmaps); -void comp_editor_set_ui_prop (CompEditor *editor, - const char *path, - const char *attr, - const char *val); -void comp_editor_focus (CompEditor *editor); - - - - -G_END_DECLS - -#endif diff --git a/calendar/gui/dialogs/copy-source-dialog.c b/calendar/gui/dialogs/copy-source-dialog.c deleted file mode 100644 index 11b523a1f8..0000000000 --- a/calendar/gui/dialogs/copy-source-dialog.c +++ /dev/null @@ -1,163 +0,0 @@ -/* Evolution calendar - Copy source dialog - * - * Copyright (C) 2003 Novell, 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. - */ - -#include <gtk/gtkbox.h> -#include <gtk/gtkdialog.h> -#include <gtk/gtklabel.h> -#include <gtk/gtkstock.h> -#include <bonobo/bonobo-i18n.h> -#include <widgets/misc/e-source-option-menu.h> -#include "copy-source-dialog.h" - -typedef struct { - GtkWidget *dialog; - GtkWidget *selector; - ESourceList *source_list; - GConfClient *conf_client; - ESource *orig_source; - CalObjType obj_type; - ESource *selected_source; -} CopySourceDialogData; - -static void -source_selected_cb (ESourceOptionMenu *menu, ESource *selected_source, gpointer user_data) -{ - CopySourceDialogData *csdd = user_data; - - csdd->selected_source = selected_source; - if (selected_source) { - if (selected_source != csdd->orig_source) - gtk_dialog_set_response_sensitive (GTK_DIALOG (csdd->dialog), GTK_RESPONSE_OK, TRUE); - else { - gtk_dialog_set_response_sensitive (GTK_DIALOG (csdd->dialog), GTK_RESPONSE_OK, FALSE); - csdd->selected_source = NULL; - } - } else - gtk_dialog_set_response_sensitive (GTK_DIALOG (csdd->dialog), GTK_RESPONSE_OK, FALSE); -} - -static gboolean -copy_source (CopySourceDialogData *csdd) -{ - char *uri; - ECal *source_client, *dest_client; - GList *obj_list = NULL; - gboolean result = FALSE; - - if (!csdd->selected_source) - return FALSE; - - /* open the source */ - source_client = e_cal_new (csdd->orig_source, csdd->obj_type); - if (!e_cal_open (source_client, TRUE, NULL)) { - g_object_unref (source_client); - g_warning (G_STRLOC ": Could not open source"); - return FALSE; - } - - /* open the destination */ - dest_client = e_cal_new (csdd->selected_source, csdd->obj_type); - if (!e_cal_open (dest_client, FALSE, NULL)) { - g_object_unref (dest_client); - g_object_unref (source_client); - g_warning (G_STRLOC ": Could not open destination"); - return FALSE; - } - - if (e_cal_get_object_list (source_client, "#t", &obj_list, NULL)) { - GList *l; - const char *uid; - icalcomponent *icalcomp; - - for (l = obj_list; l != NULL; l = l->next) { - /* FIXME: process recurrences */ - /* FIXME: process errors */ - if (e_cal_get_object (dest_client, icalcomponent_get_uid (l->data), NULL, - &icalcomp, NULL)) { - e_cal_modify_object (dest_client, icalcomp, CALOBJ_MOD_ALL, NULL); - } else { - e_cal_create_object (dest_client, l->data, (char **) &uid, NULL); - g_free ((gpointer) uid); - } - } - - e_cal_free_object_list (obj_list); - } - - return result; -} - -/** - * copy_source_dialog - * - * Implements the Copy command for sources, allowing the user to select a target - * source to copy to. - */ -gboolean -copy_source_dialog (GtkWindow *parent, ESource *source, CalObjType obj_type) -{ - CopySourceDialogData csdd; - gboolean result = FALSE; - const char *gconf_key; - GtkWidget *label; - - g_return_val_if_fail (E_IS_SOURCE (source), FALSE); - - if (obj_type == CALOBJ_TYPE_EVENT) - gconf_key = "/apps/evolution/calendar/sources"; - else if (obj_type == CALOBJ_TYPE_TODO) - gconf_key = "/apps/evolution/tasks/sources"; - else - return FALSE; - - csdd.orig_source = source; - csdd.selected_source = NULL; - csdd.obj_type = obj_type; - - /* create the dialog */ - csdd.dialog = gtk_dialog_new_with_buttons (_("Copy"), parent, 0, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OK, GTK_RESPONSE_OK, - NULL); - gtk_dialog_set_response_sensitive (GTK_DIALOG (csdd.dialog), GTK_RESPONSE_OK, FALSE); - - label = gtk_label_new (_("Select destination source")); - gtk_widget_show (label); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (csdd.dialog)->vbox), label, FALSE, FALSE, 6); - - csdd.conf_client = gconf_client_get_default (); - csdd.source_list = e_source_list_new_for_gconf (csdd.conf_client, gconf_key); - csdd.selector = e_source_option_menu_new (csdd.source_list); - g_signal_connect (G_OBJECT (csdd.selector), "source_selected", - G_CALLBACK (source_selected_cb), &csdd); - gtk_widget_show (csdd.selector); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (csdd.dialog)->vbox), csdd.selector, FALSE, FALSE, 6); - - if (gtk_dialog_run (GTK_DIALOG (csdd.dialog)) == GTK_RESPONSE_OK) { - result = copy_source (&csdd); - } - - /* free memory */ - g_object_unref (csdd.conf_client); - g_object_unref (csdd.source_list); - gtk_widget_destroy (csdd.dialog); - - return result; -} diff --git a/calendar/gui/dialogs/copy-source-dialog.h b/calendar/gui/dialogs/copy-source-dialog.h deleted file mode 100644 index e3c750d8a0..0000000000 --- a/calendar/gui/dialogs/copy-source-dialog.h +++ /dev/null @@ -1,31 +0,0 @@ -/* Evolution calendar - Copy source dialog - * - * Copyright (C) 2003 Novell, 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 COPY_SOURCE_DIALOG_H -#define COPY_SOURCE_DIALOG_H - -#include <gtk/gtkwindow.h> -#include <libedataserver/e-source.h> -#include <libecal/e-cal.h> -#include <libecal/e-cal-util.h> - -gboolean copy_source_dialog (GtkWindow *parent, ESource *source, CalObjType obj_type); - -#endif diff --git a/calendar/gui/dialogs/delete-comp.c b/calendar/gui/dialogs/delete-comp.c deleted file mode 100644 index c4f9e5dc3d..0000000000 --- a/calendar/gui/dialogs/delete-comp.c +++ /dev/null @@ -1,159 +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 <gtk/gtkstock.h> -#include <gtk/gtkmessagedialog.h> -#include <libgnome/gnome-i18n.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 (ECalComponent *comp, - gboolean consider_as_untitled, - int n_comps, ECalComponentVType vtype, - GtkWidget *widget) -{ - char *str; - GtkWidget *dialog; - int ret; - - if (comp) { - g_return_val_if_fail (E_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 != E_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) { - ECalComponentText summary; - char *tmp; - - vtype = e_cal_component_get_vtype (comp); - - if (!consider_as_untitled) { - e_cal_component_get_summary (comp, &summary); - tmp = g_strdup (summary.value); - } else - tmp = NULL; - - switch (vtype) { - case E_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 E_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 E_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 E_CAL_COMPONENT_EVENT: - str = g_strdup_printf (_("Are you sure you want to delete " - "%d appointments?"), n_comps); - break; - - case E_CAL_COMPONENT_TODO: - str = g_strdup_printf (_("Are you sure you want to delete " - "%d tasks?"), n_comps); - break; - - case E_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 = gtk_message_dialog_new ((GtkWindow *)gtk_widget_get_toplevel (widget), - 0, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, "%s", str); - g_free (str); - ret = gtk_dialog_run ((GtkDialog *)dialog) == GTK_RESPONSE_YES; - gtk_widget_destroy (dialog); - - return ret; -} diff --git a/calendar/gui/dialogs/delete-comp.h b/calendar/gui/dialogs/delete-comp.h deleted file mode 100644 index f8773c25d0..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 <libecal/e-cal-component.h> - -gboolean delete_component_dialog (ECalComponent *comp, - gboolean consider_as_untitled, - int n_comps, ECalComponentVType vtype, - GtkWidget *widget); - -#endif diff --git a/calendar/gui/dialogs/delete-error.c b/calendar/gui/dialogs/delete-error.c deleted file mode 100644 index cb076885c1..0000000000 --- a/calendar/gui/dialogs/delete-error.c +++ /dev/null @@ -1,109 +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 <gtk/gtkmessagedialog.h> -#include <libgnome/gnome-i18n.h> -#include <libgnomeui/gnome-uidefs.h> -#include "delete-error.h" - - - -/** - * delete_error_dialog: - * - * Shows any applicable error messages as the result of deleting and object - * - **/ -void -delete_error_dialog (GError *error, ECalComponentVType vtype) -{ - GtkWidget *dialog; - const char *str; - - if (!error) - return; - - switch (error->code) { - case E_CALENDAR_STATUS_CORBA_EXCEPTION: - switch (vtype) { - case E_CAL_COMPONENT_EVENT: - str = _("The event could not be deleted due to a corba error"); - break; - case E_CAL_COMPONENT_TODO: - str = _("The task could not be deleted due to a corba error"); - break; - case E_CAL_COMPONENT_JOURNAL: - str = _("The journal entry could not be deleted due to a corba error"); - break; - default: - str = _("The item could not be deleted due to a corba error"); - break; - } - break; - case E_CALENDAR_STATUS_PERMISSION_DENIED: - switch (vtype) { - case E_CAL_COMPONENT_EVENT: - str = _("The event could not be deleted because permission was denied"); - break; - case E_CAL_COMPONENT_TODO: - str = _("The task could not be deleted because permission was denied"); - break; - case E_CAL_COMPONENT_JOURNAL: - str = _("The journal entry could not be deleted because permission was denied"); - break; - default: - str = _("The item could not be deleted because permission was denied"); - break; - } - break; - case E_CALENDAR_STATUS_OTHER_ERROR: - switch (vtype) { - case E_CAL_COMPONENT_EVENT: - str = _("The event could not be deleted due to an error"); - break; - case E_CAL_COMPONENT_TODO: - str = _("The task could not be deleted due to an error"); - break; - case E_CAL_COMPONENT_JOURNAL: - str = _("The journal entry could not be deleted due to an error"); - break; - default: - str = _("The item could not be deleted due to an error"); - break; - } - break; - case E_CALENDAR_STATUS_OK: - case E_CALENDAR_STATUS_OBJECT_NOT_FOUND: - default: - /* If not found, we don't care - its gone anyhow */ - return; - } - - dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, str); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); -} diff --git a/calendar/gui/dialogs/delete-error.h b/calendar/gui/dialogs/delete-error.h deleted file mode 100644 index 68c132e479..0000000000 --- a/calendar/gui/dialogs/delete-error.h +++ /dev/null @@ -1,30 +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 DELETE_ERROR_H -#define DELETE_ERROR_H - -#include <glib.h> -#include <libecal/e-cal.h> -#include <libecal/e-cal-component.h> - -void delete_error_dialog (GError *error, ECalComponentVType vtype); - -#endif diff --git a/calendar/gui/dialogs/e-delegate-dialog.c b/calendar/gui/dialogs/e-delegate-dialog.c deleted file mode 100644 index 1a33ca194d..0000000000 --- a/calendar/gui/dialogs/e-delegate-dialog.c +++ /dev/null @@ -1,322 +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 <bonobo-activation/bonobo-activation.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 <libical/ical.h> -#include <glade/glade.h> -#include <gal/util/e-util.h> -#include <widgets/misc/e-map.h> -#include <addressbook/util/eab-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:" BASE_VERSION -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_finalize (GObject *object); - -static gboolean get_widgets (EDelegateDialog *edd); -static void addressbook_clicked_cb (GtkWidget *widget, gpointer data); - -static GtkObjectClass *parent_class; - -E_MAKE_TYPE (e_delegate_dialog, "EDelegateDialog", EDelegateDialog, e_delegate_dialog_class_init, - e_delegate_dialog_init, G_TYPE_OBJECT); - -/* Class initialization function for the event editor */ -static void -e_delegate_dialog_class_init (EDelegateDialogClass *class) -{ - GObjectClass *gobject_class; - - gobject_class = (GObjectClass *) class; - - parent_class = g_type_class_ref (G_TYPE_OBJECT); - - gobject_class->finalize = e_delegate_dialog_finalize; -} - -/* 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_finalize (GObject *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 (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (object); -} - - -EDelegateDialog * -e_delegate_dialog_construct (EDelegateDialog *edd, const char *name, const char *address) -{ - EDelegateDialogPrivate *priv; - EABDestination *dest; - EABDestination *destv[2] = {NULL, NULL}; - Bonobo_Control corba_control; - CORBA_Environment ev; - char *str; - - 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, 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 = bonobo_activation_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, 6); - - dest = eab_destination_new (); - destv[0] = dest; - if (name != NULL && *name) - eab_destination_set_name (dest, name); - if (address != NULL && *address) - eab_destination_set_email (dest, address); - str = eab_destination_exportv(destv); - bonobo_widget_set_property (BONOBO_WIDGET (priv->entry), "destinations", TC_CORBA_string, str, NULL); - g_free(str); - g_object_unref (dest); - - g_signal_connect((priv->addressbook), "clicked", - G_CALLBACK (addressbook_clicked_cb), edd); - - return edd; - - error: - - g_object_unref (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 (g_object_new (E_TYPE_DELEGATE_DIALOG, NULL)); - return e_delegate_dialog_construct (E_DELEGATE_DIALOG (edd), name, address); -} - -char * -e_delegate_dialog_get_delegate (EDelegateDialog *edd) -{ - EDelegateDialogPrivate *priv; - EABDestination **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", TC_CORBA_string, &string, NULL); - destv = eab_destination_importv (string); - - if (destv && destv[0] != NULL) { - g_free (priv->address); - priv->address = g_strdup (eab_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; - EABDestination **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", TC_CORBA_string, &string, NULL); - destv = eab_destination_importv (string); - - g_message ("importv: [%s]", string); - - if (destv && destv[0] != NULL) { - g_free (priv->name); - priv->name = g_strdup (eab_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 f08c03ad1d..0000000000 --- a/calendar/gui/dialogs/e-delegate-dialog.glade +++ /dev/null @@ -1,113 +0,0 @@ -<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> -<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> - -<glade-interface> -<requires lib="gnome"/> - -<widget class="GtkDialog" id="delegate-dialog"> - <property name="title" translatable="yes">Enter Delegate</property> - <property name="type">GTK_WINDOW_TOPLEVEL</property> - <property name="window_position">GTK_WIN_POS_NONE</property> - <property name="modal">False</property> - <property name="resizable">True</property> - <property name="destroy_with_parent">False</property> - <property name="has_separator">True</property> - - <child internal-child="vbox"> - <widget class="GtkVBox" id="dialog-vbox1"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">8</property> - - <child internal-child="action_area"> - <widget class="GtkHButtonBox" id="dialog-action_area1"> - <property name="visible">True</property> - <property name="layout_style">GTK_BUTTONBOX_END</property> - - <child> - <widget class="GtkButton" id="cancel-button"> - <property name="visible">True</property> - <property name="can_default">True</property> - <property name="can_focus">True</property> - <property name="label">gtk-cancel</property> - <property name="use_stock">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="response_id">-6</property> - </widget> - </child> - - <child> - <widget class="GtkButton" id="ok-button"> - <property name="visible">True</property> - <property name="can_default">True</property> - <property name="has_default">True</property> - <property name="can_focus">True</property> - <property name="label">gtk-ok</property> - <property name="use_stock">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="response_id">-5</property> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="pack_type">GTK_PACK_END</property> - </packing> - </child> - - <child> - <widget class="GtkHBox" id="delegate-hbox"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkLabel" id="label3"> - <property name="visible">True</property> - <property name="label" translatable="yes">Delegate To:</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkButton" id="addressbook"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Addressbook...</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="pack_type">GTK_PACK_END</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - </child> -</widget> - -</glade-interface> diff --git a/calendar/gui/dialogs/e-delegate-dialog.h b/calendar/gui/dialogs/e-delegate-dialog.h deleted file mode 100644 index 2acc853e0a..0000000000 --- a/calendar/gui/dialogs/e-delegate-dialog.h +++ /dev/null @@ -1,72 +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 <gtk/gtkwidget.h> - - - -#define E_TYPE_DELEGATE_DIALOG (e_delegate_dialog_get_type ()) -#define E_DELEGATE_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_DELEGATE_DIALOG, EDelegateDialog)) -#define E_DELEGATE_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_DELEGATE_DIALOG, \ - EDelegateDialogClass)) -#define E_IS_DELEGATE_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_DELEGATE_DIALOG)) -#define E_IS_DELEGATE_DIALOG_CLASS(klass) (G_TYPE_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 ac117a0039..0000000000 --- a/calendar/gui/dialogs/event-editor.c +++ /dev/null @@ -1,522 +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/util/e-util.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; - - EMeetingStore *model; - - gboolean meeting_shown; - gboolean updating; -}; - - - -static void event_editor_class_init (EventEditorClass *class); -static void event_editor_init (EventEditor *ee); -static void event_editor_set_e_cal (CompEditor *editor, ECal *client); -static void event_editor_edit_comp (CompEditor *editor, ECalComponent *comp); -static gboolean event_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method); -static void event_editor_finalize (GObject *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_change_insert_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data); -static void model_row_delete_cb (GtkTreeModel *model, GtkTreePath *path, gpointer data); - -static EPixmap pixmaps [] = { - E_PIXMAP ("/Toolbar/Actions/ActionScheduleMeeting", "schedule-meeting-24.png"), - E_PIXMAP_END -}; - -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. - **/ - -E_MAKE_TYPE (event_editor, "EventEditor", EventEditor, event_editor_class_init, - event_editor_init, TYPE_COMP_EDITOR); - -/* Class initialization function for the event editor */ -static void -event_editor_class_init (EventEditorClass *klass) -{ - GObjectClass *gobject_class; - CompEditorClass *editor_class; - - gobject_class = (GObjectClass *) klass; - editor_class = (CompEditorClass *) klass; - - parent_class = g_type_class_ref(TYPE_COMP_EDITOR); - - editor_class->set_e_cal = event_editor_set_e_cal; - editor_class->edit_comp = event_editor_edit_comp; - editor_class->send_comp = event_editor_send_comp; - - gobject_class->finalize = event_editor_finalize; -} - -static void -set_menu_sens (EventEditor *ee) -{ - EventEditorPrivate *priv; - gboolean sens, existing, user, read_only = TRUE; - - priv = ee->priv; - - existing = comp_editor_get_existing_org (COMP_EDITOR (ee)); - user = comp_editor_get_user_org (COMP_EDITOR (ee)); - - e_cal_is_read_only (comp_editor_get_e_cal (COMP_EDITOR (ee)), &read_only, NULL); - - sens = priv->meeting_shown; - comp_editor_set_ui_prop (COMP_EDITOR (ee), - "/commands/ActionScheduleMeeting", - "sensitive", sens || read_only ? "0" : "1"); - - sens = priv->meeting_shown && existing && !user && !read_only; - comp_editor_set_ui_prop (COMP_EDITOR (ee), - "/commands/ActionRefreshMeeting", - "sensitive", sens ? "1" : "0"); - - sens = priv->meeting_shown && existing && user && !read_only; - comp_editor_set_ui_prop (COMP_EDITOR (ee), - "/commands/ActionCancelMeeting", - "sensitive", sens? "1" : "0"); - - comp_editor_set_ui_prop (COMP_EDITOR (ee), - "/commands/FileSave", - "sensitive", read_only ? "0" : "1"); - comp_editor_set_ui_prop (COMP_EDITOR (ee), - "/commands/FileSaveAndClose", - "sensitive", read_only ? "0" : "1"); - comp_editor_set_ui_prop (COMP_EDITOR (ee), - "/commands/FileDelete", - "sensitive", read_only ? "0" : "1"); -} - -static void -init_widgets (EventEditor *ee) -{ - EventEditorPrivate *priv; - - priv = ee->priv; - - g_signal_connect((priv->model), "row_changed", - G_CALLBACK (model_row_change_insert_cb), ee); - g_signal_connect((priv->model), "row_inserted", - G_CALLBACK (model_row_change_insert_cb), ee); - g_signal_connect((priv->model), "row_deleted", - G_CALLBACK (model_row_delete_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->model = E_MEETING_STORE (e_meeting_store_new ()); - priv->meeting_shown = TRUE; - priv->updating = FALSE; -} - -EventEditor * -event_editor_construct (EventEditor *ee, ECal *client) -{ - EventEditorPrivate *priv; - - priv = ee->priv; - - priv->event_page = event_page_new (); - g_object_ref (priv->event_page); - gtk_object_sink (GTK_OBJECT (priv->event_page)); - comp_editor_append_page (COMP_EDITOR (ee), - COMP_EDITOR_PAGE (priv->event_page), - _("Appointment")); - - priv->alarm_page = alarm_page_new (); - g_object_ref (priv->alarm_page); - gtk_object_sink (GTK_OBJECT (priv->alarm_page)); - comp_editor_append_page (COMP_EDITOR (ee), - COMP_EDITOR_PAGE (priv->alarm_page), - _("Reminder")); - - priv->recur_page = recurrence_page_new (); - g_object_ref (priv->recur_page); - gtk_object_sink (GTK_OBJECT (priv->recur_page)); - comp_editor_append_page (COMP_EDITOR (ee), - COMP_EDITOR_PAGE (priv->recur_page), - _("Recurrence")); - - priv->sched_page = schedule_page_new (priv->model); - g_object_ref (priv->sched_page); - gtk_object_sink (GTK_OBJECT (priv->sched_page)); - comp_editor_append_page (COMP_EDITOR (ee), - COMP_EDITOR_PAGE (priv->sched_page), - _("Scheduling")); - - priv->meet_page = meeting_page_new (priv->model, client); - g_object_ref (priv->meet_page); - gtk_object_sink (GTK_OBJECT (priv->meet_page)); - comp_editor_append_page (COMP_EDITOR (ee), - COMP_EDITOR_PAGE (priv->meet_page), - _("Meeting")); - - comp_editor_set_e_cal (COMP_EDITOR (ee), client); - - comp_editor_merge_ui (COMP_EDITOR (ee), "evolution-event-editor.xml", verbs, pixmaps); - - init_widgets (ee); - set_menu_sens (ee); - gtk_window_set_default_size (GTK_WINDOW (ee), 300, 225); - - return ee; -} - -static void -event_editor_set_e_cal (CompEditor *editor, ECal *client) -{ - EventEditor *ee; - EventEditorPrivate *priv; - - ee = EVENT_EDITOR (editor); - priv = ee->priv; - - e_meeting_store_set_e_cal (priv->model, client); - - if (parent_class->set_e_cal) - parent_class->set_e_cal (editor, client); -} - -static void -event_editor_edit_comp (CompEditor *editor, ECalComponent *comp) -{ - EventEditor *ee; - EventEditorPrivate *priv; - ECalComponentOrganizer organizer; - ECal *client; - GSList *attendees = NULL; - - ee = EVENT_EDITOR (editor); - priv = ee->priv; - - priv->updating = TRUE; - - if (parent_class->edit_comp) - parent_class->edit_comp (editor, comp); - - client = comp_editor_get_e_cal (COMP_EDITOR (editor)); - - /* Get meeting related stuff */ - e_cal_component_get_organizer (comp, &organizer); - e_cal_component_get_attendee_list (comp, &attendees); - - /* Clear things up */ - e_meeting_store_remove_all_attendees (priv->model); - - /* Set up the attendees */ - 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; - int row; - - 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) { - ECalComponentAttendee *ca = l->data; - EMeetingAttendee *ia; - - ia = E_MEETING_ATTENDEE (e_meeting_attendee_new_from_e_cal_component_attendee (ca)); - - /* If we aren't the organizer or the attendee is just delegating, don't allow editing */ - if (!comp_editor_get_user_org (editor) || e_meeting_attendee_is_set_delto (ia)) - e_meeting_attendee_set_edit_level (ia, E_MEETING_ATTENDEE_EDIT_NONE); - e_meeting_store_add_attendee (priv->model, ia); - - g_object_unref(ia); - } - - /* If we aren't the organizer we can still change our own status */ - if (!comp_editor_get_user_org (editor)) { - EAccountList *accounts; - EAccount *account; - EIterator *it; - - accounts = itip_addresses_get (); - for (it = e_list_get_iterator((EList *)accounts);e_iterator_is_valid(it);e_iterator_next(it)) { - EMeetingAttendee *ia; - - account = (EAccount*)e_iterator_get(it); - - ia = e_meeting_store_find_attendee (priv->model, account->id->address, &row); - if (ia != NULL) - e_meeting_attendee_set_edit_level (ia, E_MEETING_ATTENDEE_EDIT_STATUS); - } - g_object_unref(it); - } else if (e_cal_get_organizer_must_attend (client)) { - EMeetingAttendee *ia; - - ia = e_meeting_store_find_attendee (priv->model, organizer.value, &row); - if (ia != NULL) - e_meeting_attendee_set_edit_level (ia, E_MEETING_ATTENDEE_EDIT_NONE); - } - - priv->meeting_shown = TRUE; - } - e_cal_component_free_attendee_list (attendees); - - set_menu_sens (ee); - comp_editor_set_needs_send (COMP_EDITOR (ee), priv->meeting_shown && itip_organizer_is_user (comp, client)); - - priv->updating = FALSE; -} - -static gboolean -event_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method) -{ - EventEditor *ee = EVENT_EDITOR (editor); - EventEditorPrivate *priv; - ECalComponent *comp = NULL; - - priv = ee->priv; - - /* Don't cancel more than once or when just publishing */ - if (method == E_CAL_COMPONENT_METHOD_PUBLISH || - method == E_CAL_COMPONENT_METHOD_CANCEL) - goto parent; - - comp = meeting_page_get_cancel_comp (priv->meet_page); - if (comp != NULL) { - ECal *client; - gboolean result; - - client = e_meeting_store_get_e_cal (priv->model); - result = itip_send_comp (E_CAL_COMPONENT_METHOD_CANCEL, comp, client, NULL); - g_object_unref (comp); - - if (!result) - return FALSE; - } - - parent: - if (parent_class->send_comp) - return parent_class->send_comp (editor, method); - - return FALSE; -} - -/* Destroy handler for the event editor */ -static void -event_editor_finalize (GObject *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; - - g_object_unref (priv->event_page); - g_object_unref (priv->alarm_page); - g_object_unref (priv->recur_page); - g_object_unref (priv->meet_page); - g_object_unref (priv->sched_page); - - g_object_unref (priv->model); - - g_free (priv); - - if (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (object); -} - -/** - * event_editor_new: - * @client: a ECal - * - * 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 (ECal *client) -{ - EventEditor *ee; - - ee = EVENT_EDITOR (g_object_new (TYPE_EVENT_EDITOR, NULL)); - return event_editor_construct (ee, client); -} - -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), E_CAL_COMPONENT_METHOD_REFRESH); -} - -static void -cancel_meeting_cmd (GtkWidget *widget, gpointer data) -{ - EventEditor *ee = EVENT_EDITOR (data); - ECalComponent *comp; - - comp = comp_editor_get_current_comp (COMP_EDITOR (ee)); - if (cancel_component_dialog ((GtkWindow *) ee, - comp_editor_get_e_cal (COMP_EDITOR (ee)), comp, FALSE)) { - comp_editor_send_comp (COMP_EDITOR (ee), E_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), E_CAL_COMPONENT_METHOD_PUBLISH); -} - -static void -model_changed (EventEditor *ee) -{ - if (!ee->priv->updating) { - comp_editor_set_changed (COMP_EDITOR (ee), TRUE); - comp_editor_set_needs_send (COMP_EDITOR (ee), TRUE); - } -} - -static void -model_row_change_insert_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) -{ - model_changed (EVENT_EDITOR (data)); -} - -static void -model_row_delete_cb (GtkTreeModel *model, GtkTreePath *path, gpointer data) -{ - model_changed (EVENT_EDITOR (data)); -} - diff --git a/calendar/gui/dialogs/event-editor.h b/calendar/gui/dialogs/event-editor.h deleted file mode 100644 index 9234b8310e..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 <gtk/gtkobject.h> -#include "comp-editor.h" - - - -#define TYPE_EVENT_EDITOR (event_editor_get_type ()) -#define EVENT_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_EVENT_EDITOR, EventEditor)) -#define EVENT_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_EVENT_EDITOR, EventEditorClass)) -#define IS_EVENT_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_EVENT_EDITOR)) -#define IS_EVENT_EDITOR_CLASS(klass) (G_TYPE_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, - ECal *client); -EventEditor *event_editor_new (ECal *client); -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 c943825c84..0000000000 --- a/calendar/gui/dialogs/event-page.c +++ /dev/null @@ -1,1371 +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 <string.h> -#include <gtk/gtksignal.h> -#include <gtk/gtktextview.h> -#include <gtk/gtktogglebutton.h> -#include <libgnome/gnome-i18n.h> -#include <glade/glade.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 <libecal/e-cal-time-util.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_frame; - GtkWidget *show_time_as_free; - GtkWidget *show_time_as_busy; - - 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; -}; - - - -static void event_page_class_init (EventPageClass *class); -static void event_page_init (EventPage *epage); -static void event_page_finalize (GObject *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, ECalComponent *comp); -static gboolean event_page_fill_component (CompEditorPage *page, ECalComponent *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. - **/ - -E_MAKE_TYPE (event_page, "EventPage", EventPage, event_page_class_init, event_page_init, - TYPE_COMP_EDITOR_PAGE); - -/* Class initialization function for the event page */ -static void -event_page_class_init (EventPageClass *class) -{ - CompEditorPageClass *editor_page_class; - GObjectClass *object_class; - - editor_page_class = (CompEditorPageClass *) class; - object_class = (GObjectClass *) class; - - parent_class = g_type_class_ref (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->finalize = event_page_finalize; -} - -/* 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_frame = NULL; - priv->show_time_as_free = NULL; - priv->show_time_as_busy = NULL; - priv->categories_btn = NULL; - priv->categories = NULL; - - priv->updating = FALSE; - priv->sync_timezones = FALSE; -} - -/* Destroy handler for the event page */ -static void -event_page_finalize (GObject *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->main) - gtk_widget_unref (priv->main); - - if (priv->xml) { - g_object_unref (priv->xml); - priv->xml = NULL; - } - - g_free (priv); - epage->priv = NULL; - - if (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (object); -} - - - -static const int classification_map[] = { - E_CAL_COMPONENT_CLASS_PUBLIC, - E_CAL_COMPONENT_CLASS_PRIVATE, - E_CAL_COMPONENT_CLASS_CONFIDENTIAL, - -1 -}; - -static const int transparency_map[] = { - E_CAL_COMPONENT_TRANSP_TRANSPARENT, - E_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, ECalComponentDateTime *start_date, ECalComponentDateTime *end_date) -{ - EventPagePrivate *priv; - struct icaltimetype *start_tt, *end_tt, implied_tt; - icaltimezone *start_zone = NULL, *end_zone = NULL; - 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) { - /* FIXME: Handle error better. */ - if (!e_cal_get_timezone (COMP_EDITOR_PAGE (epage)->client, - start_date->tzid, &start_zone, NULL)) { - 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) { - if (!e_cal_get_timezone (COMP_EDITOR_PAGE (epage)->client, - end_date->tzid, &end_zone, NULL)) { - /* FIXME: Handle error better. */ - 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 (!end_tt && start_tt->is_date) { - end_tt = &implied_tt; - *end_tt = *start_tt; - icaltime_adjust (end_tt, 1, 0, 0, 0); - } - - 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); - g_signal_handlers_block_matched (priv->end_time, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, 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); - g_signal_handlers_block_matched (priv->end_timezone, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, 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); - gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->description)), "", 0); - - /* Start and end times */ - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_time), - epage); - g_signal_handlers_block_matched (priv->end_time, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, 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, - E_CAL_COMPONENT_CLASS_PRIVATE, classification_map); - - /* Show Time As (Transparency) */ - e_dialog_radio_set (priv->show_time_as_free, - E_CAL_COMPONENT_TRANSP_OPAQUE, transparency_map); - - /* Categories */ - e_dialog_editable_set (priv->categories, NULL); -} - - -/* fill_widgets handler for the event page */ -static void -event_page_fill_widgets (CompEditorPage *page, ECalComponent *comp) -{ - EventPage *epage; - EventPagePrivate *priv; - ECalComponentText text; - ECalComponentClassification cl; - ECalComponentTransparency transparency; - ECalComponentDateTime 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) */ - - e_cal_component_get_summary (comp, &text); - e_dialog_editable_set (priv->summary, text.value); - - e_cal_component_get_location (comp, &location); - e_dialog_editable_set (priv->location, location); - - e_cal_component_get_description_list (comp, &l); - if (l) { - text = *(ECalComponentText *)l->data; - gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->description)), - text.value, -1); - } - e_cal_component_free_text_list (l); - - /* Start and end times */ - - e_cal_component_get_dtstart (comp, &start_date); - e_cal_component_get_dtend (comp, &end_date); - - update_time (epage, &start_date, &end_date); - - e_cal_component_free_datetime (&start_date); - e_cal_component_free_datetime (&end_date); - - /* Classification */ - - e_cal_component_get_classification (comp, &cl); - - switch (cl) { - case E_CAL_COMPONENT_CLASS_PUBLIC: - e_dialog_radio_set (priv->classification_public, - E_CAL_COMPONENT_CLASS_PUBLIC, - classification_map); - break; - - case E_CAL_COMPONENT_CLASS_PRIVATE: - e_dialog_radio_set (priv->classification_public, - E_CAL_COMPONENT_CLASS_PRIVATE, - classification_map); - break; - - case E_CAL_COMPONENT_CLASS_CONFIDENTIAL: - e_dialog_radio_set (priv->classification_public, - E_CAL_COMPONENT_CLASS_CONFIDENTIAL, - classification_map); - break; - - default: - /* default to PUBLIC */ - e_dialog_radio_set (priv->classification_public, - E_CAL_COMPONENT_CLASS_PUBLIC, - classification_map); - break; - } - - - /* Show Time As (Transparency) */ - e_cal_component_get_transparency (comp, &transparency); - switch (transparency) { - case E_CAL_COMPONENT_TRANSP_TRANSPARENT: - e_dialog_radio_set (priv->show_time_as_free, - E_CAL_COMPONENT_TRANSP_TRANSPARENT, - transparency_map); - break; - - default: - e_dialog_radio_set (priv->show_time_as_free, - E_CAL_COMPONENT_TRANSP_OPAQUE, - transparency_map); - break; - } - if (e_cal_get_static_capability (page->client, CAL_STATIC_CAPABILITY_NO_TRANSPARENCY)) - gtk_widget_hide (priv->show_time_frame); - else - gtk_widget_show (priv->show_time_frame); - - /* Categories */ - e_cal_component_get_categories (comp, &categories); - e_dialog_editable_set (priv->categories, categories); - - priv->updating = FALSE; -} - -/* fill_component handler for the event page */ -static gboolean -event_page_fill_component (CompEditorPage *page, ECalComponent *comp) -{ - EventPage *epage; - EventPagePrivate *priv; - ECalComponentDateTime start_date, end_date; - struct icaltimetype start_tt, end_tt; - gboolean all_day_event, start_date_set, end_date_set; - char *cat, *str; - ECalComponentClassification classif; - ECalComponentTransparency transparency; - GtkTextBuffer *text_buffer; - GtkTextIter text_iter_start, text_iter_end; - - epage = EVENT_PAGE (page); - priv = epage->priv; - text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->description)); - - /* Summary */ - - str = e_dialog_editable_get (priv->summary); - if (!str || strlen (str) == 0) - e_cal_component_set_summary (comp, NULL); - else { - ECalComponentText text; - - text.value = str; - text.altrep = NULL; - - e_cal_component_set_summary (comp, &text); - } - - if (str) - g_free (str); - - /* Location */ - - str = e_dialog_editable_get (priv->location); - if (!str || strlen (str) == 0) - e_cal_component_set_location (comp, NULL); - else - e_cal_component_set_location (comp, str); - - if (str) - g_free (str); - - /* Description */ - - gtk_text_buffer_get_start_iter (text_buffer, &text_iter_start); - gtk_text_buffer_get_end_iter (text_buffer, &text_iter_end); - str = gtk_text_buffer_get_text (text_buffer, &text_iter_start, &text_iter_end, FALSE); - - if (!str || strlen (str) == 0) - e_cal_component_set_description_list (comp, NULL); - else { - GSList l; - ECalComponentText text; - - text.value = str; - text.altrep = NULL; - l.data = &text; - l.next = NULL; - - e_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; - - if (!e_date_edit_date_is_valid (E_DATE_EDIT (priv->start_time))) { - comp_editor_page_display_validation_error (page, _("Start date is wrong"), priv->start_time); - return FALSE; - } - 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); - - if (!e_date_edit_date_is_valid (E_DATE_EDIT (priv->end_time))) { - comp_editor_page_display_validation_error (page, _("End date is wrong"), priv->end_time); - return FALSE; - } - 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; - - if (!e_date_edit_time_is_valid (E_DATE_EDIT (priv->start_time))) { - comp_editor_page_display_validation_error (page, _("Start time is wrong"), priv->start_time); - return FALSE; - } - e_date_edit_get_time_of_day (E_DATE_EDIT (priv->start_time), - &start_tt.hour, - &start_tt.minute); - if (!e_date_edit_time_is_valid (E_DATE_EDIT (priv->end_time))) { - comp_editor_page_display_validation_error (page, _("End time is wrong"), priv->end_time); - return FALSE; - } - 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); - } - - e_cal_component_set_dtstart (comp, &start_date); - e_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); - - e_cal_component_set_categories (comp, str); - - if (str) - g_free (str); - - /* Classification */ - - classif = e_dialog_radio_get (priv->classification_public, - classification_map); - e_cal_component_set_classification (comp, classif); - - /* Show Time As (Transparency) */ - - transparency = e_dialog_radio_get (priv->show_time_as_free, - transparency_map); - e_cal_component_set_transparency (comp, transparency); - - 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 (G_OBJECT (toplevel)); - if (accel_groups) { - page->accel_group = accel_groups->data; - gtk_accel_group_ref (page->accel_group); - } - - gtk_widget_ref (priv->main); - gtk_container_remove (GTK_CONTAINER (priv->main->parent), priv->main); - - priv->summary = GW ("general-summary"); - priv->location = GW ("location"); - - /* Glade's visibility flag doesn't seem to work for custom widgets */ - priv->start_time = GW ("start-time"); - gtk_widget_show (priv->start_time); - priv->end_time = GW ("end-time"); - gtk_widget_show (priv->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_frame = GW ("show-time-frame"); - priv->show_time_as_free = GW ("show-time-as-free"); - priv->show_time_as_busy = GW ("show-time-as-busy"); - - 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_frame - && priv->show_time_as_free - && priv->show_time_as_busy - && 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; - ECalComponentDateTime 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) { - g_signal_handlers_block_matched (priv->start_time, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, 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); - g_signal_handlers_unblock_matched (priv->start_time, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, epage); - } - - if (set_end_date) { - g_signal_handlers_block_matched (priv->end_time, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, 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); - g_signal_handlers_unblock_matched (priv->end_time, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, 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 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; - GtkTextBuffer *text_buffer; - 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 */ - g_signal_connect((priv->summary), "changed", - G_CALLBACK (summary_changed_cb), epage); - - /* Description */ - text_buffer = gtk_text_buffer_new (NULL); - gtk_text_view_set_buffer (GTK_TEXT_VIEW (priv->description), text_buffer); - g_object_unref (text_buffer); - - gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->description), GTK_WRAP_WORD); - - /* Start and end times */ - g_signal_connect((priv->start_time), "changed", - G_CALLBACK (date_changed_cb), epage); - g_signal_connect((priv->end_time), "changed", - G_CALLBACK (date_changed_cb), epage); - - g_signal_connect((priv->start_timezone), "changed", - G_CALLBACK (start_timezone_changed_cb), epage); - g_signal_connect((priv->end_timezone), "changed", - G_CALLBACK (end_timezone_changed_cb), epage); - - g_signal_connect((priv->all_day_event), "toggled", - G_CALLBACK (all_day_event_toggled_cb), epage); - - /* Categories button */ - g_signal_connect((priv->categories_btn), "clicked", - G_CALLBACK (categories_clicked_cb), epage); - - /* Connect the default signal handler to use to make sure we notify - * upstream of changes to the widget values. - */ - - /* Belongs to priv->description */ - g_signal_connect((text_buffer), "changed", - G_CALLBACK (field_changed_cb), epage); - - g_signal_connect((priv->summary), "changed", - G_CALLBACK (field_changed_cb), epage); - g_signal_connect((priv->location), "changed", - G_CALLBACK (field_changed_cb), epage); - g_signal_connect((priv->start_time), "changed", - G_CALLBACK (field_changed_cb), epage); - g_signal_connect((priv->end_time), "changed", - G_CALLBACK (field_changed_cb), epage); - g_signal_connect((priv->start_timezone), "changed", - G_CALLBACK (field_changed_cb), epage); - g_signal_connect((priv->end_timezone), "changed", - G_CALLBACK (field_changed_cb), epage); - g_signal_connect((priv->all_day_event), "toggled", - G_CALLBACK (field_changed_cb), epage); - g_signal_connect((priv->classification_public), - "toggled", G_CALLBACK (field_changed_cb), - epage); - g_signal_connect((priv->classification_private), - "toggled", G_CALLBACK (field_changed_cb), - epage); - g_signal_connect((priv->classification_confidential), - "toggled", G_CALLBACK (field_changed_cb), - epage); - g_signal_connect((priv->show_time_as_free), - "toggled", G_CALLBACK (field_changed_cb), - epage); - g_signal_connect((priv->show_time_as_busy), - "toggled", G_CALLBACK (field_changed_cb), - epage); - g_signal_connect((priv->categories), "changed", - G_CALLBACK (field_changed_cb), epage); - - /* 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, 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 = g_object_new (TYPE_EVENT_PAGE, NULL); - if (!event_page_construct (epage)) { - g_object_unref (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) -{ - GtkWidget *w; - - w = e_timezone_entry_new (); - gtk_widget_show (w); - return w; -} diff --git a/calendar/gui/dialogs/event-page.glade b/calendar/gui/dialogs/event-page.glade deleted file mode 100644 index b59eb61e86..0000000000 --- a/calendar/gui/dialogs/event-page.glade +++ /dev/null @@ -1,601 +0,0 @@ -<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> -<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> - -<glade-interface> - -<widget class="GtkWindow" id="event-toplevel"> - <property name="title" translatable="yes">window1</property> - <property name="type">GTK_WINDOW_TOPLEVEL</property> - <property name="window_position">GTK_WIN_POS_NONE</property> - <property name="modal">False</property> - <property name="resizable">True</property> - <property name="destroy_with_parent">False</property> - - <child> - <widget class="GtkVBox" id="event-page"> - <property name="border_width">12</property> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkTable" id="table11"> - <property name="visible">True</property> - <property name="n_rows">2</property> - <property name="n_columns">2</property> - <property name="homogeneous">False</property> - <property name="row_spacing">6</property> - <property name="column_spacing">6</property> - - <child> - <widget class="GtkLabel" id="label56"> - <property name="visible">True</property> - <property name="label" translatable="yes">Su_mmary:</property> - <property name="use_underline">True</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">7.45058e-09</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="mnemonic_widget">general-summary</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkEntry" id="general-summary"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="editable">True</property> - <property name="visibility">True</property> - <property name="max_length">0</property> - <property name="text" translatable="yes"></property> - <property name="has_frame">True</property> - <property name="invisible_char" translatable="yes">*</property> - <property name="activates_default">False</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label61"> - <property name="visible">True</property> - <property name="label" translatable="yes">L_ocation:</property> - <property name="use_underline">True</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">7.45058e-09</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="mnemonic_widget">location</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkEntry" id="location"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="editable">True</property> - <property name="visibility">True</property> - <property name="max_length">0</property> - <property name="text" translatable="yes"></property> - <property name="has_frame">True</property> - <property name="invisible_char" translatable="yes">*</property> - <property name="activates_default">False</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="y_options"></property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkFrame" id="frame31"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <property name="label_yalign">0.5</property> - <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property> - - <child> - <widget class="GtkTable" id="table12"> - <property name="border_width">6</property> - <property name="visible">True</property> - <property name="n_rows">2</property> - <property name="n_columns">4</property> - <property name="homogeneous">False</property> - <property name="row_spacing">6</property> - <property name="column_spacing">6</property> - - <child> - <widget class="GtkLabel" id="label57"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Start time:</property> - <property name="use_underline">True</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="mnemonic_widget">start-time</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label58"> - <property name="visible">True</property> - <property name="label" translatable="yes">_End time:</property> - <property name="use_underline">True</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="mnemonic_widget">end-time</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="Custom" id="start-time"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="creation_function">make_date_edit</property> - <property name="string1"></property> - <property name="string2"></property> - <property name="int1">0</property> - <property name="int2">0</property> - <property name="last_modification_time">Tue, 16 May 2000 19:11:05 GMT</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="x_options"></property> - </packing> - </child> - - <child> - <widget class="Custom" id="end-time"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="creation_function">make_date_edit</property> - <property name="int1">0</property> - <property name="int2">0</property> - <property name="last_modification_time">Tue, 16 May 2000 19:11:10 GMT</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options"></property> - </packing> - </child> - - <child> - <widget class="Custom" id="end-timezone"> - <property name="visible">True</property> - <property name="creation_function">make_timezone_entry</property> - <property name="int1">0</property> - <property name="int2">0</property> - <property name="last_modification_time">Mon, 18 Jun 2001 23:51:40 GMT</property> - </widget> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options"></property> - <property name="y_options">fill</property> - </packing> - </child> - - <child> - <widget class="Custom" id="start-timezone"> - <property name="visible">True</property> - <property name="creation_function">make_timezone_entry</property> - <property name="int1">0</property> - <property name="int2">0</property> - <property name="last_modification_time">Mon, 18 Jun 2001 23:51:34 GMT</property> - </widget> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="x_options">fill</property> - <property name="y_options">fill</property> - </packing> - </child> - - <child> - <widget class="GtkAlignment" id="alignment1"> - <property name="visible">True</property> - <property name="xalign">1</property> - <property name="yalign">7.45058e-09</property> - <property name="xscale">0</property> - <property name="yscale">0</property> - - <child> - <widget class="GtkCheckButton" id="all-day-event"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">A_ll day event</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - </widget> - </child> - </widget> - <packing> - <property name="left_attach">3</property> - <property name="right_attach">4</property> - <property name="top_attach">0</property> - <property name="bottom_attach">2</property> - <property name="y_options">fill</property> - </packing> - </child> - </widget> - </child> - - <child> - <widget class="GtkLabel" id="label62"> - <property name="visible">True</property> - <property name="label" translatable="yes">Date & Time</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkScrolledWindow" id="scrolledwindow12"> - <property name="visible">True</property> - <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> - <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="shadow_type">GTK_SHADOW_IN</property> - <property name="window_placement">GTK_CORNER_TOP_LEFT</property> - - <child> - <widget class="GtkTextView" id="description"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="editable">True</property> - <property name="justification">GTK_JUSTIFY_LEFT</property> - <property name="wrap_mode">GTK_WRAP_WORD</property> - <property name="cursor_visible">True</property> - <property name="pixels_above_lines">0</property> - <property name="pixels_below_lines">0</property> - <property name="pixels_inside_wrap">0</property> - <property name="left_margin">0</property> - <property name="right_margin">0</property> - <property name="indent">0</property> - <property name="text" translatable="yes"></property> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkHBox" id="hbox54"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkFrame" id="frame32"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <property name="label_yalign">0.5</property> - <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property> - - <child> - <widget class="GtkHBox" id="hbox52"> - <property name="border_width">6</property> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkRadioButton" id="classification-public"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Pu_blic</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="active">True</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkRadioButton" id="classification-private"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Pri_vate</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - <property name="group">classification-public</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkRadioButton" id="classification-confidential"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Co_nfidential</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - <property name="group">classification-public</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - </child> - - <child> - <widget class="GtkLabel" id="label63"> - <property name="visible">True</property> - <property name="label" translatable="yes">Classification</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkFrame" id="show-time-frame"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <property name="label_yalign">0.5</property> - <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property> - - <child> - <widget class="GtkHBox" id="hbox55"> - <property name="border_width">6</property> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkRadioButton" id="show-time-as-free"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">F_ree</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkRadioButton" id="show-time-as-busy"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">B_usy</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - <property name="group">show-time-as-free</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - </child> - - <child> - <widget class="GtkLabel" id="label64"> - <property name="visible">True</property> - <property name="label" translatable="yes">Show Time As</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkHBox" id="hbox53"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkButton" id="categories-button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Ca_tegories...</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkEntry" id="categories"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="editable">True</property> - <property name="visibility">True</property> - <property name="max_length">0</property> - <property name="text" translatable="yes"></property> - <property name="has_frame">True</property> - <property name="invisible_char" translatable="yes">*</property> - <property name="activates_default">False</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - </child> -</widget> - -</glade-interface> diff --git a/calendar/gui/dialogs/event-page.h b/calendar/gui/dialogs/event-page.h deleted file mode 100644 index a21f084e01..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" - -G_BEGIN_DECLS - - - -#define TYPE_EVENT_PAGE (event_page_get_type ()) -#define EVENT_PAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_EVENT_PAGE, EventPage)) -#define EVENT_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_EVENT_PAGE, EventPageClass)) -#define IS_EVENT_PAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_EVENT_PAGE)) -#define IS_EVENT_PAGE_CLASS(klass) (G_TYPE_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); - - - -G_END_DECLS - -#endif diff --git a/calendar/gui/dialogs/meeting-page.c b/calendar/gui/dialogs/meeting-page.c deleted file mode 100644 index fe4ade9363..0000000000 --- a/calendar/gui/dialogs/meeting-page.c +++ /dev/null @@ -1,833 +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/gtkcombo.h> -#include <gtk/gtksignal.h> -#include <gtk/gtktogglebutton.h> -#include <gtk/gtkvbox.h> -#include <gtk/gtkwindow.h> -#include <libgnome/gnome-i18n.h> -#include <glade/glade.h> -#include <libgnomeui/gnome-stock-icons.h> -#include <gal/util/e-util.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-utils.h> -#include <e-util/e-dialog-widgets.h> - -#include "../calendar-component.h" -#include "../e-meeting-attendee.h" -#include "../e-meeting-store.h" -#include "../e-meeting-list-view.h" -#include "../itip-utils.h" -#include "comp-editor-util.h" -#include "e-delegate-dialog.h" -#include "meeting-page.h" - - -/* Private part of the MeetingPage structure */ -struct _MeetingPagePrivate { - /* Lists of attendees */ - GPtrArray *deleted_attendees; - - /* To use in case of cancellation */ - ECalComponent *comp; - - /* List of identities */ - EAccountList *accounts; - EMeetingAttendee *ia; - char *default_address; - - /* Glade XML data */ - GladeXML *xml; - - /* Widgets from the Glade file */ - GtkWidget *main; - GtkWidget *organizer_table; - GtkWidget *organizer; - GtkWidget *existing_organizer_table; - GtkWidget *existing_organizer; - GtkWidget *existing_organizer_btn; - GtkWidget *invite; - - /* ListView stuff */ - EMeetingStore *model; - EMeetingListView *list_view; - gint row; - - /* For handling who the organizer is */ - gboolean existing; - - gboolean updating; -}; - - - -static void meeting_page_class_init (MeetingPageClass *class); -static void meeting_page_init (MeetingPage *mpage); -static void meeting_page_finalize (GObject *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, ECalComponent *comp); -static gboolean meeting_page_fill_component (CompEditorPage *page, ECalComponent *comp); - -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. - **/ - -E_MAKE_TYPE (meeting_page, "MeetingPage", MeetingPage, meeting_page_class_init, meeting_page_init, - TYPE_COMP_EDITOR_PAGE); - -/* Class initialization function for the task page */ -static void -meeting_page_class_init (MeetingPageClass *class) -{ - CompEditorPageClass *editor_page_class; - GObjectClass *object_class; - - editor_page_class = (CompEditorPageClass *) class; - object_class = (GObjectClass *) class; - - parent_class = g_type_class_ref (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->finalize = meeting_page_finalize; -} - -/* 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->accounts = NULL; - priv->ia = NULL; - priv->default_address = NULL; - - priv->xml = NULL; - priv->main = NULL; - priv->invite = NULL; - - priv->model = NULL; - priv->list_view = NULL; - - priv->updating = FALSE; -} - -static EAccount * -get_current_account (MeetingPage *mpage) -{ - MeetingPagePrivate *priv; - EIterator *it; - const char *str; - - priv = mpage->priv; - - str = gtk_entry_get_text (GTK_ENTRY (GTK_COMBO (priv->organizer)->entry)); - if (!str) - return NULL; - - for (it = e_list_get_iterator((EList *)priv->accounts); e_iterator_is_valid(it); e_iterator_next(it)) { - EAccount *a = (EAccount *)e_iterator_get(it); - char *full = g_strdup_printf("%s <%s>", a->id->name, a->id->address); - - if (!strcmp (full, str)) { - g_free (full); - g_object_unref (it); - - return a; - } - - g_free (full); - } - g_object_unref (it); - - return NULL; -} - -static void -set_attendees (ECalComponent *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); - ECalComponentAttendee *ca; - - ca = e_meeting_attendee_as_e_cal_component_attendee (ia); - - comp_attendees = g_slist_prepend (comp_attendees, ca); - - } - comp_attendees = g_slist_reverse (comp_attendees); - e_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++) - g_object_unref (g_ptr_array_index (attendees, i)); -} - -/* Destroy handler for the task page */ -static void -meeting_page_finalize (GObject *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) - g_object_unref (priv->comp); - - cleanup_attendees (priv->deleted_attendees); - g_ptr_array_free (priv->deleted_attendees, TRUE); - - if (priv->ia != NULL) - g_object_unref (priv->ia); - - g_object_unref (priv->model); - - if (priv->main) - gtk_widget_unref (priv->main); - - if (priv->xml) { - g_object_unref (priv->xml); - priv->xml = NULL; - } - - if (priv->default_address) { - g_free (priv->default_address); - priv->default_address = NULL; - } - - g_free (priv); - mpage->priv = NULL; - - if (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (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), priv->default_address); - gtk_label_set_text (GTK_LABEL (priv->existing_organizer), _("None")); - - gtk_widget_show (priv->organizer_table); - gtk_widget_hide (priv->existing_organizer_table); - - priv->existing = FALSE; -} - -/* fill_widgets handler for the meeting page */ -static void -meeting_page_fill_widgets (CompEditorPage *page, ECalComponent *comp) -{ - MeetingPage *mpage; - MeetingPagePrivate *priv; - ECalComponentOrganizer organizer; - - mpage = MEETING_PAGE (page); - priv = mpage->priv; - - priv->updating = TRUE; - - /* Clean out old data */ - if (priv->comp != NULL) - g_object_unref (priv->comp); - priv->comp = NULL; - - cleanup_attendees (priv->deleted_attendees); - g_ptr_array_set_size (priv->deleted_attendees, 0); - - /* Clean the screen */ - clear_widgets (mpage); - - /* Component for cancellation */ - priv->comp = e_cal_component_clone (comp); - - /* If there is an existing organizer show it properly */ - if (e_cal_component_has_organizer (comp)) { - e_cal_component_get_organizer (comp, &organizer); - if (organizer.value != NULL) { - const gchar *strip = itip_strip_mailto (organizer.value); - gchar *string; - - gtk_widget_hide (priv->organizer_table); - gtk_widget_show (priv->existing_organizer_table); - if (itip_organizer_is_user (comp, page->client)) { - gtk_widget_show (priv->invite); - if (e_cal_get_static_capability ( - page->client, - CAL_STATIC_CAPABILITY_ORGANIZER_NOT_EMAIL_ADDRESS)) - gtk_widget_hide (priv->existing_organizer_btn); - } else { - if (e_cal_get_static_capability ( - page->client, - CAL_STATIC_CAPABILITY_ORGANIZER_NOT_EMAIL_ADDRESS)) - gtk_widget_hide (priv->existing_organizer_btn); - gtk_widget_hide (priv->invite); - } - - if (organizer.cn != NULL) - string = g_strdup_printf ("%s <%s>", organizer.cn, strip); - else - string = g_strdup (strip); - gtk_label_set_text (GTK_LABEL (priv->existing_organizer), string); - g_free (string); - - priv->existing = TRUE; - } - } else { - EAccount *a; - - a = get_current_account (mpage); - if (a != NULL) { - priv->ia = e_meeting_store_add_attendee_with_defaults (priv->model); - g_object_ref (priv->ia); - - e_meeting_attendee_set_address (priv->ia, g_strdup_printf ("MAILTO:%s", a->id->address)); - e_meeting_attendee_set_cn (priv->ia, g_strdup (a->id->name)); - e_meeting_attendee_set_status (priv->ia, ICAL_PARTSTAT_ACCEPTED); - } - } - - priv->updating = FALSE; -} - -/* fill_component handler for the meeting page */ -static gboolean -meeting_page_fill_component (CompEditorPage *page, ECalComponent *comp) -{ - MeetingPage *mpage; - MeetingPagePrivate *priv; - ECalComponentOrganizer organizer = {NULL, NULL, NULL, NULL}; - - mpage = MEETING_PAGE (page); - priv = mpage->priv; - - if (!priv->existing) { - EAccount *a; - gchar *addr = NULL; - - /* Find the identity for the organizer or sentby field */ - a = get_current_account (mpage); - - /* Sanity Check */ - if (a == NULL) { - e_notice (page, GTK_MESSAGE_ERROR, - _("The organizer selected no longer has an account.")); - return FALSE; - } - - if (a->id->address == NULL || strlen (a->id->address) == 0) { - e_notice (page, GTK_MESSAGE_ERROR, - _("An organizer is required.")); - return FALSE; - } - - addr = g_strdup_printf ("MAILTO:%s", a->id->address); - - organizer.value = addr; - organizer.cn = a->id->name; - e_cal_component_set_organizer (comp, &organizer); - - g_free (addr); - } - - if (e_meeting_store_count_actual_attendees (priv->model) < 1) { - e_notice (page, GTK_MESSAGE_ERROR, - _("At least one attendee is required.")); - return FALSE; - } - set_attendees (comp, e_meeting_store_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 (G_OBJECT (toplevel)); - if (accel_groups) { - page->accel_group = accel_groups->data; - gtk_accel_group_ref (page->accel_group); - } - - gtk_widget_ref (priv->main); - gtk_container_remove (GTK_CONTAINER (priv->main->parent), priv->main); - - /* For making the user the organizer */ - priv->organizer_table = GW ("organizer-table"); - priv->organizer = GW ("organizer"); - gtk_combo_set_value_in_list (GTK_COMBO (priv->organizer), FALSE, FALSE); - - /* For showing existing organizers */ - 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->existing_organizer_table - && priv->existing_organizer - && priv->existing_organizer_btn); -} - -static void -org_changed_cb (GtkWidget *widget, gpointer data) -{ - MeetingPage *mpage; - MeetingPagePrivate *priv; - - mpage = MEETING_PAGE (data); - priv = mpage->priv; - - if (priv->updating) - return; - - if (!priv->existing && priv->ia != NULL) { - EAccount *a; - - a = get_current_account (mpage); - if (a != NULL) { - e_meeting_attendee_set_address (priv->ia, g_strdup_printf ("MAILTO:%s", a->id->address)); - e_meeting_attendee_set_cn (priv->ia, g_strdup (a->id->name)); - - if (!e_meeting_store_find_attendee (priv->model, e_meeting_attendee_get_address (priv->ia), NULL)) - e_meeting_store_add_attendee (priv->model, priv->ia); - } else { - e_meeting_store_remove_attendee (priv->model, priv->ia); - } - } - - comp_editor_page_notify_changed (COMP_EDITOR_PAGE (mpage)); -} - -/* 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); - - comp_editor_page_notify_needs_send (COMP_EDITOR_PAGE (mpage)); - - 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_list_view_invite_others_dialog (priv->list_view); -} - -/* Hooks the widget signals */ -static void -init_widgets (MeetingPage *mpage) -{ - MeetingPagePrivate *priv; - - priv = mpage->priv; - - /* Organizer */ - g_signal_connect((GTK_COMBO (priv->organizer)->entry), "changed", - G_CALLBACK (org_changed_cb), mpage); - - g_signal_connect((priv->existing_organizer_btn), "clicked", - G_CALLBACK (change_clicked_cb), mpage); - - /* Invite button */ - g_signal_connect((priv->invite), "clicked", - G_CALLBACK (invite_cb), mpage); -} - -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_store_find_attendee_at_row (priv->model, priv->row); - - /* If the user deletes the attendee explicitly, assume they no - longer want the organizer showing up */ - if (ia == priv->ia) { - g_object_unref (priv->ia); - priv->ia = NULL; - } - - /* If this was a delegatee, no longer delegate */ - if (e_meeting_attendee_is_set_delfrom (ia)) { - EMeetingAttendee *ib; - - ib = e_meeting_store_find_attendee (priv->model, e_meeting_attendee_get_delfrom (ia), &pos); - if (ib != NULL) { - e_meeting_attendee_set_delto (ib, NULL); - e_meeting_attendee_set_edit_level (ib, E_MEETING_ATTENDEE_EDIT_FULL); - } - } - - /* Handle deleting all attendees in the delegation chain */ - while (ia != NULL) { - EMeetingAttendee *ib = NULL; - - g_object_ref (ia); - g_ptr_array_add (priv->deleted_attendees, ia); - e_meeting_store_remove_attendee (priv->model, ia); - - if (e_meeting_attendee_get_delto (ia) != NULL) - ib = e_meeting_store_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..."), G_CALLBACK (popup_delegate_cb), CAN_DELEGATE), - - E_POPUP_SEPARATOR, -#endif - E_POPUP_ITEM (N_("_Delete"), G_CALLBACK (popup_delete_cb), CAN_DELETE), - - E_POPUP_TERMINATOR -}; - -#if 0 -/* FIXME: handle context menu for treeview */ -/* 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; - EMeetingAttendee *ia; - int disable_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); - - ia = e_meeting_model_find_attendee_at_row (priv->model, priv->row); - if (e_meeting_attendee_get_edit_level (ia) != E_MEETING_ATTENDEE_EDIT_FULL) - disable_mask = CAN_DELETE; - - /* FIXME: if you enable Delegate, then change index to '1'. - * (This has now been enabled). */ - /* context_menu[1].pixmap_widget = gnome_stock_new_with_icon (GNOME_STOCK_MENU_TRASH); */ - context_menu[1].pixmap_widget = - gtk_image_new_from_stock (GTK_STOCK_DELETE, GTK_ICON_SIZE_MENU); - - menu = e_popup_menu_create (context_menu, disable_mask, hide_mask, data); - e_auto_kill_popup_menu_on_selection_done (menu); - - gtk_menu_popup (menu, NULL, NULL, NULL, NULL, - event->button.button, event->button.time); - - return TRUE; -} -#endif - -static void -add_btn_clicked_cb (GtkButton *btn, MeetingPage *mpage) -{ - e_meeting_store_add_attendee_with_defaults (mpage->priv->model); -} - -/** - * 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, EMeetingStore *ems, - ECal *client) -{ - MeetingPagePrivate *priv; - char *backend_address; - EIterator *it; - EAccount *def_account; - GList *address_strings = NULL, *l; - GtkWidget *sw, *btn; - - priv = mpage->priv; - - priv->xml = glade_xml_new (EVOLUTION_GLADEDIR - "/meeting-page.glade", NULL, 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; - } - - /* Address information */ - if (!e_cal_get_cal_address (client, &backend_address, NULL)) - return NULL; - - priv->accounts = itip_addresses_get (); - def_account = itip_addresses_get_default(); - for (it = e_list_get_iterator((EList *)priv->accounts); - e_iterator_is_valid(it); - e_iterator_next(it)) { - EAccount *a = (EAccount *)e_iterator_get(it); - char *full; - - full = g_strdup_printf("%s <%s>", a->id->name, a->id->address); - - address_strings = g_list_append(address_strings, full); - - /* Note that the address specified by the backend gets - * precedence over the default mail address. - */ - if (backend_address && !strcmp (backend_address, a->id->address)) { - if (priv->default_address) - g_free (priv->default_address); - - priv->default_address = g_strdup (full); - } else if (a == def_account && !priv->default_address) { - priv->default_address = g_strdup (full); - } - } - g_object_unref(it); - g_free (backend_address); - - if (address_strings) - gtk_combo_set_popdown_strings (GTK_COMBO (priv->organizer), address_strings); - else - g_warning ("No potential organizers!"); - - for (l = address_strings; l != NULL; l = l->next) - g_free (l->data); - g_list_free (address_strings); - - /* The etable displaying attendees and their status */ - g_object_ref (ems); - priv->model = ems; - - btn = gtk_button_new_with_label ("Add Attendee"); - g_signal_connect(btn, "clicked", G_CALLBACK (add_btn_clicked_cb), mpage); - gtk_widget_show (btn); - gtk_box_pack_start (GTK_BOX (priv->main), btn, FALSE, FALSE, 6); - - priv->list_view = e_meeting_list_view_new (priv->model); - -#if 0 - /* FIXME: handle context menu for treeview */ - g_signal_connect((real_table), - "right_click", G_CALLBACK (right_click_cb), mpage); -#endif - - gtk_widget_show (GTK_WIDGET (priv->list_view)); - sw = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN); - gtk_widget_show (sw); - gtk_container_add (GTK_CONTAINER (sw), GTK_WIDGET (priv->list_view)); - gtk_box_pack_start (GTK_BOX (priv->main), sw, TRUE, TRUE, 6); - - /* 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 (EMeetingStore *ems, ECal *client) -{ - MeetingPage *mpage; - - mpage = g_object_new (TYPE_MEETING_PAGE, NULL); - if (!meeting_page_construct (mpage, ems, client)) { - g_object_unref (mpage); - return NULL; - } - - return mpage; -} - -/** - * meeting_page_get_cancel_comp: - * @mpage: - * - * - * - * Return value: - **/ -ECalComponent * -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 e_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 3b72c37b47..0000000000 --- a/calendar/gui/dialogs/meeting-page.glade +++ /dev/null @@ -1,241 +0,0 @@ -<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> -<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> - -<glade-interface> - -<widget class="GtkWindow" id="meeting-toplevel"> - <property name="title" translatable="yes">window1</property> - <property name="type">GTK_WINDOW_TOPLEVEL</property> - <property name="window_position">GTK_WIN_POS_NONE</property> - <property name="modal">False</property> - <property name="resizable">True</property> - <property name="destroy_with_parent">False</property> - - <child> - <widget class="GtkVBox" id="meeting-page"> - <property name="border_width">12</property> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkVBox" id="vbox1"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkTable" id="organizer-table"> - <property name="border_width">6</property> - <property name="visible">True</property> - <property name="n_rows">1</property> - <property name="n_columns">2</property> - <property name="homogeneous">False</property> - <property name="row_spacing">6</property> - <property name="column_spacing">6</property> - - <child> - <widget class="GtkCombo" id="organizer"> - <property name="visible">True</property> - <property name="value_in_list">True</property> - <property name="allow_empty">False</property> - <property name="case_sensitive">False</property> - <property name="enable_arrow_keys">True</property> - <property name="enable_arrows_always">False</property> - - <child internal-child="entry"> - <widget class="GtkEntry" id="entry2"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="editable">True</property> - <property name="visibility">True</property> - <property name="max_length">0</property> - <property name="text" translatable="yes"></property> - <property name="has_frame">True</property> - <property name="invisible_char" translatable="yes">*</property> - <property name="activates_default">False</property> - </widget> - </child> - - <child internal-child="list"> - <widget class="GtkList" id="convertwidget1"> - <property name="visible">True</property> - <property name="selection_mode">GTK_SELECTION_BROWSE</property> - - <child> - <widget class="GtkListItem" id="convertwidget2"> - <property name="visible">True</property> - - <child> - <widget class="GtkLabel" id="convertwidget3"> - <property name="visible">True</property> - <property name="label" translatable="yes"></property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - </child> - </widget> - </child> - </widget> - </child> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="organizer-label"> - <property name="visible">True</property> - <property name="label" translatable="yes">Organizer:</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkTable" id="existing-organizer-table"> - <property name="border_width">6</property> - <property name="visible">True</property> - <property name="n_rows">1</property> - <property name="n_columns">3</property> - <property name="homogeneous">False</property> - <property name="row_spacing">6</property> - <property name="column_spacing">6</property> - - <child> - <widget class="GtkLabel" id="label1"> - <property name="visible">True</property> - <property name="label" translatable="yes">Organizer:</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="x_options"></property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkButton" id="existing-organizer-button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">_Change Organizer</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - </widget> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="x_options"></property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="existing-organizer"> - <property name="visible">True</property> - <property name="label" translatable="yes">None</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="y_options"></property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <placeholder/> - </child> - - <child> - <widget class="GtkButton" id="invite"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">_Invite Others...</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="pack_type">GTK_PACK_END</property> - </packing> - </child> - </widget> - </child> -</widget> - -</glade-interface> diff --git a/calendar/gui/dialogs/meeting-page.h b/calendar/gui/dialogs/meeting-page.h deleted file mode 100644 index 95533cd771..0000000000 --- a/calendar/gui/dialogs/meeting-page.h +++ /dev/null @@ -1,67 +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-store.h" -#include "../itip-utils.h" -#include "comp-editor-page.h" - -G_BEGIN_DECLS - - - -#define TYPE_MEETING_PAGE (meeting_page_get_type ()) -#define MEETING_PAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_MEETING_PAGE, MeetingPage)) -#define MEETING_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_MEETING_PAGE, MeetingPageClass)) -#define IS_MEETING_PAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_MEETING_PAGE)) -#define IS_MEETING_PAGE_CLASS(klass) (G_TYPE_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, - EMeetingStore *ems, - ECal *client); -MeetingPage *meeting_page_new (EMeetingStore *ems, - ECal *client); -ECalComponent *meeting_page_get_cancel_comp (MeetingPage *mpage); - - - -G_END_DECLS - -#endif diff --git a/calendar/gui/dialogs/new-calendar.c b/calendar/gui/dialogs/new-calendar.c deleted file mode 100644 index 5cbbd99516..0000000000 --- a/calendar/gui/dialogs/new-calendar.c +++ /dev/null @@ -1,268 +0,0 @@ -/* Evolution calendar - New calendar dialog - * - * Copyright (C) 2003 Novell, 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 <string.h> -#include <bonobo/bonobo-i18n.h> -#include <gtk/gtkdialog.h> -#include <gtk/gtkentry.h> -#include <gtk/gtkmenu.h> -#include <gtk/gtkmenuitem.h> -#include <gtk/gtkmessagedialog.h> -#include <gtk/gtkoptionmenu.h> -#include <glade/glade.h> -#include <libedataserver/e-source-list.h> -#include <e-util/e-dialog-utils.h> -#include <e-util/e-url.h> -#include "new-calendar.h" - -static gchar * -print_uri_noproto (EUri *uri) -{ - gchar *uri_noproto; - - if (uri->port != 0) - uri_noproto = g_strdup_printf ( - "%s%s%s%s%s%s%s:%d%s%s%s", - uri->user ? uri->user : "", - uri->authmech ? ";auth=" : "", - uri->authmech ? uri->authmech : "", - uri->passwd ? ":" : "", - uri->passwd ? uri->passwd : "", - uri->user ? "@" : "", - uri->host ? uri->host : "", - uri->port, - uri->path ? uri->path : "", - uri->query ? "?" : "", - uri->query ? uri->query : ""); - else - uri_noproto = g_strdup_printf ( - "%s%s%s%s%s%s%s%s%s%s", - uri->user ? uri->user : "", - uri->authmech ? ";auth=" : "", - uri->authmech ? uri->authmech : "", - uri->passwd ? ":" : "", - uri->passwd ? uri->passwd : "", - uri->user ? "@" : "", - uri->host ? uri->host : "", - uri->path ? uri->path : "", - uri->query ? "?" : "", - uri->query ? uri->query : ""); - - return uri_noproto; -} - -static gboolean -group_is_remote (ESourceGroup *group) -{ - EUri *uri; - gboolean is_remote = FALSE; - - uri = e_uri_new (e_source_group_peek_base_uri (group)); - if (!uri) - return FALSE; - - if (uri->protocol && strcmp (uri->protocol, "file")) - is_remote = TRUE; - - e_uri_free (uri); - return is_remote; -} - -static gboolean -create_new_source_with_group (GtkWindow *parent, - ESourceGroup *group, - const char *source_name, - const char *source_location) -{ - ESource *source; - - if (e_source_group_peek_source_by_name (group, source_name)) { - e_notice (parent, GTK_MESSAGE_ERROR, - _("Source with name '%s' already exists in the selected group"), - source_name); - return FALSE; - } - - if (group_is_remote (group)) { - EUri *uri; - gchar *relative_uri; - char *cache_dir; - - /* Remote source */ - - if (!source_location || !strlen (source_location)) { - e_notice (parent, GTK_MESSAGE_ERROR, - _("The group '%s' is remote. You must specify a location " - "to get the calendar from"), - e_source_group_peek_name (group)); - return FALSE; - } - - uri = e_uri_new (source_location); - if (!uri) { - e_notice (parent, GTK_MESSAGE_ERROR, - _("The source location '%s' is not well-formed."), - source_location); - return FALSE; - } - - /* Make sure we're in agreement with the protocol. Note that EUri sets it - * to 'file' if none was specified in the input URI. We don't want to - * silently translate an explicit file:// into http:// though. */ - if (uri->protocol && - strcmp (uri->protocol, "http") && - strcmp (uri->protocol, "webcal")) { - e_uri_free (uri); - e_notice (parent, GTK_MESSAGE_ERROR, - _("The source location '%s' is not a webcal source."), - source_location); - return FALSE; - } - - /* Our relative_uri is everything but protocol, which is supplied by parent group */ - relative_uri = print_uri_noproto (uri); - e_uri_free (uri); - - /* Set up cache dir */ - cache_dir = g_build_filename (g_get_home_dir (), - "/.evolution/calendar/webcal/", - source_name, NULL); - if (e_mkdir_hier (cache_dir, 0700)) { - g_free (relative_uri); - g_free (cache_dir); - e_notice (parent, GTK_MESSAGE_ERROR, - _("Could not create cache for new calendar")); - return FALSE; - } - - /* Create source */ - source = e_source_new (source_name, relative_uri); - - g_free (relative_uri); - g_free (cache_dir); - } else { - char *new_dir; - - /* Local source */ - - new_dir = g_build_filename (e_source_group_peek_base_uri (group), - source_name, NULL); - if (e_mkdir_hier (new_dir, 0700)) { - g_free (new_dir); - e_notice (parent, GTK_MESSAGE_ERROR, - _("Could not create directory for new calendar")); - return FALSE; - } - - source = e_source_new (source_name, source_name); - g_free (new_dir); - } - - e_source_group_add_source (group, source, -1); - return TRUE; -} - -/** - * new_calendar_dialog - * - * Displays a dialog that allows the user to create a new calendar. - */ -gboolean -new_calendar_dialog (GtkWindow *parent) -{ - GtkWidget *dialog, *cal_group, *cal_name, *cal_location; - GladeXML *xml; - ESourceList *source_list; - GConfClient *gconf_client; - GSList *groups, *sl; - gboolean result = FALSE, retry = TRUE; - - /* load the Glade file */ - xml = glade_xml_new (EVOLUTION_GLADEDIR "/new-calendar.glade", "new-calendar-dialog", NULL); - if (!xml) { - g_warning (G_STRLOC ": cannot load Glade file"); - return FALSE; - } - - dialog = glade_xml_get_widget (xml, "new-calendar-dialog"); - cal_group = glade_xml_get_widget (xml, "calendar-group"); - cal_name = glade_xml_get_widget (xml, "calendar-name"); - cal_location = glade_xml_get_widget (xml, "calendar-location"); - - /* set up widgets */ - gconf_client = gconf_client_get_default (); - source_list = e_source_list_new_for_gconf (gconf_client, "/apps/evolution/calendar/sources"); - - groups = e_source_list_peek_groups (source_list); - for (sl = groups; sl != NULL; sl = sl->next) { - GtkWidget *menu_item, *menu; - ESourceGroup *group = sl->data; - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (cal_group)); - if (!GTK_IS_MENU (menu)) { - menu = gtk_menu_new (); - gtk_option_menu_set_menu (GTK_OPTION_MENU (cal_group), menu); - gtk_widget_show (menu); - } - - menu_item = gtk_menu_item_new_with_label (e_source_group_peek_name (group)); - gtk_widget_show (menu_item); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); - } - - if (groups) - gtk_option_menu_set_history (GTK_OPTION_MENU (cal_group), 0); - - /* run the dialog */ - do { - if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) { - const char *name; - const char *location; - - name = gtk_entry_get_text (GTK_ENTRY (cal_name)); - location = gtk_entry_get_text (GTK_ENTRY (cal_location)); - sl = g_slist_nth (groups, gtk_option_menu_get_history (GTK_OPTION_MENU (cal_group))); - if (sl) { - if (create_new_source_with_group (GTK_WINDOW (dialog), - sl->data, - name, - location)) - retry = FALSE; - } else { - e_notice (dialog, GTK_MESSAGE_ERROR, - _("A group must be selected")); - continue; - } - } else - retry = FALSE; /* user pressed Cancel */ - } while (retry); - - /* free memory */ - g_object_unref (gconf_client); - g_object_unref (source_list); - gtk_widget_destroy (dialog); - g_object_unref (xml); - - return result; -} diff --git a/calendar/gui/dialogs/new-calendar.glade b/calendar/gui/dialogs/new-calendar.glade deleted file mode 100644 index 0a136ed7c8..0000000000 --- a/calendar/gui/dialogs/new-calendar.glade +++ /dev/null @@ -1,239 +0,0 @@ -<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> -<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> - -<glade-interface> - -<widget class="GtkDialog" id="new-calendar-dialog"> - <property name="border_width">12</property> - <property name="visible">True</property> - <property name="title" translatable="yes">Add New Calendar</property> - <property name="type">GTK_WINDOW_TOPLEVEL</property> - <property name="window_position">GTK_WIN_POS_CENTER</property> - <property name="modal">False</property> - <property name="resizable">False</property> - <property name="destroy_with_parent">False</property> - <property name="has_separator">True</property> - - <child internal-child="vbox"> - <widget class="GtkVBox" id="dialog-vbox1"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">0</property> - - <child internal-child="action_area"> - <widget class="GtkHButtonBox" id="dialog-action_area1"> - <property name="visible">True</property> - <property name="layout_style">GTK_BUTTONBOX_END</property> - - <child> - <widget class="GtkButton" id="cancelbutton1"> - <property name="visible">True</property> - <property name="can_default">True</property> - <property name="can_focus">True</property> - <property name="label">gtk-cancel</property> - <property name="use_stock">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="response_id">-6</property> - </widget> - </child> - - <child> - <widget class="GtkButton" id="okbutton1"> - <property name="visible">True</property> - <property name="can_default">True</property> - <property name="can_focus">True</property> - <property name="label">gtk-ok</property> - <property name="use_stock">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="response_id">-5</property> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="pack_type">GTK_PACK_END</property> - </packing> - </child> - - <child> - <widget class="GtkTable" id="table1"> - <property name="visible">True</property> - <property name="n_rows">4</property> - <property name="n_columns">3</property> - <property name="homogeneous">False</property> - <property name="row_spacing">6</property> - <property name="column_spacing">6</property> - - <child> - <widget class="GtkLabel" id="label2"> - <property name="visible">True</property> - <property name="label" translatable="yes">Calendar Group</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_padding">6</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkOptionMenu" id="calendar-group"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="history">-1</property> - </widget> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_padding">6</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkEntry" id="calendar-name"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="editable">True</property> - <property name="visibility">True</property> - <property name="max_length">0</property> - <property name="text" translatable="yes"></property> - <property name="has_frame">True</property> - <property name="invisible_char" translatable="yes">*</property> - <property name="activates_default">False</property> - </widget> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_padding">6</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label1"> - <property name="visible">True</property> - <property name="label" translatable="yes"><b>Calendar options</b></property> - <property name="use_underline">False</property> - <property name="use_markup">True</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">3</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="y_padding">6</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label3"> - <property name="visible">True</property> - <property name="label" translatable="yes">Calendar Name</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_padding">6</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="calendar-source-label"> - <property name="visible">True</property> - <property name="label" translatable="yes">Calendar Location</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">3</property> - <property name="bottom_attach">4</property> - <property name="x_padding">6</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkEntry" id="calendar-location"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="editable">True</property> - <property name="visibility">True</property> - <property name="max_length">0</property> - <property name="text" translatable="yes"></property> - <property name="has_frame">True</property> - <property name="invisible_char" translatable="yes">*</property> - <property name="activates_default">False</property> - </widget> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - <property name="top_attach">3</property> - <property name="bottom_attach">4</property> - <property name="x_padding">6</property> - <property name="y_options"></property> - </packing> - </child> - </widget> - <packing> - <property name="padding">4</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - </child> -</widget> - -</glade-interface> diff --git a/calendar/gui/dialogs/new-calendar.h b/calendar/gui/dialogs/new-calendar.h deleted file mode 100644 index 86c819796e..0000000000 --- a/calendar/gui/dialogs/new-calendar.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Evolution calendar - New calendar dialog - * - * Copyright (C) 2003 Novell, 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 NEW_CALENDAR_H -#define NEW_CALENDAR_H - -#include <gtk/gtkwindow.h> - -gboolean new_calendar_dialog (GtkWindow *parent); - -#endif diff --git a/calendar/gui/dialogs/new-task-list.c b/calendar/gui/dialogs/new-task-list.c deleted file mode 100644 index e77d35d4ad..0000000000 --- a/calendar/gui/dialogs/new-task-list.c +++ /dev/null @@ -1,145 +0,0 @@ -/* Evolution calendar - New task list dialog - * - * Copyright (C) 2003 Novell, 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 <bonobo/bonobo-i18n.h> -#include <gtk/gtkentry.h> -#include <gtk/gtkmenu.h> -#include <gtk/gtkmenuitem.h> -#include <gtk/gtkmessagedialog.h> -#include <gtk/gtkoptionmenu.h> -#include <glade/glade.h> -#include <e-util/e-dialog-utils.h> -#include <libedataserver/e-source-list.h> -#include "new-task-list.h" - -static gboolean -create_new_source_with_group (GtkWindow *parent, - ESourceGroup *group, - const char *source_name) -{ - ESource *source; - char *new_dir; - - if (e_source_group_peek_source_by_name (group, source_name)) { - e_notice (parent, GTK_MESSAGE_ERROR, - _("Source with name '%s' already exists in the selected group"), - source_name); - return FALSE; - } - - new_dir = g_build_filename (e_source_group_peek_base_uri (group), - source_name, NULL); - if (e_mkdir_hier (new_dir, 0700)) { - g_free (new_dir); - e_notice (parent, GTK_MESSAGE_ERROR, - _("Could not create directory for new task list")); - return FALSE; - } - - source = e_source_new (source_name, source_name); - g_free (new_dir); - - e_source_group_add_source (group, source, -1); - return TRUE; -} - -/** - * new_task_list_dialog - * - * Displays a dialog that allows the user to create a new task list. - */ -gboolean -new_task_list_dialog (GtkWindow *parent) -{ - GtkWidget *dialog, *task_group, *task_name; - GladeXML *xml; - ESourceList *source_list; - GConfClient *gconf_client; - GSList *groups, *sl; - gboolean result = FALSE, retry = TRUE; - - /* load the Glade file */ - xml = glade_xml_new (EVOLUTION_GLADEDIR "/new-task-list.glade", "new-task-list-dialog", NULL); - if (!xml) { - g_warning (G_STRLOC ": cannot load Glade file"); - return FALSE; - } - - dialog = glade_xml_get_widget (xml, "new-task-list-dialog"); - task_group = glade_xml_get_widget (xml, "task-list-group"); - task_name = glade_xml_get_widget (xml, "task-list-name"); - - /* set up widgets */ - gconf_client = gconf_client_get_default (); - source_list = e_source_list_new_for_gconf (gconf_client, "/apps/evolution/tasks/sources"); - - groups = e_source_list_peek_groups (source_list); - for (sl = groups; sl != NULL; sl = sl->next) { - GtkWidget *menu_item, *menu; - ESourceGroup *group = sl->data; - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (task_group)); - if (!GTK_IS_MENU (menu)) { - menu = gtk_menu_new (); - gtk_option_menu_set_menu (GTK_OPTION_MENU (task_group), menu); - gtk_widget_show (menu); - } - - menu_item = gtk_menu_item_new_with_label (e_source_group_peek_name (group)); - gtk_widget_show (menu_item); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); - } - - if (groups) - gtk_option_menu_set_history (GTK_OPTION_MENU (task_group), 0); - - /* run the dialog */ - do { - if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) { - const char *name; - - name = gtk_entry_get_text (GTK_ENTRY (task_name)); - sl = g_slist_nth (groups, gtk_option_menu_get_history (GTK_OPTION_MENU (task_group))); - if (sl) { - if (create_new_source_with_group (GTK_WINDOW (dialog), - sl->data, - name)) - retry = FALSE; - } else { - e_notice (dialog, GTK_MESSAGE_ERROR, - _("A group must be selected")); - continue; - } - } else - retry = FALSE; /* user pressed Cancel */ - } while (retry); - - /* free memory */ - g_object_unref (gconf_client); - g_object_unref (source_list); - gtk_widget_destroy (dialog); - g_object_unref (xml); - - return result; -} diff --git a/calendar/gui/dialogs/new-task-list.glade b/calendar/gui/dialogs/new-task-list.glade deleted file mode 100644 index ffc38582c8..0000000000 --- a/calendar/gui/dialogs/new-task-list.glade +++ /dev/null @@ -1,193 +0,0 @@ -<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> -<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> - -<glade-interface> -<requires lib="gnome"/> - -<widget class="GtkDialog" id="new-task-list-dialog"> - <property name="border_width">12</property> - <property name="visible">True</property> - <property name="title" translatable="yes">Add New Task List</property> - <property name="type">GTK_WINDOW_TOPLEVEL</property> - <property name="window_position">GTK_WIN_POS_CENTER</property> - <property name="modal">False</property> - <property name="resizable">False</property> - <property name="destroy_with_parent">False</property> - <property name="has_separator">True</property> - - <child internal-child="vbox"> - <widget class="GtkVBox" id="dialog-vbox1"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">0</property> - - <child internal-child="action_area"> - <widget class="GtkHButtonBox" id="dialog-action_area1"> - <property name="visible">True</property> - <property name="layout_style">GTK_BUTTONBOX_END</property> - - <child> - <widget class="GtkButton" id="cancelbutton1"> - <property name="visible">True</property> - <property name="can_default">True</property> - <property name="can_focus">True</property> - <property name="label">gtk-cancel</property> - <property name="use_stock">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="response_id">-6</property> - </widget> - </child> - - <child> - <widget class="GtkButton" id="okbutton1"> - <property name="visible">True</property> - <property name="can_default">True</property> - <property name="can_focus">True</property> - <property name="label">gtk-ok</property> - <property name="use_stock">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="response_id">-5</property> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="pack_type">GTK_PACK_END</property> - </packing> - </child> - - <child> - <widget class="GtkTable" id="table1"> - <property name="visible">True</property> - <property name="n_rows">3</property> - <property name="n_columns">3</property> - <property name="homogeneous">False</property> - <property name="row_spacing">6</property> - <property name="column_spacing">6</property> - - <child> - <widget class="GtkLabel" id="label2"> - <property name="visible">True</property> - <property name="label" translatable="yes">Task List Group</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_padding">6</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkOptionMenu" id="task-list-group"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="history">-1</property> - </widget> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_padding">6</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkEntry" id="task-list-name"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="editable">True</property> - <property name="visibility">True</property> - <property name="max_length">0</property> - <property name="text" translatable="yes"></property> - <property name="has_frame">True</property> - <property name="invisible_char" translatable="yes">*</property> - <property name="activates_default">False</property> - </widget> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_padding">6</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label1"> - <property name="visible">True</property> - <property name="label" translatable="yes"><b>Task List Options</b></property> - <property name="use_underline">False</property> - <property name="use_markup">True</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">3</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="y_padding">6</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label3"> - <property name="visible">True</property> - <property name="label" translatable="yes">Task List Name</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_padding">6</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - </widget> - <packing> - <property name="padding">4</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - </child> -</widget> - -</glade-interface> diff --git a/calendar/gui/dialogs/new-task-list.h b/calendar/gui/dialogs/new-task-list.h deleted file mode 100644 index 3f529f39ad..0000000000 --- a/calendar/gui/dialogs/new-task-list.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Evolution calendar - New task list dialog - * - * Copyright (C) 2003 Novell, 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 NEW_TASK_LIST_H -#define NEW_TASK_LIST_H - -#include <gtk/gtkwindow.h> - -gboolean new_task_list_dialog (GtkWindow *parent); - -#endif diff --git a/calendar/gui/dialogs/recur-comp.c b/calendar/gui/dialogs/recur-comp.c deleted file mode 100644 index f097d542f7..0000000000 --- a/calendar/gui/dialogs/recur-comp.c +++ /dev/null @@ -1,106 +0,0 @@ -/* Evolution calendar - Recurring calendar component dialog - * - * Copyright (C) 2002 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 <gtk/gtk.h> -#include <libgnome/gnome-i18n.h> -#include <libgnomeui/gnome-uidefs.h> -#include "recur-comp.h" - - - -gboolean -recur_component_dialog (ECal *client, - ECalComponent *comp, - CalObjModType *mod, - GtkWindow *parent) -{ - char *str; - GtkWidget *dialog, *rb_this, *rb_prior, *rb_future, *rb_all, *hbox; - ECalComponentVType vtype; - gboolean ret; - - g_return_val_if_fail (E_IS_CAL_COMPONENT (comp), CALOBJ_MOD_THIS); - - vtype = e_cal_component_get_vtype (comp); - - switch (vtype) { - case E_CAL_COMPONENT_EVENT: - str = g_strdup_printf (_("You are modifying a recurring event, what would you like to modify?")); - break; - - case E_CAL_COMPONENT_TODO: - str = g_strdup_printf (_("You are modifying a recurring task, what would you like to modify?")); - break; - - case E_CAL_COMPONENT_JOURNAL: - str = g_strdup_printf (_("You are modifying a recurring journal entry, what would you like to modify?")); - break; - - default: - g_message ("recur_component_dialog(): Cannot handle object of type %d", vtype); - return CALOBJ_MOD_THIS; - } - - - dialog = gtk_message_dialog_new (parent, 0, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL, "%s", str); - g_free (str); - - hbox = gtk_hbox_new (FALSE, 2); - gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox); - rb_this = gtk_radio_button_new_with_label (NULL, _("This Instance Only")); - gtk_container_add (GTK_CONTAINER (hbox), rb_this); - - if (!e_cal_get_static_capability (client, CAL_STATIC_CAPABILITY_NO_THISANDPRIOR)) { - rb_prior = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (rb_this), _("This and Prior Instances")); - gtk_container_add (GTK_CONTAINER (hbox), rb_prior); - } else - rb_prior = NULL; - - if (!e_cal_get_static_capability (client, CAL_STATIC_CAPABILITY_NO_THISANDFUTURE)) { - rb_future = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (rb_this), _("This and Future Instances")); - gtk_container_add (GTK_CONTAINER (hbox), rb_future); - } else - rb_future = NULL; - - rb_all = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (rb_this), _("All Instances")); - gtk_container_add (GTK_CONTAINER (hbox), rb_all); - - gtk_widget_show_all (hbox); - - ret = gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK; - - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rb_this))) - *mod = CALOBJ_MOD_THIS; - else if (rb_prior && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rb_prior))) - *mod = CALOBJ_MOD_THISANDPRIOR; - else if (rb_future && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rb_future))) - *mod = CALOBJ_MOD_THISANDFUTURE; - else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rb_all))) - *mod = CALOBJ_MOD_ALL; - - gtk_widget_destroy (dialog); - - return ret; -} diff --git a/calendar/gui/dialogs/recur-comp.h b/calendar/gui/dialogs/recur-comp.h deleted file mode 100644 index 94ccbdae87..0000000000 --- a/calendar/gui/dialogs/recur-comp.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Evolution calendar - Recurring calendar component dialog - * - * Copyright (C) 2002 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 RECUR_COMP_H -#define RECUR_COMP_H - -#include <gtk/gtkwindow.h> -#include <libecal/e-cal.h> -#include <libecal/e-cal-component.h> -#include <libecal/e-cal-util.h> - -gboolean recur_component_dialog (ECal *client, - ECalComponent *comp, - CalObjModType *mod, - GtkWindow *parent); - -#endif diff --git a/calendar/gui/dialogs/recurrence-page.c b/calendar/gui/dialogs/recurrence-page.c deleted file mode 100644 index cdc820e6d6..0000000000 --- a/calendar/gui/dialogs/recurrence-page.c +++ /dev/null @@ -1,2411 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* Evolution calendar - Recurrence page of the calendar component dialogs - * - * Copyright (C) 2001-2003 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> - * Hans Petter Jansson <hpj@ximiman.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/gtklabel.h> -#include <gtk/gtkcellrenderertext.h> -#include <gtk/gtkmenuitem.h> -#include <gtk/gtkoptionmenu.h> -#include <gtk/gtktogglebutton.h> -#include <gtk/gtksignal.h> -#include <gtk/gtkspinbutton.h> -#include <gtk/gtktreeview.h> -#include <gtk/gtktreeselection.h> -#include <libgnome/gnome-i18n.h> -#include <glade/glade.h> -#include <e-util/e-dialog-widgets.h> -#include <e-util/e-time-utils.h> -#include <widgets/misc/e-dateedit.h> -#include <libecal/e-cal-recur.h> -#include <libecal/e-cal-time-util.h> -#include "../calendar-config.h" -#include "../tag-calendar.h" -#include "../weekday-picker.h" -#include "comp-editor-util.h" -#include "../e-date-time-list.h" -#include "../e-mini-calendar-config.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 -}; - -/* Private part of the RecurrencePage structure */ -struct _RecurrencePagePrivate { - /* Component we use to expand the recurrence rules for the preview */ - ECalComponent *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; /* This is a GtkTreeView now */ - GtkWidget *exception_add; - GtkWidget *exception_modify; - GtkWidget *exception_delete; - - GtkWidget *preview_bin; - - /* Store for exception_list */ - EDateTimeList *exception_list_store; - - /* For the recurrence preview, the actual widget */ - GtkWidget *preview_calendar; - EMiniCalendarConfig *preview_calendar_config; - - gboolean updating; -}; - - - -static void recurrence_page_class_init (RecurrencePageClass *class); -static void recurrence_page_init (RecurrencePage *rpage); -static void recurrence_page_finalize (GObject *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, ECalComponent *comp); -static gboolean recurrence_page_fill_component (CompEditorPage *page, ECalComponent *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. - **/ - -E_MAKE_TYPE (recurrence_page, "RecurrencePage", RecurrencePage, recurrence_page_class_init, - recurrence_page_init, TYPE_COMP_EDITOR_PAGE); - -/* Class initialization function for the recurrence page */ -static void -recurrence_page_class_init (RecurrencePageClass *class) -{ - CompEditorPageClass *editor_page_class; - GObjectClass *object_class; - - editor_page_class = (CompEditorPageClass *) class; - object_class = (GObjectClass *) class; - - parent_class = g_type_class_ref(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->finalize = recurrence_page_finalize; -} - -/* 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; -} - -/* Destroy handler for the recurrence page */ -static void -recurrence_page_finalize (GObject *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->main) - gtk_widget_unref (priv->main); - - if (priv->xml) { - g_object_unref (priv->xml); - priv->xml = NULL; - } - - if (priv->comp) { - g_object_unref (priv->comp); - priv->comp = NULL; - } - - if (priv->exception_list_store) { - g_object_unref (priv->exception_list_store); - priv->exception_list_store = NULL; - } - - if (priv->preview_calendar_config) { - g_object_unref (priv->preview_calendar_config); - priv->preview_calendar_config = NULL; - } - - g_free (priv); - rpage->priv = NULL; - - if (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (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; - - g_signal_handlers_block_matched (priv->none, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, rpage); - g_signal_handlers_block_matched (priv->simple, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, rpage); - g_signal_handlers_block_matched (priv->custom, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, rpage); - e_dialog_radio_set (priv->none, RECUR_NONE, type_map); - g_signal_handlers_unblock_matched (priv->none, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, rpage); - g_signal_handlers_unblock_matched (priv->simple, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, rpage); - g_signal_handlers_unblock_matched (priv->custom, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, rpage); - - adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->interval_value)); - g_signal_handlers_block_matched (adj, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, rpage); - e_dialog_spin_set (priv->interval_value, 1); - g_signal_handlers_unblock_matched (adj, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, rpage); - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->interval_unit)); - g_signal_handlers_block_matched (menu, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, rpage); - e_dialog_option_menu_set (priv->interval_unit, - ICAL_DAILY_RECURRENCE, - freq_map); - g_signal_handlers_unblock_matched (menu, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, rpage); - - priv->ending_date_tt = icaltime_today (); - priv->ending_count = 1; - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->ending_menu)); - g_signal_handlers_block_matched (menu, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, rpage); - e_dialog_option_menu_set (priv->ending_menu, - ENDING_FOREVER, - ending_types_map); - g_signal_handlers_unblock_matched (menu, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, rpage); - - /* Exceptions list */ - e_date_time_list_clear (priv->exception_list_store); -} - -/* Appends an exception date to the list */ -static void -append_exception (RecurrencePage *rpage, ECalComponentDateTime *datetime) -{ - RecurrencePagePrivate *priv; - GtkTreeView *view; - GtkTreeIter iter; - - priv = rpage->priv; - view = GTK_TREE_VIEW (priv->exception_list); - - e_date_time_list_append (priv->exception_list_store, &iter, datetime); - gtk_tree_selection_select_iter (gtk_tree_view_get_selection (view), &iter); -} - -/* Fills in the exception widgets with the data from the calendar component */ -static void -fill_exception_widgets (RecurrencePage *rpage, ECalComponent *comp) -{ - RecurrencePagePrivate *priv; - GSList *list, *l; - gboolean added = FALSE; - - priv = rpage->priv; - e_cal_component_get_exdate_list (comp, &list); - - for (l = list; l; l = l->next) { - ECalComponentDateTime *cdt; - - added = TRUE; - - cdt = l->data; - append_exception (rpage, cdt); - } - - e_cal_component_free_exdate_list (list); -} - -/* Computes a weekday mask for the start day of a calendar component, - * for use in a WeekdayPicker widget. - */ -static guint8 -get_start_weekday_mask (ECalComponent *comp) -{ - ECalComponentDateTime dt; - guint8 retval; - - e_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; - - e_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); - - /* We can't preview that well for instances right now */ - if (e_cal_component_is_instance (priv->comp)) - gtk_widget_set_sensitive (priv->preview_calendar, FALSE); - else - gtk_widget_set_sensitive (priv->preview_calendar, TRUE); - - 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, ECalComponent *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; - else - month_num++; - - 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; - - e_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 gboolean -fill_component (RecurrencePage *rpage, ECalComponent *comp) -{ - RecurrencePagePrivate *priv; - enum recur_type recur_type; - GtkTreeModel *model; - GtkTreeIter iter; - gboolean valid_iter; - GSList *list; - - priv = rpage->priv; - model = GTK_TREE_MODEL (priv->exception_list_store); - - recur_type = e_dialog_radio_get (priv->none, type_map); - - switch (recur_type) { - case RECUR_NONE: - e_cal_component_set_rdate_list (comp, NULL); - e_cal_component_set_rrule_list (comp, NULL); - e_cal_component_set_exrule_list (comp, NULL); - break; - - case RECUR_SIMPLE: - e_cal_component_set_rdate_list (comp, NULL); - e_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; - - for (valid_iter = gtk_tree_model_get_iter_first (model, &iter); valid_iter; - valid_iter = gtk_tree_model_iter_next (model, &iter)) { - const ECalComponentDateTime *dt; - ECalComponentDateTime *cdt; - - cdt = g_new (ECalComponentDateTime, 1); - cdt->value = g_new (struct icaltimetype, 1); - - dt = e_date_time_list_get_date_time (E_DATE_TIME_LIST (model), &iter); - g_assert (dt != NULL); - - if (!icaltime_is_valid_time (*dt->value)) { - comp_editor_page_display_validation_error (COMP_EDITOR_PAGE (rpage), - _("Recurrence date is invalid"), - priv->exception_list); - return FALSE; - } - - *cdt->value = *dt->value; - cdt->tzid = g_strdup (dt->tzid); - - list = g_slist_prepend (list, cdt); - } - - e_cal_component_set_exdate_list (comp, list); - e_cal_component_free_exdate_list (list); - - return TRUE; -} - -/* 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; - ECalComponent *comp; - ECalComponentDateTime cdt; - GSList *l; - icaltimezone *zone = NULL; - - priv = rpage->priv; - - /* If our component has not been set yet through ::fill_widgets(), we - * cannot preview the recurrence. - */ - if (!priv->comp || e_cal_component_is_instance (priv->comp)) - return; - - /* Create a scratch component with the start/end and - * recurrence/exception information from the one we are editing. - */ - - comp = e_cal_component_new (); - e_cal_component_set_new_vtype (comp, E_CAL_COMPONENT_EVENT); - - e_cal_component_get_dtstart (priv->comp, &cdt); - if (cdt.tzid != NULL) { - /* FIXME Will e_cal_get_timezone really not return builtin zones? */ - if (!e_cal_get_timezone (COMP_EDITOR_PAGE (rpage)->client, cdt.tzid, &zone, NULL)) - zone = icaltimezone_get_builtin_timezone_from_tzid (cdt.tzid); - } - e_cal_component_set_dtstart (comp, &cdt); - e_cal_component_free_datetime (&cdt); - - e_cal_component_get_dtend (priv->comp, &cdt); - e_cal_component_set_dtend (comp, &cdt); - e_cal_component_free_datetime (&cdt); - - e_cal_component_get_exdate_list (priv->comp, &l); - e_cal_component_set_exdate_list (comp, l); - e_cal_component_free_exdate_list (l); - - e_cal_component_get_exrule_list (priv->comp, &l); - e_cal_component_set_exrule_list (comp, l); - e_cal_component_free_recur_list (l); - - e_cal_component_get_rdate_list (priv->comp, &l); - e_cal_component_set_rdate_list (comp, l); - e_cal_component_free_period_list (l); - - e_cal_component_get_rrule_list (priv->comp, &l); - e_cal_component_set_rrule_list (comp, l); - e_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, zone, TRUE, FALSE); - g_object_unref(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, 6); - - wp = WEEKDAY_PICKER (weekday_picker_new ()); - - priv->weekday_picker = GTK_WIDGET (wp); - gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (wp), FALSE, FALSE, 6); - - 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); - - g_signal_connect((wp), "changed", - G_CALLBACK (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_get_submenu (GTK_MENU_ITEM (item)))); - - 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++) { - item = gtk_menu_item_new_with_label (_(e_cal_recur_nth[i])); - gtk_menu_shell_append(GTK_MENU_SHELL(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; - 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_shell_append(GTK_MENU_SHELL(menu), item); - gtk_widget_show (item); - } - - /* Current date */ - item = gtk_menu_item_new_with_label (_(e_cal_recur_nth[month_index - 1])); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); - gtk_widget_show (item); - - /* Other Submenu */ - submenu = gtk_menu_new (); - submenu_item = gtk_menu_item_new_with_label (_("Other Date")); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), submenu_item); - gtk_widget_show (submenu_item); - - item = make_recur_month_num_submenu ("1st to 10th", 0, 10); - gtk_menu_shell_append(GTK_MENU_SHELL(submenu), item); - item = make_recur_month_num_submenu ("11th to 20th", 10, 20); - gtk_menu_shell_append(GTK_MENU_SHELL(submenu), item); - item = make_recur_month_num_submenu ("21st to 31st", 20, 31); - gtk_menu_shell_append(GTK_MENU_SHELL(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)); - g_signal_connect((submenu), "selection_done", - G_CALLBACK (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_shell_append(GTK_MENU_SHELL(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; - - 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; - gtk_label_set_text (GTK_LABEL (label), _(e_cal_recur_nth[priv->month_index - 1])); - - 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, 6); - - 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, 6); - - priv->month_day_menu = make_recur_month_menu (); - gtk_box_pack_start (GTK_BOX (hbox), priv->month_day_menu, - FALSE, FALSE, 6); - - 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); - - g_signal_connect((adj), "value_changed", G_CALLBACK (month_index_value_changed_cb), - rpage); - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->month_num_menu)); - g_signal_connect((menu), "selection_done", - G_CALLBACK (month_num_menu_selection_done_cb), - rpage); - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->month_day_menu)); - g_signal_connect((menu), "selection_done", - G_CALLBACK (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 (priv->month_num_menu != NULL) { - gtk_widget_destroy (priv->month_num_menu); - priv->month_num_menu = NULL; - } - if (GTK_BIN (priv->special)->child != NULL) { - gtk_widget_destroy (GTK_BIN (priv->special)->child); - - priv->weekday_picker = NULL; - priv->month_day_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); - - g_signal_connect((de), "changed", - G_CALLBACK (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_spin_button_set_numeric ((GtkSpinButton *)priv->ending_count_spin, TRUE); - gtk_box_pack_start (GTK_BOX (hbox), priv->ending_count_spin, - FALSE, FALSE, 6); - - label = gtk_label_new (_("occurrences")); - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 6); - - gtk_widget_show_all (hbox); - - /* Set the values */ - - e_dialog_spin_set (priv->ending_count_spin, priv->ending_count); - - g_signal_connect((adj), "value_changed", - G_CALLBACK (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)); - g_signal_handlers_block_matched (menu, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, 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 */ - - if (!r->until.is_date) { - ECal *client = COMP_EDITOR_PAGE (rpage)->client; - ECalComponentDateTime dt; - icaltimezone *from_zone, *to_zone; - - e_cal_component_get_dtstart (priv->comp, &dt); - - if (dt.value->is_date) - to_zone = icaltimezone_get_builtin_timezone (calendar_config_get_timezone ()); - else if (dt.tzid == NULL) - to_zone = icaltimezone_get_utc_timezone (); - else - /* FIXME Error checking? */ - e_cal_get_timezone (client, dt.tzid, &to_zone, NULL); - from_zone = icaltimezone_get_utc_timezone (); - - icaltimezone_convert_time (&r->until, from_zone, to_zone); - - r->until.hour = 0; - r->until.minute = 0; - r->until.second = 0; - r->until.is_date = TRUE; - r->until.is_utc = FALSE; - } - - 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); - } - - g_signal_handlers_unblock_matched (menu, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, 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, ECalComponent *comp) -{ - RecurrencePage *rpage; - RecurrencePagePrivate *priv; - ECalComponentText 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) - g_object_unref (priv->comp); - - priv->comp = e_cal_component_clone (comp); - - /* Don't send off changes during this time */ - priv->updating = TRUE; - - /* Clean the page */ - clear_widgets (rpage); - - /* Summary */ - e_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 (!e_cal_component_has_rdates (comp) - && !e_cal_component_has_rrules (comp) - && !e_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 */ - - e_cal_component_get_rrule_list (comp, &rrule_list); - len = g_slist_length (rrule_list); - if (len > 1 - || e_cal_component_has_rdates (comp) - || e_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)); - g_signal_handlers_block_matched (menu, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, rpage); - e_dialog_option_menu_set (priv->interval_unit, - ICAL_DAILY_RECURRENCE, - freq_map); - g_signal_handlers_unblock_matched (menu, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, 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)); - g_signal_handlers_block_matched (menu, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, rpage); - e_dialog_option_menu_set (priv->interval_unit, - ICAL_WEEKLY_RECURRENCE, - freq_map); - g_signal_handlers_unblock_matched (menu, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, 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) { - ECalComponentDateTime dt; - - e_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 - 1; - priv->month_day = month_day; - } else - goto custom; - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->interval_unit)); - g_signal_handlers_block_matched (menu, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, rpage); - e_dialog_option_menu_set (priv->interval_unit, - ICAL_MONTHLY_RECURRENCE, - freq_map); - g_signal_handlers_unblock_matched (menu, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, 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)); - g_signal_handlers_block_matched (menu, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, rpage); - e_dialog_option_menu_set (priv->interval_unit, - ICAL_YEARLY_RECURRENCE, - freq_map); - g_signal_handlers_unblock_matched (menu, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, rpage); - break; - - default: - goto custom; - } - - /* If we got here it means it is a simple recurrence */ - - g_signal_handlers_block_matched (priv->none, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, rpage); - g_signal_handlers_block_matched (priv->simple, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, rpage); - g_signal_handlers_block_matched (priv->custom, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, rpage); - e_dialog_radio_set (priv->simple, RECUR_SIMPLE, type_map); - g_signal_handlers_unblock_matched (priv->none, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, rpage); - g_signal_handlers_unblock_matched (priv->simple, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, rpage); - g_signal_handlers_unblock_matched (priv->custom, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, 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)); - g_signal_handlers_block_matched (adj, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, rpage); - e_dialog_spin_set (priv->interval_value, r->interval); - g_signal_handlers_unblock_matched (adj, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, rpage); - - fill_ending_date (rpage, r); - - goto out; - - custom: - - g_signal_handlers_block_matched (priv->none, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, rpage); - g_signal_handlers_block_matched (priv->simple, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, rpage); - g_signal_handlers_block_matched (priv->custom, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, rpage); - e_dialog_radio_set (priv->custom, RECUR_CUSTOM, type_map); - g_signal_handlers_unblock_matched (priv->none, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, rpage); - g_signal_handlers_unblock_matched (priv->simple, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, rpage); - g_signal_handlers_unblock_matched (priv->custom, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, rpage); - - gtk_widget_set_sensitive (priv->custom, TRUE); - sensitize_recur_widgets (rpage); - - out: - - e_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, ECalComponent *comp) -{ - RecurrencePage *rpage; - - rpage = RECURRENCE_PAGE (page); - return fill_component (rpage, comp); -} - -/* set_summary handler for the recurrence page */ -static void -recurrence_page_set_summary (CompEditorPage *page, const char *summary) -{ - RecurrencePage *rpage; - RecurrencePagePrivate *priv; - - rpage = RECURRENCE_PAGE (page); - priv = rpage->priv; - - gtk_label_set_text (GTK_LABEL (priv->summary), summary); -} - -/* set_dates handler for the recurrence page */ -static void -recurrence_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates) -{ - RecurrencePage *rpage; - RecurrencePagePrivate *priv; - ECalComponentDateTime 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; - e_cal_component_set_dtstart (priv->comp, &dt); - } - - if (dates->end) { - icaltime = *dates->end->value; - dt.tzid = dates->end->tzid; - e_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) { - 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 (G_OBJECT (toplevel)); - if (accel_groups) { - page->accel_group = accel_groups->data; - gtk_accel_group_ref (page->accel_group); - } - - gtk_widget_ref (priv->main); - gtk_container_remove (GTK_CONTAINER (priv->main->parent), 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"); - gtk_widget_show (priv->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; - ECalComponentDateTime 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; - GtkTreeSelection *selection; - ECalComponentDateTime dt; - struct icaltimetype icaltime = icaltime_null_time (); - struct icaltimetype *tt; - GtkTreeIter iter; - - rpage = RECURRENCE_PAGE (data); - priv = rpage->priv; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->exception_list)); - if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) { - g_warning ("Could not get a selection to modify."); - return; - } - field_changed (rpage); - - dt.value = &icaltime; - 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; - - /* No TZID, since we are using a DATE value now. */ - dt.tzid = NULL; - - e_date_time_list_set_date_time (priv->exception_list_store, &iter, &dt); - preview_recur (rpage); -} - -/* Callback for the "delete exception" button */ -static void -exception_delete_cb (GtkWidget *widget, gpointer data) -{ - RecurrencePage *rpage; - RecurrencePagePrivate *priv; - GtkTreeSelection *selection; - GtkTreeIter iter; - GtkTreePath *path; - gboolean valid_iter; - - rpage = RECURRENCE_PAGE (data); - priv = rpage->priv; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->exception_list)); - if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) { - g_warning ("Could not get a selection to delete."); - return; - } - - field_changed (rpage); - - path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->exception_list_store), &iter); - e_date_time_list_remove (priv->exception_list_store, &iter); - - /* Select closest item after removal */ - valid_iter = gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->exception_list_store), &iter, path); - if (!valid_iter) { - gtk_tree_path_prev (path); - valid_iter = gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->exception_list_store), &iter, path); - } - - if (valid_iter) - gtk_tree_selection_select_iter (selection, &iter); - - gtk_tree_path_free (path); - 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_selection_changed_cb (GtkTreeSelection *selection, gpointer data) -{ - RecurrencePage *rpage; - RecurrencePagePrivate *priv; - const ECalComponentDateTime *dt; - struct icaltimetype *t; - GtkTreeIter iter; - - rpage = RECURRENCE_PAGE (data); - priv = rpage->priv; - - if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) { - gtk_widget_set_sensitive (priv->exception_modify, FALSE); - gtk_widget_set_sensitive (priv->exception_delete, FALSE); - return; - } - - gtk_widget_set_sensitive (priv->exception_modify, TRUE); - gtk_widget_set_sensitive (priv->exception_delete, TRUE); - - dt = e_date_time_list_get_date_time (priv->exception_list_store, &iter); - 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; - GtkTreeViewColumn *column; - GtkCellRenderer *cell_renderer; - - priv = rpage->priv; - - /* Recurrence preview */ - - priv->preview_calendar = e_calendar_new (); - ecal = E_CALENDAR (priv->preview_calendar); - priv->preview_calendar_config = e_mini_calendar_config_new (ecal); - g_signal_connect((ecal->calitem), "date_range_changed", - G_CALLBACK (preview_date_range_changed_cb), - rpage); - 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 */ - - g_signal_connect((priv->none), "toggled", - G_CALLBACK (type_toggled_cb), rpage); - g_signal_connect((priv->simple), "toggled", - G_CALLBACK (type_toggled_cb), rpage); - g_signal_connect((priv->custom), "toggled", - G_CALLBACK (type_toggled_cb), rpage); - - /* Recurrence interval */ - - adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->interval_value)); - g_signal_connect((adj), "value_changed", - G_CALLBACK (interval_value_changed_cb), - rpage); - - /* Recurrence units */ - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->interval_unit)); - g_signal_connect((menu), "selection_done", - G_CALLBACK (interval_selection_done_cb), - rpage); - - /* Recurrence ending */ - - menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->ending_menu)); - g_signal_connect((menu), "selection_done", - G_CALLBACK (ending_selection_done_cb), rpage); - - /* Exception buttons */ - - g_signal_connect((priv->exception_add), "clicked", - G_CALLBACK (exception_add_cb), rpage); - g_signal_connect((priv->exception_modify), "clicked", - G_CALLBACK (exception_modify_cb), rpage); - g_signal_connect((priv->exception_delete), "clicked", - G_CALLBACK (exception_delete_cb), rpage); - - gtk_widget_set_sensitive (priv->exception_modify, FALSE); - gtk_widget_set_sensitive (priv->exception_delete, FALSE); - - /* Exception list */ - - /* Model */ - priv->exception_list_store = e_date_time_list_new (); - gtk_tree_view_set_model (GTK_TREE_VIEW (priv->exception_list), - GTK_TREE_MODEL (priv->exception_list_store)); - - /* View */ - column = gtk_tree_view_column_new (); - gtk_tree_view_column_set_title (column, _("Date/Time")); - cell_renderer = GTK_CELL_RENDERER (gtk_cell_renderer_text_new ()); - gtk_tree_view_column_pack_start (column, cell_renderer, TRUE); - gtk_tree_view_column_add_attribute (column, cell_renderer, "text", E_DATE_TIME_LIST_COLUMN_DESCRIPTION); - gtk_tree_view_append_column (GTK_TREE_VIEW (priv->exception_list), column); - - g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->exception_list)), "changed", - G_CALLBACK (exception_selection_changed_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, 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 = g_object_new (TYPE_RECURRENCE_PAGE, NULL); - if (!recurrence_page_construct (rpage)) { - g_object_unref (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 c5c2158979..0000000000 --- a/calendar/gui/dialogs/recurrence-page.glade +++ /dev/null @@ -1,724 +0,0 @@ -<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> -<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> - -<glade-interface> - -<widget class="GtkWindow" id="recurrence-toplevel"> - <property name="title" translatable="yes">window1</property> - <property name="type">GTK_WINDOW_TOPLEVEL</property> - <property name="window_position">GTK_WIN_POS_NONE</property> - <property name="modal">False</property> - <property name="resizable">True</property> - <property name="destroy_with_parent">False</property> - - <child> - <widget class="GtkVBox" id="recurrence-page"> - <property name="border_width">12</property> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkFrame" id="frame35"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <property name="label_yalign">0.5</property> - <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property> - - <child> - <widget class="GtkTable" id="table14"> - <property name="border_width">6</property> - <property name="visible">True</property> - <property name="n_rows">2</property> - <property name="n_columns">2</property> - <property name="homogeneous">False</property> - <property name="row_spacing">6</property> - <property name="column_spacing">6</property> - - <child> - <widget class="GtkLabel" id="label66"> - <property name="visible">True</property> - <property name="label" translatable="yes">Summary:</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label67"> - <property name="visible">True</property> - <property name="label" translatable="yes">Date/Time:</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="summary"> - <property name="visible">True</property> - <property name="label" translatable="yes"></property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">4</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="date-time"> - <property name="visible">True</property> - <property name="label" translatable="yes"></property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">4</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="y_options"></property> - </packing> - </child> - </widget> - </child> - - <child> - <widget class="GtkLabel" id="label1"> - <property name="visible">True</property> - <property name="label" translatable="yes">Basics</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkVBox" id="vbox55"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">0</property> - - <child> - <widget class="GtkFrame" id="frame36"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <property name="label_yalign">0.5</property> - <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property> - - <child> - <widget class="GtkVBox" id="vbox56"> - <property name="border_width">6</property> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkHBox" id="hbox56"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkRadioButton" id="none"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">_No recurrence</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkRadioButton" id="simple"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">_Simple recurrence</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - <property name="group">none</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkRadioButton" id="custom"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">_Custom recurrence</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - <property name="group">none</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkHBox" id="hbox57"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkHBox" id="params"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">2</property> - - <child> - <widget class="GtkLabel" id="label68"> - <property name="visible">True</property> - <property name="label" translatable="yes">Every</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkSpinButton" id="interval-value"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="climb_rate">1</property> - <property name="digits">0</property> - <property name="numeric">True</property> - <property name="update_policy">GTK_UPDATE_ALWAYS</property> - <property name="snap_to_ticks">False</property> - <property name="wrap">False</property> - <property name="adjustment">1 1 10000 1 10 10</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkOptionMenu" id="interval-unit"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="history">0</property> - - <child internal-child="menu"> - <widget class="GtkMenu" id="convertwidget1"> - <property name="visible">True</property> - - <child> - <widget class="GtkMenuItem" id="convertwidget2"> - <property name="visible">True</property> - <property name="label" translatable="yes">day(s)</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget3"> - <property name="visible">True</property> - <property name="label" translatable="yes">week(s)</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget4"> - <property name="visible">True</property> - <property name="label" translatable="yes">month(s)</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget5"> - <property name="visible">True</property> - <property name="label" translatable="yes">year(s)</property> - <property name="use_underline">True</property> - </widget> - </child> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkAlignment" id="special"> - <property name="visible">True</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xscale">0</property> - <property name="yscale">0</property> - - <child> - <placeholder/> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkOptionMenu" id="ending-menu"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="history">0</property> - - <child internal-child="menu"> - <widget class="GtkMenu" id="convertwidget6"> - <property name="visible">True</property> - - <child> - <widget class="GtkMenuItem" id="convertwidget7"> - <property name="visible">True</property> - <property name="label" translatable="yes">for</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget8"> - <property name="visible">True</property> - <property name="label" translatable="yes">until</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget9"> - <property name="visible">True</property> - <property name="label" translatable="yes">forever</property> - <property name="use_underline">True</property> - </widget> - </child> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkAlignment" id="ending-special"> - <property name="visible">True</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xscale">0</property> - <property name="yscale">0</property> - - <child> - <placeholder/> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkAlignment" id="custom-warning-bin"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xscale">1</property> - <property name="yscale">1</property> - - <child> - <placeholder/> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - </child> - - <child> - <widget class="GtkLabel" id="label68"> - <property name="visible">True</property> - <property name="label" translatable="yes">Recurrence Rule</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkHBox" id="hbox59"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkFrame" id="frame37"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <property name="label_yalign">0.5</property> - <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property> - - <child> - <widget class="GtkHBox" id="hbox60"> - <property name="border_width">6</property> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkVBox" id="vbox57"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">4</property> - - <child> - <widget class="GtkButton" id="exception-add"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">A_dd</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkButton" id="exception-modify"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">_Modify</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkButton" id="exception-delete"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">_Remove</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkVBox" id="vbox58"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="Custom" id="exception-date"> - <property name="visible">True</property> - <property name="creation_function">make_exdate_date_edit</property> - <property name="int1">0</property> - <property name="int2">0</property> - <property name="last_modification_time">Tue, 16 May 2000 01:42:29 GMT</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkScrolledWindow" id="scrolledwindow14"> - <property name="visible">True</property> - <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> - <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="shadow_type">GTK_SHADOW_IN</property> - <property name="window_placement">GTK_CORNER_TOP_LEFT</property> - - <child> - <widget class="GtkTreeView" id="exception-list"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="headers_visible">True</property> - <property name="rules_hint">False</property> - <property name="reorderable">False</property> - <property name="enable_search">True</property> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - </child> - - <child> - <widget class="GtkLabel" id="label69"> - <property name="visible">True</property> - <property name="label" translatable="yes">Exceptions</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkVBox" id="vbox59"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkLabel" id="label70"> - <property name="visible">True</property> - <property name="label" translatable="yes">Preview</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkAlignment" id="preview-bin"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="yalign">0</property> - <property name="xscale">1</property> - <property name="yscale">1</property> - - <child> - <placeholder/> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - </child> -</widget> - -</glade-interface> diff --git a/calendar/gui/dialogs/recurrence-page.h b/calendar/gui/dialogs/recurrence-page.h deleted file mode 100644 index 7a10eff069..0000000000 --- a/calendar/gui/dialogs/recurrence-page.h +++ /dev/null @@ -1,62 +0,0 @@ -/* Evolution calendar - Recurrence page of the calendar component dialogs - * - * Copyright (C) 2001-2003 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> - * Hans Petter Jansson <hpj@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" - -G_BEGIN_DECLS - - - -#define TYPE_RECURRENCE_PAGE (recurrence_page_get_type ()) -#define RECURRENCE_PAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_RECURRENCE_PAGE, RecurrencePage)) -#define RECURRENCE_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_RECURRENCE_PAGE, RecurrencePageClass)) -#define IS_RECURRENCE_PAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_RECURRENCE_PAGE)) -#define IS_RECURRENCE_PAGE_CLASS(klass) (G_TYPE_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); - - - -G_END_DECLS - -#endif diff --git a/calendar/gui/dialogs/save-comp.c b/calendar/gui/dialogs/save-comp.c deleted file mode 100644 index 8041395fb1..0000000000 --- a/calendar/gui/dialogs/save-comp.c +++ /dev/null @@ -1,70 +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-i18n.h> -#include <gtk/gtkmessagedialog.h> -#include <gtk/gtkstock.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: the response_id of the button selected. - **/ - -GtkResponseType -save_component_dialog (GtkWindow *parent) -{ - GtkWidget *dialog; - gint r; - - dialog = gtk_message_dialog_new (GTK_WINDOW (parent), - GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, - _("This event has been changed, but has not been saved.\n\n" - "Do you wish to save your changes?")); - - gtk_dialog_add_buttons (GTK_DIALOG (dialog), - _("_Discard Changes"),GTK_RESPONSE_NO, - GTK_STOCK_CANCEL,GTK_RESPONSE_CANCEL, - GTK_STOCK_SAVE, GTK_RESPONSE_YES, - NULL); - - gtk_window_set_title (GTK_WINDOW (dialog), _("Save Event")); - gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES); - - r = gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - - return r; - -} diff --git a/calendar/gui/dialogs/save-comp.h b/calendar/gui/dialogs/save-comp.h deleted file mode 100644 index a9aedd2bce..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/gtkdialog.h> - -GtkResponseType 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 fc91916345..0000000000 --- a/calendar/gui/dialogs/schedule-page.c +++ /dev/null @@ -1,517 +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-i18n.h> -#include <libgnomeui/gnome-dialog-util.h> -#include <glade/glade.h> -#include <gal/widgets/e-popup-menu.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 */ - EMeetingStore *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_finalize (GObject *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, ECalComponent *comp); -static gboolean schedule_page_fill_component (CompEditorPage *page, ECalComponent *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. - **/ - -E_MAKE_TYPE (schedule_page, "SchedulePage", SchedulePage, schedule_page_class_init, - schedule_page_init, TYPE_COMP_EDITOR_PAGE); - -/* Class initialization function for the schedule page */ -static void -schedule_page_class_init (SchedulePageClass *class) -{ - CompEditorPageClass *editor_page_class; - GObjectClass *object_class; - - editor_page_class = (CompEditorPageClass *) class; - object_class = (GObjectClass *) class; - - parent_class = g_type_class_ref (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->finalize = schedule_page_finalize; -} - -/* 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_finalize (GObject *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->main) - gtk_widget_unref (priv->main); - - if (priv->xml) { - g_object_unref (priv->xml); - priv->xml = NULL; - } - - g_object_unref(priv->model); - - g_free (priv); - spage->priv = NULL; - - if (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (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, ECalComponentDateTime *start_date, ECalComponentDateTime *end_date) -{ - SchedulePagePrivate *priv; - struct icaltimetype start_tt, end_tt; - icaltimezone *start_zone = NULL, *end_zone = NULL; - 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) { - if (!e_cal_get_timezone (COMP_EDITOR_PAGE (spage)->client, - start_date->tzid, &start_zone, NULL)) { - /* FIXME: Handle error better. */ - 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) { - if (!e_cal_get_timezone (COMP_EDITOR_PAGE (spage)->client, - end_date->tzid, &end_zone, NULL)) { - /* FIXME: Handle error better. */ - g_warning ("Couldn't get timezone from server: %s", - end_date->tzid ? end_date->tzid : ""); - } - } - - start_tt = *start_date->value; - if (!end_date->value && start_tt.is_date) { - end_tt = start_tt; - icaltime_adjust (&end_tt, 1, 0, 0, 0); - } else { - 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_store_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, ECalComponent *comp) -{ - SchedulePage *spage; - SchedulePagePrivate *priv; - ECalComponentDateTime start_date, end_date; - - spage = SCHEDULE_PAGE (page); - priv = spage->priv; - - priv->updating = TRUE; - - /* Clean the screen */ - clear_widgets (spage); - - /* Start and end times */ - e_cal_component_get_dtstart (comp, &start_date); - e_cal_component_get_dtend (comp, &end_date); - update_time (spage, &start_date, &end_date); - - e_cal_component_free_datetime (&start_date); - e_cal_component_free_datetime (&end_date); - - priv->updating = FALSE; -} - -/* fill_component handler for the schedule page */ -static gboolean -schedule_page_fill_component (CompEditorPage *page, ECalComponent *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 (G_OBJECT (toplevel)); - if (accel_groups) { - page->accel_group = accel_groups->data; - gtk_accel_group_ref (page->accel_group); - } - - gtk_widget_ref (priv->main); - gtk_container_remove (GTK_CONTAINER (priv->main->parent), priv->main); - -#undef GW - - return TRUE; -} - -static gboolean -init_widgets (SchedulePage *spage) -{ - SchedulePagePrivate *priv; - - priv = spage->priv; - - g_signal_connect((priv->sel), - "changed", G_CALLBACK (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, EMeetingStore *ems) -{ - SchedulePagePrivate *priv; - - priv = spage->priv; - - priv->xml = glade_xml_new (EVOLUTION_GLADEDIR - "/schedule-page.glade", NULL, 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 */ - g_object_ref (ems); - priv->model = ems; - - /* Selector */ - priv->sel = E_MEETING_TIME_SELECTOR (e_meeting_time_selector_new (ems)); - 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, 6); - - 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 (EMeetingStore *ems) -{ - SchedulePage *spage; - - spage = g_object_new (TYPE_SCHEDULE_PAGE, NULL); - if (!schedule_page_construct (spage, ems)) { - g_object_unref (spage); - return NULL; - } - - return spage; -} - -static void -times_changed_cb (GtkWidget *widget, gpointer data) -{ - SchedulePage *spage = data; - SchedulePagePrivate *priv; - CompEditorPageDates dates; - ECalComponentDateTime 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 2ef8a1d9f5..0000000000 --- a/calendar/gui/dialogs/schedule-page.glade +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> -<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> - -<glade-interface> - -<widget class="GtkWindow" id="schedule-toplevel"> - <property name="title" translatable="yes">window1</property> - <property name="type">GTK_WINDOW_TOPLEVEL</property> - <property name="window_position">GTK_WIN_POS_NONE</property> - <property name="modal">False</property> - <property name="resizable">True</property> - <property name="destroy_with_parent">False</property> - - <child> - <widget class="GtkVBox" id="schedule-page"> - <property name="border_width">12</property> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - </widget> - </child> -</widget> - -</glade-interface> diff --git a/calendar/gui/dialogs/schedule-page.h b/calendar/gui/dialogs/schedule-page.h deleted file mode 100644 index d4c7eafbdd..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-store.h" -#include "comp-editor-page.h" - -G_BEGIN_DECLS - - - -#define TYPE_SCHEDULE_PAGE (schedule_page_get_type ()) -#define SCHEDULE_PAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_SCHEDULE_PAGE, SchedulePage)) -#define SCHEDULE_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_SCHEDULE_PAGE, SchedulePageClass)) -#define IS_SCHEDULE_PAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_SCHEDULE_PAGE)) -#define IS_SCHEDULE_PAGE_CLASS(klass) (G_TYPE_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, EMeetingStore *ems); -SchedulePage *schedule_page_new (EMeetingStore *ems); - - - -G_END_DECLS - -#endif diff --git a/calendar/gui/dialogs/send-comp.c b/calendar/gui/dialogs/send-comp.c deleted file mode 100644 index 65e4743c04..0000000000 --- a/calendar/gui/dialogs/send-comp.c +++ /dev/null @@ -1,93 +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 <gtk/gtkmessagedialog.h> -#include <libgnome/gnome-i18n.h> -#include <libgnomeui/gnome-uidefs.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 (GtkWindow *parent, ECal *client, ECalComponent *comp, gboolean new) -{ - GtkWidget *dialog; - ECalComponentVType vtype; - char *str; - gint response; - - if (e_cal_get_save_schedules (client)) - return FALSE; - - vtype = e_cal_component_get_vtype (comp); - - switch (vtype) { - case E_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 E_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 = gtk_message_dialog_new (parent, GTK_DIALOG_MODAL, - GTK_MESSAGE_QUESTION, - GTK_BUTTONS_YES_NO, str); - - response = gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - - if (response == GTK_RESPONSE_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 86be94ccdb..0000000000 --- a/calendar/gui/dialogs/send-comp.h +++ /dev/null @@ -1,31 +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 <gtk/gtkwindow.h> -#include <libecal/e-cal.h> -#include <libecal/e-cal-component.h> - -gboolean send_component_dialog (GtkWindow *parent, ECal *client, ECalComponent *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 5d75c9b39a..0000000000 --- a/calendar/gui/dialogs/task-details-page.c +++ /dev/null @@ -1,781 +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 <libgnome/gnome-i18n.h> -#include <glade/glade.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 *date_completed_label; - GtkWidget *completed_date; - - GtkWidget *url_label; - GtkWidget *url_entry; - GtkWidget *url; - - gboolean updating; -}; - -/* Note that these two arrays must match. */ -static const int status_map[] = { - ICAL_STATUS_NONE, - 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_finalize (GObject *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, ECalComponent *comp); -static gboolean task_details_page_fill_component (CompEditorPage *page, ECalComponent *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. - **/ - -E_MAKE_TYPE (task_details_page, "TaskDetailsPage", TaskDetailsPage, task_details_page_class_init, - task_details_page_init, TYPE_COMP_EDITOR_PAGE); - -/* Class initialization function for the task page */ -static void -task_details_page_class_init (TaskDetailsPageClass *class) -{ - CompEditorPageClass *editor_page_class; - GObjectClass *object_class; - - editor_page_class = (CompEditorPageClass *) class; - object_class = (GObjectClass *) class; - - parent_class = g_type_class_ref(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->finalize = task_details_page_finalize; -} - -/* 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->date_completed_label = NULL; - priv->completed_date = NULL; - - priv->url_label = NULL; - priv->url_entry = NULL; - priv->url = NULL; - - priv->updating = FALSE; -} - -/* Destroy handler for the task page */ -static void -task_details_page_finalize (GObject *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->main) - gtk_widget_unref (priv->main); - - if (priv->xml) { - g_object_unref (priv->xml); - priv->xml = NULL; - } - - g_free (priv); - tdpage->priv = NULL; - - if (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (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, ECalComponent *comp) -{ - TaskDetailsPage *tdpage; - TaskDetailsPagePrivate *priv; - int *priority_value, *percent = NULL; - 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. */ - e_cal_component_get_percent (comp, &percent); - if (percent) { - e_dialog_spin_set (priv->percent_complete, *percent); - } else { - /* FIXME: Could check if task is completed and set 100%. */ - e_dialog_spin_set (priv->percent_complete, 0); - } - - /* Status. */ - e_cal_component_get_status (comp, &status); - if (status == ICAL_STATUS_NONE || status == ICAL_STATUS_NEEDSACTION) { - /* Try to use the percent value. */ - if (percent) { - if (*percent == 100) - status = ICAL_STATUS_COMPLETED; - else if (*percent > 0) - status = ICAL_STATUS_INPROCESS; - else - status = ICAL_STATUS_NONE; - } else - status = ICAL_STATUS_NONE; - } - e_dialog_option_menu_set (priv->status, status, status_map); - - if (percent) - e_cal_component_free_percent (percent); - - /* Completed Date. */ - e_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); - - e_cal_component_free_icaltimetype (completed); - } - - /* Priority. */ - e_cal_component_get_priority (comp, &priority_value); - if (priority_value) { - priority = priority_value_to_index (*priority_value); - e_cal_component_free_priority (priority_value); - } else { - priority = PRIORITY_UNDEFINED; - } - e_dialog_option_menu_set (priv->priority, priority, priority_map); - - /* URL */ - e_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, ECalComponent *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); - e_cal_component_set_percent (comp, &percent); - - /* Status. */ - status = e_dialog_option_menu_get (priv->status, status_map); - e_cal_component_set_status (comp, status); - - /* Priority. */ - priority = e_dialog_option_menu_get (priv->priority, priority_map); - priority_value = priority_index_to_value (priority); - e_cal_component_set_priority (comp, &priority_value); - - icaltime = icaltime_null_time (); - - /* COMPLETED must be in UTC. */ - icaltime.is_utc = 1; - - /* Completed Date. */ - if (!e_date_edit_date_is_valid (E_DATE_EDIT (priv->completed_date)) || - !e_date_edit_time_is_valid (E_DATE_EDIT (priv->completed_date))) { - comp_editor_page_display_validation_error (page, _("Completed date is wrong"), priv->completed_date); - return FALSE; - } - - 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 ()); - e_cal_component_set_completed (comp, &icaltime); - } else { - e_cal_component_set_completed (comp, NULL); - } - - /* URL. */ - url = e_dialog_editable_get (priv->url); - e_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 (G_OBJECT (toplevel)); - if (accel_groups) { - page->accel_group = accel_groups->data; - gtk_accel_group_ref (page->accel_group); - } - - gtk_widget_ref (priv->main); - gtk_container_remove (GTK_CONTAINER (priv->main->parent), priv->main); - - priv->status = GW ("status"); - priv->priority = GW ("priority"); - priv->percent_complete = GW ("percent-complete"); - - priv->date_completed_label = GW ("date_completed_label"); - - priv->completed_date = GW ("completed-date"); - gtk_widget_show (priv->completed_date); - - priv->url_label = GW ("url_label"); - - priv->url_entry = GW ("url_entry"); - gtk_widget_show (priv->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->date_completed_label - && priv->completed_date - && priv->url_label - && 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_NONE, - 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_NONE) { - 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) { - gint percent_complete = e_dialog_spin_get_int (priv->percent_complete); - if (percent_complete <= 0 || percent_complete >= 100) - 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_NONE; - 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); - - /* These are created by hand, so hook the mnemonics manually */ - gtk_label_set_mnemonic_widget (GTK_LABEL (priv->date_completed_label), priv->completed_date); - gtk_label_set_mnemonic_widget (GTK_LABEL (priv->url_label), priv->url_entry); - - /* Connect signals. The Status, Percent Complete & Date Completed - properties are closely related so whenever one changes we may need - to update the other 2. */ - g_signal_connect((GTK_OPTION_MENU (priv->status)->menu), - "deactivate", - G_CALLBACK (status_changed), tdpage); - - g_signal_connect((GTK_SPIN_BUTTON (priv->percent_complete)->adjustment), - "value_changed", - G_CALLBACK (percent_complete_changed), tdpage); - - /* Priority */ - g_signal_connect((GTK_OPTION_MENU (priv->priority)->menu), - "deactivate", - G_CALLBACK (field_changed_cb), tdpage); - - /* Completed Date */ - g_signal_connect((priv->completed_date), "changed", - G_CALLBACK (date_changed_cb), tdpage); - - /* URL */ - g_signal_connect((priv->url), "changed", - G_CALLBACK (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, 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 = g_object_new (TYPE_TASK_DETAILS_PAGE, NULL); - if (!task_details_page_construct (tdpage)) { - g_object_unref (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 23c34c116c..0000000000 --- a/calendar/gui/dialogs/task-details-page.glade +++ /dev/null @@ -1,384 +0,0 @@ -<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> -<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> - -<glade-interface> - -<widget class="GtkWindow" id="task-details-toplevel"> - <property name="title" translatable="yes">window1</property> - <property name="type">GTK_WINDOW_TOPLEVEL</property> - <property name="window_position">GTK_WIN_POS_NONE</property> - <property name="modal">False</property> - <property name="resizable">True</property> - <property name="destroy_with_parent">False</property> - - <child> - <widget class="GtkVBox" id="task-details-page"> - <property name="border_width">12</property> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkFrame" id="frame2"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <property name="label_yalign">0.5</property> - <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property> - - <child> - <widget class="GtkVBox" id="vbox1"> - <property name="border_width">6</property> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkHBox" id="hbox1"> - <property name="border_width">4</property> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkLabel" id="label17"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Status:</property> - <property name="use_underline">True</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="mnemonic_widget">status</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkOptionMenu" id="status"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="history">0</property> - - <child internal-child="menu"> - <widget class="GtkMenu" id="convertwidget1"> - <property name="visible">True</property> - - <child> - <widget class="GtkMenuItem" id="convertwidget2"> - <property name="visible">True</property> - <property name="label" translatable="yes">Not Started</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget3"> - <property name="visible">True</property> - <property name="label" translatable="yes">In Progress</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget5"> - <property name="visible">True</property> - <property name="label" translatable="yes">Completed</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget6"> - <property name="visible">True</property> - <property name="label" translatable="yes">Cancelled</property> - <property name="use_underline">True</property> - </widget> - </child> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label18"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Priority:</property> - <property name="use_underline">True</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="mnemonic_widget">priority</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkOptionMenu" id="priority"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="history">0</property> - - <child internal-child="menu"> - <widget class="GtkMenu" id="convertwidget7"> - <property name="visible">True</property> - - <child> - <widget class="GtkMenuItem" id="convertwidget8"> - <property name="visible">True</property> - <property name="label" translatable="yes">High</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget9"> - <property name="visible">True</property> - <property name="label" translatable="yes">Normal</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget10"> - <property name="visible">True</property> - <property name="label" translatable="yes">Low</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget11"> - <property name="visible">True</property> - <property name="label" translatable="yes">Undefined</property> - <property name="use_underline">True</property> - </widget> - </child> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label19"> - <property name="visible">True</property> - <property name="label" translatable="yes">% _Complete</property> - <property name="use_underline">True</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="mnemonic_widget">percent-complete</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkSpinButton" id="percent-complete"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="climb_rate">1</property> - <property name="digits">0</property> - <property name="numeric">True</property> - <property name="update_policy">GTK_UPDATE_ALWAYS</property> - <property name="snap_to_ticks">False</property> - <property name="wrap">False</property> - <property name="adjustment">1 0 100 1 10 10</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkTable" id="table1"> - <property name="border_width">4</property> - <property name="visible">True</property> - <property name="n_rows">1</property> - <property name="n_columns">2</property> - <property name="homogeneous">False</property> - <property name="row_spacing">2</property> - <property name="column_spacing">4</property> - - <child> - <widget class="GtkLabel" id="date_completed_label"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Date Completed:</property> - <property name="use_underline">True</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="Custom" id="completed-date"> - <property name="visible">True</property> - <property name="creation_function">task_details_page_create_date_edit</property> - <property name="int1">0</property> - <property name="int2">0</property> - <property name="last_modification_time">Fri, 01 Jun 2001 18:58:51 GMT</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="x_options">fill</property> - <property name="y_options">fill</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - </child> - - <child> - <widget class="GtkLabel" id="label1"> - <property name="visible">True</property> - <property name="label" translatable="yes">Progress</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkTable" id="table2"> - <property name="border_width">6</property> - <property name="visible">True</property> - <property name="n_rows">1</property> - <property name="n_columns">2</property> - <property name="homogeneous">False</property> - <property name="row_spacing">6</property> - <property name="column_spacing">6</property> - - <child> - <widget class="GtkLabel" id="url_label"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Web Page:</property> - <property name="use_underline">True</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="Custom" id="url_entry"> - <property name="visible">True</property> - <property name="creation_function">e_url_entry_new</property> - <property name="int1">0</property> - <property name="int2">0</property> - <property name="last_modification_time">Fri, 08 Feb 2002 21:02:37 GMT</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="y_options">fill</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - </child> -</widget> - -</glade-interface> diff --git a/calendar/gui/dialogs/task-details-page.h b/calendar/gui/dialogs/task-details-page.h deleted file mode 100644 index 98b6832bbf..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" - -G_BEGIN_DECLS - - - -#define TYPE_TASK_DETAILS_PAGE (task_details_page_get_type ()) -#define TASK_DETAILS_PAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_TASK_DETAILS_PAGE, TaskDetailsPage)) -#define TASK_DETAILS_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_TASK_DETAILS_PAGE, TaskDetailsPageClass)) -#define IS_TASK_DETAILS_PAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_TASK_DETAILS_PAGE)) -#define IS_TASK_DETAILS_PAGE_CLASS(klass) (G_TYPE_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); - - - -G_END_DECLS - -#endif diff --git a/calendar/gui/dialogs/task-editor.c b/calendar/gui/dialogs/task-editor.c deleted file mode 100644 index 166dc538ba..0000000000 --- a/calendar/gui/dialogs/task-editor.c +++ /dev/null @@ -1,486 +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/util/e-util.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; - - EMeetingStore *model; - - gboolean assignment_shown; - gboolean updating; -}; - - - -static void task_editor_class_init (TaskEditorClass *class); -static void task_editor_init (TaskEditor *te); -static void task_editor_set_e_cal (CompEditor *editor, ECal *client); -static void task_editor_edit_comp (CompEditor *editor, ECalComponent *comp); -static gboolean task_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method); -static void task_editor_finalize (GObject *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_change_insert_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data); -static void model_row_delete_cb (GtkTreeModel *model, GtkTreePath *path, 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. - **/ - -E_MAKE_TYPE (task_editor, "TaskEditor", TaskEditor, task_editor_class_init, task_editor_init, - TYPE_COMP_EDITOR); - -/* Class initialization function for the event editor */ -static void -task_editor_class_init (TaskEditorClass *klass) -{ - GObjectClass *object_class; - CompEditorClass *editor_class; - - object_class = (GObjectClass *) klass; - editor_class = (CompEditorClass *) klass; - - parent_class = g_type_class_ref(TYPE_COMP_EDITOR); - - editor_class->set_e_cal = task_editor_set_e_cal; - editor_class->edit_comp = task_editor_edit_comp; - editor_class->send_comp = task_editor_send_comp; - - object_class->finalize = task_editor_finalize; -} - -static void -set_menu_sens (TaskEditor *te) -{ - TaskEditorPrivate *priv; - gboolean sens, existing, user, read_only = TRUE; - - priv = te->priv; - - existing = comp_editor_get_existing_org (COMP_EDITOR (te)); - user = comp_editor_get_user_org (COMP_EDITOR (te)); - - e_cal_is_read_only (comp_editor_get_e_cal (COMP_EDITOR (te)), &read_only, NULL); - - sens = e_cal_get_static_capability (comp_editor_get_e_cal (COMP_EDITOR (te)), - CAL_STATIC_CAPABILITY_NO_TASK_ASSIGNMENT) - || priv->assignment_shown || read_only; - comp_editor_set_ui_prop (COMP_EDITOR (te), - "/commands/ActionAssignTask", - "sensitive", sens ? "0" : "1"); - - sens = priv->assignment_shown && existing && !user && !read_only; - comp_editor_set_ui_prop (COMP_EDITOR (te), - "/commands/ActionRefreshTask", - "sensitive", sens ? "1" : "0"); - - sens = priv->assignment_shown && existing && user && !read_only; - comp_editor_set_ui_prop (COMP_EDITOR (te), - "/commands/ActionCancelTask", - "sensitive", sens ? "1" : "0"); - - comp_editor_set_ui_prop (COMP_EDITOR (te), - "/commands/FileSave", - "sensitive", read_only ? "0" : "1"); - comp_editor_set_ui_prop (COMP_EDITOR (te), - "/commands/FileSaveAndClose", - "sensitive", read_only ? "0" : "1"); - comp_editor_set_ui_prop (COMP_EDITOR (te), - "/commands/FileDelete", - "sensitive", read_only ? "0" : "1"); -} - -static void -init_widgets (TaskEditor *te) -{ - TaskEditorPrivate *priv; - - priv = te->priv; - - g_signal_connect((priv->model), "row_changed", - G_CALLBACK (model_row_change_insert_cb), te); - g_signal_connect((priv->model), "row_inserted", - G_CALLBACK (model_row_change_insert_cb), te); - g_signal_connect((priv->model), "row_deleted", - G_CALLBACK (model_row_delete_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->model = E_MEETING_STORE (e_meeting_store_new ()); - priv->assignment_shown = TRUE; - priv->updating = FALSE; - -} - -TaskEditor * -task_editor_construct (TaskEditor *te, ECal *client) -{ - TaskEditorPrivate *priv; - - priv = te->priv; - - priv->task_page = task_page_new (); - g_object_ref (priv->task_page); - gtk_object_sink (GTK_OBJECT (priv->task_page)); - comp_editor_append_page (COMP_EDITOR (te), - COMP_EDITOR_PAGE (priv->task_page), - _("Basic")); - - priv->task_details_page = task_details_page_new (); - g_object_ref (priv->task_details_page); - gtk_object_sink (GTK_OBJECT (priv->task_details_page)); - comp_editor_append_page (COMP_EDITOR (te), - COMP_EDITOR_PAGE (priv->task_details_page), - _("Details")); - - priv->meet_page = meeting_page_new (priv->model, client); - g_object_ref (priv->meet_page); - gtk_object_sink (GTK_OBJECT (priv->meet_page)); - comp_editor_append_page (COMP_EDITOR (te), - COMP_EDITOR_PAGE (priv->meet_page), - _("Assignment")); - - comp_editor_set_e_cal (COMP_EDITOR (te), client); - - comp_editor_merge_ui (COMP_EDITOR (te), "evolution-task-editor.xml", verbs, NULL); - - init_widgets (te); - set_menu_sens (te); - - return te; -} - -static void -task_editor_set_e_cal (CompEditor *editor, ECal *client) -{ - TaskEditor *te; - TaskEditorPrivate *priv; - - te = TASK_EDITOR (editor); - priv = te->priv; - - e_meeting_store_set_e_cal (priv->model, client); - - if (parent_class->set_e_cal) - parent_class->set_e_cal (editor, client); -} - -static void -task_editor_edit_comp (CompEditor *editor, ECalComponent *comp) -{ - TaskEditor *te; - TaskEditorPrivate *priv; - ECalComponentOrganizer organizer; - ECal *client; - GSList *attendees = NULL; - - te = TASK_EDITOR (editor); - priv = te->priv; - - priv->updating = TRUE; - - if (parent_class->edit_comp) - parent_class->edit_comp (editor, comp); - - client = comp_editor_get_e_cal (COMP_EDITOR (editor)); - - /* Get meeting related stuff */ - e_cal_component_get_organizer (comp, &organizer); - e_cal_component_get_attendee_list (comp, &attendees); - - /* Clear things up */ - e_meeting_store_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; - int row; - - 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) { - ECalComponentAttendee *ca = l->data; - EMeetingAttendee *ia; - - ia = E_MEETING_ATTENDEE (e_meeting_attendee_new_from_e_cal_component_attendee (ca)); - /* If we aren't the organizer or the attendee is just delegating, don't allow editing */ - if (!comp_editor_get_user_org (editor) || e_meeting_attendee_is_set_delto (ia)) - e_meeting_attendee_set_edit_level (ia, E_MEETING_ATTENDEE_EDIT_NONE); - e_meeting_store_add_attendee (priv->model, ia); - - g_object_unref(ia); - } - - /* If we aren't the organizer we can still change our own status */ - if (!comp_editor_get_user_org (editor)) { - EAccountList *accounts; - EAccount *account; - EIterator *it; - - accounts = itip_addresses_get (); - for (it = e_list_get_iterator((EList *)accounts);e_iterator_is_valid(it);e_iterator_next(it)) { - EMeetingAttendee *ia; - - account = (EAccount*)e_iterator_get(it); - - ia = e_meeting_store_find_attendee (priv->model, account->id->address, &row); - if (ia != NULL) - e_meeting_attendee_set_edit_level (ia, E_MEETING_ATTENDEE_EDIT_STATUS); - } - g_object_unref(it); - } else if (e_cal_get_organizer_must_attend (client)) { - EMeetingAttendee *ia; - - ia = e_meeting_store_find_attendee (priv->model, organizer.value, &row); - if (ia != NULL) - e_meeting_attendee_set_edit_level (ia, E_MEETING_ATTENDEE_EDIT_NONE); - } - - priv->assignment_shown = TRUE; - } - e_cal_component_free_attendee_list (attendees); - - set_menu_sens (te); - comp_editor_set_needs_send (COMP_EDITOR (te), priv->assignment_shown && itip_organizer_is_user (comp, client)); - - priv->updating = FALSE; -} - -static gboolean -task_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method) -{ - TaskEditor *te = TASK_EDITOR (editor); - TaskEditorPrivate *priv; - ECalComponent *comp = NULL; - - priv = te->priv; - - /* Don't cancel more than once or when just publishing */ - if (method == E_CAL_COMPONENT_METHOD_PUBLISH || - method == E_CAL_COMPONENT_METHOD_CANCEL) - goto parent; - - comp = meeting_page_get_cancel_comp (priv->meet_page); - if (comp != NULL) { - ECal *client; - gboolean result; - - client = e_meeting_store_get_e_cal (priv->model); - result = itip_send_comp (E_CAL_COMPONENT_METHOD_CANCEL, comp, client, NULL); - g_object_unref (comp); - - if (!result) - return FALSE; - } - - parent: - if (parent_class->send_comp) - return parent_class->send_comp (editor, method); - - return FALSE; -} - -/* Destroy handler for the event editor */ -static void -task_editor_finalize (GObject *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; - - g_object_unref (priv->task_page); - g_object_unref (priv->task_details_page); - g_object_unref (priv->meet_page); - - g_object_unref (priv->model); - - g_free (priv); - - if (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (object); -} - -/** - * task_editor_new: - * @client: a ECal - * - * 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 (ECal *client) -{ - TaskEditor *te; - - te = g_object_new (TYPE_TASK_EDITOR, NULL); - return task_editor_construct (te, client); -} - -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), E_CAL_COMPONENT_METHOD_REFRESH); -} - -static void -cancel_task_cmd (GtkWidget *widget, gpointer data) -{ - TaskEditor *te = TASK_EDITOR (data); - ECalComponent *comp; - - comp = comp_editor_get_current_comp (COMP_EDITOR (te)); - if (cancel_component_dialog ((GtkWindow *) te, - comp_editor_get_e_cal (COMP_EDITOR (te)), comp, FALSE)) { - comp_editor_send_comp (COMP_EDITOR (te), E_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), E_CAL_COMPONENT_METHOD_PUBLISH); -} - -static void -model_changed (TaskEditor *te) -{ - if (!te->priv->updating) { - comp_editor_set_changed (COMP_EDITOR (te), TRUE); - comp_editor_set_needs_send (COMP_EDITOR (te), TRUE); - } -} - -static void -model_row_change_insert_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) -{ - model_changed (TASK_EDITOR (data)); -} - -static void -model_row_delete_cb (GtkTreeModel *model, GtkTreePath *path, gpointer data) -{ - model_changed (TASK_EDITOR (data)); -} diff --git a/calendar/gui/dialogs/task-editor.h b/calendar/gui/dialogs/task-editor.h deleted file mode 100644 index e0e6ac75be..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 <gtk/gtkobject.h> -#include "comp-editor.h" - - - -#define TYPE_TASK_EDITOR (task_editor_get_type ()) -#define TASK_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_TASK_EDITOR, TaskEditor)) -#define TASK_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_TASK_EDITOR, \ - TaskEditorClass)) -#define IS_TASK_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_TASK_EDITOR)) -#define IS_TASK_EDITOR_CLASS(klass) (G_TYPE_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, - ECal *client); -TaskEditor *task_editor_new (ECal *client); -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 830e5a0bef..0000000000 --- a/calendar/gui/dialogs/task-page.c +++ /dev/null @@ -1,926 +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/gtktextview.h> -#include <gtk/gtktogglebutton.h> -#include <gtk/gtkspinbutton.h> -#include <gtk/gtkoptionmenu.h> -#include <libgnome/gnome-i18n.h> -#include <glade/glade.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 *categories_btn; - GtkWidget *categories; - - gboolean updating; -}; - -static const int classification_map[] = { - E_CAL_COMPONENT_CLASS_PUBLIC, - E_CAL_COMPONENT_CLASS_PRIVATE, - E_CAL_COMPONENT_CLASS_CONFIDENTIAL, - -1 -}; - - - -static void task_page_class_init (TaskPageClass *class); -static void task_page_init (TaskPage *tpage); -static void task_page_finalize (GObject *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, ECalComponent *comp); -static gboolean task_page_fill_component (CompEditorPage *page, ECalComponent *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. - **/ - -E_MAKE_TYPE (task_page, "TaskPage", TaskPage, task_page_class_init, task_page_init, - TYPE_COMP_EDITOR_PAGE); - -/* Class initialization function for the task page */ -static void -task_page_class_init (TaskPageClass *class) -{ - CompEditorPageClass *editor_page_class; - GObjectClass *object_class; - - editor_page_class = (CompEditorPageClass *) class; - object_class = (GObjectClass *) class; - - parent_class = g_type_class_ref(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->finalize = task_page_finalize; -} - -/* 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->categories_btn = NULL; - priv->categories = NULL; - - priv->updating = FALSE; -} - -/* Destroy handler for the task page */ -static void -task_page_finalize (GObject *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->main) - gtk_widget_unref (priv->main); - - if (priv->xml) { - g_object_unref (priv->xml); - priv->xml = NULL; - } - - g_free (priv); - tpage->priv = NULL; - - if (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (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); - gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->description)), "", 0); - - /* 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, - E_CAL_COMPONENT_CLASS_PRIVATE, classification_map); - - /* Categories */ - e_dialog_editable_set (priv->categories, NULL); -} - -/* Decode the radio button group for classifications */ -static ECalComponentClassification -classification_get (GtkWidget *widget) -{ - return e_dialog_radio_get (widget, classification_map); -} - -/* fill_widgets handler for the task page */ -static void -task_page_fill_widgets (CompEditorPage *page, ECalComponent *comp) -{ - TaskPage *tpage; - TaskPagePrivate *priv; - ECalComponentText text; - ECalComponentDateTime d; - ECalComponentClassification cl; - 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) */ - e_cal_component_get_summary (comp, &text); - e_dialog_editable_set (priv->summary, text.value); - - e_cal_component_get_description_list (comp, &l); - if (l) { - text = *(ECalComponentText *)l->data; - gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->description)), - text.value, -1); - } else { - gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->description)), - "", 0); - } - e_cal_component_free_text_list (l); - - location = calendar_config_get_timezone (); - default_zone = icaltimezone_get_builtin_timezone (location); - - /* Due Date. */ - e_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) { - if (!e_cal_get_timezone (page->client, d.tzid, &zone, NULL)) - /* FIXME: Handle error better. */ - 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); - - e_cal_component_free_datetime (&d); - - - /* Start Date. */ - e_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) { - if (!e_cal_get_timezone (page->client, d.tzid, &zone, NULL)) - /* FIXME: Handle error better. */ - 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); - - e_cal_component_free_datetime (&d); - - /* Classification. */ - e_cal_component_get_classification (comp, &cl); - - switch (cl) { - case E_CAL_COMPONENT_CLASS_PUBLIC: - e_dialog_radio_set (priv->classification_public, - E_CAL_COMPONENT_CLASS_PUBLIC, - classification_map); - break; - - case E_CAL_COMPONENT_CLASS_PRIVATE: - e_dialog_radio_set (priv->classification_public, - E_CAL_COMPONENT_CLASS_PRIVATE, - classification_map); - break; - - case E_CAL_COMPONENT_CLASS_CONFIDENTIAL: - e_dialog_radio_set (priv->classification_public, - E_CAL_COMPONENT_CLASS_CONFIDENTIAL, - classification_map); - break; - - default: - /* default to PUBLIC */ - e_dialog_radio_set (priv->classification_public, - E_CAL_COMPONENT_CLASS_PUBLIC, - classification_map); - break; - } - - /* Categories */ - e_cal_component_get_categories (comp, &categories); - e_dialog_editable_set (priv->categories, categories); - - - priv->updating = FALSE; -} - -/* fill_component handler for the task page */ -static gboolean -task_page_fill_component (CompEditorPage *page, ECalComponent *comp) -{ - TaskPage *tpage; - TaskPagePrivate *priv; - ECalComponentDateTime date; - struct icaltimetype start_tt, due_tt; - char *cat, *str; - gboolean start_date_set, due_date_set, time_set; - GtkTextBuffer *text_buffer; - GtkTextIter text_iter_start, text_iter_end; - struct icaltimetype *due_tt2; - icaltimezone *start_zone = NULL; - icaltimezone *due_zone = NULL; - - tpage = TASK_PAGE (page); - priv = tpage->priv; - text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->description)); - - /* Summary. */ - - str = e_dialog_editable_get (priv->summary); - if (!str || strlen (str) == 0) - e_cal_component_set_summary (comp, NULL); - else { - ECalComponentText text; - - text.value = str; - text.altrep = NULL; - - e_cal_component_set_summary (comp, &text); - } - - if (str) - g_free (str); - - /* Description */ - - gtk_text_buffer_get_start_iter (text_buffer, &text_iter_start); - gtk_text_buffer_get_end_iter (text_buffer, &text_iter_end); - str = gtk_text_buffer_get_text (text_buffer, &text_iter_start, &text_iter_end, FALSE); - - if (!str || strlen (str) == 0) - e_cal_component_set_description_list (comp, NULL); - else { - GSList l; - ECalComponentText text; - - text.value = str; - text.altrep = NULL; - l.data = &text; - l.next = NULL; - - e_cal_component_set_description_list (comp, &l); - } - - if (str) - g_free (str); - - /* Dates */ - - due_tt = icaltime_null_time (); - - date.value = &due_tt; - date.tzid = NULL; - - /* Due Date. */ - if (!e_date_edit_date_is_valid (E_DATE_EDIT (priv->due_date)) || - !e_date_edit_time_is_valid (E_DATE_EDIT (priv->due_date))) { - comp_editor_page_display_validation_error (page, _("Due date is wrong"), priv->due_date); - return FALSE; - } - - due_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 (due_date_set) { - if (time_set) { - due_zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->due_timezone)); - date.tzid = icaltimezone_get_tzid (due_zone); - } else { - due_tt.is_date = TRUE; - date.tzid = NULL; - } - e_cal_component_set_due (comp, &date); - } else { - e_cal_component_set_due (comp, NULL); - } - - /* Start Date. */ - if (!e_date_edit_date_is_valid (E_DATE_EDIT (priv->start_date)) || - !e_date_edit_time_is_valid (E_DATE_EDIT (priv->start_date))) { - comp_editor_page_display_validation_error (page, _("Start date is wrong"), priv->start_date); - return FALSE; - } - - start_tt = icaltime_null_time (); - date.value = &start_tt; - start_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 (start_date_set) { - if (time_set) { - start_zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->start_timezone)); - date.tzid = icaltimezone_get_tzid (start_zone); - } else { - start_tt.is_date = TRUE; - date.tzid = NULL; - } - e_cal_component_set_dtstart (comp, &date); - } else { - e_cal_component_set_dtstart (comp, NULL); - } - - /* Check whether due datetime is before start datetime */ - if (start_date_set && due_date_set) { - due_tt2 = g_new (struct icaltimetype, 1); - memcpy (due_tt2, &due_tt, sizeof(due_tt)); - icaltimezone_convert_time (due_tt2, due_zone, start_zone); - if (icaltime_compare (start_tt, *due_tt2) > 0) { - comp_editor_page_display_validation_error (page, - _("Due date is before start date!"), - priv->due_date); - g_free (due_tt2); - return FALSE; - } - g_free (due_tt2); - } - - - /* Classification. */ - e_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); - - e_cal_component_set_categories (comp, str); - - if (str) - g_free (str); - - 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 (G_OBJECT (toplevel)); - if (accel_groups) { - page->accel_group = accel_groups->data; - gtk_accel_group_ref (page->accel_group); - } - - gtk_widget_ref (priv->main); - gtk_container_remove (GTK_CONTAINER (priv->main->parent), priv->main); - - priv->summary = GW ("summary"); - - /* Glade's visibility flag doesn't seem to work for custom widgets */ - priv->due_date = GW ("due-date"); - gtk_widget_show (priv->due_date); - priv->start_date = GW ("start-date"); - gtk_widget_show (priv->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->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->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; - ECalComponentDateTime start_dt, due_dt; - struct icaltimetype start_tt = icaltime_null_time(); - struct icaltimetype due_tt = icaltime_null_time(); - - tpage = TASK_PAGE (data); - priv = tpage->priv; - - if (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 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; - GtkTextBuffer *text_buffer; - 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 */ - g_signal_connect((priv->summary), "changed", - G_CALLBACK (summary_changed_cb), tpage); - - /* Description */ - text_buffer = gtk_text_buffer_new (NULL); - gtk_text_view_set_buffer (GTK_TEXT_VIEW (priv->description), text_buffer); - g_object_unref (text_buffer); - - gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->description), GTK_WRAP_WORD); - - /* Dates */ - g_signal_connect((priv->start_date), "changed", - G_CALLBACK (date_changed_cb), tpage); - g_signal_connect((priv->due_date), "changed", - G_CALLBACK (date_changed_cb), tpage); - - g_signal_connect((priv->due_timezone), "changed", - G_CALLBACK (field_changed_cb), tpage); - g_signal_connect((priv->start_timezone), "changed", - G_CALLBACK (field_changed_cb), tpage); - - /* Classification */ - g_signal_connect((priv->classification_public), - "toggled", - G_CALLBACK (field_changed_cb), tpage); - g_signal_connect((priv->classification_private), - "toggled", - G_CALLBACK (field_changed_cb), tpage); - g_signal_connect((priv->classification_confidential), - "toggled", - G_CALLBACK (field_changed_cb), tpage); - - /* Connect the default signal handler to use to make sure the "changed" - field gets set whenever a field is changed. */ - - /* Belongs to priv->description */ - g_signal_connect ((text_buffer), "changed", - G_CALLBACK (field_changed_cb), tpage); - - g_signal_connect((priv->categories), "changed", - G_CALLBACK (field_changed_cb), tpage); - - /* Categories button */ - g_signal_connect((priv->categories_btn), "clicked", - G_CALLBACK (categories_clicked_cb), tpage); - - - /* 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, 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)) { - g_object_unref (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 02a8797b45..0000000000 --- a/calendar/gui/dialogs/task-page.glade +++ /dev/null @@ -1,477 +0,0 @@ -<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> -<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> - -<glade-interface> - -<widget class="GtkWindow" id="task-toplevel"> - <property name="title" translatable="yes">window1</property> - <property name="type">GTK_WINDOW_TOPLEVEL</property> - <property name="window_position">GTK_WIN_POS_NONE</property> - <property name="modal">False</property> - <property name="resizable">True</property> - <property name="destroy_with_parent">False</property> - - <child> - <widget class="GtkVBox" id="task-page"> - <property name="border_width">12</property> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkTable" id="table3"> - <property name="visible">True</property> - <property name="n_rows">1</property> - <property name="n_columns">2</property> - <property name="homogeneous">False</property> - <property name="row_spacing">6</property> - <property name="column_spacing">6</property> - - <child> - <widget class="GtkLabel" id="label3"> - <property name="visible">True</property> - <property name="label" translatable="yes">Su_mmary:</property> - <property name="use_underline">True</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="mnemonic_widget">summary</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="x_options"></property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkEntry" id="summary"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="editable">True</property> - <property name="visibility">True</property> - <property name="max_length">0</property> - <property name="text" translatable="yes"></property> - <property name="has_frame">True</property> - <property name="invisible_char" translatable="yes">*</property> - <property name="activates_default">False</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="y_options"></property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkFrame" id="frame2"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <property name="label_yalign">0.5</property> - <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property> - - <child> - <widget class="GtkHBox" id="hbox4"> - <property name="border_width">6</property> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkTable" id="table1"> - <property name="visible">True</property> - <property name="n_rows">2</property> - <property name="n_columns">3</property> - <property name="homogeneous">False</property> - <property name="row_spacing">2</property> - <property name="column_spacing">4</property> - - <child> - <widget class="GtkLabel" id="label6"> - <property name="visible">True</property> - <property name="label" translatable="yes">Sta_rt Date:</property> - <property name="use_underline">True</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="mnemonic_widget">start-date</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label5"> - <property name="visible">True</property> - <property name="label" translatable="yes">_Due Date:</property> - <property name="use_underline">True</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="mnemonic_widget">due-date</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="Custom" id="due-date"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="creation_function">task_page_create_date_edit</property> - <property name="int1">0</property> - <property name="int2">0</property> - <property name="last_modification_time">Fri, 01 Jun 2001 18:59:52 GMT</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="Custom" id="start-date"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="creation_function">task_page_create_date_edit</property> - <property name="int1">0</property> - <property name="int2">0</property> - <property name="last_modification_time">Fri, 01 Jun 2001 18:59:57 GMT</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="Custom" id="due-timezone"> - <property name="visible">True</property> - <property name="creation_function">make_timezone_entry</property> - <property name="int1">0</property> - <property name="int2">0</property> - <property name="last_modification_time">Tue, 19 Jun 2001 04:43:54 GMT</property> - </widget> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="y_options">fill</property> - </packing> - </child> - - <child> - <widget class="Custom" id="start-timezone"> - <property name="visible">True</property> - <property name="creation_function">make_timezone_entry</property> - <property name="int1">0</property> - <property name="int2">0</property> - <property name="last_modification_time">Tue, 19 Jun 2001 04:43:46 GMT</property> - </widget> - <packing> - <property name="left_attach">2</property> - <property name="right_attach">3</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">fill</property> - <property name="y_options">fill</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - </child> - - <child> - <widget class="GtkLabel" id="label4"> - <property name="visible">True</property> - <property name="label" translatable="yes">Date & Time</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkVBox" id="vbox1"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkLabel" id="label18"> - <property name="visible">True</property> - <property name="label" translatable="yes">Description:</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkScrolledWindow" id="scrolledwindow1"> - <property name="visible">True</property> - <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> - <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="shadow_type">GTK_SHADOW_IN</property> - <property name="window_placement">GTK_CORNER_TOP_LEFT</property> - - <child> - <widget class="GtkTextView" id="description"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="editable">True</property> - <property name="justification">GTK_JUSTIFY_LEFT</property> - <property name="wrap_mode">GTK_WRAP_WORD</property> - <property name="cursor_visible">True</property> - <property name="pixels_above_lines">0</property> - <property name="pixels_below_lines">0</property> - <property name="pixels_inside_wrap">0</property> - <property name="left_margin">0</property> - <property name="right_margin">0</property> - <property name="indent">0</property> - <property name="text" translatable="yes"></property> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkFrame" id="frame24"> - <property name="visible">True</property> - <property name="label_xalign">0</property> - <property name="label_yalign">0.5</property> - <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property> - - <child> - <widget class="GtkHBox" id="hbox6"> - <property name="border_width">6</property> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkRadioButton" id="classification-public"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Pu_blic</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="active">True</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkRadioButton" id="classification-private"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Pri_vate</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - <property name="group">classification-public</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkRadioButton" id="classification-confidential"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Con_fidential</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - <property name="group">classification-public</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - </widget> - </child> - - <child> - <widget class="GtkLabel" id="label19"> - <property name="visible">True</property> - <property name="label" translatable="yes">Classification</property> - <property name="use_underline">False</property> - <property name="use_markup">False</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">False</property> - <property name="selectable">False</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - </widget> - <packing> - <property name="type">label_item</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <widget class="GtkHBox" id="hbox2"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">6</property> - - <child> - <widget class="GtkButton" id="categories-button"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Ca_tegories...</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkEntry" id="categories"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="editable">True</property> - <property name="visibility">True</property> - <property name="max_length">0</property> - <property name="text" translatable="yes"></property> - <property name="has_frame">True</property> - <property name="invisible_char" translatable="yes">*</property> - <property name="activates_default">False</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - </child> -</widget> - -</glade-interface> diff --git a/calendar/gui/dialogs/task-page.h b/calendar/gui/dialogs/task-page.h deleted file mode 100644 index 16ced619d7..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" - -G_BEGIN_DECLS - - - -#define TYPE_TASK_PAGE (task_page_get_type ()) -#define TASK_PAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_TASK_PAGE, TaskPage)) -#define TASK_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_TASK_PAGE, TaskPageClass)) -#define IS_TASK_PAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_TASK_PAGE)) -#define IS_TASK_PAGE_CLASS(klass) (G_TYPE_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); - - - -G_END_DECLS - -#endif diff --git a/calendar/gui/e-alarm-list.c b/calendar/gui/e-alarm-list.c deleted file mode 100644 index c1429f8705..0000000000 --- a/calendar/gui/e-alarm-list.c +++ /dev/null @@ -1,690 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* EAlarmList - list of calendar alarms with GtkTreeModel interface. - * - * Copyright (C) 2003 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - * - * Authors: Hans Petter Jansson <hpj@ximian.com> - */ - -#include <config.h> -#include <string.h> -#include <gtk/gtktreemodel.h> -#include <gtk/gtksignal.h> -#include <gtk/gtktreednd.h> -#include <libgnome/gnome-i18n.h> -#include <glib.h> -#include <libecal/e-cal-time-util.h> -#include <e-util/e-time-utils.h> -#include "calendar-config.h" -#include "e-alarm-list.h" - -#define G_LIST(x) ((GList *) x) -#define E_ALARM_LIST_IS_SORTED(list) (E_ALARM_LIST (list)->sort_column_id != -2) -#define IS_VALID_ITER(dt_list, iter) (iter!= NULL && iter->user_data != NULL && \ - dt_list->stamp == iter->stamp) - -static GType column_types [E_ALARM_LIST_NUM_COLUMNS]; - -static void e_alarm_list_init (EAlarmList *file_list); -static void e_alarm_list_class_init (EAlarmListClass *class); -static void e_alarm_list_tree_model_init (GtkTreeModelIface *iface); -static void e_alarm_list_finalize (GObject *object); -static guint e_alarm_list_get_flags (GtkTreeModel *tree_model); -static gint e_alarm_list_get_n_columns (GtkTreeModel *tree_model); -static GType e_alarm_list_get_column_type (GtkTreeModel *tree_model, - gint index); -static gboolean e_alarm_list_get_iter (GtkTreeModel *tree_model, - GtkTreeIter *iter, - GtkTreePath *path); -static GtkTreePath *e_alarm_list_get_path (GtkTreeModel *tree_model, - GtkTreeIter *iter); -static void e_alarm_list_get_value (GtkTreeModel *tree_model, - GtkTreeIter *iter, - gint column, - GValue *value); -static gboolean e_alarm_list_iter_next (GtkTreeModel *tree_model, - GtkTreeIter *iter); -static gboolean e_alarm_list_iter_children (GtkTreeModel *tree_model, - GtkTreeIter *iter, - GtkTreeIter *parent); -static gboolean e_alarm_list_iter_has_child (GtkTreeModel *tree_model, - GtkTreeIter *iter); -static gint e_alarm_list_iter_n_children (GtkTreeModel *tree_model, - GtkTreeIter *iter); -static gboolean e_alarm_list_iter_nth_child (GtkTreeModel *tree_model, - GtkTreeIter *iter, - GtkTreeIter *parent, - gint n); -static gboolean e_alarm_list_iter_parent (GtkTreeModel *tree_model, - GtkTreeIter *iter, - GtkTreeIter *child); - -static GObjectClass *parent_class = NULL; - -GtkType -e_alarm_list_get_type (void) -{ - static GType alarm_list_type = 0; - - if (!alarm_list_type) { - static const GTypeInfo alarm_list_info = - { - sizeof (EAlarmListClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) e_alarm_list_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (EAlarmList), - 0, - (GInstanceInitFunc) e_alarm_list_init, - }; - - static const GInterfaceInfo tree_model_info = - { - (GInterfaceInitFunc) e_alarm_list_tree_model_init, - NULL, - NULL - }; - - column_types [E_ALARM_LIST_COLUMN_DESCRIPTION] = G_TYPE_STRING; - - alarm_list_type = g_type_register_static (G_TYPE_OBJECT, "EAlarmList", - &alarm_list_info, 0); - g_type_add_interface_static (alarm_list_type, - GTK_TYPE_TREE_MODEL, - &tree_model_info); - } - - return alarm_list_type; -} - -static void -e_alarm_list_class_init (EAlarmListClass *class) -{ - GObjectClass *object_class; - - parent_class = g_type_class_peek_parent (class); - object_class = (GObjectClass *) class; - - object_class->finalize = e_alarm_list_finalize; -} - -static void -e_alarm_list_tree_model_init (GtkTreeModelIface *iface) -{ - iface->get_flags = e_alarm_list_get_flags; - iface->get_n_columns = e_alarm_list_get_n_columns; - iface->get_column_type = e_alarm_list_get_column_type; - iface->get_iter = e_alarm_list_get_iter; - iface->get_path = e_alarm_list_get_path; - iface->get_value = e_alarm_list_get_value; - iface->iter_next = e_alarm_list_iter_next; - iface->iter_children = e_alarm_list_iter_children; - iface->iter_has_child = e_alarm_list_iter_has_child; - iface->iter_n_children = e_alarm_list_iter_n_children; - iface->iter_nth_child = e_alarm_list_iter_nth_child; - iface->iter_parent = e_alarm_list_iter_parent; -} - -static void -e_alarm_list_init (EAlarmList *alarm_list) -{ - alarm_list->stamp = g_random_int (); - alarm_list->columns_dirty = FALSE; - alarm_list->list = NULL; -} - -EAlarmList * -e_alarm_list_new (void) -{ - EAlarmList *alarm_list; - - alarm_list = E_ALARM_LIST (g_object_new (e_alarm_list_get_type (), NULL)); - - return alarm_list; -} - -static void -all_rows_deleted (EAlarmList *alarm_list) -{ - GtkTreePath *path; - gint i; - - if (!alarm_list->list) - return; - - path = gtk_tree_path_new (); - i = g_list_length (alarm_list->list); - gtk_tree_path_append_index (path, i); - - for ( ; i >= 0; i--) { - gtk_tree_model_row_deleted (GTK_TREE_MODEL (alarm_list), path); - gtk_tree_path_prev (path); - } - - gtk_tree_path_free (path); -} - -static void -row_deleted (EAlarmList *alarm_list, gint n) -{ - GtkTreePath *path; - - path = gtk_tree_path_new (); - gtk_tree_path_append_index (path, n); - gtk_tree_model_row_deleted (GTK_TREE_MODEL (alarm_list), path); - gtk_tree_path_free (path); -} - -static void -row_added (EAlarmList *alarm_list, gint n) -{ - GtkTreePath *path; - GtkTreeIter iter; - - path = gtk_tree_path_new (); - gtk_tree_path_append_index (path, n); - - if (gtk_tree_model_get_iter (GTK_TREE_MODEL (alarm_list), &iter, path)) - gtk_tree_model_row_inserted (GTK_TREE_MODEL (alarm_list), path, &iter); - - gtk_tree_path_free (path); -} - -static void -row_updated (EAlarmList *alarm_list, gint n) -{ - GtkTreePath *path; - GtkTreeIter iter; - - path = gtk_tree_path_new (); - gtk_tree_path_append_index (path, n); - - if (gtk_tree_model_get_iter (GTK_TREE_MODEL (alarm_list), &iter, path)) - gtk_tree_model_row_changed (GTK_TREE_MODEL (alarm_list), path, &iter); - - gtk_tree_path_free (path); -} - -static void -e_alarm_list_finalize (GObject *object) -{ - EAlarmList *alarm_list = E_ALARM_LIST (object); - - if (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (object); -} - -/* Fulfill the GtkTreeModel requirements */ -static guint -e_alarm_list_get_flags (GtkTreeModel *tree_model) -{ - g_return_val_if_fail (E_IS_ALARM_LIST (tree_model), 0); - - return GTK_TREE_MODEL_LIST_ONLY; -} - -static gint -e_alarm_list_get_n_columns (GtkTreeModel *tree_model) -{ - EAlarmList *alarm_list = (EAlarmList *) tree_model; - - g_return_val_if_fail (E_IS_ALARM_LIST (tree_model), 0); - - alarm_list->columns_dirty = TRUE; - return E_ALARM_LIST_NUM_COLUMNS; -} - -static GType -e_alarm_list_get_column_type (GtkTreeModel *tree_model, - gint index) -{ - EAlarmList *alarm_list = (EAlarmList *) tree_model; - - g_return_val_if_fail (E_IS_ALARM_LIST (tree_model), G_TYPE_INVALID); - g_return_val_if_fail (index < E_ALARM_LIST_NUM_COLUMNS && - index >= 0, G_TYPE_INVALID); - - alarm_list->columns_dirty = TRUE; - return column_types [index]; -} - -const ECalComponentAlarm * -e_alarm_list_get_alarm (EAlarmList *alarm_list, GtkTreeIter *iter) -{ - g_return_val_if_fail (IS_VALID_ITER (alarm_list, iter), NULL); - - return G_LIST (iter->user_data)->data; -} - -static void -free_alarm (ECalComponentAlarm *alarm) -{ - e_cal_component_alarm_free (alarm); -} - -static ECalComponentAlarm * -copy_alarm (const ECalComponentAlarm *alarm) -{ - return e_cal_component_alarm_clone ((ECalComponentAlarm *) alarm); -} - -void -e_alarm_list_set_alarm (EAlarmList *alarm_list, GtkTreeIter *iter, - const ECalComponentAlarm *alarm) -{ - ECalComponentAlarm *alarm_old; - - g_return_if_fail (IS_VALID_ITER (alarm_list, iter)); - - alarm_old = G_LIST (iter->user_data)->data; - free_alarm (alarm_old); - G_LIST (iter->user_data)->data = copy_alarm (alarm); - row_updated (alarm_list, g_list_position (alarm_list->list, G_LIST (iter->user_data))); -} - -void -e_alarm_list_append (EAlarmList *alarm_list, GtkTreeIter *iter, - const ECalComponentAlarm *alarm) -{ - g_return_if_fail (alarm != NULL); - - alarm_list->list = g_list_append (alarm_list->list, copy_alarm (alarm)); - row_added (alarm_list, g_list_length (alarm_list->list) - 1); - - if (iter) { - iter->user_data = g_list_last (alarm_list->list); - iter->stamp = alarm_list->stamp; - } -} - -void -e_alarm_list_remove (EAlarmList *alarm_list, GtkTreeIter *iter) -{ - gint n; - - g_return_if_fail (IS_VALID_ITER (alarm_list, iter)); - - n = g_list_position (alarm_list->list, G_LIST (iter->user_data)); - free_alarm ((ECalComponentAlarm *) G_LIST (iter->user_data)->data); - alarm_list->list = g_list_delete_link (alarm_list->list, G_LIST (iter->user_data)); - row_deleted (alarm_list, n); -} - -void -e_alarm_list_clear (EAlarmList *alarm_list) -{ - GList *l; - - all_rows_deleted (alarm_list); - - for (l = alarm_list->list; l; l = g_list_next (l)) { - free_alarm ((ECalComponentAlarm *) l->data); - } - - g_list_free (alarm_list->list); - alarm_list->list = NULL; -} - -static gboolean -e_alarm_list_get_iter (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreePath *path) -{ - EAlarmList *alarm_list = (EAlarmList *) tree_model; - GList *l; - gint i; - - g_return_val_if_fail (E_IS_ALARM_LIST (tree_model), FALSE); - g_return_val_if_fail (gtk_tree_path_get_depth (path) > 0, FALSE); - - if (!alarm_list->list) - return FALSE; - - alarm_list->columns_dirty = TRUE; - - i = gtk_tree_path_get_indices (path)[0]; - l = g_list_nth (alarm_list->list, i); - if (!l) - return FALSE; - - iter->user_data = l; - iter->stamp = alarm_list->stamp; - return TRUE; -} - -static GtkTreePath * -e_alarm_list_get_path (GtkTreeModel *tree_model, - GtkTreeIter *iter) -{ - EAlarmList *alarm_list = (EAlarmList *) tree_model; - GtkTreePath *retval; - GList *l; - - g_return_val_if_fail (E_IS_ALARM_LIST (tree_model), NULL); - g_return_val_if_fail (iter->stamp == E_ALARM_LIST (tree_model)->stamp, NULL); - - l = iter->user_data; - retval = gtk_tree_path_new (); - gtk_tree_path_append_index (retval, g_list_position (alarm_list->list, l)); - return retval; -} - -/* 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 (ECalComponentAlarm *alarm) -{ - ECalComponentAlarmAction action; - ECalComponentAlarmTrigger trigger; - char string[256]; - char *base, *str = NULL, *dur; - - string [0] = '\0'; - - e_cal_component_alarm_get_action (alarm, &action); - e_cal_component_alarm_get_trigger (alarm, &trigger); - - switch (action) { - case E_CAL_COMPONENT_ALARM_AUDIO: - base = _("Play a sound"); - break; - - case E_CAL_COMPONENT_ALARM_DISPLAY: - base = _("Display a message"); - break; - - case E_CAL_COMPONENT_ALARM_EMAIL: - base = _("Send an email"); - break; - - case E_CAL_COMPONENT_ALARM_PROCEDURE: - base = _("Run a program"); - break; - - case E_CAL_COMPONENT_ALARM_NONE: - case E_CAL_COMPONENT_ALARM_UNKNOWN: - default: - base = _("Unknown action to be performed"); - break; - } - - /* FIXME: This does not look like it will localize correctly. */ - - switch (trigger.type) { - case E_CAL_COMPONENT_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 E_CAL_COMPONENT_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 E_CAL_COMPONENT_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 E_CAL_COMPONENT_ALARM_TRIGGER_NONE: - default: - str = g_strdup_printf (_("%s for an unknown trigger type"), base); - break; - } - - return str; -} - -static void -e_alarm_list_get_value (GtkTreeModel *tree_model, - GtkTreeIter *iter, - gint column, - GValue *value) -{ - EAlarmList *alarm_list = E_ALARM_LIST (tree_model); - ECalComponentAlarm *alarm; - GList *l; - const gchar *str; - - g_return_if_fail (E_IS_ALARM_LIST (tree_model)); - g_return_if_fail (column < E_ALARM_LIST_NUM_COLUMNS); - g_return_if_fail (E_ALARM_LIST (tree_model)->stamp == iter->stamp); - g_return_if_fail (IS_VALID_ITER (alarm_list, iter)); - - g_value_init (value, column_types [column]); - - if (!alarm_list->list) - return; - - l = iter->user_data; - alarm = l->data; - - if (!alarm) - return; - - switch (column) { - case E_ALARM_LIST_COLUMN_DESCRIPTION: - str = get_alarm_string (alarm); - g_value_set_string (value, str); - break; - } -} - -static gboolean -e_alarm_list_iter_next (GtkTreeModel *tree_model, - GtkTreeIter *iter) -{ - GList *l; - - g_return_val_if_fail (E_IS_ALARM_LIST (tree_model), FALSE); - g_return_val_if_fail (IS_VALID_ITER (E_ALARM_LIST (tree_model), iter), FALSE); - - if (!E_ALARM_LIST (tree_model)->list) - return FALSE; - - l = iter->user_data; - l = g_list_next (l); - if (l) { - iter->user_data = l; - return TRUE; - } - - return FALSE; -} - -static gboolean -e_alarm_list_iter_children (GtkTreeModel *tree_model, - GtkTreeIter *iter, - GtkTreeIter *parent) -{ - EAlarmList *alarm_list = E_ALARM_LIST (tree_model); - - /* this is a list, nodes have no children */ - if (parent) - return FALSE; - - /* but if parent == NULL we return the list itself as children of the - * "root" */ - - if (!alarm_list->list) - return FALSE; - - iter->stamp = E_ALARM_LIST (tree_model)->stamp; - iter->user_data = alarm_list->list; - return TRUE; -} - -static gboolean -e_alarm_list_iter_has_child (GtkTreeModel *tree_model, - GtkTreeIter *iter) -{ - g_return_val_if_fail (IS_VALID_ITER (E_ALARM_LIST (tree_model), iter), FALSE); - return FALSE; -} - -static gint -e_alarm_list_iter_n_children (GtkTreeModel *tree_model, - GtkTreeIter *iter) -{ - EAlarmList *alarm_list = E_ALARM_LIST (tree_model); - - g_return_val_if_fail (E_IS_ALARM_LIST (tree_model), -1); - g_return_val_if_fail (IS_VALID_ITER (alarm_list, iter), -1); - - if (iter == NULL) - return g_list_length (alarm_list->list); - - g_return_val_if_fail (E_ALARM_LIST (tree_model)->stamp == iter->stamp, -1); - return 0; -} - -static gboolean -e_alarm_list_iter_nth_child (GtkTreeModel *tree_model, - GtkTreeIter *iter, - GtkTreeIter *parent, - gint n) -{ - EAlarmList *alarm_list = E_ALARM_LIST (tree_model); - - g_return_val_if_fail (E_IS_ALARM_LIST (tree_model), FALSE); - - if (parent) - return FALSE; - - if (alarm_list->list) { - GList *l; - - l = g_list_nth (alarm_list->list, n); - if (!l) - return FALSE; - - iter->stamp = alarm_list->stamp; - iter->user_data = l; - return TRUE; - } - - return FALSE; -} - -static gboolean -e_alarm_list_iter_parent (GtkTreeModel *tree_model, - GtkTreeIter *iter, - GtkTreeIter *child) -{ - return FALSE; -} diff --git a/calendar/gui/e-alarm-list.h b/calendar/gui/e-alarm-list.h deleted file mode 100644 index 93cc8ac58a..0000000000 --- a/calendar/gui/e-alarm-list.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* EAlarmList - list of calendar alarms with GtkTreeModel interface. - * - * Copyright (C) 2003 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - * - * Authors: Hans Petter Jansson <hpj@ximian.com> - */ - -#ifndef E_ALARM_LIST_H -#define E_ALARM_LIST_H - -#include <gtk/gtktreemodel.h> -#include <libecal/e-cal-component.h> - -G_BEGIN_DECLS - -#define E_TYPE_ALARM_LIST (e_alarm_list_get_type ()) -#define E_ALARM_LIST(obj) (GTK_CHECK_CAST ((obj), E_TYPE_ALARM_LIST, EAlarmList)) -#define E_ALARM_LIST_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_ALARM_LIST, EAlarmListClass)) -#define E_IS_ALARM_LIST(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_ALARM_LIST)) -#define E_IS_ALARM_LIST_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), E_TYPE_ALARM_LIST)) -#define E_ALARM_LIST_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), E_TYPE_ALARM_LIST, EAlarmListClass)) - -typedef struct _EAlarmList EAlarmList; -typedef struct _EAlarmListClass EAlarmListClass; - -typedef enum -{ - E_ALARM_LIST_COLUMN_DESCRIPTION, - - E_ALARM_LIST_NUM_COLUMNS -} -EAlarmListColumnType; - -struct _EAlarmList -{ - GObject parent; - - /* Private */ - - gint stamp; - GList *list; - - guint columns_dirty : 1; -}; - -struct _EAlarmListClass -{ - GObjectClass parent_class; -}; - -GtkType e_alarm_list_get_type (void); -EAlarmList *e_alarm_list_new (void); - -const ECalComponentAlarm *e_alarm_list_get_alarm (EAlarmList *alarm_list, GtkTreeIter *iter); -void e_alarm_list_set_alarm (EAlarmList *alarm_list, GtkTreeIter *iter, - const ECalComponentAlarm *datetime); -void e_alarm_list_append (EAlarmList *alarm_list, GtkTreeIter *iter, - const ECalComponentAlarm *datetime); -void e_alarm_list_remove (EAlarmList *alarm_list, GtkTreeIter *iter); -void e_alarm_list_clear (EAlarmList *alarm_list); - -G_END_DECLS - -#endif /* E_ALARM_LIST_H */ diff --git a/calendar/gui/e-cal-list-view-config.c b/calendar/gui/e-cal-list-view-config.c deleted file mode 100644 index e7d82230df..0000000000 --- a/calendar/gui/e-cal-list-view-config.c +++ /dev/null @@ -1,247 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Rodrigo Moya <rodrigo@ximian.com> - * - * Copyright 2003, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include "calendar-config.h" -#include "e-cal-list-view-config.h" - -struct _ECalListViewConfigPrivate { - ECalListView *view; - - GList *notifications; -}; - -static GObjectClass *parent_class = NULL; - -/* Property IDs */ -enum props { - PROP_0, - PROP_VIEW, -}; - -static void -e_cal_list_view_config_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) -{ - ECalListViewConfig *view_config; - ECalListViewConfigPrivate *priv; - - view_config = E_CAL_LIST_VIEW_CONFIG (object); - priv = view_config->priv; - - switch (property_id) { - case PROP_VIEW: - e_cal_list_view_config_set_view (view_config, g_value_get_object (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -e_cal_list_view_config_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) -{ - ECalListViewConfig *view_config; - ECalListViewConfigPrivate *priv; - - view_config = E_CAL_LIST_VIEW_CONFIG (object); - priv = view_config->priv; - - switch (property_id) { - case PROP_VIEW: - g_value_set_object (value, e_cal_list_view_config_get_view (view_config)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -e_cal_list_view_config_dispose (GObject *object) -{ - ECalListViewConfig *view_config = E_CAL_LIST_VIEW_CONFIG (object); - ECalListViewConfigPrivate *priv; - - priv = view_config->priv; - - e_cal_list_view_config_set_view (view_config, NULL); - - if (G_OBJECT_CLASS (parent_class)->dispose) - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -e_cal_list_view_config_finalize (GObject *object) -{ - ECalListViewConfig *view_config = E_CAL_LIST_VIEW_CONFIG (object); - ECalListViewConfigPrivate *priv; - - priv = view_config->priv; - - g_free (priv); - - if (G_OBJECT_CLASS (parent_class)->finalize) - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -e_cal_list_view_config_class_init (ECalListViewConfigClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GParamSpec *spec; - - parent_class = g_type_class_peek_parent (klass); - - /* Method override */ - gobject_class->set_property = e_cal_list_view_config_set_property; - gobject_class->get_property = e_cal_list_view_config_get_property; - gobject_class->dispose = e_cal_list_view_config_dispose; - gobject_class->finalize = e_cal_list_view_config_finalize; - - spec = g_param_spec_object ("view", NULL, NULL, e_cal_list_view_get_type (), - G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT); - g_object_class_install_property (gobject_class, PROP_VIEW, spec); -} - -static void -e_cal_list_view_config_init (ECalListViewConfig *view_config, ECalListViewConfigClass *klass) -{ - view_config->priv = g_new0 (ECalListViewConfigPrivate, 1); - -} - -E_MAKE_TYPE (e_cal_list_view_config, "ECalListViewConfig", ECalListViewConfig, e_cal_list_view_config_class_init, - e_cal_list_view_config_init, G_TYPE_OBJECT); - -ECalListViewConfig * -e_cal_list_view_config_new (ECalListView *list_view) -{ - ECalListViewConfig *view_config; - - view_config = g_object_new (e_cal_list_view_config_get_type (), "view", list_view, NULL); - - return view_config; -} - -ECalListView * -e_cal_list_view_config_get_view (ECalListViewConfig *view_config) -{ - ECalListViewConfigPrivate *priv; - - g_return_val_if_fail (view_config != NULL, NULL); - g_return_val_if_fail (E_IS_CAL_LIST_VIEW_CONFIG (view_config), NULL); - - priv = view_config->priv; - - return priv->view; -} - -static void -set_timezone (ECalListView *list_view) -{ - char *location; - icaltimezone *zone; - - location = calendar_config_get_timezone (); - zone = icaltimezone_get_builtin_timezone (location); - if (!zone) - zone = icaltimezone_get_utc_timezone (); - - e_calendar_view_set_timezone (E_CALENDAR_VIEW (list_view), zone); - - g_free (location); -} - -static void -timezone_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - ECalListViewConfig *view_config = data; - ECalListViewConfigPrivate *priv; - - priv = view_config->priv; - - set_timezone (priv->view); -} - -static void -set_twentyfour_hour (ECalListView *list_view) -{ - gboolean use_24_hour; - - use_24_hour = calendar_config_get_24_hour_format (); - - e_calendar_view_set_use_24_hour_format (E_CALENDAR_VIEW (list_view), use_24_hour); -} - -static void -twentyfour_hour_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - ECalListViewConfig *view_config = data; - ECalListViewConfigPrivate *priv; - - priv = view_config->priv; - - set_twentyfour_hour (priv->view); -} - -void -e_cal_list_view_config_set_view (ECalListViewConfig *view_config, ECalListView *list_view) -{ - ECalListViewConfigPrivate *priv; - guint not; - GList *l; - - g_return_if_fail (view_config != NULL); - g_return_if_fail (E_IS_CAL_LIST_VIEW_CONFIG (view_config)); - - priv = view_config->priv; - - if (priv->view) { - g_object_unref (priv->view); - priv->view = NULL; - } - - for (l = priv->notifications; l; l = l->next) - calendar_config_remove_notification (GPOINTER_TO_UINT (l->data)); - - g_list_free (priv->notifications); - priv->notifications = NULL; - - /* If the new view is NULL, return right now */ - if (!list_view) - return; - - priv->view = g_object_ref (list_view); - - /* Time zone */ - set_timezone (list_view); - - not = calendar_config_add_notification_timezone (timezone_changed_cb, view_config); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - /* 24 Hour format */ - set_twentyfour_hour (list_view); - - not = calendar_config_add_notification_24_hour_format (twentyfour_hour_changed_cb, view_config); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); -} diff --git a/calendar/gui/e-cal-list-view-config.h b/calendar/gui/e-cal-list-view-config.h deleted file mode 100644 index d2f87c36b3..0000000000 --- a/calendar/gui/e-cal-list-view-config.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Author : - * JP Rosevear <jpr@ximian.com> - * - * Copyright 2003, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef _E_CAL_LIST_VIEW_CONFIG_H_ -#define _E_CAL_LIST_VIEW_CONFIG_H_ - -#include "e-cal-list-view.h" - -G_BEGIN_DECLS - -#define E_CAL_LIST_VIEW_CONFIG(obj) GTK_CHECK_CAST (obj, e_cal_list_view_config_get_type (), ECalListViewConfig) -#define E_CAL_LIST_VIEW_CONFIG_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, e_cal_list_view_config_get_type (), ECalListViewConfigClass) -#define E_IS_CAL_LIST_VIEW_CONFIG(obj) GTK_CHECK_TYPE (obj, e_cal_list_view_config_get_type ()) - -typedef struct _ECalListViewConfig ECalListViewConfig; -typedef struct _ECalListViewConfigClass ECalListViewConfigClass; -typedef struct _ECalListViewConfigPrivate ECalListViewConfigPrivate; - -struct _ECalListViewConfig { - GObject parent; - - ECalListViewConfigPrivate *priv; -}; - -struct _ECalListViewConfigClass { - GObjectClass parent_class; -}; - -GType e_cal_list_view_config_get_type (void); -ECalListViewConfig *e_cal_list_view_config_new (ECalListView *list_view); -ECalListView *e_cal_list_view_config_get_view (ECalListViewConfig *view_config); -void e_cal_list_view_config_set_view (ECalListViewConfig *view_config, ECalListView *list_view); - -G_END_DECLS - -#endif diff --git a/calendar/gui/e-cal-list-view.c b/calendar/gui/e-cal-list-view.c deleted file mode 100644 index 74973e36f7..0000000000 --- a/calendar/gui/e-cal-list-view.c +++ /dev/null @@ -1,525 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Authors: - * Hans Petter Jansson <hpj@ximian.com> - * - * Copyright 2003, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -/* - * ECalListView - display calendar events in an ETable. - */ - -#include <config.h> - -#include "e-cal-list-view.h" -#include "ea-calendar.h" - -#include <math.h> -#include <time.h> -#include <sys/stat.h> -#include <gdk/gdkkeysyms.h> -#include <gdk/gdkx.h> -#include <gtk/gtkdnd.h> -#include <gtk/gtkmain.h> -#include <gtk/gtksignal.h> -#include <gtk/gtkvscrollbar.h> -#include <gtk/gtkwindow.h> -#include <gal/widgets/e-gui-utils.h> -#include <gal/util/e-util.h> -#include <gal/e-table/e-table-memory-store.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/widgets/e-popup-menu.h> -#include <widgets/misc/e-cell-date-edit.h> -#include <libgnome/gnome-i18n.h> -#include <libgnome/gnome-exec.h> -#include <libgnome/gnome-util.h> -#include <e-util/e-categories-config.h> -#include <e-util/e-dialog-utils.h> - -#include <libecal/e-cal-time-util.h> -#include "e-cal-model-calendar.h" -#include "e-cell-date-edit-text.h" -#include "dialogs/delete-comp.h" -#include "dialogs/delete-error.h" -#include "dialogs/send-comp.h" -#include "dialogs/cancel-comp.h" -#include "dialogs/recur-comp.h" -#include "comp-util.h" -#include "itip-utils.h" -#include "calendar-commands.h" -#include "calendar-config.h" -#include "goto.h" -#include "misc.h" - -static void e_cal_list_view_class_init (ECalListViewClass *class); -static void e_cal_list_view_init (ECalListView *cal_list_view); -static void e_cal_list_view_destroy (GtkObject *object); -static void e_cal_list_view_update_query (ECalendarView *cal_view); - -static GList *e_cal_list_view_get_selected_events (ECalendarView *cal_view); -static gboolean e_cal_list_view_get_visible_time_range (ECalendarView *cal_view, time_t *start_time, - time_t *end_time); - -static gboolean e_cal_list_view_popup_menu (GtkWidget *widget); - -static void e_cal_list_view_show_popup_menu (ECalListView *cal_list_view, gint row, - GdkEvent *gdk_event); -static gboolean e_cal_list_view_on_table_right_click (GtkWidget *table, gint row, gint col, - GdkEvent *event, gpointer data); - -static GtkTableClass *parent_class; /* Should be ECalendarViewClass? */ - -E_MAKE_TYPE (e_cal_list_view, "ECalListView", ECalListView, e_cal_list_view_class_init, - e_cal_list_view_init, e_calendar_view_get_type ()); - -static void -e_cal_list_view_class_init (ECalListViewClass *class) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - ECalendarViewClass *view_class; - - parent_class = g_type_class_peek_parent (class); - object_class = (GtkObjectClass *) class; - widget_class = (GtkWidgetClass *) class; - view_class = (ECalendarViewClass *) class; - - /* Method override */ - object_class->destroy = e_cal_list_view_destroy; - - widget_class->popup_menu = e_cal_list_view_popup_menu; - - view_class->get_selected_events = e_cal_list_view_get_selected_events; - view_class->get_visible_time_range = e_cal_list_view_get_visible_time_range; - - view_class->update_query = e_cal_list_view_update_query; -} - -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 void -e_cal_list_view_init (ECalListView *cal_list_view) -{ - cal_list_view->query = NULL; - cal_list_view->table_scrolled = NULL; - cal_list_view->cursor_event = NULL; - cal_list_view->set_table_id = 0; -} - -/* Returns the current time, for the ECellDateEdit items. */ -static struct tm -get_current_time_cb (ECellDateEdit *ecde, gpointer data) -{ - ECalListView *cal_list_view = data; - icaltimezone *zone; - struct tm tmp_tm = { 0 }; - struct icaltimetype tt; - - zone = e_calendar_view_get_timezone (E_CALENDAR_VIEW (cal_list_view)); - 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; -} - -static void -load_table_state (ECalListView *cal_list_view) -{ - struct stat st; - - if (!cal_list_view->table_state_path) - return; - - if (stat (cal_list_view->table_state_path, &st) == 0 && st.st_size > 0 && S_ISREG (st.st_mode)) { - e_table_load_state (e_table_scrolled_get_table (cal_list_view->table_scrolled), - cal_list_view->table_state_path); - } -} - -static void -save_table_state (ECalListView *cal_list_view) -{ - if (!cal_list_view->table_state_path) - return; - - e_table_save_state (e_table_scrolled_get_table (cal_list_view->table_scrolled), - cal_list_view->table_state_path); -} - -static void -setup_e_table (ECalListView *cal_list_view) -{ - ECalModelCalendar *model; - ETableExtras *extras; - GList *strings; - ECell *cell, *popup_cell; - GnomeCanvas *canvas; - GtkStyle *style; - - model = E_CAL_MODEL_CALENDAR (e_calendar_view_get_model (E_CALENDAR_VIEW (cal_list_view))); - - if (cal_list_view->table_scrolled) { - save_table_state (cal_list_view); - gtk_widget_destroy (GTK_WIDGET (cal_list_view->table_scrolled)); - } - - /* Create the header columns */ - - extras = e_table_extras_new(); - - /* Normal string fields */ - - cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT); - g_object_set (G_OBJECT (cell), - "bg_color_column", E_CAL_MODEL_FIELD_COLOR, - NULL); - - e_table_extras_add_cell (extras, "calstring", cell); - - /* Date fields */ - - cell = e_cell_date_edit_text_new (NULL, GTK_JUSTIFY_LEFT); - g_object_set (G_OBJECT (cell), - "bg_color_column", E_CAL_MODEL_FIELD_COLOR, - NULL); - - popup_cell = e_cell_date_edit_new (); - e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell); - g_object_unref (cell); - e_table_extras_add_cell (extras, "dateedit", popup_cell); - cal_list_view->dates_cell = E_CELL_DATE_EDIT (popup_cell); - - e_cell_date_edit_set_get_time_callback (E_CELL_DATE_EDIT (popup_cell), - get_current_time_cb, - cal_list_view, NULL); - - /* Combo fields */ - - cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT); - g_object_set (G_OBJECT (cell), - "bg_color_column", E_CAL_MODEL_FIELD_COLOR, - "editable", FALSE, - NULL); - - popup_cell = e_cell_combo_new (); - e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell); - g_object_unref (cell); - - strings = NULL; - strings = g_list_append (strings, (char*) _("Public")); - strings = g_list_append (strings, (char*) _("Private")); - strings = g_list_append (strings, (char*) _("Confidential")); - e_cell_combo_set_popdown_strings (E_CELL_COMBO (popup_cell), - strings); - - e_table_extras_add_cell (extras, "classification", popup_cell); - - /* Sorting */ - - e_table_extras_add_compare (extras, "date-compare", - date_compare_cb); - - /* Create table view */ - - cal_list_view->table_scrolled = E_TABLE_SCROLLED ( - e_table_scrolled_new_from_spec_file (E_TABLE_MODEL (model), - extras, - EVOLUTION_ETSPECDIR "/e-cal-list-view.etspec", - NULL)); - - /* Make sure text is readable on top of our color coding */ - - canvas = GNOME_CANVAS (e_table_scrolled_get_table (cal_list_view->table_scrolled)->table_canvas); - style = gtk_widget_get_style (GTK_WIDGET (canvas)); - - style->fg [GTK_STATE_SELECTED] = style->text [GTK_STATE_NORMAL]; - style->fg [GTK_STATE_ACTIVE] = style->text [GTK_STATE_NORMAL]; - gtk_widget_set_style (GTK_WIDGET (canvas), style); - - /* Load state, if possible */ - - load_table_state (cal_list_view); - - /* Connect signals */ - - g_signal_connect (e_table_scrolled_get_table (cal_list_view->table_scrolled), - "right-click", G_CALLBACK (e_cal_list_view_on_table_right_click), cal_list_view); - - /* Attach and show widget */ - - gtk_table_attach (GTK_TABLE (cal_list_view), GTK_WIDGET (cal_list_view->table_scrolled), - 0, 2, 0, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 1, 1); - gtk_widget_show (GTK_WIDGET (cal_list_view->table_scrolled)); -} - -GtkWidget * -e_cal_list_view_construct (ECalListView *cal_list_view, const gchar *table_state_path) -{ - if (table_state_path) - cal_list_view->table_state_path = g_strdup (table_state_path); - else - cal_list_view->table_state_path = NULL; - - setup_e_table (cal_list_view); - - return GTK_WIDGET (cal_list_view); -} - -/** - * e_cal_list_view_new: - * @Returns: a new #ECalListView. - * - * Creates a new #ECalListView. - **/ -GtkWidget * -e_cal_list_view_new (const gchar *table_state_path) -{ - ECalListView *cal_list_view; - ECalModel *model; - - model = E_CAL_MODEL (e_cal_model_calendar_new ()); - - cal_list_view = g_object_new (e_cal_list_view_get_type (), "model", model, NULL); - if (!e_cal_list_view_construct (cal_list_view, table_state_path)) { - g_message (G_STRLOC ": Could not construct the calendar list GUI"); - g_object_unref (cal_list_view); - return NULL; - } - - g_object_unref (model); - - return GTK_WIDGET (cal_list_view); -} - -static void -e_cal_list_view_destroy (GtkObject *object) -{ - ECalListView *cal_list_view; - - cal_list_view = E_CAL_LIST_VIEW (object); - - if (cal_list_view->query) { - g_signal_handlers_disconnect_matched (cal_list_view->query, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, cal_list_view); - g_object_unref (cal_list_view->query); - cal_list_view->query = NULL; - } - - if (cal_list_view->set_table_id) { - g_source_remove (cal_list_view->set_table_id); - cal_list_view->set_table_id = 0; - } - - if (cal_list_view->table_state_path) { - save_table_state (cal_list_view); - g_free (cal_list_view->table_state_path); - cal_list_view->table_state_path = NULL; - } - - if (cal_list_view->cursor_event) { - g_free (cal_list_view->cursor_event); - cal_list_view->cursor_event = NULL; - } - - if (cal_list_view->table_scrolled) { - gtk_widget_destroy (GTK_WIDGET (cal_list_view->table_scrolled)); - cal_list_view->table_scrolled = NULL; - } - - GTK_OBJECT_CLASS (parent_class)->destroy (object); -} - -static gboolean -setup_e_table_cb (gpointer data) -{ - setup_e_table (E_CAL_LIST_VIEW (data)); - E_CAL_LIST_VIEW (data)->set_table_id = 0; - return FALSE; -} - -static void -e_cal_list_view_update_query (ECalendarView *cal_list_view) -{ - e_calendar_view_set_status_message (E_CALENDAR_VIEW (cal_list_view), _("Searching")); - - if (!E_CAL_LIST_VIEW (cal_list_view)->set_table_id) - E_CAL_LIST_VIEW (cal_list_view)->set_table_id = - g_idle_add (setup_e_table_cb, cal_list_view); - - e_calendar_view_set_status_message (E_CALENDAR_VIEW (cal_list_view), NULL); -} - -static void -e_cal_list_view_show_popup_menu (ECalListView *cal_list_view, gint row, GdkEvent *gdk_event) -{ - GtkMenu *popup; - - popup = e_calendar_view_create_popup_menu (E_CALENDAR_VIEW (cal_list_view)); - e_popup_menu (popup, gdk_event); -} - -static gboolean -e_cal_list_view_popup_menu (GtkWidget *widget) -{ - ECalListView *cal_list_view = E_CAL_LIST_VIEW (widget); - - e_cal_list_view_show_popup_menu (cal_list_view, -1, NULL); - return TRUE; -} - -static gboolean -e_cal_list_view_on_table_right_click (GtkWidget *table, gint row, gint col, GdkEvent *event, - gpointer data) -{ - ECalListView *cal_list_view = E_CAL_LIST_VIEW (data); - - e_cal_list_view_show_popup_menu (cal_list_view, row, event); - return TRUE; -} - -static GList * -e_cal_list_view_get_selected_events (ECalendarView *cal_view) -{ - GList *event_list = NULL; - gint cursor_row; - - if (E_CAL_LIST_VIEW (cal_view)->cursor_event) { - g_free (E_CAL_LIST_VIEW (cal_view)->cursor_event); - E_CAL_LIST_VIEW (cal_view)->cursor_event = NULL; - } - - cursor_row = e_table_get_cursor_row (e_table_scrolled_get_table (E_CAL_LIST_VIEW (cal_view)->table_scrolled)); - - if (cursor_row >= 0) { - ECalendarViewEvent *event; - - event = E_CAL_LIST_VIEW (cal_view)->cursor_event = g_new0 (ECalendarViewEvent, 1); - event->comp_data = - e_cal_model_get_component_at (e_calendar_view_get_model (cal_view), - cursor_row); - event_list = g_list_prepend (event_list, event); - } - - return event_list; -} - -static void -adjust_range (icaltimetype icaltime, time_t *earliest, time_t *latest, gboolean *set) -{ - time_t t; - - if (!icaltime_is_valid_time (icaltime)) - return; - - t = icaltime_as_timet (icaltime); - *earliest = MIN (*earliest, t); - *latest = MAX (*latest, t); - - *set = TRUE; -} - -/* NOTE: Time use for this function increases linearly with number of events. This is not - * ideal, since it's used in a couple of places. We could probably be smarter about it, - * and use do it less frequently... */ -static gboolean -e_cal_list_view_get_visible_time_range (ECalendarView *cal_view, time_t *start_time, time_t *end_time) -{ - time_t earliest = G_MAXINT, latest = 0; - gboolean set = FALSE; - gint n_rows, i; - - n_rows = e_table_model_row_count (E_TABLE_MODEL (e_calendar_view_get_model (cal_view))); - - for (i = 0; i < n_rows; i++) { - ECalModelComponent *comp; - icalcomponent *icalcomp; - - comp = e_cal_model_get_component_at (e_calendar_view_get_model (cal_view), i); - if (!comp) - continue; - - icalcomp = comp->icalcomp; - if (!icalcomp) - continue; - - adjust_range (icalcomponent_get_dtstart (icalcomp), &earliest, &latest, &set); - adjust_range (icalcomponent_get_dtend (icalcomp), &earliest, &latest, &set); - } - - if (set) { - *start_time = earliest; - *end_time = latest; - return TRUE; - } - - return FALSE; -} - -gboolean -e_cal_list_view_get_range_shown (ECalListView *cal_list_view, GDate *start_date, gint *days_shown) -{ - time_t first, last; - GDate end_date; - - if (!e_cal_list_view_get_visible_time_range (E_CALENDAR_VIEW (cal_list_view), &first, &last)) - return FALSE; - - time_to_gdate_with_zone (start_date, first, e_calendar_view_get_timezone (E_CALENDAR_VIEW (cal_list_view))); - time_to_gdate_with_zone (&end_date, last, e_calendar_view_get_timezone (E_CALENDAR_VIEW (cal_list_view))); - - *days_shown = g_date_days_between (start_date, &end_date); - return TRUE; -} diff --git a/calendar/gui/e-cal-list-view.etspec b/calendar/gui/e-cal-list-view.etspec deleted file mode 100644 index e5a2cc0b6d..0000000000 --- a/calendar/gui/e-cal-list-view.etspec +++ /dev/null @@ -1,17 +0,0 @@ -<ETableSpecification draw-grid="false" alternating-row-colors="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="color" cell="calcolor" priority="-4"/> - <ETableColumn model_col="3" _title="component" cell="calcomp" priority="-4"/> - <ETableColumn model_col="4" _title="Description" expansion="2.0" minimum_width="10" resizable="true" cell="calstring" compare="string" priority="-1"/> - <ETableColumn model_col="5" _title="Start Date" expansion="2.0" minimum_width="10" resizable="true" cell="dateedit" compare="date-compare" priority="-2"/> - <ETableColumn model_col="8" _title="Summary" expansion="3.0" minimum_width="10" resizable="true" cell="calstring" compare="string" priority="10"/> - - <ETableState> - <column source="4"/> - <column source="3"/> - <column source="1"/> - <column source="0"/> - <grouping></grouping> - </ETableState> -</ETableSpecification> diff --git a/calendar/gui/e-cal-list-view.h b/calendar/gui/e-cal-list-view.h deleted file mode 100644 index 08d5b7c0e8..0000000000 --- a/calendar/gui/e-cal-list-view.h +++ /dev/null @@ -1,97 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Authors: - * Hans Petter Jansson <hpj@ximian.com> - * - * Copyright 2003, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ -#ifndef _E_CAL_LIST_VIEW_H_ -#define _E_CAL_LIST_VIEW_H_ - -#include <time.h> -#include <gtk/gtktable.h> -#include <gtk/gtktooltips.h> -#include <gal/widgets/e-popup-menu.h> - -#include "e-cal-view.h" -#include "gnome-cal.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - * ECalListView - displays calendar events in an ETable. - */ - -#define E_CAL_LIST_VIEW(obj) GTK_CHECK_CAST (obj, e_cal_list_view_get_type (), ECalListView) -#define E_CAL_LIST_VIEW_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, e_cal_list_view_get_type (), ECalListViewClass) -#define E_IS_CAL_LIST_VIEW(obj) GTK_CHECK_TYPE (obj, e_cal_list_view_get_type ()) - - -typedef struct _ECalListView ECalListView; -typedef struct _ECalListViewClass ECalListViewClass; - -struct _ECalListView -{ - ECalendarView cal_view; - - /* The main display table */ - ETableScrolled *table_scrolled; - - /* The path to the table's state file */ - gchar *table_state_path; - - /* S-expression for query and the query object */ - ECalView *query; - - /* The default category for new events */ - gchar *default_category; - - /* Date editing cell */ - ECellDateEdit *dates_cell; - - /* The last ECalendarViewEvent we returned from e_cal_list_view_get_selected_events(), to be freed */ - ECalendarViewEvent *cursor_event; - - /* Idle handler ID for setting a new ETableModel */ - gint set_table_id; -}; - -struct _ECalListViewClass -{ - ECalendarViewClass parent_class; -}; - - -GtkType e_cal_list_view_get_type (void); -GtkWidget *e_cal_list_view_construct (ECalListView *cal_list_view, const gchar *table_state_path); - -GtkWidget *e_cal_list_view_new (const gchar *table_state_path); - -void e_cal_list_view_set_query (ECalListView *cal_list_view, const gchar *sexp); -void e_cal_list_view_set_default_category (ECalListView *cal_list_view, const gchar *category); -gboolean e_cal_list_view_get_range_shown (ECalListView *cal_list_view, GDate *start_date, - gint *days_shown); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_CAL_LIST_VIEW_H_ */ diff --git a/calendar/gui/e-cal-model-calendar.c b/calendar/gui/e-cal-model-calendar.c deleted file mode 100644 index 9fd2db7544..0000000000 --- a/calendar/gui/e-cal-model-calendar.c +++ /dev/null @@ -1,465 +0,0 @@ -/* Evolution calendar - Data model for ETable - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2000 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 <config.h> -#include <string.h> -#include <libgnome/gnome-i18n.h> -#include <gal/util/e-util.h> -#include "e-cal-model-calendar.h" -#include "e-cell-date-edit-text.h" -#include "misc.h" - -struct _ECalModelCalendarPrivate { -}; - -static void ecmc_class_init (ECalModelCalendarClass *klass); -static void ecmc_init (ECalModelCalendar *model, ECalModelCalendarClass *klass); -static void ecmc_finalize (GObject *object); -static int ecmc_column_count (ETableModel *etm); -static void *ecmc_value_at (ETableModel *etm, int col, int row); -static void ecmc_set_value_at (ETableModel *etm, int col, int row, const void *value); -static gboolean ecmc_is_cell_editable (ETableModel *etm, int col, int row); -static void *ecmc_duplicate_value (ETableModel *etm, int col, const void *value); -static void ecmc_free_value (ETableModel *etm, int col, void *value); -static void *ecmc_initialize_value (ETableModel *etm, int col); -static gboolean ecmc_value_is_empty (ETableModel *etm, int col, const void *value); -static char *ecmc_value_to_string (ETableModel *etm, int col, const void *value); - -static void ecmc_fill_component_from_model (ECalModel *model, ECalModelComponent *comp_data, - ETableModel *source_model, gint row); - -static GObjectClass *parent_class = NULL; - -E_MAKE_TYPE (e_cal_model_calendar, "ECalModelCalendar", ECalModelCalendar, ecmc_class_init, - ecmc_init, E_TYPE_CAL_MODEL); - -static void -ecmc_class_init (ECalModelCalendarClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - ETableModelClass *etm_class = E_TABLE_MODEL_CLASS (klass); - ECalModelClass *model_class = E_CAL_MODEL_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - object_class->finalize = ecmc_finalize; - - etm_class->column_count = ecmc_column_count; - etm_class->value_at = ecmc_value_at; - etm_class->set_value_at = ecmc_set_value_at; - etm_class->is_cell_editable = ecmc_is_cell_editable; - etm_class->duplicate_value = ecmc_duplicate_value; - etm_class->free_value = ecmc_free_value; - etm_class->initialize_value = ecmc_initialize_value; - etm_class->value_is_empty = ecmc_value_is_empty; - etm_class->value_to_string = ecmc_value_to_string; - - model_class->fill_component_from_model = ecmc_fill_component_from_model; -} - -static void -ecmc_init (ECalModelCalendar *model, ECalModelCalendarClass *klass) -{ - ECalModelCalendarPrivate *priv; - - priv = g_new0 (ECalModelCalendarPrivate, 1); - model->priv = priv; - - e_cal_model_set_component_kind (E_CAL_MODEL (model), ICAL_VEVENT_COMPONENT); -} - -static void -ecmc_finalize (GObject *object) -{ - ECalModelCalendarPrivate *priv; - ECalModelCalendar *model = (ECalModelCalendar *) object; - - g_return_if_fail (E_IS_CAL_MODEL_CALENDAR (model)); - - priv = model->priv; - if (priv) { - g_free (priv); - model->priv = NULL; - } - - if (parent_class->finalize) - parent_class->finalize (object); -} - -/* ETableModel methods */ -static int -ecmc_column_count (ETableModel *etm) -{ - return E_CAL_MODEL_CALENDAR_FIELD_LAST; -} - -static ECellDateEditValue * -get_dtend (ECalModelComponent *comp_data) -{ - struct icaltimetype tt_end; - - if (!comp_data->dtend) { - icaltimezone *zone; - - tt_end = icalcomponent_get_dtend (comp_data->icalcomp); - if (!icaltime_is_valid_time (tt_end)) - return NULL; - - comp_data->dtend = g_new0 (ECellDateEditValue, 1); - comp_data->dtend->tt = tt_end; - - if (icaltime_get_tzid (tt_end) - && e_cal_get_timezone (comp_data->client, icaltime_get_tzid (tt_end), &zone, NULL)) - comp_data->dtend->zone = zone; - else - comp_data->dtend->zone = NULL; - } - - return comp_data->dtend; -} - -static void * -get_location (ECalModelComponent *comp_data) -{ - icalproperty *prop; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_LOCATION_PROPERTY); - if (prop) - return (void *) icalproperty_get_location (prop); - - return NULL; -} - -static void * -get_transparency (ECalModelComponent *comp_data) -{ - icalproperty *prop; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_TRANSP_PROPERTY); - if (prop) { - icalproperty_transp transp; - - transp = icalproperty_get_transp (prop); - if (transp == ICAL_TRANSP_TRANSPARENT || - transp == ICAL_TRANSP_TRANSPARENTNOCONFLICT) - return _("Free"); - else if (transp == ICAL_TRANSP_OPAQUE || - transp == ICAL_TRANSP_OPAQUENOCONFLICT) - return _("Busy"); - } - - return NULL; -} - -static void * -ecmc_value_at (ETableModel *etm, int col, int row) -{ - ECalModelComponent *comp_data; - ECalModelCalendarPrivate *priv; - ECalModelCalendar *model = (ECalModelCalendar *) etm; - - g_return_val_if_fail (E_IS_CAL_MODEL_CALENDAR (model), NULL); - - priv = model->priv; - - g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST, NULL); - g_return_val_if_fail (row >= 0 && row < e_table_model_row_count (etm), NULL); - - if (col < E_CAL_MODEL_FIELD_LAST) - return E_TABLE_MODEL_CLASS (parent_class)->value_at (etm, col, row); - - comp_data = e_cal_model_get_component_at (E_CAL_MODEL (model), row); - if (!comp_data) - return ""; - - switch (col) { - case E_CAL_MODEL_CALENDAR_FIELD_DTEND : - return get_dtend (comp_data); - case E_CAL_MODEL_CALENDAR_FIELD_LOCATION : - return get_location (comp_data); - case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY : - return get_transparency (comp_data); - } - - return ""; -} - -static void -set_dtend (ECalModelComponent *comp_data, const void *value) -{ - icalproperty *prop; - ECellDateEditValue *dv = (ECellDateEditValue *) value; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_DTEND_PROPERTY); - if (!dv) { - if (prop) { - icalcomponent_remove_property (comp_data->icalcomp, prop); - icalproperty_free (prop); - } - } else - icalcomponent_set_dtend (comp_data->icalcomp, dv->tt); -} - -static void -set_location (ECalModelComponent *comp_data, const void *value) -{ - icalproperty *prop; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_LOCATION_PROPERTY); - - if (string_is_empty (value)) { - if (prop) { - icalcomponent_remove_property (comp_data->icalcomp, prop); - icalproperty_free (prop); - } - } else { - if (prop) - icalproperty_set_location (prop, (const char *) value); - else { - prop = icalproperty_new_location ((const char *) value); - icalcomponent_add_property (comp_data->icalcomp, prop); - } - } -} - -static void -set_transparency (ECalModelComponent *comp_data, const void *value) -{ - icalproperty *prop; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_TRANSP_PROPERTY); - - if (string_is_empty (value)) { - if (prop) { - icalcomponent_remove_property (comp_data->icalcomp, prop); - icalproperty_free (prop); - } - } else { - icalproperty_transp transp; - - if (!strcasecmp (value, "FREE")) - transp = ICAL_TRANSP_TRANSPARENT; - else if (!strcasecmp (value, "OPAQUE")) - transp = ICAL_TRANSP_OPAQUE; - else { - if (prop) { - icalcomponent_remove_property (comp_data->icalcomp, prop); - icalproperty_free (prop); - } - - return; - } - - if (prop) - icalproperty_set_transp (prop, transp); - else { - prop = icalproperty_new_transp (transp); - icalcomponent_add_property (comp_data->icalcomp, prop); - } - } -} - -static void -ecmc_set_value_at (ETableModel *etm, int col, int row, const void *value) -{ - ECalModelComponent *comp_data; - ECalModelCalendar *model = (ECalModelCalendar *) etm; - - g_return_if_fail (E_IS_CAL_MODEL_CALENDAR (model)); - g_return_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST); - g_return_if_fail (row >= 0 && row < e_table_model_row_count (etm)); - - if (col < E_CAL_MODEL_FIELD_LAST) { - E_TABLE_MODEL_CLASS (parent_class)->set_value_at (etm, col, row, value); - return; - } - - comp_data = e_cal_model_get_component_at (E_CAL_MODEL (model), row); - if (!comp_data) - return; - - switch (col) { - case E_CAL_MODEL_CALENDAR_FIELD_DTEND : - set_dtend (comp_data, value); - break; - case E_CAL_MODEL_CALENDAR_FIELD_LOCATION : - set_location (comp_data, value); - break; - case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY : - set_transparency (comp_data, value); - break; - } - - /* FIXME ask about mod type */ - if (!e_cal_modify_object (comp_data->client, comp_data->icalcomp, CALOBJ_MOD_ALL, NULL)) { - g_warning (G_STRLOC ": Could not modify the object!"); - - /* FIXME Show error dialog */ - } -} - -static gboolean -ecmc_is_cell_editable (ETableModel *etm, int col, int row) -{ - ECalModelCalendar *model = (ECalModelCalendar *) etm; - - g_return_val_if_fail (E_IS_CAL_MODEL_CALENDAR (model), FALSE); - g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST, FALSE); - - /* FIXME: We can't check this as 'click-to-add' passes row 0. */ - /* g_return_val_if_fail (row >= 0 && row < e_table_model_get_row_count (etm), FALSE); */ - - if (col < E_CAL_MODEL_FIELD_LAST) - return E_TABLE_MODEL_CLASS (parent_class)->is_cell_editable (etm, col, row); - - switch (col) { - case E_CAL_MODEL_CALENDAR_FIELD_DTEND : - case E_CAL_MODEL_CALENDAR_FIELD_LOCATION : - case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY : - return TRUE; - } - - return FALSE; -} - -static void * -ecmc_duplicate_value (ETableModel *etm, int col, const void *value) -{ - g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST, NULL); - - if (col < E_CAL_MODEL_FIELD_LAST) - return E_TABLE_MODEL_CLASS (parent_class)->duplicate_value (etm, col, value); - - switch (col) { - case E_CAL_MODEL_CALENDAR_FIELD_DTEND : - /* FIXME */ - break; - case E_CAL_MODEL_CALENDAR_FIELD_LOCATION : - case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY : - return g_strdup (value); - } - - return NULL; -} - -static void -ecmc_free_value (ETableModel *etm, int col, void *value) -{ - g_return_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST); - - if (col < E_CAL_MODEL_FIELD_LAST) { - E_TABLE_MODEL_CLASS (parent_class)->free_value (etm, col, value); - return; - } - - switch (col) { - case E_CAL_MODEL_CALENDAR_FIELD_DTEND : - case E_CAL_MODEL_CALENDAR_FIELD_LOCATION : - case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY : - if (value) - g_free (value); - break; - } -} - -static void * -ecmc_initialize_value (ETableModel *etm, int col) -{ - g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST, NULL); - - if (col < E_CAL_MODEL_FIELD_LAST) - return E_TABLE_MODEL_CLASS (parent_class)->initialize_value (etm, col); - - switch (col) { - case E_CAL_MODEL_CALENDAR_FIELD_DTEND : - return NULL; - case E_CAL_MODEL_CALENDAR_FIELD_LOCATION : - case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY : - return g_strdup (""); - } - - return NULL; -} - -static gboolean -ecmc_value_is_empty (ETableModel *etm, int col, const void *value) -{ - g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST, TRUE); - - if (col < E_CAL_MODEL_FIELD_LAST) - return E_TABLE_MODEL_CLASS (parent_class)->value_is_empty (etm, col, value); - - switch (col) { - case E_CAL_MODEL_CALENDAR_FIELD_DTEND : - return value ? FALSE : TRUE; - case E_CAL_MODEL_CALENDAR_FIELD_LOCATION : - case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY : - return string_is_empty (value); - } - - return TRUE; -} - -static char * -ecmc_value_to_string (ETableModel *etm, int col, const void *value) -{ - g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST, NULL); - - if (col < E_CAL_MODEL_FIELD_LAST) - return E_TABLE_MODEL_CLASS (parent_class)->value_to_string (etm, col, value); - - switch (col) { - case E_CAL_MODEL_CALENDAR_FIELD_DTEND : - return e_cal_model_date_value_to_string (E_CAL_MODEL (etm), value); - case E_CAL_MODEL_CALENDAR_FIELD_LOCATION : - case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY : - return g_strdup (value); - } - - return NULL; -} - -/* ECalModel class methods */ - -static void -ecmc_fill_component_from_model (ECalModel *model, ECalModelComponent *comp_data, - ETableModel *source_model, gint row) -{ - g_return_if_fail (E_IS_CAL_MODEL_CALENDAR (model)); - g_return_if_fail (comp_data != NULL); - g_return_if_fail (E_IS_TABLE_MODEL (source_model)); - - set_dtend (comp_data, - e_table_model_value_at (source_model, E_CAL_MODEL_CALENDAR_FIELD_DTEND, row)); - set_location (comp_data, - e_table_model_value_at (source_model, E_CAL_MODEL_CALENDAR_FIELD_LOCATION, row)); - set_transparency (comp_data, - e_table_model_value_at (source_model, E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY, row)); -} - -/** - * e_cal_model_calendar_new - */ -ECalModelCalendar * -e_cal_model_calendar_new (void) -{ - return g_object_new (E_TYPE_CAL_MODEL_CALENDAR, NULL); -} diff --git a/calendar/gui/e-cal-model-calendar.h b/calendar/gui/e-cal-model-calendar.h deleted file mode 100644 index 450871c88f..0000000000 --- a/calendar/gui/e-cal-model-calendar.h +++ /dev/null @@ -1,60 +0,0 @@ -/* Evolution calendar - Data model for ETable - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2000 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 E_CAL_MODEL_CALENDAR_H -#define E_CAL_MODEL_CALENDAR_H - -#include "e-cal-model.h" - -G_BEGIN_DECLS - -#define E_TYPE_CAL_MODEL_CALENDAR (e_cal_model_calendar_get_type ()) -#define E_CAL_MODEL_CALENDAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CAL_MODEL_CALENDAR, ECalModelCalendar)) -#define E_CAL_MODEL_CALENDAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CAL_MODEL_CALENDAR, ECalModelCalendarClass)) -#define E_IS_CAL_MODEL_CALENDAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CAL_MODEL_CALENDAR)) -#define E_IS_CAL_MODEL_CALENDAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CAL_MODEL_CALENDAR)) - -typedef struct _ECalModelCalendarPrivate ECalModelCalendarPrivate; - -typedef enum { - /* If you add new items here or reorder them, you have to update the - .etspec files for the tables using this model */ - E_CAL_MODEL_CALENDAR_FIELD_DTEND = E_CAL_MODEL_FIELD_LAST, - E_CAL_MODEL_CALENDAR_FIELD_LOCATION, - E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY, - E_CAL_MODEL_CALENDAR_FIELD_LAST -} ECalModelCalendarField; - -typedef struct { - ECalModel model; - ECalModelCalendarPrivate *priv; -} ECalModelCalendar; - -typedef struct { - ECalModelClass parent_class; -} ECalModelCalendarClass; - -GType e_cal_model_calendar_get_type (void); -ECalModelCalendar *e_cal_model_calendar_new (void); - -G_END_DECLS - -#endif diff --git a/calendar/gui/e-cal-model-tasks.c b/calendar/gui/e-cal-model-tasks.c deleted file mode 100644 index 2251ec7f88..0000000000 --- a/calendar/gui/e-cal-model-tasks.c +++ /dev/null @@ -1,1017 +0,0 @@ -/* Evolution calendar - Data model for ETable - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2000 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 <config.h> -#include <math.h> -#include <gtk/gtkmessagedialog.h> -#include <libgnome/gnome-i18n.h> -#include <gal/util/e-util.h> -#include "calendar-config.h" -#include "e-cal-model-tasks.h" -#include "e-cell-date-edit-text.h" -#include "misc.h" - -struct _ECalModelTasksPrivate { -}; - -static void ecmt_class_init (ECalModelTasksClass *klass); -static void ecmt_init (ECalModelTasks *model, ECalModelTasksClass *klass); -static void ecmt_finalize (GObject *object); - -static int ecmt_column_count (ETableModel *etm); -static void *ecmt_value_at (ETableModel *etm, int col, int row); -static void ecmt_set_value_at (ETableModel *etm, int col, int row, const void *value); -static gboolean ecmt_is_cell_editable (ETableModel *etm, int col, int row); -static void *ecmt_duplicate_value (ETableModel *etm, int col, const void *value); -static void ecmt_free_value (ETableModel *etm, int col, void *value); -static void *ecmt_initialize_value (ETableModel *etm, int col); -static gboolean ecmt_value_is_empty (ETableModel *etm, int col, const void *value); -static char *ecmt_value_to_string (ETableModel *etm, int col, const void *value); - -static const char *ecmt_get_color_for_component (ECalModel *model, ECalModelComponent *comp_data); -static void ecmt_fill_component_from_model (ECalModel *model, ECalModelComponent *comp_data, - ETableModel *source_model, gint row); - -static GObjectClass *parent_class = NULL; - -E_MAKE_TYPE (e_cal_model_tasks, "ECalModelTasks", ECalModelTasks, ecmt_class_init, - ecmt_init, E_TYPE_CAL_MODEL); - -static void -ecmt_class_init (ECalModelTasksClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - ETableModelClass *etm_class = E_TABLE_MODEL_CLASS (klass); - ECalModelClass *model_class = E_CAL_MODEL_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - object_class->finalize = ecmt_finalize; - - etm_class->column_count = ecmt_column_count; - etm_class->value_at = ecmt_value_at; - etm_class->set_value_at = ecmt_set_value_at; - etm_class->is_cell_editable = ecmt_is_cell_editable; - etm_class->duplicate_value = ecmt_duplicate_value; - etm_class->free_value = ecmt_free_value; - etm_class->initialize_value = ecmt_initialize_value; - etm_class->value_is_empty = ecmt_value_is_empty; - etm_class->value_to_string = ecmt_value_to_string; - - model_class->get_color_for_component = ecmt_get_color_for_component; - model_class->fill_component_from_model = ecmt_fill_component_from_model; -} - -static void -ecmt_init (ECalModelTasks *model, ECalModelTasksClass *klass) -{ - ECalModelTasksPrivate *priv; - - priv = g_new0 (ECalModelTasksPrivate, 1); - model->priv = priv; - - e_cal_model_set_component_kind (E_CAL_MODEL (model), ICAL_VTODO_COMPONENT); -} - -static void -ecmt_finalize (GObject *object) -{ - ECalModelTasksPrivate *priv; - ECalModelTasks *model = (ECalModelTasks *) object; - - g_return_if_fail (E_IS_CAL_MODEL_TASKS (model)); - - priv = model->priv; - if (priv) { - g_free (priv); - model->priv = NULL; - } - - if (parent_class->finalize) - parent_class->finalize (object); -} - -/* ETableModel methods */ -static int -ecmt_column_count (ETableModel *etm) -{ - return E_CAL_MODEL_TASKS_FIELD_LAST; -} - -/* 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 (ECalModelComponent *comp_data, time_t completed_date) -{ - icalproperty *prop; - gboolean set_completed = TRUE; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_COMPLETED_PROPERTY); - - /* Date Completed. */ - if (completed_date == -1) { - if (prop) - 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); - if (prop) - icalproperty_set_completed (prop, new_completed); - else { - prop = icalproperty_new_completed (new_completed); - icalcomponent_add_property (comp_data->icalcomp, prop); - } - } - - /* Percent. */ - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_PERCENTCOMPLETE_PROPERTY); - if (!prop) - icalcomponent_add_property (comp_data->icalcomp, icalproperty_new_percentcomplete (100)); - else - icalproperty_set_percentcomplete (prop, 100); - - /* Status. */ - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_STATUS_PROPERTY); - if (prop) - icalproperty_set_status (prop, ICAL_STATUS_COMPLETED); - else - icalcomponent_add_property (comp_data->icalcomp, icalproperty_new_status (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 (ECalModelComponent *comp_data) -{ - icalproperty *prop; - - /* Date Completed. */ - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_COMPLETED_PROPERTY); - if (prop) { - icalcomponent_remove_property (comp_data->icalcomp, prop); - icalproperty_free (prop); - } - - /* Percent. */ - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_PERCENTCOMPLETE_PROPERTY); - if (prop) { - icalcomponent_remove_property (comp_data->icalcomp, prop); - icalproperty_free (prop); - } - - /* Status. */ - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_PERCENTCOMPLETE_PROPERTY); - if (prop) - icalproperty_set_status (prop, ICAL_STATUS_NEEDSACTION); -} - -static ECellDateEditValue * -get_completed (ECalModelComponent *comp_data) -{ - struct icaltimetype tt_completed; - - if (!comp_data->completed) { - icaltimezone *zone; - icalproperty *prop; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_COMPLETED_PROPERTY); - if (!prop) - return NULL; - - tt_completed = icalproperty_get_completed (prop); - if (!icaltime_is_valid_time (tt_completed)) - return NULL; - - comp_data->completed = g_new0 (ECellDateEditValue, 1); - comp_data->completed->tt = tt_completed; - - if (icaltime_get_tzid (tt_completed) - && e_cal_get_timezone (comp_data->client, icaltime_get_tzid (tt_completed), &zone, NULL)) - comp_data->completed->zone = zone; - else - comp_data->completed->zone = NULL; - } - - return comp_data->completed; -} - -static ECellDateEditValue * -get_due (ECalModelComponent *comp_data) -{ - struct icaltimetype tt_due; - - if (!comp_data->due) { - icaltimezone *zone; - icalproperty *prop; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_DUE_PROPERTY); - if (!prop) - return NULL; - - tt_due = icalproperty_get_due (prop); - if (!icaltime_is_valid_time (tt_due)) - return NULL; - - comp_data->due = g_new0 (ECellDateEditValue, 1); - comp_data->due->tt = tt_due; - - if (icaltime_get_tzid (tt_due) - && e_cal_get_timezone (comp_data->client, icaltime_get_tzid (tt_due), &zone, NULL)) - comp_data->due->zone = zone; - else - comp_data->due->zone = NULL; - } - - return comp_data->due; -} - -static char * -get_geo (ECalModelComponent *comp_data) -{ - icalproperty *prop; - struct icalgeotype geo; - static gchar buf[32]; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_GEO_PROPERTY); - if (prop) { - geo = icalproperty_get_geo (prop); - 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")); - return buf; - } - - return ""; -} - -static int -get_percent (ECalModelComponent *comp_data) -{ - icalproperty *prop; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_PERCENTCOMPLETE_PROPERTY); - if (prop) - return icalproperty_get_percentcomplete (prop); - - return 0; -} - -static char * -get_priority (ECalModelComponent *comp_data) -{ - icalproperty *prop; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_PRIORITY_PROPERTY); - if (prop) - return e_cal_util_priority_to_string (icalproperty_get_priority (prop)); - - return ""; -} - -static char * -get_status (ECalModelComponent *comp_data) -{ - icalproperty *prop; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_STATUS_PROPERTY); - if (prop) { - switch (icalproperty_get_status (prop)) { - 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; - } - } - - return ""; -} - -static char * -get_url (ECalModelComponent *comp_data) -{ - icalproperty *prop; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_URL_PROPERTY); - if (prop) - return (char *) icalproperty_get_url (prop); - - return ""; -} - -static gboolean -is_complete (ECalModelComponent *comp_data) -{ - icalproperty *prop; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_COMPLETED_PROPERTY); - - return prop ? TRUE : FALSE; -} - -typedef enum { - E_CAL_MODEL_TASKS_DUE_NEVER, - E_CAL_MODEL_TASKS_DUE_FUTURE, - E_CAL_MODEL_TASKS_DUE_TODAY, - E_CAL_MODEL_TASKS_DUE_OVERDUE, - E_CAL_MODEL_TASKS_DUE_COMPLETE -} ECalModelTasksDueStatus; - - -static ECalModelTasksDueStatus -get_due_status (ECalModelTasks *model, ECalModelComponent *comp_data) -{ - icalproperty *prop; - - /* First, do we have a due date? */ - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_DUE_PROPERTY); - if (!prop) - return E_CAL_MODEL_TASKS_DUE_NEVER; - else { - struct icaltimetype now_tt, due_tt; - icaltimezone *zone; - - /* Second, is it already completed? */ - if (is_complete (comp_data)) - return E_CAL_MODEL_TASKS_DUE_COMPLETE; - - /* Third, are we overdue as of right now? */ - due_tt = icalproperty_get_due (prop); - if (due_tt.is_date) { - int cmp; - - now_tt = icaltime_current_time_with_zone (e_cal_model_get_timezone (E_CAL_MODEL (model))); - cmp = icaltime_compare_date_only (due_tt, now_tt); - - if (cmp < 0) - return E_CAL_MODEL_TASKS_DUE_OVERDUE; - else if (cmp == 0) - return E_CAL_MODEL_TASKS_DUE_TODAY; - else - return E_CAL_MODEL_TASKS_DUE_FUTURE; - } else { - /* Get the current time in the same timezone as the DUE date.*/ - if (!e_cal_get_timezone (comp_data->client, icaltime_get_tzid (due_tt), &zone, NULL)) - return E_CAL_MODEL_TASKS_DUE_FUTURE; - - now_tt = icaltime_current_time_with_zone (zone); - - if (icaltime_compare (due_tt, now_tt) <= 0) - return E_CAL_MODEL_TASKS_DUE_OVERDUE; - else - if (icaltime_compare_date_only (due_tt, now_tt) == 0) - return E_CAL_MODEL_TASKS_DUE_TODAY; - else - return E_CAL_MODEL_TASKS_DUE_FUTURE; - } - } - - return E_CAL_MODEL_TASKS_DUE_NEVER; -} - -static gboolean -is_overdue (ECalModelTasks *model, ECalModelComponent *comp_data) -{ - switch (get_due_status (model, comp_data)) { - case E_CAL_MODEL_TASKS_DUE_NEVER: - case E_CAL_MODEL_TASKS_DUE_FUTURE: - case E_CAL_MODEL_TASKS_DUE_COMPLETE: - return FALSE; - case E_CAL_MODEL_TASKS_DUE_TODAY: - case E_CAL_MODEL_TASKS_DUE_OVERDUE: - return TRUE; - } - - return FALSE; -} - -static void * -ecmt_value_at (ETableModel *etm, int col, int row) -{ - ECalModelTasksPrivate *priv; - ECalModelComponent *comp_data; - ECalModelTasks *model = (ECalModelTasks *) etm; - - g_return_val_if_fail (E_IS_CAL_MODEL_TASKS (model), NULL); - - priv = model->priv; - - g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_TASKS_FIELD_LAST, NULL); - g_return_val_if_fail (row >= 0 && row < e_table_model_row_count (etm), NULL); - - if (col < E_CAL_MODEL_FIELD_LAST) - return E_TABLE_MODEL_CLASS (parent_class)->value_at (etm, col, row); - - comp_data = e_cal_model_get_component_at (E_CAL_MODEL (model), row); - if (!comp_data) - return ""; - - switch (col) { - case E_CAL_MODEL_TASKS_FIELD_COMPLETED : - return get_completed (comp_data); - case E_CAL_MODEL_TASKS_FIELD_COMPLETE : - return GINT_TO_POINTER (is_complete (comp_data)); - case E_CAL_MODEL_TASKS_FIELD_DUE : - return get_due (comp_data); - case E_CAL_MODEL_TASKS_FIELD_GEO : - return get_geo (comp_data); - case E_CAL_MODEL_TASKS_FIELD_OVERDUE : - return GINT_TO_POINTER (is_overdue (model, comp_data)); - case E_CAL_MODEL_TASKS_FIELD_PERCENT : - return GINT_TO_POINTER (get_percent (comp_data)); - case E_CAL_MODEL_TASKS_FIELD_PRIORITY : - return get_priority (comp_data); - case E_CAL_MODEL_TASKS_FIELD_STATUS : - return get_status (comp_data); - case E_CAL_MODEL_TASKS_FIELD_URL : - return get_url (comp_data); - } - - return ""; -} - -static void -set_completed (ECalModelTasks *model, ECalModelComponent *comp_data, const void *value) -{ - ECellDateEditValue *dv = (ECellDateEditValue *) value; - - if (!dv) - ensure_task_not_complete (comp_data); - else { - time_t t; - - if (dv->tt.is_date) { - /* if it's a date, it will be floating, - but completed needs a date time value */ - dv->tt.is_date = FALSE; - t = icaltime_as_timet_with_zone (dv->tt, e_cal_model_get_timezone (E_CAL_MODEL (model))); - } else { - /* 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_data, t); - } -} - -static void -set_complete (ECalModelComponent *comp_data, const void *value) -{ - gint state = GPOINTER_TO_INT (value); - - if (state) - ensure_task_complete (comp_data, -1); - else - ensure_task_not_complete (comp_data); -} - -static void -set_due (ECalModelComponent *comp_data, const void *value) -{ - icalproperty *prop; - ECellDateEditValue *dv = (ECellDateEditValue *) value; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_DUE_PROPERTY); - - if (!dv) { - if (prop) { - icalcomponent_remove_property (comp_data->icalcomp, prop); - icalproperty_free (prop); - } - } else { - if (prop) - icalproperty_set_due (prop, dv->tt); - else { - prop = icalproperty_new_due (dv->tt); - icalcomponent_add_property (comp_data->icalcomp, prop); - } - } -} - -/* 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 = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, - _("The geographical position must be entered " - "in the format: \n\n45.436845,125.862501")); - gtk_widget_show (dialog); -} - -static void -set_geo (ECalModelComponent *comp_data, const char *value) -{ - double latitude, longitude; - int matched; - struct icalgeotype geo; - icalproperty *prop; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_GEO_PROPERTY); - - if (string_is_empty (value)) { - if (prop) { - icalcomponent_remove_property (comp_data->icalcomp, prop); - icalproperty_free (prop); - } - } else { - matched = sscanf (value, "%lg , %lg", &latitude, &longitude); - if (matched != 2) - show_geo_warning (); - - geo.lat = latitude; - geo.lon = longitude; - if (prop) - icalproperty_set_geo (prop, geo); - else { - prop = icalproperty_new_geo (geo); - icalcomponent_add_property (comp_data->icalcomp, prop); - } - - } -} - -static void -set_status (ECalModelComponent *comp_data, const char *value) -{ - icalproperty_status status; - icalproperty *prop; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_STATUS_PROPERTY); - - /* 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; - } - - if (prop) - icalproperty_set_status (prop, status); - else { - prop = icalproperty_new_status (status); - icalcomponent_add_property (comp_data->icalcomp, prop); - } - -/* if (status == ICAL_STATUS_NEEDSACTION) { */ -/* percent = 0; */ -/* e_cal_component_set_percent (comp, &percent); */ -/* e_cal_component_set_completed (comp, NULL); */ -/* } else if (status == ICAL_STATUS_INPROCESS) { */ -/* ensure_task_not_complete (comp); */ -/* percent = 50; */ -/* e_cal_component_set_percent (comp, &percent); */ -/* } else if (status == ICAL_STATUS_COMPLETED) { */ -/* ensure_task_complete (comp, -1); */ -/* } */ -} - -static void -set_percent (ECalModelComponent *comp_data, const void *value) -{ - icalproperty *prop; - gint percent = GPOINTER_TO_INT (value); - - g_return_if_fail (percent >= -1); - g_return_if_fail (percent <= 100); - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_PERCENTCOMPLETE_PROPERTY); - - /* A value of -1 means it isn't set */ - if (percent == -1) { - if (prop) { - icalcomponent_remove_property (comp_data->icalcomp, prop); - icalproperty_free (prop); - } - ensure_task_not_complete (comp_data); - } else { - if (prop) - icalproperty_set_percentcomplete (prop, percent); - else { - prop = icalproperty_new_percentcomplete (percent); - icalcomponent_add_property (comp_data->icalcomp, prop); - } - - if (percent == 100) - ensure_task_complete (comp_data, -1); - else { - ensure_task_not_complete (comp_data); - if (percent > 0) - set_status (comp_data, _("In Progress")); - } - } - -} - -static void -set_priority (ECalModelComponent *comp_data, const char *value) -{ - icalproperty *prop; - int priority; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_PRIORITY_PROPERTY); - - priority = e_cal_util_priority_from_string (value); - if (priority == -1) { - g_warning ("Invalid priority"); - priority = 0; - } - - if (prop) - icalproperty_set_priority (prop, priority); - else { - prop = icalproperty_new_priority (priority); - icalcomponent_add_property (comp_data->icalcomp, prop); - } -} - -static void -set_url (ECalModelComponent *comp_data, const char *value) -{ - icalproperty *prop; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_URL_PROPERTY); - - if (string_is_empty (value)) { - if (prop) { - icalcomponent_remove_property (comp_data->icalcomp, prop); - icalproperty_free (prop); - } - } else { - if (prop) - icalproperty_set_url (prop, value); - else { - prop = icalproperty_new_url (value); - icalcomponent_add_property (comp_data->icalcomp, prop); - } - } -} - -static void -ecmt_set_value_at (ETableModel *etm, int col, int row, const void *value) -{ - ECalModelTasksPrivate *priv; - ECalModelComponent *comp_data; - ECalModelTasks *model = (ECalModelTasks *) etm; - - g_return_if_fail (E_IS_CAL_MODEL_TASKS (model)); - - priv = model->priv; - - g_return_if_fail (col >= 0 && col < E_CAL_MODEL_TASKS_FIELD_LAST); - g_return_if_fail (row >= 0 && row < e_table_model_row_count (etm)); - - if (col < E_CAL_MODEL_FIELD_LAST) { - E_TABLE_MODEL_CLASS (parent_class)->set_value_at (etm, col, row, value); - return; - } - - comp_data = e_cal_model_get_component_at (E_CAL_MODEL (model), row); - if (!comp_data) - return; - - switch (col) { - case E_CAL_MODEL_TASKS_FIELD_COMPLETED : - set_completed (model, comp_data, value); - break; - case E_CAL_MODEL_TASKS_FIELD_COMPLETE : - set_complete (comp_data, value); - break; - case E_CAL_MODEL_TASKS_FIELD_DUE : - set_due (comp_data, value); - break; - case E_CAL_MODEL_TASKS_FIELD_GEO : - set_geo (comp_data, value); - break; - case E_CAL_MODEL_TASKS_FIELD_PERCENT : - set_percent (comp_data, value); - break; - case E_CAL_MODEL_TASKS_FIELD_PRIORITY : - set_priority (comp_data, value); - break; - case E_CAL_MODEL_TASKS_FIELD_URL : - set_url (comp_data, value); - break; - } - - /* FIXME ask about mod type */ - if (!e_cal_modify_object (comp_data->client, comp_data->icalcomp, CALOBJ_MOD_ALL, NULL)) { - g_warning (G_STRLOC ": Could not modify the object!"); - - /* FIXME Show error dialog */ - } -} - -static gboolean -ecmt_is_cell_editable (ETableModel *etm, int col, int row) -{ - ECalModelTasksPrivate *priv; - ECalModelTasks *model = (ECalModelTasks *) etm; - - g_return_val_if_fail (E_IS_CAL_MODEL_TASKS (model), FALSE); - - priv = model->priv; - - g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_TASKS_FIELD_LAST, FALSE); - - /* FIXME: We can't check this as 'click-to-add' passes row 0. */ - /* g_return_val_if_fail (row >= 0 && row < e_table_model_get_row_count (etm), FALSE); */ - - if (col < E_CAL_MODEL_FIELD_LAST) - return E_TABLE_MODEL_CLASS (parent_class)->is_cell_editable (etm, col, row); - - switch (col) { - case E_CAL_MODEL_TASKS_FIELD_COMPLETED : - case E_CAL_MODEL_TASKS_FIELD_COMPLETE : - case E_CAL_MODEL_TASKS_FIELD_DUE : - case E_CAL_MODEL_TASKS_FIELD_GEO : - case E_CAL_MODEL_TASKS_FIELD_PERCENT : - case E_CAL_MODEL_TASKS_FIELD_PRIORITY : - case E_CAL_MODEL_TASKS_FIELD_URL : - return TRUE; - } - - return FALSE; -} - -static void * -ecmt_duplicate_value (ETableModel *etm, int col, const void *value) -{ - g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_TASKS_FIELD_LAST, NULL); - - if (col < E_CAL_MODEL_FIELD_LAST) - return E_TABLE_MODEL_CLASS (parent_class)->duplicate_value (etm, col, value); - - switch (col) { - case E_CAL_MODEL_TASKS_FIELD_GEO : - case E_CAL_MODEL_TASKS_FIELD_PRIORITY : - case E_CAL_MODEL_TASKS_FIELD_STATUS : - case E_CAL_MODEL_TASKS_FIELD_URL : - return g_strdup (value); - case E_CAL_MODEL_TASKS_FIELD_COMPLETED : - case E_CAL_MODEL_TASKS_FIELD_DUE : - /* FIXME */ - break; - case E_CAL_MODEL_TASKS_FIELD_COMPLETE : - case E_CAL_MODEL_TASKS_FIELD_PERCENT : - case E_CAL_MODEL_TASKS_FIELD_OVERDUE : - return (void *) value; - } - - return NULL; -} - -static void -ecmt_free_value (ETableModel *etm, int col, void *value) -{ - g_return_if_fail (col >= 0 && col < E_CAL_MODEL_TASKS_FIELD_LAST); - - if (col < E_CAL_MODEL_FIELD_LAST) { - E_TABLE_MODEL_CLASS (parent_class)->free_value (etm, col, value); - return; - } - - switch (col) { - case E_CAL_MODEL_TASKS_FIELD_COMPLETED : - case E_CAL_MODEL_TASKS_FIELD_DUE : - case E_CAL_MODEL_TASKS_FIELD_GEO : - case E_CAL_MODEL_TASKS_FIELD_PRIORITY : - case E_CAL_MODEL_TASKS_FIELD_STATUS : - case E_CAL_MODEL_TASKS_FIELD_URL : - if (value) - g_free (value); - break; - case E_CAL_MODEL_TASKS_FIELD_PERCENT : - case E_CAL_MODEL_TASKS_FIELD_COMPLETE : - case E_CAL_MODEL_TASKS_FIELD_OVERDUE : - break; - } -} - -static void * -ecmt_initialize_value (ETableModel *etm, int col) -{ - ECalModelTasks *model = (ECalModelTasks *) etm; - - g_return_val_if_fail (E_IS_CAL_MODEL_TASKS (model), NULL); - g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_TASKS_FIELD_LAST, NULL); - - if (col < E_CAL_MODEL_FIELD_LAST) - return E_TABLE_MODEL_CLASS (parent_class)->initialize_value (etm, col); - - switch (col) { - case E_CAL_MODEL_TASKS_FIELD_GEO : - case E_CAL_MODEL_TASKS_FIELD_PRIORITY : - case E_CAL_MODEL_TASKS_FIELD_STATUS : - case E_CAL_MODEL_TASKS_FIELD_URL : - return g_strdup (""); - case E_CAL_MODEL_TASKS_FIELD_COMPLETED : - case E_CAL_MODEL_TASKS_FIELD_DUE : - case E_CAL_MODEL_TASKS_FIELD_COMPLETE : - case E_CAL_MODEL_TASKS_FIELD_OVERDUE : - return NULL; - case E_CAL_MODEL_TASKS_FIELD_PERCENT : - return GINT_TO_POINTER (-1); - } - - return NULL; -} - -static gboolean -ecmt_value_is_empty (ETableModel *etm, int col, const void *value) -{ - ECalModelTasksPrivate *priv; - ECalModelTasks *model = (ECalModelTasks *) etm; - - g_return_val_if_fail (E_IS_CAL_MODEL_TASKS (model), TRUE); - g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_TASKS_FIELD_LAST, TRUE); - - priv = model->priv; - - if (col < E_CAL_MODEL_FIELD_LAST) - return E_TABLE_MODEL_CLASS (parent_class)->value_is_empty (etm, col, value); - - switch (col) { - case E_CAL_MODEL_TASKS_FIELD_GEO : - case E_CAL_MODEL_TASKS_FIELD_PRIORITY : - case E_CAL_MODEL_TASKS_FIELD_STATUS : - case E_CAL_MODEL_TASKS_FIELD_URL : - return string_is_empty (value); - case E_CAL_MODEL_TASKS_FIELD_COMPLETED : - case E_CAL_MODEL_TASKS_FIELD_DUE : - return value ? FALSE : TRUE; - case E_CAL_MODEL_TASKS_FIELD_PERCENT : - return (GPOINTER_TO_INT (value) < 0) ? TRUE : FALSE; - case E_CAL_MODEL_TASKS_FIELD_COMPLETE : - case E_CAL_MODEL_TASKS_FIELD_OVERDUE : - return TRUE; - } - - return TRUE; -} - -static char * -ecmt_value_to_string (ETableModel *etm, int col, const void *value) -{ - ECalModelTasks *model = (ECalModelTasks *) etm; - - g_return_val_if_fail (E_IS_CAL_MODEL_TASKS (model), NULL); - g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_TASKS_FIELD_LAST, NULL); - - if (col < E_CAL_MODEL_FIELD_LAST) - return E_TABLE_MODEL_CLASS (parent_class)->value_to_string (etm, col, value); - - switch (col) { - case E_CAL_MODEL_TASKS_FIELD_GEO : - case E_CAL_MODEL_TASKS_FIELD_PRIORITY : - case E_CAL_MODEL_TASKS_FIELD_STATUS : - case E_CAL_MODEL_TASKS_FIELD_URL : - return g_strdup (value); - case E_CAL_MODEL_TASKS_FIELD_COMPLETED : - case E_CAL_MODEL_TASKS_FIELD_DUE : - return e_cal_model_date_value_to_string (E_CAL_MODEL (model), value); - case E_CAL_MODEL_TASKS_FIELD_COMPLETE : - case E_CAL_MODEL_TASKS_FIELD_OVERDUE : - return value ? _("Yes") : _("No"); - case E_CAL_MODEL_TASKS_FIELD_PERCENT : - if (GPOINTER_TO_INT (value) < 0) - return g_strdup ("N/A"); - else - return g_strdup_printf ("%i%%", GPOINTER_TO_INT (value)); - } - - return NULL; -} - -/* ECalModel class methods */ - -static const char * -ecmt_get_color_for_component (ECalModel *model, ECalModelComponent *comp_data) -{ - g_return_val_if_fail (E_IS_CAL_MODEL_TASKS (model), NULL); - g_return_val_if_fail (comp_data != NULL, NULL); - - switch (get_due_status ((ECalModelTasks *) model, comp_data)) { - case E_CAL_MODEL_TASKS_DUE_TODAY: - return calendar_config_get_tasks_due_today_color (); - case E_CAL_MODEL_TASKS_DUE_OVERDUE: - return calendar_config_get_tasks_overdue_color (); - case E_CAL_MODEL_TASKS_DUE_NEVER: - case E_CAL_MODEL_TASKS_DUE_FUTURE: - case E_CAL_MODEL_TASKS_DUE_COMPLETE: - break; - } - - return "black"; - /* return E_CAL_MODEL_CLASS (parent_class)->get_color_for_component (model, comp_data); */ -} - -static void -ecmt_fill_component_from_model (ECalModel *model, ECalModelComponent *comp_data, - ETableModel *source_model, gint row) -{ - g_return_if_fail (E_IS_CAL_MODEL_TASKS (model)); - g_return_if_fail (comp_data != NULL); - g_return_if_fail (E_IS_TABLE_MODEL (source_model)); - - set_completed ((ECalModelTasks *) model, comp_data, - e_table_model_value_at (source_model, E_CAL_MODEL_TASKS_FIELD_COMPLETED, row)); - set_due (comp_data, - e_table_model_value_at (source_model, E_CAL_MODEL_TASKS_FIELD_DUE, row)); - set_geo (comp_data, - e_table_model_value_at (source_model, E_CAL_MODEL_TASKS_FIELD_GEO, row)); - set_percent (comp_data, - e_table_model_value_at (source_model, E_CAL_MODEL_TASKS_FIELD_PERCENT, row)); - set_priority (comp_data, - e_table_model_value_at (source_model, E_CAL_MODEL_TASKS_FIELD_PRIORITY, row)); - set_status (comp_data, - e_table_model_value_at (source_model, E_CAL_MODEL_TASKS_FIELD_STATUS, row)); - set_url (comp_data, - e_table_model_value_at (source_model, E_CAL_MODEL_TASKS_FIELD_URL, row)); -} - -/** - * e_cal_model_tasks_new - */ -ECalModelTasks * -e_cal_model_tasks_new (void) -{ - return g_object_new (E_TYPE_CAL_MODEL_TASKS, NULL); -} - -/** - * e_cal_model_tasks_mark_task_complete - */ -void -e_cal_model_tasks_mark_task_complete (ECalModelTasks *model, gint model_row) -{ - ECalModelTasksPrivate *priv; - ECalModelComponent *comp_data; - - g_return_if_fail (E_IS_CAL_MODEL_TASKS (model)); - g_return_if_fail (model_row >= 0 && model_row < e_table_model_row_count (E_TABLE_MODEL (model))); - - priv = model->priv; - - comp_data = e_cal_model_get_component_at (E_CAL_MODEL (model), model_row); - if (comp_data) - ensure_task_complete (comp_data, -1); -} diff --git a/calendar/gui/e-cal-model-tasks.h b/calendar/gui/e-cal-model-tasks.h deleted file mode 100644 index b7c5786ab4..0000000000 --- a/calendar/gui/e-cal-model-tasks.h +++ /dev/null @@ -1,68 +0,0 @@ -/* Evolution calendar - Data model for ETable - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2000 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 E_CAL_MODEL_TASKS_H -#define E_CAL_MODEL_TASKS_H - -#include "e-cal-model.h" - -G_BEGIN_DECLS - -#define E_TYPE_CAL_MODEL_TASKS (e_cal_model_tasks_get_type ()) -#define E_CAL_MODEL_TASKS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CAL_MODEL_TASKS, ECalModelTasks)) -#define E_CAL_MODEL_TASKS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CAL_MODEL_TASKS, ECalModelTasksClass)) -#define E_IS_CAL_MODEL_TASKS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CAL_MODEL_TASKS)) -#define E_IS_CAL_MODEL_TASKS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CAL_MODEL_TASKS)) - -typedef struct _ECalModelTasksPrivate ECalModelTasksPrivate; - -typedef enum { - /* If you add new items here or reorder them, you have to update the - .etspec files for the tables using this model */ - E_CAL_MODEL_TASKS_FIELD_COMPLETED = E_CAL_MODEL_FIELD_LAST, - E_CAL_MODEL_TASKS_FIELD_COMPLETE, - E_CAL_MODEL_TASKS_FIELD_DUE, - E_CAL_MODEL_TASKS_FIELD_GEO, - E_CAL_MODEL_TASKS_FIELD_OVERDUE, - E_CAL_MODEL_TASKS_FIELD_PERCENT, - E_CAL_MODEL_TASKS_FIELD_PRIORITY, - E_CAL_MODEL_TASKS_FIELD_STATUS, - E_CAL_MODEL_TASKS_FIELD_URL, - E_CAL_MODEL_TASKS_FIELD_LAST -} ECalModelTasksField; - -typedef struct { - ECalModel model; - ECalModelTasksPrivate *priv; -} ECalModelTasks; - -typedef struct { - ECalModelClass parent_class; -} ECalModelTasksClass; - -GType e_cal_model_tasks_get_type (void); -ECalModelTasks *e_cal_model_tasks_new (void); - -void e_cal_model_tasks_mark_task_complete (ECalModelTasks *model, gint model_row); - -G_END_DECLS - -#endif diff --git a/calendar/gui/e-cal-model.c b/calendar/gui/e-cal-model.c deleted file mode 100644 index 9ac1104380..0000000000 --- a/calendar/gui/e-cal-model.c +++ /dev/null @@ -1,1597 +0,0 @@ -/* Evolution calendar - Data model for ETable - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2000 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 <string.h> -#include <glib/garray.h> -#include <libgnome/gnome-i18n.h> -#include <gal/util/e-util.h> -#include <e-util/e-config-listener.h> -#include <e-util/e-time-utils.h> -#include <libecal/e-cal-time-util.h> -#include "calendar-config.h" -#include "comp-util.h" -#include "e-cal-model.h" -#include "itip-utils.h" -#include "misc.h" - -typedef struct { - ECal *client; - ECalView *query; -} ECalModelClient; - -struct _ECalModelPrivate { - /* The list of clients we are managing. Each element is of type ECalModelClient */ - GList *clients; - - /* The default client in the list */ - ECal *default_client; - - /* Array for storing the objects. Each element is of type ECalModelComponent */ - GPtrArray *objects; - - icalcomponent_kind kind; - icaltimezone *zone; - - /* The search regular expression */ - gchar *sexp; - - /* The default category */ - gchar *default_category; - - /* Addresses for determining icons */ - EAccountList *accounts; - - /* Whether we display dates in 24-hour format. */ - gboolean use_24_hour_format; -}; - -static void e_cal_model_class_init (ECalModelClass *klass); -static void e_cal_model_init (ECalModel *model, ECalModelClass *klass); -static void e_cal_model_finalize (GObject *object); - -static int ecm_column_count (ETableModel *etm); -static int ecm_row_count (ETableModel *etm); -static void *ecm_value_at (ETableModel *etm, int col, int row); -static void ecm_set_value_at (ETableModel *etm, int col, int row, const void *value); -static gboolean ecm_is_cell_editable (ETableModel *etm, int col, int row); -static void ecm_append_row (ETableModel *etm, ETableModel *source, int row); -static void *ecm_duplicate_value (ETableModel *etm, int col, const void *value); -static void ecm_free_value (ETableModel *etm, int col, void *value); -static void *ecm_initialize_value (ETableModel *etm, int col); -static gboolean ecm_value_is_empty (ETableModel *etm, int col, const void *value); -static char *ecm_value_to_string (ETableModel *etm, int col, const void *value); - -static const char *ecm_get_color_for_component (ECalModel *model, ECalModelComponent *comp_data); - -static GObjectClass *parent_class = NULL; - -E_MAKE_TYPE (e_cal_model, "ECalModel", ECalModel, e_cal_model_class_init, - e_cal_model_init, E_TABLE_MODEL_TYPE); - -static void -e_cal_model_class_init (ECalModelClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - ETableModelClass *etm_class = E_TABLE_MODEL_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - object_class->finalize = e_cal_model_finalize; - - etm_class->column_count = ecm_column_count; - etm_class->row_count = ecm_row_count; - etm_class->value_at = ecm_value_at; - etm_class->set_value_at = ecm_set_value_at; - etm_class->is_cell_editable = ecm_is_cell_editable; - etm_class->append_row = ecm_append_row; - etm_class->duplicate_value = ecm_duplicate_value; - etm_class->free_value = ecm_free_value; - etm_class->initialize_value = ecm_initialize_value; - etm_class->value_is_empty = ecm_value_is_empty; - etm_class->value_to_string = ecm_value_to_string; - - klass->get_color_for_component = ecm_get_color_for_component; - klass->fill_component_from_model = NULL; -} - -static void -e_cal_model_init (ECalModel *model, ECalModelClass *klass) -{ - ECalModelPrivate *priv; - - priv = g_new0 (ECalModelPrivate, 1); - model->priv = priv; - - priv->sexp = g_strdup ("#t"); /* match all by default */ - - priv->objects = g_ptr_array_new (); - priv->kind = ICAL_NO_COMPONENT; - - priv->accounts = itip_addresses_get (); - - priv->use_24_hour_format = TRUE; -} - -static void -free_comp_data (ECalModelComponent *comp_data) -{ - g_return_if_fail (comp_data != NULL); - - comp_data->client = NULL; - - if (comp_data->icalcomp) { - icalcomponent_free (comp_data->icalcomp); - comp_data->icalcomp = NULL; - } - - if (comp_data->dtstart) { - g_free (comp_data->dtstart); - comp_data->dtstart = NULL; - } - - if (comp_data->dtend) { - g_free (comp_data->dtend); - comp_data->dtend = NULL; - } - - if (comp_data->due) { - g_free (comp_data->due); - comp_data->due = NULL; - } - - if (comp_data->completed) { - g_free (comp_data->completed); - comp_data->completed = NULL; - } - - g_free (comp_data); -} - -static void -clear_objects_array (ECalModelPrivate *priv) -{ - gint i; - - for (i = 0; i < priv->objects->len; i++) { - ECalModelComponent *comp_data; - - comp_data = g_ptr_array_index (priv->objects, i); - g_assert (comp_data != NULL); - free_comp_data (comp_data); - } - - - g_ptr_array_set_size (priv->objects, 0); -} - -static void -e_cal_model_finalize (GObject *object) -{ - ECalModelPrivate *priv; - ECalModel *model = (ECalModel *) object; - - g_return_if_fail (E_IS_CAL_MODEL (model)); - - priv = model->priv; - if (priv) { - if (priv->clients) { - while (priv->clients != NULL) { - ECalModelClient *client_data = (ECalModelClient *) priv->clients->data; - - g_signal_handlers_disconnect_matched (client_data->client, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, model); - g_signal_handlers_disconnect_matched (client_data->query, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, model); - - priv->clients = g_list_remove (priv->clients, client_data); - g_object_unref (client_data->client); - g_object_unref (client_data->query); - g_free (client_data); - } - - priv->clients = NULL; - } - - if (priv->sexp) { - g_free (priv->sexp); - priv->sexp = NULL; - } - - if (priv->default_category) { - g_free (priv->default_category); - priv->default_category = NULL; - } - - if (priv->objects) { - clear_objects_array (priv); - g_ptr_array_free (priv->objects, FALSE); - priv->objects = NULL; - } - - if (priv->accounts) { - priv->accounts = NULL; - } - - g_free (priv); - model->priv = NULL; - } - - if (parent_class->finalize) - parent_class->finalize (object); -} - -/* ETableModel methods */ - -static int -ecm_column_count (ETableModel *etm) -{ - return E_CAL_MODEL_FIELD_LAST; -} - -static int -ecm_row_count (ETableModel *etm) -{ - ECalModelPrivate *priv; - ECalModel *model = (ECalModel *) etm; - - g_return_val_if_fail (E_IS_CAL_MODEL (model), -1); - - priv = model->priv; - - return priv->objects->len; -} - -static char * -get_categories (ECalModelComponent *comp_data) -{ - icalproperty *prop; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_CATEGORIES_PROPERTY); - if (prop) - return (char *) icalproperty_get_categories (prop); - - return ""; -} - -static char * -get_classification (ECalModelComponent *comp_data) -{ - icalproperty *prop; - icalproperty_class class; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_CLASS_PROPERTY); - - if (!prop) - return _("Public"); - - class = icalproperty_get_class (prop); - - switch (class) - { - case ICAL_CLASS_PUBLIC: - return _("Public"); - case ICAL_CLASS_PRIVATE: - return _("Private"); - case ICAL_CLASS_CONFIDENTIAL: - return _("Confidential"); - default: - return _("Unknown"); - } - - return _("Unknown"); -} - -static const char * -get_color (ECalModel *model, ECalModelComponent *comp_data) -{ - g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL); - - return e_cal_model_get_color_for_component (model, comp_data); -} - -static char * -get_description (ECalModelComponent *comp_data) -{ - icalproperty *prop; - static GString *str = NULL; - - if (str) - g_string_free (str, TRUE); - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_DESCRIPTION_PROPERTY); - if (prop) { - str = g_string_new (""); - do { - str = g_string_append (str, icalproperty_get_description (prop)); - } while ((prop = icalcomponent_get_next_property (comp_data->icalcomp, ICAL_DESCRIPTION_PROPERTY))); - - return str->str; - } - - return ""; -} - -static ECellDateEditValue* -get_dtstart (ECalModel *model, ECalModelComponent *comp_data) -{ - ECalModelPrivate *priv; - struct icaltimetype tt_start; - - priv = model->priv; - - if (!comp_data->dtstart) { - icaltimezone *zone; - icalproperty *prop; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_DTSTART_PROPERTY); - if (!prop) - return NULL; - - tt_start = icalproperty_get_dtstart (prop); - if (!icaltime_is_valid_time (tt_start)) - return NULL; - - comp_data->dtstart = g_new0 (ECellDateEditValue, 1); - comp_data->dtstart->tt = tt_start; - - if (icaltime_get_tzid (tt_start) - && e_cal_get_timezone (comp_data->client, icaltime_get_tzid (tt_start), &zone, NULL)) - comp_data->dtstart->zone = zone; - else - comp_data->dtstart->zone = NULL; - } - - return comp_data->dtstart; -} - -static char * -get_summary (ECalModelComponent *comp_data) -{ - icalproperty *prop; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_SUMMARY_PROPERTY); - if (prop) - return (char *) icalproperty_get_summary (prop); - - return ""; -} - -static char * -get_uid (ECalModelComponent *comp_data) -{ - return (char *) icalcomponent_get_uid (comp_data->icalcomp); -} - -static void * -ecm_value_at (ETableModel *etm, int col, int row) -{ - ECalModelPrivate *priv; - ECalModelComponent *comp_data; - ECalModel *model = (ECalModel *) etm; - - g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL); - - priv = model->priv; - - g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_FIELD_LAST, NULL); - g_return_val_if_fail (row >= 0 && row < priv->objects->len, NULL); - - comp_data = g_ptr_array_index (priv->objects, row); - g_assert (comp_data != NULL); - - switch (col) { - case E_CAL_MODEL_FIELD_CATEGORIES : - return get_categories (comp_data); - case E_CAL_MODEL_FIELD_CLASSIFICATION : - return get_classification (comp_data); - case E_CAL_MODEL_FIELD_COLOR : - return (void *) get_color (model, comp_data); - case E_CAL_MODEL_FIELD_COMPONENT : - return comp_data->icalcomp; - case E_CAL_MODEL_FIELD_DESCRIPTION : - return get_description (comp_data); - case E_CAL_MODEL_FIELD_DTSTART : - return (void *) get_dtstart (model, comp_data); - case E_CAL_MODEL_FIELD_HAS_ALARMS : - return GINT_TO_POINTER ((icalcomponent_get_first_component (comp_data->icalcomp, - ICAL_VALARM_COMPONENT) != NULL)); - case E_CAL_MODEL_FIELD_ICON : - { - ECalComponent *comp; - icalcomponent *icalcomp; - gint retval = 0; - - comp = e_cal_component_new (); - icalcomp = icalcomponent_new_clone (comp_data->icalcomp); - if (e_cal_component_set_icalcomponent (comp, icalcomp)) { - if (e_cal_component_has_recurrences (comp)) - retval = 1; - else if (itip_organizer_is_user (comp, comp_data->client)) - retval = 3; - else { - GSList *attendees = NULL, *sl; - - e_cal_component_get_attendee_list (comp, &attendees); - for (sl = attendees; sl != NULL; sl = sl->next) { - ECalComponentAttendee *ca = sl->data; - const char *text; - - text = itip_strip_mailto (ca->value); - if (e_account_list_find (priv->accounts, E_ACCOUNT_FIND_ID_ADDRESS, text) != NULL) { - if (ca->delto != NULL) - retval = 3; - else - retval = 2; - break; - } - } - - e_cal_component_free_attendee_list (attendees); - } - } else - icalcomponent_free (icalcomp); - - g_object_unref (comp); - - return GINT_TO_POINTER (retval); - } - case E_CAL_MODEL_FIELD_SUMMARY : - return get_summary (comp_data); - case E_CAL_MODEL_FIELD_UID : - return get_uid (comp_data); - } - - return ""; -} - -static void -set_categories (ECalModelComponent *comp_data, const char *value) -{ - icalproperty *prop; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_CATEGORIES_PROPERTY); - if (!value || !(*value)) { - if (prop) { - icalcomponent_remove_property (comp_data->icalcomp, prop); - icalproperty_free (prop); - } - } else { - if (!prop) { - prop = icalproperty_new_categories (value); - icalcomponent_add_property (comp_data->icalcomp, prop); - } else - icalproperty_set_categories (prop, value); - } -} - -static void -set_classification (ECalModelComponent *comp_data, const char *value) -{ - icalproperty *prop; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_CLASS_PROPERTY); - if (!value || !(*value)) { - if (prop) { - icalcomponent_remove_property (comp_data->icalcomp, prop); - icalproperty_free (prop); - } - } else { - icalproperty_class ical_class; - - if (!strcasecmp (value, "PUBLIC")) - ical_class = ICAL_CLASS_PUBLIC; - else if (!strcasecmp (value, "PRIVATE")) - ical_class = ICAL_CLASS_PRIVATE; - else if (!strcasecmp (value, "CONFIDENTIAL")) - ical_class = ICAL_CLASS_CONFIDENTIAL; - else - ical_class = ICAL_CLASS_NONE; - - if (!prop) { - prop = icalproperty_new_class (ical_class); - icalcomponent_add_property (comp_data->icalcomp, prop); - } else - icalproperty_set_class (prop, ical_class); - } -} - -static void -set_description (ECalModelComponent *comp_data, const char *value) -{ - icalproperty *prop; - - /* remove old description(s) */ - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_DESCRIPTION_PROPERTY); - while (prop) { - icalproperty *next; - - next = icalcomponent_get_next_property (comp_data->icalcomp, ICAL_DESCRIPTION_PROPERTY); - - icalcomponent_remove_property (comp_data->icalcomp, prop); - icalproperty_free (prop); - - prop = next; - } - - /* now add the new description */ - if (!value || !(*value)) - return; - - prop = icalproperty_new_description (value); - icalcomponent_add_property (comp_data->icalcomp, prop); -} - -static void -set_dtstart (ECalModel *model, ECalModelComponent *comp_data, const void *value) -{ - icalproperty *prop; - ECellDateEditValue *dv = (ECellDateEditValue *) value; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_DTSTART_PROPERTY); - if (!dv) { - if (prop) { - icalcomponent_remove_property (comp_data->icalcomp, prop); - icalproperty_free (prop); - } - } else - icalcomponent_set_dtstart (comp_data->icalcomp, dv->tt); -} - -static void -set_summary (ECalModelComponent *comp_data, const char *value) -{ - icalproperty *prop; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_SUMMARY_PROPERTY); - - if (string_is_empty (value)) { - if (prop) { - icalcomponent_remove_property (comp_data->icalcomp, prop); - icalproperty_free (prop); - } - } else { - if (prop) - icalproperty_set_summary (prop, value); - else { - prop = icalproperty_new_summary (value); - icalcomponent_add_property (comp_data->icalcomp, prop); - } - } -} - -static void -ecm_set_value_at (ETableModel *etm, int col, int row, const void *value) -{ - ECalModelPrivate *priv; - ECalModelComponent *comp_data; - ECalModel *model = (ECalModel *) etm; - - g_return_if_fail (E_IS_CAL_MODEL (model)); - - priv = model->priv; - - g_return_if_fail (col >= 0 && col < E_CAL_MODEL_FIELD_LAST); - g_return_if_fail (row >= 0 && row < priv->objects->len); - - comp_data = g_ptr_array_index (priv->objects, row); - g_assert (comp_data != NULL); - - switch (col) { - case E_CAL_MODEL_FIELD_CATEGORIES : - set_categories (comp_data, value); - break; - case E_CAL_MODEL_FIELD_CLASSIFICATION : - set_classification (comp_data, value); - break; - case E_CAL_MODEL_FIELD_DESCRIPTION : - set_description (comp_data, value); - break; - case E_CAL_MODEL_FIELD_DTSTART : - set_dtstart (model, comp_data, value); - break; - case E_CAL_MODEL_FIELD_SUMMARY : - set_summary (comp_data, value); - break; - } - - /* FIXME ask about mod type */ - if (!e_cal_modify_object (comp_data->client, comp_data->icalcomp, CALOBJ_MOD_ALL, NULL)) { - g_warning (G_STRLOC ": Could not modify the object!"); - - /* FIXME Show error dialog */ - } -} - -static gboolean -ecm_is_cell_editable (ETableModel *etm, int col, int row) -{ - ECalModelPrivate *priv; - ECalModel *model = (ECalModel *) etm; - - g_return_val_if_fail (E_IS_CAL_MODEL (model), FALSE); - - priv = model->priv; - - g_return_val_if_fail (col >= 0 && col <= E_CAL_MODEL_FIELD_LAST, 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 E_CAL_MODEL_FIELD_CATEGORIES : - case E_CAL_MODEL_FIELD_CLASSIFICATION : - case E_CAL_MODEL_FIELD_DESCRIPTION : - case E_CAL_MODEL_FIELD_DTSTART : - case E_CAL_MODEL_FIELD_SUMMARY : - return TRUE; - } - - return FALSE; -} - -static void -ecm_append_row (ETableModel *etm, ETableModel *source, int row) -{ - ECalModelClass *model_class; - ECalModelComponent comp_data; - ECalModel *model = (ECalModel *) etm; - - g_return_if_fail (E_IS_CAL_MODEL (model)); - g_return_if_fail (E_IS_TABLE_MODEL (source)); - - memset (&comp_data, 0, sizeof (comp_data)); - comp_data.client = e_cal_model_get_default_client (model); - - /* guard against saving before the calendar is open */ - if (!(comp_data.client && e_cal_get_load_state (comp_data.client) == E_CAL_LOAD_LOADED)) - return; - - comp_data.icalcomp = e_cal_model_create_component_with_defaults (model); - - /* set values for our fields */ - set_categories (&comp_data, e_table_model_value_at (source, E_CAL_MODEL_FIELD_CATEGORIES, row)); - set_classification (&comp_data, e_table_model_value_at (source, E_CAL_MODEL_FIELD_CLASSIFICATION, row)); - set_description (&comp_data, e_table_model_value_at (source, E_CAL_MODEL_FIELD_DESCRIPTION, row)); - set_dtstart (model, &comp_data, e_table_model_value_at (source, E_CAL_MODEL_FIELD_DTSTART, row)); - set_summary (&comp_data, e_table_model_value_at (source, E_CAL_MODEL_FIELD_SUMMARY, row)); - - /* call the class' method for filling the component */ - model_class = (ECalModelClass *) G_OBJECT_GET_CLASS (model); - if (model_class->fill_component_from_model != NULL) { - model_class->fill_component_from_model (model, &comp_data, source, row); - } - - - if (!e_cal_create_object (comp_data.client, comp_data.icalcomp, NULL, NULL)) { - g_warning (G_STRLOC ": Could not create the object!"); - - /* FIXME: show error dialog */ - } - - icalcomponent_free (comp_data.icalcomp); -} - -static void * -ecm_duplicate_value (ETableModel *etm, int col, const void *value) -{ - g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_FIELD_LAST, NULL); - - switch (col) { - case E_CAL_MODEL_FIELD_CATEGORIES : - case E_CAL_MODEL_FIELD_CLASSIFICATION : - case E_CAL_MODEL_FIELD_SUMMARY : - return g_strdup (value); - case E_CAL_MODEL_FIELD_HAS_ALARMS : - case E_CAL_MODEL_FIELD_ICON : - case E_CAL_MODEL_FIELD_COLOR : - return (void *) value; - case E_CAL_MODEL_FIELD_COMPONENT : - return icalcomponent_new_clone ((icalcomponent *) value); - case E_CAL_MODEL_FIELD_DTSTART : - if (value) { - ECellDateEditValue *dv, *orig_dv; - - orig_dv = (ECellDateEditValue *) value; - dv = g_new0 (ECellDateEditValue, 1); - *dv = *orig_dv; - - return dv; - } - break; - } - - return NULL; -} - -static void -ecm_free_value (ETableModel *etm, int col, void *value) -{ - g_return_if_fail (col >= 0 && col < E_CAL_MODEL_FIELD_LAST); - - switch (col) { - case E_CAL_MODEL_FIELD_CATEGORIES : - case E_CAL_MODEL_FIELD_DESCRIPTION : - case E_CAL_MODEL_FIELD_SUMMARY : - if (value) - g_free (value); - break; - case E_CAL_MODEL_FIELD_CLASSIFICATION : - case E_CAL_MODEL_FIELD_HAS_ALARMS : - case E_CAL_MODEL_FIELD_ICON : - case E_CAL_MODEL_FIELD_COLOR : - break; - case E_CAL_MODEL_FIELD_DTSTART : - if (value) - g_free (value); - break; - case E_CAL_MODEL_FIELD_COMPONENT : - if (value) - icalcomponent_free ((icalcomponent *) value); - break; - } -} - -static void * -ecm_initialize_value (ETableModel *etm, int col) -{ - ECalModelPrivate *priv; - ECalModel *model = (ECalModel *) etm; - - g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL); - g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_FIELD_LAST, NULL); - - priv = model->priv; - - switch (col) { - case E_CAL_MODEL_FIELD_CATEGORIES : - return g_strdup (priv->default_category); - case E_CAL_MODEL_FIELD_CLASSIFICATION : - case E_CAL_MODEL_FIELD_DESCRIPTION : - case E_CAL_MODEL_FIELD_SUMMARY : - return g_strdup (""); - case E_CAL_MODEL_FIELD_DTSTART : - case E_CAL_MODEL_FIELD_HAS_ALARMS : - case E_CAL_MODEL_FIELD_ICON : - case E_CAL_MODEL_FIELD_COLOR : - case E_CAL_MODEL_FIELD_COMPONENT : - return NULL; - } - - return NULL; -} - -static gboolean -ecm_value_is_empty (ETableModel *etm, int col, const void *value) -{ - ECalModelPrivate *priv; - ECalModel *model = (ECalModel *) etm; - - g_return_val_if_fail (E_IS_CAL_MODEL (model), TRUE); - g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_FIELD_LAST, TRUE); - - priv = model->priv; - - switch (col) { - case E_CAL_MODEL_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 - * ecm_initialize_value(). - */ - if (priv->default_category && value && strcmp (priv->default_category, value) == 0) - return TRUE; - else - return string_is_empty (value); - case E_CAL_MODEL_FIELD_CLASSIFICATION : - case E_CAL_MODEL_FIELD_DESCRIPTION : - case E_CAL_MODEL_FIELD_SUMMARY : - return string_is_empty (value); - case E_CAL_MODEL_FIELD_DTSTART : - return value ? FALSE : TRUE; - case E_CAL_MODEL_FIELD_HAS_ALARMS : - case E_CAL_MODEL_FIELD_ICON : - case E_CAL_MODEL_FIELD_COLOR : - case E_CAL_MODEL_FIELD_COMPONENT : - return TRUE; - } - - return TRUE; -} - -static char * -ecm_value_to_string (ETableModel *etm, int col, const void *value) -{ - g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_FIELD_LAST, NULL); - - switch (col) { - case E_CAL_MODEL_FIELD_CATEGORIES : - case E_CAL_MODEL_FIELD_CLASSIFICATION : - case E_CAL_MODEL_FIELD_DESCRIPTION : - case E_CAL_MODEL_FIELD_SUMMARY : - return g_strdup (value); - case E_CAL_MODEL_FIELD_DTSTART : - return e_cal_model_date_value_to_string (E_CAL_MODEL (etm), value); - case E_CAL_MODEL_FIELD_ICON : - if (GPOINTER_TO_INT (value) == 0) - return _("Normal"); - else if (GPOINTER_TO_INT (value) == 1) - return _("Recurring"); - else - return _("Assigned"); - case E_CAL_MODEL_FIELD_HAS_ALARMS : - return value ? _("Yes") : _("No"); - case E_CAL_MODEL_FIELD_COLOR : - case E_CAL_MODEL_FIELD_COMPONENT : - return NULL; - } - - return NULL; -} - -/* ECalModel class methods */ - -typedef struct { - const gchar *color; - GList *uris; -} AssignedColorData; - -static const char * -ecm_get_color_for_component (ECalModel *model, ECalModelComponent *comp_data) -{ - ECalModelPrivate *priv; - gint i, first_empty = 0; - static AssignedColorData assigned_colors[] = { - { "#BECEDD", NULL }, /* 190 206 221 Blue */ - { "#E2F0EF", NULL }, /* 226 240 239 Light Blue */ - { "#C6E2B7", NULL }, /* 198 226 183 Green */ - { "#E2F0D3", NULL }, /* 226 240 211 Light Green */ - { "#E2D4B7", NULL }, /* 226 212 183 Khaki */ - { "#EAEAC1", NULL }, /* 234 234 193 Light Khaki */ - { "#F0B8B7", NULL }, /* 240 184 183 Pink */ - { "#FED4D3", NULL }, /* 254 212 211 Light Pink */ - { "#E2C6E1", NULL }, /* 226 198 225 Purple */ - { "#F0E2EF", NULL } /* 240 226 239 Light Purple */ - }; - - g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL); - - priv = model->priv; - - for (i = 0; i < G_N_ELEMENTS (assigned_colors); i++) { - GList *l; - - if (assigned_colors[i].uris == NULL) { - first_empty = i; - continue; - } - - for (l = assigned_colors[i].uris; l != NULL; l = l->next) { - if (!strcmp ((const char *) l->data, - e_cal_get_uri (comp_data->client))) - { - return assigned_colors[i].color; - } - } - } - - /* return the first unused color */ - assigned_colors[first_empty].uris = g_list_append (assigned_colors[first_empty].uris, - g_strdup (e_cal_get_uri (comp_data->client))); - - return assigned_colors[first_empty].color; -} - -/** - * e_cal_model_get_component_kind - */ -icalcomponent_kind -e_cal_model_get_component_kind (ECalModel *model) -{ - ECalModelPrivate *priv; - - g_return_val_if_fail (E_IS_CAL_MODEL (model), ICAL_NO_COMPONENT); - - priv = model->priv; - return priv->kind; -} - -/** - * e_cal_model_set_component_kind - */ -void -e_cal_model_set_component_kind (ECalModel *model, icalcomponent_kind kind) -{ - ECalModelPrivate *priv; - - g_return_if_fail (E_IS_CAL_MODEL (model)); - - priv = model->priv; - priv->kind = kind; -} - -/** - * e_cal_model_get_timezone - */ -icaltimezone * -e_cal_model_get_timezone (ECalModel *model) -{ - g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL); - return model->priv->zone; -} - -/** - * e_cal_model_set_timezone - */ -void -e_cal_model_set_timezone (ECalModel *model, icaltimezone *zone) -{ - ECalModelPrivate *priv; - - g_return_if_fail (E_IS_CAL_MODEL (model)); - - priv = model->priv; - if (priv->zone != zone) { - e_table_model_pre_change (E_TABLE_MODEL (model)); - priv->zone = zone; - - /* the timezone affects the times shown for date fields, - so we need to redisplay everything */ - e_table_model_changed (E_TABLE_MODEL (model)); - } -} - -/** - * e_cal_model_set_default_category - */ -void -e_cal_model_set_default_category (ECalModel *model, const gchar *default_cat) -{ - g_return_if_fail (E_IS_CAL_MODEL (model)); - - if (model->priv->default_category) - g_free (model->priv->default_category); - - model->priv->default_category = g_strdup (default_cat); -} - -/** - * e_cal_model_get_use_24_hour_format - */ -gboolean -e_cal_model_get_use_24_hour_format (ECalModel *model) -{ - g_return_val_if_fail (E_IS_CAL_MODEL (model), FALSE); - - return model->priv->use_24_hour_format; -} - -/** - * e_cal_model_set_use_24_hour_format - */ -void -e_cal_model_set_use_24_hour_format (ECalModel *model, gboolean use24) -{ - g_return_if_fail (E_IS_CAL_MODEL (model)); - - if (model->priv->use_24_hour_format != use24) { - e_table_model_pre_change (E_TABLE_MODEL (model)); - model->priv->use_24_hour_format = use24; - /* Get the views to redraw themselves. */ - e_table_model_changed (E_TABLE_MODEL (model)); - } -} - -/** - * e_cal_model_get_default_client - */ -ECal * -e_cal_model_get_default_client (ECalModel *model) -{ - ECalModelPrivate *priv; - ECalModelClient *client_data; - - g_return_val_if_fail (model != NULL, NULL); - g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL); - - priv = model->priv; - - /* we always return a valid ECal, since we rely on it in many places */ - if (priv->default_client) - return priv->default_client; - - if (!priv->clients) - return NULL; - - client_data = (ECalModelClient *) priv->clients->data; - - return client_data ? client_data->client : NULL; -} - -void -e_cal_model_set_default_client (ECalModel *model, ECal *client) -{ - ECalModelPrivate *priv; - GList *l; - gboolean found = FALSE; - - g_return_if_fail (model != NULL); - g_return_if_fail (E_IS_CAL_MODEL (model)); - g_return_if_fail (client != NULL); - g_return_if_fail (E_IS_CAL (client)); - - priv = model->priv; - - /* See if we already know about the client */ - for (l = priv->clients; l != NULL; l = l->next) { - ECalModelClient *client_data = l->data; - - if (client == client_data->client) - found = TRUE; - } - - /* If its not found, add it */ - if (!found) - e_cal_model_add_client (model, client); - - /* Store the default client */ - priv->default_client = client; -} - -/** - * e_cal_model_get_client_list - */ -GList * -e_cal_model_get_client_list (ECalModel *model) -{ - GList *list = NULL, *l; - - g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL); - - for (l = model->priv->clients; l != NULL; l = l->next) { - ECalModelClient *client_data = (ECalModelClient *) l->data; - - list = g_list_append (list, client_data->client); - } - - return list; -} - -/** - * e_cal_model_get_client_for_uri - * @model: A calendar model. - * @uri: Uri for the client to get. - */ -ECal * -e_cal_model_get_client_for_uri (ECalModel *model, const char *uri) -{ - GList *l; - - g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL); - g_return_val_if_fail (uri != NULL, NULL); - - for (l = model->priv->clients; l != NULL; l = l->next) { - ECalModelClient *client_data = (ECalModelClient *) l->data; - - if (!strcmp (uri, e_cal_get_uri (client_data->client))) - return client_data->client; - } - - return NULL; -} - -static ECalModelComponent * -search_by_uid_and_client (ECalModelPrivate *priv, ECal *client, const char *uid) -{ - gint i; - - for (i = 0; i < priv->objects->len; i++) { - ECalModelComponent *comp_data = g_ptr_array_index (priv->objects, i); - - if (comp_data) { - const char *tmp_uid; - - tmp_uid = icalcomponent_get_uid (comp_data->icalcomp); - if (tmp_uid && *tmp_uid) { - if (comp_data->client == client && !strcmp (uid, tmp_uid)) - return comp_data; - } - } - } - - return NULL; -} - -static gint -get_position_in_array (GPtrArray *objects, gpointer item) -{ - gint i; - - for (i = 0; i < objects->len; i++) { - if (g_ptr_array_index (objects, i) == item) - return i; - } - - return -1; -} - -static void -e_cal_view_objects_added_cb (ECalView *query, GList *objects, gpointer user_data) -{ - ECalModel *model = (ECalModel *) user_data; - ECalModelPrivate *priv; - GList *l; - - priv = model->priv; - - for (l = objects; l; l = l->next) { - ECalModelComponent *comp_data; - - e_table_model_pre_change (E_TABLE_MODEL (model)); - - comp_data = g_new0 (ECalModelComponent, 1); - comp_data->client = e_cal_view_get_client (query); - comp_data->icalcomp = icalcomponent_new_clone (l->data); - - g_ptr_array_add (priv->objects, comp_data); - - e_table_model_row_inserted (E_TABLE_MODEL (model), priv->objects->len - 1); - } -} - -static void -e_cal_view_objects_modified_cb (ECalView *query, GList *objects, gpointer user_data) -{ - ECalModelPrivate *priv; - ECalModel *model = (ECalModel *) user_data; - GList *l; - - priv = model->priv; - - for (l = objects; l; l = l->next) { - ECalModelComponent *comp_data; - - e_table_model_pre_change (E_TABLE_MODEL (model)); - - comp_data = search_by_uid_and_client (priv, e_cal_view_get_client (query), icalcomponent_get_uid (l->data)); - g_assert (comp_data); - - if (comp_data->icalcomp) - icalcomponent_free (comp_data->icalcomp); - if (comp_data->dtstart) { - g_free (comp_data->dtstart); - comp_data->dtstart = NULL; - } - if (comp_data->dtend) { - g_free (comp_data->dtend); - comp_data->dtend = NULL; - } - if (comp_data->due) { - g_free (comp_data->due); - comp_data->due = NULL; - } - if (comp_data->completed) { - g_free (comp_data->completed); - comp_data->completed = NULL; - } - - comp_data->icalcomp = icalcomponent_new_clone (l->data); - - e_table_model_row_changed (E_TABLE_MODEL (model), get_position_in_array (priv->objects, comp_data)); - } -} - -static void -e_cal_view_objects_removed_cb (ECalView *query, GList *uids, gpointer user_data) -{ - ECalModelPrivate *priv; - ECalModel *model = (ECalModel *) user_data; - GList *l; - - priv = model->priv; - - for (l = uids; l; l = l->next) { - ECalModelComponent *comp_data; - int pos; - - e_table_model_pre_change (E_TABLE_MODEL (model)); - - comp_data = search_by_uid_and_client (priv, e_cal_view_get_client (query), l->data); - g_assert (comp_data); - - pos = get_position_in_array (priv->objects, comp_data); - - g_ptr_array_remove (priv->objects, comp_data); - free_comp_data (comp_data); - - e_table_model_row_deleted (E_TABLE_MODEL (model), pos); - } -} - -static void -e_cal_view_progress_cb (ECalView *query, const char *message, int percent, gpointer user_data) -{ - ECalModel *model = (ECalModel *) user_data; - - g_return_if_fail (E_IS_CAL_MODEL (model)); - - /* FIXME Update status bar */ -} - -static void -e_cal_view_done_cb (ECalView *query, ECalendarStatus status, gpointer user_data) -{ - ECalModel *model = (ECalModel *) user_data; - - g_return_if_fail (E_IS_CAL_MODEL (model)); - - /* FIXME Clear status bar */ -} - -static void -update_e_cal_view_for_client (ECalModel *model, ECalModelClient *client_data) -{ - ECalModelPrivate *priv; - - priv = model->priv; - - /* free the previous query, if any */ - if (client_data->query) { - g_signal_handlers_disconnect_matched (client_data->query, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, model); - g_object_unref (client_data->query); - client_data->query = NULL; - } - - /* prepare the query */ - g_assert (priv->sexp != NULL); - - if (!e_cal_get_query (client_data->client, priv->sexp, &client_data->query, NULL)) { - g_warning (G_STRLOC ": Unable to get query"); - - return; - } - - g_signal_connect (client_data->query, "objects_added", G_CALLBACK (e_cal_view_objects_added_cb), model); - g_signal_connect (client_data->query, "objects_modified", G_CALLBACK (e_cal_view_objects_modified_cb), model); - g_signal_connect (client_data->query, "objects_removed", G_CALLBACK (e_cal_view_objects_removed_cb), model); - g_signal_connect (client_data->query, "view_progress", G_CALLBACK (e_cal_view_progress_cb), model); - g_signal_connect (client_data->query, "view_done", G_CALLBACK (e_cal_view_done_cb), model); - - e_cal_view_start (client_data->query); -} - -static void -backend_died_cb (ECal *client, gpointer user_data) -{ - ECalModel *model; - - model = E_CAL_MODEL (user_data); - - e_cal_model_remove_client (model, client); -} - -static void -add_new_client (ECalModel *model, ECal *client) -{ - ECalModelPrivate *priv; - ECalModelClient *client_data; - - priv = model->priv; - - client_data = g_new0 (ECalModelClient, 1); - client_data->client = client; - client_data->query = NULL; - g_object_ref (client_data->client); - - priv->clients = g_list_append (priv->clients, client_data); - - g_signal_connect (G_OBJECT (client_data->client), "backend_died", - G_CALLBACK (backend_died_cb), model); - - update_e_cal_view_for_client (model, client_data); -} - -static void -cal_opened_cb (ECal *client, ECalendarStatus status, gpointer user_data) -{ - ECalModel *model = (ECalModel *) user_data; - - if (status != E_CALENDAR_STATUS_OK) - return; - - add_new_client (model, client); -} - -/** - * e_cal_model_add_client - */ -void -e_cal_model_add_client (ECalModel *model, ECal *client) -{ - ECalModelPrivate *priv; - - g_return_if_fail (E_IS_CAL_MODEL (model)); - g_return_if_fail (E_IS_CAL (client)); - - priv = model->priv; - - if (e_cal_get_load_state (client) == E_CAL_LOAD_LOADED) - add_new_client (model, client); - else - g_signal_connect (client, "cal_opened", G_CALLBACK (cal_opened_cb), model); -} - -static void -remove_client (ECalModel *model, ECalModelClient *client_data) -{ - gint i; - - g_signal_handlers_disconnect_matched (client_data->client, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, model); - g_signal_handlers_disconnect_matched (client_data->query, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, model); - - model->priv->clients = g_list_remove (model->priv->clients, client_data); - - /* remove all objects belonging to this client */ - e_table_model_pre_change (E_TABLE_MODEL (model)); - for (i = model->priv->objects->len; i > 0; i--) { - ECalModelComponent *comp_data = (ECalModelComponent *) g_ptr_array_index (model->priv->objects, i - 1); - - g_assert (comp_data != NULL); - - if (comp_data->client == client_data->client) { - g_ptr_array_remove (model->priv->objects, comp_data); - free_comp_data (comp_data); - } - } - e_table_model_changed (E_TABLE_MODEL (model)); - - /* free all remaining memory */ - g_object_unref (client_data->client); - g_object_unref (client_data->query); - g_free (client_data); - -} - -/** - * e_cal_model_remove_client - */ -void -e_cal_model_remove_client (ECalModel *model, ECal *client) -{ - GList *l; - ECalModelPrivate *priv; - - g_return_if_fail (E_IS_CAL_MODEL (model)); - g_return_if_fail (E_IS_CAL (client)); - - priv = model->priv; - for (l = priv->clients; l != NULL; l = l->next) { - ECalModelClient *client_data = (ECalModelClient *) l->data; - - if (client_data->client == client) { - remove_client (model, client_data); - break; - } - } -} - -/** - * e_cal_model_remove_all_clients - */ -void -e_cal_model_remove_all_clients (ECalModel *model) -{ - ECalModelPrivate *priv; - - g_return_if_fail (E_IS_CAL_MODEL (model)); - - priv = model->priv; - while (priv->clients != NULL) { - ECalModelClient *client_data = (ECalModelClient *) priv->clients->data; - remove_client (model, client_data); - } -} - -/** - * e_cal_model_set_query - */ -void -e_cal_model_set_query (ECalModel *model, const char *sexp) -{ - ECalModelPrivate *priv; - GList *l; - - g_return_if_fail (E_IS_CAL_MODEL (model)); - g_return_if_fail (sexp != NULL); - - priv = model->priv; - - if (priv->sexp) - g_free (priv->sexp); - - priv->sexp = g_strdup (sexp); - - /* clean up the current contents */ - e_table_model_pre_change (E_TABLE_MODEL (model)); - clear_objects_array (priv); - e_table_model_changed (E_TABLE_MODEL (model)); - - /* update the query for all clients */ - for (l = priv->clients; l != NULL; l = l->next) { - ECalModelClient *client_data; - - client_data = (ECalModelClient *) l->data; - update_e_cal_view_for_client (model, client_data); - } -} - -/** - * e_cal_model_create_component_with_defaults - */ -icalcomponent * -e_cal_model_create_component_with_defaults (ECalModel *model) -{ - ECalModelPrivate *priv; - ECalComponent *comp; - icalcomponent *icalcomp; - ECal *client; - - g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL); - - priv = model->priv; - - g_return_val_if_fail (priv->clients != NULL, NULL); - - client = e_cal_model_get_default_client (model); - if (!client) - return icalcomponent_new (priv->kind); - - switch (priv->kind) { - case ICAL_VEVENT_COMPONENT : - comp = cal_comp_event_new_with_defaults (client); - break; - case ICAL_VTODO_COMPONENT : - comp = cal_comp_task_new_with_defaults (client); - break; - default: - return NULL; - } - - if (!comp) - return icalcomponent_new (priv->kind); - - icalcomp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (comp)); - g_object_unref (comp); - - /* make sure the component has an UID */ - if (!icalcomponent_get_uid (icalcomp)) { - char *uid; - - uid = e_cal_component_gen_uid (); - icalcomponent_set_uid (icalcomp, uid); - - g_free (uid); - } - - return icalcomp; -} - -/** - * e_cal_model_get_color_for_component - */ -const gchar * -e_cal_model_get_color_for_component (ECalModel *model, ECalModelComponent *comp_data) -{ - ECalModelClass *model_class; - const gchar *color = NULL; - - g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL); - g_return_val_if_fail (comp_data != NULL, NULL); - - model_class = (ECalModelClass *) G_OBJECT_GET_CLASS (model); - if (model_class->get_color_for_component != NULL) - color = model_class->get_color_for_component (model, comp_data); - - if (!color) - color = ecm_get_color_for_component (model, comp_data); - - return color; -} - -/** - * e_cal_model_get_component_at - */ -ECalModelComponent * -e_cal_model_get_component_at (ECalModel *model, gint row) -{ - ECalModelPrivate *priv; - - g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL); - - priv = model->priv; - - g_return_val_if_fail (row >= 0 && row < priv->objects->len, NULL); - - return g_ptr_array_index (priv->objects, row); -} - -/** - * e_cal_model_date_value_to_string - */ -gchar* -e_cal_model_date_value_to_string (ECalModel *model, const void *value) -{ - ECalModelPrivate *priv; - ECellDateEditValue *dv = (ECellDateEditValue *) value; - struct icaltimetype tt; - struct tm tmp_tm; - char buffer[64]; - - g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL); - - 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); - - memset (buffer, 0, sizeof (buffer)); - e_time_format_date_and_time (&tmp_tm, priv->use_24_hour_format, - TRUE, FALSE, - buffer, sizeof (buffer)); - return g_strdup (buffer); -} - -/** - * e_cal_model_free_component_data - */ -void -e_cal_model_free_component_data (ECalModelComponent *comp_data) -{ - g_return_if_fail (comp_data != NULL); - - if (comp_data->icalcomp) - icalcomponent_free (comp_data->icalcomp); - if (comp_data->dtstart) - g_free (comp_data->dtstart); - if (comp_data->dtend) - g_free (comp_data->dtend); - if (comp_data->due) - g_free (comp_data->due); - if (comp_data->completed) - g_free (comp_data->completed); - - g_free (comp_data); -} diff --git a/calendar/gui/e-cal-model.h b/calendar/gui/e-cal-model.h deleted file mode 100644 index 9f193b4f07..0000000000 --- a/calendar/gui/e-cal-model.h +++ /dev/null @@ -1,111 +0,0 @@ -/* Evolution calendar - Data model for ETable - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2000 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 E_CAL_MODEL_H -#define E_CAL_MODEL_H - -#include <gal/e-table/e-table-model.h> -#include <libecal/e-cal.h> -#include "e-cell-date-edit-text.h" - -G_BEGIN_DECLS - -#define E_TYPE_CAL_MODEL (e_cal_model_get_type ()) -#define E_CAL_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CAL_MODEL, ECalModel)) -#define E_CAL_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CAL_MODEL, ECalModelClass)) -#define E_IS_CAL_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CAL_MODEL)) -#define E_IS_CAL_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CAL_MODEL)) - -typedef struct _ECalModelPrivate ECalModelPrivate; - -typedef enum { - /* If you add new items here or reorder them, you have to update the - .etspec files for the tables using this model */ - E_CAL_MODEL_FIELD_CATEGORIES, - E_CAL_MODEL_FIELD_CLASSIFICATION, - E_CAL_MODEL_FIELD_COLOR, /* not a real field */ - E_CAL_MODEL_FIELD_COMPONENT, /* not a real field */ - E_CAL_MODEL_FIELD_DESCRIPTION, - E_CAL_MODEL_FIELD_DTSTART, - E_CAL_MODEL_FIELD_HAS_ALARMS, /* not a real field */ - E_CAL_MODEL_FIELD_ICON, /* not a real field */ - E_CAL_MODEL_FIELD_SUMMARY, - E_CAL_MODEL_FIELD_UID, - E_CAL_MODEL_FIELD_LAST -} ECalModelField; - -typedef struct { - ECal *client; - icalcomponent *icalcomp; - - /* private data */ - ECellDateEditValue *dtstart; - ECellDateEditValue *dtend; - ECellDateEditValue *due; - ECellDateEditValue *completed; -} ECalModelComponent; - -typedef struct { - ETableModel model; - ECalModelPrivate *priv; -} ECalModel; - -typedef struct { - ETableModelClass parent_class; - - /* virtual methods */ - const gchar * (* get_color_for_component) (ECalModel *model, ECalModelComponent *comp_data); - void (* fill_component_from_model) (ECalModel *model, ECalModelComponent *comp_data, - ETableModel *source_model, gint row); -} ECalModelClass; - -GType e_cal_model_get_type (void); - -icalcomponent_kind e_cal_model_get_component_kind (ECalModel *model); -void e_cal_model_set_component_kind (ECalModel *model, icalcomponent_kind kind); -icaltimezone *e_cal_model_get_timezone (ECalModel *model); -void e_cal_model_set_timezone (ECalModel *model, icaltimezone *zone); - -void e_cal_model_set_default_category (ECalModel *model, const gchar *default_cat); -gboolean e_cal_model_get_use_24_hour_format (ECalModel *model); -void e_cal_model_set_use_24_hour_format (ECalModel *model, gboolean use24); - -ECal *e_cal_model_get_default_client (ECalModel *model); -void e_cal_model_set_default_client (ECalModel *model, ECal *client); -GList *e_cal_model_get_client_list (ECalModel *model); -ECal *e_cal_model_get_client_for_uri (ECalModel *model, const char *uri); -void e_cal_model_add_client (ECalModel *model, ECal *client); -void e_cal_model_remove_client (ECalModel *model, ECal *client); -void e_cal_model_remove_all_clients (ECalModel *model); - -void e_cal_model_set_query (ECalModel *model, const gchar *sexp); - -icalcomponent *e_cal_model_create_component_with_defaults (ECalModel *model); -const gchar *e_cal_model_get_color_for_component (ECalModel *model, ECalModelComponent *comp_data); -ECalModelComponent *e_cal_model_get_component_at (ECalModel *model, gint row); - -gchar *e_cal_model_date_value_to_string (ECalModel *model, const void *value); - -void e_cal_model_free_component_data (ECalModelComponent *comp_data); - -G_END_DECLS - -#endif diff --git a/calendar/gui/e-cal-view.c b/calendar/gui/e-cal-view.c deleted file mode 100644 index f93cee6c10..0000000000 --- a/calendar/gui/e-cal-view.c +++ /dev/null @@ -1,1492 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Rodrigo Moya <rodrigo@ximian.com> - * - * Copyright 2003, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include <config.h> -#include <string.h> -#include <gtk/gtkimage.h> -#include <gtk/gtkstock.h> -#include <libgnome/gnome-i18n.h> -#include <gal/util/e-util.h> -#include "e-util/e-dialog-utils.h" -#include "e-calendar-marshal.h" -#include <libecal/e-cal-time-util.h> - -#include "calendar-commands.h" -#include "calendar-component.h" -#include "calendar-config.h" -#include "comp-util.h" -#include "e-cal-model-calendar.h" -#include "e-cal-view.h" -#include "e-comp-editor-registry.h" -#include "itip-utils.h" -#include "dialogs/delete-comp.h" -#include "dialogs/delete-error.h" -#include "dialogs/event-editor.h" -#include "dialogs/send-comp.h" -#include "dialogs/cancel-comp.h" -#include "dialogs/recur-comp.h" -#include "print.h" -#include "goto.h" -#include "ea-calendar.h" - -/* Used for the status bar messages */ -#define EVOLUTION_CALENDAR_PROGRESS_IMAGE "evolution-calendar-mini.png" -static GdkPixbuf *progress_icon = NULL; - -struct _ECalendarViewPrivate { - /* The GnomeCalendar we are associated to */ - GnomeCalendar *calendar; - - /* The calendar model we are monitoring */ - ECalModel *model; - - /* Current activity (for the EActivityHandler, i.e. the status bar). */ - guint activity_id; - - /* clipboard selections */ - gchar *clipboard_selection; - - /* The popup menu */ - EPopupMenu *view_menu; - - /* The default category */ - char *default_category; -}; - -static void e_calendar_view_class_init (ECalendarViewClass *klass); -static void e_calendar_view_init (ECalendarView *cal_view, ECalendarViewClass *klass); -static void e_calendar_view_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); -static void e_calendar_view_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); -static void e_calendar_view_destroy (GtkObject *object); - -static GObjectClass *parent_class = NULL; -static GdkAtom clipboard_atom = GDK_NONE; -extern ECompEditorRegistry *comp_editor_registry; - -/* Property IDs */ -enum props { - PROP_0, - PROP_MODEL, -}; - -/* FIXME Why are we emitting these event signals here? Can't the model just be listened to? */ -/* Signal IDs */ -enum { - SELECTION_CHANGED, - SELECTED_TIME_CHANGED, - TIMEZONE_CHANGED, - EVENT_CHANGED, - EVENT_ADDED, - LAST_SIGNAL -}; - -static guint e_calendar_view_signals[LAST_SIGNAL] = { 0 }; - -static void -e_calendar_view_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) -{ - ECalendarView *cal_view; - ECalendarViewPrivate *priv; - - cal_view = E_CALENDAR_VIEW (object); - priv = cal_view->priv; - - switch (property_id) { - case PROP_MODEL: - e_calendar_view_set_model (cal_view, E_CAL_MODEL (g_value_get_object (value))); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -e_calendar_view_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) -{ - ECalendarView *cal_view; - ECalendarViewPrivate *priv; - - cal_view = E_CALENDAR_VIEW (object); - priv = cal_view->priv; - - switch (property_id) { - case PROP_MODEL: - g_value_set_object (value, e_calendar_view_get_model (cal_view)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -e_calendar_view_class_init (ECalendarViewClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - /* Method override */ - gobject_class->set_property = e_calendar_view_set_property; - gobject_class->get_property = e_calendar_view_get_property; - object_class->destroy = e_calendar_view_destroy; - - klass->selection_changed = NULL; - klass->selected_time_changed = NULL; - klass->event_changed = NULL; - klass->event_added = NULL; - - klass->get_selected_events = NULL; - klass->get_selected_time_range = NULL; - klass->set_selected_time_range = NULL; - klass->get_visible_time_range = NULL; - klass->update_query = NULL; - - g_object_class_install_property (gobject_class, PROP_MODEL, - g_param_spec_object ("model", NULL, NULL, E_TYPE_CAL_MODEL, - G_PARAM_READABLE | G_PARAM_WRITABLE - | G_PARAM_CONSTRUCT)); - - /* Create class' signals */ - e_calendar_view_signals[SELECTION_CHANGED] = - g_signal_new ("selection_changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ECalendarViewClass, selection_changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - e_calendar_view_signals[SELECTED_TIME_CHANGED] = - g_signal_new ("selected_time_changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ECalendarViewClass, selected_time_changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - e_calendar_view_signals[TIMEZONE_CHANGED] = - g_signal_new ("timezone_changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ECalendarViewClass, timezone_changed), - NULL, NULL, - e_calendar_marshal_VOID__POINTER_POINTER, - G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER); - - e_calendar_view_signals[EVENT_CHANGED] = - g_signal_new ("event_changed", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (ECalendarViewClass, event_changed), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - - e_calendar_view_signals[EVENT_ADDED] = - g_signal_new ("event_added", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (ECalendarViewClass, event_added), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - - /* clipboard atom */ - if (!clipboard_atom) - clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE); - - /* init the accessibility support for e_day_view */ - e_cal_view_a11y_init (); -} - -static void -model_changed_cb (ETableModel *etm, gpointer user_data) -{ - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - e_calendar_view_update_query (cal_view); -} - -static void -model_row_changed_cb (ETableModel *etm, int row, gpointer user_data) -{ - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - e_calendar_view_update_query (cal_view); -} - -static void -model_cell_changed_cb (ETableModel *etm, int col, int row, gpointer user_data) -{ - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - e_calendar_view_update_query (cal_view); -} - -static void -model_rows_changed_cb (ETableModel *etm, int row, int count, gpointer user_data) -{ - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - e_calendar_view_update_query (cal_view); -} - -void -e_calendar_view_add_event (ECalendarView *cal_view, ECal *client, time_t dtstart, - icaltimezone *default_zone, icalcomponent *icalcomp, gboolean in_top_canvas) -{ - ECalComponent *comp; - struct icaltimetype itime, old_dtstart, old_dtend; - time_t tt_start, tt_end, new_dtstart; - struct icaldurationtype ic_dur; - char *uid; - gint start_offset, end_offset; - gboolean all_day_event; - - start_offset = 0; - end_offset = 0; - - old_dtstart = icalcomponent_get_dtstart (icalcomp); - tt_start = icaltime_as_timet (old_dtstart); - old_dtend = icalcomponent_get_dtend (icalcomp); - tt_end = icaltime_as_timet (old_dtend); - ic_dur = icaldurationtype_from_int (tt_end - tt_start); - - if (icaldurationtype_as_int (ic_dur) > 60*60*24) { - /* This is a long event */ - start_offset = old_dtstart.hour * 60 + old_dtstart.minute; - end_offset = old_dtstart.hour * 60 + old_dtend.minute; - } - - if (start_offset == 0 && end_offset == 0 && in_top_canvas) - all_day_event = TRUE; - else - all_day_event = FALSE; - - if (in_top_canvas) - new_dtstart = dtstart + start_offset * 60; - else - new_dtstart = dtstart; - - itime = icaltime_from_timet_with_zone (new_dtstart, FALSE, default_zone); - if (all_day_event) - itime.is_date = TRUE; - icalcomponent_set_dtstart (icalcomp, itime); - - itime = icaltime_add (itime, ic_dur); - if (all_day_event) - itime.is_date = TRUE; - icalcomponent_set_dtend (icalcomp, itime); - - /* FIXME The new uid stuff can go away once we actually set it in the backend */ - uid = e_cal_component_gen_uid (); - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent ( - comp, icalcomponent_new_clone (icalcomp)); - e_cal_component_set_uid (comp, uid); - - /* FIXME Error handling */ - if (e_cal_create_object (client, e_cal_component_get_icalcomponent (comp), NULL, NULL)) { - if (itip_organizer_is_user (comp, client) && - send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)), - client, comp, TRUE)) { - itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, - client, NULL); - } - } else { - g_message (G_STRLOC ": Could not create the object!"); - } - - free (uid); - g_object_unref (comp); -} - -static void -e_calendar_view_init (ECalendarView *cal_view, ECalendarViewClass *klass) -{ - cal_view->priv = g_new0 (ECalendarViewPrivate, 1); - - cal_view->priv->model = (ECalModel *) e_cal_model_calendar_new (); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_changed", - G_CALLBACK (model_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_row_changed", - G_CALLBACK (model_row_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_cell_changed", - G_CALLBACK (model_cell_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_rows_inserted", - G_CALLBACK (model_rows_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_rows_deleted", - G_CALLBACK (model_rows_changed_cb), cal_view); - - cal_view->priv->clipboard_selection = NULL; -} - -static void -e_calendar_view_destroy (GtkObject *object) -{ - ECalendarView *cal_view = (ECalendarView *) object; - - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - if (cal_view->priv) { - if (cal_view->priv->model) { - g_signal_handlers_disconnect_matched (cal_view->priv->model, - G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, cal_view); - g_object_unref (cal_view->priv->model); - cal_view->priv->model = NULL; - } - - if (cal_view->priv->clipboard_selection) { - g_free (cal_view->priv->clipboard_selection); - cal_view->priv->clipboard_selection = NULL; - } - - if (cal_view->priv->default_category) { - g_free (cal_view->priv->default_category); - cal_view->priv->default_category = NULL; - } - - g_free (cal_view->priv); - cal_view->priv = NULL; - } - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - GTK_OBJECT_CLASS (parent_class)->destroy (object); -} - -E_MAKE_TYPE (e_calendar_view, "ECalendarView", ECalendarView, e_calendar_view_class_init, - e_calendar_view_init, GTK_TYPE_TABLE); - -GnomeCalendar * -e_calendar_view_get_calendar (ECalendarView *cal_view) -{ - g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), NULL); - - return cal_view->priv->calendar; -} - -void -e_calendar_view_set_calendar (ECalendarView *cal_view, GnomeCalendar *calendar) -{ - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - cal_view->priv->calendar = calendar; -} - -ECalModel * -e_calendar_view_get_model (ECalendarView *cal_view) -{ - g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), NULL); - - return cal_view->priv->model; -} - -void -e_calendar_view_set_model (ECalendarView *cal_view, ECalModel *model) -{ - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - g_return_if_fail (E_IS_CAL_MODEL (model)); - - if (cal_view->priv->model) { - g_signal_handlers_disconnect_matched (cal_view->priv->model, G_SIGNAL_MATCH_DATA, - 0, 0, 0, NULL, cal_view); - g_object_unref (cal_view->priv->model); - } - - cal_view->priv->model = model; - g_object_ref (cal_view->priv->model); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_changed", G_CALLBACK (model_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_row_changed", G_CALLBACK (model_row_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_cell_changed", G_CALLBACK (model_cell_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_rows_inserted", G_CALLBACK (model_rows_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_rows_deleted", G_CALLBACK (model_rows_changed_cb), cal_view); - - e_calendar_view_update_query (cal_view); -} - -icaltimezone * -e_calendar_view_get_timezone (ECalendarView *cal_view) -{ - g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), NULL); - return e_cal_model_get_timezone (cal_view->priv->model); -} - -void -e_calendar_view_set_timezone (ECalendarView *cal_view, icaltimezone *zone) -{ - icaltimezone *old_zone; - - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - old_zone = e_cal_model_get_timezone (cal_view->priv->model); - if (old_zone == zone) - return; - - e_cal_model_set_timezone (cal_view->priv->model, zone); - g_signal_emit (G_OBJECT (cal_view), e_calendar_view_signals[TIMEZONE_CHANGED], 0, - old_zone, zone); -} - -const char * -e_calendar_view_get_default_category (ECalendarView *cal_view) -{ - g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), NULL); - return (const char *) cal_view->priv->default_category; -} - -/** - * e_calendar_view_set_default_category - * @cal_view: A calendar view. - * @category: Default category name or NULL for no category. - * - * Sets the default category that will be used when creating new calendar - * components from the given calendar view. - */ -void -e_calendar_view_set_default_category (ECalendarView *cal_view, const char *category) -{ - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - if (cal_view->priv->default_category) - g_free (cal_view->priv->default_category); - - cal_view->priv->default_category = g_strdup (category); -} - -/** - * e_calendar_view_get_use_24_hour_format: - * @cal_view: A calendar view. - * - * Gets whether the view is using 24 hour times or not. - * - * Returns: the 24 hour setting. - */ -gboolean -e_calendar_view_get_use_24_hour_format (ECalendarView *cal_view) -{ - g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), FALSE); - - return e_cal_model_get_use_24_hour_format (cal_view->priv->model); -} - -/** - * e_calendar_view_set_use_24_hour_format - * @cal_view: A calendar view. - * @use_24_hour: Whether to use 24 hour times or not. - * - * Sets the 12/24 hour times setting for the given view. - */ -void -e_calendar_view_set_use_24_hour_format (ECalendarView *cal_view, gboolean use_24_hour) -{ - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - e_cal_model_set_use_24_hour_format (cal_view->priv->model, use_24_hour); -} - -void -e_calendar_view_set_status_message (ECalendarView *cal_view, const gchar *message) -{ - EActivityHandler *activity_handler = calendar_component_peek_activity_handler (calendar_component_peek ()); - - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - if (!message || !*message) { - if (cal_view->priv->activity_id != 0) { - e_activity_handler_operation_finished (activity_handler, cal_view->priv->activity_id); - cal_view->priv->activity_id = 0; - } - } else if (cal_view->priv->activity_id == 0) { - char *client_id = g_strdup_printf ("%p", cal_view); - - if (progress_icon == NULL) - progress_icon = gdk_pixbuf_new_from_file (EVOLUTION_IMAGESDIR "/" EVOLUTION_CALENDAR_PROGRESS_IMAGE, NULL); - - cal_view->priv->activity_id = e_activity_handler_operation_started (activity_handler, client_id, progress_icon, message, TRUE); - - g_free (client_id); - } else { - e_activity_handler_operation_progressing (activity_handler, cal_view->priv->activity_id, message, -1.0); - } -} - -GList * -e_calendar_view_get_selected_events (ECalendarView *cal_view) -{ - g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), NULL); - - if (E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->get_selected_events) - return E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->get_selected_events (cal_view); - - return NULL; -} - -void -e_calendar_view_get_selected_time_range (ECalendarView *cal_view, time_t *start_time, time_t *end_time) -{ - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - if (E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->get_selected_time_range) { - E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->get_selected_time_range ( - cal_view, start_time, end_time); - } -} - -void -e_calendar_view_set_selected_time_range (ECalendarView *cal_view, time_t start_time, time_t end_time) -{ - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - if (E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->set_selected_time_range) { - E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->set_selected_time_range ( - cal_view, start_time, end_time); - } -} - -gboolean -e_calendar_view_get_visible_time_range (ECalendarView *cal_view, time_t *start_time, time_t *end_time) -{ - g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), FALSE); - - if (E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->get_visible_time_range) { - return E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->get_visible_time_range ( - cal_view, start_time, end_time); - } - - return FALSE; -} - -void -e_calendar_view_update_query (ECalendarView *cal_view) -{ - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - e_calendar_view_set_status_message (cal_view, _("Searching")); - - if (E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->update_query) { - E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->update_query (cal_view); - } - - e_calendar_view_set_status_message (cal_view, NULL); -} - -void -e_calendar_view_cut_clipboard (ECalendarView *cal_view) -{ - GList *selected, *l; - const char *uid; - - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - selected = e_calendar_view_get_selected_events (cal_view); - if (!selected) - return; - - e_calendar_view_set_status_message (cal_view, _("Deleting selected objects")); - - e_calendar_view_copy_clipboard (cal_view); - for (l = selected; l != NULL; l = l->next) { - ECalComponent *comp; - ECalendarViewEvent *event = (ECalendarViewEvent *) l->data; - GError *error = NULL; - - if (!event) - continue; - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); - - if (itip_organizer_is_user (comp, event->comp_data->client) - && cancel_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)), - event->comp_data->client, comp, TRUE)) - itip_send_comp (E_CAL_COMPONENT_METHOD_CANCEL, comp, - event->comp_data->client, NULL); - - e_cal_component_get_uid (comp, &uid); - e_cal_remove_object (event->comp_data->client, uid, &error); - delete_error_dialog (error, E_CAL_COMPONENT_EVENT); - - g_clear_error (&error); - - g_object_unref (comp); - } - - e_calendar_view_set_status_message (cal_view, NULL); - - g_list_free (selected); -} - -void -e_calendar_view_copy_clipboard (ECalendarView *cal_view) -{ - GList *selected, *l; - gchar *comp_str; - icalcomponent *vcal_comp; - icalcomponent *new_icalcomp; - ECalendarViewEvent *event; - - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - selected = e_calendar_view_get_selected_events (cal_view); - if (!selected) - return; - - /* create top-level VCALENDAR component and add VTIMEZONE's */ - vcal_comp = e_cal_util_new_top_level (); - for (l = selected; l != NULL; l = l->next) { - event = (ECalendarViewEvent *) l->data; - - if (event) - e_cal_util_add_timezones_from_component (vcal_comp, event->comp_data->icalcomp); - } - - for (l = selected; l != NULL; l = l->next) { - event = (ECalendarViewEvent *) l->data; - - new_icalcomp = icalcomponent_new_clone (event->comp_data->icalcomp); - icalcomponent_add_component (vcal_comp, new_icalcomp); - } - - /* copy the VCALENDAR to the clipboard */ - comp_str = icalcomponent_as_ical_string (vcal_comp); - if (cal_view->priv->clipboard_selection != NULL) - g_free (cal_view->priv->clipboard_selection); - cal_view->priv->clipboard_selection = g_strdup (comp_str); - gtk_clipboard_set_text (gtk_widget_get_clipboard (GTK_WIDGET (cal_view), clipboard_atom), - (const gchar *) comp_str, - g_utf8_strlen (comp_str, -1)); - - /* free memory */ - icalcomponent_free (vcal_comp); - g_list_free (selected); -} - -static void -clipboard_get_text_cb (GtkClipboard *clipboard, const gchar *text, ECalendarView *cal_view) -{ - char *default_tzid; - icalcomponent *icalcomp; - icalcomponent_kind kind; - time_t selected_time_start, selected_time_end; - icaltimezone *default_zone; - ECal *client; - - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - icalcomp = icalparser_parse_string ((const char *) text); - if (!icalcomp) - return; - - default_tzid = calendar_config_get_timezone (); - - client = e_cal_model_get_default_client (cal_view->priv->model); - /* FIXME Error checking */ - e_cal_get_timezone (client, default_tzid, &default_zone, NULL); - - /* check the type of the component */ - /* FIXME An error dialog if we return? */ - kind = icalcomponent_isa (icalcomp); - if (kind != ICAL_VCALENDAR_COMPONENT && kind != ICAL_VEVENT_COMPONENT) - return; - - e_calendar_view_set_status_message (cal_view, _("Updating objects")); - e_calendar_view_get_selected_time_range (cal_view, &selected_time_start, &selected_time_end); - - /* FIXME Timezone handling */ - if (kind == ICAL_VCALENDAR_COMPONENT) { - icalcomponent_kind child_kind; - icalcomponent *subcomp; - - subcomp = icalcomponent_get_first_component (icalcomp, ICAL_ANY_COMPONENT); - while (subcomp) { - child_kind = icalcomponent_isa (subcomp); - if (child_kind == ICAL_VEVENT_COMPONENT) - e_calendar_view_add_event (cal_view, client, selected_time_start, - default_zone, subcomp, FALSE); - else if (child_kind == ICAL_VTIMEZONE_COMPONENT) { - icaltimezone *zone; - - zone = icaltimezone_new (); - icaltimezone_set_component (zone, subcomp); - e_cal_add_timezone (client, zone, NULL); - - icaltimezone_free (zone, 1); - } - - subcomp = icalcomponent_get_next_component ( - icalcomp, ICAL_ANY_COMPONENT); - } - - icalcomponent_free (icalcomp); - - } else { - e_calendar_view_add_event (cal_view, client, selected_time_start, default_zone, icalcomp, FALSE); - } - - e_calendar_view_set_status_message (cal_view, NULL); -} - -void -e_calendar_view_paste_clipboard (ECalendarView *cal_view) -{ - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - gtk_clipboard_request_text (gtk_widget_get_clipboard (GTK_WIDGET (cal_view), clipboard_atom), - (GtkClipboardTextReceivedFunc) clipboard_get_text_cb, cal_view); -} - -static void -delete_event (ECalendarView *cal_view, ECalendarViewEvent *event) -{ - ECalComponent *comp; - ECalComponentVType vtype; - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); - vtype = e_cal_component_get_vtype (comp); - - if (delete_component_dialog (comp, FALSE, 1, vtype, GTK_WIDGET (cal_view))) { - const char *uid; - GError *error = NULL; - - if (itip_organizer_is_user (comp, event->comp_data->client) - && cancel_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)), - event->comp_data->client, - comp, TRUE)) - itip_send_comp (E_CAL_COMPONENT_METHOD_CANCEL, comp, - event->comp_data->client, NULL); - - e_cal_component_get_uid (comp, &uid); - if (!uid || !*uid) { - g_object_unref (comp); - return; - } - - e_cal_remove_object (event->comp_data->client, uid, &error); - delete_error_dialog (error, E_CAL_COMPONENT_EVENT); - g_clear_error (&error); - } - - g_object_unref (comp); -} - -void -e_calendar_view_delete_selected_event (ECalendarView *cal_view) -{ - GList *selected; - ECalendarViewEvent *event; - - selected = e_calendar_view_get_selected_events (cal_view); - if (!selected) - return; - - event = (ECalendarViewEvent *) selected->data; - if (event) - delete_event (cal_view, event); - - g_list_free (selected); -} - -void -e_calendar_view_delete_selected_events (ECalendarView *cal_view) -{ - GList *selected, *l; - ECalendarViewEvent *event; - - selected = e_calendar_view_get_selected_events (cal_view); - if (!selected) - return; - - for (l = selected; l != NULL; l = l->next) { - event = (ECalendarViewEvent *) l->data; - if (event) - delete_event (cal_view, event); - } - - g_list_free (selected); -} - -void -e_calendar_view_delete_selected_occurrence (ECalendarView *cal_view) -{ - ECalendarViewEvent *event; - GList *selected; - const char *uid; - GError *error = NULL; - - selected = e_calendar_view_get_selected_events (cal_view); - if (!selected) - return; - - event = (ECalendarViewEvent *) selected->data; - - uid = icalcomponent_get_uid (event->comp_data->icalcomp); - /* FIXME: use 'rid' argument */ - e_cal_remove_object_with_mod (event->comp_data->client, uid, NULL, CALOBJ_MOD_THIS, &error); - - delete_error_dialog (error, E_CAL_COMPONENT_EVENT); - g_clear_error (&error); - - /* free memory */ - g_list_free (selected); -} - -static void -on_new_appointment (GtkWidget *widget, gpointer user_data) -{ - ECalendarView *cal_view = (ECalendarView *) user_data; - - e_calendar_view_new_appointment (cal_view); -} - -static void -on_new_event (GtkWidget *widget, gpointer user_data) -{ - time_t dtstart, dtend; - ECalendarView *cal_view = (ECalendarView *) user_data; - - e_calendar_view_get_selected_time_range (cal_view, &dtstart, &dtend); - e_calendar_view_new_appointment_for (cal_view, dtstart, dtend, TRUE, FALSE); -} - -static void -on_new_meeting (GtkWidget *widget, gpointer user_data) -{ - time_t dtstart, dtend; - ECalendarView *cal_view = (ECalendarView *) user_data; - - e_calendar_view_get_selected_time_range (cal_view, &dtstart, &dtend); - e_calendar_view_new_appointment_for (cal_view, dtstart, dtend, FALSE, TRUE); -} - -static void -on_new_task (GtkWidget *widget, gpointer user_data) -{ - ECalendarView *cal_view = (ECalendarView *) user_data; - gnome_calendar_new_task (cal_view->priv->calendar); -} - -static void -on_goto_date (GtkWidget *widget, gpointer user_data) -{ - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - goto_dialog (cal_view->priv->calendar); -} - -static void -on_goto_today (GtkWidget *widget, gpointer user_data) -{ - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - calendar_goto_today (cal_view->priv->calendar); -} - -static void -on_edit_appointment (GtkWidget *widget, gpointer user_data) -{ - GList *selected; - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - selected = e_calendar_view_get_selected_events (cal_view); - if (selected) { - ECalendarViewEvent *event = (ECalendarViewEvent *) selected->data; - - if (event) - e_calendar_view_edit_appointment (cal_view, event->comp_data->client, - event->comp_data->icalcomp, FALSE); - - g_list_free (selected); - } -} - -static void -on_print (GtkWidget *widget, gpointer user_data) -{ - ECalendarView *cal_view; - time_t start; - GnomeCalendarViewType view_type; - PrintView print_view; - - cal_view = E_CALENDAR_VIEW (user_data); - - e_calendar_view_get_visible_time_range (cal_view, &start, NULL); - view_type = gnome_calendar_get_view (cal_view->priv->calendar); - - 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 (cal_view->priv->calendar, FALSE, start, print_view); -} - -static void -on_save_as (GtkWidget *widget, gpointer user_data) -{ - ECalendarView *cal_view; - GList *selected; - char *filename; - char *ical_string; - FILE *file; - ECalendarViewEvent *event; - - cal_view = E_CALENDAR_VIEW (user_data); - - selected = e_calendar_view_get_selected_events (cal_view); - if (!selected) - return; - - filename = e_file_dialog_save (_("Save as...")); - if (filename == NULL) - return; - - event = (ECalendarViewEvent *) selected->data; - ical_string = e_cal_get_component_as_string (event->comp_data->client, event->comp_data->icalcomp); - 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); - - g_list_free (selected); -} - -static void -on_print_event (GtkWidget *widget, gpointer user_data) -{ - ECalendarView *cal_view; - GList *selected; - ECalendarViewEvent *event; - ECalComponent *comp; - - cal_view = E_CALENDAR_VIEW (user_data); - selected = e_calendar_view_get_selected_events (cal_view); - if (!selected) - return; - - event = (ECalendarViewEvent *) selected->data; - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); - print_comp (comp, event->comp_data->client, FALSE); - - g_object_unref (comp); -} - -static void -on_meeting (GtkWidget *widget, gpointer user_data) -{ - GList *selected; - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - selected = e_calendar_view_get_selected_events (cal_view); - if (selected) { - ECalendarViewEvent *event = (ECalendarViewEvent *) selected->data; - e_calendar_view_edit_appointment (cal_view, event->comp_data->client, event->comp_data->icalcomp, TRUE); - - g_list_free (selected); - } -} - -static void -on_forward (GtkWidget *widget, gpointer user_data) -{ - GList *selected; - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - selected = e_calendar_view_get_selected_events (cal_view); - if (selected) { - ECalComponent *comp; - ECalendarViewEvent *event = (ECalendarViewEvent *) selected->data; - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); - itip_send_comp (E_CAL_COMPONENT_METHOD_PUBLISH, comp, event->comp_data->client, NULL); - - g_list_free (selected); - g_object_unref (comp); - } -} - -static void -on_publish (GtkWidget *widget, gpointer user_data) -{ - ECalendarView *cal_view; - icaltimezone *utc; - time_t start = time (NULL), end; - GList *comp_list = NULL, *client_list, *cl; - - cal_view = E_CALENDAR_VIEW (user_data); - - utc = icaltimezone_get_utc_timezone (); - start = time_day_begin_with_zone (start, utc); - end = time_add_week_with_zone (start, 6, utc); - - client_list = e_cal_model_get_client_list (cal_view->priv->model); - for (cl = client_list; cl != NULL; cl = cl->next) { - if (e_cal_get_free_busy ((ECal *) cl->data, NULL, start, end, &comp_list, NULL)) { - GList *l; - - for (l = comp_list; l; l = l->next) { - ECalComponent *comp = E_CAL_COMPONENT (l->data); - itip_send_comp (E_CAL_COMPONENT_METHOD_PUBLISH, comp, (ECal *) cl->data, NULL); - - g_object_unref (comp); - } - - g_list_free (comp_list); - } - } - - g_list_free (client_list); -} - -static void -on_delete_appointment (GtkWidget *widget, gpointer user_data) -{ - ECalendarView *cal_view; - - cal_view = E_CALENDAR_VIEW (user_data); - e_calendar_view_delete_selected_event (cal_view); -} - -static void -on_delete_occurrence (GtkWidget *widget, gpointer user_data) -{ - ECalendarView *cal_view; - - cal_view = E_CALENDAR_VIEW (user_data); - e_calendar_view_delete_selected_occurrence (cal_view); -} - -static void -on_cut (GtkWidget *widget, gpointer user_data) -{ - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - e_calendar_view_cut_clipboard (cal_view); -} - -static void -on_copy (GtkWidget *widget, gpointer user_data) -{ - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - e_calendar_view_copy_clipboard (cal_view); -} - -static void -on_paste (GtkWidget *widget, gpointer user_data) -{ - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - e_calendar_view_paste_clipboard (cal_view); -} - -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, - - /* - * This is used to when an event is already a meeting and - * we want to disable the schedule meeting command - */ - MASK_MEETING = 16, - - /* - * To disable cut and copy for meetings the user is not the - * organizer of - */ - MASK_MEETING_ORGANIZER = 32, - - /* - * To disable things not valid for instances - */ - MASK_INSTANCE = 64 -}; - -static EPopupMenu main_items [] = { - E_POPUP_ITEM (N_("New _Appointment..."), GTK_SIGNAL_FUNC (on_new_appointment), MASK_EDITABLE), - E_POPUP_ITEM (N_("New All Day _Event"), GTK_SIGNAL_FUNC (on_new_event), MASK_EDITABLE), - E_POPUP_ITEM (N_("New Meeting"), GTK_SIGNAL_FUNC (on_new_meeting), MASK_EDITABLE), - E_POPUP_ITEM (N_("New Task"), GTK_SIGNAL_FUNC (on_new_task), MASK_EDITABLE), - - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("_Print..."), GTK_SIGNAL_FUNC (on_print), 0), - - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("_Paste"), GTK_SIGNAL_FUNC (on_paste), MASK_EDITABLE), - - E_POPUP_SEPARATOR, - - E_POPUP_SUBMENU (N_("Current View"), NULL, 0), - - E_POPUP_ITEM (N_("Go to _Today"), GTK_SIGNAL_FUNC (on_goto_today), 0), - E_POPUP_ITEM (N_("_Go to Date..."), GTK_SIGNAL_FUNC (on_goto_date), 0), - - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("_Publish Free/Busy Information"), GTK_SIGNAL_FUNC (on_publish), 0), - - E_POPUP_TERMINATOR -}; - -static EPopupMenu child_items [] = { - E_POPUP_ITEM (N_("_Open"), GTK_SIGNAL_FUNC (on_edit_appointment), MASK_EDITING), - E_POPUP_ITEM (N_("_Save As..."), GTK_SIGNAL_FUNC (on_save_as), MASK_EDITING), - E_POPUP_ITEM (N_("_Print..."), GTK_SIGNAL_FUNC (on_print_event), MASK_EDITING), - - /* Only show this separator if one of the above is shown. */ - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("C_ut"), GTK_SIGNAL_FUNC (on_cut), MASK_EDITING | MASK_EDITABLE | MASK_MEETING_ORGANIZER), - E_POPUP_ITEM (N_("_Copy"), GTK_SIGNAL_FUNC (on_copy), MASK_EDITING | MASK_MEETING_ORGANIZER), - E_POPUP_ITEM (N_("_Paste"), GTK_SIGNAL_FUNC (on_paste), MASK_EDITABLE), - - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("_Schedule Meeting..."), GTK_SIGNAL_FUNC (on_meeting), MASK_EDITABLE | MASK_EDITING | MASK_MEETING), - E_POPUP_ITEM (N_("_Forward as iCalendar..."), GTK_SIGNAL_FUNC (on_forward), MASK_EDITING), - - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("_Delete"), GTK_SIGNAL_FUNC (on_delete_appointment), MASK_EDITABLE | MASK_SINGLE | MASK_EDITING), - E_POPUP_ITEM (N_("Delete this _Occurrence"), GTK_SIGNAL_FUNC (on_delete_occurrence), MASK_RECURRING | MASK_EDITING | MASK_EDITABLE), - E_POPUP_ITEM (N_("Delete _All Occurrences"), GTK_SIGNAL_FUNC (on_delete_appointment), MASK_RECURRING | MASK_EDITING | MASK_EDITABLE), - - E_POPUP_TERMINATOR -}; - -static void -free_view_popup (GtkWidget *widget, gpointer data) -{ - ECalendarView *cal_view = E_CALENDAR_VIEW (data); - - if (cal_view->priv->view_menu == NULL) - return; - - gnome_calendar_discard_view_popup (cal_view->priv->calendar, cal_view->priv->view_menu); - cal_view->priv->view_menu = NULL; -} - -static void -setup_popup_icons (EPopupMenu *context_menu) -{ - gint i; - - for (i = 0; context_menu[i].name; i++) { - GtkWidget *pixmap_widget = NULL; - - if (!strcmp (context_menu[i].name, _("_Copy"))) - pixmap_widget = gtk_image_new_from_stock (GTK_STOCK_COPY, GTK_ICON_SIZE_MENU); - else if (!strcmp (context_menu[i].name, _("C_ut"))) - pixmap_widget = gtk_image_new_from_stock (GTK_STOCK_CUT, GTK_ICON_SIZE_MENU); - else if (!strcmp (context_menu[i].name, _("_Delete")) || - !strcmp (context_menu[i].name, _("Delete this _Occurrence")) || - !strcmp (context_menu[i].name, _("Delete _All Occurrences"))) - pixmap_widget = gtk_image_new_from_stock (GTK_STOCK_DELETE, GTK_ICON_SIZE_MENU); - else if (!strcmp (context_menu[i].name, _("Go to _Today"))) - pixmap_widget = gtk_image_new_from_stock (GTK_STOCK_HOME, GTK_ICON_SIZE_MENU); - else if (!strcmp (context_menu[i].name, _("_Go to Date..."))) - pixmap_widget = gtk_image_new_from_stock (GTK_STOCK_JUMP_TO, GTK_ICON_SIZE_MENU); - else if (!strcmp (context_menu[i].name, _("New _Appointment..."))) - pixmap_widget = gtk_image_new_from_file (EVOLUTION_IMAGESDIR "/new_appointment.xpm"); - else if (!strcmp (context_menu[i].name, _("New All Day _Event"))) - pixmap_widget = gtk_image_new_from_file (EVOLUTION_IMAGESDIR "/new_all_day_event.png"); - else if (!strcmp (context_menu[i].name, _("New Meeting"))) - pixmap_widget = gtk_image_new_from_file (EVOLUTION_IMAGESDIR "/meeting-request-16.png"); - else if (!strcmp (context_menu[i].name, _("New Task"))) - pixmap_widget = gtk_image_new_from_file (EVOLUTION_IMAGESDIR "/new_task-16.png"); - else if (!strcmp (context_menu[i].name, _("_Open"))) - pixmap_widget = gtk_image_new_from_stock (GTK_STOCK_OPEN, GTK_ICON_SIZE_MENU); - else if (!strcmp (context_menu[i].name, _("_Paste"))) - pixmap_widget = gtk_image_new_from_stock (GTK_STOCK_PASTE, GTK_ICON_SIZE_MENU); - else if (!strcmp (context_menu[i].name, _("_Print..."))) - pixmap_widget = gtk_image_new_from_stock (GTK_STOCK_PRINT, GTK_ICON_SIZE_MENU); - else if (!strcmp (context_menu[i].name, _("_Save As..."))) - pixmap_widget = gtk_image_new_from_stock (GTK_STOCK_SAVE_AS, GTK_ICON_SIZE_MENU); - else if (!strcmp (context_menu[i].name, _("_Settings..."))) - pixmap_widget = gtk_image_new_from_stock (GTK_STOCK_PREFERENCES, GTK_ICON_SIZE_MENU); - - if (pixmap_widget) - gtk_widget_show (pixmap_widget); - context_menu[i].pixmap_widget = pixmap_widget; - } -} - -GtkMenu * -e_calendar_view_create_popup_menu (ECalendarView *cal_view) -{ - GList *selected; - EPopupMenu *context_menu; - guint32 disable_mask = 0, hide_mask = 0; - GtkMenu *popup; - ECal *client = NULL; - gboolean read_only = TRUE; - - g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), NULL); - - /* get the selection */ - selected = e_calendar_view_get_selected_events (cal_view); - - if (selected == NULL) { - cal_view->priv->view_menu = gnome_calendar_setup_view_popup (cal_view->priv->calendar); - main_items[9].submenu = cal_view->priv->view_menu; - context_menu = main_items; - - client = e_cal_model_get_default_client (cal_view->priv->model); - } else { - ECalendarViewEvent *event; - - context_menu = child_items; - - event = (ECalendarViewEvent *) selected->data; - if (e_cal_util_component_has_recurrences (event->comp_data->icalcomp)) - hide_mask |= MASK_SINGLE; - else - hide_mask |= MASK_RECURRING; - - if (e_cal_util_component_is_instance (event->comp_data->icalcomp)) - hide_mask |= MASK_INSTANCE; - - if (e_cal_util_component_has_organizer (event->comp_data->icalcomp)) { - ECalComponent *comp; - - disable_mask |= MASK_MEETING; - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); - if (!itip_organizer_is_user (comp, event->comp_data->client)) - disable_mask |= MASK_MEETING_ORGANIZER; - - g_object_unref (comp); - } - - client = event->comp_data->client; - } - - e_cal_is_read_only (client, &read_only, NULL); - if (read_only) - disable_mask |= MASK_EDITABLE; - - setup_popup_icons (context_menu); - popup = e_popup_menu_create (context_menu, disable_mask, hide_mask, cal_view); - g_signal_connect (popup, "selection-done", G_CALLBACK (free_view_popup), cal_view); - - return popup; -} - -/** - * e_calendar_view_new_appointment_for - * @cal_view: A calendar view. - * @dtstart: A Unix time_t that marks the beginning of the appointment. - * @dtend: A Unix time_t that marks the end of the appointment. - * @all_day: If TRUE, the dtstart and dtend are expanded to cover - * the entire day, and the event is set to TRANSPARENT. - * @meeting: Whether the appointment is a meeting or not. - * - * Opens an event editor dialog for a new appointment. - */ -void -e_calendar_view_new_appointment_for (ECalendarView *cal_view, - time_t dtstart, time_t dtend, - gboolean all_day, - gboolean meeting) -{ - ECalendarViewPrivate *priv; - struct icaltimetype itt; - ECalComponentDateTime dt; - ECalComponent *comp; - icalcomponent *icalcomp; - ECalComponentTransparency transparency; - - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - priv = cal_view->priv; - - dt.value = &itt; - if (all_day) - dt.tzid = NULL; - else - dt.tzid = icaltimezone_get_tzid (e_cal_model_get_timezone (cal_view->priv->model)); - - icalcomp = e_cal_model_create_component_with_defaults (priv->model); - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomp); - - /* DTSTART, DTEND */ - itt = icaltime_from_timet_with_zone (dtstart, FALSE, e_cal_model_get_timezone (cal_view->priv->model)); - if (all_day) { - itt.hour = itt.minute = itt.second = 0; - itt.is_date = TRUE; - } - e_cal_component_set_dtstart (comp, &dt); - - itt = icaltime_from_timet_with_zone (dtend, FALSE, e_cal_model_get_timezone (cal_view->priv->model)); - 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; - } - e_cal_component_set_dtend (comp, &dt); - - /* TRANSPARENCY */ - transparency = all_day ? E_CAL_COMPONENT_TRANSP_TRANSPARENT - : E_CAL_COMPONENT_TRANSP_OPAQUE; - e_cal_component_set_transparency (comp, transparency); - - /* CATEGORY */ - e_cal_component_set_categories (comp, priv->default_category); - - /* edit the object */ - e_cal_component_commit_sequence (comp); - - e_calendar_view_edit_appointment (cal_view, - e_cal_model_get_default_client (priv->model), - icalcomp, meeting); - - g_object_unref (comp); -} - -/** - * e_calendar_view_new_appointment - * @cal_view: A calendar view. - * - * Opens an event editor dialog for a new appointment. The appointment's - * start and end times are set to the currently selected time range in - * the calendar view. - */ -void -e_calendar_view_new_appointment (ECalendarView *cal_view) -{ - time_t dtstart, dtend; - - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - e_calendar_view_get_selected_time_range (cal_view, &dtstart, &dtend); - e_calendar_view_new_appointment_for (cal_view, dtstart, dtend, FALSE, FALSE); -} - -/** - * e_calendar_view_edit_appointment - * @cal_view: A calendar view. - * @client: Calendar client. - * @icalcomp: The object to be edited. - * @meeting: Whether the appointment is a meeting or not. - * - * Opens an editor window to allow the user to edit the selected - * object. - */ -void -e_calendar_view_edit_appointment (ECalendarView *cal_view, - ECal *client, - icalcomponent *icalcomp, - gboolean meeting) -{ - ECalendarViewPrivate *priv; - CompEditor *ce; - const char *uid; - ECalComponent *comp; - - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - g_return_if_fail (E_IS_CAL (client)); - g_return_if_fail (icalcomp != NULL); - - priv = cal_view->priv; - - uid = icalcomponent_get_uid (icalcomp); - - ce = e_comp_editor_registry_find (comp_editor_registry, uid); - if (!ce) { - EventEditor *ee; - - ee = event_editor_new (client); - ce = COMP_EDITOR (ee); - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp)); - comp_editor_edit_comp (ce, comp); - if (meeting) - event_editor_show_meeting (ee); - - e_comp_editor_registry_add (comp_editor_registry, ce, FALSE); - - g_object_unref (comp); - } - - comp_editor_focus (ce); -} diff --git a/calendar/gui/e-cal-view.h b/calendar/gui/e-cal-view.h deleted file mode 100644 index a1b11023b3..0000000000 --- a/calendar/gui/e-cal-view.h +++ /dev/null @@ -1,137 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Rodrigo Moya <rodrigo@ximian.com> - * - * Copyright 2003, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ -#ifndef _E_CALENDAR_VIEW_H_ -#define _E_CALENDAR_VIEW_H_ - -#include <libecal/e-cal.h> -#include <gtk/gtktable.h> -#include "e-cal-model.h" -#include "gnome-cal.h" - -G_BEGIN_DECLS - -/* - * EView - base widget class for the calendar views. - */ - -#define E_CALENDAR_VIEW(obj) GTK_CHECK_CAST (obj, e_calendar_view_get_type (), ECalendarView) -#define E_CALENDAR_VIEW_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, e_calendar_view_get_type (), ECalendarViewClass) -#define E_IS_CALENDAR_VIEW(obj) GTK_CHECK_TYPE (obj, e_calendar_view_get_type ()) - -typedef enum { - E_CALENDAR_VIEW_POS_OUTSIDE, - E_CALENDAR_VIEW_POS_NONE, - E_CALENDAR_VIEW_POS_EVENT, - E_CALENDAR_VIEW_POS_LEFT_EDGE, - E_CALENDAR_VIEW_POS_RIGHT_EDGE, - E_CALENDAR_VIEW_POS_TOP_EDGE, - E_CALENDAR_VIEW_POS_BOTTOM_EDGE -} ECalendarViewPosition; - -#define E_CALENDAR_VIEW_EVENT_FIELDS \ - GnomeCanvasItem *canvas_item; \ - ECalModelComponent *comp_data; \ - gboolean allocated_comp_data; \ - time_t start; \ - time_t end; \ - guint16 start_minute; \ - guint16 end_minute; \ - guint different_timezone : 1; - -typedef struct { - E_CALENDAR_VIEW_EVENT_FIELDS -} ECalendarViewEvent; - -typedef struct _ECalendarView ECalendarView; -typedef struct _ECalendarViewClass ECalendarViewClass; -typedef struct _ECalendarViewPrivate ECalendarViewPrivate; - -struct _ECalendarView { - GtkTable table; - ECalendarViewPrivate *priv; -}; - -struct _ECalendarViewClass { - GtkTableClass parent_class; - - /* Notification signals */ - void (* selection_changed) (ECalendarView *cal_view); - void (* selected_time_changed) (ECalendarView *cal_view); - void (* timezone_changed) (ECalendarView *cal_view, icaltimezone *old_zone, icaltimezone *new_zone); - void (* event_changed) (ECalendarView *day_view, ECalendarViewEvent *event); - void (* event_added) (ECalendarView *day_view, ECalendarViewEvent *event); - - /* Virtual methods */ - GList * (* get_selected_events) (ECalendarView *cal_view); /* a GList of ECalendarViewEvent's */ - void (* get_selected_time_range) (ECalendarView *cal_view, time_t *start_time, time_t *end_time); - void (* set_selected_time_range) (ECalendarView *cal_view, time_t start_time, time_t end_time); - gboolean (* get_visible_time_range) (ECalendarView *cal_view, time_t *start_time, time_t *end_time); - void (* update_query) (ECalendarView *cal_view); -}; - -GType e_calendar_view_get_type (void); - -GnomeCalendar *e_calendar_view_get_calendar (ECalendarView *cal_view); -void e_calendar_view_set_calendar (ECalendarView *cal_view, GnomeCalendar *calendar); -ECalModel *e_calendar_view_get_model (ECalendarView *cal_view); -void e_calendar_view_set_model (ECalendarView *cal_view, ECalModel *model); -icaltimezone *e_calendar_view_get_timezone (ECalendarView *cal_view); -void e_calendar_view_set_timezone (ECalendarView *cal_view, icaltimezone *zone); -const char *e_calendar_view_get_default_category (ECalendarView *cal_view); -void e_calendar_view_set_default_category (ECalendarView *cal_view, const char *category); -gboolean e_calendar_view_get_use_24_hour_format (ECalendarView *view); -void e_calendar_view_set_use_24_hour_format (ECalendarView *view, gboolean use_24_hour); - -void e_calendar_view_set_status_message (ECalendarView *cal_view, const gchar *message); - -GList *e_calendar_view_get_selected_events (ECalendarView *cal_view); -void e_calendar_view_get_selected_time_range (ECalendarView *cal_view, time_t *start_time, time_t *end_time); -void e_calendar_view_set_selected_time_range (ECalendarView *cal_view, time_t start_time, time_t end_time); -gboolean e_calendar_view_get_visible_time_range (ECalendarView *cal_view, time_t *start_time, time_t *end_time); -void e_calendar_view_update_query (ECalendarView *cal_view); - -void e_calendar_view_cut_clipboard (ECalendarView *cal_view); -void e_calendar_view_copy_clipboard (ECalendarView *cal_view); -void e_calendar_view_paste_clipboard (ECalendarView *cal_view); -void e_calendar_view_delete_selected_event (ECalendarView *cal_view); -void e_calendar_view_delete_selected_events (ECalendarView *cal_view); -void e_calendar_view_delete_selected_occurrence (ECalendarView *cal_view); - -GtkMenu *e_calendar_view_create_popup_menu (ECalendarView *cal_view); - -void e_calendar_view_add_event (ECalendarView *cal_view, ECal *client, time_t dtstart, - icaltimezone *default_zone, icalcomponent *icalcomp, gboolean in_top_canvas); -void e_calendar_view_new_appointment_for (ECalendarView *cal_view, - time_t dtstart, - time_t dtend, - gboolean all_day, - gboolean meeting); -void e_calendar_view_new_appointment (ECalendarView *cal_view); -void e_calendar_view_edit_appointment (ECalendarView *cal_view, - ECal *client, - icalcomponent *icalcomp, - gboolean meeting); - -G_END_DECLS - -#endif diff --git a/calendar/gui/e-calendar-marshal.list b/calendar/gui/e-calendar-marshal.list deleted file mode 100644 index 86087cf1ae..0000000000 --- a/calendar/gui/e-calendar-marshal.list +++ /dev/null @@ -1,15 +0,0 @@ -NONE:INT -NONE:POINTER -NONE:INT,STRING -NONE:INT,BOOL -NONE:INT,POINTER -NONE:STRING,INT -NONE:INT,INT -NONE:ENUM,ENUM -NONE:ENUM,STRING -NONE:STRING,BOOL,INT,INT -NONE:STRING,STRING -NONE:STRING,STRING,STRING -NONE:POINTER,ENUM -NONE:POINTER,STRING -NONE:POINTER,POINTER diff --git a/calendar/gui/e-calendar-table-config.c b/calendar/gui/e-calendar-table-config.c deleted file mode 100644 index 74be72143f..0000000000 --- a/calendar/gui/e-calendar-table-config.c +++ /dev/null @@ -1,263 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Author : - * JP Rosevear <jpr@ximian.com> - * - * Copyright 2003, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include "calendar-config.h" -#include "e-cell-date-edit-config.h" -#include "e-calendar-table-config.h" - -struct _ECalendarTableConfigPrivate { - ECalendarTable *table; - - ECellDateEditConfig *cell_config; - - GList *notifications; -}; - -static GObjectClass *parent_class = NULL; - -/* Property IDs */ -enum props { - PROP_0, - PROP_TABLE -}; - -static void -e_calendar_table_config_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) -{ - ECalendarTableConfig *table_config; - ECalendarTableConfigPrivate *priv; - - table_config = E_CALENDAR_TABLE_CONFIG (object); - priv = table_config->priv; - - switch (property_id) { - case PROP_TABLE: - e_calendar_table_config_set_table (table_config, g_value_get_object (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -e_calendar_table_config_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) -{ - ECalendarTableConfig *table_config; - ECalendarTableConfigPrivate *priv; - - table_config = E_CALENDAR_TABLE_CONFIG (object); - priv = table_config->priv; - - switch (property_id) { - case PROP_TABLE: - g_value_set_object (value, e_calendar_table_config_get_table (table_config)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -e_calendar_table_config_dispose (GObject *object) -{ - ECalendarTableConfig *table_config = E_CALENDAR_TABLE_CONFIG (object); - ECalendarTableConfigPrivate *priv; - - priv = table_config->priv; - - e_calendar_table_config_set_table (table_config, NULL); - - if (G_OBJECT_CLASS (parent_class)->dispose) - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -e_calendar_table_config_finalize (GObject *object) -{ - ECalendarTableConfig *table_config = E_CALENDAR_TABLE_CONFIG (object); - ECalendarTableConfigPrivate *priv; - - priv = table_config->priv; - - g_free (priv); - - if (G_OBJECT_CLASS (parent_class)->finalize) - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -e_calendar_table_config_class_init (ECalendarTableConfigClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GParamSpec *spec; - - parent_class = g_type_class_peek_parent (klass); - - /* Method override */ - gobject_class->set_property = e_calendar_table_config_set_property; - gobject_class->get_property = e_calendar_table_config_get_property; - gobject_class->dispose = e_calendar_table_config_dispose; - gobject_class->finalize = e_calendar_table_config_finalize; - - spec = g_param_spec_object ("table", NULL, NULL, e_calendar_table_get_type (), - G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT); - g_object_class_install_property (gobject_class, PROP_TABLE, spec); -} - -static void -e_calendar_table_config_init (ECalendarTableConfig *table_config, ECalendarTableConfigClass *klass) -{ - table_config->priv = g_new0 (ECalendarTableConfigPrivate, 1); - -} - -E_MAKE_TYPE (e_calendar_table_config, "ECalendarTableConfig", ECalendarTableConfig, e_calendar_table_config_class_init, - e_calendar_table_config_init, G_TYPE_OBJECT); - -ECalendarTableConfig * -e_calendar_table_config_new (ECalendarTable *table) -{ - ECalendarTableConfig *table_config; - - table_config = g_object_new (e_calendar_table_config_get_type (), "table", table, NULL); - - return table_config; -} - -ECalendarTable * -e_calendar_table_config_get_table (ECalendarTableConfig *table_config) -{ - ECalendarTableConfigPrivate *priv; - - g_return_val_if_fail (table_config != NULL, NULL); - g_return_val_if_fail (E_IS_CALENDAR_TABLE_CONFIG (table_config), NULL); - - priv = table_config->priv; - - return priv->table; -} - -static void -set_timezone (ECalendarTable *table) -{ - ECalModel *model; - char *location; - icaltimezone *zone; - - location = calendar_config_get_timezone (); - zone = icaltimezone_get_builtin_timezone (location); - if (!zone) - zone = icaltimezone_get_utc_timezone (); - - model = e_calendar_table_get_model (table); - if (model) - e_cal_model_set_timezone (model, zone); - - g_free (location); -} - -static void -timezone_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - ECalendarTableConfig *table_config = data; - ECalendarTableConfigPrivate *priv; - - priv = table_config->priv; - - set_timezone (priv->table); -} - -static void -set_twentyfour_hour (ECalendarTable *table) -{ - ECalModel *model; - gboolean use_24_hour; - - use_24_hour = calendar_config_get_24_hour_format (); - - model = e_calendar_table_get_model (table); - if (model) - e_cal_model_set_use_24_hour_format (model, use_24_hour); -} - -static void -twentyfour_hour_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - ECalendarTableConfig *table_config = data; - ECalendarTableConfigPrivate *priv; - - priv = table_config->priv; - - set_twentyfour_hour (priv->table); -} - -void -e_calendar_table_config_set_table (ECalendarTableConfig *table_config, ECalendarTable *table) -{ - ECalendarTableConfigPrivate *priv; - guint not; - GList *l; - - g_return_if_fail (table_config != NULL); - g_return_if_fail (E_IS_CALENDAR_TABLE_CONFIG (table_config)); - - priv = table_config->priv; - - if (priv->table) { - g_object_unref (priv->table); - priv->table = NULL; - } - - if (priv->cell_config) { - g_object_unref (priv->cell_config); - priv->cell_config = NULL; - } - - for (l = priv->notifications; l; l = l->next) - calendar_config_remove_notification (GPOINTER_TO_UINT (l->data)); - - g_list_free (priv->notifications); - priv->notifications = NULL; - - /* If the new view is NULL, return right now */ - if (!table) - return; - - priv->table = g_object_ref (table); - - /* Time zone */ - set_timezone (table); - - not = calendar_config_add_notification_timezone (timezone_changed_cb, table_config); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - /* 24 Hour format */ - set_twentyfour_hour (table); - - not = calendar_config_add_notification_24_hour_format (twentyfour_hour_changed_cb, table_config); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - /* Date cell */ - priv->cell_config = e_cell_date_edit_config_new (table->dates_cell); -} diff --git a/calendar/gui/e-calendar-table-config.h b/calendar/gui/e-calendar-table-config.h deleted file mode 100644 index 399f3254d1..0000000000 --- a/calendar/gui/e-calendar-table-config.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Author : - * JP Rosevear <jpr@ximian.com> - * - * Copyright 2003, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef _E_CALENDAR_TABLE_CONFIG_H_ -#define _E_CALENDAR_TABLE_CONFIG_H_ - -#include "e-calendar-table.h" - -G_BEGIN_DECLS - -#define E_CALENDAR_TABLE_CONFIG(obj) GTK_CHECK_CAST (obj, e_calendar_table_config_get_type (), ECalendarTableConfig) -#define E_CALENDAR_TABLE_CONFIG_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, e_calendar_table_config_get_type (), ECalendarTableConfigClass) -#define E_IS_CALENDAR_TABLE_CONFIG(obj) GTK_CHECK_TYPE (obj, e_calendar_table_config_get_type ()) - -typedef struct _ECalendarTableConfig ECalendarTableConfig; -typedef struct _ECalendarTableConfigClass ECalendarTableConfigClass; -typedef struct _ECalendarTableConfigPrivate ECalendarTableConfigPrivate; - -struct _ECalendarTableConfig { - GObject parent; - - ECalendarTableConfigPrivate *priv; -}; - -struct _ECalendarTableConfigClass { - GObjectClass parent_class; -}; - -GType e_calendar_table_config_get_type (void); -ECalendarTableConfig *e_calendar_table_config_new (ECalendarTable *table); -ECalendarTable *e_calendar_table_config_get_table (ECalendarTableConfig *view_config); -void e_calendar_table_config_set_table (ECalendarTableConfig *view_config, ECalendarTable *table); - -G_END_DECLS - -#endif diff --git a/calendar/gui/e-calendar-table.c b/calendar/gui/e-calendar-table.c deleted file mode 100644 index d9ea59905b..0000000000 --- a/calendar/gui/e-calendar-table.c +++ /dev/null @@ -1,1464 +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, 2001, 2002, 2003 Novell, 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 ECalComponent 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/widgets/e-gui-utils.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/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 "calendar-component.h" -#include "calendar-config.h" -#include "dialogs/delete-comp.h" -#include "dialogs/delete-error.h" -#include "dialogs/task-editor.h" -#include "e-cal-model-tasks.h" -#include "e-calendar-table.h" -#include "e-cell-date-edit-text.h" -#include "e-comp-editor-registry.h" -#include "print.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" - -extern ECompEditorRegistry *comp_editor_registry; - -static void e_calendar_table_class_init (ECalendarTableClass *class); -static void e_calendar_table_init (ECalendarTable *cal_table); -static void e_calendar_table_destroy (GtkObject *object); - -static void e_calendar_table_on_double_click (ETable *table, - gint row, - gint col, - GdkEvent *event, - ECalendarTable *cal_table); -static gint e_calendar_table_show_popup_menu (ETable *table, - GdkEvent *gdk_event, - ECalendarTable *cal_table); - -static gint e_calendar_table_on_right_click (ETable *table, - gint row, - gint col, - GdkEvent *event, - ECalendarTable *cal_table); -static gboolean e_calendar_table_on_popup_menu (GtkWidget *widget, - gpointer data); - -static 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 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; - -E_MAKE_TYPE (e_calendar_table, "ECalendarTable", ECalendarTable, e_calendar_table_class_init, - e_calendar_table_init, GTK_TYPE_TABLE); - -static void -e_calendar_table_class_init (ECalendarTableClass *class) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - - parent_class = g_type_class_peek_parent (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 ECalComponents, but I think it - * may just be passed pointers to the 2 cell values. - */ -static gint -task_compare_cb (gconstpointer a, gconstpointer b) -{ - ECalComponent *ca, *cb; - ECalComponentDateTime due_a, due_b; - int *prio_a, *prio_b; - int retval; - - ca = E_CAL_COMPONENT (a); - cb = E_CAL_COMPONENT (b); - - e_cal_component_get_due (ca, &due_a); - e_cal_component_get_due (cb, &due_b); - e_cal_component_get_priority (ca, &prio_a); - e_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 - ECal, 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); - - e_cal_component_free_datetime (&due_a); - e_cal_component_free_datetime (&due_b); - - if (prio_a) - e_cal_component_free_priority (prio_a); - - if (prio_b) - e_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 = e_cal_util_priority_from_string ((const char*) a); - priority2 = e_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 = (ECalModel *) e_cal_model_tasks_new (); - - /* Create the header columns */ - - extras = e_table_extras_new(); - - /* - * Normal string fields. - */ - cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT); - g_object_set (G_OBJECT (cell), - "strikeout_column", E_CAL_MODEL_TASKS_FIELD_COMPLETE, - "bold_column", E_CAL_MODEL_TASKS_FIELD_OVERDUE, - "color_column", E_CAL_MODEL_FIELD_COLOR, - NULL); - - e_table_extras_add_cell (extras, "calstring", cell); - - - /* - * Date fields. - */ - cell = e_cell_date_edit_text_new (NULL, GTK_JUSTIFY_LEFT); - g_object_set (G_OBJECT (cell), - "strikeout_column", E_CAL_MODEL_TASKS_FIELD_COMPLETE, - "bold_column", E_CAL_MODEL_TASKS_FIELD_OVERDUE, - "color_column", E_CAL_MODEL_FIELD_COLOR, - NULL); - - popup_cell = e_cell_date_edit_new (); - e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell); - g_object_unref (cell); - e_table_extras_add_cell (extras, "dateedit", popup_cell); - 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); - g_object_set (G_OBJECT (cell), - "strikeout_column", E_CAL_MODEL_TASKS_FIELD_COMPLETE, - "bold_column", E_CAL_MODEL_TASKS_FIELD_OVERDUE, - "color_column", E_CAL_MODEL_FIELD_COLOR, - "editable", FALSE, - NULL); - - popup_cell = e_cell_combo_new (); - e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell); - g_object_unref (cell); - - strings = NULL; - strings = g_list_append (strings, (char*) _("Public")); - strings = g_list_append (strings, (char*) _("Private")); - strings = g_list_append (strings, (char*) _("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); - g_object_set (G_OBJECT (cell), - "strikeout_column", E_CAL_MODEL_TASKS_FIELD_COMPLETE, - "bold_column", E_CAL_MODEL_TASKS_FIELD_OVERDUE, - "color_column", E_CAL_MODEL_FIELD_COLOR, - "editable", FALSE, - NULL); - - popup_cell = e_cell_combo_new (); - e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell); - g_object_unref (cell); - - strings = NULL; - strings = g_list_append (strings, (char*) _("High")); - strings = g_list_append (strings, (char*) _("Normal")); - strings = g_list_append (strings, (char*) _("Low")); - strings = g_list_append (strings, (char*) _("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); - g_object_set (G_OBJECT (cell), - "strikeout_column", E_CAL_MODEL_TASKS_FIELD_COMPLETE, - "bold_column", E_CAL_MODEL_TASKS_FIELD_OVERDUE, - "color_column", E_CAL_MODEL_FIELD_COLOR, - NULL); - - popup_cell = e_cell_combo_new (); - e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell); - g_object_unref (cell); - - strings = NULL; - strings = g_list_append (strings, (char*) _("0%")); - strings = g_list_append (strings, (char*) _("10%")); - strings = g_list_append (strings, (char*) _("20%")); - strings = g_list_append (strings, (char*) _("30%")); - strings = g_list_append (strings, (char*) _("40%")); - strings = g_list_append (strings, (char*) _("50%")); - strings = g_list_append (strings, (char*) _("60%")); - strings = g_list_append (strings, (char*) _("70%")); - strings = g_list_append (strings, (char*) _("80%")); - strings = g_list_append (strings, (char*) _("90%")); - strings = g_list_append (strings, (char*) _("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); - g_object_set (G_OBJECT (cell), - "strikeout_column", E_CAL_MODEL_TASKS_FIELD_COMPLETE, - "bold_column", E_CAL_MODEL_TASKS_FIELD_OVERDUE, - "color_column", E_CAL_MODEL_FIELD_COLOR, - "editable", FALSE, - NULL); - - popup_cell = e_cell_combo_new (); - e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell); - g_object_unref (cell); - - strings = NULL; - strings = g_list_append (strings, (char*) _("Free")); - strings = g_list_append (strings, (char*) _("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); - g_object_set (G_OBJECT (cell), - "strikeout_column", E_CAL_MODEL_TASKS_FIELD_COMPLETE, - "bold_column", E_CAL_MODEL_TASKS_FIELD_OVERDUE, - "color_column", E_CAL_MODEL_FIELD_COLOR, - "editable", FALSE, - NULL); - - popup_cell = e_cell_combo_new (); - e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell); - g_object_unref (cell); - - strings = NULL; - strings = g_list_append (strings, (char*) _("Not Started")); - strings = g_list_append (strings, (char*) _("In Progress")); - strings = g_list_append (strings, (char*) _("Completed")); - strings = g_list_append (strings, (char*) _("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); - /* FIXME: this causes a message from GLib about 'extras' having only a floating - reference */ - /* g_object_unref (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)); - g_signal_connect (e_table, "double_click", G_CALLBACK (e_calendar_table_on_double_click), cal_table); - g_signal_connect (e_table, "right_click", G_CALLBACK (e_calendar_table_on_right_click), cal_table); - g_signal_connect (e_table, "key_press", G_CALLBACK (e_calendar_table_on_key_press), cal_table); - g_signal_connect (e_table, "popup_menu", G_CALLBACK (e_calendar_table_on_popup_menu), cal_table); - - /* 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); - g_signal_connect (cal_table->invisible, "selection_get", - G_CALLBACK (selection_get), cal_table); - g_signal_connect (cal_table->invisible, "selection_clear_event", - G_CALLBACK (selection_clear_event), cal_table); - g_signal_connect (cal_table->invisible, "selection_received", - G_CALLBACK (selection_received), 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 (g_object_new (e_calendar_table_get_type (), NULL)); - - 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. - **/ -ECalModel * -e_calendar_table_get_model (ECalendarTable *cal_table) -{ - g_return_val_if_fail (cal_table != NULL, NULL); - g_return_val_if_fail (E_IS_CALENDAR_TABLE (cal_table), NULL); - - return cal_table->model; -} - - -static void -e_calendar_table_destroy (GtkObject *object) -{ - ECalendarTable *cal_table; - - cal_table = E_CALENDAR_TABLE (object); - - if (cal_table->model) { - g_object_unref (cal_table->model); - cal_table->model = NULL; - } - - if (cal_table->invisible) { - gtk_widget_destroy (cal_table->invisible); - cal_table->invisible = NULL; - } - 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 ECalModelComponent * -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 e_cal_model_get_component_at (cal_table->model, row); -} - -struct get_selected_uids_closure { - ECalendarTable *cal_table; - GSList *objects; -}; - -/* 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; - ECalModelComponent *comp_data; - - closure = data; - - comp_data = e_cal_model_get_component_at (closure->cal_table->model, model_row); - - closure->objects = g_slist_prepend (closure->objects, comp_data); -} - -static GSList * -get_selected_objects (ECalendarTable *cal_table) -{ - struct get_selected_uids_closure closure; - ETable *etable; - - closure.cal_table = cal_table; - closure.objects = NULL; - - etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable)); - e_table_selected_row_foreach (etable, add_uid_cb, &closure); - - return closure.objects; -} - -/* Deletes all of the selected components in the table */ -static void -delete_selected_components (ECalendarTable *cal_table) -{ - GSList *objs, *l; - - objs = get_selected_objects (cal_table); - - e_calendar_table_set_status_message (cal_table, _("Deleting selected objects")); - - for (l = objs; l; l = l->next) { - ECalModelComponent *comp_data = (ECalModelComponent *) l->data; - GError *error = NULL; - - e_cal_remove_object (comp_data->client, - icalcomponent_get_uid (comp_data->icalcomp), &error); - delete_error_dialog (error, E_CAL_COMPONENT_TODO); - g_clear_error (&error); - } - - e_calendar_table_set_status_message (cal_table, NULL); - - g_slist_free (objs); -} - -/** - * 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; - ECalModelComponent *comp_data; - ECalComponent *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_data = get_selected_comp (cal_table); - else - comp_data = NULL; - - /* FIXME: this may be something other than a TODO component */ - - comp = e_cal_component_new (); - if (comp_data) - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp)); - - if (delete_component_dialog (comp, FALSE, n_selected, E_CAL_COMPONENT_TODO, - GTK_WIDGET (cal_table))) - delete_selected_components (cal_table); - - /* free memory */ - g_object_unref (comp); -} - -/** - * 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; - ECalModelComponent *comp_data; - gchar *comp_str; - icalcomponent *child; - - cal_table = E_CALENDAR_TABLE (data); - - g_return_if_fail (cal_table->tmp_vcal != NULL); - - comp_data = e_cal_model_get_component_at (cal_table->model, model_row); - if (!comp_data) - return; - - /* add timezones to the VCALENDAR component */ - e_cal_util_add_timezones_from_component (cal_table->tmp_vcal, comp_data->icalcomp); - - /* add the new component to the VCALENDAR component */ - comp_str = icalcomponent_as_ical_string (comp_data->icalcomp); - child = icalparser_parse_string (comp_str); - if (child) { - icalcomponent_add_component (cal_table->tmp_vcal, - icalcomponent_new_clone (child)); - icalcomponent_free (child); - } -} - -/** - * 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 = e_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, ECalModelComponent *comp_data, gboolean assign) -{ - CompEditor *tedit; - const char *uid; - - uid = icalcomponent_get_uid (comp_data->icalcomp); - - tedit = e_comp_editor_registry_find (comp_editor_registry, uid); - if (tedit == NULL) { - ECalComponent *comp; - - tedit = COMP_EDITOR (task_editor_new (comp_data->client)); - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp)); - comp_editor_edit_comp (tedit, comp); - if (assign) - task_editor_show_assignment (TASK_EDITOR (tedit)); - - e_comp_editor_registry_add (comp_editor_registry, tedit, FALSE); - } - - comp_editor_focus (tedit); -} - -/* Opens the task in the specified row */ -static void -open_task_by_row (ECalendarTable *cal_table, int row) -{ - ECalModelComponent *comp_data; - - comp_data = e_cal_model_get_component_at (cal_table->model, row); - open_task (cal_table, comp_data, 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); - e_cal_model_tasks_mark_task_complete (E_CAL_MODEL_TASKS (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); -} - -/* Opens the URL of the task */ -static void -open_url_cb (GtkWidget *menuitem, gpointer data) -{ - ECalendarTable *cal_table; - ECalModelComponent *comp_data; - icalproperty *prop; - - cal_table = E_CALENDAR_TABLE (data); - - comp_data = get_selected_comp (cal_table); - if (!comp_data) - return; - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_URL_PROPERTY); - if (!prop) - return; - - gnome_url_show (icalproperty_get_url (prop), NULL); -} - -/* 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. */ - MASK_EDITABLE = 1 << 2, /* For commands disabled in read-only folders */ - MASK_ASSIGNABLE = 1 << 3, /* For non-task assignable backends */ - MASK_LACKS_URL = 1 << 4 /* For tasks that don't have the URL property set */ -}; - - -static EPopupMenu tasks_popup_menu [] = { - E_POPUP_ITEM (N_("_Open"), GTK_SIGNAL_FUNC (e_calendar_table_on_open_task), MASK_SINGLE), - E_POPUP_ITEM (N_("Open _Web Page"), GTK_SIGNAL_FUNC (open_url_cb), MASK_SINGLE | MASK_LACKS_URL), - E_POPUP_ITEM (N_("_Save As..."), GTK_SIGNAL_FUNC (e_calendar_table_on_save_as), MASK_SINGLE), - E_POPUP_ITEM (N_("_Print..."), GTK_SIGNAL_FUNC (e_calendar_table_on_print_task), MASK_SINGLE), - - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("C_ut"), GTK_SIGNAL_FUNC (e_calendar_table_on_cut), MASK_EDITABLE), - E_POPUP_ITEM (N_("_Copy"), GTK_SIGNAL_FUNC (e_calendar_table_on_copy), 0), - E_POPUP_ITEM (N_("_Paste"), GTK_SIGNAL_FUNC (e_calendar_table_on_paste), MASK_EDITABLE), - - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("_Assign Task"), GTK_SIGNAL_FUNC (e_calendar_table_on_assign), MASK_SINGLE | MASK_EDITABLE | MASK_ASSIGNABLE), - E_POPUP_ITEM (N_("_Forward as iCalendar"), GTK_SIGNAL_FUNC (e_calendar_table_on_forward), MASK_SINGLE), - E_POPUP_ITEM (N_("_Mark as Complete"), GTK_SIGNAL_FUNC (mark_as_complete_cb), MASK_SINGLE | MASK_EDITABLE), - E_POPUP_ITEM (N_("_Mark Selected Tasks as Complete"), GTK_SIGNAL_FUNC (mark_as_complete_cb), MASK_MULTIPLE | MASK_EDITABLE), - - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("_Delete"), GTK_SIGNAL_FUNC (delete_cb), MASK_SINGLE | MASK_EDITABLE), - E_POPUP_ITEM (N_("_Delete Selected Tasks"), GTK_SIGNAL_FUNC (delete_cb), MASK_MULTIPLE | MASK_EDITABLE), - - E_POPUP_TERMINATOR -}; - -static void -setup_popup_icons (EPopupMenu *context_menu) -{ - gint i; - - for (i = 0; context_menu[i].name; i++) { - GtkWidget *pixmap_widget = NULL; - - if (!strcmp (context_menu[i].name, _("_Copy"))) - pixmap_widget = gtk_image_new_from_stock (GTK_STOCK_COPY, GTK_ICON_SIZE_MENU); - else if (!strcmp (context_menu[i].name, _("C_ut"))) - pixmap_widget = gtk_image_new_from_stock (GTK_STOCK_CUT, GTK_ICON_SIZE_MENU); - else if (!strcmp (context_menu[i].name, _("_Delete")) || - !strcmp (context_menu[i].name, _("_Delete Selected Tasks"))) - pixmap_widget = gtk_image_new_from_stock (GTK_STOCK_DELETE, GTK_ICON_SIZE_MENU); - else if (!strcmp (context_menu[i].name, _("_Open"))) - pixmap_widget = gtk_image_new_from_stock (GTK_STOCK_OPEN, GTK_ICON_SIZE_MENU); - else if (!strcmp (context_menu[i].name, _("_Paste"))) - pixmap_widget = gtk_image_new_from_stock (GTK_STOCK_PASTE, GTK_ICON_SIZE_MENU); - else if (!strcmp (context_menu[i].name, _("_Print..."))) - pixmap_widget = gtk_image_new_from_stock (GTK_STOCK_PRINT, GTK_ICON_SIZE_MENU); - else if (!strcmp (context_menu[i].name, _("_Save As..."))) - pixmap_widget = gtk_image_new_from_stock (GTK_STOCK_SAVE_AS, GTK_ICON_SIZE_MENU); - - if (pixmap_widget) - gtk_widget_show (pixmap_widget); - context_menu[i].pixmap_widget = pixmap_widget; - } -} - -static gint -e_calendar_table_show_popup_menu (ETable *table, - GdkEvent *gdk_event, - ECalendarTable *cal_table) -{ - int n_selected; - int hide_mask = 0; - int disable_mask = 0; - GtkMenu *gtk_menu; - icalproperty *prop; - ECalModelComponent *comp_data; - gboolean read_only = TRUE; - - n_selected = e_table_selected_count (table); - if (n_selected <= 0) - return TRUE; - - comp_data = get_selected_comp (cal_table); - g_assert (comp_data != NULL); - - if (n_selected == 1) { - hide_mask = MASK_MULTIPLE; - - /* See if the task has the URL property set */ - - prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_URL_PROPERTY); - if (!prop) - disable_mask |= MASK_LACKS_URL; - } else - hide_mask = MASK_SINGLE; - - e_cal_is_read_only (comp_data->client, &read_only, NULL); - if (read_only) - disable_mask |= MASK_EDITABLE; - - if (e_cal_get_static_capability (comp_data->client, CAL_STATIC_CAPABILITY_NO_TASK_ASSIGNMENT)) - disable_mask |= MASK_ASSIGNABLE; - - setup_popup_icons (tasks_popup_menu); - gtk_menu = e_popup_menu_create (tasks_popup_menu, disable_mask, - hide_mask, cal_table); - - e_popup_menu (gtk_menu, gdk_event); - - return TRUE; -} - -static gint -e_calendar_table_on_right_click (ETable *table, - gint row, - gint col, - GdkEvent *event, - ECalendarTable *cal_table) -{ - return e_calendar_table_show_popup_menu (table, event, cal_table); -} - -static gboolean -e_calendar_table_on_popup_menu (GtkWidget *widget, gpointer data) -{ - ETable *table = E_TABLE(widget); - g_return_val_if_fail(table, FALSE); - - return e_calendar_table_show_popup_menu (table, NULL, - E_CALENDAR_TABLE(data)); -} - -static void -e_calendar_table_on_open_task (GtkWidget *menuitem, - gpointer data) -{ - ECalendarTable *cal_table; - ECalModelComponent *comp_data; - - cal_table = E_CALENDAR_TABLE (data); - - comp_data = get_selected_comp (cal_table); - if (comp_data) - open_task (cal_table, comp_data, FALSE); -} - -static void -e_calendar_table_on_save_as (GtkWidget *widget, gpointer data) -{ - ECalendarTable *cal_table; - ECalModelComponent *comp_data; - char *filename; - char *ical_string; - FILE *file; - - cal_table = E_CALENDAR_TABLE (data); - - comp_data = get_selected_comp (cal_table); - if (comp_data == NULL) - return; - - filename = e_file_dialog_save (_("Save as...")); - if (filename == NULL) - return; - - ical_string = e_cal_get_component_as_string (comp_data->client, comp_data->icalcomp); - if (ical_string == NULL) { - g_warning ("Couldn't convert item to a string"); - return; - } - - 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; - ECalModelComponent *comp_data; - ECalComponent *comp; - - cal_table = E_CALENDAR_TABLE (data); - - comp_data = get_selected_comp (cal_table); - if (comp_data == NULL) - return; - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp)); - print_comp (comp, comp_data->client, FALSE); - - g_object_unref (comp); -} - -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; - ECalModelComponent *comp_data; - - cal_table = E_CALENDAR_TABLE (data); - - comp_data = get_selected_comp (cal_table); - if (comp_data) - open_task (cal_table, comp_data, TRUE); -} - -static void -e_calendar_table_on_forward (GtkWidget *widget, gpointer data) -{ - ECalendarTable *cal_table; - ECalModelComponent *comp_data; - - cal_table = E_CALENDAR_TABLE (data); - - comp_data = get_selected_comp (cal_table); - if (comp_data) { - ECalComponent *comp; - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp)); - itip_send_comp (E_CAL_COMPONENT_METHOD_PUBLISH, comp, comp_data->client, NULL); - - g_object_unref (comp); - } -} - -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 -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; - ECalComponent *comp; - ECal *client; - 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; - } - - client = e_cal_model_get_default_client (cal_table->model); - - e_calendar_table_set_status_message (cal_table, _("Updating objects")); - - if (kind == ICAL_VCALENDAR_COMPONENT) { - 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) { - ECalComponent *tmp_comp; - - uid = e_cal_component_gen_uid (); - tmp_comp = e_cal_component_new (); - e_cal_component_set_icalcomponent ( - tmp_comp, icalcomponent_new_clone (subcomp)); - e_cal_component_set_uid (tmp_comp, uid); - free (uid); - - /* FIXME should we convert start/due/complete times? */ - /* FIXME Error handling */ - e_cal_create_object (client, e_cal_component_get_icalcomponent (tmp_comp), NULL, NULL); - - g_object_unref (tmp_comp); - } - subcomp = icalcomponent_get_next_component ( - vcal_comp, ICAL_ANY_COMPONENT); - } - } - else { - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomp); - uid = e_cal_component_gen_uid (); - e_cal_component_set_uid (comp, (const char *) uid); - free (uid); - - e_cal_create_object (client, e_cal_component_get_icalcomponent (comp), NULL, NULL); - - g_object_unref (comp); - } - - e_calendar_table_set_status_message (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 - -/* Displays messages on the status bar */ -#define EVOLUTION_TASKS_PROGRESS_IMAGE "evolution-tasks-mini.png" -static GdkPixbuf *progress_icon = NULL; - -void -e_calendar_table_set_status_message (ECalendarTable *cal_table, const gchar *message) -{ - EActivityHandler *activity_handler = calendar_component_peek_activity_handler (calendar_component_peek ()); - - g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table)); - - if (!message || !*message) { - if (cal_table->activity_id != 0) { - e_activity_handler_operation_finished (activity_handler, cal_table->activity_id); - cal_table->activity_id = 0; - } - } else if (cal_table->activity_id == 0) { - char *client_id = g_strdup_printf ("%p", cal_table); - - if (progress_icon == NULL) - progress_icon = gdk_pixbuf_new_from_file (EVOLUTION_IMAGESDIR "/" EVOLUTION_TASKS_PROGRESS_IMAGE, NULL); - - cal_table->activity_id = e_activity_handler_operation_started (activity_handler, client_id, - progress_icon, message, TRUE); - - g_free (client_id); - } else { - e_activity_handler_operation_progressing (activity_handler, cal_table->activity_id, message, -1.0); - } -} diff --git a/calendar/gui/e-calendar-table.etspec b/calendar/gui/e-calendar-table.etspec deleted file mode 100644 index 2d87771d53..0000000000 --- a/calendar/gui/e-calendar-table.etspec +++ /dev/null @@ -1,25 +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="4" _title="Description" expansion="2.0" minimum_width="10" resizable="true" cell="calstring" compare="string" priority="-1"/> - <ETableColumn model_col= "5" _title="Start Date" expansion="2.0" minimum_width="10" resizable="true" cell="dateedit" compare="date-compare" priority="-2"/> - <ETableColumn model_col="6" _title="Alarms" expansion="1.0" minimum_width="10" resizable="true" cell="calstring" compare="string" disabled="true"/> - <ETableColumn model_col="7" pixbuf="icon" _title="Type" expansion="1.0" minimum_width="16" resizable="false" cell="icon" compare="integer" priority="-4"/> - <ETableColumn model_col= "8" _title="Summary" expansion="3.0" minimum_width="10" resizable="true" cell="calstring" compare="string" priority="10"/> - <ETableColumn model_col= "10" _title="Completion Date" expansion="2.0" minimum_width="10" resizable="true" cell="dateedit" compare="date-compare" priority="-2"/> - <ETableColumn model_col="11" pixbuf="complete" _title="Complete" expansion="1.0" minimum_width="16" resizable="false" cell="checkbox" compare="integer" priority="-4"/> - <ETableColumn model_col= "12" _title="Due Date" expansion="2.0" minimum_width="10" resizable="true" cell="dateedit" compare="date-compare" priority="-2"/> - <ETableColumn model_col= "13" _title="Geographical Position" expansion="1.0" minimum_width="10" resizable="true" cell="calstring" compare="string"/> - <ETableColumn model_col= "15" _title="% Complete" expansion="1.0" minimum_width="10" resizable="true" cell="percent" compare="percent-compare" priority="-3"/> - <ETableColumn model_col= "16" _title="Priority" expansion="1.0" minimum_width="10" resizable="true" cell="priority" compare="priority-compare" priority="-3"/> - <ETableColumn model_col="17" _title="Status" expansion="1.0" minimum_width="10" resizable="true" cell="calstatus" compare="string" priority="-1"/> - <ETableColumn model_col="18" _title="URL" expansion="2.0" minimum_width="10" resizable="true" cell="calstring" compare="string"/> - <ETableColumn model_col="19" _title="Task sort" cell="task-sort" compare="task-sort" priority="-4"/> - - <ETableState> - <column source="7"/> - <column source="11"/> - <column source= "8"/> - <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 810c78254b..0000000000 --- a/calendar/gui/e-calendar-table.h +++ /dev/null @@ -1,101 +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 "e-cal-model.h" - -G_BEGIN_DECLS - -/* - * 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 */ - ECalModel *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; - - /* Activity ID for the EActivityHandler (i.e. the status bar). */ - guint activity_id; -}; - -struct _ECalendarTableClass { - GtkTableClass parent_class; -}; - - -GtkType e_calendar_table_get_type (void); -GtkWidget* e_calendar_table_new (void); - -ECalModel *e_calendar_table_get_model (ECalendarTable *cal_table); - -ETable *e_calendar_table_get_table (ECalendarTable *cal_table); - -void e_calendar_table_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); - -void e_calendar_table_set_status_message (ECalendarTable *cal_table, - const gchar *message); - -G_END_DECLS - -#endif /* _E_CALENDAR_TABLE_H_ */ diff --git a/calendar/gui/e-calendar-view.c b/calendar/gui/e-calendar-view.c deleted file mode 100644 index f93cee6c10..0000000000 --- a/calendar/gui/e-calendar-view.c +++ /dev/null @@ -1,1492 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Rodrigo Moya <rodrigo@ximian.com> - * - * Copyright 2003, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include <config.h> -#include <string.h> -#include <gtk/gtkimage.h> -#include <gtk/gtkstock.h> -#include <libgnome/gnome-i18n.h> -#include <gal/util/e-util.h> -#include "e-util/e-dialog-utils.h" -#include "e-calendar-marshal.h" -#include <libecal/e-cal-time-util.h> - -#include "calendar-commands.h" -#include "calendar-component.h" -#include "calendar-config.h" -#include "comp-util.h" -#include "e-cal-model-calendar.h" -#include "e-cal-view.h" -#include "e-comp-editor-registry.h" -#include "itip-utils.h" -#include "dialogs/delete-comp.h" -#include "dialogs/delete-error.h" -#include "dialogs/event-editor.h" -#include "dialogs/send-comp.h" -#include "dialogs/cancel-comp.h" -#include "dialogs/recur-comp.h" -#include "print.h" -#include "goto.h" -#include "ea-calendar.h" - -/* Used for the status bar messages */ -#define EVOLUTION_CALENDAR_PROGRESS_IMAGE "evolution-calendar-mini.png" -static GdkPixbuf *progress_icon = NULL; - -struct _ECalendarViewPrivate { - /* The GnomeCalendar we are associated to */ - GnomeCalendar *calendar; - - /* The calendar model we are monitoring */ - ECalModel *model; - - /* Current activity (for the EActivityHandler, i.e. the status bar). */ - guint activity_id; - - /* clipboard selections */ - gchar *clipboard_selection; - - /* The popup menu */ - EPopupMenu *view_menu; - - /* The default category */ - char *default_category; -}; - -static void e_calendar_view_class_init (ECalendarViewClass *klass); -static void e_calendar_view_init (ECalendarView *cal_view, ECalendarViewClass *klass); -static void e_calendar_view_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); -static void e_calendar_view_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); -static void e_calendar_view_destroy (GtkObject *object); - -static GObjectClass *parent_class = NULL; -static GdkAtom clipboard_atom = GDK_NONE; -extern ECompEditorRegistry *comp_editor_registry; - -/* Property IDs */ -enum props { - PROP_0, - PROP_MODEL, -}; - -/* FIXME Why are we emitting these event signals here? Can't the model just be listened to? */ -/* Signal IDs */ -enum { - SELECTION_CHANGED, - SELECTED_TIME_CHANGED, - TIMEZONE_CHANGED, - EVENT_CHANGED, - EVENT_ADDED, - LAST_SIGNAL -}; - -static guint e_calendar_view_signals[LAST_SIGNAL] = { 0 }; - -static void -e_calendar_view_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) -{ - ECalendarView *cal_view; - ECalendarViewPrivate *priv; - - cal_view = E_CALENDAR_VIEW (object); - priv = cal_view->priv; - - switch (property_id) { - case PROP_MODEL: - e_calendar_view_set_model (cal_view, E_CAL_MODEL (g_value_get_object (value))); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -e_calendar_view_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) -{ - ECalendarView *cal_view; - ECalendarViewPrivate *priv; - - cal_view = E_CALENDAR_VIEW (object); - priv = cal_view->priv; - - switch (property_id) { - case PROP_MODEL: - g_value_set_object (value, e_calendar_view_get_model (cal_view)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -e_calendar_view_class_init (ECalendarViewClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - /* Method override */ - gobject_class->set_property = e_calendar_view_set_property; - gobject_class->get_property = e_calendar_view_get_property; - object_class->destroy = e_calendar_view_destroy; - - klass->selection_changed = NULL; - klass->selected_time_changed = NULL; - klass->event_changed = NULL; - klass->event_added = NULL; - - klass->get_selected_events = NULL; - klass->get_selected_time_range = NULL; - klass->set_selected_time_range = NULL; - klass->get_visible_time_range = NULL; - klass->update_query = NULL; - - g_object_class_install_property (gobject_class, PROP_MODEL, - g_param_spec_object ("model", NULL, NULL, E_TYPE_CAL_MODEL, - G_PARAM_READABLE | G_PARAM_WRITABLE - | G_PARAM_CONSTRUCT)); - - /* Create class' signals */ - e_calendar_view_signals[SELECTION_CHANGED] = - g_signal_new ("selection_changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ECalendarViewClass, selection_changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - e_calendar_view_signals[SELECTED_TIME_CHANGED] = - g_signal_new ("selected_time_changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ECalendarViewClass, selected_time_changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - e_calendar_view_signals[TIMEZONE_CHANGED] = - g_signal_new ("timezone_changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ECalendarViewClass, timezone_changed), - NULL, NULL, - e_calendar_marshal_VOID__POINTER_POINTER, - G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER); - - e_calendar_view_signals[EVENT_CHANGED] = - g_signal_new ("event_changed", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (ECalendarViewClass, event_changed), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - - e_calendar_view_signals[EVENT_ADDED] = - g_signal_new ("event_added", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (ECalendarViewClass, event_added), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - - /* clipboard atom */ - if (!clipboard_atom) - clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE); - - /* init the accessibility support for e_day_view */ - e_cal_view_a11y_init (); -} - -static void -model_changed_cb (ETableModel *etm, gpointer user_data) -{ - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - e_calendar_view_update_query (cal_view); -} - -static void -model_row_changed_cb (ETableModel *etm, int row, gpointer user_data) -{ - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - e_calendar_view_update_query (cal_view); -} - -static void -model_cell_changed_cb (ETableModel *etm, int col, int row, gpointer user_data) -{ - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - e_calendar_view_update_query (cal_view); -} - -static void -model_rows_changed_cb (ETableModel *etm, int row, int count, gpointer user_data) -{ - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - e_calendar_view_update_query (cal_view); -} - -void -e_calendar_view_add_event (ECalendarView *cal_view, ECal *client, time_t dtstart, - icaltimezone *default_zone, icalcomponent *icalcomp, gboolean in_top_canvas) -{ - ECalComponent *comp; - struct icaltimetype itime, old_dtstart, old_dtend; - time_t tt_start, tt_end, new_dtstart; - struct icaldurationtype ic_dur; - char *uid; - gint start_offset, end_offset; - gboolean all_day_event; - - start_offset = 0; - end_offset = 0; - - old_dtstart = icalcomponent_get_dtstart (icalcomp); - tt_start = icaltime_as_timet (old_dtstart); - old_dtend = icalcomponent_get_dtend (icalcomp); - tt_end = icaltime_as_timet (old_dtend); - ic_dur = icaldurationtype_from_int (tt_end - tt_start); - - if (icaldurationtype_as_int (ic_dur) > 60*60*24) { - /* This is a long event */ - start_offset = old_dtstart.hour * 60 + old_dtstart.minute; - end_offset = old_dtstart.hour * 60 + old_dtend.minute; - } - - if (start_offset == 0 && end_offset == 0 && in_top_canvas) - all_day_event = TRUE; - else - all_day_event = FALSE; - - if (in_top_canvas) - new_dtstart = dtstart + start_offset * 60; - else - new_dtstart = dtstart; - - itime = icaltime_from_timet_with_zone (new_dtstart, FALSE, default_zone); - if (all_day_event) - itime.is_date = TRUE; - icalcomponent_set_dtstart (icalcomp, itime); - - itime = icaltime_add (itime, ic_dur); - if (all_day_event) - itime.is_date = TRUE; - icalcomponent_set_dtend (icalcomp, itime); - - /* FIXME The new uid stuff can go away once we actually set it in the backend */ - uid = e_cal_component_gen_uid (); - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent ( - comp, icalcomponent_new_clone (icalcomp)); - e_cal_component_set_uid (comp, uid); - - /* FIXME Error handling */ - if (e_cal_create_object (client, e_cal_component_get_icalcomponent (comp), NULL, NULL)) { - if (itip_organizer_is_user (comp, client) && - send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)), - client, comp, TRUE)) { - itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, - client, NULL); - } - } else { - g_message (G_STRLOC ": Could not create the object!"); - } - - free (uid); - g_object_unref (comp); -} - -static void -e_calendar_view_init (ECalendarView *cal_view, ECalendarViewClass *klass) -{ - cal_view->priv = g_new0 (ECalendarViewPrivate, 1); - - cal_view->priv->model = (ECalModel *) e_cal_model_calendar_new (); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_changed", - G_CALLBACK (model_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_row_changed", - G_CALLBACK (model_row_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_cell_changed", - G_CALLBACK (model_cell_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_rows_inserted", - G_CALLBACK (model_rows_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_rows_deleted", - G_CALLBACK (model_rows_changed_cb), cal_view); - - cal_view->priv->clipboard_selection = NULL; -} - -static void -e_calendar_view_destroy (GtkObject *object) -{ - ECalendarView *cal_view = (ECalendarView *) object; - - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - if (cal_view->priv) { - if (cal_view->priv->model) { - g_signal_handlers_disconnect_matched (cal_view->priv->model, - G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, cal_view); - g_object_unref (cal_view->priv->model); - cal_view->priv->model = NULL; - } - - if (cal_view->priv->clipboard_selection) { - g_free (cal_view->priv->clipboard_selection); - cal_view->priv->clipboard_selection = NULL; - } - - if (cal_view->priv->default_category) { - g_free (cal_view->priv->default_category); - cal_view->priv->default_category = NULL; - } - - g_free (cal_view->priv); - cal_view->priv = NULL; - } - - if (GTK_OBJECT_CLASS (parent_class)->destroy) - GTK_OBJECT_CLASS (parent_class)->destroy (object); -} - -E_MAKE_TYPE (e_calendar_view, "ECalendarView", ECalendarView, e_calendar_view_class_init, - e_calendar_view_init, GTK_TYPE_TABLE); - -GnomeCalendar * -e_calendar_view_get_calendar (ECalendarView *cal_view) -{ - g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), NULL); - - return cal_view->priv->calendar; -} - -void -e_calendar_view_set_calendar (ECalendarView *cal_view, GnomeCalendar *calendar) -{ - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - cal_view->priv->calendar = calendar; -} - -ECalModel * -e_calendar_view_get_model (ECalendarView *cal_view) -{ - g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), NULL); - - return cal_view->priv->model; -} - -void -e_calendar_view_set_model (ECalendarView *cal_view, ECalModel *model) -{ - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - g_return_if_fail (E_IS_CAL_MODEL (model)); - - if (cal_view->priv->model) { - g_signal_handlers_disconnect_matched (cal_view->priv->model, G_SIGNAL_MATCH_DATA, - 0, 0, 0, NULL, cal_view); - g_object_unref (cal_view->priv->model); - } - - cal_view->priv->model = model; - g_object_ref (cal_view->priv->model); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_changed", G_CALLBACK (model_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_row_changed", G_CALLBACK (model_row_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_cell_changed", G_CALLBACK (model_cell_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_rows_inserted", G_CALLBACK (model_rows_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_rows_deleted", G_CALLBACK (model_rows_changed_cb), cal_view); - - e_calendar_view_update_query (cal_view); -} - -icaltimezone * -e_calendar_view_get_timezone (ECalendarView *cal_view) -{ - g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), NULL); - return e_cal_model_get_timezone (cal_view->priv->model); -} - -void -e_calendar_view_set_timezone (ECalendarView *cal_view, icaltimezone *zone) -{ - icaltimezone *old_zone; - - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - old_zone = e_cal_model_get_timezone (cal_view->priv->model); - if (old_zone == zone) - return; - - e_cal_model_set_timezone (cal_view->priv->model, zone); - g_signal_emit (G_OBJECT (cal_view), e_calendar_view_signals[TIMEZONE_CHANGED], 0, - old_zone, zone); -} - -const char * -e_calendar_view_get_default_category (ECalendarView *cal_view) -{ - g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), NULL); - return (const char *) cal_view->priv->default_category; -} - -/** - * e_calendar_view_set_default_category - * @cal_view: A calendar view. - * @category: Default category name or NULL for no category. - * - * Sets the default category that will be used when creating new calendar - * components from the given calendar view. - */ -void -e_calendar_view_set_default_category (ECalendarView *cal_view, const char *category) -{ - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - if (cal_view->priv->default_category) - g_free (cal_view->priv->default_category); - - cal_view->priv->default_category = g_strdup (category); -} - -/** - * e_calendar_view_get_use_24_hour_format: - * @cal_view: A calendar view. - * - * Gets whether the view is using 24 hour times or not. - * - * Returns: the 24 hour setting. - */ -gboolean -e_calendar_view_get_use_24_hour_format (ECalendarView *cal_view) -{ - g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), FALSE); - - return e_cal_model_get_use_24_hour_format (cal_view->priv->model); -} - -/** - * e_calendar_view_set_use_24_hour_format - * @cal_view: A calendar view. - * @use_24_hour: Whether to use 24 hour times or not. - * - * Sets the 12/24 hour times setting for the given view. - */ -void -e_calendar_view_set_use_24_hour_format (ECalendarView *cal_view, gboolean use_24_hour) -{ - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - e_cal_model_set_use_24_hour_format (cal_view->priv->model, use_24_hour); -} - -void -e_calendar_view_set_status_message (ECalendarView *cal_view, const gchar *message) -{ - EActivityHandler *activity_handler = calendar_component_peek_activity_handler (calendar_component_peek ()); - - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - if (!message || !*message) { - if (cal_view->priv->activity_id != 0) { - e_activity_handler_operation_finished (activity_handler, cal_view->priv->activity_id); - cal_view->priv->activity_id = 0; - } - } else if (cal_view->priv->activity_id == 0) { - char *client_id = g_strdup_printf ("%p", cal_view); - - if (progress_icon == NULL) - progress_icon = gdk_pixbuf_new_from_file (EVOLUTION_IMAGESDIR "/" EVOLUTION_CALENDAR_PROGRESS_IMAGE, NULL); - - cal_view->priv->activity_id = e_activity_handler_operation_started (activity_handler, client_id, progress_icon, message, TRUE); - - g_free (client_id); - } else { - e_activity_handler_operation_progressing (activity_handler, cal_view->priv->activity_id, message, -1.0); - } -} - -GList * -e_calendar_view_get_selected_events (ECalendarView *cal_view) -{ - g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), NULL); - - if (E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->get_selected_events) - return E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->get_selected_events (cal_view); - - return NULL; -} - -void -e_calendar_view_get_selected_time_range (ECalendarView *cal_view, time_t *start_time, time_t *end_time) -{ - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - if (E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->get_selected_time_range) { - E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->get_selected_time_range ( - cal_view, start_time, end_time); - } -} - -void -e_calendar_view_set_selected_time_range (ECalendarView *cal_view, time_t start_time, time_t end_time) -{ - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - if (E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->set_selected_time_range) { - E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->set_selected_time_range ( - cal_view, start_time, end_time); - } -} - -gboolean -e_calendar_view_get_visible_time_range (ECalendarView *cal_view, time_t *start_time, time_t *end_time) -{ - g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), FALSE); - - if (E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->get_visible_time_range) { - return E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->get_visible_time_range ( - cal_view, start_time, end_time); - } - - return FALSE; -} - -void -e_calendar_view_update_query (ECalendarView *cal_view) -{ - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - e_calendar_view_set_status_message (cal_view, _("Searching")); - - if (E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->update_query) { - E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (cal_view))->update_query (cal_view); - } - - e_calendar_view_set_status_message (cal_view, NULL); -} - -void -e_calendar_view_cut_clipboard (ECalendarView *cal_view) -{ - GList *selected, *l; - const char *uid; - - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - selected = e_calendar_view_get_selected_events (cal_view); - if (!selected) - return; - - e_calendar_view_set_status_message (cal_view, _("Deleting selected objects")); - - e_calendar_view_copy_clipboard (cal_view); - for (l = selected; l != NULL; l = l->next) { - ECalComponent *comp; - ECalendarViewEvent *event = (ECalendarViewEvent *) l->data; - GError *error = NULL; - - if (!event) - continue; - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); - - if (itip_organizer_is_user (comp, event->comp_data->client) - && cancel_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)), - event->comp_data->client, comp, TRUE)) - itip_send_comp (E_CAL_COMPONENT_METHOD_CANCEL, comp, - event->comp_data->client, NULL); - - e_cal_component_get_uid (comp, &uid); - e_cal_remove_object (event->comp_data->client, uid, &error); - delete_error_dialog (error, E_CAL_COMPONENT_EVENT); - - g_clear_error (&error); - - g_object_unref (comp); - } - - e_calendar_view_set_status_message (cal_view, NULL); - - g_list_free (selected); -} - -void -e_calendar_view_copy_clipboard (ECalendarView *cal_view) -{ - GList *selected, *l; - gchar *comp_str; - icalcomponent *vcal_comp; - icalcomponent *new_icalcomp; - ECalendarViewEvent *event; - - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - selected = e_calendar_view_get_selected_events (cal_view); - if (!selected) - return; - - /* create top-level VCALENDAR component and add VTIMEZONE's */ - vcal_comp = e_cal_util_new_top_level (); - for (l = selected; l != NULL; l = l->next) { - event = (ECalendarViewEvent *) l->data; - - if (event) - e_cal_util_add_timezones_from_component (vcal_comp, event->comp_data->icalcomp); - } - - for (l = selected; l != NULL; l = l->next) { - event = (ECalendarViewEvent *) l->data; - - new_icalcomp = icalcomponent_new_clone (event->comp_data->icalcomp); - icalcomponent_add_component (vcal_comp, new_icalcomp); - } - - /* copy the VCALENDAR to the clipboard */ - comp_str = icalcomponent_as_ical_string (vcal_comp); - if (cal_view->priv->clipboard_selection != NULL) - g_free (cal_view->priv->clipboard_selection); - cal_view->priv->clipboard_selection = g_strdup (comp_str); - gtk_clipboard_set_text (gtk_widget_get_clipboard (GTK_WIDGET (cal_view), clipboard_atom), - (const gchar *) comp_str, - g_utf8_strlen (comp_str, -1)); - - /* free memory */ - icalcomponent_free (vcal_comp); - g_list_free (selected); -} - -static void -clipboard_get_text_cb (GtkClipboard *clipboard, const gchar *text, ECalendarView *cal_view) -{ - char *default_tzid; - icalcomponent *icalcomp; - icalcomponent_kind kind; - time_t selected_time_start, selected_time_end; - icaltimezone *default_zone; - ECal *client; - - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - icalcomp = icalparser_parse_string ((const char *) text); - if (!icalcomp) - return; - - default_tzid = calendar_config_get_timezone (); - - client = e_cal_model_get_default_client (cal_view->priv->model); - /* FIXME Error checking */ - e_cal_get_timezone (client, default_tzid, &default_zone, NULL); - - /* check the type of the component */ - /* FIXME An error dialog if we return? */ - kind = icalcomponent_isa (icalcomp); - if (kind != ICAL_VCALENDAR_COMPONENT && kind != ICAL_VEVENT_COMPONENT) - return; - - e_calendar_view_set_status_message (cal_view, _("Updating objects")); - e_calendar_view_get_selected_time_range (cal_view, &selected_time_start, &selected_time_end); - - /* FIXME Timezone handling */ - if (kind == ICAL_VCALENDAR_COMPONENT) { - icalcomponent_kind child_kind; - icalcomponent *subcomp; - - subcomp = icalcomponent_get_first_component (icalcomp, ICAL_ANY_COMPONENT); - while (subcomp) { - child_kind = icalcomponent_isa (subcomp); - if (child_kind == ICAL_VEVENT_COMPONENT) - e_calendar_view_add_event (cal_view, client, selected_time_start, - default_zone, subcomp, FALSE); - else if (child_kind == ICAL_VTIMEZONE_COMPONENT) { - icaltimezone *zone; - - zone = icaltimezone_new (); - icaltimezone_set_component (zone, subcomp); - e_cal_add_timezone (client, zone, NULL); - - icaltimezone_free (zone, 1); - } - - subcomp = icalcomponent_get_next_component ( - icalcomp, ICAL_ANY_COMPONENT); - } - - icalcomponent_free (icalcomp); - - } else { - e_calendar_view_add_event (cal_view, client, selected_time_start, default_zone, icalcomp, FALSE); - } - - e_calendar_view_set_status_message (cal_view, NULL); -} - -void -e_calendar_view_paste_clipboard (ECalendarView *cal_view) -{ - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - gtk_clipboard_request_text (gtk_widget_get_clipboard (GTK_WIDGET (cal_view), clipboard_atom), - (GtkClipboardTextReceivedFunc) clipboard_get_text_cb, cal_view); -} - -static void -delete_event (ECalendarView *cal_view, ECalendarViewEvent *event) -{ - ECalComponent *comp; - ECalComponentVType vtype; - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); - vtype = e_cal_component_get_vtype (comp); - - if (delete_component_dialog (comp, FALSE, 1, vtype, GTK_WIDGET (cal_view))) { - const char *uid; - GError *error = NULL; - - if (itip_organizer_is_user (comp, event->comp_data->client) - && cancel_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)), - event->comp_data->client, - comp, TRUE)) - itip_send_comp (E_CAL_COMPONENT_METHOD_CANCEL, comp, - event->comp_data->client, NULL); - - e_cal_component_get_uid (comp, &uid); - if (!uid || !*uid) { - g_object_unref (comp); - return; - } - - e_cal_remove_object (event->comp_data->client, uid, &error); - delete_error_dialog (error, E_CAL_COMPONENT_EVENT); - g_clear_error (&error); - } - - g_object_unref (comp); -} - -void -e_calendar_view_delete_selected_event (ECalendarView *cal_view) -{ - GList *selected; - ECalendarViewEvent *event; - - selected = e_calendar_view_get_selected_events (cal_view); - if (!selected) - return; - - event = (ECalendarViewEvent *) selected->data; - if (event) - delete_event (cal_view, event); - - g_list_free (selected); -} - -void -e_calendar_view_delete_selected_events (ECalendarView *cal_view) -{ - GList *selected, *l; - ECalendarViewEvent *event; - - selected = e_calendar_view_get_selected_events (cal_view); - if (!selected) - return; - - for (l = selected; l != NULL; l = l->next) { - event = (ECalendarViewEvent *) l->data; - if (event) - delete_event (cal_view, event); - } - - g_list_free (selected); -} - -void -e_calendar_view_delete_selected_occurrence (ECalendarView *cal_view) -{ - ECalendarViewEvent *event; - GList *selected; - const char *uid; - GError *error = NULL; - - selected = e_calendar_view_get_selected_events (cal_view); - if (!selected) - return; - - event = (ECalendarViewEvent *) selected->data; - - uid = icalcomponent_get_uid (event->comp_data->icalcomp); - /* FIXME: use 'rid' argument */ - e_cal_remove_object_with_mod (event->comp_data->client, uid, NULL, CALOBJ_MOD_THIS, &error); - - delete_error_dialog (error, E_CAL_COMPONENT_EVENT); - g_clear_error (&error); - - /* free memory */ - g_list_free (selected); -} - -static void -on_new_appointment (GtkWidget *widget, gpointer user_data) -{ - ECalendarView *cal_view = (ECalendarView *) user_data; - - e_calendar_view_new_appointment (cal_view); -} - -static void -on_new_event (GtkWidget *widget, gpointer user_data) -{ - time_t dtstart, dtend; - ECalendarView *cal_view = (ECalendarView *) user_data; - - e_calendar_view_get_selected_time_range (cal_view, &dtstart, &dtend); - e_calendar_view_new_appointment_for (cal_view, dtstart, dtend, TRUE, FALSE); -} - -static void -on_new_meeting (GtkWidget *widget, gpointer user_data) -{ - time_t dtstart, dtend; - ECalendarView *cal_view = (ECalendarView *) user_data; - - e_calendar_view_get_selected_time_range (cal_view, &dtstart, &dtend); - e_calendar_view_new_appointment_for (cal_view, dtstart, dtend, FALSE, TRUE); -} - -static void -on_new_task (GtkWidget *widget, gpointer user_data) -{ - ECalendarView *cal_view = (ECalendarView *) user_data; - gnome_calendar_new_task (cal_view->priv->calendar); -} - -static void -on_goto_date (GtkWidget *widget, gpointer user_data) -{ - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - goto_dialog (cal_view->priv->calendar); -} - -static void -on_goto_today (GtkWidget *widget, gpointer user_data) -{ - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - calendar_goto_today (cal_view->priv->calendar); -} - -static void -on_edit_appointment (GtkWidget *widget, gpointer user_data) -{ - GList *selected; - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - selected = e_calendar_view_get_selected_events (cal_view); - if (selected) { - ECalendarViewEvent *event = (ECalendarViewEvent *) selected->data; - - if (event) - e_calendar_view_edit_appointment (cal_view, event->comp_data->client, - event->comp_data->icalcomp, FALSE); - - g_list_free (selected); - } -} - -static void -on_print (GtkWidget *widget, gpointer user_data) -{ - ECalendarView *cal_view; - time_t start; - GnomeCalendarViewType view_type; - PrintView print_view; - - cal_view = E_CALENDAR_VIEW (user_data); - - e_calendar_view_get_visible_time_range (cal_view, &start, NULL); - view_type = gnome_calendar_get_view (cal_view->priv->calendar); - - 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 (cal_view->priv->calendar, FALSE, start, print_view); -} - -static void -on_save_as (GtkWidget *widget, gpointer user_data) -{ - ECalendarView *cal_view; - GList *selected; - char *filename; - char *ical_string; - FILE *file; - ECalendarViewEvent *event; - - cal_view = E_CALENDAR_VIEW (user_data); - - selected = e_calendar_view_get_selected_events (cal_view); - if (!selected) - return; - - filename = e_file_dialog_save (_("Save as...")); - if (filename == NULL) - return; - - event = (ECalendarViewEvent *) selected->data; - ical_string = e_cal_get_component_as_string (event->comp_data->client, event->comp_data->icalcomp); - 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); - - g_list_free (selected); -} - -static void -on_print_event (GtkWidget *widget, gpointer user_data) -{ - ECalendarView *cal_view; - GList *selected; - ECalendarViewEvent *event; - ECalComponent *comp; - - cal_view = E_CALENDAR_VIEW (user_data); - selected = e_calendar_view_get_selected_events (cal_view); - if (!selected) - return; - - event = (ECalendarViewEvent *) selected->data; - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); - print_comp (comp, event->comp_data->client, FALSE); - - g_object_unref (comp); -} - -static void -on_meeting (GtkWidget *widget, gpointer user_data) -{ - GList *selected; - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - selected = e_calendar_view_get_selected_events (cal_view); - if (selected) { - ECalendarViewEvent *event = (ECalendarViewEvent *) selected->data; - e_calendar_view_edit_appointment (cal_view, event->comp_data->client, event->comp_data->icalcomp, TRUE); - - g_list_free (selected); - } -} - -static void -on_forward (GtkWidget *widget, gpointer user_data) -{ - GList *selected; - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - selected = e_calendar_view_get_selected_events (cal_view); - if (selected) { - ECalComponent *comp; - ECalendarViewEvent *event = (ECalendarViewEvent *) selected->data; - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); - itip_send_comp (E_CAL_COMPONENT_METHOD_PUBLISH, comp, event->comp_data->client, NULL); - - g_list_free (selected); - g_object_unref (comp); - } -} - -static void -on_publish (GtkWidget *widget, gpointer user_data) -{ - ECalendarView *cal_view; - icaltimezone *utc; - time_t start = time (NULL), end; - GList *comp_list = NULL, *client_list, *cl; - - cal_view = E_CALENDAR_VIEW (user_data); - - utc = icaltimezone_get_utc_timezone (); - start = time_day_begin_with_zone (start, utc); - end = time_add_week_with_zone (start, 6, utc); - - client_list = e_cal_model_get_client_list (cal_view->priv->model); - for (cl = client_list; cl != NULL; cl = cl->next) { - if (e_cal_get_free_busy ((ECal *) cl->data, NULL, start, end, &comp_list, NULL)) { - GList *l; - - for (l = comp_list; l; l = l->next) { - ECalComponent *comp = E_CAL_COMPONENT (l->data); - itip_send_comp (E_CAL_COMPONENT_METHOD_PUBLISH, comp, (ECal *) cl->data, NULL); - - g_object_unref (comp); - } - - g_list_free (comp_list); - } - } - - g_list_free (client_list); -} - -static void -on_delete_appointment (GtkWidget *widget, gpointer user_data) -{ - ECalendarView *cal_view; - - cal_view = E_CALENDAR_VIEW (user_data); - e_calendar_view_delete_selected_event (cal_view); -} - -static void -on_delete_occurrence (GtkWidget *widget, gpointer user_data) -{ - ECalendarView *cal_view; - - cal_view = E_CALENDAR_VIEW (user_data); - e_calendar_view_delete_selected_occurrence (cal_view); -} - -static void -on_cut (GtkWidget *widget, gpointer user_data) -{ - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - e_calendar_view_cut_clipboard (cal_view); -} - -static void -on_copy (GtkWidget *widget, gpointer user_data) -{ - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - e_calendar_view_copy_clipboard (cal_view); -} - -static void -on_paste (GtkWidget *widget, gpointer user_data) -{ - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - e_calendar_view_paste_clipboard (cal_view); -} - -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, - - /* - * This is used to when an event is already a meeting and - * we want to disable the schedule meeting command - */ - MASK_MEETING = 16, - - /* - * To disable cut and copy for meetings the user is not the - * organizer of - */ - MASK_MEETING_ORGANIZER = 32, - - /* - * To disable things not valid for instances - */ - MASK_INSTANCE = 64 -}; - -static EPopupMenu main_items [] = { - E_POPUP_ITEM (N_("New _Appointment..."), GTK_SIGNAL_FUNC (on_new_appointment), MASK_EDITABLE), - E_POPUP_ITEM (N_("New All Day _Event"), GTK_SIGNAL_FUNC (on_new_event), MASK_EDITABLE), - E_POPUP_ITEM (N_("New Meeting"), GTK_SIGNAL_FUNC (on_new_meeting), MASK_EDITABLE), - E_POPUP_ITEM (N_("New Task"), GTK_SIGNAL_FUNC (on_new_task), MASK_EDITABLE), - - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("_Print..."), GTK_SIGNAL_FUNC (on_print), 0), - - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("_Paste"), GTK_SIGNAL_FUNC (on_paste), MASK_EDITABLE), - - E_POPUP_SEPARATOR, - - E_POPUP_SUBMENU (N_("Current View"), NULL, 0), - - E_POPUP_ITEM (N_("Go to _Today"), GTK_SIGNAL_FUNC (on_goto_today), 0), - E_POPUP_ITEM (N_("_Go to Date..."), GTK_SIGNAL_FUNC (on_goto_date), 0), - - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("_Publish Free/Busy Information"), GTK_SIGNAL_FUNC (on_publish), 0), - - E_POPUP_TERMINATOR -}; - -static EPopupMenu child_items [] = { - E_POPUP_ITEM (N_("_Open"), GTK_SIGNAL_FUNC (on_edit_appointment), MASK_EDITING), - E_POPUP_ITEM (N_("_Save As..."), GTK_SIGNAL_FUNC (on_save_as), MASK_EDITING), - E_POPUP_ITEM (N_("_Print..."), GTK_SIGNAL_FUNC (on_print_event), MASK_EDITING), - - /* Only show this separator if one of the above is shown. */ - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("C_ut"), GTK_SIGNAL_FUNC (on_cut), MASK_EDITING | MASK_EDITABLE | MASK_MEETING_ORGANIZER), - E_POPUP_ITEM (N_("_Copy"), GTK_SIGNAL_FUNC (on_copy), MASK_EDITING | MASK_MEETING_ORGANIZER), - E_POPUP_ITEM (N_("_Paste"), GTK_SIGNAL_FUNC (on_paste), MASK_EDITABLE), - - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("_Schedule Meeting..."), GTK_SIGNAL_FUNC (on_meeting), MASK_EDITABLE | MASK_EDITING | MASK_MEETING), - E_POPUP_ITEM (N_("_Forward as iCalendar..."), GTK_SIGNAL_FUNC (on_forward), MASK_EDITING), - - E_POPUP_SEPARATOR, - - E_POPUP_ITEM (N_("_Delete"), GTK_SIGNAL_FUNC (on_delete_appointment), MASK_EDITABLE | MASK_SINGLE | MASK_EDITING), - E_POPUP_ITEM (N_("Delete this _Occurrence"), GTK_SIGNAL_FUNC (on_delete_occurrence), MASK_RECURRING | MASK_EDITING | MASK_EDITABLE), - E_POPUP_ITEM (N_("Delete _All Occurrences"), GTK_SIGNAL_FUNC (on_delete_appointment), MASK_RECURRING | MASK_EDITING | MASK_EDITABLE), - - E_POPUP_TERMINATOR -}; - -static void -free_view_popup (GtkWidget *widget, gpointer data) -{ - ECalendarView *cal_view = E_CALENDAR_VIEW (data); - - if (cal_view->priv->view_menu == NULL) - return; - - gnome_calendar_discard_view_popup (cal_view->priv->calendar, cal_view->priv->view_menu); - cal_view->priv->view_menu = NULL; -} - -static void -setup_popup_icons (EPopupMenu *context_menu) -{ - gint i; - - for (i = 0; context_menu[i].name; i++) { - GtkWidget *pixmap_widget = NULL; - - if (!strcmp (context_menu[i].name, _("_Copy"))) - pixmap_widget = gtk_image_new_from_stock (GTK_STOCK_COPY, GTK_ICON_SIZE_MENU); - else if (!strcmp (context_menu[i].name, _("C_ut"))) - pixmap_widget = gtk_image_new_from_stock (GTK_STOCK_CUT, GTK_ICON_SIZE_MENU); - else if (!strcmp (context_menu[i].name, _("_Delete")) || - !strcmp (context_menu[i].name, _("Delete this _Occurrence")) || - !strcmp (context_menu[i].name, _("Delete _All Occurrences"))) - pixmap_widget = gtk_image_new_from_stock (GTK_STOCK_DELETE, GTK_ICON_SIZE_MENU); - else if (!strcmp (context_menu[i].name, _("Go to _Today"))) - pixmap_widget = gtk_image_new_from_stock (GTK_STOCK_HOME, GTK_ICON_SIZE_MENU); - else if (!strcmp (context_menu[i].name, _("_Go to Date..."))) - pixmap_widget = gtk_image_new_from_stock (GTK_STOCK_JUMP_TO, GTK_ICON_SIZE_MENU); - else if (!strcmp (context_menu[i].name, _("New _Appointment..."))) - pixmap_widget = gtk_image_new_from_file (EVOLUTION_IMAGESDIR "/new_appointment.xpm"); - else if (!strcmp (context_menu[i].name, _("New All Day _Event"))) - pixmap_widget = gtk_image_new_from_file (EVOLUTION_IMAGESDIR "/new_all_day_event.png"); - else if (!strcmp (context_menu[i].name, _("New Meeting"))) - pixmap_widget = gtk_image_new_from_file (EVOLUTION_IMAGESDIR "/meeting-request-16.png"); - else if (!strcmp (context_menu[i].name, _("New Task"))) - pixmap_widget = gtk_image_new_from_file (EVOLUTION_IMAGESDIR "/new_task-16.png"); - else if (!strcmp (context_menu[i].name, _("_Open"))) - pixmap_widget = gtk_image_new_from_stock (GTK_STOCK_OPEN, GTK_ICON_SIZE_MENU); - else if (!strcmp (context_menu[i].name, _("_Paste"))) - pixmap_widget = gtk_image_new_from_stock (GTK_STOCK_PASTE, GTK_ICON_SIZE_MENU); - else if (!strcmp (context_menu[i].name, _("_Print..."))) - pixmap_widget = gtk_image_new_from_stock (GTK_STOCK_PRINT, GTK_ICON_SIZE_MENU); - else if (!strcmp (context_menu[i].name, _("_Save As..."))) - pixmap_widget = gtk_image_new_from_stock (GTK_STOCK_SAVE_AS, GTK_ICON_SIZE_MENU); - else if (!strcmp (context_menu[i].name, _("_Settings..."))) - pixmap_widget = gtk_image_new_from_stock (GTK_STOCK_PREFERENCES, GTK_ICON_SIZE_MENU); - - if (pixmap_widget) - gtk_widget_show (pixmap_widget); - context_menu[i].pixmap_widget = pixmap_widget; - } -} - -GtkMenu * -e_calendar_view_create_popup_menu (ECalendarView *cal_view) -{ - GList *selected; - EPopupMenu *context_menu; - guint32 disable_mask = 0, hide_mask = 0; - GtkMenu *popup; - ECal *client = NULL; - gboolean read_only = TRUE; - - g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), NULL); - - /* get the selection */ - selected = e_calendar_view_get_selected_events (cal_view); - - if (selected == NULL) { - cal_view->priv->view_menu = gnome_calendar_setup_view_popup (cal_view->priv->calendar); - main_items[9].submenu = cal_view->priv->view_menu; - context_menu = main_items; - - client = e_cal_model_get_default_client (cal_view->priv->model); - } else { - ECalendarViewEvent *event; - - context_menu = child_items; - - event = (ECalendarViewEvent *) selected->data; - if (e_cal_util_component_has_recurrences (event->comp_data->icalcomp)) - hide_mask |= MASK_SINGLE; - else - hide_mask |= MASK_RECURRING; - - if (e_cal_util_component_is_instance (event->comp_data->icalcomp)) - hide_mask |= MASK_INSTANCE; - - if (e_cal_util_component_has_organizer (event->comp_data->icalcomp)) { - ECalComponent *comp; - - disable_mask |= MASK_MEETING; - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); - if (!itip_organizer_is_user (comp, event->comp_data->client)) - disable_mask |= MASK_MEETING_ORGANIZER; - - g_object_unref (comp); - } - - client = event->comp_data->client; - } - - e_cal_is_read_only (client, &read_only, NULL); - if (read_only) - disable_mask |= MASK_EDITABLE; - - setup_popup_icons (context_menu); - popup = e_popup_menu_create (context_menu, disable_mask, hide_mask, cal_view); - g_signal_connect (popup, "selection-done", G_CALLBACK (free_view_popup), cal_view); - - return popup; -} - -/** - * e_calendar_view_new_appointment_for - * @cal_view: A calendar view. - * @dtstart: A Unix time_t that marks the beginning of the appointment. - * @dtend: A Unix time_t that marks the end of the appointment. - * @all_day: If TRUE, the dtstart and dtend are expanded to cover - * the entire day, and the event is set to TRANSPARENT. - * @meeting: Whether the appointment is a meeting or not. - * - * Opens an event editor dialog for a new appointment. - */ -void -e_calendar_view_new_appointment_for (ECalendarView *cal_view, - time_t dtstart, time_t dtend, - gboolean all_day, - gboolean meeting) -{ - ECalendarViewPrivate *priv; - struct icaltimetype itt; - ECalComponentDateTime dt; - ECalComponent *comp; - icalcomponent *icalcomp; - ECalComponentTransparency transparency; - - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - priv = cal_view->priv; - - dt.value = &itt; - if (all_day) - dt.tzid = NULL; - else - dt.tzid = icaltimezone_get_tzid (e_cal_model_get_timezone (cal_view->priv->model)); - - icalcomp = e_cal_model_create_component_with_defaults (priv->model); - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomp); - - /* DTSTART, DTEND */ - itt = icaltime_from_timet_with_zone (dtstart, FALSE, e_cal_model_get_timezone (cal_view->priv->model)); - if (all_day) { - itt.hour = itt.minute = itt.second = 0; - itt.is_date = TRUE; - } - e_cal_component_set_dtstart (comp, &dt); - - itt = icaltime_from_timet_with_zone (dtend, FALSE, e_cal_model_get_timezone (cal_view->priv->model)); - 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; - } - e_cal_component_set_dtend (comp, &dt); - - /* TRANSPARENCY */ - transparency = all_day ? E_CAL_COMPONENT_TRANSP_TRANSPARENT - : E_CAL_COMPONENT_TRANSP_OPAQUE; - e_cal_component_set_transparency (comp, transparency); - - /* CATEGORY */ - e_cal_component_set_categories (comp, priv->default_category); - - /* edit the object */ - e_cal_component_commit_sequence (comp); - - e_calendar_view_edit_appointment (cal_view, - e_cal_model_get_default_client (priv->model), - icalcomp, meeting); - - g_object_unref (comp); -} - -/** - * e_calendar_view_new_appointment - * @cal_view: A calendar view. - * - * Opens an event editor dialog for a new appointment. The appointment's - * start and end times are set to the currently selected time range in - * the calendar view. - */ -void -e_calendar_view_new_appointment (ECalendarView *cal_view) -{ - time_t dtstart, dtend; - - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - e_calendar_view_get_selected_time_range (cal_view, &dtstart, &dtend); - e_calendar_view_new_appointment_for (cal_view, dtstart, dtend, FALSE, FALSE); -} - -/** - * e_calendar_view_edit_appointment - * @cal_view: A calendar view. - * @client: Calendar client. - * @icalcomp: The object to be edited. - * @meeting: Whether the appointment is a meeting or not. - * - * Opens an editor window to allow the user to edit the selected - * object. - */ -void -e_calendar_view_edit_appointment (ECalendarView *cal_view, - ECal *client, - icalcomponent *icalcomp, - gboolean meeting) -{ - ECalendarViewPrivate *priv; - CompEditor *ce; - const char *uid; - ECalComponent *comp; - - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - g_return_if_fail (E_IS_CAL (client)); - g_return_if_fail (icalcomp != NULL); - - priv = cal_view->priv; - - uid = icalcomponent_get_uid (icalcomp); - - ce = e_comp_editor_registry_find (comp_editor_registry, uid); - if (!ce) { - EventEditor *ee; - - ee = event_editor_new (client); - ce = COMP_EDITOR (ee); - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp)); - comp_editor_edit_comp (ce, comp); - if (meeting) - event_editor_show_meeting (ee); - - e_comp_editor_registry_add (comp_editor_registry, ce, FALSE); - - g_object_unref (comp); - } - - comp_editor_focus (ce); -} diff --git a/calendar/gui/e-calendar-view.h b/calendar/gui/e-calendar-view.h deleted file mode 100644 index a1b11023b3..0000000000 --- a/calendar/gui/e-calendar-view.h +++ /dev/null @@ -1,137 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Rodrigo Moya <rodrigo@ximian.com> - * - * Copyright 2003, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ -#ifndef _E_CALENDAR_VIEW_H_ -#define _E_CALENDAR_VIEW_H_ - -#include <libecal/e-cal.h> -#include <gtk/gtktable.h> -#include "e-cal-model.h" -#include "gnome-cal.h" - -G_BEGIN_DECLS - -/* - * EView - base widget class for the calendar views. - */ - -#define E_CALENDAR_VIEW(obj) GTK_CHECK_CAST (obj, e_calendar_view_get_type (), ECalendarView) -#define E_CALENDAR_VIEW_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, e_calendar_view_get_type (), ECalendarViewClass) -#define E_IS_CALENDAR_VIEW(obj) GTK_CHECK_TYPE (obj, e_calendar_view_get_type ()) - -typedef enum { - E_CALENDAR_VIEW_POS_OUTSIDE, - E_CALENDAR_VIEW_POS_NONE, - E_CALENDAR_VIEW_POS_EVENT, - E_CALENDAR_VIEW_POS_LEFT_EDGE, - E_CALENDAR_VIEW_POS_RIGHT_EDGE, - E_CALENDAR_VIEW_POS_TOP_EDGE, - E_CALENDAR_VIEW_POS_BOTTOM_EDGE -} ECalendarViewPosition; - -#define E_CALENDAR_VIEW_EVENT_FIELDS \ - GnomeCanvasItem *canvas_item; \ - ECalModelComponent *comp_data; \ - gboolean allocated_comp_data; \ - time_t start; \ - time_t end; \ - guint16 start_minute; \ - guint16 end_minute; \ - guint different_timezone : 1; - -typedef struct { - E_CALENDAR_VIEW_EVENT_FIELDS -} ECalendarViewEvent; - -typedef struct _ECalendarView ECalendarView; -typedef struct _ECalendarViewClass ECalendarViewClass; -typedef struct _ECalendarViewPrivate ECalendarViewPrivate; - -struct _ECalendarView { - GtkTable table; - ECalendarViewPrivate *priv; -}; - -struct _ECalendarViewClass { - GtkTableClass parent_class; - - /* Notification signals */ - void (* selection_changed) (ECalendarView *cal_view); - void (* selected_time_changed) (ECalendarView *cal_view); - void (* timezone_changed) (ECalendarView *cal_view, icaltimezone *old_zone, icaltimezone *new_zone); - void (* event_changed) (ECalendarView *day_view, ECalendarViewEvent *event); - void (* event_added) (ECalendarView *day_view, ECalendarViewEvent *event); - - /* Virtual methods */ - GList * (* get_selected_events) (ECalendarView *cal_view); /* a GList of ECalendarViewEvent's */ - void (* get_selected_time_range) (ECalendarView *cal_view, time_t *start_time, time_t *end_time); - void (* set_selected_time_range) (ECalendarView *cal_view, time_t start_time, time_t end_time); - gboolean (* get_visible_time_range) (ECalendarView *cal_view, time_t *start_time, time_t *end_time); - void (* update_query) (ECalendarView *cal_view); -}; - -GType e_calendar_view_get_type (void); - -GnomeCalendar *e_calendar_view_get_calendar (ECalendarView *cal_view); -void e_calendar_view_set_calendar (ECalendarView *cal_view, GnomeCalendar *calendar); -ECalModel *e_calendar_view_get_model (ECalendarView *cal_view); -void e_calendar_view_set_model (ECalendarView *cal_view, ECalModel *model); -icaltimezone *e_calendar_view_get_timezone (ECalendarView *cal_view); -void e_calendar_view_set_timezone (ECalendarView *cal_view, icaltimezone *zone); -const char *e_calendar_view_get_default_category (ECalendarView *cal_view); -void e_calendar_view_set_default_category (ECalendarView *cal_view, const char *category); -gboolean e_calendar_view_get_use_24_hour_format (ECalendarView *view); -void e_calendar_view_set_use_24_hour_format (ECalendarView *view, gboolean use_24_hour); - -void e_calendar_view_set_status_message (ECalendarView *cal_view, const gchar *message); - -GList *e_calendar_view_get_selected_events (ECalendarView *cal_view); -void e_calendar_view_get_selected_time_range (ECalendarView *cal_view, time_t *start_time, time_t *end_time); -void e_calendar_view_set_selected_time_range (ECalendarView *cal_view, time_t start_time, time_t end_time); -gboolean e_calendar_view_get_visible_time_range (ECalendarView *cal_view, time_t *start_time, time_t *end_time); -void e_calendar_view_update_query (ECalendarView *cal_view); - -void e_calendar_view_cut_clipboard (ECalendarView *cal_view); -void e_calendar_view_copy_clipboard (ECalendarView *cal_view); -void e_calendar_view_paste_clipboard (ECalendarView *cal_view); -void e_calendar_view_delete_selected_event (ECalendarView *cal_view); -void e_calendar_view_delete_selected_events (ECalendarView *cal_view); -void e_calendar_view_delete_selected_occurrence (ECalendarView *cal_view); - -GtkMenu *e_calendar_view_create_popup_menu (ECalendarView *cal_view); - -void e_calendar_view_add_event (ECalendarView *cal_view, ECal *client, time_t dtstart, - icaltimezone *default_zone, icalcomponent *icalcomp, gboolean in_top_canvas); -void e_calendar_view_new_appointment_for (ECalendarView *cal_view, - time_t dtstart, - time_t dtend, - gboolean all_day, - gboolean meeting); -void e_calendar_view_new_appointment (ECalendarView *cal_view); -void e_calendar_view_edit_appointment (ECalendarView *cal_view, - ECal *client, - icalcomponent *icalcomp, - gboolean meeting); - -G_END_DECLS - -#endif diff --git a/calendar/gui/e-cell-date-edit-config.c b/calendar/gui/e-cell-date-edit-config.c deleted file mode 100644 index 8993e53d68..0000000000 --- a/calendar/gui/e-cell-date-edit-config.c +++ /dev/null @@ -1,339 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Author : - * JP Rosevear <jpr@ximian.com> - * - * Copyright 2003, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include "calendar-config.h" -#include "e-mini-calendar-config.h" -#include "e-cell-date-edit-config.h" - -struct _ECellDateEditConfigPrivate { - ECellDateEdit *cell; - - EMiniCalendarConfig *mini_config; - - GList *notifications; -}; - -static GObjectClass *parent_class = NULL; - -/* Property IDs */ -enum props { - PROP_0, - PROP_CELL, -}; - -static void -e_cell_date_edit_config_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) -{ - ECellDateEditConfig *view_config; - ECellDateEditConfigPrivate *priv; - - view_config = E_CELL_DATE_EDIT_CONFIG (object); - priv = view_config->priv; - - switch (property_id) { - case PROP_CELL: - e_cell_date_edit_config_set_cell (view_config, g_value_get_object (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -e_cell_date_edit_config_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) -{ - ECellDateEditConfig *view_config; - ECellDateEditConfigPrivate *priv; - - view_config = E_CELL_DATE_EDIT_CONFIG (object); - priv = view_config->priv; - - switch (property_id) { - case PROP_CELL: - g_value_set_object (value, e_cell_date_edit_config_get_cell (view_config)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -e_cell_date_edit_config_dispose (GObject *object) -{ - ECellDateEditConfig *view_config = E_CELL_DATE_EDIT_CONFIG (object); - ECellDateEditConfigPrivate *priv; - - priv = view_config->priv; - - e_cell_date_edit_config_set_cell (view_config, NULL); - - if (G_OBJECT_CLASS (parent_class)->dispose) - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -e_cell_date_edit_config_finalize (GObject *object) -{ - ECellDateEditConfig *view_config = E_CELL_DATE_EDIT_CONFIG (object); - ECellDateEditConfigPrivate *priv; - - priv = view_config->priv; - - g_free (priv); - - if (G_OBJECT_CLASS (parent_class)->finalize) - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -e_cell_date_edit_config_class_init (ECellDateEditConfigClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GParamSpec *spec; - - parent_class = g_type_class_peek_parent (klass); - - /* Method override */ - gobject_class->set_property = e_cell_date_edit_config_set_property; - gobject_class->get_property = e_cell_date_edit_config_get_property; - gobject_class->dispose = e_cell_date_edit_config_dispose; - gobject_class->finalize = e_cell_date_edit_config_finalize; - - spec = g_param_spec_object ("cell", NULL, NULL, e_cell_date_edit_get_type (), - G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT); - g_object_class_install_property (gobject_class, PROP_CELL, spec); -} - -static void -e_cell_date_edit_config_init (ECellDateEditConfig *view_config, ECellDateEditConfigClass *klass) -{ - view_config->priv = g_new0 (ECellDateEditConfigPrivate, 1); - -} - -E_MAKE_TYPE (e_cell_date_edit_config, "ECellDateEditConfig", ECellDateEditConfig, e_cell_date_edit_config_class_init, - e_cell_date_edit_config_init, G_TYPE_OBJECT); - -ECellDateEditConfig * -e_cell_date_edit_config_new (ECellDateEdit *cell) -{ - ECellDateEditConfig *view_config; - - view_config = g_object_new (e_cell_date_edit_config_get_type (), "cell", cell, NULL); - - return view_config; -} - -ECellDateEdit * -e_cell_date_edit_config_get_cell (ECellDateEditConfig *view_config) -{ - ECellDateEditConfigPrivate *priv; - - g_return_val_if_fail (view_config != NULL, NULL); - g_return_val_if_fail (E_IS_CELL_DATE_EDIT_CONFIG (view_config), NULL); - - priv = view_config->priv; - - return priv->cell; -} - -static void -set_timezone (ECellDateEdit *cell) -{ - ECellDateEditText *cell_text; - ECellPopup *cell_popup; - char *location; - icaltimezone *zone; - - location = calendar_config_get_timezone (); - zone = icaltimezone_get_builtin_timezone (location); - if (!zone) - zone = icaltimezone_get_utc_timezone (); - - cell_popup = E_CELL_POPUP (cell); - cell_text = E_CELL_DATE_EDIT_TEXT (cell_popup->child); - e_cell_date_edit_text_set_timezone (cell_text, zone); - - g_free (location); -} - -static void -timezone_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - ECellDateEditConfig *view_config = data; - ECellDateEditConfigPrivate *priv; - - priv = view_config->priv; - - set_timezone (priv->cell); -} - -static void -set_twentyfour_hour (ECellDateEdit *cell) -{ - ECellDateEditText *cell_text; - ECellPopup *cell_popup; - gboolean use_24_hour; - - use_24_hour = calendar_config_get_24_hour_format (); - - e_cell_date_edit_freeze (cell); - g_object_set (G_OBJECT (cell), - "use_24_hour_format", use_24_hour, - NULL); - e_cell_date_edit_thaw (cell); - - cell_popup = E_CELL_POPUP (cell); - cell_text = E_CELL_DATE_EDIT_TEXT (cell_popup->child); - e_cell_date_edit_text_set_use_24_hour_format (cell_text, use_24_hour); -} - -static void -twentyfour_hour_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - ECellDateEditConfig *view_config = data; - ECellDateEditConfigPrivate *priv; - - priv = view_config->priv; - - set_twentyfour_hour (priv->cell); -} - -static void -set_range (ECellDateEdit *cell) -{ - int start_hour, end_hour; - - 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++; - - /* Make sure the start hour is ok */ - if (start_hour > end_hour) - start_hour = end_hour; - - /* We use the default 0 - 24 now. */ -#if 0 - g_object_set (G_OBJECT (cell), - "lower_hour", start_hour, - "upper_hour", end_hour, - NULL); -#endif -} - -static void -day_start_hour_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - ECellDateEditConfig *view_config = data; - ECellDateEditConfigPrivate *priv; - - priv = view_config->priv; - - set_range (priv->cell); -} - -static void -day_end_hour_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - ECellDateEditConfig *view_config = data; - ECellDateEditConfigPrivate *priv; - - priv = view_config->priv; - - set_range (priv->cell); -} - -static void -day_end_minute_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - ECellDateEditConfig *view_config = data; - ECellDateEditConfigPrivate *priv; - - priv = view_config->priv; - - set_range (priv->cell); -} - -void -e_cell_date_edit_config_set_cell (ECellDateEditConfig *view_config, ECellDateEdit *cell) -{ - ECellDateEditConfigPrivate *priv; - guint not; - GList *l; - - g_return_if_fail (view_config != NULL); - g_return_if_fail (E_IS_CELL_DATE_EDIT_CONFIG (view_config)); - - priv = view_config->priv; - - if (priv->cell) { - g_object_unref (priv->cell); - priv->cell = NULL; - } - - if (priv->mini_config) { - g_object_unref (priv->mini_config); - priv->mini_config = NULL; - } - - for (l = priv->notifications; l; l = l->next) - calendar_config_remove_notification (GPOINTER_TO_UINT (l->data)); - - g_list_free (priv->notifications); - priv->notifications = NULL; - - /* If the new view is NULL, return right now */ - if (!cell) - return; - - priv->cell = g_object_ref (cell); - - /* Time zone */ - set_timezone (cell); - - not = calendar_config_add_notification_timezone (timezone_changed_cb, view_config); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - /* 24 Hour format */ - set_twentyfour_hour (cell); - - not = calendar_config_add_notification_24_hour_format (twentyfour_hour_changed_cb, view_config); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - /* Popup time range */ - set_range (cell); - - not = calendar_config_add_notification_day_start_hour (day_start_hour_changed_cb, view_config); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - not = calendar_config_add_notification_day_end_hour (day_end_hour_changed_cb, view_config); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - not = calendar_config_add_notification_day_end_minute (day_end_minute_changed_cb, view_config); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - /* The mini calendar */ - priv->mini_config = e_mini_calendar_config_new (E_CALENDAR (cell->calendar)); -} diff --git a/calendar/gui/e-cell-date-edit-config.h b/calendar/gui/e-cell-date-edit-config.h deleted file mode 100644 index fad1d9e508..0000000000 --- a/calendar/gui/e-cell-date-edit-config.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Author : - * JP Rosevear <jpr@ximian.com> - * - * Copyright 2003, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef _E_CELL_DATE_EDIT_CONFIG_H_ -#define _E_CELL_DATE_EDIT_CONFIG_H_ - -#include <widgets/misc/e-cell-date-edit.h> - -G_BEGIN_DECLS - -#define E_CELL_DATE_EDIT_CONFIG(obj) GTK_CHECK_CAST (obj, e_cell_date_edit_config_get_type (), ECellDateEditConfig) -#define E_CELL_DATE_EDIT_CONFIG_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, e_cell_date_edit_config_get_type (), ECellDateEditConfigClass) -#define E_IS_CELL_DATE_EDIT_CONFIG(obj) GTK_CHECK_TYPE (obj, e_cell_date_edit_config_get_type ()) - -typedef struct _ECellDateEditConfig ECellDateEditConfig; -typedef struct _ECellDateEditConfigClass ECellDateEditConfigClass; -typedef struct _ECellDateEditConfigPrivate ECellDateEditConfigPrivate; - -struct _ECellDateEditConfig { - GObject parent; - - ECellDateEditConfigPrivate *priv; -}; - -struct _ECellDateEditConfigClass { - GObjectClass parent_class; -}; - -GType e_cell_date_edit_config_get_type (void); -ECellDateEditConfig *e_cell_date_edit_config_new (ECellDateEdit *cell); -ECellDateEdit *e_cell_date_edit_config_get_cell (ECellDateEditConfig *cell_config); -void e_cell_date_edit_config_set_cell (ECellDateEditConfig *view_config, ECellDateEdit *cell); - -G_END_DECLS - -#endif 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 d487a78ae4..0000000000 --- a/calendar/gui/e-cell-date-edit-text.c +++ /dev/null @@ -1,234 +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 ECalComponentDateTime* 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-icons.h> -#include <libgnome/gnome-i18n.h> -#include <gal/util/e-util.h> -#include <e-util/e-time-utils.h> -#include <libecal/e-cal-time-util.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 g_strdup (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"); - - e_utf8_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 ECalComponentDateTime*. - * - * 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 = g_object_new (e_cell_date_edit_text_get_type (), NULL); - - 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 ab00c0b39c..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 ECalComponentDateTime* model value. - */ - -#ifndef _E_CELL_DATE_EDIT_TEXT_H_ -#define _E_CELL_DATE_EDIT_TEXT_H_ - -#include <libical/ical.h> -#include <gal/e-table/e-cell-text.h> - -G_BEGIN_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); -G_END_DECLS - -#endif /* _E_CELL_DATE_EDIT_TEXT_H_ */ diff --git a/calendar/gui/e-comp-editor-registry.c b/calendar/gui/e-comp-editor-registry.c deleted file mode 100644 index 9e2a63bd48..0000000000 --- a/calendar/gui/e-comp-editor-registry.c +++ /dev/null @@ -1,212 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-comp-editor-registry.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: JP Rosevear - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gnome.h> -#include <gal/util/e-util.h> -#include "e-comp-editor-registry.h" - -struct _ECompEditorRegistryPrivate { - GHashTable *editors; -}; - -struct _ECompEditorRegistryData -{ - CompEditor *editor; - char *uid; -}; - -typedef struct _ECompEditorRegistryData ECompEditorRegistryData; -typedef struct _ECompEditorRegistryForeachData ECompEditorRegistryForeachData; - -static GtkObjectClass *parent_class = NULL; - -static void editor_destroy_cb (GtkWidget *widget, gpointer data); - -static void -destroy (GtkObject *obj) -{ - ECompEditorRegistry *reg; - ECompEditorRegistryPrivate *priv; - - reg = E_COMP_EDITOR_REGISTRY (obj); - priv = reg->priv; - - if (priv) { - if (priv->editors) { - g_hash_table_destroy (priv->editors); - priv->editors = NULL; - } - - g_free (priv); - reg->priv = NULL; - } - - (* GTK_OBJECT_CLASS (parent_class)->destroy) (obj); -} - -static void -class_init (ECompEditorRegistryClass *klass) -{ - GtkObjectClass *object_class; - - object_class = GTK_OBJECT_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - object_class->destroy = destroy; -} - -static void -init (ECompEditorRegistry *reg) -{ - ECompEditorRegistryPrivate *priv; - - priv = g_new0 (ECompEditorRegistryPrivate, 1); - - reg->priv = priv; - - priv->editors = g_hash_table_new (g_str_hash, g_str_equal); -} - - - -E_MAKE_TYPE (e_comp_editor_registry, "ECompEditorRegistry", ECompEditorRegistry, - class_init, init, gtk_object_get_type ()); - -GtkObject * -e_comp_editor_registry_new (void) -{ - return g_object_new (E_TYPE_COMP_EDITOR_REGISTRY, NULL); -} - -void -e_comp_editor_registry_add (ECompEditorRegistry *reg, CompEditor *editor, gboolean remote) -{ - ECompEditorRegistryPrivate *priv; - ECompEditorRegistryData *rdata; - ECalComponent *comp; - const char *uid; - - g_return_if_fail (reg != NULL); - g_return_if_fail (E_IS_COMP_EDITOR_REGISTRY (reg)); - g_return_if_fail (editor != NULL); - g_return_if_fail (IS_COMP_EDITOR (editor)); - - priv = reg->priv; - - comp = comp_editor_get_comp (editor); - e_cal_component_get_uid (comp, &uid); - - rdata = g_new0 (ECompEditorRegistryData, 1); - - rdata->editor = editor; - rdata->uid = g_strdup (uid); - g_hash_table_insert (priv->editors, rdata->uid, rdata); - - g_signal_connect (editor, "destroy", G_CALLBACK (editor_destroy_cb), reg); - -} - -CompEditor * -e_comp_editor_registry_find (ECompEditorRegistry *reg, const char *uid) -{ - ECompEditorRegistryPrivate *priv; - ECompEditorRegistryData *rdata; - - g_return_val_if_fail (reg != NULL, NULL); - g_return_val_if_fail (E_IS_COMP_EDITOR_REGISTRY (reg), NULL); - g_return_val_if_fail (uid != NULL, NULL); - - priv = reg->priv; - - rdata = g_hash_table_lookup (priv->editors, uid); - if (rdata != NULL) - return rdata->editor; - - return NULL; -} - -static gboolean -foreach_close_cb (gpointer key, gpointer value, gpointer data) -{ - ECompEditorRegistryData *rdata; - - rdata = value; - - g_signal_handlers_block_matched (rdata->editor, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, data); - - comp_editor_focus (rdata->editor); - if (!comp_editor_close (rdata->editor)) { - g_signal_handlers_unblock_matched (rdata->editor, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, data); - return FALSE; - } - - g_free (rdata->uid); - g_free (rdata); - - return TRUE; -} - -gboolean -e_comp_editor_registry_close_all (ECompEditorRegistry *reg) -{ - ECompEditorRegistryPrivate *priv; - - g_return_val_if_fail (reg != NULL, FALSE); - g_return_val_if_fail (E_IS_COMP_EDITOR_REGISTRY (reg), FALSE); - - priv = reg->priv; - - g_hash_table_foreach_remove (priv->editors, foreach_close_cb, reg); - if (g_hash_table_size (priv->editors) != 0) - return FALSE; - - return TRUE; -} - -static void -editor_destroy_cb (GtkWidget *widget, gpointer data) -{ - ECompEditorRegistry *reg; - ECompEditorRegistryPrivate *priv; - ECompEditorRegistryData *rdata; - ECalComponent *comp; - const char *uid; - - reg = E_COMP_EDITOR_REGISTRY (data); - priv = reg->priv; - - comp = comp_editor_get_comp (COMP_EDITOR (widget)); - e_cal_component_get_uid (comp, &uid); - - rdata = g_hash_table_lookup (priv->editors, uid); - - if (rdata != NULL) { - g_hash_table_remove (priv->editors, rdata->uid); - g_free (rdata->uid); - g_free (rdata); - } -} diff --git a/calendar/gui/e-comp-editor-registry.h b/calendar/gui/e-comp-editor-registry.h deleted file mode 100644 index dfcc1b21bc..0000000000 --- a/calendar/gui/e-comp-editor-registry.h +++ /dev/null @@ -1,79 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-comp-editor-registry.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: JP Rosevear - */ - -#ifndef _E_COMP_EDITOR_REGISTRY_H_ -#define _E_COMP_EDITOR_REGISTRY_H_ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gtk/gtk.h> -#include <dialogs/comp-editor.h> - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -#define E_TYPE_COMP_EDITOR_REGISTRY (e_comp_editor_registry_get_type ()) -#define E_COMP_EDITOR_REGISTRY(obj) (GTK_CHECK_CAST ((obj), E_TYPE_COMP_EDITOR_REGISTRY, ECompEditorRegistry)) -#define E_COMP_EDITOR_REGISTRY_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_COMP_EDITOR_REGISTRY, ECompEditorRegistryClass)) -#define E_IS_COMP_EDITOR_REGISTRY(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_COMP_EDITOR_REGISTRY)) -#define E_IS_COMP_EDITOR_REGISTRY_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_COMP_EDITOR_REGISTRY)) - - -typedef struct _ECompEditorRegistry ECompEditorRegistry; -typedef struct _ECompEditorRegistryPrivate ECompEditorRegistryPrivate; -typedef struct _ECompEditorRegistryClass ECompEditorRegistryClass; - -struct _ECompEditorRegistry { - GtkObject parent; - - ECompEditorRegistryPrivate *priv; -}; - -struct _ECompEditorRegistryClass { - GtkObjectClass parent_class; -}; - -typedef void (* ECompEditorRegistryForeachFn) (CompEditor *editor, gpointer data); - - - - -GtkType e_comp_editor_registry_get_type (void); -GtkObject *e_comp_editor_registry_new (void); -void e_comp_editor_registry_add (ECompEditorRegistry *reg, - CompEditor *editor, - gboolean remote); -CompEditor *e_comp_editor_registry_find (ECompEditorRegistry *reg, - const char *uid); -gboolean e_comp_editor_registry_close_all (ECompEditorRegistry *reg); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_COMP_EDITOR_REGISTRY_H_ */ - - diff --git a/calendar/gui/e-date-edit-config.c b/calendar/gui/e-date-edit-config.c deleted file mode 100644 index f3d88fdd53..0000000000 --- a/calendar/gui/e-date-edit-config.c +++ /dev/null @@ -1,269 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Author : - * JP Rosevear <jpr@ximian.com> - * - * Copyright 2003, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include "calendar-config.h" -#include "e-date-edit-config.h" - -struct _EDateEditConfigPrivate { - EDateEdit *edit; - - GList *notifications; -}; - -static GObjectClass *parent_class = NULL; - -/* Property IDs */ -enum props { - PROP_0, - PROP_EDIT, -}; - -static void -e_date_edit_config_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) -{ - EDateEditConfig *edit_config; - EDateEditConfigPrivate *priv; - - edit_config = E_DATE_EDIT_CONFIG (object); - priv = edit_config->priv; - - switch (property_id) { - case PROP_EDIT: - e_date_edit_config_set_edit (edit_config, g_value_get_object (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -e_date_edit_config_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) -{ - EDateEditConfig *edit_config; - EDateEditConfigPrivate *priv; - - edit_config = E_DATE_EDIT_CONFIG (object); - priv = edit_config->priv; - - switch (property_id) { - case PROP_EDIT: - g_value_set_object (value, e_date_edit_config_get_edit (edit_config)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -e_date_edit_config_dispose (GObject *object) -{ - EDateEditConfig *edit_config = E_DATE_EDIT_CONFIG (object); - EDateEditConfigPrivate *priv; - - priv = edit_config->priv; - - e_date_edit_config_set_edit (edit_config, NULL); - - if (G_OBJECT_CLASS (parent_class)->dispose) - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -e_date_edit_config_finalize (GObject *object) -{ - EDateEditConfig *edit_config = E_DATE_EDIT_CONFIG (object); - EDateEditConfigPrivate *priv; - - priv = edit_config->priv; - - g_free (priv); - - if (G_OBJECT_CLASS (parent_class)->finalize) - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -e_date_edit_config_class_init (EDateEditConfigClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GParamSpec *spec; - - parent_class = g_type_class_peek_parent (klass); - - /* Method override */ - gobject_class->set_property = e_date_edit_config_set_property; - gobject_class->get_property = e_date_edit_config_get_property; - gobject_class->dispose = e_date_edit_config_dispose; - gobject_class->finalize = e_date_edit_config_finalize; - - spec = g_param_spec_object ("edit", NULL, NULL, e_date_edit_get_type (), - G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT); - g_object_class_install_property (gobject_class, PROP_EDIT, spec); -} - -static void -e_date_edit_config_init (EDateEditConfig *edit_config, EDateEditConfigClass *klass) -{ - edit_config->priv = g_new0 (EDateEditConfigPrivate, 1); - -} - -E_MAKE_TYPE (e_date_edit_config, "EDateEditConfig", EDateEditConfig, e_date_edit_config_class_init, - e_date_edit_config_init, G_TYPE_OBJECT); - -EDateEditConfig * -e_date_edit_config_new (EDateEdit *date_edit) -{ - EDateEditConfig *edit_config; - - edit_config = g_object_new (e_date_edit_config_get_type (), "edit", date_edit, NULL); - - return edit_config; -} - -EDateEdit * -e_date_edit_config_get_edit (EDateEditConfig *edit_config) -{ - EDateEditConfigPrivate *priv; - - g_return_val_if_fail (edit_config != NULL, NULL); - g_return_val_if_fail (E_IS_DATE_EDIT_CONFIG (edit_config), NULL); - - priv = edit_config->priv; - - return priv->edit; -} - -static void -set_week_start (EDateEdit *date_edit) -{ - int week_start_day; - - 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_date_edit_set_week_start_day (date_edit, week_start_day); -} - -static void -week_start_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - EDateEditConfig *edit_config = data; - EDateEditConfigPrivate *priv; - - priv = edit_config->priv; - - set_week_start (priv->edit); -} - -static void -set_twentyfour_hour (EDateEdit *date_edit) -{ - gboolean use_24_hour; - - use_24_hour = calendar_config_get_24_hour_format (); - - e_date_edit_set_use_24_hour_format (date_edit, use_24_hour); -} - -static void -twentyfour_hour_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - EDateEditConfig *edit_config = data; - EDateEditConfigPrivate *priv; - - priv = edit_config->priv; - - set_twentyfour_hour (priv->edit); -} - -static void -set_dnav_show_week_no (EDateEdit *date_edit) -{ - gboolean show_week_no; - - show_week_no = calendar_config_get_dnav_show_week_no (); - - e_date_edit_set_show_week_numbers (date_edit, show_week_no); -} - -static void -dnav_show_week_no_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - EDateEditConfig *edit_config = data; - EDateEditConfigPrivate *priv; - - priv = edit_config->priv; - - set_dnav_show_week_no (priv->edit); -} -void -e_date_edit_config_set_edit (EDateEditConfig *edit_config, EDateEdit *date_edit) -{ - EDateEditConfigPrivate *priv; - guint not; - GList *l; - - g_return_if_fail (edit_config != NULL); - g_return_if_fail (E_IS_DATE_EDIT_CONFIG (edit_config)); - - priv = edit_config->priv; - - if (priv->edit) { - g_object_unref (priv->edit); - priv->edit = NULL; - } - - for (l = priv->notifications; l; l = l->next) - calendar_config_remove_notification (GPOINTER_TO_UINT (l->data)); - - g_list_free (priv->notifications); - priv->notifications = NULL; - - /* If the new edit is NULL, return right now */ - if (!date_edit) - return; - - priv->edit = g_object_ref (date_edit); - - /* Week start */ - set_week_start (date_edit); - - not = calendar_config_add_notification_week_start_day (week_start_changed_cb, edit_config); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - /* 24 Hour format */ - set_twentyfour_hour (date_edit); - - not = calendar_config_add_notification_24_hour_format (twentyfour_hour_changed_cb, edit_config); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - /* Show week numbers */ - set_dnav_show_week_no (date_edit); - - not = calendar_config_add_notification_dnav_show_week_no (dnav_show_week_no_changed_cb, edit_config); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); -} diff --git a/calendar/gui/e-date-edit-config.h b/calendar/gui/e-date-edit-config.h deleted file mode 100644 index 0707666bff..0000000000 --- a/calendar/gui/e-date-edit-config.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Author : - * JP Rosevear <jpr@ximian.com> - * - * Copyright 2003, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef _E_DATE_EDIT_CONFIG_H_ -#define _E_DATE_EDIT_CONFIG_H_ - -#include <widgets/misc/e-dateedit.h> - -G_BEGIN_DECLS - -#define E_DATE_EDIT_CONFIG(obj) GTK_CHECK_CAST (obj, e_date_edit_config_get_type (), EDateEditConfig) -#define E_DATE_EDIT_CONFIG_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, e_date_edit_config_get_type (), EDateEditConfigClass) -#define E_IS_DATE_EDIT_CONFIG(obj) GTK_CHECK_TYPE (obj, e_date_edit_config_get_type ()) - -typedef struct _EDateEditConfig EDateEditConfig; -typedef struct _EDateEditConfigClass EDateEditConfigClass; -typedef struct _EDateEditConfigPrivate EDateEditConfigPrivate; - -struct _EDateEditConfig { - GObject parent; - - EDateEditConfigPrivate *priv; -}; - -struct _EDateEditConfigClass { - GObjectClass parent_class; -}; - -GType e_date_edit_config_get_type (void); -EDateEditConfig *e_date_edit_config_new (EDateEdit *date_edit); -EDateEdit *e_date_edit_config_get_edit (EDateEditConfig *edit_config); -void e_date_edit_config_set_edit (EDateEditConfig *edit_config, EDateEdit *date_edit); - -G_END_DECLS - -#endif diff --git a/calendar/gui/e-date-time-list.c b/calendar/gui/e-date-time-list.c deleted file mode 100644 index 348ccc86a9..0000000000 --- a/calendar/gui/e-date-time-list.c +++ /dev/null @@ -1,566 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* EDateTimeList - list of calendar dates/times with GtkTreeModel interface. - * - * Copyright (C) 2003 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - * - * Authors: Hans Petter Jansson <hpj@ximian.com> - */ - -#include <string.h> -#include <gtk/gtktreemodel.h> -#include <gtk/gtksignal.h> -#include <gtk/gtktreednd.h> -#include <glib.h> -#include <e-util/e-time-utils.h> -#include "e-date-time-list.h" -#include <libecal/e-cal-time-util.h> -#include "calendar-config.h" - -#define G_LIST(x) ((GList *) x) -#define E_DATE_TIME_LIST_IS_SORTED(list) (E_DATE_TIME_LIST (list)->sort_column_id != -2) -#define IS_VALID_ITER(dt_list, iter) (iter!= NULL && iter->user_data != NULL && \ - dt_list->stamp == iter->stamp) - -static GType column_types [E_DATE_TIME_LIST_NUM_COLUMNS]; - -static void e_date_time_list_init (EDateTimeList *file_list); -static void e_date_time_list_class_init (EDateTimeListClass *class); -static void e_date_time_list_tree_model_init (GtkTreeModelIface *iface); -static void e_date_time_list_finalize (GObject *object); -static guint e_date_time_list_get_flags (GtkTreeModel *tree_model); -static gint e_date_time_list_get_n_columns (GtkTreeModel *tree_model); -static GType e_date_time_list_get_column_type (GtkTreeModel *tree_model, - gint index); -static gboolean e_date_time_list_get_iter (GtkTreeModel *tree_model, - GtkTreeIter *iter, - GtkTreePath *path); -static GtkTreePath *e_date_time_list_get_path (GtkTreeModel *tree_model, - GtkTreeIter *iter); -static void e_date_time_list_get_value (GtkTreeModel *tree_model, - GtkTreeIter *iter, - gint column, - GValue *value); -static gboolean e_date_time_list_iter_next (GtkTreeModel *tree_model, - GtkTreeIter *iter); -static gboolean e_date_time_list_iter_children (GtkTreeModel *tree_model, - GtkTreeIter *iter, - GtkTreeIter *parent); -static gboolean e_date_time_list_iter_has_child (GtkTreeModel *tree_model, - GtkTreeIter *iter); -static gint e_date_time_list_iter_n_children (GtkTreeModel *tree_model, - GtkTreeIter *iter); -static gboolean e_date_time_list_iter_nth_child (GtkTreeModel *tree_model, - GtkTreeIter *iter, - GtkTreeIter *parent, - gint n); -static gboolean e_date_time_list_iter_parent (GtkTreeModel *tree_model, - GtkTreeIter *iter, - GtkTreeIter *child); - -static GObjectClass *parent_class = NULL; - -GtkType -e_date_time_list_get_type (void) -{ - static GType date_time_list_type = 0; - - if (!date_time_list_type) { - static const GTypeInfo date_time_list_info = - { - sizeof (EDateTimeListClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) e_date_time_list_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (EDateTimeList), - 0, - (GInstanceInitFunc) e_date_time_list_init, - }; - - static const GInterfaceInfo tree_model_info = - { - (GInterfaceInitFunc) e_date_time_list_tree_model_init, - NULL, - NULL - }; - - column_types [E_DATE_TIME_LIST_COLUMN_DESCRIPTION] = G_TYPE_STRING; - - date_time_list_type = g_type_register_static (G_TYPE_OBJECT, "EDateTimeList", - &date_time_list_info, 0); - g_type_add_interface_static (date_time_list_type, - GTK_TYPE_TREE_MODEL, - &tree_model_info); - } - - return date_time_list_type; -} - -static void -e_date_time_list_class_init (EDateTimeListClass *class) -{ - GObjectClass *object_class; - - parent_class = g_type_class_peek_parent (class); - object_class = (GObjectClass*) class; - - object_class->finalize = e_date_time_list_finalize; -} - -static void -e_date_time_list_tree_model_init (GtkTreeModelIface *iface) -{ - iface->get_flags = e_date_time_list_get_flags; - iface->get_n_columns = e_date_time_list_get_n_columns; - iface->get_column_type = e_date_time_list_get_column_type; - iface->get_iter = e_date_time_list_get_iter; - iface->get_path = e_date_time_list_get_path; - iface->get_value = e_date_time_list_get_value; - iface->iter_next = e_date_time_list_iter_next; - iface->iter_children = e_date_time_list_iter_children; - iface->iter_has_child = e_date_time_list_iter_has_child; - iface->iter_n_children = e_date_time_list_iter_n_children; - iface->iter_nth_child = e_date_time_list_iter_nth_child; - iface->iter_parent = e_date_time_list_iter_parent; -} - -static void -e_date_time_list_init (EDateTimeList *date_time_list) -{ - date_time_list->stamp = g_random_int (); - date_time_list->columns_dirty = FALSE; - date_time_list->list = NULL; -} - -EDateTimeList * -e_date_time_list_new (void) -{ - EDateTimeList *date_time_list; - - date_time_list = E_DATE_TIME_LIST (g_object_new (e_date_time_list_get_type (), NULL)); - - return date_time_list; -} - -static void -all_rows_deleted (EDateTimeList *date_time_list) -{ - GtkTreePath *path; - gint i; - - if (!date_time_list->list) - return; - - path = gtk_tree_path_new (); - i = g_list_length (date_time_list->list); - gtk_tree_path_append_index (path, i); - - for ( ; i >= 0; i--) { - gtk_tree_model_row_deleted (GTK_TREE_MODEL (date_time_list), path); - gtk_tree_path_prev (path); - } - - gtk_tree_path_free (path); -} - -static void -row_deleted (EDateTimeList *date_time_list, gint n) -{ - GtkTreePath *path; - - path = gtk_tree_path_new (); - gtk_tree_path_append_index (path, n); - gtk_tree_model_row_deleted (GTK_TREE_MODEL (date_time_list), path); - gtk_tree_path_free (path); -} - -static void -row_added (EDateTimeList *date_time_list, gint n) -{ - GtkTreePath *path; - GtkTreeIter iter; - - path = gtk_tree_path_new (); - gtk_tree_path_append_index (path, n); - - if (gtk_tree_model_get_iter (GTK_TREE_MODEL (date_time_list), &iter, path)) - gtk_tree_model_row_inserted (GTK_TREE_MODEL (date_time_list), path, &iter); - - gtk_tree_path_free (path); -} - -static void -row_updated (EDateTimeList *date_time_list, gint n) -{ - GtkTreePath *path; - GtkTreeIter iter; - - path = gtk_tree_path_new (); - gtk_tree_path_append_index (path, n); - - if (gtk_tree_model_get_iter (GTK_TREE_MODEL (date_time_list), &iter, path)) - gtk_tree_model_row_changed (GTK_TREE_MODEL (date_time_list), path, &iter); - - gtk_tree_path_free (path); -} - -static void -e_date_time_list_finalize (GObject *object) -{ - EDateTimeList *date_time_list = E_DATE_TIME_LIST (object); - - if (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (object); -} - -/* Fulfill the GtkTreeModel requirements */ -static guint -e_date_time_list_get_flags (GtkTreeModel *tree_model) -{ - g_return_val_if_fail (E_IS_DATE_TIME_LIST (tree_model), 0); - - return GTK_TREE_MODEL_LIST_ONLY; -} - -static gint -e_date_time_list_get_n_columns (GtkTreeModel *tree_model) -{ - EDateTimeList *date_time_list = (EDateTimeList *) tree_model; - - g_return_val_if_fail (E_IS_DATE_TIME_LIST (tree_model), 0); - - date_time_list->columns_dirty = TRUE; - return E_DATE_TIME_LIST_NUM_COLUMNS; -} - -static GType -e_date_time_list_get_column_type (GtkTreeModel *tree_model, - gint index) -{ - EDateTimeList *date_time_list = (EDateTimeList *) tree_model; - - g_return_val_if_fail (E_IS_DATE_TIME_LIST (tree_model), G_TYPE_INVALID); - g_return_val_if_fail (index < E_DATE_TIME_LIST_NUM_COLUMNS && - index >= 0, G_TYPE_INVALID); - - date_time_list->columns_dirty = TRUE; - return column_types [index]; -} - -const ECalComponentDateTime * -e_date_time_list_get_date_time (EDateTimeList *date_time_list, GtkTreeIter *iter) -{ - g_return_val_if_fail (IS_VALID_ITER (date_time_list, iter), NULL); - - return G_LIST (iter->user_data)->data; -} - -static void -free_datetime (ECalComponentDateTime *datetime) -{ - g_free (datetime->value); - if (datetime->tzid) - g_free ((gchar *) datetime->tzid); - g_free (datetime); -} - -static ECalComponentDateTime * -copy_datetime (const ECalComponentDateTime *datetime) -{ - ECalComponentDateTime *datetime_copy; - - datetime_copy = g_new0 (ECalComponentDateTime, 1); - datetime_copy->value = g_new (struct icaltimetype, 1); - *datetime_copy->value = *datetime->value; - - if (datetime->tzid) - datetime_copy->tzid = g_strdup (datetime->tzid); - - return datetime_copy; -} - -static gint -compare_datetime (const ECalComponentDateTime *datetime1, const ECalComponentDateTime *datetime2) -{ - return icaltime_compare (*datetime1->value, *datetime2->value); -} - -void -e_date_time_list_set_date_time (EDateTimeList *date_time_list, GtkTreeIter *iter, - const ECalComponentDateTime *datetime) -{ - ECalComponentDateTime *datetime_old; - - g_return_if_fail (IS_VALID_ITER (date_time_list, iter)); - - datetime_old = G_LIST (iter->user_data)->data; - free_datetime (datetime_old); - G_LIST (iter->user_data)->data = copy_datetime (datetime); - row_updated (date_time_list, g_list_position (date_time_list->list, G_LIST (iter->user_data))); -} - -void -e_date_time_list_append (EDateTimeList *date_time_list, GtkTreeIter *iter, - const ECalComponentDateTime *datetime) -{ - g_return_if_fail (datetime != NULL); - - if (g_list_find_custom (date_time_list->list, datetime, (GCompareFunc)compare_datetime) == NULL) { - date_time_list->list = g_list_append (date_time_list->list, copy_datetime (datetime)); - row_added (date_time_list, g_list_length (date_time_list->list) - 1); - } - - if (iter) { - iter->user_data = g_list_last (date_time_list->list); - iter->stamp = date_time_list->stamp; - } -} - -void -e_date_time_list_remove (EDateTimeList *date_time_list, GtkTreeIter *iter) -{ - gint n; - - g_return_if_fail (IS_VALID_ITER (date_time_list, iter)); - - n = g_list_position (date_time_list->list, G_LIST (iter->user_data)); - free_datetime ((ECalComponentDateTime *) G_LIST (iter->user_data)->data); - date_time_list->list = g_list_delete_link (date_time_list->list, G_LIST (iter->user_data)); - row_deleted (date_time_list, n); -} - -void -e_date_time_list_clear (EDateTimeList *date_time_list) -{ - GList *l; - - all_rows_deleted (date_time_list); - - for (l = date_time_list->list; l; l = g_list_next (l)) { - free_datetime ((ECalComponentDateTime *) l->data); - } - - g_list_free (date_time_list->list); - date_time_list->list = NULL; -} - -static gboolean -e_date_time_list_get_iter (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreePath *path) -{ - EDateTimeList *date_time_list = (EDateTimeList *) tree_model; - GList *l; - gint i; - - g_return_val_if_fail (E_IS_DATE_TIME_LIST (tree_model), FALSE); - g_return_val_if_fail (gtk_tree_path_get_depth (path) > 0, FALSE); - - if (!date_time_list->list) - return FALSE; - - date_time_list->columns_dirty = TRUE; - - i = gtk_tree_path_get_indices (path)[0]; - l = g_list_nth (date_time_list->list, i); - if (!l) - return FALSE; - - iter->user_data = l; - iter->stamp = date_time_list->stamp; - return TRUE; -} - -static GtkTreePath * -e_date_time_list_get_path (GtkTreeModel *tree_model, - GtkTreeIter *iter) -{ - EDateTimeList *date_time_list = (EDateTimeList *) tree_model; - GtkTreePath *retval; - GList *l; - - g_return_val_if_fail (E_IS_DATE_TIME_LIST (tree_model), NULL); - g_return_val_if_fail (iter->stamp == E_DATE_TIME_LIST (tree_model)->stamp, NULL); - - l = iter->user_data; - retval = gtk_tree_path_new (); - gtk_tree_path_append_index (retval, g_list_position (date_time_list->list, l)); - return retval; -} - -/* Builds a static string out of an exception date */ -static char * -get_exception_string (ECalComponentDateTime *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; -} - -static void -e_date_time_list_get_value (GtkTreeModel *tree_model, - GtkTreeIter *iter, - gint column, - GValue *value) -{ - EDateTimeList *date_time_list = E_DATE_TIME_LIST (tree_model); - ECalComponentDateTime *datetime; - GList *l; - const gchar *str; - - g_return_if_fail (E_IS_DATE_TIME_LIST (tree_model)); - g_return_if_fail (column < E_DATE_TIME_LIST_NUM_COLUMNS); - g_return_if_fail (E_DATE_TIME_LIST (tree_model)->stamp == iter->stamp); - g_return_if_fail (IS_VALID_ITER (date_time_list, iter)); - - g_value_init (value, column_types [column]); - - if (!date_time_list->list) - return; - - l = iter->user_data; - datetime = l->data; - - if (!datetime) - return; - - switch (column) { - case E_DATE_TIME_LIST_COLUMN_DESCRIPTION: - str = get_exception_string (datetime); - g_value_set_string (value, str); - break; - } -} - -static gboolean -e_date_time_list_iter_next (GtkTreeModel *tree_model, - GtkTreeIter *iter) -{ - GList *l; - - g_return_val_if_fail (E_IS_DATE_TIME_LIST (tree_model), FALSE); - g_return_val_if_fail (IS_VALID_ITER (E_DATE_TIME_LIST (tree_model), iter), FALSE); - - if (!E_DATE_TIME_LIST (tree_model)->list) - return FALSE; - - l = iter->user_data; - l = g_list_next (l); - if (l) { - iter->user_data = l; - return TRUE; - } - - return FALSE; -} - -static gboolean -e_date_time_list_iter_children (GtkTreeModel *tree_model, - GtkTreeIter *iter, - GtkTreeIter *parent) -{ - EDateTimeList *date_time_list = E_DATE_TIME_LIST (tree_model); - - /* this is a list, nodes have no children */ - if (parent) - return FALSE; - - /* but if parent == NULL we return the list itself as children of the - * "root" */ - - if (!date_time_list->list) - return FALSE; - - iter->stamp = E_DATE_TIME_LIST (tree_model)->stamp; - iter->user_data = date_time_list->list; - return TRUE; -} - -static gboolean -e_date_time_list_iter_has_child (GtkTreeModel *tree_model, - GtkTreeIter *iter) -{ - g_return_val_if_fail (IS_VALID_ITER (E_DATE_TIME_LIST (tree_model), iter), FALSE); - return FALSE; -} - -static gint -e_date_time_list_iter_n_children (GtkTreeModel *tree_model, - GtkTreeIter *iter) -{ - EDateTimeList *date_time_list = E_DATE_TIME_LIST (tree_model); - - g_return_val_if_fail (E_IS_DATE_TIME_LIST (tree_model), -1); - g_return_val_if_fail (IS_VALID_ITER (date_time_list, iter), -1); - - if (iter == NULL) - return g_list_length (date_time_list->list); - - g_return_val_if_fail (E_DATE_TIME_LIST (tree_model)->stamp == iter->stamp, -1); - return 0; -} - -static gboolean -e_date_time_list_iter_nth_child (GtkTreeModel *tree_model, - GtkTreeIter *iter, - GtkTreeIter *parent, - gint n) -{ - EDateTimeList *date_time_list = E_DATE_TIME_LIST (tree_model); - - g_return_val_if_fail (E_IS_DATE_TIME_LIST (tree_model), FALSE); - - if (parent) - return FALSE; - - if (date_time_list->list) { - GList *l; - - l = g_list_nth (date_time_list->list, n); - if (!l) - return FALSE; - - iter->stamp = date_time_list->stamp; - iter->user_data = l; - return TRUE; - } - - return FALSE; -} - -static gboolean -e_date_time_list_iter_parent (GtkTreeModel *tree_model, - GtkTreeIter *iter, - GtkTreeIter *child) -{ - return FALSE; -} diff --git a/calendar/gui/e-date-time-list.h b/calendar/gui/e-date-time-list.h deleted file mode 100644 index 83b145c7c6..0000000000 --- a/calendar/gui/e-date-time-list.h +++ /dev/null @@ -1,83 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* EDateTimeList - list of calendar dates/times with GtkTreeModel interface. - * - * Copyright (C) 2003 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - * - * Authors: Hans Petter Jansson <hpj@ximian.com> - */ - -#ifndef E_DATE_TIME_LIST_H -#define E_DATE_TIME_LIST_H - -#include <gtk/gtktreemodel.h> -#include <libecal/e-cal-component.h> - -G_BEGIN_DECLS - -#define E_TYPE_DATE_TIME_LIST (e_date_time_list_get_type ()) -#define E_DATE_TIME_LIST(obj) (GTK_CHECK_CAST ((obj), E_TYPE_DATE_TIME_LIST, EDateTimeList)) -#define E_DATE_TIME_LIST_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_DATE_TIME_LIST, EDateTimeListClass)) -#define E_IS_DATE_TIME_LIST(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_DATE_TIME_LIST)) -#define E_IS_DATE_TIME_LIST_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), E_TYPE_DATE_TIME_LIST)) -#define E_DATE_TIME_LIST_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), E_TYPE_DATE_TIME_LIST, EDateTimeListClass)) - -typedef struct _EDateTimeList EDateTimeList; -typedef struct _EDateTimeListClass EDateTimeListClass; - -typedef enum -{ - E_DATE_TIME_LIST_COLUMN_DESCRIPTION, - - E_DATE_TIME_LIST_NUM_COLUMNS -} -EDateTimeListColumnType; - -struct _EDateTimeList -{ - GObject parent; - - /* Private */ - - gint stamp; - GList *list; - - guint columns_dirty : 1; -}; - -struct _EDateTimeListClass -{ - GObjectClass parent_class; -}; - -GtkType e_date_time_list_get_type (void); -EDateTimeList *e_date_time_list_new (void); - -const ECalComponentDateTime *e_date_time_list_get_date_time (EDateTimeList *date_time_list, - GtkTreeIter *iter); -void e_date_time_list_set_date_time (EDateTimeList *date_time_list, - GtkTreeIter *iter, - const ECalComponentDateTime *datetime); -void e_date_time_list_append (EDateTimeList *date_time_list, - GtkTreeIter *iter, - const ECalComponentDateTime *datetime); -void e_date_time_list_remove (EDateTimeList *date_time_list, - GtkTreeIter *iter); -void e_date_time_list_clear (EDateTimeList *date_time_list); - -G_END_DECLS - -#endif /* E_DATE_TIME_LIST_H */ diff --git a/calendar/gui/e-day-view-config.c b/calendar/gui/e-day-view-config.c deleted file mode 100644 index 4c10451f40..0000000000 --- a/calendar/gui/e-day-view-config.c +++ /dev/null @@ -1,475 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Rodrigo Moya <rodrigo@ximian.com> - * - * Copyright 2003, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include "calendar-config.h" -#include "e-day-view-config.h" - -struct _EDayViewConfigPrivate { - EDayView *view; - - GList *notifications; -}; - -static GObjectClass *parent_class = NULL; - -/* Property IDs */ -enum props { - PROP_0, - PROP_VIEW, -}; - -static void -e_day_view_config_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) -{ - EDayViewConfig *view_config; - EDayViewConfigPrivate *priv; - - view_config = E_DAY_VIEW_CONFIG (object); - priv = view_config->priv; - - switch (property_id) { - case PROP_VIEW: - e_day_view_config_set_view (view_config, g_value_get_object (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -e_day_view_config_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) -{ - EDayViewConfig *view_config; - EDayViewConfigPrivate *priv; - - view_config = E_DAY_VIEW_CONFIG (object); - priv = view_config->priv; - - switch (property_id) { - case PROP_VIEW: - g_value_set_object (value, e_day_view_config_get_view (view_config)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -e_day_view_config_dispose (GObject *object) -{ - EDayViewConfig *view_config = E_DAY_VIEW_CONFIG (object); - EDayViewConfigPrivate *priv; - - priv = view_config->priv; - - e_day_view_config_set_view (view_config, NULL); - - if (G_OBJECT_CLASS (parent_class)->dispose) - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -e_day_view_config_finalize (GObject *object) -{ - EDayViewConfig *view_config = E_DAY_VIEW_CONFIG (object); - EDayViewConfigPrivate *priv; - - priv = view_config->priv; - - g_free (priv); - - if (G_OBJECT_CLASS (parent_class)->finalize) - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -e_day_view_config_class_init (EDayViewConfigClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GParamSpec *spec; - - parent_class = g_type_class_peek_parent (klass); - - /* Method override */ - gobject_class->set_property = e_day_view_config_set_property; - gobject_class->get_property = e_day_view_config_get_property; - gobject_class->dispose = e_day_view_config_dispose; - gobject_class->finalize = e_day_view_config_finalize; - - spec = g_param_spec_object ("view", NULL, NULL, e_day_view_get_type (), - G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT); - g_object_class_install_property (gobject_class, PROP_VIEW, spec); -} - -static void -e_day_view_config_init (EDayViewConfig *view_config, EDayViewConfigClass *klass) -{ - view_config->priv = g_new0 (EDayViewConfigPrivate, 1); - -} - -E_MAKE_TYPE (e_day_view_config, "EDayViewConfig", EDayViewConfig, e_day_view_config_class_init, - e_day_view_config_init, G_TYPE_OBJECT); - -EDayViewConfig * -e_day_view_config_new (EDayView *day_view) -{ - EDayViewConfig *view_config; - - view_config = g_object_new (e_day_view_config_get_type (), "view", day_view, NULL); - - return view_config; -} - -EDayView * -e_day_view_config_get_view (EDayViewConfig *view_config) -{ - EDayViewConfigPrivate *priv; - - g_return_val_if_fail (view_config != NULL, NULL); - g_return_val_if_fail (E_IS_DAY_VIEW_CONFIG (view_config), NULL); - - priv = view_config->priv; - - return priv->view; -} - -static void -set_timezone (EDayView *day_view) -{ - char *location; - icaltimezone *zone; - - location = calendar_config_get_timezone (); - zone = icaltimezone_get_builtin_timezone (location); - if (!zone) - zone = icaltimezone_get_utc_timezone (); - - e_calendar_view_set_timezone (E_CALENDAR_VIEW (day_view), zone); - - g_free (location); -} - -static void -timezone_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - EDayViewConfig *view_config = data; - EDayViewConfigPrivate *priv; - - priv = view_config->priv; - - set_timezone (priv->view); -} - -static void -set_week_start (EDayView *day_view) -{ - int week_start_day; - - 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 (day_view, week_start_day); -} - -static void -week_start_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - EDayViewConfig *view_config = data; - EDayViewConfigPrivate *priv; - - priv = view_config->priv; - - set_week_start (priv->view); -} - -static void -set_twentyfour_hour (EDayView *day_view) -{ - gboolean use_24_hour; - - use_24_hour = calendar_config_get_24_hour_format (); - - e_calendar_view_set_use_24_hour_format (E_CALENDAR_VIEW (day_view), use_24_hour); -} - -static void -twentyfour_hour_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - EDayViewConfig *view_config = data; - EDayViewConfigPrivate *priv; - - priv = view_config->priv; - - set_twentyfour_hour (priv->view); -} - -static void -set_working_days (EDayView *day_view) -{ - CalWeekdays working_days; - - working_days = calendar_config_get_working_days (); - - e_day_view_set_working_days (day_view, working_days); -} - -static void -working_days_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - EDayViewConfig *view_config = data; - EDayViewConfigPrivate *priv; - - priv = view_config->priv; - - set_working_days (priv->view); -} - -static void -set_day_start_hour (EDayView *day_view) -{ - int start_hour, start_minute, end_hour, end_minute; - - e_day_view_get_working_day (day_view, &start_hour, &start_minute, &end_hour, &end_minute); - - start_hour = calendar_config_get_day_start_hour (); - - e_day_view_set_working_day (day_view, start_hour, start_minute, end_hour, end_minute); -} - -static void -day_start_hour_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - EDayViewConfig *view_config = data; - EDayViewConfigPrivate *priv; - - priv = view_config->priv; - - set_day_start_hour (priv->view); -} - -static void -set_day_start_minute (EDayView *day_view) -{ - int start_hour, start_minute, end_hour, end_minute; - - e_day_view_get_working_day (day_view, &start_hour, &start_minute, &end_hour, &end_minute); - - start_minute = calendar_config_get_day_start_minute (); - - e_day_view_set_working_day (day_view, start_hour, start_minute, end_hour, end_minute); -} - -static void -day_start_minute_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - EDayViewConfig *view_config = data; - EDayViewConfigPrivate *priv; - - priv = view_config->priv; - - set_day_start_minute (priv->view); -} - -static void -set_day_end_hour (EDayView *day_view) -{ - int start_hour, start_minute, end_hour, end_minute; - - e_day_view_get_working_day (day_view, &start_hour, &start_minute, &end_hour, &end_minute); - - end_hour = calendar_config_get_day_end_hour (); - - e_day_view_set_working_day (day_view, start_hour, start_minute, end_hour, end_minute); -} - -static void -day_end_hour_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - EDayViewConfig *view_config = data; - EDayViewConfigPrivate *priv; - - priv = view_config->priv; - - set_day_end_hour (priv->view); -} - - -static void -set_day_end_minute (EDayView *day_view) -{ - int start_hour, start_minute, end_hour, end_minute; - - e_day_view_get_working_day (day_view, &start_hour, &start_minute, &end_hour, &end_minute); - - end_minute = calendar_config_get_day_end_minute (); - - e_day_view_set_working_day (day_view, start_hour, start_minute, end_hour, end_minute); -} - -static void -day_end_minute_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - EDayViewConfig *view_config = data; - EDayViewConfigPrivate *priv; - - priv = view_config->priv; - - set_day_end_minute (priv->view); -} - -static void -set_time_divisions (EDayView *day_view) -{ - int time_divisions; - - time_divisions = calendar_config_get_time_divisions (); - - e_day_view_set_mins_per_row (day_view, time_divisions); -} - -static void -time_divisions_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - EDayViewConfig *view_config = data; - EDayViewConfigPrivate *priv; - - priv = view_config->priv; - - set_time_divisions (priv->view); -} - -static void -set_show_event_end (EDayView *day_view) -{ - gboolean show_event_end; - - show_event_end = calendar_config_get_show_event_end (); - - e_day_view_set_show_event_end_times (day_view, show_event_end); -} - -static void -show_event_end_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - EDayViewConfig *view_config = data; - EDayViewConfigPrivate *priv; - - priv = view_config->priv; - - set_show_event_end (priv->view); -} - -void -e_day_view_config_set_view (EDayViewConfig *view_config, EDayView *day_view) -{ - EDayViewConfigPrivate *priv; - guint not; - GList *l; - - g_return_if_fail (view_config != NULL); - g_return_if_fail (E_IS_DAY_VIEW_CONFIG (view_config)); - - priv = view_config->priv; - - if (priv->view) { - g_object_unref (priv->view); - priv->view = NULL; - } - - for (l = priv->notifications; l; l = l->next) - calendar_config_remove_notification (GPOINTER_TO_UINT (l->data)); - - g_list_free (priv->notifications); - priv->notifications = NULL; - - /* If the new view is NULL, return right now */ - if (!day_view) - return; - - priv->view = g_object_ref (day_view); - - /* Time zone */ - set_timezone (day_view); - - not = calendar_config_add_notification_timezone (timezone_changed_cb, view_config); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - /* Week start */ - set_week_start (day_view); - - not = calendar_config_add_notification_week_start_day (week_start_changed_cb, view_config); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - /* 24 Hour format */ - set_twentyfour_hour (day_view); - - not = calendar_config_add_notification_24_hour_format (twentyfour_hour_changed_cb, view_config); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - /* Working days */ - set_working_days (day_view); - - not = calendar_config_add_notification_working_days (working_days_changed_cb, view_config); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - /* Day start hour */ - set_day_start_hour (day_view); - - not = calendar_config_add_notification_day_start_hour (day_start_hour_changed_cb, view_config); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - /* Day start minute */ - set_day_start_minute (day_view); - - not = calendar_config_add_notification_day_start_minute (day_start_minute_changed_cb, view_config); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - /* Day end hour */ - set_day_end_hour (day_view); - - not = calendar_config_add_notification_day_end_hour (day_end_hour_changed_cb, view_config); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - /* Day start minute */ - set_day_end_minute (day_view); - - not = calendar_config_add_notification_day_end_minute (day_end_minute_changed_cb, view_config); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - /* Time divisions */ - set_time_divisions (day_view); - - not = calendar_config_add_notification_time_divisions (time_divisions_changed_cb, view_config); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - /* Showing event end */ - set_show_event_end (day_view); - - not = calendar_config_add_notification_show_event_end (show_event_end_changed_cb, view_config); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); -} diff --git a/calendar/gui/e-day-view-config.h b/calendar/gui/e-day-view-config.h deleted file mode 100644 index 105cbb4f07..0000000000 --- a/calendar/gui/e-day-view-config.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Author : - * JP Rosevear <jpr@ximian.com> - * - * Copyright 2003, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef _E_DAY_VIEW_CONFIG_H_ -#define _E_DAY_VIEW_CONFIG_H_ - -#include "e-day-view.h" - -G_BEGIN_DECLS - -#define E_DAY_VIEW_CONFIG(obj) GTK_CHECK_CAST (obj, e_day_view_config_get_type (), EDayViewConfig) -#define E_DAY_VIEW_CONFIG_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, e_day_view_config_get_type (), EDayViewConfigClass) -#define E_IS_DAY_VIEW_CONFIG(obj) GTK_CHECK_TYPE (obj, e_day_view_config_get_type ()) - -typedef struct _EDayViewConfig EDayViewConfig; -typedef struct _EDayViewConfigClass EDayViewConfigClass; -typedef struct _EDayViewConfigPrivate EDayViewConfigPrivate; - -struct _EDayViewConfig { - GObject parent; - - EDayViewConfigPrivate *priv; -}; - -struct _EDayViewConfigClass { - GObjectClass parent_class; -}; - -GType e_day_view_config_get_type (void); -EDayViewConfig *e_day_view_config_new (EDayView *day_view); -EDayView *e_day_view_config_get_view (EDayViewConfig *view_config); -void e_day_view_config_set_view (EDayViewConfig *view_config, EDayView *day_view); - -G_END_DECLS - -#endif 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 2b7787ded4..0000000000 --- a/calendar/gui/e-day-view-main-item.c +++ /dev/null @@ -1,796 +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" -#include "ea-calendar.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 -}; - -E_MAKE_TYPE (e_day_view_main_item, "EDayViewMainItem", EDayViewMainItem, - e_day_view_main_item_class_init, e_day_view_main_item_init, GNOME_TYPE_CANVAS_ITEM); - -static void -e_day_view_main_item_class_init (EDayViewMainItemClass *class) -{ - GtkObjectClass *object_class; - GnomeCanvasItemClass *item_class; - - parent_class = g_type_class_peek_parent (class); - - 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; - - /* init the accessibility support for e_day_view */ - e_day_view_main_item_a11y_init (); -} - - -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; - gint row, row_y, grid_x1, grid_x2; - gint day, grid_y1, grid_y2; - 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_get_style (GTK_WIDGET (day_view)); - - /* Paint the background colors. */ - gc = day_view->main_gc; - work_day_start_y = e_day_view_convert_time_to_position (day_view, day_view->work_day_start_hour, day_view->work_day_start_minute) - y; - work_day_end_y = e_day_view_convert_time_to_position (day_view, day_view->work_day_end_hour, day_view->work_day_end_minute) - y; - - for (day = 0; day < day_view->days_shown; day++) { - day_start_tt = icaltime_from_timet_with_zone (day_view->day_starts[day], FALSE, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - 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 (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; - - if (GTK_WIDGET_HAS_FOCUS(day_view)) - gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_BG_SELECTED]); - else - gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_BG_SELECTED_UNFOCUSSED]); - 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; - ECalComponentTransparency 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++) { - ECalComponent *comp; - - event = &g_array_index (day_view->events[day], EDayViewEvent, - event_num); - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); - - /* If the event is TRANSPARENT, skip it. */ - e_cal_component_get_transparency (comp, &transparency); - if (transparency == E_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); - - g_object_unref (comp); - } -} - - -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; - ECalComponentTransparency 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++) { - ECalComponent *comp; - - event = &g_array_index (day_view->long_events, EDayViewEvent, - event_num); - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); - - /* If the event is TRANSPARENT, skip it. */ - e_cal_component_get_transparency (comp, &transparency); - if (transparency == E_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); - } - } - - - g_object_unref (comp); - } -} - - -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; - GdkColor bg_color; - ECalComponent *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, draw_meeting_icon; - GSList *categories_list, *elem; - ECalComponentTransparency 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; - - /* 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 event 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 (gdk_color_parse (e_cal_model_get_color_for_component (e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)), event->comp_data), - &bg_color)) { - GdkColormap *colormap; - - colormap = gtk_widget_get_colormap (GTK_WIDGET (day_view)); - if (gdk_colormap_alloc_color (colormap, &bg_color, TRUE, TRUE)) - gdk_gc_set_foreground (gc, &bg_color); - } - -#if 1 - if (event->start_row_or_col == 0) - gdk_draw_rectangle (drawable, 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, gc, TRUE, - item_x + 1, item_y + 1, - MAX (item_w - 2, 0), item_h - 2); - - gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR]); - - /* 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_CALENDAR_VIEW_POS_NONE - && day_view->resize_event_day == day - && day_view->resize_event_num == event_num) { - if (day_view->resize_drag_pos == E_CALENDAR_VIEW_POS_TOP_EDGE) - bar_y1 = item_y + 1; - else if (day_view->resize_drag_pos == E_CALENDAR_VIEW_POS_BOTTOM_EDGE) - bar_y2 = item_y + item_h - 1; - } - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); - - /* Only fill it in if the event isn't TRANSPARENT. */ - e_cal_component_get_transparency (comp, &transparency); - if (transparency != E_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; - draw_meeting_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; - - if (e_cal_component_has_alarms (comp)) { - draw_reminder_icon = TRUE; - num_icons++; - } - - if (e_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++; - } - - if (e_cal_component_has_organizer (comp)) { - draw_meeting_icon = TRUE; - num_icons++; - } - - e_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; - if (e_categories_config_get_icon_for (category, &pixmap, &mask)) - num_icons++; - } - - if (num_icons != 0) { - if (item_h >= (E_DAY_VIEW_ICON_HEIGHT + E_DAY_VIEW_ICON_Y_PAD) - * num_icons) { - icon_x_inc = 0; - icon_y_inc = E_DAY_VIEW_ICON_HEIGHT - + E_DAY_VIEW_ICON_Y_PAD; - } else { - icon_x_inc = E_DAY_VIEW_ICON_WIDTH - + E_DAY_VIEW_ICON_X_PAD; - icon_y_inc = 0; - } - - if (draw_reminder_icon) { - max_icon_w = item_x + item_w - icon_x - - E_DAY_VIEW_EVENT_BORDER_WIDTH; - max_icon_h = item_y + item_h - icon_y - - E_DAY_VIEW_EVENT_BORDER_HEIGHT; - - gdk_gc_set_clip_origin (gc, icon_x, icon_y); - gdk_gc_set_clip_mask (gc, day_view->reminder_mask); - gdk_draw_pixmap (drawable, gc, - day_view->reminder_icon, - 0, 0, icon_x, icon_y, - MIN (E_DAY_VIEW_ICON_WIDTH, - max_icon_w), - MIN (E_DAY_VIEW_ICON_HEIGHT, - max_icon_h)); - icon_x += icon_x_inc; - icon_y += icon_y_inc; - } - - if (draw_recurrence_icon) { - max_icon_w = item_x + item_w - icon_x - - E_DAY_VIEW_EVENT_BORDER_WIDTH; - max_icon_h = item_y + item_h - icon_y - - E_DAY_VIEW_EVENT_BORDER_HEIGHT; - - gdk_gc_set_clip_origin (gc, icon_x, icon_y); - gdk_gc_set_clip_mask (gc, day_view->recurrence_mask); - gdk_draw_pixmap (drawable, gc, - day_view->recurrence_icon, - 0, 0, icon_x, icon_y, - MIN (E_DAY_VIEW_ICON_WIDTH, - max_icon_w), - MIN (E_DAY_VIEW_ICON_HEIGHT, - max_icon_h)); - - 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; - } - - - if (draw_meeting_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->meeting_mask); - gdk_draw_pixmap (drawable, gc, - day_view->meeting_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; - if (!e_categories_config_get_icon_for (category, &pixmap, &mask)) - 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 */ - e_cal_component_free_categories_list (categories_list); - g_object_unref (comp); -} - - -/* 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 d70b0fd861..0000000000 --- a/calendar/gui/e-day-view-time-item.c +++ /dev/null @@ -1,671 +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 <string.h> -#include <glib.h> -#include <gtk/gtksignal.h> -#include <gtk/gtkradiomenuitem.h> -#include <gtk/gtkcheckmenuitem.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 -}; - -E_MAKE_TYPE (e_day_view_time_item, "EDayViewTimeItem", EDayViewTimeItem, - e_day_view_time_item_class_init, e_day_view_time_item_init, GNOME_TYPE_CANVAS_ITEM); - -static void -e_day_view_time_item_class_init (EDayViewTimeItemClass *class) -{ - GtkObjectClass *object_class; - GnomeCanvasItemClass *item_class; - - parent_class = g_type_class_peek_parent (class); - - 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; - 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; - PangoContext *context; - - day_view = dvtmitem->day_view; - g_return_val_if_fail (day_view != NULL, 0); - - style = gtk_widget_get_style (GTK_WIDGET (day_view)); - g_return_val_if_fail (style != NULL, 0); - - context = gtk_widget_get_pango_context (GTK_WIDGET (day_view)); - - /* Find the maximum width a digit can have. FIXME: We could use pango's - * approximation function, but I worry it won't be precise enough. Also - * it needs a language tag that I don't know where to get. */ - for (digit = '0'; digit <= '9'; digit++) { - PangoLayout *layout; - gchar digit_str [2]; - - digit_str [0] = digit; - digit_str [1] = '\0'; - - layout = gtk_widget_create_pango_layout (GTK_WIDGET (day_view), digit_str); - pango_layout_set_font_description (layout, day_view->large_font_desc); - pango_layout_get_pixel_size (layout, &large_digit_width, NULL); - g_object_unref (layout); - - 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; - 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; - PangoLayout *layout; - PangoContext *context; - PangoFontDescription *small_font_desc; - PangoFontMetrics *large_font_metrics, *small_font_metrics; - - dvtmitem = E_DAY_VIEW_TIME_ITEM (canvas_item); - day_view = dvtmitem->day_view; - g_return_if_fail (day_view != NULL); - - style = gtk_widget_get_style (GTK_WIDGET (day_view)); - small_font_desc = style->font_desc; - - context = gtk_widget_get_pango_context (GTK_WIDGET (day_view)); - large_font_metrics = pango_context_get_metrics (context, day_view->large_font_desc, - pango_context_get_language (context)); - small_font_metrics = pango_context_get_metrics (context, small_font_desc, - pango_context_get_language (context)); - - 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 = E_DVTMI_LARGE_HOUR_Y_PAD; - - /* The offset of the small time/minute string from top of row. */ - small_font_y_offset = 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, - (pango_font_metrics_get_ascent (large_font_metrics) + - pango_font_metrics_get_descent (large_font_metrics)) / PANGO_SCALE + - E_DVTMI_LARGE_HOUR_Y_PAD); - - /* 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 (e_calendar_view_get_use_24_hour_format (E_CALENDAR_VIEW (day_view))) { - g_snprintf (buffer, sizeof (buffer), "%i:%02i", - display_hour, minute); - } else { - g_snprintf (buffer, sizeof (buffer), "%i %s", - display_hour, suffix); - } - - layout = gtk_widget_create_pango_layout (GTK_WIDGET (day_view), buffer); - pango_layout_get_pixel_size (layout, &minute_width, NULL); - gdk_draw_layout (drawable, fg_gc, - minute_x2 - minute_width, - row_y + small_font_y_offset, - layout); - g_object_unref (layout); - } 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); - - layout = gtk_widget_create_pango_layout (GTK_WIDGET (day_view), buffer); - pango_layout_set_font_description (layout, day_view->large_font_desc); - pango_layout_get_pixel_size (layout, &hour_width, NULL); - gdk_draw_layout (drawable, fg_gc, - large_hour_x2 - hour_width, - row_y + large_hour_y_offset, - layout); - g_object_unref (layout); - } 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 - && !e_calendar_view_get_use_24_hour_format (E_CALENDAR_VIEW (day_view))) { - strcpy (buffer, suffix); - } else { - g_snprintf (buffer, sizeof (buffer), - "%02i", minute); - } - - layout = gtk_widget_create_pango_layout (GTK_WIDGET (day_view), buffer); - pango_layout_get_pixel_size (layout, &minute_width, NULL); - gdk_draw_layout (drawable, fg_gc, - minute_x2 - minute_width, - row_y + small_font_y_offset, - layout); - g_object_unref (layout); - } - } - - e_day_view_time_item_increment_time (&hour, &minute, - day_view->mins_per_row); - } - - pango_font_metrics_unref (large_font_metrics); - pango_font_metrics_unref (small_font_metrics); -} - - -/* 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_selection_done (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); - - g_object_set_data (G_OBJECT (item), "divisions", - GINT_TO_POINTER (divisions[i])); - - g_signal_connect (item, "toggled", - G_CALLBACK (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_get_active (GTK_CHECK_MENU_ITEM (item))) - return; - - divisions = GPOINTER_TO_INT (g_object_get_data (G_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 d2f60d7e7d..0000000000 --- a/calendar/gui/e-day-view-top-item.c +++ /dev/null @@ -1,701 +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-i18n.h> -#include <gal/util/e-util.h> -#include "e-util/e-categories-config.h" -#include <libecal/e-cal-time-util.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 -}; - -E_MAKE_TYPE (e_day_view_top_item, "EDayViewTopItem", EDayViewTopItem, e_day_view_top_item_class_init, - e_day_view_top_item_init, GNOME_TYPE_CANVAS_ITEM); - -static void -e_day_view_top_item_class_init (EDayViewTopItemClass *class) -{ - GtkObjectClass *object_class; - GnomeCanvasItemClass *item_class; - - parent_class = g_type_class_peek_parent (class); - - 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]; - GdkRectangle clip_rect; - gint canvas_width, canvas_height, left_edge, day, date_width, date_x; - gint item_height, event_num; - PangoLayout *layout; - -#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_get_style (GTK_WIDGET (day_view)); - 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++) { - e_day_view_top_item_get_day_label (day_view, day, - buffer, sizeof (buffer)); - 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); - - layout = gtk_widget_create_pango_layout (GTK_WIDGET (day_view), buffer); - pango_layout_get_pixel_size (layout, &date_width, NULL); - date_x = day_view->day_offsets[day] + (day_view->day_widths[day] - date_width) / 2; - - gdk_draw_layout (drawable, fg_gc, - date_x - x, - 3 - y, - layout); - g_object_unref (layout); - - 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; - gint start_day, end_day; - gint item_x, item_y, item_w, item_h; - gint text_x, icon_x, icon_y, icon_x_inc; - ECalComponent *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; - PangoLayout *layout; - GdkColor bg_color; - - 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_get_style (GTK_WIDGET (day_view)); - gc = day_view->main_gc; - fg_gc = style->fg_gc[GTK_STATE_NORMAL]; - bg_gc = style->bg_gc[GTK_STATE_NORMAL]; - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); - - /* 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. */ - if (gdk_color_parse (e_cal_model_get_color_for_component (e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)), - event->comp_data), - &bg_color)) { - GdkColormap *colormap; - - colormap = gtk_widget_get_colormap (GTK_WIDGET (day_view)); - if (gdk_colormap_alloc_color (colormap, &bg_color, TRUE, TRUE)) - gdk_gc_set_foreground (gc, &bg_color); - else - gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_LONG_EVENT_BACKGROUND]); - } else - 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_CALENDAR_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_CALENDAR_VIEW_POS_LEFT_EDGE) - draw_start_triangle = FALSE; - - if (day_view->resize_drag_pos == E_CALENDAR_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 (e_calendar_view_get_use_24_hour_format (E_CALENDAR_VIEW (day_view))) { - 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; - - layout = gtk_widget_create_pango_layout (GTK_WIDGET (day_view), buffer); - gdk_draw_layout (drawable, fg_gc, - time_x, - item_y + E_DAY_VIEW_LONG_EVENT_BORDER_HEIGHT + - E_DAY_VIEW_LONG_EVENT_Y_PAD - y, - layout); - g_object_unref (layout); - - 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 (e_calendar_view_get_use_24_hour_format (E_CALENDAR_VIEW (day_view))) { - 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; - - layout = gtk_widget_create_pango_layout (GTK_WIDGET (day_view), buffer); - gdk_draw_layout (drawable, fg_gc, - time_x, - item_y + E_DAY_VIEW_LONG_EVENT_Y_PAD + 1 - y, - layout); - g_object_unref (layout); - - 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 && e_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 && e_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 */ - e_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); - } - - e_cal_component_free_categories_list (categories_list); - g_object_unref (comp); - - 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; -} - -void -e_day_view_top_item_get_day_label (EDayView *day_view, gint day, - gchar *buffer, gint buffer_len) -{ - struct icaltimetype day_start_tt; - struct tm day_start = { 0 }; - gchar *format; - - day_start_tt = icaltime_from_timet_with_zone (day_view->day_starts[day], - FALSE, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - 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"; - - e_utf8_strftime (buffer, buffer_len, format, &day_start); -} 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 9b8342af99..0000000000 --- a/calendar/gui/e-day-view-top-item.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Damon Chaplin <damon@ximian.com> - * - * Copyright 1999, 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); -void e_day_view_top_item_get_day_label (EDayView *day_view, gint day, - gchar *buffer, gint buffer_len); - - -#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 0c08468a7d..0000000000 --- a/calendar/gui/e-day-view.c +++ /dev/null @@ -1,7229 +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-2003, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -/* - * EDayView - displays the Day & Work-Week views of the calendar. - */ - -#include <config.h> - -#include "e-day-view.h" -#include "ea-calendar.h" - -#include <math.h> -#include <time.h> -#include <gdk/gdkkeysyms.h> -#include <gdk/gdkx.h> -#include <gtk/gtkdnd.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-popup-menu.h> -#include <gal/widgets/e-gui-utils.h> -#include <gal/widgets/e-unicode.h> -#include <gal/util/e-util.h> -#include <libgnomecanvas/gnome-canvas-rect-ellipse.h> -#include <libgnome/gnome-i18n.h> -#include <libgnome/gnome-exec.h> -#include <libgnome/gnome-util.h> -#include <e-util/e-categories-config.h> -#include <e-util/e-dialog-utils.h> - -#include <libecal/e-cal-time-util.h> -#include "dialogs/delete-comp.h" -#include "dialogs/delete-error.h" -#include "dialogs/send-comp.h" -#include "dialogs/cancel-comp.h" -#include "dialogs/recur-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-cal-model-calendar.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" -#include "art/schedule-meeting-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_PTSIZE 18 - -/* 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 - -typedef struct { - EDayView *day_view; - ECalModelComponent *comp_data; -} AddEventData; - -/* Drag and Drop stuff. */ -enum { - TARGET_CALENDAR_EVENT, - TARGET_VCALENDAR -}; -static GtkTargetEntry target_table[] = { - { "application/x-e-calendar-event", 0, TARGET_CALENDAR_EVENT }, - { "text/x-calendar", 0, TARGET_VCALENDAR }, - { "text/calendar", 0, TARGET_VCALENDAR } -}; -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 gboolean e_day_view_key_press (GtkWidget *widget, - GdkEventKey *event); -static gboolean e_day_view_focus (GtkWidget *widget, - GtkDirectionType direction); -static gboolean e_day_view_get_next_tab_event (EDayView *day_view, - GtkDirectionType direction, - gint *day, gint *event_num); -static gboolean e_day_view_get_extreme_long_event (EDayView *day_view, - gboolean first, - gint *day_out, - gint *event_num_out); -static gboolean e_day_view_get_extreme_event (EDayView *day_view, - gint start_day, - gint end_day, - gboolean first, - gint *day_out, - gint *event_num_out); -static gboolean e_day_view_do_key_press (GtkWidget *widget, - GdkEventKey *event); -static gboolean e_day_view_popup_menu (GtkWidget *widget); -static GList *e_day_view_get_selected_events (ECalendarView *cal_view); -static void e_day_view_get_selected_time_range (ECalendarView *cal_view, time_t *start_time, time_t *end_time); -static void e_day_view_set_selected_time_range (ECalendarView *cal_view, time_t start_time, time_t end_time); -static gboolean e_day_view_get_visible_time_range (ECalendarView *cal_view, time_t *start_time, time_t *end_time); -static void e_day_view_update_query (ECalendarView *cal_view); -static void e_day_view_goto_start_of_work_day (EDayView *day_view); -static void e_day_view_goto_end_of_work_day (EDayView *day_view); -static void e_day_view_change_duration_to_start_of_work_day (EDayView *day_view); -static void e_day_view_change_duration_to_end_of_work_day (EDayView *day_view); -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_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_main_canvas_scroll (GtkWidget *widget, - GdkEventScroll *scroll, - EDayView *day_view); - -static gboolean e_day_view_on_time_canvas_scroll (GtkWidget *widget, - GdkEventScroll *scroll, - 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, - ECalendarViewPosition 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, - ECalendarViewPosition pos, - gint event_x, - gint event_y); -static void e_day_view_on_long_event_click (EDayView *day_view, - gint event_num, - GdkEventButton *bevent, - ECalendarViewPosition 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, - ECalendarViewPosition 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_show_popup_menu (EDayView *day_view, - GdkEvent *gdk_event, - 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 ECalendarViewPosition e_day_view_convert_position_in_top_canvas (EDayView *day_view, - gint x, - gint y, - gint *day_return, - gint *event_num_return); -static ECalendarViewPosition 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_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 (ECalComponent *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_change_event_end_time_up (EDayView *day_view); -static void e_day_view_change_event_end_time_down (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 EDayViewEvent* e_day_view_get_popup_menu_event (EDayView *day_view); - -static gboolean 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 gboolean 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 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; - -E_MAKE_TYPE (e_day_view, "EDayView", EDayView, e_day_view_class_init, - e_day_view_init, e_calendar_view_get_type ()); - -static void -e_day_view_class_init (EDayViewClass *class) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - ECalendarViewClass *view_class; - - parent_class = g_type_class_peek_parent (class); - object_class = (GtkObjectClass *) class; - widget_class = (GtkWidgetClass *) class; - view_class = (ECalendarViewClass *) class; - - /* Method override */ - object_class->destroy = e_day_view_destroy; - - widget_class->realize = e_day_view_realize; - widget_class->unrealize = e_day_view_unrealize; - widget_class->style_set = e_day_view_style_set; - widget_class->size_allocate = e_day_view_size_allocate; - widget_class->focus_in_event = e_day_view_focus_in; - widget_class->focus_out_event = e_day_view_focus_out; - widget_class->key_press_event = e_day_view_key_press; - widget_class->focus = e_day_view_focus; - widget_class->popup_menu = e_day_view_popup_menu; - - view_class->get_selected_events = e_day_view_get_selected_events; - view_class->get_selected_time_range = e_day_view_get_selected_time_range; - view_class->set_selected_time_range = e_day_view_set_selected_time_range; - view_class->get_visible_time_range = e_day_view_get_visible_time_range; - view_class->update_query = e_day_view_update_query; - - /* init the accessibility support for e_day_view */ - e_day_view_a11y_init (); -} - -static void -timezone_changed_cb (ECalendarView *cal_view, icaltimezone *old_zone, - icaltimezone *new_zone, gpointer user_data) -{ - struct icaltimetype tt; - time_t lower; - EDayView *day_view = (EDayView *) cal_view; - - g_return_if_fail (E_IS_DAY_VIEW (day_view)); - - /* 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, new_zone); - - e_day_view_recalc_day_starts (day_view, lower); - e_day_view_update_query ((ECalendarView *) day_view); -} - -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->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->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_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_CALENDAR_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->large_font_desc = NULL; - - /* 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); - g_signal_connect_after (day_view->top_canvas, "button_press_event", - G_CALLBACK (e_day_view_on_top_canvas_button_press), day_view); - g_signal_connect (day_view->top_canvas, "button_release_event", - G_CALLBACK (e_day_view_on_top_canvas_button_release), day_view); - g_signal_connect (day_view->top_canvas, "motion_notify_event", - G_CALLBACK (e_day_view_on_top_canvas_motion), day_view); - g_signal_connect (day_view->top_canvas, "drag_motion", - G_CALLBACK (e_day_view_on_top_canvas_drag_motion), day_view); - g_signal_connect (day_view->top_canvas, "drag_leave", - G_CALLBACK (e_day_view_on_top_canvas_drag_leave), day_view); - - g_signal_connect (day_view->top_canvas, "drag_begin", - G_CALLBACK (e_day_view_on_drag_begin), day_view); - g_signal_connect (day_view->top_canvas, "drag_end", - G_CALLBACK (e_day_view_on_drag_end), day_view); - g_signal_connect (day_view->top_canvas, "drag_data_get", - G_CALLBACK (e_day_view_on_drag_data_get), day_view); - g_signal_connect (day_view->top_canvas, "drag_data_received", - G_CALLBACK (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(), - "width_pixels", 1, - 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); - g_signal_connect (day_view->main_canvas, "realize", - G_CALLBACK (e_day_view_on_canvas_realized), day_view); - - g_signal_connect (day_view->main_canvas, - "button_press_event", - G_CALLBACK (e_day_view_on_main_canvas_button_press), - day_view); - g_signal_connect (day_view->main_canvas, - "button_release_event", - G_CALLBACK (e_day_view_on_main_canvas_button_release), - day_view); - g_signal_connect (day_view->main_canvas, - "scroll_event", - G_CALLBACK (e_day_view_on_main_canvas_scroll), - day_view); - g_signal_connect (day_view->main_canvas, - "motion_notify_event", - G_CALLBACK (e_day_view_on_main_canvas_motion), - day_view); - g_signal_connect (day_view->main_canvas, - "drag_motion", - G_CALLBACK (e_day_view_on_main_canvas_drag_motion), - day_view); - g_signal_connect (day_view->main_canvas, - "drag_leave", - G_CALLBACK (e_day_view_on_main_canvas_drag_leave), - day_view); - - g_signal_connect (day_view->main_canvas, "drag_begin", - G_CALLBACK (e_day_view_on_drag_begin), day_view); - g_signal_connect (day_view->main_canvas, "drag_end", - G_CALLBACK (e_day_view_on_drag_end), day_view); - g_signal_connect (day_view->main_canvas, "drag_data_get", - G_CALLBACK (e_day_view_on_drag_data_get), day_view); - g_signal_connect (day_view->main_canvas, "drag_data_received", - G_CALLBACK (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(), - "width_pixels", 1, - 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(), - "width_pixels", 1, - 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); - g_signal_connect_after (day_view->time_canvas, "scroll_event", - G_CALLBACK (e_day_view_on_time_canvas_scroll), 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); - - /* connect to ECalendarView's signals */ - g_signal_connect (G_OBJECT (day_view), "timezone_changed", - G_CALLBACK (timezone_changed_cb), 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; - ECalModel *model; - - model = E_CAL_MODEL (e_cal_model_calendar_new ()); - - day_view = GTK_WIDGET (g_object_new (e_day_view_get_type (), "model", model, NULL)); - - g_object_unref (model); - - 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->query) { - g_signal_handlers_disconnect_matched (day_view->query, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, day_view); - g_object_unref (day_view->query); - day_view->query = NULL; - } - - if (day_view->large_font_desc) { - pango_font_description_free (day_view->large_font_desc); - day_view->large_font_desc = NULL; - } - - if (day_view->normal_cursor) { - gdk_cursor_unref (day_view->normal_cursor); - day_view->normal_cursor = NULL; - } - if (day_view->move_cursor) { - gdk_cursor_unref (day_view->move_cursor); - day_view->move_cursor = NULL; - } - if (day_view->resize_width_cursor) { - gdk_cursor_unref (day_view->resize_width_cursor); - day_view->resize_width_cursor = NULL; - } - if (day_view->resize_height_cursor) { - gdk_cursor_unref (day_view->resize_height_cursor); - day_view->resize_height_cursor = NULL; - } - - if (day_view->long_events) { - 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++) { - if (day_view->events[day]) { - g_array_free (day_view->events[day], TRUE); - day_view->events[day] = 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_SELECTED_UNFOCUSSED].red = 16 * 257; - day_view->colors[E_DAY_VIEW_COLOR_BG_SELECTED_UNFOCUSSED].green = 78 * 257; - day_view->colors[E_DAY_VIEW_COLOR_BG_SELECTED_UNFOCUSSED].blue = 139 * 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); - day_view->meeting_icon = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &day_view->meeting_mask, NULL, schedule_meeting_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; - - day_view = E_DAY_VIEW (widget); - - gdk_gc_unref (day_view->main_gc); - day_view->main_gc = NULL; - - colormap = gtk_widget_get_colormap (widget); - gdk_colormap_free_colors (colormap, day_view->colors, E_DAY_VIEW_COLOR_LAST); - - 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; - 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; - PangoFontDescription *font_desc; - PangoContext *pango_context; - PangoFontMetrics *font_metrics; - PangoLayout *layout; - - if (GTK_WIDGET_CLASS (parent_class)->style_set) - (*GTK_WIDGET_CLASS (parent_class)->style_set)(widget, previous_style); - - day_view = E_DAY_VIEW (widget); - - /* Set up Pango prerequisites */ - font_desc = gtk_widget_get_style (widget)->font_desc; - pango_context = gtk_widget_get_pango_context (widget); - font_metrics = pango_context_get_metrics (pango_context, font_desc, - pango_context_get_language (pango_context)); - layout = pango_layout_new (pango_context); - - /* Create the large font. */ - if (day_view->large_font_desc != NULL) - pango_font_description_free (day_view->large_font_desc); - - day_view->large_font_desc = pango_font_description_copy (font_desc); - pango_font_description_set_size (day_view->large_font_desc, - E_DAY_VIEW_LARGE_FONT_PTSIZE * PANGO_SCALE); - - /* Recalculate the height of each row based on the font size. */ - day_view->row_height = - PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) + - PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics)) + - 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 = - PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) + - PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics)) + - 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; - - e_utf8_strftime (buffer, sizeof (buffer), "%B", &date_tm); - pango_layout_set_text (layout, buffer, -1); - pango_layout_get_pixel_size (layout, &width, NULL); - - if (width > longest_month_width) { - longest_month_width = width; - day_view->longest_month_name = month; - } - - e_utf8_strftime (buffer, sizeof (buffer), "%b", &date_tm); - pango_layout_set_text (layout, buffer, -1); - pango_layout_get_pixel_size (layout, &width, NULL); - - 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; - - e_utf8_strftime (buffer, sizeof (buffer), "%A", &date_tm); - pango_layout_set_text (layout, buffer, -1); - pango_layout_get_pixel_size (layout, &width, NULL); - - if (width > longest_weekday_width) { - longest_weekday_width = width; - day_view->longest_weekday_name = day; - } - - e_utf8_strftime (buffer, sizeof (buffer), "%a", &date_tm); - pango_layout_set_text (layout, buffer, -1); - pango_layout_get_pixel_size (layout, &width, NULL); - - 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); - pango_layout_set_text (layout, buffer, -1); - pango_layout_get_pixel_size (layout, &day_view->small_hour_widths [hour], NULL); - - 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); - pango_layout_set_text (layout, buffer, -1); - pango_layout_get_pixel_size (layout, &minute_width, NULL); - - max_minute_width = MAX (max_minute_width, minute_width); - } - day_view->max_minute_width = max_minute_width; - - pango_layout_set_text (layout, ":", 1); - pango_layout_get_pixel_size (layout, &day_view->colon_width, NULL); - pango_layout_set_text (layout, "0", 1); - pango_layout_get_pixel_size (layout, &day_view->digit_width, NULL); - - pango_layout_set_text (layout, day_view->am_string, -1); - pango_layout_get_pixel_size (layout, &day_view->am_string_width, NULL); - pango_layout_set_text (layout, day_view->pm_string, -1); - pango_layout_get_pixel_size (layout, &day_view->pm_string_width, NULL); - - /* 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); - - g_object_unref (layout); - pango_font_metrics_unref (font_metrics); -} - - -/* 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; - char buffer[128]; - PangoFontDescription *font_desc; - PangoContext *pango_context; - PangoLayout *layout; - gint pango_width; - - g_return_if_fail (((GtkWidget*)day_view)->style != NULL); - - /* Set up Pango prerequisites */ - font_desc = gtk_widget_get_style (GTK_WIDGET (day_view))->font_desc; - pango_context = gtk_widget_get_pango_context (GTK_WIDGET (day_view)); - layout = pango_layout_new (pango_context); - - /* 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. */ - e_utf8_strftime (buffer, sizeof (buffer), _("%A %d %B"), &date_tm); - pango_layout_set_text (layout, buffer, -1); - pango_layout_get_pixel_size (layout, &pango_width, NULL); - - if (pango_width < 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. */ - e_utf8_strftime (buffer, sizeof (buffer), _("%a %d %b"), &date_tm); - pango_layout_set_text (layout, buffer, -1); - pango_layout_get_pixel_size (layout, &pango_width, NULL); - - if (pango_width < 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. */ - e_utf8_strftime (buffer, sizeof (buffer), _("%d %b"), &date_tm); - pango_layout_set_text (layout, buffer, -1); - pango_layout_get_pixel_size (layout, &pango_width, NULL); - - if (pango_width < max_width) - day_view->date_format = E_DAY_VIEW_DATE_NO_WEEKDAY; - else - day_view->date_format = E_DAY_VIEW_DATE_SHORT; - - g_object_unref (layout); -} - - -static gint -e_day_view_focus_in (GtkWidget *widget, GdkEventFocus *event) -{ - EDayView *day_view; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (E_IS_DAY_VIEW (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - day_view = E_DAY_VIEW (widget); - - GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS); - - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); - - return FALSE; -} - - -static gint -e_day_view_focus_out (GtkWidget *widget, GdkEventFocus *event) -{ - EDayView *day_view; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (E_IS_DAY_VIEW (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - day_view = E_DAY_VIEW (widget); - - GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS); - - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); - - return FALSE; -} - -static gboolean -e_day_view_update_event_cb (EDayView *day_view, - gint day, - gint event_num, - gpointer data) -{ - EDayViewEvent *event; - ECalModelComponent *comp_data; - - comp_data = 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); - } - - if (event->allocated_comp_data) - e_cal_model_free_component_data (event->comp_data); - event->comp_data = comp_data; - event->allocated_comp_data = FALSE; - - 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); - } - - g_signal_emit_by_name (G_OBJECT(day_view), - "event_changed", event); - - 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); - - u = icalcomponent_get_uid (event->comp_data->icalcomp); - 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); - - u = icalcomponent_get_uid (event->comp_data->icalcomp); - 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)); - - if (event->allocated_comp_data) { - e_cal_model_free_component_data (event->comp_data); - event->allocated_comp_data = FALSE; - } - - 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; - const gchar *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; - - summary = icalcomponent_get_summary (event->comp_data->icalcomp); - text = summary ? (char *) summary : ""; - - 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 (e_calendar_view_get_use_24_hour_format (E_CALENDAR_VIEW (day_view))) { - 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; - const gchar *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; - - summary = icalcomponent_get_summary (event->comp_data->icalcomp); - gnome_canvas_item_set (event->canvas_item, - "text", summary ? summary : "", - 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. */ -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; - - if (!uid) - return FALSE; - - for (day = 0; day < day_view->days_shown; day++) { - for (event_num = 0; event_num < day_view->events[day]->len; - event_num++) { - event = &g_array_index (day_view->events[day], - EDayViewEvent, event_num); - - u = icalcomponent_get_uid (event->comp_data->icalcomp); - 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); - - u = icalcomponent_get_uid (event->comp_data->icalcomp); - 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. */ -static void -e_day_view_set_selected_time_range (ECalendarView *cal_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; - EDayView *day_view = E_DAY_VIEW (cal_view); - - 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, e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - } else { - lower = e_day_view_find_work_week_start (day_view, start_time); - } - - /* See if we need to change the days shown. */ - if (lower != day_view->lower) { - e_day_view_recalc_day_starts (day_view, lower); - e_day_view_update_query ((ECalendarView *) 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); - } -} - -static void -e_day_view_set_selected_time_range_in_top_visible (EDayView *day_view, - time_t start_time, - time_t end_time) -{ - 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)); - - /* 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 (!start_in_grid) - start_col = 0; - if (!end_in_grid) - end_col = day_view->days_shown - 1; - - if (start_row != day_view->selection_start_row - || start_col != day_view->selection_start_day) { - need_redraw = TRUE; - day_view->selection_in_top_canvas = TRUE; - day_view->selection_start_row = -1; - 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 = TRUE; - day_view->selection_end_row = -1; - 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); - } -} - -static void -e_day_view_set_selected_time_range_visible (EDayView *day_view, - time_t start_time, - time_t end_time) -{ - 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)); - - /* 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; - guint offset; - struct icaltimetype tt = icaltime_null_time (); - - time_to_gdate_with_zone (&date, start_time, e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - - /* 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. */ - if (weekday < day) { - offset = (day - weekday) % 7; - g_date_add_days (&date, offset); - } else { - offset = (weekday - 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, e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); -} - -/* Returns the selected time range. */ -static void -e_day_view_get_selected_time_range (ECalendarView *cal_view, time_t *start_time, time_t *end_time) -{ - gint start_col, start_row, end_col, end_row; - time_t start, end; - EDayView *day_view = E_DAY_VIEW (cal_view); - - 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; -} - -/* Gets the visible time range. Returns FALSE if no time range has been set. */ -static gboolean -e_day_view_get_visible_time_range (ECalendarView *cal_view, - time_t *start_time, - time_t *end_time) -{ - EDayView *day_view = E_DAY_VIEW (cal_view); - - /* 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; -} - -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, e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - } - -#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]; - - e_day_view_update_query (day_view); -} - - -/* Whether we are displaying a work-week, in which case the display always - starts on the first day of the working week. */ -gboolean -e_day_view_get_work_week_view (EDayView *day_view) -{ - g_return_val_if_fail (E_IS_DAY_VIEW (day_view), FALSE); - - return day_view->work_week_view; -} - - -void -e_day_view_set_work_week_view (EDayView *day_view, - gboolean work_week_view) -{ - g_return_if_fail (E_IS_DAY_VIEW (day_view)); - - if (day_view->work_week_view == work_week_view) - return; - - day_view->work_week_view = work_week_view; - - if (day_view->work_week_view) - e_day_view_recalc_work_week (day_view); -} - - -gint -e_day_view_get_days_shown (EDayView *day_view) -{ - g_return_val_if_fail (E_IS_DAY_VIEW (day_view), -1); - - return day_view->days_shown; -} - - -void -e_day_view_set_days_shown (EDayView *day_view, - gint days_shown) -{ - g_return_if_fail (E_IS_DAY_VIEW (day_view)); - g_return_if_fail (days_shown >= 1); - g_return_if_fail (days_shown <= E_DAY_VIEW_MAX_DAYS); - - if (day_view->days_shown == days_shown) - return; - - day_view->days_shown = days_shown; - - /* If the date isn't set, just return. */ - if (day_view->lower == 0 && day_view->upper == 0) - return; - - e_day_view_recalc_day_starts (day_view, day_view->lower); - e_day_view_recalc_cell_sizes (day_view); - - e_day_view_update_query ((ECalendarView *) 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 display event end times in the main canvas. */ -gboolean -e_day_view_get_show_event_end_times (EDayView *day_view) -{ - g_return_val_if_fail (E_IS_DAY_VIEW (day_view), TRUE); - - return day_view->show_event_end_times; -} - - -void -e_day_view_set_show_event_end_times (EDayView *day_view, - gboolean show) -{ - g_return_if_fail (E_IS_DAY_VIEW (day_view)); - - if (day_view->show_event_end_times != show) { - day_view->show_event_end_times = show; - e_day_view_foreach_event (day_view, - e_day_view_set_show_times_cb, NULL); - } -} - -/* This is a callback used to update all day event labels. */ -static gboolean -e_day_view_set_show_times_cb (EDayView *day_view, - gint day, - gint event_num, - gpointer data) -{ - if (day != E_DAY_VIEW_LONG_EVENT) { - e_day_view_update_event_label (day_view, day, event_num); - } - - return TRUE; -} - - -/* The first day of the week, 0 (Monday) to 6 (Sunday). */ -gint -e_day_view_get_week_start_day (EDayView *day_view) -{ - g_return_val_if_fail (E_IS_DAY_VIEW (day_view), 0); - - return day_view->week_start_day; -} - - -void -e_day_view_set_week_start_day (EDayView *day_view, - gint week_start_day) -{ - g_return_if_fail (E_IS_DAY_VIEW (day_view)); - g_return_if_fail (week_start_day >= 0); - g_return_if_fail (week_start_day < 7); - - if (day_view->week_start_day == week_start_day) - return; - - day_view->week_start_day = week_start_day; - - if (day_view->work_week_view) - e_day_view_recalc_work_week (day_view); -} - -static void -e_day_view_recalc_work_week (EDayView *day_view) -{ - time_t lower; - - /* If we aren't showing the work week, just return. */ - if (!day_view->work_week_view) - return; - - e_day_view_recalc_work_week_days_shown (day_view); - - /* If the date isn't set, just return. */ - if (day_view->lower == 0 && day_view->upper == 0) - return; - - lower = e_day_view_find_work_week_start (day_view, day_view->lower); - if (lower != day_view->lower) { - /* Reset the selection, as it may disappear. */ - day_view->selection_start_day = -1; - - e_day_view_recalc_day_starts (day_view, lower); - e_day_view_update_query ((ECalendarView *) 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, day, event_num; - ECalendarViewPosition 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; - - pos = e_day_view_convert_position_in_top_canvas (day_view, - event_x, event_y, - &day, &event_num); - - if (pos == E_CALENDAR_VIEW_POS_OUTSIDE) - return FALSE; - - if (pos != E_CALENDAR_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 ((ECalendarView *) day_view, &dtstart, &dtend); - e_calendar_view_new_appointment_for (E_CALENDAR_VIEW (day_view), - 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)); - - if (day < day_view->selection_start_day || day > day_view->selection_end_day) { - e_day_view_start_selection (day_view, day, -1); - e_day_view_finish_selection (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, row, day, event_num; - ECalendarViewPosition pos; - -#if 0 - g_print ("In e_day_view_on_main_canvas_button_press\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*) event, - GTK_LAYOUT (widget)->bin_window, - &event_x, &event_y)) - return FALSE; - - /* 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_CALENDAR_VIEW_POS_OUTSIDE) - return FALSE; - - if (pos != E_CALENDAR_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 ((ECalendarView *) day_view, &dtstart, &dtend); - e_calendar_view_new_appointment_for (E_CALENDAR_VIEW (day_view), - 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)); - - - if ((day < day_view->selection_start_day || day > day_view->selection_end_day) - || (day == day_view->selection_start_day && row < day_view->selection_start_row) - || (day == day_view->selection_end_day && row > day_view->selection_end_row)) { - e_day_view_start_selection (day_view, day, row); - e_day_view_finish_selection (day_view); - } - - e_day_view_on_event_right_click (day_view, event, -1, -1); - } - - return TRUE; -} - -static gboolean -e_day_view_on_main_canvas_scroll (GtkWidget *widget, - GdkEventScroll *scroll, - EDayView *day_view) -{ - switch (scroll->direction) { - case GDK_SCROLL_UP: - e_day_view_scroll (day_view, E_DAY_VIEW_WHEEL_MOUSE_STEP_SIZE); - return TRUE; - case GDK_SCROLL_DOWN: - e_day_view_scroll (day_view, -E_DAY_VIEW_WHEEL_MOUSE_STEP_SIZE); - return TRUE; - default: - break; - } - - return FALSE; -} - - -static gboolean -e_day_view_on_time_canvas_scroll (GtkWidget *widget, - GdkEventScroll *scroll, - EDayView *day_view) -{ - - switch (scroll->direction) { - case GDK_SCROLL_UP: - e_day_view_scroll (day_view, E_DAY_VIEW_WHEEL_MOUSE_STEP_SIZE); - return TRUE; - case GDK_SCROLL_DOWN: - e_day_view_scroll (day_view, -E_DAY_VIEW_WHEEL_MOUSE_STEP_SIZE); - return TRUE; - default: - break; - } - - return FALSE; -} - -static gboolean -e_day_view_on_long_event_button_press (EDayView *day_view, - gint event_num, - GdkEventButton *event, - ECalendarViewPosition 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; - - e = &g_array_index (day_view->long_events, EDayViewEvent, event_num); - - if (!GTK_WIDGET_HAS_FOCUS (day_view)) - gtk_widget_grab_focus (GTK_WIDGET (day_view)); - - e_day_view_set_selected_time_range_in_top_visible (day_view, e->start, e->end); - - 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, - ECalendarViewPosition 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; - - e = &g_array_index (day_view->events[day], EDayViewEvent, event_num); - - if (!GTK_WIDGET_HAS_FOCUS (day_view)) - gtk_widget_grab_focus (GTK_WIDGET (day_view)); - - e_day_view_set_selected_time_range_visible (day_view, e->start, e->end); - - 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, - ECalendarViewPosition 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_CALENDAR_VIEW_POS_EVENT - && E_TEXT (event->canvas_item)->editing) - return; - - if ((e_cal_util_component_is_instance (event->comp_data->icalcomp) || - !e_cal_util_component_has_recurrences (event->comp_data->icalcomp)) - && (pos == E_CALENDAR_VIEW_POS_LEFT_EDGE - || pos == E_CALENDAR_VIEW_POS_RIGHT_EDGE)) { - if (!e_day_view_find_long_event_days (event, - day_view->days_shown, - day_view->day_starts, - &start_day, &end_day)) - return; - - /* Grab the keyboard focus, so the event being edited is saved - and we can use the Escape key to abort the resize. */ - if (!GTK_WIDGET_HAS_FOCUS (day_view)) - gtk_widget_grab_focus (GTK_WIDGET (day_view)); - - if (gdk_pointer_grab (GTK_LAYOUT (day_view->top_canvas)->bin_window, FALSE, - GDK_POINTER_MOTION_MASK - | GDK_BUTTON_RELEASE_MASK, - FALSE, NULL, bevent->time) == 0) { - - day_view->resize_event_day = E_DAY_VIEW_LONG_EVENT; - day_view->resize_event_num = event_num; - day_view->resize_drag_pos = pos; - day_view->resize_start_row = start_day; - day_view->resize_end_row = end_day; - - /* Create the edit rect if necessary. */ - e_day_view_reshape_resize_long_event_rect_item (day_view); - - /* Make sure the text item is on top. */ - gnome_canvas_item_raise_to_top (day_view->resize_long_event_rect_item); - - /* Raise the event's item, above the rect as well. */ - gnome_canvas_item_raise_to_top (event->canvas_item); - } - } else if (e_day_view_get_long_event_position (day_view, event_num, - &start_day, &end_day, - &item_x, &item_y, - &item_w, &item_h)) { - /* Remember the item clicked and the mouse position, - so we can start a drag if the mouse moves. */ - day_view->pressed_event_day = E_DAY_VIEW_LONG_EVENT; - day_view->pressed_event_num = event_num; - - day_view->drag_event_x = event_x; - day_view->drag_event_y = event_y; - - e_day_view_convert_position_in_top_canvas (day_view, - event_x, event_y, - &day, NULL); - day_view->drag_event_offset = day - start_day; - } -} - - -static void -e_day_view_on_event_click (EDayView *day_view, - gint day, - gint event_num, - GdkEventButton *bevent, - ECalendarViewPosition 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_CALENDAR_VIEW_POS_EVENT - && E_TEXT (event->canvas_item)->editing) - return; - - if ((e_cal_util_component_is_instance (event->comp_data->icalcomp) || - !e_cal_util_component_has_recurrences (event->comp_data->icalcomp)) - && (pos == E_CALENDAR_VIEW_POS_TOP_EDGE - || pos == E_CALENDAR_VIEW_POS_BOTTOM_EDGE)) { - /* Grab the keyboard focus, so the event being edited is saved - and we can use the Escape key to abort the resize. */ - if (!GTK_WIDGET_HAS_FOCUS (day_view)) - gtk_widget_grab_focus (GTK_WIDGET (day_view)); - - if (gdk_pointer_grab (GTK_LAYOUT (day_view->main_canvas)->bin_window, FALSE, - GDK_POINTER_MOTION_MASK - | GDK_BUTTON_RELEASE_MASK, - FALSE, NULL, bevent->time) == 0) { - - day_view->resize_event_day = day; - day_view->resize_event_num = event_num; - day_view->resize_drag_pos = pos; - day_view->resize_start_row = event->start_minute / day_view->mins_per_row; - day_view->resize_end_row = (event->end_minute - 1) / day_view->mins_per_row; - 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_CALENDAR_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_CALENDAR_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; - - 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); - - e_day_view_stop_editing_event (day_view); - - e_calendar_view_edit_appointment (E_CALENDAR_VIEW (day_view), - event->comp_data->client, - event->comp_data->icalcomp, FALSE); -} - -static void -e_day_view_show_popup_menu (EDayView *day_view, - GdkEvent *gdk_event, - gint day, - gint event_num) -{ - GtkMenu *popup; - - day_view->popup_event_day = day; - day_view->popup_event_num = event_num; - - popup = e_calendar_view_create_popup_menu (E_CALENDAR_VIEW (day_view)); - e_popup_menu (popup, gdk_event); -} - -static gboolean -e_day_view_popup_menu (GtkWidget *widget) -{ - EDayView *day_view = E_DAY_VIEW (widget); - e_day_view_show_popup_menu (day_view, NULL, - day_view->editing_event_day, - day_view->editing_event_num); - return TRUE; -} - -/* Returns the currently-selected event, or NULL if none */ -static GList * -e_day_view_get_selected_events (ECalendarView *cal_view) -{ - EDayViewEvent *event = NULL; - GList *list = NULL; - EDayView *day_view = (EDayView *) cal_view; - - g_return_val_if_fail (E_IS_DAY_VIEW (day_view), NULL); - - if (day_view->editing_event_num != -1) { - 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); - } else if (day_view->popup_event_num != -1) { - if (day_view->popup_event_day == E_DAY_VIEW_LONG_EVENT) - event = &g_array_index (day_view->long_events, - EDayViewEvent, - day_view->popup_event_num); - else - event = &g_array_index (day_view->events[day_view->popup_event_day], - EDayViewEvent, - day_view->popup_event_num); - } - - if (event) - list = g_list_append (list, event); - - return list; -} - -static void -process_component (EDayView *day_view, ECalModelComponent *comp_data) -{ - EDayViewEvent *event; - gint day, event_num; - const char *uid; - ECalComponent *comp; - AddEventData add_event_data; - - /* If our time hasn't been set yet, just return. */ - if (day_view->lower == 0 && day_view->upper == 0) - 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. */ - uid = icalcomponent_get_uid (comp_data->icalcomp); - - 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 (!e_cal_util_component_has_recurrences (comp_data->icalcomp) - && e_cal_util_event_dates_match (event->comp_data->icalcomp, comp_data->icalcomp)) { -#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_data); - 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 */ - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp)); - - add_event_data.day_view = day_view; - add_event_data.comp_data = comp_data; - e_cal_recur_generate_instances (comp, day_view->lower, - day_view->upper, - e_day_view_add_event, &add_event_data, - e_cal_resolve_tzid_cb, comp_data->client, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - - g_object_unref (comp); - - e_day_view_queue_layout (day_view); -} - -/* Restarts a query for the day view */ -static void -e_day_view_update_query (ECalendarView *cal_view) -{ - gint rows, r; - EDayView *day_view = E_DAY_VIEW (cal_view); - - 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); - - rows = e_table_model_row_count (E_TABLE_MODEL (e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)))); - for (r = 0; r < rows; r++) { - ECalModelComponent *comp_data; - - comp_data = e_cal_model_get_component_at (e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)), r); - g_assert (comp_data != NULL); - process_component (day_view, comp_data); - } -} - -static void -e_day_view_on_event_right_click (EDayView *day_view, - GdkEventButton *bevent, - gint day, - gint event_num) -{ - e_day_view_show_popup_menu (day_view, (GdkEvent*)bevent, - day, event_num); -} - -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_CALENDAR_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_CALENDAR_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; -} - - -void -e_day_view_update_calendar_selection_time (EDayView *day_view) -{ - time_t start, end; - GnomeCalendar *calendar; - - e_day_view_get_selected_time_range ((ECalendarView *) day_view, &start, &end); - -#if 0 - g_print ("Start: %s", ctime (&start)); - g_print ("End : %s", ctime (&end)); -#endif - - calendar = e_calendar_view_get_calendar (E_CALENDAR_VIEW (day_view)); - if (calendar) - gnome_calendar_set_selected_time_range (calendar, - start, end); -} - - -static gboolean -e_day_view_on_top_canvas_motion (GtkWidget *widget, - GdkEventMotion *mevent, - EDayView *day_view) -{ - EDayViewEvent *event = NULL; - ECalendarViewPosition pos; - gint event_x, event_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; - - canvas_x = event_x; - canvas_y = event_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_CALENDAR_VIEW_POS_NONE) { - if (pos != E_CALENDAR_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 ((e_cal_util_component_is_instance (event->comp_data->icalcomp) || - !e_cal_util_component_has_recurrences (event->comp_data->icalcomp)) - && (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 && (e_cal_util_component_is_instance (event->comp_data->icalcomp) || - !e_cal_util_component_has_recurrences (event->comp_data->icalcomp))) { - switch (pos) { - case E_CALENDAR_VIEW_POS_LEFT_EDGE: - case E_CALENDAR_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; - ECalendarViewPosition pos; - gint event_x, event_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; - - canvas_x = event_x; - canvas_y = event_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_CALENDAR_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_CALENDAR_VIEW_POS_NONE) { - if (pos != E_CALENDAR_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 ((e_cal_util_component_is_instance (event->comp_data->icalcomp) || - !e_cal_util_component_has_recurrences (event->comp_data->icalcomp)) - && (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 && (e_cal_util_component_is_instance (event->comp_data->icalcomp) || - !e_cal_util_component_has_recurrences (event->comp_data->icalcomp))) { - switch (pos) { - case E_CALENDAR_VIEW_POS_LEFT_EDGE: - cursor = day_view->move_cursor; - break; - case E_CALENDAR_VIEW_POS_TOP_EDGE: - case E_CALENDAR_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_CALENDAR_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_CALENDAR_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; - ECalComponent *comp; - ECalComponentDateTime date; - struct icaltimetype itt; - time_t dt; - ECal *client; - CalObjModType mod = CALOBJ_MOD_ALL; - GtkWindow *toplevel; - - event_num = day_view->resize_event_num; - event = &g_array_index (day_view->long_events, EDayViewEvent, - event_num); - - client = event->comp_data->client; - - /* 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 = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); - - date.value = &itt; - /* FIXME: Should probably keep the timezone of the original start - and end times. */ - date.tzid = icaltimezone_get_tzid (e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - - if (day_view->resize_drag_pos == E_CALENDAR_VIEW_POS_LEFT_EDGE) { - dt = day_view->day_starts[day_view->resize_start_row]; - *date.value = icaltime_from_timet_with_zone (dt, FALSE, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - e_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, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - e_cal_component_set_dtend (comp, &date); - } - - if (e_cal_component_has_recurrences (comp)) { - if (!recur_component_dialog (client, comp, &mod, NULL)) { - gtk_widget_queue_draw (day_view->top_canvas); - goto out; - } - } - - toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (day_view))); - - if (e_cal_modify_object (client, e_cal_component_get_icalcomponent (comp), mod, NULL)) { - if (itip_organizer_is_user (comp, client) && - send_component_dialog (toplevel, client, comp, TRUE)) { - itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, client, NULL); - } else { - g_message (G_STRLOC ": Could not update the object!"); - } - } - - out: - gnome_canvas_item_hide (day_view->resize_long_event_rect_item); - - day_view->resize_drag_pos = E_CALENDAR_VIEW_POS_NONE; - - g_object_unref (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; - ECalComponent *comp; - ECalComponentDateTime date; - struct icaltimetype itt; - time_t dt; - ECal *client; - CalObjModType mod = CALOBJ_MOD_ALL; - GtkWindow *toplevel; - - day = day_view->resize_event_day; - event_num = day_view->resize_event_num; - event = &g_array_index (day_view->events[day], EDayViewEvent, - event_num); - - client = event->comp_data->client; - - /* 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 = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); - - date.value = &itt; - /* FIXME: Should probably keep the timezone of the original start - and end times. */ - date.tzid = icaltimezone_get_tzid (e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - - if (day_view->resize_drag_pos == E_CALENDAR_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, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - e_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, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - e_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_CALENDAR_VIEW_POS_NONE; - - if (e_cal_component_has_recurrences (comp)) { - if (!recur_component_dialog (client, comp, &mod, NULL)) { - gtk_widget_queue_draw (day_view->top_canvas); - goto out; - } - } - - toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (day_view))); - - e_cal_component_commit_sequence (comp); - if (e_cal_modify_object (client, e_cal_component_get_icalcomponent (comp), mod, NULL)) { - if (itip_organizer_is_user (comp, client) && - send_component_dialog (toplevel, client, comp, TRUE)) { - itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, client, NULL); - } else { - g_message (G_STRLOC ": Could not update the object!"); - } - } - - out: - g_object_unref (comp); -} - - -static void -e_day_view_abort_resize (EDayView *day_view, - guint32 time) -{ - gint day, event_num; - - if (day_view->resize_drag_pos == E_CALENDAR_VIEW_POS_NONE) - return; - - day_view->resize_drag_pos = E_CALENDAR_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)); - - if (event->allocated_comp_data) { - e_cal_model_free_component_data (event->comp_data); - event->allocated_comp_data = FALSE; - } - } - - 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 (ECalComponent *comp, - time_t start, - time_t end, - gpointer data) - -{ - EDayViewEvent event; - gint day, offset; - struct icaltimetype start_tt, end_tt; - AddEventData *add_event_data; - - add_event_data = data; - -#if 0 - g_print ("Day view lower: %s", ctime (&add_event_data->day_view->lower)); - g_print ("Day view upper: %s", ctime (&add_event_data->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 < add_event_data->day_view->upper, TRUE); - g_return_val_if_fail (end > add_event_data->day_view->lower, TRUE); - - start_tt = icaltime_from_timet_with_zone (start, FALSE, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (add_event_data->day_view))); - end_tt = icaltime_from_timet_with_zone (end, FALSE, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (add_event_data->day_view))); - - if (add_event_data->comp_data) { - event.comp_data = add_event_data->comp_data; - event.allocated_comp_data = FALSE; - } else { - event.comp_data = g_new0 (ECalModelComponent, 1); - event.allocated_comp_data = TRUE; - - event.comp_data->client = e_cal_model_get_default_client (e_calendar_view_get_model (E_CALENDAR_VIEW (add_event_data->day_view))); - e_cal_component_commit_sequence (comp); - event.comp_data->icalcomp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (comp)); - } - - event.start = start; - event.end = end; - event.canvas_item = NULL; - - /* Calculate the start & end minute, relative to the top of the - display. */ - offset = add_event_data->day_view->first_hour_shown * 60 - + add_event_data->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, - event.comp_data->client, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (add_event_data->day_view)))) - event.different_timezone = TRUE; - - /* Find out which array to add the event to. */ - for (day = 0; day < add_event_data->day_view->days_shown; day++) { - if (start >= add_event_data->day_view->day_starts[day] - && end <= add_event_data->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 == add_event_data->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 == add_event_data->day_view->day_starts[day]) - break; - - event.end_minute = 24 * 60; - } - - g_array_append_val (add_event_data->day_view->events[day], event); - add_event_data->day_view->events_sorted[day] = FALSE; - add_event_data->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 (add_event_data->day_view->long_events, event); - add_event_data->day_view->long_events_sorted = FALSE; - add_event_data->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; - 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; - ECalComponent *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; - PangoFontDescription *font_desc; - PangoContext *pango_context; - PangoLayout *layout; - - 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 = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); - - /* Set up Pango prerequisites */ - font_desc = gtk_widget_get_style (GTK_WIDGET (day_view))->font_desc; - pango_context = gtk_widget_get_pango_context (GTK_WIDGET (day_view)); - layout = pango_layout_new (pango_context); - - if (day_view->resize_drag_pos != E_CALENDAR_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, *elem; - - if (e_cal_component_has_alarms (comp)) - num_icons++; - if (e_cal_component_has_recurrences (comp)) - num_icons++; - if (event->different_timezone) - num_icons++; - if (e_cal_component_has_organizer (comp)) - num_icons++; - - e_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; - if (e_categories_config_get_icon_for (category, &pixmap, &mask)) - num_icons++; - } - e_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 (), - "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), - "im_context", E_CANVAS (day_view->top_canvas)->im_context, - NULL); - g_signal_connect (event->canvas_item, "event", - G_CALLBACK (e_day_view_on_text_item_event), day_view); - g_signal_emit_by_name (G_OBJECT(day_view), - "event_added", event); - - 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. */ - g_object_get (G_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); - pango_layout_set_text (layout, text, line_len); - pango_layout_get_pixel_size (layout, &text_width, NULL); - 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); - - g_object_unref (layout); -} - - -/* 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); - if (event_num == day_view->resize_event_num) { - EDayViewEvent *event; - event = &g_array_index (day_view->events[day], EDayViewEvent, - event_num); - e_canvas_item_grab_focus (event->canvas_item, TRUE); - } - } -} - - -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; - - event = &g_array_index (day_view->events[day], EDayViewEvent, - event_num); - - 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_CALENDAR_VIEW_POS_NONE - || day_view->resize_event_day != day - || day_view->resize_event_num != event_num) { - GSList *categories_list, *elem; - ECalComponent *comp; - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); - - if (e_cal_component_has_alarms (comp)) - num_icons++; - if (e_cal_component_has_recurrences (comp)) - num_icons++; - if (event->different_timezone) - num_icons++; - if (e_cal_component_has_organizer (comp)) - num_icons++; - - e_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; - if (e_categories_config_get_icon_for (category, &pixmap, &mask)) - num_icons++; - } - e_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 (), - "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), - "im_context", E_CANVAS (day_view->main_canvas)->im_context, - NULL); - g_signal_connect (event->canvas_item, "event", - G_CALLBACK (e_day_view_on_text_item_event), day_view); - g_signal_emit_by_name (G_OBJECT(day_view), - "event_added", event); - - 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) { - g_object_get (G_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 gboolean -e_day_view_do_key_press (GtkWidget *widget, GdkEventKey *event) -{ - EDayView *day_view; - icalcomponent *icalcomp; - ECalComponent *comp; - gint day, event_num; - gchar *initial_text; - guint keyval; - gboolean stop_emission; - time_t dtstart, dtend; - ECalComponentDateTime start_dt, end_dt; - struct icaltimetype start_tt, end_tt; - const char *uid; - AddEventData add_event_data; - - 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_CALENDAR_VIEW_POS_NONE) { - if (keyval == GDK_Escape) { - e_day_view_abort_resize (day_view, event->time); - } - return FALSE; - } - - /*Go to the start/end of a work day*/ - if ((keyval == GDK_Home) - &&((event->state & GDK_SHIFT_MASK) != GDK_SHIFT_MASK) - &&((event->state & GDK_CONTROL_MASK) != GDK_CONTROL_MASK) - &&((event->state & GDK_MOD1_MASK) != GDK_MOD1_MASK)) { - e_day_view_goto_start_of_work_day (day_view); - return TRUE; - } - if ((keyval == GDK_End) - &&((event->state & GDK_SHIFT_MASK) != GDK_SHIFT_MASK) - &&((event->state & GDK_CONTROL_MASK) != GDK_CONTROL_MASK) - &&((event->state & GDK_MOD1_MASK) != GDK_MOD1_MASK)) { - e_day_view_goto_end_of_work_day (day_view); - return TRUE; - } - - /* In DayView, Shift+Home/End, Change the duration to the time that begins/ends the current work day */ - if ((keyval == GDK_Home) - &&((event->state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK) - &&((event->state & GDK_CONTROL_MASK) != GDK_CONTROL_MASK) - &&((event->state & GDK_MOD1_MASK) != GDK_MOD1_MASK)) { - e_day_view_change_duration_to_start_of_work_day (day_view); - return TRUE; - } - if ((keyval == GDK_End) - &&((event->state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK) - &&((event->state & GDK_CONTROL_MASK) != GDK_CONTROL_MASK) - &&((event->state & GDK_MOD1_MASK) != GDK_MOD1_MASK)) { - e_day_view_change_duration_to_end_of_work_day (day_view); - return TRUE; - } - - - /* 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 if (!(event->state & GDK_MOD1_MASK)) { - 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; - } - } - else - stop_emission = FALSE; - 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 */ - - icalcomp = e_cal_model_create_component_with_defaults (e_calendar_view_get_model (E_CALENDAR_VIEW (day_view))); - if (!icalcomp) - return FALSE; - uid = icalcomponent_get_uid (icalcomp); - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomp); - - e_day_view_get_selected_time_range ((ECalendarView *) day_view, &dtstart, &dtend); - - start_tt = icaltime_from_timet_with_zone (dtstart, FALSE, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - - end_tt = icaltime_from_timet_with_zone (dtend, FALSE, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - - 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 (e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - } - - start_dt.value = &start_tt; - end_dt.value = &end_tt; - end_dt.tzid = start_dt.tzid; - e_cal_component_set_dtstart (comp, &start_dt); - e_cal_component_set_dtend (comp, &end_dt); - - e_cal_component_set_categories ( - comp, e_calendar_view_get_default_category (E_CALENDAR_VIEW (day_view))); - - /* We add the event locally and start editing it. We don't send it - to the server until the user finishes editing it. */ - add_event_data.day_view = day_view; - add_event_data.comp_data = NULL; - e_day_view_add_event (comp, dtstart, dtend, &add_event_data); - e_day_view_check_layout (day_view); - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); - - 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); - - g_object_unref (comp); - - return TRUE; -} - -static gboolean -e_day_view_key_press (GtkWidget *widget, GdkEventKey *event) -{ - gboolean handled = FALSE; - handled = e_day_view_do_key_press (widget, event); - - /* if not handled, try key bindings */ - if (!handled) - handled = GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event); - return handled; -} - -/* Select the time that begins a work day*/ -static void -e_day_view_goto_start_of_work_day (EDayView *day_view) -{ - g_return_if_fail(day_view!=NULL); - - if (day_view->selection_in_top_canvas) - return; - else - day_view->selection_start_row = - e_day_view_convert_time_to_row (day_view, - day_view->work_day_start_hour, - day_view->work_day_start_minute); - day_view->selection_end_row = day_view->selection_start_row; - - 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); - - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); -} - - -/* Select the time that ends a work day*/ -static void -e_day_view_goto_end_of_work_day (EDayView *day_view) -{ - if (day_view->selection_in_top_canvas) - return; - else - day_view->selection_start_row = - e_day_view_convert_time_to_row (day_view, - day_view->work_day_end_hour-1, - day_view->work_day_end_minute+30); - day_view->selection_end_row = day_view->selection_start_row; - - 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); - - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); -} - -/* Change the duration to the time that begins the current work day */ -static void -e_day_view_change_duration_to_start_of_work_day (EDayView *day_view) -{ - g_return_if_fail(day_view != NULL); - - if (day_view->selection_in_top_canvas) - return; - else { - gint work_start_row,work_end_row,selection_start_row,selection_end_row; - - work_start_row = - e_day_view_convert_time_to_row (day_view, - day_view->work_day_start_hour, - day_view->work_day_start_minute); - work_end_row = - e_day_view_convert_time_to_row (day_view, - day_view->work_day_end_hour - 1, - day_view->work_day_end_minute + 30); - selection_start_row = day_view->selection_start_row; - selection_end_row = day_view->selection_end_row; - if (selection_start_row < work_start_row) - day_view->selection_end_row = work_start_row - 1; - else day_view->selection_start_row = work_start_row; - } - - 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); - - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); -} - -/* Change the duration to the time that ends the current work day */ -static void -e_day_view_change_duration_to_end_of_work_day (EDayView *day_view) -{ - g_return_if_fail(day_view != NULL); - - if (day_view->selection_in_top_canvas) - return; - else { - gint work_start_row,work_end_row,selection_start_row,selection_end_row; - work_start_row = - e_day_view_convert_time_to_row (day_view, - day_view->work_day_start_hour, - day_view->work_day_start_minute); - work_end_row = e_day_view_convert_time_to_row (day_view, - day_view->work_day_end_hour-1, - day_view->work_day_end_minute+30); - selection_start_row = day_view->selection_start_row; - selection_end_row = day_view->selection_end_row; - if (selection_start_row <= work_end_row) - day_view->selection_end_row = work_end_row; - else { - day_view->selection_start_row = work_end_row + 1; - day_view->selection_end_row = selection_start_row; - } - } - - 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); - - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); -} - - -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 gboolean -e_day_view_focus (GtkWidget *widget, GtkDirectionType direction) -{ - EDayView *day_view; - gint new_day; - gint new_event_num; - gint start_row, end_row; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (E_IS_DAY_VIEW (widget), FALSE); - day_view = E_DAY_VIEW (widget); - - if (!e_day_view_get_next_tab_event (day_view, direction, - &new_day, &new_event_num)) - return FALSE; - - if ((new_day == -1) && (new_event_num == -1)) { - /* focus should go to the day view widget itself - */ - gtk_widget_grab_focus (GTK_WIDGET(day_view)); - return TRUE; - } - - if (new_day != E_DAY_VIEW_LONG_EVENT && new_day != -1) { - if (e_day_view_get_event_rows (day_view, new_day, - new_event_num, - &start_row, &end_row)) - /* ensure the event to be seen */ - e_day_view_ensure_rows_visible (day_view, - start_row, end_row); - } - e_day_view_start_editing_event (day_view, new_day, - new_event_num, NULL); - - return TRUE; -} - -/** - * e_day_view_get_extreme_event - * @day_view: the day view widget operates on - * @start_day, @end_day: range of search, both inclusive - * @first: %TURE indicate to return the data for the first event in the range, - * %FALSE to return data for the last event in the range. - * @day_out: out value, day of the event found. -1 for no event found. - * @event_num_out: out value, event number of the event found. - * -1 for no event found. - * - * Get day and event_num value for the first or last event found in the day range. - * - * Return value: %TRUE, if a event found. - **/ -static gboolean -e_day_view_get_extreme_event (EDayView *day_view, gint start_day, - gint end_day, gboolean first, - gint *day_out, gint *event_num_out) -{ - gint loop_day; - - g_return_val_if_fail (day_view != NULL, FALSE); - g_return_val_if_fail (start_day >= 0, FALSE); - g_return_val_if_fail (end_day <= E_DAY_VIEW_LONG_EVENT, FALSE); - g_return_val_if_fail (day_out && event_num_out, FALSE); - - if (start_day > end_day) - return FALSE; - if (first) { - for (loop_day = start_day; loop_day <= end_day; ++loop_day) - if (day_view->events[loop_day]->len > 0) { - *day_out = loop_day; - *event_num_out = 0; - return TRUE; - } - } - else { - for (loop_day = end_day; loop_day >= start_day; --loop_day) - if (day_view->events[loop_day]->len > 0) { - *day_out = loop_day; - *event_num_out = - day_view->events[loop_day]->len - 1; - return TRUE; - } - } - *day_out = -1; - *event_num_out = -1; - return FALSE; -} - -/** - * e_day_view_get_extreme_long_event - * @day_view: the day view widget operates on - * @first: %TURE indicate to return the data for the first event in the range, - * %FALSE to return data for the last event in the range. - * @event_num_out: out value, event number of the event found. - * -1 for no event found. - * - * Similar to e_day_view_get_extreme_event, but run for long events. - * - * Return value: %TRUE, if a event found. - **/ -static gboolean -e_day_view_get_extreme_long_event (EDayView *day_view, gboolean first, - gint *day_out, gint *event_num_out) -{ - g_return_val_if_fail (day_view != NULL, FALSE); - g_return_val_if_fail (day_out && event_num_out, FALSE); - - if (first && (day_view->long_events->len > 0)) { - *day_out = E_DAY_VIEW_LONG_EVENT; - *event_num_out = 0; - return TRUE; - } - if ((!first) && (day_view->long_events->len > 0)) { - *day_out = E_DAY_VIEW_LONG_EVENT; - *event_num_out = day_view->long_events->len - 1; - return TRUE; - } - *day_out = -1; - *event_num_out = -1; - return FALSE; -} - -/** - * e_day_view_get_next_tab_event - * @day_view: the day view widget operates on - * @direction: GTK_DIR_TAB_BACKWARD or GTK_DIR_TAB_FORWARD - * @day_out: out value, day of the event found. -1 for no event found. - * @event_num_out: out value, event number of the event found. - * -1 for no event found. - * - * Decide on which event the focus should go next. - * if ((day_out == -1) && (event_num_out == -1)) is true, focus should go - * to day_view widget itself. - * - * Return value: %TRUE, if a event found. - **/ -static gboolean -e_day_view_get_next_tab_event (EDayView *day_view, GtkDirectionType direction, - gint *day_out, gint *event_num_out) -{ - gint new_day; - gint new_event_num; - gint days_shown; - - g_return_val_if_fail (day_view != NULL, FALSE); - g_return_val_if_fail (day_out != NULL, FALSE); - g_return_val_if_fail (event_num_out != NULL, FALSE); - - days_shown = e_day_view_get_days_shown(day_view); - *day_out = -1; - *event_num_out = -1; - - g_return_val_if_fail (days_shown > 0, FALSE); - - switch (direction) { - case GTK_DIR_TAB_BACKWARD: - new_event_num = day_view->editing_event_num - 1; - break; - case GTK_DIR_TAB_FORWARD: - new_event_num = day_view->editing_event_num + 1; - break; - default: - return FALSE; - } - - new_day = day_view->editing_event_day; - - /* not current editing event, set to first long event if there is one - */ - if (new_day == -1) { - if (direction == GTK_DIR_TAB_FORWARD) { - if (e_day_view_get_extreme_long_event (day_view, TRUE, - day_out, - event_num_out)) - return TRUE; - - /* no long event, set to first event if there is - */ - e_day_view_get_extreme_event (day_view, 0, - days_shown - 1, TRUE, - day_out, event_num_out); - /* go to event if found, or day view widget - */ - return TRUE; - } - else { - if (e_day_view_get_extreme_event (day_view, 0, - days_shown - 1, FALSE, - day_out, event_num_out)) - return TRUE; - - /* no event, set to last long event if there is - */ - e_day_view_get_extreme_long_event (day_view, FALSE, - day_out, - event_num_out); - - /* go to long event if found, or day view widget - */ - return TRUE; - } - } - /* go backward from the first long event */ - else if ((new_day == E_DAY_VIEW_LONG_EVENT) && (new_event_num < 0)) { - /* let focus go to day view widget in this case - */ - return TRUE; - } - /* go forward from the last long event */ - else if ((new_day == E_DAY_VIEW_LONG_EVENT) && - (new_event_num >= day_view->long_events->len)) { - e_day_view_get_extreme_event (day_view, 0, - days_shown - 1, TRUE, - day_out, event_num_out); - /* go to the next main item event if found or day view widget - */ - return TRUE; - } - - /* go backward from the first event in current editting day */ - else if ((new_day < E_DAY_VIEW_LONG_EVENT) && (new_event_num < 0)) { - /* try to find a event from the previous day in days shown - */ - if (e_day_view_get_extreme_event (day_view, 0, - new_day - 1, FALSE, - day_out, event_num_out)) - return TRUE; - /* try to find a long event - */ - e_day_view_get_extreme_long_event (day_view, FALSE, - day_out, event_num_out); - /* go to a long event if found, or day view widget - */ - return TRUE; - } - /* go forward from the last event in current editting day */ - else if ((new_day < E_DAY_VIEW_LONG_EVENT) && - (new_event_num >= day_view->events[new_day]->len)) { - /* try to find a event from the next day in days shown - */ - e_day_view_get_extreme_event (day_view, (new_day + 1), - days_shown - 1, TRUE, - day_out, event_num_out); - /* go to a event found, or day view widget - */ - return TRUE; - } - /* in the normal case - */ - *day_out = new_day; - *event_num_out = new_event_num; - return TRUE; -} - -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); - - g_signal_emit_by_name (day_view, "selected_time_changed"); - 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); - - g_signal_emit_by_name (day_view, "selected_time_changed"); - 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) { - gnome_calendar_previous (e_calendar_view_get_calendar (E_CALENDAR_VIEW (day_view))); - } 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); - } - g_signal_emit_by_name (day_view, "selected_time_changed"); -} - - -static void -e_day_view_cursor_key_right (EDayView *day_view, GdkEventKey *event) -{ - if (day_view->selection_end_day == day_view->days_shown - 1) { - gnome_calendar_next (e_calendar_view_get_calendar (E_CALENDAR_VIEW (day_view))); - } else { - 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); - } - g_signal_emit_by_name (day_view, "selected_time_changed"); -} - - -/* 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; -} - - -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. */ - g_object_get (G_OBJECT (event->canvas_item), - "event_processor", &event_processor, - NULL); - if (event_processor) { - command.action = E_TEP_MOVE; - command.position = E_TEP_END_OF_BUFFER; - g_signal_emit_by_name (event_processor, - "command", &command); - } -} - - -/* This stops the current edit. If accept is TRUE the event summary is updated, - 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; - const gchar *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 */ - - summary = icalcomponent_get_summary (event->comp_data->icalcomp); - g_object_set (G_OBJECT (event->canvas_item), - "text", summary ? summary : "", - 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) { - day_view->resize_event_num = -1; - - /* 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"); - /* focus should go to day view when stop editing */ - gtk_widget_grab_focus (GTK_WIDGET (day_view)); - return TRUE; - } else if ((event->key.keyval == GDK_Up) - && (event->key.state & GDK_SHIFT_MASK) - && (event->key.state & GDK_CONTROL_MASK) - && (event->key.state & GDK_MOD1_MASK)) { - e_day_view_change_event_end_time_up (day_view); - return TRUE; - } else if ((event->key.keyval == GDK_Down) - && (event->key.state & GDK_SHIFT_MASK) - && (event->key.state & GDK_CONTROL_MASK) - && (event->key.state & GDK_MOD1_MASK)) { - e_day_view_change_event_end_time_down (day_view); - 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_change_event_end_time_up (EDayView *day_view) -{ - EDayViewEvent *event; - gint day, event_num, resize_start_row, resize_end_row; - - day = day_view->editing_event_day; - event_num = day_view->editing_event_num; - if ((day == -1) || (day == E_DAY_VIEW_LONG_EVENT)) - return; - event = &g_array_index (day_view->events[day], EDayViewEvent, - event_num); - day_view->resize_event_day = day; - day_view->resize_event_num = event_num; - day_view->resize_bars_event_day = day; - day_view->resize_bars_event_num = event_num; - resize_start_row = event->start_minute / day_view->mins_per_row; - resize_end_row = (event->end_minute - 1) / day_view->mins_per_row; - if (resize_end_row < resize_start_row) - resize_end_row = resize_start_row; - if (resize_end_row == resize_start_row) - return; - day_view->resize_drag_pos = E_CALENDAR_VIEW_POS_BOTTOM_EDGE; - resize_end_row--; - day_view->resize_start_row = resize_start_row; - day_view->resize_end_row = resize_end_row; - e_day_view_finish_resize (day_view); - e_day_view_ensure_rows_visible (day_view, resize_start_row, resize_end_row); -} - - -static void -e_day_view_change_event_end_time_down (EDayView *day_view) -{ - EDayViewEvent *event; - gint day, event_num, resize_start_row, resize_end_row; - - day = day_view->editing_event_day; - event_num = day_view->editing_event_num; - if ((day == -1) || (day == E_DAY_VIEW_LONG_EVENT)) - return; - event = &g_array_index (day_view->events[day], EDayViewEvent, - event_num); - day_view->resize_event_day = day; - day_view->resize_event_num = event_num; - day_view->resize_bars_event_day = day; - day_view->resize_bars_event_num = event_num; - resize_start_row = event->start_minute / day_view->mins_per_row; - resize_end_row = (event->end_minute - 1) / day_view->mins_per_row; - if (resize_end_row < resize_start_row) - resize_end_row = resize_start_row; - if (resize_end_row == day_view->rows -1) - return; - day_view->resize_drag_pos = E_CALENDAR_VIEW_POS_BOTTOM_EDGE; - resize_end_row++; - day_view->resize_start_row = resize_start_row; - day_view->resize_end_row = resize_end_row; - e_day_view_finish_resize (day_view); - e_day_view_ensure_rows_visible (day_view, resize_start_row, resize_end_row); -} - - -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); - } - - g_signal_emit_by_name (day_view, "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; - ECalComponentText summary; - ECalComponent *comp; - ECal *client; - gboolean on_server; - - /* Note: the item we are passed here isn't reliable, so we just stop - the edit of whatever item was being edited. We also receive this - event twice for some reason. */ - 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; - - g_object_set (event->canvas_item, "handle_popup", FALSE, NULL); - g_object_get (G_OBJECT (event->canvas_item), - "text", &text, - NULL); - g_assert (text != NULL); - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); - - client = event->comp_data->client; - on_server = cal_comp_is_on_server (comp, client); - - if (string_is_empty (text) && !on_server) { - const char *uid; - - e_cal_component_get_uid (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; - } - - /* Only update the summary if necessary. */ - e_cal_component_get_summary (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 if (summary.value || !string_is_empty (text)) { - icalcomponent *icalcomp = e_cal_component_get_icalcomponent (comp); - - summary.value = text; - summary.altrep = NULL; - e_cal_component_set_summary (comp, &summary); - - if (!on_server) { - if (!e_cal_create_object (client, icalcomp, NULL, NULL)) - g_message (G_STRLOC ": Could not create the object!"); - } else { - CalObjModType mod = CALOBJ_MOD_ALL; - GtkWindow *toplevel; - if (e_cal_component_has_recurrences (comp)) { - if (!recur_component_dialog (client, comp, &mod, NULL)) { - goto out; - } - } - - /* FIXME When sending here, what exactly should we send? */ - toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (day_view))); - if (e_cal_modify_object (client, icalcomp, mod, NULL)) { - if (itip_organizer_is_user (comp, client) - && send_component_dialog (toplevel, client, comp, FALSE)) - itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, - client, NULL); - } - } - - } - - out: - - g_object_unref (comp); - g_free (text); - - g_signal_emit_by_name (day_view, "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, e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - tt.hour = minutes / 60; - tt.minute = minutes % 60; - tt.second = 0; - - val = icaltime_as_timet_with_zone (tt, e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - 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, e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - - 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) -{ - gint scroll_x, scroll_y; - - gnome_canvas_get_scroll_offsets (GNOME_CANVAS (day_view->main_canvas), - &scroll_x, &scroll_y); - - event_x -= scroll_x; - event_y -= scroll_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; - ECalendarViewPosition 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. */ - - /* FIXME: Since GNOME 2.0 we can't do this, since the canvas - * won't update when its's thawed. Is this a bug or should we - * really be doing something else? Investigate. */ -#if 0 - gtk_layout_freeze (GTK_LAYOUT (day_view->main_canvas)); -#endif - - gnome_canvas_scroll_to (GNOME_CANVAS (day_view->main_canvas), - scroll_x, new_scroll_y); -#if 0 - gtk_layout_thaw (GTK_LAYOUT (day_view->main_canvas)); -#endif - } - - 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_CALENDAR_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_CALENDAR_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_rows (EDayView *day_view, - gint day, - gint event_num, - gint *start_row_out, - gint *end_row_out) -{ - gint start_row, end_row; - EDayViewEvent *event; - - g_return_val_if_fail (day >= 0, FALSE); - g_return_val_if_fail (day < E_DAY_VIEW_LONG_EVENT, FALSE); - g_return_val_if_fail (event_num >= 0, FALSE); - - event = &g_array_index (day_view->events[day], EDayViewEvent, - 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; - - *start_row_out = start_row; - *end_row_out = end_row; - 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; - - e_day_view_get_event_rows(day_view, day, event_num, &start_row, &end_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_CALENDAR_VIEW_POS_NONE - && day_view->resize_event_day == day - && day_view->resize_event_num == event_num) { - if (day_view->resize_drag_pos == E_CALENDAR_VIEW_POS_TOP_EDGE) - start_row = day_view->resize_start_row; - else if (day_view->resize_drag_pos == E_CALENDAR_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_CALENDAR_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_CALENDAR_VIEW_POS_LEFT_EDGE) - *start_day = day_view->resize_start_row; - else if (day_view->resize_drag_pos == E_CALENDAR_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 ECalendarViewPosition -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_CALENDAR_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_CALENDAR_VIEW_POS_OUTSIDE; - - *day_return = day; - - /* If only the grid position is wanted, return. */ - if (event_num_return == NULL) - return E_CALENDAR_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_CALENDAR_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_CALENDAR_VIEW_POS_RIGHT_EDGE; - - return E_CALENDAR_VIEW_POS_EVENT; - } - - return E_CALENDAR_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 ECalendarViewPosition -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; - -#if 0 - g_print ("e_day_view_convert_position_in_main_canvas: (%d, %d)\n", x, y); -#endif - - *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_CALENDAR_VIEW_POS_OUTSIDE; - - row = y / day_view->row_height; - if (row >= day_view->rows) - return E_CALENDAR_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_CALENDAR_VIEW_POS_OUTSIDE; - - *day_return = day; - *row_return = row; - - /* If only the grid position is wanted, return. */ - if (event_num_return == NULL) - return E_CALENDAR_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_CALENDAR_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_CALENDAR_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_CALENDAR_VIEW_POS_LEFT_EDGE; - - if (y < item_y + E_DAY_VIEW_EVENT_BORDER_HEIGHT - + E_DAY_VIEW_EVENT_Y_PAD) - return E_CALENDAR_VIEW_POS_TOP_EDGE; - - if (y >= item_y + item_h - E_DAY_VIEW_EVENT_BORDER_HEIGHT - - E_DAY_VIEW_EVENT_Y_PAD) - return E_CALENDAR_VIEW_POS_BOTTOM_EDGE; - - return E_CALENDAR_VIEW_POS_EVENT; - } - - return E_CALENDAR_VIEW_POS_NONE; -} - - -static gboolean -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) -{ - ECalendarViewPosition 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_CALENDAR_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; - 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); - - gnome_canvas_item_set (day_view->drag_long_event_item, - "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)) { - const gchar *summary; - - if (event) { - summary = icalcomponent_get_summary (event->comp_data->icalcomp); - text = g_strdup (summary); - } 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 gboolean -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, day_view->drag_event_x, day_view->drag_event_y); - - return TRUE; -} - - -static void -e_day_view_reshape_main_canvas_drag_item (EDayView *day_view) -{ - ECalendarViewPosition 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_CALENDAR_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; - 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); - - gnome_canvas_item_set (day_view->drag_item, - "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)) { - const gchar *summary; - - if (event) { - summary = icalcomponent_get_summary (event->comp_data->icalcomp); - text = g_strdup (summary); - } 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; - - 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); - - if (info == TARGET_CALENDAR_EVENT || info == TARGET_VCALENDAR) { - /* we will pass an icalcalendar component for both types */ - char *comp_str; - icalcomponent *vcal; - - vcal = e_cal_util_new_top_level (); - e_cal_util_add_timezones_from_component (vcal, event->comp_data->icalcomp); - icalcomponent_add_component ( - vcal, - icalcomponent_new_clone (event->comp_data->icalcomp)); - - comp_str = icalcomponent_as_ical_string (vcal); - if (comp_str) { - gtk_selection_data_set (selection_data, selection_data->target, - 8, comp_str, strlen (comp_str)); - } - - icalcomponent_free (vcal); - } -} - - -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; - ECalendarViewPosition pos; - gint day, start_day, end_day, num_days; - gint start_offset, end_offset; - ECalComponent *comp; - ECalComponentDateTime date; - struct icaltimetype itt; - time_t dt; - gboolean all_day_event; - ECal *client; - gboolean drag_from_same_window; - - if (day_view->drag_event_day != -1) - drag_from_same_window = TRUE; - else - drag_from_same_window = FALSE; - - client = e_cal_model_get_default_client (e_calendar_view_get_model (E_CALENDAR_VIEW (day_view))); - - /* Note that we only support DnD within the EDayView at present. */ - if ((data->length >= 0) && (data->format == 8) - && (day_view->drag_event_day != -1)) { - /* We are dragging in the same window */ - - pos = e_day_view_convert_position_in_top_canvas (day_view, - x, y, &day, - NULL); - if (pos != E_CALENDAR_VIEW_POS_OUTSIDE) { - CalObjModType mod = CALOBJ_MOD_ALL; - GtkWindow *toplevel; - - 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); - } - - client = event->comp_data->client; - - /* 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 = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); - - 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, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - 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 (e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - } - e_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, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - 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 (e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - } - e_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 (e_cal_component_has_recurrences (comp)) { - if (!recur_component_dialog (client, comp, &mod, NULL)) - return; - } - - toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (day_view))); - e_cal_component_commit_sequence (comp); - - if (e_cal_modify_object (client, e_cal_component_get_icalcomponent (comp), mod, NULL)) { - if (itip_organizer_is_user (comp, client) - && send_component_dialog (toplevel, client, comp, FALSE)) - itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, - client, NULL); - } - - g_object_unref (comp); - - return; - } - } - - if ((data->length >= 0) && (data->format == 8) - && !drag_from_same_window) { - /* We are dragging between different window */ - - char *comp_str, *default_tzid; - icalcomponent *icalcomp; - icalcomponent_kind kind; - time_t dtstart; - icaltimezone *default_zone; - - pos = e_day_view_convert_position_in_top_canvas (day_view, - x, y, &day, - NULL); - if (pos == E_CALENDAR_VIEW_POS_OUTSIDE) - goto error; - - comp_str = (char *) data->data; - icalcomp = icalparser_parse_string ((const char *) comp_str); - if (!icalcomp) - goto error; - - default_tzid = calendar_config_get_timezone (); - e_cal_get_timezone (client, default_tzid, &default_zone, NULL); - - /* check the type of the component */ - kind = icalcomponent_isa (icalcomp); - if (kind != ICAL_VCALENDAR_COMPONENT && kind != ICAL_VEVENT_COMPONENT) - goto error; - - dtstart = day_view->day_starts[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) - e_calendar_view_add_event (E_CALENDAR_VIEW (day_view), client, dtstart, - default_zone, subcomp, TRUE); - else if (child_kind == ICAL_VTIMEZONE_COMPONENT) { - icaltimezone *zone; - - zone = icaltimezone_new (); - icaltimezone_set_component (zone, subcomp); - e_cal_add_timezone (client, zone, NULL); - - icaltimezone_free (zone, 1); - } - - subcomp = icalcomponent_get_next_component ( - icalcomp, ICAL_ANY_COMPONENT); - } - - icalcomponent_free (icalcomp); - - } else { - e_calendar_view_add_event (E_CALENDAR_VIEW (day_view), client, dtstart, default_zone, icalcomp, TRUE); - } - - gtk_drag_finish (context, TRUE, TRUE, time); - return; - } - -error: - 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; - ECalendarViewPosition pos; - gint day, row, start_row, end_row, num_rows, scroll_x, scroll_y; - gint start_offset, end_offset; - ECalComponent *comp; - ECalComponentDateTime date; - struct icaltimetype itt; - time_t dt; - ECal *client; - gboolean drag_from_same_window; - - if (day_view->drag_event_day != -1) - drag_from_same_window = TRUE; - else - drag_from_same_window = FALSE; - - client = e_cal_model_get_default_client (e_calendar_view_get_model (E_CALENDAR_VIEW (day_view))); - - 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)) { - /* We are dragging in the same window */ - - pos = e_day_view_convert_position_in_main_canvas (day_view, - x, y, &day, - &row, NULL); - if (pos != E_CALENDAR_VIEW_POS_OUTSIDE) { - CalObjModType mod = CALOBJ_MOD_ALL; - GtkWindow *toplevel; - - 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; - } - - client = event->comp_data->client; - - /* 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 = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); - - date.value = &itt; - date.tzid = icaltimezone_get_tzid (e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - - 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, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - e_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, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - e_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 (e_cal_component_has_recurrences (comp)) { - if (!recur_component_dialog (client, comp, &mod, NULL)) { - g_object_unref (comp); - return; - } - } - - toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (day_view))); - e_cal_component_commit_sequence (comp); - - if (e_cal_modify_object (client, e_cal_component_get_icalcomponent (comp), mod, NULL)) { - if (itip_organizer_is_user (comp, client) - && send_component_dialog (toplevel, client, comp, FALSE)) - itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, - client, NULL); - } - - g_object_unref (comp); - - return; - } - } - - if ((data->length >= 0) && (data->format == 8) - && !drag_from_same_window) { - /* We are dragging between different window */ - - char *comp_str, *default_tzid; - icalcomponent *icalcomp; - icalcomponent_kind kind; - time_t dtstart; - icaltimezone *default_zone; - - pos = e_day_view_convert_position_in_main_canvas (day_view, - x, y, &day, - &row, NULL); - if (pos == E_CALENDAR_VIEW_POS_OUTSIDE) - goto error; - - comp_str = (char *) data->data; - icalcomp = icalparser_parse_string ((const char *) comp_str); - if (!icalcomp) - goto error; - - default_tzid = calendar_config_get_timezone (); - e_cal_get_timezone (client, default_tzid, &default_zone, NULL); - - /* check the type of the component */ - kind = icalcomponent_isa (icalcomp); - if (kind != ICAL_VCALENDAR_COMPONENT && kind != ICAL_VEVENT_COMPONENT) - goto error; - - dtstart = e_day_view_convert_grid_position_to_time (day_view, day, row); - - 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) - e_calendar_view_add_event (E_CALENDAR_VIEW (day_view), client, dtstart, - default_zone, subcomp, FALSE); - else if (child_kind == ICAL_VTIMEZONE_COMPONENT) { - icaltimezone *zone; - - zone = icaltimezone_new (); - icaltimezone_set_component (zone, subcomp); - e_cal_add_timezone (client, zone, NULL); - - icaltimezone_free (zone, 1); - } - - subcomp = icalcomponent_get_next_component ( - icalcomp, ICAL_ANY_COMPONENT); - } - - icalcomponent_free (icalcomp); - - } else { - e_calendar_view_add_event (E_CALENDAR_VIEW (day_view), client, dtstart, default_zone, icalcomp, FALSE); - } - - gtk_drag_finish (context, TRUE, TRUE, time); - return; - } - -error: - 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 (e_calendar_view_get_use_24_hour_format (E_CALENDAR_VIEW (day_view))) { - *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 (!e_calendar_view_get_use_24_hour_format (E_CALENDAR_VIEW (day_view))) - time_width += MAX (day_view->am_string_width, - day_view->pm_string_width); - - return time_width; -} - -/* 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; -} - - diff --git a/calendar/gui/e-day-view.h b/calendar/gui/e-day-view.h deleted file mode 100644 index 652efc7399..0000000000 --- a/calendar/gui/e-day-view.h +++ /dev/null @@ -1,586 +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 <gtk/gtktooltips.h> -#include <libgnomecanvas/gnome-canvas.h> -#include <gal/widgets/e-popup-menu.h> - -#include "e-cal-view.h" -#include "gnome-cal.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - * EDayView - displays the Day & Work-Week views of the calendar. - */ - -/* The maximum number of days shown. We use the week view for anything more - than about 9 days. */ -#define E_DAY_VIEW_MAX_DAYS 10 - -/* This is used as a special code to signify a long event instead of the day - of a normal event. */ -#define E_DAY_VIEW_LONG_EVENT E_DAY_VIEW_MAX_DAYS - -/* The maximum number of columns of appointments within a day. */ -#define E_DAY_VIEW_MAX_COLUMNS 6 - -/* The width of the gap between appointments. This should be at least - E_DAY_VIEW_BAR_WIDTH, since in the top canvas we use this space to draw - the triangle to represent continuing events. */ -#define E_DAY_VIEW_GAP_WIDTH 7 - -/* The width of the bars down the left of each column and appointment. - This includes the borders on each side of it. */ -#define E_DAY_VIEW_BAR_WIDTH 7 - -/* The height of the horizontal bar above & beneath the selected event. - This includes the borders on the top and bottom. */ -#define E_DAY_VIEW_BAR_HEIGHT 6 - -/* The size of the reminder & recurrence icons, and padding around them. */ -#define E_DAY_VIEW_ICON_WIDTH 16 -#define E_DAY_VIEW_ICON_HEIGHT 16 -#define E_DAY_VIEW_ICON_X_PAD 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_SELECTED_UNFOCUSSED, - 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; - -typedef struct _EDayViewEvent EDayViewEvent; -struct _EDayViewEvent { - E_CALENDAR_VIEW_EVENT_FIELDS - - /* 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; -}; - - -#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 -{ - ECalendarView cal_view; - - /* 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; - - /* S-expression for query and the query object */ - ECalView *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]; - - /* 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 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. */ - PangoFontDescription *large_font_desc; - - /* 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; - GdkPixmap *meeting_icon; - GdkBitmap *meeting_mask; - - /* Colors for drawing. */ - GdkColor colors[E_DAY_VIEW_COLOR_LAST]; - - /* The normal & resizing cursors. */ - GdkCursor *normal_cursor; - GdkCursor *move_cursor; - GdkCursor *resize_width_cursor; - GdkCursor *resize_height_cursor; - - /* This remembers the last cursor set on the window. */ - GdkCursor *last_cursor_set_in_top_canvas; - GdkCursor *last_cursor_set_in_main_canvas; - - /* - * Editing, Selection & Dragging data - */ - - /* The horizontal bars to resize events in the main canvas. */ - GnomeCanvasItem *main_canvas_top_resize_bar_item; - GnomeCanvasItem *main_canvas_bottom_resize_bar_item; - - /* The event currently being edited. The day is -1 if no event is - being edited, or E_DAY_VIEW_LONG_EVENT if a long event is edited. */ - gint editing_event_day; - gint editing_event_num; - - /* This is a GnomeCanvasRect which is placed around an item while it - is being resized, so we can raise it above all other EText items. */ - GnomeCanvasItem *resize_long_event_rect_item; - GnomeCanvasItem *resize_rect_item; - GnomeCanvasItem *resize_bar_item; - - /* The event for which a popup menu is being displayed, as above. */ - gint popup_event_day; - gint popup_event_num; - - /* The currently selected region. If selection_start_day is -1 there is - no current selection. If start_row or end_row is -1 then the - selection is in the top canvas. */ - gint selection_start_day; - gint selection_end_day; - gint selection_start_row; - gint selection_end_row; - - /* This is TRUE if the selection is currently being dragged using the - mouse. */ - gboolean selection_is_being_dragged; - - /* This specifies which end of the selection is being dragged. */ - EDayViewDragPosition selection_drag_pos; - - /* This is TRUE if the selection is in the top canvas only (i.e. if the - last motion event was in the top canvas). */ - gboolean selection_in_top_canvas; - - /* The last mouse position, relative to the main canvas window. - Used when auto-scrolling to update the selection. */ - gint last_mouse_x; - gint last_mouse_y; - - /* Auto-scroll info for when selecting an area or dragging an item. */ - gint auto_scroll_timeout_id; - gint auto_scroll_delay; - gboolean auto_scroll_up; - - /* These are used for the resize bars. */ - gint resize_bars_event_day; - gint resize_bars_event_num; - - /* These are used when resizing events. */ - gint resize_event_day; - gint resize_event_num; - ECalendarViewPosition resize_drag_pos; - gint resize_start_row; - gint resize_end_row; - - /* This is the event the mouse button was pressed on. If the button - is released we start editing it, but if the mouse is dragged we set - this to -1. */ - gint pressed_event_day; - gint pressed_event_num; - - /* These are used when dragging events. If drag_event_day is not -1 we - know that we are dragging one of the EDayView events around. */ - gint drag_event_day; - gint drag_event_num; - - /* The last mouse position when dragging, in the entire canvas. */ - gint drag_event_x; - gint drag_event_y; - - /* The offset of the mouse from the top of the event, in rows. - In the top canvas this is the offset from the left, in days. */ - gint drag_event_offset; - - /* The last day & row dragged to, so we know when we need to update - the dragged event's position. */ - gint drag_last_day; - gint drag_last_row; - - /* This is a GnomeCanvasRect which is placed around an item while it - is being resized, so we can raise it above all other EText items. */ - GnomeCanvasItem *drag_long_event_rect_item; - GnomeCanvasItem *drag_long_event_item; - GnomeCanvasItem *drag_rect_item; - GnomeCanvasItem *drag_bar_item; - GnomeCanvasItem *drag_item; - - /* "am" and "pm" in the current locale, and their widths. */ - gchar *am_string; - gchar *pm_string; - gint am_string_width; - gint pm_string_width; -}; - -struct _EDayViewClass -{ - ECalendarViewClass parent_class; -}; - - -GtkType e_day_view_get_type (void); -GtkWidget* e_day_view_new (void); - -void e_day_view_set_query (EDayView *day_view, - const char *sexp); - -/* 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 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); - -void e_day_view_delete_occurrence (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_rows (EDayView *day_view, - gint day, - gint event_num, - gint *start_row_out, - gint *end_row_out); -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); - -gboolean e_day_view_find_event_from_item (EDayView *day_view, - GnomeCanvasItem *item, - gint *day_return, - gint *event_num_return); -void e_day_view_update_calendar_selection_time (EDayView *day_view); -void e_day_view_ensure_rows_visible (EDayView *day_view, - gint start_row, - gint end_row); - - -#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 44f0a97c2c..0000000000 --- a/calendar/gui/e-itip-control.c +++ /dev/null @@ -1,2373 +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 <unistd.h> -#include <glib.h> -#include <gtk/gtkmisc.h> -#include <libgnome/gnome-i18n.h> -#include <libgnome/gnome-util.h> -#include <libgnomeui/gnome-stock-icons.h> -#include <libgnomeui/gnome-uidefs.h> -#include <libgnomeui/gnome-dialog.h> -#include <libgnomeui/gnome-dialog-util.h> -#include <bonobo/bonobo-object.h> -#include <bonobo/bonobo-exception.h> -#include <gtkhtml/gtkhtml.h> -#include <gtkhtml/gtkhtml-stream.h> -#include <libical/ical.h> -#include <libecal/e-cal-component.h> -#include <libecal/e-cal-time-util.h> -#include <libecal/e-cal.h> -#include <e-util/e-time-utils.h> -#include <e-util/e-dialog-widgets.h> -#include <camel/camel-mime-filter-tohtml.h> -#include "dialogs/delete-error.h" -#include "calendar-config.h" -#include "itip-utils.h" -#include "e-itip-control.h" - -struct _EItipControlPrivate { - GtkWidget *html; - - GPtrArray *event_clients; - ECal *event_client; - GPtrArray *task_clients; - ECal *task_client; - - char *vcalendar; - ECalComponent *comp; - icalcomponent *main_comp; - icalcomponent *ical_comp; - icalcomponent *top_level; - icalcompiter iter; - icalproperty_method method; - - int current; - int total; - - gchar *calendar_uri; - - EAccountList *accounts; - - gchar *from_address; - gchar *delegator_address; - gchar *delegator_name; - gchar *my_address; - gint view_only; - - gboolean destroyed; -}; - -/* 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 intentionally use "calendar" instead of "calendar / *" here. We - * don't want public calendars. - */ -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); -static void finalize (GObject *obj); - -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; - -E_MAKE_TYPE (e_itip_control, "EItipControl", EItipControl, class_init, init, - GTK_TYPE_VBOX); - -static void -class_init (EItipControlClass *klass) -{ - GObjectClass *object_class; - GtkObjectClass *gtkobject_class; - - object_class = G_OBJECT_CLASS (klass); - gtkobject_class = GTK_OBJECT_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - gtkobject_class->destroy = destroy; - - object_class->finalize = finalize; -} - -static ECal * -start_calendar_server (EItipControl *itip, char *uri) -{ - ECal *client; - GError *error = NULL; - - client = e_cal_new_from_uri (uri, CALOBJ_TYPE_EVENT); - - if (!e_cal_open (client, TRUE, &error)) { - g_warning (_("start_calendar_server(): %s"), error->message); - g_error_free (error); - g_object_unref (client); - return NULL; - } - - return client; -} - -static gboolean -start_default_server (EItipControl *itip, ECal *client, gboolean tasks) -{ -#if 0 - if (tasks) - return e_cal_open_default_tasks (client, FALSE); - else - return e_cal_open_default_calendar (client, FALSE); -#endif - return FALSE; -} - -#if 0 /* EPFIXME, rewrite this */ -static GPtrArray * -get_servers (EItipControl *itip, 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 (); - - g_object_ref (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; - - CORBA_exception_init (&ev); - - storage = storage_list->_buffer[i]; - folder_list = GNOME_Evolution_Storage__get_folderList (storage, &ev); - if (BONOBO_EX (&ev)) { - CORBA_exception_free (&ev); - continue; - } - - CORBA_exception_free (&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++) { - ECal *client; - char *uri; - - if (itip->priv->destroyed) - continue; - - if (strcmp (possible_types[k], folder.type)) - continue; - - uri = e_cal_util_expand_uri (folder.physicalUri, tasks); - client = start_calendar_server (itip, uri); - if (client != NULL) - g_ptr_array_add (servers, client); - g_free (uri); - - break; - } - } - - CORBA_free (folder_list); - } - - g_object_unref (shell_client); - - return servers; -} -#endif - -static ECal * -find_server (GPtrArray *servers, ECalComponent *comp) -{ - const char *uid; - int i; - - e_cal_component_get_uid (comp, &uid); - for (i = 0; i < servers->len; i++) { - ECal *client; - icalcomponent *icalcomp; - - client = g_ptr_array_index (servers, i); - if (e_cal_get_object (client, uid, NULL, &icalcomp, NULL)) { - icalcomponent_free (icalcomp); - g_object_ref (client); - - return client; - } - } - - return NULL; -} - -static void -html_destroyed (gpointer data) -{ - EItipControl *itip = data; - EItipControlPrivate *priv; - - priv = itip->priv; - - priv->html = NULL; -} - -static void -init (EItipControl *itip) -{ - EItipControlPrivate *priv; - GtkWidget *scrolled_window; - - priv = g_new0 (EItipControlPrivate, 1); - - itip->priv = priv; - - /* Addresses */ - priv->accounts = itip_addresses_get (); - - /* Initialize the cal clients */ - priv->event_clients = NULL; - priv->event_client = NULL; - priv->task_clients = NULL; - priv->task_client = NULL; - - /* Other fields to init */ - priv->calendar_uri = NULL; - priv->from_address = NULL; - priv->delegator_address = NULL; - priv->delegator_name = NULL; - priv->my_address = NULL; - priv->view_only = 0; - - /* Html Widget */ - priv->html = gtk_html_new (); - gtk_html_set_default_content_type (GTK_HTML (priv->html), - "text/html; charset=utf-8"); - gtk_html_load_from_string (GTK_HTML (priv->html), " ", 1); - 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_object_weakref (GTK_OBJECT (priv->html), html_destroyed, itip); - gtk_widget_set_usize (scrolled_window, 600, 400); - gtk_box_pack_start (GTK_BOX (itip), scrolled_window, FALSE, FALSE, 6); - - g_signal_connect (priv->html, "url_requested", G_CALLBACK (url_requested_cb), itip); - g_signal_connect (priv->html, "object_requested", G_CALLBACK (object_requested_cb), itip); - g_signal_connect (priv->html, "submit", G_CALLBACK (ok_clicked_cb), itip); - - priv->destroyed = FALSE; -} - -static void -clean_up (EItipControl *itip) -{ - EItipControlPrivate *priv; - - priv = itip->priv; - if (!priv) - return; - - g_free (priv->vcalendar); - priv->vcalendar = NULL; - - if (priv->comp) { - g_object_unref (priv->comp); - priv->comp = NULL; - } - - if (priv->top_level) { - icalcomponent_free (priv->top_level); - priv->top_level = NULL; - } - - if (priv->main_comp) { - icalcomponent_free (priv->main_comp); - priv->main_comp = NULL; - } - priv->ical_comp = NULL; - - priv->current = 0; - priv->total = 0; - - g_free (priv->calendar_uri); - priv->calendar_uri = NULL; - - g_free (priv->from_address); - priv->from_address = NULL; - g_free (priv->delegator_address); - priv->delegator_address = NULL; - g_free (priv->delegator_name); - priv->delegator_name = NULL; - g_free (priv->my_address); - priv->my_address = NULL; -} - -static void -destroy (GtkObject *obj) -{ - EItipControl *itip = E_ITIP_CONTROL (obj); - EItipControlPrivate *priv; - - priv = itip->priv; - - priv->destroyed = TRUE; - - (* GTK_OBJECT_CLASS (parent_class)->destroy) (obj); -} - -static void -finalize (GObject *obj) -{ - EItipControl *itip = E_ITIP_CONTROL (obj); - EItipControlPrivate *priv; - int i; - - priv = itip->priv; - - clean_up (itip); - - if (priv->html) - gtk_object_weakunref (GTK_OBJECT (priv->html), html_destroyed, itip); - - priv->accounts = NULL; - - if (priv->event_clients) { - for (i = 0; i < priv->event_clients->len; i++) - g_object_unref (g_ptr_array_index (priv->event_clients, i)); - g_ptr_array_free (priv->event_clients, TRUE); - priv->event_client = NULL; - priv->event_clients = NULL; - } - - if (priv->task_clients) { - for (i = 0; i < priv->task_clients->len; i++) - g_object_unref (g_ptr_array_index (priv->task_clients, i)); - g_ptr_array_free (priv->task_clients, TRUE); - priv->task_client = NULL; - priv->task_clients = NULL; - } - - g_free (priv); - itip->priv = NULL; - - if (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (obj); -} - -GtkWidget * -e_itip_control_new (void) -{ - return g_object_new (E_TYPE_ITIP_CONTROL, NULL); -} - -static void -find_my_address (EItipControl *itip, icalcomponent *ical_comp) -{ - EItipControlPrivate *priv; - icalproperty *prop; - char *my_alt_address = NULL; - - priv = itip->priv; - - /* If the mailer told us the address to use, use that */ - if (priv->delegator_address != NULL) { - priv->my_address = g_strdup (itip_strip_mailto (priv->delegator_address)); - priv->my_address = g_strstrip (priv->my_address); - return; - } - - 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; - EIterator *it; - - 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; - } - - it = e_list_get_iterator((EList *)priv->accounts); - while (e_iterator_is_valid(it)) { - const EAccount *account = e_iterator_get(it); - - /* Check for a matching address */ - if (attendee_clean != NULL - && !g_ascii_strcasecmp (account->id->address, attendee_clean)) { - priv->my_address = g_strdup (account->id->address); - g_free (attendee_clean); - g_free (name_clean); - g_free (my_alt_address); - g_object_unref(it); - return; - } - - /* Check for a matching cname to fall back on */ - if (name_clean != NULL - && !g_ascii_strcasecmp (account->id->name, name_clean)) - my_alt_address = g_strdup (attendee_clean); - - e_iterator_next(it); - } - g_free (attendee_clean); - g_free (name_clean); - g_object_unref(it); - } - - 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; -} - -static void -write_label_piece (EItipControl *itip, ECalComponentDateTime *dt, - char *buffer, int size, - const char *stext, const char *etext, - gboolean just_date) -{ - EItipControlPrivate *priv; - struct tm tmp_tm; - char time_buf[64]; - 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 (just_date) - tmp_tm.tm_hour = tmp_tm.tm_min = tmp_tm.tm_sec = 0; - - 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)); - strcat (buffer, time_buf); - - 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 && !just_date) { - /* 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, " <font size=-1>["); - - /* We check if it is one of our builtin timezone names, - in which case we call gettext to translate it. */ - if (icaltimezone_get_builtin_timezone (display_name)) { - strcat (buffer, _(display_name)); - } else { - strcat (buffer, display_name); - } - strcat (buffer, "]</font>"); - } - } - - if (etext != NULL) - strcat (buffer, etext); -} - -static const char * -nth (int n) -{ - if (n == -1) - return "last"; - else if (n < 1 || n > 31) - return "?"; - else - return e_cal_recur_nth[n]; -} - -static const char *dayname[] = { - N_("Sunday"), - N_("Monday"), - N_("Tuesday"), - N_("Wednesday"), - N_("Thursday"), - N_("Friday"), - N_("Saturday") -}; - -static inline char * -get_dayname (struct icalrecurrencetype *r, int i) -{ - enum icalrecurrencetype_weekday day; - - day = icalrecurrencetype_day_day_of_week (r->by_day[i]); - g_return_val_if_fail (day > 0 && day < 8, "?"); - - return _(dayname[day - 1]); -} - -static void -write_recurrence_piece (EItipControl *itip, ECalComponent *comp, - char *buffer, int size) -{ - GSList *rrules; - struct icalrecurrencetype *r; - int len, i; - - strcpy (buffer, "<b>Recurring:</b> "); - len = strlen (buffer); - buffer += len; - size -= len; - - if (!e_cal_component_has_simple_recurrence (comp)) { - strcpy (buffer, _("Yes. (Complex Recurrence)")); - return; - } - - e_cal_component_get_rrule_list (comp, &rrules); - g_return_if_fail (rrules && !rrules->next); - - r = rrules->data; - - switch (r->freq) { - case ICAL_DAILY_RECURRENCE: - if (r->interval == 1) - strcpy (buffer, _("Every day")); - else - sprintf (buffer, _("Every %d days"), r->interval); - break; - - case ICAL_WEEKLY_RECURRENCE: - if (r->by_day[0] == ICAL_RECURRENCE_ARRAY_MAX) { - if (r->interval == 1) - strcpy (buffer, _("Every week")); - else - sprintf (buffer, _("Every %d weeks"), r->interval); - } else { - if (r->interval == 1) - strcpy (buffer, _("Every week on ")); - else - sprintf (buffer, _("Every %d weeks on "), r->interval); - - for (i = 1; i < 8 && r->by_day[i] != ICAL_RECURRENCE_ARRAY_MAX; i++) { - if (i > 1) - strcat (buffer, ", "); - strcat (buffer, get_dayname (r, i - 1)); - } - if (i > 1) - strcat (buffer, _(" and ")); - strcat (buffer, get_dayname (r, i - 1)); - } - break; - - case ICAL_MONTHLY_RECURRENCE: - if (r->by_month_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { - sprintf (buffer, _("The %s day of "), - nth (r->by_month_day[0])); - } else { - int pos; - - /* Outlook 2000 uses BYDAY=TU;BYSETPOS=2, and will not - accept BYDAY=2TU. So we now use the same as Outlook - by default. */ - - pos = icalrecurrencetype_day_position (r->by_day[0]); - if (pos == 0) - pos = r->by_set_pos[0]; - - sprintf (buffer, _("The %s %s of "), - nth (pos), get_dayname (r, 0)); - } - - if (r->interval == 1) - strcat (buffer, _("every month")); - else { - len = strlen (buffer); - buffer += len; - size -= len; - sprintf (buffer, _("every %d months"), r->interval); - } - break; - - case ICAL_YEARLY_RECURRENCE: - if (r->interval == 1) - strcpy (buffer, _("Every year")); - else { - sprintf (buffer, _("Every %d years"), r->interval); - } - break; - - default: - g_assert_not_reached (); - } - - len = strlen (buffer); - buffer += len; - size -= len; - if (r->count) { - sprintf (buffer, _(" a total of %d times"), r->count); - } else if (!icaltime_is_null_time (r->until)) { - ECalComponentDateTime dt; - - /* FIXME This should get the tzid id, not the whole zone */ - dt.value = &r->until; - dt.tzid = r->until.zone; - - write_label_piece (itip, &dt, buffer, size, - _(", ending on "), NULL, TRUE); - } - - strcat (buffer, "<br>"); -} - -static void -set_date_label (EItipControl *itip, GtkHTML *html, GtkHTMLStream *html_stream, - ECalComponent *comp) -{ - EItipControlPrivate *priv; - ECalComponentDateTime datetime; - static char buffer[1024]; - gboolean wrote = FALSE, task_completed = FALSE; - ECalComponentVType type; - - priv = itip->priv; - - type = e_cal_component_get_vtype (comp); - - buffer[0] = '\0'; - e_cal_component_get_dtstart (comp, &datetime); - if (datetime.value) { - write_label_piece (itip, &datetime, buffer, 1024, - _("<b>Starts:</b> "), - "<br>", FALSE); - gtk_html_write (html, html_stream, buffer, strlen(buffer)); - wrote = TRUE; - } - e_cal_component_free_datetime (&datetime); - - buffer[0] = '\0'; - e_cal_component_get_dtend (comp, &datetime); - if (datetime.value){ - write_label_piece (itip, &datetime, buffer, 1024, _("<b>Ends:</b> "), "<br>", FALSE); - gtk_html_write (html, html_stream, buffer, strlen (buffer)); - wrote = TRUE; - } - e_cal_component_free_datetime (&datetime); - - buffer[0] = '\0'; - if (e_cal_component_has_recurrences (comp)) { - write_recurrence_piece (itip, comp, buffer, 1024); - gtk_html_write (html, html_stream, buffer, strlen (buffer)); - wrote = TRUE; - } - - buffer[0] = '\0'; - datetime.tzid = NULL; - e_cal_component_get_completed (comp, &datetime.value); - if (type == E_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, _("<b>Completed:</b> "), "<br>", FALSE); - gtk_html_write (html, html_stream, buffer, strlen (buffer)); - wrote = TRUE; - task_completed = TRUE; - } - e_cal_component_free_datetime (&datetime); - - buffer[0] = '\0'; - e_cal_component_get_due (comp, &datetime); - if (type == E_CAL_COMPONENT_TODO && !task_completed && datetime.value) { - write_label_piece (itip, &datetime, buffer, 1024, _("<b>Due:</b> "), "<br>", FALSE); - gtk_html_write (html, html_stream, buffer, strlen (buffer)); - wrote = TRUE; - } - - e_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>", - _("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, _("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; - ECalComponentText text; - ECalComponentOrganizer organizer; - ECalComponentAttendee *attendee; - GSList *attendees, *l = NULL; - const char *string; - gchar *html; - const gchar *const_html; - - priv = itip->priv; - - if (priv->html == NULL) - return; - - /* Html widget */ - html_stream = gtk_html_begin (GTK_HTML (priv->html)); - gtk_html_stream_printf (html_stream, - "<html><head><title>%s</title></head>", - _("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 */ - e_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, _("An unknown person")); - } - break; - case ICAL_METHOD_REQUEST: - /* The organizer sent this */ - e_cal_component_get_organizer (priv->comp, &organizer); - if (priv->delegator_address != NULL) { - if (organizer.value != NULL) - html = g_strdup_printf (itip_desc, - organizer.cn ? - organizer.cn : - itip_strip_mailto (organizer.value), - priv->delegator_name ? - priv->delegator_name : - priv->delegator_address); - else - html = g_strdup_printf (itip_desc, _("An unknown person"), - priv->delegator_name ? - priv->delegator_name : - priv->delegator_address); - } else { - 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, _("An unknown person")); - } - - break; - - case ICAL_METHOD_PUBLISH: - case ICAL_METHOD_ADD: - case ICAL_METHOD_CANCEL: - default: - /* The organizer sent this */ - e_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, _("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 = _("<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 */ - e_cal_component_get_summary (priv->comp, &text); - html = text.value ? camel_text_to_html (text.value, CAMEL_MIME_FILTER_TOHTML_CONVERT_NL, 0) : _("<i>None</i>"); - gtk_html_stream_printf (html_stream, "<b>%s</b><br>%s<br><br>", - _("Summary:"), html); - if (text.value) - g_free (html); - - /* Location */ - e_cal_component_get_location (priv->comp, &string); - if (string != NULL) { - html = camel_text_to_html (string, CAMEL_MIME_FILTER_TOHTML_CONVERT_NL, 0); - gtk_html_stream_printf (html_stream, "<b>%s</b><br>%s<br><br>", - _("Location:"), html); - g_free (html); - } - - /* Status */ - if (priv->method == ICAL_METHOD_REPLY) { - GSList *alist; - - e_cal_component_get_attendee_list (priv->comp, &alist); - - if (alist != NULL) { - ECalComponentAttendee *a = alist->data; - - gtk_html_stream_printf (html_stream, "<b>%s</b><br>", - _("Status:")); - - switch (a->status) { - case ICAL_PARTSTAT_ACCEPTED: - gtk_html_stream_printf (html_stream, "%s<br><br>", - _("Accepted")); - break; - case ICAL_PARTSTAT_TENTATIVE: - gtk_html_stream_printf (html_stream, "%s<br><br>", - _("Tentatively Accepted")); - break; - case ICAL_PARTSTAT_DECLINED: - gtk_html_stream_printf (html_stream, "%s<br><br>", - _("Declined")); - break; - default: - gtk_html_stream_printf (html_stream, "%s<br><br>", - _("Unknown")); - } - } - - e_cal_component_free_attendee_list (alist); - } - - /* Description */ - e_cal_component_get_description_list (priv->comp, &l); - if (l) - text = *((ECalComponentText *)l->data); - - if (l && text.value) { - html = camel_text_to_html (text.value, CAMEL_MIME_FILTER_TOHTML_CONVERT_NL, 0); - gtk_html_stream_printf (html_stream, "<b>%s</b><br>%s", - _("Description:"), html); - g_free (html); - } - e_cal_component_free_text_list (l); - - /* Separator */ - gtk_html_write (GTK_HTML (priv->html), html_stream, HTML_SEP, strlen (HTML_SEP)); - - /* Options */ - if (!e_itip_control_get_view_only (itip)) { - 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>", - _("Choose an action:"), - _("Update"), - _("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>", - _("Choose an action:"), - _("Accept"), - _("Tentatively accept"), - _("Decline"), - _("RSVP"), - _("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>", - _("Choose an action:"), - _("Send Free/Busy Information"), - _("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>", - _("Choose an action:"), - _("Update respondent status"), - _("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>", - _("Choose an action:"), - _("Send Latest Information"), - _("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>", - _("Choose an action:"), - _("Cancel"), - _("OK")); -} - - -static ECalComponent * -get_real_item (EItipControl *itip) -{ - EItipControlPrivate *priv; - ECalComponent *comp; - icalcomponent *icalcomp; - ECalComponentVType type; - gboolean found = FALSE; - const char *uid; - - priv = itip->priv; - - type = e_cal_component_get_vtype (priv->comp); - e_cal_component_get_uid (priv->comp, &uid); - - switch (type) { - case E_CAL_COMPONENT_EVENT: - if (priv->event_client != NULL) - found = e_cal_get_object (priv->event_client, uid, NULL, &icalcomp, NULL); - break; - case E_CAL_COMPONENT_TODO: - if (priv->task_client != NULL) - found = e_cal_get_object (priv->task_client, uid, NULL, &icalcomp, NULL); - break; - default: - found = FALSE; - } - - if (!found) - return NULL; - - comp = e_cal_component_new (); - if (!e_cal_component_set_icalcomponent (comp, icalcomp)) { - g_object_unref (comp); - icalcomponent_free (icalcomp); - return NULL; - } - - return comp; -} - -static void -adjust_item (EItipControl *itip, ECalComponent *comp) -{ - ECalComponent *real_comp; - - real_comp = get_real_item (itip); - if (real_comp != NULL) { - ECalComponentText text; - const char *string; - GSList *l; - - e_cal_component_get_summary (real_comp, &text); - e_cal_component_set_summary (comp, &text); - e_cal_component_get_location (real_comp, &string); - e_cal_component_set_location (comp, string); - e_cal_component_get_description_list (real_comp, &l); - e_cal_component_set_description_list (comp, l); - e_cal_component_free_text_list (l); - - g_object_unref (real_comp); - } else { - ECalComponentText text = {_("Unknown"), NULL}; - - e_cal_component_set_summary (comp, &text); - } -} - -static void -show_current_event (EItipControl *itip) -{ - EItipControlPrivate *priv; - const gchar *itip_title, *itip_desc; - char *options; - - priv = itip->priv; - - if (priv->calendar_uri) - priv->event_client = start_calendar_server (itip, priv->calendar_uri); - else - priv->event_client = find_server (priv->event_clients, priv->comp); - - switch (priv->method) { - case ICAL_METHOD_PUBLISH: - itip_desc = _("<b>%s</b> has published meeting information."); - itip_title = _("Meeting Information"); - options = get_publish_options (priv->event_client ? FALSE : TRUE); - break; - case ICAL_METHOD_REQUEST: - if (priv->delegator_address != NULL) - itip_desc = _("<b>%s</b> requests the presence of %s at a meeting."); - else - itip_desc = _("<b>%s</b> requests your presence at a meeting."); - itip_title = _("Meeting Proposal"); - options = get_request_options (priv->event_client ? FALSE : TRUE); - break; - case ICAL_METHOD_ADD: - itip_desc = _("<b>%s</b> wishes to add to an existing meeting."); - itip_title = _("Meeting Update"); - options = get_publish_options (priv->event_client ? FALSE : TRUE); - break; - case ICAL_METHOD_REFRESH: - itip_desc = _("<b>%s</b> wishes to receive the latest meeting information."); - itip_title = _("Meeting Update Request"); - options = get_refresh_options (); - - /* Provide extra info, since its not in the component */ - adjust_item (itip, priv->comp); - break; - case ICAL_METHOD_REPLY: - itip_desc = _("<b>%s</b> has replied to a meeting request."); - itip_title = _("Meeting Reply"); - options = get_reply_options (); - - /* Provide extra info, since might not be in the component */ - adjust_item (itip, priv->comp); - break; - case ICAL_METHOD_CANCEL: - itip_desc = _("<b>%s</b> has cancelled a meeting."); - itip_title = _("Meeting Cancellation"); - options = get_cancel_options (); - - /* Provide extra info, since might not be in the component */ - adjust_item (itip, priv->comp); - break; - default: - itip_desc = _("<b>%s</b> has sent an unintelligible message."); - itip_title = _("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; - const gchar *itip_title, *itip_desc; - char *options; - - priv = itip->priv; - - if (priv->calendar_uri) - priv->task_client = start_calendar_server (itip, priv->calendar_uri); - else - priv->task_client = find_server (priv->task_clients, priv->comp); - - switch (priv->method) { - case ICAL_METHOD_PUBLISH: - itip_desc = _("<b>%s</b> has published task information."); - itip_title = _("Task Information"); - options = get_publish_options (priv->task_client ? FALSE : TRUE); - break; - case ICAL_METHOD_REQUEST: - if (priv->delegator_address != NULL) - itip_desc = _("<b>%s</b> requests %s to perform a task."); - else - itip_desc = _("<b>%s</b> requests you perform a task."); - itip_title = _("Task Proposal"); - options = get_request_options (priv->task_client ? FALSE : TRUE); - break; - case ICAL_METHOD_ADD: - itip_desc = _("<b>%s</b> wishes to add to an existing task."); - itip_title = _("Task Update"); - options = get_publish_options (priv->task_client ? FALSE : TRUE); - break; - case ICAL_METHOD_REFRESH: - itip_desc = _("<b>%s</b> wishes to receive the latest task information."); - itip_title = _("Task Update Request"); - options = get_refresh_options (); - - /* Provide extra info, since its not in the component */ - adjust_item (itip, priv->comp); - break; - case ICAL_METHOD_REPLY: - itip_desc = _("<b>%s</b> has replied to a task assignment."); - itip_title = _("Task Reply"); - options = get_reply_options (); - - /* Provide extra info, since might not be in the component */ - adjust_item (itip, priv->comp); - break; - case ICAL_METHOD_CANCEL: - itip_desc = _("<b>%s</b> has cancelled a task."); - itip_title = _("Task Cancellation"); - options = get_cancel_options (); - - /* Provide extra info, since might not be in the component */ - adjust_item (itip, priv->comp); - break; - default: - itip_desc = _("<b>%s</b> has sent an unintelligible message."); - itip_title = _("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 = _("<b>%s</b> has published free/busy information."); - itip_title = _("Free/Busy Information"); - options = NULL; - break; - case ICAL_METHOD_REQUEST: - itip_desc = _("<b>%s</b> requests your free/busy information."); - itip_title = _("Free/Busy Request"); - options = get_request_fb_options (); - break; - case ICAL_METHOD_REPLY: - itip_desc = _("<b>%s</b> has replied to a free/busy request."); - itip_title = _("Free/Busy Reply"); - options = NULL; - break; - default: - itip_desc = _("<b>%s</b> has sent an unintelligible message."); - itip_title = _("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; -} - -static void -show_current (EItipControl *itip) -{ - EItipControlPrivate *priv; - ECalComponentVType type; - icalcomponent *alarm_comp; - icalcompiter alarm_iter; - icalproperty *prop; - - priv = itip->priv; - - g_object_ref (itip); - - if (priv->comp) - g_object_unref (priv->comp); - if (priv->event_client != NULL) - g_object_unref (priv->event_client); - priv->event_client = NULL; - if (priv->task_client != NULL) - g_object_unref (priv->task_client); - priv->task_client = NULL; - - /* Determine any delegate sections */ - prop = icalcomponent_get_first_property (priv->ical_comp, ICAL_X_PROPERTY); - while (prop) { - const char *x_name, *x_val; - - x_name = icalproperty_get_x_name (prop); - x_val = icalproperty_get_x (prop); - - if (!strcmp (x_name, "X-EVOLUTION-DELEGATOR-CALENDAR-URI")) - e_itip_control_set_calendar_uri (itip, x_val); - else if (!strcmp (x_name, "X-EVOLUTION-DELEGATOR-ADDRESS")) - e_itip_control_set_delegator_address (itip, x_val); - else if (!strcmp (x_name, "X-EVOLUTION-DELEGATOR-NAME")) - e_itip_control_set_delegator_name (itip, x_val); - - prop = icalcomponent_get_next_property (priv->ical_comp, ICAL_X_PROPERTY); - } - - /* 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 = e_cal_component_new (); - if (!e_cal_component_set_icalcomponent (priv->comp, priv->ical_comp)) { - write_error_html (itip, _("The message does not appear to be properly formed")); - g_object_unref (priv->comp); - priv->comp = NULL; - g_object_unref (itip); - return; - }; - - /* Add default reminder if the config says so */ - if (calendar_config_get_use_default_reminder ()) { - ECalComponentAlarm *acomp; - int interval; - CalUnits units; - ECalComponentAlarmTrigger trigger; - - interval = calendar_config_get_default_reminder_interval (); - units = calendar_config_get_default_reminder_units (); - - acomp = e_cal_component_alarm_new (); - - e_cal_component_alarm_set_action (acomp, E_CAL_COMPONENT_ALARM_DISPLAY); - - trigger.type = E_CAL_COMPONENT_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 (); - } - - e_cal_component_alarm_set_trigger (acomp, trigger); - e_cal_component_add_alarm (priv->comp, acomp); - - e_cal_component_alarm_free (acomp); - } - - type = e_cal_component_get_vtype (priv->comp); - - switch (type) { - case E_CAL_COMPONENT_EVENT: - if (!priv->event_clients) { - priv->event_clients = g_ptr_array_new (); - /* EPFIXME */ - /* priv->event_clients = get_servers (itip, global_shell_client, calendar_types, FALSE); */ - } - show_current_event (itip); - break; - case E_CAL_COMPONENT_TODO: - if (!priv->task_clients) { - /* EPFIXME */ - /* priv->task_clients = get_servers (itip, global_shell_client, tasks_types, TRUE); */ - } - show_current_todo (itip); - break; - case E_CAL_COMPONENT_FREEBUSY: - show_current_freebusy (itip); - break; - default: - write_error_html (itip, _("The message contains only unsupported requests.")); - } - - find_my_address (itip, priv->ical_comp); - - g_object_unref (itip); -} - -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); - - if (text == NULL || *text == '\0') { - gtk_html_load_from_string (GTK_HTML (priv->html), " ", 1); - return; - } - - priv->vcalendar = g_strdup (text); - priv->top_level = e_cal_util_new_top_level (); - - priv->main_comp = icalparser_parse_string (priv->vcalendar); - if (priv->main_comp == NULL) { - write_error_html (itip, _("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, _("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, _("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; -} - -void -e_itip_control_set_view_only (EItipControl *itip, gint view_only) -{ - EItipControlPrivate *priv; - - priv = itip->priv; - - priv->view_only = view_only; -} - -gint -e_itip_control_get_view_only (EItipControl *itip) -{ - EItipControlPrivate *priv; - - priv = itip->priv; - - return priv->view_only; -} - - -void -e_itip_control_set_delegator_address (EItipControl *itip, const gchar *address) -{ - EItipControlPrivate *priv; - - priv = itip->priv; - - if (priv->delegator_address) - g_free (priv->delegator_address); - - priv->delegator_address = g_strdup (address); -} - -const gchar * -e_itip_control_get_delegator_address (EItipControl *itip) -{ - EItipControlPrivate *priv; - - priv = itip->priv; - - return priv->delegator_address; -} - - -void -e_itip_control_set_delegator_name (EItipControl *itip, const gchar *name) -{ - EItipControlPrivate *priv; - - priv = itip->priv; - - if (priv->delegator_name) - g_free (priv->delegator_name); - - priv->delegator_name = g_strdup (name); -} - -const gchar * -e_itip_control_get_delegator_name (EItipControl *itip) -{ - EItipControlPrivate *priv; - - priv = itip->priv; - - return priv->delegator_name; -} - -void -e_itip_control_set_calendar_uri (EItipControl *itip, const gchar *uri) -{ - EItipControlPrivate *priv; - - priv = itip->priv; - - if (priv->calendar_uri) - g_free (priv->calendar_uri); - - priv->calendar_uri = g_strdup (uri); -} - -const gchar * -e_itip_control_get_calendar_uri (EItipControl *itip) -{ - EItipControlPrivate *priv; - - priv = itip->priv; - - return priv->calendar_uri; -} - - -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 { - EAccount *a; - - a = itip_addresses_get_default (); - - prop = icalproperty_new_attendee (a->id->address); - icalcomponent_add_property (ical_comp, prop); - - param = icalparameter_new_cn (a->id->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); - } - } - - return TRUE; -} - -static void -update_item (EItipControl *itip) -{ - EItipControlPrivate *priv; - struct icaltimetype stamp; - icalproperty *prop; - icalcomponent *clone; - ECal *client; - ECalComponentVType type; - GtkWidget *dialog; - - priv = itip->priv; - - /* Set X-MICROSOFT-CDO-REPLYTIME to record the time at which - * the user accepted/declined the request. (Outlook ignores - * SEQUENCE in REPLY reponses and instead requires that each - * updated response have a later REPLYTIME than the previous - * one.) This also ends up getting saved in our own copy of - * the meeting, though there's currently no way to see that - * information (unless it's being saved to an Exchange folder - * and you then look at it in Outlook). - */ - stamp = icaltime_current_time_with_zone (icaltimezone_get_utc_timezone ()); - prop = icalproperty_new_x (icaltime_as_ical_string (stamp)); - icalproperty_set_x_name (prop, "X-MICROSOFT-CDO-REPLYTIME"); - icalcomponent_add_property (priv->ical_comp, prop); - - type = e_cal_component_get_vtype (priv->comp); - if (type == E_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); - icalcomponent_set_method (priv->top_level, priv->method); - - /* FIXME Better error dialog */ - if (!e_cal_receive_objects (client, priv->top_level, NULL)) { - 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); -} - -#if 0 -static void -update_attendee_status (EItipControl *itip) -{ - EItipControlPrivate *priv; - ECal *client; - ECalGetStatus status; - ECalComponent *comp = NULL; - icalcomponent *icalcomp = NULL; - ECalComponentVType type; - const char *uid; - GtkWidget *dialog; - ECalResult result; - - priv = itip->priv; - - type = e_cal_component_get_vtype (priv->comp); - if (type == E_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 */ - e_cal_component_get_uid (priv->comp, &uid); - status = e_cal_get_object (client, uid, NULL, &icalcomp); - - if (status == E_CAL_GET_SUCCESS) { - GSList *attendees; - - comp = e_cal_component_new (); - if (!e_cal_component_set_icalcomponent (comp, icalcomp)) { - icalcomponent_free (icalcomp); - - dialog = gnome_warning_dialog (_("Object is invalid and cannot be updated\n")); - } else { - e_cal_component_get_attendee_list (priv->comp, &attendees); - if (attendees != NULL) { - ECalComponentAttendee *a = attendees->data; - icalproperty *prop; - - prop = find_attendee (icalcomp, 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 (icalcomp, - itip_strip_mailto (a->value), - a->status); - e_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 (icalcomp, - itip_strip_mailto (a->value), - a->status); - e_cal_component_rescan (comp); - } - } - } - - result = e_cal_update_object (client, comp); - switch (result) { - case E_CAL_RESULT_INVALID_OBJECT : - dialog = gnome_warning_dialog (_("Object is invalid and cannot be updated\n")); - break; - case E_CAL_RESULT_CORBA_ERROR : - dialog = gnome_warning_dialog (_("There was an error on the CORBA system\n")); - break; - case E_CAL_RESULT_NOT_FOUND : - dialog = gnome_warning_dialog (_("Object could not be found\n")); - break; - case E_CAL_RESULT_PERMISSION_DENIED : - dialog = gnome_warning_dialog (_("You don't have the right permissions to update the calendar\n")); - break; - case E_CAL_RESULT_SUCCESS : - dialog = gnome_ok_dialog (_("Attendee status updated\n")); - break; - default : - dialog = gnome_warning_dialog (_("Attendee status could not be updated!\n")); - } - } else { - dialog = gnome_warning_dialog (_("Attendee status can not be updated " - "because the item no longer exists")); - } - - cleanup: - if (comp != NULL) - g_object_unref (comp); - gnome_dialog_run_and_close (GNOME_DIALOG (dialog)); -} -#endif - -static void -remove_item (EItipControl *itip) -{ - EItipControlPrivate *priv; - ECal *client; - ECalComponentVType type; - const char *uid; - GtkWidget *dialog; - GError *error = NULL; - - priv = itip->priv; - - type = e_cal_component_get_vtype (priv->comp); - if (type == E_CAL_COMPONENT_TODO) - client = priv->task_client; - else - client = priv->event_client; - - if (client == NULL) - return; - - e_cal_component_get_uid (priv->comp, &uid); - e_cal_remove_object (client, uid, &error); - if (!error || error->code == E_CALENDAR_STATUS_OBJECT_NOT_FOUND) { - dialog = gnome_ok_dialog (_("Removal Complete")); - gnome_dialog_run_and_close (GNOME_DIALOG (dialog)); - } else { - delete_error_dialog (error, type); - } - - g_clear_error (&error); -} - -static void -send_item (EItipControl *itip) -{ - EItipControlPrivate *priv; - ECalComponent *comp; - ECalComponentVType vtype; - GtkWidget *dialog; - - priv = itip->priv; - - comp = get_real_item (itip); - vtype = e_cal_component_get_vtype (comp); - - if (comp != NULL) { - switch (vtype) { - case E_CAL_COMPONENT_EVENT: - itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, priv->event_client, NULL); - break; - case E_CAL_COMPONENT_TODO: - itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, priv->task_client, NULL); - break; - default: - itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, NULL, NULL); - } - g_object_unref (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; - ECalComponentDateTime datetime; - time_t start, end; - GtkWidget *dialog; - GList *comp_list = NULL; - icaltimezone *zone; - - priv = itip->priv; - - e_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); - e_cal_component_free_datetime (&datetime); - - e_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); - e_cal_component_free_datetime (&datetime); - - if (e_cal_get_free_busy (priv->event_client, NULL, start, end, &comp_list, NULL)) { - GList *l; - - for (l = comp_list; l; l = l->next) { - ECalComponent *comp = E_CAL_COMPONENT (l->data); - itip_send_comp (E_CAL_COMPONENT_METHOD_REPLY, comp, priv->event_client, NULL); - - g_object_unref (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 /* FIXME */ -static void -button_selected_cb (EvolutionFolderSelectorButton *button, GNOME_Evolution_Folder *folder, gpointer data) -{ - EItipControl *itip = E_ITIP_CONTROL (data); - EItipControlPrivate *priv; - ECalComponentVType type; - char *uri; - - priv = itip->priv; - - type = e_cal_component_get_vtype (priv->comp); - if (type == E_CAL_COMPONENT_TODO) - uri = e_cal_util_expand_uri (folder->physicalUri, TRUE); - else - uri = e_cal_util_expand_uri (folder->physicalUri, FALSE); - - g_object_unref (priv->event_client); - priv->event_client = start_calendar_server (itip, uri); - - g_free (uri); -} -#endif - -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_IMAGESDIR, 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); -} - -typedef struct -{ - EItipControl *itip; - GtkHTMLEmbedded *eb; - ECal *client; -} -ObjectRequestContext; - -static void -default_server_started_cb (ECal *client, ECalendarStatus status, gpointer data) -{ - ObjectRequestContext *context = data; - EItipControlPrivate *priv; - GtkWidget *button; - ECalComponentVType vtype; - - priv = context->itip->priv; - - if (status != E_CALENDAR_STATUS_OK || - context->itip->priv->destroyed || - context->itip->priv->html == NULL) { - g_object_unref (context->client); - g_object_unref (context->itip); - g_free (context); - return; - } - - priv->event_client = client; - vtype = e_cal_component_get_vtype (priv->comp); - - switch (vtype) { -#if 0 /* EPFIXME */ - case E_CAL_COMPONENT_EVENT: - button = evolution_folder_selector_button_new ( - global_shell_client, _("Select Calendar Folder"), - calendar_config_default_calendar_folder (), - calendar_types); - break; - case E_CAL_COMPONENT_TODO: - button = evolution_folder_selector_button_new ( - global_shell_client, _("Select Tasks Folder"), - calendar_config_default_tasks_folder (), - tasks_types); - break; -#endif - default: - button = NULL; - } - -#if 0 - g_signal_connect (button, "selected", G_CALLBACK (button_selected_cb), context->itip); -#endif - - gtk_container_add (GTK_CONTAINER (context->eb), button); - gtk_widget_show (button); - - g_object_unref (context->itip); - g_free (context); - return; -} - -static gboolean -object_requested_cb (GtkHTML *html, GtkHTMLEmbedded *eb, gpointer data) -{ - EItipControl *itip = E_ITIP_CONTROL (data); - ObjectRequestContext *context; - EItipControlPrivate *priv; - ECalComponentVType vtype; - gboolean success; - - priv = itip->priv; - vtype = e_cal_component_get_vtype (priv->comp); - - context = g_new0 (ObjectRequestContext, 1); - context->itip = itip; - context->eb = eb; - - switch (vtype) { - case E_CAL_COMPONENT_EVENT: - context->client = e_cal_new_from_uri ("", CALOBJ_TYPE_EVENT); - success = start_default_server (itip, context->client, FALSE); - break; - case E_CAL_COMPONENT_TODO: - context->client = e_cal_new_from_uri ("", CALOBJ_TYPE_TODO); - success = start_default_server (itip, context->client, TRUE); - break; - default: - g_free (context); - return FALSE; - } - - if (!success) { - g_object_unref (context->client); - g_free (context); - return FALSE; - } - - g_object_ref (itip); - - 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) { - e_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) { - e_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) { - e_cal_component_rescan (priv->comp); - remove_item (itip); - } - break; - case 'F': - send_freebusy (itip); - break; - case 'R': - /* FIXME Make sure this does the right thing in the backend */ - update_item (itip); - break; - case 'S': - send_item (itip); - break; - case 'C': - update_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) { - ECalComponent *comp = NULL; - ECalComponentVType vtype; - icalcomponent *ical_comp; - icalproperty *prop; - icalvalue *value; - const char *attendee; - GSList *l, *list = NULL; - - comp = e_cal_component_clone (priv->comp); - if (comp == NULL) - return; - vtype = e_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 = e_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); - - e_cal_component_rescan (comp); - switch (vtype) { - case E_CAL_COMPONENT_EVENT: - itip_send_comp (E_CAL_COMPONENT_METHOD_REPLY, comp, - priv->event_client, priv->top_level); - break; - case E_CAL_COMPONENT_TODO: - itip_send_comp (E_CAL_COMPONENT_METHOD_REPLY, comp, - priv->task_client, priv->top_level); - break; - default: - itip_send_comp (E_CAL_COMPONENT_METHOD_REPLY, comp, NULL, NULL); - } - g_object_unref (comp); - } -} diff --git a/calendar/gui/e-itip-control.glade b/calendar/gui/e-itip-control.glade deleted file mode 100644 index 344bcdeced..0000000000 --- a/calendar/gui/e-itip-control.glade +++ /dev/null @@ -1,493 +0,0 @@ -<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> -<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd" > - -<glade-interface> - <widget class="GtkWindow" id="window1"> - <property name="visible">no</property> - <property name="title" translatable="yes">window1</property> - <property name="type">GTK_WINDOW_TOPLEVEL</property> - <property name="modal">no</property> - <property name="allow_shrink">no</property> - <property name="allow_grow">yes</property> - <property name="window-position">GTK_WIN_POS_NONE</property> - - <child> - <widget class="GtkFrame" id="main_frame"> - <property name="border_width">4</property> - <property name="label" translatable="yes">Calendar Message</property> - <property name="label_xalign">0</property> - <property name="shadow">GTK_SHADOW_ETCHED_IN</property> - <property name="visible">yes</property> - - <child> - <widget class="GtkScrolledWindow" id="scrolledwindow1"> - <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> - <property name="vscrollbar_policy">GTK_POLICY_NEVER</property> - <property name="visible">yes</property> - - <child> - <widget class="GtkViewport" id="viewport1"> - <property name="shadow_type">GTK_SHADOW_NONE</property> - <property name="visible">yes</property> - - <child> - <widget class="GtkVBox" id="vbox1"> - <property name="homogeneous">no</property> - <property name="spacing">0</property> - <property name="visible">yes</property> - - <child> - <widget class="GtkTable" id="table1"> - <property name="border_width">3</property> - <property name="homogeneous">no</property> - <property name="row_spacing">3</property> - <property name="column_spacing">3</property> - <property name="n-rows">4</property> - <property name="n-columns">2</property> - <property name="visible">yes</property> - - <child> - <widget class="GtkEntry" id="organizer_entry"> - <property name="can_focus">yes</property> - <property name="editable">no</property> - <property name="text" translatable="yes"></property> - <property name="max-length">0</property> - <property name="visibility">yes</property> - <property name="visible">yes</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="x_padding">0</property> - <property name="y_padding">0</property> - <property name="x_options">expand|fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkEntry" id="summary_entry"> - <property name="can_focus">yes</property> - <property name="editable">no</property> - <property name="text" translatable="yes"></property> - <property name="max-length">0</property> - <property name="visibility">yes</property> - <property name="visible">yes</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_padding">0</property> - <property name="y_padding">0</property> - <property name="x_options">expand|fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkScrolledWindow" id="scrolledwindow2"> - <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="shadow_type">GTK_SHADOW_IN</property> - <property name="visible">yes</property> - - <child> - <widget class="GtkTextView" id="description_box"> - <property name="can_focus">yes</property> - <property name="editable">no</property> - <property name="text" translatable="yes"></property> - <property name="wrap_mode">GTK_WRAP_WORD</property> - <property name="visible">yes</property> - </widget> - </child> - - <child internal-child="hscrollbar"> - <widget class="GtkHScrollbar" id="convertwidget3"> - <property name="update_policy">GTK_UPDATE_CONTINUOUS</property> - <property name="visible">yes</property> - </widget> - </child> - - <child internal-child="vscrollbar"> - <widget class="GtkVScrollbar" id="convertwidget4"> - <property name="update_policy">GTK_UPDATE_CONTINUOUS</property> - <property name="visible">yes</property> - </widget> - </child> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">3</property> - <property name="bottom_attach">4</property> - <property name="x_padding">0</property> - <property name="y_padding">0</property> - <property name="x_options">fill</property> - <property name="y_options">fill</property> - </packing> - </child> - - <child> - <widget class="GtkAlignment" id="alignment1"> - <property name="xalign">0</property> - <property name="yalign">0</property> - <property name="xscale">1</property> - <property name="yscale">1</property> - <property name="visible">yes</property> - - <child> - <widget class="GtkHBox" id="hbox1"> - <property name="homogeneous">no</property> - <property name="spacing">0</property> - <property name="visible">yes</property> - - <child> - <widget class="GtkLabel" id="dtstart_label"> - <property name="label" translatable="yes">date-start</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">no</property> - <property name="xalign">0.5</property> - <property name="yalign">0</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="visible">yes</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">no</property> - <property name="fill">no</property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label3"> - <property name="label" translatable="yes">--to--</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">no</property> - <property name="xalign">0.5</property> - <property name="yalign">0</property> - <property name="xpad">19</property> - <property name="ypad">0</property> - <property name="visible">yes</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">no</property> - <property name="fill">no</property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="dtend_label"> - <property name="label" translatable="yes">date-end</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">no</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="visible">yes</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">no</property> - <property name="fill">no</property> - </packing> - </child> - </widget> - </child> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_padding">0</property> - <property name="y_padding">0</property> - <property name="x_options">expand|fill</property> - <property name="y_options">fill</property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label6"> - <property name="label" translatable="yes">Organizer:</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">no</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="visible">yes</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="x_padding">0</property> - <property name="y_padding">0</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label7"> - <property name="label" translatable="yes">Date:</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">no</property> - <property name="xalign">0</property> - <property name="yalign">0</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="visible">yes</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_padding">0</property> - <property name="y_padding">0</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label8"> - <property name="label" translatable="yes">Summary:</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">no</property> - <property name="xalign">0</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="visible">yes</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_padding">0</property> - <property name="y_padding">0</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label9"> - <property name="label" translatable="yes">Description:</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">no</property> - <property name="xalign">0</property> - <property name="yalign">0</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="visible">yes</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">3</property> - <property name="bottom_attach">4</property> - <property name="x_padding">0</property> - <property name="y_padding">0</property> - <property name="x_options">fill</property> - <property name="y_options">fill</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">6</property> - <property name="expand">yes</property> - <property name="fill">yes</property> - </packing> - </child> - - <child> - <widget class="GtkLabel" id="label12"> - <property name="label" translatable="yes">Server Message:</property> - <property name="justify">GTK_JUSTIFY_LEFT</property> - <property name="wrap">no</property> - <property name="xalign">7.45058e-09</property> - <property name="yalign">0.5</property> - <property name="xpad">3</property> - <property name="ypad">0</property> - <property name="visible">yes</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">no</property> - <property name="fill">no</property> - </packing> - </child> - - <child> - <widget class="GtkScrolledWindow" id="scrolledwindow3"> - <property name="border_width">3</property> - <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> - <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> - <property name="shadow_type">GTK_SHADOW_IN</property> - <property name="width-request">365</property> - <property name="visible">yes</property> - - <child> - <widget class="GtkTextView" id="message_text"> - <property name="can_focus">yes</property> - <property name="editable">no</property> - <property name="text" translatable="yes"></property> - <property name="wrap_mode">GTK_WRAP_WORD</property> - <property name="visible">yes</property> - </widget> - </child> - - <child internal-child="hscrollbar"> - <widget class="GtkHScrollbar" id="convertwidget5"> - <property name="update_policy">GTK_UPDATE_CONTINUOUS</property> - <property name="visible">yes</property> - </widget> - </child> - - <child internal-child="vscrollbar"> - <widget class="GtkVScrollbar" id="convertwidget6"> - <property name="update_policy">GTK_UPDATE_CONTINUOUS</property> - <property name="visible">yes</property> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">yes</property> - <property name="fill">no</property> - </packing> - </child> - - <child> - <widget class="GtkHBox" id="button_box"> - <property name="border_width">3</property> - <property name="homogeneous">no</property> - <property name="spacing">0</property> - <property name="height-request">30</property> - <property name="visible">yes</property> - - <child> - <placeholder /> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">no</property> - <property name="fill">no</property> - </packing> - </child> - </widget> - </child> - </widget> - </child> - - <child internal-child="hscrollbar"> - <widget class="GtkHScrollbar" id="convertwidget1"> - <property name="update_policy">GTK_UPDATE_CONTINUOUS</property> - <property name="visible">yes</property> - </widget> - </child> - - <child internal-child="vscrollbar"> - <widget class="GtkVScrollbar" id="convertwidget2"> - <property name="update_policy">GTK_UPDATE_CONTINUOUS</property> - <property name="visible">yes</property> - </widget> - </child> - </widget> - </child> - </widget> - </child> - </widget> - <widget class="GtkWindow" id="loading_window"> - <property name="visible">no</property> - <property name="title" translatable="yes">Loading Calendar</property> - <property name="type">GTK_WINDOW_DIALOG</property> - <property name="modal">no</property> - <property name="allow_shrink">no</property> - <property name="allow_grow">yes</property> - <property name="window-position">GTK_WIN_POS_CENTER</property> - - <child> - <widget class="GtkFrame" id="frame1"> - <property name="border_width">4</property> - <property name="label" translatable="yes"></property> - <property name="label_xalign">0</property> - <property name="shadow">GTK_SHADOW_ETCHED_OUT</property> - <property name="visible">yes</property> - - <child> - <widget class="GtkVBox" id="vbox2"> - <property name="border_width">7</property> - <property name="homogeneous">no</property> - <property name="spacing">1</property> - <property name="visible">yes</property> - - <child> - <widget class="GtkHBox" id="hbox2"> - <property name="border_width">6</property> - <property name="homogeneous">no</property> - <property name="spacing">9</property> - <property name="visible">yes</property> - - <child> - <widget class="GtkLabel" id="label10"> - <property name="label" translatable="yes">Loading calendar...</property> - <property name="justify">GTK_JUSTIFY_CENTER</property> - <property name="wrap">no</property> - <property name="xalign">0.5</property> - <property name="yalign">0.5</property> - <property name="xpad">0</property> - <property name="ypad">0</property> - <property name="visible">yes</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">no</property> - <property name="fill">no</property> - </packing> - </child> - - <child> - <widget class="GtkProgressBar" id="loading_progress"> - <property name="bar_style">GTK_PROGRESS_CONTINUOUS</property> - <property name="orientation">GTK_PROGRESS_LEFT_TO_RIGHT</property> - <property name="activity_mode">no</property> - <property name="show_text">no</property> - <property name="format" translatable="yes">%P %%</property> - <property name="text_xalign">0.5</property> - <property name="text_yalign">0.5</property> - <property name="visible">yes</property> - <property name="adjustment">0 0 100 1 10 10</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">no</property> - <property name="fill">no</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">no</property> - <property name="fill">no</property> - </packing> - </child> - </widget> - </child> - </widget> - </child> - </widget> -</glade-interface> diff --git a/calendar/gui/e-itip-control.h b/calendar/gui/e-itip-control.h deleted file mode 100644 index 12ddf7354e..0000000000 --- a/calendar/gui/e-itip-control.h +++ /dev/null @@ -1,82 +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); -void e_itip_control_set_view_only (EItipControl *itip, - gboolean view_only); -gboolean e_itip_control_get_view_only (EItipControl *itip); -void e_itip_control_set_delegator_address (EItipControl *itip, - const gchar *address); -const gchar *e_itip_control_get_delegator_address (EItipControl *itip); -void e_itip_control_set_delegator_name (EItipControl *itip, - const gchar *name); -const gchar *e_itip_control_get_delegator_name (EItipControl *itip); -void e_itip_control_set_calendar_uri (EItipControl *itip, - const gchar *uri); -const gchar *e_itip_control_get_calendar_uri (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 474cf7b1a4..0000000000 --- a/calendar/gui/e-meeting-attendee.c +++ /dev/null @@ -1,1000 +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 <gal/util/e-util.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; - - EMeetingAttendeeEditLevel edit_level; - - 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 finalize (GObject *obj); - - -static GObjectClass *parent_class = NULL; - -E_MAKE_TYPE (e_meeting_attendee, "EMeetingAttendee", EMeetingAttendee, - class_init, init, G_TYPE_OBJECT); - -static void -class_init (EMeetingAttendeeClass *klass) -{ - GObjectClass *object_class; - - object_class = G_OBJECT_CLASS (klass); - parent_class = g_type_class_peek_parent (klass); - - signals[CHANGED] = - g_signal_new ("changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (EMeetingAttendeeClass, changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - object_class->finalize = finalize; -} - -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) -{ - g_signal_emit_by_name (G_OBJECT (ia), "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->edit_level = E_MEETING_ATTENDEE_EDIT_FULL; - 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 -finalize (GObject *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); - - if (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (obj); -} - -GObject * -e_meeting_attendee_new (void) -{ - return g_object_new (E_TYPE_MEETING_ATTENDEE, NULL); -} - -GObject * -e_meeting_attendee_new_from_e_cal_component_attendee (ECalComponentAttendee *ca) -{ - EMeetingAttendee *ia; - - ia = E_MEETING_ATTENDEE (g_object_new (E_TYPE_MEETING_ATTENDEE, NULL)); - - 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 G_OBJECT (ia); -} - -ECalComponentAttendee * -e_meeting_attendee_as_e_cal_component_attendee (EMeetingAttendee *ia) -{ - EMeetingAttendeePrivate *priv; - ECalComponentAttendee *ca; - - priv = ia->priv; - - ca = g_new0 (ECalComponentAttendee, 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; -} - - -EMeetingAttendeeEditLevel -e_meeting_attendee_get_edit_level (EMeetingAttendee *ia) -{ - EMeetingAttendeePrivate *priv; - - g_return_val_if_fail (ia != NULL, E_MEETING_ATTENDEE_EDIT_NONE); - g_return_val_if_fail (E_IS_MEETING_ATTENDEE (ia), E_MEETING_ATTENDEE_EDIT_NONE); - - priv = ia->priv; - - return priv->edit_level; -} - -void -e_meeting_attendee_set_edit_level (EMeetingAttendee *ia, EMeetingAttendeeEditLevel level) -{ - EMeetingAttendeePrivate *priv; - - g_return_if_fail (ia != NULL); - g_return_if_fail (E_IS_MEETING_ATTENDEE (ia)); - - priv = ia->priv; - - priv->edit_level = level; -} - - -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 42c5e13c2e..0000000000 --- a/calendar/gui/e-meeting-attendee.h +++ /dev/null @@ -1,172 +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 <libecal/e-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) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_MEETING_ATTENDEE, EMeetingAttendee)) -#define E_MEETING_ATTENDEE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_MEETING_ATTENDEE, EMeetingAttendeeClass)) -#define E_IS_MEETING_ATTENDEE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_MEETING_ATTENDEE)) -#define E_IS_MEETING_ATTENDEE_CLASS(klass) (G_TYPE_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; - -typedef enum -{ - E_MEETING_ATTENDEE_EDIT_FULL, - E_MEETING_ATTENDEE_EDIT_STATUS, - E_MEETING_ATTENDEE_EDIT_NONE -} EMeetingAttendeeEditLevel; - -struct _EMeetingAttendee { - GtkObject parent; - - EMeetingAttendeePrivate *priv; -}; - -struct _EMeetingAttendeeClass { - GtkObjectClass parent_class; - - void (* changed) (EMeetingAttendee *ia); -}; - - -GType e_meeting_attendee_get_type (void); -GObject *e_meeting_attendee_new (void); -GObject *e_meeting_attendee_new_from_e_cal_component_attendee (ECalComponentAttendee *ca); - -ECalComponentAttendee *e_meeting_attendee_as_e_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); - -EMeetingAttendeeEditLevel e_meeting_attendee_get_edit_level (EMeetingAttendee *ia); -void e_meeting_attendee_set_edit_level (EMeetingAttendee *ia, EMeetingAttendeeEditLevel level); - -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-list-view.c b/calendar/gui/e-meeting-list-view.c deleted file mode 100644 index 5613f6adea..0000000000 --- a/calendar/gui/e-meeting-list-view.c +++ /dev/null @@ -1,460 +0,0 @@ -/* - * e-meeting-list-view.c - * - * Authors: Mike Kestner <mkestner@ximian.com> - * JP Rosevear <jpr@ximian.com> - * - * Copyright (C) 2003 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <glib.h> -#include <gtk/gtktreemodel.h> -#include <bonobo/bonobo-control.h> -#include <bonobo/bonobo-widget.h> -#include <bonobo/bonobo-exception.h> -#include <libgnome/gnome-i18n.h> -#include <libgnome/gnome-util.h> -#include <libgnomevfs/gnome-vfs.h> -#include <libebook/e-book.h> -#include <libebook/e-vcard.h> -#include <libecal/e-cal-component.h> -#include <libecal/e-cal-util.h> -#include <libecal/e-cal-time-util.h> -#include "Evolution-Addressbook-SelectNames.h" -#include "calendar-config.h" -#include "e-meeting-list-view.h" -#include <misc/e-cell-renderer-combo.h> -#include <addressbook/util/eab-destination.h> -#include "e-select-names-renderer.h" - -#define SELECT_NAMES_OAFID "OAFIID:GNOME_Evolution_Addressbook_SelectNames:" BASE_VERSION - -struct _EMeetingListViewPrivate -{ - EMeetingStore *store; - - EBook *ebook; - - GNOME_Evolution_Addressbook_SelectNames corba_select_names; -}; - -#define BUF_SIZE 1024 - -static char *sections[] = {N_("Chair Persons"), - N_("Required Participants"), - N_("Optional Participants"), - N_("Resources"), - NULL}; -static icalparameter_role roles[] = {ICAL_ROLE_CHAIR, - ICAL_ROLE_REQPARTICIPANT, - ICAL_ROLE_OPTPARTICIPANT, - ICAL_ROLE_NONPARTICIPANT, - ICAL_ROLE_NONE}; - -static GtkTreeViewClass *parent_class = NULL; - -static void -start_addressbook_server (EMeetingListView *view) -{ - GError *error = NULL; - - view->priv->ebook = e_book_new (); - if (!e_book_load_local_addressbook (view->priv->ebook, &error)) { - g_warning ("start_addressbook_server(): %s", error->message); - g_error_free (error); - - return; - } -} - -static void -emlv_finalize (GObject *obj) -{ - EMeetingListView *view = E_MEETING_LIST_VIEW (obj); - EMeetingListViewPrivate *priv = view->priv; - - if (priv->ebook != NULL) - g_object_unref (priv->ebook); - - if (priv->corba_select_names != CORBA_OBJECT_NIL) { - CORBA_Environment ev; - CORBA_exception_init (&ev); - bonobo_object_release_unref (priv->corba_select_names, &ev); - CORBA_exception_free (&ev); - } - - g_free (priv); - - if (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (obj); -} - -static void -emlv_class_init (GObjectClass *klass) -{ - parent_class = g_type_class_peek_parent (klass); - - klass->finalize = emlv_finalize; -} - - -static void -emlv_init (EMeetingListView *view) -{ - EMeetingListViewPrivate *priv; - - priv = g_new0 (EMeetingListViewPrivate, 1); - - view->priv = priv; - - priv->corba_select_names = CORBA_OBJECT_NIL; - - start_addressbook_server (view); -} - -E_MAKE_TYPE (e_meeting_list_view, "EMeetingListView", EMeetingListView, emlv_class_init, emlv_init, GTK_TYPE_TREE_VIEW); -static GList * -get_type_strings () -{ - GList *strings = NULL; - - strings = g_list_append (strings, (char*) _("Individual")); - strings = g_list_append (strings, (char*) _("Group")); - strings = g_list_append (strings, (char*) _("Resource")); - strings = g_list_append (strings, (char*) _("Room")); - strings = g_list_append (strings, (char*) _("Unknown")); - - return strings; -} - -static GList * -get_role_strings () -{ - GList *strings = NULL; - - strings = g_list_append (strings, (char*) _("Chair")); - strings = g_list_append (strings, (char*) _("Required Participant")); - strings = g_list_append (strings, (char*) _("Optional Participant")); - strings = g_list_append (strings, (char*) _("Non-Participant")); - strings = g_list_append (strings, (char*) _("Unknown")); - - return strings; -} - -static GList * -get_rsvp_strings () -{ - GList *strings = NULL; - - strings = g_list_append (strings, (char*) _("Yes")); - strings = g_list_append (strings, (char*) _("No")); - - return strings; -} - -static GList * -get_status_strings () -{ - GList *strings = NULL; - - strings = g_list_append (strings, (char*) _("Needs Action")); - strings = g_list_append (strings, (char*) _("Accepted")); - strings = g_list_append (strings, (char*) _("Declined")); - strings = g_list_append (strings, (char*) _("Tentative")); - strings = g_list_append (strings, (char*) _("Delegated")); - - return strings; -} - -static void -value_edited (GtkTreeView *view, gint col, const gchar *path, const gchar *text) -{ - EMeetingStore *model = E_MEETING_STORE (gtk_tree_view_get_model (view)); - GtkTreePath *treepath = gtk_tree_path_new_from_string (path); - int row = gtk_tree_path_get_indices (treepath)[0]; - - e_meeting_store_set_value (model, row, col, text); - gtk_tree_path_free (treepath); -} - -static void -attendee_edited_cb (GtkCellRenderer *renderer, const gchar *path, const gchar *address, const gchar *name, GtkTreeView *view) -{ - value_edited (view, E_MEETING_STORE_ADDRESS_COL, path, address); - value_edited (view, E_MEETING_STORE_CN_COL, path, name); -} - -static void -type_edited_cb (GtkCellRenderer *renderer, const gchar *path, const gchar *text, GtkTreeView *view) -{ - value_edited (view, E_MEETING_STORE_TYPE_COL, path, text); -} - -static void -role_edited_cb (GtkCellRenderer *renderer, const gchar *path, const gchar *text, GtkTreeView *view) -{ - value_edited (view, E_MEETING_STORE_ROLE_COL, path, text); -} - -static void -rsvp_edited_cb (GtkCellRenderer *renderer, const gchar *path, const gchar *text, GtkTreeView *view) -{ - value_edited (view, E_MEETING_STORE_RSVP_COL, path, text); -} - -static void -status_edited_cb (GtkCellRenderer *renderer, const gchar *path, const gchar *text, GtkTreeView *view) -{ - value_edited (view, E_MEETING_STORE_STATUS_COL, path, text); -} - -static void -build_table (GtkTreeView *view) -{ - GtkCellRenderer *renderer; - - gtk_tree_view_set_headers_visible (view, TRUE); - gtk_tree_view_set_rules_hint (view, TRUE); - - renderer = e_select_names_renderer_new (); - g_object_set (G_OBJECT (renderer), "editable", TRUE, NULL); - gtk_tree_view_insert_column_with_attributes (view, -1, _("Attendee"), renderer, - "text", E_MEETING_STORE_ATTENDEE_COL, - "address", E_MEETING_STORE_ADDRESS_COL, - "underline", E_MEETING_STORE_ATTENDEE_UNDERLINE_COL, - NULL); - g_signal_connect (renderer, "cell_edited", G_CALLBACK (attendee_edited_cb), view); - - renderer = e_cell_renderer_combo_new (); - g_object_set (G_OBJECT (renderer), "list", get_type_strings (), "editable", TRUE, NULL); - gtk_tree_view_insert_column_with_attributes (view, -1, _("Type"), renderer, - "text", E_MEETING_STORE_TYPE_COL, - NULL); - g_signal_connect (renderer, "edited", G_CALLBACK (type_edited_cb), view); - - renderer = e_cell_renderer_combo_new (); - g_object_set (G_OBJECT (renderer), "list", get_role_strings (), "editable", TRUE, NULL); - gtk_tree_view_insert_column_with_attributes (view, -1, _("Role"), renderer, - "text", E_MEETING_STORE_ROLE_COL, - NULL); - g_signal_connect (renderer, "edited", G_CALLBACK (role_edited_cb), view); - - renderer = e_cell_renderer_combo_new (); - g_object_set (G_OBJECT (renderer), "list", get_rsvp_strings (), "editable", TRUE, NULL); - gtk_tree_view_insert_column_with_attributes (view, -1, _("RSVP"), renderer, - "text", E_MEETING_STORE_RSVP_COL, - NULL); - g_signal_connect (renderer, "edited", G_CALLBACK (rsvp_edited_cb), view); - - renderer = e_cell_renderer_combo_new (); - g_object_set (G_OBJECT (renderer), "list", get_status_strings (), "editable", TRUE, NULL); - gtk_tree_view_insert_column_with_attributes (view, -1, _("Status"), renderer, - "text", E_MEETING_STORE_STATUS_COL, - NULL); - g_signal_connect (renderer, "edited", G_CALLBACK (status_edited_cb), view); -} - -EMeetingListView * -e_meeting_list_view_new (EMeetingStore *store) -{ - EMeetingListView *view = g_object_new (E_TYPE_MEETING_LIST_VIEW, NULL); - - if (view) { - view->priv->store = store; - gtk_tree_view_set_model (GTK_TREE_VIEW (view), GTK_TREE_MODEL (store)); - build_table (GTK_TREE_VIEW (view)); - } - - return view; -} - -void -e_meeting_list_view_column_set_visible (EMeetingListView *view, const gchar *col_name, gboolean visible) -{ - GList *cols, *l; - - cols = gtk_tree_view_get_columns (GTK_TREE_VIEW (view)); - - for (l = cols; l; l = l->next) { - GtkTreeViewColumn *col = (GtkTreeViewColumn *) l->data; - - if (strcmp (gtk_tree_view_column_get_title (col), col_name) == 0) { - gtk_tree_view_column_set_visible (col, visible); - break; - } - } -} - -static void -process_section (EMeetingListView *view, EABDestination **cards, icalparameter_role role) -{ - EMeetingListViewPrivate *priv; - int i; - - priv = view->priv; - for (i = 0; i < G_N_ELEMENTS (cards); i++) { - const char *name, *attendee = NULL; - char *attr = NULL; - - name = eab_destination_get_name (cards[i]); - - /* Get the field as attendee from the backend */ - if (e_cal_get_ldap_attribute (e_meeting_store_get_e_cal (priv->store), - &attr, NULL)) { - /* FIXME this should be more general */ - if (!g_ascii_strcasecmp (attr, "icscalendar")) { - EContact *contact; - - /* FIXME: this does not work, have to use first - eab_destination_use_contact() */ - contact = eab_destination_get_contact (cards[i]); - if (contact) { - attendee = e_contact_get (contact, E_CONTACT_FREEBUSY_URL); - if (!attendee) - attendee = e_contact_get (contact, E_CONTACT_CALENDAR_URI); - } - } - } - - /* If we couldn't get the attendee prior, get the email address as the default */ - if (attendee == NULL || *attendee == '\0') { - attendee = eab_destination_get_email (cards[i]); - } - - if (attendee == NULL || *attendee == '\0') - continue; - - if (e_meeting_store_find_attendee (priv->store, attendee, NULL) == NULL) { - EMeetingAttendee *ia = e_meeting_store_add_attendee_with_defaults (priv->store); - - e_meeting_attendee_set_address (ia, g_strdup_printf ("MAILTO:%s", attendee)); - e_meeting_attendee_set_role (ia, role); - if (role == ICAL_ROLE_NONPARTICIPANT) - e_meeting_attendee_set_cutype (ia, ICAL_CUTYPE_RESOURCE); - e_meeting_attendee_set_cn (ia, g_strdup (name)); - } - } -} - -static void -select_names_ok_cb (BonoboListener *listener, const char *event_name, const CORBA_any *arg, CORBA_Environment *ev, gpointer data) -{ - EMeetingListView *view = E_MEETING_LIST_VIEW (data); - int i; - - for (i = 0; sections[i] != NULL; i++) { - EABDestination **destv; - char *string = NULL; - Bonobo_Control corba_control = GNOME_Evolution_Addressbook_SelectNames_getEntryBySection - (view->priv->corba_select_names, sections[i], ev); - GtkWidget *control_widget = bonobo_widget_new_control_from_objref (corba_control, CORBA_OBJECT_NIL); - - bonobo_widget_get_property (BONOBO_WIDGET (control_widget), "destinations", - TC_CORBA_string, &string, NULL); - destv = eab_destination_importv (string); - if (destv) { - process_section (view, destv, roles[i]); - g_free (destv); - } - } -} - -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 (EMeetingListView *view) -{ - EMeetingListViewPrivate *priv; - CORBA_Environment ev; - int i; - - priv = view->priv; - - CORBA_exception_init (&ev); - - if (priv->corba_select_names != CORBA_OBJECT_NIL) { - int i; - - for (i = 0; sections[i] != NULL; i++) { - GtkWidget *control_widget; - Bonobo_Control corba_control = GNOME_Evolution_Addressbook_SelectNames_getEntryBySection - (priv->corba_select_names, sections[i], &ev); - if (BONOBO_EX (&ev)) { - CORBA_exception_free (&ev); - return FALSE; - } - - control_widget = bonobo_widget_new_control_from_objref (corba_control, CORBA_OBJECT_NIL); - - bonobo_widget_set_property (BONOBO_WIDGET (control_widget), "text", TC_CORBA_string, "", NULL); - } - CORBA_exception_free (&ev); - - return TRUE; - } - - priv->corba_select_names = bonobo_activation_activate_from_id (SELECT_NAMES_OAFID, 0, NULL, &ev); - - for (i = 0; sections[i] != NULL; i++) - add_section (priv->corba_select_names, sections[i]); - - bonobo_event_source_client_add_listener (priv->corba_select_names, - (BonoboListenerCallbackFn) select_names_ok_cb, - "GNOME/Evolution:ok:dialog", NULL, view); - - if (BONOBO_EX (&ev)) { - CORBA_exception_free (&ev); - return FALSE; - } - - CORBA_exception_free (&ev); - - return TRUE; -} - -void -e_meeting_list_view_invite_others_dialog (EMeetingListView *view) -{ - CORBA_Environment ev; - - if (!get_select_name_dialog (view)) - return; - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_SelectNames_activateDialog ( - view->priv->corba_select_names, _("Required Participants"), &ev); - - CORBA_exception_free (&ev); -} - diff --git a/calendar/gui/e-meeting-list-view.h b/calendar/gui/e-meeting-list-view.h deleted file mode 100644 index dd539b9652..0000000000 --- a/calendar/gui/e-meeting-list-view.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * e-meeting-list-view.h - * - * Author: Mike Kestner <mkestner@ximian.com> - * - * Copyright (C) 2003 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef _E_MEETING_LIST_VIEW_H_ -#define _E_MEETING_LIST_VIEW_H_ - -#include <gtk/gtktreeview.h> -#include "e-meeting-store.h" - -G_BEGIN_DECLS - -#define E_TYPE_MEETING_LIST_VIEW (e_meeting_list_view_get_type ()) -#define E_MEETING_LIST_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_MEETING_LIST_VIEW, EMeetingListView)) -#define E_MEETING_LIST_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_MEETING_LIST_VIEW, EMeetingListViewClass)) -#define E_IS_MEETING_LIST_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_MEETING_LIST_VIEW)) -#define E_IS_MEETING_LIST_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_MEETING_LIST_VIEW)) - - -typedef struct _EMeetingListView EMeetingListView; -typedef struct _EMeetingListViewPrivate EMeetingListViewPrivate; -typedef struct _EMeetingListViewClass EMeetingListViewClass; - -struct _EMeetingListView { - GtkTreeView parent; - - EMeetingListViewPrivate *priv; -}; - -struct _EMeetingListViewClass { - GtkTreeViewClass parent_class; -}; - -GType e_meeting_list_view_get_type (void); - -EMeetingListView *e_meeting_list_view_new (EMeetingStore *store); - -void e_meeting_list_view_column_set_visible (EMeetingListView *emlv, const gchar *col_name, gboolean visible); - -void e_meeting_list_view_invite_others_dialog (EMeetingListView *emlv); - -G_END_DECLS - -#endif diff --git a/calendar/gui/e-meeting-model.c b/calendar/gui/e-meeting-model.c deleted file mode 100644 index 559ede9b6c..0000000000 --- a/calendar/gui/e-meeting-model.c +++ /dev/null @@ -1,1780 +0,0 @@ -/* -*- Mod:e C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* itip-model.c - * - * Copyright (C) 2001 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: JP Rosevear - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <glib.h> -#include <bonobo/bonobo-control.h> -#include <bonobo/bonobo-widget.h> -#include <bonobo/bonobo-exception.h> -#include <libgnome/gnome-i18n.h> -#include <libgnome/gnome-util.h> -#include <libgnomevfs/gnome-vfs.h> -#include <gal/e-table/e-table-without.h> -#include <gal/e-table/e-cell-text.h> -#include <gal/e-table/e-cell-popup.h> -#include <gal/e-table/e-cell-combo.h> -#include <addressbook/util/eab-destination.h> -#include <ebook/e-book.h> -#include <ebook/e-book-async.h> -#include <ebook/e-contact.h> -#include <libecal/e-cal-component.h> -#include <libecal/e-cal-util.h> -#include <libecal/e-cal-time-util.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:" BASE_VERSION - -struct _EMeetingModelPrivate -{ - GPtrArray *attendees; - - GList *tables; - - ECal *client; - icaltimezone *zone; - - EBook *ebook; - gboolean book_loaded; - gboolean book_load_wait; - - GPtrArray *refresh_queue; - GHashTable *refresh_data; - guint refresh_idle_id; - - /* For invite others dialogs */ - GNOME_Evolution_Addressbook_SelectNames corba_select_names; -}; - -#define BUF_SIZE 1024 - -static char *sections[] = {N_("Chair Persons"), - N_("Required Participants"), - N_("Optional Participants"), - N_("Resources"), - NULL}; -static icalparameter_role roles[] = {ICAL_ROLE_CHAIR, - ICAL_ROLE_REQPARTICIPANT, - ICAL_ROLE_OPTPARTICIPANT, - ICAL_ROLE_NONPARTICIPANT, - ICAL_ROLE_NONE}; - -typedef struct _EMeetingModelQueueData EMeetingModelQueueData; -struct _EMeetingModelQueueData { - EMeetingModel *im; - EMeetingAttendee *ia; - - gboolean refreshing; - - EMeetingTime start; - EMeetingTime end; - - char buffer[BUF_SIZE]; - GString *string; - - GPtrArray *call_backs; - GPtrArray *data; -}; - - -static void class_init (EMeetingModelClass *klass); -static void init (EMeetingModel *model); -static void finalize (GObject *obj); - -static void refresh_queue_add (EMeetingModel *im, int row, - EMeetingTime *start, - EMeetingTime *end, - EMeetingModelRefreshCallback call_back, - gpointer data); -static void refresh_queue_remove (EMeetingModel *im, - EMeetingAttendee *ia); -static gboolean refresh_busy_periods (gpointer data); - -static void attendee_changed_cb (EMeetingAttendee *ia, gpointer data); -static void select_names_ok_cb (BonoboListener *listener, - const char *event_name, - const CORBA_any *arg, - CORBA_Environment *ev, - gpointer data); - -static void table_destroy_state_cb (ETableScrolled *etable, gpointer data); -static void table_destroy_list_cb (ETableScrolled *etable, gpointer data); - -static ETableModelClass *parent_class = NULL; - -E_MAKE_TYPE (e_meeting_model, "EMeetingModel", EMeetingModel, - class_init, init, E_TABLE_MODEL_TYPE); - -static void -book_open_cb (EBook *book, EBookStatus status, gpointer data) -{ - EMeetingModel *im = E_MEETING_MODEL (data); - EMeetingModelPrivate *priv; - - priv = im->priv; - - priv->ebook = book; - - if (status == E_BOOK_ERROR_OK) - priv->book_loaded = TRUE; - else - g_warning ("Book not loaded"); - - if (priv->book_load_wait) { - priv->book_load_wait = FALSE; - gtk_main_quit (); - } -} - -static void -start_addressbook_server (EMeetingModel *im) -{ - e_book_async_get_default_addressbook (book_open_cb, im); -} - -static EMeetingAttendee * -find_match (EMeetingModel *im, const char *address, int *pos) -{ - EMeetingModelPrivate *priv; - EMeetingAttendee *ia; - const gchar *ia_address; - int i; - - priv = im->priv; - - if (address == NULL) - return NULL; - - /* Make sure we can add the new delegatee person */ - for (i = 0; i < priv->attendees->len; i++) { - ia = g_ptr_array_index (priv->attendees, i); - - ia_address = e_meeting_attendee_get_address (ia); - if (ia_address != NULL && !g_strcasecmp (itip_strip_mailto (ia_address), itip_strip_mailto (address))) { - if (pos != NULL) - *pos = i; - return ia; - } - } - - return NULL; -} - -static icalparameter_cutype -text_to_type (const char *type) -{ - if (!g_strcasecmp (type, _("Individual"))) - return ICAL_CUTYPE_INDIVIDUAL; - else if (!g_strcasecmp (type, _("Group"))) - return ICAL_CUTYPE_GROUP; - else if (!g_strcasecmp (type, _("Resource"))) - return ICAL_CUTYPE_RESOURCE; - else if (!g_strcasecmp (type, _("Room"))) - return ICAL_CUTYPE_ROOM; - else - return ICAL_CUTYPE_NONE; -} - -static char * -type_to_text (icalparameter_cutype type) -{ - switch (type) { - case ICAL_CUTYPE_INDIVIDUAL: - return _("Individual"); - case ICAL_CUTYPE_GROUP: - return _("Group"); - case ICAL_CUTYPE_RESOURCE: - return _("Resource"); - case ICAL_CUTYPE_ROOM: - return _("Room"); - default: - return _("Unknown"); - } - - return NULL; - -} - -static icalparameter_role -text_to_role (const char *role) -{ - if (!g_strcasecmp (role, _("Chair"))) - return ICAL_ROLE_CHAIR; - else if (!g_strcasecmp (role, _("Required Participant"))) - return ICAL_ROLE_REQPARTICIPANT; - else if (!g_strcasecmp (role, _("Optional Participant"))) - return ICAL_ROLE_OPTPARTICIPANT; - else if (!g_strcasecmp (role, _("Non-Participant"))) - return ICAL_ROLE_NONPARTICIPANT; - else - return ICAL_ROLE_NONE; -} - -static char * -role_to_text (icalparameter_role role) -{ - switch (role) { - case ICAL_ROLE_CHAIR: - return _("Chair"); - case ICAL_ROLE_REQPARTICIPANT: - return _("Required Participant"); - case ICAL_ROLE_OPTPARTICIPANT: - return _("Optional Participant"); - case ICAL_ROLE_NONPARTICIPANT: - return _("Non-Participant"); - default: - return _("Unknown"); - } - - return NULL; -} - -static gboolean -text_to_boolean (const char *role) -{ - if (!g_strcasecmp (role, _("Yes"))) - return TRUE; - else - return FALSE; -} - -static char * -boolean_to_text (gboolean b) -{ - if (b) - return _("Yes"); - else - return _("No"); -} - -static icalparameter_partstat -text_to_partstat (const char *partstat) -{ - if (!g_strcasecmp (partstat, _("Needs Action"))) - return ICAL_PARTSTAT_NEEDSACTION; - else if (!g_strcasecmp (partstat, _("Accepted"))) - return ICAL_PARTSTAT_ACCEPTED; - else if (!g_strcasecmp (partstat, _("Declined"))) - return ICAL_PARTSTAT_DECLINED; - else if (!g_strcasecmp (partstat, _("Tentative"))) - return ICAL_PARTSTAT_TENTATIVE; - else if (!g_strcasecmp (partstat, _("Delegated"))) - return ICAL_PARTSTAT_DELEGATED; - else if (!g_strcasecmp (partstat, _("Completed"))) - return ICAL_PARTSTAT_COMPLETED; - else if (!g_strcasecmp (partstat, _("In Process"))) - return ICAL_PARTSTAT_INPROCESS; - else - return ICAL_PARTSTAT_NONE; -} - -static char * -partstat_to_text (icalparameter_partstat partstat) -{ - switch (partstat) { - case ICAL_PARTSTAT_NEEDSACTION: - return _("Needs Action"); - case ICAL_PARTSTAT_ACCEPTED: - return _("Accepted"); - case ICAL_PARTSTAT_DECLINED: - return _("Declined"); - case ICAL_PARTSTAT_TENTATIVE: - return _("Tentative"); - case ICAL_PARTSTAT_DELEGATED: - return _("Delegated"); - case ICAL_PARTSTAT_COMPLETED: - return _("Completed"); - case ICAL_PARTSTAT_INPROCESS: - return _("In Process"); - case ICAL_PARTSTAT_NONE: - default: - return _("Unknown"); - } - - return NULL; -} - -static int -column_count (ETableModel *etm) -{ - return E_MEETING_MODEL_COLUMN_COUNT; -} - -static int -row_count (ETableModel *etm) -{ - EMeetingModel *im; - EMeetingModelPrivate *priv; - - im = E_MEETING_MODEL (etm); - priv = im->priv; - - return (priv->attendees->len); -} - -static void -append_row (ETableModel *etm, ETableModel *source, int row) -{ - EMeetingModel *im; - EMeetingModelPrivate *priv; - EMeetingAttendee *ia; - char *address; - - im = E_MEETING_MODEL (etm); - priv = im->priv; - - address = (char *) e_table_model_value_at (source, E_MEETING_MODEL_ADDRESS_COL, row); - if (find_match (im, address, NULL) != NULL) { - return; - } - - ia = E_MEETING_ATTENDEE (e_meeting_attendee_new ()); - - e_meeting_attendee_set_address (ia, g_strdup_printf ("MAILTO:%s", address)); - e_meeting_attendee_set_member (ia, g_strdup (e_table_model_value_at (source, E_MEETING_MODEL_MEMBER_COL, row))); - e_meeting_attendee_set_cutype (ia, text_to_type (e_table_model_value_at (source, E_MEETING_MODEL_TYPE_COL, row))); - e_meeting_attendee_set_role (ia, text_to_role (e_table_model_value_at (source, E_MEETING_MODEL_ROLE_COL, row))); - e_meeting_attendee_set_rsvp (ia, text_to_boolean (e_table_model_value_at (source, E_MEETING_MODEL_RSVP_COL, row))); - e_meeting_attendee_set_delto (ia, g_strdup (e_table_model_value_at (source, E_MEETING_MODEL_DELTO_COL, row))); - e_meeting_attendee_set_delfrom (ia, g_strdup (e_table_model_value_at (source, E_MEETING_MODEL_DELFROM_COL, row))); - e_meeting_attendee_set_status (ia, text_to_partstat (e_table_model_value_at (source, E_MEETING_MODEL_STATUS_COL, row))); - e_meeting_attendee_set_cn (ia, g_strdup (e_table_model_value_at (source, E_MEETING_MODEL_CN_COL, row))); - e_meeting_attendee_set_language (ia, g_strdup (e_table_model_value_at (source, E_MEETING_MODEL_LANGUAGE_COL, row))); - - e_meeting_model_add_attendee (E_MEETING_MODEL (etm), ia); - g_object_unref (ia); -} - -static void * -value_at (ETableModel *etm, int col, int row) -{ - EMeetingModel *im; - EMeetingModelPrivate *priv; - EMeetingAttendee *ia; - - im = E_MEETING_MODEL (etm); - priv = im->priv; - - ia = g_ptr_array_index (priv->attendees, row); - - switch (col) { - case E_MEETING_MODEL_ADDRESS_COL: - return (void *)itip_strip_mailto (e_meeting_attendee_get_address (ia)); - case E_MEETING_MODEL_MEMBER_COL: - return (void *)e_meeting_attendee_get_member (ia); - case E_MEETING_MODEL_TYPE_COL: - return type_to_text (e_meeting_attendee_get_cutype (ia)); - case E_MEETING_MODEL_ROLE_COL: - return role_to_text (e_meeting_attendee_get_role (ia)); - case E_MEETING_MODEL_RSVP_COL: - return boolean_to_text (e_meeting_attendee_get_rsvp (ia)); - case E_MEETING_MODEL_DELTO_COL: - return (void *)itip_strip_mailto (e_meeting_attendee_get_delto (ia)); - case E_MEETING_MODEL_DELFROM_COL: - return (void *)itip_strip_mailto (e_meeting_attendee_get_delfrom (ia)); - case E_MEETING_MODEL_STATUS_COL: - return partstat_to_text (e_meeting_attendee_get_status (ia)); - case E_MEETING_MODEL_CN_COL: - return (void *)e_meeting_attendee_get_cn (ia); - case E_MEETING_MODEL_LANGUAGE_COL: - return (void *)e_meeting_attendee_get_language (ia); - } - - return NULL; -} - -static void -set_value_at (ETableModel *etm, int col, int row, const void *val) -{ - EMeetingModel *im; - EMeetingModelPrivate *priv; - EMeetingAttendee *ia; - icalparameter_cutype type; - - im = E_MEETING_MODEL (etm); - priv = im->priv; - - ia = g_ptr_array_index (priv->attendees, row); - - e_table_model_pre_change (etm); - - switch (col) { - case E_MEETING_MODEL_ADDRESS_COL: - if (val != NULL && *((char *)val)) - e_meeting_attendee_set_address (ia, g_strdup_printf ("MAILTO:%s", (char *) val)); - break; - case E_MEETING_MODEL_MEMBER_COL: - e_meeting_attendee_set_member (ia, g_strdup (val)); - break; - case E_MEETING_MODEL_TYPE_COL: - type = text_to_type (val); - e_meeting_attendee_set_cutype (ia, text_to_type (val)); - if (type == ICAL_CUTYPE_RESOURCE) { - e_meeting_attendee_set_role (ia, ICAL_ROLE_NONPARTICIPANT); - e_table_model_cell_changed (etm, E_MEETING_MODEL_ROLE_COL, row); - } - break; - case E_MEETING_MODEL_ROLE_COL: - e_meeting_attendee_set_role (ia, text_to_role (val)); - break; - case E_MEETING_MODEL_RSVP_COL: - e_meeting_attendee_set_rsvp (ia, text_to_boolean (val)); - break; - case E_MEETING_MODEL_DELTO_COL: - e_meeting_attendee_set_delto (ia, g_strdup (val)); - break; - case E_MEETING_MODEL_DELFROM_COL: - e_meeting_attendee_set_delfrom (ia, g_strdup (val)); - break; - case E_MEETING_MODEL_STATUS_COL: - e_meeting_attendee_set_status (ia, text_to_partstat (val)); - break; - case E_MEETING_MODEL_CN_COL: - e_meeting_attendee_set_cn (ia, g_strdup (val)); - break; - case E_MEETING_MODEL_LANGUAGE_COL: - e_meeting_attendee_set_language (ia, g_strdup (val)); - break; - } - - e_table_model_cell_changed (etm, col, row); -} - -static gboolean -is_cell_editable (ETableModel *etm, int col, int row) -{ - EMeetingModel *im; - EMeetingModelPrivate *priv; - EMeetingAttendee *ia; - EMeetingAttendeeEditLevel level; - - im = E_MEETING_MODEL (etm); - priv = im->priv; - - if (col == E_MEETING_MODEL_DELTO_COL - || col == E_MEETING_MODEL_DELFROM_COL) - return FALSE; - - if (row == -1) - return TRUE; - if (row >= priv->attendees->len) - return TRUE; - - ia = g_ptr_array_index (priv->attendees, row); - level = e_meeting_attendee_get_edit_level (ia); - - switch (level) { - case E_MEETING_ATTENDEE_EDIT_FULL: - return TRUE; - case E_MEETING_ATTENDEE_EDIT_STATUS: - return col == E_MEETING_MODEL_STATUS_COL; - case E_MEETING_ATTENDEE_EDIT_NONE: - return FALSE; - } - - return TRUE; -} - -static void * -duplicate_value (ETableModel *etm, int col, const void *val) -{ - return g_strdup (val); -} - -static void -free_value (ETableModel *etm, int col, void *val) -{ - g_free (val); -} - -static void * -init_value (ETableModel *etm, int col) -{ - switch (col) { - case E_MEETING_MODEL_ADDRESS_COL: - return g_strdup (""); - case E_MEETING_MODEL_MEMBER_COL: - return g_strdup (""); - case E_MEETING_MODEL_TYPE_COL: - return g_strdup (_("Individual")); - case E_MEETING_MODEL_ROLE_COL: - return g_strdup (_("Required Participant")); - case E_MEETING_MODEL_RSVP_COL: - return g_strdup (_("Yes")); - case E_MEETING_MODEL_DELTO_COL: - return g_strdup (""); - case E_MEETING_MODEL_DELFROM_COL: - return g_strdup (""); - case E_MEETING_MODEL_STATUS_COL: - return g_strdup (_("Needs Action")); - case E_MEETING_MODEL_CN_COL: - return g_strdup (""); - case E_MEETING_MODEL_LANGUAGE_COL: - return g_strdup ("en"); - } - - return g_strdup (""); -} - -static gboolean -value_is_empty (ETableModel *etm, int col, const void *val) -{ - - switch (col) { - case E_MEETING_MODEL_ADDRESS_COL: - case E_MEETING_MODEL_MEMBER_COL: - case E_MEETING_MODEL_DELTO_COL: - case E_MEETING_MODEL_DELFROM_COL: - case E_MEETING_MODEL_CN_COL: - if (val && !g_strcasecmp (val, "")) - return TRUE; - else - return FALSE; - default: - ; - } - - return TRUE; -} - -static char * -value_to_string (ETableModel *etm, int col, const void *val) -{ - return g_strdup (val); -} - -static void -class_init (EMeetingModelClass *klass) -{ - GObjectClass *gobject_class; - ETableModelClass *etm_class; - - gobject_class = G_OBJECT_CLASS (klass); - etm_class = E_TABLE_MODEL_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - gobject_class->finalize = finalize; - - etm_class->column_count = column_count; - etm_class->row_count = row_count; - etm_class->value_at = value_at; - etm_class->set_value_at = set_value_at; - etm_class->is_cell_editable = is_cell_editable; - etm_class->append_row = append_row; - etm_class->duplicate_value = duplicate_value; - etm_class->free_value = free_value; - etm_class->initialize_value = init_value; - etm_class->value_is_empty = value_is_empty; - etm_class->value_to_string = value_to_string; -} - - -static void -init (EMeetingModel *im) -{ - EMeetingModelPrivate *priv; - - priv = g_new0 (EMeetingModelPrivate, 1); - - im->priv = priv; - - priv->attendees = g_ptr_array_new (); - - priv->tables = NULL; - - priv->client = NULL; - priv->zone = icaltimezone_get_builtin_timezone (calendar_config_get_timezone ()); - - priv->ebook = NULL; - priv->book_loaded = FALSE; - priv->book_load_wait = FALSE; - - priv->refresh_queue = g_ptr_array_new (); - priv->refresh_data = g_hash_table_new (g_direct_hash, g_direct_equal); - priv->refresh_idle_id = 0; - - priv->corba_select_names = CORBA_OBJECT_NIL; - - start_addressbook_server (im); -} - -static void -finalize (GObject *obj) -{ - EMeetingModel *im = E_MEETING_MODEL (obj); - EMeetingModelPrivate *priv; - GList *l; - int i; - - priv = im->priv; - - for (i = 0; i < priv->attendees->len; i++) - g_object_unref (g_ptr_array_index (priv->attendees, i)); - g_ptr_array_free (priv->attendees, TRUE); - - for (l = priv->tables; l != NULL; l = l->next) - g_signal_handlers_disconnect_matched (G_OBJECT (l->data), G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, im); - g_list_free (priv->tables); - - if (priv->client != NULL) - g_object_unref (priv->client); - - if (priv->ebook != NULL) - g_object_unref (priv->ebook); - - if (priv->corba_select_names != CORBA_OBJECT_NIL) { - CORBA_Environment ev; - CORBA_exception_init (&ev); - bonobo_object_release_unref (priv->corba_select_names, &ev); - CORBA_exception_free (&ev); - } - - while (priv->refresh_queue->len > 0) - refresh_queue_remove (im, g_ptr_array_index (priv->refresh_queue, 0)); - g_ptr_array_free (priv->refresh_queue, TRUE); - g_hash_table_destroy (priv->refresh_data); - - if (priv->refresh_idle_id) - g_source_remove (priv->refresh_idle_id); - - g_free (priv); - - if (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (obj); -} - -GtkObject * -e_meeting_model_new (void) -{ - return g_object_new (E_TYPE_MEETING_MODEL, NULL); -} - - -ECal * -e_meeting_model_get_e_cal (EMeetingModel *im) -{ - EMeetingModelPrivate *priv; - - priv = im->priv; - - return priv->client; -} - -void -e_meeting_model_set_e_cal (EMeetingModel *im, ECal *client) -{ - EMeetingModelPrivate *priv; - - priv = im->priv; - - if (priv->client != NULL) - g_object_unref (priv->client); - - if (client != NULL) - g_object_ref (client); - priv->client = client; -} - -icaltimezone * -e_meeting_model_get_zone (EMeetingModel *im) -{ - EMeetingModelPrivate *priv; - - g_return_val_if_fail (im != NULL, NULL); - g_return_val_if_fail (E_IS_MEETING_MODEL (im), NULL); - - priv = im->priv; - - return priv->zone; -} - -void -e_meeting_model_set_zone (EMeetingModel *im, icaltimezone *zone) -{ - EMeetingModelPrivate *priv; - - g_return_if_fail (im != NULL); - g_return_if_fail (E_IS_MEETING_MODEL (im)); - - priv = im->priv; - - priv->zone = zone; -} - -static ETableScrolled * -build_etable (ETableModel *model, const gchar *spec_file, const gchar *state_file) -{ - GtkWidget *etable; - ETable *real_table; - ETableExtras *extras; - GList *strings; - ECell *popup_cell, *cell; - - extras = e_table_extras_new (); - - /* For type */ - cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT); - popup_cell = e_cell_combo_new (); - e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell); - g_object_unref (cell); - - strings = NULL; - strings = g_list_append (strings, (char*) _("Individual")); - strings = g_list_append (strings, (char*) _("Group")); - strings = g_list_append (strings, (char*) _("Resource")); - strings = g_list_append (strings, (char*) _("Room")); - strings = g_list_append (strings, (char*) _("Unknown")); - - e_cell_combo_set_popdown_strings (E_CELL_COMBO (popup_cell), strings); - e_table_extras_add_cell (extras, "typeedit", popup_cell); - - /* For role */ - cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT); - popup_cell = e_cell_combo_new (); - e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell); - g_object_unref (cell); - - strings = NULL; - strings = g_list_append (strings, (char*) _("Chair")); - strings = g_list_append (strings, (char*) _("Required Participant")); - strings = g_list_append (strings, (char*) _("Optional Participant")); - strings = g_list_append (strings, (char*) _("Non-Participant")); - strings = g_list_append (strings, (char*) _("Unknown")); - - e_cell_combo_set_popdown_strings (E_CELL_COMBO (popup_cell), strings); - e_table_extras_add_cell (extras, "roleedit", popup_cell); - - /* For rsvp */ - cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT); - popup_cell = e_cell_combo_new (); - e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell); - g_object_unref (cell); - - strings = NULL; - strings = g_list_append (strings, (char*) _("Yes")); - strings = g_list_append (strings, (char*) _("No")); - - e_cell_combo_set_popdown_strings (E_CELL_COMBO (popup_cell), strings); - e_table_extras_add_cell (extras, "rsvpedit", popup_cell); - - /* For status */ - cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT); - popup_cell = e_cell_combo_new (); - e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell); - g_object_unref (cell); - - strings = NULL; - strings = g_list_append (strings, (char*) _("Needs Action")); - strings = g_list_append (strings, (char*) _("Accepted")); - strings = g_list_append (strings, (char*) _("Declined")); - strings = g_list_append (strings, (char*) _("Tentative")); - strings = g_list_append (strings, (char*) _("Delegated")); - - e_cell_combo_set_popdown_strings (E_CELL_COMBO (popup_cell), strings); - e_table_extras_add_cell (extras, "statusedit", popup_cell); - - etable = e_table_scrolled_new_from_spec_file (model, extras, spec_file, NULL); - real_table = e_table_scrolled_get_table (E_TABLE_SCROLLED (etable)); - g_object_set (G_OBJECT (real_table), "uniform_row_height", TRUE, NULL); - e_table_load_state (real_table, state_file); - -#if 0 - g_signal_connect (real_table, "right_click", G_CALLBACK (right_click_cb), mpage); -#endif - - g_signal_connect (etable, "destroy", G_CALLBACK (table_destroy_state_cb), g_strdup (state_file)); - - g_object_unref (extras); - - return E_TABLE_SCROLLED (etable); -} - -void -e_meeting_model_add_attendee (EMeetingModel *im, EMeetingAttendee *ia) -{ - EMeetingModelPrivate *priv; - - priv = im->priv; - - e_table_model_pre_change (E_TABLE_MODEL (im)); - - g_object_ref (ia); - g_ptr_array_add (priv->attendees, ia); - - g_signal_connect (ia, "changed", G_CALLBACK (attendee_changed_cb), im); - - e_table_model_row_inserted (E_TABLE_MODEL (im), row_count (E_TABLE_MODEL (im)) - 1); -} - -EMeetingAttendee * -e_meeting_model_add_attendee_with_defaults (EMeetingModel *im) -{ - EMeetingAttendee *ia; - char *str; - - ia = E_MEETING_ATTENDEE (e_meeting_attendee_new ()); - - e_meeting_attendee_set_address (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_ADDRESS_COL)); - e_meeting_attendee_set_member (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_MEMBER_COL)); - - str = init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_TYPE_COL); - e_meeting_attendee_set_cutype (ia, text_to_type (str)); - g_free (str); - str = init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_ROLE_COL); - e_meeting_attendee_set_role (ia, text_to_role (str)); - g_free (str); - str = init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_RSVP_COL); - e_meeting_attendee_set_rsvp (ia, text_to_boolean (str)); - g_free (str); - - e_meeting_attendee_set_delto (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_DELTO_COL)); - e_meeting_attendee_set_delfrom (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_DELFROM_COL)); - - str = init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_STATUS_COL); - e_meeting_attendee_set_status (ia, text_to_partstat (str)); - g_free (str); - - e_meeting_attendee_set_cn (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_CN_COL)); - e_meeting_attendee_set_language (ia, init_value (E_TABLE_MODEL (im), E_MEETING_MODEL_LANGUAGE_COL)); - - e_meeting_model_add_attendee (im, ia); - - return ia; -} - -void -e_meeting_model_remove_attendee (EMeetingModel *im, EMeetingAttendee *ia) -{ - EMeetingModelPrivate *priv; - gint i, row = -1; - - priv = im->priv; - - for (i = 0; i < priv->attendees->len; i++) { - if (ia == g_ptr_array_index (priv->attendees, i)) { - row = i; - break; - } - } - - if (row != -1) { - e_table_model_pre_change (E_TABLE_MODEL (im)); - - g_ptr_array_remove_index (priv->attendees, row); - g_object_unref (ia); - - e_table_model_row_deleted (E_TABLE_MODEL (im), row); - } -} - -void -e_meeting_model_remove_all_attendees (EMeetingModel *im) -{ - EMeetingModelPrivate *priv; - gint i, len; - - priv = im->priv; - - e_table_model_pre_change (E_TABLE_MODEL (im)); - - len = priv->attendees->len; - - for (i = 0; i < len; i++) { - EMeetingAttendee *ia = g_ptr_array_index (priv->attendees, i); - g_object_unref (ia); - } - g_ptr_array_set_size (priv->attendees, 0); - - e_table_model_rows_deleted (E_TABLE_MODEL (im), 0, len); -} - -EMeetingAttendee * -e_meeting_model_find_attendee (EMeetingModel *im, const gchar *address, gint *row) -{ - EMeetingModelPrivate *priv; - EMeetingAttendee *ia; - int i; - - priv = im->priv; - - if (address == NULL) - return NULL; - - for (i = 0; i < priv->attendees->len; i++) { - const gchar *ia_address; - - ia = g_ptr_array_index (priv->attendees, i); - - ia_address = e_meeting_attendee_get_address (ia); - if (ia_address && !g_strcasecmp (itip_strip_mailto (ia_address), itip_strip_mailto (address))) { - if (row != NULL) - *row = i; - - return ia; - } - } - - return NULL; -} - -EMeetingAttendee * -e_meeting_model_find_attendee_at_row (EMeetingModel *im, gint row) -{ - EMeetingModelPrivate *priv; - - g_return_val_if_fail (im != NULL, NULL); - g_return_val_if_fail (E_IS_MEETING_MODEL (im), NULL); - g_return_val_if_fail (row >= 0, NULL); - - priv = im->priv; - g_return_val_if_fail (row < priv->attendees->len, NULL); - - return g_ptr_array_index (priv->attendees, row); -} - -gint -e_meeting_model_count_actual_attendees (EMeetingModel *im) -{ - EMeetingModelPrivate *priv; - - priv = im->priv; - - return e_table_model_row_count (E_TABLE_MODEL (im)); -} - -const GPtrArray * -e_meeting_model_get_attendees (EMeetingModel *im) -{ - EMeetingModelPrivate *priv; - - priv = im->priv; - - return priv->attendees; -} - -static icaltimezone * -find_zone (icalproperty *ip, icalcomponent *tz_top_level) -{ - icalparameter *param; - icalcomponent *sub_comp; - const char *tzid; - icalcompiter iter; - - if (tz_top_level == NULL) - return NULL; - - param = icalproperty_get_first_parameter (ip, ICAL_TZID_PARAMETER); - if (param == NULL) - return NULL; - tzid = icalparameter_get_tzid (param); - - iter = icalcomponent_begin_component (tz_top_level, ICAL_VTIMEZONE_COMPONENT); - while ((sub_comp = icalcompiter_deref (&iter)) != NULL) { - icalcomponent *clone; - const char *tz_tzid; - - /* FIXME We aren't passing a property here */ - tz_tzid = icalproperty_get_tzid (sub_comp); - if (!strcmp (tzid, tz_tzid)) { - icaltimezone *zone; - - zone = icaltimezone_new (); - clone = icalcomponent_new_clone (sub_comp); - icaltimezone_set_component (zone, clone); - - return zone; - } - - icalcompiter_next (&iter); - } - - return NULL; -} - - -static void -refresh_queue_add (EMeetingModel *im, int row, - EMeetingTime *start, - EMeetingTime *end, - EMeetingModelRefreshCallback call_back, - gpointer data) -{ - EMeetingModelPrivate *priv; - EMeetingAttendee *ia; - EMeetingModelQueueData *qdata; - - priv = im->priv; - - ia = g_ptr_array_index (priv->attendees, row); - if (ia == NULL) - return; - - qdata = g_hash_table_lookup (priv->refresh_data, ia); - if (qdata == NULL) { - qdata = g_new0 (EMeetingModelQueueData, 1); - - qdata->im = im; - qdata->ia = ia; - e_meeting_attendee_clear_busy_periods (ia); - e_meeting_attendee_set_has_calendar_info (ia, FALSE); - - qdata->start = *start; - qdata->end = *end; - qdata->string = g_string_new (NULL); - qdata->call_backs = g_ptr_array_new (); - qdata->data = g_ptr_array_new (); - g_ptr_array_add (qdata->call_backs, call_back); - g_ptr_array_add (qdata->data, data); - - g_hash_table_insert (priv->refresh_data, ia, qdata); - } else { - if (e_meeting_time_compare_times (start, &qdata->start) == -1) - qdata->start = *start; - if (e_meeting_time_compare_times (end, &qdata->end) == 1) - qdata->end = *end; - g_ptr_array_add (qdata->call_backs, call_back); - g_ptr_array_add (qdata->data, data); - } - - g_object_ref (ia); - g_ptr_array_add (priv->refresh_queue, ia); - - if (priv->refresh_idle_id == 0) - priv->refresh_idle_id = g_idle_add (refresh_busy_periods, im); -} - -static void -refresh_queue_remove (EMeetingModel *im, EMeetingAttendee *ia) -{ - EMeetingModelPrivate *priv; - EMeetingModelQueueData *qdata; - - priv = im->priv; - - /* Free the queue data */ - qdata = g_hash_table_lookup (priv->refresh_data, ia); - g_assert (qdata != NULL); - - g_hash_table_remove (priv->refresh_data, ia); - g_ptr_array_free (qdata->call_backs, TRUE); - g_ptr_array_free (qdata->data, TRUE); - g_free (qdata); - - /* Unref the attendee */ - g_ptr_array_remove (priv->refresh_queue, ia); - g_object_unref (ia); -} - -static void -process_callbacks (EMeetingModelQueueData *qdata) -{ - EMeetingModel *im; - int i; - - for (i = 0; i < qdata->call_backs->len; i++) { - EMeetingModelRefreshCallback call_back; - gpointer *data; - - call_back = g_ptr_array_index (qdata->call_backs, i); - data = g_ptr_array_index (qdata->data, i); - - call_back (data); - } - - im = qdata->im; - refresh_queue_remove (qdata->im, qdata->ia); - g_object_unref (im); -} - -static void -process_free_busy_comp (EMeetingAttendee *ia, - icalcomponent *fb_comp, - icaltimezone *zone, - icalcomponent *tz_top_level) -{ - icalproperty *ip; - - ip = icalcomponent_get_first_property (fb_comp, ICAL_DTSTART_PROPERTY); - if (ip != NULL) { - struct icaltimetype dtstart; - icaltimezone *ds_zone; - - dtstart = icalproperty_get_dtstart (ip); - if (!dtstart.is_utc) - ds_zone = find_zone (ip, tz_top_level); - else - ds_zone = icaltimezone_get_utc_timezone (); - icaltimezone_convert_time (&dtstart, ds_zone, zone); - e_meeting_attendee_set_start_busy_range (ia, - dtstart.year, - dtstart.month, - dtstart.day, - dtstart.hour, - dtstart.minute); - } - - ip = icalcomponent_get_first_property (fb_comp, ICAL_DTEND_PROPERTY); - if (ip != NULL) { - struct icaltimetype dtend; - icaltimezone *de_zone; - - dtend = icalproperty_get_dtend (ip); - if (!dtend.is_utc) - de_zone = find_zone (ip, tz_top_level); - else - de_zone = icaltimezone_get_utc_timezone (); - icaltimezone_convert_time (&dtend, de_zone, zone); - e_meeting_attendee_set_end_busy_range (ia, - dtend.year, - dtend.month, - dtend.day, - dtend.hour, - dtend.minute); - } - - ip = icalcomponent_get_first_property (fb_comp, ICAL_FREEBUSY_PROPERTY); - while (ip != NULL) { - icalparameter *param; - struct icalperiodtype fb; - EMeetingFreeBusyType busy_type = E_MEETING_FREE_BUSY_LAST; - icalparameter_fbtype fbtype = ICAL_FBTYPE_BUSY; - - fb = icalproperty_get_freebusy (ip); - param = icalproperty_get_first_parameter (ip, ICAL_FBTYPE_PARAMETER); - if (param != NULL) - fbtype = icalparameter_get_fbtype (param); - - switch (fbtype) { - case ICAL_FBTYPE_BUSY: - busy_type = E_MEETING_FREE_BUSY_BUSY; - break; - - case ICAL_FBTYPE_BUSYUNAVAILABLE: - busy_type = E_MEETING_FREE_BUSY_OUT_OF_OFFICE; - break; - - case ICAL_FBTYPE_BUSYTENTATIVE: - busy_type = E_MEETING_FREE_BUSY_TENTATIVE; - break; - - default: - break; - } - - if (busy_type != E_MEETING_FREE_BUSY_LAST) { - icaltimezone *utc_zone = icaltimezone_get_utc_timezone (); - - icaltimezone_convert_time (&fb.start, utc_zone, zone); - icaltimezone_convert_time (&fb.end, utc_zone, zone); - e_meeting_attendee_add_busy_period (ia, - fb.start.year, - fb.start.month, - fb.start.day, - fb.start.hour, - fb.start.minute, - fb.end.year, - fb.end.month, - fb.end.day, - fb.end.hour, - fb.end.minute, - busy_type); - } - - ip = icalcomponent_get_next_property (fb_comp, ICAL_FREEBUSY_PROPERTY); - } -} - -static void -process_free_busy (EMeetingModelQueueData *qdata, char *text) -{ - EMeetingModel *im = qdata->im; - EMeetingModelPrivate *priv; - EMeetingAttendee *ia = qdata->ia; - icalcomponent *main_comp; - icalcomponent_kind kind = ICAL_NO_COMPONENT; - - priv = im->priv; - - main_comp = icalparser_parse_string (text); - if (main_comp == NULL) { - process_callbacks (qdata); - return; - } - - kind = icalcomponent_isa (main_comp); - if (kind == ICAL_VCALENDAR_COMPONENT) { - icalcompiter iter; - icalcomponent *tz_top_level, *sub_comp; - - tz_top_level = e_cal_util_new_top_level (); - - iter = icalcomponent_begin_component (main_comp, ICAL_VTIMEZONE_COMPONENT); - while ((sub_comp = icalcompiter_deref (&iter)) != NULL) { - icalcomponent *clone; - - clone = icalcomponent_new_clone (sub_comp); - icalcomponent_add_component (tz_top_level, clone); - - icalcompiter_next (&iter); - } - - iter = icalcomponent_begin_component (main_comp, ICAL_VFREEBUSY_COMPONENT); - while ((sub_comp = icalcompiter_deref (&iter)) != NULL) { - process_free_busy_comp (ia, sub_comp, priv->zone, tz_top_level); - - icalcompiter_next (&iter); - } - icalcomponent_free (tz_top_level); - } else if (kind == ICAL_VFREEBUSY_COMPONENT) { - process_free_busy_comp (ia, main_comp, priv->zone, NULL); - } - - icalcomponent_free (main_comp); - - process_callbacks (qdata); -} - -static void -async_close (GnomeVFSAsyncHandle *handle, - GnomeVFSResult result, - gpointer data) -{ - EMeetingModelQueueData *qdata = data; - - process_free_busy (qdata, qdata->string->str); -} - -static void -async_read (GnomeVFSAsyncHandle *handle, - GnomeVFSResult result, - gpointer buffer, - GnomeVFSFileSize requested, - GnomeVFSFileSize read, - gpointer data) -{ - EMeetingModelQueueData *qdata = data; - GnomeVFSFileSize buf_size = BUF_SIZE - 1; - - if (result != GNOME_VFS_OK && result != GNOME_VFS_ERROR_EOF) { - gnome_vfs_async_close (handle, async_close, qdata); - return; - } - - ((char *)buffer)[read] = '\0'; - qdata->string = g_string_append (qdata->string, buffer); - - if (result == GNOME_VFS_ERROR_EOF) { - gnome_vfs_async_close (handle, async_close, qdata); - return; - } - - gnome_vfs_async_read (handle, qdata->buffer, buf_size, async_read, qdata); -} - -static void -async_open (GnomeVFSAsyncHandle *handle, - GnomeVFSResult result, - gpointer data) -{ - EMeetingModelQueueData *qdata = data; - GnomeVFSFileSize buf_size = BUF_SIZE - 1; - - if (result != GNOME_VFS_OK) { - gnome_vfs_async_close (handle, async_close, qdata); - return; - } - - gnome_vfs_async_read (handle, qdata->buffer, buf_size, async_read, qdata); -} - -static void -contacts_cb (EBook *book, EBookStatus status, GList *contacts, gpointer data) -{ - EMeetingModelQueueData *qdata = data; - GList *l; - - if (status != E_BOOK_ERROR_OK) - return; - - for (l = contacts; l; l = l->next) { - GnomeVFSAsyncHandle *handle; - EContact *contact = E_CONTACT (l->data); - const char *fburl = e_contact_get_const (contact, E_CONTACT_FREEBUSY_URL); - - if (!fburl || !*fburl) - continue; - - /* Read in free/busy data from the url */ - gnome_vfs_async_open (&handle, fburl, GNOME_VFS_OPEN_READ, - GNOME_VFS_PRIORITY_DEFAULT, async_open, qdata); - - e_free_object_list (contacts); - return; - } - - process_callbacks (qdata); - e_free_object_list (contacts); -} - -static gboolean -refresh_busy_periods (gpointer data) -{ - EMeetingModel *im = E_MEETING_MODEL (data); - EMeetingModelPrivate *priv; - EMeetingAttendee *ia = NULL; - EMeetingModelQueueData *qdata = NULL; - char *query; - int i; - - priv = im->priv; - - /* Check to see if there are any remaining attendees in the queue */ - for (i = 0; i < priv->refresh_queue->len; i++) { - ia = g_ptr_array_index (priv->refresh_queue, i); - g_assert (ia != NULL); - - qdata = g_hash_table_lookup (priv->refresh_data, ia); - g_assert (qdata != NULL); - - if (!qdata->refreshing) - break; - } - - /* The everything in the queue is being refreshed */ - if (i >= priv->refresh_queue->len) { - priv->refresh_idle_id = 0; - return FALSE; - } - - /* Indicate we are trying to refresh it */ - qdata->refreshing = TRUE; - - /* We take a ref in case we get destroyed in the gui during a callback */ - g_object_ref (qdata->im); - - /* Check the server for free busy data */ - if (priv->client) { - GList *fb_data = NULL, *users = NULL; - struct icaltimetype itt; - time_t startt, endt; - const char *user; - - itt = icaltime_null_time (); - itt.year = g_date_year (&qdata->start.date); - itt.month = g_date_month (&qdata->start.date); - itt.day = g_date_day (&qdata->start.date); - itt.hour = qdata->start.hour; - itt.minute = qdata->start.minute; - startt = icaltime_as_timet_with_zone (itt, priv->zone); - - itt = icaltime_null_time (); - itt.year = g_date_year (&qdata->end.date); - itt.month = g_date_month (&qdata->end.date); - itt.day = g_date_day (&qdata->end.date); - itt.hour = qdata->end.hour; - itt.minute = qdata->end.minute; - endt = icaltime_as_timet_with_zone (itt, priv->zone); - - user = itip_strip_mailto (e_meeting_attendee_get_address (ia)); - users = g_list_append (users, g_strdup (user)); - - /* FIXME Error checking */ - e_cal_get_free_busy (priv->client, users, startt, endt, &fb_data, NULL); - - g_list_foreach (users, (GFunc)g_free, NULL); - g_list_free (users); - - if (fb_data != NULL) { - ECalComponent *comp = fb_data->data; - char *comp_str; - - comp_str = e_cal_component_get_as_string (comp); - process_free_busy (qdata, comp_str); - g_free (comp_str); - return TRUE; - } - } - - /* Look for fburl's of attendee with no free busy info on server */ - if (!priv->book_loaded) { - priv->book_load_wait = TRUE; - gtk_main (); - } - - if (!e_meeting_attendee_is_set_address (ia)) { - process_callbacks (qdata); - return TRUE; - } - - query = g_strdup_printf ("(is \"email\" \"%s\")", - itip_strip_mailto (e_meeting_attendee_get_address (ia))); - if (!e_book_async_get_contacts (priv->ebook, query, contacts_cb, qdata)) - process_callbacks (qdata); - g_free (query); - - return TRUE; -} - -void -e_meeting_model_refresh_all_busy_periods (EMeetingModel *im, - EMeetingTime *start, - EMeetingTime *end, - EMeetingModelRefreshCallback call_back, - gpointer data) -{ - EMeetingModelPrivate *priv; - int i; - - g_return_if_fail (im != NULL); - g_return_if_fail (E_IS_MEETING_MODEL (im)); - - priv = im->priv; - - for (i = 0; i < priv->attendees->len; i++) - refresh_queue_add (im, i, start, end, call_back, data); -} - -void -e_meeting_model_refresh_busy_periods (EMeetingModel *im, - int row, - EMeetingTime *start, - EMeetingTime *end, - EMeetingModelRefreshCallback call_back, - gpointer data) -{ - EMeetingModelPrivate *priv; - - g_return_if_fail (im != NULL); - g_return_if_fail (E_IS_MEETING_MODEL (im)); - - priv = im->priv; - - refresh_queue_add (im, row, start, end, call_back, data); -} - -ETableScrolled * -e_meeting_model_etable_from_model (EMeetingModel *im, const gchar *spec_file, const gchar *state_file) -{ - EMeetingModelPrivate *priv; - ETableScrolled *ets; - - g_return_val_if_fail (im != NULL, NULL); - g_return_val_if_fail (E_IS_MEETING_MODEL (im), NULL); - - priv = im->priv; - - ets = build_etable (E_TABLE_MODEL (im), spec_file, state_file); - - priv->tables = g_list_prepend (priv->tables, ets); - - g_signal_connect (ets, "destroy", G_CALLBACK (table_destroy_list_cb), im); - - return ets; -} - -void -e_meeting_model_etable_click_to_add (EMeetingModel *im, gboolean click_to_add) -{ - EMeetingModelPrivate *priv; - GList *l; - - g_return_if_fail (im != NULL); - g_return_if_fail (E_IS_MEETING_MODEL (im)); - - priv = im->priv; - - for (l = priv->tables; l != NULL; l = l->next) { - ETableScrolled *ets; - ETable *real_table; - - ets = l->data; - real_table = e_table_scrolled_get_table (ets); - - g_object_set (G_OBJECT (real_table), "use_click_to_add", click_to_add, NULL); - } -} - -int -e_meeting_model_etable_model_to_view_row (ETable *et, EMeetingModel *im, int model_row) -{ - EMeetingModelPrivate *priv; - - g_return_val_if_fail (im != NULL, -1); - g_return_val_if_fail (E_IS_MEETING_MODEL (im), -1); - - priv = im->priv; - - return e_table_model_to_view_row (et, model_row); -} - -int -e_meeting_model_etable_view_to_model_row (ETable *et, EMeetingModel *im, int view_row) -{ - EMeetingModelPrivate *priv; - - g_return_val_if_fail (im != NULL, -1); - g_return_val_if_fail (E_IS_MEETING_MODEL (im), -1); - - priv = im->priv; - - return e_table_view_to_model_row (et, view_row); -} - - -static void -add_section (GNOME_Evolution_Addressbook_SelectNames corba_select_names, const char *name) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_SelectNames_addSection (corba_select_names, - name, - gettext (name), - &ev); - - CORBA_exception_free (&ev); -} - -static gboolean -get_select_name_dialog (EMeetingModel *im) -{ - EMeetingModelPrivate *priv; - CORBA_Environment ev; - int i; - - priv = im->priv; - - if (priv->corba_select_names != CORBA_OBJECT_NIL) { - Bonobo_Control corba_control; - GtkWidget *control_widget; - int i; - - CORBA_exception_init (&ev); - for (i = 0; sections[i] != NULL; i++) { - corba_control = GNOME_Evolution_Addressbook_SelectNames_getEntryBySection - (priv->corba_select_names, sections[i], &ev); - if (BONOBO_EX (&ev)) { - CORBA_exception_free (&ev); - return FALSE; - } - - control_widget = bonobo_widget_new_control_from_objref (corba_control, CORBA_OBJECT_NIL); - - bonobo_widget_set_property (BONOBO_WIDGET (control_widget), "text", TC_CORBA_string, "", NULL); - } - CORBA_exception_free (&ev); - - return TRUE; - } - - CORBA_exception_init (&ev); - - priv->corba_select_names = bonobo_activation_activate_from_id (SELECT_NAMES_OAFID, 0, NULL, &ev); - - for (i = 0; sections[i] != NULL; i++) - add_section (priv->corba_select_names, sections[i]); - - bonobo_event_source_client_add_listener (priv->corba_select_names, - (BonoboListenerCallbackFn) select_names_ok_cb, - "GNOME/Evolution:ok:dialog", - NULL, im); - - if (BONOBO_EX (&ev)) { - CORBA_exception_free (&ev); - return FALSE; - } - - CORBA_exception_free (&ev); - - return TRUE; -} - -void -e_meeting_model_invite_others_dialog (EMeetingModel *im) -{ - EMeetingModelPrivate *priv; - CORBA_Environment ev; - - priv = im->priv; - - if (!get_select_name_dialog (im)) - return; - - CORBA_exception_init (&ev); - - GNOME_Evolution_Addressbook_SelectNames_activateDialog ( - priv->corba_select_names, _("Required Participants"), &ev); - - CORBA_exception_free (&ev); -} - -static void -process_section (EMeetingModel *im, EABDestination **destv, icalparameter_role role) -{ - EMeetingModelPrivate *priv; - int i; - - if (!destv) - return; - - priv = im->priv; - for (i = 0; destv[i]; i++) { - EMeetingAttendee *ia; - const char *name, *attendee = NULL; - char *attr; - CORBA_Environment ev; - EABDestination *dest = destv[i]; - - CORBA_exception_init (&ev); - - /* Get the CN */ - name = eab_destination_get_name (dest); - - /* Get the field as attendee from the backend */ - if (e_cal_get_ldap_attribute (priv->client, &attr, NULL) && attr) { - /* FIXME this should be more general */ - if (!strcmp (attr, "icscalendar")) { - EContact *contact = eab_destination_get_contact (dest); - if (contact) - attendee = e_contact_get_const (contact, E_CONTACT_ICS_CALENDAR); - } - - g_free (attr); - } - - CORBA_exception_init (&ev); - - /* If we couldn't get the attendee prior, get the email address as the default */ - if (attendee == NULL || *attendee == '\0') { - attendee = eab_destination_get_email (dest); - } - - CORBA_exception_free (&ev); - - if (attendee == NULL || *attendee == '\0') - continue; - - if (e_meeting_model_find_attendee (im, attendee, NULL) == NULL) { - ia = e_meeting_model_add_attendee_with_defaults (im); - - e_meeting_attendee_set_address (ia, g_strdup_printf ("MAILTO:%s", attendee)); - e_meeting_attendee_set_role (ia, role); - if (role == ICAL_ROLE_NONPARTICIPANT) - e_meeting_attendee_set_cutype (ia, ICAL_CUTYPE_RESOURCE); - e_meeting_attendee_set_cn (ia, g_strdup (name)); - } - } -} - -static void -select_names_ok_cb (BonoboListener *listener, - const char *event_name, - const CORBA_any *arg, - CORBA_Environment *ev, - gpointer data) -{ - EMeetingModel *im = data; - EMeetingModelPrivate *priv; - Bonobo_Control corba_control; - GtkWidget *control_widget; - BonoboControlFrame *control_frame; - Bonobo_PropertyBag pb; - char *dest_str; - EABDestination **dest; - int i; - - priv = im->priv; - - for (i = 0; sections[i] != NULL; i++) { - corba_control = GNOME_Evolution_Addressbook_SelectNames_getEntryBySection - (priv->corba_select_names, sections[i], ev); - control_widget = bonobo_widget_new_control_from_objref - (corba_control, CORBA_OBJECT_NIL); - - control_frame = bonobo_widget_get_control_frame (BONOBO_WIDGET (control_widget)); - pb = bonobo_control_frame_get_control_property_bag (control_frame, NULL); - dest_str = bonobo_pbclient_get_string (pb, "destinations", NULL); - dest = eab_destination_importv (dest_str); - process_section (im, dest, roles[i]); - eab_destination_freev (dest); - } -} - -static void -attendee_changed_cb (EMeetingAttendee *ia, gpointer data) -{ - EMeetingModel *im = E_MEETING_MODEL (data); - EMeetingModelPrivate *priv; - gint row = -1, i; - - priv = im->priv; - - /* FIXME: Ideally I think you are supposed to call pre_change() before - the data structures are changed. */ - e_table_model_pre_change (E_TABLE_MODEL (im)); - - for (i = 0; i < priv->attendees->len; i++) { - if (ia == g_ptr_array_index (priv->attendees, i)) { - row = i; - break; - } - } - - if (row == -1) - e_table_model_no_change (E_TABLE_MODEL (im)); - else - e_table_model_row_changed (E_TABLE_MODEL (im), row); -} - -static void -table_destroy_state_cb (ETableScrolled *etable, gpointer data) -{ - ETable *real_table; - char *filename = data; - - real_table = e_table_scrolled_get_table (etable); - e_table_save_state (real_table, filename); - - g_free (data); -} - -static void -table_destroy_list_cb (ETableScrolled *etable, gpointer data) -{ - EMeetingModel *im = E_MEETING_MODEL (data); - EMeetingModelPrivate *priv; - - priv = im->priv; - - priv->tables = g_list_remove (priv->tables, etable); -} - diff --git a/calendar/gui/e-meeting-model.h b/calendar/gui/e-meeting-model.h deleted file mode 100644 index e709cd3aa4..0000000000 --- a/calendar/gui/e-meeting-model.h +++ /dev/null @@ -1,116 +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_MEETING_MODEL_H_ -#define _E_MEETING_MODEL_H_ - -#include <gtk/gtk.h> -#include <gal/e-table/e-table-scrolled.h> -#include <gal/e-table/e-table-model.h> -#include <libecal/e-cal.h> -#include "e-meeting-attendee.h" - -G_BEGIN_DECLS - -#define E_TYPE_MEETING_MODEL (e_meeting_model_get_type ()) -#define E_MEETING_MODEL(obj) (GTK_CHECK_CAST ((obj), E_TYPE_MEETING_MODEL, EMeetingModel)) -#define E_MEETING_MODEL_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_MEETING_MODEL, EMeetingModelClass)) -#define E_IS_MEETING_MODEL(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_MEETING_MODEL)) -#define E_IS_MEETING_MODEL_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_MEETING_MODEL)) - - -typedef struct _EMeetingModel EMeetingModel; -typedef struct _EMeetingModelPrivate EMeetingModelPrivate; -typedef struct _EMeetingModelClass EMeetingModelClass; - -typedef enum { - E_MEETING_MODEL_ADDRESS_COL, - E_MEETING_MODEL_MEMBER_COL, - E_MEETING_MODEL_TYPE_COL, - E_MEETING_MODEL_ROLE_COL, - E_MEETING_MODEL_RSVP_COL, - E_MEETING_MODEL_DELTO_COL, - E_MEETING_MODEL_DELFROM_COL, - E_MEETING_MODEL_STATUS_COL, - E_MEETING_MODEL_CN_COL, - E_MEETING_MODEL_LANGUAGE_COL, - E_MEETING_MODEL_COLUMN_COUNT -} EMeetingModelColumns; - -struct _EMeetingModel { - ETableModel parent; - - EMeetingModelPrivate *priv; -}; - -struct _EMeetingModelClass { - ETableModelClass parent_class; -}; - -typedef void (* EMeetingModelRefreshCallback) (gpointer data); - - -GtkType e_meeting_model_get_type (void); -GtkObject *e_meeting_model_new (void); - -ECal *e_meeting_model_get_e_cal (EMeetingModel *im); -void e_meeting_model_set_e_cal (EMeetingModel *im, ECal *client); - -icaltimezone *e_meeting_model_get_zone (EMeetingModel *im); -void e_meeting_model_set_zone (EMeetingModel *im, icaltimezone *zone); - -void e_meeting_model_add_attendee (EMeetingModel *im, EMeetingAttendee *ia); -EMeetingAttendee *e_meeting_model_add_attendee_with_defaults (EMeetingModel *im); - -void e_meeting_model_remove_attendee (EMeetingModel *im, EMeetingAttendee *ia); -void e_meeting_model_remove_all_attendees (EMeetingModel *im); - -EMeetingAttendee *e_meeting_model_find_attendee (EMeetingModel *im, const gchar *address, gint *row); -EMeetingAttendee *e_meeting_model_find_attendee_at_row (EMeetingModel *im, gint row); - -gint e_meeting_model_count_actual_attendees (EMeetingModel *im); -const GPtrArray *e_meeting_model_get_attendees (EMeetingModel *im); - -void e_meeting_model_refresh_all_busy_periods (EMeetingModel *im, - EMeetingTime *start, - EMeetingTime *end, - EMeetingModelRefreshCallback call_back, - gpointer data); -void e_meeting_model_refresh_busy_periods (EMeetingModel *im, - int row, - EMeetingTime *start, - EMeetingTime *end, - EMeetingModelRefreshCallback call_back, - gpointer data); - - -/* Helpful functions */ -ETableScrolled *e_meeting_model_etable_from_model (EMeetingModel *im, const gchar *spec_file, const gchar *state_file); -void e_meeting_model_etable_click_to_add (EMeetingModel *im, gboolean click_to_add); -int e_meeting_model_etable_model_to_view_row (ETable *et, EMeetingModel *im, int model_row); -int e_meeting_model_etable_view_to_model_row (ETable *et, EMeetingModel *im, int view_row); - -void e_meeting_model_invite_others_dialog (EMeetingModel *im); - -G_END_DECLS - -#endif diff --git a/calendar/gui/e-meeting-store.c b/calendar/gui/e-meeting-store.c deleted file mode 100644 index 01ac267fe1..0000000000 --- a/calendar/gui/e-meeting-store.c +++ /dev/null @@ -1,1295 +0,0 @@ -/* - * e-meeting-store.c - * - * Copyright (C) 2001-2003 Ximian, Inc. - * - * Authors: JP Rosevear <jpr@ximian.com> - * Mike Kestner <mkestner@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-i18n.h> -#include <libgnome/gnome-util.h> -#include <libgnomevfs/gnome-vfs.h> -#include <libebook/e-book.h> -#include <libecal/e-cal-component.h> -#include <libecal/e-cal-util.h> -#include <libecal/e-cal-time-util.h> -#include "calendar-config.h" -#include "itip-utils.h" -#include "e-meeting-utils.h" -#include "e-meeting-attendee.h" -#include "e-meeting-store.h" - -#define ROW_VALID(store, row) (row >= 0 && row < store->priv->attendees->len) - -struct _EMeetingStorePrivate { - GPtrArray *attendees; - gint stamp; - - ECal *client; - icaltimezone *zone; - - EBook *ebook; - - GPtrArray *refresh_queue; - GHashTable *refresh_data; - guint refresh_idle_id; -}; - -#define BUF_SIZE 1024 - -typedef struct _EMeetingStoreQueueData EMeetingStoreQueueData; -struct _EMeetingStoreQueueData { - EMeetingStore *store; - EMeetingAttendee *attendee; - - gboolean refreshing; - - EMeetingTime start; - EMeetingTime end; - - char buffer[BUF_SIZE]; - GString *string; - - GPtrArray *call_backs; - GPtrArray *data; -}; - - -static GObjectClass *parent_class = NULL; - -static void -start_addressbook_server (EMeetingStore *store) -{ - store->priv->ebook = e_book_new (); - e_book_load_local_addressbook (store->priv->ebook, 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 GtkTreeModelFlags -get_flags (GtkTreeModel *model) -{ - g_return_val_if_fail (E_IS_MEETING_STORE (model), 0); - - return GTK_TREE_MODEL_ITERS_PERSIST | GTK_TREE_MODEL_LIST_ONLY; -} - -static int -get_n_columns (GtkTreeModel *model) -{ - g_return_val_if_fail (E_IS_MEETING_STORE (model), 0); - - return E_MEETING_STORE_COLUMN_COUNT; -} - -static GType -get_column_type (GtkTreeModel *model, int col) -{ - g_return_val_if_fail (E_IS_MEETING_STORE (model), G_TYPE_INVALID); - - switch (col) { - case E_MEETING_STORE_ADDRESS_COL: - case E_MEETING_STORE_MEMBER_COL: - case E_MEETING_STORE_TYPE_COL: - case E_MEETING_STORE_ROLE_COL: - case E_MEETING_STORE_RSVP_COL: - case E_MEETING_STORE_DELTO_COL: - case E_MEETING_STORE_DELFROM_COL: - case E_MEETING_STORE_STATUS_COL: - case E_MEETING_STORE_CN_COL: - case E_MEETING_STORE_LANGUAGE_COL: - case E_MEETING_STORE_ATTENDEE_COL: - return G_TYPE_STRING; - case E_MEETING_STORE_ATTENDEE_UNDERLINE_COL: - return PANGO_TYPE_UNDERLINE; - default: - return G_TYPE_INVALID; - } -} - -static gboolean -get_iter (GtkTreeModel *model, GtkTreeIter *iter, GtkTreePath *path) -{ - int row; - - g_return_val_if_fail (E_IS_MEETING_STORE (model), FALSE); - g_return_val_if_fail (gtk_tree_path_get_depth (path) > 0, FALSE); - - row = gtk_tree_path_get_indices (path) [0]; - - if (!ROW_VALID (E_MEETING_STORE (model), row)) - return FALSE; - - iter->stamp = E_MEETING_STORE (model)->priv->stamp; - iter->user_data = GINT_TO_POINTER (row); - - return TRUE; -} - -static GtkTreePath * -get_path (GtkTreeModel *model, GtkTreeIter *iter) -{ - int row; - GtkTreePath *result; - - g_return_val_if_fail (E_IS_MEETING_STORE (model), NULL); - g_return_val_if_fail (iter->stamp == E_MEETING_STORE (model)->priv->stamp, NULL); - - row = GPOINTER_TO_INT (iter->user_data); - - g_return_val_if_fail (ROW_VALID (E_MEETING_STORE (model), row), NULL); - - result = gtk_tree_path_new (); - gtk_tree_path_append_index (result, row); - return result; -} - -static void -get_value (GtkTreeModel *model, GtkTreeIter *iter, int col, GValue *value) -{ - EMeetingStore *store; - EMeetingAttendee *attendee; - const gchar *cn; - int row; - - g_return_if_fail (E_IS_MEETING_STORE (model)); - g_return_if_fail (col >= 0 && col < E_MEETING_STORE_COLUMN_COUNT); - - row = GPOINTER_TO_INT (iter->user_data); - store = E_MEETING_STORE (model); - - g_return_if_fail (iter->stamp == store->priv->stamp); - g_return_if_fail (ROW_VALID (E_MEETING_STORE (model), row)); - - attendee = g_ptr_array_index (store->priv->attendees, row); - - switch (col) { - case E_MEETING_STORE_ADDRESS_COL: - g_value_init (value, G_TYPE_STRING); - g_value_set_string (value, itip_strip_mailto (e_meeting_attendee_get_address (attendee))); - break; - case E_MEETING_STORE_MEMBER_COL: - g_value_init (value, G_TYPE_STRING); - g_value_set_string (value, e_meeting_attendee_get_member (attendee)); - break; - case E_MEETING_STORE_TYPE_COL: - g_value_init (value, G_TYPE_STRING); - g_value_set_string (value, type_to_text (e_meeting_attendee_get_cutype (attendee))); - break; - case E_MEETING_STORE_ROLE_COL: - g_value_init (value, G_TYPE_STRING); - g_value_set_string (value, role_to_text (e_meeting_attendee_get_role (attendee))); - break; - case E_MEETING_STORE_RSVP_COL: - g_value_init (value, G_TYPE_STRING); - g_value_set_string (value, boolean_to_text (e_meeting_attendee_get_rsvp (attendee))); - break; - case E_MEETING_STORE_DELTO_COL: - g_value_init (value, G_TYPE_STRING); - g_value_set_string (value, itip_strip_mailto (e_meeting_attendee_get_delto (attendee))); - break; - case E_MEETING_STORE_DELFROM_COL: - g_value_init (value, G_TYPE_STRING); - g_value_set_string (value, itip_strip_mailto (e_meeting_attendee_get_delfrom (attendee))); - break; - case E_MEETING_STORE_STATUS_COL: - g_value_init (value, G_TYPE_STRING); - g_value_set_string (value, partstat_to_text (e_meeting_attendee_get_status (attendee))); - break; - case E_MEETING_STORE_CN_COL: - g_value_init (value, G_TYPE_STRING); - g_value_set_string (value, e_meeting_attendee_get_cn (attendee)); - break; - case E_MEETING_STORE_LANGUAGE_COL: - g_value_init (value, G_TYPE_STRING); - g_value_set_string (value, e_meeting_attendee_get_language (attendee)); - break; - case E_MEETING_STORE_ATTENDEE_COL: - g_value_init (value, G_TYPE_STRING); - cn = e_meeting_attendee_get_cn (attendee); - if (strcmp (cn, "")) - g_value_set_string (value, cn); - else - g_value_set_string (value, itip_strip_mailto (e_meeting_attendee_get_address (attendee))); - break; - case E_MEETING_STORE_ATTENDEE_UNDERLINE_COL: - cn = e_meeting_attendee_get_cn (attendee); - g_value_init (value, PANGO_TYPE_UNDERLINE); - g_value_set_enum (value, strcmp ("", cn) == 0 ? PANGO_UNDERLINE_NONE : PANGO_UNDERLINE_SINGLE); - } -} - -static gboolean -iter_next (GtkTreeModel *model, GtkTreeIter *iter) -{ - int row; - - g_return_val_if_fail (E_IS_MEETING_STORE (model), FALSE); - g_return_val_if_fail (iter->stamp == E_MEETING_STORE (model)->priv->stamp, FALSE); - - row = GPOINTER_TO_INT (iter->user_data) + 1; - iter->user_data = GINT_TO_POINTER (row); - - return ROW_VALID (E_MEETING_STORE (model), row); -} - -static gboolean -iter_children (GtkTreeModel *model, GtkTreeIter *iter, GtkTreeIter *parent) -{ - EMeetingStore *store; - - g_return_val_if_fail (E_IS_MEETING_STORE (model), FALSE); - - store = E_MEETING_STORE (model); - - if (parent || store->priv->attendees->len <= 0) - return FALSE; - - iter->stamp = store->priv->stamp; - iter->user_data = GINT_TO_POINTER (0); - - return TRUE; -} - -static gboolean -iter_has_child (GtkTreeModel *model, GtkTreeIter *iter) -{ - return FALSE; -} - -static int -iter_n_children (GtkTreeModel *model, GtkTreeIter *iter) -{ - g_return_val_if_fail (E_IS_MEETING_STORE (model), -1); - - if (!iter) - return E_MEETING_STORE (model)->priv->attendees->len; - - g_return_val_if_fail (iter->stamp == E_MEETING_STORE (model)->priv->stamp, -1); - - return 0; -} - -static gboolean -iter_nth_child (GtkTreeModel *model, GtkTreeIter *iter, GtkTreeIter *parent, int n) -{ - EMeetingStore *store; - - g_return_val_if_fail (E_IS_MEETING_STORE (model), FALSE); - - store = E_MEETING_STORE (model); - - if (parent || !ROW_VALID (store, n)) - return FALSE; - - iter->stamp = store->priv->stamp; - iter->user_data = GINT_TO_POINTER (n); - - return TRUE; -} - -static gboolean -iter_parent (GtkTreeModel *model, GtkTreeIter *iter, GtkTreeIter *child) -{ - return FALSE; -} - -static void -ems_tree_model_init (GtkTreeModelIface *iface) -{ - iface->get_flags = get_flags; - iface->get_n_columns = get_n_columns; - iface->get_column_type = get_column_type; - iface->get_iter = get_iter; - iface->get_path = get_path; - iface->get_value = get_value; - iface->iter_next = iter_next; - iface->iter_children = iter_children; - iface->iter_has_child = iter_has_child; - iface->iter_n_children = iter_n_children; - iface->iter_nth_child = iter_nth_child; - iface->iter_parent = iter_parent; -} - -void -e_meeting_store_set_value (EMeetingStore *store, int row, int col, const gchar *val) -{ - icalparameter_cutype type; - EMeetingAttendee *attendee = g_ptr_array_index (store->priv->attendees, row); - - switch (col) { - case E_MEETING_STORE_ADDRESS_COL: - if (val != NULL && *((char *)val)) - e_meeting_attendee_set_address (attendee, g_strdup_printf ("MAILTO:%s", (char *) val)); - break; - case E_MEETING_STORE_MEMBER_COL: - e_meeting_attendee_set_member (attendee, g_strdup (val)); - break; - case E_MEETING_STORE_TYPE_COL: - type = text_to_type (val); - e_meeting_attendee_set_cutype (attendee, text_to_type (val)); - if (type == ICAL_CUTYPE_RESOURCE) { - e_meeting_attendee_set_role (attendee, ICAL_ROLE_NONPARTICIPANT); - } - break; - case E_MEETING_STORE_ROLE_COL: - e_meeting_attendee_set_role (attendee, text_to_role (val)); - break; - case E_MEETING_STORE_RSVP_COL: - e_meeting_attendee_set_rsvp (attendee, text_to_boolean (val)); - break; - case E_MEETING_STORE_DELTO_COL: - e_meeting_attendee_set_delto (attendee, g_strdup (val)); - break; - case E_MEETING_STORE_DELFROM_COL: - e_meeting_attendee_set_delfrom (attendee, g_strdup (val)); - break; - case E_MEETING_STORE_STATUS_COL: - e_meeting_attendee_set_status (attendee, text_to_partstat (val)); - break; - case E_MEETING_STORE_CN_COL: - e_meeting_attendee_set_cn (attendee, g_strdup (val)); - break; - case E_MEETING_STORE_LANGUAGE_COL: - e_meeting_attendee_set_language (attendee, g_strdup (val)); - break; - } -} - -static gboolean -is_cell_editable (EMeetingStore *etm, int col, int row) -{ - EMeetingStore *store; - EMeetingStorePrivate *priv; - EMeetingAttendee *attendee; - EMeetingAttendeeEditLevel level; - - store = E_MEETING_STORE (etm); - priv = store->priv; - - if (col == E_MEETING_STORE_DELTO_COL - || col == E_MEETING_STORE_DELFROM_COL) - return FALSE; - - if (row == -1) - return TRUE; - if (row >= priv->attendees->len) - return TRUE; - - attendee = g_ptr_array_index (priv->attendees, row); - level = e_meeting_attendee_get_edit_level (attendee); - - switch (level) { - case E_MEETING_ATTENDEE_EDIT_FULL: - return TRUE; - case E_MEETING_ATTENDEE_EDIT_STATUS: - return col == E_MEETING_STORE_STATUS_COL; - case E_MEETING_ATTENDEE_EDIT_NONE: - return FALSE; - } - - return TRUE; -} - -static void -refresh_queue_remove (EMeetingStore *store, EMeetingAttendee *attendee) -{ - EMeetingStorePrivate *priv; - EMeetingStoreQueueData *qdata; - - priv = store->priv; - - /* Free the queue data */ - qdata = g_hash_table_lookup (priv->refresh_data, attendee); - if (qdata) { - g_hash_table_remove (priv->refresh_data, attendee); - 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, attendee); - g_object_unref (attendee); -} - -static void -ems_finalize (GObject *obj) -{ - EMeetingStore *store = E_MEETING_STORE (obj); - EMeetingStorePrivate *priv; - int i; - - priv = store->priv; - - for (i = 0; i < priv->attendees->len; i++) - g_object_unref (g_ptr_array_index (priv->attendees, i)); - g_ptr_array_free (priv->attendees, TRUE); - - if (priv->client != NULL) - g_object_unref (priv->client); - - if (priv->ebook != NULL) - g_object_unref (priv->ebook); - - while (priv->refresh_queue->len > 0) - refresh_queue_remove (store, g_ptr_array_index (priv->refresh_queue, 0)); - g_ptr_array_free (priv->refresh_queue, TRUE); - g_hash_table_destroy (priv->refresh_data); - - if (priv->refresh_idle_id) - g_source_remove (priv->refresh_idle_id); - - g_free (priv); - - if (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (obj); -} - -static void -ems_class_init (GObjectClass *klass) -{ - parent_class = g_type_class_peek_parent (klass); - - klass->finalize = ems_finalize; -} - - -static void -ems_init (EMeetingStore *store) -{ - EMeetingStorePrivate *priv; - - priv = g_new0 (EMeetingStorePrivate, 1); - - store->priv = priv; - - priv->attendees = g_ptr_array_new (); - - priv->zone = icaltimezone_get_builtin_timezone (calendar_config_get_timezone ()); - - priv->refresh_queue = g_ptr_array_new (); - priv->refresh_data = g_hash_table_new (g_direct_hash, g_direct_equal); - - start_addressbook_server (store); -} - -GType -e_meeting_store_get_type (void) -{ - static GType ems_type = 0; - - if (!ems_type) { - static const GTypeInfo ems_info = { - sizeof (EMeetingStoreClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) ems_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (EMeetingStore), - 0, - (GInstanceInitFunc) ems_init }; - - static const GInterfaceInfo tree_model_info = { - (GInterfaceInitFunc) ems_tree_model_init, - NULL, - NULL }; - - ems_type = g_type_register_static (GTK_TYPE_LIST_STORE, - "EMeetingStore", - &ems_info, 0); - - g_type_add_interface_static (ems_type, - GTK_TYPE_TREE_MODEL, - &tree_model_info); - } - - return ems_type; -} - -GObject * -e_meeting_store_new (void) -{ - return g_object_new (E_TYPE_MEETING_STORE, NULL); -} - - -ECal * -e_meeting_store_get_e_cal (EMeetingStore *store) -{ - return store->priv->client; -} - -void -e_meeting_store_set_e_cal (EMeetingStore *store, ECal *client) -{ - if (store->priv->client != NULL) - g_object_unref (store->priv->client); - - if (client != NULL) - g_object_ref (client); - store->priv->client = client; -} - -icaltimezone * -e_meeting_store_get_zone (EMeetingStore *store) -{ - g_return_val_if_fail (E_IS_MEETING_STORE (store), NULL); - - return store->priv->zone; -} - -void -e_meeting_store_set_zone (EMeetingStore *store, icaltimezone *zone) -{ - g_return_if_fail (E_IS_MEETING_STORE (store)); - - store->priv->zone = zone; -} - -static void -attendee_changed_cb (EMeetingAttendee *attendee, gpointer data) -{ - EMeetingStore *store = E_MEETING_STORE (data); - GtkTreePath *path; - GtkTreeIter iter; - gint row = -1, i; - - for (i = 0; i < store->priv->attendees->len; i++) { - if (attendee == g_ptr_array_index (store->priv->attendees, i)) { - row = i; - break; - } - } - - if (row == -1) - return; - - path = gtk_tree_path_new (); - gtk_tree_path_append_index (path, row); - get_iter (GTK_TREE_MODEL (store), &iter, path); - gtk_tree_model_row_changed (GTK_TREE_MODEL (store), path, &iter); - gtk_tree_path_free (path); -} - -void -e_meeting_store_add_attendee (EMeetingStore *store, EMeetingAttendee *attendee) -{ - GtkTreePath *path; - GtkTreeIter iter; - - g_return_if_fail (E_IS_MEETING_STORE (store)); - - g_object_ref (attendee); - g_ptr_array_add (store->priv->attendees, attendee); - - g_signal_connect (attendee, "changed", G_CALLBACK (attendee_changed_cb), store); - - path = gtk_tree_path_new (); - gtk_tree_path_append_index (path, store->priv->attendees->len - 1); - get_iter (GTK_TREE_MODEL (store), &iter, path); - gtk_tree_model_row_inserted (GTK_TREE_MODEL (store), path, &iter); - gtk_tree_path_free (path); -} - -EMeetingAttendee * -e_meeting_store_add_attendee_with_defaults (EMeetingStore *store) -{ - EMeetingAttendee *attendee; - char *str; - - attendee = E_MEETING_ATTENDEE (e_meeting_attendee_new ()); - - e_meeting_attendee_set_address (attendee, g_strdup ("")); - e_meeting_attendee_set_member (attendee, g_strdup ("")); - - str = g_strdup (_("Individual")); - e_meeting_attendee_set_cutype (attendee, text_to_type (str)); - g_free (str); - str = g_strdup (_("Required Participant")); - e_meeting_attendee_set_role (attendee, text_to_role (str)); - g_free (str); - str = g_strdup (_("Yes")); - e_meeting_attendee_set_rsvp (attendee, text_to_boolean (str)); - g_free (str); - - e_meeting_attendee_set_delto (attendee, g_strdup ("")); - e_meeting_attendee_set_delfrom (attendee, g_strdup ("")); - - str = g_strdup (_("Needs Action")); - e_meeting_attendee_set_status (attendee, text_to_partstat (str)); - g_free (str); - - e_meeting_attendee_set_cn (attendee, g_strdup ("")); - e_meeting_attendee_set_language (attendee, g_strdup ("en")); - - e_meeting_store_add_attendee (store, attendee); - - return attendee; -} - -void -e_meeting_store_remove_attendee (EMeetingStore *store, EMeetingAttendee *attendee) -{ - gint i, row = -1; - GtkTreePath *path; - - for (i = 0; i < store->priv->attendees->len; i++) { - if (attendee == g_ptr_array_index (store->priv->attendees, i)) { - row = i; - break; - } - } - - if (row != -1) { - g_ptr_array_remove_index (store->priv->attendees, row); - g_object_unref (attendee); - - path = gtk_tree_path_new (); - gtk_tree_path_append_index (path, row); - gtk_tree_model_row_deleted (GTK_TREE_MODEL (store), path); - gtk_tree_path_free (path); - } -} - -void -e_meeting_store_remove_all_attendees (EMeetingStore *store) -{ - gint i; - GtkTreePath *path = gtk_tree_path_new (); - - gtk_tree_path_append_index (path, 0); - - for (i = 0; i < store->priv->attendees->len; i++) { - EMeetingAttendee *attendee = g_ptr_array_index (store->priv->attendees, i); - g_object_unref (attendee); - - gtk_tree_model_row_deleted (GTK_TREE_MODEL (store), path); - gtk_tree_path_next (path); - } - - g_ptr_array_set_size (store->priv->attendees, 0); - gtk_tree_path_free (path); -} - -EMeetingAttendee * -e_meeting_store_find_attendee (EMeetingStore *store, const gchar *address, gint *row) -{ - EMeetingAttendee *attendee; - int i; - - if (address == NULL) - return NULL; - - for (i = 0; i < store->priv->attendees->len; i++) { - const gchar *attendee_address; - - attendee = g_ptr_array_index (store->priv->attendees, i); - - attendee_address = e_meeting_attendee_get_address (attendee); - if (attendee_address && !g_strcasecmp (itip_strip_mailto (attendee_address), itip_strip_mailto (address))) { - if (row != NULL) - *row = i; - - return attendee; - } - } - - return NULL; -} - -EMeetingAttendee * -e_meeting_store_find_attendee_at_row (EMeetingStore *store, gint row) -{ - g_return_val_if_fail (E_IS_MEETING_STORE (store), NULL); - g_return_val_if_fail (ROW_VALID (store, row), NULL); - - return g_ptr_array_index (store->priv->attendees, row); -} - -gint -e_meeting_store_count_actual_attendees (EMeetingStore *store) -{ - g_return_val_if_fail (E_IS_MEETING_STORE (store), 0); - - return store->priv->attendees->len; -} - -const GPtrArray * -e_meeting_store_get_attendees (EMeetingStore *store) -{ - g_return_val_if_fail (E_IS_MEETING_STORE (store), NULL); - - return store->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; - icalproperty *prop; - const char *tz_tzid; - - prop = icalcomponent_get_first_property (sub_comp, ICAL_TZID_PROPERTY); - tz_tzid = icalproperty_get_tzid (prop); - 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 -process_callbacks (EMeetingStoreQueueData *qdata) -{ - EMeetingStore *store; - int i; - - for (i = 0; i < qdata->call_backs->len; i++) { - EMeetingStoreRefreshCallback 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); - } - - store = qdata->store; - refresh_queue_remove (qdata->store, qdata->attendee); - g_object_unref (store); -} - -static void -process_free_busy_comp (EMeetingAttendee *attendee, - 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 (attendee, - 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 (attendee, - dtend.year, - dtend.month, - dtend.day, - dtend.hour, - dtend.minute); - } - - ip = icalcomponent_get_first_property (fb_comp, ICAL_FREEBUSY_PROPERTY); - while (ip != NULL) { - icalparameter *param; - struct icalperiodtype fb; - EMeetingFreeBusyType busy_type = E_MEETING_FREE_BUSY_LAST; - icalparameter_fbtype fbtype = ICAL_FBTYPE_BUSY; - - fb = icalproperty_get_freebusy (ip); - param = icalproperty_get_first_parameter (ip, ICAL_FBTYPE_PARAMETER); - if (param != NULL) - fbtype = icalparameter_get_fbtype (param); - - switch (fbtype) { - case ICAL_FBTYPE_BUSY: - busy_type = E_MEETING_FREE_BUSY_BUSY; - break; - - case ICAL_FBTYPE_BUSYUNAVAILABLE: - busy_type = E_MEETING_FREE_BUSY_OUT_OF_OFFICE; - break; - - case ICAL_FBTYPE_BUSYTENTATIVE: - busy_type = E_MEETING_FREE_BUSY_TENTATIVE; - break; - - default: - break; - } - - if (busy_type != E_MEETING_FREE_BUSY_LAST) { - icaltimezone *utc_zone = icaltimezone_get_utc_timezone (); - - icaltimezone_convert_time (&fb.start, utc_zone, zone); - icaltimezone_convert_time (&fb.end, utc_zone, zone); - e_meeting_attendee_add_busy_period (attendee, - 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 (EMeetingStoreQueueData *qdata, char *text) -{ - EMeetingStore *store = qdata->store; - EMeetingStorePrivate *priv; - EMeetingAttendee *attendee = qdata->attendee; - icalcomponent *main_comp; - icalcomponent_kind kind = ICAL_NO_COMPONENT; - - priv = store->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 = e_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 (attendee, 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 (attendee, main_comp, priv->zone, NULL); - } - - icalcomponent_free (main_comp); - - process_callbacks (qdata); -} - -static gboolean -refresh_busy_periods (gpointer data) -{ - EMeetingStore *store = E_MEETING_STORE (data); - EMeetingStorePrivate *priv; - EMeetingAttendee *attendee = NULL; - EMeetingStoreQueueData *qdata = NULL; - char *query; - int i; - - priv = store->priv; - - /* Check to see if there are any remaining attendees in the queue */ - for (i = 0; i < priv->refresh_queue->len; i++) { - attendee = g_ptr_array_index (priv->refresh_queue, i); - g_assert (attendee != NULL); - - qdata = g_hash_table_lookup (priv->refresh_data, attendee); - if (!qdata) - continue; - - if (!qdata->refreshing) - break; - } - - /* The everything in the queue is being refreshed */ - if (i >= priv->refresh_queue->len) { - priv->refresh_idle_id = 0; - return FALSE; - } - - /* Indicate we are trying to refresh it */ - qdata->refreshing = TRUE; - - /* We take a ref in case we get destroyed in the gui during a callback */ - g_object_ref (qdata->store); - - /* Check the server for free busy data */ - if (priv->client) { - GList *fb_data = NULL, *users = NULL; - struct icaltimetype itt; - time_t startt, endt; - const char *user; - - itt = icaltime_null_time (); - itt.year = g_date_year (&qdata->start.date); - itt.month = g_date_month (&qdata->start.date); - itt.day = g_date_day (&qdata->start.date); - itt.hour = qdata->start.hour; - itt.minute = qdata->start.minute; - startt = icaltime_as_timet_with_zone (itt, priv->zone); - - itt = icaltime_null_time (); - itt.year = g_date_year (&qdata->end.date); - itt.month = g_date_month (&qdata->end.date); - itt.day = g_date_day (&qdata->end.date); - itt.hour = qdata->end.hour; - itt.minute = qdata->end.minute; - endt = icaltime_as_timet_with_zone (itt, priv->zone); - - user = itip_strip_mailto (e_meeting_attendee_get_address (attendee)); - users = g_list_append (users, g_strdup (user)); - e_cal_get_free_busy (priv->client, users, startt, endt, &fb_data, NULL); - - g_list_foreach (users, (GFunc)g_free, NULL); - g_list_free (users); - - if (fb_data != NULL) { - ECalComponent *comp = fb_data->data; - char *comp_str; - - comp_str = e_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 (!e_meeting_attendee_is_set_address (attendee)) { - process_callbacks (qdata); - return TRUE; - } - - query = g_strdup_printf ("(contains \"email\" \"%s\")", - itip_strip_mailto (e_meeting_attendee_get_address (attendee))); - process_callbacks (qdata); - g_free (query); - - return TRUE; -} - -static void -refresh_queue_add (EMeetingStore *store, int row, - EMeetingTime *start, - EMeetingTime *end, - EMeetingStoreRefreshCallback call_back, - gpointer data) -{ - EMeetingStorePrivate *priv; - EMeetingAttendee *attendee; - EMeetingStoreQueueData *qdata; - - priv = store->priv; - - attendee = g_ptr_array_index (priv->attendees, row); - if (attendee == NULL) - return; - - qdata = g_hash_table_lookup (priv->refresh_data, attendee); - if (qdata == NULL) { - qdata = g_new0 (EMeetingStoreQueueData, 1); - - qdata->store = store; - qdata->attendee = attendee; - e_meeting_attendee_clear_busy_periods (attendee); - e_meeting_attendee_set_has_calendar_info (attendee, 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, attendee, qdata); - } else { - if (e_meeting_time_compare_times (start, &qdata->start) == -1) - qdata->start = *start; - if (e_meeting_time_compare_times (end, &qdata->end) == 1) - qdata->end = *end; - g_ptr_array_add (qdata->call_backs, call_back); - g_ptr_array_add (qdata->data, data); - } - - g_object_ref (attendee); - g_ptr_array_add (priv->refresh_queue, attendee); - - if (priv->refresh_idle_id == 0) - priv->refresh_idle_id = g_idle_add (refresh_busy_periods, store); -} - -static void -async_close (GnomeVFSAsyncHandle *handle, - GnomeVFSResult result, - gpointer data) -{ - EMeetingStoreQueueData *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) -{ - EMeetingStoreQueueData *qdata = data; - GnomeVFSFileSize buf_size = BUF_SIZE - 1; - - if (result != GNOME_VFS_OK && result != GNOME_VFS_ERROR_EOF) { - gnome_vfs_async_close (handle, async_close, qdata); - return; - } - - ((char *)buffer)[read] = '\0'; - qdata->string = g_string_append (qdata->string, buffer); - - if (result == GNOME_VFS_ERROR_EOF) { - gnome_vfs_async_close (handle, async_close, qdata); - return; - } - - gnome_vfs_async_read (handle, qdata->buffer, buf_size, async_read, qdata); -} - -void -e_meeting_store_refresh_all_busy_periods (EMeetingStore *store, - EMeetingTime *start, - EMeetingTime *end, - EMeetingStoreRefreshCallback call_back, - gpointer data) -{ - int i; - - g_return_if_fail (E_IS_MEETING_STORE (store)); - - for (i = 0; i < store->priv->attendees->len; i++) - refresh_queue_add (store, i, start, end, call_back, data); -} - -void -e_meeting_store_refresh_busy_periods (EMeetingStore *store, - int row, - EMeetingTime *start, - EMeetingTime *end, - EMeetingStoreRefreshCallback call_back, - gpointer data) -{ - g_return_if_fail (E_IS_MEETING_STORE (store)); - - refresh_queue_add (store, row, start, end, call_back, data); -} - diff --git a/calendar/gui/e-meeting-store.h b/calendar/gui/e-meeting-store.h deleted file mode 100644 index 8454c380b0..0000000000 --- a/calendar/gui/e-meeting-store.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * e-meeting-store.h - * - * Copyright (C) 2003 Ximian, Inc. - * - * Author: Mike Kestner - * - * 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_STORE_H_ -#define _E_MEETING_STORE_H_ - -#include <gtk/gtkliststore.h> -#include <libecal/e-cal.h> -#include "e-meeting-attendee.h" - -G_BEGIN_DECLS - -#define E_TYPE_MEETING_STORE (e_meeting_store_get_type ()) -#define E_MEETING_STORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_MEETING_STORE, EMeetingStore)) -#define E_MEETING_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_MEETING_STORE, EMeetingStoreClass)) -#define E_IS_MEETING_STORE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_MEETING_STORE)) -#define E_IS_MEETING_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_MEETING_STORE)) - -typedef struct _EMeetingStore EMeetingStore; -typedef struct _EMeetingStorePrivate EMeetingStorePrivate; -typedef struct _EMeetingStoreClass EMeetingStoreClass; - -typedef enum { - E_MEETING_STORE_ADDRESS_COL, - E_MEETING_STORE_MEMBER_COL, - E_MEETING_STORE_TYPE_COL, - E_MEETING_STORE_ROLE_COL, - E_MEETING_STORE_RSVP_COL, - E_MEETING_STORE_DELTO_COL, - E_MEETING_STORE_DELFROM_COL, - E_MEETING_STORE_STATUS_COL, - E_MEETING_STORE_CN_COL, - E_MEETING_STORE_LANGUAGE_COL, - E_MEETING_STORE_ATTENDEE_COL, - E_MEETING_STORE_ATTENDEE_UNDERLINE_COL, - E_MEETING_STORE_COLUMN_COUNT -} EMeetingStoreColumns; - -struct _EMeetingStore { - GtkListStore parent; - - EMeetingStorePrivate *priv; -}; - -struct _EMeetingStoreClass { - GtkListStoreClass parent_class; -}; - -typedef void (* EMeetingStoreRefreshCallback) (gpointer data); - -GType e_meeting_store_get_type (void); -GObject *e_meeting_store_new (void); - -void e_meeting_store_set_value (EMeetingStore *im, int row, int col, const gchar *val); - -ECal *e_meeting_store_get_e_cal (EMeetingStore *im); -void e_meeting_store_set_e_cal (EMeetingStore *im, ECal *client); - -icaltimezone *e_meeting_store_get_zone (EMeetingStore *im); -void e_meeting_store_set_zone (EMeetingStore *im, icaltimezone *zone); - -void e_meeting_store_add_attendee (EMeetingStore *im, EMeetingAttendee *ia); -EMeetingAttendee *e_meeting_store_add_attendee_with_defaults (EMeetingStore *im); - -void e_meeting_store_remove_attendee (EMeetingStore *im, EMeetingAttendee *ia); -void e_meeting_store_remove_all_attendees (EMeetingStore *im); - -EMeetingAttendee *e_meeting_store_find_attendee (EMeetingStore *im, const gchar *address, gint *row); -EMeetingAttendee *e_meeting_store_find_attendee_at_row (EMeetingStore *im, gint row); - -gint e_meeting_store_count_actual_attendees (EMeetingStore *im); -const GPtrArray *e_meeting_store_get_attendees (EMeetingStore *im); - -void e_meeting_store_refresh_all_busy_periods (EMeetingStore *im, - EMeetingTime *start, - EMeetingTime *end, - EMeetingStoreRefreshCallback call_back, - gpointer data); -void e_meeting_store_refresh_busy_periods (EMeetingStore *im, - int row, - EMeetingTime *start, - EMeetingTime *end, - EMeetingStoreRefreshCallback call_back, - gpointer data); - - -G_END_DECLS - -#endif 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 c714684569..0000000000 --- a/calendar/gui/e-meeting-time-sel-item.c +++ /dev/null @@ -1,999 +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-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 -}; - -E_MAKE_TYPE (e_meeting_time_selector_item, "EMeetingTimeSelectorItem", EMeetingTimeSelectorItem, - e_meeting_time_selector_item_class_init, e_meeting_time_selector_item_init, - GNOME_TYPE_CANVAS_ITEM); - -static void -e_meeting_time_selector_item_class_init (EMeetingTimeSelectorItemClass *mts_item_class) -{ - GtkObjectClass *object_class; - GnomeCanvasItemClass *item_class; - - parent_class = g_type_class_peek_parent (mts_item_class); - - 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); - - if (mts_item->normal_cursor) { - gdk_cursor_destroy (mts_item->normal_cursor); - mts_item->normal_cursor = NULL; - } - if (mts_item->resize_cursor) { - gdk_cursor_destroy (mts_item->resize_cursor); - mts_item->resize_cursor = NULL; - } - - 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; - 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; - - 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_store_count_actual_attendees (mts->model) && row_y < height) { - ia = e_meeting_store_find_attendee_at_row (mts->model, row); - - if (e_meeting_attendee_get_has_calendar_info (ia)) { - if (e_meeting_time_selector_item_calculate_busy_range (mts, 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; - gint y, grid_x; - gchar buffer[128], *format; - gint hour, hour_x, hour_y; - GdkRectangle clip_rect; - PangoLayout *layout; - - mts = mts_item->mts; - gc = mts_item->main_gc; - - gdk_gc_set_foreground (gc, &mts->grid_color); - layout = gtk_widget_create_pango_layout (GTK_WIDGET (mts), NULL); - - /* 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. */ - 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); - pango_layout_set_text (layout, buffer, -1); - gdk_draw_layout (drawable, gc, - x + 2, - 4 - scroll_y, - layout); - 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 - scroll_y; - while (hour < mts->last_hour_shown) { - if (calendar_config_get_24_hour_format ()) - pango_layout_set_text (layout, EMeetingTimeSelectorHours [hour], -1); - else - pango_layout_set_text (layout, EMeetingTimeSelectorHours12 [hour], -1); - - gdk_draw_layout (drawable, gc, - hour_x, - hour_y, - layout); - - hour += mts->zoomed_out ? 3 : 1; - hour_x += mts->col_width; - } - - g_object_unref (layout); -} - - -/* 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_store_count_actual_attendees (mts->model)); - for (row = 0; row < e_meeting_store_count_actual_attendees (mts->model); row++) { - ia = e_meeting_store_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_store_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_store_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_store_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; - gint row, y, first_period; - GdkGC *gc; - - mts = mts_item->mts; - gc = mts_item->main_gc; - - /* 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_store_count_actual_attendees (mts->model)) { - - /* Find the first visible busy period. */ - first_period = e_meeting_time_selector_item_find_first_busy_period (mts_item, date, 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, 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_store_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_store_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_store_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 91d915a4d7..0000000000 --- a/calendar/gui/e-meeting-time-sel.c +++ /dev/null @@ -1,2850 +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 <libgnomecanvas/gnome-canvas-widget.h> - -#include <gal/widgets/e-canvas.h> -#include <gal/widgets/e-canvas-utils.h> - -#include <widgets/misc/e-dateedit.h> - -#include "calendar-component.h" -#include "calendar-config.h" -#include "e-meeting-utils.h" -#include "e-meeting-list-view.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_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_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, - gboolean *push_in, - 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 gboolean e_meeting_time_selector_on_invite_others_button_expose (GtkWidget *button, - GdkEventExpose *event, - 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, - gboolean *push_in, - 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 row_inserted_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data); -static void row_changed_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data); -static void row_deleted_cb (GtkTreeModel *model, GtkTreePath *path, gpointer data); - -static GtkTableClass *parent_class; - -E_MAKE_TYPE (e_meeting_time_selector, "EMeetingTimeSelector", EMeetingTimeSelector, - e_meeting_time_selector_class_init, e_meeting_time_selector_init, - GTK_TYPE_TABLE); - -static void -e_meeting_time_selector_class_init (EMeetingTimeSelectorClass * klass) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - - parent_class = g_type_class_peek_parent (klass); - object_class = (GtkObjectClass *) klass; - widget_class = (GtkWidgetClass *) klass; - - mts_signals [CHANGED] = - gtk_signal_new ("changed", GTK_RUN_FIRST, - G_TYPE_FROM_CLASS (object_class), - GTK_SIGNAL_OFFSET (EMeetingTimeSelectorClass, - changed), - gtk_signal_default_marshaller, - GTK_TYPE_NONE, 0); - - 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; -} - - -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->list_view = NULL; -} - - -void -e_meeting_time_selector_construct (EMeetingTimeSelector * mts, EMeetingStore *ems) -{ - char *filename; - GtkWidget *hbox, *vbox, *separator, *button, *label, *table; - GtkWidget *alignment, *child_hbox, *arrow, *menuitem; - GSList *group; - GdkVisual *visual; - GdkColormap *colormap; - guint accel_key; - time_t meeting_start_time; - struct tm *meeting_start_tm; - 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 = 17; - 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_build_filename (calendar_component_peek_config_directory (calendar_component_peek ()), - "config", "et-header-meeting-time-sel", NULL); - mts->model = ems; - - if (mts->model) - g_object_ref (mts->model); - - g_signal_connect (mts->model, "row_inserted", G_CALLBACK (row_inserted_cb), mts); - g_signal_connect (mts->model, "row_changed", G_CALLBACK (row_changed_cb), mts); - g_signal_connect (mts->model, "row_deleted", G_CALLBACK (row_deleted_cb), mts); - - mts->list_view = e_meeting_list_view_new (mts->model); - e_meeting_list_view_column_set_visible (mts->list_view, "Role", FALSE); - e_meeting_list_view_column_set_visible (mts->list_view, "RSVP", FALSE); - gtk_widget_show (GTK_WIDGET (mts->list_view)); - -#if 0 - /* FIXME: do we need sorting here */ - g_signal_connect (real_table->sort_info, "sort_info_changed", G_CALLBACK (sort_info_changed_cb), mts); -#endif - - gtk_box_pack_start (GTK_BOX (mts->attendees_vbox), GTK_WIDGET (mts->list_view), TRUE, TRUE, 6); - - /* 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); - g_signal_connect (mts->display_top, "realize", - G_CALLBACK (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); - g_signal_connect (mts->display_main, "realize", - G_CALLBACK (e_meeting_time_selector_on_canvas_realized), mts); - g_signal_connect (mts->display_main, "size_allocate", - G_CALLBACK (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, 6, 6); - 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 (""); - gtk_label_set_text_with_mnemonic (GTK_LABEL (GTK_BIN (button)->child), - _("_Invite Others...")); - accel_key = gtk_label_get_mnemonic_keyval (GTK_LABEL (GTK_BIN (button)->child)); - gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 6); - gtk_widget_show (button); - gtk_widget_add_accelerator (button, "clicked", mts->accel_group, - accel_key, GDK_MOD1_MASK, 0); - g_signal_connect (button, "clicked", - G_CALLBACK (e_meeting_time_selector_on_invite_others_button_clicked), mts); - g_signal_connect (button, "expose-event", - G_CALLBACK (e_meeting_time_selector_on_invite_others_button_expose), mts); - - mts->options_button = gtk_button_new (); - gtk_box_pack_start (GTK_BOX (hbox), mts->options_button, TRUE, TRUE, 6); - gtk_widget_show (mts->options_button); - - g_signal_connect (mts->options_button, "clicked", - G_CALLBACK (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 (""); - gtk_label_set_text_with_mnemonic (GTK_LABEL (label), _("_Options")); - accel_key = gtk_label_get_mnemonic_keyval (GTK_LABEL (label)); - gtk_box_pack_start (GTK_BOX (child_hbox), label, TRUE, TRUE, 6); - 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, 6); - 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); - - menuitem = gtk_check_menu_item_new_with_label (""); - gtk_label_set_text_with_mnemonic (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); - - g_signal_connect (menuitem, "toggled", - G_CALLBACK (e_meeting_time_selector_on_working_hours_toggled), mts); - gtk_widget_show (menuitem); - - menuitem = gtk_check_menu_item_new_with_label (""); - gtk_label_set_text_with_mnemonic (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); - - g_signal_connect (menuitem, "toggled", - G_CALLBACK (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 (""); - gtk_label_set_text_with_mnemonic (GTK_LABEL (GTK_BIN (menuitem)->child), _("_Update Free/Busy")); - gtk_menu_append (GTK_MENU (mts->options_menu), menuitem); - - g_signal_connect (menuitem, "activate", - G_CALLBACK (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 (""); - gtk_label_set_text_with_mnemonic (GTK_LABEL (GTK_BIN (button)->child), - _("_<<")); - accel_key = gtk_label_get_mnemonic_keyval (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, 6); - gtk_widget_show (button); - g_signal_connect (button, "clicked", - G_CALLBACK (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, 6); - 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 (""); - gtk_label_set_text_with_mnemonic (GTK_LABEL (label), _("_Autopick")); - accel_key = gtk_label_get_mnemonic_keyval (GTK_LABEL (label)); - gtk_box_pack_start (GTK_BOX (child_hbox), label, TRUE, TRUE, 6); - gtk_widget_show (label); - gtk_widget_add_accelerator (mts->autopick_button, "clicked", mts->accel_group, - accel_key, GDK_MOD1_MASK, 0); - g_signal_connect (mts->autopick_button, "clicked", - G_CALLBACK (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, 6); - gtk_widget_show (arrow); - - button = gtk_button_new_with_label (""); - gtk_label_set_text_with_mnemonic (GTK_LABEL (GTK_BIN (button)->child), - _(">_>")); - accel_key = gtk_label_get_mnemonic_keyval (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, 6); - gtk_widget_show (button); - g_signal_connect (button, "clicked", - G_CALLBACK (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); - - 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)); - gtk_label_set_text_with_mnemonic (GTK_LABEL (GTK_BIN (menuitem)->child), _("_All People and Resources")); - gtk_menu_append (GTK_MENU (mts->autopick_menu), menuitem); - g_signal_connect (menuitem, "toggled", - G_CALLBACK (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)); - gtk_label_set_text_with_mnemonic (GTK_LABEL (GTK_BIN (menuitem)->child), _("All _People and One Resource")); - gtk_menu_append (GTK_MENU (mts->autopick_menu), menuitem); - g_signal_connect (menuitem, "toggled", - G_CALLBACK (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)); - gtk_label_set_text_with_mnemonic (GTK_LABEL (GTK_BIN (menuitem)->child), _("_Required People")); - gtk_menu_append (GTK_MENU (mts->autopick_menu), menuitem); - g_signal_connect (menuitem, "activate", - G_CALLBACK (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)); - gtk_label_set_text_with_mnemonic (GTK_LABEL (GTK_BIN (menuitem)->child), _("Required People and _One Resource")); - gtk_menu_append (GTK_MENU (mts->autopick_menu), menuitem); - g_signal_connect (menuitem, "activate", - G_CALLBACK (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 (""); - gtk_label_set_text_with_mnemonic (GTK_LABEL (label), - _("Meeting _start time:")); - accel_key = gtk_label_get_mnemonic_keyval (GTK_LABEL (label)); - 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); - g_signal_connect (mts->start_date_edit, "changed", - G_CALLBACK (e_meeting_time_selector_on_start_time_changed), mts); - - label = gtk_label_new (""); - gtk_label_set_text_with_mnemonic (GTK_LABEL (label), - _("Meeting _end time:")); - accel_key = gtk_label_get_mnemonic_keyval (GTK_LABEL (label)); - 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); - g_signal_connect (mts->end_date_edit, "changed", - G_CALLBACK (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)); - 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. */ - g_signal_connect (GTK_LAYOUT (mts->display_main)->hadjustment, "value_changed", - G_CALLBACK (e_meeting_time_selector_hadjustment_changed), mts); - g_signal_connect (GTK_LAYOUT (mts->display_main)->vadjustment, "value_changed", - G_CALLBACK (e_meeting_time_selector_vadjustment_changed), mts); - g_signal_connect (GTK_LAYOUT (mts->display_main)->vadjustment, "changed", - G_CALLBACK (e_meeting_time_selector_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, 6); - gtk_widget_show (label); - - g_signal_connect (darea, "expose_event", - G_CALLBACK (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) -{ - GdkColormap *colormap; - - g_return_if_fail (name != NULL); - g_return_if_fail (c != NULL); - - gdk_color_parse (name, c); - colormap = gtk_widget_get_colormap (GTK_WIDGET (mts)); - if (!gdk_colormap_alloc_color (colormap, c, TRUE, TRUE)) - 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 (EMeetingStore *ems) -{ - GtkWidget *mts; - - mts = GTK_WIDGET (g_object_new (e_meeting_time_selector_get_type (), NULL)); - - e_meeting_time_selector_construct (E_MEETING_TIME_SELECTOR (mts), ems); - - 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); - - if (mts->stipple) { - gdk_bitmap_unref (mts->stipple); - mts->stipple = NULL; - } - - if (mts->model) { - g_object_unref (mts->model); - mts->model = NULL; - } - - mts->display_top = NULL; - mts->display_main = NULL; - - 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; - int hour, max_hour_width; - int maxheight; - PangoFontDescription *font_desc; - PangoContext *pango_context; - PangoFontMetrics *font_metrics; - PangoLayout *layout; - GtkTreePath *path; - GdkRectangle cell_area; - - if (GTK_WIDGET_CLASS (parent_class)->style_set) - (*GTK_WIDGET_CLASS (parent_class)->style_set)(widget, previous_style); - - mts = E_MEETING_TIME_SELECTOR (widget); - - /* Set up Pango prerequisites */ - font_desc = gtk_widget_get_style (widget)->font_desc; - pango_context = gtk_widget_get_pango_context (widget); - font_metrics = pango_context_get_metrics (pango_context, font_desc, - pango_context_get_language (pango_context)); - layout = pango_layout_new (pango_context); - - /* 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 ()) - pango_layout_set_text (layout, EMeetingTimeSelectorHours [hour], -1); - else - pango_layout_set_text (layout, EMeetingTimeSelectorHours12 [hour], -1); - - pango_layout_get_pixel_size (layout, &mts->hour_widths [hour], NULL); - max_hour_width = MAX (max_hour_width, mts->hour_widths[hour]); - } - - pango_layout_get_pixel_size (layout, NULL, &mts->row_height); - mts->col_width = max_hour_width + 6; - - 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 + 4); - - /* Calculate header height */ - if (GTK_WIDGET_REALIZED (mts->list_view)) { - path = gtk_tree_path_new (); - gtk_tree_path_append_index (path, 0); - gtk_tree_view_get_cell_area (GTK_TREE_VIEW (mts->list_view), path, NULL, &cell_area); - gtk_tree_path_free (path); - maxheight = cell_area.y; - } else - maxheight = 10; - - gtk_widget_set_usize (mts->attendees_vbox_spacer, 1, mts->row_height * 3 - maxheight); - - GTK_LAYOUT (mts->display_main)->hadjustment->step_increment = mts->col_width; - GTK_LAYOUT (mts->display_main)->vadjustment->step_increment = mts->row_height; - - g_object_unref (layout); - pango_font_metrics_unref (font_metrics); -} - -/* 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_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 = gtk_tree_view_get_vadjustment (GTK_TREE_VIEW (mts->list_view)); - 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; - - /* Make sure we always show atleast an hour */ - if (day_start_hour * 60 + day_start_minute + 60 < day_end_hour * 60 + day_end_minute) { - mts->day_end_hour = day_end_hour; - mts->day_end_minute = day_end_minute; - } else { - mts->day_end_hour = day_start_hour + 1; - mts->day_end_minute = day_start_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; - - if (mts->display_top != NULL) - gtk_widget_queue_draw (mts->display_top); - if (mts->display_main != NULL) - gtk_widget_queue_draw (mts->display_main); - - gtk_object_unref (GTK_OBJECT (mts)); -} - -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; - - /* Ref ourselves in case we are called back after destruction, - * we can do this because we will get a call back even after - * an error */ - /* FIXME We should really have a mechanism to unqueue the - * notification */ - if (all) { - int i; - - for (i = 0; i < e_meeting_store_count_actual_attendees (mts->model); i++) - gtk_object_ref (GTK_OBJECT (mts)); - } else { - gtk_object_ref (GTK_OBJECT (mts)); - } - - if (all) - e_meeting_store_refresh_all_busy_periods (mts->model, &start, &end, - e_meeting_time_selector_refresh_cb, mts); - else - e_meeting_store_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 gboolean -e_meeting_time_selector_on_invite_others_button_expose (GtkWidget *button, - GdkEventExpose *event, - EMeetingTimeSelector *mts) -{ - gboolean click_to_add = TRUE; - - gtk_widget_set_sensitive (button, click_to_add); - return FALSE; -} - -static void -e_meeting_time_selector_on_invite_others_button_clicked (GtkWidget *button, - EMeetingTimeSelector *mts) -{ - e_meeting_list_view_invite_others_dialog (mts->list_view); -} - - -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, - gboolean *push_in, - 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); - *x += mts->options_button->allocation.x; - *y += mts->options_button->allocation.y + mts->options_button->allocation.height / 2 - 2; - - /* 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, - gboolean *push_in, - 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); - *x += mts->autopick_button->allocation.x; - *y += mts->autopick_button->allocation.y + mts->autopick_button->allocation.height / 2 - 2; - - /* 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_store_count_actual_attendees (mts->model); row++) { - attendee = e_meeting_store_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); - e_meeting_time_selector_ensure_meeting_time_shown (mts); -} - - -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); - e_meeting_time_selector_ensure_meeting_time_shown (mts); -} - - -/* 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]; - PangoFontDescription *font_desc; - PangoContext *pango_context; - PangoLayout *layout; - - /* Set up Pango prerequisites */ - font_desc = gtk_widget_get_style (GTK_WIDGET (mts))->font_desc; - pango_context = gtk_widget_get_pango_context (GTK_WIDGET (mts)); - layout = pango_layout_new (pango_context); - - /* 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); - pango_layout_set_text (layout, buffer, -1); - pango_layout_get_pixel_size (layout, &width, NULL); - 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); - pango_layout_set_text (layout, buffer, -1); - pango_layout_get_pixel_size (layout, &width, NULL); - 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 - - pango_layout_set_text (layout, buffer, -1); - pango_layout_get_pixel_size (layout, &width, NULL); - if (width < 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); - pango_layout_set_text (layout, buffer, -1); - pango_layout_get_pixel_size (layout, &width, NULL); - 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 - - pango_layout_set_text (layout, buffer, -1); - pango_layout_get_pixel_size (layout, &width, NULL); - if (width < max_date_width) - mts->date_format = E_MEETING_TIME_SELECTOR_DATE_ABBREVIATED_DAY; - else - mts->date_format = E_MEETING_TIME_SELECTOR_DATE_SHORT; - - g_object_unref (layout); -} - - -/* 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_store_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 -row_inserted_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) -{ - EMeetingTimeSelector *mts = E_MEETING_TIME_SELECTOR (data); - int row = gtk_tree_path_get_indices (path) [0]; - /* 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 */ - e_meeting_time_selector_refresh_free_busy (mts, row, FALSE); -} - -static void -row_changed_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) -{ - EMeetingTimeSelector *mts = E_MEETING_TIME_SELECTOR (data); - int row = gtk_tree_path_get_indices (path) [0]; - - /* Get the latest free/busy info */ - e_meeting_time_selector_refresh_free_busy (mts, row, FALSE); -} - -static void -row_deleted_cb (GtkTreeModel *model, GtkTreePath *path, 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); -} - 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 ee23dbe672..0000000000 --- a/calendar/gui/e-meeting-time-sel.h +++ /dev/null @@ -1,379 +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 <libgnomecanvas/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-store.h" -#include "e-meeting-list-view.h" - -G_BEGIN_DECLS - -/* - * 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 */ - EMeetingStore *model; - EMeetingListView *list_view; - - /* 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. */ - 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 (EMeetingStore *ems); -void e_meeting_time_selector_construct (EMeetingTimeSelector * mts, EMeetingStore *ems); - -/* 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 */ - -G_END_DECLS - -#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-mini-calendar-config.c b/calendar/gui/e-mini-calendar-config.c deleted file mode 100644 index 2f17b23beb..0000000000 --- a/calendar/gui/e-mini-calendar-config.c +++ /dev/null @@ -1,247 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Author : - * JP Rosevear <jpr@ximian.com> - * - * Copyright 2003, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include "calendar-config.h" -#include "e-mini-calendar-config.h" - -struct _EMiniCalendarConfigPrivate { - ECalendar *mini_cal; - - GList *notifications; -}; - -static GObjectClass *parent_class = NULL; - -/* Property IDs */ -enum props { - PROP_0, - PROP_CALENDAR -}; - -static void -e_mini_calendar_config_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) -{ - EMiniCalendarConfig *mini_config; - EMiniCalendarConfigPrivate *priv; - - mini_config = E_MINI_CALENDAR_CONFIG (object); - priv = mini_config->priv; - - switch (property_id) { - case PROP_CALENDAR: - e_mini_calendar_config_set_calendar (mini_config, g_value_get_object (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -e_mini_calendar_config_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) -{ - EMiniCalendarConfig *mini_config; - EMiniCalendarConfigPrivate *priv; - - mini_config = E_MINI_CALENDAR_CONFIG (object); - priv = mini_config->priv; - - switch (property_id) { - case PROP_CALENDAR: - g_value_set_object (value, e_mini_calendar_config_get_calendar (mini_config)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -e_mini_calendar_config_dispose (GObject *object) -{ - EMiniCalendarConfig *mini_config = E_MINI_CALENDAR_CONFIG (object); - EMiniCalendarConfigPrivate *priv; - - priv = mini_config->priv; - - e_mini_calendar_config_set_calendar (mini_config, NULL); - - if (G_OBJECT_CLASS (parent_class)->dispose) - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -e_mini_calendar_config_finalize (GObject *object) -{ - EMiniCalendarConfig *mini_config = E_MINI_CALENDAR_CONFIG (object); - EMiniCalendarConfigPrivate *priv; - - priv = mini_config->priv; - - g_free (priv); - - if (G_OBJECT_CLASS (parent_class)->finalize) - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -e_mini_calendar_config_class_init (EMiniCalendarConfigClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GParamSpec *spec; - - parent_class = g_type_class_peek_parent (klass); - - /* Method override */ - gobject_class->set_property = e_mini_calendar_config_set_property; - gobject_class->get_property = e_mini_calendar_config_get_property; - gobject_class->dispose = e_mini_calendar_config_dispose; - gobject_class->finalize = e_mini_calendar_config_finalize; - - spec = g_param_spec_object ("calendar", NULL, NULL, e_calendar_get_type (), - G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT); - g_object_class_install_property (gobject_class, PROP_CALENDAR, spec); -} - -static void -e_mini_calendar_config_init (EMiniCalendarConfig *mini_config, EMiniCalendarConfigClass *klass) -{ - mini_config->priv = g_new0 (EMiniCalendarConfigPrivate, 1); - -} - -E_MAKE_TYPE (e_mini_calendar_config, "EMiniCalendarConfig", EMiniCalendarConfig, e_mini_calendar_config_class_init, - e_mini_calendar_config_init, G_TYPE_OBJECT); - -EMiniCalendarConfig * -e_mini_calendar_config_new (ECalendar *mini_cal) -{ - EMiniCalendarConfig *mini_config; - - mini_config = g_object_new (e_mini_calendar_config_get_type (), "calendar", mini_cal, NULL); - - return mini_config; -} - -ECalendar * -e_mini_calendar_config_get_calendar (EMiniCalendarConfig *mini_config) -{ - EMiniCalendarConfigPrivate *priv; - - g_return_val_if_fail (mini_config != NULL, NULL); - g_return_val_if_fail (E_IS_MINI_CALENDAR_CONFIG (mini_config), NULL); - - priv = mini_config->priv; - - return priv->mini_cal; -} - -static void -set_week_start (ECalendar *mini_cal) -{ - int week_start_day; - - 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 (mini_cal->calitem), - "week_start_day", week_start_day, - NULL); -} - -static void -week_start_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - EMiniCalendarConfig *mini_config = data; - EMiniCalendarConfigPrivate *priv; - - priv = mini_config->priv; - - set_week_start (priv->mini_cal); -} - -static void -set_dnav_show_week_no (ECalendar *mini_cal) -{ - gboolean show_week_no; - - show_week_no = calendar_config_get_dnav_show_week_no (); - - gnome_canvas_item_set (GNOME_CANVAS_ITEM (mini_cal->calitem), - "show_week_numbers", show_week_no, - NULL); -} - -static void -dnav_show_week_no_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - EMiniCalendarConfig *mini_config = data; - EMiniCalendarConfigPrivate *priv; - - priv = mini_config->priv; - - set_dnav_show_week_no (priv->mini_cal); -} - -void -e_mini_calendar_config_set_calendar (EMiniCalendarConfig *mini_config, ECalendar *mini_cal) -{ - EMiniCalendarConfigPrivate *priv; - guint not; - GList *l; - - g_return_if_fail (mini_config != NULL); - g_return_if_fail (E_IS_MINI_CALENDAR_CONFIG (mini_config)); - - priv = mini_config->priv; - - if (priv->mini_cal) { - g_object_unref (priv->mini_cal); - priv->mini_cal = NULL; - } - - for (l = priv->notifications; l; l = l->next) - calendar_config_remove_notification (GPOINTER_TO_UINT (l->data)); - - g_list_free (priv->notifications); - priv->notifications = NULL; - - /* If the new view is NULL, return right now */ - if (!mini_cal) - return; - - priv->mini_cal = g_object_ref (mini_cal); - - /* Week start */ - set_week_start (mini_cal); - - not = calendar_config_add_notification_week_start_day (week_start_changed_cb, mini_config); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - /* Show week numbers */ - set_dnav_show_week_no (mini_cal); - - not = calendar_config_add_notification_dnav_show_week_no (dnav_show_week_no_changed_cb, mini_config); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); -} diff --git a/calendar/gui/e-mini-calendar-config.h b/calendar/gui/e-mini-calendar-config.h deleted file mode 100644 index 78b9cfd363..0000000000 --- a/calendar/gui/e-mini-calendar-config.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Author : - * JP Rosevear <jpr@ximian.com> - * - * Copyright 2003, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef _E_MINI_CALENDAR_CONFIG_H_ -#define _E_MINI_CALENDAR_CONFIG_H_ - -#include <widgets/misc/e-calendar.h> - -G_BEGIN_DECLS - -#define E_MINI_CALENDAR_CONFIG(obj) GTK_CHECK_CAST (obj, e_mini_calendar_config_get_type (), EMiniCalendarConfig) -#define E_MINI_CALENDAR_CONFIG_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, e_mini_calendar_config_get_type (), EMiniCalendarConfigClass) -#define E_IS_MINI_CALENDAR_CONFIG(obj) GTK_CHECK_TYPE (obj, e_mini_calendar_config_get_type ()) - -typedef struct _EMiniCalendarConfig EMiniCalendarConfig; -typedef struct _EMiniCalendarConfigClass EMiniCalendarConfigClass; -typedef struct _EMiniCalendarConfigPrivate EMiniCalendarConfigPrivate; - -struct _EMiniCalendarConfig { - GObject parent; - - EMiniCalendarConfigPrivate *priv; -}; - -struct _EMiniCalendarConfigClass { - GObjectClass parent_class; -}; - -GType e_mini_calendar_config_get_type (void); -EMiniCalendarConfig *e_mini_calendar_config_new (ECalendar *mini_cal); -ECalendar *e_mini_calendar_config_get_calendar (EMiniCalendarConfig *mini_config); -void e_mini_calendar_config_set_calendar (EMiniCalendarConfig *mini_config, ECalendar *mini_cal); - -G_END_DECLS - -#endif diff --git a/calendar/gui/e-select-names-editable.c b/calendar/gui/e-select-names-editable.c deleted file mode 100644 index cf2cd1d661..0000000000 --- a/calendar/gui/e-select-names-editable.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * e-select-names-editable.c - * - * Author: Mike Kestner <mkestner@ximian.com> - * - * Copyright (C) 2003 Ximian Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include <config.h> -#include <gdk/gdkkeysyms.h> -#include <gtk/gtkcelleditable.h> -#include <bonobo/bonobo-exception.h> -#include <bonobo/bonobo-widget.h> -#include <addressbook/util/eab-destination.h> - -#include "e-select-names-editable.h" -#include "Evolution-Addressbook-SelectNames.h" - -#define SELECT_NAMES_OAFIID "OAFIID:GNOME_Evolution_Addressbook_SelectNames:" BASE_VERSION - -struct _ESelectNamesEditablePriv { - GNOME_Evolution_Addressbook_SelectNames select_names; - Bonobo_Control control; - Bonobo_PropertyBag bag; -}; - -static BonoboWidgetClass *parent_class; - -static void -esne_start_editing (GtkCellEditable *cell_editable, GdkEvent *event) -{ - ESelectNamesEditable *esne = E_SELECT_NAMES_EDITABLE (cell_editable); - -} - -static void -esne_cell_editable_init (GtkCellEditableIface *iface) -{ - iface->start_editing = esne_start_editing; -} - -static void -esne_finalize (GObject *obj) -{ - ESelectNamesEditable *esne = (ESelectNamesEditable *) obj; - - if (esne->priv->select_names != CORBA_OBJECT_NIL) - bonobo_object_release_unref (esne->priv->select_names, NULL); - esne->priv->select_names = CORBA_OBJECT_NIL; - - if (esne->priv->bag != CORBA_OBJECT_NIL) - bonobo_object_release_unref (esne->priv->bag, NULL); - esne->priv->bag = CORBA_OBJECT_NIL; - - g_free (esne->priv); - - if (G_OBJECT_CLASS (parent_class)->finalize) - G_OBJECT_CLASS (parent_class)->finalize (obj); -} - -static void -esne_init (ESelectNamesEditable *esne) -{ - esne->priv = g_new0 (ESelectNamesEditablePriv, 1); - - esne->priv->select_names = CORBA_OBJECT_NIL; - esne->priv->control = CORBA_OBJECT_NIL; - esne->priv->bag = CORBA_OBJECT_NIL; -} - -static void -esne_class_init (GObjectClass *klass) -{ - klass->finalize = esne_finalize; - - parent_class = BONOBO_WIDGET_CLASS (g_type_class_peek_parent (klass)); -} - -GType -e_select_names_editable_get_type (void) -{ - static GType esne_type = 0; - - if (!esne_type) { - static const GTypeInfo esne_info = { - sizeof (ESelectNamesEditableClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) esne_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (ESelectNamesEditable), - 0, /* n_preallocs */ - (GInstanceInitFunc) esne_init, - }; - - static const GInterfaceInfo cell_editable_info = { - (GInterfaceInitFunc) esne_cell_editable_init, - NULL, - NULL - }; - - esne_type = g_type_register_static (BONOBO_TYPE_WIDGET, "ESelectNamesEditable", &esne_info, 0); - - g_type_add_interface_static (esne_type, GTK_TYPE_CELL_EDITABLE, &cell_editable_info); - } - - return esne_type; -} - -static void -entry_activate (BonoboListener *listener, const char *event_name, const CORBA_any *arg, CORBA_Environment *ev, gpointer esne) -{ - gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (esne)); - gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (esne)); -} - -ESelectNamesEditable * -e_select_names_editable_construct (ESelectNamesEditable *esne) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - esne->priv->select_names = bonobo_activation_activate_from_id (SELECT_NAMES_OAFIID, 0, NULL, &ev); - if (BONOBO_EX (&ev)) { - CORBA_exception_free (&ev); - return NULL; - } - - GNOME_Evolution_Addressbook_SelectNames_addSection (esne->priv->select_names, "A", "A", &ev); - if (BONOBO_EX (&ev)) { - CORBA_exception_free (&ev); - return NULL; - } - - esne->priv->control = GNOME_Evolution_Addressbook_SelectNames_getEntryBySection ( - esne->priv->select_names, "A", &ev); - if (BONOBO_EX (&ev)) { - CORBA_exception_free (&ev); - return NULL; - } - - bonobo_widget_construct_control_from_objref (BONOBO_WIDGET (esne), esne->priv->control, CORBA_OBJECT_NIL, &ev); - - CORBA_exception_free (&ev); - - esne->priv->bag = bonobo_control_frame_get_control_property_bag ( - bonobo_widget_get_control_frame (BONOBO_WIDGET (esne)), NULL); - bonobo_event_source_client_add_listener (esne->priv->bag, entry_activate, - "GNOME/Evolution/Addressbook/SelectNames:activate:entry", - NULL, esne); - - return esne; -} - -ESelectNamesEditable * -e_select_names_editable_new () -{ - ESelectNamesEditable *esne = g_object_new (E_TYPE_SELECT_NAMES_EDITABLE, NULL); - - if (!esne) - return NULL; - - if (!e_select_names_editable_construct (esne)) { - g_object_unref (esne); - return NULL; - } - - return esne; -} - -gchar * -e_select_names_editable_get_address (ESelectNamesEditable *esne) -{ - EABDestination **dest; - gchar *dest_str; - gchar *result; - - g_return_val_if_fail (E_SELECT_NAMES_EDITABLE (esne), NULL); - - dest_str = bonobo_pbclient_get_string (esne->priv->bag, "destinations", NULL); - dest = eab_destination_importv (dest_str); - result = g_strdup (eab_destination_get_email (*dest)); - eab_destination_freev (dest); - - return result; -} - -gchar * -e_select_names_editable_get_name (ESelectNamesEditable *esne) -{ - EABDestination **dest; - gchar *dest_str; - gchar *result; - - g_return_val_if_fail (E_SELECT_NAMES_EDITABLE (esne), NULL); - - dest_str = bonobo_pbclient_get_string (esne->priv->bag, "destinations", NULL); - dest = eab_destination_importv (dest_str); - result = g_strdup (eab_destination_get_name (*dest)); - eab_destination_freev (dest); - - return result; -} - -void -e_select_names_editable_set_address (ESelectNamesEditable *esne, const gchar *text) -{ - g_return_if_fail (E_IS_SELECT_NAMES_EDITABLE (esne)); - - bonobo_pbclient_set_string (esne->priv->bag, "addresses", text, NULL); -} - diff --git a/calendar/gui/e-select-names-editable.h b/calendar/gui/e-select-names-editable.h deleted file mode 100644 index 867118fe9e..0000000000 --- a/calendar/gui/e-select-names-editable.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * e-select-names-editable.h - * - * Author: Mike Kestner <mkestner@ximian.com> - * - * Copyright (C) 2003 Ximian Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __E_SELECT_NAMES_EDITABLE_H__ -#define __E_SELECT_NAMES_EDITABLE_H__ - -#include <bonobo/bonobo-widget.h> - -G_BEGIN_DECLS - -#define E_TYPE_SELECT_NAMES_EDITABLE (e_select_names_editable_get_type ()) -#define E_SELECT_NAMES_EDITABLE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_SELECT_NAMES_EDITABLE, ESelectNamesEditable)) -#define E_SELECT_NAMES_EDITABLE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), E_TYPE_SELECT_NAMES_EDITABLE, ESelectNamesEditableClass)) -#define E_IS_SELECT_NAMES_EDITABLE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_SELECT_NAMES_EDITABLE)) -#define E_IS_SELECT_NAMES_EDITABLE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((o), E_TYPE_SELECT_NAMES_EDITABLE)) -#define E_SELECT_NAMES_EDITABLE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), E_TYPE_SELECT_NAMES_EDITABLE, ESelectNamesEditableClass)) - -typedef struct _ESelectNamesEditable ESelectNamesEditable; -typedef struct _ESelectNamesEditableClass ESelectNamesEditableClass; -typedef struct _ESelectNamesEditablePriv ESelectNamesEditablePriv; - -struct _ESelectNamesEditable -{ - BonoboWidget parent; - - ESelectNamesEditablePriv *priv; -}; - -struct _ESelectNamesEditableClass -{ - BonoboWidgetClass parent_class; -}; - -GType e_select_names_editable_get_type (void); - -ESelectNamesEditable *e_select_names_editable_construct (ESelectNamesEditable *esne); -ESelectNamesEditable *e_select_names_editable_new (void); - -gchar *e_select_names_editable_get_address (ESelectNamesEditable *esne); -void e_select_names_editable_set_address (ESelectNamesEditable *esne, const gchar *text); - -gchar *e_select_names_editable_get_name (ESelectNamesEditable *esne); -G_END_DECLS - -#endif /* __E_SELECT_NAMES_EDITABLE_H__ */ diff --git a/calendar/gui/e-select-names-renderer.c b/calendar/gui/e-select-names-renderer.c deleted file mode 100644 index fbda387d23..0000000000 --- a/calendar/gui/e-select-names-renderer.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * e-select-names-renderer.c - * - * Author: Mike Kestner <mkestner@ximian.com> - * - * Copyright (C) 2003 Ximian Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include <config.h> -#include <gtk/gtkcellrenderertext.h> -#include <gal/util/e-util.h> - -#include "e-calendar-marshal.h" - -#include "e-select-names-editable.h" -#include "e-select-names-renderer.h" - - -struct _ESelectNamesRendererPriv { - ESelectNamesEditable *editable; - gchar *path; - gchar *address; -}; - -enum { - PROP_0, - PROP_ADDRESS -}; - -enum { - CELL_EDITED, - LAST_SIGNAL -}; - -static GtkCellRendererTextClass *parent_class; -static gint signals [LAST_SIGNAL]; - -static void -esnr_editing_done (GtkCellEditable *editable, ESelectNamesRenderer *cell) -{ - gchar *new_address, *new_name; - - new_address = e_select_names_editable_get_address (E_SELECT_NAMES_EDITABLE (editable)); - new_name = e_select_names_editable_get_name (E_SELECT_NAMES_EDITABLE (editable)); - - g_signal_emit (cell, signals [CELL_EDITED], 0, cell->priv->path, new_address, new_name); - g_free (new_address); - g_free (new_name); - g_free (cell->priv->path); - cell->priv->path = NULL; -} - -static GtkCellEditable * -esnr_start_editing (GtkCellRenderer *cell, GdkEvent *event, GtkWidget *widget, const gchar *path, - GdkRectangle *bg_area, GdkRectangle *cell_area, GtkCellRendererState flags) -{ - ESelectNamesRenderer *sn_cell = E_SELECT_NAMES_RENDERER (cell); - GtkCellRendererText *text_cell = GTK_CELL_RENDERER_TEXT (cell); - ESelectNamesEditable *editable; - - if (!text_cell->editable) - return NULL; - - editable = E_SELECT_NAMES_EDITABLE (e_select_names_editable_new ()); - e_select_names_editable_set_address (editable, sn_cell->priv->address); - gtk_widget_show (GTK_WIDGET (editable)); - - g_signal_connect (editable, "editing-done", G_CALLBACK (esnr_editing_done), sn_cell); - - sn_cell->priv->editable = g_object_ref (editable); - sn_cell->priv->path = g_strdup (path); - - return GTK_CELL_EDITABLE (editable); -} - -static void -esnr_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) -{ - ESelectNamesRenderer *esnr = E_SELECT_NAMES_RENDERER (object); - - switch (prop_id) { - case PROP_ADDRESS: - g_value_set_string (value, esnr->priv->address); - break; - default: - break; - } -} - -static void -esnr_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) -{ - ESelectNamesRenderer *esnr = E_SELECT_NAMES_RENDERER (object); - - switch (prop_id) { - case PROP_ADDRESS: - g_free (esnr->priv->address); - esnr->priv->address = g_strdup (g_value_get_string (value)); - break; - default: - break; - } -} - -static void -esnr_finalize (GObject *obj) -{ - ESelectNamesRenderer *cell = (ESelectNamesRenderer *) obj; - - if (cell->priv->editable) - g_object_unref (cell->priv->editable); - cell->priv->editable = NULL; - - g_free (cell->priv->path); - g_free (cell->priv->address); - g_free (cell->priv); - - if (G_OBJECT_CLASS (parent_class)->finalize) - G_OBJECT_CLASS (parent_class)->finalize (obj); -} - -static void -esnr_init (ESelectNamesRenderer *cell) -{ - cell->priv = g_new0 (ESelectNamesRendererPriv, 1); -} - -static void -esnr_class_init (ESelectNamesRendererClass *class) -{ - GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (class); - GObjectClass *obj_class = G_OBJECT_CLASS (class); - - parent_class = GTK_CELL_RENDERER_TEXT_CLASS (g_type_class_peek_parent (class)); - - obj_class->finalize = esnr_finalize; - obj_class->get_property = esnr_get_property; - obj_class->set_property = esnr_set_property; - - cell_class->start_editing = esnr_start_editing; - - g_object_class_install_property (obj_class, PROP_ADDRESS, - g_param_spec_string ("address", "Address", "Email address.", NULL, G_PARAM_READWRITE)); - - signals [CELL_EDITED] = g_signal_new ("cell_edited", - G_OBJECT_CLASS_TYPE (obj_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ESelectNamesRendererClass, cell_edited), - NULL, NULL, - e_calendar_marshal_VOID__STRING_STRING_STRING, - G_TYPE_NONE, 3, - G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); -} - -E_MAKE_TYPE (e_select_names_renderer, "ESelectNamesRenderer", ESelectNamesRenderer, esnr_class_init, esnr_init, GTK_TYPE_CELL_RENDERER_TEXT) - -GtkCellRenderer * -e_select_names_renderer_new (void) -{ - return GTK_CELL_RENDERER (g_object_new (E_TYPE_SELECT_NAMES_RENDERER, NULL)); -} - diff --git a/calendar/gui/e-select-names-renderer.h b/calendar/gui/e-select-names-renderer.h deleted file mode 100644 index fb045d928f..0000000000 --- a/calendar/gui/e-select-names-renderer.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * e-select-names-renderer.h - * - * Author: Mike Kestner <mkestner@ximian.com> - * - * Copyright (C) 2003 Ximian Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __E_SELECT_NAMES_RENDERER_H__ -#define __E_SELECT_NAMES_RENDERER_H__ - -#include <gtk/gtkcellrenderertext.h> - -G_BEGIN_DECLS - -#define E_TYPE_SELECT_NAMES_RENDERER (e_select_names_renderer_get_type ()) -#define E_SELECT_NAMES_RENDERER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_SELECT_NAMES_RENDERER, ESelectNamesRenderer)) -#define E_SELECT_NAMES_RENDERER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), E_TYPE_SELECT_NAMES_RENDERER, ESelectNamesRendererClass)) -#define E_IS_SELECT_NAMES_RENDERER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_SELECT_NAMES_RENDERER)) -#define E_IS_SELECT_NAMES_RENDERER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((o), E_TYPE_SELECT_NAMES_RENDERER)) -#define E_SELECT_NAMES_RENDERER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), E_TYPE_SELECT_NAMES_RENDERER, ESelectNamesRendererClass)) - -typedef struct _ESelectNamesRenderer ESelectNamesRenderer; -typedef struct _ESelectNamesRendererClass ESelectNamesRendererClass; -typedef struct _ESelectNamesRendererPriv ESelectNamesRendererPriv; - -struct _ESelectNamesRenderer -{ - GtkCellRendererText parent; - - ESelectNamesRendererPriv *priv; -}; - -struct _ESelectNamesRendererClass -{ - GtkCellRendererTextClass parent_class; - - void (* cell_edited) (ESelectNamesRenderer *renderer, - const gchar *path, - const gchar *address, - const gchar *name); -}; - -GType e_select_names_renderer_get_type (void); -GtkCellRenderer *e_select_names_renderer_new (void); - -G_END_DECLS - -#endif /* __E_SELECT_NAMES_RENDERER_H__ */ diff --git a/calendar/gui/e-tasks.c b/calendar/gui/e-tasks.c deleted file mode 100644 index 936344de43..0000000000 --- a/calendar/gui/e-tasks.c +++ /dev/null @@ -1,1163 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-tasks.c - * - * Copyright (C) 2001-2003 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: Federico Mena Quintero <federico@ximian.com> - * Damon Chaplin <damon@ximian.com> - * Rodrigo Moya <rodrigo@ximian.com> - */ - -#include <config.h> -#include <gnome.h> -#include <libgnomevfs/gnome-vfs-ops.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 <gtkhtml/gtkhtml.h> -#include <gtkhtml/gtkhtml-stream.h> - -#include "e-util/e-categories-config.h" -#include "e-util/e-time-utils.h" -#include "e-util/e-url.h" -#include <libecal/e-cal-time-util.h> -#include "widgets/menus/gal-view-menus.h" -#include "dialogs/delete-error.h" -#include "dialogs/task-editor.h" -#include "cal-search-bar.h" -#include "calendar-config.h" -#include "calendar-component.h" -#include "comp-util.h" -#include "e-calendar-table-config.h" -#include "misc.h" - -#include "e-tasks.h" - - -/* Private part of the GnomeCalendar structure */ -struct _ETasksPrivate { - /* The task lists for display */ - GHashTable *clients; - GList *clients_list; - - ECalView *query; - - /* The ECalendarTable showing the tasks. */ - GtkWidget *tasks_view; - ECalendarTableConfig *tasks_view_config; - - /* Calendar search bar for tasks */ - GtkWidget *search_bar; - - /* The HTML widget to display the task's details */ - GtkWidget *html; - gchar *current_uid; - - /* View instance and the view menus handler */ - GalViewInstance *view_instance; - GalViewMenus *view_menus; - - GList *notifications; -}; - - -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 (ECal *client, ECalendarStatus status, gpointer data); -static void backend_error_cb (ECal *client, const char *message, gpointer data); - -/* 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) - -/* 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, calendar_config_get_24_hour_format (), - FALSE, FALSE, buf, sizeof (buf)); - return g_strdup (buf); -} - -static void -write_html (GtkHTMLStream *stream, ECalComponent *comp) -{ - ECalComponentText text; - ECalComponentDateTime dt; - gchar *buf, *str; - icaltimezone *current_zone; - GSList *l; - icalproperty_status status; - int *priority_value; - - g_return_if_fail (E_IS_CAL_COMPONENT (comp)); - - str = calendar_config_get_timezone (); - if (str && str[0]) { - current_zone = icaltimezone_get_builtin_timezone (str); - } else - current_zone = icaltimezone_get_utc_timezone (); - - /* write document header */ - e_cal_component_get_summary (comp, &text); - gtk_html_stream_printf (stream, - "<HTML><BODY><H1>%s</H1>", - text.value); - - /* write icons for the categories */ - e_cal_component_get_categories_list (comp, &l); - if (l) { - GSList *node; - - for (node = l; node != NULL; node = node->next) { - const char *icon_file; - - icon_file = e_categories_config_get_icon_file_for ((const char *) node->data); - if (icon_file) { - gtk_html_stream_printf (stream, "<IMG ALT=\"%s\" SRC=\"file://%s\">", - (const char *) node->data, icon_file); - } - } - - e_cal_component_free_categories_list (l); - } - - /* write summary */ - gtk_html_stream_printf (stream, - "<BR><BR><BR><TABLE BORDER=\"0\" WIDTH=\"80%%\">" - "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\" WIDTH=\"15%%\"><B>%s</B></TD><TD>%s</TD></TR>", - _("Summary:"), text.value); - - /* write start date */ - e_cal_component_get_dtstart (comp, &dt); - if (dt.value != NULL) { - buf = timet_to_str_with_zone (icaltime_as_timet (*dt.value), current_zone); - str = g_locale_to_utf8 (buf, -1, NULL, NULL, NULL); - - g_free (buf); - } else - str = g_strdup (""); - - gtk_html_stream_printf (stream, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\"><B>%s</B></TD><TD>%s</TD></TR>", - _("Start Date:"), str); - - e_cal_component_free_datetime (&dt); - g_free (str); - - /* write Due Date */ - e_cal_component_get_due (comp, &dt); - if (dt.value != NULL) { - buf = timet_to_str_with_zone (icaltime_as_timet (*dt.value), current_zone); - str = g_locale_to_utf8 (buf, -1, NULL, NULL, NULL); - - g_free (buf); - } else - str = g_strdup (""); - - gtk_html_stream_printf (stream, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\"><B>%s</B></TD><TD>%s</TD></TR>", - _("Due Date:"), str); - - e_cal_component_free_datetime (&dt); - g_free (str); - - /* write status */ - gtk_html_stream_printf (stream, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\"><B>%s</B></TD>", _("Status:")); - e_cal_component_get_status (comp, &status); - switch (status) { - case ICAL_STATUS_INPROCESS : - str = g_strdup (_("In Progress")); - break; - case ICAL_STATUS_COMPLETED : - str = g_strdup (_("Completed")); - break; - case ICAL_STATUS_CANCELLED : - str = g_strdup (_("Cancelled")); - break; - case ICAL_STATUS_NONE : - default : - str = g_strdup (_("Not Started")); - break; - } - - gtk_html_stream_printf (stream, "<TD>%s</TD></TR>", str); - g_free (str); - - /* write priority */ - gtk_html_stream_printf (stream, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\"><B>%s</B></TD>", _("Priority:")); - e_cal_component_get_priority (comp, &priority_value); - if (priority_value) { - if (*priority_value == 0) - str = g_strdup (""); - else if (*priority_value <= 4) - str = g_strdup (_("High")); - else if (*priority_value == 5) - str = g_strdup (_("Normal")); - else - str = g_strdup (_("Low")); - - gtk_html_stream_printf (stream, "<TD>%s</TD></TR>", str); - - g_free (str); - e_cal_component_free_priority (priority_value); - } else - gtk_html_stream_printf (stream, "<TD></TD></TR>"); - - /* write description and URL */ - gtk_html_stream_printf (stream, "<TR><TD COLSPAN=\"2\"><HR></TD></TR>"); - - gtk_html_stream_printf (stream, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\"><B>%s</B></TD>", _("Description:")); - e_cal_component_get_description_list (comp, &l); - if (l) { - GSList *node; - - gtk_html_stream_printf (stream, "<TD>"); - - for (node = l; node != NULL; node = node->next) { - gint i; - GString *str = g_string_new ("");; - - text = * (ECalComponentText *) node->data; - for (i = 0; i < strlen (text.value ? text.value : 0); i++) { - if (text.value[i] == '\n') - str = g_string_append (str, "<BR>"); - else if (text.value[i] == '<') - str = g_string_append (str, "<"); - else if (text.value[i] == '>') - str = g_string_append (str, ">"); - else - str = g_string_append_c (str, text.value[i]); - } - - gtk_html_stream_printf (stream, str->str); - g_string_free (str, TRUE); - } - - gtk_html_stream_printf (stream, "</TD></TR>"); - - e_cal_component_free_text_list (l); - } else - gtk_html_stream_printf (stream, "<TD></TD></TR>"); - - /* URL */ - gtk_html_stream_printf (stream, "<TR><TD VALIGN=\"TOP\" ALIGN=\"RIGHT\"><B>%s</B></TD>", _("Web Page:")); - e_cal_component_get_url (comp, (const char **) &str); - if (str) - gtk_html_stream_printf (stream, "<TD><A HREF=\"%s\">%s</A></TD></TR>", str, str); - else - gtk_html_stream_printf (stream, "<TD></TD></TR>"); - - gtk_html_stream_printf (stream, "</TABLE>"); - - /* close document */ - gtk_html_stream_printf (stream, "</BODY></HTML>"); -} - -static void -on_link_clicked (GtkHTML *html, const char *url, gpointer data) -{ - GError *err = NULL; - - gnome_url_show (url, &err); - - if (err) { - g_warning ("gnome_url_show: %s", err->message); - g_error_free (err); - } -} - -/* Callback used when the cursor changes in the table */ -static void -table_cursor_change_cb (ETable *etable, int row, gpointer data) -{ - ETasks *tasks; - ETasksPrivate *priv; - int n_selected; - - tasks = E_TASKS (data); - priv = tasks->priv; - - n_selected = e_table_selected_count (etable); - - /* update the HTML widget */ - if (n_selected == 1) { - GtkHTMLStream *stream; - ECalModel *model; - ECalModelComponent *comp_data; - ECalComponent *comp; - const char *uid; - - model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view)); - - stream = gtk_html_begin (GTK_HTML (priv->html)); - - comp_data = e_cal_model_get_component_at (model, e_table_get_cursor_row (etable)); - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp)); - write_html (stream, comp); - - gtk_html_stream_close (stream, GTK_HTML_STREAM_OK); - - e_cal_component_get_uid (comp, &uid); - if (priv->current_uid) - g_free (priv->current_uid); - priv->current_uid = g_strdup (uid); - - g_object_unref (comp); - } else - gtk_html_load_empty (GTK_HTML (priv->html)); -} - -/* 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; - ECalModel *model; - - tasks = E_TASKS (data); - priv = tasks->priv; - - model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view)); - e_cal_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; - ECalModel *model; - - tasks = E_TASKS (data); - priv = tasks->priv; - - model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view)); - e_cal_model_set_default_category (model, category); -} - -/* Callback used when the user selects a URL in the HTML widget */ -static void -url_requested_cb (GtkHTML *html, const char *url, GtkHTMLStream *stream, gpointer data) -{ - if (!strncmp ("file:///", url, strlen ("file:///"))) { - GnomeVFSHandle *handle; - GnomeVFSResult result; - char buffer[4096]; - - if (gnome_vfs_open (&handle, url, GNOME_VFS_OPEN_READ) == GNOME_VFS_OK) { - do { - GnomeVFSFileSize bread; - - result = gnome_vfs_read (handle, buffer, sizeof (buffer), &bread); - if (result == GNOME_VFS_OK) - gtk_html_stream_write (stream, buffer, bread); - } while (result == GNOME_VFS_OK); - - gnome_vfs_close (handle); - } - } -} - -static gboolean -vpaned_resized_cb (GtkWidget *widget, GdkEventButton *event, ETasks *tasks) -{ - calendar_config_set_task_vpane_pos (gtk_paned_get_position (GTK_PANED (widget))); - - return FALSE; -} - -static void -set_timezone (ETasks *tasks) -{ - ETasksPrivate *priv; - char *location; - icaltimezone *zone; - GList *l; - - priv = tasks->priv; - - location = calendar_config_get_timezone (); - zone = icaltimezone_get_builtin_timezone (location); - g_free (location); - - if (!zone) - zone = icaltimezone_get_utc_timezone (); - - for (l = priv->clients_list; l != NULL; l = l->next) { - ECal *client = l->data; - - if (e_cal_get_load_state (client) == E_CAL_LOAD_LOADED) - /* FIXME Error checking */ - e_cal_set_default_timezone (client, zone, NULL); - } -} - -static void -timezone_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - ETasks *tasks = data; - - set_timezone (tasks); -} - -static void -setup_config (ETasks *tasks) -{ - ETasksPrivate *priv; - guint not; - - priv = tasks->priv; - - /* Timezone */ - set_timezone (tasks); - - not = calendar_config_add_notification_timezone (timezone_changed_cb, tasks); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); -} - -#define E_TASKS_TABLE_DEFAULT_STATE \ - "<?xml version=\"1.0\"?>" \ - "<ETableState>" \ - "<column source=\"13\"/>" \ - "<column source=\"14\"/>" \ - "<column source=\"9\"/>" \ - "<column source=\"5\"/>" \ - "<grouping/>" \ - "</ETableState>" - -static void -setup_widgets (ETasks *tasks) -{ - ETasksPrivate *priv; - ETable *etable; - GtkWidget *paned, *scroll; - - priv = tasks->priv; - - priv->search_bar = cal_search_bar_new (); - g_signal_connect (priv->search_bar, "sexp_changed", - G_CALLBACK (search_bar_sexp_changed_cb), tasks); - g_signal_connect (priv->search_bar, "category_changed", - G_CALLBACK (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); - - /* add the paned widget for the task list and task detail areas */ - paned = gtk_vpaned_new (); - gtk_paned_set_position (GTK_PANED (paned), calendar_config_get_task_vpane_pos ()); - g_signal_connect (G_OBJECT (paned), "button_release_event", - G_CALLBACK (vpaned_resized_cb), tasks); - gtk_table_attach (GTK_TABLE (tasks), paned, 0, 1, 1, 2, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - gtk_widget_show (paned); - - /* create the task list */ - priv->tasks_view = e_calendar_table_new (); - priv->tasks_view_config = e_calendar_table_config_new (E_CALENDAR_TABLE (priv->tasks_view)); - - 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_paned_add1 (GTK_PANED (paned), priv->tasks_view); - gtk_widget_show (priv->tasks_view); - - g_signal_connect (etable, "cursor_change", G_CALLBACK (table_cursor_change_cb), tasks); - g_signal_connect (etable, "selection_change", G_CALLBACK (table_selection_change_cb), tasks); - - /* create the task detail */ - priv->html = gtk_html_new (); - gtk_html_set_default_content_type (GTK_HTML (priv->html), "charset=utf-8"); - gtk_html_load_empty (GTK_HTML (priv->html)); - - g_signal_connect (G_OBJECT (priv->html), "url_requested", - G_CALLBACK (url_requested_cb), NULL); - g_signal_connect (G_OBJECT (priv->html), "link_clicked", - G_CALLBACK (on_link_clicked), tasks); - - gtk_widget_pop_colormap (); - scroll = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN); - gtk_container_add (GTK_CONTAINER (scroll), priv->html); - gtk_paned_add2 (GTK_PANED (paned), scroll); - gtk_widget_show_all (scroll); -} - -/* 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, - G_TYPE_FROM_CLASS (object_class), - GTK_SIGNAL_OFFSET (ETasksClass, selection_changed), - gtk_marshal_NONE__INT, - GTK_TYPE_NONE, 1, - GTK_TYPE_INT); - - 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; - - setup_config (tasks); - setup_widgets (tasks); - - priv->clients = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); - priv->query = NULL; - priv->view_instance = NULL; - priv->view_menus = NULL; - priv->current_uid = NULL; -} - -/* Callback used when the set of categories changes in the calendar client */ -static void -client_categories_changed_cb (ECal *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); -} - -static void -client_obj_updated_cb (ECal *client, const char *uid, gpointer data) -{ - ETasks *tasks; - ETasksPrivate *priv; - - tasks = E_TASKS (data); - priv = tasks->priv; - - if (priv->current_uid) { - if (!strcmp (uid, priv->current_uid)) { - ETable *etable; - - etable = e_table_scrolled_get_table ( - E_TABLE_SCROLLED (E_CALENDAR_TABLE (priv->tasks_view)->etable)); - table_cursor_change_cb (etable, 0, tasks); - } - } -} - - -GtkWidget * -e_tasks_new (void) -{ - ETasks *tasks; - - tasks = g_object_new (e_tasks_get_type (), NULL); - - 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; - - g_return_if_fail (object != NULL); - g_return_if_fail (E_IS_TASKS (object)); - - tasks = E_TASKS (object); - priv = tasks->priv; - - if (priv) { - GList *l; - - /* disconnect from signals on all the clients */ - for (l = priv->clients_list; l != NULL; l = l->next) { - g_signal_handlers_disconnect_matched (l->data, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, tasks); - } - - g_hash_table_destroy (priv->clients); - g_list_free (priv->clients_list); - - if (priv->current_uid) { - g_free (priv->current_uid); - priv->current_uid = NULL; - } - - if (priv->tasks_view_config) { - g_object_unref (priv->tasks_view_config); - priv->tasks_view_config = NULL; - } - - for (l = priv->notifications; l; l = l->next) - calendar_config_remove_notification (GPOINTER_TO_UINT (l->data)); - priv->notifications = NULL; - - g_free (priv); - tasks->priv = NULL; - } - - 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; - - priv = tasks->priv; - - e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->tasks_view), message); -} - -/* Displays an error to indicate that loading a calendar failed */ -static void -load_error (ETasks *tasks, - const char *uri) -{ - char *msg; - char *urinopwd; - - urinopwd = get_uri_without_password (uri); - msg = g_strdup_printf (_("Could not load the tasks in `%s'"), urinopwd); - gnome_error_dialog_parented (msg, GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tasks)))); - g_free (msg); - g_free (urinopwd); -} - -/* Displays an error to indicate that the specified URI method is not supported */ -static void -method_error (ETasks *tasks, - const char *uri) -{ - char *msg; - char *urinopwd; - - urinopwd = get_uri_without_password (uri); - msg = g_strdup_printf (_("The method required to load `%s' is not supported"), urinopwd); - gnome_error_dialog_parented (msg, GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tasks)))); - g_free (msg); - g_free (urinopwd); -} - -/* Displays an error to indicate permission problems */ -static void -permission_error (ETasks *tasks, const char *uri) -{ - char *msg; - char *urinopwd; - - urinopwd = get_uri_without_password (uri); - msg = g_strdup_printf (_("You don't have permission to open the folder in `%s'"), urinopwd); - gnome_error_dialog_parented (msg, GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tasks)))); - g_free (msg); - g_free (urinopwd); -} - -/* Callback from the calendar client when a calendar is opened */ -static void -cal_opened_cb (ECal *client, - ECalendarStatus status, - gpointer data) -{ - ETasks *tasks; - ETasksPrivate *priv; - - tasks = E_TASKS (data); - priv = tasks->priv; - - set_status_message (tasks, NULL); - - switch (status) { - case E_CALENDAR_STATUS_OK: - /* Everything is OK */ - set_timezone (tasks); - return; - - case E_CALENDAR_STATUS_OTHER_ERROR: - load_error (tasks, e_cal_get_uri (client)); - break; - - case E_CALENDAR_STATUS_NO_SUCH_CALENDAR: - /* bullshit; we did not specify only_if_exists */ - g_assert_not_reached (); - return; - - case E_CALENDAR_STATUS_PROTOCOL_NOT_SUPPORTED: - method_error (tasks, e_cal_get_uri (client)); - break; - - case E_CALENDAR_STATUS_PERMISSION_DENIED: - permission_error (tasks, e_cal_get_uri (client)); - break; - - default: - g_assert_not_reached (); - } -} - -/* Callback from the calendar client when an error occurs in the backend */ -static void -backend_error_cb (ECal *client, const char *message, gpointer data) -{ - ETasks *tasks; - ETasksPrivate *priv; - char *errmsg; - char *urinopwd; - - tasks = E_TASKS (data); - priv = tasks->priv; - - urinopwd = get_uri_without_password (e_cal_get_uri (client)); - errmsg = g_strdup_printf (_("Error on %s:\n %s"), urinopwd, message); - gnome_error_dialog_parented (errmsg, GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tasks)))); - g_free (errmsg); - g_free (urinopwd); -} - -void -e_tasks_new_task (ETasks *tasks) -{ - ETasksPrivate *priv; - TaskEditor *tedit; - ECalComponent *comp; - const char *category; - ECal *ecal; - - g_return_if_fail (E_IS_TASKS (tasks)); - - priv = tasks->priv; - - /* FIXME What to do about no default client */ - ecal = e_tasks_get_default_client (tasks); - if (!ecal) - return; - - comp = cal_comp_task_new_with_defaults (ecal); - - category = cal_search_bar_get_category (CAL_SEARCH_BAR (priv->search_bar)); - e_cal_component_set_categories (comp, category); - - tedit = task_editor_new (ecal); - comp_editor_edit_comp (COMP_EDITOR (tedit), comp); - g_object_unref (comp); - - comp_editor_focus (COMP_EDITOR (tedit)); -} - -gboolean -e_tasks_add_todo_uri (ETasks *tasks, const char *str_uri) -{ - ETasksPrivate *priv; - ECal *client; - ECalModel *model; - - g_return_val_if_fail (tasks != NULL, FALSE); - g_return_val_if_fail (E_IS_TASKS (tasks), FALSE); - g_return_val_if_fail (str_uri != NULL, FALSE); - - priv = tasks->priv; - - client = g_hash_table_lookup (priv->clients, str_uri); - if (client) - return TRUE; - - client = e_cal_new_from_uri (str_uri, CALOBJ_TYPE_TODO); - g_hash_table_insert (priv->clients, g_strdup (str_uri), client); - priv->clients_list = g_list_prepend (priv->clients_list, client); - - g_signal_connect (G_OBJECT (client), "backend_error", G_CALLBACK (backend_error_cb), tasks); - g_signal_connect (G_OBJECT (client), "categories_changed", G_CALLBACK (client_categories_changed_cb), tasks); - - if (!e_cal_open (client, FALSE, NULL)) { - g_hash_table_remove (priv->clients, str_uri); - priv->clients_list = g_list_prepend (priv->clients_list, client); - g_signal_handlers_disconnect_matched (client, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, tasks); - - return FALSE; - } - - model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view)); - e_cal_model_add_client (model, client); - - return TRUE; -} - -gboolean -e_tasks_remove_todo_uri (ETasks *tasks, const char *str_uri) -{ - ETasksPrivate *priv; - ECal *client; - ECalModel *model; - - g_return_val_if_fail (tasks != NULL, FALSE); - g_return_val_if_fail (E_IS_TASKS (tasks), FALSE); - g_return_val_if_fail (str_uri != NULL, FALSE); - - priv = tasks->priv; - - client = g_hash_table_lookup (priv->clients, str_uri); - if (!client) - return TRUE; - - g_hash_table_remove (priv->clients, str_uri); - priv->clients_list = g_list_remove (priv->clients_list, client); - g_signal_handlers_disconnect_matched (client, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, tasks); - - model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view)); - e_cal_model_remove_client (model, client); - - return TRUE; -} - -gboolean -e_tasks_set_default_uri (ETasks *tasks, const char *str_uri) -{ - ETasksPrivate *priv; - ECal *ecal; - ECalModel *model; - - g_return_val_if_fail (tasks != NULL, FALSE); - g_return_val_if_fail (E_IS_TASKS (tasks), FALSE); - g_return_val_if_fail (str_uri != NULL, FALSE); - - priv = tasks->priv; - - ecal = g_hash_table_lookup (priv->clients, str_uri); - if (!ecal) - return FALSE; - - model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view)); - e_cal_model_set_default_client (model, ecal); - - return TRUE; -} - -ECal * -e_tasks_get_default_client (ETasks *tasks) -{ - ETasksPrivate *priv; - - g_return_val_if_fail (tasks != NULL, NULL); - g_return_val_if_fail (E_IS_TASKS (tasks), NULL); - - priv = tasks->priv; - - return e_cal_model_get_default_client (e_calendar_table_get_model (E_CALENDAR_TABLE (priv->tasks_view))); -} - -/** - * e_tasks_complete_selected: - * @tasks: A tasks control widget - * - * Marks the selected tasks complete - **/ -void -e_tasks_complete_selected (ETasks *tasks) -{ - ETasksPrivate *priv; - ECalendarTable *cal_table; - - g_return_if_fail (tasks != NULL); - g_return_if_fail (E_IS_TASKS (tasks)); - - priv = tasks->priv; - - cal_table = E_CALENDAR_TABLE (priv->tasks_view); - - set_status_message (tasks, _("Completing tasks...")); - e_calendar_table_complete_selected (cal_table); - set_status_message (tasks, NULL); -} - -/** - * e_tasks_delete_selected: - * @tasks: A tasks control widget. - * - * Deletes the selected tasks in the task list. - **/ -void -e_tasks_delete_selected (ETasks *tasks) -{ - ETasksPrivate *priv; - ECalendarTable *cal_table; - - g_return_if_fail (tasks != NULL); - g_return_if_fail (E_IS_TASKS (tasks)); - - priv = tasks->priv; - - cal_table = E_CALENDAR_TABLE (priv->tasks_view); - set_status_message (tasks, _("Deleting selected objects...")); - e_calendar_table_delete_selected (cal_table); - set_status_message (tasks, NULL); -} - -/** - * e_tasks_expunge: - * @tasks: A tasks control widget - * - * Removes all tasks marked as completed - **/ -void -e_tasks_delete_completed (ETasks *tasks) -{ - ETasksPrivate *priv; - char *sexp; - GList *l; - - g_return_if_fail (tasks != NULL); - g_return_if_fail (E_IS_TASKS (tasks)); - - priv = tasks->priv; - - sexp = g_strdup ("(is-completed?)"); - - set_status_message (tasks, _("Expunging")); - - for (l = priv->clients_list; l != NULL; l = l->next) { - ECal *client = l->data; - GList *objects, *m; - gboolean read_only = TRUE; - - e_cal_is_read_only (client, &read_only, NULL); - if (read_only) - continue; - - if (!e_cal_get_object_list (client, sexp, &objects, NULL)) { - g_warning (G_STRLOC ": Could not get the objects"); - - continue; - } - - for (m = objects; m; m = m->next) { - /* FIXME Better error handling */ - e_cal_remove_object (client, icalcomponent_get_uid (m->data), NULL); - } - } - - set_status_message (tasks, NULL); - - g_free (sexp); -} - -/* Callback used from the view collection when we need to display a new view */ -static void -display_view_cb (GalViewInstance *instance, GalView *view, gpointer data) -{ - ETasks *tasks; - - tasks = E_TASKS (data); - - if (GAL_IS_VIEW_ETABLE (view)) { - gal_view_etable_attach_table (GAL_VIEW_ETABLE (view), e_table_scrolled_get_table (E_TABLE_SCROLLED (E_CALENDAR_TABLE (tasks->priv->tasks_view)->etable))); - } -} - -/** - * 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 (); - - gal_view_collection_set_title (collection, _("Tasks")); - - dir = gnome_util_prepend_user_home ("/evolution/views/tasks/"); - gal_view_collection_set_storage_directories (collection, - EVOLUTION_GALVIEWSDIR "/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); - g_object_unref (spec); - gal_view_collection_add_factory (collection, factory); - g_object_unref (factory); - - /* Load the collection and create the menus */ - - gal_view_collection_load (collection); - } - - priv->view_instance = gal_view_instance_new (collection, e_cal_get_uri (e_tasks_get_default_client (tasks))); - - priv->view_menus = gal_view_menus_new (priv->view_instance); - gal_view_menus_apply (priv->view_menus, uic, NULL); - g_signal_connect (priv->view_instance, "display_view", G_CALLBACK (display_view_cb), tasks); - display_view_cb (priv->view_instance, gal_view_instance_get_current_view (priv->view_instance), tasks); -} - -/** - * e_tasks_discard_view_menus: - * @tasks: A tasks widget. - * - * Discards the #GalView menus used by a tasks control. This function should be - * called from the Bonobo control deactivation callback for this tasks control. - * The menus should have been set up with e_tasks_setup_view_menus(). - **/ -void -e_tasks_discard_view_menus (ETasks *tasks) -{ - ETasksPrivate *priv; - - g_return_if_fail (tasks != NULL); - g_return_if_fail (E_IS_TASKS (tasks)); - - priv = tasks->priv; - - g_return_if_fail (priv->view_instance != NULL); - - g_assert (priv->view_instance != NULL); - g_assert (priv->view_menus != NULL); - - g_object_unref (priv->view_instance); - priv->view_instance = NULL; - - g_object_unref (priv->view_menus); - priv->view_menus = NULL; -} - -/** - * e_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); -} diff --git a/calendar/gui/e-tasks.h b/calendar/gui/e-tasks.h deleted file mode 100644 index 10e79ef8c3..0000000000 --- a/calendar/gui/e-tasks.h +++ /dev/null @@ -1,83 +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 <bonobo/bonobo-ui-component.h> -#include <gtk/gtktable.h> -#include <libecal/e-cal.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_add_todo_uri (ETasks *tasks, const char *str_uri); -gboolean e_tasks_remove_todo_uri (ETasks *tasks, const char *str_uri); -gboolean e_tasks_set_default_uri (ETasks *tasks, const char *str_uri); -ECal *e_tasks_get_default_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); - -#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 6f6a965f7a..0000000000 --- a/calendar/gui/e-timezone-entry.c +++ /dev/null @@ -1,320 +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/util/e-util.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 { - /* The current timezone, set in e_timezone_entry_set_timezone() - or from the timezone dialog. 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 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; - - GtkWidget *entry; - GtkWidget *button; -}; - - -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 gboolean e_timezone_entry_mnemonic_activate (GtkWidget *widget, - gboolean group_cycling); -static void on_entry_changed (GtkEntry *entry, - ETimezoneEntry *tentry); -static void on_button_clicked (GtkWidget *widget, - ETimezoneEntry *tentry); - -static void e_timezone_entry_set_entry (ETimezoneEntry *tentry); - - -static GtkHBoxClass *parent_class; -static guint timezone_entry_signals[LAST_SIGNAL] = { 0 }; - -E_MAKE_TYPE (e_timezone_entry, "ETimezoneEntry", ETimezoneEntry, - e_timezone_entry_class_init, e_timezone_entry_init, GTK_TYPE_HBOX); - -static void -e_timezone_entry_class_init (ETimezoneEntryClass *class) -{ - GtkObjectClass *object_class = (GtkObjectClass *) class; - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class) ; - - object_class = (GtkObjectClass*) class; - - parent_class = g_type_class_peek_parent (class); - - widget_class->mnemonic_activate = e_timezone_entry_mnemonic_activate; - timezone_entry_signals[CHANGED] = - gtk_signal_new ("changed", - GTK_RUN_LAST, - G_TYPE_FROM_CLASS (object_class), - GTK_SIGNAL_OFFSET (ETimezoneEntryClass, - changed), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - - 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->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, 6); - gtk_widget_show (priv->entry); - g_signal_connect (priv->entry, "changed", G_CALLBACK (on_entry_changed), tentry); - - priv->button = gtk_button_new (); - g_signal_connect (priv->button, "clicked", G_CALLBACK (on_button_clicked), tentry); - gtk_box_pack_start (GTK_BOX (tentry), priv->button, FALSE, FALSE, 6); - 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 = g_object_new (e_timezone_entry_get_type (), NULL); - - GTK_WIDGET_SET_FLAGS (GTK_WIDGET(tentry), GTK_CAN_FOCUS); - - 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; - - priv = tentry->priv; - - timezone_dialog = e_timezone_dialog_new (); - - e_timezone_dialog_set_timezone (timezone_dialog, priv->zone); - - dialog = e_timezone_dialog_get_toplevel (timezone_dialog); - - if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { - priv->zone = e_timezone_dialog_get_timezone (timezone_dialog); - e_timezone_entry_set_entry (tentry); - } - - g_object_unref (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; - - g_return_val_if_fail (E_IS_TIMEZONE_ENTRY (tentry), NULL); - - priv = tentry->priv; - - return priv->zone; -} - - -void -e_timezone_entry_set_timezone (ETimezoneEntry *tentry, - icaltimezone *zone) -{ - ETimezoneEntryPrivate *priv; - - g_return_if_fail (E_IS_TIMEZONE_ENTRY (tentry)); - - priv = tentry->priv; - - priv->zone = zone; - - e_timezone_entry_set_entry (tentry); -} - - -/* 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 (tentry); -} - - -static void -e_timezone_entry_set_entry (ETimezoneEntry *tentry) -{ - ETimezoneEntryPrivate *priv; - const char *display_name; - char *name_buffer; - - priv = tentry->priv; - - if (priv->zone) { - display_name = icaltimezone_get_display_name (priv->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 - don't. */ - if (icaltimezone_get_builtin_timezone (display_name)) - display_name = _(display_name); - } else - display_name = ""; - - name_buffer = g_strdup (display_name); - - gtk_entry_set_text (GTK_ENTRY (priv->entry), name_buffer); - - if (!priv->default_zone || (priv->zone != priv->default_zone)) - gtk_widget_show (priv->entry); - else - gtk_widget_hide (priv->entry); - - g_free (name_buffer); -} - - -static gboolean -e_timezone_entry_mnemonic_activate (GtkWidget *widget, - gboolean group_cycling) -{ - GtkButton *button = NULL; - - if (GTK_WIDGET_CAN_FOCUS (widget)) { - button=((ETimezoneEntryPrivate*) ((ETimezoneEntry*) widget)->priv)->button; - if (button != NULL) - gtk_widget_grab_focus (button); - } - - return TRUE; -} - diff --git a/calendar/gui/e-timezone-entry.h b/calendar/gui/e-timezone-entry.h deleted file mode 100644 index 94a7df9efc..0000000000 --- a/calendar/gui/e-timezone-entry.h +++ /dev/null @@ -1,80 +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 <libecal/e-cal.h> - -G_BEGIN_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); -}; - -GType 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); - -G_END_DECLS - -#endif /* __E_TIMEZONE_ENTRY_H_ */ diff --git a/calendar/gui/e-week-view-config.c b/calendar/gui/e-week-view-config.c deleted file mode 100644 index 1257813062..0000000000 --- a/calendar/gui/e-week-view-config.c +++ /dev/null @@ -1,332 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * Author : - * Rodrigo Moya <rodrigo@ximian.com> - * - * Copyright 2003, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#include "calendar-config.h" -#include "e-week-view-config.h" - -struct _EWeekViewConfigPrivate { - EWeekView *view; - - GList *notifications; -}; - -static GObjectClass *parent_class = NULL; - -/* Property IDs */ -enum props { - PROP_0, - PROP_VIEW, -}; - -static void -e_week_view_config_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) -{ - EWeekViewConfig *view_config; - EWeekViewConfigPrivate *priv; - - view_config = E_WEEK_VIEW_CONFIG (object); - priv = view_config->priv; - - switch (property_id) { - case PROP_VIEW: - e_week_view_config_set_view (view_config, g_value_get_object (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -e_week_view_config_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) -{ - EWeekViewConfig *view_config; - EWeekViewConfigPrivate *priv; - - view_config = E_WEEK_VIEW_CONFIG (object); - priv = view_config->priv; - - switch (property_id) { - case PROP_VIEW: - g_value_set_object (value, e_week_view_config_get_view (view_config)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -e_week_view_config_dispose (GObject *object) -{ - EWeekViewConfig *view_config = E_WEEK_VIEW_CONFIG (object); - EWeekViewConfigPrivate *priv; - - priv = view_config->priv; - - e_week_view_config_set_view (view_config, NULL); - - if (G_OBJECT_CLASS (parent_class)->dispose) - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -e_week_view_config_finalize (GObject *object) -{ - EWeekViewConfig *view_config = E_WEEK_VIEW_CONFIG (object); - EWeekViewConfigPrivate *priv; - - priv = view_config->priv; - - g_free (priv); - - if (G_OBJECT_CLASS (parent_class)->finalize) - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -e_week_view_config_class_init (EWeekViewConfigClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - GParamSpec *spec; - - parent_class = g_type_class_peek_parent (klass); - - /* Method override */ - gobject_class->set_property = e_week_view_config_set_property; - gobject_class->get_property = e_week_view_config_get_property; - gobject_class->dispose = e_week_view_config_dispose; - gobject_class->finalize = e_week_view_config_finalize; - - spec = g_param_spec_object ("view", NULL, NULL, e_week_view_get_type (), - G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT); - g_object_class_install_property (gobject_class, PROP_VIEW, spec); -} - -static void -e_week_view_config_init (EWeekViewConfig *view_config, EWeekViewConfigClass *klass) -{ - view_config->priv = g_new0 (EWeekViewConfigPrivate, 1); - -} - -E_MAKE_TYPE (e_week_view_config, "EWeekViewConfig", EWeekViewConfig, e_week_view_config_class_init, - e_week_view_config_init, G_TYPE_OBJECT); - -EWeekViewConfig * -e_week_view_config_new (EWeekView *week_view) -{ - EWeekViewConfig *view_config; - - view_config = g_object_new (e_week_view_config_get_type (), "view", week_view, NULL); - - return view_config; -} - -EWeekView * -e_week_view_config_get_view (EWeekViewConfig *view_config) -{ - EWeekViewConfigPrivate *priv; - - g_return_val_if_fail (view_config != NULL, NULL); - g_return_val_if_fail (E_IS_WEEK_VIEW_CONFIG (view_config), NULL); - - priv = view_config->priv; - - return priv->view; -} - -static void -set_timezone (EWeekView *week_view) -{ - char *location; - icaltimezone *zone; - - location = calendar_config_get_timezone (); - zone = icaltimezone_get_builtin_timezone (location); - if (!zone) - zone = icaltimezone_get_utc_timezone (); - - e_calendar_view_set_timezone (E_CALENDAR_VIEW (week_view), zone); - - g_free (location); -} - -static void -timezone_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - EWeekViewConfig *view_config = data; - EWeekViewConfigPrivate *priv; - - priv = view_config->priv; - - set_timezone (priv->view); -} - -static void -set_week_start (EWeekView *week_view) -{ - int week_start_week; - - week_start_week = calendar_config_get_week_start_day (); - - /* Convert it to 0 (Mon) to 6 (Sun), which is what we use. */ - week_start_week = (week_start_week + 6) % 7; - - e_week_view_set_week_start_day (week_view, week_start_week); -} - -static void -week_start_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - EWeekViewConfig *view_config = data; - EWeekViewConfigPrivate *priv; - - priv = view_config->priv; - - set_week_start (priv->view); -} - -static void -set_twentyfour_hour (EWeekView *week_view) -{ - gboolean use_24_hour; - - use_24_hour = calendar_config_get_24_hour_format (); - - e_calendar_view_set_use_24_hour_format (E_CALENDAR_VIEW (week_view), use_24_hour); -} - -static void -twentyfour_hour_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - EWeekViewConfig *view_config = data; - EWeekViewConfigPrivate *priv; - - priv = view_config->priv; - - set_twentyfour_hour (priv->view); -} - -static void -set_show_event_end (EWeekView *week_view) -{ - gboolean show_event_end; - - show_event_end = calendar_config_get_show_event_end (); - - e_week_view_set_show_event_end_times (week_view, show_event_end); -} - -static void -show_event_end_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - EWeekViewConfig *view_config = data; - EWeekViewConfigPrivate *priv; - - priv = view_config->priv; - - set_show_event_end (priv->view); -} - -static void -set_compress_weekend (EWeekView *week_view) -{ - gboolean compress_weekend; - - compress_weekend = calendar_config_get_compress_weekend (); - - e_week_view_set_compress_weekend (week_view, compress_weekend); -} - -static void -compress_weekend_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - EWeekViewConfig *view_config = data; - EWeekViewConfigPrivate *priv; - - priv = view_config->priv; - - set_compress_weekend (priv->view); -} - -void -e_week_view_config_set_view (EWeekViewConfig *view_config, EWeekView *week_view) -{ - EWeekViewConfigPrivate *priv; - guint not; - GList *l; - - g_return_if_fail (view_config != NULL); - g_return_if_fail (E_IS_WEEK_VIEW_CONFIG (view_config)); - - priv = view_config->priv; - - if (priv->view) { - g_object_unref (priv->view); - priv->view = NULL; - } - - for (l = priv->notifications; l; l = l->next) - calendar_config_remove_notification (GPOINTER_TO_UINT (l->data)); - - g_list_free (priv->notifications); - priv->notifications = NULL; - - /* If the new view is NULL, return right now */ - if (!week_view) - return; - - priv->view = g_object_ref (week_view); - - /* Time zone */ - set_timezone (week_view); - - not = calendar_config_add_notification_timezone (timezone_changed_cb, view_config); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - /* Week start */ - set_week_start (week_view); - - not = calendar_config_add_notification_week_start_day (week_start_changed_cb, view_config); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - /* 24 Hour format */ - set_twentyfour_hour (week_view); - - not = calendar_config_add_notification_24_hour_format (twentyfour_hour_changed_cb, view_config); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - /* Show event end */ - set_show_event_end (week_view); - - not = calendar_config_add_notification_show_event_end (show_event_end_changed_cb, view_config); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - /* Compress weekend */ - set_compress_weekend (week_view); - - not = calendar_config_add_notification_compress_weekend (compress_weekend_changed_cb, view_config); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); -} - diff --git a/calendar/gui/e-week-view-config.h b/calendar/gui/e-week-view-config.h deleted file mode 100644 index e37cb0cfc0..0000000000 --- a/calendar/gui/e-week-view-config.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Author : - * JP Rosevear <jpr@ximian.com> - * - * Copyright 2003, Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA - */ - -#ifndef _E_WEEK_VIEW_CONFIG_H_ -#define _E_WEEK_VIEW_CONFIG_H_ - -#include "e-week-view.h" - -G_BEGIN_DECLS - -#define E_WEEK_VIEW_CONFIG(obj) GTK_CHECK_CAST (obj, e_week_view_config_get_type (), EWeekViewConfig) -#define E_WEEK_VIEW_CONFIG_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, e_week_view_config_get_type (), EWeekViewConfigClass) -#define E_IS_WEEK_VIEW_CONFIG(obj) GTK_CHECK_TYPE (obj, e_week_view_config_get_type ()) - -typedef struct _EWeekViewConfig EWeekViewConfig; -typedef struct _EWeekViewConfigClass EWeekViewConfigClass; -typedef struct _EWeekViewConfigPrivate EWeekViewConfigPrivate; - -struct _EWeekViewConfig { - GObject parent; - - EWeekViewConfigPrivate *priv; -}; - -struct _EWeekViewConfigClass { - GObjectClass parent_class; -}; - -GType e_week_view_config_get_type (void); -EWeekViewConfig *e_week_view_config_new (EWeekView *week_view); -EWeekView *e_week_view_config_get_view (EWeekViewConfig *view_config); -void e_week_view_config_set_view (EWeekViewConfig *view_config, EWeekView *week_view); - -G_END_DECLS - -#endif 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 85e1cf775a..0000000000 --- a/calendar/gui/e-week-view-event-item.c +++ /dev/null @@ -1,945 +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 ECalendarViewPosition 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 -}; - -E_MAKE_TYPE (e_week_view_event_item, "EWeekViewEventItem", EWeekViewEventItem, - e_week_view_event_item_class_init, e_week_view_event_item_init, - GNOME_TYPE_CANVAS_ITEM); - -static void -e_week_view_event_item_class_init (EWeekViewEventItemClass *class) -{ - GtkObjectClass *object_class; - GnomeCanvasItemClass *item_class; - - parent_class = g_type_class_peek_parent (class); - - 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; - GdkColor bg_color; - -#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 + 1; - 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; - - if (gdk_color_parse (e_cal_model_get_color_for_component (e_calendar_view_get_model (E_CALENDAR_VIEW (week_view)), - event->comp_data), - &bg_color)) { - GdkColormap *colormap; - - colormap = gtk_widget_get_colormap (GTK_WIDGET (week_view)); - if (gdk_colormap_alloc_color (colormap, &bg_color, TRUE, TRUE)) - gdk_gc_set_foreground (gc, &bg_color); - else - gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND]); - } else - 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]); - gdk_draw_line (drawable, gc, rect_x, y1 + 1, rect_x + rect_w, y1 + 1); - gdk_draw_line (drawable, gc, rect_x, y2, rect_x + rect_w, y2); - gdk_draw_line (drawable, gc, rect_x, y1 + 1, rect_x, y1 + (y2 - (y1 + 1))); - gdk_draw_line (drawable, gc, rect_x + rect_w, y1 + 1, rect_x + rect_w, y1 + (y2 - (y1 + 1))); - - /* 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; - } - - if (gdk_color_parse (e_cal_model_get_color_for_component (e_calendar_view_get_model (E_CALENDAR_VIEW (week_view)), - event->comp_data), - &bg_color)) { - GdkColormap *colormap; - - colormap = gtk_widget_get_colormap (GTK_WIDGET (week_view)); - if (gdk_colormap_alloc_color (colormap, &bg_color, TRUE, TRUE)) - gdk_gc_set_foreground (gc, &bg_color); - else - gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND]); - } else - 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; - gint hour_to_display, suffix_width; - gint time_y_normal_font, time_y_small_font; - gchar buffer[128], *suffix; - PangoLayout *layout; - PangoFontDescription *small_font_desc; - - style = gtk_widget_get_style (GTK_WIDGET (week_view)); - small_font_desc = week_view->small_font_desc; - gc = week_view->main_gc; - - gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_EVENT_TEXT]); - - layout = gtk_widget_create_pango_layout (GTK_WIDGET (week_view), NULL); - - time_y_normal_font = time_y_small_font = time_y; - if (small_font_desc) - time_y_small_font = time_y; - - 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_desc) { - g_snprintf (buffer, sizeof (buffer), "%2i:%02i", - hour_to_display, minute); - - /* Draw the hour. */ - if (hour_to_display < 10) { - pango_layout_set_text (layout, buffer + 1, 1); - gdk_draw_layout (drawable, gc, - time_x + week_view->digit_width, - time_y_normal_font, - layout); - } else { - pango_layout_set_text (layout, buffer, 2); - gdk_draw_layout (drawable, gc, - time_x, - time_y_normal_font, - layout); - } - - time_x += week_view->digit_width * 2; - - /* Draw the start minute, in the small font. */ - pango_layout_set_font_description (layout, week_view->small_font_desc); - pango_layout_set_text (layout, buffer + 3, 2); - gdk_draw_layout (drawable, gc, - time_x, - time_y_small_font, - layout); - - pango_layout_set_font_description (layout, style->font_desc); - - time_x += week_view->small_digit_width * 2; - - /* Draw the 'am'/'pm' suffix, if 12-hour format. */ - if (!e_calendar_view_get_use_24_hour_format (E_CALENDAR_VIEW (week_view))) { - pango_layout_set_text (layout, suffix, -1); - gdk_draw_layout (drawable, gc, - time_x, - time_y_normal_font, - layout); - } - } 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) { - pango_layout_set_text (layout, buffer + 1, -1); - gdk_draw_layout (drawable, gc, - time_x + week_view->digit_width, - time_y_normal_font, - layout); - } else { - pango_layout_set_text (layout, buffer, -1); - gdk_draw_layout (drawable, gc, - time_x, - time_y_normal_font, - layout); - } - - } - - g_object_unref (layout); -} - - -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; - ECalComponent *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 = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); - - gc = week_view->main_gc; - - if (e_cal_component_has_alarms (comp)) { - draw_reminder_icon = TRUE; - num_icons++; - } - - if (e_cal_component_has_recurrences (comp)) { - draw_recurrence_icon = TRUE; - num_icons++; - } - - if (event->different_timezone) { - draw_timezone_icon = TRUE; - num_icons++; - } - - e_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; - if (e_categories_config_get_icon_for (category, &pixmap, &mask)) - num_icons++; - } - - icon_x_inc = E_WEEK_VIEW_ICON_WIDTH + E_WEEK_VIEW_ICON_X_PAD; - - if (right_align) - icon_x -= icon_x_inc * num_icons; - - if (draw_reminder_icon && icon_x + E_WEEK_VIEW_ICON_WIDTH <= x2) { - gdk_gc_set_clip_origin (gc, icon_x, icon_y); - gdk_gc_set_clip_mask (gc, week_view->reminder_mask); - gdk_draw_pixmap (drawable, gc, - week_view->reminder_icon, - 0, 0, icon_x, icon_y, - E_WEEK_VIEW_ICON_WIDTH, - E_WEEK_VIEW_ICON_HEIGHT); - icon_x += icon_x_inc; - } - - if (draw_recurrence_icon && icon_x + E_WEEK_VIEW_ICON_WIDTH <= x2) { - gdk_gc_set_clip_origin (gc, icon_x, icon_y); - gdk_gc_set_clip_mask (gc, week_view->recurrence_mask); - gdk_draw_pixmap (drawable, gc, - week_view->recurrence_icon, - 0, 0, icon_x, icon_y, - E_WEEK_VIEW_ICON_WIDTH, - E_WEEK_VIEW_ICON_HEIGHT); - icon_x += icon_x_inc; - } - - 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; - if (!e_categories_config_get_icon_for (category, &pixmap, &mask)) - 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); - } - - e_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; - ECalendarViewPosition 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_CALENDAR_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_set_selected_time_range_visible (week_view, event->start, event->end); - - 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); - - e_calendar_view_edit_appointment (E_CALENDAR_VIEW (week_view), event->comp_data->client, event->comp_data->icalcomp, FALSE); - - return TRUE; -} - - -static ECalendarViewPosition -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_CALENDAR_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_CALENDAR_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_CALENDAR_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_CALENDAR_VIEW_POS_RIGHT_EDGE; - } - - return E_CALENDAR_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 ed823c2dcd..0000000000 --- a/calendar/gui/e-week-view-main-item.c +++ /dev/null @@ -1,400 +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-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 -}; - -E_MAKE_TYPE (e_week_view_main_item, "EWeekViewMainItem", EWeekViewMainItem, - e_week_view_main_item_class_init, e_week_view_main_item_init, - GNOME_TYPE_CANVAS_ITEM); - -static void -e_week_view_main_item_class_init (EWeekViewMainItemClass *class) -{ - GtkObjectClass *object_class; - GnomeCanvasItemClass *item_class; - - parent_class = g_type_class_peek_parent (class); - - 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; - 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; - PangoFontDescription *font_desc; - PangoContext *pango_context; - PangoFontMetrics *font_metrics; - PangoLayout *layout; - -#if 0 - g_print ("Drawing Day:%i at %i,%i\n", day, x, y); -#endif - week_view = wvmitem->week_view; - style = gtk_widget_get_style (GTK_WIDGET (week_view)); - gc = week_view->main_gc; - - /* Set up Pango prerequisites */ - font_desc = style->font_desc; - pango_context = gtk_widget_get_pango_context (GTK_WIDGET (week_view)); - font_metrics = pango_context_get_metrics (pango_context, font_desc, - pango_context_get_language (pango_context)); - - 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 + - PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) + - PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics)) + - 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 (week_view->selection_start_day == -1 - || week_view->selection_start_day > day - || week_view->selection_end_day < day) - selected = FALSE; - if (selected) { - if (GTK_WIDGET_HAS_FOCUS (week_view)) - gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_SELECTED]); - else - gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_SELECTED_UNFOCUSSED]); - - 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 + - PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) + - PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics))); - } 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"); - } - - 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, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view))); - 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]); - } - - g_date_strftime (buffer, sizeof (buffer), - format_string ? format_string : "%d", date); - - layout = gtk_widget_create_pango_layout (GTK_WIDGET (week_view), buffer); - pango_layout_get_pixel_size (layout, &date_width, NULL); - date_x = x + width - date_width - E_WEEK_VIEW_DATE_R_PAD; - date_x = MAX (date_x, x + 1); - - gdk_draw_layout (drawable, gc, - date_x, - y + E_WEEK_VIEW_DATE_T_PAD, - layout); - g_object_unref (layout); - - /* 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); - } - - pango_font_metrics_unref (font_metrics); -} - - - - -/* 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 733bec9a81..0000000000 --- a/calendar/gui/e-week-view-titles-item.c +++ /dev/null @@ -1,296 +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 <string.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 -}; - -E_MAKE_TYPE (e_week_view_titles_item, "EWeekViewTitlesItem", EWeekViewTitlesItem, - e_week_view_titles_item_class_init, e_week_view_titles_item_init, - GNOME_TYPE_CANVAS_ITEM); - -static void -e_week_view_titles_item_class_init (EWeekViewTitlesItemClass *class) -{ - GtkObjectClass *object_class; - GnomeCanvasItemClass *item_class; - - parent_class = g_type_class_peek_parent (class); - - 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; - 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; - PangoLayout *layout; - -#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_get_style (GTK_WIDGET (week_view)); - 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; - layout = gtk_widget_create_pango_layout (GTK_WIDGET (week_view), NULL); - - /* 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]); - - pango_layout_set_text (layout, buffer, -1); - gdk_draw_layout (drawable, fg_gc, - date_x - x, - 3 - y, - layout); - - 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); - } - - g_object_unref (layout); -} - - -/* 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 dfa175c90e..0000000000 --- a/calendar/gui/e-week-view.c +++ /dev/null @@ -1,3676 +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 "ea-calendar.h" - -#include <math.h> -#include <gdk/gdkkeysyms.h> -#include <gtk/gtkselection.h> -#include <gtk/gtksignal.h> -#include <gtk/gtkvscrollbar.h> -#include <gtk/gtkwindow.h> -#include <gtk/gtkmain.h> -#include <libgnome/gnome-i18n.h> -#include <libgnome/gnome-exec.h> -#include <libgnome/gnome-util.h> -#include <gdk-pixbuf/gdk-pixbuf.h> -#include <libgnomecanvas/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-categories-config.h> -#include <e-util/e-dialog-utils.h> -#include "dialogs/delete-comp.h" -#include "dialogs/delete-error.h" -#include "dialogs/send-comp.h" -#include "dialogs/cancel-comp.h" -#include "dialogs/recur-comp.h" -#include "comp-util.h" -#include "itip-utils.h" -#include <libecal/e-cal-time-util.h> -#include "calendar-commands.h" -#include "calendar-config.h" -#include "print.h" -#include "goto.h" -#include "e-cal-model-calendar.h" -#include "e-week-view-event-item.h" -#include "e-week-view-layout.h" -#include "e-week-view-main-item.h" -#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_PTSIZE 7 - -#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 - -#define E_WEEK_VIEW_JUMP_BUTTON_NO_FOCUS -1 - -/* 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 - - -typedef struct { - EWeekView *week_view; - ECalModelComponent *comp_data; -} AddEventData; - -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 gboolean e_week_view_get_next_tab_event (EWeekView *week_view, - GtkDirectionType direction, - gint current_event_num, - gint current_span_num, - gint *next_event_num, - gint *next_span_num); -static gboolean e_week_view_focus (GtkWidget *widget, - GtkDirectionType direction); -static GList *e_week_view_get_selected_events (ECalendarView *cal_view); -static void e_week_view_get_selected_time_range (ECalendarView *cal_view, time_t *start_time, time_t *end_time); -static void e_week_view_set_selected_time_range (ECalendarView *cal_view, time_t start_time, time_t end_time); -static gboolean e_week_view_get_visible_time_range (ECalendarView *cal_view, time_t *start_time, time_t *end_time); -static void e_week_view_update_query (ECalendarView *cal_view); -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_scroll (GtkWidget *widget, - GdkEventScroll *scroll, - 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 (ECalComponent *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_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 gboolean e_week_view_key_press (GtkWidget *widget, GdkEventKey *event); -static gboolean e_week_view_do_key_press (GtkWidget *widget, - GdkEventKey *event); -static void e_week_view_on_key_up (EWeekView *week_view, GdkEventKey *event); -static void e_week_view_on_key_down (EWeekView *week_view, GdkEventKey *event); -static void e_week_view_on_key_left (EWeekView *week_view, GdkEventKey *event); -static void e_week_view_on_key_right (EWeekView *week_view, GdkEventKey *event); -static gboolean e_week_view_popup_menu (GtkWidget *widget); - -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 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 ECalendarViewClass *parent_class; - -E_MAKE_TYPE (e_week_view, "EWeekView", EWeekView, e_week_view_class_init, - e_week_view_init, e_calendar_view_get_type ()); - -static void -e_week_view_class_init (EWeekViewClass *class) -{ - GtkObjectClass *object_class; - GtkWidgetClass *widget_class; - ECalendarViewClass *view_class; - - parent_class = g_type_class_peek_parent (class); - object_class = (GtkObjectClass *) class; - widget_class = (GtkWidgetClass *) class; - view_class = (ECalendarViewClass *) class; - - /* Method override */ - object_class->destroy = e_week_view_destroy; - - widget_class->realize = e_week_view_realize; - widget_class->unrealize = e_week_view_unrealize; - widget_class->style_set = e_week_view_style_set; - widget_class->size_allocate = e_week_view_size_allocate; - widget_class->focus_in_event = e_week_view_focus_in; - widget_class->focus_out_event = e_week_view_focus_out; - widget_class->key_press_event = e_week_view_key_press; - widget_class->popup_menu = e_week_view_popup_menu; - widget_class->expose_event = e_week_view_expose_event; - widget_class->focus = e_week_view_focus; - - view_class->get_selected_events = e_week_view_get_selected_events; - view_class->get_selected_time_range = e_week_view_get_selected_time_range; - view_class->set_selected_time_range = e_week_view_set_selected_time_range; - view_class->get_visible_time_range = e_week_view_get_visible_time_range; - view_class->update_query = e_week_view_update_query; - - /* init the accessibility support for e_week_view */ - e_week_view_a11y_init (); -} - -static void -timezone_changed_cb (ECalendarView *cal_view, icaltimezone *old_zone, - icaltimezone *new_zone, gpointer user_data) -{ - struct icaltimetype tt = icaltime_null_time (); - time_t lower; - EWeekView *week_view = (EWeekView *) cal_view; - - g_return_if_fail (E_IS_WEEK_VIEW (week_view)); - - /* 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, new_zone); - - e_week_view_recalc_day_starts (week_view, lower); - e_week_view_update_query ((ECalendarView *) week_view); -} - -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->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->multi_week_view = FALSE; - week_view->weeks_shown = 6; - week_view->rows = 6; - week_view->columns = 2; - week_view->compress_weekend = TRUE; - week_view->show_event_end_times = TRUE; - week_view->week_start_day = 0; /* Monday. */ - week_view->display_start_day = 0; /* Monday. */ - - g_date_clear (&week_view->base_date, 1); - g_date_clear (&week_view->first_day_shown, 1); - - week_view->row_height = 10; - week_view->rows_per_cell = 1; - - week_view->selection_start_day = -1; - week_view->selection_drag_pos = E_WEEK_VIEW_DRAG_NONE; - - week_view->pressed_event_num = -1; - week_view->editing_event_num = -1; - - week_view->main_gc = NULL; - - /* Create the small font. */ - week_view->use_small_font = TRUE; - - week_view->small_font_desc = - pango_font_description_copy (gtk_widget_get_style (GTK_WIDGET (week_view))->font_desc); - pango_font_description_set_size (week_view->small_font_desc, - E_WEEK_VIEW_SMALL_FONT_PTSIZE * PANGO_SCALE); - - /* 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); - - g_signal_connect_after (week_view->main_canvas, "button_press_event", - G_CALLBACK (e_week_view_on_button_press), week_view); - g_signal_connect (week_view->main_canvas, "button_release_event", - G_CALLBACK (e_week_view_on_button_release), week_view); - g_signal_connect (week_view->main_canvas, "scroll_event", - G_CALLBACK (e_week_view_on_scroll), week_view); - g_signal_connect (week_view->main_canvas, "motion_notify_event", - G_CALLBACK (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); - - g_signal_connect (week_view->jump_buttons[i], "event", - G_CALLBACK (e_week_view_on_jump_button_event), week_view); - } - week_view->focused_jump_button = E_WEEK_VIEW_JUMP_BUTTON_NO_FOCUS; - - gdk_pixbuf_unref (pixbuf); - - /* - * Scrollbar. - */ - adjustment = gtk_adjustment_new (0, -52, 52, 1, 1, 1); - gtk_signal_connect (adjustment, "value_changed", - G_CALLBACK (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; - - /* connect to ECalendarView's signals */ - g_signal_connect (G_OBJECT (week_view), "timezone_changed", - G_CALLBACK (timezone_changed_cb), NULL); -} - - -/** - * e_week_view_new: - * @Returns: a new #EWeekView. - * - * Creates a new #EWeekView. - **/ -GtkWidget * -e_week_view_new (void) -{ - GtkWidget *week_view; - ECalModel *model; - - model = E_CAL_MODEL (e_cal_model_calendar_new ()); - - week_view = GTK_WIDGET (g_object_new (e_week_view_get_type (), "model", model, NULL)); - - g_object_unref (model); - - 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); - - if (week_view->events) { - e_week_view_free_events (week_view); - g_array_free (week_view->events, TRUE); - week_view->events = NULL; - } - - if (week_view->query) { - g_signal_handlers_disconnect_matched (week_view->query, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, week_view); - g_object_unref (week_view->query); - week_view->query = NULL; - } - - if (week_view->small_font_desc) { - pango_font_description_free (week_view->small_font_desc); - week_view->small_font_desc = NULL; - } - - if (week_view->normal_cursor) { - gdk_cursor_unref (week_view->normal_cursor); - week_view->normal_cursor = NULL; - } - if (week_view->move_cursor) { - gdk_cursor_unref (week_view->move_cursor); - week_view->move_cursor = NULL; - } - if (week_view->resize_width_cursor) { - gdk_cursor_unref (week_view->resize_width_cursor); - week_view->resize_width_cursor = 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_SELECTED_UNFOCUSSED].red = 16 * 257; - week_view->colors[E_WEEK_VIEW_COLOR_SELECTED_UNFOCUSSED].green = 78 * 257; - week_view->colors[E_WEEK_VIEW_COLOR_SELECTED_UNFOCUSSED].blue = 139 * 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; - - week_view = E_WEEK_VIEW (widget); - - gdk_gc_unref (week_view->main_gc); - week_view->main_gc = NULL; - - colormap = gtk_widget_get_colormap (widget); - gdk_colormap_free_colors (colormap, week_view->colors, E_WEEK_VIEW_COLOR_LAST); - - 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 gint -get_string_width (PangoLayout *layout, const gchar *string) -{ - gint width; - - pango_layout_set_text (layout, string, -1); - pango_layout_get_pixel_size (layout, &width, NULL); - return width; -} - -/* FIXME: This is also needed in e-day-view-time-item.c. We should probably use - * pango's approximation function, but it needs a language tag. Find out how to - * get one of those properly. */ -static gint -get_digit_width (PangoLayout *layout) -{ - gint digit; - gint max_digit_width = 1; - - for (digit = '0'; digit <= '9'; digit++) { - gchar digit_char; - gint digit_width; - - digit_char = digit; - - pango_layout_set_text (layout, &digit_char, 1); - pango_layout_get_pixel_size (layout, &digit_width, NULL); - - max_digit_width = MAX (max_digit_width, digit_width); - } - - return max_digit_width; -} - -static void -e_week_view_style_set (GtkWidget *widget, - GtkStyle *previous_style) -{ - EWeekView *week_view; - GtkStyle *style; - gint day, day_width, max_day_width, max_abbr_day_width; - gint month, month_width, max_month_width, max_abbr_month_width; - GDate date; - gchar buffer[128]; - PangoFontDescription *font_desc; - PangoContext *pango_context; - PangoFontMetrics *font_metrics; - PangoLayout *layout; - - if (GTK_WIDGET_CLASS (parent_class)->style_set) - (*GTK_WIDGET_CLASS (parent_class)->style_set)(widget, previous_style); - - week_view = E_WEEK_VIEW (widget); - style = gtk_widget_get_style (widget); - - /* Set up Pango prerequisites */ - font_desc = style->font_desc; - pango_context = gtk_widget_get_pango_context (widget); - font_metrics = pango_context_get_metrics (pango_context, font_desc, - pango_context_get_language (pango_context)); - layout = pango_layout_new (pango_context); - - /* Recalculate the height of each row based on the font size. */ - week_view->row_height = PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) + - PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics)) + - 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_desc) { - if (PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) + - PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics)) - <= E_WEEK_VIEW_SMALL_FONT_PTSIZE) - week_view->use_small_font = FALSE; - } - - /* Set the height of the top canvas. */ - gtk_widget_set_usize (week_view->titles_canvas, -1, - PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) + - PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics)) + 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 = get_string_width (layout, 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 = get_string_width (layout, 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 = get_string_width (layout, 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 = get_string_width (layout, buffer); - week_view->abbr_month_widths[month] = month_width; - max_abbr_month_width = MAX (max_abbr_month_width, month_width); - } - - week_view->space_width = get_string_width (layout, " "); - week_view->colon_width = get_string_width (layout, ":"); - week_view->slash_width = get_string_width (layout, "/"); - week_view->digit_width = get_digit_width (layout); - if (week_view->small_font_desc) { - pango_layout_set_font_description (layout, week_view->small_font_desc); - week_view->small_digit_width = get_digit_width (layout); - pango_layout_set_font_description (layout, style->font_desc); - } - 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 = get_string_width (layout, - week_view->am_string); - week_view->pm_string_width = get_string_width (layout, - week_view->pm_string); - - g_object_unref (layout); - pango_font_metrics_unref (font_metrics); -} - - -/* 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; - GtkStyle *style; - gint width, height, time_width; - PangoFontDescription *font_desc; - PangoContext *pango_context; - PangoFontMetrics *font_metrics; - - 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); - style = gtk_widget_get_style (widget); - if (!style) - return; - font_desc = style->font_desc; - if (!font_desc) - return; - - pango_context = gtk_widget_get_pango_context (widget); - font_metrics = pango_context_get_metrics (pango_context, font_desc, - pango_context_get_language (pango_context)); - - - /* 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 + - + PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) - + PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics)) - + E_WEEK_VIEW_DATE_B_PAD; - } else { - week_view->events_y_offset = E_WEEK_VIEW_DATE_T_PAD - + PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) - + PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics)) - + 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_desc) { - 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; - } - - pango_font_metrics_unref (font_metrics); -} - - -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; -} - -/** - * e_week_view_get_next_tab_event - * @week_view: the week_view widget operate on - * @direction: GTK_DIR_TAB_BACKWARD or GTK_DIR_TAB_FORWARD. - * @current_event_num and @current_span_num: current status. - * @next_event_num: the event number focus should go next. - * -1 indicates focus should go to week_view widget. - * @next_span_num: always return 0. - **/ -static gboolean -e_week_view_get_next_tab_event (EWeekView *week_view, - GtkDirectionType direction, - gint current_event_num, - gint current_span_num, - gint *next_event_num, - gint *next_span_num) -{ - gint event_num; - - g_return_val_if_fail (week_view != NULL, FALSE); - g_return_val_if_fail (next_event_num != NULL, FALSE); - g_return_val_if_fail (next_span_num != NULL, FALSE); - - if (week_view->events->len <= 0) - return FALSE; - - /* we only tab through events not spans */ - *next_span_num = 0; - - switch (direction) { - case GTK_DIR_TAB_BACKWARD: - event_num = current_event_num - 1; - break; - case GTK_DIR_TAB_FORWARD: - event_num = current_event_num + 1; - break; - default: - return FALSE; - } - - if (event_num == -1) - /* backward, out of event range, go to week view widget - */ - *next_event_num = -1; - else if (event_num < -1) - /* backward from week_view, go to the last event - */ - *next_event_num = week_view->events->len - 1; - else if (event_num >= week_view->events->len) - /* forward, out of event range, go to week view widget - */ - *next_event_num = -1; - else - *next_event_num = event_num; - return TRUE; -} - -static gboolean -e_week_view_focus (GtkWidget *widget, GtkDirectionType direction) -{ - EWeekView *week_view; - gint new_event_num; - gint new_span_num; - gint event_loop; - gboolean editable = FALSE; - static gint last_focus_event_num = -1, last_focus_span_num = -1; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (E_IS_WEEK_VIEW (widget), FALSE); - - week_view = E_WEEK_VIEW (widget); - - if (week_view->focused_jump_button == E_WEEK_VIEW_JUMP_BUTTON_NO_FOCUS) { - last_focus_event_num = week_view->editing_event_num; - last_focus_span_num = week_view->editing_span_num; - } - - for (event_loop = 0; event_loop < week_view->events->len; - ++event_loop) { - if (!e_week_view_get_next_tab_event (week_view, direction, - last_focus_event_num, - last_focus_span_num, - &new_event_num, - &new_span_num)) - return FALSE; - - if (new_event_num == -1) { - /* focus should go to week_view widget - */ - gtk_widget_grab_focus (widget); - return TRUE; - } - - editable = e_week_view_start_editing_event (week_view, - new_event_num, - new_span_num, - NULL); - if (editable) - break; - else { - /* check if we should go to the jump button */ - - EWeekViewEvent *event; - EWeekViewEventSpan *span; - gint current_day; - - event = &g_array_index (week_view->events, - EWeekViewEvent, - new_event_num); - span = &g_array_index (week_view->spans, - EWeekViewEventSpan, - event->spans_index + new_span_num); - current_day = span->start_day; - - if ((week_view->focused_jump_button != current_day) && - e_week_view_is_jump_button_visible(week_view, current_day)) { - - /* focus go to the jump button */ - e_week_view_stop_editing_event (week_view); - gnome_canvas_item_grab_focus (week_view->jump_buttons[current_day]); - return TRUE; - } - } - last_focus_event_num = new_event_num; - last_focus_span_num = new_span_num; - } - return editable; -} - -/* Returns the currently-selected event, or NULL if none */ -static GList * -e_week_view_get_selected_events (ECalendarView *cal_view) -{ - EWeekViewEvent *event = NULL; - GList *list = NULL; - EWeekView *week_view = (EWeekView *) cal_view; - - g_return_val_if_fail (E_IS_WEEK_VIEW (week_view), NULL); - - if (week_view->editing_event_num != -1) { - event = &g_array_index (week_view->events, EWeekViewEvent, - week_view->editing_event_num); - } else if (week_view->popup_event_num != -1) { - event = &g_array_index (week_view->events, EWeekViewEvent, - week_view->popup_event_num); - } - - if (event) - list = g_list_prepend (list, event); - - return list; -} - -static void -process_component (EWeekView *week_view, ECalModelComponent *comp_data) -{ - EWeekViewEvent *event; - gint event_num, num_days; - ECalComponent *comp = NULL; - AddEventData add_event_data; - const char *uid; - - /* If we don't have a valid date set yet, just return. */ - if (!g_date_valid (&week_view->first_day_shown)) - return; - - comp = e_cal_component_new (); - if (!e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp))) { - g_object_unref (comp); - - g_message ("process_component(): Could not set icalcomponent on ECalComponent"); - return; - } - - e_cal_component_get_uid (comp, &uid); - - /* 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)) { - ECalComponent *tmp_comp; - - event = &g_array_index (week_view->events, EWeekViewEvent, - event_num); - - tmp_comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (tmp_comp, icalcomponent_new_clone (comp_data->icalcomp)); - if (!e_cal_component_has_recurrences (comp) - && !e_cal_component_has_recurrences (tmp_comp) - && e_cal_component_event_dates_match (comp, tmp_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_data); - g_object_unref (comp); - g_object_unref (tmp_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); - - g_object_unref (tmp_comp); - } - - /* Add the occurrences of the event */ - num_days = week_view->multi_week_view ? week_view->weeks_shown * 7 : 7; - - add_event_data.week_view = week_view; - add_event_data.comp_data = comp_data; - e_cal_recur_generate_instances (comp, - week_view->day_starts[0], - week_view->day_starts[num_days], - e_week_view_add_event, &add_event_data, - e_cal_resolve_tzid_cb, comp_data->client, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view))); - - g_object_unref (comp); - - e_week_view_queue_layout (week_view); -} - -/* Restarts a query for the week view */ -static void -e_week_view_update_query (ECalendarView *cal_view) -{ - gint rows, r; - EWeekView *week_view = E_WEEK_VIEW (cal_view); - - gtk_widget_queue_draw (week_view->main_canvas); - e_week_view_free_events (week_view); - e_week_view_queue_layout (week_view); - - rows = e_table_model_row_count (E_TABLE_MODEL (e_calendar_view_get_model (E_CALENDAR_VIEW (week_view)))); - for (r = 0; r < rows; r++) { - ECalModelComponent *comp_data; - - comp_data = e_cal_model_get_component_at (e_calendar_view_get_model (E_CALENDAR_VIEW (week_view)), r); - g_assert (comp_data != NULL); - process_component (week_view, comp_data); - } -} - -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); -} - -/* 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. */ -static void -e_week_view_set_selected_time_range (ECalendarView *cal_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; - EWeekView *week_view = E_WEEK_VIEW (cal_view); - - g_return_if_fail (E_IS_WEEK_VIEW (week_view)); - - time_to_gdate_with_zone (&date, start_time, e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view))); - - 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, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view))); - start_time = time_day_begin_with_zone (start_time, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view))); - e_week_view_recalc_day_starts (week_view, start_time); - e_week_view_update_query ((ECalendarView *) 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, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view)))) - week_view->selection_end_day = week_view->selection_start_day; - else { - time_to_gdate_with_zone (&end_date, end_time - 60, e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view))); - 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); -} - -void -e_week_view_set_selected_time_range_visible (EWeekView *week_view, - time_t start_time, - time_t end_time) -{ - GDate date, end_date; - gint num_days; - - g_return_if_fail (E_IS_WEEK_VIEW (week_view)); - - time_to_gdate_with_zone (&date, start_time, e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view))); - - /* Set the selection to the given days. */ - week_view->selection_start_day = g_date_julian (&date) - - g_date_julian (&week_view->first_day_shown); - if (end_time == start_time - || end_time <= time_add_day_with_zone (start_time, 1, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view)))) - week_view->selection_end_day = week_view->selection_start_day; - else { - time_to_gdate_with_zone (&end_date, end_time - 60, e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view))); - week_view->selection_end_day = g_date_julian (&end_date) - - g_date_julian (&week_view->first_day_shown); - } - - /* 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); - - gtk_widget_queue_draw (week_view->main_canvas); -} - - -/* Returns the selected time range. */ -static void -e_week_view_get_selected_time_range (ECalendarView *cal_view, - time_t *start_time, - time_t *end_time) -{ - gint start_day, end_day; - EWeekView *week_view = E_WEEK_VIEW (cal_view); - - 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]; -} - -/* Gets the visible time range. Returns FALSE if no time range has been set. */ -static gboolean -e_week_view_get_visible_time_range (ECalendarView *cal_view, - time_t *start_time, - time_t *end_time) -{ - gint num_days; - EWeekView *week_view = E_WEEK_VIEW (cal_view); - - /* 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; -} - - -/* 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, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view))); - - e_week_view_recalc_day_starts (week_view, start_time); - e_week_view_update_query ((ECalendarView *) 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, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view))); - 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); - - e_week_view_update_query ((ECalendarView *) 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); - } - - gtk_widget_queue_draw (week_view->main_canvas); -} - -/* 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); -} - -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; - const gchar *text; - ECalModelComponent *comp_data; - - comp_data = data; - - event = &g_array_index (week_view->events, EWeekViewEvent, event_num); - - if (event->allocated_comp_data) - e_cal_model_free_component_data (event->comp_data); - event->comp_data = comp_data; - event->allocated_comp_data = FALSE; - - 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) { - text = icalcomponent_get_summary (comp_data->icalcomp); - gnome_canvas_item_set (span->text_item, - "text", text ? text : "", - NULL); - - e_week_view_reshape_event_span (week_view, event_num, - span_num); - } - } - g_signal_emit_by_name (G_OBJECT(week_view), - "event_changed", event); - - - 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); - - u = icalcomponent_get_uid (event->comp_data->icalcomp); - 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; - } - } - - if (event->allocated_comp_data) { - e_cal_model_free_component_data (event->comp_data); - event->allocated_comp_data = FALSE; - } - - 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 - - /* 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) { - e_calendar_view_new_appointment (E_CALENDAR_VIEW (week_view)); - 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)); - - if (day < week_view->selection_start_day || day > week_view->selection_end_day) { - week_view->selection_start_day = day; - week_view->selection_end_day = day; - week_view->selection_drag_pos = E_WEEK_VIEW_DRAG_NONE; - - /* FIXME: Optimise? */ - gtk_widget_queue_draw (week_view->main_canvas); - } - - e_week_view_show_popup_menu (week_view, event, -1); - } - - return TRUE; -} - - -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]; - - gnome_calendar_set_selected_time_range (e_calendar_view_get_calendar (E_CALENDAR_VIEW (week_view)), - start, end); - } - - return FALSE; -} - -static gboolean -e_week_view_on_scroll (GtkWidget *widget, - GdkEventScroll *scroll, - EWeekView *week_view) -{ - GtkAdjustment *adj = GTK_RANGE (week_view->vscrollbar)->adjustment; - gfloat new_value; - - switch (scroll->direction){ - case GDK_SCROLL_UP: - new_value = adj->value - adj->page_increment; - break; - case GDK_SCROLL_DOWN: - new_value = adj->value + adj->page_increment; - break; - default: - return FALSE; - } - - new_value = CLAMP (new_value, adj->lower, adj->upper - adj->page_size); - gtk_adjustment_set_value (adj, new_value); - - return TRUE; -} - - -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); - if (event->allocated_comp_data) - e_cal_model_free_component_data (event->comp_data); - } - - 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 (ECalComponent *comp, - time_t start, - time_t end, - gpointer data) - -{ - AddEventData *add_event_data; - EWeekViewEvent event; - gint num_days; - struct icaltimetype start_tt, end_tt; - - add_event_data = data; - - /* Check that the event times are valid. */ - num_days = add_event_data->week_view->multi_week_view ? add_event_data->week_view->weeks_shown * 7 : 7; - -#if 0 - g_print ("View start:%li end:%li Event start:%li end:%li\n", - add_event_data->week_view->day_starts[0], add_event_data->week_view->day_starts[num_days], - start, end); -#endif - g_return_val_if_fail (start <= end, TRUE); - g_return_val_if_fail (start < add_event_data->week_view->day_starts[num_days], TRUE); - g_return_val_if_fail (end > add_event_data->week_view->day_starts[0], TRUE); - - start_tt = icaltime_from_timet_with_zone (start, FALSE, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (add_event_data->week_view))); - end_tt = icaltime_from_timet_with_zone (end, FALSE, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (add_event_data->week_view))); - - if (add_event_data->comp_data) { - event.comp_data = add_event_data->comp_data; - event.allocated_comp_data = FALSE; - } else { - event.comp_data = g_new0 (ECalModelComponent, 1); - event.allocated_comp_data = TRUE; - - event.comp_data->client = e_cal_model_get_default_client (e_calendar_view_get_model (E_CALENDAR_VIEW (add_event_data->week_view))); - e_cal_component_commit_sequence (comp); - event.comp_data->icalcomp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (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, - event.comp_data->client, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (add_event_data->week_view)))) - event.different_timezone = TRUE; - - g_array_append_val (add_event_data->week_view->events, event); - add_event_data->week_view->events_sorted = FALSE; - add_event_data->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; - 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; - ECalComponent *comp; - gdouble text_x, text_y, text_w, text_h; - gchar *text, *end_of_line; - gint line_len, text_width; - PangoFontDescription *font_desc; - PangoContext *pango_context; - PangoFontMetrics *font_metrics; - PangoLayout *layout; - - event = &g_array_index (week_view->events, EWeekViewEvent, event_num); - span = &g_array_index (week_view->spans, EWeekViewEventSpan, - event->spans_index + span_num); - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); - - 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; - - g_object_unref (comp); - return; - } - - /* Set up Pango prerequisites */ - font_desc = gtk_widget_get_style (GTK_WIDGET (week_view))->font_desc; - pango_context = gtk_widget_get_pango_context (GTK_WIDGET (week_view)); - font_metrics = pango_context_get_metrics (pango_context, font_desc, - pango_context_get_language (pango_context)); - layout = pango_layout_new (pango_context); - - /* 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, *elem; - - if (e_cal_component_has_alarms (comp)) - num_icons++; - if (e_cal_component_has_recurrences (comp)) - num_icons++; - if (event->different_timezone) - num_icons++; - - e_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; - if (e_categories_config_get_icon_for (category, &pixmap, &mask)) - num_icons++; - } - - e_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) { - ECalComponentText text; - - e_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 (), - "anchor", GTK_ANCHOR_NW, - "clip", TRUE, - "max_lines", 1, - "editable", TRUE, - "text", text.value ? text.value : "", - "use_ellipsis", TRUE, - "fill_color_rgba", GNOME_CANVAS_COLOR(0, 0, 0), - "im_context", E_CANVAS (week_view->main_canvas)->im_context, - NULL); - - g_signal_connect (span->text_item, "event", - G_CALLBACK (e_week_view_on_text_item_event), - week_view); - g_signal_emit_by_name (G_OBJECT(week_view), - "event_added", event); - - } - - /* 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 = - PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) + - PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics)); - - 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. */ - g_object_get (G_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); - - pango_layout_set_text (layout, text, line_len); - pango_layout_get_pixel_size (layout, &text_width, NULL); - 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); - - g_object_unref (comp); - g_object_unref (layout); - pango_font_metrics_unref (font_metrics); -} - - -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, e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view))); - - e_week_view_recalc_day_starts (week_view, lower); - e_week_view_update_query ((ECalendarView *) 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]; - gnome_calendar_set_selected_time_range (e_calendar_view_get_calendar (E_CALENDAR_VIEW (week_view)), - start, end); - } -} - - -gboolean -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 TRUE; - - 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 FALSE; - - 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. */ - g_object_get (G_OBJECT (span->text_item), "event_processor", &event_processor, NULL); - if (event_processor) { - command.action = E_TEP_MOVE; - command.position = E_TEP_END_OF_BUFFER; - g_signal_emit_by_name (event_processor, - "command", &command); - } - return TRUE; -} - - -/* 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; - const gchar *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 */ - - summary = icalcomponent_get_summary (event->comp_data->icalcomp); - g_object_set (G_OBJECT (span->text_item), "text", summary ? summary : "", NULL); - - /* Stop editing */ - e_week_view_stop_editing_event (week_view); -} - -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"); - /* focus should go to week view when stop editing */ - gtk_widget_grab_focus (GTK_WIDGET (week_view)); - 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); - - e_calendar_view_edit_appointment (E_CALENDAR_VIEW (week_view), - event->comp_data->client, - event->comp_data->icalcomp, FALSE); - - 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 && !E_TEXT (item)->editing) { - EWeekViewEvent *e; - - e = &g_array_index (week_view->events, EWeekViewEvent, event_num); - - if (!GTK_WIDGET_HAS_FOCUS (week_view)) - gtk_widget_grab_focus (GTK_WIDGET (week_view)); - - e_week_view_set_selected_time_range_visible (week_view, e->start, e->end); - - 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; - } - - if (gdkevent->button.button != 3) { - 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); - } - - g_signal_emit_by_name (week_view, "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; - ECalComponent *comp; - ECalComponentText summary; - ECal *client; - const char *uid; - gboolean on_server; - - /* Note: the item we are passed here isn't reliable, so we just stop - the edit of whatever item was being edited. We also receive this - event twice for some reason. */ - 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. */ - uid = icalcomponent_get_uid (event->comp_data->icalcomp); - if (!uid) - return; - - g_object_set (span->text_item, "handle_popup", FALSE, NULL); - g_object_get (G_OBJECT (span->text_item), "text", &text, NULL); - g_assert (text != NULL); - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); - - client = event->comp_data->client; - on_server = cal_comp_is_on_server (comp, client); - - if (string_is_empty (text) && !on_server) { - const char *uid; - - e_cal_component_get_uid (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; - } - - /* Only update the summary if necessary. */ - e_cal_component_get_summary (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 if (summary.value || !string_is_empty (text)) { - icalcomponent *icalcomp = e_cal_component_get_icalcomponent (comp); - - summary.value = text; - summary.altrep = NULL; - e_cal_component_set_summary (comp, &summary); - - if (!on_server) { - if (!e_cal_create_object (client, icalcomp, NULL, NULL)) - g_message (G_STRLOC ": Could not create the object!"); - } else { - CalObjModType mod = CALOBJ_MOD_ALL; - GtkWindow *toplevel; - - if (e_cal_component_has_recurrences (comp)) { - if (!recur_component_dialog (client, comp, &mod, NULL)) { - goto out; - } - } - - /* FIXME When sending here, what exactly should we send? */ - toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (week_view))); - if (e_cal_modify_object (client, icalcomp, mod, NULL)) { - if (itip_organizer_is_user (comp, client) - && send_component_dialog (toplevel, client, comp, FALSE)) - itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, - client, NULL); - } - } - } - - out: - - g_free (text); - g_object_unref (comp); - - g_signal_emit_by_name (week_view, "selection_changed"); -} - - -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; - - *event_num_return = -1; - if (!uid) - return FALSE; - - num_events = week_view->events->len; - for (event_num = 0; event_num < num_events; event_num++) { - const char *u; - - event = &g_array_index (week_view->events, EWeekViewEvent, - event_num); - - u = icalcomponent_get_uid (event->comp_data->icalcomp); - 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 gboolean -e_week_view_do_key_press (GtkWidget *widget, GdkEventKey *event) -{ - EWeekView *week_view; - ECalComponent *comp; - icalcomponent *icalcomp; - gint event_num; - gchar *initial_text; - ECalComponentDateTime date; - struct icaltimetype itt; - time_t dtstart, dtend; - const char *uid; - AddEventData add_event_data; - - 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_CALENDAR_VIEW_POS_NONE) { - if (event->keyval == GDK_Escape) { - e_week_view_abort_resize (week_view, event->time); - } - return FALSE; - } -#endif - - /*Navigation through days with arrow keys*/ - switch (event->keyval) { - case GDK_Up: - e_week_view_on_key_up (week_view, event); - return TRUE; - case GDK_Down: - e_week_view_on_key_down (week_view, event); - return TRUE; - case GDK_Left: - e_week_view_on_key_left (week_view, event); - return TRUE; - case GDK_Right: - e_week_view_on_key_right (week_view, event); - return TRUE; - default: - break; - } - - 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. */ - icalcomp = e_cal_model_create_component_with_defaults (e_calendar_view_get_model (E_CALENDAR_VIEW (week_view))); - if (!icalcomp) - return FALSE; - uid = icalcomponent_get_uid (icalcomp); - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomp); - - 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 (e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view)));*/ - - *date.value = icaltime_from_timet_with_zone (dtstart, TRUE, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view))); - e_cal_component_set_dtstart (comp, &date); - - *date.value = icaltime_from_timet_with_zone (dtend, TRUE, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view))); - e_cal_component_set_dtend (comp, &date); - - e_cal_component_set_categories ( - comp, e_calendar_view_get_default_category (E_CALENDAR_VIEW (week_view))); - - /* We add the event locally and start editing it. We don't send it - to the server until the user finishes editing it. */ - add_event_data.week_view = week_view; - add_event_data.comp_data = NULL; - e_week_view_add_event (comp, dtstart, dtend, &add_event_data); - e_week_view_check_layout (week_view); - gtk_widget_queue_draw (week_view->main_canvas); - - 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); - - g_object_unref (comp); - - return TRUE; -} - -static void -e_week_view_on_key_up (EWeekView *week_view, GdkEventKey *event) -{ - gint selection_start_day, selection_end_day; - - selection_start_day = week_view->selection_start_day; - selection_end_day = week_view->selection_end_day; - - if (selection_start_day == -1) { - selection_start_day = 0; - selection_end_day = 0; - } - - if (week_view->multi_week_view) { - if (selection_end_day < 7) { - g_date_subtract_days (&(week_view->first_day_shown), 7); - } else - selection_end_day -= 7; - } - else { - if (selection_start_day == selection_end_day) { - if (selection_end_day == 0) { - g_date_subtract_days (&(week_view->first_day_shown), 7); - selection_end_day = 6; - } else - selection_end_day--; - } else { - selection_end_day = - (selection_start_day + selection_end_day)/2; - } - } - - week_view->selection_start_day = selection_end_day; - week_view->selection_end_day = selection_end_day; - - gtk_widget_queue_draw (week_view->main_canvas); -} - -static void -e_week_view_on_key_down (EWeekView *week_view, GdkEventKey *event) -{ - gint selection_start_day, selection_end_day; - - selection_start_day = week_view->selection_start_day; - selection_end_day = week_view->selection_end_day; - - if (selection_start_day == -1) { - selection_start_day = 0; - selection_end_day = 0; - } - - if (week_view->multi_week_view) { - if ((selection_end_day+7) / 7 >= week_view->weeks_shown) { - g_date_add_days (&(week_view->first_day_shown), 7); - } else - selection_end_day += 7; - } - else { - if (selection_start_day == selection_end_day) { - if (selection_end_day == 6) { - g_date_add_days (&(week_view->first_day_shown), 7); - selection_end_day = 0; - } else - selection_end_day++; - } else { - selection_end_day = - (selection_start_day + selection_end_day)/2; - } - } - - week_view->selection_start_day = selection_end_day; - week_view->selection_end_day = selection_end_day; - - gtk_widget_queue_draw (week_view->main_canvas); -} - -static void -e_week_view_on_key_left (EWeekView *week_view, GdkEventKey *event) -{ - gint selection_start_day, selection_end_day; - - selection_start_day = week_view->selection_start_day; - selection_end_day = week_view->selection_end_day; - - if (selection_start_day == -1) { - selection_start_day = 0; - selection_end_day = 0; - } - - if (week_view->multi_week_view) { - if (selection_end_day == 0) { - g_date_subtract_days (&(week_view->first_day_shown), 7); - selection_end_day = 6; - } else - selection_end_day -= 1; - } - else { - switch (selection_end_day) { - case 0: - case 1: - case 2: - g_date_subtract_days (&(week_view->first_day_shown), 7); - selection_end_day += 3; - break; - case 3: - case 4: - case 5: - selection_end_day -= 3; - break; - case 6: - selection_end_day -= 4; - break; - default: - break; - } - } - - week_view->selection_start_day = selection_end_day; - week_view->selection_end_day = selection_end_day; - - gtk_widget_queue_draw (week_view->main_canvas); - -} - -static void -e_week_view_on_key_right (EWeekView *week_view, GdkEventKey *event) -{ - - gint selection_start_day, selection_end_day; - - selection_start_day = week_view->selection_start_day; - selection_end_day = week_view->selection_end_day; - - if (selection_start_day == -1) { - selection_start_day = 0; - selection_end_day = 0; - } - - if (week_view->multi_week_view) { - if (selection_end_day == week_view->weeks_shown*7 -1 ) { - g_date_add_days (&(week_view->first_day_shown), 7); - selection_end_day -= 6; - } else - selection_end_day++; - } - else { - switch (selection_end_day) { - case 0: - case 1: - case 2: - selection_end_day += 3; - break; - case 3: - case 4: - case 5: - g_date_add_days (&(week_view->first_day_shown), 7); - selection_end_day -= 3; - break; - case 6: - g_date_add_days (&(week_view->first_day_shown), 7); - selection_end_day -= 4; - break; - default: - break; - } - } - - week_view->selection_start_day = selection_end_day; - week_view->selection_end_day = selection_end_day; - - gtk_widget_queue_draw (week_view->main_canvas); -} - -static gboolean -e_week_view_key_press (GtkWidget *widget, GdkEventKey *event) -{ - gboolean handled = FALSE; - handled = e_week_view_do_key_press (widget, event); - - /* if not handled, try key bindings */ - if (!handled) - handled = GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event); - return handled; -} - -void -e_week_view_show_popup_menu (EWeekView *week_view, - GdkEventButton *bevent, - gint event_num) -{ - GtkMenu *popup; - - week_view->popup_event_num = event_num; - - popup = e_calendar_view_create_popup_menu (E_CALENDAR_VIEW (week_view)); - e_popup_menu (popup, (GdkEvent *) bevent); -} - -static gboolean -e_week_view_popup_menu (GtkWidget *widget) -{ - EWeekView *week_view = E_WEEK_VIEW (widget); - e_week_view_show_popup_menu (week_view, NULL, - week_view->editing_event_num); - return TRUE; -} - -void -e_week_view_jump_to_button_item (EWeekView *week_view, GnomeCanvasItem *item) -{ - gint day; - GnomeCalendar *calendar; - - for (day = 0; day < E_WEEK_VIEW_MAX_WEEKS * 7; ++day) { - if (item == week_view->jump_buttons[day]) { - calendar = e_calendar_view_get_calendar (E_CALENDAR_VIEW (week_view)); - if (calendar) - gnome_calendar_dayjump - (calendar, - week_view->day_starts[day]); - else - g_warning ("Calendar not set"); - return; - } - } -} - -static gboolean -e_week_view_on_jump_button_event (GnomeCanvasItem *item, - GdkEvent *event, - EWeekView *week_view) -{ - gint day; - - if (event->type == GDK_BUTTON_PRESS) { - e_week_view_jump_to_button_item (week_view, item); - return TRUE; - } - else if (event->type == GDK_KEY_PRESS) { - /* return, if Tab, Control or Alt is pressed */ - if ((event->key.keyval == GDK_Tab) || - (event->key.state & (GDK_CONTROL_MASK | GDK_MOD1_MASK))) - return FALSE; - /* with a return key or a simple character (from 0x20 to 0xff), - * jump to the day - */ - if ((event->key.keyval == GDK_Return) || - ((event->key.keyval >= 0x20) && - (event->key.keyval <= 0xFF))) { - e_week_view_jump_to_button_item (week_view, item); - return TRUE; - } - } - else if (event->type == GDK_FOCUS_CHANGE) { - GdkEventFocus *focus_event = (GdkEventFocus *)event; - GdkPixbuf *pixbuf = NULL; - - for (day = 0; day < E_WEEK_VIEW_MAX_WEEKS * 7; day++) { - if (item == week_view->jump_buttons[day]) - break; - } - - if (focus_event->in) { - week_view->focused_jump_button = day; - pixbuf = gdk_pixbuf_new_from_xpm_data ((const char**) jump_xpm_focused); - gnome_canvas_item_set (week_view->jump_buttons[day], - "GnomeCanvasPixbuf::pixbuf", - pixbuf, NULL); - } - else { - week_view->focused_jump_button = E_WEEK_VIEW_JUMP_BUTTON_NO_FOCUS; - pixbuf = gdk_pixbuf_new_from_xpm_data ((const char**) jump_xpm); - gnome_canvas_item_set (week_view->jump_buttons[day], - "GnomeCanvasPixbuf::pixbuf", - pixbuf, NULL); - } - if (pixbuf) - gdk_pixbuf_unref (pixbuf); - } - - 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 (e_calendar_view_get_use_24_hour_format (E_CALENDAR_VIEW (week_view))) { - *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_desc) - 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 (!e_calendar_view_get_use_24_hour_format (E_CALENDAR_VIEW (week_view))) - time_width += MAX (week_view->am_string_width, - week_view->pm_string_width); - - return time_width; -} - -/* 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; -} - -gboolean -e_week_view_is_jump_button_visible (EWeekView *week_view, gint day) -{ - g_return_val_if_fail (E_IS_WEEK_VIEW (week_view), FALSE); - - if ((day >= 0) && (day < E_WEEK_VIEW_MAX_WEEKS * 7)) - return week_view->jump_buttons[day]->object.flags & GNOME_CANVAS_ITEM_VISIBLE; - return FALSE; -} diff --git a/calendar/gui/e-week-view.h b/calendar/gui/e-week-view.h deleted file mode 100644 index aca3f2bc2a..0000000000 --- a/calendar/gui/e-week-view.h +++ /dev/null @@ -1,438 +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 <libgnomecanvas/gnome-canvas.h> -#include <gal/widgets/e-popup-menu.h> - -#include "e-cal-view.h" -#include "gnome-cal.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - * EWeekView - displays the Week & Month views of the calendar. - */ - -/* The maximum number of weeks we show. 5 is usually enough for 1 month, - but we allow 6 for longer selections. */ -#define E_WEEK_VIEW_MAX_WEEKS 6 - -/* The size of the reminder & recurrence icons, and padding around them. - X_PAD is the padding between icons. R_PAD is the padding on the right of - the last icon, before the event text. */ -#define E_WEEK_VIEW_ICON_WIDTH 16 -#define E_WEEK_VIEW_ICON_HEIGHT 16 -#define E_WEEK_VIEW_ICON_X_PAD 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_SELECTED_UNFOCUSSED, - 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; - -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 { - E_CALENDAR_VIEW_EVENT_FIELDS - gint spans_index; - guint8 num_spans; -}; - - -#define E_WEEK_VIEW(obj) GTK_CHECK_CAST (obj, e_week_view_get_type (), EWeekView) -#define E_WEEK_VIEW_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, e_week_view_get_type (), EWeekViewClass) -#define E_IS_WEEK_VIEW(obj) GTK_CHECK_TYPE (obj, e_week_view_get_type ()) - - -typedef struct _EWeekView EWeekView; -typedef struct _EWeekViewClass EWeekViewClass; - -struct _EWeekView -{ - ECalendarView cal_view; - - /* 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]; - gint focused_jump_button; - - GtkWidget *vscrollbar; - - /* The query object */ - ECalView *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 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; - - /* 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. */ - PangoFontDescription *small_font_desc; - - /* 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; - - /* The last mouse position when dragging, in the entire canvas. */ - gint drag_event_x; - gint drag_event_y; - - /* "am" and "pm" in the current locale, and their widths. */ - gchar *am_string; - gchar *pm_string; - gint am_string_width; - gint pm_string_width; -}; - -struct _EWeekViewClass -{ - ECalendarViewClass parent_class; -}; - - -GtkType e_week_view_get_type (void); -GtkWidget* e_week_view_new (void); - -/* 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); - -/* 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_visible (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); - -void e_week_view_delete_occurrence (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); -gboolean 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); - -gboolean e_week_view_find_event_from_item (EWeekView *week_view, - GnomeCanvasItem *item, - gint *event_num_return, - gint *span_num_return); - -gboolean e_week_view_is_jump_button_visible (EWeekView *week_view, - gint day); -void e_week_view_jump_to_button_item (EWeekView *week_view, GnomeCanvasItem *item); - -#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 8978f38988..0000000000 --- a/calendar/gui/gnome-cal.c +++ /dev/null @@ -1,2925 +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. - * Copyright (C) 2003 Novell, Inc - * - * Authors: Miguel de Icaza <miguel@ximian.com> - * Federico Mena-Quintero <federico@ximian.com> - * Seth Alves <alves@hungry.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 <unistd.h> -#include <signal.h> -#include <sys/wait.h> -#include <fcntl.h> -#include <glib.h> -#include <gdk/gdkkeysyms.h> -#include <gtk/gtkbindings.h> -#include <libgnome/gnome-i18n.h> -#include <libgnome/gnome-util.h> -#include <libgnomeui/gnome-dialog.h> -#include <libgnomeui/gnome-dialog-util.h> -#include <bonobo/bonobo-exception.h> -#include "e-util/e-url.h" -#include <libecal/e-cal-time-util.h> -#include "widgets/menus/gal-view-menus.h" -#include "e-comp-editor-registry.h" -#include "dialogs/delete-error.h" -#include "dialogs/event-editor.h" -#include "dialogs/task-editor.h" -#include "comp-util.h" -#include "e-cal-model-calendar.h" -#include "e-day-view.h" -#include "e-day-view-config.h" -#include "e-day-view-time-item.h" -#include "e-week-view.h" -#include "e-week-view-config.h" -#include "e-cal-list-view.h" -#include "e-cal-list-view-config.h" -#include "e-mini-calendar-config.h" -#include "e-calendar-table-config.h" -#include "evolution-calendar.h" -#include "gnome-cal.h" -#include "calendar-component.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" -#include "misc.h" -#include "ea-calendar.h" - - - -/* Private part of the GnomeCalendar structure */ -struct _GnomeCalendarPrivate { - /* The calendars for display */ - GHashTable *clients; - GList *clients_list; - - /* Set of categories from the calendar client */ - /* FIXME are we getting all the categories? */ - GPtrArray *cal_categories; - - /* - * The TaskPad Folder. - */ - - /* The calendar client object we monitor */ - ECal *task_pad_client; - - /* Set of categories from the tasks client */ - GPtrArray *tasks_categories; - - /* - * Fields for the calendar view - */ - - /* 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; - EMiniCalendarConfig *date_navigator_config; - GtkWidget *todo; - ECalendarTableConfig *todo_config; - - GtkWidget *day_view; - GtkWidget *work_week_view; - GtkWidget *week_view; - GtkWidget *month_view; - GtkWidget *list_view; - - /* Calendar query for the date navigator */ - GList *dn_queries; /* list of CalQueries */ - char *sexp; - guint e_cal_view_timeout; - - /* 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. */ - ECalendarView *views[GNOME_CAL_LAST_VIEW]; - GObject *configs[GNOME_CAL_LAST_VIEW]; - GnomeCalendarViewType current_view_type; - GList *notifications; - - 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. */ - gint hpane_pos; - gint vpane_pos; - gint hpane_pos_month_view; - gint 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; - - /* 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, - GOTO_DATE, - 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_goto_date (GnomeCalendar *gcal, - GnomeCalendarGotoDateType goto_date); - -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_hpane_realized (GtkWidget *w, GnomeCalendar *gcal); -static void gnome_calendar_vpane_realized (GtkWidget *w, GnomeCalendar *gcal); -static gboolean gnome_calendar_vpane_resized (GtkWidget *w, GdkEventButton *e, GnomeCalendar *gcal); -static gboolean gnome_calendar_hpane_resized (GtkWidget *w, GdkEventButton *e, GnomeCalendar *gcal); - -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; - - - - -E_MAKE_TYPE (gnome_calendar, "GnomeCalendar", GnomeCalendar, gnome_calendar_class_init, - gnome_calendar_init, GTK_TYPE_VBOX); - -/* Class initialization function for the gnome calendar */ -static void -gnome_calendar_class_init (GnomeCalendarClass *class) -{ - GtkObjectClass *object_class; - GtkBindingSet *binding_set; - - object_class = (GtkObjectClass *) class; - - parent_class = g_type_class_peek_parent (class); - - gnome_calendar_signals[DATES_SHOWN_CHANGED] = - gtk_signal_new ("dates_shown_changed", - GTK_RUN_LAST, - G_TYPE_FROM_CLASS (object_class), - 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, - G_TYPE_FROM_CLASS (object_class), - 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, - G_TYPE_FROM_CLASS (object_class), - 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, - G_TYPE_FROM_CLASS (object_class), - 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, - G_TYPE_FROM_CLASS (object_class), - GTK_SIGNAL_OFFSET (GnomeCalendarClass, taskpad_focus_change), - gtk_marshal_NONE__BOOL, - GTK_TYPE_NONE, 1, - GTK_TYPE_BOOL); - - gnome_calendar_signals[GOTO_DATE] = - g_signal_new ("goto_date", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (GnomeCalendarClass, goto_date), - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, - 1, - G_TYPE_INT); - - - 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; - class->goto_date = gnome_calendar_goto_date; - - /* - * Key bindings - */ - - binding_set = gtk_binding_set_by_class (class); - - /* Alt+PageUp/PageDown, go to the first/last day of the month */ - gtk_binding_entry_add_signal (binding_set, GDK_Page_Up, - GDK_MOD1_MASK, - "goto_date", 1, - G_TYPE_ENUM, - GNOME_CAL_GOTO_FIRST_DAY_OF_MONTH); - gtk_binding_entry_add_signal (binding_set, GDK_KP_Page_Up, - GDK_MOD1_MASK, - "goto_date", 1, - G_TYPE_ENUM, - GNOME_CAL_GOTO_FIRST_DAY_OF_MONTH); - gtk_binding_entry_add_signal (binding_set, GDK_Page_Down, - GDK_MOD1_MASK, - "goto_date", 1, - G_TYPE_ENUM, - GNOME_CAL_GOTO_LAST_DAY_OF_MONTH); - gtk_binding_entry_add_signal (binding_set, GDK_KP_Page_Down, - GDK_MOD1_MASK, - "goto_date", 1, - G_TYPE_ENUM, - GNOME_CAL_GOTO_LAST_DAY_OF_MONTH); - - /* Alt+Home/End, go to the first/last day of the week */ - gtk_binding_entry_add_signal (binding_set, GDK_Home, - GDK_MOD1_MASK, - "goto_date", 1, - G_TYPE_ENUM, - GNOME_CAL_GOTO_FIRST_DAY_OF_WEEK); - gtk_binding_entry_add_signal (binding_set, GDK_End, - GDK_MOD1_MASK, - "goto_date", 1, - G_TYPE_ENUM, - GNOME_CAL_GOTO_LAST_DAY_OF_WEEK); - gtk_binding_entry_add_signal (binding_set, GDK_KP_Home, - GDK_MOD1_MASK, - "goto_date", 1, - G_TYPE_ENUM, - GNOME_CAL_GOTO_FIRST_DAY_OF_WEEK); - gtk_binding_entry_add_signal (binding_set, GDK_KP_End, - GDK_MOD1_MASK, - "goto_date", 1, - G_TYPE_ENUM, - GNOME_CAL_GOTO_LAST_DAY_OF_WEEK); - - /*Alt+Left/Right, go to the same day of the previous/next week*/ - gtk_binding_entry_add_signal (binding_set,GDK_Left, - GDK_MOD1_MASK, - "goto_date",1, - G_TYPE_ENUM, - GNOME_CAL_GOTO_SAME_DAY_OF_PREVIOUS_WEEK); - gtk_binding_entry_add_signal (binding_set,GDK_KP_Left, - GDK_MOD1_MASK, - "goto_date",1, - G_TYPE_ENUM, - GNOME_CAL_GOTO_SAME_DAY_OF_PREVIOUS_WEEK); - gtk_binding_entry_add_signal (binding_set,GDK_Right, - GDK_MOD1_MASK, - "goto_date",1, - G_TYPE_ENUM, - GNOME_CAL_GOTO_SAME_DAY_OF_NEXT_WEEK); - gtk_binding_entry_add_signal (binding_set,GDK_KP_Right, - GDK_MOD1_MASK, - "goto_date",1, - G_TYPE_ENUM, - GNOME_CAL_GOTO_SAME_DAY_OF_NEXT_WEEK); - /* init the accessibility support for gnome_calendar */ - gnome_calendar_a11y_init (); - -} - -/* Callback used when the calendar query reports of an updated object */ -static void -dn_e_cal_view_objects_added_cb (ECalView *query, GList *objects, gpointer data) -{ - GnomeCalendar *gcal; - GnomeCalendarPrivate *priv; - GList *l; - - gcal = GNOME_CALENDAR (data); - priv = gcal->priv; - - for (l = objects; l; l = l->next) { - ECalComponent *comp = NULL; - - comp = e_cal_component_new (); - if (!e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (l->data))) { - g_object_unref (comp); - - continue; - } - - tag_calendar_by_comp (priv->date_navigator, comp, e_cal_view_get_client (query), NULL, - FALSE, TRUE); - g_object_unref (comp); - } -} - -static void -dn_e_cal_view_objects_modified_cb (ECalView *query, GList *objects, gpointer data) -{ - GnomeCalendar *gcal; - GnomeCalendarPrivate *priv; - - gcal = GNOME_CALENDAR (data); - priv = gcal->priv; - - /* We have to retag the whole thing: an event may change dates - * and the tag_calendar_by_comp() below would not know how to - * untag the old dates. - */ - update_query (gcal); -} - -/* Callback used when the calendar query reports of a removed object */ -static void -dn_e_cal_view_objects_removed_cb (ECalView *query, GList *uids, 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_e_cal_view_done_cb (ECalView *query, ECalendarStatus status, gpointer data) -{ - GnomeCalendar *gcal; - - gcal = GNOME_CALENDAR (data); - - /* FIXME Better error reporting */ - if (status != E_CALENDAR_STATUS_OK) - g_warning (G_STRLOC ": Query did not successfully complete"); -} - -/* Returns the current view widget, an EDayView, EWeekView or ECalListView. */ -GtkWidget* -gnome_calendar_get_current_view_widget (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - - priv = gcal->priv; - - return GTK_WIDGET (priv->views[priv->current_view_type]); -} - -/* 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; - ECalListView *lv; - - widget = gnome_calendar_get_current_view_widget (gcal); - - switch (priv->current_view_type) { - case GNOME_CAL_DAY_VIEW: - case GNOME_CAL_WORK_WEEK_VIEW: - dv = E_DAY_VIEW (widget); - - if (GTK_WIDGET_HAS_FOCUS (dv->top_canvas) - || 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; - - case GNOME_CAL_LIST_VIEW: - lv = E_CAL_LIST_VIEW (widget); - - if (GTK_WIDGET_HAS_FOCUS (e_table_scrolled_get_table (lv->table_scrolled))) - return FOCUS_CALENDAR; - else - return FOCUS_OTHER; - - default: - g_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_e_cal_view_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 (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; - ECalView *old_query; - char *real_sexp; - GList *l; - - priv = gcal->priv; - - e_calendar_item_clear_marks (priv->date_navigator->calitem); - - e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), _("Searching")); - - /* free the previous queries */ - for (l = priv->dn_queries; l != NULL; l = l->next) { - old_query = l->data; - - if (old_query) { - g_signal_handlers_disconnect_matched (old_query, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, gcal); - g_object_unref (old_query); - } - } - - g_list_free (priv->dn_queries); - priv->dn_queries = NULL; - - g_assert (priv->sexp != NULL); - - real_sexp = adjust_e_cal_view_sexp (gcal, priv->sexp); - if (!real_sexp) { - e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL); - return; /* No time range is set, so don't start a query */ - } - - /* create queries for each loaded client */ - for (l = priv->clients_list; l != NULL; l = l->next) { - if (!e_cal_get_query ((ECal *) l->data, real_sexp, &old_query, NULL)) { - g_warning (G_STRLOC ": Could not create the query"); - - continue; - } - - g_signal_connect (old_query, "objects_added", - G_CALLBACK (dn_e_cal_view_objects_added_cb), gcal); - g_signal_connect (old_query, "objects_modified", - G_CALLBACK (dn_e_cal_view_objects_modified_cb), gcal); - g_signal_connect (old_query, "objects_removed", - G_CALLBACK (dn_e_cal_view_objects_removed_cb), gcal); - g_signal_connect (old_query, "view_done", - G_CALLBACK (dn_e_cal_view_done_cb), gcal); - - priv->dn_queries = g_list_append (priv->dn_queries, old_query); - - e_cal_view_start (old_query); - } - - g_free (real_sexp); - - e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL); -} - -static void -adjust_e_cal_view_for_view (ECalendarView *cal_view, const char *sexp) -{ - char *real_sexp, *start, *end; - time_t ttstart, ttend; - - e_calendar_view_get_visible_time_range (cal_view, &ttstart, &ttend); - - start = isodate_from_time_t (ttstart); - end = isodate_from_time_t (ttend); - - real_sexp = g_strdup_printf ( - "(and (occur-in-time-range? (make-time \"%s\")" - " (make-time \"%s\"))" - " %s)", - start, end, sexp); - - e_cal_model_set_query (e_calendar_view_get_model (cal_view), real_sexp); - - g_free (start); - g_free (end); - g_free (real_sexp); -} - -/** - * 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; - ECalModel *model; - int i; - - 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 views */ - for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) - adjust_e_cal_view_for_view (E_CALENDAR_VIEW (priv->views[i]), sexp); - - /* Set the query on the task pad */ - model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo)); - e_cal_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; - ECalModel *model; - int i; - - gcal = GNOME_CALENDAR (data); - priv = gcal->priv; - - for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) { - e_calendar_view_set_default_category (E_CALENDAR_VIEW (priv->views[i]), - category); - } - - model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo)); - e_cal_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) -{ - g_signal_connect (dv->top_canvas, "focus_in_event", - G_CALLBACK (calendar_focus_change_cb), gcal); - g_signal_connect (dv->top_canvas, "focus_out_event", - G_CALLBACK (calendar_focus_change_cb), gcal); - - g_signal_connect (dv->main_canvas, "focus_in_event", - G_CALLBACK (calendar_focus_change_cb), gcal); - g_signal_connect (dv->main_canvas, "focus_out_event", - G_CALLBACK (calendar_focus_change_cb), gcal); -} - -/* Connects to the focus change signals of a week view widget */ -static void -connect_week_view_focus (GnomeCalendar *gcal, EWeekView *wv) -{ - g_signal_connect (wv->main_canvas, "focus_in_event", - G_CALLBACK (calendar_focus_change_cb), gcal); - g_signal_connect (wv->main_canvas, "focus_out_event", - G_CALLBACK (calendar_focus_change_cb), gcal); -} - -static void -connect_list_view_focus (GnomeCalendar *gcal, ECalListView *lv) -{ - g_signal_connect (lv, "focus_in_event", - G_CALLBACK (calendar_focus_change_cb), gcal); - g_signal_connect (lv, "focus_out_event", - G_CALLBACK (calendar_focus_change_cb), gcal); -} - -/* Callback used when the selection in the taskpad table changes. We just proxy - * the signal with our own one. - */ -static void -table_selection_change_cb (ETable *etable, gpointer data) -{ - GnomeCalendar *gcal; - 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 -set_timezone (GnomeCalendar *calendar) -{ - GnomeCalendarPrivate *priv; - char *location; - GList *l; - - priv = calendar->priv; - - location = calendar_config_get_timezone (); - priv->zone = icaltimezone_get_builtin_timezone (location); - g_free (location); - - if (!priv->zone) - priv->zone = icaltimezone_get_utc_timezone (); - - for (l = priv->clients_list; l != NULL; l = l->next) { - ECal *client = l->data; - - if (e_cal_get_load_state (client) == E_CAL_LOAD_LOADED) - /* FIXME Error checking */ - e_cal_set_default_timezone (client, priv->zone, NULL); - } - - if (priv->task_pad_client - && e_cal_get_load_state (priv->task_pad_client) == E_CAL_LOAD_LOADED) { - /* FIXME Error Checking */ - e_cal_set_default_timezone (priv->task_pad_client, - priv->zone, NULL); - } -} - -static void -timezone_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - GnomeCalendar *calendar = data; - - set_timezone (calendar); -} - -static void -setup_config (GnomeCalendar *calendar) -{ - GnomeCalendarPrivate *priv; - guint not; - - priv = calendar->priv; - - /* Timezone */ - set_timezone (calendar); - - not = calendar_config_add_notification_timezone (timezone_changed_cb, calendar); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - /* Pane positions */ - priv->hpane_pos = calendar_config_get_hpane_pos (); - priv->vpane_pos = calendar_config_get_vpane_pos (); - priv->hpane_pos_month_view = calendar_config_get_month_hpane_pos (); - priv->vpane_pos_month_view = calendar_config_get_month_vpane_pos (); -} - -static void -setup_widgets (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - GtkWidget *w; - gchar *filename; - ETable *etable; - int i; - - priv = gcal->priv; - - priv->search_bar = cal_search_bar_new (); - g_signal_connect (priv->search_bar, "sexp_changed", - G_CALLBACK (search_bar_sexp_changed_cb), gcal); - g_signal_connect (priv->search_bar, "category_changed", - G_CALLBACK (search_bar_category_changed_cb), gcal); - - gtk_widget_show (priv->search_bar); - gtk_box_pack_start (GTK_BOX (gcal), priv->search_bar, FALSE, FALSE, 6); - - /* The main HPaned, with the notebook of calendar views on the left - and the ECalendar and ToDo list on the right. */ - priv->hpane = gtk_hpaned_new (); - g_signal_connect_after(priv->hpane, "realize", - G_CALLBACK(gnome_calendar_hpane_realized), gcal); - g_signal_connect (priv->hpane, "button_release_event", - G_CALLBACK (gnome_calendar_hpane_resized), gcal); - gtk_widget_show (priv->hpane); - gtk_box_pack_start (GTK_BOX (gcal), priv->hpane, TRUE, TRUE, 6); - - /* 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); - gtk_paned_pack1 (GTK_PANED (priv->hpane), priv->notebook, FALSE, TRUE); - - /* The VPaned widget, to contain the GtkCalendar & ToDo list. */ - priv->vpane = gtk_vpaned_new (); - g_signal_connect_after (priv->vpane, "realize", - G_CALLBACK(gnome_calendar_vpane_realized), gcal); - g_signal_connect (priv->vpane, "button_release_event", - G_CALLBACK (gnome_calendar_vpane_resized), gcal); - gtk_widget_show (priv->vpane); - gtk_paned_pack2 (GTK_PANED (priv->hpane), priv->vpane, TRUE, TRUE); - - /* The ECalendar. */ - w = e_calendar_new (); - priv->date_navigator = E_CALENDAR (w); - priv->date_navigator_config = e_mini_calendar_config_new (priv->date_navigator); - 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); - - gtk_paned_pack1 (GTK_PANED (priv->vpane), w, FALSE, TRUE); - - g_signal_connect (priv->date_navigator->calitem, "selection_changed", - G_CALLBACK (gnome_calendar_on_date_navigator_selection_changed), gcal); - g_signal_connect (priv->date_navigator->calitem, "date_range_changed", - G_CALLBACK (gnome_calendar_on_date_navigator_date_range_changed), gcal); - - /* The ToDo list. */ - priv->todo = e_calendar_table_new (); - priv->todo_config = e_calendar_table_config_new (E_CALENDAR_TABLE (priv->todo)); - gtk_paned_pack2 (GTK_PANED (priv->vpane), priv->todo, TRUE, TRUE); - gtk_widget_show (priv->todo); - - filename = g_build_filename (calendar_component_peek_config_directory (calendar_component_peek ()), - "TaskPad", NULL); - e_calendar_table_load_state (E_CALENDAR_TABLE (priv->todo), filename); - g_free (filename); - - etable = e_calendar_table_get_table (E_CALENDAR_TABLE (priv->todo)); - g_signal_connect (etable->table_canvas, "focus_in_event", - G_CALLBACK (table_canvas_focus_change_cb), gcal); - g_signal_connect (etable->table_canvas, "focus_out_event", - G_CALLBACK (table_canvas_focus_change_cb), gcal); - - g_signal_connect (etable, "selection_change", - G_CALLBACK (table_selection_change_cb), gcal); - - /* The Day View. */ - priv->day_view = e_day_view_new (); - g_signal_connect (priv->day_view, "selection_changed", - G_CALLBACK (view_selection_changed_cb), gcal); - - connect_day_view_focus (gcal, E_DAY_VIEW (priv->day_view)); - - /* The Work Week View. */ - priv->work_week_view = e_day_view_new (); - 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_calendar_view_set_calendar (E_CALENDAR_VIEW (priv->work_week_view), gcal); - - connect_day_view_focus (gcal, E_DAY_VIEW (priv->work_week_view)); - - /* The Week View. */ - priv->week_view = e_week_view_new (); - e_calendar_view_set_calendar (E_CALENDAR_VIEW (priv->week_view), gcal); - g_signal_connect (priv->week_view, "selection_changed", - G_CALLBACK (view_selection_changed_cb), gcal); - - connect_week_view_focus (gcal, E_WEEK_VIEW (priv->week_view)); - - /* The Month View. */ - priv->month_view = e_week_view_new (); - e_calendar_view_set_calendar (E_CALENDAR_VIEW (priv->month_view), gcal); - e_week_view_set_multi_week_view (E_WEEK_VIEW (priv->month_view), TRUE); - g_signal_connect (priv->month_view, "selection_changed", - G_CALLBACK (view_selection_changed_cb), gcal); - - connect_week_view_focus (gcal, E_WEEK_VIEW (priv->month_view)); - - /* The List View. */ - filename = g_strdup_printf (".evolution/config/CalListView"); - priv->list_view = e_cal_list_view_new (filename); - g_free (filename); - - e_calendar_view_set_calendar (E_CALENDAR_VIEW (priv->list_view), gcal); - - connect_list_view_focus (gcal, E_CAL_LIST_VIEW (priv->list_view)); - - priv->views[GNOME_CAL_DAY_VIEW] = E_CALENDAR_VIEW (priv->day_view); - priv->configs[GNOME_CAL_DAY_VIEW] = e_day_view_config_new (E_DAY_VIEW (priv->views[GNOME_CAL_DAY_VIEW])); - priv->views[GNOME_CAL_WORK_WEEK_VIEW] = E_CALENDAR_VIEW (priv->work_week_view); - priv->configs[GNOME_CAL_WORK_WEEK_VIEW] = e_day_view_config_new (E_DAY_VIEW (priv->views[GNOME_CAL_WORK_WEEK_VIEW])); - priv->views[GNOME_CAL_WEEK_VIEW] = E_CALENDAR_VIEW (priv->week_view); - priv->configs[GNOME_CAL_WEEK_VIEW] = e_week_view_config_new (E_WEEK_VIEW (priv->views[GNOME_CAL_WEEK_VIEW])); - priv->views[GNOME_CAL_MONTH_VIEW] = E_CALENDAR_VIEW (priv->month_view); - priv->configs[GNOME_CAL_MONTH_VIEW] = e_week_view_config_new (E_WEEK_VIEW (priv->views[GNOME_CAL_MONTH_VIEW])); - priv->views[GNOME_CAL_LIST_VIEW] = E_CALENDAR_VIEW (priv->list_view); - priv->configs[GNOME_CAL_MONTH_VIEW] = e_cal_list_view_config_new (E_CAL_LIST_VIEW (priv->views[GNOME_CAL_LIST_VIEW])); - priv->configs[GNOME_CAL_LIST_VIEW] = NULL; - - for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) { - gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), - GTK_WIDGET (priv->views[i]), gtk_label_new ("")); - - gtk_widget_show (GTK_WIDGET (priv->views[i])); - } -} - -/* 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->clients = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); - - priv->cal_categories = NULL; - priv->tasks_categories = NULL; - - priv->current_view_type = GNOME_CAL_DAY_VIEW; - priv->range_selected = FALSE; - - setup_config (gcal); - setup_widgets (gcal); - - priv->dn_queries = 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); -} - -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; - - if (priv) { - GList *l; - int i; - - /* disconnect from signals on all the clients */ - for (l = priv->clients_list; l != NULL; l = l->next) { - g_signal_handlers_disconnect_matched (l->data, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, gcal); - } - - g_hash_table_destroy (priv->clients); - g_list_free (priv->clients_list); - - free_categories (priv->cal_categories); - priv->cal_categories = NULL; - - free_categories (priv->tasks_categories); - priv->tasks_categories = NULL; - - for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) { - if (priv->configs[i]) - g_object_unref (priv->configs[i]); - priv->configs[i] = NULL; - } - g_object_unref (priv->date_navigator_config); - g_object_unref (priv->todo_config); - - for (l = priv->notifications; l; l = l->next) - calendar_config_remove_notification (GPOINTER_TO_UINT (l->data)); - g_list_free (priv->notifications); - priv->notifications = NULL; - - /* Save the TaskPad layout. */ - filename = g_build_filename (calendar_component_peek_config_directory (calendar_component_peek ()), - "TaskPad", NULL); - e_calendar_table_save_state (E_CALENDAR_TABLE (priv->todo), filename); - g_free (filename); - - if (priv->dn_queries) { - for (l = priv->dn_queries; l != NULL; l = l->next) { - g_signal_handlers_disconnect_matched ((ECalView *) l->data, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, gcal); - g_object_unref (l->data); - } - - g_list_free (priv->dn_queries); - priv->dn_queries = NULL; - } - - if (priv->sexp) { - g_free (priv->sexp); - priv->sexp = NULL; - } - - if (priv->e_cal_view_timeout) { - g_source_remove (priv->e_cal_view_timeout); - priv->e_cal_view_timeout = 0; - } - - if (priv->task_pad_client) { - g_signal_handlers_disconnect_matched (priv->task_pad_client, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, gcal); - g_object_unref (priv->task_pad_client); - priv->task_pad_client = NULL; - } - - if (priv->view_instance) { - g_object_unref (priv->view_instance); - priv->view_instance = NULL; - } - - if (priv->view_menus) { - g_object_unref (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); -} - -static void -gnome_calendar_goto_date (GnomeCalendar *gcal, - GnomeCalendarGotoDateType goto_date) -{ - GnomeCalendarPrivate *priv; - time_t start_time; - time_t end_time; - gboolean need_updating = FALSE; - - g_return_if_fail (gcal != NULL); - g_return_if_fail (GNOME_IS_CALENDAR(gcal)); - - priv = gcal->priv; - - gnome_calendar_get_current_time_range (gcal, &start_time, &end_time); - - switch (goto_date) { - /* GNOME_CAL_GOTO_TODAY and GNOME_CAL_GOTO_DATE are - currently not used - */ - case GNOME_CAL_GOTO_TODAY: - break; - case GNOME_CAL_GOTO_DATE: - break; - case GNOME_CAL_GOTO_FIRST_DAY_OF_MONTH: - priv->selection_start_time = - time_month_begin_with_zone (start_time, priv->zone); - priv->selection_end_time = - time_add_day_with_zone (priv->selection_start_time, - 1, priv->zone); - need_updating = TRUE; - break; - case GNOME_CAL_GOTO_LAST_DAY_OF_MONTH: - start_time = time_add_month_with_zone (start_time, 1, - priv->zone); - priv->selection_end_time = - time_month_begin_with_zone (start_time, priv->zone); - priv->selection_start_time = - time_add_day_with_zone (priv->selection_end_time, - -1, priv->zone); - need_updating = TRUE; - break; - case GNOME_CAL_GOTO_FIRST_DAY_OF_WEEK: - /* 1 for Monday */ - priv->selection_start_time = - time_week_begin_with_zone (start_time, 1, priv->zone); - priv->selection_end_time = - time_add_day_with_zone (priv->selection_start_time, - 1, priv->zone); - need_updating = TRUE; - break; - case GNOME_CAL_GOTO_LAST_DAY_OF_WEEK: - /* 1 for Monday */ - start_time = time_week_begin_with_zone (start_time, 1, - priv->zone); - if (priv->current_view_type == GNOME_CAL_DAY_VIEW || - priv->current_view_type == GNOME_CAL_WORK_WEEK_VIEW) { - /* goto Friday of this week */ - priv->selection_start_time = - time_add_day_with_zone (start_time, - 4, priv->zone); - } - else { - /* goto Sunday of this week */ - priv->selection_start_time = - time_add_day_with_zone (start_time, - 6, priv->zone); - } - priv->selection_end_time = - time_add_day_with_zone (priv->selection_start_time, - 1, priv->zone); - need_updating = TRUE; - break; - case GNOME_CAL_GOTO_SAME_DAY_OF_PREVIOUS_WEEK: - priv->selection_start_time = time_add_day_with_zone (start_time, - -7, priv->zone); - priv->selection_end_time = time_add_day_with_zone (end_time, - -7,priv->zone); - need_updating = TRUE; - break; - case GNOME_CAL_GOTO_SAME_DAY_OF_NEXT_WEEK: - priv->selection_start_time = time_add_day_with_zone (start_time, - 7, priv->zone); - priv->selection_end_time = time_add_day_with_zone (end_time, - 7,priv->zone); - need_updating = TRUE; - break; - - default: - break; - } - - if (need_updating) { - gnome_calendar_update_view_times (gcal); - gnome_calendar_update_date_navigator (gcal); - gnome_calendar_notify_dates_shown_changed (gcal); - } -} - -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; - - e_calendar_view_set_selected_time_range (E_CALENDAR_VIEW (gnome_calendar_get_current_view_widget (gcal)), - priv->selection_start_time, - priv->selection_end_time); -} - -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: - 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_LIST_VIEW: - g_warning ("Using month view time interval for list view."); - 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; - - gtk_widget_grab_focus (gnome_calendar_get_current_view_widget (gcal)); -} - -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; - const char *view_id; - static gboolean updating = FALSE; - - if (updating) - return; - - priv = gcal->priv; - - round_selection = FALSE; - - switch (view_type) { - case GNOME_CAL_DAY_VIEW: - view_id = "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"; - break; - - case GNOME_CAL_WEEK_VIEW: - view_id = "Week_View"; - round_selection = TRUE; - break; - - case GNOME_CAL_MONTH_VIEW: - view_id = "Month_View"; - - if (!range_selected) - e_week_view_set_weeks_shown (E_WEEK_VIEW (priv->month_view), 5); - - round_selection = TRUE; - break; - - case GNOME_CAL_LIST_VIEW: - view_id = "List_View"; - break; - - default: - g_warning ("A penguin is loose!"); - g_assert_not_reached (); - return; - } - - priv->current_view_type = view_type; - priv->range_selected = range_selected; - - calendar_config_set_default_view (view_type); - - updating = TRUE; - gtk_notebook_set_page (GTK_NOTEBOOK (priv->notebook), (int) view_type); - if (priv->view_instance) - gal_view_instance_set_current_view_id (priv->view_instance, view_id); - updating = FALSE; - - if (grab_focus) - gtk_widget_grab_focus (GTK_WIDGET (priv->views[view_type])); - - 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. */ - g_object_set (G_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 (); - - gal_view_collection_set_title (collection, _("Calendar")); - - path = gnome_util_prepend_user_home ("/evolution/views/calendar/"); - gal_view_collection_set_storage_directories (collection, - EVOLUTION_GALVIEWSDIR "/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)); - g_object_unref (factory); - - factory = calendar_view_factory_new (GNOME_CAL_WORK_WEEK_VIEW); - gal_view_collection_add_factory (collection, GAL_VIEW_FACTORY (factory)); - g_object_unref (factory); - - factory = calendar_view_factory_new (GNOME_CAL_WEEK_VIEW); - gal_view_collection_add_factory (collection, GAL_VIEW_FACTORY (factory)); - g_object_unref (factory); - - factory = calendar_view_factory_new (GNOME_CAL_MONTH_VIEW); - gal_view_collection_add_factory (collection, GAL_VIEW_FACTORY (factory)); - g_object_unref (factory); - - factory = calendar_view_factory_new (GNOME_CAL_LIST_VIEW); - gal_view_collection_add_factory (collection, GAL_VIEW_FACTORY (factory)); - g_object_unref (factory); - - /* Load the collection and create the menus */ - - gal_view_collection_load (collection); - } - - priv->view_instance = gal_view_instance_new (collection, - e_cal_get_uri (gnome_calendar_get_default_client (gcal))); - - priv->view_menus = gal_view_menus_new (priv->view_instance); - gal_view_menus_set_show_define_views (priv->view_menus, FALSE); - gal_view_menus_apply (priv->view_menus, uic, NULL); - gnome_calendar_set_view (gcal, priv->current_view_type, TRUE, FALSE); - - g_signal_connect (priv->view_instance, "display_view", - G_CALLBACK (display_view_cb), gcal); - display_view_cb (priv->view_instance, gal_view_instance_get_current_view (priv->view_instance), gcal); -} - -/** - * gnome_calendar_discard_view_menus: - * @gcal: A calendar. - * - * Discards the #GalView menus used by a calendar. This function should be - * called from the Bonobo control deactivation callback for this calendar. The - * menus should have been set up with gnome_calendar_setup_view_menus(). - **/ -void -gnome_calendar_discard_view_menus (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - - g_return_if_fail (gcal != NULL); - - priv = gcal->priv; - - g_return_if_fail (priv->view_instance != NULL); - - g_assert (priv->view_instance != NULL); - g_assert (priv->view_menus != NULL); - - g_object_unref (priv->view_instance); - priv->view_instance = NULL; - - g_object_unref (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; - - priv = gcal->priv; - - if (priv->current_view_type == GNOME_CAL_MONTH_VIEW && !priv->range_selected) { - gtk_paned_set_position (GTK_PANED (priv->hpane), priv->hpane_pos_month_view); - gtk_paned_set_position (GTK_PANED (priv->vpane), priv->vpane_pos_month_view); - } else { - gtk_paned_set_position (GTK_PANED (priv->hpane), priv->hpane_pos); - gtk_paned_set_position (GTK_PANED (priv->vpane), priv->vpane_pos); - } -} - -/* Displays an error to indicate that opening a calendar failed */ -static void -open_error (GnomeCalendar *gcal, const char *uri) -{ - char *msg; - char *urinopwd; - - urinopwd = get_uri_without_password (uri); - msg = g_strdup_printf (_("Could not open the folder in `%s'"), urinopwd); - gnome_error_dialog_parented (msg, GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (gcal)))); - g_free (msg); - g_free (urinopwd); -} - -/* Displays an error to indicate that the specified URI method is not supported */ -static void -method_error (GnomeCalendar *gcal, const char *uri) -{ - char *msg; - char *urinopwd; - - urinopwd = get_uri_without_password (uri); - msg = g_strdup_printf (_("The method required to open `%s' is not supported"), urinopwd); - gnome_error_dialog_parented (msg, GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (gcal)))); - g_free (msg); - g_free (urinopwd); -} - -/* Displays an error to indicate permission problems */ -static void -permission_error (GnomeCalendar *gcal, const char *uri) -{ - char *msg; - char *urinopwd; - - urinopwd = get_uri_without_password (uri); - msg = g_strdup_printf (_("You don't have permission to open the folder in `%s'"), urinopwd); - gnome_error_dialog_parented (msg, GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (gcal)))); - g_free (msg); - g_free (urinopwd); -} - -/* Callback from the calendar client when a calendar is loaded */ -static gboolean -update_e_cal_view_timeout (gpointer data) -{ - GnomeCalendar *gcal = data; - GnomeCalendarPrivate *priv; - - gcal = GNOME_CALENDAR (data); - priv = gcal->priv; - - update_query (gcal); - priv->e_cal_view_timeout = 0; - - return FALSE; -} - -static void -client_cal_opened_cb (ECal *client, ECalendarStatus status, gpointer data) -{ - GnomeCalendar *gcal; - GnomeCalendarPrivate *priv; - char *msg; - char *uristr; - - gcal = GNOME_CALENDAR (data); - priv = gcal->priv; - - switch (status) { - case E_CALENDAR_STATUS_OK: - /* Set the client's default timezone, if we have one. */ - if (priv->zone) { - /* FIXME Error checking */ - e_cal_set_default_timezone (client, priv->zone, NULL); - } - - /* add the alarms for this client */ - uristr = get_uri_without_password (e_cal_get_uri (client)); - msg = g_strdup_printf (_("Adding alarms for %s"), uristr); - g_free (uristr); - if (client == priv->task_pad_client) { - e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo), msg); - e_cal_model_add_client (e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo)), - priv->task_pad_client); - } - else { - e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), msg); - e_cal_model_add_client (e_calendar_view_get_model (E_CALENDAR_VIEW (priv->week_view)), client); - - priv->e_cal_view_timeout = g_timeout_add (100, update_e_cal_view_timeout, gcal); - } - g_free (msg); - - break; - - case E_CALENDAR_STATUS_OTHER_ERROR: - open_error (gcal, e_cal_get_uri (client)); - break; - - case E_CALENDAR_STATUS_NO_SUCH_CALENDAR: - /* bullshit; we did not specify only_if_exists */ - g_assert_not_reached (); - return; - - case E_CALENDAR_STATUS_PROTOCOL_NOT_SUPPORTED: - method_error (gcal, e_cal_get_uri (client)); - break; - - case E_CALENDAR_STATUS_PERMISSION_DENIED : - permission_error (gcal, e_cal_get_uri (client)); - break; - - default: - g_assert_not_reached (); - return; - } - - if (client == priv->task_pad_client) - e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo), NULL); - else - e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL); -} - -/* 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 (ECal *client, GPtrArray *categories, gpointer data) -{ - GnomeCalendar *gcal; - GnomeCalendarPrivate *priv; - GPtrArray *merged; - - gcal = GNOME_CALENDAR (data); - priv = gcal->priv; - - if (client == priv->task_pad_client) { - free_categories (priv->tasks_categories); - priv->tasks_categories = copy_categories (categories); - } else { - free_categories (priv->cal_categories); - priv->cal_categories = copy_categories (categories); - } - - merged = merge_categories (priv->cal_categories, priv->tasks_categories); - cal_search_bar_set_categories (CAL_SEARCH_BAR (priv->search_bar), merged); - free_categories (merged); -} - -/* Callback when we get an error message from the backend */ -static void -backend_error_cb (ECal *client, const char *message, gpointer data) -{ - GnomeCalendar *gcal; - GnomeCalendarPrivate *priv; - char *errmsg; - char *uristr; - - gcal = GNOME_CALENDAR (data); - priv = gcal->priv; - - uristr = get_uri_without_password (e_cal_get_uri (client)); - errmsg = g_strdup_printf (_("Error on %s:\n %s"), uristr, message); - gnome_error_dialog_parented (errmsg, GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (gcal)))); - g_free (errmsg); - g_free (uristr); -} - -/* Callback when the backend dies */ -static void -backend_died_cb (ECal *client, gpointer data) -{ - GnomeCalendar *gcal; - GnomeCalendarPrivate *priv; - char *message; - char *uristr; - - gcal = GNOME_CALENDAR (data); - priv = gcal->priv; - - /* FIXME This doesn't remove the calendar from the list or anything */ - uristr = get_uri_without_password (e_cal_get_uri (client)); - if (client == priv->task_pad_client) { - message = g_strdup_printf (_("The task backend for\n%s\n has crashed. " - "You will have to restart Evolution in order " - "to use it again"), - uristr); - e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo), NULL); - } else { - int i; - - message = g_strdup_printf (_("The calendar backend for\n%s\n has crashed. " - "You will have to restart Evolution in order " - "to use it again"), - uristr); - - for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) - e_calendar_view_set_status_message (priv->views[i], NULL); - } - - gnome_error_dialog_parented (message, GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (gcal)))); - g_free (message); - g_free (uristr); -} - -GtkWidget * -gnome_calendar_construct (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - GnomeCalendarViewType view_type; - - g_return_val_if_fail (gcal != NULL, NULL); - g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL); - - priv = gcal->priv; - - /* - * TaskPad Folder Client. - */ - priv->task_pad_client = e_cal_new_from_uri ("", CALOBJ_TYPE_TODO); /* FIXME: use default tasks */ - if (!priv->task_pad_client) - return NULL; - - g_signal_connect (priv->task_pad_client, "cal_opened", - G_CALLBACK (client_cal_opened_cb), gcal); - g_signal_connect (priv->task_pad_client, "backend_error", - G_CALLBACK (backend_error_cb), gcal); - g_signal_connect (priv->task_pad_client, "categories_changed", - G_CALLBACK (client_categories_changed_cb), gcal); - g_signal_connect (priv->task_pad_client, "backend_died", - G_CALLBACK (backend_died_cb), gcal); - - /* Get the default view to show. */ - view_type = calendar_config_get_default_view (); - if (view_type < GNOME_CAL_DAY_VIEW || view_type > GNOME_CAL_LIST_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 = g_object_new (gnome_calendar_get_type (), NULL); - - if (!gnome_calendar_construct (gcal)) { - g_message ("gnome_calendar_new(): Could not construct the calendar GUI"); - g_object_unref (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_calendar_model: - * @gcal: A calendar view. - * - * Queries the calendar model object that a calendar view is using. - * - * Return value: A calendar client interface object. - **/ -ECalModel * -gnome_calendar_get_calendar_model (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 e_calendar_view_get_model (priv->views[priv->current_view_type]); -} - -/** - * gnome_calendar_get_default_client - */ -ECal * -gnome_calendar_get_default_client (GnomeCalendar *gcal) -{ - g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL); - - return e_cal_model_get_default_client (e_calendar_view_get_model (E_CALENDAR_VIEW (gcal->priv->week_view))); -} - -/** - * gnome_calendar_get_task_pad_e_cal: - * @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. - **/ -ECal * -gnome_calendar_get_task_pad_e_cal (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; -} - -/** - * gnome_calendar_add_event_uri: - * @gcal: A GnomeCalendar. - * @str_uri: URI to add to the calendar views. - * - * Adds the given calendar URI to the calendar views. - * - * Returns: TRUE if successful, FALSE if error. - */ -gboolean -gnome_calendar_add_event_uri (GnomeCalendar *gcal, const char *str_uri) -{ - GnomeCalendarPrivate *priv; - ECal *client; - int i; - - g_return_val_if_fail (gcal != NULL, FALSE); - g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), FALSE); - g_return_val_if_fail (str_uri != NULL, FALSE); - - priv = gcal->priv; - - client = g_hash_table_lookup (priv->clients, str_uri); - if (client) - return TRUE; - - client = e_cal_new_from_uri (str_uri, CALOBJ_TYPE_EVENT); - g_hash_table_insert (priv->clients, g_strdup (str_uri), client); - priv->clients_list = g_list_prepend (priv->clients_list, client); - - g_signal_connect (G_OBJECT (client), "backend_error", G_CALLBACK (backend_error_cb), gcal); - g_signal_connect (G_OBJECT (client), "categories_changed", G_CALLBACK (client_categories_changed_cb), gcal); - g_signal_connect (G_OBJECT (client), "backend_died", G_CALLBACK (backend_died_cb), gcal); - - /* FIXME Do this async? */ - if (!e_cal_open (client, FALSE, NULL)) { - g_hash_table_remove (priv->clients, str_uri); - priv->clients_list = g_list_prepend (priv->clients_list, client); - g_signal_handlers_disconnect_matched (client, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, gcal); - - return FALSE; - } - - for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) { - ECalModel *model; - - model = e_calendar_view_get_model (priv->views[i]); - e_cal_model_add_client (model, client); - } - - /* update date navigator query */ - update_query (gcal); - - return TRUE; -} - -/** - * gnome_calendar_remove_event_uri - * @gcal: A #GnomeCalendar. - * @str_uri: URI to be removed from the clients. - * - * Removes the given URI from the list of clients being shown by the - * calendar views. - * - * Returns: TRUE if successful, FALSE otherwise. - */ -gboolean -gnome_calendar_remove_event_uri (GnomeCalendar *gcal, const char *str_uri) -{ - GnomeCalendarPrivate *priv; - ECal *client; - int i; - - g_return_val_if_fail (gcal != NULL, FALSE); - g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), FALSE); - g_return_val_if_fail (str_uri != NULL, FALSE); - - priv = gcal->priv; - - client = g_hash_table_lookup (priv->clients, str_uri); - if (!client) - return TRUE; - - g_hash_table_remove (priv->clients, str_uri); - priv->clients_list = g_list_remove (priv->clients_list, client); - g_signal_handlers_disconnect_matched (client, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, gcal); - - for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) { - ECalModel *model; - - model = e_calendar_view_get_model (priv->views[i]); - e_cal_model_remove_client (model, client); - } - - /* update date navigator query */ - update_query (gcal); - - return TRUE; -} - -/** - * gnome_calendar_set_default_uri: - * @gcal: A calendar view - * @uri: The uri to use as default - * - * Set the default uri on the given calendar view, the default uri - * will be used as the default when creating events in the view. - - * - * Return value: TRUE if the uri was already added and is set, FALSE - * otherwise - **/ -gboolean -gnome_calendar_set_default_uri (GnomeCalendar *gcal, const char *str_uri) -{ - GnomeCalendarPrivate *priv; - ECal *client; - int i; - - g_return_val_if_fail (gcal != NULL, FALSE); - g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), FALSE); - g_return_val_if_fail (str_uri != NULL, FALSE); - - priv = gcal->priv; - - client = g_hash_table_lookup (priv->clients, str_uri); - if (!client) - return FALSE; - - for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) { - e_cal_model_set_default_client ( - e_calendar_view_get_model (E_CALENDAR_VIEW (priv->views[i])), - client); - } - - return TRUE; -} - -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; -} - -/** - * 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; - ECalComponent *comp; - icalcomponent *icalcomp; - const char *category; - - g_return_if_fail (gcal != NULL); - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - - priv = gcal->priv; - - tedit = task_editor_new (priv->task_pad_client); - - icalcomp = e_cal_model_create_component_with_defaults (e_calendar_view_get_model (E_CALENDAR_VIEW (priv->week_view))); - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomp); - - category = cal_search_bar_get_category (CAL_SEARCH_BAR (priv->search_bar)); - e_cal_component_set_categories (comp, category); - - comp_editor_edit_comp (COMP_EDITOR (tedit), comp); - g_object_unref (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; - - e_calendar_view_get_selected_time_range (E_CALENDAR_VIEW (gnome_calendar_get_current_view_widget (gcal)), - start_time, 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) -{ - GnomeCalendarPrivate *priv; - gboolean retval = FALSE; - - g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), FALSE); - - priv = gcal->priv; - - retval = e_calendar_view_get_visible_time_range (E_CALENDAR_VIEW (gnome_calendar_get_current_view_widget (gcal)), - start_time, end_time); - - 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; - - case GNOME_CAL_LIST_VIEW: - if (!e_cal_list_view_get_range_shown (E_CAL_LIST_VIEW (priv->list_view), - start_date, days_shown)) { - /* No valid items in list */ - time_to_gdate_with_zone (start_date, time (NULL), priv->zone); - *days_shown = 1; - } - else if (*days_shown < 1) { - *days_shown = 1; - } - 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; - struct icaltimetype tt; - - 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; - - /* Update selection to be in the new time range */ - tt = icaltime_null_time (); - tt.year = g_date_year (&new_start_date); - tt.month = g_date_month (&new_start_date); - tt.day = g_date_day (&new_start_date); - priv->selection_start_time = icaltime_as_timet_with_zone (tt, priv->zone); - icaltime_adjust (&tt, 1, 0, 0, 0); - priv->selection_end_time = icaltime_as_timet_with_zone (tt, priv->zone); - - /* 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 { - e_day_view_set_days_shown (E_DAY_VIEW (priv->day_view), new_days_shown); - - if (new_days_shown == 5 && priv->current_view_type == GNOME_CAL_WORK_WEEK_VIEW) - gnome_calendar_set_view (gcal, GNOME_CAL_WORK_WEEK_VIEW, TRUE, FALSE); - else - 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_hpane_realized (GtkWidget *w, GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - - priv = gcal->priv; - - if (priv->current_view_type == GNOME_CAL_MONTH_VIEW && !priv->range_selected) { - gtk_paned_set_position (GTK_PANED (priv->hpane), priv->hpane_pos_month_view); - } else { - gtk_paned_set_position (GTK_PANED (priv->hpane), priv->hpane_pos); - } -} - -static void -gnome_calendar_vpane_realized (GtkWidget *w, GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - - priv = gcal->priv; - - if (priv->current_view_type == GNOME_CAL_MONTH_VIEW && !priv->range_selected) { - gtk_paned_set_position (GTK_PANED (priv->vpane), priv->vpane_pos_month_view); - } else { - gtk_paned_set_position (GTK_PANED (priv->vpane), priv->vpane_pos); - } -} - -static gboolean -gnome_calendar_vpane_resized (GtkWidget *w, GdkEventButton *e, GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - - priv = gcal->priv; - - if (priv->current_view_type == GNOME_CAL_MONTH_VIEW && !priv->range_selected) { - priv->vpane_pos_month_view = gtk_paned_get_position (GTK_PANED (priv->vpane)); - calendar_config_set_month_vpane_pos (priv->vpane_pos_month_view); - } else { - priv->vpane_pos = gtk_paned_get_position (GTK_PANED (priv->vpane)); - calendar_config_set_vpane_pos (priv->vpane_pos); - } - - return FALSE; -} - -static gboolean -gnome_calendar_hpane_resized (GtkWidget *w, GdkEventButton *e, GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - gint times_width; - - priv = gcal->priv; - - if (priv->current_view_type == GNOME_CAL_MONTH_VIEW && !priv->range_selected) { - priv->hpane_pos_month_view = gtk_paned_get_position (GTK_PANED (priv->hpane)); - calendar_config_set_month_hpane_pos (priv->hpane_pos_month_view); - } else { - priv->hpane_pos = gtk_paned_get_position (GTK_PANED (priv->hpane)); - calendar_config_set_hpane_pos (priv->hpane_pos); - } - - /* adjust the size of the EDayView's time column */ - times_width = e_day_view_time_item_get_column_width ( - E_DAY_VIEW_TIME_ITEM (E_DAY_VIEW (priv->day_view)->time_canvas_item)); - if (times_width < priv->hpane_pos - 20) - gtk_widget_set_usize (E_DAY_VIEW (priv->day_view)->time_canvas, times_width, -1); - else - gtk_widget_set_usize (E_DAY_VIEW (priv->day_view)->time_canvas, priv->hpane_pos - 20, -1); - - - return FALSE; -} - -void -gnome_calendar_cut_clipboard (GnomeCalendar *gcal) -{ - GnomeCalendarPrivate *priv; - FocusLocation location; - - priv = gcal->priv; - - location = get_focus_location (gcal); - - if (location == FOCUS_CALENDAR) { - e_calendar_view_cut_clipboard (E_CALENDAR_VIEW (gnome_calendar_get_current_view_widget (gcal))); - } else if (location == FOCUS_TASKPAD) - e_calendar_table_cut_clipboard (E_CALENDAR_TABLE (priv->todo)); - else - 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) { - e_calendar_view_copy_clipboard (E_CALENDAR_VIEW (gnome_calendar_get_current_view_widget (gcal))); - } else if (location == FOCUS_TASKPAD) - e_calendar_table_copy_clipboard (E_CALENDAR_TABLE (priv->todo)); - else - 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) { - e_calendar_view_paste_clipboard (E_CALENDAR_VIEW (gnome_calendar_get_current_view_widget (gcal))); - } else if (location == FOCUS_TASKPAD) - e_calendar_table_paste_clipboard (E_CALENDAR_TABLE (priv->todo)); - else - 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); - - e_calendar_view_delete_selected_events (E_CALENDAR_VIEW (view)); - } else if (location == FOCUS_TASKPAD) - e_calendar_table_delete_selected (E_CALENDAR_TABLE (priv->todo)); - else - g_assert_not_reached (); -} - -void -gnome_calendar_delete_selected_occurrence (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); - e_calendar_view_delete_selected_occurrence (E_CALENDAR_VIEW (view)); - } -} - -static gboolean -check_instance_cb (ECalComponent *comp, - time_t instance_start, - time_t instance_end, - gpointer data) -{ - gboolean *remove = data; - - *remove = FALSE; - - return FALSE; -} - -void -gnome_calendar_purge (GnomeCalendar *gcal, time_t older_than) -{ - GnomeCalendarPrivate *priv; - char *sexp, *start, *end; - GList *l; - - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - - priv = gcal->priv; - - start = isodate_from_time_t (0); - end = isodate_from_time_t (older_than); - sexp = g_strdup_printf ("(occur-in-time-range? (make-time \"%s\")" - " (make-time \"%s\"))", - start, end); - - e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), _("Purging")); - - /* FIXME Confirm expunge */ - for (l = priv->clients_list; l != NULL; l = l->next) { - ECal *client = l->data; - GList *objects, *m; - gboolean read_only = TRUE; - - e_cal_is_read_only (client, &read_only, NULL); - if (!read_only) - continue; - - if (!e_cal_get_object_list (client, sexp, &objects, NULL)) { - g_warning (G_STRLOC ": Could not get the objects"); - - continue; - } - - for (m = objects; m; m = m->next) { - ECalComponent *comp; - gboolean remove = TRUE; - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (m->data)); - - e_cal_recur_generate_instances (comp, older_than, -1, - (ECalRecurInstanceFn) check_instance_cb, - &remove, - (ECalRecurResolveTimezoneFn) e_cal_resolve_tzid_cb, - client, priv->zone); - - /* FIXME Better error handling */ - if (remove) - e_cal_remove_object (client, icalcomponent_get_uid (m->data), NULL); - - g_object_unref (comp); - } - } - - e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL); - - g_free (sexp); - g_free (start); - g_free (end); - -} - -ECalendarTable* -gnome_calendar_get_task_pad (GnomeCalendar *gcal) -{ - g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL); - - return E_CALENDAR_TABLE (gcal->priv->todo); -} - -GtkWidget * -gnome_calendar_get_e_calendar_widget (GnomeCalendar *gcal) -{ - g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL); - - return GTK_WIDGET(gcal->priv->date_navigator); -} - -GtkWidget * -gnome_calendar_get_search_bar_widget (GnomeCalendar *gcal) -{ - g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL); - - return GTK_WIDGET(gcal->priv->search_bar); -} - -GtkWidget * -gnome_calendar_get_view_notebook_widget (GnomeCalendar *gcal) -{ - g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL); - - return GTK_WIDGET(gcal->priv->notebook); -} diff --git a/calendar/gui/gnome-cal.h b/calendar/gui/gnome-cal.h deleted file mode 100644 index 896faaa13b..0000000000 --- a/calendar/gui/gnome-cal.h +++ /dev/null @@ -1,189 +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 <gtk/gtkvbox.h> -#include <bonobo/bonobo-ui-component.h> -#include <gal/widgets/e-popup-menu.h> -#include <widgets/misc/e-calendar.h> -#include <libecal/e-cal.h> - -#include "e-calendar-table.h" - -G_BEGIN_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, - GNOME_CAL_LIST_VIEW, - GNOME_CAL_LAST_VIEW -} GnomeCalendarViewType; - -typedef enum { - GNOME_CAL_GOTO_TODAY, - GNOME_CAL_GOTO_DATE, - GNOME_CAL_GOTO_FIRST_DAY_OF_MONTH, - GNOME_CAL_GOTO_LAST_DAY_OF_MONTH, - GNOME_CAL_GOTO_FIRST_DAY_OF_WEEK, - GNOME_CAL_GOTO_LAST_DAY_OF_WEEK, - GNOME_CAL_GOTO_SAME_DAY_OF_PREVIOUS_WEEK, - GNOME_CAL_GOTO_SAME_DAY_OF_NEXT_WEEK -} GnomeCalendarGotoDateType; - -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); - void (* goto_date) (GnomeCalendar *gcal, - GnomeCalendarGotoDateType date); - -}; - - -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); - -ECalModel *gnome_calendar_get_calendar_model (GnomeCalendar *gcal); -ECal *gnome_calendar_get_default_client (GnomeCalendar *gcal); -ECal *gnome_calendar_get_task_pad_e_cal(GnomeCalendar *gcal); - -gboolean gnome_calendar_add_event_uri (GnomeCalendar *gcal, const char *str_uri); -gboolean gnome_calendar_remove_event_uri (GnomeCalendar *gcal, const char *str_uri); -gboolean gnome_calendar_set_default_uri (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); - -GtkWidget *gnome_calendar_get_current_view_widget (GnomeCalendar *gcal); - -ECalendarTable *gnome_calendar_get_task_pad (GnomeCalendar *gcal); -GtkWidget *gnome_calendar_get_e_calendar_widget (GnomeCalendar *gcal); -GtkWidget *gnome_calendar_get_search_bar_widget (GnomeCalendar *gcal); -GtkWidget *gnome_calendar_get_view_notebook_widget (GnomeCalendar *gcal); - -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_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); - -/* 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); -void gnome_calendar_delete_selected_occurrence (GnomeCalendar *gcal); -void gnome_calendar_purge (GnomeCalendar *gcal, - time_t older_than); - - - -G_END_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 b268e03294..0000000000 --- a/calendar/gui/goto-dialog.glade +++ /dev/null @@ -1,225 +0,0 @@ -<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> -<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> - -<glade-interface> - -<widget class="GtkDialog" id="goto-dialog"> - <property name="title" translatable="yes">Go To Date</property> - <property name="type">GTK_WINDOW_TOPLEVEL</property> - <property name="window_position">GTK_WIN_POS_NONE</property> - <property name="modal">False</property> - <property name="resizable">True</property> - <property name="destroy_with_parent">False</property> - <property name="has_separator">True</property> - - <child internal-child="vbox"> - <widget class="GtkVBox" id="dialog-vbox1"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">8</property> - - <child internal-child="action_area"> - <widget class="GtkHButtonBox" id="dialog-action_area1"> - <property name="visible">True</property> - <property name="layout_style">GTK_BUTTONBOX_END</property> - - <child> - <widget class="GtkButton" id="button4"> - <property name="visible">True</property> - <property name="can_default">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">Go To Today</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="response_id">0</property> - </widget> - </child> - - <child> - <widget class="GtkButton" id="button5"> - <property name="visible">True</property> - <property name="can_default">True</property> - <property name="can_focus">True</property> - <property name="label">gtk-cancel</property> - <property name="use_stock">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="response_id">-6</property> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="pack_type">GTK_PACK_END</property> - </packing> - </child> - - <child> - <widget class="GtkVBox" id="vbox"> - <property name="visible">True</property> - <property name="homogeneous">False</property> - <property name="spacing">4</property> - - <child> - <widget class="GtkHBox" id="hbox12"> - <property name="visible">True</property> - <property name="homogeneous">True</property> - <property name="spacing">4</property> - - <child> - <widget class="GtkOptionMenu" id="month"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="history">0</property> - - <child internal-child="menu"> - <widget class="GtkMenu" id="convertwidget1"> - <property name="visible">True</property> - - <child> - <widget class="GtkMenuItem" id="convertwidget2"> - <property name="visible">True</property> - <property name="label" translatable="yes">January</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget3"> - <property name="visible">True</property> - <property name="label" translatable="yes">February</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget4"> - <property name="visible">True</property> - <property name="label" translatable="yes">March</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget5"> - <property name="visible">True</property> - <property name="label" translatable="yes">April</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget6"> - <property name="visible">True</property> - <property name="label" translatable="yes">May</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget7"> - <property name="visible">True</property> - <property name="label" translatable="yes">June</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget8"> - <property name="visible">True</property> - <property name="label" translatable="yes">July</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget9"> - <property name="visible">True</property> - <property name="label" translatable="yes">August</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget10"> - <property name="visible">True</property> - <property name="label" translatable="yes">September</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget11"> - <property name="visible">True</property> - <property name="label" translatable="yes">October</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget12"> - <property name="visible">True</property> - <property name="label" translatable="yes">November</property> - <property name="use_underline">True</property> - </widget> - </child> - - <child> - <widget class="GtkMenuItem" id="convertwidget13"> - <property name="visible">True</property> - <property name="label" translatable="yes">December</property> - <property name="use_underline">True</property> - </widget> - </child> - </widget> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">False</property> - <property name="fill">False</property> - </packing> - </child> - - <child> - <widget class="GtkSpinButton" id="year"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="climb_rate">1</property> - <property name="digits">0</property> - <property name="numeric">True</property> - <property name="update_policy">GTK_UPDATE_IF_VALID</property> - <property name="snap_to_ticks">False</property> - <property name="wrap">False</property> - <property name="adjustment">1969 1969 2038 1 5 10</property> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - - <child> - <placeholder/> - </child> - </widget> - <packing> - <property name="padding">0</property> - <property name="expand">True</property> - <property name="fill">True</property> - </packing> - </child> - </widget> - </child> -</widget> - -</glade-interface> diff --git a/calendar/gui/goto.c b/calendar/gui/goto.c deleted file mode 100644 index 66c6ecbad4..0000000000 --- a/calendar/gui/goto.c +++ /dev/null @@ -1,266 +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 <gtk/gtkdialog.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; - ECal *client; - - client = gnome_calendar_get_default_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); - - gtk_dialog_response (GTK_DIALOG (dlg->dialog), GTK_RESPONSE_NONE); - /* 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; - - gnome_canvas_item_set (GNOME_CANVAS_ITEM (calitem), - "move_selection_when_moving", FALSE, - NULL); - 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) - g_signal_connect (menu, "selection_done", G_CALLBACK (month_changed), dlg); - - adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (dlg->year)); - g_signal_connect (adj, "value_changed", G_CALLBACK (year_changed), dlg); - - g_signal_connect (dlg->ecal->calitem, "date_range_changed", G_CALLBACK (ecal_date_range_changed), dlg); - g_signal_connect (dlg->ecal->calitem, "selection_changed", G_CALLBACK (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, 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); - - gtk_window_set_transient_for (GTK_WINDOW (dlg->dialog), - GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (gcal)))); - - /* set initial selection to current day */ - - dlg->ecal->calitem->selection_set = TRUE; - dlg->ecal->calitem->selection_start_month_offset = 0; - dlg->ecal->calitem->selection_start_day = tt.day; - dlg->ecal->calitem->selection_end_month_offset = 0; - dlg->ecal->calitem->selection_end_day = tt.day; - - gnome_canvas_item_grab_focus (GNOME_CANVAS_ITEM (dlg->ecal->calitem)); - - b = gtk_dialog_run (GTK_DIALOG (dlg->dialog)); - gtk_widget_destroy (dlg->dialog); - - if (b == 0) - goto_today (dlg); - - g_object_unref (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 391bc1f73d..0000000000 --- a/calendar/gui/itip-bonobo-control.c +++ /dev/null @@ -1,265 +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 <string.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 <libical/ical.h> - -#include "e-itip-control.h" -#include "itip-bonobo-control.h" - -extern gchar *evolution_dir; - -enum E_ITIP_BONOBO_ARGS { - FROM_ADDRESS_ARG_ID, - VIEW_ONLY_ARG_ID -}; - -/* - * Bonobo::PersistStream - * - * These two functions implement the Bonobo::PersistStream load and - * save methods which allow data to be loaded into and out of the - * BonoboObject. - */ - -static char * -stream_read (Bonobo_Stream stream) -{ - Bonobo_Stream_iobuf *buffer; - CORBA_Environment ev; - gchar *data = NULL; - gint length = 0; - - CORBA_exception_init (&ev); - do { -#define READ_CHUNK_SIZE 65536 - Bonobo_Stream_read (stream, READ_CHUNK_SIZE, - &buffer, &ev); - - if (BONOBO_EX (&ev)) { - CORBA_exception_free (&ev); - return NULL; - } - - if (buffer->_length <= 0) - break; - - data = g_realloc (data, length + buffer->_length + 1); - memcpy (data + length, buffer->_buffer, buffer->_length); - length += buffer->_length; - data[length] = '\0'; - - CORBA_free (buffer); -#undef READ_CHUNK_SIZE - } while (1); - - CORBA_free (buffer); - CORBA_exception_free (&ev); - - if (data == NULL) - data = g_strdup(""); - - return data; -} /* stream_read */ - -/* - * This function implements the Bonobo::PersistStream:load method. - */ -typedef struct { - EItipControl *itip; - char *text; -} idle_data; - -static gboolean -set_data_idle_cb (gpointer data) -{ - idle_data *id = data; - - e_itip_control_set_data (id->itip, id->text); - g_object_unref (id->itip); - g_free (id->text); - g_free (id); - - return FALSE; -} - -static void -pstream_load (BonoboPersistStream *ps, const Bonobo_Stream stream, - Bonobo_Persist_ContentType type, void *data, - CORBA_Environment *ev) -{ - EItipControl *itip = data; - idle_data *id; - - if (type && g_strcasecmp (type, "text/calendar") != 0 && - g_strcasecmp (type, "text/x-calendar") != 0) { - bonobo_exception_set (ev, ex_Bonobo_Persist_WrongDataType); - return; - } - - id = g_new0 (idle_data, 1); - if ((id->text = stream_read (stream)) == NULL) { - bonobo_exception_set (ev, ex_Bonobo_Persist_FileNotFound); - g_free (id); - return; - } - g_object_ref (itip); - id->itip = itip; - - g_idle_add (set_data_idle_cb, id); -} -/* - * This function implements the Bonobo::PersistStream:save method. - */ -static void -pstream_save (BonoboPersistStream *ps, const Bonobo_Stream stream, - Bonobo_Persist_ContentType type, void *data, - CORBA_Environment *ev) -{ - EItipControl *itip = data; - gchar *text; - gint len; - - if (type && g_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; - case VIEW_ONLY_ARG_ID: - BONOBO_ARG_SET_INT (arg, e_itip_control_get_view_only (itip)); - break; - } -} - -static void -set_prop ( BonoboPropertyBag *bag, - const BonoboArg *arg, - guint arg_id, - CORBA_Environment *ev, - gpointer user_data) -{ - EItipControl *itip = user_data; - - switch (arg_id) { - case FROM_ADDRESS_ARG_ID: - e_itip_control_set_from_address (itip, BONOBO_ARG_GET_STRING (arg)); - break; - case VIEW_ONLY_ARG_ID: - e_itip_control_set_view_only (itip, BONOBO_ARG_GET_INT (arg)); - break; - } -} - - -BonoboControl * -itip_bonobo_control_new (void) -{ - BonoboControl *control; - BonoboPropertyBag *prop_bag; - BonoboPersistStream *stream; - GtkWidget *itip; - - itip = e_itip_control_new (); - gtk_widget_show (itip); - control = bonobo_control_new (itip); - - /* create a property bag */ - prop_bag = bonobo_property_bag_new (get_prop, set_prop, itip); - bonobo_property_bag_add (prop_bag, "from_address", FROM_ADDRESS_ARG_ID, BONOBO_ARG_STRING, NULL, - "from_address", 0 ); - bonobo_property_bag_add (prop_bag, "view_only", VIEW_ONLY_ARG_ID, BONOBO_ARG_INT, NULL, - "view_only", 0 ); - - bonobo_control_set_properties (control, bonobo_object_corba_objref (BONOBO_OBJECT (prop_bag)), NULL); - bonobo_object_unref (BONOBO_OBJECT (prop_bag)); - - bonobo_control_set_automerge (control, TRUE); - - stream = bonobo_persist_stream_new (pstream_load, pstream_save, - pstream_get_content_types, - "OAFIID:GNOME_Evolution_Calendar_iTip_Control:" BASE_VERSION, - itip); - - if (stream == NULL) { - bonobo_object_unref (BONOBO_OBJECT (control)); - return NULL; - } - - bonobo_object_add_interface (BONOBO_OBJECT (control), - BONOBO_OBJECT (stream)); - - return control; -} diff --git a/calendar/gui/itip-bonobo-control.h b/calendar/gui/itip-bonobo-control.h deleted file mode 100644 index 11b33e6602..0000000000 --- a/calendar/gui/itip-bonobo-control.h +++ /dev/null @@ -1,31 +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__ - -#include <bonobo/bonobo-control.h> - -BonoboControl *itip_bonobo_control_new (void); - -#endif /* __ITIP_CONTROL_H__ */ diff --git a/calendar/gui/itip-utils.c b/calendar/gui/itip-utils.c deleted file mode 100644 index 30e95dbcfe..0000000000 --- a/calendar/gui/itip-utils.c +++ /dev/null @@ -1,979 +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-moniker-util.h> -#include <libgnome/gnome-i18n.h> -#include <gtk/gtkmessagedialog.h> -#include <gtk/gtkwidget.h> -#include <gal/util/e-util.h> -#include <libical/ical.h> -#include <Evolution-Composer.h> -#include <e-util/e-dialog-utils.h> -#include <e-util/e-time-utils.h> -#include <libecal/e-cal-time-util.h> -#include <libecal/e-cal-util.h> -#include "calendar-config.h" -#include "itip-utils.h" - -#define GNOME_EVOLUTION_COMPOSER_OAFIID "OAFIID:GNOME_Evolution_Mail_Composer:" BASE_VERSION - -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 EAccountList *accounts = NULL; - -EAccountList * -itip_addresses_get (void) -{ - if (accounts == NULL) { - GConfClient *gconf_client = gconf_client_get_default (); - accounts = e_account_list_new (gconf_client); - g_object_unref (gconf_client); - } - - return accounts; -} - -EAccount * -itip_addresses_get_default (void) -{ - return (EAccount *)e_account_list_get_default(itip_addresses_get()); -} - -gboolean -itip_organizer_is_user (ECalComponent *comp, ECal *client) -{ - ECalComponentOrganizer organizer; - const char *strip; - gboolean user_org = FALSE; - - if (!e_cal_component_has_organizer (comp)) - return FALSE; - - e_cal_component_get_organizer (comp, &organizer); - if (organizer.value != NULL) { - - strip = itip_strip_mailto (organizer.value); - - if (e_cal_get_static_capability (client, CAL_STATIC_CAPABILITY_ORGANIZER_NOT_EMAIL_ADDRESS)) { - char *email; - - if (e_cal_get_cal_address (client, &email, NULL) && !g_strcasecmp (email, strip)) { - g_free (email); - - return TRUE; - } - - return FALSE; - } - - user_org = e_account_list_find(itip_addresses_get(), E_ACCOUNT_FIND_ID_ADDRESS, strip) != NULL; - } - - return user_org; -} - -gboolean -itip_sentby_is_user (ECalComponent *comp) -{ - ECalComponentOrganizer organizer; - const char *strip; - gboolean user_sentby = FALSE; - - if (!e_cal_component_has_organizer (comp)) - return FALSE; - - e_cal_component_get_organizer (comp, &organizer); - if (organizer.sentby != NULL) { - strip = itip_strip_mailto (organizer.sentby); - user_sentby = e_account_list_find(itip_addresses_get(), E_ACCOUNT_FIND_ID_ADDRESS, strip) != NULL; - } - - return user_sentby; -} - -const gchar * -itip_strip_mailto (const gchar *address) -{ - if (address == NULL) - return NULL; - - if (!g_strncasecmp (address, "mailto:", 7)) - address += 7; - - return address; -} - -static char * -get_label (struct icaltimetype *tt) -{ - char buffer[1000]; - struct tm tmp_tm; - - tmp_tm = icaltimetype_to_tm (tt); - e_time_format_date_and_time (&tmp_tm, - calendar_config_get_24_hour_format (), - FALSE, FALSE, - buffer, 1000); - - return g_strdup (buffer); -} - -typedef struct { - GHashTable *tzids; - icalcomponent *icomp; - ECal *client; - icalcomponent *zones; -} ItipUtilTZData; - - -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) - e_cal_get_timezone (tz_data->client, tzid, &zone, NULL); - 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 icalcomponent * -comp_toplevel_with_zones (ECalComponentItipMethod method, ECalComponent *comp, ECal *client, icalcomponent *zones) -{ - icalcomponent *top_level, *icomp; - icalproperty *prop; - icalvalue *value; - ItipUtilTZData tz_data; - - top_level = e_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 = e_cal_component_get_icalcomponent (comp); - icomp = icalcomponent_new_clone (icomp); - - 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); - - return top_level; -} - -static gboolean -users_has_attendee (GList *users, const char *address) -{ - GList *l; - - for (l = users; l != NULL; l = l->next) { - if (!g_strcasecmp (address, l->data)) - return TRUE; - } - - return FALSE; -} - -static CORBA_char * -comp_from (ECalComponentItipMethod method, ECalComponent *comp) -{ - ECalComponentOrganizer organizer; - ECalComponentAttendee *attendee; - GSList *attendees; - CORBA_char *str; - - switch (method) { - case E_CAL_COMPONENT_METHOD_PUBLISH: - return CORBA_string_dup (""); - - case E_CAL_COMPONENT_METHOD_REQUEST: - case E_CAL_COMPONENT_METHOD_CANCEL: - case E_CAL_COMPONENT_METHOD_ADD: - e_cal_component_get_organizer (comp, &organizer); - if (organizer.value == NULL) { - e_notice (NULL, GTK_MESSAGE_ERROR, - _("An organizer must be set.")); - return NULL; - } - - return CORBA_string_dup (itip_strip_mailto (organizer.value)); - - default: - if (!e_cal_component_has_attendees (comp)) - return CORBA_string_dup (""); - - e_cal_component_get_attendee_list (comp, &attendees); - attendee = attendees->data; - str = CORBA_string_dup (attendee->value ? itip_strip_mailto (attendee->value) : ""); - e_cal_component_free_attendee_list (attendees); - - return str; - } -} - -static GNOME_Evolution_Composer_RecipientList * -comp_to_list (ECalComponentItipMethod method, ECalComponent *comp, GList *users) -{ - GNOME_Evolution_Composer_RecipientList *to_list; - GNOME_Evolution_Composer_Recipient *recipient; - ECalComponentOrganizer organizer; - GSList *attendees, *l; - gint len; - - switch (method) { - case E_CAL_COMPONENT_METHOD_REQUEST: - case E_CAL_COMPONENT_METHOD_CANCEL: - e_cal_component_get_attendee_list (comp, &attendees); - len = g_slist_length (attendees); - if (len <= 0) { - e_notice (NULL, GTK_MESSAGE_ERROR, - _("At least one attendee is necessary")); - e_cal_component_free_attendee_list (attendees); - return NULL; - } - - to_list = GNOME_Evolution_Composer_RecipientList__alloc (); - to_list->_maximum = len; - to_list->_length = 0; - to_list->_buffer = CORBA_sequence_GNOME_Evolution_Composer_Recipient_allocbuf (len); - - e_cal_component_get_organizer (comp, &organizer); - if (organizer.value == NULL) { - e_notice (NULL, GTK_MESSAGE_ERROR, - _("An organizer must be set.")); - return NULL; - } - - for (l = attendees; l != NULL; l = l->next) { - ECalComponentAttendee *att = l->data; - - if (users_has_attendee (users, att->value)) - continue; - else if (!g_strcasecmp (att->value, organizer.value)) - continue; - - recipient = &(to_list->_buffer[to_list->_length]); - 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)); - - to_list->_length++; - } - e_cal_component_free_attendee_list (attendees); - break; - - case E_CAL_COMPONENT_METHOD_REPLY: - case E_CAL_COMPONENT_METHOD_ADD: - case E_CAL_COMPONENT_METHOD_REFRESH: - case E_CAL_COMPONENT_METHOD_COUNTER: - case E_CAL_COMPONENT_METHOD_DECLINECOUNTER: - e_cal_component_get_organizer (comp, &organizer); - if (organizer.value == NULL) { - e_notice (NULL, GTK_MESSAGE_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 (ECalComponentItipMethod method, ECalComponent *comp) -{ - ECalComponentText caltext; - const char *description, *prefix = NULL; - GSList *alist; - CORBA_char *subject; - - e_cal_component_get_summary (comp, &caltext); - if (caltext.value != NULL) - description = caltext.value; - else { - switch (e_cal_component_get_vtype (comp)) { - case E_CAL_COMPONENT_EVENT: - description = _("Event information"); - case E_CAL_COMPONENT_TODO: - description = _("Task information"); - case E_CAL_COMPONENT_JOURNAL: - description = _("Journal information"); - case E_CAL_COMPONENT_FREEBUSY: - description = _("Free/Busy information"); - default: - description = _("Calendar information"); - } - } - - switch (method) { - case E_CAL_COMPONENT_METHOD_PUBLISH: - case E_CAL_COMPONENT_METHOD_REQUEST: - /* FIXME: If this is an update to a previous - * PUBLISH or REQUEST, then - prefix = U_("Updated"); - */ - break; - - case E_CAL_COMPONENT_METHOD_REPLY: - e_cal_component_get_attendee_list (comp, &alist); - if (alist != NULL) { - ECalComponentAttendee *a = alist->data; - - switch (a->status) { - case ICAL_PARTSTAT_ACCEPTED: - prefix = _("Accepted"); - break; - case ICAL_PARTSTAT_TENTATIVE: - prefix = _("Tentatively Accepted"); - break; - case ICAL_PARTSTAT_DECLINED: - prefix = _("Declined"); - break; - default: - break; - } - e_cal_component_free_attendee_list (alist); - } - break; - - case E_CAL_COMPONENT_METHOD_ADD: - prefix = _("Updated"); - break; - - case E_CAL_COMPONENT_METHOD_CANCEL: - prefix = _("Cancel"); - break; - - case E_CAL_COMPONENT_METHOD_REFRESH: - prefix = _("Refresh"); - break; - - case E_CAL_COMPONENT_METHOD_COUNTER: - prefix = _("Counter-proposal"); - break; - - case E_CAL_COMPONENT_METHOD_DECLINECOUNTER: - prefix = _("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 (ECalComponent *comp, ECalComponentItipMethod method) -{ - char tmp[256]; - - sprintf (tmp, "text/calendar; name=\"%s\"; charset=utf-8; METHOD=%s", - e_cal_component_get_vtype (comp) == E_CAL_COMPONENT_FREEBUSY ? - "freebusy.ifb" : "calendar.ics", itip_methods[method]); - return CORBA_string_dup (tmp); - -} - -static CORBA_char * -comp_filename (ECalComponent *comp) -{ - switch (e_cal_component_get_vtype (comp)) { - case E_CAL_COMPONENT_FREEBUSY: - return CORBA_string_dup ("freebusy.ifb"); - default: - return CORBA_string_dup ("calendar.ics"); - } -} - -static CORBA_char * -comp_description (ECalComponent *comp) -{ - CORBA_char *description; - ECalComponentDateTime dt; - char *start = NULL, *end = NULL; - - switch (e_cal_component_get_vtype (comp)) { - case E_CAL_COMPONENT_EVENT: - return CORBA_string_dup (_("Event information")); - case E_CAL_COMPONENT_TODO: - return CORBA_string_dup (_("Task information")); - case E_CAL_COMPONENT_JOURNAL: - return CORBA_string_dup (_("Journal information")); - case E_CAL_COMPONENT_FREEBUSY: - e_cal_component_get_dtstart (comp, &dt); - if (dt.value) - start = get_label (dt.value); - e_cal_component_free_datetime (&dt); - - e_cal_component_get_dtend (comp, &dt); - if (dt.value) - end = get_label (dt.value); - e_cal_component_free_datetime (&dt); - - if (start != NULL && end != NULL) { - char *tmp; - tmp = g_strdup_printf (_("Free/Busy information (%s to %s)"), start, end); - description = CORBA_string_dup (tmp); - g_free (tmp); - } else { - description = CORBA_string_dup (_("Free/Busy information")); - } - g_free (start); - g_free (end); - return description; - default: - return CORBA_string_dup (_("iCalendar information")); - } -} - -static gboolean -comp_server_send (ECalComponentItipMethod method, ECalComponent *comp, ECal *client, - icalcomponent *zones, GList **users) -{ - icalcomponent *top_level; - gboolean retval = TRUE; - GError *error = NULL; - - top_level = comp_toplevel_with_zones (method, comp, client, zones); - if (!e_cal_send_objects (client, top_level, &error)) { - /* FIXME Really need a book problem status code */ - if (error->code != E_CALENDAR_STATUS_OK) { - /* FIXME Better error message */ - e_notice (NULL, GTK_MESSAGE_ERROR, "Unable to book"); - - retval = FALSE; - } - } - - g_clear_error (&error); - - icalcomponent_free (top_level); - - return retval; -} - -static gboolean -comp_limit_attendees (ECalComponent *comp) -{ - icalcomponent *icomp; - icalproperty *prop; - gboolean found = FALSE, match = FALSE; - GSList *l, *list = NULL; - - icomp = e_cal_component_get_icalcomponent (comp); - - 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; - - /* 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); - found = match = e_account_list_find(itip_addresses_get(), E_ACCOUNT_FIND_ID_ADDRESS, text) != NULL; - 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); - - return found; -} - -static void -comp_sentby (ECalComponent *comp, ECal *client) -{ - ECalComponentOrganizer organizer; - - e_cal_component_get_organizer (comp, &organizer); - if (!organizer.value) { - EAccount *a = itip_addresses_get_default (); - - organizer.value = g_strdup_printf ("MAILTO:%s", a->id->address); - organizer.sentby = NULL; - organizer.cn = a->id->name; - organizer.language = NULL; - - e_cal_component_set_organizer (comp, &organizer); - g_free ((char *) organizer.value); - - return; - } - - if (!itip_organizer_is_user (comp, client) && !itip_sentby_is_user (comp)) { - EAccount *a = itip_addresses_get_default (); - - organizer.value = g_strdup (organizer.value); - organizer.sentby = g_strdup_printf ("MAILTO:%s", a->id->address); - organizer.cn = g_strdup (organizer.cn); - organizer.language = g_strdup (organizer.language); - - e_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); - } -} -static ECalComponent * -comp_minimal (ECalComponent *comp, gboolean attendee) -{ - ECalComponent *clone; - icalcomponent *icomp, *icomp_clone; - icalproperty *prop; - ECalComponentOrganizer organizer; - const char *uid; - GSList *comments; - struct icaltimetype itt; - ECalComponentRange recur_id; - - clone = e_cal_component_new (); - e_cal_component_set_new_vtype (clone, e_cal_component_get_vtype (comp)); - - if (attendee) { - GSList *attendees; - - e_cal_component_get_attendee_list (comp, &attendees); - e_cal_component_set_attendee_list (clone, attendees); - - if (!comp_limit_attendees (clone)) { - e_notice (NULL, GTK_MESSAGE_ERROR, - _("You must be an attendee of the event.")); - goto error; - } - } - - itt = icaltime_from_timet_with_zone (time (NULL), FALSE, - icaltimezone_get_utc_timezone ()); - e_cal_component_set_dtstamp (clone, &itt); - - e_cal_component_get_organizer (comp, &organizer); - if (organizer.value == NULL) - goto error; - e_cal_component_set_organizer (clone, &organizer); - - e_cal_component_get_uid (comp, &uid); - e_cal_component_set_uid (clone, uid); - - e_cal_component_get_comment_list (comp, &comments); - if (g_slist_length (comments) <= 1) { - e_cal_component_set_comment_list (clone, comments); - } else { - GSList *l = comments; - - comments = g_slist_remove_link (comments, l); - e_cal_component_set_comment_list (clone, l); - e_cal_component_free_text_list (l); - } - e_cal_component_free_text_list (comments); - - e_cal_component_get_recurid (comp, &recur_id); - if (recur_id.datetime.value != NULL) - e_cal_component_set_recurid (clone, &recur_id); - - icomp = e_cal_component_get_icalcomponent (comp); - icomp_clone = e_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); - } - - e_cal_component_rescan (clone); - - return clone; - - error: - g_object_unref (clone); - return NULL; -} - -static ECalComponent * -comp_compliant (ECalComponentItipMethod method, ECalComponent *comp, ECal *client, icalcomponent *zones) -{ - ECalComponent *clone, *temp_clone; - struct icaltimetype itt; - - clone = e_cal_component_clone (comp); - itt = icaltime_from_timet_with_zone (time (NULL), FALSE, - icaltimezone_get_utc_timezone ()); - e_cal_component_set_dtstamp (clone, &itt); - - /* Make UNTIL date a datetime in a simple recurrence */ - if (e_cal_component_has_recurrences (clone) - && e_cal_component_has_simple_recurrence (clone)) { - GSList *rrule_list; - struct icalrecurrencetype *r; - - e_cal_component_get_rrule_list (clone, &rrule_list); - r = rrule_list->data; - - if (!icaltime_is_null_time (r->until) && r->until.is_date) { - ECalComponentDateTime dt; - icaltimezone *from_zone = NULL, *to_zone; - - e_cal_component_get_dtstart (clone, &dt); - - if (dt.value->is_date) { - from_zone = icaltimezone_get_builtin_timezone (calendar_config_get_timezone ()); - } else if (dt.tzid == NULL) { - from_zone = icaltimezone_get_utc_timezone (); - } else { - if (zones != NULL) - from_zone = icalcomponent_get_timezone (zones, dt.tzid); - if (from_zone == NULL) - from_zone = icaltimezone_get_builtin_timezone_from_tzid (dt.tzid); - if (from_zone == NULL && client != NULL) - /* FIXME Error checking */ - e_cal_get_timezone (client, dt.tzid, &from_zone, NULL); - } - - to_zone = icaltimezone_get_utc_timezone (); - - r->until.hour = dt.value->hour; - r->until.minute = dt.value->minute; - r->until.second = dt.value->second; - r->until.is_date = FALSE; - - icaltimezone_convert_time (&r->until, from_zone, to_zone); - r->until.is_utc = TRUE; - - e_cal_component_set_rrule_list (clone, rrule_list); - e_cal_component_abort_sequence (clone); - } - - e_cal_component_free_recur_list (rrule_list); - } - - /* We delete incoming alarms anyhow, and this helps with outlook */ - e_cal_component_remove_all_alarms (clone); - - /* Strip X-LIC-ERROR stuff */ - e_cal_component_strip_errors (clone); - - /* Comply with itip spec */ - switch (method) { - case E_CAL_COMPONENT_METHOD_PUBLISH: - comp_sentby (clone, client); - e_cal_component_set_attendee_list (clone, NULL); - break; - case E_CAL_COMPONENT_METHOD_REQUEST: - comp_sentby (clone, client); - break; - case E_CAL_COMPONENT_METHOD_CANCEL: - comp_sentby (clone, client); - break; - case E_CAL_COMPONENT_METHOD_REPLY: - break; - case E_CAL_COMPONENT_METHOD_ADD: - break; - case E_CAL_COMPONENT_METHOD_REFRESH: - /* Need to remove almost everything */ - temp_clone = comp_minimal (clone, TRUE); - g_object_unref (clone); - clone = temp_clone; - break; - case E_CAL_COMPONENT_METHOD_COUNTER: - break; - case E_CAL_COMPONENT_METHOD_DECLINECOUNTER: - /* Need to remove almost everything */ - temp_clone = comp_minimal (clone, FALSE); - g_object_unref (clone); - clone = temp_clone; - break; - default: - break; - } - - return clone; -} - -gboolean -itip_send_comp (ECalComponentItipMethod method, ECalComponent *send_comp, - ECal *client, icalcomponent *zones) -{ - GNOME_Evolution_Composer composer_server; - ECalComponent *comp = NULL; - icalcomponent *top_level = NULL; - GList *users = 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 *from = NULL, *filename = NULL, *description = NULL; - GNOME_Evolution_Composer_AttachmentData *attach_data = NULL; - char *ical_string; - CORBA_Environment ev; - gboolean retval = FALSE; - - CORBA_exception_init (&ev); - - /* Give the server a chance to manipulate the comp */ - if (method != E_CAL_COMPONENT_METHOD_PUBLISH) { - if (!comp_server_send (method, send_comp, client, zones, &users)) - goto cleanup; - } - - /* Tidy up the comp */ - comp = comp_compliant (method, send_comp, client, zones); - if (comp == NULL) - goto cleanup; - - /* Recipients */ - to_list = comp_to_list (method, comp, users); - if (method != E_CAL_COMPONENT_METHOD_PUBLISH) { - if (to_list == NULL || to_list->_length == 0) { - /* We sent them all via the server */ - retval = TRUE; - 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); - - /* From address */ - from = comp_from (method, comp); - - /* Obtain an object reference for the Composer. */ - composer_server = bonobo_activation_activate_from_id (GNOME_EVOLUTION_COMPOSER_OAFIID, 0, NULL, &ev); - if (BONOBO_EX (&ev)) { - g_warning ("Could not activate composer: %s", bonobo_exception_get_text (&ev)); - CORBA_exception_free (&ev); - return FALSE; - } - - /* Set recipients, subject */ - GNOME_Evolution_Composer_setHeaders (composer_server, from, to_list, cc_list, bcc_list, subject, &ev); - if (BONOBO_EX (&ev)) { - g_warning ("Unable to set composer headers while sending iTip message: %s", - bonobo_exception_get_text (&ev)); - goto cleanup; - } - - - /* Content type */ - content_type = comp_content_type (comp, method); - - top_level = comp_toplevel_with_zones (method, comp, client, zones); - ical_string = icalcomponent_as_ical_string (top_level); - - if (e_cal_component_get_vtype (comp) == E_CAL_COMPONENT_EVENT) { - GNOME_Evolution_Composer_setBody (composer_server, ical_string, content_type, &ev); - } else { - GNOME_Evolution_Composer_setMultipartType (composer_server, GNOME_Evolution_Composer_MIXED, &ev); - if (BONOBO_EX (&ev)) { - g_warning ("Unable to set multipart type while sending iTip message"); - goto cleanup; - } - - filename = comp_filename (comp); - description = comp_description (comp); - - GNOME_Evolution_Composer_setBody (composer_server, description, "text/plain", &ev); - if (BONOBO_EX (&ev)) { - g_warning ("Unable to set body text while sending iTip message"); - goto cleanup; - } - - 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_attachData (composer_server, - content_type, filename, description, - TRUE, attach_data, - &ev); - } - - if (BONOBO_EX (&ev)) { - g_warning ("Unable to place iTip message in composer"); - goto cleanup; - } - - if (method == E_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 - retval = TRUE; - } else { - GNOME_Evolution_Composer_send (composer_server, &ev); - if (BONOBO_EX (&ev)) - g_warning ("Unable to send iTip message"); - else - retval = TRUE; - } - - cleanup: - CORBA_exception_free (&ev); - - if (comp != NULL) - g_object_unref (comp); - if (top_level != NULL) - icalcomponent_free (top_level); - - 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 (from != NULL) - CORBA_free (from); - 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->_buffer); - CORBA_free (attach_data); - } - - return retval; -} - diff --git a/calendar/gui/itip-utils.h b/calendar/gui/itip-utils.h deleted file mode 100644 index cf9dd37643..0000000000 --- a/calendar/gui/itip-utils.h +++ /dev/null @@ -1,35 +0,0 @@ - -#ifndef ITIP_UTILS_HEADER -#define ITIP_UTILS_HEADER - -#include <libical/ical.h> -#include <string.h> -#include <glib.h> -#include <libecal/e-cal.h> -#include <libecal/e-cal-component.h> -#include <e-util/e-account-list.h> - -typedef enum { - E_CAL_COMPONENT_METHOD_PUBLISH, - E_CAL_COMPONENT_METHOD_REQUEST, - E_CAL_COMPONENT_METHOD_REPLY, - E_CAL_COMPONENT_METHOD_ADD, - E_CAL_COMPONENT_METHOD_CANCEL, - E_CAL_COMPONENT_METHOD_REFRESH, - E_CAL_COMPONENT_METHOD_COUNTER, - E_CAL_COMPONENT_METHOD_DECLINECOUNTER -} ECalComponentItipMethod; - -EAccountList *itip_addresses_get (void); -EAccount *itip_addresses_get_default (void); - -gboolean itip_organizer_is_user (ECalComponent *comp, ECal *client); -gboolean itip_sentby_is_user (ECalComponent *comp); - -const gchar *itip_strip_mailto (const gchar *address); - -gboolean itip_send_comp (ECalComponentItipMethod method, ECalComponent *comp, - ECal *client, icalcomponent *zones); - - -#endif diff --git a/calendar/gui/main.c b/calendar/gui/main.c deleted file mode 100644 index 838917244d..0000000000 --- a/calendar/gui/main.c +++ /dev/null @@ -1,181 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* main.c - * - * Copyright (C) 2000, 2001, 2002, 2003 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Ettore Perazzoli - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <glib.h> -#include <libgnome/gnome-i18n.h> -#include <libgnome/gnome-init.h> -#include <libgnomevfs/gnome-vfs-init.h> -#include <glade/glade.h> - -#include <bonobo/bonobo-main.h> -#include <bonobo/bonobo-shlib-factory.h> -#include <bonobo/bonobo-exception.h> - -#include <gal/widgets/e-cursors.h> - -#include "dialogs/cal-prefs-dialog.h" -#include "calendar-commands.h" -#include "calendar-config.h" -#include "calendar-component.h" -#include "e-comp-editor-registry.h" -#include "comp-editor-factory.h" -#include "control-factory.h" -#include "itip-bonobo-control.h" -#include "tasks-control.h" -#include "tasks-component.h" - - -#define FACTORY_ID "OAFIID:GNOME_Evolution_Calendar_Factory:" BASE_VERSION - -#define CALENDAR_COMPONENT_ID "OAFIID:GNOME_Evolution_Calendar_Component:" BASE_VERSION -#define CALENDAR_CONTROL_ID "OAFIID:GNOME_Evolution_Calendar_Control:" BASE_VERSION -#define TASKS_COMPONENT_ID "OAFIID:GNOME_Evolution_Tasks_Component:" BASE_VERSION -#define TASKS_CONTROL_ID "OAFIID:GNOME_Evolution_Tasks_Control:" BASE_VERSION -#define ITIP_CONTROL_ID "OAFIID:GNOME_Evolution_Calendar_iTip_Control:" BASE_VERSION -#define CONFIG_CONTROL_ID "OAFIID:GNOME_Evolution_Calendar_ConfigControl:" BASE_VERSION -#define COMP_EDITOR_FACTORY_ID "OAFIID:GNOME_Evolution_Calendar_CompEditorFactory:" BASE_VERSION - -ECompEditorRegistry *comp_editor_registry = NULL; - -/* The component editor factory */ -static CompEditorFactory *comp_editor_factory = NULL; - - -/* Factory function for the calendar component factory; just creates and - * references a singleton service object. - */ -static BonoboObject * -comp_editor_factory_fn (void) -{ - if (!comp_editor_factory) { - comp_editor_factory = comp_editor_factory_new (); - if (!comp_editor_factory) - return NULL; - } - - bonobo_object_ref (BONOBO_OBJECT (comp_editor_factory)); - return BONOBO_OBJECT (comp_editor_factory); -} - - -/* Does a simple activation and unreffing of the alarm notification service so - * that the daemon will be launched if it is not running yet. - */ -static gboolean -launch_alarm_daemon_cb (gpointer data) -{ - CORBA_Environment ev; - CORBA_Object an; - guint *idle_id = (guint *) data; - - /* remove the idle function */ - g_source_remove (*idle_id); - g_free (idle_id); - - /* activate the alarm daemon */ - CORBA_exception_init (&ev); - an = bonobo_activation_activate_from_id ("OAFIID:GNOME_Evolution_Calendar_AlarmNotify:" BASE_VERSION, 0, NULL, &ev); - - if (BONOBO_EX (&ev)) { - g_message ("launch_alarm_daemon_cb(): Could not activate the alarm notification service"); - CORBA_exception_free (&ev); - return FALSE; - } - CORBA_exception_free (&ev); - - /* Just get rid of it; what we are interested in is that it gets launched */ - - CORBA_exception_init (&ev); - bonobo_object_release_unref (an, &ev); - if (BONOBO_EX (&ev)) - g_message ("add_alarms(): Could not unref the alarm notification service"); - - CORBA_exception_free (&ev); - - return FALSE; -} - -static void -launch_alarm_daemon (void) -{ - guint *idle_id; - - idle_id = g_new0 (guint, 1); - *idle_id = g_idle_add ((GSourceFunc) launch_alarm_daemon_cb, idle_id); -} - -static void -initialize (void) -{ - comp_editor_registry = E_COMP_EDITOR_REGISTRY (e_comp_editor_registry_new ()); - - calendar_config_init (); - -#if 0 - itip_control_factory_init (); - component_editor_factory_init (); -#endif - - launch_alarm_daemon (); -} - - -static BonoboObject * -factory (BonoboGenericFactory *factory, - const char *component_id, - void *closure) -{ - static gboolean initialized = FALSE; - - if (! initialized) { - initialize (); - initialized = TRUE; - } - - if (strcmp (component_id, CALENDAR_COMPONENT_ID) == 0) { - BonoboObject *object = BONOBO_OBJECT (calendar_component_peek ()); - bonobo_object_ref (object); - return object; - } else if (strcmp (component_id, CALENDAR_CONTROL_ID) == 0) - return BONOBO_OBJECT (control_factory_new_control ()); - else if (strcmp (component_id, TASKS_COMPONENT_ID) == 0) { - BonoboObject *object = BONOBO_OBJECT (tasks_component_peek ()); - bonobo_object_ref (object); - return object; - } else if (strcmp (component_id, TASKS_CONTROL_ID) == 0) - return BONOBO_OBJECT (tasks_control_new ()); - else if (strcmp (component_id, ITIP_CONTROL_ID) == 0) - return BONOBO_OBJECT (itip_bonobo_control_new ()); - else if (strcmp (component_id, CONFIG_CONTROL_ID) == 0) - return BONOBO_OBJECT (cal_prefs_dialog_new ()); - else if (strcmp (component_id, COMP_EDITOR_FACTORY_ID) == 0) - return BONOBO_OBJECT (comp_editor_factory_fn ()); - - g_warning (FACTORY_ID ": Don't know what to do with %s", component_id); - return NULL; -} - -BONOBO_ACTIVATION_SHLIB_FACTORY (FACTORY_ID, "Evolution Calendar component factory", factory, NULL) diff --git a/calendar/gui/migration.c b/calendar/gui/migration.c deleted file mode 100644 index afb0a59b68..0000000000 --- a/calendar/gui/migration.c +++ /dev/null @@ -1,150 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* calendar-component.c - * - * Copyright (C) 2003 Ximian, Inc - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Rodrigo Moya <rodrigo@ximian.com> - */ - -#include <bonobo/bonobo-i18n.h> -#include <libgnomevfs/gnome-vfs-uri.h> -#include <libgnomevfs/gnome-vfs-xfer.h> -#include <gal/util/e-util.h> -#include "migration.h" - - -static gboolean -process_old_dir (ESourceGroup *source_group, const char *path, - const char *filename, const char *name, const char *base_uri) -{ - char *s; - GnomeVFSURI *from, *to; - GnomeVFSResult vres; - ESource *source; - GDir *dir; - gboolean retval = TRUE; - - s = g_build_filename (path, filename, NULL); - if (!g_file_test (s, G_FILE_TEST_EXISTS)) { - g_free (s); - return FALSE; - } - - /* transfer the old file to its new location */ - from = gnome_vfs_uri_new (s); - g_free (s); - if (!from) - return FALSE; - - s = g_build_filename (e_source_group_peek_base_uri (source_group), base_uri, - filename, NULL); - if (e_mkdir_hier (s, 0700) != 0) { - gnome_vfs_uri_unref (from); - g_free (s); - return FALSE; - } - to = gnome_vfs_uri_new (s); - g_free (s); - if (!to) { - gnome_vfs_uri_unref (from); - return FALSE; - } - - vres = gnome_vfs_xfer_uri ((const GnomeVFSURI *) from, - (const GnomeVFSURI *) to, - GNOME_VFS_XFER_DEFAULT, - GNOME_VFS_XFER_ERROR_MODE_ABORT, - GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE, - NULL, NULL); - gnome_vfs_uri_unref (from); - gnome_vfs_uri_unref (to); - - if (vres != GNOME_VFS_OK) - return FALSE; - - /* create the new source */ - source = e_source_new (name, base_uri); - e_source_group_add_source (source_group, source, -1); - - /* process subfolders */ - s = g_build_filename (path, "subfolders", NULL); - dir = g_dir_open (s, 0, NULL); - if (dir) { - const char *name, *tmp_s; - - while ((name = g_dir_read_name (dir))) { - tmp_s = g_build_filename (s, name, NULL); - if (g_file_test (tmp_s, G_FILE_TEST_IS_DIR)) { - retval = process_old_dir (source_group, tmp_s, filename, name, name); - } - - g_free (tmp_s); - } - - g_dir_close (dir); - } - - g_free (s); - - return retval; -} - -gboolean -migrate_old_calendars (ESourceGroup *source_group) -{ - char *path; - gboolean retval; - - g_return_val_if_fail (E_IS_SOURCE_GROUP (source_group), FALSE); - - path = g_build_filename (g_get_home_dir (), "evolution", NULL); - if (!g_file_test (path, G_FILE_TEST_IS_DIR)) { - g_free (path); - return FALSE; - } - g_free (path); - - /* look for the top-level calendar */ - path = g_build_filename (g_get_home_dir (), "evolution/local/Calendar", NULL); - retval = process_old_dir (source_group, path, "calendar.ics", _("Personal"), "Personal"); - g_free (path); - - return retval; -} - -gboolean -migrate_old_tasks (ESourceGroup *source_group) -{ - char *path; - gboolean retval; - - g_return_val_if_fail (E_IS_SOURCE_GROUP (source_group), FALSE); - - path = g_build_filename (g_get_home_dir (), "evolution", NULL); - if (!g_file_test (path, G_FILE_TEST_IS_DIR)) { - g_free (path); - return FALSE; - } - g_free (path); - - /* look for the top-level calendar */ - path = g_build_filename (g_get_home_dir (), "evolution/local/Tasks", NULL); - retval = process_old_dir (source_group, path, "tasks.ics", _("Personal"), "Personal"); - g_free (path); - - return retval; -} diff --git a/calendar/gui/migration.h b/calendar/gui/migration.h deleted file mode 100644 index b217ae97c8..0000000000 --- a/calendar/gui/migration.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* calendar-component.c - * - * Copyright (C) 2003 Ximian, Inc - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Rodrigo Moya <rodrigo@ximian.com> - */ - -#ifndef MIGRATION_H -#define MIGRATION_H - -#include <libedataserver/e-source-group.h> - -gboolean migrate_old_calendars (ESourceGroup *source_group); -gboolean migrate_old_tasks (ESourceGroup *source_group); - -#endif diff --git a/calendar/gui/misc.c b/calendar/gui/misc.c deleted file mode 100644 index e286442a89..0000000000 --- a/calendar/gui/misc.c +++ /dev/null @@ -1,80 +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 <e-util/e-url.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; - -} - -/** - * get_uri_without_password - */ -char * -get_uri_without_password (const char *full_uri) -{ - EUri *uri; - char *uristr; - - uri = e_uri_new (full_uri); - if (!uri) - return NULL; - - uristr = e_uri_to_string (uri, FALSE); - e_uri_free (uri); - - return uristr; - } diff --git a/calendar/gui/misc.h b/calendar/gui/misc.h deleted file mode 100644 index d32739f9f5..0000000000 --- a/calendar/gui/misc.h +++ /dev/null @@ -1,30 +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); -char *get_uri_without_password (const char *uri); - -#endif diff --git a/calendar/gui/print.c b/calendar/gui/print.c deleted file mode 100644 index 1e647c096b..0000000000 --- a/calendar/gui/print.c +++ /dev/null @@ -1,2658 +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 <string.h> -#include <time.h> -#include <glib.h> -#include <gtk/gtkradiobutton.h> -#include <libgnome/gnome-i18n.h> -#include <libgnomeui/gnome-dialog.h> -#include <libgnomeui/gnome-uidefs.h> -#include <libgnomeui/gnome-stock-icons.h> -#include <libgnomeprint/gnome-print.h> -#include <libgnomeprint/gnome-print-paper.h> -#include <libgnomeprint/gnome-print-job.h> -#include <libgnomeprintui/gnome-print-job-preview.h> -#include <libgnomeprintui/gnome-print-paper-selector.h> -#include <libgnomeprintui/gnome-print-preview.h> -#include <libgnomeprintui/gnome-print-dialog.h> -#include <gal/util/e-util.h> -#include <e-util/e-dialog-widgets.h> -#include <e-util/e-time-utils.h> -#include <libecal/e-cal-time-util.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. - */ - -/* GtkHTML prints using a fixed margin. It has code to get the margins from - * gnome-print keys, but it's commented out. The corresponding code here - * doesn't seem to work either (getting zero margins), so we adopt - * gtkhtml's cheat. */ -#define TEMP_MARGIN .05 - -/* The fonts to use */ -#define REGULAR_FONT "Sans Regular" -#define BOLD_FONT "Sans Bold" - -/* 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 GnomePrintConfig *print_config = 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; - gchar *font_name; - - if (weight <= GNOME_FONT_BOOK) - font_name = REGULAR_FONT; - else - font_name = BOLD_FONT; - - if (italic) - font_name = g_strconcat (font_name, " Italic", NULL); - - /* This function is broken in gnome-print (it doesn't find a suitable face). - * face = gnome_font_face_find_closest_from_weight_slant (DEFAULT_FONT, weight, italic); */ - face = gnome_font_face_find (font_name); - - asc = gnome_font_face_get_ascender (face); - desc = abs (gnome_font_face_get_descender (face)); - size = h * 1000 / (asc + desc); - - /* This function is broken in gnome-print (it doesn't find a suitable font). - * font = gnome_font_find_closest_from_weight_slant (DEFAULT_FONT, weight, italic, size); */ - font = gnome_font_find_closest (font_name, size); - - g_object_unref (face); - if (italic) - g_free (font_name); - 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); - g_object_unref (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); - g_object_unref (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; - - 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"); - } - e_utf8_strftime(buffer, bufflen, fmt, &tm); - buffer[bufflen - 1] = '\0'; - - return buffer; -} - -static gboolean -instance_cb (ECalComponent *comp, time_t instance_start, time_t instance_end, gpointer data) -{ - gboolean *found = data; - - *found = TRUE; - - return FALSE; -} - - -/* - print out the month small, embolden any days with events. -*/ -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 (); - ECal *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); - g_object_unref (font); - - top -= header_size; - - client = gnome_calendar_get_default_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, _(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) { - gboolean found = FALSE; - - sprintf (buf, "%d", day); - - /* this is a slow messy way to do this ... but easy ... */ - e_cal_generate_instances (client, now, CALOBJ_TYPE_EVENT, - time_day_end_with_zone (now, zone), - instance_cb, &found); - - font = found ? font_bold : font_normal; - - next = time_add_day_with_zone (now, 1, zone); - if ((now >= greystart && now < greyend) - || (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; - } - } - } - g_object_unref (font_normal); - g_object_unref (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 = _("am"); - else - minute = _("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++; - } - - g_object_unref (font_hour); - g_object_unref (font_minute); -} - - -/* This adds one event to the view, adding it to the appropriate array. */ -static gint -print_day_add_event (ECalComponent *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; */ -/* g_object_ref (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 (ECalComponent *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)); - } - - 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) -{ - const gchar *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. */ - summary = icalcomponent_get_summary (event->comp_data->icalcomp); - text = summary ? (char*) summary : ""; - - 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) -{ - const gchar *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); - - summary = icalcomponent_get_summary (event->comp_data->icalcomp); - text = summary ? (char*) summary : ""; - - - 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 (); - ECal *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_default_client (gcal); - e_cal_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); - } - g_object_unref (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); - } - g_object_unref (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 (ECalComponent *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; */ -/* g_object_ref (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; - const gchar *summary; - char *text; - int num_days, start_x, start_y, start_h, end_x, end_y, end_h; - double x1, x2, y1, y2; - - summary = icalcomponent_get_summary (event->comp_data->icalcomp); - text = summary ? (char*) summary : ""; - - 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]; - - 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"); - - } - - e_utf8_strftime (buffer, sizeof (buffer), format_string, &tm); - print_text_size (pc, buffer, ALIGN_RIGHT, - x1, x2 - 4, y1 - 2, y1 - 2 - font_size); - } -} - - - -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 (); - ECal *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_default_client (gcal); - e_cal_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); - } - - g_object_unref (font); - - /* Free everything. */ - for (event_num = 0; event_num < psi.events->len; event_num++) { - event = &g_array_index (psi.events, EWeekViewEvent, event_num); - } - 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++) { - if (tm.tm_wday == 6 && compress_weekend) { - e_utf8_strftime (buffer, sizeof (buffer), "%a/", &tm); - len = strlen (buffer); - tm.tm_mday++; - tm.tm_wday = (tm.tm_wday + 1) % 7; - e_utf8_strftime (buffer + len, sizeof (buffer) - len, - "%a", &tm); - } else { - e_utf8_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); - print_text_size (pc, buffer, ALIGN_CENTER, x1, x2, y1, y2); - - tm.tm_mday++; - tm.tm_wday = (tm.tm_wday + 1) % 7; - } - g_object_unref (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) -{ - ECal *client; - GnomeFont *font_summary; - double y, yend, x, xend; - struct icaltimetype *tt; - ECalendarTable *task_pad; - ETable *table; - ECalModel *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_e_cal (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, _("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++) { - ECalModelComponent *comp_data; - ECalComponent *comp; - ECalComponentText summary; - int model_row; - - model_row = e_table_view_to_model_row (table, row); - comp_data = e_cal_model_get_component_at (model, model_row); - if (!comp_data) - continue; - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp)); - - e_cal_component_get_summary (comp, &summary); - if (!summary.value) { - g_object_unref (comp); - 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. */ - e_cal_component_get_completed (comp, &tt); - if (tt) { - e_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; - - g_object_unref (comp); - } - - g_object_unref (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 */ - - e_utf8_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) { - e_utf8_strftime (str1, sizeof (str1), _("%a %b %d"), &week_begin_tm); - e_utf8_strftime (str2, sizeof (str2), _("%a %d %Y"), &week_end_tm); - } else { - if (week_begin_tm.tm_year == week_end_tm.tm_year) { - e_utf8_strftime (str1, sizeof (str1), _("%a %b %d"), &week_begin_tm); - e_utf8_strftime (str2, sizeof (str2), _("%a %b %d %Y"), &week_end_tm); - } else { - e_utf8_strftime (str1, sizeof (str1), _("%a %b %d %Y"), &week_begin_tm); - e_utf8_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 */ - - e_utf8_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 */ - - e_utf8_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; - - gnome_print_beginpage (pc, NULL); - - /* 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; - - gnome_print_beginpage (pc, NULL); - - 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; - - gnome_print_beginpage (pc, NULL); - - /* 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]; - - gnome_print_beginpage (pc, NULL); - - 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 (ECal *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) { - if (!e_cal_get_timezone (client, tzid, &zone, NULL)) - /* FIXME: Handle error better. */ - g_warning ("Couldn't get timezone from server: %s", - tzid ? tzid : ""); - } - - return zone; -} - -static void -print_date_label (GnomePrintContext *pc, ECalComponent *comp, ECal *client, - double left, double right, double top, double bottom) -{ - icaltimezone *start_zone, *end_zone, *due_zone, *completed_zone; - ECalComponentDateTime datetime; - time_t start = 0, end = 0, complete = 0, due = 0; - static char buffer[1024]; - - e_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); - } - e_cal_component_free_datetime (&datetime); - - e_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); - } - e_cal_component_free_datetime (&datetime); - - e_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); - } - e_cal_component_free_datetime (&datetime); - - e_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); - e_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); - } - - print_text_size_bold (pc, buffer, ALIGN_LEFT, - left, right, top, top - 15); -} - -static void -print_comp_item (GnomePrintContext *pc, ECalComponent *comp, ECal *client, - double left, double right, double top, double bottom) -{ - GnomeFont *font; - ECalComponentVType vtype; - ECalComponentText text; - GSList *desc, *l; - const char *title, *categories; - char *categories_string; - GSList *contact_list, *elem; - gint header_size; - - vtype = e_cal_component_get_vtype (comp); - - /* We should only be asked to print VEVENTs or VTODOs. */ - if (vtype == E_CAL_COMPONENT_EVENT) - title = _("Appointment"); - else if (vtype == E_CAL_COMPONENT_TODO) - title = _("Task"); - else - return; - - gnome_print_beginpage (pc, NULL); - - /* 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); - g_object_unref (font); - - top -= header_size + 10; - - /* Summary */ - font = get_font_for_size (18, GNOME_FONT_BOLD, FALSE); - e_cal_component_get_summary (comp, &text); - top = bound_text (pc, font, text.value, left, right, - top - 3, bottom, 0); - g_object_unref (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 == E_CAL_COMPONENT_TODO) { - icalproperty_status status; - const char *status_string = NULL; - int *percent; - int *priority; - const char *url; - - /* Status */ - e_cal_component_get_status (comp, &status); - if (status != ICAL_STATUS_NONE) { - switch (status) { - case ICAL_STATUS_NEEDSACTION: - status_string = _("Not Started"); - break; - case ICAL_STATUS_INPROCESS: - status_string = _("In Progress"); - break; - case ICAL_STATUS_COMPLETED: - status_string = _("Completed"); - break; - case ICAL_STATUS_CANCELLED: - status_string = _("Cancelled"); - break; - default: - break; - } - - if (status_string) { - char *text = g_strdup_printf (_("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 */ - e_cal_component_get_priority (comp, &priority); - if (priority && *priority >= 0) { - char *priority_string, *text; - - priority_string = e_cal_util_priority_to_string (*priority); - e_cal_component_free_priority (priority); - - text = g_strdup_printf (_("Priority: %s"), priority_string); - top = bound_text (pc, font, text, - left, right, top, bottom, 0); - top += gnome_font_get_size (font) - 6; - g_free (text); - } - - /* Percent Complete */ - e_cal_component_get_percent (comp, &percent); - if (percent) { - char *percent_string; - - percent_string = g_strdup_printf (_("Percent Complete: %i"), *percent); - e_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 */ - e_cal_component_get_url (comp, &url); - if (url && url[0]) { - char *url_string = g_strdup_printf (_("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 */ - e_cal_component_get_categories (comp, &categories); - if (categories && categories[0]) { - categories_string = g_strdup_printf (_("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 */ - e_cal_component_get_contact_list (comp, &contact_list); - if (contact_list) { - GString *contacts = g_string_new (_("Contacts: ")); - for (elem = contact_list; elem; elem = elem->next) { - ECalComponentText *t = elem->data; - /* Put a comma between contacts. */ - if (elem != contact_list) - g_string_append (contacts, ", "); - g_string_append (contacts, t->value); - } - e_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 */ - e_cal_component_get_description_list (comp, &desc); - for (l = desc; l != NULL; l = l->next) { - ECalComponentText *text = l->data; - - if (text->value != NULL) - top = bound_text (pc, font, text->value, left, right, top-3, bottom, 0); - } - e_cal_component_free_text_list (desc); - g_object_unref (font); - - gnome_print_showpage (pc); -} - -void -print_calendar (GnomeCalendar *gcal, gboolean preview, time_t date, - PrintView default_view) -{ - GnomePrintJob *gpm; - GnomePrintContext *pc; - int copies, collate; - double l, r, t, b; - gchar *old_orientation; - - g_return_if_fail (gcal != NULL); - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - - if (!print_config) - print_config = gnome_print_config_default (); - - copies = 1; - collate = FALSE; - - gpm = gnome_print_job_new (print_config); - - if (!preview) { - GtkWidget *gpd; - GtkWidget *range; - int view; - - gpd = gnome_print_dialog_new (gpm, _("Print"), 0); - - view = (int) default_view; - range = range_selector_new (gpd, date, &view); - gnome_print_dialog_construct_range_custom (GNOME_PRINT_DIALOG (gpd), range); - - gtk_dialog_set_default_response (GTK_DIALOG (gpd), - GNOME_PRINT_DIALOG_RESPONSE_PRINT); - - /* Run dialog */ - - switch (gtk_dialog_run (GTK_DIALOG (gpd))) { - case GNOME_PRINT_DIALOG_RESPONSE_PRINT: - break; - - case GNOME_PRINT_DIALOG_RESPONSE_PREVIEW: - preview = TRUE; - break; - - case -1: - return; - - default: - gtk_widget_destroy (gpd); - return; - } - - e_dialog_get_values (gpd); - default_view = (PrintView) view; - - gtk_widget_destroy (gpd); - } - - old_orientation = gnome_print_config_get (print_config, GNOME_PRINT_KEY_PAGE_ORIENTATION); - - if (default_view == PRINT_VIEW_MONTH) - gnome_print_config_set (print_config, GNOME_PRINT_KEY_PAGE_ORIENTATION, "R90"); - - pc = gnome_print_job_get_context (gpm); - gnome_print_config_get_page_size (print_config, &r, &t); - - /* See top of source for an explanation of this */ - - /* gnome_print_config_get_double (print_config, GNOME_PRINT_KEY_PAGE_MARGIN_TOP, &temp_d); - * t -= temp_d; - * gnome_print_config_get_double (print_config, GNOME_PRINT_KEY_PAGE_MARGIN_RIGHT, &temp_d); - * r -= temp_d; - * gnome_print_config_get_double (print_config, GNOME_PRINT_KEY_PAGE_MARGIN_BOTTOM, &b); - * gnome_print_config_get_double (print_config, GNOME_PRINT_KEY_PAGE_MARGIN_LEFT, &l); - * b = l = TEMP_MARGIN; */ - - b = t * TEMP_MARGIN; - l = r * TEMP_MARGIN; - t *= (1.0 - TEMP_MARGIN); - r *= (1.0 - TEMP_MARGIN); - - /* 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: - print_month_view (pc, gcal, date, l, r, t, b); - break; - case PRINT_VIEW_YEAR: - print_year_view (pc, gcal, date, l, r, t, b); - break; - default: - g_assert_not_reached (); - } - - gnome_print_job_close (gpm); - - if (preview) { - GtkWidget *gpmp; - - gpmp = gnome_print_job_preview_new (gpm, _("Print Preview")); - gtk_widget_show (gpmp); - } else { - gnome_print_job_print (gpm); - } - - gnome_print_config_set (print_config, GNOME_PRINT_KEY_PAGE_ORIENTATION, old_orientation); - g_free (old_orientation); - g_object_unref (gpm); -} - - -void -print_comp (ECalComponent *comp, ECal *client, gboolean preview) -{ - GnomePrintJob *gpm; - GnomePrintContext *pc; - int copies, collate; - double l, r, t, b; - - g_return_if_fail (comp != NULL); - g_return_if_fail (E_IS_CAL_COMPONENT (comp)); - - if (!print_config) - print_config = gnome_print_config_default (); - - copies = 1; - collate = FALSE; - - gpm = gnome_print_job_new (print_config); - - if (!preview) { - GtkWidget *gpd; - - gpd = gnome_print_dialog_new (gpm, _("Print Item"), - GNOME_PRINT_DIALOG_COPIES); - - gtk_dialog_set_default_response (GTK_DIALOG (gpd), - GNOME_PRINT_DIALOG_RESPONSE_PRINT); - - /* Run dialog */ - - switch (gtk_dialog_run (GTK_DIALOG (gpd))) { - case GNOME_PRINT_DIALOG_RESPONSE_PRINT: - break; - - case GNOME_PRINT_DIALOG_RESPONSE_PREVIEW: - preview = TRUE; - break; - - case -1: - return; - - default: - gtk_widget_destroy (gpd); - return; - } - - e_dialog_get_values (gpd); - gtk_widget_destroy (gpd); - } - - pc = gnome_print_job_get_context (gpm); - gnome_print_config_get_page_size (print_config, &r, &t); - - /* See top of source for an explanation of this */ - - /* gnome_print_config_get_double (print_config, GNOME_PRINT_KEY_PAGE_MARGIN_TOP, &temp_d); - * t -= temp_d; - * gnome_print_config_get_double (print_config, GNOME_PRINT_KEY_PAGE_MARGIN_RIGHT, &temp_d); - * r -= temp_d; - * gnome_print_config_get_double (print_config, GNOME_PRINT_KEY_PAGE_MARGIN_BOTTOM, &b); - * gnome_print_config_get_double (print_config, GNOME_PRINT_KEY_PAGE_MARGIN_LEFT, &l); - * b = l = TEMP_MARGIN; */ - - b = t * TEMP_MARGIN; - l = r * TEMP_MARGIN; - t *= (1.0 - TEMP_MARGIN); - r *= (1.0 - TEMP_MARGIN); - - print_comp_item (pc, comp, client, l, r, t, b); - gnome_print_job_close (gpm); - - if (preview) { - GtkWidget *gpmp; - - gpmp = gnome_print_job_preview_new (gpm, _("Print Preview")); - gtk_widget_show (gpmp); - } else { - gnome_print_job_print (gpm); - } - - g_object_unref (gpm); -} - -void -print_setup (void) -{ - GtkWidget *ps; - - if (!print_config) - print_config = gnome_print_config_default (); - - ps = gnome_paper_selector_new (print_config); - gtk_widget_show (ps); - -#if 0 - dlg = gtk_dialog_new_with_buttons (_("Print Setup"), - NULL, /* FIXME: Set a sensible parent */ - 0, - GNOME_STOCK_BUTTON_OK, - GNOME_STOCK_BUTTON_CANCEL, - NULL); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), ps, TRUE, TRUE, 2); - - btn = gtk_dialog_run (GTK_DIALOG (dlg)); - if (btn == 0) { - gchar *name; - - print_config = gnome_paper_selector_get_config (ps); - - name = gnome_paper_selector_get_name (GNOME_PAPER_SELECTOR (ps)); - paper_info = gnome_paper_with_name (name); - } - - gtk_widget_destroy (dlg); -#endif -} diff --git a/calendar/gui/print.h b/calendar/gui/print.h deleted file mode 100644 index 495007d81d..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 (ECalComponent *comp, ECal *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 8e6937d08a..0000000000 --- a/calendar/gui/tag-calendar.c +++ /dev/null @@ -1,230 +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 <libecal/e-cal-time-util.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, icaltimezone *zone, 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; - - if (zone) { - c->zone = zone; - } else { - 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 e_cal_generate_instances() */ -static gboolean -tag_calendar_cb (ECalComponent *comp, - time_t istart, - time_t iend, - gpointer data) -{ - struct calendar_tag_closure *c = data; - struct icaltimetype start_tt, end_tt; - ECalComponentTransparency transparency; - - /* If we are skipping TRANSPARENT events, return if the event is - transparent. */ - if (c->skip_transparent_events) { - e_cal_component_get_transparency (comp, &transparency); - if (transparency == E_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, ECal *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 (E_IS_CAL (client)); - - /* If the ECalendar isn't visible, we just return. */ - if (!GTK_WIDGET_VISIBLE (ecal)) - return; - - if (e_cal_get_load_state (client) != E_CAL_LOAD_LOADED) - return; - - if (!prepare_tag (ecal, &c, NULL, TRUE)) - return; - - c.skip_transparent_events = TRUE; - -#if 0 - g_print ("DateNavigator generating instances\n"); -#endif - e_cal_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) -{ - ECal *client; - icaltimezone *zone = NULL; - - g_return_val_if_fail (data != NULL, NULL); - g_return_val_if_fail (E_IS_CAL (data), NULL); - - client = E_CAL (data); - - /* Try to find the builtin timezone first. */ - zone = icaltimezone_get_builtin_timezone_from_tzid (tzid); - - if (!zone) { - /* FIXME: Handle errors. */ - e_cal_get_timezone (client, tzid, &zone, NULL); - } - - 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, ECalComponent *comp, ECal *client, icaltimezone *display_zone, - 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 (E_IS_CAL_COMPONENT (comp)); - - /* If the ECalendar isn't visible, we just return. */ - if (!GTK_WIDGET_VISIBLE (ecal)) - return; - - if (!prepare_tag (ecal, &c, display_zone, clear_first)) - return; - - c.skip_transparent_events = FALSE; - -#if 0 - g_print ("DateNavigator generating instances\n"); -#endif - if (comp_is_on_server) { - e_cal_recur_generate_instances (comp, c.start_time, c.end_time, - tag_calendar_cb, &c, - e_cal_resolve_tzid_cb, - client, c.zone); - } else { - e_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 d31d675543..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 <libecal/e-cal.h> - -void tag_calendar_by_client (ECalendar *ecal, ECal *client); -void tag_calendar_by_comp (ECalendar *ecal, ECalComponent *comp, - ECal *client, icaltimezone *display_zone, - gboolean clear_first, gboolean comp_is_on_server); - -#endif diff --git a/calendar/gui/tasks-component.c b/calendar/gui/tasks-component.c deleted file mode 100644 index db7864bdd7..0000000000 --- a/calendar/gui/tasks-component.c +++ /dev/null @@ -1,812 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* tasks-component.c - * - * Copyright (C) 2003 Rodrigo Moya - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Rodrigo Moya <rodrigo@ximian.com> - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <errno.h> -#include <string.h> -#include <bonobo/bonobo-control.h> -#include <bonobo/bonobo-i18n.h> -#include <bonobo/bonobo-exception.h> -#include <gconf/gconf-client.h> -#include <libecal/e-cal.h> -#include "e-cal-model.h" -#include "e-tasks.h" -#include "tasks-component.h" -#include "tasks-control.h" -#include "e-comp-editor-registry.h" -#include "migration.h" -#include "comp-util.h" -#include "calendar-config.h" -#include "dialogs/comp-editor.h" -#include "dialogs/copy-source-dialog.h" -#include "dialogs/new-task-list.h" -#include "dialogs/task-editor.h" -#include "widgets/misc/e-source-selector.h" - - -#define CREATE_TASK_ID "task" - - -#define PARENT_TYPE bonobo_object_get_type () - -static BonoboObjectClass *parent_class = NULL; - -/* Tasks should have their own registry */ -extern ECompEditorRegistry *comp_editor_registry; - -struct _TasksComponentPrivate { - char *config_directory; - GConfClient *gconf_client; - - ESourceList *source_list; - GSList *source_selection; - - ETasks *tasks; - GtkWidget *source_selector; - - ECal *create_ecal; - - GList *notifications; -}; - -/* Utility functions. */ -/* FIXME Some of these are duplicated from calendar-component.c */ -static void -add_uri_for_source (ESource *source, ETasks *tasks) -{ - char *uri = e_source_get_uri (source); - - e_tasks_add_todo_uri (tasks, uri); - g_free (uri); -} - -static void -remove_uri_for_source (ESource *source, ETasks *tasks) -{ - char *uri = e_source_get_uri (source); - - e_tasks_remove_todo_uri (tasks, uri); - g_free (uri); -} - -static gboolean -is_in_selection (GSList *selection, ESource *source) -{ - GSList *l; - - for (l = selection; l; l = l->next) { - ESource *selected_source = l->data; - - if (!strcmp (e_source_peek_uid (selected_source), e_source_peek_uid (source))) - return TRUE; - } - - return FALSE; -} - -static gboolean -is_in_uids (GSList *uids, ESource *source) -{ - GSList *l; - - for (l = uids; l; l = l->next) { - const char *uid = l->data; - - if (!strcmp (uid, e_source_peek_uid (source))) - return TRUE; - } - - return FALSE; -} - -static ESource * -find_first_source (ESourceList *source_list) -{ - GSList *groups, *sources, *l, *m; - - groups = e_source_list_peek_groups (source_list); - for (l = groups; l; l = l->next) { - ESourceGroup *group = l->data; - - sources = e_source_group_peek_sources (group); - for (m = sources; m; m = m->next) { - ESource *source = m->data; - - return source; - } - } - - return NULL; -} - -static void -update_uris_for_selection (TasksComponent *component) -{ - TasksComponentPrivate *priv; - GSList *selection, *l, *uids_selected = NULL; - - priv = component->priv; - - selection = e_source_selector_get_selection (E_SOURCE_SELECTOR (priv->source_selector)); - - for (l = priv->source_selection; l; l = l->next) { - ESource *old_selected_source = l->data; - - if (!is_in_selection (selection, old_selected_source)) - remove_uri_for_source (old_selected_source, E_TASKS (priv->tasks)); - } - - for (l = selection; l; l = l->next) { - ESource *selected_source = l->data; - - add_uri_for_source (selected_source, E_TASKS (priv->tasks)); - uids_selected = g_slist_append (uids_selected, (char *)e_source_peek_uid (selected_source)); - } - - e_source_selector_free_selection (priv->source_selection); - priv->source_selection = selection; - - /* Save the selection for next time we start up */ - calendar_config_set_tasks_selected (uids_selected); - g_slist_free (uids_selected); -} - -static void -update_uri_for_primary_selection (TasksComponent *component) -{ - TasksComponentPrivate *priv; - ESource *source; - char *uri; - - priv = component->priv; - - source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (priv->source_selector)); - if (!source) - return; - - /* Set the default */ - uri = e_source_get_uri (source); - e_tasks_set_default_uri (priv->tasks, uri); - g_free (uri); - - /* Save the selection for next time we start up */ - calendar_config_set_primary_tasks (e_source_peek_uid (source)); -} - -static void -update_selection (TasksComponent *task_component) -{ - TasksComponentPrivate *priv; - GSList *selection, *uids_selected, *l; - - priv = task_component->priv; - - /* Get the selection in gconf */ - uids_selected = calendar_config_get_tasks_selected (); - - /* Remove any that aren't there any more */ - selection = e_source_selector_get_selection (E_SOURCE_SELECTOR (priv->source_selector)); - - for (l = selection; l; l = l->next) { - ESource *source = l->data; - - if (!is_in_uids (uids_selected, source)) - e_source_selector_unselect_source (E_SOURCE_SELECTOR (priv->source_selector), source); - } - - e_source_selector_free_selection (selection); - - /* Make sure the whole selection is there */ - for (l = uids_selected; l; l = l->next) { - char *uid = l->data; - ESource *source; - - source = e_source_list_peek_source_by_uid (priv->source_list, uid); - if (source) - e_source_selector_select_source (E_SOURCE_SELECTOR (priv->source_selector), source); - - g_free (uid); - } - g_slist_free (uids_selected); -} - -static void -update_primary_selection (TasksComponent *component) -{ - TasksComponentPrivate *priv; - ESource *source; - char *uid; - - priv = component->priv; - - uid = calendar_config_get_primary_tasks (); - if (uid) { - source = e_source_list_peek_source_by_uid (priv->source_list, uid); - g_free (uid); - - e_source_selector_set_primary_selection (E_SOURCE_SELECTOR (priv->source_selector), source); - } else { - ESource *source; - - /* Try to create a default if there isn't one */ - source = find_first_source (priv->source_list); - if (source) - e_source_selector_set_primary_selection (E_SOURCE_SELECTOR (priv->source_selector), source); - } -} - -/* FIXME This is duplicated from comp-editor-factory.c, should it go in comp-util? */ -static ECalComponent * -get_default_task (ECal *ecal) -{ - ECalComponent *comp; - - comp = cal_comp_task_new_with_defaults (ecal); - - return comp; -} - -/* Callbacks. */ -static void -add_popup_menu_item (GtkMenu *menu, const char *label, const char *pixmap, - GCallback callback, gpointer user_data, gboolean sensitive) -{ - GtkWidget *item, *image; - - if (pixmap) { - item = gtk_image_menu_item_new_with_label (label); - - /* load the image */ - image = gtk_image_new_from_stock (pixmap, GTK_ICON_SIZE_MENU); - if (!image) - image = gtk_image_new_from_file (pixmap); - - if (image) { - gtk_widget_show (image); - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); - } - } else { - item = gtk_menu_item_new_with_label (label); - } - - if (callback) - g_signal_connect (G_OBJECT (item), "activate", callback, user_data); - - if (!sensitive) - gtk_widget_set_sensitive (item, FALSE); - - gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); - gtk_widget_show (item); -} - -static void -copy_task_list_cb (GtkWidget *widget, TasksComponent *comp) -{ - ESource *selected_source; - TasksComponentPrivate *priv; - - priv = comp->priv; - - selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (priv->source_selector)); - if (!selected_source) - return; - - copy_source_dialog (GTK_WINDOW (gtk_widget_get_toplevel (widget)), selected_source, CALOBJ_TYPE_TODO); -} - -static void -delete_task_list_cb (GtkWidget *widget, TasksComponent *comp) -{ - ESource *selected_source; - TasksComponentPrivate *priv; - GtkWidget *dialog; - - priv = comp->priv; - - selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (priv->source_selector)); - if (!selected_source) - return; - - /* create the confirmation dialog */ - dialog = gtk_message_dialog_new ( - GTK_WINDOW (gtk_widget_get_toplevel (widget)), - GTK_DIALOG_MODAL, - GTK_MESSAGE_QUESTION, - GTK_BUTTONS_YES_NO, - _("Task List '%s' will be removed. Are you sure you want to continue?"), - e_source_peek_name (selected_source)); - if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_YES) { - if (e_source_selector_source_is_selected (E_SOURCE_SELECTOR (priv->source_selector), - selected_source)) - e_source_selector_unselect_source (E_SOURCE_SELECTOR (priv->source_selector), - selected_source); - - e_source_group_remove_source (e_source_peek_group (selected_source), selected_source); - - /* FIXME: remove the tasks.ics file and the directory */ - } - - gtk_widget_destroy (dialog); -} - -static void -new_task_list_cb (GtkWidget *widget, TasksComponent *component) -{ - new_task_list_dialog (GTK_WINDOW (gtk_widget_get_toplevel (widget))); -} - -static void -rename_task_list_cb (GtkWidget *widget, TasksComponent *comp) -{ - TasksComponentPrivate *priv; - ESource *selected_source; - GtkWidget *dialog, *entry; - - priv = comp->priv; - - selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (priv->source_selector)); - if (!selected_source) - return; - - /* create the dialog to prompt the user for the new name */ - dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (widget)), - GTK_DIALOG_MODAL, - GTK_MESSAGE_QUESTION, - GTK_BUTTONS_OK_CANCEL, - _("Rename this task list to")); - entry = gtk_entry_new (); - gtk_entry_set_text (GTK_ENTRY (entry), e_source_peek_name (selected_source)); - gtk_widget_show (entry); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), entry, TRUE, FALSE, 6); - - if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) - e_source_set_name (selected_source, gtk_entry_get_text (GTK_ENTRY (entry))); - - gtk_widget_destroy (dialog); -} - -static void -fill_popup_menu_cb (ESourceSelector *selector, GtkMenu *menu, TasksComponent *component) -{ - gboolean sensitive; - - sensitive = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component->priv->source_selector)) ? - TRUE : FALSE; - - add_popup_menu_item (menu, _("New Task List"), GTK_STOCK_NEW, G_CALLBACK (new_task_list_cb), - component, TRUE); - add_popup_menu_item (menu, _("Copy"), NULL, G_CALLBACK (copy_task_list_cb), component, sensitive); - add_popup_menu_item (menu, _("Rename"), NULL, G_CALLBACK (rename_task_list_cb), - component, sensitive); - add_popup_menu_item (menu, _("Delete"), GTK_STOCK_DELETE, G_CALLBACK (delete_task_list_cb), - component, sensitive); -} - -static void -source_selection_changed_cb (ESourceSelector *selector, TasksComponent *component) -{ - update_uris_for_selection (component); -} - -static void -primary_source_selection_changed_cb (ESourceSelector *selector, TasksComponent *component) -{ - update_uri_for_primary_selection (component); -} - -static void -config_selection_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - update_selection (data); -} - -static void -config_primary_selection_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - update_primary_selection (data); -} - -/* GObject methods */ - -static void -impl_dispose (GObject *object) -{ - TasksComponentPrivate *priv = TASKS_COMPONENT (object)->priv; - GList *l; - - if (priv->source_list != NULL) { - g_object_unref (priv->source_list); - priv->source_list = NULL; - } - - if (priv->source_selection != NULL) { - e_source_selector_free_selection (priv->source_selection); - priv->source_selection = NULL; - } - - if (priv->gconf_client != NULL) { - g_object_unref (priv->gconf_client); - priv->gconf_client = NULL; - } - - if (priv->create_ecal) { - g_object_unref (priv->create_ecal); - priv->create_ecal = NULL; - } - - for (l = priv->notifications; l; l = l->next) - calendar_config_remove_notification (GPOINTER_TO_UINT (l->data)); - g_list_free (priv->notifications); - priv->notifications = NULL; - - (* G_OBJECT_CLASS (parent_class)->dispose) (object); -} - -static void -impl_finalize (GObject *object) -{ - TasksComponentPrivate *priv = TASKS_COMPONENT (object)->priv; - - g_free (priv->config_directory); - g_free (priv); - - (* G_OBJECT_CLASS (parent_class)->finalize) (object); -} - -/* Evolution::Component CORBA methods */ - -static void -control_activate_cb (BonoboControl *control, gboolean activate, gpointer data) -{ - ETasks *tasks = data; - - if (activate) - tasks_control_activate (control, tasks); - else - tasks_control_deactivate (control, tasks); -} - -static void -impl_createControls (PortableServer_Servant servant, - Bonobo_Control *corba_sidebar_control, - Bonobo_Control *corba_view_control, - Bonobo_Control *corba_statusbar_control, - CORBA_Environment *ev) -{ - TasksComponent *component = TASKS_COMPONENT (bonobo_object_from_servant (servant)); - TasksComponentPrivate *priv; - GtkWidget *selector_scrolled_window; - BonoboControl *sidebar_control, *view_control; - guint not; - - priv = component->priv; - - /* create sidebar selector */ - priv->source_selector = e_source_selector_new (priv->source_list); - gtk_widget_show (priv->source_selector); - - selector_scrolled_window = gtk_scrolled_window_new (NULL, NULL); - gtk_container_add (GTK_CONTAINER (selector_scrolled_window), priv->source_selector); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (selector_scrolled_window), - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (selector_scrolled_window), - GTK_SHADOW_IN); - gtk_widget_show (selector_scrolled_window); - - sidebar_control = bonobo_control_new (selector_scrolled_window); - - /* create the tasks view */ - priv->tasks = E_TASKS (e_tasks_new ()); - if (!priv->tasks) { - g_warning (G_STRLOC ": could not create the control!"); - bonobo_exception_set (ev, ex_GNOME_Evolution_Component_Failed); - return; - } - - gtk_widget_show (GTK_WIDGET (priv->tasks)); - - view_control = bonobo_control_new (GTK_WIDGET (priv->tasks)); - if (!view_control) { - g_warning (G_STRLOC ": could not create the control!"); - bonobo_exception_set (ev, ex_GNOME_Evolution_Component_Failed); - return; - } - - g_signal_connect (view_control, "activate", G_CALLBACK (control_activate_cb), priv->tasks); - - g_signal_connect_object (priv->source_selector, "selection_changed", - G_CALLBACK (source_selection_changed_cb), - G_OBJECT (component), 0); - g_signal_connect_object (priv->source_selector, "primary_selection_changed", - G_CALLBACK (primary_source_selection_changed_cb), - G_OBJECT (component), 0); - g_signal_connect_object (priv->source_selector, "fill_popup_menu", - G_CALLBACK (fill_popup_menu_cb), - G_OBJECT (component), 0); - - /* Load the selection from the last run */ - update_selection (component); - update_primary_selection (component); - - /* If it gets fiddled with update */ - not = calendar_config_add_notification_tasks_selected (config_selection_changed_cb, - component); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - not = calendar_config_add_notification_primary_tasks (config_primary_selection_changed_cb, - component); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - /* Return the controls */ - *corba_sidebar_control = CORBA_Object_duplicate (BONOBO_OBJREF (sidebar_control), ev); - *corba_view_control = CORBA_Object_duplicate (BONOBO_OBJREF (view_control), ev); - - /* The tasks component doesn't use the status bar so just return an empty label. */ - { - GtkWidget *label = gtk_label_new (""); - BonoboControl *control; - - gtk_widget_show (label); - control = bonobo_control_new (label); - *corba_statusbar_control = CORBA_Object_duplicate (BONOBO_OBJREF (control), ev); - } -} - -static GNOME_Evolution_CreatableItemTypeList * -impl__get_userCreatableItems (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - GNOME_Evolution_CreatableItemTypeList *list = GNOME_Evolution_CreatableItemTypeList__alloc (); - - list->_length = 1; - list->_maximum = list->_length; - list->_buffer = GNOME_Evolution_CreatableItemTypeList_allocbuf (list->_length); - - CORBA_sequence_set_release (list, FALSE); - - list->_buffer[0].id = CREATE_TASK_ID; - list->_buffer[0].description = _("New task"); - list->_buffer[0].menuDescription = _("_Task"); - list->_buffer[0].tooltip = _("Create a new task"); - list->_buffer[0].menuShortcut = 't'; - list->_buffer[0].iconName = "new_task-16.png"; - - return list; -} - -static void -config_create_ecal_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) -{ - TasksComponent *component = data; - TasksComponentPrivate *priv; - - priv = component->priv; - - g_object_unref (priv->create_ecal); - priv->create_ecal = NULL; - - priv->notifications = g_list_remove (priv->notifications, GUINT_TO_POINTER (id)); -} - -static gboolean -setup_create_ecal (TasksComponent *component) -{ - TasksComponentPrivate *priv; - ESource *source = NULL; - char *uid; - guint not; - - priv = component->priv; - - if (priv->create_ecal) - return TRUE; - - /* Try to use the client from the calendar first to avoid re-opening things */ - if (priv->tasks) { - ECal *default_ecal; - - default_ecal = e_tasks_get_default_client (priv->tasks); - if (default_ecal) { - priv->create_ecal = g_object_ref (default_ecal); - return TRUE; - } - } - - /* Get the current primary calendar, or try to set one if it doesn't already exist */ - uid = calendar_config_get_primary_tasks (); - if (uid) { - source = e_source_list_peek_source_by_uid (priv->source_list, uid); - g_free (uid); - - priv->create_ecal = e_cal_new (source, CALOBJ_TYPE_TODO); - } - - if (!priv->create_ecal) { - /* Try to create a default if there isn't one */ - source = find_first_source (priv->source_list); - if (source) - priv->create_ecal = e_cal_new (source, CALOBJ_TYPE_TODO); - } - - if (priv->create_ecal) { - if (!e_cal_open (priv->create_ecal, FALSE, NULL)) { - GtkWidget *dialog; - - dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, - GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, - _("Unable to open the task list '%s' for creating events and meetings"), - e_source_peek_name (source)); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - - return FALSE; - } - } else { - GtkWidget *dialog; - - dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, - GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, - _("There is no calendar available for creating tasks")); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - - return FALSE; - } - - /* Handle the fact it may change on us */ - not = calendar_config_add_notification_primary_calendar (config_create_ecal_changed_cb, - component); - priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); - - /* Save the primary source for use elsewhere */ - calendar_config_set_primary_tasks (e_source_peek_uid (source)); - - return TRUE; -} - -static void -impl_requestCreateItem (PortableServer_Servant servant, - const CORBA_char *item_type_name, - CORBA_Environment *ev) -{ - TasksComponent *tasks_component = TASKS_COMPONENT (bonobo_object_from_servant (servant)); - TasksComponentPrivate *priv; - ECalComponent *comp; - TaskEditor *editor; - - priv = tasks_component->priv; - - if (!setup_create_ecal (tasks_component)) - return; - - editor = task_editor_new (priv->create_ecal); - - if (strcmp (item_type_name, CREATE_TASK_ID) == 0) { - comp = get_default_task (priv->create_ecal); - } else { - bonobo_exception_set (ev, ex_GNOME_Evolution_Component_UnknownType); - return; - } - - comp_editor_edit_comp (COMP_EDITOR (editor), comp); - comp_editor_focus (COMP_EDITOR (editor)); - - e_comp_editor_registry_add (comp_editor_registry, COMP_EDITOR (editor), TRUE); -} - -/* Initialization */ - -static void -tasks_component_class_init (TasksComponentClass *klass) -{ - POA_GNOME_Evolution_Component__epv *epv = &klass->epv; - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - epv->createControls = impl_createControls; - epv->_get_userCreatableItems = impl__get_userCreatableItems; - epv->requestCreateItem = impl_requestCreateItem; - - object_class->dispose = impl_dispose; - object_class->finalize = impl_finalize; -} - -static void -tasks_component_init (TasksComponent *component, TasksComponentClass *klass) -{ - TasksComponentPrivate *priv; - GSList *groups; - - priv = g_new0 (TasksComponentPrivate, 1); - priv->config_directory = g_build_filename (g_get_home_dir (), - ".evolution", "tasks", "config", - NULL); - - /* load the groups from the configuration */ - priv->gconf_client = gconf_client_get_default (); - priv->source_list = e_source_list_new_for_gconf (priv->gconf_client, - "/apps/evolution/tasks/sources"); - - /* create default tasks folders if there are no groups */ - groups = e_source_list_peek_groups (priv->source_list); - if (!groups) { - ESourceGroup *group; - ESource *source; - char *base_uri, *new_dir; - - /* create the source group */ - base_uri = g_build_filename (g_get_home_dir (), - ".evolution/tasks/local/OnThisComputer/", - NULL); - group = e_source_group_new (_("On This Computer"), base_uri); - e_source_list_add_group (priv->source_list, group, -1); - - /* migrate tasks from older setup */ - if (!migrate_old_tasks (group)) { - /* create default tasks folders */ - new_dir = g_build_filename (base_uri, "Personal/", NULL); - if (!e_mkdir_hier (new_dir, 0700)) { - source = e_source_new (_("Personal"), "Personal"); - e_source_group_add_source (group, source, -1); - } - - g_free (new_dir); - } - - g_free (base_uri); - } - - component->priv = priv; -} - -/* Public API */ - -TasksComponent * -tasks_component_peek (void) -{ - static TasksComponent *component = NULL; - - if (component == NULL) { - component = g_object_new (tasks_component_get_type (), NULL); - - if (e_mkdir_hier (component->priv->config_directory, 0777) != 0) { - g_warning (G_STRLOC ": Cannot create directory %s: %s", - component->priv->config_directory, g_strerror (errno)); - g_object_unref (component); - component = NULL; - } - } - - return component; -} - -const char * -tasks_component_peek_config_directory (TasksComponent *component) -{ - return (const char *) component->priv->config_directory; -} - -BONOBO_TYPE_FUNC_FULL (TasksComponent, GNOME_Evolution_Component, PARENT_TYPE, tasks_component) diff --git a/calendar/gui/tasks-component.h b/calendar/gui/tasks-component.h deleted file mode 100644 index 1c47c4d9b1..0000000000 --- a/calendar/gui/tasks-component.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* tasks-component.h - * - * Copyright (C) 2003 Rodrigo Moya - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Author: Rodrigo Moya <rodrigo@ximian.com> - */ - -#ifndef _TASKS_COMPONENT_H_ -#define _TASKS_COMPONENT_H_ - -#include <bonobo/bonobo-object.h> -#include <libedataserver/e-source-list.h> -#include "Evolution.h" - - -#define TASKS_TYPE_COMPONENT (tasks_component_get_type ()) -#define TASKS_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TASKS_TYPE_COMPONENT, TasksComponent)) -#define TASKS_COMPONENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TASKS_TYPE_COMPONENT, TasksComponentClass)) -#define TASKS_IS_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TASKS_TYPE_COMPONENT)) -#define TASKS_IS_COMPONENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), TASKS_TYPE_COMPONENT)) - - -typedef struct _TasksComponent TasksComponent; -typedef struct _TasksComponentPrivate TasksComponentPrivate; -typedef struct _TasksComponentClass TasksComponentClass; - -struct _TasksComponent { - BonoboObject parent; - - TasksComponentPrivate *priv; -}; - -struct _TasksComponentClass { - BonoboObjectClass parent_class; - - POA_GNOME_Evolution_Component__epv epv; -}; - - -GType tasks_component_get_type (void); -TasksComponent *tasks_component_peek (void); -const char *tasks_component_peek_config_directory (TasksComponent *component); -ESourceList *tasks_component_peek_source_list (TasksComponent *component); - -#endif /* _TASKS_COMPONENT_H_ */ diff --git a/calendar/gui/tasks-control.c b/calendar/gui/tasks-control.c deleted file mode 100644 index 0c0a3bd202..0000000000 --- a/calendar/gui/tasks-control.c +++ /dev/null @@ -1,627 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* tasks-control.c - * - * Copyright (C) 2000, 2001, 2002, 2003 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: Damon Chaplin <damon@ximian.com> - * Ettore Perazzoli - */ - -#include <config.h> -#include <gtk/gtksignal.h> -#include <gtk/gtklabel.h> -#include <gtk/gtkcheckbutton.h> -#include <gtk/gtkmessagedialog.h> -#include <libgnome/gnome-i18n.h> -#include <libgnome/gnome-util.h> -#include <libgnomeui/gnome-dialog.h> -#include <libgnomeui/gnome-dialog-util.h> -#include <libgnomeui/gnome-stock-icons.h> -#include <libgnomeprint/gnome-print.h> -#include <libgnomeprint/gnome-print-paper.h> -#include <libgnomeprint/gnome-print-job.h> -#include <libgnomeprintui/gnome-print-job-preview.h> -#include <libgnomeprintui/gnome-print-paper-selector.h> -#include <libgnomeprintui/gnome-print-preview.h> -#include <libgnomeprintui/gnome-print-dialog.h> -#include <bonobo/bonobo-control.h> -#include <bonobo/bonobo-property-bag.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 "e-calendar-table.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 -#define FIXED_MARGIN .05 - - -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_new_task_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path); -static void tasks_control_cut_cmd (BonoboUIComponent *uic, - gpointer data, - const gchar *path); -static void tasks_control_copy_cmd (BonoboUIComponent *uic, - gpointer data, - const gchar *path); -static void tasks_control_paste_cmd (BonoboUIComponent *uic, - gpointer data, - const gchar *path); -static void tasks_control_delete_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path); -static void tasks_control_complete_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path); -static void tasks_control_purge_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path); -static void tasks_control_print_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path); -static void tasks_control_print_preview_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path); - - -static GnomePrintConfig *print_config = NULL; - - -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)); - - g_signal_connect (control, "activate", G_CALLBACK (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, bonobo_object_corba_objref (BONOBO_OBJECT (pbag)), NULL); - 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; - const char *uri; - ECalModel *model; - - switch (arg_id) { - - case TASKS_CONTROL_PROPERTY_URI_IDX: - model = e_calendar_table_get_model (e_tasks_get_calendar_table (tasks)); - uri = e_cal_get_uri (e_cal_model_get_default_client (model)); - 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: - /* FIXME Remove the old uri? */ - uri = BONOBO_ARG_GET_STRING (arg); - if (!e_tasks_add_todo_uri (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; - gboolean read_only = TRUE; - ECalModel *model; - - uic = bonobo_control_get_ui_component (control); - g_assert (uic != NULL); - - model = e_calendar_table_get_model (e_tasks_get_calendar_table (tasks)); - e_cal_is_read_only (e_cal_model_get_default_client (model), &read_only, NULL); - - bonobo_ui_component_set_prop (uic, "/commands/TasksCut", "sensitive", - n_selected == 0 || read_only ? "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/TasksPaste", "sensitive", - read_only ? "0" : "1", - NULL); - bonobo_ui_component_set_prop (uic, "/commands/TasksDelete", "sensitive", - n_selected == 0 || read_only ? "0" : "1", - NULL); - bonobo_ui_component_set_prop (uic, "/commands/TasksMarkComplete", "sensitive", - n_selected == 0 || read_only ? "0" : "1", - NULL); - bonobo_ui_component_set_prop (uic, "/commands/TasksPurge", "sensitive", - read_only ? "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 ("TasksPurge", tasks_control_purge_cmd), - BONOBO_UI_VERB ("TasksPrint", tasks_control_print_cmd), - BONOBO_UI_VERB ("TasksPrintPreview", tasks_control_print_preview_cmd), - - BONOBO_UI_VERB_END -}; - -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); - - remote_uih = bonobo_control_get_remote_ui_container (control, NULL); - bonobo_ui_component_set_container (uic, remote_uih, NULL); - bonobo_object_release_unref (remote_uih, NULL); - - e_tasks_set_ui_component (tasks, uic); - - bonobo_ui_component_add_verb_list_with_data (uic, verbs, tasks); - - bonobo_ui_component_freeze (uic, NULL); - - bonobo_ui_util_set_ui (uic, PREFIX, - EVOLUTION_UIDIR "/evolution-tasks.xml", - "evolution-tasks", - NULL); - - e_tasks_setup_view_menus (tasks, uic); - - /* Signals from the tasks widget; also sensitize the menu items as appropriate */ - - g_signal_connect (tasks, "selection_changed", G_CALLBACK (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 -} - - -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 */ - g_signal_handlers_disconnect_matched (tasks, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, control); - - bonobo_ui_component_rm (uic, "/", NULL); - bonobo_ui_component_unset_container (uic, NULL); -} - - -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_purge (ETasks *tasks) -{ - GtkWidget *dialog, *checkbox, *parent; - int button; - - if (!calendar_config_get_confirm_purge ()) - return TRUE; - - parent = gtk_widget_get_toplevel (GTK_WIDGET (tasks)); - dialog = gtk_message_dialog_new ( - (GtkWindow *)parent, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_WARNING, - GTK_BUTTONS_YES_NO, - _("This operation will permanently erase all tasks marked as completed. If you continue, you will not be able to recover these tasks.\n\nReally erase these tasks?")); - gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_NO); - - checkbox = gtk_check_button_new_with_label (_("Do not ask me again.")); - gtk_widget_show (checkbox); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), checkbox, TRUE, TRUE, 6); - - button = gtk_dialog_run (GTK_DIALOG (dialog)); - if (button == GTK_RESPONSE_YES && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbox))) - calendar_config_set_confirm_purge (FALSE); - gtk_widget_destroy (dialog); - - return button == GTK_RESPONSE_YES ? TRUE : FALSE; -} - -static void -tasks_control_purge_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path) -{ - ETasks *tasks; - - tasks = E_TASKS (data); - - if (confirm_purge (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_find_closest ("Sans Bold", 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); - - g_object_unref (font); -} - -static void -print_tasks (ETasks *tasks, gboolean preview) -{ - ECalendarTable *cal_table; - EPrintable *printable; - ETable *etable; - GnomePrintContext *pc; - GnomePrintJob *gpm; - double l, r, t, b, page_width, page_height, left_margin, bottom_margin; - - if (!print_config) - print_config = gnome_print_config_default (); - - 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); - g_object_ref (printable); - gtk_object_sink (GTK_OBJECT (printable)); - e_printable_reset (printable); - - gpm = gnome_print_job_new (print_config); - pc = gnome_print_job_get_context (gpm); - - gnome_print_config_get_page_size (print_config, &r, &t); - -#if 0 - gnome_print_config_get_double (print_config, GNOME_PRINT_KEY_PAGE_MARGIN_TOP, &temp_d); - t -= temp_d; - gnome_print_config_get_double (print_config, GNOME_PRINT_KEY_PAGE_MARGIN_RIGHT, &temp_d); - r -= temp_d; - gnome_print_config_get_double (print_config, GNOME_PRINT_KEY_PAGE_MARGIN_BOTTOM, &b); - gnome_print_config_get_double (print_config, GNOME_PRINT_KEY_PAGE_MARGIN_LEFT, &l); -#endif - - b = t * FIXED_MARGIN; - l = r * FIXED_MARGIN; - t *= (1.0 - FIXED_MARGIN); - r *= (1.0 - FIXED_MARGIN); - - 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); - - 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_job_close (gpm); - - if (preview) { - GtkWidget *gpmp; - gpmp = gnome_print_job_preview_new (gpm, _("Print Preview")); - gtk_widget_show (gpmp); - } else { - gnome_print_job_print (gpm); - } - - g_object_unref (gpm); - g_object_unref (printable); -} - - -/* File/Print callback */ -static void -tasks_control_print_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path) -{ - ETasks *tasks; - GtkWidget *gpd; - gboolean preview = FALSE; - GnomePrintJob *gpm; - - tasks = E_TASKS (data); - - if (!print_config) - print_config = gnome_print_config_default (); - - gpm = gnome_print_job_new (print_config); - - gpd = gnome_print_dialog_new (gpm, _("Print Tasks"), GNOME_PRINT_DIALOG_COPIES); - gtk_dialog_set_default_response (GTK_DIALOG (gpd), GNOME_PRINT_DIALOG_RESPONSE_PRINT); - - /* Run dialog */ - switch (gtk_dialog_run (GTK_DIALOG (gpd))) { - case GNOME_PRINT_DIALOG_RESPONSE_PRINT: - break; - - case GNOME_PRINT_DIALOG_RESPONSE_PREVIEW: - preview = TRUE; - break; - - case -1: - return; - - default: - gtk_widget_destroy (gpd); - return; - } - - gtk_widget_destroy (gpd); - print_tasks (tasks, preview); -} - -static void -tasks_control_print_preview_cmd (BonoboUIComponent *uic, - gpointer data, - const char *path) -{ - ETasks *tasks; - - tasks = E_TASKS (data); - - print_tasks (tasks, TRUE); -} - diff --git a/calendar/gui/tasks-control.h b/calendar/gui/tasks-control.h deleted file mode 100644 index eca68c3f0a..0000000000 --- a/calendar/gui/tasks-control.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* tasks-control.h - * - * Copyright (C) 2000, 2001, 2002, 2003 Ximian, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - * - * Authors: Federico Mena Quintero <federico@ximian.com> - * Damon Chaplin <damon@ximian.com> - */ - -#ifndef _TASKS_CONTROL_H_ -#define _TASKS_CONTROL_H_ - -#include "e-tasks.h" - -BonoboControl *tasks_control_new (void); -void tasks_control_activate (BonoboControl *control, ETasks *tasks); -void tasks_control_deactivate (BonoboControl *control, ETasks *tasks); - - -#endif /* _TASKS_CONTROL_H_ */ diff --git a/calendar/gui/weekday-picker.c b/calendar/gui/weekday-picker.c deleted file mode 100644 index 87438fd62d..0000000000 --- a/calendar/gui/weekday-picker.c +++ /dev/null @@ -1,572 +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-i18n.h> -#include <libgnomecanvas/gnome-canvas-rect-ellipse.h> -#include <libgnomecanvas/gnome-canvas-text.h> -#include <gal/util/e-util.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_destroy (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]; - - - -E_MAKE_TYPE (weekday_picker, "WeekdayPicker", WeekdayPicker, - weekday_picker_class_init, weekday_picker_init, GNOME_TYPE_CANVAS); - -/* 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 = g_type_class_peek_parent (class); - - wp_signals[CHANGED] = - gtk_signal_new ("changed", - GTK_RUN_FIRST, - G_TYPE_FROM_CLASS (object_class), - GTK_SIGNAL_OFFSET (WeekdayPickerClass, changed), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - object_class->destroy = weekday_picker_destroy; - - 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); - g_signal_connect (priv->boxes[i], "event", G_CALLBACK (day_event_cb), wp); - - priv->labels[i] = gnome_canvas_item_new (parent, - GNOME_TYPE_CANVAS_TEXT, - NULL); - g_signal_connect (priv->labels[i], "event", G_CALLBACK (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_destroy (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)->destroy) - (* GTK_OBJECT_CLASS (parent_class)->destroy) (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 char * -get_day_text (int day_index) -{ - const char *str = _("SMTWTFS"); - char *day; - int char_size = 0; - - day = g_utf8_offset_to_pointer (str, day_index); - - /* we use strlen because we actually want to count bytes */ - if (day_index == 6) - char_size = strlen (day); - else - char_size = strlen (day) - strlen (g_utf8_find_next_char (day, NULL)); - - return g_strndup (day, char_size); -} - -static void -configure_items (WeekdayPicker *wp) -{ - WeekdayPickerPrivate *priv; - int width, height; - int box_width; - int i; - - priv = wp->priv; - - width = GTK_WIDGET (wp)->allocation.width; - height = GTK_WIDGET (wp)->allocation.height; - - box_width = (width - 1) / 7; - - 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 = get_day_text (day); - gnome_canvas_item_set (priv->labels[i], - "text", c, -#if 0 - "font_gdk", gtk_style_get_font (gtk_widget_get_style (GTK_WIDGET (wp))), -#endif - "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; - int i; - PangoFontDescription *font_desc; - PangoContext *pango_context; - PangoFontMetrics *font_metrics; - PangoLayout *layout; - - wp = WEEKDAY_PICKER (widget); - priv = wp->priv; - - /* Set up Pango prerequisites */ - font_desc = gtk_widget_get_style (widget)->font_desc; - pango_context = gtk_widget_get_pango_context (widget); - font_metrics = pango_context_get_metrics (pango_context, font_desc, - pango_context_get_language (pango_context)); - layout = pango_layout_new (pango_context); - - priv->font_ascent = PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)); - priv->font_descent = PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics)); - - max_width = 0; - - for (i = 0; i < 7; i++) { - char *c; - int w; - - c = get_day_text (i); - pango_layout_set_text (layout, c, strlen (c)); - pango_layout_get_pixel_size (layout, &w, NULL); - g_free (c); - - if (w > max_width) - max_width = w; - } - - priv->max_letter_width = max_width; - - configure_items (wp); - g_object_unref (layout); - pango_font_metrics_unref (font_metrics); - - 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 g_object_new (TYPE_WEEKDAY_PICKER, NULL); -} - -/** - * 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 67a72f9ebd..0000000000 --- a/calendar/gui/weekday-picker.h +++ /dev/null @@ -1,71 +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 <libgnomecanvas/gnome-canvas.h> - -G_BEGIN_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); - - - -G_END_DECLS - -#endif |