aboutsummaryrefslogtreecommitdiffstats
path: root/calendar
diff options
context:
space:
mode:
authorJP Rosevear <jpr@ximian.com>2001-06-02 07:54:43 +0800
committerJP Rosevear <jpr@src.gnome.org>2001-06-02 07:54:43 +0800
commitf4e8698fdd4c48422f217f409e92ec7a2d26c443 (patch)
tree52e697a2a46e790a2d8059680c7a3bff252e97ad /calendar
parent58d8f86e64d42782ac80ec4ed40b5269a3493454 (diff)
downloadgsoc2013-evolution-f4e8698fdd4c48422f217f409e92ec7a2d26c443.tar
gsoc2013-evolution-f4e8698fdd4c48422f217f409e92ec7a2d26c443.tar.gz
gsoc2013-evolution-f4e8698fdd4c48422f217f409e92ec7a2d26c443.tar.bz2
gsoc2013-evolution-f4e8698fdd4c48422f217f409e92ec7a2d26c443.tar.lz
gsoc2013-evolution-f4e8698fdd4c48422f217f409e92ec7a2d26c443.tar.xz
gsoc2013-evolution-f4e8698fdd4c48422f217f409e92ec7a2d26c443.tar.zst
gsoc2013-evolution-f4e8698fdd4c48422f217f409e92ec7a2d26c443.zip
renamed from editor-page for consistency, more complete implementation
2001-06-01 JP Rosevear <jpr@ximian.com> * gui/dialogs/comp-editor-page.[hc]: renamed from editor-page for consistency, more complete implementation * gui/dialogs/comp-editor.[hc]: More complete implementation * gui/dialogs/*-page.*: The various pages needed to construct the event and task dialogs * gui/dialogs/comp-editor-util.[hc]: useful utility functions for the component editor pages to use * gui/dialogs/Makefile.am: Build and install new files * gui/event-editor*: Remove, obsoleted by the new comp-editor stuff * gui/dialogs/task-editor-dialog.glade: ditto * gui/e-calendar-table.c (open_task): update to use comp editor stuff * gui/e-tasks.c (e_tasks_new_task): ditto * gui/gnome-cal.c (gnome_calendar_edit_object): ditto * gui/Makefile.am: don't build non-existent files nor try to install them svn path=/trunk/; revision=10088
Diffstat (limited to 'calendar')
-rw-r--r--calendar/ChangeLog30
-rw-r--r--calendar/gui/Makefile.am6
-rw-r--r--calendar/gui/dialogs/Makefile.am17
-rw-r--r--calendar/gui/dialogs/alarm-page.c175
-rw-r--r--calendar/gui/dialogs/alarm-page.glade87
-rw-r--r--calendar/gui/dialogs/alarm-page.h14
-rw-r--r--calendar/gui/dialogs/comp-editor-page.c277
-rw-r--r--calendar/gui/dialogs/comp-editor-page.h93
-rw-r--r--calendar/gui/dialogs/comp-editor-util.c129
-rw-r--r--calendar/gui/dialogs/comp-editor-util.h31
-rw-r--r--calendar/gui/dialogs/comp-editor.c385
-rw-r--r--calendar/gui/dialogs/comp-editor.h23
-rw-r--r--calendar/gui/dialogs/editor-page.c260
-rw-r--r--calendar/gui/dialogs/editor-page.h86
-rw-r--r--calendar/gui/dialogs/event-editor.c155
-rw-r--r--calendar/gui/dialogs/event-editor.h (renamed from calendar/gui/event-editor.h)37
-rw-r--r--calendar/gui/dialogs/event-page.c281
-rw-r--r--calendar/gui/dialogs/event-page.glade3
-rw-r--r--calendar/gui/dialogs/event-page.h20
-rw-r--r--calendar/gui/dialogs/recurrence-page.c338
-rw-r--r--calendar/gui/dialogs/recurrence-page.glade85
-rw-r--r--calendar/gui/dialogs/recurrence-page.h14
-rw-r--r--calendar/gui/dialogs/task-details-page.c461
-rw-r--r--calendar/gui/dialogs/task-details-page.glade318
-rw-r--r--calendar/gui/dialogs/task-details-page.h62
-rw-r--r--calendar/gui/dialogs/task-editor-dialog.glade695
-rw-r--r--calendar/gui/dialogs/task-editor.c1301
-rw-r--r--calendar/gui/dialogs/task-editor.h83
-rw-r--r--calendar/gui/dialogs/task-page.c966
-rw-r--r--calendar/gui/dialogs/task-page.glade15
-rw-r--r--calendar/gui/dialogs/task-page.h61
-rw-r--r--calendar/gui/e-calendar-table.c7
-rw-r--r--calendar/gui/e-tasks.c7
-rw-r--r--calendar/gui/event-editor-dialog.glade1408
-rw-r--r--calendar/gui/event-editor.c3377
-rw-r--r--calendar/gui/gnome-cal.c8
36 files changed, 3562 insertions, 7753 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog
index b39133a852..985f817fb1 100644
--- a/calendar/ChangeLog
+++ b/calendar/ChangeLog
@@ -1,5 +1,35 @@
2001-06-01 JP Rosevear <jpr@ximian.com>
+ * gui/dialogs/comp-editor-page.[hc]: renamed from editor-page for
+ consistency, more complete implementation
+
+ * gui/dialogs/comp-editor.[hc]: More complete implementation
+
+ * gui/dialogs/*-page.*: The various pages needed to construct the
+ event and task dialogs
+
+ * gui/dialogs/comp-editor-util.[hc]: useful utility functions for the
+ component editor pages to use
+
+ * gui/dialogs/Makefile.am: Build and install new files
+
+ * gui/event-editor*: Remove, obsoleted by the new comp-editor
+ stuff
+
+ * gui/dialogs/task-editor-dialog.glade: ditto
+
+ * gui/e-calendar-table.c (open_task): update to use comp editor
+ stuff
+
+ * gui/e-tasks.c (e_tasks_new_task): ditto
+
+ * gui/gnome-cal.c (gnome_calendar_edit_object): ditto
+
+ * gui/Makefile.am: don't build non-existent files nor try to
+ install them
+
+2001-06-01 JP Rosevear <jpr@ximian.com>
+
* gui/e-itip-control.c (e_itip_control_factory_init): ditto
* gui/tasks-control-factory.c (tasks_control_factory_init):
diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am
index 571d4f6db8..55a19bbf4c 100644
--- a/calendar/gui/Makefile.am
+++ b/calendar/gui/Makefile.am
@@ -42,7 +42,6 @@ INCLUDES = \
gladedir = $(datadir)/evolution/glade
glade_DATA = \
- event-editor-dialog.glade \
e-meeting-dialog.glade \
e-itip-control.glade \
goto-dialog.glade
@@ -91,8 +90,6 @@ evolution_calendar_SOURCES = \
e-week-view.h \
e-tasks.c \
e-tasks.h \
- event-editor.c \
- event-editor.h \
gnome-cal.c \
gnome-cal.h \
goto.c \
@@ -131,8 +128,7 @@ evolution_calendar_LDADD = \
$(BONOBO_HTML_GNOME_LIBS) \
$(GNOME_VFS_LIBS) \
$(GAL_LIBS) \
- $(INTLLIBS) \
- $(DB3_LDADD)
+ $(INTLLIBS)
#evolution_calendar_LDFLAGS = `gnome-config --libs gdk_pixbuf`
diff --git a/calendar/gui/dialogs/Makefile.am b/calendar/gui/dialogs/Makefile.am
index 034e4060fc..74c65d72ab 100644
--- a/calendar/gui/dialogs/Makefile.am
+++ b/calendar/gui/dialogs/Makefile.am
@@ -24,10 +24,16 @@ libcal_dialogs_a_SOURCES = \
alarm-page.h \
cal-prefs-dialog.c \
cal-prefs-dialog.h \
+ comp-editor.c \
+ comp-editor.h \
+ comp-editor-page.c \
+ comp-editor-page.h \
+ comp-editor-util.c \
+ comp-editor-util.h \
delete-comp.c \
delete-comp.h \
- editor-page.c \
- editor-page.h \
+ event-editor.c \
+ event-editor.h \
event-page.c \
event-page.h \
recurrence-page.c \
@@ -35,7 +41,11 @@ libcal_dialogs_a_SOURCES = \
save-comp.c \
save-comp.h \
task-editor.c \
- task-editor.h
+ task-editor.h \
+ task-details-page.c \
+ task-details-page.h \
+ task-page.c \
+ task-page.h
glade_DATA = \
alarm-notify.glade \
@@ -44,7 +54,6 @@ glade_DATA = \
event-page.glade \
recurrence-page.glade \
task-details-page.glade \
- task-editor-dialog.glade \
task-page.glade
EXTRA_DIST = \
diff --git a/calendar/gui/dialogs/alarm-page.c b/calendar/gui/dialogs/alarm-page.c
index 85141e9c47..74e728ad4c 100644
--- a/calendar/gui/dialogs/alarm-page.c
+++ b/calendar/gui/dialogs/alarm-page.c
@@ -26,13 +26,15 @@
#include <config.h>
#endif
+#include <string.h>
#include <gtk/gtksignal.h>
#include <libgnome/gnome-defs.h>
#include <libgnome/gnome-i18n.h>
#include <glade/glade.h>
#include <gal/widgets/e-unicode.h>
-#include "cal-util/cal-util.h"
#include "e-util/e-dialog-widgets.h"
+#include "cal-util/cal-util.h"
+#include "comp-editor-util.h"
#include "alarm-page.h"
@@ -47,7 +49,7 @@ struct _AlarmPagePrivate {
GtkWidget *main;
GtkWidget *summary;
- GtkWidget *starting_date;
+ GtkWidget *date_time;
GtkWidget *list;
GtkWidget *add;
@@ -58,6 +60,8 @@ struct _AlarmPagePrivate {
GtkWidget *value_units;
GtkWidget *relative;
GtkWidget *time;
+
+ gboolean updating;
};
@@ -66,14 +70,13 @@ static void alarm_page_class_init (AlarmPageClass *class);
static void alarm_page_init (AlarmPage *apage);
static void alarm_page_destroy (GtkObject *object);
-static GtkWidget *alarm_page_get_widget (EditorPage *page);
-static void alarm_page_fill_widgets (EditorPage *page, CalComponent *comp);
-static void alarm_page_fill_component (EditorPage *page, CalComponent *comp);
-static void alarm_page_set_summary (EditorPage *page, const char *summary);
-static char *alarm_page_get_summary (EditorPage *page);
-static void alarm_page_set_dates (EditorPage *page, time_t start, time_t end);
+static GtkWidget *alarm_page_get_widget (CompEditorPage *page);
+static void alarm_page_fill_widgets (CompEditorPage *page, CalComponent *comp);
+static void alarm_page_fill_component (CompEditorPage *page, CalComponent *comp);
+static void alarm_page_set_summary (CompEditorPage *page, const char *summary);
+static void alarm_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates);
-static EditorPageClass *parent_class = NULL;
+static CompEditorPageClass *parent_class = NULL;
@@ -102,7 +105,8 @@ alarm_page_get_type (void)
(GtkClassInitFunc) NULL
};
- alarm_page_type = gtk_type_unique (TYPE_EDITOR_PAGE, &alarm_page_info);
+ alarm_page_type = gtk_type_unique (TYPE_COMP_EDITOR_PAGE,
+ &alarm_page_info);
}
return alarm_page_type;
@@ -112,19 +116,18 @@ alarm_page_get_type (void)
static void
alarm_page_class_init (AlarmPageClass *class)
{
- EditorPageClass *editor_page_class;
+ CompEditorPageClass *editor_page_class;
GtkObjectClass *object_class;
- editor_page_class = (EditorPageClass *) class;
+ editor_page_class = (CompEditorPageClass *) class;
object_class = (GtkObjectClass *) class;
- parent_class = gtk_type_class (TYPE_EDITOR_PAGE);
+ parent_class = gtk_type_class (TYPE_COMP_EDITOR_PAGE);
editor_page_class->get_widget = alarm_page_get_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->get_summary = alarm_page_get_summary;
editor_page_class->set_dates = alarm_page_set_dates;
object_class->destroy = alarm_page_destroy;
@@ -143,7 +146,7 @@ alarm_page_init (AlarmPage *apage)
priv->main = NULL;
priv->summary = NULL;
- priv->starting_date = NULL;
+ priv->date_time = NULL;
priv->list = NULL;
priv->add = NULL;
priv->delete = NULL;
@@ -152,6 +155,8 @@ alarm_page_init (AlarmPage *apage)
priv->value_units = NULL;
priv->relative = NULL;
priv->time = NULL;
+
+ priv->updating = FALSE;
}
/* Frees all the alarm data and empties the list */
@@ -159,24 +164,25 @@ static void
free_alarms (AlarmPage *apage)
{
AlarmPagePrivate *priv;
- GtkCList *clist;
int i;
priv = apage->priv;
- clist = GTK_CLIST (priv->list);
-
- for (i = 0; i < clist->rows; i++) {
- CalComponentAlarm *alarm;
-
- alarm = gtk_clist_get_row_data (clist, i);
- g_assert (alarm != NULL);
- cal_component_alarm_free (alarm);
-
- gtk_clist_set_row_data (clist, i, NULL);
+ if (priv->list != NULL) {
+ GtkCList *clist = GTK_CLIST (priv->list);
+
+ for (i = 0; i < clist->rows; i++) {
+ CalComponentAlarm *alarm;
+
+ alarm = gtk_clist_get_row_data (clist, i);
+ g_assert (alarm != NULL);
+ cal_component_alarm_free (alarm);
+
+ gtk_clist_set_row_data (clist, i, NULL);
+ }
+
+ gtk_clist_clear (clist);
}
-
- gtk_clist_clear (clist);
}
/* Destroy handler for the alarm page */
@@ -210,7 +216,7 @@ alarm_page_destroy (GtkObject *object)
/* get_widget handler for the alarm page */
static GtkWidget *
-alarm_page_get_widget (EditorPage *page)
+alarm_page_get_widget (CompEditorPage *page)
{
AlarmPage *apage;
AlarmPagePrivate *priv;
@@ -230,10 +236,10 @@ clear_widgets (AlarmPage *apage)
priv = apage->priv;
/* Summary */
- e_dialog_editable_set (priv->summary, NULL);
+ gtk_label_set_text (GTK_LABEL (priv->summary), "");
/* Start date */
- gtk_label_set_text (GTK_LABEL (priv->starting_date), "");
+ gtk_label_set_text (GTK_LABEL (priv->date_time), "");
/* List data */
free_alarms (apage);
@@ -310,6 +316,7 @@ get_alarm_string (CalComponentAlarm *alarm)
case CAL_ALARM_NONE:
case CAL_ALARM_UNKNOWN:
+ default:
base = _("Unknown");
break;
}
@@ -344,6 +351,7 @@ get_alarm_string (CalComponentAlarm *alarm)
break;
case CAL_ALARM_TRIGGER_NONE:
case CAL_ALARM_TRIGGER_ABSOLUTE:
+ default:
str = g_strdup_printf ("%s %s", base,
_("Unknown"));
break;
@@ -377,22 +385,31 @@ append_reminder (AlarmPage *apage, CalComponentAlarm *alarm)
/* fill_widgets handler for the alarm page */
static void
-alarm_page_fill_widgets (EditorPage *page, CalComponent *comp)
+alarm_page_fill_widgets (CompEditorPage *page, CalComponent *comp)
{
AlarmPage *apage;
AlarmPagePrivate *priv;
CalComponentText text;
GList *alarms, *l;
GtkCList *clist;
-
+ CompEditorPageDates dates;
+
apage = ALARM_PAGE (page);
priv = apage->priv;
+ /* Don't send off changes during this time */
+ priv->updating = TRUE;
+
+ /* Clean the page */
clear_widgets (apage);
/* Summary */
cal_component_get_summary (comp, &text);
- e_dialog_editable_set (priv->summary, text.value);
+ alarm_page_set_summary (page, text.value);
+
+ /* Dates */
+ comp_editor_dates (&dates, comp);
+ alarm_page_set_dates (page, &dates);
/* List */
if (!cal_component_has_alarms (comp))
@@ -415,11 +432,13 @@ alarm_page_fill_widgets (EditorPage *page, CalComponent *comp)
append_reminder (apage, ca_copy);
}
cal_obj_uid_list_free (alarms);
+
+ priv->updating = FALSE;
}
/* fill_component handler for the alarm page */
static void
-alarm_page_fill_component (EditorPage *page, CalComponent *comp)
+alarm_page_fill_component (CompEditorPage *page, CalComponent *comp)
{
AlarmPage *apage;
AlarmPagePrivate *priv;
@@ -462,48 +481,31 @@ alarm_page_fill_component (EditorPage *page, CalComponent *comp)
/* set_summary handler for the alarm page */
static void
-alarm_page_set_summary (EditorPage *page, const char *summary)
+alarm_page_set_summary (CompEditorPage *page, const char *summary)
{
AlarmPage *apage;
AlarmPagePrivate *priv;
-
+ gchar *s;
+
apage = ALARM_PAGE (page);
priv = apage->priv;
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->summary), apage);
- e_utf8_gtk_entry_set_text (GTK_ENTRY (priv->summary), summary);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->summary), apage);
-}
-
-/* get_summary handler for the alarm page */
-static char *
-alarm_page_get_summary (EditorPage *page)
-{
- AlarmPage *apage;
- AlarmPagePrivate *priv;
-
- apage = ALARM_PAGE (page);
- priv = apage->priv;
-
- return e_utf8_gtk_entry_get_text (GTK_ENTRY (priv->summary));
+ s = e_utf8_to_gtk_string (priv->summary, summary);
+ gtk_label_set_text (GTK_LABEL (priv->summary), s);
+ g_free (s);
}
/* set_dates handler for the alarm page */
static void
-alarm_page_set_dates (EditorPage *page, time_t start, time_t end)
+alarm_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates)
{
AlarmPage *apage;
AlarmPagePrivate *priv;
- char str[128];
- struct tm tm;
apage = ALARM_PAGE (page);
priv = apage->priv;
- tm = *localtime (&start);
- strftime (str, sizeof (str), _("%A %b %d %Y %H:%M:%S"), &tm);
-
- gtk_label_set_text (GTK_LABEL (priv->starting_date), str);
+ comp_editor_date_label (dates, priv->date_time);
}
@@ -554,23 +556,18 @@ static gboolean
get_widgets (AlarmPage *apage)
{
AlarmPagePrivate *priv;
- GtkWidget *toplevel;
priv = apage->priv;
#define GW(name) glade_xml_get_widget (priv->xml, name)
- toplevel = GW ("alarm-toplevel");
priv->main = GW ("alarm-page");
- if (!(toplevel && priv->main))
- return FALSE;
-
+ g_assert (priv->main);
gtk_widget_ref (priv->main);
gtk_widget_unparent (priv->main);
- gtk_widget_destroy (toplevel);
-
+
priv->summary = GW ("summary");
- priv->starting_date = GW ("starting-date");
+ priv->date_time = GW ("date-time");
priv->list = GW ("list");
priv->add = GW ("add");
@@ -585,7 +582,7 @@ get_widgets (AlarmPage *apage)
#undef GW
return (priv->summary
- && priv->starting_date
+ && priv->date_time
&& priv->list
&& priv->add
&& priv->delete
@@ -596,24 +593,18 @@ get_widgets (AlarmPage *apage)
&& priv->time);
}
-/* Callback used when the summary changes; we emit the notification signal. */
-static void
-summary_changed_cb (GtkEditable *editable, gpointer data)
-{
- AlarmPage *apage;
-
- apage = ALARM_PAGE (data);
- editor_page_notify_summary_changed (EDITOR_PAGE (apage));
-}
-
/* 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);
- editor_page_notify_changed (EDITOR_PAGE (apage));
+ priv = apage->priv;
+
+ if (!priv->updating)
+ comp_editor_page_notify_changed (COMP_EDITOR_PAGE (apage));
}
/* Callback used for the "add reminder" button */
@@ -639,15 +630,18 @@ add_clicked_cb (GtkButton *button, gpointer data)
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);
+ 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);
+ 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);
+ trigger.u.rel_duration.days =
+ e_dialog_spin_get_int (priv->interval_value);
break;
default:
@@ -702,10 +696,6 @@ init_widgets (AlarmPage *apage)
priv = apage->priv;
- /* Summary */
- gtk_signal_connect (GTK_OBJECT (priv->summary), "changed",
- GTK_SIGNAL_FUNC (summary_changed_cb), apage);
-
/* Reminder buttons */
gtk_signal_connect (GTK_OBJECT (priv->add), "clicked",
GTK_SIGNAL_FUNC (add_clicked_cb), apage);
@@ -739,14 +729,17 @@ alarm_page_construct (AlarmPage *apage)
priv = apage->priv;
- priv->xml = glade_xml_new (EVOLUTION_GLADEDIR "/alarm-page.glade", NULL);
+ priv->xml = glade_xml_new (EVOLUTION_GLADEDIR "/alarm-page.glade",
+ NULL);
if (!priv->xml) {
- g_message ("alarm_page_construct(): Could not load the Glade XML file!");
+ 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!");
+ g_message ("alarm_page_construct(): "
+ "Could not find all widgets in the XML file!");
return NULL;
}
diff --git a/calendar/gui/dialogs/alarm-page.glade b/calendar/gui/dialogs/alarm-page.glade
index 3a4a8d6765..183ec1b95b 100644
--- a/calendar/gui/dialogs/alarm-page.glade
+++ b/calendar/gui/dialogs/alarm-page.glade
@@ -18,6 +18,7 @@
<widget>
<class>GtkWindow</class>
<name>alarm-toplevel</name>
+ <visible>False</visible>
<title>window1</title>
<type>GTK_WINDOW_TOPLEVEL</type>
<position>GTK_WIN_POS_NONE</position>
@@ -36,7 +37,7 @@
<widget>
<class>GtkFrame</class>
<name>frame33</name>
- <label>Appointment Basics</label>
+ <label>Basics</label>
<label_xalign>0</label_xalign>
<shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
<child>
@@ -58,14 +59,13 @@
<widget>
<class>GtkLabel</class>
<name>label62</name>
- <label>Su_mmary:</label>
+ <label>Summary:</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
- <default_focus_target>reminder-summary</default_focus_target>
<child>
<left_attach>0</left_attach>
<right_attach>1</right_attach>
@@ -83,42 +83,44 @@
</widget>
<widget>
- <class>GtkEntry</class>
- <name>reminder-summary</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
+ <class>GtkLabel</class>
+ <name>label63</name>
+ <label>Date/Time:</label>
+ <justify>GTK_JUSTIFY_CENTER</justify>
+ <wrap>False</wrap>
+ <xalign>0</xalign>
+ <yalign>0</yalign>
+ <xpad>0</xpad>
+ <ypad>0</ypad>
<child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
+ <left_attach>0</left_attach>
+ <right_attach>1</right_attach>
+ <top_attach>1</top_attach>
+ <bottom_attach>2</bottom_attach>
<xpad>0</xpad>
<ypad>0</ypad>
- <xexpand>True</xexpand>
+ <xexpand>False</xexpand>
<yexpand>False</yexpand>
- <xshrink>True</xshrink>
+ <xshrink>False</xshrink>
<yshrink>False</yshrink>
<xfill>True</xfill>
- <yfill>False</yfill>
+ <yfill>True</yfill>
</child>
</widget>
<widget>
<class>GtkLabel</class>
- <name>label63</name>
- <label>_Starting date:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
+ <name>date-time</name>
+ <label></label>
+ <justify>GTK_JUSTIFY_LEFT</justify>
<wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0</yalign>
- <xpad>0</xpad>
+ <xalign>0.5</xalign>
+ <yalign>0.5</yalign>
+ <xpad>4</xpad>
<ypad>0</ypad>
<child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
+ <left_attach>1</left_attach>
+ <right_attach>2</right_attach>
<top_attach>1</top_attach>
<bottom_attach>2</bottom_attach>
<xpad>0</xpad>
@@ -134,19 +136,19 @@
<widget>
<class>GtkLabel</class>
- <name>starting date</name>
- <label>assbarn it</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
+ <name>summary</name>
+ <label></label>
+ <justify>GTK_JUSTIFY_LEFT</justify>
<wrap>False</wrap>
<xalign>0</xalign>
- <yalign>0</yalign>
- <xpad>0</xpad>
+ <yalign>0.5</yalign>
+ <xpad>4</xpad>
<ypad>0</ypad>
<child>
<left_attach>1</left_attach>
<right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
+ <top_attach>0</top_attach>
+ <bottom_attach>1</bottom_attach>
<xpad>0</xpad>
<ypad>0</ypad>
<xexpand>False</xexpand>
@@ -154,7 +156,7 @@
<xshrink>False</xshrink>
<yshrink>False</yshrink>
<xfill>True</xfill>
- <yfill>True</yfill>
+ <yfill>False</yfill>
</child>
</widget>
</widget>
@@ -192,7 +194,7 @@
<widget>
<class>GtkOptionMenu</class>
- <name>reminder-action</name>
+ <name>action</name>
<can_focus>True</can_focus>
<items>Show a dialog
Play a sound
@@ -209,7 +211,7 @@ Run a program
<widget>
<class>GtkSpinButton</class>
- <name>reminder-interval-value</name>
+ <name>interval-value</name>
<can_focus>True</can_focus>
<climb_rate>1</climb_rate>
<digits>0</digits>
@@ -232,7 +234,7 @@ Run a program
<widget>
<class>GtkOptionMenu</class>
- <name>reminder-value-units</name>
+ <name>value-units</name>
<can_focus>True</can_focus>
<items>minute(s)
hour(s)
@@ -248,7 +250,7 @@ day(s)
<widget>
<class>GtkOptionMenu</class>
- <name>reminder-relative</name>
+ <name>relative</name>
<can_focus>True</can_focus>
<items>before
after
@@ -263,7 +265,7 @@ after
<widget>
<class>GtkOptionMenu</class>
- <name>reminder-time</name>
+ <name>time</name>
<can_focus>True</can_focus>
<items>start of appointment
end of appointment
@@ -281,7 +283,6 @@ end of appointment
<name>button9</name>
<can_focus>True</can_focus>
<label>Settings...</label>
- <relief>GTK_RELIEF_NORMAL</relief>
<child>
<padding>0</padding>
<expand>False</expand>
@@ -316,7 +317,7 @@ end of appointment
<widget>
<class>GtkCList</class>
- <name>reminder-list</name>
+ <name>list</name>
<can_focus>True</can_focus>
<columns>1</columns>
<column_widths>80</column_widths>
@@ -356,20 +357,18 @@ end of appointment
<widget>
<class>GtkButton</class>
- <name>reminder-add</name>
+ <name>add</name>
<can_default>True</can_default>
<can_focus>True</can_focus>
<label>Add</label>
- <relief>GTK_RELIEF_NORMAL</relief>
</widget>
<widget>
<class>GtkButton</class>
- <name>reminder-delete</name>
+ <name>delete</name>
<can_default>True</can_default>
<can_focus>True</can_focus>
<label>Delete</label>
- <relief>GTK_RELIEF_NORMAL</relief>
</widget>
</widget>
</widget>
diff --git a/calendar/gui/dialogs/alarm-page.h b/calendar/gui/dialogs/alarm-page.h
index 1cb0b301bd..97c1361f4d 100644
--- a/calendar/gui/dialogs/alarm-page.h
+++ b/calendar/gui/dialogs/alarm-page.h
@@ -25,7 +25,7 @@
#ifndef ALARM_PAGE_H
#define ALARM_PAGE_H
-#include "editor-page.h"
+#include "comp-editor-page.h"
BEGIN_GNOME_DECLS
@@ -33,29 +33,27 @@ BEGIN_GNOME_DECLS
#define TYPE_ALARM_PAGE (alarm_page_get_type ())
#define ALARM_PAGE(obj) (GTK_CHECK_CAST ((obj), TYPE_ALARM_PAGE, AlarmPage))
-#define ALARM_PAGE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_ALARM_PAGE, \
- AlarmPageClass))
+#define ALARM_PAGE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_ALARM_PAGE, AlarmPageClass))
#define IS_ALARM_PAGE(obj) (GTK_CHECK_TYPE ((obj), TYPE_ALARM_PAGE))
#define IS_ALARM_PAGE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), TYPE_ALARM_PAGE))
typedef struct _AlarmPagePrivate AlarmPagePrivate;
typedef struct {
- EditorPage page;
+ CompEditorPage page;
/* Private data */
AlarmPagePrivate *priv;
} AlarmPage;
typedef struct {
- EditorPageClass parent_class;
+ CompEditorPageClass parent_class;
} AlarmPageClass;
-GtkType alarm_page_get_type (void);
+GtkType alarm_page_get_type (void);
AlarmPage *alarm_page_construct (AlarmPage *apage);
-
-AlarmPage *alarm_page_new (void);
+AlarmPage *alarm_page_new (void);
diff --git a/calendar/gui/dialogs/comp-editor-page.c b/calendar/gui/dialogs/comp-editor-page.c
new file mode 100644
index 0000000000..f390e86dd8
--- /dev/null
+++ b/calendar/gui/dialogs/comp-editor-page.c
@@ -0,0 +1,277 @@
+/* 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 the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtksignal.h>
+#include "comp-editor-page.h"
+
+
+
+static void comp_editor_page_class_init (CompEditorPageClass *class);
+
+/* Signal IDs */
+
+enum {
+ CHANGED,
+ SUMMARY_CHANGED,
+ DATES_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint comp_editor_page_signals[LAST_SIGNAL];
+
+#define CLASS(page) (COMP_EDITOR_PAGE_CLASS (GTK_OBJECT (page)->klass))
+
+
+
+/**
+ * comp_editor_page_get_type:
+ *
+ * Registers the #CompEditorPage class if necessary, and returns the type ID
+ * associated to it.
+ *
+ * Return value: The type ID of the #CompEditorPage class.
+ **/
+GtkType
+comp_editor_page_get_type (void)
+{
+ static GtkType comp_editor_page_type = 0;
+
+ if (!comp_editor_page_type) {
+ static const GtkTypeInfo comp_editor_page_info = {
+ "CompEditorPage",
+ sizeof (CompEditorPage),
+ sizeof (CompEditorPageClass),
+ (GtkClassInitFunc) comp_editor_page_class_init,
+ (GtkObjectInitFunc) NULL,
+ 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;
+
+ comp_editor_page_signals[CHANGED] =
+ gtk_signal_new ("changed",
+ GTK_RUN_FIRST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (CompEditorPageClass,
+ changed),
+ gtk_marshal_NONE__NONE,
+ GTK_TYPE_NONE, 0);
+
+ comp_editor_page_signals[SUMMARY_CHANGED] =
+ gtk_signal_new ("summary_changed",
+ GTK_RUN_FIRST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (CompEditorPageClass,
+ summary_changed),
+ gtk_marshal_NONE__POINTER,
+ GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
+
+ comp_editor_page_signals[DATES_CHANGED] =
+ gtk_signal_new ("dates_changed",
+ GTK_RUN_FIRST,
+ object_class->type,
+ GTK_SIGNAL_OFFSET (CompEditorPageClass,
+ dates_changed),
+ gtk_marshal_NONE__POINTER,
+ GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
+
+ gtk_object_class_add_signals (object_class,
+ comp_editor_page_signals,
+ LAST_SIGNAL);
+
+ class->changed = NULL;
+ class->summary_changed = NULL;
+ class->dates_changed = NULL;
+
+ class->get_widget = NULL;
+ class->fill_widgets = NULL;
+ class->fill_component = NULL;
+ class->set_summary = NULL;
+ class->set_dates = NULL;
+}
+
+
+
+/**
+ * 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_fill_widgets:
+ * @page: An editor page.
+ * @comp: A calendar component.
+ *
+ * Fills the widgets of an editor page with the data from a calendar component.
+ **/
+void
+comp_editor_page_fill_widgets (CompEditorPage *page, CalComponent *comp)
+{
+ g_return_if_fail (page != NULL);
+ g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
+ g_return_if_fail (comp != NULL);
+
+ g_assert (CLASS (page)->fill_widgets != NULL);
+ (* CLASS (page)->fill_widgets) (page, comp);
+}
+
+/**
+ * comp_editor_page_fill_component:
+ * @page: An editor page.
+ * @comp: A calendar component.
+ *
+ * Takes the data from the widgets of an editor page and sets it on a calendar
+ * component, replacing the contents of the properties that the editor page
+ * knows how to manipulate.
+ **/
+void
+comp_editor_page_fill_component (CompEditorPage *page, CalComponent *comp)
+{
+ g_return_if_fail (page != NULL);
+ g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
+ g_return_if_fail (comp != NULL);
+
+ if (CLASS (page)->fill_component != NULL)
+ (* CLASS (page)->fill_component) (page, comp);
+}
+
+/**
+ * comp_editor_page_set_summary:
+ * @page: An editor page
+ * @summary: The text of the new summary value
+ *
+ * Sets the summary value for this group of widgets
+ **/
+void
+comp_editor_page_set_summary (CompEditorPage *page, const char *summary)
+{
+ g_return_if_fail (page != NULL);
+ g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
+
+ if (CLASS (page)->set_summary != NULL)
+ (* CLASS (page)->set_summary) (page, summary);
+}
+
+/**
+ * comp_editor_page_set_dates:
+ * @page: An editor page
+ * @dates: A collection of various dates in time_t format
+ *
+ * Sets the date values for this group of widgets
+ **/
+void
+comp_editor_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates)
+{
+ g_return_if_fail (page != NULL);
+ g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
+
+ if (CLASS (page)->set_dates != NULL)
+ (* CLASS (page)->set_dates) (page, dates);
+}
+
+/**
+ * comp_editor_page_notify_changed:
+ * @page: An editor page.
+ *
+ * Makes an editor page emit the "changed" signal. This is meant to be
+ * used only by page implementations.
+ **/
+void
+comp_editor_page_notify_changed (CompEditorPage *page)
+{
+ g_return_if_fail (page != NULL);
+ g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
+
+ gtk_signal_emit (GTK_OBJECT (page), comp_editor_page_signals[CHANGED]);
+}
+
+/**
+ * comp_editor_page_notify_summary_changed:
+ * @page: An editor page.
+ *
+ * Makes an editor page emit the "summary_changed" signal. This is meant to be
+ * used only by page implementations.
+ **/
+void
+comp_editor_page_notify_summary_changed (CompEditorPage *page,
+ const char *summary)
+{
+ g_return_if_fail (page != NULL);
+ g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
+
+
+ gtk_signal_emit (GTK_OBJECT (page),
+ comp_editor_page_signals[SUMMARY_CHANGED],
+ summary);
+}
+
+/**
+ * comp_editor_page_notify_dates_changed:
+ * @page: An editor page.
+ *
+ * Makes an editor page emit the "dates_changed" signal. This is meant to be
+ * used only by page implementations.
+ **/
+void
+comp_editor_page_notify_dates_changed (CompEditorPage *page,
+ CompEditorPageDates *dates)
+{
+ g_return_if_fail (page != NULL);
+ g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
+
+ gtk_signal_emit (GTK_OBJECT (page),
+ comp_editor_page_signals[DATES_CHANGED],
+ dates);
+}
diff --git a/calendar/gui/dialogs/comp-editor-page.h b/calendar/gui/dialogs/comp-editor-page.h
new file mode 100644
index 0000000000..ac088e7759
--- /dev/null
+++ b/calendar/gui/dialogs/comp-editor-page.h
@@ -0,0 +1,93 @@
+/* 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 the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef COMP_EDITOR_PAGE_H
+#define COMP_EDITOR_PAGE_H
+
+#include <time.h>
+#include <libgnome/gnome-defs.h>
+#include <gtk/gtkwidget.h>
+#include <cal-util/cal-component.h>
+
+BEGIN_GNOME_DECLS
+
+
+
+#define TYPE_COMP_EDITOR_PAGE (comp_editor_page_get_type ())
+#define COMP_EDITOR_PAGE(obj) (GTK_CHECK_CAST ((obj), TYPE_COMP_EDITOR_PAGE, CompEditorPage))
+#define COMP_EDITOR_PAGE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_COMP_EDITOR_PAGE, CompEditorPageClass))
+#define IS_COMP_EDITOR_PAGE(obj) (GTK_CHECK_TYPE ((obj), TYPE_COMP_EDITOR_PAGE))
+#define IS_COMP_EDITOR_PAGE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), TYPE_COMP_EDITOR_PAGE))
+
+typedef struct {
+ time_t start;
+ time_t end;
+ time_t due;
+ time_t complete;
+} CompEditorPageDates;
+
+typedef struct {
+ GtkObject object;
+} CompEditorPage;
+
+typedef struct {
+ GtkObjectClass parent_class;
+
+ /* Notification signals */
+
+ void (* changed) (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 (* fill_widgets) (CompEditorPage *page, CalComponent *comp);
+ void (* fill_component) (CompEditorPage *page, CalComponent *comp);
+
+ void (* set_summary) (CompEditorPage *page, const char *summary);
+ void (* set_dates) (CompEditorPage *page, CompEditorPageDates *dates);
+} CompEditorPageClass;
+
+
+GtkType comp_editor_page_get_type (void);
+GtkWidget *comp_editor_page_get_widget (CompEditorPage *page);
+void comp_editor_page_fill_widgets (CompEditorPage *page,
+ CalComponent *comp);
+void comp_editor_page_fill_component (CompEditorPage *page,
+ CalComponent *comp);
+void comp_editor_page_set_summary (CompEditorPage *page,
+ const char *summary);
+void comp_editor_page_set_dates (CompEditorPage *page,
+ CompEditorPageDates *dates);
+void comp_editor_page_notify_changed (CompEditorPage *page);
+void comp_editor_page_notify_summary_changed (CompEditorPage *page,
+ const char *summary);
+void comp_editor_page_notify_dates_changed (CompEditorPage *page,
+ CompEditorPageDates *dates);
+
+
+
+
+END_GNOME_DECLS
+
+#endif
diff --git a/calendar/gui/dialogs/comp-editor-util.c b/calendar/gui/dialogs/comp-editor-util.c
new file mode 100644
index 0000000000..1110b5f18a
--- /dev/null
+++ b/calendar/gui/dialogs/comp-editor-util.c
@@ -0,0 +1,129 @@
+/* Evolution calendar - Widget utilities
+ *
+ * Copyright (C) 2000 Helix Code, Inc.
+ *
+ * Author: Federico Mena-Quintero <federico@helixcode.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <glib.h>
+#include <libgnome/gnome-defs.h>
+#include <libgnome/gnome-i18n.h>
+#include <e-util/e-time-utils.h>
+#include "../calendar-config.h"
+#include "comp-editor-util.h"
+
+
+
+/**
+ * comp_editor_dates:
+ * @dates: A structure to be filled out with dates of a component
+ * @comp: The component to extract the dates from
+ *
+ * Extracts the dates from the calendar component into the
+ * CompEditorPageDates structure
+ **/
+void
+comp_editor_dates (CompEditorPageDates *dates, CalComponent *comp)
+{
+ CalComponentDateTime dt;
+ struct icaltimetype *completed;
+
+ dates->start = 0;
+ dates->end = 0;
+ dates->due = 0;
+ dates->complete = 0;
+
+ cal_component_get_dtstart (comp, &dt);
+ if (dt.value)
+ dates->start = icaltime_as_timet (*dt.value);
+
+ cal_component_get_dtend (comp, &dt);
+ if (dt.value)
+ dates->end = icaltime_as_timet (*dt.value);
+
+ cal_component_get_due (comp, &dt);
+ if (dt.value)
+ dates->due = icaltime_as_timet (*dt.value);
+
+ cal_component_get_completed (comp, &completed);
+ if (completed) {
+ dates->complete = icaltime_as_timet (*completed);
+ cal_component_free_icaltimetype (completed);
+ }
+}
+
+static void
+write_label_piece (time_t t, char *buffer, int size, char *stext, char *etext)
+{
+ struct tm *tmp_tm;
+ int len;
+
+ tmp_tm = localtime (&t);
+ 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);
+}
+
+/**
+ * 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)
+{
+ static char buffer[1024];
+
+ buffer[0] = '\0';
+
+ if (dates->start > 0)
+ write_label_piece (dates->start, buffer, 1024, NULL, NULL);
+
+ if (dates->end > 0 && dates->start > 0)
+ write_label_piece (dates->end, buffer, 1024, _(" to "), NULL);
+
+ if (dates->complete > 0) {
+ if (dates->start > 0)
+ write_label_piece (dates->complete, buffer, 1024, _(" (Completed "), ")");
+ else
+ write_label_piece (dates->complete, buffer, 1024, _(" Completed "), NULL);
+ }
+
+ if (dates->due > 0 && dates->complete == 0) {
+ if (dates->start > 0)
+ write_label_piece (dates->due, buffer, 1024, _(" (Due "), ")");
+ else
+ write_label_piece (dates->due, buffer, 1024, _("Due "), NULL);
+ }
+
+ gtk_label_set_text (GTK_LABEL (label), buffer);
+}
diff --git a/calendar/gui/dialogs/comp-editor-util.h b/calendar/gui/dialogs/comp-editor-util.h
new file mode 100644
index 0000000000..ad27ab06ca
--- /dev/null
+++ b/calendar/gui/dialogs/comp-editor-util.h
@@ -0,0 +1,31 @@
+/* Evolution calendar - Widget utilities
+ *
+ * Copyright (C) 2000 Helix Code, Inc.
+ *
+ * Author: JP Rosevear <jpr@ximian.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _COMP_EDITOR_UTIL_H_
+#define _COMP_EDITOR_UTIL_H_
+
+#include <gtk/gtkwidget.h>
+#include "comp-editor-page.h"
+
+void comp_editor_dates (CompEditorPageDates *date, CalComponent *comp);
+void comp_editor_date_label (CompEditorPageDates *dates, GtkWidget *label);
+
+#endif
diff --git a/calendar/gui/dialogs/comp-editor.c b/calendar/gui/dialogs/comp-editor.c
index f101bfa15a..ddf9f9a9ae 100644
--- a/calendar/gui/dialogs/comp-editor.c
+++ b/calendar/gui/dialogs/comp-editor.c
@@ -23,12 +23,21 @@
#include <config.h>
#endif
+#include <gnome.h>
+#include <gal/widgets/e-unicode.h>
+#include "save-comp.h"
#include "comp-editor.h"
/* Private part of the CompEditor structure */
struct _CompEditorPrivate {
+ /* Client to use */
+ CalClient *client;
+
+ /* Calendar object/uid we are editing; this is an internal copy */
+ CalComponent *comp;
+
/* The pages we have */
GList *pages;
@@ -37,6 +46,8 @@ struct _CompEditorPrivate {
/* Notebook to hold the pages */
GtkNotebook *notebook;
+
+ gboolean changed;
};
@@ -45,6 +56,15 @@ static void comp_editor_class_init (CompEditorClass *class);
static void comp_editor_init (CompEditor *editor);
static void comp_editor_destroy (GtkObject *object);
+static void page_summary_changed_cb (GtkWidget *widget, const char *summary, gpointer data);
+static void page_dates_changed_cb (GtkWidget *widget, CompEditorPageDates *dates, gpointer data);
+static void page_changed_cb (GtkWidget *widget, gpointer data);
+
+static void save_clicked_cb (GtkWidget *widget, gpointer data);
+static void close_clicked_cb (GtkWidget *widget, gpointer data);
+static void help_clicked_cb (GtkWidget *widget, gpointer data);
+static gint delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data);
+
static GtkObjectClass *parent_class;
@@ -52,21 +72,22 @@ static GtkObjectClass *parent_class;
GtkType
comp_editor_get_type (void)
{
- static GtkType comp_editor_type;
+ static GtkType comp_editor_type = 0;
if (!comp_editor_type) {
- static const GtkTypeInfo comp_editor_info = {
+ GtkTypeInfo comp_editor_info = {
"CompEditor",
sizeof (CompEditor),
sizeof (CompEditorClass),
(GtkClassInitFunc) comp_editor_class_init,
- (GtkObjectInitfunc) comp_editor_init,
+ (GtkObjectInitFunc) comp_editor_init,
NULL, /* reserved_1 */
NULL, /* reserved_2 */
(GtkClassInitFunc) NULL
- }
+ };
- comp_editor_type = gtk_type_unique (GTK_TYPE_OBJECT, &comp_editor_info);
+ comp_editor_type = gtk_type_unique (GTK_TYPE_OBJECT,
+ &comp_editor_info);
}
return comp_editor_type;
@@ -110,23 +131,30 @@ setup_widgets (CompEditor *editor)
/* Notebook */
priv->notebook = GTK_NOTEBOOK (gtk_notebook_new ());
- gtk_box_pack_start (GTK_BOX (vbox), priv->notebook, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (priv->notebook),
+ TRUE, TRUE, 0);
/* Buttons */
bbox = gtk_hbutton_box_new ();
- gtk_hbutton_box_set_layout_default (GTK_HBUTTON_BOX (bbox), GTK_BUTTONBOX_END);
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, FALSE, 0);
pixmap = gnome_stock_pixmap_widget (NULL, GNOME_STOCK_PIXMAP_SAVE);
button = gnome_pixmap_button (pixmap, _("Save"));
gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 0);
-
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (save_clicked_cb), editor);
+
button = gnome_stock_button (GNOME_STOCK_BUTTON_CLOSE);
gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 0);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (close_clicked_cb), editor);
button = gnome_stock_button (GNOME_STOCK_BUTTON_HELP);
gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 0);
+ gtk_signal_connect (GTK_OBJECT (button), "clicked",
+ GTK_SIGNAL_FUNC (help_clicked_cb), editor);
}
/* Object initialization function for the calendar component editor */
@@ -141,6 +169,7 @@ comp_editor_init (CompEditor *editor)
setup_widgets (editor);
priv->pages = NULL;
+ priv->changed = FALSE;
}
/* Destroy handler for the calendar component editor */
@@ -167,8 +196,18 @@ comp_editor_destroy (GtkObject *object)
+/**
+ * comp_editor_append_page:
+ * @editor: A component editor
+ * @page: Top level widget of the page
+ * @label: Label of the page
+ *
+ * Appends a page to the editor notebook with the given label
+ **/
void
-comp_editor_append_page (CompEditor *editor, EditorPage *page, const char *label)
+comp_editor_append_page (CompEditor *editor,
+ CompEditorPage *page,
+ const char *label)
{
CompEditorPrivate *priv;
GtkWidget *page_widget;
@@ -177,7 +216,7 @@ comp_editor_append_page (CompEditor *editor, EditorPage *page, const char *label
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_EDITOR_PAGE (page));
+ g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
g_return_if_fail (label != NULL);
priv = editor->priv;
@@ -185,11 +224,333 @@ comp_editor_append_page (CompEditor *editor, EditorPage *page, const char *label
/* Only allow adding the pages while a component has not been set */
g_return_if_fail (priv->comp == NULL);
- page_widget = editor_page_get_widget (page);
+ page_widget = comp_editor_page_get_widget (page);
g_assert (page_widget != NULL);
-
+
label_widget = gtk_label_new (label);
priv->pages = g_list_append (priv->pages, page);
gtk_notebook_append_page (priv->notebook, page_widget, label_widget);
+
+ /* Listen for things happening on the page */
+ gtk_signal_connect (GTK_OBJECT (page), "summary_changed",
+ GTK_SIGNAL_FUNC (page_summary_changed_cb), editor);
+ gtk_signal_connect (GTK_OBJECT (page), "dates_changed",
+ GTK_SIGNAL_FUNC (page_dates_changed_cb), editor);
+ gtk_signal_connect (GTK_OBJECT (page), "changed",
+ GTK_SIGNAL_FUNC (page_changed_cb), editor);
+}
+
+/**
+ * comp_editor_set_cal_client:
+ * @editor: A component editor
+ * @client: The calendar client to use
+ *
+ * Sets the calendar client used by the editor to update components
+ **/
+void
+comp_editor_set_cal_client (CompEditor *editor, CalClient *client)
+{
+ CompEditorPrivate *priv;
+
+ g_return_if_fail (editor != NULL);
+ g_return_if_fail (IS_COMP_EDITOR (editor));
+
+ priv = editor->priv;
+
+ if (client == priv->client)
+ return;
+
+ if (client) {
+ g_return_if_fail (IS_CAL_CLIENT (client));
+ g_return_if_fail (cal_client_get_load_state (client) ==
+ CAL_CLIENT_LOAD_LOADED);
+ gtk_object_ref (GTK_OBJECT (client));
+ }
+
+ if (priv->client) {
+ gtk_signal_disconnect_by_data (GTK_OBJECT (priv->client),
+ editor);
+ gtk_object_unref (GTK_OBJECT (priv->client));
+ }
+
+ priv->client = client;
+}
+
+/**
+ * comp_editor_get_cal_client:
+ * @editor: A component editor
+ *
+ * Returns the calendar client of the editor
+ *
+ * Return value: The calendar client of the editor
+ **/
+CalClient *
+comp_editor_get_cal_client (CompEditor *editor)
+{
+ CompEditorPrivate *priv;
+
+ g_return_val_if_fail (editor != NULL, NULL);
+ g_return_val_if_fail (IS_COMP_EDITOR (editor), NULL);
+
+ priv = editor->priv;
+
+ return priv->client;
+}
+
+/* Creates an appropriate title for the event editor dialog */
+static char *
+make_title_from_comp (CalComponent *comp)
+{
+ char *title;
+ const char *type_string;
+ CalComponentVType type;
+ CalComponentText text;
+
+ if (!comp)
+ return g_strdup (_("Edit Appointment"));
+
+ type = cal_component_get_vtype (comp);
+ switch (type) {
+ case CAL_COMPONENT_EVENT:
+ type_string = _("Appointment - %s");
+ break;
+ case CAL_COMPONENT_TODO:
+ type_string = _("Task - %s");
+ break;
+ case CAL_COMPONENT_JOURNAL:
+ type_string = _("Journal entry - %s");
+ break;
+ default:
+ g_message ("make_title_from_comp(): Cannot handle object of type %d", type);
+ return NULL;
+ }
+
+ cal_component_get_summary (comp, &text);
+ if (text.value) {
+ char *summary;
+ summary = e_utf8_to_locale_string (text.value);
+ title = g_strdup_printf (type_string, summary);
+ g_free (summary);
+ } else
+ title = g_strdup_printf (type_string, _("No summary"));
+
+ return title;
+}
+
+/* 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 (priv->window), title);
+ g_free (title);
+}
+
+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);
+}
+
+/**
+ * comp_editor_edit_comp:
+ * @editor: A component editor
+ * @comp: A calendar component
+ *
+ * Starts the editor editing the given component
+ **/
+void
+comp_editor_edit_comp (CompEditor *editor, CalComponent *comp)
+{
+ CompEditorPrivate *priv;
+
+ g_return_if_fail (editor != NULL);
+ g_return_if_fail (IS_COMP_EDITOR (editor));
+
+ priv = editor->priv;
+
+ if (priv->comp) {
+ gtk_object_unref (GTK_OBJECT (priv->comp));
+ priv->comp = NULL;
+ }
+
+ if (comp)
+ priv->comp = cal_component_clone (comp);
+
+ set_title_from_comp (editor);
+ fill_widgets (editor);
+}
+
+
+/* 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_all (priv->window);
+ raise_and_focus (priv->window);
+}
+
+static void
+save_comp (CompEditor *editor)
+{
+ CompEditorPrivate *priv;
+ GList *l;
+
+ priv = editor->priv;
+
+ for (l = priv->pages; l != NULL; l = l->next)
+ comp_editor_page_fill_component (l->data, priv->comp);
+
+ if (!cal_client_update_object (priv->client, priv->comp))
+ g_message ("save_comp (): Could not update the object!");
+ else
+ priv->changed = FALSE;
+}
+
+static gboolean
+prompt_to_save_changes (CompEditor *editor)
+{
+ CompEditorPrivate *priv;
+
+ priv = editor->priv;
+
+ if (!priv->changed)
+ return TRUE;
+
+ switch (save_component_dialog (GTK_WINDOW (priv->window))) {
+ case 0: /* Save */
+ /* FIXME: If an error occurs here, we should popup a dialog
+ and then return FALSE. */
+ save_comp (editor);
+ return TRUE;
+ case 1: /* Discard */
+ return TRUE;
+ case 2: /* Cancel */
+ default:
+ return FALSE;
+ break;
+ }
+}
+
+/* Closes the dialog box and emits the appropriate signals */
+static void
+close_dialog (CompEditor *editor)
+{
+ CompEditorPrivate *priv;
+
+ priv = editor->priv;
+
+ g_assert (priv->window != NULL);
+
+ gtk_object_destroy (GTK_OBJECT (editor));
+}
+
+static void
+save_clicked_cb (GtkWidget *widget, gpointer data)
+{
+ CompEditor *editor = COMP_EDITOR (data);
+
+ save_comp (editor);
+ close_dialog (editor);
+}
+
+static void
+close_clicked_cb (GtkWidget *widget, gpointer data)
+{
+ CompEditor *editor = COMP_EDITOR (data);
+
+ if (prompt_to_save_changes (editor))
+ close_dialog (editor);
+}
+
+static void
+help_clicked_cb (GtkWidget *widget, gpointer data)
+{
+}
+
+static void
+page_summary_changed_cb (GtkWidget *widget, 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)
+ comp_editor_page_set_summary (l->data, summary);
+
+ priv->changed = TRUE;
+}
+
+static void
+page_dates_changed_cb (GtkWidget *widget,
+ 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)
+ comp_editor_page_set_dates (l->data, dates);
+
+ priv->changed = TRUE;
+}
+
+
+static void
+page_changed_cb (GtkWidget *widget, gpointer data)
+{
+ CompEditor *editor = COMP_EDITOR (data);
+ CompEditorPrivate *priv;
+
+ priv = editor->priv;
+
+ priv->changed = TRUE;
+}
+
+static gint
+delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data)
+{
+ CompEditor *editor = COMP_EDITOR (data);
+
+ if (prompt_to_save_changes (editor))
+ close_dialog (editor);
+
+ return TRUE;
}
diff --git a/calendar/gui/dialogs/comp-editor.h b/calendar/gui/dialogs/comp-editor.h
index 2362c1d012..225abeac3c 100644
--- a/calendar/gui/dialogs/comp-editor.h
+++ b/calendar/gui/dialogs/comp-editor.h
@@ -22,7 +22,9 @@
#ifndef COMP_EDITOR_H
#define COMP_EDITOR_H
-#include "editor-page.h"
+#include <gtk/gtk.h>
+#include "cal-client.h"
+#include "comp-editor-page.h"
BEGIN_GNOME_DECLS
@@ -30,8 +32,7 @@ BEGIN_GNOME_DECLS
#define TYPE_COMP_EDITOR (comp_editor_get_type ())
#define COMP_EDITOR(obj) (GTK_CHECK_CAST ((obj), TYPE_COMP_EDITOR, CompEditor))
-#define COMP_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_COMP_EDITOR, \
- CompEditorClass))
+#define COMP_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_COMP_EDITOR, CompEditorClass))
#define IS_COMP_EDITOR(obj) (GTK_CHECK_TYPE ((obj), TYPE_COMP_EDITOR))
#define IS_COMP_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), TYPE_COMP_EDITOR))
@@ -48,11 +49,17 @@ typedef struct {
GtkObjectClass parent_class;
} CompEditorClass;
-GtkType comp_editor_get_type (void);
-
-CompEditor *comp_editor_new (void);
-
-void comp_editor_add_page (CompEditor *editor, EditorPage *page);
+GtkType comp_editor_get_type (void);
+CompEditor *comp_editor_new (void);
+void comp_editor_append_page (CompEditor *editor,
+ CompEditorPage *page,
+ const char *label);
+void comp_editor_set_cal_client (CompEditor *editor,
+ CalClient *client);
+CalClient * comp_editor_get_cal_client (CompEditor *editor);
+void comp_editor_edit_comp (CompEditor *ee,
+ CalComponent *comp);
+void comp_editor_focus (CompEditor *editor);
diff --git a/calendar/gui/dialogs/editor-page.c b/calendar/gui/dialogs/editor-page.c
deleted file mode 100644
index 5aad3aa01e..0000000000
--- a/calendar/gui/dialogs/editor-page.c
+++ /dev/null
@@ -1,260 +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 the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gtk/gtksignal.h>
-#include "editor-page.h"
-
-
-
-static void editor_page_class_init (EditorPageClass *class);
-
-/* Signal IDs */
-
-enum {
- CHANGED,
- SUMMARY_CHANGED,
- LAST_SIGNAL
-};
-
-static guint editor_page_signals[LAST_SIGNAL];
-
-#define CLASS(page) (EDITOR_PAGE_CLASS (GTK_OBJECT (page)->klass))
-
-
-
-/**
- * editor_page_get_type:
- *
- * Registers the #EditorPage class if necessary, and returns the type ID
- * associated to it.
- *
- * Return value: The type ID of the #EditorPage class.
- **/
-GtkType
-editor_page_get_type (void)
-{
- static GtkType editor_page_type = 0;
-
- if (!editor_page_type) {
- static const GtkTypeInfo editor_page_info = {
- "EditorPage",
- sizeof (EditorPage),
- sizeof (EditorPageClass),
- (GtkClassInitFunc) editor_page_class_init,
- (GtkObjectInitFunc) NULL,
- NULL, /* reserved_1 */
- NULL, /* reserved_2 */
- (GtkClassInitFunc) NULL
- };
-
- editor_page_type = gtk_type_unique (GTK_TYPE_OBJECT, &editor_page_info);
- }
-
- return editor_page_type;
-}
-
-/* Class initialization function for the abstract editor page */
-static void
-editor_page_class_init (EditorPageClass *class)
-{
- GtkObjectClass *object_class;
-
- object_class = (GtkObjectClass *) class;
-
- editor_page_signals[CHANGED] =
- gtk_signal_new ("changed",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EditorPageClass, changed),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- editor_page_signals[SUMMARY_CHANGED] =
- gtk_signal_new ("summary_changed",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EditorPageClass, summary_changed),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- gtk_object_class_add_signals (object_class, editor_page_signals, LAST_SIGNAL);
-
- class->changed = NULL;
- class->summary_changed = NULL;
-
- class->get_widget = NULL;
- class->fill_widgets = NULL;
- class->fill_component = NULL;
- class->set_summary = NULL;
- class->get_summary = NULL;
- class->set_dates = NULL;
-}
-
-
-
-/**
- * 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 *
-editor_page_get_widget (EditorPage *page)
-{
- g_return_val_if_fail (page != NULL, NULL);
- g_return_val_if_fail (IS_EDITOR_PAGE (page), NULL);
-
- g_assert (CLASS (page)->get_widget != NULL);
- return (* CLASS (page)->get_widget) (page);
-}
-
-/**
- * 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
-editor_page_fill_widgets (EditorPage *page, CalComponent *comp)
-{
- g_return_if_fail (page != NULL);
- g_return_if_fail (IS_EDITOR_PAGE (page));
- g_return_if_fail (comp != NULL);
-
- g_assert (CLASS (page)->fill_widgets != NULL);
- (* CLASS (page)->fill_widgets) (page, 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.
- **/
-void
-editor_page_fill_component (EditorPage *page, CalComponent *comp)
-{
- g_return_if_fail (page != NULL);
- g_return_if_fail (IS_EDITOR_PAGE (page));
- g_return_if_fail (comp != NULL);
-
- g_assert (CLASS (page)->fill_component != NULL);
- (* CLASS (page)->fill_component) (page, comp);
-}
-
-/**
- * editor_page_set_summary:
- * @page: An editor page.
- * @summary: Summary string to set in the page's widgets, which must be encoded
- * in UTF8.
- *
- * Sets the calendar component summary string in an editor page.
- **/
-void
-editor_page_set_summary (EditorPage *page, const char *summary)
-{
- g_return_if_fail (page != NULL);
- g_return_if_fail (IS_EDITOR_PAGE (page));
- g_return_if_fail (summary != NULL);
-
- g_assert (CLASS (page)->set_summary != NULL);
- (* CLASS (page)->set_summary) (page, summary);
-}
-
-/**
- * editor_page_get_summary:
- * @page: An editor page.
- *
- * Queries the current summary string in an editor page.
- *
- * Return value: Summary string in UTF8; must be freed by the caller.
- **/
-char *
-editor_page_get_summary (EditorPage *page)
-{
- g_return_val_if_fail (page != NULL, NULL);
- g_return_val_if_fail (IS_EDITOR_PAGE (page), NULL);
-
- g_assert (CLASS (page)->get_summary != NULL);
- return (* CLASS (page)->get_summary) (page);
-}
-
-/**
- * editor_page_set_dates:
- * @page: An editor page.
- * @start: Start date for calendar component.
- * @end: End date for calendar component.
- *
- * Sets the calendar component DTSTART and DTEND in an editor page.
- **/
-void
-editor_page_set_dates (EditorPage *page, time_t start, time_t end)
-{
- g_return_if_fail (page != NULL);
- g_return_if_fail (IS_EDITOR_PAGE (page));
- g_return_if_fail (start != -1);
-
- g_assert (CLASS (page)->set_dates != NULL);
- (* CLASS (page)->set_dates) (page, start, end);
-}
-
-/**
- * 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
-editor_page_notify_changed (EditorPage *page)
-{
- g_return_if_fail (page != NULL);
- g_return_if_fail (IS_EDITOR_PAGE (page));
-
- gtk_signal_emit (GTK_OBJECT (page), editor_page_signals[CHANGED]);
-}
-
-/**
- * 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
-editor_page_notify_summary_changed (EditorPage *page)
-{
- g_return_if_fail (page != NULL);
- g_return_if_fail (IS_EDITOR_PAGE (page));
-
- gtk_signal_emit (GTK_OBJECT (page), editor_page_signals[SUMMARY_CHANGED]);
-}
diff --git a/calendar/gui/dialogs/editor-page.h b/calendar/gui/dialogs/editor-page.h
deleted file mode 100644
index 48e688ae16..0000000000
--- a/calendar/gui/dialogs/editor-page.h
+++ /dev/null
@@ -1,86 +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 the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef EDITOR_PAGE_H
-#define EDITOR_PAGE_H
-
-#include <time.h>
-#include <libgnome/gnome-defs.h>
-#include <gtk/gtkwidget.h>
-#include <cal-util/cal-component.h>
-
-BEGIN_GNOME_DECLS
-
-
-
-#define TYPE_EDITOR_PAGE (editor_page_get_type ())
-#define EDITOR_PAGE(obj) (GTK_CHECK_CAST ((obj), TYPE_EDITOR_PAGE, EditorPage))
-#define EDITOR_PAGE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_EDITOR_PAGE, \
- EditorPageClass))
-#define IS_EDITOR_PAGE(obj) (GTK_CHECK_TYPE ((obj), TYPE_EDITOR_PAGE))
-#define IS_EDITOR_PAGE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), TYPE_EDITOR_PAGE))
-
-typedef struct {
- GtkObject object;
-} EditorPage;
-
-typedef struct {
- GtkObjectClass parent_class;
-
- /* Notification signals */
-
- void (* changed) (EditorPage *page);
- void (* summary_changed) (EditorPage *page);
- void (* dtstart_changed) (EditorPage *page);
-
- /* Virtual methods */
-
- GtkWidget *(* get_widget) (EditorPage *page);
-
- void (* fill_widgets) (EditorPage *page, CalComponent *comp);
- void (* fill_component) (EditorPage *page, CalComponent *comp);
-
- void (* set_summary) (EditorPage *page, const char *summary);
- char *(* get_summary) (EditorPage *page);
-
- void (* set_dates) (EditorPage *page, time_t start, time_t end);
-} EditorPageClass;
-
-GtkType editor_page_get_type (void);
-
-GtkWidget *editor_page_get_widget (EditorPage *page);
-
-void editor_page_fill_widgets (EditorPage *page, CalComponent *comp);
-void editor_page_fill_component (EditorPage *page, CalComponent *comp);
-
-void editor_page_set_summary (EditorPage *page, const char *summary);
-char *editor_page_get_summary (EditorPage *page);
-
-void editor_page_set_dates (EditorPage *page, time_t start, time_t end);
-
-void editor_page_notify_changed (EditorPage *page);
-void editor_page_notify_summary_changed (EditorPage *page);
-
-
-
-END_GNOME_DECLS
-
-#endif
diff --git a/calendar/gui/dialogs/event-editor.c b/calendar/gui/dialogs/event-editor.c
new file mode 100644
index 0000000000..b53efe12aa
--- /dev/null
+++ b/calendar/gui/dialogs/event-editor.c
@@ -0,0 +1,155 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/* Evolution calendar - Event editor dialog
+ *
+ * Copyright (C) 2000 Helix Code, Inc.
+ * Copyright (C) 2001 Ximian, Inc.
+ *
+ * Authors: Miguel de Icaza <miguel@ximian.com>
+ * Federico Mena-Quintero <federico@ximian.com>
+ * Seth Alves <alves@hungry.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <string.h>
+#include <glade/glade.h>
+#include <gal/widgets/e-unicode.h>
+#include <libgnome/gnome-i18n.h>
+#include <widgets/misc/e-dateedit.h>
+
+#include "event-page.h"
+#include "alarm-page.h"
+#include "recurrence-page.h"
+#include "event-editor.h"
+
+struct _EventEditorPrivate {
+ EventPage *event_page;
+ AlarmPage *alarm_page;
+ RecurrencePage *recur_page;
+};
+
+
+
+static void event_editor_class_init (EventEditorClass *class);
+static void event_editor_init (EventEditor *ee);
+static void event_editor_destroy (GtkObject *object);
+
+static CompEditor *parent_class;
+
+
+
+/**
+ * event_editor_get_type:
+ *
+ * Registers the #EventEditor class if necessary, and returns the type ID
+ * associated to it.
+ *
+ * Return value: The type ID of the #EventEditor class.
+ **/
+GtkType
+event_editor_get_type (void)
+{
+ static GtkType event_editor_type = 0;
+
+ if (!event_editor_type) {
+ static const GtkTypeInfo event_editor_info = {
+ "EventEditor",
+ sizeof (EventEditor),
+ sizeof (EventEditorClass),
+ (GtkClassInitFunc) event_editor_class_init,
+ (GtkObjectInitFunc) event_editor_init,
+ NULL, /* reserved_1 */
+ NULL, /* reserved_2 */
+ (GtkClassInitFunc) NULL
+ };
+
+ event_editor_type = gtk_type_unique (TYPE_COMP_EDITOR,
+ &event_editor_info);
+ }
+
+ return event_editor_type;
+}
+
+/* Class initialization function for the event editor */
+static void
+event_editor_class_init (EventEditorClass *class)
+{
+ GtkObjectClass *object_class;
+
+ object_class = (GtkObjectClass *) class;
+
+ parent_class = gtk_type_class (TYPE_COMP_EDITOR);
+
+ object_class->destroy = event_editor_destroy;
+}
+
+/* Object initialization function for the event editor */
+static void
+event_editor_init (EventEditor *ee)
+{
+ EventEditorPrivate *priv;
+
+ priv = g_new0 (EventEditorPrivate, 1);
+ ee->priv = priv;
+
+ priv->event_page = event_page_new ();
+ comp_editor_append_page (COMP_EDITOR (ee),
+ COMP_EDITOR_PAGE (priv->event_page),
+ _("Appointment"));
+
+ priv->alarm_page = alarm_page_new ();
+ comp_editor_append_page (COMP_EDITOR (ee),
+ COMP_EDITOR_PAGE (priv->alarm_page),
+ _("Reminder"));
+
+ priv->recur_page = recurrence_page_new ();
+ comp_editor_append_page (COMP_EDITOR (ee),
+ COMP_EDITOR_PAGE (priv->recur_page),
+ _("Recurrence"));
+
+}
+
+/* Destroy handler for the event editor */
+static void
+event_editor_destroy (GtkObject *object)
+{
+ EventEditor *ee;
+ EventEditorPrivate *priv;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (IS_EVENT_EDITOR (object));
+
+ ee = EVENT_EDITOR (object);
+ priv = ee->priv;
+
+ if (GTK_OBJECT_CLASS (parent_class)->destroy)
+ (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+/**
+ * event_editor_new:
+ *
+ * Creates a new event editor dialog.
+ *
+ * Return value: A newly-created event editor dialog, or NULL if the event
+ * editor could not be created.
+ **/
+EventEditor *
+event_editor_new (void)
+{
+ return EVENT_EDITOR (gtk_type_new (TYPE_EVENT_EDITOR));
+}
diff --git a/calendar/gui/event-editor.h b/calendar/gui/dialogs/event-editor.h
index 60be54c784..6f05b1cf46 100644
--- a/calendar/gui/event-editor.h
+++ b/calendar/gui/dialogs/event-editor.h
@@ -22,19 +22,18 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
-#ifndef __EVENT_EDITOR_DIALOG_H__
-#define __EVENT_EDITOR_DIALOG_H__
+#ifndef __EVENT_EDITOR_H__
+#define __EVENT_EDITOR_H__
#include <libgnome/gnome-defs.h>
#include <gtk/gtkobject.h>
-#include "gnome-cal.h"
+#include "comp-editor.h"
#define TYPE_EVENT_EDITOR (event_editor_get_type ())
#define EVENT_EDITOR(obj) (GTK_CHECK_CAST ((obj), TYPE_EVENT_EDITOR, EventEditor))
-#define EVENT_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_EVENT_EDITOR, \
- EventEditorClass))
+#define EVENT_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_EVENT_EDITOR, EventEditorClass))
#define IS_EVENT_EDITOR(obj) (GTK_CHECK_TYPE ((obj), TYPE_EVENT_EDITOR))
#define IS_EVENT_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), TYPE_EVENT_EDITOR))
@@ -43,35 +42,21 @@ typedef struct _EventEditorClass EventEditorClass;
typedef struct _EventEditorPrivate EventEditorPrivate;
struct _EventEditor {
- GtkObject object;
+ CompEditor parent;
/* Private data */
EventEditorPrivate *priv;
};
struct _EventEditorClass {
- GtkObjectClass parent_class;
+ CompEditorClass parent_class;
};
-
-GtkType event_editor_get_type (void);
-EventEditor *event_editor_construct (EventEditor *ee);
-
-EventEditor *event_editor_new (void);
-
-void event_editor_set_cal_client (EventEditor *ee, CalClient *client);
-CalClient *event_editor_get_cal_client (EventEditor *ee);
-
-void event_editor_set_event_object (EventEditor *ee, CalComponent *comp);
-
-void event_editor_focus (EventEditor *ee);
-
-void event_editor_update_widgets (EventEditor *ee);
-
-
-GtkWidget *make_date_edit (void);
-GtkWidget *make_spin_button (int val, int low, int high);
+GtkType event_editor_get_type (void);
+EventEditor *event_editor_construct (EventEditor *ee);
+EventEditor *event_editor_new (void);
+void event_editor_update_widgets (EventEditor *ee);
-#endif /* __EVENT_EDITOR_DIALOG_H__ */
+#endif /* __EVENT_EDITOR_H__ */
diff --git a/calendar/gui/dialogs/event-page.c b/calendar/gui/dialogs/event-page.c
index 940ccf815c..8ade431f36 100644
--- a/calendar/gui/dialogs/event-page.c
+++ b/calendar/gui/dialogs/event-page.c
@@ -31,9 +31,10 @@
#include <glade/glade.h>
#include <gal/widgets/e-unicode.h>
#include <gal/widgets/e-categories.h>
-#include "cal-util/timeutil.h"
#include "e-util/e-dialog-widgets.h"
#include "widgets/misc/e-dateedit.h"
+#include "cal-util/timeutil.h"
+#include "../widget-util.h"
#include "../calendar-config.h"
#include "event-page.h"
@@ -65,6 +66,8 @@ struct _EventPagePrivate {
GtkWidget *categories_btn;
GtkWidget *categories;
+
+ gboolean updating;
};
@@ -73,22 +76,15 @@ static void event_page_class_init (EventPageClass *class);
static void event_page_init (EventPage *epage);
static void event_page_destroy (GtkObject *object);
-static GtkWidget *event_page_get_widget (EditorPage *page);
-static void event_page_fill_widgets (EditorPage *page, CalComponent *comp);
-static void event_page_fill_component (EditorPage *page, CalComponent *comp);
-static void event_page_set_summary (EditorPage *page, const char *summary);
-static char *event_page_get_summary (EditorPage *page);
-static void event_page_set_dates (EditorPage *page, time_t start, time_t end);
-
-/* Signal IDs */
-enum {
- DATES_CHANGED,
- LAST_SIGNAL
-};
+static GtkWidget *event_page_get_widget (CompEditorPage *page);
+static void event_page_fill_widgets (CompEditorPage *page, CalComponent *comp);
+static void event_page_fill_component (CompEditorPage *page, CalComponent *comp);
+static void event_page_set_summary (CompEditorPage *page, const char *summary);
+static void event_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates);
-static guint event_page_signals[LAST_SIGNAL] = { 0 };
+GtkWidget *make_date_edit (void);
-static EditorPageClass *parent_class = NULL;
+static CompEditorPageClass *parent_class = NULL;
@@ -117,7 +113,8 @@ event_page_get_type (void)
(GtkClassInitFunc) NULL
};
- event_page_type = gtk_type_unique (TYPE_EDITOR_PAGE, &event_page_info);
+ event_page_type = gtk_type_unique (TYPE_COMP_EDITOR_PAGE,
+ &event_page_info);
}
return event_page_type;
@@ -127,31 +124,18 @@ event_page_get_type (void)
static void
event_page_class_init (EventPageClass *class)
{
- EditorPageClass *editor_page_class;
+ CompEditorPageClass *editor_page_class;
GtkObjectClass *object_class;
- editor_page_class = (EditorPageClass *) class;
+ editor_page_class = (CompEditorPageClass *) class;
object_class = (GtkObjectClass *) class;
- parent_class = gtk_type_class (TYPE_EDITOR_PAGE);
-
- event_page_signals[DATES_CHANGED] =
- gtk_signal_new ("dates_changed",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EventPageClass, dates_changed),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- gtk_object_class_add_signals (object_class, event_page_signals, LAST_SIGNAL);
-
- class->dates_changed = NULL;
+ parent_class = gtk_type_class (TYPE_COMP_EDITOR_PAGE);
editor_page_class->get_widget = event_page_get_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->get_summary = event_page_get_summary;
editor_page_class->set_dates = event_page_set_dates;
object_class->destroy = event_page_destroy;
@@ -181,6 +165,8 @@ event_page_init (EventPage *epage)
priv->contacts = NULL;
priv->categories_btn = NULL;
priv->categories = NULL;
+
+ priv->updating = FALSE;
}
/* Destroy handler for the event page */
@@ -219,7 +205,7 @@ static const int classification_map[] = {
/* get_widget handler for the event page */
static GtkWidget *
-event_page_get_widget (EditorPage *page)
+event_page_get_widget (CompEditorPage *page)
{
EventPage *epage;
EventPagePrivate *priv;
@@ -230,8 +216,8 @@ event_page_get_widget (EditorPage *page)
return priv->main;
}
-/* Checks if the event's time starts and ends at midnight, and sets the "all day
- * event" box accordingly.
+/* Checks if the event's time starts and ends at midnight, and sets the
+ *"all day event" box accordingly.
*/
static void
check_all_day (EventPage *epage)
@@ -251,12 +237,15 @@ check_all_day (EventPage *epage)
g_assert (ev_end != -1);
/* all day event checkbox */
- if (time_day_begin (ev_start) == ev_start && time_day_begin (ev_end) == ev_end)
+ if (time_day_begin (ev_start) == ev_start
+ && time_day_begin (ev_end) == ev_end)
all_day = TRUE;
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->all_day_event), epage);
+ 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);
+ 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);
@@ -278,14 +267,17 @@ clear_widgets (EventPage *epage)
e_dialog_editable_set (priv->description, NULL);
/* Start and end times */
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_time), epage);
+ gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_time),
+ epage);
gtk_signal_handler_block_by_data (GTK_OBJECT (priv->end_time), epage);
e_date_edit_set_time (E_DATE_EDIT (priv->start_time), now);
e_date_edit_set_time (E_DATE_EDIT (priv->end_time), now);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->start_time), epage);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->end_time), epage);
+ gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->start_time),
+ epage);
+ gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->end_time),
+ epage);
check_all_day (epage);
@@ -299,7 +291,7 @@ clear_widgets (EventPage *epage)
/* fill_widgets handler for the event page */
static void
-event_page_fill_widgets (EditorPage *page, CalComponent *comp)
+event_page_fill_widgets (CompEditorPage *page, CalComponent *comp)
{
EventPage *epage;
EventPagePrivate *priv;
@@ -313,6 +305,10 @@ event_page_fill_widgets (EditorPage *page, CalComponent *comp)
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, description(s) */
@@ -341,17 +337,21 @@ event_page_fill_widgets (EditorPage *page, CalComponent *comp)
dtend = icaltime_as_timet (*d.value);
cal_component_free_datetime (&d);
- if (time_day_begin (dtstart) == dtstart && time_day_begin (dtend) == dtend)
+ if (time_day_begin (dtstart) == dtstart
+ && time_day_begin (dtend) == dtend)
dtend = time_add_day (dtend, -1);
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_time), epage);
+ gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_time),
+ epage);
gtk_signal_handler_block_by_data (GTK_OBJECT (priv->end_time), epage);
e_date_edit_set_time (E_DATE_EDIT (priv->start_time), dtstart);
e_date_edit_set_time (E_DATE_EDIT (priv->end_time), dtend);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->start_time), epage);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->end_time), epage);
+ gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->start_time),
+ epage);
+ gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->end_time),
+ epage);
check_all_day (epage);
@@ -361,17 +361,20 @@ event_page_fill_widgets (EditorPage *page, CalComponent *comp)
switch (cl) {
case CAL_COMPONENT_CLASS_PUBLIC:
- e_dialog_radio_set (priv->classification_public, CAL_COMPONENT_CLASS_PUBLIC,
+ e_dialog_radio_set (priv->classification_public,
+ CAL_COMPONENT_CLASS_PUBLIC,
classification_map);
break;
case CAL_COMPONENT_CLASS_PRIVATE:
- e_dialog_radio_set (priv->classification_public, CAL_COMPONENT_CLASS_PRIVATE,
+ e_dialog_radio_set (priv->classification_public,
+ CAL_COMPONENT_CLASS_PRIVATE,
classification_map);
break;
case CAL_COMPONENT_CLASS_CONFIDENTIAL:
- e_dialog_radio_set (priv->classification_public, CAL_COMPONENT_CLASS_CONFIDENTIAL,
+ e_dialog_radio_set (priv->classification_public,
+ CAL_COMPONENT_CLASS_CONFIDENTIAL,
classification_map);
break;
@@ -382,14 +385,15 @@ event_page_fill_widgets (EditorPage *page, CalComponent *comp)
}
/* Categories */
-
cal_component_get_categories (comp, &categories);
e_dialog_editable_set (priv->categories, categories);
+
+ priv->updating = FALSE;
}
/* fill_component handler for the event page */
static void
-event_page_fill_component (EditorPage *page, CalComponent *comp)
+event_page_fill_component (CompEditorPage *page, CalComponent *comp)
{
EventPage *epage;
EventPagePrivate *priv;
@@ -477,13 +481,14 @@ event_page_fill_component (EditorPage *page, CalComponent *comp)
/* Classification */
- classif = e_dialog_radio_get (priv->classification_public, classification_map);
+ classif = e_dialog_radio_get (priv->classification_public,
+ classification_map);
cal_component_set_classification (comp, classif);
}
/* set_summary handler for the event page */
static void
-event_page_set_summary (EditorPage *page, const char *summary)
+event_page_set_summary (CompEditorPage *page, const char *summary)
{
EventPage *epage;
EventPagePrivate *priv;
@@ -496,24 +501,8 @@ event_page_set_summary (EditorPage *page, const char *summary)
gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->summary), epage);
}
-/* get_summary handler for the event page */
-static char *
-event_page_get_summary (EditorPage *page)
-{
- EventPage *epage;
- EventPagePrivate *priv;
-
- epage = EVENT_PAGE (page);
- priv = epage->priv;
-
- return e_utf8_gtk_entry_get_text (GTK_ENTRY (priv->summary));
-}
-
-/* set_dates handler for the event page. We do nothing since we are *the*
- * only provider of the date values.
- */
static void
-event_page_set_dates (EditorPage *page, time_t start, time_t end)
+event_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates)
{
/* nothing */
}
@@ -525,22 +514,17 @@ static gboolean
get_widgets (EventPage *epage)
{
EventPagePrivate *priv;
- GtkWidget *toplevel;
priv = epage->priv;
#define GW(name) glade_xml_get_widget (priv->xml, name)
- toplevel = GW ("event-toplevel");
priv->main = GW ("event-page");
- if (!(toplevel && priv->main))
- return FALSE;
-
+ g_assert (priv->main);
gtk_widget_ref (priv->main);
gtk_widget_unparent (priv->main);
- gtk_widget_destroy (toplevel);
- priv->summary = GW ("summary");
+ priv->summary = GW ("general-summary");
priv->start_time = GW ("start-time");
priv->end_time = GW ("end-time");
@@ -579,9 +563,19 @@ static void
summary_changed_cb (GtkEditable *editable, gpointer data)
{
EventPage *epage;
+ EventPagePrivate *priv;
+ gchar *summary;
epage = EVENT_PAGE (data);
- editor_page_notify_summary_changed (EDITOR_PAGE (epage));
+ priv = epage->priv;
+
+ if (priv->updating)
+ return;
+
+ summary = gtk_editable_get_chars (editable, 0, -1);
+ comp_editor_page_notify_summary_changed (COMP_EDITOR_PAGE (epage),
+ summary);
+ g_free (summary);
}
/* Callback used when the start or end date widgets change. We check that the
@@ -594,12 +588,15 @@ date_changed_cb (EDateEdit *dedit, gpointer data)
EventPagePrivate *priv;
time_t start, end;
struct tm tm_start, tm_end;
-
+ CompEditorPageDates dates;
+
epage = EVENT_PAGE (data);
priv = epage->priv;
- /* Ensure that start < end */
+ if (priv->updating)
+ return;
+ /* Ensure that start < end */
start = e_date_edit_get_time (E_DATE_EDIT (priv->start_time));
g_assert (start != -1);
end = e_date_edit_get_time (E_DATE_EDIT (priv->end_time));
@@ -611,10 +608,10 @@ date_changed_cb (EDateEdit *dedit, gpointer data)
if (start == end && tm_start.tm_hour == 0
&& tm_start.tm_min == 0 && tm_start.tm_sec == 0) {
- /* If the start and end times are the same, but both are
- * on day boundaries, then that is OK since it means we
- * have an all-day event lasting 1 day. So we do
- * nothing here.
+ /* If the start and end times are the same, but both
+ * are on day boundaries, then that is OK since it
+ * means we have an all-day event lasting 1 day. So
+ * we do nothing here.
*/
} else if (GTK_WIDGET (dedit) == priv->start_time) {
/* Modify the end time */
@@ -627,7 +624,8 @@ date_changed_cb (EDateEdit *dedit, gpointer data)
tm_end.tm_sec = tm_start.tm_sec;
gtk_signal_handler_block_by_data (GTK_OBJECT (priv->end_time), epage);
- e_date_edit_set_time (E_DATE_EDIT (priv->end_time), mktime (&tm_end));
+ end = mktime (&tm_end);
+ e_date_edit_set_time (E_DATE_EDIT (priv->end_time), end);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->end_time), epage);
} else if (GTK_WIDGET (dedit) == priv->end_time) {
/* Modify the start time */
@@ -640,7 +638,8 @@ date_changed_cb (EDateEdit *dedit, gpointer data)
tm_start.tm_sec = tm_end.tm_sec;
gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_time), epage);
- e_date_edit_set_time (E_DATE_EDIT (priv->start_time), mktime (&tm_start));
+ start = mktime (&tm_start);
+ e_date_edit_set_time (E_DATE_EDIT (priv->start_time), start);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->start_time), epage);
} else
g_assert_not_reached ();
@@ -650,7 +649,12 @@ date_changed_cb (EDateEdit *dedit, gpointer data)
check_all_day (epage);
/* Notify upstream */
- gtk_signal_emit (GTK_OBJECT (epage), event_page_signals[DATES_CHANGED]);
+ dates.start = start;
+ dates.end = end;
+ dates.due = 0;
+ dates.complete = 0;
+ comp_editor_page_notify_dates_changed (COMP_EDITOR_PAGE (epage),
+ &dates);
}
/* Callback: all day event button toggled.
@@ -666,19 +670,21 @@ all_day_event_toggled_cb (GtkWidget *toggle, gpointer data)
struct tm start_tm, end_tm;
time_t start_t, end_t;
gboolean all_day;
-
+ CompEditorPageDates dates;
+
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 do not round it down to the previous
- * day, since if we do that and the user repeatedly turns the all_day
- * toggle on and off, the event keeps shrinking. (We'd also need to
- * make sure we didn't adjust the time when the radio button is
- * initially set.)
+ /* When the all_day toggle is turned on, the start date is
+ * rounded down to the start of the day, and end date is
+ * rounded down to the start of the day on which the event
+ * ends. The event is then taken to be inclusive of the days
+ * between the start and end days. Note that if the event end
+ * is at midnight, we do not round it down to the previous
+ * day, since if we do that and the user repeatedly turns the
+ * all_day toggle on and off, the event keeps shrinking.
+ * (We'd also need to make sure we didn't adjust the time when
+ * the radio button is initially set.)
*
* When the all_day_toggle is turned off, we set the event start to the
* start of the working day, and if the event end is on or before the
@@ -737,20 +743,30 @@ all_day_event_toggled_cb (GtkWidget *toggle, gpointer data)
}
}
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_time), epage);
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->end_time), epage);
+ gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_time),
+ epage);
+ gtk_signal_handler_block_by_data (GTK_OBJECT (priv->end_time),
+ epage);
- e_date_edit_set_time (E_DATE_EDIT (priv->start_time), mktime (&start_tm));
- e_date_edit_set_time (E_DATE_EDIT (priv->end_time), mktime (&end_tm));
+ start_t = mktime (&start_tm);
+ end_t = mktime (&end_tm);
+ e_date_edit_set_time (E_DATE_EDIT (priv->start_time), start_t);
+ e_date_edit_set_time (E_DATE_EDIT (priv->end_time), end_t);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->start_time), epage);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->end_time), epage);
+ gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->start_time),
+ epage);
+ gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->end_time),
+ 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);
/* Notify upstream */
- gtk_signal_emit (GTK_OBJECT (epage), event_page_signals[DATES_CHANGED]);
+ dates.start = start_t;
+ dates.end = end_t;
+ dates.due = 0;
+ comp_editor_page_notify_dates_changed (COMP_EDITOR_PAGE (epage),
+ &dates);
}
/* Callback used when the categories button is clicked; we must bring up the
@@ -792,9 +808,13 @@ static void
field_changed_cb (GtkWidget *widget, gpointer data)
{
EventPage *epage;
-
+ EventPagePrivate *priv;
+
epage = EVENT_PAGE (data);
- editor_page_notify_changed (EDITOR_PAGE (epage));
+ priv = epage->priv;
+
+ if (!priv->updating)
+ comp_editor_page_notify_changed (COMP_EDITOR_PAGE (epage));
}
/* Hooks the widget signals */
@@ -836,12 +856,15 @@ init_widgets (EventPage *epage)
GTK_SIGNAL_FUNC (field_changed_cb), epage);
gtk_signal_connect (GTK_OBJECT (priv->description), "changed",
GTK_SIGNAL_FUNC (field_changed_cb), epage);
- gtk_signal_connect (GTK_OBJECT (priv->classification_public), "toggled",
- GTK_SIGNAL_FUNC (field_changed_cb), epage);
- gtk_signal_connect (GTK_OBJECT (priv->classification_private), "toggled",
- GTK_SIGNAL_FUNC (field_changed_cb), epage);
- gtk_signal_connect (GTK_OBJECT (priv->classification_confidential), "toggled",
- GTK_SIGNAL_FUNC (field_changed_cb), epage);
+ gtk_signal_connect (GTK_OBJECT (priv->classification_public),
+ "toggled", GTK_SIGNAL_FUNC (field_changed_cb),
+ epage);
+ gtk_signal_connect (GTK_OBJECT (priv->classification_private),
+ "toggled", GTK_SIGNAL_FUNC (field_changed_cb),
+ epage);
+ gtk_signal_connect (GTK_OBJECT (priv->classification_confidential),
+ "toggled", GTK_SIGNAL_FUNC (field_changed_cb),
+ epage);
gtk_signal_connect (GTK_OBJECT (priv->categories), "changed",
GTK_SIGNAL_FUNC (field_changed_cb), epage);
@@ -869,14 +892,17 @@ event_page_construct (EventPage *epage)
priv = epage->priv;
- priv->xml = glade_xml_new (EVOLUTION_GLADEDIR "/event-page.glade", NULL);
+ priv->xml = glade_xml_new (EVOLUTION_GLADEDIR "/event-page.glade",
+ NULL);
if (!priv->xml) {
- g_message ("event_page_construct(): Could not load the Glade XML file!");
+ 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!");
+ g_message ("event_page_construct(): "
+ "Could not find all widgets in the XML file!");
return NULL;
}
@@ -907,27 +933,8 @@ event_page_new (void)
return epage;
}
-/**
- * event_page_get_dates:
- * @page: An event page.
- * @start: Return value for the start date, can be NULL.
- * @end: Return value for the end date, can be NULL.
- *
- * Queries the start and end dates for the calendar component in an event page.
- **/
-void
-event_page_get_dates (EventPage *page, time_t *start, time_t *end)
+GtkWidget *
+make_date_edit (void)
{
- EventPagePrivate *priv;
-
- g_return_if_fail (page != NULL);
- g_return_if_fail (IS_EVENT_PAGE (page));
-
- priv = page->priv;
-
- if (start)
- *start = e_date_edit_get_time (E_DATE_EDIT (priv->start_time));
-
- if (end)
- *end = e_date_edit_get_time (E_DATE_EDIT (priv->end_time));
+ return date_edit_new (TRUE, TRUE);
}
diff --git a/calendar/gui/dialogs/event-page.glade b/calendar/gui/dialogs/event-page.glade
index 76d2d4043e..e9b774fe41 100644
--- a/calendar/gui/dialogs/event-page.glade
+++ b/calendar/gui/dialogs/event-page.glade
@@ -18,6 +18,7 @@
<widget>
<class>GtkWindow</class>
<name>event-toplevel</name>
+ <visible>False</visible>
<title>window1</title>
<type>GTK_WINDOW_TOPLEVEL</type>
<position>GTK_WIN_POS_NONE</position>
@@ -349,7 +350,6 @@
<class>GtkButton</class>
<name>contacts-button</name>
<can_focus>True</can_focus>
- <relief>GTK_RELIEF_NORMAL</relief>
<child>
<padding>0</padding>
<expand>False</expand>
@@ -388,7 +388,6 @@
<class>GtkButton</class>
<name>categories-button</name>
<can_focus>True</can_focus>
- <relief>GTK_RELIEF_NORMAL</relief>
<child>
<padding>0</padding>
<expand>False</expand>
diff --git a/calendar/gui/dialogs/event-page.h b/calendar/gui/dialogs/event-page.h
index 04b01a0333..232455e491 100644
--- a/calendar/gui/dialogs/event-page.h
+++ b/calendar/gui/dialogs/event-page.h
@@ -25,7 +25,7 @@
#ifndef EVENT_PAGE_H
#define EVENT_PAGE_H
-#include "editor-page.h"
+#include "comp-editor-page.h"
BEGIN_GNOME_DECLS
@@ -33,35 +33,27 @@ BEGIN_GNOME_DECLS
#define TYPE_EVENT_PAGE (event_page_get_type ())
#define EVENT_PAGE(obj) (GTK_CHECK_CAST ((obj), TYPE_EVENT_PAGE, EventPage))
-#define EVENT_PAGE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_EVENT_PAGE, \
- EventPageClass))
+#define EVENT_PAGE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_EVENT_PAGE, EventPageClass))
#define IS_EVENT_PAGE(obj) (GTK_CHECK_TYPE ((obj), TYPE_EVENT_PAGE))
#define IS_EVENT_PAGE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), TYPE_EVENT_PAGE))
typedef struct _EventPagePrivate EventPagePrivate;
typedef struct {
- EditorPage page;
+ CompEditorPage page;
/* Private data */
EventPagePrivate *priv;
} EventPage;
typedef struct {
- EditorPageClass parent_class;
-
- /* Notification signals */
-
- void (* dates_changed) (EventPage *epage);
+ CompEditorPageClass parent_class;
} EventPageClass;
-GtkType event_page_get_type (void);
+GtkType event_page_get_type (void);
EventPage *event_page_construct (EventPage *epage);
-
-EventPage *event_page_new (void);
-
-void event_page_get_dates (EventPage *epage, time_t *start, time_t *end);
+EventPage *event_page_new (void);
diff --git a/calendar/gui/dialogs/recurrence-page.c b/calendar/gui/dialogs/recurrence-page.c
index 363ca94cc5..4d690be6dc 100644
--- a/calendar/gui/dialogs/recurrence-page.c
+++ b/calendar/gui/dialogs/recurrence-page.c
@@ -39,6 +39,7 @@
#include "../tag-calendar.h"
#include "../weekday-picker.h"
#include "../widget-util.h"
+#include "comp-editor-util.h"
#include "recurrence-page.h"
@@ -102,6 +103,9 @@ static const int ending_types_map[] = {
/* Private part of the RecurrencePage structure */
struct _RecurrencePagePrivate {
+ /* Component we use to expand the recurrence rules for the preview */
+ CalComponent *comp;
+
/* Glade XML data */
GladeXML *xml;
@@ -110,7 +114,7 @@ struct _RecurrencePagePrivate {
GtkWidget *main;
GtkWidget *summary;
- GtkWidget *starting_date;
+ GtkWidget *date_time;
GtkWidget *none;
GtkWidget *simple;
@@ -157,8 +161,7 @@ struct _RecurrencePagePrivate {
/* For the recurrence preview, the actual widget */
GtkWidget *preview_calendar;
- /* Component we use to expand the recurrence rules for the preview calendar */
- CalComponent *comp;
+ gboolean updating;
};
@@ -167,14 +170,15 @@ static void recurrence_page_class_init (RecurrencePageClass *class);
static void recurrence_page_init (RecurrencePage *rpage);
static void recurrence_page_destroy (GtkObject *object);
-static GtkWidget *recurrence_page_get_widget (EditorPage *page);
-static void recurrence_page_fill_widgets (EditorPage *page, CalComponent *comp);
-static void recurrence_page_fill_component (EditorPage *page, CalComponent *comp);
-static void recurrence_page_set_summary (EditorPage *page, const char *summary);
-static char *recurrence_page_get_summary (EditorPage *page);
-static void recurrence_page_set_dates (EditorPage *page, time_t start, time_t end);
+static GtkWidget *recurrence_page_get_widget (CompEditorPage *page);
+static void recurrence_page_fill_widgets (CompEditorPage *page, CalComponent *comp);
+static void recurrence_page_fill_component (CompEditorPage *page, CalComponent *comp);
+static void recurrence_page_set_summary (CompEditorPage *page, const char *summary);
+static void recurrence_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates);
-static EditorPageClass *parent_class = NULL;
+static void field_changed (RecurrencePage *apage);
+
+static CompEditorPageClass *parent_class = NULL;
@@ -203,7 +207,8 @@ recurrence_page_get_type (void)
(GtkClassInitFunc) NULL
};
- recurrence_page_type = gtk_type_unique (TYPE_EDITOR_PAGE, &recurrence_page_info);
+ recurrence_page_type = gtk_type_unique (TYPE_COMP_EDITOR_PAGE,
+ &recurrence_page_info);
}
return recurrence_page_type;
@@ -213,19 +218,18 @@ recurrence_page_get_type (void)
static void
recurrence_page_class_init (RecurrencePageClass *class)
{
- EditorPageClass *editor_page_class;
+ CompEditorPageClass *editor_page_class;
GtkObjectClass *object_class;
- editor_page_class = (EditorPageClass *) class;
+ editor_page_class = (CompEditorPageClass *) class;
object_class = (GtkObjectClass *) class;
- parent_class = gtk_type_class (TYPE_EDITOR_PAGE);
+ parent_class = gtk_type_class (TYPE_COMP_EDITOR_PAGE);
editor_page_class->get_widget = recurrence_page_get_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->get_summary = recurrence_page_get_summary;
editor_page_class->set_dates = recurrence_page_set_dates;
object_class->destroy = recurrence_page_destroy;
@@ -244,7 +248,7 @@ recurrence_page_init (RecurrencePage *rpage)
priv->main = NULL;
priv->summary = NULL;
- priv->starting_date = NULL;
+ priv->date_time = NULL;
priv->none = NULL;
priv->simple = NULL;
priv->custom = NULL;
@@ -276,22 +280,23 @@ static void
free_exception_clist_data (RecurrencePage *rpage)
{
RecurrencePagePrivate *priv;
- GtkCList *clist;
int i;
priv = rpage->priv;
- clist = GTK_CLIST (priv->exception_list);
-
- for (i = 0; i < clist->rows; i++) {
- gpointer data;
+ if (priv->exception_list) {
+ GtkCList *clist = GTK_CLIST (priv->exception_list);
- data = gtk_clist_get_row_data (clist, i);
- g_free (data);
- gtk_clist_set_row_data (clist, i, NULL);
+ for (i = 0; i < clist->rows; i++) {
+ gpointer data;
+
+ data = gtk_clist_get_row_data (clist, i);
+ g_free (data);
+ gtk_clist_set_row_data (clist, i, NULL);
+ }
+
+ gtk_clist_clear (clist);
}
-
- gtk_clist_clear (clist);
}
/* Destroy handler for the recurrence page */
@@ -325,7 +330,7 @@ recurrence_page_destroy (GtkObject *object)
/* get_widget handler for the recurrence page */
static GtkWidget *
-recurrence_page_get_widget (EditorPage *page)
+recurrence_page_get_widget (CompEditorPage *page)
{
RecurrencePage *rpage;
RecurrencePagePrivate *priv;
@@ -366,7 +371,9 @@ clear_widgets (RecurrencePage *rpage)
menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->interval_unit));
gtk_signal_handler_block_by_data (GTK_OBJECT (menu), rpage);
- e_dialog_option_menu_set (priv->interval_unit, ICAL_DAILY_RECURRENCE, freq_map);
+ e_dialog_option_menu_set (priv->interval_unit,
+ ICAL_DAILY_RECURRENCE,
+ freq_map);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), rpage);
priv->ending_date = time (NULL);
@@ -374,7 +381,9 @@ clear_widgets (RecurrencePage *rpage)
menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->ending_menu));
gtk_signal_handler_block_by_data (GTK_OBJECT (menu), rpage);
- e_dialog_option_menu_set (priv->ending_menu, ENDING_FOREVER, ending_types_map);
+ e_dialog_option_menu_set (priv->ending_menu,
+ ENDING_FOREVER,
+ ending_types_map);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), rpage);
/* Exceptions list */
@@ -455,8 +464,8 @@ fill_exception_widgets (RecurrencePage *rpage, CalComponent *comp)
gtk_clist_select_row (GTK_CLIST (priv->exception_list), 0, 0);
}
-/* Computes a weekday mask for the start day of a calendar component, for use in
- * a WeekdayPicker widget.
+/* Computes a weekday mask for the start day of a calendar component,
+ * for use in a WeekdayPicker widget.
*/
static guint8
get_start_weekday_mask (CalComponent *comp)
@@ -533,9 +542,11 @@ sensitize_recur_widgets (RecurrencePage *rpage)
gtk_widget_set_sensitive (priv->params, FALSE);
gtk_widget_hide (priv->params);
- label = gtk_label_new (_("This appointment contains recurrences that Evolution "
+ label = gtk_label_new (_("This appointment contains "
+ "recurrences that Evolution "
"cannot edit."));
- gtk_container_add (GTK_CONTAINER (priv->custom_warning_bin), label);
+ gtk_container_add (GTK_CONTAINER (priv->custom_warning_bin),
+ label);
gtk_widget_show_all (priv->custom_warning_bin);
break;
@@ -574,7 +585,8 @@ simple_recur_to_comp (RecurrencePage *rpage, CalComponent *comp)
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 ();
+ r.week_start = ICAL_SUNDAY_WEEKDAY
+ + calendar_config_get_week_start_day ();
/* Frequency-specific data */
@@ -639,31 +651,38 @@ simple_recur_to_comp (RecurrencePage *rpage, CalComponent *comp)
break;
case MONTH_DAY_MON:
- r.by_day[0] = nth_weekday (day_index, ICAL_MONDAY_WEEKDAY);
+ r.by_day[0] = nth_weekday (day_index,
+ ICAL_MONDAY_WEEKDAY);
break;
case MONTH_DAY_TUE:
- r.by_day[0] = nth_weekday (day_index, ICAL_TUESDAY_WEEKDAY);
+ r.by_day[0] = nth_weekday (day_index,
+ ICAL_TUESDAY_WEEKDAY);
break;
case MONTH_DAY_WED:
- r.by_day[0] = nth_weekday (day_index, ICAL_WEDNESDAY_WEEKDAY);
+ r.by_day[0] = nth_weekday (day_index,
+ ICAL_WEDNESDAY_WEEKDAY);
break;
case MONTH_DAY_THU:
- r.by_day[0] = nth_weekday (day_index, ICAL_THURSDAY_WEEKDAY);
+ r.by_day[0] = nth_weekday (day_index,
+ ICAL_THURSDAY_WEEKDAY);
break;
case MONTH_DAY_FRI:
- r.by_day[0] = nth_weekday (day_index, ICAL_FRIDAY_WEEKDAY);
+ r.by_day[0] = nth_weekday (day_index,
+ ICAL_FRIDAY_WEEKDAY);
break;
case MONTH_DAY_SAT:
- r.by_day[0] = nth_weekday (day_index, ICAL_SATURDAY_WEEKDAY);
+ r.by_day[0] = nth_weekday (day_index,
+ ICAL_SATURDAY_WEEKDAY);
break;
case MONTH_DAY_SUN:
- r.by_day[0] = nth_weekday (day_index, ICAL_SUNDAY_WEEKDAY);
+ r.by_day[0] = nth_weekday (day_index,
+ ICAL_SUNDAY_WEEKDAY);
break;
default:
@@ -683,7 +702,8 @@ simple_recur_to_comp (RecurrencePage *rpage, CalComponent *comp)
/* Ending date */
- ending_type = e_dialog_option_menu_get (priv->ending_menu, ending_types_map);
+ ending_type = e_dialog_option_menu_get (priv->ending_menu,
+ ending_types_map);
switch (ending_type) {
case ENDING_FOR:
@@ -842,7 +862,7 @@ weekday_picker_changed_cb (WeekdayPicker *wp, gpointer data)
rpage = RECURRENCE_PAGE (data);
- editor_page_notify_changed (EDITOR_PAGE (rpage));
+ field_changed (rpage);
preview_recur (rpage);
}
@@ -882,7 +902,8 @@ make_weekly_special (RecurrencePage *rpage)
weekday_picker_set_blocked_days (wp, priv->weekday_blocked_day_mask);
gtk_signal_connect (GTK_OBJECT (wp), "changed",
- GTK_SIGNAL_FUNC (weekday_picker_changed_cb), rpage);
+ GTK_SIGNAL_FUNC (weekday_picker_changed_cb),
+ rpage);
}
/* Creates the option menu for the monthly recurrence days */
@@ -938,7 +959,8 @@ adjust_day_index_spin (RecurrencePage *rpage)
g_assert (priv->month_index_spin != NULL);
g_assert (GTK_IS_SPIN_BUTTON (priv->month_index_spin));
- month_day = e_dialog_option_menu_get (priv->month_day_menu, month_day_options_map);
+ month_day = e_dialog_option_menu_get (priv->month_day_menu,
+ month_day_options_map);
adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->month_index_spin));
@@ -970,9 +992,9 @@ adjust_day_index_spin (RecurrencePage *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.
+/* 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)
@@ -982,7 +1004,7 @@ month_day_menu_selection_done_cb (GtkMenuShell *menu_shell, gpointer data)
rpage = RECURRENCE_PAGE (data);
adjust_day_index_spin (rpage);
- editor_page_notify_changed (EDITOR_PAGE (rpage));
+ field_changed (rpage);
preview_recur (rpage);
}
@@ -994,7 +1016,7 @@ month_index_value_changed_cb (GtkAdjustment *adj, gpointer data)
rpage = RECURRENCE_PAGE (data);
- editor_page_notify_changed (EDITOR_PAGE (rpage));
+ field_changed (rpage);
preview_recur (rpage);
}
@@ -1024,13 +1046,15 @@ make_monthly_special (RecurrencePage *rpage)
adj = GTK_ADJUSTMENT (gtk_adjustment_new (1, 1, 31, 1, 10, 10));
priv->month_index_spin = gtk_spin_button_new (adj, 1, 0);
- gtk_box_pack_start (GTK_BOX (hbox), priv->month_index_spin, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), priv->month_index_spin,
+ FALSE, FALSE, 0);
label = gtk_label_new (_("th"));
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
priv->month_day_menu = make_recur_month_menu ();
- gtk_box_pack_start (GTK_BOX (hbox), priv->month_day_menu, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), priv->month_day_menu,
+ FALSE, FALSE, 0);
gtk_widget_show_all (hbox);
@@ -1043,11 +1067,13 @@ make_monthly_special (RecurrencePage *rpage)
adjust_day_index_spin (rpage);
gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
- GTK_SIGNAL_FUNC (month_index_value_changed_cb), rpage);
+ GTK_SIGNAL_FUNC (month_index_value_changed_cb),
+ rpage);
menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->month_day_menu));
gtk_signal_connect (GTK_OBJECT (menu), "selection_done",
- GTK_SIGNAL_FUNC (month_day_menu_selection_done_cb), rpage);
+ GTK_SIGNAL_FUNC (month_day_menu_selection_done_cb),
+ rpage);
}
/* Changes the recurrence-special widget to match the interval units.
@@ -1099,7 +1125,7 @@ make_recurrence_special (RecurrencePage *rpage)
}
}
-/* Counts the number of elements in the by_xxx fields of an icalrecurrencetype */
+/* Counts the elements in the by_xxx fields of an icalrecurrencetype */
static int
count_by_xxx (short *field, int max_elements)
{
@@ -1119,7 +1145,7 @@ ending_until_changed_cb (EDateEdit *de, gpointer data)
RecurrencePage *rpage;
rpage = RECURRENCE_PAGE (data);
- editor_page_notify_changed (EDITOR_PAGE (rpage));
+ field_changed (rpage);
preview_recur (rpage);
}
@@ -1140,7 +1166,8 @@ make_ending_until_special (RecurrencePage *rpage)
priv->ending_date_edit = date_edit_new (TRUE, FALSE);
de = E_DATE_EDIT (priv->ending_date_edit);
- gtk_container_add (GTK_CONTAINER (priv->ending_special), GTK_WIDGET (de));
+ gtk_container_add (GTK_CONTAINER (priv->ending_special),
+ GTK_WIDGET (de));
gtk_widget_show_all (GTK_WIDGET (de));
/* Set the value */
@@ -1158,7 +1185,7 @@ ending_count_value_changed_cb (GtkAdjustment *adj, gpointer data)
RecurrencePage *rpage;
rpage = RECURRENCE_PAGE (data);
- editor_page_notify_changed (EDITOR_PAGE (rpage));
+ field_changed (rpage);
preview_recur (rpage);
}
@@ -1183,7 +1210,8 @@ make_ending_count_special (RecurrencePage *rpage)
adj = GTK_ADJUSTMENT (gtk_adjustment_new (1, 1, 10000, 1, 10, 10));
priv->ending_count_spin = gtk_spin_button_new (adj, 1, 0);
- gtk_box_pack_start (GTK_BOX (hbox), priv->ending_count_spin, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), priv->ending_count_spin,
+ FALSE, FALSE, 0);
label = gtk_label_new (_("occurrences"));
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
@@ -1195,10 +1223,11 @@ make_ending_count_special (RecurrencePage *rpage)
e_dialog_spin_set (priv->ending_count_spin, priv->ending_count);
gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
- GTK_SIGNAL_FUNC (ending_count_value_changed_cb), rpage);
+ GTK_SIGNAL_FUNC (ending_count_value_changed_cb),
+ rpage);
}
-/* Changes the recurrence-ending-special widget to match the ending date option.
+/* Changes the recurrence-ending-special widget to match the ending date option
*
* For: <n> [days, weeks, months, years, occurrences]
* Until: <date selector>
@@ -1219,7 +1248,8 @@ make_ending_special (RecurrencePage *rpage)
priv->ending_count_spin = NULL;
}
- ending_type = e_dialog_option_menu_get (priv->ending_menu, ending_types_map);
+ ending_type = e_dialog_option_menu_get (priv->ending_menu,
+ ending_types_map);
switch (ending_type) {
case ENDING_FOR:
@@ -1290,10 +1320,12 @@ fill_ending_date (RecurrencePage *rpage, struct icalrecurrencetype *r)
* no rdates or exrules (exdates are handled just fine elsewhere).
*/
static void
-recurrence_page_fill_widgets (EditorPage *page, CalComponent *comp)
+recurrence_page_fill_widgets (CompEditorPage *page, CalComponent *comp)
{
RecurrencePage *rpage;
RecurrencePagePrivate *priv;
+ CalComponentText text;
+ CompEditorPageDates dates;
GSList *rrule_list;
int len;
struct icalrecurrencetype *r;
@@ -1306,8 +1338,8 @@ recurrence_page_fill_widgets (EditorPage *page, CalComponent *comp)
rpage = RECURRENCE_PAGE (page);
priv = rpage->priv;
- /* Keep a copy of the component so that we can expand the recurrence set
- * for the preview.
+ /* Keep a copy of the component so that we can expand the recurrence
+ * set for the preview.
*/
if (priv->comp)
@@ -1315,10 +1347,21 @@ recurrence_page_fill_widgets (EditorPage *page, CalComponent *comp)
priv->comp = cal_component_clone (comp);
- /* Clean the page */
+ /* Don't send off changes during this time */
+ priv->updating = TRUE;
+ /* Clean the page */
clear_widgets (rpage);
+ /* Summary */
+ cal_component_get_summary (comp, &text);
+ recurrence_page_set_summary (page, text.value);
+
+ /* Dates */
+ comp_editor_dates (&dates, comp);
+ recurrence_page_set_dates (page, &dates);
+
+ /* Exceptions */
fill_exception_widgets (rpage, comp);
/* Set up defaults for the special widgets */
@@ -1329,13 +1372,19 @@ recurrence_page_fill_widgets (EditorPage *page, CalComponent *comp)
if (!cal_component_has_rdates (comp)
&& !cal_component_has_rrules (comp)
&& !cal_component_has_exrules (comp)) {
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->none), rpage);
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->simple), rpage);
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->custom), rpage);
+ 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_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);
@@ -1400,7 +1449,9 @@ recurrence_page_fill_widgets (EditorPage *page, CalComponent *comp)
menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->interval_unit));
gtk_signal_handler_block_by_data (GTK_OBJECT (menu), rpage);
- e_dialog_option_menu_set (priv->interval_unit, ICAL_DAILY_RECURRENCE, freq_map);
+ e_dialog_option_menu_set (priv->interval_unit,
+ ICAL_DAILY_RECURRENCE,
+ freq_map);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), rpage);
break;
@@ -1465,7 +1516,9 @@ recurrence_page_fill_widgets (EditorPage *page, CalComponent *comp)
menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->interval_unit));
gtk_signal_handler_block_by_data (GTK_OBJECT (menu), rpage);
- e_dialog_option_menu_set (priv->interval_unit, ICAL_WEEKLY_RECURRENCE, freq_map);
+ e_dialog_option_menu_set (priv->interval_unit,
+ ICAL_WEEKLY_RECURRENCE,
+ freq_map);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), rpage);
break;
}
@@ -1537,7 +1590,9 @@ recurrence_page_fill_widgets (EditorPage *page, CalComponent *comp)
menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->interval_unit));
gtk_signal_handler_block_by_data (GTK_OBJECT (menu), rpage);
- e_dialog_option_menu_set (priv->interval_unit, ICAL_MONTHLY_RECURRENCE, freq_map);
+ e_dialog_option_menu_set (priv->interval_unit,
+ ICAL_MONTHLY_RECURRENCE,
+ freq_map);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), rpage);
break;
@@ -1552,7 +1607,9 @@ recurrence_page_fill_widgets (EditorPage *page, CalComponent *comp)
menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->interval_unit));
gtk_signal_handler_block_by_data (GTK_OBJECT (menu), rpage);
- e_dialog_option_menu_set (priv->interval_unit, ICAL_YEARLY_RECURRENCE, freq_map);
+ e_dialog_option_menu_set (priv->interval_unit,
+ ICAL_YEARLY_RECURRENCE,
+ freq_map);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), rpage);
break;
@@ -1601,11 +1658,13 @@ recurrence_page_fill_widgets (EditorPage *page, CalComponent *comp)
cal_component_free_recur_list (rrule_list);
preview_recur (rpage);
+
+ priv->updating = FALSE;
}
/* fill_component handler for the recurrence page */
static void
-recurrence_page_fill_component (EditorPage *page, CalComponent *comp)
+recurrence_page_fill_component (CompEditorPage *page, CalComponent *comp)
{
RecurrencePage *rpage;
@@ -1615,52 +1674,33 @@ recurrence_page_fill_component (EditorPage *page, CalComponent *comp)
/* set_summary handler for the recurrence page */
static void
-recurrence_page_set_summary (EditorPage *page, const char *summary)
+recurrence_page_set_summary (CompEditorPage *page, const char *summary)
{
RecurrencePage *rpage;
RecurrencePagePrivate *priv;
-
+ gchar *s;
+
rpage = RECURRENCE_PAGE (page);
priv = rpage->priv;
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->summary), rpage);
- e_utf8_gtk_entry_set_text (GTK_ENTRY (priv->summary), summary);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->summary), rpage);
-}
-
-/* get_summary handler for the recurrence page */
-static char *
-recurrence_page_get_summary (EditorPage *page)
-{
- RecurrencePage *rpage;
- RecurrencePagePrivate *priv;
-
- rpage = RECURRENCE_PAGE (page);
- priv = rpage->priv;
-
- return e_utf8_gtk_entry_get_text (GTK_ENTRY (priv->summary));
+ s = e_utf8_to_gtk_string (priv->summary, summary);
+ gtk_label_set_text (GTK_LABEL (priv->summary), s);
+ g_free (s);
}
/* set_dates handler for the recurrence page */
static void
-recurrence_page_set_dates (EditorPage *page, time_t start, time_t end)
+recurrence_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates)
{
RecurrencePage *rpage;
RecurrencePagePrivate *priv;
- char str[128];
- struct tm tm;
CalComponentDateTime dt;
struct icaltimetype icaltime;
rpage = RECURRENCE_PAGE (page);
priv = rpage->priv;
- /* Set the starting date label */
-
- tm = *localtime (&start);
- strftime (str, sizeof (str), _("%A %b %d %Y %H:%M:%S"), &tm);
-
- gtk_label_set_text (GTK_LABEL (priv->starting_date), str);
+ comp_editor_date_label (dates, priv->date_time);
/* Copy the dates to our component */
@@ -1670,11 +1710,13 @@ recurrence_page_set_dates (EditorPage *page, time_t start, time_t end)
dt.value = &icaltime;
dt.tzid = NULL;
- *dt.value = icaltime_from_timet (start, FALSE);
+ *dt.value = icaltime_from_timet (dates->start, FALSE);
cal_component_set_dtstart (priv->comp, &dt);
- *dt.value = icaltime_from_timet (end, FALSE);
- cal_component_set_dtend (priv->comp, &dt);
+ if (dates->end != 0) {
+ *dt.value = icaltime_from_timet (dates->end, FALSE);
+ cal_component_set_dtend (priv->comp, &dt);
+ }
}
@@ -1684,23 +1726,18 @@ static gboolean
get_widgets (RecurrencePage *rpage)
{
RecurrencePagePrivate *priv;
- GtkWidget *toplevel;
priv = rpage->priv;
#define GW(name) glade_xml_get_widget (priv->xml, name)
- toplevel = GW ("recurrence-toplevel");
priv->main = GW ("recurrence-page");
- if (!(toplevel && priv->main))
- return FALSE;
-
+ g_assert (priv->main);
gtk_widget_ref (priv->main);
gtk_widget_unparent (priv->main);
- gtk_widget_destroy (toplevel);
priv->summary = GW ("summary");
- priv->starting_date = GW ("starting-date");
+ priv->date_time = GW ("date-time");
priv->none = GW ("none");
priv->simple = GW ("simple");
@@ -1723,9 +1760,9 @@ get_widgets (RecurrencePage *rpage)
priv->preview_bin = GW ("preview-bin");
#undef GW
-
+
return (priv->summary
- && priv->starting_date
+ && priv->date_time
&& priv->none
&& priv->simple
&& priv->custom
@@ -1744,16 +1781,6 @@ get_widgets (RecurrencePage *rpage)
&& priv->preview_bin);
}
-/* Callback used when the summary changes; we emit the notification signal. */
-static void
-summary_changed_cb (GtkEditable *editable, gpointer data)
-{
- RecurrencePage *rpage;
-
- rpage = RECURRENCE_PAGE (data);
- editor_page_notify_summary_changed (EDITOR_PAGE (rpage));
-}
-
/* Callback used when the displayed date range in the recurrence preview
* calendar changes.
*/
@@ -1776,7 +1803,7 @@ type_toggled_cb (GtkToggleButton *toggle, gpointer data)
rpage = RECURRENCE_PAGE (data);
- editor_page_notify_changed (EDITOR_PAGE (rpage));
+ field_changed (rpage);
if (toggle->active) {
sensitize_recur_widgets (rpage);
@@ -1792,7 +1819,7 @@ interval_value_changed_cb (GtkAdjustment *adj, gpointer data)
rpage = RECURRENCE_PAGE (data);
- editor_page_notify_changed (EDITOR_PAGE (rpage));
+ field_changed (rpage);
preview_recur (rpage);
}
@@ -1806,7 +1833,7 @@ interval_selection_done_cb (GtkMenuShell *menu_shell, gpointer data)
rpage = RECURRENCE_PAGE (data);
- editor_page_notify_changed (EDITOR_PAGE (rpage));
+ field_changed (rpage);
make_recurrence_special (rpage);
preview_recur (rpage);
}
@@ -1821,7 +1848,7 @@ ending_selection_done_cb (GtkMenuShell *menu_shell, gpointer data)
rpage = RECURRENCE_PAGE (data);
- editor_page_notify_changed (EDITOR_PAGE (rpage));
+ field_changed (rpage);
make_ending_special (rpage);
preview_recur (rpage);
}
@@ -1837,7 +1864,7 @@ exception_add_cb (GtkWidget *widget, gpointer data)
rpage = RECURRENCE_PAGE (data);
priv = rpage->priv;
- editor_page_notify_changed (EDITOR_PAGE (rpage));
+ field_changed (rpage);
t = e_date_edit_get_time (E_DATE_EDIT (priv->exception_date));
append_exception (rpage, t);
@@ -1861,7 +1888,7 @@ exception_modify_cb (GtkWidget *widget, gpointer data)
if (!clist->selection)
return;
- editor_page_notify_changed (EDITOR_PAGE (rpage));
+ field_changed (rpage);
sel = GPOINTER_TO_INT (clist->selection->data);
@@ -1890,7 +1917,7 @@ exception_delete_cb (GtkWidget *widget, gpointer data)
if (!clist->selection)
return;
- editor_page_notify_changed (EDITOR_PAGE (rpage));
+ field_changed (rpage);
sel = GPOINTER_TO_INT (clist->selection->data);
@@ -1912,11 +1939,13 @@ exception_delete_cb (GtkWidget *widget, gpointer data)
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.
+/* Callback used when a row is selected in the list of exception
+ * dates. We must update the date/time widgets to reflect the
+ * exception's value.
*/
static void
-exception_select_row_cb (GtkCList *clist, gint row, gint col, GdkEvent *event, gpointer data)
+exception_select_row_cb (GtkCList *clist, gint row, gint col,
+ GdkEvent *event, gpointer data)
{
RecurrencePage *rpage;
RecurrencePagePrivate *priv;
@@ -1931,6 +1960,18 @@ exception_select_row_cb (GtkCList *clist, gint row, gint col, GdkEvent *event, g
e_date_edit_set_time (E_DATE_EDIT (priv->exception_date), *t);
}
+/* 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)
@@ -1942,19 +1983,17 @@ init_widgets (RecurrencePage *rpage)
priv = rpage->priv;
- /* Summary */
- gtk_signal_connect (GTK_OBJECT (priv->summary), "changed",
- GTK_SIGNAL_FUNC (summary_changed_cb), rpage);
-
/* Recurrence preview */
priv->preview_calendar = e_calendar_new ();
ecal = E_CALENDAR (priv->preview_calendar);
gtk_signal_connect (GTK_OBJECT (ecal->calitem), "date_range_changed",
- GTK_SIGNAL_FUNC (preview_date_range_changed_cb), rpage);
+ GTK_SIGNAL_FUNC (preview_date_range_changed_cb),
+ rpage);
calendar_config_configure_e_calendar (ecal);
e_calendar_item_set_max_days_sel (ecal->calitem, 0);
- gtk_container_add (GTK_CONTAINER (priv->preview_bin), priv->preview_calendar);
+ gtk_container_add (GTK_CONTAINER (priv->preview_bin),
+ priv->preview_calendar);
gtk_widget_show (priv->preview_calendar);
/* Recurrence types */
@@ -1970,13 +2009,15 @@ init_widgets (RecurrencePage *rpage)
adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->interval_value));
gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
- GTK_SIGNAL_FUNC (interval_value_changed_cb), rpage);
+ GTK_SIGNAL_FUNC (interval_value_changed_cb),
+ rpage);
/* Recurrence units */
menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->interval_unit));
gtk_signal_connect (GTK_OBJECT (menu), "selection_done",
- GTK_SIGNAL_FUNC (interval_selection_done_cb), rpage);
+ GTK_SIGNAL_FUNC (interval_selection_done_cb),
+ rpage);
/* Recurrence ending */
@@ -2017,14 +2058,17 @@ recurrence_page_construct (RecurrencePage *rpage)
priv = rpage->priv;
- priv->xml = glade_xml_new (EVOLUTION_GLADEDIR "/recurrence-page.glade", NULL);
+ priv->xml = glade_xml_new (EVOLUTION_GLADEDIR
+ "/recurrence-page.glade", NULL);
if (!priv->xml) {
- g_message ("recurrence_page_construct(): Could not load the Glade XML file!");
+ 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!");
+ g_message ("recurrence_page_construct(): "
+ "Could not find all widgets in the XML file!");
return NULL;
}
diff --git a/calendar/gui/dialogs/recurrence-page.glade b/calendar/gui/dialogs/recurrence-page.glade
index b84a3c288c..1793e175d7 100644
--- a/calendar/gui/dialogs/recurrence-page.glade
+++ b/calendar/gui/dialogs/recurrence-page.glade
@@ -18,6 +18,7 @@
<widget>
<class>GtkWindow</class>
<name>recurrence-toplevel</name>
+ <visible>False</visible>
<title>window1</title>
<type>GTK_WINDOW_TOPLEVEL</type>
<position>GTK_WIN_POS_NONE</position>
@@ -36,7 +37,7 @@
<widget>
<class>GtkFrame</class>
<name>frame35</name>
- <label>Appointment Basics</label>
+ <label>Basics</label>
<label_xalign>0</label_xalign>
<shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
<child>
@@ -58,14 +59,13 @@
<widget>
<class>GtkLabel</class>
<name>label66</name>
- <label>Su_mmary:</label>
+ <label>Summary:</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
- <default_focus_target>recurrence-summary</default_focus_target>
<child>
<left_attach>0</left_attach>
<right_attach>1</right_attach>
@@ -85,7 +85,7 @@
<widget>
<class>GtkLabel</class>
<name>label67</name>
- <label>_Starting date:</label>
+ <label>Date/Time:</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0</xalign>
@@ -109,13 +109,15 @@
</widget>
<widget>
- <class>GtkEntry</class>
- <name>recurrence-summary</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
+ <class>GtkLabel</class>
+ <name>summary</name>
+ <label></label>
+ <justify>GTK_JUSTIFY_CENTER</justify>
+ <wrap>False</wrap>
+ <xalign>0</xalign>
+ <yalign>0.5</yalign>
+ <xpad>4</xpad>
+ <ypad>0</ypad>
<child>
<left_attach>1</left_attach>
<right_attach>2</right_attach>
@@ -123,9 +125,9 @@
<bottom_attach>1</bottom_attach>
<xpad>0</xpad>
<ypad>0</ypad>
- <xexpand>True</xexpand>
+ <xexpand>False</xexpand>
<yexpand>False</yexpand>
- <xshrink>True</xshrink>
+ <xshrink>False</xshrink>
<yshrink>False</yshrink>
<xfill>True</xfill>
<yfill>False</yfill>
@@ -133,12 +135,15 @@
</widget>
<widget>
- <class>GtkAlignment</class>
- <name>alignment40</name>
+ <class>GtkLabel</class>
+ <name>date-time</name>
+ <label></label>
+ <justify>GTK_JUSTIFY_CENTER</justify>
+ <wrap>False</wrap>
<xalign>0</xalign>
<yalign>0.5</yalign>
- <xscale>0</xscale>
- <yscale>0</yscale>
+ <xpad>4</xpad>
+ <ypad>0</ypad>
<child>
<left_attach>1</left_attach>
<right_attach>2</right_attach>
@@ -151,17 +156,8 @@
<xshrink>False</xshrink>
<yshrink>False</yshrink>
<xfill>True</xfill>
- <yfill>True</yfill>
+ <yfill>False</yfill>
</child>
-
- <widget>
- <class>Custom</class>
- <name>recurrence-starting-date</name>
- <creation_function>make_date_edit</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Fri, 22 Sep 2000 20:51:38 GMT</last_modification_time>
- </widget>
</widget>
</widget>
</widget>
@@ -209,7 +205,7 @@
<widget>
<class>GtkRadioButton</class>
- <name>recurrence-none</name>
+ <name>none</name>
<can_focus>True</can_focus>
<label>No recurrence</label>
<active>False</active>
@@ -224,7 +220,7 @@
<widget>
<class>GtkRadioButton</class>
- <name>recurrence-simple</name>
+ <name>simple</name>
<can_focus>True</can_focus>
<label>Simple recurrence</label>
<active>False</active>
@@ -239,7 +235,7 @@
<widget>
<class>GtkRadioButton</class>
- <name>recurrence-custom</name>
+ <name>custom</name>
<can_focus>True</can_focus>
<label>Custom recurrence</label>
<active>False</active>
@@ -266,7 +262,7 @@
<widget>
<class>GtkHBox</class>
- <name>recurrence-params</name>
+ <name>params</name>
<homogeneous>False</homogeneous>
<spacing>2</spacing>
<child>
@@ -294,7 +290,7 @@
<widget>
<class>GtkSpinButton</class>
- <name>recurrence-interval-value</name>
+ <name>interval-value</name>
<can_focus>True</can_focus>
<climb_rate>1</climb_rate>
<digits>0</digits>
@@ -317,7 +313,7 @@
<widget>
<class>GtkOptionMenu</class>
- <name>recurrence-interval-unit</name>
+ <name>interval-unit</name>
<can_focus>True</can_focus>
<items>day(s)
week(s)
@@ -334,7 +330,7 @@ year(s)
<widget>
<class>GtkAlignment</class>
- <name>recurrence-special</name>
+ <name>special</name>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xscale>0</xscale>
@@ -352,7 +348,7 @@ year(s)
<widget>
<class>GtkOptionMenu</class>
- <name>recurrence-ending-menu</name>
+ <name>ending-menu</name>
<can_focus>True</can_focus>
<items>for
until
@@ -368,7 +364,7 @@ forever
<widget>
<class>GtkAlignment</class>
- <name>recurrence-ending-special</name>
+ <name>ending-special</name>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xscale>0</xscale>
@@ -387,7 +383,7 @@ forever
<widget>
<class>GtkAlignment</class>
- <name>recurrence-custom-warning-bin</name>
+ <name>custom-warning-bin</name>
<xalign>0</xalign>
<yalign>0.5</yalign>
<xscale>1</xscale>
@@ -449,10 +445,9 @@ forever
<widget>
<class>GtkButton</class>
- <name>recurrence-exception-add</name>
+ <name>exception-add</name>
<can_focus>True</can_focus>
<label>Add</label>
- <relief>GTK_RELIEF_NORMAL</relief>
<child>
<padding>0</padding>
<expand>False</expand>
@@ -462,10 +457,9 @@ forever
<widget>
<class>GtkButton</class>
- <name>recurrence-exception-modify</name>
+ <name>exception-modify</name>
<can_focus>True</can_focus>
<label>Modify</label>
- <relief>GTK_RELIEF_NORMAL</relief>
<child>
<padding>0</padding>
<expand>False</expand>
@@ -475,10 +469,9 @@ forever
<widget>
<class>GtkButton</class>
- <name>recurrence-exception-delete</name>
+ <name>exception-delete</name>
<can_focus>True</can_focus>
<label>Delete</label>
- <relief>GTK_RELIEF_NORMAL</relief>
<child>
<padding>0</padding>
<expand>False</expand>
@@ -500,7 +493,7 @@ forever
<widget>
<class>Custom</class>
- <name>recurrence-exception-date</name>
+ <name>exception-date</name>
<creation_function>make_date_edit</creation_function>
<int1>0</int1>
<int2>0</int2>
@@ -527,7 +520,7 @@ forever
<widget>
<class>GtkCList</class>
- <name>recurrence-exception-list</name>
+ <name>exception-list</name>
<can_focus>True</can_focus>
<columns>1</columns>
<column_widths>80</column_widths>
@@ -583,7 +576,7 @@ forever
<widget>
<class>GtkAlignment</class>
- <name>recurrence-preview-bin</name>
+ <name>preview-bin</name>
<xalign>0</xalign>
<yalign>0</yalign>
<xscale>1</xscale>
diff --git a/calendar/gui/dialogs/recurrence-page.h b/calendar/gui/dialogs/recurrence-page.h
index 39123644b4..aba59003f7 100644
--- a/calendar/gui/dialogs/recurrence-page.h
+++ b/calendar/gui/dialogs/recurrence-page.h
@@ -25,7 +25,7 @@
#ifndef RECURRENCE_PAGE_H
#define RECURRENCE_PAGE_H
-#include "editor-page.h"
+#include "comp-editor-page.h"
BEGIN_GNOME_DECLS
@@ -33,29 +33,27 @@ BEGIN_GNOME_DECLS
#define TYPE_RECURRENCE_PAGE (recurrence_page_get_type ())
#define RECURRENCE_PAGE(obj) (GTK_CHECK_CAST ((obj), TYPE_RECURRENCE_PAGE, RecurrencePage))
-#define RECURRENCE_PAGE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_RECURRENCE_PAGE, \
- RecurrencePageClass))
+#define RECURRENCE_PAGE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_RECURRENCE_PAGE, RecurrencePageClass))
#define IS_RECURRENCE_PAGE(obj) (GTK_CHECK_TYPE ((obj), TYPE_RECURRENCE_PAGE))
#define IS_RECURRENCE_PAGE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), TYPE_RECURRENCE_PAGE))
typedef struct _RecurrencePagePrivate RecurrencePagePrivate;
typedef struct {
- EditorPage page;
+ CompEditorPage page;
/* Private data */
RecurrencePagePrivate *priv;
} RecurrencePage;
typedef struct {
- EditorPageClass parent_class;
+ CompEditorPageClass parent_class;
} RecurrencePageClass;
-GtkType recurrence_page_get_type (void);
+GtkType recurrence_page_get_type (void);
RecurrencePage *recurrence_page_construct (RecurrencePage *rpage);
-
-RecurrencePage *recurrence_page_new (void);
+RecurrencePage *recurrence_page_new (void);
diff --git a/calendar/gui/dialogs/task-details-page.c b/calendar/gui/dialogs/task-details-page.c
new file mode 100644
index 0000000000..317f36dbe6
--- /dev/null
+++ b/calendar/gui/dialogs/task-details-page.c
@@ -0,0 +1,461 @@
+/* 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 the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtksignal.h>
+#include <gtk/gtktogglebutton.h>
+#include <glade/glade.h>
+#include <gal/widgets/e-unicode.h>
+#include <widgets/misc/e-dateedit.h>
+#include "e-util/e-dialog-widgets.h"
+#include "../widget-util.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 *summary;
+ GtkWidget *date_time;
+
+ GtkWidget *completed_date;
+ GtkWidget *url;
+
+ gboolean updating;
+};
+
+
+
+static void task_details_page_class_init (TaskDetailsPageClass *class);
+static void task_details_page_init (TaskDetailsPage *tdpage);
+static void task_details_page_destroy (GtkObject *object);
+
+static GtkWidget *task_details_page_get_widget (CompEditorPage *page);
+static void task_details_page_fill_widgets (CompEditorPage *page, CalComponent *comp);
+static void task_details_page_fill_component (CompEditorPage *page, CalComponent *comp);
+static void task_details_page_set_summary (CompEditorPage *page, const char *summary);
+static void task_details_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates);
+
+static CompEditorPageClass *parent_class = NULL;
+
+
+
+/**
+ * task_details_page_get_type:
+ *
+ * Registers the #TaskDetailsPage class if necessary, and returns the type ID
+ * associated to it.
+ *
+ * Return value: The type ID of the #TaskDetailsPage class.
+ **/
+GtkType
+task_details_page_get_type (void)
+{
+ static GtkType task_details_page_type;
+
+ if (!task_details_page_type) {
+ static const GtkTypeInfo task_details_page_info = {
+ "TaskDetailsPage",
+ sizeof (TaskDetailsPage),
+ sizeof (TaskDetailsPageClass),
+ (GtkClassInitFunc) task_details_page_class_init,
+ (GtkObjectInitFunc) task_details_page_init,
+ NULL, /* reserved_1 */
+ NULL, /* reserved_2 */
+ (GtkClassInitFunc) NULL
+ };
+
+ task_details_page_type =
+ gtk_type_unique (TYPE_COMP_EDITOR_PAGE,
+ &task_details_page_info);
+ }
+
+ return task_details_page_type;
+}
+
+/* Class initialization function for the task page */
+static void
+task_details_page_class_init (TaskDetailsPageClass *class)
+{
+ CompEditorPageClass *editor_page_class;
+ GtkObjectClass *object_class;
+
+ editor_page_class = (CompEditorPageClass *) class;
+ object_class = (GtkObjectClass *) class;
+
+ parent_class = gtk_type_class (TYPE_COMP_EDITOR_PAGE);
+
+ editor_page_class->get_widget = task_details_page_get_widget;
+ editor_page_class->fill_widgets = task_details_page_fill_widgets;
+ editor_page_class->fill_component = task_details_page_fill_component;
+ editor_page_class->set_summary = task_details_page_set_summary;
+ editor_page_class->set_dates = task_details_page_set_dates;
+
+ object_class->destroy = task_details_page_destroy;
+}
+
+/* Object initialization function for the task page */
+static void
+task_details_page_init (TaskDetailsPage *tdpage)
+{
+ TaskDetailsPagePrivate *priv;
+
+ priv = g_new0 (TaskDetailsPagePrivate, 1);
+ tdpage->priv = priv;
+
+ priv->xml = NULL;
+
+ priv->main = NULL;
+ priv->summary = NULL;
+ priv->date_time = NULL;
+ priv->completed_date = NULL;
+ priv->url = NULL;
+
+ priv->updating = FALSE;
+}
+
+/* Destroy handler for the task page */
+static void
+task_details_page_destroy (GtkObject *object)
+{
+ TaskDetailsPage *tdpage;
+ TaskDetailsPagePrivate *priv;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (IS_TASK_DETAILS_PAGE (object));
+
+ tdpage = TASK_DETAILS_PAGE (object);
+ priv = tdpage->priv;
+
+ if (priv->xml) {
+ gtk_object_unref (GTK_OBJECT (priv->xml));
+ priv->xml = NULL;
+ }
+
+ g_free (priv);
+ tdpage->priv = NULL;
+
+ if (GTK_OBJECT_CLASS (parent_class)->destroy)
+ (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+
+
+/* get_widget handler for the task page */
+static GtkWidget *
+task_details_page_get_widget (CompEditorPage *page)
+{
+ TaskDetailsPage *tdpage;
+ TaskDetailsPagePrivate *priv;
+
+ tdpage = TASK_DETAILS_PAGE (page);
+ priv = tdpage->priv;
+
+ return priv->main;
+}
+
+/* Fills the widgets with default values */
+static void
+clear_widgets (TaskDetailsPage *tdpage)
+{
+ TaskDetailsPagePrivate *priv;
+
+ priv = tdpage->priv;
+
+ /* Summary */
+ gtk_label_set_text (GTK_LABEL (priv->summary), "");
+
+ /* Start date */
+ gtk_label_set_text (GTK_LABEL (priv->date_time), "");
+
+ /* Date completed */
+ e_date_edit_set_time (E_DATE_EDIT (priv->completed_date), -1);
+
+ /* URL */
+ e_dialog_editable_set (priv->url, NULL);
+}
+
+/* fill_widgets handler for the task page */
+static void
+task_details_page_fill_widgets (CompEditorPage *page, CalComponent *comp)
+{
+ TaskDetailsPage *tdpage;
+ TaskDetailsPagePrivate *priv;
+ CalComponentText text;
+ const char *url;
+ CompEditorPageDates dates;
+
+ tdpage = TASK_DETAILS_PAGE (page);
+ priv = tdpage->priv;
+
+ priv->updating = TRUE;
+
+ /* Clean the screen */
+ clear_widgets (tdpage);
+
+ /* Summary */
+ cal_component_get_summary (comp, &text);
+ task_details_page_set_summary (page, text.value);
+
+ /* Dates */
+ comp_editor_dates (&dates, comp);
+ task_details_page_set_dates (page, &dates);
+
+ /* URL */
+ cal_component_get_url (comp, &url);
+ e_dialog_editable_set (priv->url, url);
+
+ priv->updating = FALSE;
+}
+
+/* fill_component handler for the task page */
+static void
+task_details_page_fill_component (CompEditorPage *page, CalComponent *comp)
+{
+ TaskDetailsPage *tdpage;
+ TaskDetailsPagePrivate *priv;
+ CalComponentDateTime date;
+ time_t t;
+ char *url;
+
+ tdpage = TASK_DETAILS_PAGE (page);
+ priv = tdpage->priv;
+
+ /* Completed Date. */
+ date.value = g_new (struct icaltimetype, 1);
+ date.tzid = NULL;
+
+ t = e_date_edit_get_time (E_DATE_EDIT (priv->completed_date));
+ if (t != -1) {
+ *date.value = icaltime_from_timet (t, FALSE);
+ cal_component_set_completed (comp, date.value);
+ } else {
+ cal_component_set_completed (comp, NULL);
+ }
+
+ g_free (date.value);
+
+ /* URL. */
+ url = e_dialog_editable_get (priv->url);
+ cal_component_set_url (comp, url);
+ if (url)
+ g_free (url);
+}
+
+/* set_summary handler for the task page */
+static void
+task_details_page_set_summary (CompEditorPage *page, const char *summary)
+{
+ TaskDetailsPage *tdpage;
+ TaskDetailsPagePrivate *priv;
+ gchar *s;
+
+ tdpage = TASK_DETAILS_PAGE (page);
+ priv = tdpage->priv;
+
+ s = e_utf8_to_gtk_string (priv->summary, summary);
+ gtk_label_set_text (GTK_LABEL (priv->summary), s);
+ g_free (s);
+}
+
+static void
+task_details_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates)
+{
+ TaskDetailsPage *tdpage;
+ TaskDetailsPagePrivate *priv;
+
+ tdpage = TASK_DETAILS_PAGE (page);
+ priv = tdpage->priv;
+
+ comp_editor_date_label (dates, priv->date_time);
+}
+
+
+
+/* Gets the widgets from the XML file and returns if they are all available. */
+static gboolean
+get_widgets (TaskDetailsPage *tdpage)
+{
+ TaskDetailsPagePrivate *priv;
+
+ priv = tdpage->priv;
+
+#define GW(name) glade_xml_get_widget (priv->xml, name)
+
+ priv->main = GW ("task-details-page");
+ g_assert (priv->main);
+ gtk_widget_ref (priv->main);
+ gtk_widget_unparent (priv->main);
+
+ priv->summary = GW ("summary");
+ priv->date_time = GW ("date-time");
+
+ priv->completed_date = GW ("completed-date");
+ priv->url = GW ("url");
+
+#undef GW
+
+ return (priv->summary
+ && priv->date_time
+ && priv->completed_date
+ && priv->url);
+}
+
+/* Callback used when the start or end date widgets change. We check that the
+ * start date < end date and we set the "all day task" button as appropriate.
+ */
+static void
+date_changed_cb (EDateEdit *dedit, gpointer data)
+{
+ TaskDetailsPage *tdpage;
+ TaskDetailsPagePrivate *priv;
+ CompEditorPageDates dates;
+
+ tdpage = TASK_DETAILS_PAGE (data);
+ priv = tdpage->priv;
+
+ if (priv->updating)
+ return;
+
+ dates.start = 0;
+ dates.end = 0;
+ dates.due = 0;
+ dates.complete = e_date_edit_get_time (E_DATE_EDIT (priv->completed_date));
+
+ /* Notify upstream */
+ comp_editor_page_notify_dates_changed (COMP_EDITOR_PAGE (tdpage), &dates);
+}
+
+/* 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;
+
+ /* Completed Date */
+ gtk_signal_connect (GTK_OBJECT (priv->completed_date), "changed",
+ GTK_SIGNAL_FUNC (date_changed_cb), tdpage);
+
+ /* URL */
+ gtk_signal_connect (GTK_OBJECT (priv->url), "changed",
+ GTK_SIGNAL_FUNC (field_changed_cb), tdpage);
+}
+
+
+
+/**
+ * task_details_page_construct:
+ * @tdpage: An task details page.
+ *
+ * Constructs an task page by loading its Glade data.
+ *
+ * Return value: The same object as @tdpage, or NULL if the widgets could not
+ * be created.
+ **/
+TaskDetailsPage *
+task_details_page_construct (TaskDetailsPage *tdpage)
+{
+ TaskDetailsPagePrivate *priv;
+
+ priv = tdpage->priv;
+
+ priv->xml = glade_xml_new (EVOLUTION_GLADEDIR
+ "/task-details-page.glade", NULL);
+ if (!priv->xml) {
+ g_message ("task_details_page_construct(): "
+ "Could not load the Glade XML file!");
+ return NULL;
+ }
+
+ if (!get_widgets (tdpage)) {
+ g_message ("task_details_page_construct(): "
+ "Could not find all widgets in the XML file!");
+ return NULL;
+ }
+
+ init_widgets (tdpage);
+
+ return tdpage;
+}
+
+/**
+ * task_details_page_new:
+ *
+ * Creates a new task details page.
+ *
+ * Return value: A newly-created task details page, or NULL if the page could
+ * not be created.
+ **/
+TaskDetailsPage *
+task_details_page_new (void)
+{
+ TaskDetailsPage *tdpage;
+
+ tdpage = gtk_type_new (TYPE_TASK_DETAILS_PAGE);
+ if (!task_details_page_construct (tdpage)) {
+ gtk_object_unref (GTK_OBJECT (tdpage));
+ return NULL;
+ }
+
+ return tdpage;
+}
+
+GtkWidget *task_details_page_create_date_edit (void);
+
+GtkWidget *
+task_details_page_create_date_edit (void)
+{
+ GtkWidget *dedit;
+
+ dedit = date_edit_new (TRUE, TRUE);
+ 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
index 31e3aba6c4..9d13387d59 100644
--- a/calendar/gui/dialogs/task-details-page.glade
+++ b/calendar/gui/dialogs/task-details-page.glade
@@ -15,6 +15,7 @@
<widget>
<class>GtkWindow</class>
<name>task-details-toplevel</name>
+ <visible>False</visible>
<title>window1</title>
<type>GTK_WINDOW_TOPLEVEL</type>
<position>GTK_WIN_POS_NONE</position>
@@ -24,112 +25,253 @@
<auto_shrink>False</auto_shrink>
<widget>
- <class>GtkTable</class>
+ <class>GtkVBox</class>
<name>task-details-page</name>
<border_width>4</border_width>
- <rows>2</rows>
- <columns>2</columns>
<homogeneous>False</homogeneous>
- <row_spacing>2</row_spacing>
- <column_spacing>4</column_spacing>
+ <spacing>4</spacing>
<widget>
- <class>GtkLabel</class>
- <name>label12</name>
- <label>Date Completed:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
+ <class>GtkFrame</class>
+ <name>frame1</name>
+ <label>Basics</label>
+ <label_xalign>0</label_xalign>
+ <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
<child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
+ <padding>0</padding>
+ <expand>False</expand>
+ <fill>False</fill>
</child>
+
+ <widget>
+ <class>GtkTable</class>
+ <name>table1</name>
+ <border_width>4</border_width>
+ <rows>2</rows>
+ <columns>2</columns>
+ <homogeneous>False</homogeneous>
+ <row_spacing>2</row_spacing>
+ <column_spacing>2</column_spacing>
+
+ <widget>
+ <class>GtkLabel</class>
+ <name>label15</name>
+ <label>Summary:</label>
+ <justify>GTK_JUSTIFY_CENTER</justify>
+ <wrap>False</wrap>
+ <xalign>0</xalign>
+ <yalign>0.5</yalign>
+ <xpad>0</xpad>
+ <ypad>0</ypad>
+ <child>
+ <left_attach>0</left_attach>
+ <right_attach>1</right_attach>
+ <top_attach>0</top_attach>
+ <bottom_attach>1</bottom_attach>
+ <xpad>0</xpad>
+ <ypad>0</ypad>
+ <xexpand>False</xexpand>
+ <yexpand>False</yexpand>
+ <xshrink>False</xshrink>
+ <yshrink>False</yshrink>
+ <xfill>False</xfill>
+ <yfill>False</yfill>
+ </child>
+ </widget>
+
+ <widget>
+ <class>GtkLabel</class>
+ <name>label16</name>
+ <label>Date/Time:</label>
+ <justify>GTK_JUSTIFY_CENTER</justify>
+ <wrap>False</wrap>
+ <xalign>0</xalign>
+ <yalign>0.5</yalign>
+ <xpad>0</xpad>
+ <ypad>0</ypad>
+ <child>
+ <left_attach>0</left_attach>
+ <right_attach>1</right_attach>
+ <top_attach>1</top_attach>
+ <bottom_attach>2</bottom_attach>
+ <xpad>0</xpad>
+ <ypad>0</ypad>
+ <xexpand>False</xexpand>
+ <yexpand>False</yexpand>
+ <xshrink>False</xshrink>
+ <yshrink>False</yshrink>
+ <xfill>False</xfill>
+ <yfill>False</yfill>
+ </child>
+ </widget>
+
+ <widget>
+ <class>GtkLabel</class>
+ <name>date-time</name>
+ <label></label>
+ <justify>GTK_JUSTIFY_CENTER</justify>
+ <wrap>False</wrap>
+ <xalign>0</xalign>
+ <yalign>0.5</yalign>
+ <xpad>4</xpad>
+ <ypad>0</ypad>
+ <child>
+ <left_attach>1</left_attach>
+ <right_attach>2</right_attach>
+ <top_attach>1</top_attach>
+ <bottom_attach>2</bottom_attach>
+ <xpad>0</xpad>
+ <ypad>0</ypad>
+ <xexpand>False</xexpand>
+ <yexpand>False</yexpand>
+ <xshrink>False</xshrink>
+ <yshrink>False</yshrink>
+ <xfill>True</xfill>
+ <yfill>False</yfill>
+ </child>
+ </widget>
+
+ <widget>
+ <class>GtkLabel</class>
+ <name>summary</name>
+ <label></label>
+ <justify>GTK_JUSTIFY_LEFT</justify>
+ <wrap>False</wrap>
+ <xalign>0</xalign>
+ <yalign>0.5</yalign>
+ <xpad>4</xpad>
+ <ypad>0</ypad>
+ <child>
+ <left_attach>1</left_attach>
+ <right_attach>2</right_attach>
+ <top_attach>0</top_attach>
+ <bottom_attach>1</bottom_attach>
+ <xpad>0</xpad>
+ <ypad>0</ypad>
+ <xexpand>False</xexpand>
+ <yexpand>False</yexpand>
+ <xshrink>False</xshrink>
+ <yshrink>False</yshrink>
+ <xfill>True</xfill>
+ <yfill>False</yfill>
+ </child>
+ </widget>
+ </widget>
</widget>
<widget>
- <class>GtkLabel</class>
- <name>label14</name>
- <label>URL:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
+ <class>GtkTable</class>
+ <name>table1</name>
+ <border_width>4</border_width>
+ <rows>2</rows>
+ <columns>2</columns>
+ <homogeneous>False</homogeneous>
+ <row_spacing>2</row_spacing>
+ <column_spacing>4</column_spacing>
<child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
+ <padding>0</padding>
+ <expand>True</expand>
+ <fill>True</fill>
</child>
- </widget>
- <widget>
- <class>GtkEntry</class>
- <name>url</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
+ <widget>
+ <class>GtkLabel</class>
+ <name>label12</name>
+ <label>Date Completed:</label>
+ <justify>GTK_JUSTIFY_CENTER</justify>
+ <wrap>False</wrap>
+ <xalign>0</xalign>
+ <yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
+ <child>
+ <left_attach>0</left_attach>
+ <right_attach>1</right_attach>
+ <top_attach>0</top_attach>
+ <bottom_attach>1</bottom_attach>
+ <xpad>0</xpad>
+ <ypad>0</ypad>
+ <xexpand>False</xexpand>
+ <yexpand>False</yexpand>
+ <xshrink>False</xshrink>
+ <yshrink>False</yshrink>
+ <xfill>True</xfill>
+ <yfill>False</yfill>
+ </child>
+ </widget>
- <widget>
- <class>Custom</class>
- <name>completed-date</name>
- <creation_function>task_editor_create_date_edit</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Sun, 10 Sep 2000 17:34:07 GMT</last_modification_time>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
+ <widget>
+ <class>GtkLabel</class>
+ <name>label14</name>
+ <label>URL:</label>
+ <justify>GTK_JUSTIFY_CENTER</justify>
+ <wrap>False</wrap>
+ <xalign>0</xalign>
+ <yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
+ <child>
+ <left_attach>0</left_attach>
+ <right_attach>1</right_attach>
+ <top_attach>1</top_attach>
+ <bottom_attach>2</bottom_attach>
+ <xpad>0</xpad>
+ <ypad>0</ypad>
+ <xexpand>False</xexpand>
+ <yexpand>False</yexpand>
+ <xshrink>False</xshrink>
+ <yshrink>False</yshrink>
+ <xfill>True</xfill>
+ <yfill>False</yfill>
+ </child>
+ </widget>
+
+ <widget>
+ <class>GtkEntry</class>
+ <name>url</name>
+ <can_focus>True</can_focus>
+ <editable>True</editable>
+ <text_visible>True</text_visible>
+ <text_max_length>0</text_max_length>
+ <text></text>
+ <child>
+ <left_attach>1</left_attach>
+ <right_attach>2</right_attach>
+ <top_attach>1</top_attach>
+ <bottom_attach>2</bottom_attach>
+ <xpad>0</xpad>
+ <ypad>0</ypad>
+ <xexpand>True</xexpand>
+ <yexpand>False</yexpand>
+ <xshrink>False</xshrink>
+ <yshrink>False</yshrink>
+ <xfill>True</xfill>
+ <yfill>False</yfill>
+ </child>
+ </widget>
+
+ <widget>
+ <class>Custom</class>
+ <name>completed-date</name>
+ <creation_function>task_details_page_create_date_edit</creation_function>
+ <int1>0</int1>
+ <int2>0</int2>
+ <last_modification_time>Fri, 01 Jun 2001 18:58:51 GMT</last_modification_time>
+ <child>
+ <left_attach>1</left_attach>
+ <right_attach>2</right_attach>
+ <top_attach>0</top_attach>
+ <bottom_attach>1</bottom_attach>
+ <xpad>0</xpad>
+ <ypad>0</ypad>
+ <xexpand>True</xexpand>
+ <yexpand>False</yexpand>
+ <xshrink>False</xshrink>
+ <yshrink>False</yshrink>
+ <xfill>True</xfill>
+ <yfill>False</yfill>
+ </child>
+ </widget>
</widget>
</widget>
</widget>
diff --git a/calendar/gui/dialogs/task-details-page.h b/calendar/gui/dialogs/task-details-page.h
new file mode 100644
index 0000000000..d285eb9cc0
--- /dev/null
+++ b/calendar/gui/dialogs/task-details-page.h
@@ -0,0 +1,62 @@
+/* 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 the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef TASK_DETAILS_PAGE_H
+#define TASK_DETAILS_PAGE_H
+
+#include "comp-editor-page.h"
+
+BEGIN_GNOME_DECLS
+
+
+
+#define TYPE_TASK_DETAILS_PAGE (task_details_page_get_type ())
+#define TASK_DETAILS_PAGE(obj) (GTK_CHECK_CAST ((obj), TYPE_TASK_DETAILS_PAGE, TaskDetailsPage))
+#define TASK_DETAILS_PAGE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_TASK_DETAILS_PAGE, TaskDetailsPageClass))
+#define IS_TASK_DETAILS_PAGE(obj) (GTK_CHECK_TYPE ((obj), TYPE_TASK_DETAILS_PAGE))
+#define IS_TASK_DETAILS_PAGE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), TYPE_TASK_DETAILS_PAGE))
+
+typedef struct _TaskDetailsPagePrivate TaskDetailsPagePrivate;
+
+typedef struct {
+ CompEditorPage page;
+
+ /* Private data */
+ TaskDetailsPagePrivate *priv;
+} TaskDetailsPage;
+
+typedef struct {
+ CompEditorPageClass parent_class;
+} TaskDetailsPageClass;
+
+
+GtkType task_details_page_get_type (void);
+TaskDetailsPage *task_details_page_construct (TaskDetailsPage *epage);
+TaskDetailsPage *task_details_page_new (void);
+
+
+
+END_GNOME_DECLS
+
+#endif
diff --git a/calendar/gui/dialogs/task-editor-dialog.glade b/calendar/gui/dialogs/task-editor-dialog.glade
deleted file mode 100644
index ae7ea9681a..0000000000
--- a/calendar/gui/dialogs/task-editor-dialog.glade
+++ /dev/null
@@ -1,695 +0,0 @@
-<?xml version="1.0"?>
-<GTK-Interface>
-
-<project>
- <name>task-editor-dialog</name>
- <program_name>task-editor-dialog</program_name>
- <directory></directory>
- <source_directory>src</source_directory>
- <pixmaps_directory>pixmaps</pixmaps_directory>
- <language>C</language>
- <gnome_support>True</gnome_support>
- <gettext_support>True</gettext_support>
-</project>
-
-<widget>
- <class>GnomePropertyBox</class>
- <name>task-editor-dialog</name>
- <visible>False</visible>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>False</allow_grow>
- <auto_shrink>False</auto_shrink>
-
- <widget>
- <class>GtkNotebook</class>
- <child_name>GnomeDock:contents</child_name>
- <name>notebook1</name>
- <border_width>2</border_width>
- <can_focus>True</can_focus>
- <show_tabs>True</show_tabs>
- <show_border>True</show_border>
- <tab_pos>GTK_POS_TOP</tab_pos>
- <scrollable>False</scrollable>
- <tab_hborder>2</tab_hborder>
- <tab_vborder>2</tab_vborder>
- <popup_enable>False</popup_enable>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox1</name>
- <border_width>4</border_width>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
-
- <widget>
- <class>GtkTable</class>
- <name>table3</name>
- <rows>1</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>4</row_spacing>
- <column_spacing>4</column_spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label3</name>
- <label>Su_mmary:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <default_focus_target>summary</default_focus_target>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>False</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>summary</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame2</name>
- <label>Date &amp; Time</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox4</name>
- <border_width>4</border_width>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>GtkTable</class>
- <name>table1</name>
- <rows>2</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>2</row_spacing>
- <column_spacing>4</column_spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label6</name>
- <label>Sta_rt Date:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label5</name>
- <label>_Due Date:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>Custom</class>
- <name>due-date</name>
- <creation_function>task_editor_create_date_edit</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Sun, 10 Sep 2000 17:32:18 GMT</last_modification_time>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>Custom</class>
- <name>start-date</name>
- <creation_function>task_editor_create_date_edit</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Sun, 10 Sep 2000 17:33:31 GMT</last_modification_time>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkScrolledWindow</class>
- <name>scrolledwindow1</name>
- <hscrollbar_policy>GTK_POLICY_NEVER</hscrollbar_policy>
- <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy>
- <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
- <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkText</class>
- <name>description</name>
- <height>80</height>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text></text>
- </widget>
- </widget>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame23</name>
- <label>Progress</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox3</name>
- <border_width>4</border_width>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
-
- <widget>
- <class>GtkLabel</class>
- <name>label7</name>
- <label>_Status:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <default_focus_target>status</default_focus_target>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkOptionMenu</class>
- <name>status</name>
- <can_focus>True</can_focus>
- <items>Not Started
-In Progress
-Completed
-Cancelled
-</items>
- <initial_choice>0</initial_choice>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label8</name>
- <label>_Priority:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <default_focus_target>priority</default_focus_target>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkOptionMenu</class>
- <name>priority</name>
- <can_focus>True</can_focus>
- <items>High
-Normal
-Low
-Undefined
-</items>
- <initial_choice>0</initial_choice>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label9</name>
- <label>% Comp_lete:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <default_focus_target>percent-complete</default_focus_target>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkSpinButton</class>
- <name>percent-complete</name>
- <width>60</width>
- <can_focus>True</can_focus>
- <climb_rate>1</climb_rate>
- <digits>0</digits>
- <numeric>False</numeric>
- <update_policy>GTK_UPDATE_ALWAYS</update_policy>
- <snap>False</snap>
- <wrap>False</wrap>
- <value>0</value>
- <lower>0</lower>
- <upper>100</upper>
- <step>10</step>
- <page>10</page>
- <page_size>10</page_size>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame24</name>
- <label>Classification</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox6</name>
- <border_width>2</border_width>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
-
- <widget>
- <class>GtkRadioButton</class>
- <name>classification-public</name>
- <can_focus>True</can_focus>
- <label>Pu_blic</label>
- <active>True</active>
- <draw_indicator>True</draw_indicator>
- <group>classification_radio_group</group>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkRadioButton</class>
- <name>classification-private</name>
- <can_focus>True</can_focus>
- <label>Pri_vate</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <group>classification_radio_group</group>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkRadioButton</class>
- <name>classification-confidential</name>
- <can_focus>True</can_focus>
- <label>_Confidential</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <group>classification_radio_group</group>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox2</name>
- <homogeneous>False</homogeneous>
- <spacing>2</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>contacts-button</name>
- <can_focus>True</can_focus>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label16</name>
- <label>_Contacts...</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>4</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>contacts</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>categories-button</name>
- <can_focus>True</can_focus>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label17</name>
- <label>Ca_tegories...</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>4</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>categories</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label1</name>
- <label>Task</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkTable</class>
- <name>table4</name>
- <border_width>4</border_width>
- <rows>2</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>2</row_spacing>
- <column_spacing>4</column_spacing>
-
- <widget>
- <class>GtkLabel</class>
- <name>label12</name>
- <label>Date Completed:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label14</name>
- <label>URL:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>url</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>Custom</class>
- <name>completed-date</name>
- <creation_function>task_editor_create_date_edit</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Sun, 10 Sep 2000 17:34:07 GMT</last_modification_time>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label2</name>
- <label>Details</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
-</widget>
-
-</GTK-Interface>
diff --git a/calendar/gui/dialogs/task-editor.c b/calendar/gui/dialogs/task-editor.c
index b21de4bd32..2a1f25cfbf 100644
--- a/calendar/gui/dialogs/task-editor.c
+++ b/calendar/gui/dialogs/task-editor.c
@@ -1,16 +1,18 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Author :
- * Damon Chaplin <damon@ximian.com>
+/* Evolution calendar - Event editor dialog
*
- * Copyright 2000, Helix Code, Inc.
- * Copyright 2000, Ximian, Inc.
+ * Copyright (C) 2000 Helix Code, Inc.
+ * Copyright (C) 2001 Ximian, Inc.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
+ * Authors: Miguel de Icaza <miguel@ximian.com>
+ * Federico Mena-Quintero <federico@ximian.com>
+ * Seth Alves <alves@hungry.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -19,1276 +21,127 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-/*
- * TaskEditor - a GtkObject which handles a libglade-loaded dialog to edit
- * tasks.
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
#include <config.h>
+#include <string.h>
#include <glade/glade.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <gal/util/e-util.h>
#include <gal/widgets/e-unicode.h>
-#include <gal/widgets/e-categories.h>
-#include <e-util/e-dialog-widgets.h>
-#include <widgets/misc/e-dateedit.h>
-#include <cal-util/timeutil.h>
-#include "delete-comp.h"
-#include "save-comp.h"
-#include "task-editor.h"
-#include "../calendar-config.h"
-#include "../widget-util.h"
-
-
-typedef struct {
- /* Glade XML data */
- GladeXML *xml;
-
- /* Client to use */
- CalClient *client;
-
- /* Calendar component we are editing; this is an internal copy and is
- * not one of the read-only objects from the parent calendar.
- */
- CalComponent *comp;
-
-
- /* This is TRUE while we are setting the widget values. We just return
- from any signal handlers. */
- gboolean ignore_callbacks;
-
- /* Widgets from the Glade file */
-
- GtkWidget *app;
-
- GtkWidget *summary;
-
- GtkWidget *due_date;
- GtkWidget *start_date;
-
- GtkWidget *percent_complete;
-
- GtkWidget *status;
- GtkWidget *priority;
-
- GtkWidget *description;
-
- GtkWidget *classification_public;
- GtkWidget *classification_private;
- GtkWidget *classification_confidential;
-
- GtkWidget *contacts_btn;
- GtkWidget *contacts;
-
- GtkWidget *categories_btn;
- GtkWidget *categories;
-
- GtkWidget *completed_date;
- GtkWidget *url;
-
- /* Call task_editor_set_changed() to set this to TRUE when any field
- in the dialog is changed. When the user closes the dialog we will
- prompt to save changes. */
- gboolean changed;
-} TaskEditorPrivate;
-
-
-/* Note that these two arrays must match. */
-static const int status_map[] = {
- ICAL_STATUS_NEEDSACTION,
- ICAL_STATUS_INPROCESS,
- ICAL_STATUS_COMPLETED,
- ICAL_STATUS_CANCELLED,
- -1
-};
+#include <libgnome/gnome-i18n.h>
-typedef enum {
- PRIORITY_HIGH,
- PRIORITY_NORMAL,
- PRIORITY_LOW,
- PRIORITY_UNDEFINED,
-} TaskEditorPriority;
+#include "task-page.h"
+#include "task-details-page.h"
+#include "recurrence-page.h"
+#include "task-editor.h"
-static const int priority_map[] = {
- PRIORITY_HIGH,
- PRIORITY_NORMAL,
- PRIORITY_LOW,
- PRIORITY_UNDEFINED,
- -1
+struct _TaskEditorPrivate {
+ TaskPage *task_page;
+ TaskDetailsPage *task_details_page;
};
-static const int classification_map[] = {
- CAL_COMPONENT_CLASS_PUBLIC,
- CAL_COMPONENT_CLASS_PRIVATE,
- CAL_COMPONENT_CLASS_CONFIDENTIAL,
- -1
-};
+
static void task_editor_class_init (TaskEditorClass *class);
-static void task_editor_init (TaskEditor *tedit);
-static void tedit_apply_event_cb (GtkWidget *widget, gint page_num, gpointer data);
-static gint tedit_close_event_cb (GtkWidget *widget, gpointer data);
-static gint tedit_delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data);
-static void close_dialog (TaskEditor *tedit);
-static gboolean get_widgets (TaskEditor *tedit);
-static void init_widgets (TaskEditor *tedit);
+static void task_editor_init (TaskEditor *te);
static void task_editor_destroy (GtkObject *object);
-static char * make_title_from_comp (CalComponent *comp);
-static void set_title_from_comp (TaskEditor *tedit, CalComponent *comp);
-static void clear_widgets (TaskEditor *tedit);
-static void fill_widgets (TaskEditor *tedit);
-
-static void save_todo_object (TaskEditor *tedit);
-static void dialog_to_comp_object (TaskEditor *tedit);
-
-static void obj_updated_cb (CalClient *client, const char *uid, gpointer data);
-static void obj_removed_cb (CalClient *client, const char *uid, gpointer data);
-static void raise_and_focus (GtkWidget *widget);
-
-static TaskEditorPriority priority_value_to_index (int priority_value);
-static int priority_index_to_value (TaskEditorPriority priority);
-
-static void completed_changed (EDateEdit *dedit,
- TaskEditor *tedit);
-static void status_changed (GtkMenu *menu,
- TaskEditor *tedit);
-static void percent_complete_changed (GtkAdjustment *adj,
- TaskEditor *tedit);
-static void field_changed (GtkWidget *widget,
- TaskEditor *tedit);
-static void task_editor_set_changed (TaskEditor *tedit,
- gboolean changed);
-static gboolean prompt_to_save_changes (TaskEditor *tedit);
-static CalComponentClassification classification_get (GtkWidget *widget);
-static void categories_clicked (GtkWidget *button,
- TaskEditor *editor);
-
-/* The function libglade calls to create the EDateEdit widgets in the GUI. */
-GtkWidget * task_editor_create_date_edit (void);
-
-static GtkObjectClass *parent_class;
-
-E_MAKE_TYPE(task_editor, "TaskEditor", TaskEditor,
- task_editor_class_init, task_editor_init, GTK_TYPE_OBJECT)
-
-
-static void
-task_editor_class_init (TaskEditorClass *class)
-{
- GtkObjectClass *object_class;
-
- object_class = (GtkObjectClass *) class;
-
- parent_class = gtk_type_class (GTK_TYPE_OBJECT);
-
- object_class->destroy = task_editor_destroy;
-}
-
-
-static void
-task_editor_init (TaskEditor *tedit)
-{
- TaskEditorPrivate *priv;
-
- priv = g_new0 (TaskEditorPrivate, 1);
- tedit->priv = priv;
-
- priv->ignore_callbacks = FALSE;
-
- task_editor_set_changed (tedit, FALSE);
-}
-
-/**
- * task_editor_new:
- * @Returns: a new #TaskEditor.
- *
- * Creates a new #TaskEditor.
- **/
-TaskEditor *
-task_editor_new (void)
-{
- TaskEditor *tedit;
+static CompEditor *parent_class;
- tedit = TASK_EDITOR (gtk_type_new (task_editor_get_type ()));
- return task_editor_construct (tedit);
-}
+
/**
- * task_editor_construct:
- * @tedit: A #TaskEditor.
+ * task_editor_get_type:
*
- * Constructs a task editor by loading its Glade XML file.
+ * Registers the #TaskEditor class if necessary, and returns the type ID
+ * associated to it.
*
- * Return value: The same object as @tedit, or NULL if the widgets could not be
- * created. In the latter case, the task editor will automatically be
- * destroyed.
+ * Return value: The type ID of the #TaskEditor class.
**/
-TaskEditor *
-task_editor_construct (TaskEditor *tedit)
+GtkType
+task_editor_get_type (void)
{
- TaskEditorPrivate *priv;
+ static GtkType task_editor_type = 0;
- g_return_val_if_fail (tedit != NULL, NULL);
- g_return_val_if_fail (IS_TASK_EDITOR (tedit), NULL);
+ if (!task_editor_type) {
+ static const GtkTypeInfo task_editor_info = {
+ "TaskEditor",
+ sizeof (TaskEditor),
+ sizeof (TaskEditorClass),
+ (GtkClassInitFunc) task_editor_class_init,
+ (GtkObjectInitFunc) task_editor_init,
+ NULL, /* reserved_1 */
+ NULL, /* reserved_2 */
+ (GtkClassInitFunc) NULL
+ };
- priv = tedit->priv;
-
- /* Load the content widgets */
-
- priv->xml = glade_xml_new (EVOLUTION_GLADEDIR "/task-editor-dialog.glade", NULL);
- if (!priv->xml) {
- g_message ("task_editor_construct(): Could not load the Glade XML file!");
- goto error;
+ task_editor_type = gtk_type_unique (TYPE_COMP_EDITOR,
+ &task_editor_info);
}
- if (!get_widgets (tedit)) {
- g_message ("task_editor_construct(): Could not find all widgets in the XML file!");
- goto error;
- }
-
- init_widgets (tedit);
-
- /* Hook to destruction of the dialog */
- gtk_signal_connect (GTK_OBJECT (priv->app), "apply",
- GTK_SIGNAL_FUNC (tedit_apply_event_cb), tedit);
- gtk_signal_connect (GTK_OBJECT (priv->app), "close",
- GTK_SIGNAL_FUNC (tedit_close_event_cb), tedit);
- gtk_signal_connect (GTK_OBJECT (priv->app), "delete_event",
- GTK_SIGNAL_FUNC (tedit_delete_event_cb), tedit);
-
- /* Add focus to the summary entry */
- gtk_widget_grab_focus (GTK_WIDGET (priv->summary));
-
-
- return tedit;
-
- error:
-
- gtk_object_unref (GTK_OBJECT (tedit));
- return NULL;
-}
-
-
-/* Called by libglade to create our custom EDateEdit widgets. */
-GtkWidget *
-task_editor_create_date_edit (void)
-{
- GtkWidget *dedit;
-
- dedit = date_edit_new (TRUE, TRUE);
- e_date_edit_set_allow_no_date_set (E_DATE_EDIT (dedit), TRUE);
-
- return dedit;
-}
-
-/* Callback used when the dialog box is destroyed */
-static void
-tedit_apply_event_cb (GtkWidget *widget, gint page_num, gpointer data)
-{
- TaskEditor *tedit;
-
- g_return_if_fail (IS_TASK_EDITOR (data));
-
- tedit = TASK_EDITOR (data);
-
- if (page_num != -1)
- return;
-
- save_todo_object (tedit);
-}
-
-/* Callback used when the dialog box is destroyed */
-static gint
-tedit_close_event_cb (GtkWidget *widget, gpointer data)
-{
- TaskEditor *tedit;
-
- g_return_val_if_fail (IS_TASK_EDITOR (data), TRUE);
-
- tedit = TASK_EDITOR (data);
-
- if (prompt_to_save_changes (tedit))
- close_dialog (tedit);
-
- return TRUE;
-}
-
-/* Callback used when the dialog box is destroyed */
-static gint
-tedit_delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data)
-{
- TaskEditor *tedit;
-
- g_return_val_if_fail (IS_TASK_EDITOR (data), TRUE);
-
- tedit = TASK_EDITOR (data);
-
- if (prompt_to_save_changes (tedit))
- close_dialog (tedit);
-
- return TRUE;
+ return task_editor_type;
}
-
-/* Closes the dialog box and emits the appropriate signals */
+/* Class initialization function for the event editor */
static void
-close_dialog (TaskEditor *tedit)
-{
- TaskEditorPrivate *priv;
-
- priv = tedit->priv;
-
- g_assert (priv->app != NULL);
-
- gtk_object_destroy (GTK_OBJECT (tedit));
-}
-
-
-/* Gets the widgets from the XML file and returns if they are all available.
- * For the widgets whose values can be simply set with e-dialog-utils, it does
- * that as well.
- */
-static gboolean
-get_widgets (TaskEditor *tedit)
+task_editor_class_init (TaskEditorClass *class)
{
- TaskEditorPrivate *priv;
-
- priv = tedit->priv;
-
-#define GW(name) glade_xml_get_widget (priv->xml, name)
-
- priv->app = GW ("task-editor-dialog");
-
- priv->summary = GW ("summary");
-
- priv->due_date = GW ("due-date");
- priv->start_date = GW ("start-date");
-
- priv->percent_complete = GW ("percent-complete");
-
- priv->status = GW ("status");
- priv->priority = GW ("priority");
-
- priv->description = GW ("description");
-
- priv->classification_public = GW ("classification-public");
- priv->classification_private = GW ("classification-private");
- priv->classification_confidential = GW ("classification-confidential");
-
- priv->contacts_btn = GW ("contacts-button");
- priv->contacts = GW ("contacts");
-
- priv->categories_btn = GW ("categories-button");
- priv->categories = GW ("categories");
+ GtkObjectClass *object_class;
- priv->completed_date = GW ("completed-date");
- priv->url = GW ("url");
+ object_class = (GtkObjectClass *) class;
-#undef GW
+ parent_class = gtk_type_class (TYPE_COMP_EDITOR);
- return (priv->app
- && priv->summary
- && priv->due_date
- && priv->start_date
- && priv->percent_complete
- && priv->status
- && priv->priority
- && priv->classification_public
- && priv->classification_private
- && priv->classification_confidential
- && priv->description
- && priv->contacts_btn
- && priv->contacts
- && priv->categories_btn
- && priv->categories
- && priv->completed_date
- && priv->url);
+ object_class->destroy = task_editor_destroy;
}
-
-/* Hooks the widget signals */
+/* Object initialization function for the event editor */
static void
-init_widgets (TaskEditor *tedit)
+task_editor_init (TaskEditor *te)
{
TaskEditorPrivate *priv;
+
+ priv = g_new0 (TaskEditorPrivate, 1);
+ te->priv = priv;
- priv = tedit->priv;
-
- /* Connect signals. The Status, Percent Complete & Date Completed
- properties are closely related so whenever one changes we may need
- to update the other 2. */
- gtk_signal_connect (GTK_OBJECT (priv->completed_date), "changed",
- GTK_SIGNAL_FUNC (completed_changed), tedit);
-
- gtk_signal_connect (GTK_OBJECT (GTK_OPTION_MENU (priv->status)->menu),
- "deactivate",
- GTK_SIGNAL_FUNC (status_changed), tedit);
-
- gtk_signal_connect (GTK_OBJECT (GTK_SPIN_BUTTON (priv->percent_complete)->adjustment),
- "value_changed",
- GTK_SIGNAL_FUNC (percent_complete_changed), tedit);
-
- /* Classification */
- gtk_signal_connect (GTK_OBJECT (priv->description), "changed",
- GTK_SIGNAL_FUNC (field_changed), tedit);
- gtk_signal_connect (GTK_OBJECT (priv->classification_public),
- "toggled",
- GTK_SIGNAL_FUNC (field_changed), tedit);
- gtk_signal_connect (GTK_OBJECT (priv->classification_private),
- "toggled",
- GTK_SIGNAL_FUNC (field_changed), tedit);
- gtk_signal_connect (GTK_OBJECT (priv->classification_confidential),
- "toggled",
- GTK_SIGNAL_FUNC (field_changed), tedit);
-
- /* Connect the default signal handler to use to make sure the "changed"
- field gets set whenever a field is changed. */
- gtk_signal_connect (GTK_OBJECT (priv->summary), "changed",
- GTK_SIGNAL_FUNC (field_changed), tedit);
- gtk_signal_connect (GTK_OBJECT (priv->due_date), "changed",
- GTK_SIGNAL_FUNC (field_changed), tedit);
- gtk_signal_connect (GTK_OBJECT (priv->start_date), "changed",
- GTK_SIGNAL_FUNC (field_changed), tedit);
- gtk_signal_connect (GTK_OBJECT (GTK_OPTION_MENU (priv->priority)->menu),
- "deactivate",
- GTK_SIGNAL_FUNC (field_changed), tedit);
- gtk_signal_connect (GTK_OBJECT (priv->description), "changed",
- GTK_SIGNAL_FUNC (field_changed), tedit);
- gtk_signal_connect (GTK_OBJECT (priv->contacts), "changed",
- GTK_SIGNAL_FUNC (field_changed), tedit);
- gtk_signal_connect (GTK_OBJECT (priv->categories), "changed",
- GTK_SIGNAL_FUNC (field_changed), tedit);
- gtk_signal_connect (GTK_OBJECT (priv->url), "changed",
- GTK_SIGNAL_FUNC (field_changed), tedit);
-
- /* Button clicks */
- gtk_signal_connect (GTK_OBJECT (priv->categories_btn), "clicked",
- GTK_SIGNAL_FUNC (categories_clicked), tedit);
-
- /* FIXME: we do not support these fields yet, so we disable them */
+ priv->task_page = task_page_new ();
+ comp_editor_append_page (COMP_EDITOR (te),
+ COMP_EDITOR_PAGE (priv->task_page),
+ _("Task"));
- gtk_widget_set_sensitive (priv->contacts_btn, FALSE);
- gtk_widget_set_sensitive (priv->contacts, FALSE);
+ priv->task_details_page = task_details_page_new ();
+ comp_editor_append_page (COMP_EDITOR (te),
+ COMP_EDITOR_PAGE (priv->task_details_page),
+ _("Details"));
}
+/* Destroy handler for the event editor */
static void
task_editor_destroy (GtkObject *object)
{
- TaskEditor *tedit;
+ TaskEditor *te;
TaskEditorPrivate *priv;
g_return_if_fail (object != NULL);
g_return_if_fail (IS_TASK_EDITOR (object));
- tedit = TASK_EDITOR (object);
- priv = tedit->priv;
-
- if (priv->app) {
- gtk_widget_destroy (priv->app);
- priv->app = NULL;
- }
-
- if (priv->comp) {
- gtk_object_unref (GTK_OBJECT (priv->comp));
- priv->comp = NULL;
- }
-
- if (priv->client) {
- gtk_signal_disconnect_by_data (GTK_OBJECT (priv->client),
- tedit);
- gtk_object_unref (GTK_OBJECT (priv->client));
- priv->client = NULL;
- }
-
- if (priv->xml) {
- gtk_object_unref (GTK_OBJECT (priv->xml));
- priv->xml = NULL;
- }
-
- g_free (priv);
- tedit->priv = NULL;
+ te = TASK_EDITOR (object);
+ priv = te->priv;
if (GTK_OBJECT_CLASS (parent_class)->destroy)
(* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
}
-
-void
-task_editor_set_cal_client (TaskEditor *tedit,
- CalClient *client)
-{
- TaskEditorPrivate *priv;
-
- g_return_if_fail (tedit != NULL);
- g_return_if_fail (IS_TASK_EDITOR (tedit));
-
- priv = tedit->priv;
-
- if (client == priv->client)
- return;
-
- if (client)
- g_return_if_fail (IS_CAL_CLIENT (client));
-
- if (client)
- g_return_if_fail (cal_client_get_load_state (client) == CAL_CLIENT_LOAD_LOADED);
-
- if (client)
- gtk_object_ref (GTK_OBJECT (client));
-
- if (priv->client) {
- gtk_signal_disconnect_by_data (GTK_OBJECT (priv->client),
- tedit);
- gtk_object_unref (GTK_OBJECT (priv->client));
- }
-
- priv->client = client;
-
- if (priv->client) {
- gtk_signal_connect (GTK_OBJECT (priv->client), "obj_updated",
- GTK_SIGNAL_FUNC (obj_updated_cb), tedit);
- gtk_signal_connect (GTK_OBJECT (priv->client), "obj_removed",
- GTK_SIGNAL_FUNC (obj_removed_cb), tedit);
- }
-}
-
-
-/* Callback used when the calendar client tells us that an object changed */
-static void
-obj_updated_cb (CalClient *client, const char *uid, gpointer data)
-{
- /* FIXME: Do something sensible if the component changes under our feet */
-#if 0
- TaskEditor *tedit;
- TaskEditorPrivate *priv;
- CalComponent *comp;
- CalClientGetStatus status;
- const gchar *editing_uid;
-
- tedit = TASK_EDITOR (data);
-
- g_return_if_fail (IS_TASK_EDITOR (tedit));
-
- priv = tedit->priv;
-
- /* If we aren't showing the object which has been updated, return. */
- if (!priv->comp)
- return;
- cal_component_get_uid (priv->comp, &editing_uid);
- if (strcmp (uid, editing_uid))
- return;
-
-
- /* Get the task from the server. */
- status = cal_client_get_object (priv->client, uid, &comp);
-
- switch (status) {
- case CAL_CLIENT_GET_SUCCESS:
- /* Everything is fine */
- break;
-
- case CAL_CLIENT_GET_SYNTAX_ERROR:
- g_message ("obj_updated_cb(): Syntax error when getting object `%s'", uid);
- return;
-
- case CAL_CLIENT_GET_NOT_FOUND:
- /* The object is no longer in the server, so do nothing */
- return;
-
- default:
- g_assert_not_reached ();
- return;
- }
-
- raise_and_focus (priv->app);
-#endif
-}
-
-/* Callback used when the calendar client tells us that an object was removed */
-static void
-obj_removed_cb (CalClient *client, const char *uid, gpointer data)
-{
- /* FIXME: Do something sensible if the component is removed under our
- * feet.
- */
-#if 0
- TaskEditor *tedit;
- TaskEditorPrivate *priv;
- const gchar *editing_uid;
-
- tedit = TASK_EDITOR (data);
-
- g_return_if_fail (tedit != NULL);
- g_return_if_fail (IS_TASK_EDITOR (tedit));
-
- priv = tedit->priv;
-
- /* If we aren't showing the object which has been updated, return. */
- if (!priv->comp)
- return;
- cal_component_get_uid (priv->comp, &editing_uid);
- if (strcmp (uid, editing_uid))
- return;
-
-
- raise_and_focus (priv->app);
-#endif
-}
-
-
-/* Brings attention to a window by raising it and giving it focus */
-static void
-raise_and_focus (GtkWidget *widget)
-{
- g_assert (GTK_WIDGET_REALIZED (widget));
- gdk_window_show (widget->window);
- gtk_widget_grab_focus (widget);
-}
-
-
/**
- * task_editor_set_todo_object:
- * @tedit: A #TaskEditor.
- * @comp: A todo object.
+ * task_editor_new:
+ *
+ * Creates a new event editor dialog.
*
- * Sets the todo object that a task editor dialog will manipulate.
+ * Return value: A newly-created event editor dialog, or NULL if the event
+ * editor could not be created.
**/
-void
-task_editor_set_todo_object (TaskEditor *tedit,
- CalComponent *comp)
-{
- TaskEditorPrivate *priv;
-
- g_return_if_fail (tedit != NULL);
- g_return_if_fail (IS_TASK_EDITOR (tedit));
-
- priv = tedit->priv;
-
- if (priv->comp) {
- gtk_object_unref (GTK_OBJECT (priv->comp));
- priv->comp = NULL;
- }
-
- if (comp)
- priv->comp = cal_component_clone (comp);
-
- set_title_from_comp (tedit, priv->comp);
- fill_widgets (tedit);
-}
-
-void
-task_editor_focus (TaskEditor *tedit)
-{
- TaskEditorPrivate *priv;
-
- g_return_if_fail (tedit != NULL);
- g_return_if_fail (IS_TASK_EDITOR (tedit));
-
- priv = tedit->priv;
- gtk_widget_show_now (priv->app);
- raise_and_focus (priv->app);
-}
-
-#warning this is duplicated function from ../event-editor.c
-/* Creates an appropriate title for the task editor dialog */
-static char *
-make_title_from_comp (CalComponent *comp)
-{
- char *title;
- const char *type_string;
- CalComponentVType type;
- CalComponentText text;
-
- if (!comp)
- return g_strdup (_("Edit Task"));
-
- type = cal_component_get_vtype (comp);
- switch (type) {
- case CAL_COMPONENT_EVENT:
- type_string = _("Appointment - %s");
- break;
- case CAL_COMPONENT_TODO:
- type_string = _("Task - %s");
- break;
- case CAL_COMPONENT_JOURNAL:
- type_string = _("Journal entry - %s");
- break;
- default:
- g_message ("make_title_from_comp(): Cannot handle object of type %d", type);
- return NULL;
- }
-
- cal_component_get_summary (comp, &text);
- if (text.value) {
- char *summary;
- summary = e_utf8_to_locale_string (text.value);
- title = g_strdup_printf (type_string, summary);
- g_free (summary);
- } else
- title = g_strdup_printf (type_string, _("No summary"));
-
- return title;
-}
-
-/* Sets the event editor's window title from a calendar component */
-static void
-set_title_from_comp (TaskEditor *tedit, CalComponent *comp)
-{
- TaskEditorPrivate *priv = tedit->priv;
- char *title;
-
- title = make_title_from_comp (comp);
- gtk_window_set_title (GTK_WINDOW (priv->app), title);
- g_free (title);
-}
-
-/* Fills the widgets with default values */
-static void
-clear_widgets (TaskEditor *tedit)
-{
- TaskEditorPrivate *priv;
-
- priv = tedit->priv;
-
-
-}
-
-/* Fills in the widgets with the proper values */
-static void
-fill_widgets (TaskEditor *tedit)
-{
- TaskEditorPrivate *priv;
- CalComponentText text;
- CalComponentDateTime d;
- CalComponentClassification cl;
- struct icaltimetype *completed;
- GSList *l;
- time_t t;
- int *priority_value, *percent;
- icalproperty_status status;
- TaskEditorPriority priority;
- const char *url;
- const char *categories;
-
- priv = tedit->priv;
-
- task_editor_set_changed (tedit, FALSE);
-
- clear_widgets (tedit);
-
- if (!priv->comp)
- return;
-
- /* We want to ignore any signals emitted while changing fields. */
- priv->ignore_callbacks = TRUE;
-
-
- cal_component_get_summary (priv->comp, &text);
- e_dialog_editable_set (priv->summary, text.value);
-
- cal_component_get_description_list (priv->comp, &l);
- if (l) {
- text = *(CalComponentText *)l->data;
- e_dialog_editable_set (priv->description, text.value);
- } else {
- e_dialog_editable_set (priv->description, NULL);
- }
- cal_component_free_text_list (l);
-
- /* Due Date. */
- cal_component_get_due (priv->comp, &d);
- if (d.value) {
- t = icaltime_as_timet (*d.value);
- } else {
- t = -1;
- }
- e_date_edit_set_time (E_DATE_EDIT (priv->due_date), t);
-
- /* Start Date. */
- cal_component_get_dtstart (priv->comp, &d);
- if (d.value) {
- t = icaltime_as_timet (*d.value);
- } else {
- t = -1;
- }
- e_date_edit_set_time (E_DATE_EDIT (priv->start_date), t);
-
- /* Completed Date. */
- cal_component_get_completed (priv->comp, &completed);
- if (completed) {
- t = icaltime_as_timet (*completed);
- cal_component_free_icaltimetype (completed);
- } else {
- t = -1;
- }
- e_date_edit_set_time (E_DATE_EDIT (priv->completed_date), t);
-
- /* Percent Complete. */
- cal_component_get_percent (priv->comp, &percent);
- if (percent) {
- e_dialog_spin_set (priv->percent_complete, *percent);
- cal_component_free_percent (percent);
- } else {
- /* FIXME: Could check if task is completed and set 100%. */
- e_dialog_spin_set (priv->percent_complete, 0);
- }
-
- /* Status. */
- cal_component_get_status (priv->comp, &status);
- if (status == ICAL_STATUS_NONE) {
- /* Try to user the percent value. */
- if (percent) {
- if (*percent == 0)
- status = ICAL_STATUS_NEEDSACTION;
- else if (*percent == 100)
- status = ICAL_STATUS_COMPLETED;
- else
- status = ICAL_STATUS_INPROCESS;
- } else
- status = ICAL_STATUS_NEEDSACTION;
- }
- e_dialog_option_menu_set (priv->status, status, status_map);
-
- /* Priority. */
- cal_component_get_priority (priv->comp, &priority_value);
- if (priority_value) {
- priority = priority_value_to_index (*priority_value);
- cal_component_free_priority (priority_value);
- } else {
- priority = PRIORITY_UNDEFINED;
- }
- e_dialog_option_menu_set (priv->priority, priority, priority_map);
-
-
- /* Classification. */
- cal_component_get_classification (priv->comp, &cl);
-
- switch (cl) {
- case CAL_COMPONENT_CLASS_PUBLIC:
- e_dialog_radio_set (priv->classification_public, CAL_COMPONENT_CLASS_PUBLIC,
- classification_map);
- case CAL_COMPONENT_CLASS_PRIVATE:
- e_dialog_radio_set (priv->classification_public, CAL_COMPONENT_CLASS_PRIVATE,
- classification_map);
- case CAL_COMPONENT_CLASS_CONFIDENTIAL:
- e_dialog_radio_set (priv->classification_public, CAL_COMPONENT_CLASS_CONFIDENTIAL,
- classification_map);
- default:
- /* What do do? We can't g_assert_not_reached() since it is a
- * value from an external file.
- */
- }
-
- /* Categories */
- cal_component_get_categories (priv->comp, &categories);
- e_dialog_editable_set (priv->categories, categories);
-
- /* URL. */
- cal_component_get_url (priv->comp, &url);
- e_dialog_editable_set (priv->url, url);
-
- priv->ignore_callbacks = FALSE;
-}
-
-
-static void
-save_todo_object (TaskEditor *tedit)
-{
- TaskEditorPrivate *priv;
-
- priv = tedit->priv;
-
- g_return_if_fail (priv->client != NULL);
-
- if (!priv->comp)
- return;
-
- dialog_to_comp_object (tedit);
- set_title_from_comp (tedit, priv->comp);
-
- if (!cal_client_update_object (priv->client, priv->comp))
- g_message ("save_todo_object(): Could not update the object!");
- else
- task_editor_set_changed (tedit, FALSE);
-}
-
-
-/* Get the values of the widgets in the event editor and put them in the iCalObject */
-static void
-dialog_to_comp_object (TaskEditor *tedit)
-{
- TaskEditorPrivate *priv;
- CalComponent *comp;
- CalComponentDateTime date;
- time_t t;
- icalproperty_status status;
- TaskEditorPriority priority;
- int priority_value, percent;
- char *url, *cat;
- char *str;
-
- priv = tedit->priv;
- comp = priv->comp;
-
- /* Summary. */
-
- str = e_dialog_editable_get (priv->summary);
- if (!str || strlen (str) == 0)
- cal_component_set_summary (comp, NULL);
- else {
- CalComponentText text;
-
- text.value = str;
- text.altrep = NULL;
-
- cal_component_set_summary (comp, &text);
- }
-
- if (str)
- g_free (str);
-
- /* Description */
-
- str = e_dialog_editable_get (priv->description);
- if (!str || strlen (str) == 0)
- cal_component_set_description_list (comp, NULL);
- else {
- GSList l;
- CalComponentText text;
-
- text.value = str;
- text.altrep = NULL;
- l.data = &text;
- l.next = NULL;
-
- cal_component_set_description_list (comp, &l);
- }
-
- if (!str)
- g_free (str);
-
- /* Dates */
-
- date.value = g_new (struct icaltimetype, 1);
- date.tzid = NULL;
-
- /* Due Date. */
- t = e_date_edit_get_time (E_DATE_EDIT (priv->due_date));
- if (t != -1) {
- *date.value = icaltime_from_timet (t, FALSE);
- cal_component_set_due (comp, &date);
- } else {
- cal_component_set_due (comp, NULL);
- }
-
- /* Start Date. */
- t = e_date_edit_get_time (E_DATE_EDIT (priv->start_date));
- if (t != -1) {
- *date.value = icaltime_from_timet (t, FALSE);
- cal_component_set_dtstart (comp, &date);
- } else {
- cal_component_set_dtstart (comp, NULL);
- }
-
- /* Completed Date. */
- t = e_date_edit_get_time (E_DATE_EDIT (priv->completed_date));
- if (t != -1) {
- *date.value = icaltime_from_timet (t, FALSE);
- cal_component_set_completed (comp, date.value);
- } else {
- cal_component_set_completed (comp, NULL);
- }
-
- g_free (date.value);
-
- /* Percent Complete. */
- percent = e_dialog_spin_get_int (priv->percent_complete);
- cal_component_set_percent (comp, &percent);
-
- /* Status. */
- status = e_dialog_option_menu_get (priv->status, status_map);
- cal_component_set_status (comp, status);
-
- /* Priority. */
- priority = e_dialog_option_menu_get (priv->priority, priority_map);
- priority_value = priority_index_to_value (priority);
- cal_component_set_priority (comp, &priority_value);
-
- /* Classification. */
- cal_component_set_classification (comp, classification_get (priv->classification_public));
-
- /* Categories */
- cat = e_dialog_editable_get (priv->categories);
- cal_component_set_categories (comp, cat);
-
- if (cat)
- g_free (cat);
-
- /* URL. */
- url = e_dialog_editable_get (priv->url);
- cal_component_set_url (comp, url);
-
- if (url)
- g_free (url);
-
- cal_component_commit_sequence (comp);
-}
-
-static TaskEditorPriority
-priority_value_to_index (int priority_value)
-{
- TaskEditorPriority retval;
-
- if (priority_value == 0)
- retval = PRIORITY_UNDEFINED;
- else if (priority_value <= 4)
- retval = PRIORITY_HIGH;
- else if (priority_value == 5)
- retval = PRIORITY_NORMAL;
- else
- retval = PRIORITY_LOW;
-
- return retval;
-}
-
-
-static int
-priority_index_to_value (TaskEditorPriority priority)
-{
- int retval;
-
- switch (priority) {
- case PRIORITY_UNDEFINED:
- retval = 0;
- break;
- case PRIORITY_HIGH:
- retval = 3;
- break;
- case PRIORITY_NORMAL:
- retval = 5;
- break;
- case PRIORITY_LOW:
- retval = 7;
- break;
- default:
- retval = -1;
- g_assert_not_reached ();
- break;
- }
-
- return retval;
-}
-
-
-static void
-completed_changed (EDateEdit *dedit,
- TaskEditor *tedit)
-{
- TaskEditorPrivate *priv;
- time_t t;
-
- g_return_if_fail (IS_TASK_EDITOR (tedit));
-
- priv = tedit->priv;
-
- if (priv->ignore_callbacks)
- return;
-
- task_editor_set_changed (tedit, TRUE);
-
- priv->ignore_callbacks = TRUE;
- t = e_date_edit_get_time (E_DATE_EDIT (priv->completed_date));
- if (t == -1) {
- /* If the 'Completed Date' is set to 'None', we set the
- status to 'Not Started' and the percent-complete to 0.
- The task may actually be partially-complete, but we leave
- it to the user to set those fields. */
- e_dialog_option_menu_set (priv->status, ICAL_STATUS_NEEDSACTION,
- status_map);
- e_dialog_spin_set (priv->percent_complete, 0);
- } else {
- e_dialog_option_menu_set (priv->status, ICAL_STATUS_COMPLETED,
- status_map);
- e_dialog_spin_set (priv->percent_complete, 100);
- }
- priv->ignore_callbacks = FALSE;
-}
-
-
-static void
-status_changed (GtkMenu *menu,
- TaskEditor *tedit)
-{
- TaskEditorPrivate *priv;
- icalproperty_status status;
-
- g_return_if_fail (IS_TASK_EDITOR (tedit));
-
- priv = tedit->priv;
-
- if (priv->ignore_callbacks)
- return;
-
- task_editor_set_changed (tedit, TRUE);
-
- status = e_dialog_option_menu_get (priv->status, status_map);
- priv->ignore_callbacks = TRUE;
- if (status == ICAL_STATUS_NEEDSACTION) {
- e_dialog_spin_set (priv->percent_complete, 0);
- e_date_edit_set_time (E_DATE_EDIT (priv->completed_date), -1);
- } else if (status == ICAL_STATUS_COMPLETED) {
- e_dialog_spin_set (priv->percent_complete, 100);
- e_date_edit_set_time (E_DATE_EDIT (priv->completed_date),
- time (NULL));
- }
- priv->ignore_callbacks = FALSE;
-}
-
-
-static void
-percent_complete_changed (GtkAdjustment *adj,
- TaskEditor *tedit)
-{
- TaskEditorPrivate *priv;
- gint percent;
- icalproperty_status status;
- time_t date_completed;
-
- g_return_if_fail (IS_TASK_EDITOR (tedit));
-
- priv = tedit->priv;
-
- if (priv->ignore_callbacks)
- return;
-
- task_editor_set_changed (tedit, TRUE);
-
- percent = e_dialog_spin_get_int (priv->percent_complete);
- priv->ignore_callbacks = TRUE;
-
- if (percent == 100) {
- date_completed = time (NULL);
- status = ICAL_STATUS_COMPLETED;
- } else {
- /* FIXME: Set to 'None'. */
- date_completed = time (NULL);
-
- if (percent == 0)
- status = ICAL_STATUS_NEEDSACTION;
- else
- status = ICAL_STATUS_INPROCESS;
- }
-
- e_date_edit_set_time (E_DATE_EDIT (priv->completed_date),
- date_completed);
- e_dialog_option_menu_set (priv->status, status, status_map);
-
- priv->ignore_callbacks = FALSE;
-}
-
-/* Decode the radio button group for classifications */
-static CalComponentClassification
-classification_get (GtkWidget *widget)
-{
- return e_dialog_radio_get (widget, classification_map);
-}
-
-
-/* This is called when all fields except those handled above (status, percent
- complete & completed date) are changed. It just sets the "changed" flag. */
-static void
-field_changed (GtkWidget *widget,
- TaskEditor *tedit)
-{
- TaskEditorPrivate *priv;
-
- g_return_if_fail (IS_TASK_EDITOR (tedit));
-
- priv = tedit->priv;
-
- if (priv->ignore_callbacks)
- return;
-
- task_editor_set_changed (tedit, TRUE);
-}
-
-
-static void
-task_editor_set_changed (TaskEditor *tedit,
- gboolean changed)
-{
- TaskEditorPrivate *priv;
-
- priv = tedit->priv;
-
-#if 0
- g_print ("In task_editor_set_changed: %s\n",
- changed ? "TRUE" : "FALSE");
-#endif
-
- priv->changed = changed;
-
- if (priv->app)
- gnome_property_box_set_state (GNOME_PROPERTY_BOX (priv->app), changed);
-}
-
-
-/* This checks if the "changed" field is set, and if so it prompts to save
- the changes using a "Save/Discard/Cancel" modal dialog. It then saves the
- changes if requested. It returns TRUE if the dialog should now be closed. */
-static gboolean
-prompt_to_save_changes (TaskEditor *tedit)
-{
- TaskEditorPrivate *priv;
-
- priv = tedit->priv;
-
- if (!priv->changed)
- return TRUE;
-
- switch (save_component_dialog (GTK_WINDOW (priv->app))) {
- case 0: /* Save */
- /* FIXME: If an error occurs here, we should popup a dialog
- and then return FALSE. */
- save_todo_object (tedit);
- return TRUE;
- case 1: /* Discard */
- return TRUE;
- case 2: /* Cancel */
- default:
- return FALSE;
- break;
- }
-
-}
-
-static void
-categories_clicked(GtkWidget *button, TaskEditor *tedit)
+TaskEditor *
+task_editor_new (void)
{
- char *categories;
- GnomeDialog *dialog;
- int result;
- GtkWidget *entry;
-
- entry = ((TaskEditorPrivate *)tedit->priv)->categories;
- categories = e_utf8_gtk_entry_get_text (GTK_ENTRY (entry));
-
- dialog = GNOME_DIALOG (e_categories_new (categories));
- result = gnome_dialog_run (dialog);
- g_free (categories);
-
- if (result == 0) {
- gtk_object_get (GTK_OBJECT (dialog),
- "categories", &categories,
- NULL);
- e_utf8_gtk_entry_set_text (GTK_ENTRY (entry), categories);
- g_free (categories);
- }
- gtk_object_destroy (GTK_OBJECT (dialog));
+ return TASK_EDITOR (gtk_type_new (TYPE_TASK_EDITOR));
}
diff --git a/calendar/gui/dialogs/task-editor.h b/calendar/gui/dialogs/task-editor.h
index 7327803a72..bd29d7989d 100644
--- a/calendar/gui/dialogs/task-editor.h
+++ b/calendar/gui/dialogs/task-editor.h
@@ -1,16 +1,16 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-/*
- * Author :
- * Damon Chaplin <damon@ximian.com>
+/* Evolution calendar - Task editor dialog
+ *
+ * Copyright (C) 2000 Helix Code, Inc.
+ * Copyright (C) 2001 Ximian, Inc.
*
- * Copyright 2000, Helix Code, Inc.
- * Copyright 2000, Ximian, Inc.
+ * Authors: Miguel de Icaza <miguel@ximian.com>
+ * Federico Mena-Quintero <federico@ximian.com>
+ * Seth Alves <alves@hungry.com>
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -19,52 +19,45 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
-#ifndef _TASK_EDITOR_H_
-#define _TASK_EDITOR_H_
-
-#include <gtk/gtkobject.h>
-#include <libgnome/gnome-defs.h>
-#include <bonobo.h>
-#include <cal-client/cal-client.h>
-BEGIN_GNOME_DECLS
+#ifndef __TASK_EDITOR_H__
+#define __TASK_EDITOR_H__
+#include <libgnome/gnome-defs.h>
+#include <gtk/gtkobject.h>
+#include "comp-editor.h"
-#define TASK_EDITOR(obj) GTK_CHECK_CAST (obj, task_editor_get_type (), TaskEditor)
-#define TASK_EDITOR_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, task_editor_get_type (), TaskEditorClass)
-#define IS_TASK_EDITOR(obj) GTK_CHECK_TYPE (obj, task_editor_get_type ())
+
+#define TYPE_TASK_EDITOR (task_editor_get_type ())
+#define TASK_EDITOR(obj) (GTK_CHECK_CAST ((obj), TYPE_TASK_EDITOR, TaskEditor))
+#define TASK_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_TASK_EDITOR, \
+ TaskEditorClass))
+#define IS_TASK_EDITOR(obj) (GTK_CHECK_TYPE ((obj), TYPE_TASK_EDITOR))
+#define IS_TASK_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), TYPE_TASK_EDITOR))
-typedef struct _TaskEditor TaskEditor;
-typedef struct _TaskEditorClass TaskEditorClass;
+typedef struct _TaskEditor TaskEditor;
+typedef struct _TaskEditorClass TaskEditorClass;
+typedef struct _TaskEditorPrivate TaskEditorPrivate;
-struct _TaskEditor
-{
- GtkObject object;
+struct _TaskEditor {
+ CompEditor parent;
/* Private data */
- gpointer priv;
+ TaskEditorPrivate *priv;
};
-struct _TaskEditorClass
-{
- GtkObjectClass parent_class;
+struct _TaskEditorClass {
+ CompEditorClass parent_class;
};
-GtkType task_editor_get_type (void);
-TaskEditor* task_editor_construct (TaskEditor *tedit);
-TaskEditor* task_editor_new (void);
-void task_editor_set_cal_client (TaskEditor *tedit,
- CalClient *client);
-void task_editor_set_todo_object (TaskEditor *tedit,
- CalComponent *comp);
-void task_editor_focus (TaskEditor *tedit);
-
-
+GtkType task_editor_get_type (void);
+TaskEditor *task_editor_construct (TaskEditor *ee);
+TaskEditor *task_editor_new (void);
+void task_editor_update_widgets (TaskEditor *ee);
-END_GNOME_DECLS
+
-#endif /* _TASK_EDITOR_H_ */
+#endif /* __TASK_EDITOR_H__ */
diff --git a/calendar/gui/dialogs/task-page.c b/calendar/gui/dialogs/task-page.c
new file mode 100644
index 0000000000..a1e66260c2
--- /dev/null
+++ b/calendar/gui/dialogs/task-page.c
@@ -0,0 +1,966 @@
+/* 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 the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <gtk/gtksignal.h>
+#include <gtk/gtktogglebutton.h>
+#include <gtk/gtkspinbutton.h>
+#include <gtk/gtkoptionmenu.h>
+#include <glade/glade.h>
+#include <gal/widgets/e-unicode.h>
+#include <gal/widgets/e-categories.h>
+#include <widgets/misc/e-dateedit.h>
+#include "e-util/e-dialog-widgets.h"
+#include "../widget-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 *percent_complete;
+
+ GtkWidget *status;
+ GtkWidget *priority;
+
+ GtkWidget *description;
+
+ GtkWidget *classification_public;
+ GtkWidget *classification_private;
+ GtkWidget *classification_confidential;
+
+ GtkWidget *contacts_btn;
+ GtkWidget *contacts;
+
+ GtkWidget *categories_btn;
+ GtkWidget *categories;
+
+ gboolean updating;
+};
+
+/* Note that these two arrays must match. */
+static const int status_map[] = {
+ ICAL_STATUS_NEEDSACTION,
+ ICAL_STATUS_INPROCESS,
+ ICAL_STATUS_COMPLETED,
+ ICAL_STATUS_CANCELLED,
+ -1
+};
+
+typedef enum {
+ PRIORITY_HIGH,
+ PRIORITY_NORMAL,
+ PRIORITY_LOW,
+ PRIORITY_UNDEFINED,
+} TaskEditorPriority;
+
+static const int priority_map[] = {
+ PRIORITY_HIGH,
+ PRIORITY_NORMAL,
+ PRIORITY_LOW,
+ PRIORITY_UNDEFINED,
+ -1
+};
+
+static const int classification_map[] = {
+ CAL_COMPONENT_CLASS_PUBLIC,
+ CAL_COMPONENT_CLASS_PRIVATE,
+ CAL_COMPONENT_CLASS_CONFIDENTIAL,
+ -1
+};
+
+
+
+static void task_page_class_init (TaskPageClass *class);
+static void task_page_init (TaskPage *tpage);
+static void task_page_destroy (GtkObject *object);
+
+static GtkWidget *task_page_get_widget (CompEditorPage *page);
+static void task_page_fill_widgets (CompEditorPage *page, CalComponent *comp);
+static void task_page_fill_component (CompEditorPage *page, CalComponent *comp);
+static void task_page_set_summary (CompEditorPage *page, const char *summary);
+static void task_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates);
+
+static CompEditorPageClass *parent_class = NULL;
+
+
+
+/**
+ * task_page_get_type:
+ *
+ * Registers the #TaskPage class if necessary, and returns the type ID
+ * associated to it.
+ *
+ * Return value: The type ID of the #TaskPage class.
+ **/
+GtkType
+task_page_get_type (void)
+{
+ static GtkType task_page_type;
+
+ if (!task_page_type) {
+ static const GtkTypeInfo task_page_info = {
+ "TaskPage",
+ sizeof (TaskPage),
+ sizeof (TaskPageClass),
+ (GtkClassInitFunc) task_page_class_init,
+ (GtkObjectInitFunc) task_page_init,
+ NULL, /* reserved_1 */
+ NULL, /* reserved_2 */
+ (GtkClassInitFunc) NULL
+ };
+
+ task_page_type = gtk_type_unique (TYPE_COMP_EDITOR_PAGE,
+ &task_page_info);
+ }
+
+ return task_page_type;
+}
+
+/* Class initialization function for the task page */
+static void
+task_page_class_init (TaskPageClass *class)
+{
+ CompEditorPageClass *editor_page_class;
+ GtkObjectClass *object_class;
+
+ editor_page_class = (CompEditorPageClass *) class;
+ object_class = (GtkObjectClass *) class;
+
+ parent_class = gtk_type_class (TYPE_COMP_EDITOR_PAGE);
+
+ editor_page_class->get_widget = task_page_get_widget;
+ editor_page_class->fill_widgets = task_page_fill_widgets;
+ editor_page_class->fill_component = task_page_fill_component;
+ editor_page_class->set_summary = task_page_set_summary;
+ editor_page_class->set_dates = task_page_set_dates;
+
+ object_class->destroy = task_page_destroy;
+}
+
+/* Object initialization function for the task page */
+static void
+task_page_init (TaskPage *tpage)
+{
+ TaskPagePrivate *priv;
+
+ priv = g_new0 (TaskPagePrivate, 1);
+ tpage->priv = priv;
+
+ priv->xml = NULL;
+
+ priv->main = NULL;
+ priv->summary = NULL;
+ priv->due_date = NULL;
+ priv->start_date = NULL;
+ priv->percent_complete = NULL;
+ priv->status = NULL;
+ priv->description = NULL;
+ priv->classification_public = NULL;
+ priv->classification_private = NULL;
+ priv->classification_confidential = NULL;
+ priv->contacts_btn = NULL;
+ priv->contacts = NULL;
+ priv->categories_btn = NULL;
+ priv->categories = NULL;
+
+ priv->updating = FALSE;
+}
+
+/* Destroy handler for the task page */
+static void
+task_page_destroy (GtkObject *object)
+{
+ TaskPage *tpage;
+ TaskPagePrivate *priv;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (IS_TASK_PAGE (object));
+
+ tpage = TASK_PAGE (object);
+ priv = tpage->priv;
+
+ if (priv->xml) {
+ gtk_object_unref (GTK_OBJECT (priv->xml));
+ priv->xml = NULL;
+ }
+
+ g_free (priv);
+ tpage->priv = NULL;
+
+ if (GTK_OBJECT_CLASS (parent_class)->destroy)
+ (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+
+
+/* get_widget handler for the task page */
+static GtkWidget *
+task_page_get_widget (CompEditorPage *page)
+{
+ TaskPage *tpage;
+ TaskPagePrivate *priv;
+
+ tpage = TASK_PAGE (page);
+ priv = tpage->priv;
+
+ return priv->main;
+}
+
+/* Fills the widgets with default values */
+static void
+clear_widgets (TaskPage *tpage)
+{
+ TaskPagePrivate *priv;
+ time_t now;
+
+ priv = tpage->priv;
+
+ now = time (NULL);
+
+ /* Summary, description */
+ e_dialog_editable_set (priv->summary, NULL);
+ e_dialog_editable_set (priv->description, NULL);
+
+ /* Start, due times */
+ e_date_edit_set_time (E_DATE_EDIT (priv->start_date), now);
+ e_date_edit_set_time (E_DATE_EDIT (priv->due_date), now);
+
+ /* Classification */
+ e_dialog_radio_set (priv->classification_public,
+ CAL_COMPONENT_CLASS_PRIVATE, classification_map);
+
+ /* Status, priority, complete percent */
+ e_dialog_spin_set (priv->percent_complete, 0.0);
+ e_dialog_option_menu_set (priv->status, 0, status_map);
+ e_dialog_option_menu_set (priv->priority, 0, priority_map);
+
+ /* Categories */
+ e_dialog_editable_set (priv->categories, NULL);
+}
+
+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;
+}
+
+/* Decode the radio button group for classifications */
+static CalComponentClassification
+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, CalComponent *comp)
+{
+ TaskPage *tpage;
+ TaskPagePrivate *priv;
+ CalComponentText text;
+ CalComponentDateTime d;
+ CalComponentClassification cl;
+ GSList *l;
+ time_t t;
+ int *priority_value, *percent;
+ icalproperty_status status;
+ TaskEditorPriority priority;
+ const char *categories;
+
+ tpage = TASK_PAGE (page);
+ priv = tpage->priv;
+
+ priv->updating = TRUE;
+
+ /* Clean the screen */
+ clear_widgets (tpage);
+
+ /* Summary, description(s) */
+ cal_component_get_summary (comp, &text);
+ e_dialog_editable_set (priv->summary, text.value);
+
+ cal_component_get_description_list (comp, &l);
+ if (l) {
+ text = *(CalComponentText *)l->data;
+ e_dialog_editable_set (priv->description, text.value);
+ } else {
+ e_dialog_editable_set (priv->description, NULL);
+ }
+ cal_component_free_text_list (l);
+
+ /* Due Date. */
+ cal_component_get_due (comp, &d);
+ if (d.value) {
+ t = icaltime_as_timet (*d.value);
+ } else {
+ t = -1;
+ }
+ e_date_edit_set_time (E_DATE_EDIT (priv->due_date), t);
+
+ /* Start Date. */
+ cal_component_get_dtstart (comp, &d);
+ if (d.value) {
+ t = icaltime_as_timet (*d.value);
+ } else {
+ t = -1;
+ }
+ e_date_edit_set_time (E_DATE_EDIT (priv->start_date), t);
+
+ /* Percent Complete. */
+ cal_component_get_percent (comp, &percent);
+ if (percent) {
+ e_dialog_spin_set (priv->percent_complete, *percent);
+ cal_component_free_percent (percent);
+ } else {
+ /* FIXME: Could check if task is completed and set 100%. */
+ e_dialog_spin_set (priv->percent_complete, 0);
+ }
+
+ /* Status. */
+ cal_component_get_status (comp, &status);
+ if (status == ICAL_STATUS_NONE) {
+ /* Try to user the percent value. */
+ if (percent) {
+ if (*percent == 0)
+ status = ICAL_STATUS_NEEDSACTION;
+ else if (*percent == 100)
+ status = ICAL_STATUS_COMPLETED;
+ else
+ status = ICAL_STATUS_INPROCESS;
+ } else
+ status = ICAL_STATUS_NEEDSACTION;
+ }
+ e_dialog_option_menu_set (priv->status, status, status_map);
+
+ /* Priority. */
+ cal_component_get_priority (comp, &priority_value);
+ if (priority_value) {
+ priority = priority_value_to_index (*priority_value);
+ cal_component_free_priority (priority_value);
+ } else {
+ priority = PRIORITY_UNDEFINED;
+ }
+ e_dialog_option_menu_set (priv->priority, priority, priority_map);
+
+
+ /* Classification. */
+ cal_component_get_classification (comp, &cl);
+
+ switch (cl) {
+ case CAL_COMPONENT_CLASS_PUBLIC:
+ e_dialog_radio_set (priv->classification_public,
+ CAL_COMPONENT_CLASS_PUBLIC,
+ classification_map);
+ case CAL_COMPONENT_CLASS_PRIVATE:
+ e_dialog_radio_set (priv->classification_public,
+ CAL_COMPONENT_CLASS_PRIVATE,
+ classification_map);
+ case CAL_COMPONENT_CLASS_CONFIDENTIAL:
+ e_dialog_radio_set (priv->classification_public,
+ CAL_COMPONENT_CLASS_CONFIDENTIAL,
+ classification_map);
+ default:
+ /* What do do? We can't g_assert_not_reached() since it is a
+ * value from an external file.
+ */
+ }
+
+ /* Categories */
+ cal_component_get_categories (comp, &categories);
+ e_dialog_editable_set (priv->categories, categories);
+
+ priv->updating = FALSE;
+}
+
+/* fill_component handler for the task page */
+static void
+task_page_fill_component (CompEditorPage *page, CalComponent *comp)
+{
+ TaskPage *tpage;
+ TaskPagePrivate *priv;
+ CalComponentDateTime date;
+ time_t t;
+ icalproperty_status status;
+ TaskEditorPriority priority;
+ int priority_value, percent;
+ char *cat;
+ char *str;
+
+ tpage = TASK_PAGE (page);
+ priv = tpage->priv;
+
+ /* Summary. */
+
+ str = e_dialog_editable_get (priv->summary);
+ if (!str || strlen (str) == 0)
+ cal_component_set_summary (comp, NULL);
+ else {
+ CalComponentText text;
+
+ text.value = str;
+ text.altrep = NULL;
+
+ cal_component_set_summary (comp, &text);
+ }
+
+ if (str)
+ g_free (str);
+
+ /* Description */
+
+ str = e_dialog_editable_get (priv->description);
+ if (!str || strlen (str) == 0)
+ cal_component_set_description_list (comp, NULL);
+ else {
+ GSList l;
+ CalComponentText text;
+
+ text.value = str;
+ text.altrep = NULL;
+ l.data = &text;
+ l.next = NULL;
+
+ cal_component_set_description_list (comp, &l);
+ }
+
+ if (!str)
+ g_free (str);
+
+ /* Dates */
+
+ date.value = g_new (struct icaltimetype, 1);
+ date.tzid = NULL;
+
+ /* Due Date. */
+ t = e_date_edit_get_time (E_DATE_EDIT (priv->due_date));
+ if (t != -1) {
+ *date.value = icaltime_from_timet (t, FALSE);
+ cal_component_set_due (comp, &date);
+ } else {
+ cal_component_set_due (comp, NULL);
+ }
+
+ /* Start Date. */
+ t = e_date_edit_get_time (E_DATE_EDIT (priv->start_date));
+ if (t != -1) {
+ *date.value = icaltime_from_timet (t, FALSE);
+ cal_component_set_dtstart (comp, &date);
+ } else {
+ cal_component_set_dtstart (comp, NULL);
+ }
+
+ /* Percent Complete. */
+ percent = e_dialog_spin_get_int (priv->percent_complete);
+ cal_component_set_percent (comp, &percent);
+
+ /* Status. */
+ status = e_dialog_option_menu_get (priv->status, status_map);
+ cal_component_set_status (comp, status);
+
+ /* Priority. */
+ priority = e_dialog_option_menu_get (priv->priority, priority_map);
+ priority_value = priority_index_to_value (priority);
+ cal_component_set_priority (comp, &priority_value);
+
+ /* Classification. */
+ cal_component_set_classification (comp, classification_get (priv->classification_public));
+
+ /* Categories */
+ cat = e_dialog_editable_get (priv->categories);
+ cal_component_set_categories (comp, cat);
+
+ if (cat)
+ g_free (cat);
+}
+
+/* set_summary handler for the task page */
+static void
+task_page_set_summary (CompEditorPage *page, const char *summary)
+{
+ TaskPage *tpage;
+ TaskPagePrivate *priv;
+
+ tpage = TASK_PAGE (page);
+ priv = tpage->priv;
+
+ gtk_signal_handler_block_by_data (GTK_OBJECT (priv->summary), tpage);
+ e_utf8_gtk_entry_set_text (GTK_ENTRY (priv->summary), summary);
+ gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->summary), tpage);
+}
+
+static void
+task_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates)
+{
+ TaskPage *tpage;
+ TaskPagePrivate *priv;
+
+ tpage = TASK_PAGE (page);
+ priv = tpage->priv;
+
+ priv->updating = TRUE;
+
+ if (dates->complete != 0) {
+ if (dates->complete == -1) {
+ /* If the 'Completed Date' is set to 'None',
+ we set the status to 'Not Started' and the
+ percent-complete to 0. The task may
+ actually be partially-complete, but we
+ leave it to the user to set those
+ fields. */
+ e_dialog_option_menu_set (priv->status,
+ ICAL_STATUS_NEEDSACTION,
+ status_map);
+ e_dialog_spin_set (priv->percent_complete, 0);
+ } else {
+ e_dialog_option_menu_set (priv->status,
+ ICAL_STATUS_COMPLETED,
+ status_map);
+ e_dialog_spin_set (priv->percent_complete, 100);
+ }
+ }
+
+ priv->updating = FALSE;
+}
+
+
+
+/* Gets the widgets from the XML file and returns if they are all available. */
+static gboolean
+get_widgets (TaskPage *tpage)
+{
+ TaskPagePrivate *priv;
+
+ priv = tpage->priv;
+
+#define GW(name) glade_xml_get_widget (priv->xml, name)
+
+ priv->main = GW ("task-page");
+ g_assert (priv->main);
+ gtk_widget_ref (priv->main);
+ gtk_widget_unparent (priv->main);
+
+ priv->summary = GW ("summary");
+
+ priv->due_date = GW ("due-date");
+ priv->start_date = GW ("start-date");
+
+ priv->percent_complete = GW ("percent-complete");
+
+ priv->status = GW ("status");
+ priv->priority = GW ("priority");
+
+ priv->description = GW ("description");
+
+ priv->classification_public = GW ("classification-public");
+ priv->classification_private = GW ("classification-private");
+ priv->classification_confidential = GW ("classification-confidential");
+
+ priv->contacts_btn = GW ("contacts-button");
+ priv->contacts = GW ("contacts");
+
+ priv->categories_btn = GW ("categories-button");
+ priv->categories = GW ("categories");
+
+#undef GW
+
+ return (priv->summary
+ && priv->due_date
+ && priv->start_date
+ && priv->percent_complete
+ && priv->status
+ && priv->priority
+ && priv->classification_public
+ && priv->classification_private
+ && priv->classification_confidential
+ && priv->description
+ && priv->contacts_btn
+ && priv->contacts
+ && 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 = gtk_editable_get_chars (editable, 0, -1);
+ comp_editor_page_notify_summary_changed (COMP_EDITOR_PAGE (tpage),
+ summary);
+ g_free (summary);
+}
+
+/* Callback used when the start or end date widgets change. We check that the
+ * start date < end date and we set the "all day task" button as appropriate.
+ */
+static void
+date_changed_cb (EDateEdit *dedit, gpointer data)
+{
+ TaskPage *tpage;
+ TaskPagePrivate *priv;
+ CompEditorPageDates dates;
+
+ tpage = TASK_PAGE (data);
+ priv = tpage->priv;
+
+ if (priv->updating)
+ return;
+
+ dates.start = e_date_edit_get_time (E_DATE_EDIT (priv->start_date));
+ dates.end = 0;
+ dates.due = e_date_edit_get_time (E_DATE_EDIT (priv->due_date));
+ dates.complete = 0;
+
+ /* 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;
+ char *categories;
+ GnomeDialog *dialog;
+ int result;
+ GtkWidget *entry;
+
+ tpage = TASK_PAGE (data);
+ priv = tpage->priv;
+
+ entry = priv->categories;
+ categories = e_utf8_gtk_entry_get_text (GTK_ENTRY (entry));
+
+ dialog = GNOME_DIALOG (e_categories_new (categories));
+ result = gnome_dialog_run (dialog);
+ g_free (categories);
+
+ if (result == 0) {
+ gtk_object_get (GTK_OBJECT (dialog),
+ "categories", &categories,
+ NULL);
+ e_utf8_gtk_entry_set_text (GTK_ENTRY (entry), categories);
+ g_free (categories);
+ }
+
+ gtk_object_destroy (GTK_OBJECT (dialog));
+}
+
+/* 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));
+}
+
+static void
+complete_date_changed (TaskPage *tpage, time_t complete)
+{
+ TaskPagePrivate *priv;
+ CompEditorPageDates dates;
+
+ priv = tpage->priv;
+
+ if (priv->updating)
+ return;
+
+ dates.start = 0;
+ dates.end = 0;
+ dates.due = 0;
+ dates.complete = complete;
+
+ /* Notify upstream */
+ comp_editor_page_notify_dates_changed (COMP_EDITOR_PAGE (tpage),
+ &dates);
+}
+
+static void
+status_changed (GtkMenu *menu, TaskPage *tpage)
+{
+ TaskPagePrivate *priv;
+ icalproperty_status status;
+
+ priv = tpage->priv;
+
+ if (priv->updating)
+ return;
+
+ status = e_dialog_option_menu_get (priv->status, status_map);
+ if (status == ICAL_STATUS_NEEDSACTION) {
+ e_dialog_spin_set (priv->percent_complete, 0);
+ complete_date_changed (tpage, -1);
+ } else if (status == ICAL_STATUS_INPROCESS) {
+ e_dialog_spin_set (priv->percent_complete, 50);
+ complete_date_changed (tpage, -1);
+ } else if (status == ICAL_STATUS_COMPLETED) {
+ e_dialog_spin_set (priv->percent_complete, 100);
+ complete_date_changed (tpage, time (NULL));
+ }
+
+ comp_editor_page_notify_changed (COMP_EDITOR_PAGE (tpage));
+}
+
+static void
+percent_complete_changed (GtkAdjustment *adj, TaskPage *tpage)
+{
+ TaskPagePrivate *priv;
+ gint percent;
+ icalproperty_status status;
+ time_t date_completed;
+
+ priv = tpage->priv;
+
+ if (priv->updating)
+ return;
+
+ percent = e_dialog_spin_get_int (priv->percent_complete);
+ if (percent == 100) {
+ date_completed = time (NULL);
+ status = ICAL_STATUS_COMPLETED;
+ } else {
+ date_completed = -1;
+
+ if (percent == 0)
+ status = ICAL_STATUS_NEEDSACTION;
+ else
+ status = ICAL_STATUS_INPROCESS;
+ }
+
+ complete_date_changed (tpage, date_completed);
+ e_dialog_option_menu_set (priv->status, status, status_map);
+
+ comp_editor_page_notify_changed (COMP_EDITOR_PAGE (tpage));
+}
+
+
+/* Hooks the widget signals */
+static void
+init_widgets (TaskPage *tpage)
+{
+ TaskPagePrivate *priv;
+
+ priv = tpage->priv;
+
+
+ /* Summary */
+ gtk_signal_connect (GTK_OBJECT (priv->summary), "changed",
+ GTK_SIGNAL_FUNC (summary_changed_cb), tpage);
+
+ /* Dates */
+ gtk_signal_connect (GTK_OBJECT (priv->start_date), "changed",
+ GTK_SIGNAL_FUNC (date_changed_cb), tpage);
+ gtk_signal_connect (GTK_OBJECT (priv->due_date), "changed",
+ GTK_SIGNAL_FUNC (date_changed_cb), tpage);
+
+ /* Connect signals. The Status, Percent Complete & Date Completed
+ properties are closely related so whenever one changes we may need
+ to update the other 2. */
+ gtk_signal_connect (GTK_OBJECT (GTK_OPTION_MENU (priv->status)->menu),
+ "deactivate",
+ GTK_SIGNAL_FUNC (status_changed), tpage);
+
+ gtk_signal_connect (GTK_OBJECT (GTK_SPIN_BUTTON (priv->percent_complete)->adjustment),
+ "value_changed",
+ GTK_SIGNAL_FUNC (percent_complete_changed), tpage);
+
+ /* Classification */
+ gtk_signal_connect (GTK_OBJECT (priv->description), "changed",
+ GTK_SIGNAL_FUNC (field_changed_cb), tpage);
+ gtk_signal_connect (GTK_OBJECT (priv->classification_public),
+ "toggled",
+ GTK_SIGNAL_FUNC (field_changed_cb), tpage);
+ gtk_signal_connect (GTK_OBJECT (priv->classification_private),
+ "toggled",
+ GTK_SIGNAL_FUNC (field_changed_cb), tpage);
+ gtk_signal_connect (GTK_OBJECT (priv->classification_confidential),
+ "toggled",
+ GTK_SIGNAL_FUNC (field_changed_cb), tpage);
+
+ /* Connect the default signal handler to use to make sure the "changed"
+ field gets set whenever a field is changed. */
+ gtk_signal_connect (GTK_OBJECT (GTK_OPTION_MENU (priv->priority)->menu),
+ "deactivate",
+ GTK_SIGNAL_FUNC (field_changed_cb), tpage);
+ gtk_signal_connect (GTK_OBJECT (priv->description), "changed",
+ GTK_SIGNAL_FUNC (field_changed_cb), tpage);
+ gtk_signal_connect (GTK_OBJECT (priv->contacts), "changed",
+ GTK_SIGNAL_FUNC (field_changed_cb), tpage);
+ gtk_signal_connect (GTK_OBJECT (priv->categories), "changed",
+ GTK_SIGNAL_FUNC (field_changed_cb), tpage);
+
+ /* Button clicks */
+ gtk_signal_connect (GTK_OBJECT (priv->categories_btn), "clicked",
+ GTK_SIGNAL_FUNC (categories_clicked_cb), tpage);
+
+ /* FIXME: we do not support these fields yet, so we disable them */
+
+ gtk_widget_set_sensitive (priv->contacts_btn, FALSE);
+ gtk_widget_set_sensitive (priv->contacts, FALSE);
+}
+
+
+
+/**
+ * task_page_construct:
+ * @tpage: An task page.
+ *
+ * Constructs an task page by loading its Glade data.
+ *
+ * Return value: The same object as @tpage, or NULL if the widgets could not be
+ * created.
+ **/
+TaskPage *
+task_page_construct (TaskPage *tpage)
+{
+ TaskPagePrivate *priv;
+
+ priv = tpage->priv;
+
+ priv->xml = glade_xml_new (EVOLUTION_GLADEDIR "/task-page.glade",
+ NULL);
+ if (!priv->xml) {
+ g_message ("task_page_construct(): "
+ "Could not load the Glade XML file!");
+ return NULL;
+ }
+
+ if (!get_widgets (tpage)) {
+ g_message ("task_page_construct(): "
+ "Could not find all widgets in the XML file!");
+ return NULL;
+ }
+
+ init_widgets (tpage);
+
+ return tpage;
+}
+
+/**
+ * task_page_new:
+ *
+ * Creates a new task page.
+ *
+ * Return value: A newly-created task page, or NULL if the page could
+ * not be created.
+ **/
+TaskPage *
+task_page_new (void)
+{
+ TaskPage *tpage;
+
+ tpage = gtk_type_new (TYPE_TASK_PAGE);
+ if (!task_page_construct (tpage)) {
+ gtk_object_unref (GTK_OBJECT (tpage));
+ return NULL;
+ }
+
+ return tpage;
+}
+
+GtkWidget *task_page_create_date_edit (void);
+
+GtkWidget *
+task_page_create_date_edit (void)
+{
+ GtkWidget *dedit;
+
+ dedit = date_edit_new (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
index e9f0d4700d..b6182cd860 100644
--- a/calendar/gui/dialogs/task-page.glade
+++ b/calendar/gui/dialogs/task-page.glade
@@ -15,6 +15,7 @@
<widget>
<class>GtkWindow</class>
<name>task-toplevel</name>
+ <visible>False</visible>
<title>window1</title>
<type>GTK_WINDOW_TOPLEVEL</type>
<position>GTK_WIN_POS_NONE</position>
@@ -184,10 +185,10 @@
<widget>
<class>Custom</class>
<name>due-date</name>
- <creation_function>task_editor_create_date_edit</creation_function>
+ <creation_function>task_page_create_date_edit</creation_function>
<int1>0</int1>
<int2>0</int2>
- <last_modification_time>Sun, 10 Sep 2000 17:32:18 GMT</last_modification_time>
+ <last_modification_time>Fri, 01 Jun 2001 18:59:52 GMT</last_modification_time>
<child>
<left_attach>1</left_attach>
<right_attach>2</right_attach>
@@ -207,10 +208,10 @@
<widget>
<class>Custom</class>
<name>start-date</name>
- <creation_function>task_editor_create_date_edit</creation_function>
+ <creation_function>task_page_create_date_edit</creation_function>
<int1>0</int1>
<int2>0</int2>
- <last_modification_time>Sun, 10 Sep 2000 17:33:31 GMT</last_modification_time>
+ <last_modification_time>Fri, 01 Jun 2001 18:59:57 GMT</last_modification_time>
<child>
<left_attach>1</left_attach>
<right_attach>2</right_attach>
@@ -239,7 +240,7 @@
<vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
<child>
<padding>0</padding>
- <expand>False</expand>
+ <expand>True</expand>
<fill>True</fill>
</child>
@@ -459,7 +460,7 @@ Undefined
<spacing>2</spacing>
<child>
<padding>0</padding>
- <expand>True</expand>
+ <expand>False</expand>
<fill>True</fill>
</child>
@@ -467,7 +468,6 @@ Undefined
<class>GtkButton</class>
<name>contacts-button</name>
<can_focus>True</can_focus>
- <relief>GTK_RELIEF_NORMAL</relief>
<child>
<padding>0</padding>
<expand>False</expand>
@@ -506,7 +506,6 @@ Undefined
<class>GtkButton</class>
<name>categories-button</name>
<can_focus>True</can_focus>
- <relief>GTK_RELIEF_NORMAL</relief>
<child>
<padding>0</padding>
<expand>False</expand>
diff --git a/calendar/gui/dialogs/task-page.h b/calendar/gui/dialogs/task-page.h
new file mode 100644
index 0000000000..cc56892c5b
--- /dev/null
+++ b/calendar/gui/dialogs/task-page.h
@@ -0,0 +1,61 @@
+/* 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 the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef TASK_PAGE_H
+#define TASK_PAGE_H
+
+#include "comp-editor-page.h"
+
+BEGIN_GNOME_DECLS
+
+
+
+#define TYPE_TASK_PAGE (task_page_get_type ())
+#define TASK_PAGE(obj) (GTK_CHECK_CAST ((obj), TYPE_TASK_PAGE, TaskPage))
+#define TASK_PAGE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_TASK_PAGE, TaskPageClass))
+#define IS_TASK_PAGE(obj) (GTK_CHECK_TYPE ((obj), TYPE_TASK_PAGE))
+#define IS_TASK_PAGE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), TYPE_TASK_PAGE))
+
+typedef struct _TaskPagePrivate TaskPagePrivate;
+
+typedef struct {
+ CompEditorPage page;
+
+ /* Private data */
+ TaskPagePrivate *priv;
+} TaskPage;
+
+typedef struct {
+ CompEditorPageClass parent_class;
+} TaskPageClass;
+
+GtkType task_page_get_type (void);
+TaskPage *task_page_construct (TaskPage *epage);
+TaskPage *task_page_new (void);
+
+
+
+END_GNOME_DECLS
+
+#endif
diff --git a/calendar/gui/e-calendar-table.c b/calendar/gui/e-calendar-table.c
index 685a56d9f9..d95318cb04 100644
--- a/calendar/gui/e-calendar-table.c
+++ b/calendar/gui/e-calendar-table.c
@@ -31,6 +31,7 @@
#include <config.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <gnome.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>
@@ -674,9 +675,9 @@ open_task (ECalendarTable *cal_table, CalComponent *comp)
TaskEditor *tedit;
tedit = task_editor_new ();
- task_editor_set_cal_client (tedit, calendar_model_get_cal_client (cal_table->model));
- task_editor_set_todo_object (tedit, comp);
- task_editor_focus (tedit);
+ comp_editor_set_cal_client (COMP_EDITOR (tedit), calendar_model_get_cal_client (cal_table->model));
+ comp_editor_edit_comp (COMP_EDITOR (tedit), comp);
+ comp_editor_focus (COMP_EDITOR (tedit));
}
/* Opens the task in the specified row */
diff --git a/calendar/gui/e-tasks.c b/calendar/gui/e-tasks.c
index 609e2551c1..4a25646676 100644
--- a/calendar/gui/e-tasks.c
+++ b/calendar/gui/e-tasks.c
@@ -24,6 +24,7 @@
*/
#include <config.h>
+#include <gnome.h>
#include <gal/util/e-util.h>
#include <gal/e-table/e-table-scrolled.h>
#include <gal/menus/gal-view-collection.h>
@@ -468,15 +469,15 @@ e_tasks_new_task (ETasks *tasks)
priv = tasks->priv;
tedit = task_editor_new ();
- task_editor_set_cal_client (tedit, priv->client);
+ comp_editor_set_cal_client (COMP_EDITOR (tedit), priv->client);
comp = cal_component_new ();
cal_component_set_new_vtype (comp, CAL_COMPONENT_TODO);
- task_editor_set_todo_object (tedit, comp);
+ comp_editor_edit_comp (COMP_EDITOR (tedit), comp);
gtk_object_unref (GTK_OBJECT (comp));
- task_editor_focus (tedit);
+ comp_editor_focus (COMP_EDITOR (tedit));
}
/**
diff --git a/calendar/gui/event-editor-dialog.glade b/calendar/gui/event-editor-dialog.glade
deleted file mode 100644
index 615bd3eed3..0000000000
--- a/calendar/gui/event-editor-dialog.glade
+++ /dev/null
@@ -1,1408 +0,0 @@
-<?xml version="1.0"?>
-<GTK-Interface>
-
-<project>
- <name>event-editor-dialog</name>
- <program_name>event-editor-dialog</program_name>
- <directory></directory>
- <source_directory>.</source_directory>
- <pixmaps_directory>pixmaps</pixmaps_directory>
- <language>C</language>
- <gnome_support>True</gnome_support>
- <gettext_support>True</gettext_support>
- <output_main_file>False</output_main_file>
- <output_support_files>False</output_support_files>
- <output_build_files>False</output_build_files>
-</project>
-
-<widget>
- <class>GnomePropertyBox</class>
- <name>event-editor-dialog</name>
- <visible>False</visible>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>False</allow_grow>
- <auto_shrink>False</auto_shrink>
-
- <widget>
- <class>GtkNotebook</class>
- <child_name>GnomeDock:contents</child_name>
- <name>notebook1</name>
- <border_width>2</border_width>
- <can_focus>True</can_focus>
- <show_tabs>True</show_tabs>
- <show_border>True</show_border>
- <tab_pos>GTK_POS_TOP</tab_pos>
- <scrollable>False</scrollable>
- <tab_hborder>2</tab_hborder>
- <tab_vborder>2</tab_vborder>
- <popup_enable>False</popup_enable>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox51</name>
- <border_width>4</border_width>
- <homogeneous>False</homogeneous>
- <spacing>6</spacing>
-
- <widget>
- <class>GtkTable</class>
- <name>table11</name>
- <rows>1</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>4</row_spacing>
- <column_spacing>4</column_spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label56</name>
- <label>Su_mmary:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <default_focus_target>general-summary</default_focus_target>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>general-summary</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame31</name>
- <label>Date &amp; Time</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkTable</class>
- <name>table12</name>
- <border_width>4</border_width>
- <rows>2</rows>
- <columns>3</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>4</row_spacing>
- <column_spacing>4</column_spacing>
-
- <widget>
- <class>GtkLabel</class>
- <name>label57</name>
- <label>_Start time:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label58</name>
- <label>_End time:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkCheckButton</class>
- <name>all-day-event</name>
- <can_focus>True</can_focus>
- <label>A_ll day event</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <child>
- <left_attach>2</left_attach>
- <right_attach>3</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>Custom</class>
- <name>start-time</name>
- <creation_function>make_date_edit</creation_function>
- <string1></string1>
- <string2></string2>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Tue, 16 May 2000 19:11:05 GMT</last_modification_time>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>True</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>False</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>Custom</class>
- <name>end-time</name>
- <creation_function>make_date_edit</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Tue, 16 May 2000 19:11:10 GMT</last_modification_time>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>True</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>False</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkScrolledWindow</class>
- <name>scrolledwindow12</name>
- <hscrollbar_policy>GTK_POLICY_NEVER</hscrollbar_policy>
- <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy>
- <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
- <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkText</class>
- <name>description</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text></text>
- </widget>
- </widget>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame32</name>
- <label>Classification</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox52</name>
- <border_width>2</border_width>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
-
- <widget>
- <class>GtkRadioButton</class>
- <name>classification-public</name>
- <can_focus>True</can_focus>
- <label>Pu_blic</label>
- <active>True</active>
- <draw_indicator>True</draw_indicator>
- <group>classification_radio_group</group>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkRadioButton</class>
- <name>classification-private</name>
- <can_focus>True</can_focus>
- <label>Pri_vate</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <group>classification_radio_group</group>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkRadioButton</class>
- <name>classification-confidential</name>
- <can_focus>True</can_focus>
- <label>_Confidential</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <group>classification_radio_group</group>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox53</name>
- <homogeneous>False</homogeneous>
- <spacing>2</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>contacts-button</name>
- <can_focus>True</can_focus>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label59</name>
- <label>_Contacts...</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>4</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>contacts</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>categories-button</name>
- <can_focus>True</can_focus>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label60</name>
- <label>Ca_tegories...</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>4</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>categories</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label61</name>
- <label>Appointment</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox52</name>
- <border_width>4</border_width>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame33</name>
- <label>Appointment Basics</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkTable</class>
- <name>table13</name>
- <border_width>4</border_width>
- <rows>2</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>2</row_spacing>
- <column_spacing>2</column_spacing>
-
- <widget>
- <class>GtkLabel</class>
- <name>label62</name>
- <label>Su_mmary:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <default_focus_target>reminder-summary</default_focus_target>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label63</name>
- <label>_Starting date:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>reminder-summary</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>True</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>reminder-starting-data</name>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xscale>0</xscale>
- <yscale>0</yscale>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>Custom</class>
- <name>reminder-starting-date</name>
- <creation_function>make_date_edit</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Fri, 22 Sep 2000 20:51:38 GMT</last_modification_time>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame34</name>
- <label>Reminders</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox53</name>
- <border_width>4</border_width>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox54</name>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkOptionMenu</class>
- <name>reminder-action</name>
- <can_focus>True</can_focus>
- <items>Show a dialog
-Play a sound
-Send an email
-Run a program
-</items>
- <initial_choice>0</initial_choice>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkSpinButton</class>
- <name>reminder-interval-value</name>
- <can_focus>True</can_focus>
- <climb_rate>1</climb_rate>
- <digits>0</digits>
- <numeric>True</numeric>
- <update_policy>GTK_UPDATE_ALWAYS</update_policy>
- <snap>False</snap>
- <wrap>False</wrap>
- <value>1</value>
- <lower>0</lower>
- <upper>100</upper>
- <step>1</step>
- <page>10</page>
- <page_size>10</page_size>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkOptionMenu</class>
- <name>reminder-value-units</name>
- <can_focus>True</can_focus>
- <items>minute(s)
-hour(s)
-day(s)
-</items>
- <initial_choice>0</initial_choice>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkOptionMenu</class>
- <name>reminder-relative</name>
- <can_focus>True</can_focus>
- <items>before
-after
-</items>
- <initial_choice>0</initial_choice>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkOptionMenu</class>
- <name>reminder-time</name>
- <can_focus>True</can_focus>
- <items>start of appointment
-end of appointment
-</items>
- <initial_choice>0</initial_choice>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button9</name>
- <can_focus>True</can_focus>
- <label>Settings...</label>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox55</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkScrolledWindow</class>
- <name>scrolledwindow13</name>
- <hscrollbar_policy>GTK_POLICY_NEVER</hscrollbar_policy>
- <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy>
- <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
- <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkCList</class>
- <name>reminder-list</name>
- <can_focus>True</can_focus>
- <columns>1</columns>
- <column_widths>80</column_widths>
- <selection_mode>GTK_SELECTION_BROWSE</selection_mode>
- <show_titles>False</show_titles>
- <shadow_type>GTK_SHADOW_IN</shadow_type>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label64</name>
- <label>label55</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkVButtonBox</class>
- <name>vbuttonbox2</name>
- <layout_style>GTK_BUTTONBOX_START</layout_style>
- <spacing>10</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>reminder-add</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <label>Add</label>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>reminder-delete</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <label>Delete</label>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label65</name>
- <label>Reminder</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox54</name>
- <border_width>4</border_width>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame35</name>
- <label>Appointment Basics</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkTable</class>
- <name>table14</name>
- <border_width>4</border_width>
- <rows>2</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>2</row_spacing>
- <column_spacing>2</column_spacing>
-
- <widget>
- <class>GtkLabel</class>
- <name>label66</name>
- <label>Su_mmary:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <default_focus_target>recurrence-summary</default_focus_target>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label67</name>
- <label>_Starting date:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>recurrence-summary</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>True</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment40</name>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xscale>0</xscale>
- <yscale>0</yscale>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>Custom</class>
- <name>recurrence-starting-date</name>
- <creation_function>make_date_edit</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Fri, 22 Sep 2000 20:51:38 GMT</last_modification_time>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox55</name>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame36</name>
- <label>Recurrence Rule</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox56</name>
- <border_width>4</border_width>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox56</name>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkRadioButton</class>
- <name>recurrence-none</name>
- <can_focus>True</can_focus>
- <label>No recurrence</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <group>recurrence-radio</group>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkRadioButton</class>
- <name>recurrence-simple</name>
- <can_focus>True</can_focus>
- <label>Simple recurrence</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <group>recurrence-radio</group>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkRadioButton</class>
- <name>recurrence-custom</name>
- <can_focus>True</can_focus>
- <label>Custom recurrence</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <group>recurrence-radio</group>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox57</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkHBox</class>
- <name>recurrence-params</name>
- <homogeneous>False</homogeneous>
- <spacing>2</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label68</name>
- <label>Every</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkSpinButton</class>
- <name>recurrence-interval-value</name>
- <can_focus>True</can_focus>
- <climb_rate>1</climb_rate>
- <digits>0</digits>
- <numeric>True</numeric>
- <update_policy>GTK_UPDATE_ALWAYS</update_policy>
- <snap>False</snap>
- <wrap>False</wrap>
- <value>1</value>
- <lower>1</lower>
- <upper>10000</upper>
- <step>1</step>
- <page>10</page>
- <page_size>10</page_size>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkOptionMenu</class>
- <name>recurrence-interval-unit</name>
- <can_focus>True</can_focus>
- <items>day(s)
-week(s)
-month(s)
-year(s)
-</items>
- <initial_choice>0</initial_choice>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>recurrence-special</name>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xscale>0</xscale>
- <yscale>0</yscale>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>Placeholder</class>
- </widget>
- </widget>
-
- <widget>
- <class>GtkOptionMenu</class>
- <name>recurrence-ending-menu</name>
- <can_focus>True</can_focus>
- <items>for
-until
-forever
-</items>
- <initial_choice>0</initial_choice>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>recurrence-ending-special</name>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xscale>0</xscale>
- <yscale>0</yscale>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>Placeholder</class>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>recurrence-custom-warning-bin</name>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xscale>1</xscale>
- <yscale>1</yscale>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>Placeholder</class>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox59</name>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame37</name>
- <label>Exceptions</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox60</name>
- <border_width>4</border_width>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox57</name>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>recurrence-exception-add</name>
- <can_focus>True</can_focus>
- <label>Add</label>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>recurrence-exception-modify</name>
- <can_focus>True</can_focus>
- <label>Modify</label>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>recurrence-exception-delete</name>
- <can_focus>True</can_focus>
- <label>Delete</label>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox58</name>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>Custom</class>
- <name>recurrence-exception-date</name>
- <creation_function>make_date_edit</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Tue, 16 May 2000 01:42:29 GMT</last_modification_time>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkScrolledWindow</class>
- <name>scrolledwindow14</name>
- <hscrollbar_policy>GTK_POLICY_NEVER</hscrollbar_policy>
- <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy>
- <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
- <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkCList</class>
- <name>recurrence-exception-list</name>
- <can_focus>True</can_focus>
- <columns>1</columns>
- <column_widths>80</column_widths>
- <selection_mode>GTK_SELECTION_BROWSE</selection_mode>
- <show_titles>False</show_titles>
- <shadow_type>GTK_SHADOW_IN</shadow_type>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label69</name>
- <label>label21</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox59</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label70</name>
- <label>Preview</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>recurrence-preview-bin</name>
- <xalign>0</xalign>
- <yalign>0</yalign>
- <xscale>1</xscale>
- <yscale>1</yscale>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>Placeholder</class>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label71</name>
- <label>Recurrence</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
-</widget>
-
-</GTK-Interface>
diff --git a/calendar/gui/event-editor.c b/calendar/gui/event-editor.c
deleted file mode 100644
index c96c94dadd..0000000000
--- a/calendar/gui/event-editor.c
+++ /dev/null
@@ -1,3377 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-/* Evolution calendar - Event editor dialog
- *
- * Copyright (C) 2000 Helix Code, Inc.
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Authors: Miguel de Icaza <miguel@ximian.com>
- * Federico Mena-Quintero <federico@ximian.com>
- * Seth Alves <alves@hungry.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <config.h>
-#include <string.h>
-#include <glade/glade.h>
-#include <gal/widgets/e-unicode.h>
-#include <gal/widgets/e-categories.h>
-#include <libgnomeui/gnome-propertybox.h>
-#include <libgnome/gnome-i18n.h>
-
-#include "calendar-config.h"
-#include "cal-util/timeutil.h"
-#include "dialogs/delete-comp.h"
-#include "dialogs/save-comp.h"
-#include "e-meeting-edit.h"
-#include "e-util/e-dialog-widgets.h"
-#include "event-editor.h"
-#include "tag-calendar.h"
-#include "weekday-picker.h"
-#include "widgets/misc/e-dateedit.h"
-#include "widget-util.h"
-
-enum {BEFORE, AFTER};
-enum {MINUTES, HOURS, DAYS};
-
-/* Reminder maps */
-static const int reminder_action_map[] = {
- CAL_ALARM_DISPLAY,
- CAL_ALARM_AUDIO,
- CAL_ALARM_EMAIL,
- CAL_ALARM_PROCEDURE,
- -1
-};
-
-static const int reminder_value_map[] = {
- MINUTES,
- HOURS,
- DAYS,
- -1
-};
-
-static const int reminder_relative_map[] = {
- BEFORE,
- AFTER,
- -1
-};
-
-static const int reminder_time_map[] = {
- CAL_ALARM_TRIGGER_RELATIVE_START,
- CAL_ALARM_TRIGGER_RELATIVE_END,
- -1
-};
-
-/* Recurrence maps */
-static const int recur_freq_map[] = {
- ICAL_DAILY_RECURRENCE,
- ICAL_WEEKLY_RECURRENCE,
- ICAL_MONTHLY_RECURRENCE,
- ICAL_YEARLY_RECURRENCE,
- -1
-};
-
-enum month_day_options {
- MONTH_DAY_NTH,
- MONTH_DAY_MON,
- MONTH_DAY_TUE,
- MONTH_DAY_WED,
- MONTH_DAY_THU,
- MONTH_DAY_FRI,
- MONTH_DAY_SAT,
- MONTH_DAY_SUN
-};
-
-static const int month_day_options_map[] = {
- MONTH_DAY_NTH,
- MONTH_DAY_MON,
- MONTH_DAY_TUE,
- MONTH_DAY_WED,
- MONTH_DAY_THU,
- MONTH_DAY_FRI,
- MONTH_DAY_SAT,
- MONTH_DAY_SUN,
- -1
-};
-
-/* Row data for the reminders */
-typedef enum {NEW_ALARM, EXISTING_ALARM} ReminderStatus;
-
-typedef struct {
- ReminderStatus status;
- CalComponentAlarm *alarm;
-} ReminderData;
-
-struct _EventEditorPrivate {
- /* Glade XML data */
- GladeXML *xml;
-
- /* Client to use */
- CalClient *client;
-
- /* Calendar object/uid we are editing; this is an internal copy */
- CalComponent *comp;
-
- /* Widgets from the Glade file */
-
- GtkWidget *app;
-
- GtkWidget *general_summary;
-
- GtkWidget *start_time;
- GtkWidget *end_time;
- GtkWidget *all_day_event;
-
- GtkWidget *description;
-
- GtkWidget *classification_public;
- GtkWidget *classification_private;
- GtkWidget *classification_confidential;
-
- GtkWidget *contacts;
- GtkWidget *contacts_btn;
-
- GtkWidget *categories;
- GtkWidget *categories_btn;
-
- GtkWidget *reminder_summary;
- GtkWidget *reminder_starting_date;
-
- GtkWidget *reminder_list;
- GtkWidget *reminder_add;
- GtkWidget *reminder_delete;
-
- GtkWidget *reminder_action;
- GtkWidget *reminder_interval_value;
- GtkWidget *reminder_value_units;
- GtkWidget *reminder_relative;
- GtkWidget *reminder_time;
-
- GtkWidget *recurrence_summary;
- GtkWidget *recurrence_starting_date;
-
- GtkWidget *recurrence_none;
- GtkWidget *recurrence_simple;
- GtkWidget *recurrence_custom;
-
- GtkWidget *recurrence_params;
- GtkWidget *recurrence_interval_value;
- GtkWidget *recurrence_interval_unit;
- GtkWidget *recurrence_special;
- GtkWidget *recurrence_ending_menu;
- GtkWidget *recurrence_ending_special;
- GtkWidget *recurrence_custom_warning_bin;
-
- /* For weekly recurrences, created by hand */
- GtkWidget *recurrence_weekday_picker;
- guint8 recurrence_weekday_day_mask;
- guint8 recurrence_weekday_blocked_day_mask;
-
- /* For monthly recurrences, created by hand */
- GtkWidget *recurrence_month_index_spin;
- int recurrence_month_index;
-
- GtkWidget *recurrence_month_day_menu;
- enum month_day_options recurrence_month_day;
-
- /* For ending date, created by hand */
- GtkWidget *recurrence_ending_date_edit;
- time_t recurrence_ending_date;
-
- /* For ending count of occurrences, created by hand */
- GtkWidget *recurrence_ending_count_spin;
- int recurrence_ending_count;
-
- /* More widgets from the Glade file */
-
- GtkWidget *recurrence_exception_date;
- GtkWidget *recurrence_exception_list;
- GtkWidget *recurrence_exception_add;
- GtkWidget *recurrence_exception_modify;
- GtkWidget *recurrence_exception_delete;
-
- GtkWidget *recurrence_preview_bin;
-
- /* For the recurrence preview, the actual widget */
- GtkWidget *recurrence_preview_calendar;
-
- /* Call event_editor_set_changed() to set this to TRUE when any field
- in the dialog is changed. When the user closes the dialog we will
- prompt to save changes. */
- gboolean changed;
-};
-
-
-
-static void event_editor_class_init (EventEditorClass *class);
-static void event_editor_init (EventEditor *ee);
-static void event_editor_destroy (GtkObject *object);
-
-static GtkObjectClass *parent_class;
-
-
-static void append_reminder (EventEditor *ee, CalComponentAlarm *alarm, ReminderStatus status);
-static void append_exception (EventEditor *ee, time_t t);
-static void check_all_day (EventEditor *ee);
-static void set_all_day (GtkWidget *toggle, EventEditor *ee);
-static void date_changed_cb (EDateEdit *dedit, gpointer data);
-static void preview_recur (EventEditor *ee);
-static void recur_to_comp_object (EventEditor *ee, CalComponent *comp);
-static void reminder_to_comp_object (EventEditor *ee, CalComponent *comp);
-static void reminder_add_cb (GtkWidget *widget, EventEditor *ee);
-static void reminder_delete_cb (GtkWidget *widget, EventEditor *ee);
-static void recurrence_exception_add_cb (GtkWidget *widget, EventEditor *ee);
-static void recurrence_exception_modify_cb (GtkWidget *widget, EventEditor *ee);
-static void recurrence_exception_delete_cb (GtkWidget *widget, EventEditor *ee);
-static void recurrence_exception_select_row_cb (GtkCList *clist, gint row, gint col, GdkEvent *event,
- gpointer data);
-static void field_changed (GtkWidget *widget,
- EventEditor *ee);
-static void event_editor_set_changed (EventEditor *ee,
- gboolean changed);
-static gboolean prompt_to_save_changes (EventEditor *ee);
-static void categories_clicked (GtkWidget *button, EventEditor *ee);
-
-
-
-/**
- * event_editor_get_type:
- *
- * Registers the #EventEditor class if necessary, and returns the type ID
- * associated to it.
- *
- * Return value: The type ID of the #EventEditor class.
- **/
-GtkType
-event_editor_get_type (void)
-{
- static GtkType event_editor_type = 0;
-
- if (!event_editor_type) {
- static const GtkTypeInfo event_editor_info = {
- "EventEditor",
- sizeof (EventEditor),
- sizeof (EventEditorClass),
- (GtkClassInitFunc) event_editor_class_init,
- (GtkObjectInitFunc) event_editor_init,
- NULL, /* reserved_1 */
- NULL, /* reserved_2 */
- (GtkClassInitFunc) NULL
- };
-
- event_editor_type = gtk_type_unique (GTK_TYPE_OBJECT, &event_editor_info);
- }
-
- return event_editor_type;
-}
-
-/* Class initialization function for the event editor */
-static void
-event_editor_class_init (EventEditorClass *class)
-{
- GtkObjectClass *object_class;
-
- object_class = (GtkObjectClass *) class;
-
- parent_class = gtk_type_class (GTK_TYPE_OBJECT);
-
- object_class->destroy = event_editor_destroy;
-}
-
-/* Object initialization function for the event editor */
-static void
-event_editor_init (EventEditor *ee)
-{
- EventEditorPrivate *priv;
-
- priv = g_new0 (EventEditorPrivate, 1);
- ee->priv = priv;
-
- event_editor_set_changed (ee, FALSE);
-}
-
-/* Frees the rows and the row data in the recurrence exceptions GtkCList */
-static void
-free_exception_clist_data (GtkCList *clist)
-{
- int i;
-
- for (i = 0; i < clist->rows; i++) {
- gpointer data;
-
- data = gtk_clist_get_row_data (clist, i);
- g_free (data);
- gtk_clist_set_row_data (clist, i, NULL);
- }
-
- gtk_clist_clear (clist);
-}
-
-/* Destroy handler for the event editor */
-static void
-event_editor_destroy (GtkObject *object)
-{
- EventEditor *ee;
- EventEditorPrivate *priv;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (IS_EVENT_EDITOR (object));
-
- ee = EVENT_EDITOR (object);
- priv = ee->priv;
-
- free_exception_clist_data (GTK_CLIST (priv->recurrence_exception_list));
-
- if (priv->app) {
- gtk_signal_disconnect_by_data (GTK_OBJECT (priv->app), ee);
- gtk_widget_destroy (priv->app);
- priv->app = NULL;
- }
-
- if (priv->comp) {
- gtk_object_unref (GTK_OBJECT (priv->comp));
- priv->comp = NULL;
- }
-
- if (priv->client) {
- gtk_signal_disconnect_by_data (GTK_OBJECT (priv->client), ee);
- gtk_object_unref (GTK_OBJECT (priv->client));
- priv->client = NULL;
- }
-
- if (priv->xml) {
- gtk_object_unref (GTK_OBJECT (priv->xml));
- priv->xml = NULL;
- }
-
- g_free (priv);
- ee->priv = NULL;
-
- if (GTK_OBJECT_CLASS (parent_class)->destroy)
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-/* Creates an appropriate title for the event editor dialog */
-static char *
-make_title_from_comp (CalComponent *comp)
-{
- char *title;
- const char *type_string;
- CalComponentVType type;
- CalComponentText text;
-
- if (!comp)
- return g_strdup (_("Edit Appointment"));
-
- type = cal_component_get_vtype (comp);
- switch (type) {
- case CAL_COMPONENT_EVENT:
- type_string = _("Appointment - %s");
- break;
- case CAL_COMPONENT_TODO:
- type_string = _("Task - %s");
- break;
- case CAL_COMPONENT_JOURNAL:
- type_string = _("Journal entry - %s");
- break;
- default:
- g_message ("make_title_from_comp(): Cannot handle object of type %d", type);
- return NULL;
- }
-
- cal_component_get_summary (comp, &text);
- if (text.value) {
- char *summary;
- summary = e_utf8_to_locale_string (text.value);
- title = g_strdup_printf (type_string, summary);
- g_free (summary);
- } else
- title = g_strdup_printf (type_string, _("No summary"));
-
- return title;
-}
-
-/* Sets the event editor's window title from a calendar component */
-static void
-set_title_from_comp (EventEditor *ee, CalComponent *comp)
-{
- EventEditorPrivate *priv = ee->priv;
- char *title;
-
- title = make_title_from_comp (comp);
- gtk_window_set_title (GTK_WINDOW (priv->app), title);
- g_free (title);
-}
-
-/* Callback used when the recurrence weekday picker changes */
-static void
-recur_weekday_picker_changed_cb (WeekdayPicker *wp, gpointer data)
-{
- EventEditor *ee;
-
- ee = EVENT_EDITOR (data);
- event_editor_set_changed (ee, TRUE);
- preview_recur (ee);
-}
-
-/* Creates the special contents for weekly recurrences */
-static void
-make_recur_weekly_special (EventEditor *ee)
-{
- EventEditorPrivate *priv;
- GtkWidget *hbox;
- GtkWidget *label;
- WeekdayPicker *wp;
-
- priv = ee->priv;
-
- g_assert (GTK_BIN (priv->recurrence_special)->child == NULL);
- g_assert (priv->recurrence_weekday_picker == NULL);
-
- /* Create the widgets */
-
- hbox = gtk_hbox_new (FALSE, 2);
- gtk_container_add (GTK_CONTAINER (priv->recurrence_special), hbox);
-
- label = gtk_label_new (_("on"));
- gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-
- wp = WEEKDAY_PICKER (weekday_picker_new ());
-
- priv->recurrence_weekday_picker = GTK_WIDGET (wp);
- gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (wp), FALSE, FALSE, 0);
-
- gtk_widget_show_all (hbox);
-
- /* Set the weekdays */
-
- weekday_picker_set_week_start_day (wp, calendar_config_get_week_start_day ());
- weekday_picker_set_days (wp, priv->recurrence_weekday_day_mask);
- weekday_picker_set_blocked_days (wp, priv->recurrence_weekday_blocked_day_mask);
-
- gtk_signal_connect (GTK_OBJECT (wp), "changed",
- GTK_SIGNAL_FUNC (recur_weekday_picker_changed_cb), ee);
-}
-
-/* Creates the option menu for the monthly recurrence days */
-static GtkWidget *
-make_recur_month_menu (void)
-{
- static const char *options[] = {
- N_("day"),
- N_("Monday"),
- N_("Tuesday"),
- N_("Wednesday"),
- N_("Thursday"),
- N_("Friday"),
- N_("Saturday"),
- N_("Sunday")
- };
-
- GtkWidget *menu;
- GtkWidget *omenu;
- int i;
-
- menu = gtk_menu_new ();
-
- for (i = 0; i < sizeof (options) / sizeof (options[0]); i++) {
- GtkWidget *item;
-
- item = gtk_menu_item_new_with_label (_(options[i]));
- gtk_menu_append (GTK_MENU (menu), item);
- gtk_widget_show (item);
- }
-
- omenu = gtk_option_menu_new ();
- gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
-
- return omenu;
-}
-
-/* For monthly recurrences, changes the valid range of the recurrence day index
- * spin button; e.g. month days are 1-31 while the valid range for a Sunday is
- * the 1st through 5th of the month.
- */
-static void
-adjust_day_index_spin (EventEditor *ee)
-{
- EventEditorPrivate *priv;
- GtkAdjustment *adj;
- enum month_day_options month_day;
-
- priv = ee->priv;
-
- g_assert (priv->recurrence_month_day_menu != NULL);
- g_assert (GTK_IS_OPTION_MENU (priv->recurrence_month_day_menu));
- g_assert (priv->recurrence_month_index_spin != NULL);
- g_assert (GTK_IS_SPIN_BUTTON (priv->recurrence_month_index_spin));
-
- month_day = e_dialog_option_menu_get (priv->recurrence_month_day_menu, month_day_options_map);
-
- adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->recurrence_month_index_spin));
-
- switch (month_day) {
- case MONTH_DAY_NTH:
- adj->upper = 31;
- gtk_adjustment_changed (adj);
- break;
-
- case MONTH_DAY_MON:
- case MONTH_DAY_TUE:
- case MONTH_DAY_WED:
- case MONTH_DAY_THU:
- case MONTH_DAY_FRI:
- case MONTH_DAY_SAT:
- case MONTH_DAY_SUN:
- adj->upper = 5;
- gtk_adjustment_changed (adj);
-
- if (adj->value > 5) {
- adj->value = 5;
- gtk_adjustment_value_changed (adj);
- }
-
- break;
-
- default:
- g_assert_not_reached ();
- }
-}
-
-/* Callback used when the monthly day selection menu changes. We need to change
- * the valid range of the day index spin button; e.g. days are 1-31 while a
- * Sunday is the 1st through 5th.
- */
-static void
-month_day_menu_selection_done_cb (GtkMenuShell *menu_shell, gpointer data)
-{
- EventEditor *ee;
-
- ee = EVENT_EDITOR (data);
- adjust_day_index_spin (ee);
- event_editor_set_changed (ee, TRUE);
- preview_recur (ee);
-}
-
-/* Callback used when the month index value changes. */
-static void
-recur_month_index_value_changed_cb (GtkAdjustment *adj, gpointer data)
-{
- EventEditor *ee;
-
- ee = EVENT_EDITOR (data);
- event_editor_set_changed (ee, TRUE);
- preview_recur (ee);
-}
-
-/* Creates the special contents for monthly recurrences */
-static void
-make_recur_monthly_special (EventEditor *ee)
-{
- EventEditorPrivate *priv;
- GtkWidget *hbox;
- GtkWidget *label;
- GtkAdjustment *adj;
- GtkWidget *menu;
-
- priv = ee->priv;
-
- g_assert (GTK_BIN (priv->recurrence_special)->child == NULL);
- g_assert (priv->recurrence_month_index_spin == NULL);
- g_assert (priv->recurrence_month_day_menu == NULL);
-
- /* Create the widgets */
-
- hbox = gtk_hbox_new (FALSE, 2);
- gtk_container_add (GTK_CONTAINER (priv->recurrence_special), hbox);
-
- label = gtk_label_new (_("on the"));
- gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-
- adj = GTK_ADJUSTMENT (gtk_adjustment_new (1, 1, 31, 1, 10, 10));
- priv->recurrence_month_index_spin = gtk_spin_button_new (adj, 1, 0);
- gtk_box_pack_start (GTK_BOX (hbox), priv->recurrence_month_index_spin, FALSE, FALSE, 0);
-
- label = gtk_label_new (_("th"));
- gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-
- priv->recurrence_month_day_menu = make_recur_month_menu ();
- gtk_box_pack_start (GTK_BOX (hbox), priv->recurrence_month_day_menu, FALSE, FALSE, 0);
-
- gtk_widget_show_all (hbox);
-
- /* Set the options */
-
- e_dialog_spin_set (priv->recurrence_month_index_spin, priv->recurrence_month_index);
- e_dialog_option_menu_set (priv->recurrence_month_day_menu,
- priv->recurrence_month_day,
- month_day_options_map);
- adjust_day_index_spin (ee);
-
- gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
- GTK_SIGNAL_FUNC (recur_month_index_value_changed_cb), ee);
-
- menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->recurrence_month_day_menu));
- gtk_signal_connect (GTK_OBJECT (menu), "selection_done",
- GTK_SIGNAL_FUNC (month_day_menu_selection_done_cb), ee);
-}
-
-/* Changes the recurrence-special widget to match the interval units.
- *
- * For daily recurrences: nothing.
- * For weekly recurrences: weekday selector.
- * For monthly recurrences: "on the" <nth> [day, Weekday]
- * For yearly recurrences: nothing.
- */
-static void
-make_recurrence_special (EventEditor *ee)
-{
- EventEditorPrivate *priv;
- icalrecurrencetype_frequency frequency;
-
- priv = ee->priv;
-
- if (GTK_BIN (priv->recurrence_special)->child != NULL) {
- gtk_widget_destroy (GTK_BIN (priv->recurrence_special)->child);
-
- priv->recurrence_weekday_picker = NULL;
- priv->recurrence_month_index_spin = NULL;
- priv->recurrence_month_day_menu = NULL;
- }
-
- frequency = e_dialog_option_menu_get (priv->recurrence_interval_unit, recur_freq_map);
-
- switch (frequency) {
- case ICAL_DAILY_RECURRENCE:
- gtk_widget_hide (priv->recurrence_special);
- break;
-
- case ICAL_WEEKLY_RECURRENCE:
- make_recur_weekly_special (ee);
- gtk_widget_show (priv->recurrence_special);
- break;
-
- case ICAL_MONTHLY_RECURRENCE:
- make_recur_monthly_special (ee);
- gtk_widget_show (priv->recurrence_special);
- break;
-
- case ICAL_YEARLY_RECURRENCE:
- gtk_widget_hide (priv->recurrence_special);
- break;
-
- default:
- g_assert_not_reached ();
- }
-}
-
-/* Callback used when the ending-until date editor changes */
-static void
-recur_ending_until_changed_cb (EDateEdit *de, gpointer data)
-{
- EventEditor *ee;
-
- ee = EVENT_EDITOR (data);
- event_editor_set_changed (ee, TRUE);
- preview_recur (ee);
-}
-
-/* Creates the special contents for "ending until" (end date) recurrences */
-static void
-make_recur_ending_until_special (EventEditor *ee)
-{
- EventEditorPrivate *priv;
- EDateEdit *de;
-
- priv = ee->priv;
-
- g_assert (GTK_BIN (priv->recurrence_ending_special)->child == NULL);
- g_assert (priv->recurrence_ending_date_edit == NULL);
-
- /* Create the widget */
-
- priv->recurrence_ending_date_edit = date_edit_new (TRUE, FALSE);
- de = E_DATE_EDIT (priv->recurrence_ending_date_edit);
-
- gtk_container_add (GTK_CONTAINER (priv->recurrence_ending_special), GTK_WIDGET (de));
- gtk_widget_show_all (GTK_WIDGET (de));
-
- /* Set the value */
-
- e_date_edit_set_time (de, priv->recurrence_ending_date);
-
- gtk_signal_connect (GTK_OBJECT (de), "changed",
- GTK_SIGNAL_FUNC (recur_ending_until_changed_cb), ee);
-}
-
-/* Callback used when the ending-count value changes */
-static void
-recur_ending_count_value_changed_cb (GtkAdjustment *adj, gpointer data)
-{
- EventEditor *ee;
-
- ee = EVENT_EDITOR (data);
- event_editor_set_changed (ee, TRUE);
- preview_recur (ee);
-}
-
-/* Creates the special contents for the occurrence count case */
-static void
-make_recur_ending_count_special (EventEditor *ee)
-{
- EventEditorPrivate *priv;
- GtkWidget *hbox;
- GtkWidget *label;
- GtkAdjustment *adj;
-
- priv = ee->priv;
-
- g_assert (GTK_BIN (priv->recurrence_ending_special)->child == NULL);
- g_assert (priv->recurrence_ending_count_spin == NULL);
-
- /* Create the widgets */
-
- hbox = gtk_hbox_new (FALSE, 2);
- gtk_container_add (GTK_CONTAINER (priv->recurrence_ending_special), hbox);
-
- adj = GTK_ADJUSTMENT (gtk_adjustment_new (1, 1, 10000, 1, 10, 10));
- priv->recurrence_ending_count_spin = gtk_spin_button_new (adj, 1, 0);
- gtk_box_pack_start (GTK_BOX (hbox), priv->recurrence_ending_count_spin, FALSE, FALSE, 0);
-
- label = gtk_label_new (_("occurrences"));
- gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-
- gtk_widget_show_all (hbox);
-
- /* Set the values */
-
- e_dialog_spin_set (priv->recurrence_ending_count_spin,
- priv->recurrence_ending_count);
-
- gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
- GTK_SIGNAL_FUNC (recur_ending_count_value_changed_cb), ee);
-}
-
-enum ending_type {
- ENDING_FOR,
- ENDING_UNTIL,
- ENDING_FOREVER
-};
-
-static const int ending_types_map[] = {
- ENDING_FOR,
- ENDING_UNTIL,
- ENDING_FOREVER,
- -1
-};
-
-/* Changes the recurrence-ending-special widget to match the ending date option.
- *
- * For: <n> [days, weeks, months, years, occurrences]
- * Until: <date selector>
- * Forever: nothing.
- */
-static void
-make_recurrence_ending_special (EventEditor *ee)
-{
- EventEditorPrivate *priv;
- enum ending_type ending_type;
-
- priv = ee->priv;
-
- if (GTK_BIN (priv->recurrence_ending_special)->child != NULL) {
- gtk_widget_destroy (GTK_BIN (priv->recurrence_ending_special)->child);
-
- priv->recurrence_ending_date_edit = NULL;
- priv->recurrence_ending_count_spin = NULL;
- }
-
- ending_type = e_dialog_option_menu_get (priv->recurrence_ending_menu, ending_types_map);
-
- switch (ending_type) {
- case ENDING_FOR:
- make_recur_ending_count_special (ee);
- gtk_widget_show (priv->recurrence_ending_special);
- break;
-
- case ENDING_UNTIL:
- make_recur_ending_until_special (ee);
- gtk_widget_show (priv->recurrence_ending_special);
- break;
-
- case ENDING_FOREVER:
- gtk_widget_hide (priv->recurrence_ending_special);
- break;
-
- default:
- g_assert_not_reached ();
- }
-}
-
-enum recur_type {
- RECUR_NONE,
- RECUR_SIMPLE,
- RECUR_CUSTOM
-};
-
-static const int recur_type_map[] = {
- RECUR_NONE,
- RECUR_SIMPLE,
- RECUR_CUSTOM,
- -1
-};
-
-/* Sensitizes the recurrence widgets based on the state of the recurrence type
- * radio group.
- */
-static void
-sensitize_recur_widgets (EventEditor *ee)
-{
- EventEditorPrivate *priv;
- enum recur_type type;
- GtkWidget *label;
-
- priv = ee->priv;
-
- type = e_dialog_radio_get (priv->recurrence_none, recur_type_map);
-
- if (GTK_BIN (priv->recurrence_custom_warning_bin)->child)
- gtk_widget_destroy (GTK_BIN (priv->recurrence_custom_warning_bin)->child);
-
- switch (type) {
- case RECUR_NONE:
- gtk_widget_set_sensitive (priv->recurrence_params, FALSE);
- gtk_widget_show (priv->recurrence_params);
- gtk_widget_hide (priv->recurrence_custom_warning_bin);
- break;
-
- case RECUR_SIMPLE:
- gtk_widget_set_sensitive (priv->recurrence_params, TRUE);
- gtk_widget_show (priv->recurrence_params);
- gtk_widget_hide (priv->recurrence_custom_warning_bin);
- break;
-
- case RECUR_CUSTOM:
- gtk_widget_set_sensitive (priv->recurrence_params, FALSE);
- gtk_widget_hide (priv->recurrence_params);
-
- label = gtk_label_new (_("This appointment contains recurrences that Evolution "
- "cannot edit."));
- gtk_container_add (GTK_CONTAINER (priv->recurrence_custom_warning_bin), label);
- gtk_widget_show_all (priv->recurrence_custom_warning_bin);
- break;
-
- default:
- g_assert_not_reached ();
- }
-}
-
-/* Callback used when one of the recurrence type radio buttons is toggled. We
- * enable or the recurrence parameters.
- */
-static void
-recurrence_type_toggled_cb (GtkToggleButton *toggle, gpointer data)
-{
- EventEditor *ee;
-
- ee = EVENT_EDITOR (data);
-
- event_editor_set_changed (ee, TRUE);
-
- if (toggle->active) {
- sensitize_recur_widgets (ee);
- preview_recur (ee);
- }
-}
-
-/* Callback used when the recurrence interval value spin button changes. */
-static void
-recur_interval_value_changed_cb (GtkAdjustment *adj, gpointer data)
-{
- EventEditor *ee;
-
- ee = EVENT_EDITOR (data);
- event_editor_set_changed (ee, TRUE);
- preview_recur (ee);
-}
-
-/* Callback used when the recurrence interval option menu changes. We need to
- * change the contents of the recurrence special widget.
- */
-static void
-recur_interval_selection_done_cb (GtkMenuShell *menu_shell, gpointer data)
-{
- EventEditor *ee;
-
- ee = EVENT_EDITOR (data);
- event_editor_set_changed (ee, TRUE);
- make_recurrence_special (ee);
- preview_recur (ee);
-}
-
-/* Callback used when the recurrence ending option menu changes. We need to
- * change the contents of the ending special widget.
- */
-static void
-recur_ending_selection_done_cb (GtkMenuShell *menu_shell, gpointer data)
-{
- EventEditor *ee;
-
- ee = EVENT_EDITOR (data);
- event_editor_set_changed (ee, TRUE);
- make_recurrence_ending_special (ee);
- preview_recur (ee);
-}
-
-/* Gets the widgets from the XML file and returns if they are all available.
- * For the widgets whose values can be simply set with e-dialog-utils, it does
- * that as well.
- */
-static gboolean
-get_widgets (EventEditor *ee)
-{
- EventEditorPrivate *priv;
-
- priv = ee->priv;
-
-#define GW(name) glade_xml_get_widget (priv->xml, name)
-
- priv->app = GW ("event-editor-dialog");
-
- priv->general_summary = GW ("general-summary");
-
- priv->start_time = GW ("start-time");
- priv->end_time = GW ("end-time");
- priv->all_day_event = GW ("all-day-event");
-
- priv->description = GW ("description");
-
- priv->classification_public = GW ("classification-public");
- priv->classification_private = GW ("classification-private");
- priv->classification_confidential = GW ("classification-confidential");
-
- priv->contacts_btn = GW ("contacts-button");
- priv->contacts = GW ("contacts");
-
- priv->categories_btn = GW ("categories-button");
- priv->categories = GW ("categories");
-
- priv->reminder_summary = GW ("reminder-summary");
- priv->reminder_starting_date = GW ("reminder-starting-date");
-
- priv->reminder_list = GW ("reminder-list");
- priv->reminder_add = GW ("reminder-add");
- priv->reminder_delete = GW ("reminder-delete");
-
- priv->reminder_action = GW ("reminder-action");
- priv->reminder_interval_value = GW ("reminder-interval-value");
- priv->reminder_value_units = GW ("reminder-value-units");
- priv->reminder_relative = GW ("reminder-relative");
- priv->reminder_time = GW ("reminder-time");
-
- priv->recurrence_summary = GW ("recurrence-summary");
- priv->recurrence_starting_date = GW ("recurrence-starting-date");
-
- priv->recurrence_none = GW ("recurrence-none");
- priv->recurrence_simple = GW ("recurrence-simple");
- priv->recurrence_custom = GW ("recurrence-custom");
- priv->recurrence_params = GW ("recurrence-params");
-
- priv->recurrence_interval_value = GW ("recurrence-interval-value");
- priv->recurrence_interval_unit = GW ("recurrence-interval-unit");
- priv->recurrence_special = GW ("recurrence-special");
- priv->recurrence_ending_menu = GW ("recurrence-ending-menu");
- priv->recurrence_ending_special = GW ("recurrence-ending-special");
- priv->recurrence_custom_warning_bin = GW ("recurrence-custom-warning-bin");
-
- priv->recurrence_exception_date = GW ("recurrence-exception-date");
- priv->recurrence_exception_list = GW ("recurrence-exception-list");
- priv->recurrence_exception_add = GW ("recurrence-exception-add");
- priv->recurrence_exception_modify = GW ("recurrence-exception-modify");
- priv->recurrence_exception_delete = GW ("recurrence-exception-delete");
-
- priv->recurrence_preview_bin = GW ("recurrence-preview-bin");
-
-#undef GW
-
- return (priv->app
- && priv->general_summary
- && priv->start_time
- && priv->end_time
- && priv->all_day_event
- && priv->description
- && priv->classification_public
- && priv->classification_private
- && priv->classification_confidential
- && priv->contacts_btn
- && priv->contacts
- && priv->categories_btn
- && priv->categories
- && priv->reminder_summary
- && priv->reminder_starting_date
- && priv->reminder_list
- && priv->reminder_add
- && priv->reminder_delete
- && priv->reminder_action
- && priv->reminder_interval_value
- && priv->reminder_value_units
- && priv->reminder_relative
- && priv->reminder_time
- && priv->recurrence_summary
- && priv->recurrence_starting_date
- && priv->recurrence_none
- && priv->recurrence_simple
- && priv->recurrence_custom
- && priv->recurrence_params
- && priv->recurrence_interval_value
- && priv->recurrence_interval_unit
- && priv->recurrence_special
- && priv->recurrence_ending_menu
- && priv->recurrence_ending_special
- && priv->recurrence_custom_warning_bin
- && priv->recurrence_exception_date
- && priv->recurrence_exception_list
- && priv->recurrence_exception_add
- && priv->recurrence_exception_modify
- && priv->recurrence_exception_delete
- && priv->recurrence_preview_bin);
-}
-
-/* Syncs the contents of two entry widgets, while blocking signals from each
- * other.
- */
-static void
-sync_entries (EventEditor *ee, GtkEditable *source, GtkEditable *dest)
-{
- char *str;
-
- gtk_signal_handler_block_by_data (GTK_OBJECT (dest), ee);
-
- str = gtk_editable_get_chars (source, 0, -1);
- gtk_entry_set_text (GTK_ENTRY (dest), str);
- g_free (str);
-
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (dest), ee);
-}
-
-/* Syncs the contents of two date editor widgets, while blocking signals on the
- * specified data.
- */
-static void
-sync_date_edits (EventEditor *ee, EDateEdit *source, EDateEdit *dest)
-{
- time_t t;
-
- gtk_signal_handler_block_by_data (GTK_OBJECT (dest), ee);
-
- t = e_date_edit_get_time (source);
- e_date_edit_set_time (dest, t);
-
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (dest), ee);
-}
-
-/* Callback used when one of the general or recurrence summary entries change;
- * we sync the other entry to it.
- */
-static void
-summary_changed_cb (GtkEditable *editable, gpointer data)
-{
- EventEditor *ee;
- EventEditorPrivate *priv;
-
- ee = EVENT_EDITOR (data);
- priv = ee->priv;
-
- if (editable != GTK_EDITABLE (priv->general_summary))
- sync_entries (ee, editable, GTK_EDITABLE (priv->general_summary));
- if (editable != GTK_EDITABLE (priv->reminder_summary))
- sync_entries (ee, editable, GTK_EDITABLE (priv->reminder_summary));
- if (editable != GTK_EDITABLE (priv->recurrence_summary))
- sync_entries (ee, editable, GTK_EDITABLE (priv->recurrence_summary));
-}
-
-/* Callback used when one of the general or recurrence starting date widgets
- * change; we sync the other date editor to it.
- */
-static void
-start_date_changed_cb (EDateEdit *de, gpointer data)
-{
- EventEditor *ee;
- EventEditorPrivate *priv;
-
- ee = EVENT_EDITOR (data);
- priv = ee->priv;
-
- if (de != E_DATE_EDIT (priv->start_time))
- sync_date_edits (ee,de, E_DATE_EDIT (priv->start_time));
- if (de != E_DATE_EDIT (priv->reminder_starting_date))
- sync_date_edits (ee, de, E_DATE_EDIT (priv->reminder_starting_date));
- if (de != E_DATE_EDIT (priv->recurrence_starting_date))
- sync_date_edits (ee, de, E_DATE_EDIT (priv->recurrence_starting_date));
-}
-
-/* Callback used when the displayed date range in the recurrence preview
- * calendar changes.
- */
-static void
-recur_preview_date_range_changed_cb (ECalendarItem *item, gpointer data)
-{
- EventEditor *ee;
-
- ee = EVENT_EDITOR (data);
- preview_recur (ee);
-}
-
-/* Hooks the widget signals */
-static void
-init_widgets (EventEditor *ee)
-{
- EventEditorPrivate *priv;
- GtkWidget *menu;
- GtkAdjustment *adj;
- ECalendar *ecal;
-
- priv = ee->priv;
-
- /* Summary in the main, reminder and recurrence pages */
- gtk_signal_connect (GTK_OBJECT (priv->general_summary), "changed",
- GTK_SIGNAL_FUNC (summary_changed_cb), ee);
- gtk_signal_connect (GTK_OBJECT (priv->reminder_summary), "changed",
- GTK_SIGNAL_FUNC (summary_changed_cb), ee);
- gtk_signal_connect (GTK_OBJECT (priv->recurrence_summary), "changed",
- GTK_SIGNAL_FUNC (summary_changed_cb), ee);
-
- /* Categories button */
- gtk_signal_connect (GTK_OBJECT (priv->categories_btn), "clicked",
- GTK_SIGNAL_FUNC (categories_clicked), ee);
-
- /* Start dates in the main and recurrence pages */
-
- gtk_signal_connect (GTK_OBJECT (priv->start_time), "changed",
- GTK_SIGNAL_FUNC (start_date_changed_cb), ee);
- gtk_signal_connect (GTK_OBJECT (priv->reminder_starting_date), "changed",
- GTK_SIGNAL_FUNC (start_date_changed_cb), ee);
- gtk_signal_connect (GTK_OBJECT (priv->recurrence_starting_date), "changed",
- GTK_SIGNAL_FUNC (start_date_changed_cb), ee);
-
- /* Start and end times */
-
- gtk_signal_connect (GTK_OBJECT (priv->start_time), "changed",
- GTK_SIGNAL_FUNC (date_changed_cb), ee);
- gtk_signal_connect (GTK_OBJECT (priv->end_time), "changed",
- GTK_SIGNAL_FUNC (date_changed_cb), ee);
-
- gtk_signal_connect (GTK_OBJECT (priv->all_day_event), "toggled",
- GTK_SIGNAL_FUNC (set_all_day), ee);
-
- /* Reminder buttons */
-
- gtk_signal_connect (GTK_OBJECT (priv->reminder_add), "clicked",
- GTK_SIGNAL_FUNC (reminder_add_cb), ee);
- gtk_signal_connect (GTK_OBJECT (priv->reminder_delete), "clicked",
- GTK_SIGNAL_FUNC (reminder_delete_cb), ee);
-
- /* Recurrence preview */
-
- priv->recurrence_preview_calendar = e_calendar_new ();
- ecal = E_CALENDAR (priv->recurrence_preview_calendar);
- gtk_signal_connect (GTK_OBJECT (ecal->calitem), "date_range_changed",
- GTK_SIGNAL_FUNC (recur_preview_date_range_changed_cb), ee);
- calendar_config_configure_e_calendar (ecal);
- e_calendar_item_set_max_days_sel (ecal->calitem, 0);
- gtk_container_add (GTK_CONTAINER (priv->recurrence_preview_bin),
- priv->recurrence_preview_calendar);
- gtk_widget_show (priv->recurrence_preview_calendar);
-
- /* Recurrence types */
-
- gtk_signal_connect (GTK_OBJECT (priv->recurrence_none), "toggled",
- GTK_SIGNAL_FUNC (recurrence_type_toggled_cb), ee);
- gtk_signal_connect (GTK_OBJECT (priv->recurrence_simple), "toggled",
- GTK_SIGNAL_FUNC (recurrence_type_toggled_cb), ee);
- gtk_signal_connect (GTK_OBJECT (priv->recurrence_custom), "toggled",
- GTK_SIGNAL_FUNC (recurrence_type_toggled_cb), ee);
-
- /* Recurrence interval */
-
- adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->recurrence_interval_value));
- gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
- GTK_SIGNAL_FUNC (recur_interval_value_changed_cb), ee);
-
- /* Recurrence units */
-
- menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->recurrence_interval_unit));
- gtk_signal_connect (GTK_OBJECT (menu), "selection_done",
- GTK_SIGNAL_FUNC (recur_interval_selection_done_cb), ee);
-
- /* Recurrence ending */
-
- menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->recurrence_ending_menu));
- gtk_signal_connect (GTK_OBJECT (menu), "selection_done",
- GTK_SIGNAL_FUNC (recur_ending_selection_done_cb), ee);
-
- /* Exception buttons */
-
- gtk_signal_connect (GTK_OBJECT (priv->recurrence_exception_add), "clicked",
- GTK_SIGNAL_FUNC (recurrence_exception_add_cb), ee);
- gtk_signal_connect (GTK_OBJECT (priv->recurrence_exception_modify), "clicked",
- GTK_SIGNAL_FUNC (recurrence_exception_modify_cb), ee);
- gtk_signal_connect (GTK_OBJECT (priv->recurrence_exception_delete), "clicked",
- GTK_SIGNAL_FUNC (recurrence_exception_delete_cb), ee);
-
- /* Selections in the exceptions list */
-
- gtk_signal_connect (GTK_OBJECT (priv->recurrence_exception_list), "select_row",
- GTK_SIGNAL_FUNC (recurrence_exception_select_row_cb), ee);
-
- /*
- * Connect the default signal handler to use to make sure the "changed"
- * field gets set whenever a field is changed.
- */
-
- /* Appointment Page */
- gtk_signal_connect (GTK_OBJECT (priv->general_summary), "changed",
- GTK_SIGNAL_FUNC (field_changed), ee);
- gtk_signal_connect (GTK_OBJECT (priv->description), "changed",
- GTK_SIGNAL_FUNC (field_changed), ee);
- gtk_signal_connect (GTK_OBJECT (priv->classification_public), "toggled",
- GTK_SIGNAL_FUNC (field_changed), ee);
- gtk_signal_connect (GTK_OBJECT (priv->classification_private), "toggled",
- GTK_SIGNAL_FUNC (field_changed), ee);
- gtk_signal_connect (GTK_OBJECT (priv->classification_confidential), "toggled",
- GTK_SIGNAL_FUNC (field_changed), ee);
- gtk_signal_connect (GTK_OBJECT (priv->categories), "changed",
- GTK_SIGNAL_FUNC (field_changed), ee);
-
- /* FIXME: we do not support these fields yet, so we disable them */
-
- gtk_widget_set_sensitive (priv->contacts_btn, FALSE);
- gtk_widget_set_sensitive (priv->contacts, FALSE);
-}
-
-static const int classification_map[] = {
- CAL_COMPONENT_CLASS_PUBLIC,
- CAL_COMPONENT_CLASS_PRIVATE,
- CAL_COMPONENT_CLASS_CONFIDENTIAL,
- -1
-};
-
-static const int month_pos_map[] = { 0, 1, 2, 3, 4, -1 };
-static const int weekday_map[] = { 0, 1, 2, 3, 4, 5, 6, -1 };
-
-/* Fills the widgets with default values */
-static void
-clear_widgets (EventEditor *ee)
-{
- EventEditorPrivate *priv;
- time_t now;
- GtkAdjustment *adj;
- GtkWidget *menu;
-
- priv = ee->priv;
-
- now = time (NULL);
-
- /* Summary, description */
-
- e_dialog_editable_set (priv->general_summary, NULL); /* will also change recur summary */
- e_dialog_editable_set (priv->description, NULL);
-
- /* Start and end times */
-
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_time), ee);
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->end_time), ee);
-
- e_date_edit_set_time (E_DATE_EDIT (priv->start_time), now); /* will set recur start too */
- e_date_edit_set_time (E_DATE_EDIT (priv->end_time), now);
-
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->start_time), ee);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->end_time), ee);
-
- check_all_day (ee);
-
- /* Classification */
-
- e_dialog_radio_set (priv->classification_public,
- CAL_COMPONENT_CLASS_PRIVATE, classification_map);
-
- /* Recurrences */
-
- priv->recurrence_weekday_day_mask = 0;
-
- priv->recurrence_month_index = 1;
- priv->recurrence_month_day = MONTH_DAY_NTH;
-
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->recurrence_none), ee);
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->recurrence_simple), ee);
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->recurrence_custom), ee);
- e_dialog_radio_set (priv->recurrence_none, RECUR_NONE, recur_type_map);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->recurrence_none), ee);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->recurrence_simple), ee);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->recurrence_custom), ee);
-
- adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->recurrence_interval_value));
- gtk_signal_handler_block_by_data (GTK_OBJECT (adj), ee);
- e_dialog_spin_set (priv->recurrence_interval_value, 1);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (adj), ee);
-
- menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->recurrence_interval_unit));
- gtk_signal_handler_block_by_data (GTK_OBJECT (menu), ee);
- e_dialog_option_menu_set (priv->recurrence_interval_unit, ICAL_DAILY_RECURRENCE,
- recur_freq_map);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), ee);
-
- priv->recurrence_ending_date = time (NULL);
- priv->recurrence_ending_count = 1;
-
- menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->recurrence_ending_menu));
- gtk_signal_handler_block_by_data (GTK_OBJECT (menu), ee);
- e_dialog_option_menu_set (priv->recurrence_ending_menu, ENDING_FOREVER,
- ending_types_map);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), ee);
-
- /* Exceptions list */
-
- free_exception_clist_data (GTK_CLIST (priv->recurrence_exception_list));
-}
-
-/* Fills the recurrence ending date widgets with the values from the calendar
- * component.
- */
-static void
-fill_ending_date (EventEditor *ee, struct icalrecurrencetype *r)
-{
- EventEditorPrivate *priv;
- GtkWidget *menu;
-
- priv = ee->priv;
-
- menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->recurrence_ending_menu));
- gtk_signal_handler_block_by_data (GTK_OBJECT (menu), ee);
-
- if (r->count == 0) {
- if (r->until.year == 0) {
- /* Forever */
-
- e_dialog_option_menu_set (priv->recurrence_ending_menu,
- ENDING_FOREVER,
- ending_types_map);
- } else {
- /* Ending date */
-
- priv->recurrence_ending_date = icaltime_as_timet (r->until);
- e_dialog_option_menu_set (priv->recurrence_ending_menu,
- ENDING_UNTIL,
- ending_types_map);
- }
- } else {
- /* Count of occurrences */
-
- priv->recurrence_ending_count = r->count;
- e_dialog_option_menu_set (priv->recurrence_ending_menu,
- ENDING_FOR,
- ending_types_map);
- }
-
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), ee);
-
- make_recurrence_ending_special (ee);
-}
-
-/* Counts the number of elements in the by_xxx fields of an icalrecurrencetype */
-static int
-count_by_xxx (short *field, int max_elements)
-{
- int i;
-
- for (i = 0; i < max_elements; i++)
- if (field[i] == ICAL_RECURRENCE_ARRAY_MAX)
- break;
-
- return i;
-}
-
-/* Re-tags the recurrence preview calendar based on the current information of
- * the event editor.
- */
-static void
-preview_recur (EventEditor *ee)
-{
- EventEditorPrivate *priv;
- CalComponent *comp;
- CalComponentDateTime cdt;
- GSList *l;
-
- priv = ee->priv;
- g_assert (priv->comp != NULL);
-
- /* Create a scratch component with the start/end and
- * recurrence/excepttion information from the one we are editing.
- */
-
- comp = cal_component_new ();
- cal_component_set_new_vtype (comp, CAL_COMPONENT_EVENT);
-
- cal_component_get_dtstart (priv->comp, &cdt);
- cal_component_set_dtstart (comp, &cdt);
- cal_component_free_datetime (&cdt);
-
- cal_component_get_dtend (priv->comp, &cdt);
- cal_component_set_dtend (comp, &cdt);
- cal_component_free_datetime (&cdt);
-
- cal_component_get_exdate_list (priv->comp, &l);
- cal_component_set_exdate_list (comp, l);
- cal_component_free_exdate_list (l);
-
- cal_component_get_exrule_list (priv->comp, &l);
- cal_component_set_exrule_list (comp, l);
- cal_component_free_recur_list (l);
-
- cal_component_get_rdate_list (priv->comp, &l);
- cal_component_set_rdate_list (comp, l);
- cal_component_free_period_list (l);
-
- cal_component_get_rrule_list (priv->comp, &l);
- cal_component_set_rrule_list (comp, l);
- cal_component_free_recur_list (l);
-
- recur_to_comp_object (ee, comp);
-
- tag_calendar_by_comp (E_CALENDAR (priv->recurrence_preview_calendar), comp);
- gtk_object_unref (GTK_OBJECT (comp));
-}
-
-/* Fills in the exception widgets with the data from the calendar component */
-static void
-fill_exception_widgets (EventEditor *ee)
-{
- EventEditorPrivate *priv;
- GSList *list, *l;
- gboolean added;
-
- priv = ee->priv;
- g_assert (priv->comp != NULL);
-
- /* Exceptions list */
-
- cal_component_get_exdate_list (priv->comp, &list);
-
- added = FALSE;
-
- for (l = list; l; l = l->next) {
- CalComponentDateTime *cdt;
- time_t ext;
-
- added = TRUE;
-
- cdt = l->data;
- ext = icaltime_as_timet (*cdt->value);
- append_exception (ee, ext);
- }
-
- cal_component_free_exdate_list (list);
-
- if (added)
- gtk_clist_select_row (GTK_CLIST (priv->recurrence_exception_list), 0, 0);
-}
-
-/* Computes a weekday mask for the start day of a calendar component, for use in
- * a WeekdayPicker widget.
- */
-static guint8
-get_start_weekday_mask (CalComponent *comp)
-{
- CalComponentDateTime dt;
- guint8 retval;
-
- cal_component_get_dtstart (comp, &dt);
-
- if (dt.value) {
- time_t t;
- struct tm tm;
-
- t = icaltime_as_timet (*dt.value);
- tm = *localtime (&t);
-
- retval = 0x1 << tm.tm_wday;
- } else
- retval = 0;
-
- cal_component_free_datetime (&dt);
-
- return retval;
-}
-
-/* Sets some sane defaults for the data sources for the recurrence special
- * widgets, even if they will not be used immediately.
- */
-static void
-set_recur_special_defaults (EventEditor *ee)
-{
- EventEditorPrivate *priv;
- guint8 mask;
-
- priv = ee->priv;
-
- mask = get_start_weekday_mask (priv->comp);
-
- priv->recurrence_weekday_day_mask = mask;
- priv->recurrence_weekday_blocked_day_mask = mask;
-}
-
-static char *
-get_alarm_duration_string (struct icaldurationtype *duration)
-{
- GString *string = g_string_new (NULL);
- char *ret;
-
- if (duration->days > 1)
- g_string_sprintf (string, _(" %d days"), duration->days);
- else if (duration->days == 1)
- g_string_append (string, _(" 1 day"));
-
- if (duration->weeks > 1)
- g_string_sprintf (string, _(" %d weeks"), duration->weeks);
- else if (duration->weeks == 1)
- g_string_append (string, _(" 1 week"));
-
- if (duration->hours > 1)
- g_string_sprintf (string, _(" %d hours"), duration->hours);
- else if (duration->hours == 1)
- g_string_append (string, _(" 1 hour"));
-
- if (duration->minutes > 1)
- g_string_sprintf (string, _(" %d minutes"), duration->minutes);
- else if (duration->minutes == 1)
- g_string_append (string, _(" 1 minute"));
-
- if (duration->seconds > 1)
- g_string_sprintf (string, _(" %d seconds"), duration->seconds);
- else if (duration->seconds == 1)
- g_string_append (string, _(" 1 second"));
-
- ret = string->str;
- g_string_free (string, FALSE);
-
- return ret;
-}
-
-static char *
-get_alarm_string (CalComponentAlarm *alarm)
-{
- CalAlarmAction action;
- CalAlarmTrigger trigger;
- char string[256];
- char *dur;
-
- string [0] = '\0';
-
- cal_component_alarm_get_action (alarm, &action);
- cal_component_alarm_get_trigger (alarm, &trigger);
-
- switch (action) {
- case CAL_ALARM_AUDIO:
- strcat (string, _("Play a sound"));
- break;
- case CAL_ALARM_DISPLAY:
- strcat (string, _("Show a dialog"));
- break;
- case CAL_ALARM_EMAIL:
- strcat (string, _("Send an email"));
- break;
- case CAL_ALARM_PROCEDURE:
- strcat (string, _("Run a program"));
- break;
- case CAL_ALARM_NONE:
- case CAL_ALARM_UNKNOWN:
- strcat (string, _("Unknown"));
- break;
- }
-
- switch (trigger.type) {
- case CAL_ALARM_TRIGGER_RELATIVE_START:
- dur = get_alarm_duration_string (&trigger.u.rel_duration);
- strcat (string, dur);
- g_free (dur);
-
- if (trigger.u.rel_duration.is_neg)
- strcat (string, _(" before start of appointment"));
- else
- strcat (string, _(" after start of appointment"));
- break;
- case CAL_ALARM_TRIGGER_RELATIVE_END:
- dur = get_alarm_duration_string (&trigger.u.rel_duration);
- strcat (string, dur);
- g_free (dur);
-
- if (trigger.u.rel_duration.is_neg)
- strcat (string, _(" before end of appointment"));
- else
- strcat (string, _(" after end of appointment"));
- break;
- case CAL_ALARM_TRIGGER_NONE:
- case CAL_ALARM_TRIGGER_ABSOLUTE:
- strcat (string, _("Unknown"));
- break;
- }
-
- return g_strdup (string);
-}
-
-static void
-fill_reminder_widgets (EventEditor *ee)
-{
- EventEditorPrivate *priv;
- GList *alarms, *l;
- GtkCList *clist;
-
- int row = 0;
-
- priv = ee->priv;
- g_assert (priv->comp != NULL);
-
- if (!cal_component_has_alarms (priv->comp))
- return;
-
- alarms = cal_component_get_alarm_uids (priv->comp);
-
- clist = GTK_CLIST (priv->reminder_list);
- for (l = alarms; l != NULL; l = l->next, row++) {
- CalComponentAlarm *ca = cal_component_get_alarm (priv->comp, l->data);
-
- /* Add it to the clist */
- append_reminder (ee, ca, EXISTING_ALARM);
- }
- cal_obj_uid_list_free (alarms);
-}
-
-/* Fills in the recurrence widgets with the values from the calendar component.
- * This function is particularly tricky because it has to discriminate between
- * recurrences we support for editing and the ones we don't. We only support at
- * most one recurrence rule; no rdates or exrules (exdates are handled just fine
- * elsewhere).
- */
-static void
-fill_recurrence_widgets (EventEditor *ee)
-{
- EventEditorPrivate *priv;
- GSList *rrule_list;
- int len;
- struct icalrecurrencetype *r;
- int n_by_second, n_by_minute, n_by_hour;
- int n_by_day, n_by_month_day, n_by_year_day;
- int n_by_week_no, n_by_month, n_by_set_pos;
- GtkWidget *menu;
- GtkAdjustment *adj;
-
- priv = ee->priv;
- g_assert (priv->comp != NULL);
-
- fill_exception_widgets (ee);
-
- /* Set up defaults for the special widgets */
-
- set_recur_special_defaults (ee);
-
- /* No recurrences? */
-
- if (!cal_component_has_rdates (priv->comp)
- && !cal_component_has_rrules (priv->comp)
- && !cal_component_has_exrules (priv->comp)) {
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->recurrence_none), ee);
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->recurrence_simple), ee);
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->recurrence_custom), ee);
- e_dialog_radio_set (priv->recurrence_none, RECUR_NONE, recur_type_map);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->recurrence_none), ee);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->recurrence_simple), ee);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->recurrence_custom), ee);
-
- gtk_widget_set_sensitive (priv->recurrence_custom, FALSE);
-
- sensitize_recur_widgets (ee);
- preview_recur (ee);
- return;
- }
-
- /* See if it is a custom set we don't support */
-
- cal_component_get_rrule_list (priv->comp, &rrule_list);
- len = g_slist_length (rrule_list);
- if (len > 1
- || cal_component_has_rdates (priv->comp)
- || cal_component_has_exrules (priv->comp))
- goto custom;
-
- /* Down to one rule, so test that one */
-
- g_assert (len == 1);
- r = rrule_list->data;
-
- /* Any funky frequency? */
-
- if (r->freq == ICAL_SECONDLY_RECURRENCE
- || r->freq == ICAL_MINUTELY_RECURRENCE
- || r->freq == ICAL_HOURLY_RECURRENCE)
- goto custom;
-
- /* Any funky shit? */
-
-#define N_HAS_BY(field) (count_by_xxx (field, sizeof (field) / sizeof (field[0])))
-
- n_by_second = N_HAS_BY (r->by_second);
- n_by_minute = N_HAS_BY (r->by_minute);
- n_by_hour = N_HAS_BY (r->by_hour);
- n_by_day = N_HAS_BY (r->by_day);
- n_by_month_day = N_HAS_BY (r->by_month_day);
- n_by_year_day = N_HAS_BY (r->by_year_day);
- n_by_week_no = N_HAS_BY (r->by_week_no);
- n_by_month = N_HAS_BY (r->by_month);
- n_by_set_pos = N_HAS_BY (r->by_set_pos);
-
- if (n_by_second != 0
- || n_by_minute != 0
- || n_by_hour != 0)
- goto custom;
-
- /* Filter the funky shit based on the frequency; if there is nothing
- * weird we can actually set the widgets.
- */
-
- switch (r->freq) {
- case ICAL_DAILY_RECURRENCE:
- if (n_by_day != 0
- || n_by_month_day != 0
- || n_by_year_day != 0
- || n_by_week_no != 0
- || n_by_month != 0
- || n_by_set_pos != 0)
- goto custom;
-
- menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->recurrence_interval_unit));
- gtk_signal_handler_block_by_data (GTK_OBJECT (menu), ee);
- e_dialog_option_menu_set (priv->recurrence_interval_unit, ICAL_DAILY_RECURRENCE,
- recur_freq_map);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), ee);
- break;
-
- case ICAL_WEEKLY_RECURRENCE: {
- int i;
- guint8 day_mask;
-
- if (n_by_month_day != 0
- || n_by_year_day != 0
- || n_by_week_no != 0
- || n_by_month != 0
- || n_by_set_pos != 0)
- goto custom;
-
- day_mask = 0;
-
- for (i = 0; i < 8 && r->by_day[i] != ICAL_RECURRENCE_ARRAY_MAX; i++) {
- enum icalrecurrencetype_weekday weekday;
- int pos;
-
- weekday = icalrecurrencetype_day_day_of_week (r->by_day[i]);
- pos = icalrecurrencetype_day_position (r->by_day[i]);
-
- if (pos != 0)
- goto custom;
-
- switch (weekday) {
- case ICAL_SUNDAY_WEEKDAY:
- day_mask |= 1 << 0;
- break;
-
- case ICAL_MONDAY_WEEKDAY:
- day_mask |= 1 << 1;
- break;
-
- case ICAL_TUESDAY_WEEKDAY:
- day_mask |= 1 << 2;
- break;
-
- case ICAL_WEDNESDAY_WEEKDAY:
- day_mask |= 1 << 3;
- break;
-
- case ICAL_THURSDAY_WEEKDAY:
- day_mask |= 1 << 4;
- break;
-
- case ICAL_FRIDAY_WEEKDAY:
- day_mask |= 1 << 5;
- break;
-
- case ICAL_SATURDAY_WEEKDAY:
- day_mask |= 1 << 6;
- break;
-
- default:
- break;
- }
- }
-
- priv->recurrence_weekday_day_mask = day_mask;
-
- menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->recurrence_interval_unit));
- gtk_signal_handler_block_by_data (GTK_OBJECT (menu), ee);
- e_dialog_option_menu_set (priv->recurrence_interval_unit, ICAL_WEEKLY_RECURRENCE,
- recur_freq_map);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), ee);
- break;
- }
-
- case ICAL_MONTHLY_RECURRENCE:
- if (n_by_year_day != 0
- || n_by_week_no != 0
- || n_by_month != 0
- || n_by_set_pos != 0)
- goto custom;
-
- if (n_by_month_day == 1) {
- int nth;
-
- nth = r->by_month_day[0];
- if (nth < 1)
- goto custom;
-
- priv->recurrence_month_index = nth;
- priv->recurrence_month_day = MONTH_DAY_NTH;
- } else if (n_by_day == 1) {
- enum icalrecurrencetype_weekday weekday;
- int pos;
- enum month_day_options month_day;
-
- weekday = icalrecurrencetype_day_day_of_week (r->by_day[0]);
- pos = icalrecurrencetype_day_position (r->by_day[0]);
-
- if (pos < 1)
- goto custom;
-
- switch (weekday) {
- case ICAL_MONDAY_WEEKDAY:
- month_day = MONTH_DAY_MON;
- break;
-
- case ICAL_TUESDAY_WEEKDAY:
- month_day = MONTH_DAY_TUE;
- break;
-
- case ICAL_WEDNESDAY_WEEKDAY:
- month_day = MONTH_DAY_WED;
- break;
-
- case ICAL_THURSDAY_WEEKDAY:
- month_day = MONTH_DAY_THU;
- break;
-
- case ICAL_FRIDAY_WEEKDAY:
- month_day = MONTH_DAY_FRI;
- break;
-
- case ICAL_SATURDAY_WEEKDAY:
- month_day = MONTH_DAY_SAT;
- break;
-
- case ICAL_SUNDAY_WEEKDAY:
- month_day = MONTH_DAY_SUN;
- break;
-
- default:
- goto custom;
- }
-
- priv->recurrence_month_index = pos;
- priv->recurrence_month_day = month_day;
- } else
- goto custom;
-
- menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->recurrence_interval_unit));
- gtk_signal_handler_block_by_data (GTK_OBJECT (menu), ee);
- e_dialog_option_menu_set (priv->recurrence_interval_unit, ICAL_MONTHLY_RECURRENCE,
- recur_freq_map);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), ee);
- break;
-
- case ICAL_YEARLY_RECURRENCE:
- if (n_by_day != 0
- || n_by_month_day != 0
- || n_by_year_day != 0
- || n_by_week_no != 0
- || n_by_month != 0
- || n_by_set_pos != 0)
- goto custom;
-
- menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (priv->recurrence_interval_unit));
- gtk_signal_handler_block_by_data (GTK_OBJECT (menu), ee);
- e_dialog_option_menu_set (priv->recurrence_interval_unit, ICAL_YEARLY_RECURRENCE,
- recur_freq_map);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), ee);
- break;
-
- default:
- goto custom;
- }
-
- /* If we got here it means it is a simple recurrence */
-
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->recurrence_none), ee);
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->recurrence_simple), ee);
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->recurrence_custom), ee);
- e_dialog_radio_set (priv->recurrence_simple, RECUR_SIMPLE, recur_type_map);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->recurrence_none), ee);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->recurrence_simple), ee);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->recurrence_custom), ee);
-
- gtk_widget_set_sensitive (priv->recurrence_custom, FALSE);
-
- sensitize_recur_widgets (ee);
- make_recurrence_special (ee);
-
- adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->recurrence_interval_value));
- gtk_signal_handler_block_by_data (GTK_OBJECT (adj), ee);
- e_dialog_spin_set (priv->recurrence_interval_value, r->interval);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (adj), ee);
-
- fill_ending_date (ee, r);
-
- goto out;
-
- custom:
-
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->recurrence_none), ee);
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->recurrence_simple), ee);
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->recurrence_custom), ee);
- e_dialog_radio_set (priv->recurrence_custom, RECUR_CUSTOM, recur_type_map);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->recurrence_none), ee);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->recurrence_simple), ee);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->recurrence_custom), ee);
-
- gtk_widget_set_sensitive (priv->recurrence_custom, TRUE);
- sensitize_recur_widgets (ee);
-
- out:
-
- cal_component_free_recur_list (rrule_list);
- preview_recur (ee);
-}
-
-/* Fills in the widgets with the value from the calendar component */
-static void
-fill_widgets (EventEditor *ee)
-{
- EventEditorPrivate *priv;
- CalComponentText text;
- CalComponentClassification cl;
- CalComponentDateTime d;
- GSList *l;
- time_t dtstart, dtend;
- const char *categories;
-
- priv = ee->priv;
-
- clear_widgets (ee);
-
- if (!priv->comp)
- return;
-
- /* Summary, description(s) */
-
- cal_component_get_summary (priv->comp, &text);
- e_dialog_editable_set (priv->general_summary, text.value); /* will also set recur summary */
-
- cal_component_get_description_list (priv->comp, &l);
- if (l) {
- text = *(CalComponentText *)l->data;
- e_dialog_editable_set (priv->description, text.value);
- }
- cal_component_free_text_list (l);
-
- /* Start and end times */
-
- /* All-day events are inclusive, i.e. if the end date shown is 2nd Feb
- then the event includes all of the 2nd Feb. We would normally show
- 3rd Feb as the end date, since it really ends at midnight on 3rd,
- so we have to subtract a day so we only show the 2nd. */
- cal_component_get_dtstart (priv->comp, &d);
- dtstart = icaltime_as_timet (*d.value);
- cal_component_free_datetime (&d);
-
- cal_component_get_dtend (priv->comp, &d);
- dtend = icaltime_as_timet (*d.value);
- cal_component_free_datetime (&d);
-
- if (time_day_begin (dtstart) == dtstart
- && time_day_begin (dtend) == dtend) {
- dtend = time_add_day (dtend, -1);
- }
-
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_time), ee);
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->end_time), ee);
-
- e_date_edit_set_time (E_DATE_EDIT (priv->start_time), dtstart);
- e_date_edit_set_time (E_DATE_EDIT (priv->reminder_starting_date), dtstart);
- e_date_edit_set_time (E_DATE_EDIT (priv->recurrence_starting_date), dtstart);
- e_date_edit_set_time (E_DATE_EDIT (priv->end_time), dtend);
-
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->start_time), ee);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->end_time), ee);
-
- check_all_day (ee);
-
- /* Classification */
-
- cal_component_get_classification (priv->comp, &cl);
-
- switch (cl) {
- case CAL_COMPONENT_CLASS_PUBLIC:
- e_dialog_radio_set (priv->classification_public, CAL_COMPONENT_CLASS_PUBLIC,
- classification_map);
- case CAL_COMPONENT_CLASS_PRIVATE:
- e_dialog_radio_set (priv->classification_public, CAL_COMPONENT_CLASS_PRIVATE,
- classification_map);
- case CAL_COMPONENT_CLASS_CONFIDENTIAL:
- e_dialog_radio_set (priv->classification_public, CAL_COMPONENT_CLASS_CONFIDENTIAL,
- classification_map);
- default:
- /* What do do? We can't g_assert_not_reached() since it is a
- * value from an external file.
- */
- }
-
- /* Categories */
- cal_component_get_categories (priv->comp, &categories);
- e_dialog_editable_set (priv->categories, categories);
-
- /* Reminders */
- fill_reminder_widgets (ee);
-
- /* Recurrences */
- fill_recurrence_widgets (ee);
-
- /* Do this last, since the callbacks will set it to TRUE. */
- event_editor_set_changed (ee, FALSE);
-}
-
-
-/**
- * event_editor_update_widgets:
- * @ee: An event editor.
- *
- * Causes an event editor dialog to re-read the values of its calendar component
- * object. This function should be used if the #CalComponent is changed by
- * external means while it is open in the editor.
- **/
-void
-event_editor_update_widgets (EventEditor *ee)
-{
- g_return_if_fail (ee != NULL);
- g_return_if_fail (IS_EVENT_EDITOR (ee));
-
- fill_widgets (ee);
-}
-
-
-
-/* Decode the radio button group for classifications */
-static CalComponentClassification
-classification_get (GtkWidget *widget)
-{
- return e_dialog_radio_get (widget, classification_map);
-}
-
-/* Encondes a position/weekday pair into the proper format for
- * icalrecurrencetype.by_day.
- */
-static short
-nth_weekday (int pos, icalrecurrencetype_weekday weekday)
-{
- g_assert (pos > 0 && pos <= 5);
-
- return (pos << 3) | (int) weekday;
-}
-
-static void
-reminder_to_comp_object (EventEditor *ee, CalComponent *comp)
-{
- EventEditorPrivate *priv;
- GtkCList *reminder_list;
- ReminderData *rdata;
- int i;
-
- priv = ee->priv;
-
- reminder_list = GTK_CLIST (priv->reminder_list);
- for (i = 0; i < reminder_list->rows; i++) {
- rdata = gtk_clist_get_row_data (reminder_list, i);
- if (rdata->status == NEW_ALARM)
- cal_component_add_alarm (priv->comp, rdata->alarm);
- g_free (rdata);
- }
-}
-
-/* Gets the simple recurrence data from the recurrence widgets and stores it in
- * the calendar component object.
- */
-static void
-simple_recur_to_comp_object (EventEditor *ee, CalComponent *comp)
-{
- EventEditorPrivate *priv;
- struct icalrecurrencetype r;
- GSList l;
- enum ending_type ending_type;
-
- priv = ee->priv;
-
- icalrecurrencetype_clear (&r);
-
- /* Frequency, interval, week start */
-
- r.freq = e_dialog_option_menu_get (priv->recurrence_interval_unit, recur_freq_map);
- r.interval = e_dialog_spin_get_int (priv->recurrence_interval_value);
- r.week_start = ICAL_SUNDAY_WEEKDAY + calendar_config_get_week_start_day ();
-
- /* Frequency-specific data */
-
- switch (r.freq) {
- case ICAL_DAILY_RECURRENCE:
- /* Nothing else is required */
- break;
-
- case ICAL_WEEKLY_RECURRENCE: {
- guint8 day_mask;
- int i;
-
- g_assert (GTK_BIN (priv->recurrence_special)->child != NULL);
- g_assert (priv->recurrence_weekday_picker != NULL);
- g_assert (IS_WEEKDAY_PICKER (priv->recurrence_weekday_picker));
-
- day_mask = weekday_picker_get_days (WEEKDAY_PICKER (priv->recurrence_weekday_picker));
-
- i = 0;
-
- if (day_mask & (1 << 0))
- r.by_day[i++] = ICAL_SUNDAY_WEEKDAY;
-
- if (day_mask & (1 << 1))
- r.by_day[i++] = ICAL_MONDAY_WEEKDAY;
-
- if (day_mask & (1 << 2))
- r.by_day[i++] = ICAL_TUESDAY_WEEKDAY;
-
- if (day_mask & (1 << 3))
- r.by_day[i++] = ICAL_WEDNESDAY_WEEKDAY;
-
- if (day_mask & (1 << 4))
- r.by_day[i++] = ICAL_THURSDAY_WEEKDAY;
-
- if (day_mask & (1 << 5))
- r.by_day[i++] = ICAL_FRIDAY_WEEKDAY;
-
- if (day_mask & (1 << 6))
- r.by_day[i++] = ICAL_SATURDAY_WEEKDAY;
-
- break;
- }
-
- case ICAL_MONTHLY_RECURRENCE: {
- int day_index;
- enum month_day_options month_day;
-
- g_assert (GTK_BIN (priv->recurrence_special)->child != NULL);
- g_assert (priv->recurrence_month_index_spin != NULL);
- g_assert (GTK_IS_SPIN_BUTTON (priv->recurrence_month_index_spin));
- g_assert (priv->recurrence_month_day_menu != NULL);
- g_assert (GTK_IS_OPTION_MENU (priv->recurrence_month_day_menu));
-
- day_index = e_dialog_spin_get_int (priv->recurrence_month_index_spin);
- month_day = e_dialog_option_menu_get (priv->recurrence_month_day_menu,
- month_day_options_map);
-
- switch (month_day) {
- case MONTH_DAY_NTH:
- r.by_month_day[0] = day_index;
- break;
-
- case MONTH_DAY_MON:
- r.by_day[0] = nth_weekday (day_index, ICAL_MONDAY_WEEKDAY);
- break;
-
- case MONTH_DAY_TUE:
- r.by_day[0] = nth_weekday (day_index, ICAL_TUESDAY_WEEKDAY);
- break;
-
- case MONTH_DAY_WED:
- r.by_day[0] = nth_weekday (day_index, ICAL_WEDNESDAY_WEEKDAY);
- break;
-
- case MONTH_DAY_THU:
- r.by_day[0] = nth_weekday (day_index, ICAL_THURSDAY_WEEKDAY);
- break;
-
- case MONTH_DAY_FRI:
- r.by_day[0] = nth_weekday (day_index, ICAL_FRIDAY_WEEKDAY);
- break;
-
- case MONTH_DAY_SAT:
- r.by_day[0] = nth_weekday (day_index, ICAL_SATURDAY_WEEKDAY);
- break;
-
- case MONTH_DAY_SUN:
- r.by_day[0] = nth_weekday (day_index, ICAL_SUNDAY_WEEKDAY);
- break;
-
- default:
- g_assert_not_reached ();
- }
-
- break;
- }
-
- case ICAL_YEARLY_RECURRENCE:
- /* Nothing else is required */
- break;
-
- default:
- g_assert_not_reached ();
- }
-
- /* Ending date */
-
- ending_type = e_dialog_option_menu_get (priv->recurrence_ending_menu, ending_types_map);
-
- switch (ending_type) {
- case ENDING_FOR:
- g_assert (priv->recurrence_ending_count_spin != NULL);
- g_assert (GTK_IS_SPIN_BUTTON (priv->recurrence_ending_count_spin));
-
- r.count = e_dialog_spin_get_int (priv->recurrence_ending_count_spin);
- break;
-
- case ENDING_UNTIL:
- g_assert (priv->recurrence_ending_date_edit != NULL);
- g_assert (E_IS_DATE_EDIT (priv->recurrence_ending_date_edit));
-
- r.until = icaltime_from_timet (
- e_date_edit_get_time (E_DATE_EDIT (priv->recurrence_ending_date_edit)),
- TRUE);
- break;
-
- case ENDING_FOREVER:
- /* Nothing to be done */
- break;
-
- default:
- g_assert_not_reached ();
- }
-
- /* Set the recurrence */
-
- l.data = &r;
- l.next = NULL;
-
- cal_component_set_rrule_list (comp, &l);
-}
-
-/* Gets the data from the recurrence widgets and stores it in the calendar
- * component object.
- */
-static void
-recur_to_comp_object (EventEditor *ee, CalComponent *comp)
-{
- EventEditorPrivate *priv;
- enum recur_type recur_type;
- GtkCList *exception_list;
- GSList *list;
- int i;
-
- priv = ee->priv;
-
- recur_type = e_dialog_radio_get (priv->recurrence_none, recur_type_map);
-
- switch (recur_type) {
- case RECUR_NONE:
- cal_component_set_rdate_list (comp, NULL);
- cal_component_set_rrule_list (comp, NULL);
- cal_component_set_exrule_list (comp, NULL);
- break;
-
- case RECUR_SIMPLE:
- cal_component_set_rdate_list (comp, NULL);
- cal_component_set_exrule_list (comp, NULL);
- simple_recur_to_comp_object (ee, comp);
- break;
-
- case RECUR_CUSTOM:
- /* We just keep whatever the component has currently */
- break;
-
- default:
- g_assert_not_reached ();
- }
-
- /* Set exceptions */
-
- list = NULL;
- exception_list = GTK_CLIST (priv->recurrence_exception_list);
- for (i = 0; i < exception_list->rows; i++) {
- CalComponentDateTime *cdt;
- time_t *tim;
-
- cdt = g_new (CalComponentDateTime, 1);
- cdt->value = g_new (struct icaltimetype, 1);
- cdt->tzid = NULL;
-
- tim = gtk_clist_get_row_data (exception_list, i);
- g_assert (tim != NULL);
- *cdt->value = icaltime_from_timet (*tim, FALSE);
-
- list = g_slist_prepend (list, cdt);
- }
-
- cal_component_set_exdate_list (comp, list);
- cal_component_free_exdate_list (list);
-}
-
-/* Gets the data from the widgets and stores it in the calendar component object */
-static void
-dialog_to_comp_object (EventEditor *ee, CalComponent *comp)
-{
- EventEditorPrivate *priv;
- CalComponentDateTime date;
- time_t t;
- gboolean all_day_event;
- char *cat, *str;
-
- priv = ee->priv;
-
- /* Summary */
-
- str = e_dialog_editable_get (priv->general_summary);
- if (!str || strlen (str) == 0)
- cal_component_set_summary (comp, NULL);
- else {
- CalComponentText text;
-
- text.value = str;
- text.altrep = NULL;
-
- cal_component_set_summary (comp, &text);
- }
-
- if (str)
- g_free (str);
-
- /* Description */
-
- str = e_dialog_editable_get (priv->description);
- if (!str || strlen (str) == 0)
- cal_component_set_description_list (comp, NULL);
- else {
- GSList l;
- CalComponentText text;
-
- text.value = str;
- text.altrep = NULL;
- l.data = &text;
- l.next = NULL;
-
- cal_component_set_description_list (comp, &l);
- }
-
- if (str)
- g_free (str);
-
- /* Dates */
-
- date.value = g_new (struct icaltimetype, 1);
- date.tzid = NULL;
-
- t = e_date_edit_get_time (E_DATE_EDIT (priv->start_time));
- if (t != -1) {
- *date.value = icaltime_from_timet (t, FALSE);
- cal_component_set_dtstart (comp, &date);
- } else {
- /* FIXME: What do we do here? */
- }
-
- /* If the all_day toggle is set, the end date is inclusive of the
- entire day on which it points to. */
- all_day_event = e_dialog_toggle_get (priv->all_day_event);
- t = e_date_edit_get_time (E_DATE_EDIT (priv->end_time));
- if (t != -1) {
- if (all_day_event)
- t = time_day_end (t);
-
- *date.value = icaltime_from_timet (t, FALSE);
- cal_component_set_dtend (comp, &date);
- } else {
- /* FIXME: What do we do here? */
- }
- g_free (date.value);
-
- /* Categories */
- cat = e_dialog_editable_get (priv->categories);
- cal_component_set_categories (comp, cat);
-
- if (cat)
- g_free (cat);
-
- cal_component_set_classification (comp, classification_get (priv->classification_public));
-
- /* Reminder information */
- reminder_to_comp_object (ee, comp);
-
- /* Recurrence information */
- recur_to_comp_object (ee, comp);
-
- cal_component_commit_sequence (comp);
-}
-
-/* Fills the calendar component object from the data in the widgets and commits
- * the component to the storage.
- */
-static void
-save_event_object (EventEditor *ee)
-{
- EventEditorPrivate *priv;
-
- priv = ee->priv;
-
- if (!priv->comp)
- return;
-
- dialog_to_comp_object (ee, priv->comp);
- set_title_from_comp (ee, priv->comp);
-
- if (!cal_client_update_object (priv->client, priv->comp))
- g_message ("save_event_object(): Could not update the object!");
- else
- event_editor_set_changed (ee, FALSE);
-}
-
-/* Closes the dialog box and emits the appropriate signals */
-static void
-close_dialog (EventEditor *ee)
-{
- EventEditorPrivate *priv;
-
- priv = ee->priv;
-
- g_assert (priv->app != NULL);
-
- gtk_object_destroy (GTK_OBJECT (ee));
-}
-
-
-
-/* Callback used when the dialog box is "applied" */
-static void
-ee_apply_event_cb (GtkWidget *widget, gint page_num, gpointer data)
-{
- EventEditor *ee;
-
- g_return_if_fail (IS_EVENT_EDITOR (data));
-
- ee = EVENT_EDITOR (data);
-
- if (page_num != -1)
- return;
-
- save_event_object (ee);
-}
-
-/* Callback used when the dialog box is destroyed */
-static gint
-ee_close_event_cb (GtkWidget *widget, gpointer data)
-{
- EventEditor *ee;
-
- g_return_val_if_fail (IS_EVENT_EDITOR (data), TRUE);
-
- ee = EVENT_EDITOR (data);
-
- if (prompt_to_save_changes (ee))
- close_dialog (ee);
-
- return TRUE;
-}
-
-/* Callback used when the dialog box is destroyed */
-static gint
-ee_delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data)
-{
- EventEditor *ee;
-
- g_return_val_if_fail (IS_EVENT_EDITOR (data), TRUE);
-
- ee = EVENT_EDITOR (data);
-
- if (prompt_to_save_changes (ee))
- close_dialog (ee);
-
- return TRUE;
-}
-
-/**
- * event_editor_construct:
- * @ee: An event editor.
- *
- * Constructs an event editor by loading its Glade data.
- *
- * Return value: The same object as @ee, or NULL if the widgets could not be
- * created. In the latter case, the event editor will automatically be
- * destroyed.
- **/
-EventEditor *
-event_editor_construct (EventEditor *ee)
-{
- EventEditorPrivate *priv;
-
- g_return_val_if_fail (ee != NULL, NULL);
- g_return_val_if_fail (IS_EVENT_EDITOR (ee), NULL);
-
- priv = ee->priv;
-
- /* Load the content widgets */
-
- priv->xml = glade_xml_new (EVOLUTION_GLADEDIR "/event-editor-dialog.glade", NULL);
- if (!priv->xml) {
- g_message ("event_editor_construct(): Could not load the Glade XML file!");
- goto error;
- }
-
- if (!get_widgets (ee)) {
- g_message ("event_editor_construct(): Could not find all widgets in the XML file!");
- goto error;
- }
-
- init_widgets (ee);
-
- /* Hook to destruction of the dialog */
- gtk_signal_connect (GTK_OBJECT (priv->app), "apply",
- GTK_SIGNAL_FUNC (ee_apply_event_cb), ee);
- gtk_signal_connect (GTK_OBJECT (priv->app), "close",
- GTK_SIGNAL_FUNC (ee_close_event_cb), ee);
- gtk_signal_connect (GTK_OBJECT (priv->app), "delete_event",
- GTK_SIGNAL_FUNC (ee_delete_event_cb), ee);
-
- /* Add focus to the summary entry */
- gtk_widget_grab_focus (GTK_WIDGET (priv->general_summary));
-
- return ee;
-
- error:
-
- gtk_object_unref (GTK_OBJECT (ee));
- return NULL;
-}
-
-/**
- * event_editor_new:
- *
- * Creates a new event editor dialog.
- *
- * Return value: A newly-created event editor dialog, or NULL if the event
- * editor could not be created.
- **/
-EventEditor *
-event_editor_new (void)
-{
- EventEditor *ee;
-
- ee = EVENT_EDITOR (gtk_type_new (TYPE_EVENT_EDITOR));
- return event_editor_construct (EVENT_EDITOR (ee));
-}
-
-/* Brings attention to a window by raising it and giving it focus */
-static void
-raise_and_focus (GtkWidget *widget)
-{
- g_assert (GTK_WIDGET_REALIZED (widget));
- gdk_window_show (widget->window);
- gtk_widget_grab_focus (widget);
-}
-
-/* Callback used when the calendar client tells us that an object changed */
-static void
-obj_updated_cb (CalClient *client, const char *uid, gpointer data)
-{
- /* FIXME: Do something sensible if the component changes under our feet */
-#if 0
- EventEditor *ee;
- EventEditorPrivate *priv;
- CalComponent *comp;
- CalClientGetStatus status;
- const gchar *editing_uid;
-
- ee = EVENT_EDITOR (data);
-
- g_return_if_fail (IS_EVENT_EDITOR (ee));
-
- priv = ee->priv;
-
- /* If we aren't showing the object which has been updated, return. */
- if (!priv->comp)
- return;
- cal_component_get_uid (priv->comp, &editing_uid);
- if (strcmp (uid, editing_uid))
- return;
-
-
- /* Get the event from the server. */
- status = cal_client_get_object (priv->client, uid, &comp);
-
- switch (status) {
- case CAL_CLIENT_GET_SUCCESS:
- /* Everything is fine */
- break;
-
- case CAL_CLIENT_GET_SYNTAX_ERROR:
- g_message ("obj_updated_cb(): Syntax error when getting object `%s'", uid);
- return;
-
- case CAL_CLIENT_GET_NOT_FOUND:
- /* The object is no longer in the server, so do nothing */
- return;
-
- default:
- g_assert_not_reached ();
- return;
- }
-
- raise_and_focus (priv->app);
-#endif
-}
-
-/* Callback used when the calendar client tells us that an object was removed */
-static void
-obj_removed_cb (CalClient *client, const char *uid, gpointer data)
-{
- /* FIXME: Do something sensible if the component is removed under our
- * feet.
- */
-#if 0
- EventEditor *ee;
- EventEditorPrivate *priv;
- const gchar *editing_uid;
-
- ee = EVENT_EDITOR (data);
-
- g_return_if_fail (ee != NULL);
- g_return_if_fail (IS_EVENT_EDITOR (ee));
-
- priv = ee->priv;
-
- /* If we aren't showing the object which has been updated, return. */
- if (!priv->comp)
- return;
- cal_component_get_uid (priv->comp, &editing_uid);
- if (strcmp (uid, editing_uid))
- return;
-
-
- raise_and_focus (priv->app);
-#endif
-}
-
-/**
- * event_editor_set_cal_client:
- * @ee: An event editor.
- * @client: Calendar client.
- *
- * Sets the calendar client than an event editor will use for updating its
- * calendar components.
- **/
-void
-event_editor_set_cal_client (EventEditor *ee, CalClient *client)
-{
- EventEditorPrivate *priv;
-
- g_return_if_fail (ee != NULL);
- g_return_if_fail (IS_EVENT_EDITOR (ee));
-
- priv = ee->priv;
-
- if (client == priv->client)
- return;
-
- if (client)
- g_return_if_fail (IS_CAL_CLIENT (client));
-
- if (client)
- g_return_if_fail (cal_client_get_load_state (client) == CAL_CLIENT_LOAD_LOADED);
-
- if (client)
- gtk_object_ref (GTK_OBJECT (client));
-
- if (priv->client) {
- gtk_signal_disconnect_by_data (GTK_OBJECT (priv->client), ee);
- gtk_object_unref (GTK_OBJECT (priv->client));
- }
-
- priv->client = client;
-
- if (priv->client) {
- gtk_signal_connect (GTK_OBJECT (priv->client), "obj_updated",
- GTK_SIGNAL_FUNC (obj_updated_cb), ee);
- gtk_signal_connect (GTK_OBJECT (priv->client), "obj_removed",
- GTK_SIGNAL_FUNC (obj_removed_cb), ee);
- }
-}
-
-/**
- * event_editor_get_cal_client:
- * @ee: An event editor.
- *
- * Queries the calendar client that an event editor is using to update its
- * calendar components.
- *
- * Return value: A calendar client object.
- **/
-CalClient *
-event_editor_get_cal_client (EventEditor *ee)
-{
- EventEditorPrivate *priv;
-
- g_return_val_if_fail (ee != NULL, NULL);
- g_return_val_if_fail (IS_EVENT_EDITOR (ee), NULL);
-
- priv = ee->priv;
- return priv->client;
-}
-
-/**
- * event_editor_set_event_object:
- * @ee: An event editor.
- * @comp: A calendar object.
- *
- * Sets the calendar object that an event editor dialog will manipulate.
- **/
-void
-event_editor_set_event_object (EventEditor *ee, CalComponent *comp)
-{
- EventEditorPrivate *priv;
-
- g_return_if_fail (ee != NULL);
- g_return_if_fail (IS_EVENT_EDITOR (ee));
-
- priv = ee->priv;
-
- if (priv->comp) {
- gtk_object_unref (GTK_OBJECT (priv->comp));
- priv->comp = NULL;
- }
-
- if (comp) {
- priv->comp = cal_component_clone (comp);
- }
-
- set_title_from_comp (ee, priv->comp);
- fill_widgets (ee);
-}
-
-/**
- * event_editor_focus:
- * @ee: An event editor.
- *
- * Makes sure an event editor is shown, on top of other windows, and focused.
- **/
-void
-event_editor_focus (EventEditor *ee)
-{
- EventEditorPrivate *priv;
-
- g_return_if_fail (ee != NULL);
- g_return_if_fail (IS_EVENT_EDITOR (ee));
-
- priv = ee->priv;
- gtk_widget_show_now (priv->app);
- raise_and_focus (priv->app);
-}
-
-/* Checks if the event's time starts and ends at midnight, and sets the
- * "all day event" box accordingly.
- */
-static void
-check_all_day (EventEditor *ee)
-{
- EventEditorPrivate *priv;
- time_t ev_start, ev_end;
- gboolean all_day = FALSE;
-
- priv = ee->priv;
-
- /* Currently we just return if the date is not set or not valid.
- I'm not entirely sure this is the corrent thing to do. */
- ev_start = e_date_edit_get_time (E_DATE_EDIT (priv->start_time));
- g_return_if_fail (ev_start != -1);
-
- ev_end = e_date_edit_get_time (E_DATE_EDIT (priv->end_time));
- g_return_if_fail (ev_end != -1);
-
- /* all day event checkbox */
- if (time_day_begin (ev_start) == ev_start
- && time_day_begin (ev_end) == ev_end)
- all_day = TRUE;
-
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->all_day_event), ee);
-
- e_dialog_toggle_set (priv->all_day_event, all_day);
-
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->all_day_event), ee);
-
- e_date_edit_set_show_time (E_DATE_EDIT (priv->start_time), !all_day);
- e_date_edit_set_show_time (E_DATE_EDIT (priv->end_time), !all_day);
-}
-
-/*
- * Callback: all day event button toggled.
- * Note that this should only be called when the user explicitly toggles the
- * button. Be sure to block this handler when the toggle button's state is set
- * within the code.
- */
-static void
-set_all_day (GtkWidget *toggle, EventEditor *ee)
-{
- EventEditorPrivate *priv;
- struct tm start_tm, end_tm;
- time_t start_t, end_t;
- gboolean all_day;
-
- priv = ee->priv;
-
- event_editor_set_changed (ee, TRUE);
-
- /* When the all_day toggle is turned on, the start date is rounded down
- to the start of the day, and end date is rounded down to the start
- of the day on which the event ends. The event is then taken to be
- inclusive of the days between the start and end days.
- Note that if the event end is at midnight, we do not round it down
- to the previous day, since if we do that and the user repeatedly
- turns the all_day toggle on and off, the event keeps shrinking.
- (We'd also need to make sure we didn't adjust the time when the
- radio button is initially set.)
-
- When the all_day_toggle is turned off, we set the event start to the
- start of the working day, and if the event end is on or before the
- day of the event start we set it to one hour after the event start.
- */
- all_day = GTK_TOGGLE_BUTTON (toggle)->active;
-
- /*
- * Start time.
- */
- start_t = e_date_edit_get_time (E_DATE_EDIT (priv->start_time));
- g_return_if_fail (start_t != -1);
-
- start_tm = *localtime (&start_t);
-
- if (all_day) {
- /* Round down to the start of the day. */
- start_tm.tm_hour = 0;
- start_tm.tm_min = 0;
- start_tm.tm_sec = 0;
- } else {
- /* Set to the start of the working day. */
- start_tm.tm_hour = calendar_config_get_day_start_hour ();
- start_tm.tm_min = calendar_config_get_day_start_minute ();
- start_tm.tm_sec = 0;
- }
-
- /*
- * End time.
- */
- end_t = e_date_edit_get_time (E_DATE_EDIT (priv->end_time));
- g_return_if_fail (end_t != -1);
-
- end_tm = *localtime (&end_t);
-
- if (all_day) {
- /* Round down to the start of the day. */
- end_tm.tm_hour = 0;
- end_tm.tm_min = 0;
- end_tm.tm_sec = 0;
- } else {
- /* If the event end is now on or before the event start day,
- make it end one hour after the start. mktime() will fix any
- overflows. */
- if (end_tm.tm_year < start_tm.tm_year
- || (end_tm.tm_year == start_tm.tm_year
- && end_tm.tm_mon < start_tm.tm_mon)
- || (end_tm.tm_year == start_tm.tm_year
- && end_tm.tm_mon == start_tm.tm_mon
- && end_tm.tm_mday <= start_tm.tm_mday)) {
- end_tm.tm_year = start_tm.tm_year;
- end_tm.tm_mon = start_tm.tm_mon;
- end_tm.tm_mday = start_tm.tm_mday;
- end_tm.tm_hour = start_tm.tm_hour + 1;
- }
- }
-
- /* Block date_changed_cb, or dates_changed() will be called after the
- start time is set (but before the end time is set) and will call
- check_all_day() and mess us up. */
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_time), ee);
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->end_time), ee);
-
- /* will set recur start too */
- e_date_edit_set_time (E_DATE_EDIT (priv->start_time), mktime (&start_tm));
-
- e_date_edit_set_time (E_DATE_EDIT (priv->end_time), mktime (&end_tm));
-
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->start_time), ee);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->end_time), ee);
-
- e_date_edit_set_show_time (E_DATE_EDIT (priv->start_time), !all_day);
- e_date_edit_set_show_time (E_DATE_EDIT (priv->end_time), !all_day);
-
- preview_recur (ee);
-}
-
-/* Callback used when the start or end date widgets change. We check that the
- * start date < end date and we set the "all day event" button as appropriate.
- */
-static void
-date_changed_cb (EDateEdit *dedit, gpointer data)
-{
- EventEditor *ee;
- EventEditorPrivate *priv;
- time_t start, end;
- struct tm tm_start, tm_end;
-
- ee = EVENT_EDITOR (data);
- priv = ee->priv;
-
- event_editor_set_changed (ee, TRUE);
-
- /* Ensure that start < end */
-
- start = e_date_edit_get_time (E_DATE_EDIT (priv->start_time));
- g_return_if_fail (start != -1);
- end = e_date_edit_get_time (E_DATE_EDIT (priv->end_time));
- g_return_if_fail (end != -1);
-
- if (start >= end) {
- tm_start = *localtime (&start);
- tm_end = *localtime (&end);
-
- if (start == end && tm_start.tm_hour == 0
- && tm_start.tm_min == 0 && tm_start.tm_sec == 0) {
- /* If the start and end times are the same, but both
- are on day boundaries, then that is OK since it
- means we have an all-day event lasting 1 day.
- So we do nothing here. */
-
- } else if (GTK_WIDGET (dedit) == priv->start_time) {
- /* Modify the end time */
-
- tm_end.tm_year = tm_start.tm_year;
- tm_end.tm_mon = tm_start.tm_mon;
- tm_end.tm_mday = tm_start.tm_mday;
- tm_end.tm_hour = tm_start.tm_hour + 1;
- tm_end.tm_min = tm_start.tm_min;
- tm_end.tm_sec = tm_start.tm_sec;
-
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->end_time), ee);
- e_date_edit_set_time (E_DATE_EDIT (priv->end_time), mktime (&tm_end));
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->end_time), ee);
- } else if (GTK_WIDGET (dedit) == priv->end_time) {
- /* Modify the start time */
-
- tm_start.tm_year = tm_end.tm_year;
- tm_start.tm_mon = tm_end.tm_mon;
- tm_start.tm_mday = tm_end.tm_mday;
- tm_start.tm_hour = tm_end.tm_hour - 1;
- tm_start.tm_min = tm_end.tm_min;
- tm_start.tm_sec = tm_end.tm_sec;
-
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_time), ee);
- e_date_edit_set_time (E_DATE_EDIT (priv->start_time), mktime (&tm_start));
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->start_time), ee);
- } else
- g_assert_not_reached ();
- }
-
- /* Set the "all day event" button as appropriate */
-
- check_all_day (ee);
-
- /* Retag the recurrence preview calendar */
-
- preview_recur (ee);
-}
-
-/* Appends an alarm to the list */
-static void
-append_reminder (EventEditor *ee, CalComponentAlarm *alarm, ReminderStatus status)
-{
- EventEditorPrivate *priv;
- GtkCList *clist;
- ReminderData *rdata;
- char *c[1];
- int i;
-
- priv = ee->priv;
-
- clist = GTK_CLIST (priv->reminder_list);
-
- c[0] = get_alarm_string (alarm);
- i = gtk_clist_append (clist, c);
-
- rdata = g_new (ReminderData, 1);
- rdata->status = status;
- rdata->alarm = alarm;
- gtk_clist_set_row_data (clist, i, rdata);
- gtk_clist_select_row (clist, i, 0);
- g_free (c[0]);
-
- gtk_widget_set_sensitive (priv->reminder_delete, TRUE);
-}
-
-/* Callback for the "add reminder" button */
-static void
-reminder_add_cb (GtkWidget *widget, EventEditor *ee)
-{
- EventEditorPrivate *priv;
- CalComponentAlarm *alarm;
- CalAlarmTrigger trigger;
-
- priv = ee->priv;
-
- event_editor_set_changed (ee, TRUE);
-
- alarm = cal_component_alarm_new ();
-
- memset (&trigger, 0, sizeof (CalAlarmTrigger));
- trigger.type = e_dialog_option_menu_get (priv->reminder_time, reminder_time_map);
- if (e_dialog_option_menu_get (priv->reminder_relative, reminder_relative_map) == BEFORE)
- trigger.u.rel_duration.is_neg = 1;
- else
- trigger.u.rel_duration.is_neg = 0;
-
- switch (e_dialog_option_menu_get (priv->reminder_value_units, reminder_value_map)) {
- case MINUTES:
- trigger.u.rel_duration.minutes = e_dialog_spin_get_int (priv->reminder_interval_value);
- break;
- case HOURS:
- trigger.u.rel_duration.hours = e_dialog_spin_get_int (priv->reminder_interval_value);
- break;
- case DAYS:
- trigger.u.rel_duration.days = e_dialog_spin_get_int (priv->reminder_interval_value);
- break;
- }
- cal_component_alarm_set_trigger (alarm, trigger);
-
- cal_component_alarm_set_action (alarm, e_dialog_option_menu_get (priv->reminder_action, reminder_action_map));
-
- append_reminder (ee, alarm, NEW_ALARM);
-}
-
-/* Callback for the "delete reminder" button */
-static void
-reminder_delete_cb (GtkWidget *widget, EventEditor *ee)
-{
- EventEditorPrivate *priv;
- GtkCList *clist;
- ReminderData *rdata;
- int sel;
-
- priv = ee->priv;
-
- clist = GTK_CLIST (priv->reminder_list);
- if (!clist->selection)
- return;
-
- event_editor_set_changed (ee, TRUE);
-
- sel = GPOINTER_TO_INT (clist->selection->data);
-
- rdata = gtk_clist_get_row_data (clist, sel);
-
- if (rdata->status == EXISTING_ALARM) {
- const char *uid;
-
- uid = cal_component_alarm_get_uid (rdata->alarm);
- cal_component_remove_alarm (priv->comp, uid);
- }
- cal_component_alarm_free (rdata->alarm);
- g_free (rdata);
-
- gtk_clist_remove (clist, sel);
- if (sel >= clist->rows)
- sel--;
-
- if (clist->rows > 0)
- gtk_clist_select_row (clist, sel, 0);
- else
- gtk_widget_set_sensitive (priv->reminder_delete, FALSE);
-}
-
-
-/* Builds a static string out of an exception date */
-static char *
-get_exception_string (time_t t)
-{
- static char buf[256];
-
- strftime (buf, sizeof (buf), _("%a %b %d %Y"), localtime (&t));
- return buf;
-}
-
-/* Appends an exception date to the list */
-static void
-append_exception (EventEditor *ee, time_t t)
-{
- EventEditorPrivate *priv;
- time_t *tt;
- char *c[1];
- int i;
- GtkCList *clist;
-
- priv = ee->priv;
-
- tt = g_new (time_t, 1);
- *tt = t;
-
- clist = GTK_CLIST (priv->recurrence_exception_list);
-
- gtk_signal_handler_block_by_data (GTK_OBJECT (clist), ee);
-
- c[0] = get_exception_string (t);
- i = gtk_clist_append (clist, c);
-
- gtk_clist_set_row_data (clist, i, tt);
-
- gtk_clist_select_row (clist, i, 0);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (clist), ee);
-
- e_date_edit_set_time (E_DATE_EDIT (priv->recurrence_exception_date), t);
-
- gtk_widget_set_sensitive (priv->recurrence_exception_modify, TRUE);
- gtk_widget_set_sensitive (priv->recurrence_exception_delete, TRUE);
-}
-
-
-/* Callback for the "add exception" button */
-static void
-recurrence_exception_add_cb (GtkWidget *widget, EventEditor *ee)
-{
- EventEditorPrivate *priv;
- time_t t;
-
- priv = ee->priv;
-
- event_editor_set_changed (ee, TRUE);
- t = e_date_edit_get_time (E_DATE_EDIT (priv->recurrence_exception_date));
- append_exception (ee, t);
- preview_recur (ee);
-}
-
-/* Callback for the "modify exception" button */
-static void
-recurrence_exception_modify_cb (GtkWidget *widget, EventEditor *ee)
-{
- EventEditorPrivate *priv;
- GtkCList *clist;
- time_t *t;
- int sel;
-
- priv = ee->priv;
-
- clist = GTK_CLIST (priv->recurrence_exception_list);
- if (!clist->selection)
- return;
-
- event_editor_set_changed (ee, TRUE);
-
- sel = GPOINTER_TO_INT (clist->selection->data);
-
- t = gtk_clist_get_row_data (clist, sel);
- *t = e_date_edit_get_time (E_DATE_EDIT (priv->recurrence_exception_date));
-
- gtk_clist_set_text (clist, sel, 0, get_exception_string (*t));
-
- preview_recur (ee);
-}
-
-/* Callback for the "delete exception" button */
-static void
-recurrence_exception_delete_cb (GtkWidget *widget, EventEditor *ee)
-{
- EventEditorPrivate *priv;
- GtkCList *clist;
- int sel;
- time_t *t;
-
- priv = ee->priv;
-
- clist = GTK_CLIST (priv->recurrence_exception_list);
- if (!clist->selection)
- return;
-
- event_editor_set_changed (ee, TRUE);
-
- sel = GPOINTER_TO_INT (clist->selection->data);
-
- t = gtk_clist_get_row_data (clist, sel);
- g_assert (t != NULL);
- g_free (t);
-
- gtk_clist_remove (clist, sel);
- if (sel >= clist->rows)
- sel--;
-
- if (clist->rows > 0)
- gtk_clist_select_row (clist, sel, 0);
- else {
- gtk_widget_set_sensitive (priv->recurrence_exception_modify, FALSE);
- gtk_widget_set_sensitive (priv->recurrence_exception_delete, FALSE);
- }
-
- preview_recur (ee);
-}
-
-/* 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
-recurrence_exception_select_row_cb (GtkCList *clist, gint row, gint col, GdkEvent *event,
- gpointer data)
-{
- EventEditor *ee;
- EventEditorPrivate *priv;
- time_t *t;
-
- ee = EVENT_EDITOR (data);
- priv = ee->priv;
-
- t = gtk_clist_get_row_data (clist, row);
- g_assert (t != NULL);
-
- e_date_edit_set_time (E_DATE_EDIT (priv->recurrence_exception_date), *t);
-}
-
-GtkWidget *
-make_date_edit (void)
-{
- return date_edit_new (TRUE, TRUE);
-}
-
-
-GtkWidget *
-make_spin_button (int val, int low, int high)
-{
- GtkAdjustment *adj;
- GtkWidget *spin;
-
- adj = GTK_ADJUSTMENT (gtk_adjustment_new (val, low, high, 1, 10, 10));
- spin = gtk_spin_button_new (adj, 0.5, 0);
- gtk_widget_set_usize (spin, 60, 0);
-
- return spin;
-}
-
-
-/* This is called when most fields are changed (except those which already
- have signal handlers). It just sets the "changed" flag. */
-static void
-field_changed (GtkWidget *widget,
- EventEditor *ee)
-{
- EventEditorPrivate *priv;
-
- g_return_if_fail (IS_EVENT_EDITOR (ee));
-
- priv = ee->priv;
-
- event_editor_set_changed (ee, TRUE);
-}
-
-
-static void
-event_editor_set_changed (EventEditor *ee,
- gboolean changed)
-{
- EventEditorPrivate *priv;
-
- priv = ee->priv;
-
-#if 0
- g_print ("In event_editor_set_changed: %s\n",
- changed ? "TRUE" : "FALSE");
-#endif
-
- priv->changed = changed;
-
- if (priv->app)
- gnome_property_box_set_state (GNOME_PROPERTY_BOX (priv->app), changed);
-}
-
-
-/* This checks if the "changed" field is set, and if so it prompts to save
- the changes using a "Save/Discard/Cancel" modal dialog. It then saves the
- changes if requested. It returns TRUE if the dialog should now be closed. */
-static gboolean
-prompt_to_save_changes (EventEditor *ee)
-{
- EventEditorPrivate *priv;
-
- priv = ee->priv;
-
- if (!priv->changed)
- return TRUE;
-
- switch (save_component_dialog (GTK_WINDOW (priv->app))) {
- case 0: /* Save */
- /* FIXME: If an error occurs here, we should popup a dialog
- and then return FALSE. */
- save_event_object (ee);
- return TRUE;
- case 1: /* Discard */
- return TRUE;
- case 2: /* Cancel */
- default:
- return FALSE;
- break;
- }
-}
-
-static void
-categories_clicked (GtkWidget *button, EventEditor *ee)
-{
- char *categories;
- GnomeDialog *dialog;
- int result;
- GtkWidget *entry;
-
- entry = ee->priv->categories;
- categories = e_utf8_gtk_entry_get_text (GTK_ENTRY (entry));
-
- dialog = GNOME_DIALOG (e_categories_new (categories));
- result = gnome_dialog_run (dialog);
- g_free (categories);
-
- if (result == 0) {
- gtk_object_get (GTK_OBJECT (dialog),
- "categories", &categories,
- NULL);
- e_utf8_gtk_entry_set_text (GTK_ENTRY (entry), categories);
- g_free (categories);
- }
- gtk_object_destroy (GTK_OBJECT (dialog));
-}
diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c
index 96f88d79a7..46cc26292f 100644
--- a/calendar/gui/gnome-cal.c
+++ b/calendar/gui/gnome-cal.c
@@ -40,10 +40,10 @@
#include "widgets/misc/e-search-bar.h"
#include "widgets/misc/e-filter-bar.h"
#include "dialogs/alarm-notify-dialog.h"
+#include "dialogs/event-editor.h"
#include "e-calendar-table.h"
#include "e-day-view.h"
#include "e-week-view.h"
-#include "event-editor.h"
#include "gnome-cal.h"
#include "component-factory.h"
#include "calendar-commands.h"
@@ -1308,11 +1308,11 @@ gnome_calendar_edit_object (GnomeCalendar *gcal, CalComponent *comp)
GTK_SIGNAL_FUNC (editor_closed_cb),
ec);
- event_editor_set_cal_client (EVENT_EDITOR (ee), priv->client);
- event_editor_set_event_object (EVENT_EDITOR (ee), comp);
+ comp_editor_set_cal_client (COMP_EDITOR (ee), priv->client);
+ comp_editor_edit_comp (COMP_EDITOR (ee), comp);
}
- event_editor_focus (ee);
+ comp_editor_focus (COMP_EDITOR (ee));
}
/**