diff options
author | Matthew Barnes <mbarnes@src.gnome.org> | 2009-01-21 10:52:05 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@src.gnome.org> | 2009-01-21 10:52:05 +0800 |
commit | ab00f5b08adb1d74a0c70d935a32ffd982e86f34 (patch) | |
tree | 45bfaa44682bc3eee5a2ad8a64112b248767af5b /calendar/gui | |
parent | 5a1c48696363e3f3c7ffe11bdffdcad6557f811a (diff) | |
download | gsoc2013-evolution-ab00f5b08adb1d74a0c70d935a32ffd982e86f34.tar.gz gsoc2013-evolution-ab00f5b08adb1d74a0c70d935a32ffd982e86f34.tar.zst gsoc2013-evolution-ab00f5b08adb1d74a0c70d935a32ffd982e86f34.zip |
Merge revisions 37075:37107 from trunk.
svn path=/branches/kill-bonobo/; revision=37112
Diffstat (limited to 'calendar/gui')
30 files changed, 829 insertions, 200 deletions
diff --git a/calendar/gui/apps_evolution_calendar.schemas.in b/calendar/gui/apps_evolution_calendar.schemas.in index 41bdca1b0e..7f370d1a19 100644 --- a/calendar/gui/apps_evolution_calendar.schemas.in +++ b/calendar/gui/apps_evolution_calendar.schemas.in @@ -538,6 +538,18 @@ </locale> </schema> + <schema> + <key>/schemas/apps/evolution/calendar/display/day_view_show_week_number</key> + <applyto>/apps/evolution/calendar/display/day_view_show_week_number</applyto> + <owner>evolution-calendar</owner> + <type>bool</type> + <default>false</default> + <locale name="C"> + <short>Show week number in Day and Work Week View</short> + <long>Whether to show week number in the Day and Work Week View.</long> + </locale> + </schema> + <!-- Date navigator --> <schema> diff --git a/calendar/gui/calendar-config-keys.h b/calendar/gui/calendar-config-keys.h index 9d50d21c86..05feb18d00 100644 --- a/calendar/gui/calendar-config-keys.h +++ b/calendar/gui/calendar-config-keys.h @@ -61,6 +61,7 @@ G_BEGIN_DECLS #define CALENDAR_CONFIG_COMPRESS_WEEKEND CALENDAR_CONFIG_PREFIX "/display/compress_weekend" #define CALENDAR_CONFIG_SHOW_EVENT_END CALENDAR_CONFIG_PREFIX "/display/show_event_end" #define CALENDAR_CONFIG_WORKING_DAYS CALENDAR_CONFIG_PREFIX "/display/working_days" +#define CALENDAR_CONFIG_DV_WEEK_NUMBER CALENDAR_CONFIG_PREFIX "/display/day_view_show_week_number" #define CALENDAR_CONFIG_DAY_SECOND_ZONE CALENDAR_CONFIG_PREFIX "/display/day_second_zone" #define CALENDAR_CONFIG_DAY_SECOND_ZONES_LIST CALENDAR_CONFIG_PREFIX "/display/day_second_zones" #define CALENDAR_CONFIG_DAY_SECOND_ZONES_MAX CALENDAR_CONFIG_PREFIX "/display/day_second_zones_max" @@ -95,6 +96,11 @@ G_BEGIN_DECLS #define CALENDAR_CONFIG_TEMPLATE CALENDAR_CONFIG_PREFIX"/publish/template" #define CALENDAR_CONFIG_SAVE_DIR CALENDAR_CONFIG_PREFIX"/audio_dir" + +/* Birthday & Anniversary reminder */ +#define CALENDAR_CONFIG_BA_REMINDER CALENDAR_CONFIG_PREFIX "/other/use_ba_reminder" +#define CALENDAR_CONFIG_BA_REMINDER_INTERVAL CALENDAR_CONFIG_PREFIX "/other/ba_reminder_interval" +#define CALENDAR_CONFIG_BA_REMINDER_UNITS CALENDAR_CONFIG_PREFIX "/other/ba_reminder_units" G_END_DECLS #endif diff --git a/calendar/gui/calendar-config.c b/calendar/gui/calendar-config.c index 60df6a9285..b5928b6523 100644 --- a/calendar/gui/calendar-config.c +++ b/calendar/gui/calendar-config.c @@ -106,6 +106,22 @@ units_to_string (CalUnits units) } } +/* opposite function to 'units_to_string' */ +static CalUnits +string_to_units (const char *units) +{ + CalUnits res; + + if (units && !strcmp (units, "days")) + res = CAL_DAYS; + else if (units && !strcmp (units, "hours")) + res = CAL_HOURS; + else + res = CAL_MINUTES; + + return res; +} + /* * Calendar Settings. */ @@ -678,6 +694,36 @@ calendar_config_add_notification_marcus_bains (GConfClientNotifyFunc func, gpoin *not_tcolor = gconf_client_notify_add (config, CALENDAR_CONFIG_MARCUS_BAINS_COLOR_TIMEBAR, func, data, NULL, NULL); } +/* Whether we show week number in the Day View. */ +gboolean +calendar_config_get_dview_show_week_no (void) +{ + calendar_config_init (); + + return gconf_client_get_bool (config, CALENDAR_CONFIG_DV_WEEK_NUMBER, NULL); +} + + +void +calendar_config_set_dview_show_week_no (gboolean show_week_no) +{ + calendar_config_init (); + + gconf_client_set_bool (config, CALENDAR_CONFIG_DV_WEEK_NUMBER, show_week_no, NULL); +} + +guint +calendar_config_add_notification_dview_show_week_no (GConfClientNotifyFunc func, gpointer data) +{ + guint id; + + calendar_config_init (); + + id = gconf_client_notify_add (config, CALENDAR_CONFIG_DV_WEEK_NUMBER, func, data, NULL, NULL); + + return id; +} + /* Whether we show week numbers in the Date Navigator. */ gboolean calendar_config_get_dnav_show_week_no (void) @@ -1424,13 +1470,7 @@ calendar_config_get_default_reminder_units (void) calendar_config_init (); units = gconf_client_get_string (config, CALENDAR_CONFIG_DEFAULT_REMINDER_UNITS, NULL); - - if (units && !strcmp (units, "days")) - cu = CAL_DAYS; - else if (units && !strcmp (units, "hours")) - cu = CAL_HOURS; - else - cu = CAL_MINUTES; + cu = string_to_units (units); g_free (units); return cu; @@ -1451,6 +1491,59 @@ calendar_config_set_default_reminder_units (CalUnits units) } /** + * calendar_config_get_ba_reminder: + * Retrieves setup of the Birthdays & Anniversaries reminder. + * + * @interval: Retrieves the interval setup for the reminder; can be NULL. + * @units: Retrieves units for the interval; can be NULL. + * + * Returns whether the reminder is on or off. The values for interval and/or units + * are retrieved even when returns FALSE. + **/ +gboolean +calendar_config_get_ba_reminder (int *interval, CalUnits *units) +{ + calendar_config_init (); + + if (interval) { + *interval = gconf_client_get_int (config, CALENDAR_CONFIG_BA_REMINDER_INTERVAL, NULL); + } + + if (units) { + char *str; + + str = gconf_client_get_string (config, CALENDAR_CONFIG_BA_REMINDER_UNITS, NULL); + *units = string_to_units (str); + g_free (str); + } + + return gconf_client_get_bool (config, CALENDAR_CONFIG_BA_REMINDER, NULL); +} + +/** + * calendar_config_set_ba_reminder: + * Stores new values for Birthdays & Anniversaries reminder to GConf. Only those, which are not NULL. + * + * @enabled: The enabled state; can be NULL. + * @interval: The reminder interval; can be NULL. + * @units: The units of the reminder; can be NULL. + **/ +void +calendar_config_set_ba_reminder (gboolean *enabled, int *interval, CalUnits *units) +{ + calendar_config_init (); + + if (enabled) + gconf_client_set_bool (config, CALENDAR_CONFIG_BA_REMINDER, *enabled, NULL); + + if (interval) + gconf_client_set_int (config, CALENDAR_CONFIG_BA_REMINDER_INTERVAL, *interval, NULL); + + if (units) + gconf_client_set_string (config, CALENDAR_CONFIG_BA_REMINDER_UNITS, units_to_string (*units), NULL); +} + +/** * calendar_config_get_hide_completed_tasks_sexp: * * @get_completed: Whether to form subexpression that diff --git a/calendar/gui/calendar-config.h b/calendar/gui/calendar-config.h index 495b5c591b..0d79d2050c 100644 --- a/calendar/gui/calendar-config.h +++ b/calendar/gui/calendar-config.h @@ -154,6 +154,11 @@ gboolean calendar_config_get_dnav_show_week_no (void); void calendar_config_set_dnav_show_week_no (gboolean show_week_no); guint calendar_config_add_notification_dnav_show_week_no (GConfClientNotifyFunc func, gpointer data); +/* Whether we show week number in the day view. */ +gboolean calendar_config_get_dview_show_week_no (void); +void calendar_config_set_dview_show_week_no (gboolean show_week_no); +guint calendar_config_add_notification_dview_show_week_no (GConfClientNotifyFunc func, gpointer data); + /* The positions of the panes in the normal and month views. */ gint calendar_config_get_hpane_pos (void); void calendar_config_set_hpane_pos (gint hpane_pos); @@ -265,4 +270,8 @@ char * calendar_config_get_day_second_zone (void); void calendar_config_select_day_second_zone (void); guint calendar_config_add_notification_day_second_zone (GConfClientNotifyFunc func, gpointer data); +/* Birthdays & Anniversaries reminder settings */ +gboolean calendar_config_get_ba_reminder (int *interval, CalUnits *units); +void calendar_config_set_ba_reminder (gboolean *enabled, int *interval, CalUnits *units); + #endif /* _CALENDAR_CONFIG_H_ */ diff --git a/calendar/gui/comp-editor-factory.c b/calendar/gui/comp-editor-factory.c index a6694bbbcc..8b9e33d58f 100644 --- a/calendar/gui/comp-editor-factory.c +++ b/calendar/gui/comp-editor-factory.c @@ -417,6 +417,12 @@ cal_opened_cb (ECal *client, ECalendarStatus status, gpointer data) "%s", _("Permission denied to open the calendar")); break; + case E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED: + dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, + GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, + "%s", _("Authentication Required")); + break; + case E_CALENDAR_STATUS_AUTHENTICATION_FAILED : dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, diff --git a/calendar/gui/comp-util.c b/calendar/gui/comp-util.c index 0e63a9c336..9504c7bda7 100644 --- a/calendar/gui/comp-util.c +++ b/calendar/gui/comp-util.c @@ -530,3 +530,80 @@ cal_comp_selection_get_string_list (GtkSelectionData *data) return list; } + +static void +datetime_to_zone (ECal *client, ECalComponentDateTime *date, const char *tzid) +{ + icaltimezone *from, *to; + + g_return_if_fail (date != NULL); + + if (date->tzid == NULL || tzid == NULL || + date->tzid == tzid || g_str_equal (date->tzid, tzid)) + return; + + from = icaltimezone_get_builtin_timezone_from_tzid (date->tzid); + if (!from) { + if (!e_cal_get_timezone (client, date->tzid, &from, NULL)) + g_warning ("%s: Could not get timezone from server: %s", G_STRFUNC, date->tzid ? date->tzid : ""); + } + + to = icaltimezone_get_builtin_timezone_from_tzid (tzid); + if (!to) { + /* do not check failure here, maybe the zone is not available there */ + e_cal_get_timezone (client, tzid, &to, NULL); + } + + icaltimezone_convert_time (date->value, from, to); + date->tzid = tzid; +} + +/** + * cal_comp_set_dtstart_with_oldzone: + * Changes 'dtstart' of the component, but converts time to the old timezone. + * @param client ECal structure, to retrieve timezone from, when required. + * @param comp Component, where make the change. + * @param pdate Value, to change to. + **/ +void +cal_comp_set_dtstart_with_oldzone (ECal *client, ECalComponent *comp, const ECalComponentDateTime *pdate) +{ + ECalComponentDateTime olddate, date; + + g_return_if_fail (comp != NULL); + g_return_if_fail (pdate != NULL); + + e_cal_component_get_dtstart (comp, &olddate); + + date = *pdate; + + datetime_to_zone (client, &date, olddate.tzid); + e_cal_component_set_dtstart (comp, &date); + + e_cal_component_free_datetime (&olddate); +} + +/** + * cal_comp_set_dtend_with_oldzone: + * Changes 'dtend' of the component, but converts time to the old timezone. + * @param client ECal structure, to retrieve timezone from, when required. + * @param comp Component, where make the change. + * @param pdate Value, to change to. + **/ +void +cal_comp_set_dtend_with_oldzone (ECal *client, ECalComponent *comp, const ECalComponentDateTime *pdate) +{ + ECalComponentDateTime olddate, date; + + g_return_if_fail (comp != NULL); + g_return_if_fail (pdate != NULL); + + e_cal_component_get_dtend (comp, &olddate); + + date = *pdate; + + datetime_to_zone (client, &date, olddate.tzid); + e_cal_component_set_dtend (comp, &date); + + e_cal_component_free_datetime (&olddate); +} diff --git a/calendar/gui/comp-util.h b/calendar/gui/comp-util.h index 5e471815c6..e4e200217e 100644 --- a/calendar/gui/comp-util.h +++ b/calendar/gui/comp-util.h @@ -54,4 +54,7 @@ ECalComponent *cal_comp_memo_new_with_defaults (ECal *client); void cal_comp_selection_set_string_list (GtkSelectionData *data, GSList *str_list); GSList *cal_comp_selection_get_string_list (GtkSelectionData *data); +void cal_comp_set_dtstart_with_oldzone (ECal *client, ECalComponent *comp, const ECalComponentDateTime *pdate); +void cal_comp_set_dtend_with_oldzone (ECal *client, ECalComponent *comp, const ECalComponentDateTime *pdate); + #endif diff --git a/calendar/gui/dialogs/cal-prefs-dialog.c b/calendar/gui/dialogs/cal-prefs-dialog.c index 38871c2f89..21ace5aea4 100644 --- a/calendar/gui/dialogs/cal-prefs-dialog.c +++ b/calendar/gui/dialogs/cal-prefs-dialog.c @@ -49,6 +49,7 @@ static const int hide_completed_units_map[] = { CAL_MINUTES, CAL_HOURS, CAL_DAYS, -1 }; +/* same is used for Birthdays & Anniversaries calendar */ static const int default_reminder_units_map[] = { CAL_MINUTES, CAL_HOURS, CAL_DAYS, -1 }; @@ -333,6 +334,12 @@ dnav_show_week_no_toggled (GtkToggleButton *toggle, CalendarPrefsDialog *prefs) } static void +dview_show_week_no_toggled (GtkToggleButton *toggle, CalendarPrefsDialog *prefs) +{ + calendar_config_set_dview_show_week_no (gtk_toggle_button_get_active (toggle)); +} + +static void hide_completed_tasks_toggled (GtkToggleButton *toggle, CalendarPrefsDialog *prefs) { gboolean hide; @@ -408,6 +415,34 @@ default_reminder_units_changed (GtkWidget *widget, CalendarPrefsDialog *prefs) } static void +ba_reminder_toggled (GtkToggleButton *toggle, CalendarPrefsDialog *prefs) +{ + gboolean enabled = gtk_toggle_button_get_active (toggle); + + calendar_config_set_ba_reminder (&enabled, NULL, NULL); +} + +static void +ba_reminder_interval_changed (GtkWidget *widget, CalendarPrefsDialog *prefs) +{ + const gchar *str; + int value; + + str = gtk_entry_get_text (GTK_ENTRY (widget)); + value = (int) g_ascii_strtod (str, NULL); + + calendar_config_set_ba_reminder (NULL, &value, NULL); +} + +static void +ba_reminder_units_changed (GtkWidget *widget, CalendarPrefsDialog *prefs) +{ + CalUnits units = e_dialog_combo_box_get (prefs->ba_reminder_units, default_reminder_units_map); + + calendar_config_set_ba_reminder (NULL, NULL, &units); +} + +static void alarms_selection_changed (ESourceSelector *selector, CalendarPrefsDialog *prefs) { ESourceList *source_list = prefs->alarms_list; @@ -483,6 +518,7 @@ setup_changes (CalendarPrefsDialog *prefs) g_signal_connect (G_OBJECT (prefs->show_end_times), "toggled", G_CALLBACK (show_end_times_toggled), prefs); g_signal_connect (G_OBJECT (prefs->compress_weekend), "toggled", G_CALLBACK (compress_weekend_toggled), prefs); g_signal_connect (G_OBJECT (prefs->dnav_show_week_no), "toggled", G_CALLBACK (dnav_show_week_no_toggled), prefs); + g_signal_connect (G_OBJECT (prefs->dview_show_week_no), "toggled", G_CALLBACK (dview_show_week_no_toggled), prefs); g_signal_connect (G_OBJECT (prefs->tasks_hide_completed), "toggled", G_CALLBACK (hide_completed_tasks_toggled), prefs); @@ -500,6 +536,11 @@ setup_changes (CalendarPrefsDialog *prefs) G_CALLBACK (default_reminder_interval_changed), prefs); g_signal_connect (G_OBJECT (prefs->default_reminder_units), "changed", G_CALLBACK (default_reminder_units_changed), prefs); + g_signal_connect (G_OBJECT (prefs->ba_reminder), "toggled", G_CALLBACK (ba_reminder_toggled), prefs); + g_signal_connect (G_OBJECT (prefs->ba_reminder_interval), "changed", + G_CALLBACK (ba_reminder_interval_changed), prefs); + g_signal_connect (G_OBJECT (prefs->ba_reminder_units), "changed", G_CALLBACK (ba_reminder_units_changed), prefs); + g_signal_connect (G_OBJECT (prefs->alarm_list_widget), "selection_changed", G_CALLBACK (alarms_selection_changed), prefs); @@ -593,6 +634,8 @@ show_config (CalendarPrefsDialog *prefs) gboolean sensitive, set = FALSE; icalcomponent *icalcomp, *dl_comp; char *location; + CalUnits units; + int interval; /* Timezone. */ location = calendar_config_get_timezone (); @@ -654,6 +697,9 @@ show_config (CalendarPrefsDialog *prefs) /* Date Navigator - Show Week Numbers. */ e_dialog_toggle_set (prefs->dnav_show_week_no, calendar_config_get_dnav_show_week_no ()); + /* Day/Work Week view - Show Week Number. */ + e_dialog_toggle_set (prefs->dview_show_week_no, calendar_config_get_dview_show_week_no ()); + /* Task list */ show_task_list_config (prefs); @@ -668,6 +714,13 @@ show_config (CalendarPrefsDialog *prefs) e_dialog_toggle_set (prefs->default_reminder, calendar_config_get_use_default_reminder ()); e_dialog_spin_set (prefs->default_reminder_interval, calendar_config_get_default_reminder_interval ()); e_dialog_combo_box_set (prefs->default_reminder_units, calendar_config_get_default_reminder_units (), default_reminder_units_map); + + /* Birthdays & Anniversaries reminder */ + set = calendar_config_get_ba_reminder (&interval, &units); + + e_dialog_toggle_set (prefs->ba_reminder, set); + e_dialog_spin_set (prefs->ba_reminder_interval, interval); + e_dialog_combo_box_set (prefs->ba_reminder_units, units, default_reminder_units_map); } /* plugin meta-data */ @@ -749,12 +802,16 @@ calendar_prefs_dialog_construct (CalendarPrefsDialog *prefs) prefs->default_reminder = glade_xml_get_widget (gui, "default_reminder"); prefs->default_reminder_interval = glade_xml_get_widget (gui, "default_reminder_interval"); prefs->default_reminder_units = glade_xml_get_widget (gui, "default_reminder_units"); + prefs->ba_reminder = glade_xml_get_widget (gui, "ba_reminder"); + prefs->ba_reminder_interval = glade_xml_get_widget (gui, "ba_reminder_interval"); + prefs->ba_reminder_units = glade_xml_get_widget (gui, "ba_reminder_units"); /* Display tab */ prefs->time_divisions = glade_xml_get_widget (gui, "time_divisions"); prefs->show_end_times = glade_xml_get_widget (gui, "show_end_times"); prefs->compress_weekend = glade_xml_get_widget (gui, "compress_weekend"); prefs->dnav_show_week_no = glade_xml_get_widget (gui, "dnav_show_week_no"); + prefs->dview_show_week_no = glade_xml_get_widget (gui, "dview_show_week_no"); prefs->tasks_due_today_color = glade_xml_get_widget (gui, "tasks_due_today_color"); prefs->tasks_overdue_color = glade_xml_get_widget (gui, "tasks_overdue_color"); prefs->tasks_hide_completed = glade_xml_get_widget (gui, "tasks_hide_completed"); diff --git a/calendar/gui/dialogs/cal-prefs-dialog.glade b/calendar/gui/dialogs/cal-prefs-dialog.glade index 0282d17d4d..b8947b4c44 100644 --- a/calendar/gui/dialogs/cal-prefs-dialog.glade +++ b/calendar/gui/dialogs/cal-prefs-dialog.glade @@ -950,6 +950,98 @@ Days</property> <property name="fill">True</property> </packing> </child> + + <child> + <widget class="GtkHBox" id="hbox25"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">4</property> + + <child> + <widget class="GtkCheckButton" id="ba_reminder"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">Show a _reminder</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkSpinButton" id="ba_reminder_interval"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="climb_rate">1</property> + <property name="digits">0</property> + <property name="numeric">False</property> + <property name="update_policy">GTK_UPDATE_ALWAYS</property> + <property name="snap_to_ticks">False</property> + <property name="wrap">False</property> + <property name="adjustment">0 0 9999 1 10 10</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkComboBox" id="ba_reminder_units"> + <property name="visible">True</property> + <property name="items" translatable="yes">Minutes +Hours +Days</property> + <property name="add_tearoffs">False</property> + <property name="focus_on_click">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="ba_reminder_label"> + <property name="visible">True</property> + <property name="label" translatable="yes">before every anniversary/birthday</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> </widget> <packing> <property name="padding">0</property> @@ -1176,6 +1268,24 @@ Days</property> <property name="fill">False</property> </packing> </child> + <child> + <widget class="GtkCheckButton" id="dview_show_week_no"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">Show week n_umber in Day and Work Week View</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> </widget> <packing> <property name="padding">0</property> diff --git a/calendar/gui/dialogs/cal-prefs-dialog.h b/calendar/gui/dialogs/cal-prefs-dialog.h index bb51d9d50d..895a263986 100644 --- a/calendar/gui/dialogs/cal-prefs-dialog.h +++ b/calendar/gui/dialogs/cal-prefs-dialog.h @@ -55,12 +55,16 @@ struct _CalendarPrefsDialog { GtkWidget *default_reminder; GtkWidget *default_reminder_interval; GtkWidget *default_reminder_units; + GtkWidget *ba_reminder; + GtkWidget *ba_reminder_interval; + GtkWidget *ba_reminder_units; /* Display tab */ GtkWidget *time_divisions; GtkWidget *show_end_times; GtkWidget *compress_weekend; GtkWidget *dnav_show_week_no; + GtkWidget *dview_show_week_no; GtkWidget *tasks_due_today_color; GtkWidget *tasks_overdue_color; GtkWidget *tasks_hide_completed; diff --git a/calendar/gui/dialogs/comp-editor.c b/calendar/gui/dialogs/comp-editor.c index 5d9298cd18..e9967eccaf 100644 --- a/calendar/gui/dialogs/comp-editor.c +++ b/calendar/gui/dialogs/comp-editor.c @@ -171,7 +171,7 @@ static void comp_editor_show_help (CompEditor *editor); static void setup_widgets (CompEditor *editor); static void real_edit_comp (CompEditor *editor, ECalComponent *comp); -static gboolean real_send_comp (CompEditor *editor, ECalComponentItipMethod method); +static gboolean real_send_comp (CompEditor *editor, ECalComponentItipMethod method, gboolean strip_alarms); static gboolean prompt_and_save_changes (CompEditor *editor, gboolean send); static void close_dialog (CompEditor *editor); @@ -897,6 +897,7 @@ save_comp_with_send (CompEditor *editor) CompEditorFlags flags; gboolean send; gboolean delegate; + gboolean strip_alarms = TRUE; priv = editor->priv; @@ -916,18 +917,18 @@ save_comp_with_send (CompEditor *editor) if (!save_comp (editor)) return FALSE; - if ((delegate && !e_cal_get_save_schedules (priv->client)) || (send && send_component_dialog ((GtkWindow *) editor, priv->client, priv->comp, !priv->existing_org))) { + if ((delegate && !e_cal_get_save_schedules (priv->client)) || (send && send_component_dialog ((GtkWindow *) editor, priv->client, priv->comp, !priv->existing_org, &strip_alarms))) { if ((itip_organizer_is_user (priv->comp, priv->client) || itip_sentby_is_user (priv->comp))) { if (e_cal_component_get_vtype (priv->comp) == E_CAL_COMPONENT_JOURNAL) - return comp_editor_send_comp (editor, E_CAL_COMPONENT_METHOD_PUBLISH); + return comp_editor_send_comp (editor, E_CAL_COMPONENT_METHOD_PUBLISH, strip_alarms); else - return comp_editor_send_comp (editor, E_CAL_COMPONENT_METHOD_REQUEST); + return comp_editor_send_comp (editor, E_CAL_COMPONENT_METHOD_REQUEST, strip_alarms); } else { - if (!comp_editor_send_comp (editor, E_CAL_COMPONENT_METHOD_REQUEST)) + if (!comp_editor_send_comp (editor, E_CAL_COMPONENT_METHOD_REQUEST, strip_alarms)) return FALSE; if (delegate) - return comp_editor_send_comp (editor, E_CAL_COMPONENT_METHOD_REPLY); + return comp_editor_send_comp (editor, E_CAL_COMPONENT_METHOD_REPLY, strip_alarms); } } @@ -3083,7 +3084,7 @@ get_users_from_memo_comp (ECalComponent *comp, GList **users) } static gboolean -real_send_comp (CompEditor *editor, ECalComponentItipMethod method) +real_send_comp (CompEditor *editor, ECalComponentItipMethod method, gboolean strip_alarms) { CompEditorPrivate *priv; CompEditorFlags flags; @@ -3129,7 +3130,7 @@ real_send_comp (CompEditor *editor, ECalComponentItipMethod method) if (!e_cal_component_has_attachments (priv->comp) || e_cal_get_static_capability (priv->client, CAL_STATIC_CAPABILITY_CREATE_MESSAGES)) { if (itip_send_comp (method, send_comp, priv->client, - NULL, NULL, users)) { + NULL, NULL, users, strip_alarms)) { g_object_unref (send_comp); return TRUE; } @@ -3150,7 +3151,7 @@ real_send_comp (CompEditor *editor, ECalComponentItipMethod method) /* mime_attach_list is freed by itip_send_comp */ mime_attach_list = comp_editor_get_mime_attach_list (editor); if (itip_send_comp (method, send_comp, priv->client, - NULL, mime_attach_list, users)) { + NULL, mime_attach_list, users, strip_alarms)) { save_comp (editor); g_object_unref (send_comp); return TRUE; @@ -3272,7 +3273,7 @@ comp_editor_delete_comp (CompEditor *editor) * **/ gboolean -comp_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method) +comp_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method, gboolean strip_alarms) { CompEditorClass *class; @@ -3281,7 +3282,7 @@ comp_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method) class = COMP_EDITOR_GET_CLASS (editor); if (class->send_comp) - return class->send_comp (editor, method); + return class->send_comp (editor, method, strip_alarms); return FALSE; } diff --git a/calendar/gui/dialogs/comp-editor.h b/calendar/gui/dialogs/comp-editor.h index 23a8d3acea..7fdc17ba16 100644 --- a/calendar/gui/dialogs/comp-editor.h +++ b/calendar/gui/dialogs/comp-editor.h @@ -67,7 +67,7 @@ struct _CompEditorClass { /* Virtual functions */ void (*edit_comp) (CompEditor *page, ECalComponent *comp); void (*object_created) (CompEditor *page); - gboolean (*send_comp) (CompEditor *page, ECalComponentItipMethod method); + gboolean (*send_comp) (CompEditor *page, ECalComponentItipMethod method, gboolean strip_alarms); void (*show_categories) (CompEditor *editor, gboolean visible); void (*show_role) (CompEditor *editor, gboolean visible); @@ -131,7 +131,8 @@ gboolean comp_editor_save_comp (CompEditor *editor, gboolean send); void comp_editor_delete_comp (CompEditor *editor); gboolean comp_editor_send_comp (CompEditor *editor, - ECalComponentItipMethod method); + ECalComponentItipMethod method, + gboolean strip_alarms); GSList * comp_editor_get_mime_attach_list(CompEditor *editor); gboolean comp_editor_close (CompEditor *editor); diff --git a/calendar/gui/dialogs/event-editor.c b/calendar/gui/dialogs/event-editor.c index ef94f631d0..72cbf37823 100644 --- a/calendar/gui/dialogs/event-editor.c +++ b/calendar/gui/dialogs/event-editor.c @@ -98,7 +98,7 @@ static const gchar *ui = "</ui>"; static void event_editor_edit_comp (CompEditor *editor, ECalComponent *comp); -static gboolean event_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method); +static gboolean event_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method, gboolean strip_alarms); G_DEFINE_TYPE (EventEditor, event_editor, TYPE_COMP_EDITOR) @@ -619,7 +619,7 @@ event_editor_edit_comp (CompEditor *editor, ECalComponent *comp) } static gboolean -event_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method) +event_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method, gboolean strip_alarms) { EventEditorPrivate *priv; ECalComponent *comp = NULL; @@ -638,7 +638,7 @@ event_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method) client = e_meeting_store_get_e_cal (priv->model); result = itip_send_comp (E_CAL_COMPONENT_METHOD_CANCEL, comp, - client, NULL, NULL, NULL); + client, NULL, NULL, NULL, strip_alarms); g_object_unref (comp); return result; @@ -646,7 +646,7 @@ event_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method) parent: if (COMP_EDITOR_CLASS (event_editor_parent_class)->send_comp) - return COMP_EDITOR_CLASS (event_editor_parent_class)->send_comp (editor, method); + return COMP_EDITOR_CLASS (event_editor_parent_class)->send_comp (editor, method, strip_alarms); return FALSE; } diff --git a/calendar/gui/dialogs/send-comp.c b/calendar/gui/dialogs/send-comp.c index 11d6e74757..a7d87c47f4 100644 --- a/calendar/gui/dialogs/send-comp.c +++ b/calendar/gui/dialogs/send-comp.c @@ -26,11 +26,44 @@ #include <config.h> #endif +#include <glib/gi18n-lib.h> #include "e-util/e-error.h" #include "send-comp.h" +static gboolean +have_nonprocedural_alarm (ECalComponent *comp) +{ + GList *uids, *l; + + g_return_val_if_fail (comp != NULL, FALSE); + + uids = e_cal_component_get_alarm_uids (comp); + + for (l = uids; l; l = l->next) { + ECalComponentAlarm *alarm; + ECalComponentAlarmAction action = E_CAL_COMPONENT_ALARM_UNKNOWN; + + alarm = e_cal_component_get_alarm (comp, (const char *)l->data); + if (alarm) { + e_cal_component_alarm_get_action (alarm, &action); + e_cal_component_alarm_free (alarm); + + if (action != E_CAL_COMPONENT_ALARM_NONE && + action != E_CAL_COMPONENT_ALARM_PROCEDURE && + action != E_CAL_COMPONENT_ALARM_UNKNOWN) { + cal_obj_uid_list_free (uids); + return TRUE; + } + } + } + + cal_obj_uid_list_free (uids); + + return FALSE; +} + /** * send_component_dialog: * @@ -40,11 +73,14 @@ * Return value: TRUE if the user clicked Yes, FALSE otherwise. **/ gboolean -send_component_dialog (GtkWindow *parent, ECal *client, ECalComponent *comp, gboolean new) +send_component_dialog (GtkWindow *parent, ECal *client, ECalComponent *comp, gboolean new, gboolean *strip_alarms) { ECalComponentVType vtype; const char *id; + if (strip_alarms) + *strip_alarms = TRUE; + if (e_cal_get_save_schedules (client)) return FALSE; @@ -72,10 +108,32 @@ send_component_dialog (GtkWindow *parent, ECal *client, ECalComponent *comp, gbo return FALSE; } - if (e_error_run (parent, id, NULL) == GTK_RESPONSE_YES) - return TRUE; - else - return FALSE; + if (strip_alarms && have_nonprocedural_alarm (comp)) { + GtkWidget *dialog, *checkbox, *align; + gboolean res; + + dialog = e_error_new (parent, id, NULL); + checkbox = gtk_check_button_new_with_label (_("Send my alarms with this event")); + align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0); + gtk_container_add (GTK_CONTAINER (align), checkbox); + gtk_widget_show (checkbox); + gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->vbox), align, TRUE, TRUE, 6); + gtk_widget_show (align); + + res = gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_YES; + + if (res) + *strip_alarms = !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbox)); + + gtk_widget_destroy (GTK_WIDGET (dialog)); + + return res; + } else { + if (e_error_run (parent, id, NULL) == GTK_RESPONSE_YES) + return TRUE; + else + return FALSE; + } } gboolean diff --git a/calendar/gui/dialogs/send-comp.h b/calendar/gui/dialogs/send-comp.h index 4a1a6c55ab..21b310947a 100644 --- a/calendar/gui/dialogs/send-comp.h +++ b/calendar/gui/dialogs/send-comp.h @@ -28,7 +28,7 @@ #include <libecal/e-cal.h> #include <libecal/e-cal-component.h> -gboolean send_component_dialog (GtkWindow *parent, ECal *client, ECalComponent *comp, gboolean new); +gboolean send_component_dialog (GtkWindow *parent, ECal *client, ECalComponent *comp, gboolean new, gboolean *strip_alarms); gboolean send_component_prompt_subject (GtkWindow *parent, ECal *client, ECalComponent *comp); #endif diff --git a/calendar/gui/dialogs/task-editor.c b/calendar/gui/dialogs/task-editor.c index 3ef5b4bcf2..656e7b4836 100644 --- a/calendar/gui/dialogs/task-editor.c +++ b/calendar/gui/dialogs/task-editor.c @@ -87,7 +87,7 @@ static const gchar *ui = "</ui>"; static void task_editor_edit_comp (CompEditor *editor, ECalComponent *comp); -static gboolean task_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method); +static gboolean task_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method, gboolean strip_alarms); G_DEFINE_TYPE (TaskEditor, task_editor, TYPE_COMP_EDITOR) @@ -445,7 +445,7 @@ task_editor_edit_comp (CompEditor *editor, ECalComponent *comp) } static gboolean -task_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method) +task_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method, gboolean strip_alarms) { TaskEditorPrivate *priv; ECalComponent *comp = NULL; @@ -464,7 +464,7 @@ task_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method) client = e_meeting_store_get_e_cal (priv->model); result = itip_send_comp (E_CAL_COMPONENT_METHOD_CANCEL, comp, - client, NULL, NULL, NULL); + client, NULL, NULL, NULL, strip_alarms); g_object_unref (comp); if (!result) @@ -473,7 +473,7 @@ task_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method) parent: if (COMP_EDITOR_CLASS (task_editor_parent_class)->send_comp) - return COMP_EDITOR_CLASS (task_editor_parent_class)->send_comp (editor, method); + return COMP_EDITOR_CLASS (task_editor_parent_class)->send_comp (editor, method, strip_alarms); return FALSE; } diff --git a/calendar/gui/e-cal-model-calendar.c b/calendar/gui/e-cal-model-calendar.c index 27c73dd12c..7f5d7b55c6 100644 --- a/calendar/gui/e-cal-model-calendar.c +++ b/calendar/gui/e-cal-model-calendar.c @@ -382,8 +382,10 @@ ecmc_set_value_at (ETableModel *etm, int col, int row, const void *value) } if (e_cal_modify_object (comp_data->client, comp_data->icalcomp, mod, NULL)) { + gboolean strip_alarms = TRUE; + if (itip_organizer_is_user (comp, comp_data->client) && - send_component_dialog (NULL, comp_data->client, comp, FALSE)) { + send_component_dialog (NULL, comp_data->client, comp, FALSE, &strip_alarms)) { ECalComponent *send_comp = NULL; if (mod == CALOBJ_MOD_ALL && e_cal_component_is_instance (comp)) { @@ -403,7 +405,7 @@ ecmc_set_value_at (ETableModel *etm, int col, int row, const void *value) } itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, send_comp ? send_comp : comp, - comp_data->client, NULL, NULL, NULL); + comp_data->client, NULL, NULL, NULL, strip_alarms); if (send_comp) g_object_unref (send_comp); diff --git a/calendar/gui/e-cal-model.c b/calendar/gui/e-cal-model.c index acbee0cd26..850807ed05 100644 --- a/calendar/gui/e-cal-model.c +++ b/calendar/gui/e-cal-model.c @@ -77,6 +77,10 @@ struct _ECalModelPrivate { /* Whether we display dates in 24-hour format. */ gboolean use_24_hour_format; + + /* callback, to retrieve start time for newly added rows by click-to-add */ + ECalModelDefaultTimeFunc get_default_time; + gpointer get_default_time_user_data; }; #define E_CAL_MODEL_COMPONENT_GET_PRIVATE(obj) \ @@ -816,9 +820,26 @@ ecm_append_row (ETableModel *etm, ETableModel *source, int row) set_categories (&comp_data, e_table_model_value_at (source, E_CAL_MODEL_FIELD_CATEGORIES, row)); set_classification (&comp_data, e_table_model_value_at (source, E_CAL_MODEL_FIELD_CLASSIFICATION, row)); set_description (&comp_data, e_table_model_value_at (source, E_CAL_MODEL_FIELD_DESCRIPTION, row)); - set_dtstart (model, &comp_data, e_table_model_value_at (source, E_CAL_MODEL_FIELD_DTSTART, row)); set_summary (&comp_data, e_table_model_value_at (source, E_CAL_MODEL_FIELD_SUMMARY, row)); + if (e_table_model_value_at (source, E_CAL_MODEL_FIELD_DTSTART, row)) { + set_dtstart (model, &comp_data, e_table_model_value_at (source, E_CAL_MODEL_FIELD_DTSTART, row)); + } else if (model->priv->get_default_time) { + time_t tt = model->priv->get_default_time (model, model->priv->get_default_time_user_data); + + if (tt > 0) { + struct icaltimetype itt = icaltime_from_timet_with_zone (tt, FALSE, e_cal_model_get_timezone (model)); + icalproperty *prop = icalcomponent_get_first_property (comp_data.icalcomp, ICAL_DTSTART_PROPERTY); + + if (prop) { + icalproperty_set_dtstart (prop, itt); + } else { + prop = icalproperty_new_dtstart (itt); + icalcomponent_add_property (comp_data.icalcomp, prop); + } + } + } + /* call the class' method for filling the component */ model_class = (ECalModelClass *) G_OBJECT_GET_CLASS (model); if (model_class->fill_component_from_model != NULL) { @@ -2460,3 +2481,17 @@ e_cal_model_set_instance_times (ECalModelComponent *comp_data, const icaltimezon } comp_data->instance_end = icaltime_as_timet_with_zone (end_time, zone); } + +/** + * e_cal_model_set_default_time_func: + * This function will be used when creating new item from the "click-to-add", + * when user didn't fill a start date there. + **/ +void +e_cal_model_set_default_time_func (ECalModel *model, ECalModelDefaultTimeFunc func, gpointer user_data) +{ + g_return_if_fail (E_IS_CAL_MODEL (model)); + + model->priv->get_default_time = func; + model->priv->get_default_time_user_data = user_data; +} diff --git a/calendar/gui/e-cal-model.h b/calendar/gui/e-cal-model.h index ad9bc7d9ae..80ba4d4b5b 100644 --- a/calendar/gui/e-cal-model.h +++ b/calendar/gui/e-cal-model.h @@ -121,6 +121,8 @@ typedef struct { void (* cal_view_done) (ECalModel *model, ECalendarStatus status, ECalSourceType type); } ECalModelClass; +typedef time_t (*ECalModelDefaultTimeFunc)(ECalModel *model, gpointer user_data); + GType e_cal_model_get_type (void); GType e_cal_model_component_get_type (void); icalcomponent_kind e_cal_model_get_component_kind (ECalModel *model); @@ -184,6 +186,8 @@ void e_cal_model_set_search_query_with_time_range (ECalModel *model, const char gboolean e_cal_model_test_row_editable (ECalModel *model, int row); +void e_cal_model_set_default_time_func (ECalModel *model, ECalModelDefaultTimeFunc func, gpointer user_data); + G_END_DECLS #endif diff --git a/calendar/gui/e-calendar-view.c b/calendar/gui/e-calendar-view.c index 633291adc4..e24cb6230a 100644 --- a/calendar/gui/e-calendar-view.c +++ b/calendar/gui/e-calendar-view.c @@ -372,6 +372,8 @@ e_calendar_view_add_event (ECalendarView *cal_view, ECal *client, time_t dtstart /* FIXME Error handling */ uid = NULL; if (e_cal_create_object (client, e_cal_component_get_icalcomponent (comp), &uid, NULL)) { + gboolean strip_alarms = TRUE; + if (uid) { e_cal_component_set_uid (comp, uid); g_free (uid); @@ -379,9 +381,9 @@ e_calendar_view_add_event (ECalendarView *cal_view, ECal *client, time_t dtstart if ((itip_organizer_is_user (comp, client) || itip_sentby_is_user (comp)) && send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)), - client, comp, TRUE)) { + client, comp, TRUE, &strip_alarms)) { itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, - client, NULL, NULL, NULL); + client, NULL, NULL, NULL, strip_alarms); } } else { g_message (G_STRLOC ": Could not create the object!"); @@ -635,7 +637,7 @@ e_calendar_view_cut_clipboard (ECalendarView *cal_view) && cancel_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)), event->comp_data->client, comp, TRUE)) itip_send_comp (E_CAL_COMPONENT_METHOD_CANCEL, comp, - event->comp_data->client, NULL, NULL, NULL); + event->comp_data->client, NULL, NULL, NULL, TRUE); e_cal_component_get_uid (comp, &uid); if (e_cal_component_is_instance (comp)) { @@ -985,7 +987,7 @@ delete_event (ECalendarView *cal_view, ECalendarViewEvent *event) event->comp_data->client, comp, TRUE)) itip_send_comp (E_CAL_COMPONENT_METHOD_CANCEL, comp, - event->comp_data->client, NULL, NULL, NULL); + event->comp_data->client, NULL, NULL, NULL, TRUE); e_cal_component_get_uid (comp, &uid); if (!uid || !*uid) { @@ -1134,7 +1136,7 @@ e_calendar_view_delete_selected_occurrence (ECalendarView *cal_view) e_cal_component_free_datetime (&range.datetime); } - itip_send_comp (E_CAL_COMPONENT_METHOD_CANCEL, comp, event->comp_data->client, NULL, NULL, NULL); + itip_send_comp (E_CAL_COMPONENT_METHOD_CANCEL, comp, event->comp_data->client, NULL, NULL, NULL, TRUE); } if (is_instance) @@ -1312,7 +1314,28 @@ transfer_item_to (ECalendarViewEvent *event, ECal *dest_client, gboolean remove_ if (!e_cal_modify_object (dest_client, event->comp_data->icalcomp, CALOBJ_MOD_ALL, NULL)) return; } else { - orig_icalcomp = icalcomponent_new_clone (event->comp_data->icalcomp); + if (e_cal_util_component_is_instance (event->comp_data->icalcomp)) { + icalcomponent *icalcomp = NULL; + + if (e_cal_get_object (event->comp_data->client, uid, NULL, &icalcomp, NULL)) { + /* use master object when working with recurring event */ + orig_icalcomp = icalcomponent_new_clone (icalcomp); + icalcomponent_free (icalcomp); + } else { + /* ... or remove the recurrence id property... */ + orig_icalcomp = icalcomponent_new_clone (event->comp_data->icalcomp); + + if (e_cal_util_component_has_recurrences (orig_icalcomp)) { + /* ... for non-detached instances, to make it a master object */ + icalproperty *prop; + + prop = icalcomponent_get_first_property (orig_icalcomp, ICAL_RECURRENCEID_PROPERTY); + if (prop) + icalcomponent_remove_property (orig_icalcomp, prop); + } + } + } else + orig_icalcomp = icalcomponent_new_clone (event->comp_data->icalcomp); icalprop = icalproperty_new_x ("1"); icalproperty_set_x_name (icalprop, "X-EVOLUTION-MOVE-CALENDAR"); @@ -1339,10 +1362,16 @@ transfer_item_to (ECalendarViewEvent *event, ECal *dest_client, gboolean remove_ /* remove the item from the source calendar */ if (remove_item) { - if (e_cal_util_component_is_instance (event->comp_data->icalcomp) || e_cal_util_component_is_instance (event->comp_data->icalcomp)) - e_cal_remove_object_with_mod (event->comp_data->client, uid, - NULL, CALOBJ_MOD_ALL, NULL); - else + if (e_cal_util_component_is_instance (event->comp_data->icalcomp) || e_cal_util_component_has_recurrences (event->comp_data->icalcomp)) { + char *rid = NULL; + struct icaltimetype recur_id = icalcomponent_get_recurrenceid (event->comp_data->icalcomp); + + if (!icaltime_is_null_time (recur_id)) + rid = icaltime_as_ical_string (recur_id); + + e_cal_remove_object_with_mod (event->comp_data->client, uid, rid, CALOBJ_MOD_ALL, NULL); + g_free (rid); + } else e_cal_remove_object (event->comp_data->client, uid, NULL); } } @@ -1521,7 +1550,7 @@ on_forward (EPopup *ep, EPopupItem *pitem, void *data) comp = e_cal_component_new (); e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); - itip_send_comp (E_CAL_COMPONENT_METHOD_PUBLISH, comp, event->comp_data->client, NULL, NULL, NULL); + itip_send_comp (E_CAL_COMPONENT_METHOD_PUBLISH, comp, event->comp_data->client, NULL, NULL, NULL, TRUE); g_list_free (selected); g_object_unref (comp); @@ -1629,10 +1658,10 @@ on_unrecur_appointment (EPopup *ep, EPopupItem *pitem, void *data) *date.value = icaltime_from_timet_with_zone (event->comp_data->instance_start, FALSE, e_calendar_view_get_timezone (cal_view)); - e_cal_component_set_dtstart (new_comp, &date); + cal_comp_set_dtstart_with_oldzone (client, new_comp, &date); *date.value = icaltime_from_timet_with_zone (event->comp_data->instance_end, FALSE, e_calendar_view_get_timezone (cal_view)); - e_cal_component_set_dtend (new_comp, &date); + cal_comp_set_dtend_with_oldzone (client, new_comp, &date); e_cal_component_commit_sequence (new_comp); /* Now update both ECalComponents. Note that we do this last since at @@ -2012,8 +2041,10 @@ e_calendar_view_modify_and_send (ECalComponent *comp, gboolean new) { if (e_cal_modify_object (client, e_cal_component_get_icalcomponent (comp), mod, NULL)) { + gboolean strip_alarms = TRUE; + if ((itip_organizer_is_user (comp, client) || itip_sentby_is_user (comp)) && - send_component_dialog (toplevel, client, comp, new)) { + send_component_dialog (toplevel, client, comp, new, &strip_alarms)) { ECalComponent *send_comp = NULL; if (mod == CALOBJ_MOD_ALL && e_cal_component_is_instance (comp)) { @@ -2032,7 +2063,7 @@ e_calendar_view_modify_and_send (ECalComponent *comp, } } - itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, send_comp ? send_comp : comp, client, NULL, NULL, NULL); + itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, send_comp ? send_comp : comp, client, NULL, NULL, NULL, strip_alarms); if (send_comp) g_object_unref (send_comp); diff --git a/calendar/gui/e-day-view-layout.c b/calendar/gui/e-day-view-layout.c index 26459997df..949f4b7ce2 100644 --- a/calendar/gui/e-day-view-layout.c +++ b/calendar/gui/e-day-view-layout.c @@ -29,6 +29,7 @@ #include <config.h> #include "e-day-view-layout.h" +#include "e-util/e-bit-array.h" static void e_day_view_layout_long_event (EDayViewEvent *event, guint8 *grid, @@ -37,13 +38,14 @@ static void e_day_view_layout_long_event (EDayViewEvent *event, gint *rows_in_top_display); static void e_day_view_layout_day_event (EDayViewEvent *event, - guint8 *grid, + EBitArray **grid, guint16 *group_starts, guint8 *cols_per_row, gint rows, - gint mins_per_row); + gint mins_per_row, + gint max_cols); static void e_day_view_expand_day_event (EDayViewEvent *event, - guint8 *grid, + EBitArray **grid, guint8 *cols_per_row, gint mins_per_row); static void e_day_view_recalc_cols_per_row (gint rows, @@ -127,15 +129,17 @@ e_day_view_layout_long_event (EDayViewEvent *event, } -void +/* returns maximum number of columns among all rows */ +gint e_day_view_layout_day_events (GArray *events, gint rows, gint mins_per_row, - guint8 *cols_per_row) + guint8 *cols_per_row, + gint max_cols) { EDayViewEvent *event; - gint row, event_num; - guint8 *grid; + gint row, event_num, res; + EBitArray **grid; /* This is a temporary array which keeps track of rows which are connected. When an appointment spans multiple rows then the number @@ -145,18 +149,20 @@ e_day_view_layout_day_events (GArray *events, rows. */ guint16 group_starts[12 * 24]; + /* This is a temporary 2-d grid which is used to place events. + Each element is 0 if the position is empty, or 1 if occupied. */ + grid = g_new0 (EBitArray *, rows); + /* Reset the cols_per_row array, and initialize the connected rows so that all rows are not connected - each row is the start of a new group. */ for (row = 0; row < rows; row++) { cols_per_row[row] = 0; group_starts[row] = row; - } - - /* This is a temporary 2-d grid which is used to place events. - Each element is 0 if the position is empty, or 1 if occupied. */ - grid = g_new0 (guint8, rows * E_DAY_VIEW_MAX_COLUMNS); + /* row doesn't contain any event at the moment */ + grid [row] = e_bit_array_new (0); + } /* Iterate over the events, finding which rows they cover, and putting them in the first free column available. Increment the number of @@ -166,7 +172,7 @@ e_day_view_layout_day_events (GArray *events, event = &g_array_index (events, EDayViewEvent, event_num); e_day_view_layout_day_event (event, grid, group_starts, - cols_per_row, rows, mins_per_row); + cols_per_row, rows, mins_per_row, max_cols); } /* Recalculate the number of columns needed in each row. */ @@ -180,8 +186,15 @@ e_day_view_layout_day_events (GArray *events, mins_per_row); } - /* Free the grid. */ + /* Free the grid and compute maximum number of columns used. */ + res = 0; + for (row = 0; row < rows; row++) { + res = MAX (res, e_bit_array_bit_count (grid [row])); + g_object_unref (grid [row]); + } g_free (grid); + + return res; } @@ -190,11 +203,12 @@ e_day_view_layout_day_events (GArray *events, sure they are all in one group. */ static void e_day_view_layout_day_event (EDayViewEvent *event, - guint8 *grid, + EBitArray **grid, guint16 *group_starts, guint8 *cols_per_row, gint rows, - gint mins_per_row) + gint mins_per_row, + gint max_cols) { gint start_row, end_row, free_col, col, row, group_start; @@ -214,10 +228,11 @@ e_day_view_layout_day_event (EDayViewEvent *event, end_row = CLAMP (end_row, 0, rows - 1); /* Try each column until we find a free one. */ - for (col = 0; col < E_DAY_VIEW_MAX_COLUMNS; col++) { + for (col = 0; max_cols <= 0 || col < max_cols; col++) { free_col = col; for (row = start_row; row <= end_row; row++) { - if (grid[row * E_DAY_VIEW_MAX_COLUMNS + col]) { + if (e_bit_array_bit_count (grid [row]) > col && + e_bit_array_value_at (grid [row], col)) { free_col = -1; break; } @@ -243,7 +258,11 @@ e_day_view_layout_day_event (EDayViewEvent *event, all the events have been layed out. Also make sure all the rows that the event covers are in one group. */ for (row = start_row; row <= end_row; row++) { - grid[row * E_DAY_VIEW_MAX_COLUMNS + free_col] = 1; + /* resize the array if necessary */ + if (e_bit_array_bit_count (grid [row]) <= free_col) + e_bit_array_insert (grid [row], e_bit_array_bit_count (grid [row]), free_col - e_bit_array_bit_count (grid [row]) + 1); + + e_bit_array_change_one_row (grid [row], free_col, TRUE); cols_per_row[row]++; group_starts[row] = group_start; } @@ -284,7 +303,7 @@ e_day_view_recalc_cols_per_row (gint rows, /* Expands the event horizontally to fill any free space. */ static void e_day_view_expand_day_event (EDayViewEvent *event, - guint8 *grid, + EBitArray **grid, guint8 *cols_per_row, gint mins_per_row) { @@ -300,7 +319,8 @@ e_day_view_expand_day_event (EDayViewEvent *event, clashed = FALSE; for (col = event->start_row_or_col + 1; col < cols_per_row[start_row]; col++) { for (row = start_row; row <= end_row; row++) { - if (grid[row * E_DAY_VIEW_MAX_COLUMNS + col]) { + if (e_bit_array_bit_count (grid [row]) > col && + e_bit_array_value_at (grid [row], col)) { clashed = TRUE; break; } diff --git a/calendar/gui/e-day-view-layout.h b/calendar/gui/e-day-view-layout.h index 19ee6ee036..4ad1de64bd 100644 --- a/calendar/gui/e-day-view-layout.h +++ b/calendar/gui/e-day-view-layout.h @@ -39,10 +39,11 @@ void e_day_view_layout_long_events (GArray *events, gint *rows_in_top_display); -void e_day_view_layout_day_events (GArray *events, +gint e_day_view_layout_day_events (GArray *events, gint rows, gint mins_per_row, - guint8 *cols_per_row); + guint8 *cols_per_row, + gint max_cols); gboolean e_day_view_find_long_event_days (EDayViewEvent *event, gint days_shown, diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c index 21a3102e9f..9391f48ced 100644 --- a/calendar/gui/e-day-view.c +++ b/calendar/gui/e-day-view.c @@ -181,8 +181,6 @@ static void e_day_view_top_scroll (EDayView *day_view, static void e_day_view_update_top_scroll (EDayView *day_view, gboolean scroll_to_top); -static gboolean e_day_view_check_if_new_event_fits (EDayView *day_view); - static void e_day_view_on_canvas_realized (GtkWidget *widget, EDayView *day_view); @@ -705,6 +703,12 @@ timezone_changed_cb (ECalendarView *cal_view, icaltimezone *old_zone, } static void +dview_show_week_no_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) +{ + e_day_view_set_show_week_number (data, calendar_config_get_dview_show_week_no ()); +} + +static void e_day_view_init (EDayView *day_view) { gint day; @@ -808,6 +812,12 @@ e_day_view_init (EDayView *day_view) day_view->before_click_dtstart = 0; day_view->before_click_dtend = 0; + day_view->week_number_label = gtk_label_new (""); + gtk_table_attach (GTK_TABLE (day_view), day_view->week_number_label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0); + day_view->wn_notif_id = calendar_config_add_notification_dview_show_week_no (dview_show_week_no_changed_cb, day_view); + if (calendar_config_get_dview_show_week_no ()) + gtk_widget_show (day_view->week_number_label); + /* * Top Canvas */ @@ -988,6 +998,10 @@ e_day_view_init (EDayView *day_view) /* * Scrollbar. */ + day_view->mc_hscrollbar = gtk_hscrollbar_new (GTK_LAYOUT (day_view->main_canvas)->hadjustment); + gtk_table_attach (GTK_TABLE (day_view), day_view->mc_hscrollbar, 1, 2, 2, 3, GTK_FILL, 0, 0, 0); + gtk_widget_show (day_view->mc_hscrollbar); + day_view->tc_vscrollbar = gtk_vscrollbar_new (GTK_LAYOUT (day_view->top_canvas)->vadjustment); gtk_table_attach (GTK_TABLE (day_view), day_view->tc_vscrollbar, 2, 3, 0, 1, 0, GTK_FILL, 0, 0); @@ -1080,6 +1094,11 @@ e_day_view_destroy (GtkObject *object) e_day_view_stop_auto_scroll (day_view); + if (day_view->wn_notif_id) { + calendar_config_remove_notification (day_view->wn_notif_id); + day_view->wn_notif_id = 0; + } + if (day_view->large_font_desc) { pango_font_description_free (day_view->large_font_desc); day_view->large_font_desc = NULL; @@ -1462,28 +1481,19 @@ e_day_view_style_set (GtkWidget *widget, pango_font_metrics_unref (font_metrics); } -/* This recalculates the sizes of each column. */ static void -e_day_view_size_allocate (GtkWidget *widget, GtkAllocation *allocation) +e_day_view_recalc_main_canvas_size (EDayView *day_view) { - EDayView *day_view; gint day, scroll_y; gboolean need_reshape; -#if 0 - g_print ("In e_day_view_size_allocate\n"); -#endif - day_view = E_DAY_VIEW (widget); - - (*GTK_WIDGET_CLASS (e_day_view_parent_class)->size_allocate) (widget, allocation); - - e_day_view_recalc_cell_sizes (day_view); - /* Set the scroll region of the top canvas */ e_day_view_update_top_scroll (day_view, TRUE); need_reshape = e_day_view_update_scroll_regions (day_view); + e_day_view_recalc_cell_sizes (day_view); + /* Scroll to the start of the working day, if this is the initial allocation. */ if (day_view->scroll_to_work_day) { @@ -1504,6 +1514,17 @@ e_day_view_size_allocate (GtkWidget *widget, GtkAllocation *allocation) } } +/* This recalculates the sizes of each column. */ +static void +e_day_view_size_allocate (GtkWidget *widget, GtkAllocation *allocation) +{ +#if 0 + g_print ("In e_day_view_size_allocate\n"); +#endif + (*GTK_WIDGET_CLASS (e_day_view_parent_class)->size_allocate) (widget, allocation); + + e_day_view_recalc_main_canvas_size (E_DAY_VIEW (widget)); +} static void e_day_view_recalc_cell_sizes (EDayView *day_view) @@ -1530,6 +1551,8 @@ e_day_view_recalc_cell_sizes (EDayView *day_view) get divided evenly. Note that we use one more element than the number of columns, to make it easy to get the column widths. */ width = day_view->main_canvas->allocation.width; + if (day_view->days_shown == 1) + width = MAX (width, day_view->max_cols * (E_DAY_VIEW_MIN_DAY_COL_WIDTH + E_DAY_VIEW_GAP_WIDTH) - E_DAY_VIEW_MIN_DAY_COL_WIDTH - 1); width /= day_view->days_shown; offset = 0; for (day = 0; day <= day_view->days_shown; day++) { @@ -2276,6 +2299,9 @@ e_day_view_recalc_day_starts (EDayView *day_view, time_t start_time) { gint day; + char *str; + struct icaltimetype tt; + GDate dt; day_view->day_starts[0] = start_time; for (day = 1; day <= day_view->days_shown; day++) { @@ -2289,8 +2315,36 @@ e_day_view_recalc_day_starts (EDayView *day_view, day_view->lower = start_time; day_view->upper = day_view->day_starts[day_view->days_shown]; + + tt = icaltime_from_timet_with_zone (day_view->day_starts[0], FALSE, e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); + g_date_clear (&dt, 1); + g_date_set_dmy (&dt, tt.day, tt.month, tt.year); + /* To Translators: the %d stands for a week number, it's value between 1 and 52/53 */ + str = g_strdup_printf (_("Week %d"), g_date_get_iso8601_week_of_year (&dt)); + gtk_label_set_text (GTK_LABEL (day_view->week_number_label), str); + g_free (str); } +gboolean +e_day_view_get_show_week_number (EDayView *day_view) +{ + g_return_val_if_fail (day_view != NULL, FALSE); + + return GTK_WIDGET_VISIBLE (day_view->week_number_label); +} + +void +e_day_view_set_show_week_number (EDayView *day_view, gboolean show) +{ + g_return_if_fail (day_view != NULL); + + if (e_day_view_get_show_week_number (day_view) != show) { + if (show) + gtk_widget_show (day_view->week_number_label); + else + gtk_widget_hide (day_view->week_number_label); + } +} /* Whether we are displaying a work-week, in which case the display always starts on the first day of the working week. */ @@ -2674,12 +2728,21 @@ e_day_view_update_scroll_regions (EDayView *day_view) gnome_canvas_get_scroll_region (GNOME_CANVAS (day_view->main_canvas), NULL, NULL, &old_x2, &old_y2); new_x2 = day_view->main_canvas->allocation.width - 1; + + if (day_view->days_shown == 1) + new_x2 = MAX (new_x2, day_view->max_cols * (E_DAY_VIEW_MIN_DAY_COL_WIDTH + E_DAY_VIEW_GAP_WIDTH) - E_DAY_VIEW_MIN_DAY_COL_WIDTH - 1); + if (old_x2 != new_x2 || old_y2 != new_y2) { need_reshape = TRUE; gnome_canvas_set_scroll_region (GNOME_CANVAS (day_view->main_canvas), 0, 0, new_x2, new_y2); } + if (new_x2 <= day_view->main_canvas->allocation.width - 1) + gtk_widget_hide (day_view->mc_hscrollbar); + else + gtk_widget_show (day_view->mc_hscrollbar); + return need_reshape; } @@ -3929,7 +3992,7 @@ e_day_view_finish_long_event_resize (EDayView *day_view) dt = day_view->day_starts[day_view->resize_start_row]; *date.value = icaltime_from_timet_with_zone (dt, is_date, e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - e_cal_component_set_dtstart (comp, &date); + cal_comp_set_dtstart_with_oldzone (client, comp, &date); e_cal_component_free_datetime (&ecdt); date.tzid = NULL; /* do not reuse it later */ } else { @@ -3942,7 +4005,7 @@ e_day_view_finish_long_event_resize (EDayView *day_view) dt = day_view->day_starts[day_view->resize_end_row + 1]; *date.value = icaltime_from_timet_with_zone (dt, is_date, e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - e_cal_component_set_dtend (comp, &date); + cal_comp_set_dtend_with_oldzone (client, comp, &date); e_cal_component_free_datetime (&ecdt); date.tzid = NULL; /* do not reuse it later */ } @@ -3960,12 +4023,12 @@ e_day_view_finish_long_event_resize (EDayView *day_view) *date.value = icaltime_from_timet_with_zone ( event->comp_data->instance_end, FALSE, e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - e_cal_component_set_dtend (comp, &date); + cal_comp_set_dtend_with_oldzone (client, comp, &date); } else { *date.value = icaltime_from_timet_with_zone ( event->comp_data->instance_start, FALSE, e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - e_cal_component_set_dtstart (comp, &date); + cal_comp_set_dtstart_with_oldzone (client, comp, &date); } e_cal_component_set_rdate_list (comp, NULL); @@ -4025,20 +4088,18 @@ e_day_view_finish_resize (EDayView *day_view) } date.value = &itt; - /* FIXME: Should probably keep the timezone of the original start - and end times. */ date.tzid = icaltimezone_get_tzid (e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); if (day_view->resize_drag_pos == E_CALENDAR_VIEW_POS_TOP_EDGE) { dt = e_day_view_convert_grid_position_to_time (day_view, day, day_view->resize_start_row); *date.value = icaltime_from_timet_with_zone (dt, FALSE, e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - e_cal_component_set_dtstart (comp, &date); + cal_comp_set_dtstart_with_oldzone (client, comp, &date); } else { dt = e_day_view_convert_grid_position_to_time (day_view, day, day_view->resize_end_row + 1); *date.value = icaltime_from_timet_with_zone (dt, FALSE, e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - e_cal_component_set_dtend (comp, &date); + cal_comp_set_dtend_with_oldzone (client, comp, &date); } e_cal_component_commit_sequence (comp); @@ -4069,12 +4130,12 @@ e_day_view_finish_resize (EDayView *day_view) *date.value = icaltime_from_timet_with_zone ( event->comp_data->instance_end, FALSE, e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - e_cal_component_set_dtend (comp, &date); + cal_comp_set_dtend_with_oldzone (client, comp, &date); } else { *date.value = icaltime_from_timet_with_zone ( event->comp_data->instance_start, FALSE, e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - e_cal_component_set_dtstart (comp, &date); + cal_comp_set_dtstart_with_oldzone (client, comp, &date); } e_cal_component_set_rdate_list (comp, NULL); @@ -4265,13 +4326,13 @@ e_day_view_add_event (ECalComponent *comp, return TRUE; } - /* This lays out the short (less than 1 day) events in the columns. Any long events are simply skipped. */ void e_day_view_check_layout (EDayView *day_view) { gint day, rows_in_top_display; + gint max_cols = -1; /* Don't bother if we aren't visible. */ if (!E_CALENDAR_VIEW (day_view)->in_focus) @@ -4281,11 +4342,17 @@ e_day_view_check_layout (EDayView *day_view) e_day_view_ensure_events_sorted (day_view); for (day = 0; day < day_view->days_shown; day++) { - if (day_view->need_layout[day]) - e_day_view_layout_day_events (day_view->events[day], + if (day_view->need_layout[day]) { + gint cols; + + cols = e_day_view_layout_day_events (day_view->events[day], day_view->rows, day_view->mins_per_row, - day_view->cols_per_row[day]); + day_view->cols_per_row[day], + day_view->days_shown == 1 ? -1 : E_DAY_VIEW_MULTI_DAY_MAX_COLUMNS); + + max_cols = MAX (cols, max_cols); + } if (day_view->need_layout[day] || day_view->need_reshape[day]) { @@ -4311,13 +4378,17 @@ e_day_view_check_layout (EDayView *day_view) } } - if (day_view->long_events_need_layout || day_view->long_events_need_reshape) e_day_view_reshape_long_events (day_view); day_view->long_events_need_layout = FALSE; day_view->long_events_need_reshape = FALSE; + + if (max_cols != -1 && max_cols != day_view->max_cols) { + day_view->max_cols = max_cols; + e_day_view_recalc_main_canvas_size (day_view); + } } @@ -4930,13 +5001,6 @@ e_day_view_do_key_press (GtkWidget *widget, GdkEventKey *event) if (day_view->selection_start_day == -1) return FALSE; - /* Check if there is room for a new event to be typed in. If there - isn't we don't want to add an event as we will then add a new - event for every key press. */ - if (!e_day_view_check_if_new_event_fits (day_view)) { - return FALSE; - } - /* We only want to start an edit with a return key or a simple character. */ if ((keyval != GDK_Return) && @@ -5588,33 +5652,6 @@ e_day_view_top_scroll (EDayView *day_view, gtk_adjustment_set_value (adj, new_value); } -static gboolean -e_day_view_check_if_new_event_fits (EDayView *day_view) -{ - gint day, start_row, end_row, row; - - day = day_view->selection_start_day; - start_row = day_view->selection_start_row; - end_row = day_view->selection_end_row; - - /* Long events always fit, since we keep adding rows to the top - canvas. */ - if (day != day_view->selection_end_day) - return TRUE; - if (start_row == 0 && end_row == day_view->rows) - return TRUE; - - /* If any of the rows already have E_DAY_VIEW_MAX_COLUMNS columns, - return FALSE. */ - for (row = start_row; row <= end_row; row++) { - if (day_view->cols_per_row[day][row] >= E_DAY_VIEW_MAX_COLUMNS) - return FALSE; - } - - return TRUE; -} - - void e_day_view_ensure_rows_visible (EDayView *day_view, gint start_row, @@ -6073,10 +6110,10 @@ e_day_view_change_event_time (EDayView *day_view, time_t start_dt, time_t end_dt *date.value = icaltime_from_timet_with_zone (start_dt, FALSE, e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - e_cal_component_set_dtstart (comp, &date); + cal_comp_set_dtstart_with_oldzone (client, comp, &date); *date.value = icaltime_from_timet_with_zone (end_dt, FALSE, e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - e_cal_component_set_dtend (comp, &date); + cal_comp_set_dtend_with_oldzone (client, comp, &date); e_cal_component_commit_sequence (comp); @@ -7449,7 +7486,7 @@ e_day_view_on_top_canvas_drag_data_received (GtkWidget *widget, the original start and end times. */ date.tzid = icaltimezone_get_tzid (e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); } - e_cal_component_set_dtstart (comp, &date); + cal_comp_set_dtstart_with_oldzone (client, comp, &date); if (end_offset == 0) dt = day_view->day_starts[day + num_days]; @@ -7465,7 +7502,7 @@ e_day_view_on_top_canvas_drag_data_received (GtkWidget *widget, the original start and end times. */ date.tzid = icaltimezone_get_tzid (e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); } - e_cal_component_set_dtend (comp, &date); + cal_comp_set_dtend_with_oldzone (client, comp, &date); gtk_drag_finish (context, TRUE, TRUE, time); @@ -7662,11 +7699,11 @@ e_day_view_on_main_canvas_drag_data_received (GtkWidget *widget, dt = e_day_view_convert_grid_position_to_time (day_view, day, row) + start_offset * 60; *date.value = icaltime_from_timet_with_zone (dt, FALSE, e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - e_cal_component_set_dtstart (comp, &date); + cal_comp_set_dtstart_with_oldzone (client, comp, &date); dt = e_day_view_convert_grid_position_to_time (day_view, day, row + num_rows) - end_offset * 60; *date.value = icaltime_from_timet_with_zone (dt, FALSE, e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - e_cal_component_set_dtend (comp, &date); + cal_comp_set_dtend_with_oldzone (client, comp, &date); e_cal_component_abort_sequence (comp); gtk_drag_finish (context, TRUE, TRUE, time); diff --git a/calendar/gui/e-day-view.h b/calendar/gui/e-day-view.h index 6f4c0d7da1..1f518198fa 100644 --- a/calendar/gui/e-day-view.h +++ b/calendar/gui/e-day-view.h @@ -45,8 +45,11 @@ G_BEGIN_DECLS of a normal event. */ #define E_DAY_VIEW_LONG_EVENT E_DAY_VIEW_MAX_DAYS -/* The maximum number of columns of appointments within a day. */ -#define E_DAY_VIEW_MAX_COLUMNS 6 +/* The maximum number of columns of appointments within a day in multi-day view. */ +#define E_DAY_VIEW_MULTI_DAY_MAX_COLUMNS 6 + +/* minimum width of the event in one-day view in pixels */ +#define E_DAY_VIEW_MIN_DAY_COL_WIDTH 60 /* The width of the gap between appointments. This should be at least E_DAY_VIEW_BAR_WIDTH, since in the top canvas we use this space to draw @@ -204,6 +207,9 @@ struct _EDayView /* scrollbar for top_canvas */ GtkWidget *tc_vscrollbar; + /* horizontal scrollbar for main_canvas */ + GtkWidget *mc_hscrollbar; + /* The main canvas where the rest of the appointments are shown. */ GtkWidget *main_canvas; GnomeCanvasItem *main_canvas_item; @@ -214,6 +220,11 @@ struct _EDayView GtkWidget *vscrollbar; + /* label showing week number in upper-left corner */ + GtkWidget *week_number_label; + /* option change notification id for week number */ + guint wn_notif_id; + /* S-expression for query and the query object */ ECalView *query; @@ -310,6 +321,8 @@ struct _EDayView Note that there are a maximum of 12 * 24 rows (when a row is 5 mins) but we don't always have that many rows. */ guint8 cols_per_row[E_DAY_VIEW_MAX_DAYS][12 * 24]; + /* The maximum number of columns from all rows in cols_per_row */ + gint max_cols; /* Sizes of the various time strings. */ gint small_hour_widths[24]; @@ -599,9 +612,12 @@ void e_day_view_ensure_rows_visible (EDayView *day_view, gint start_row, gint end_row); - void e_day_view_update_marcus_bains (EDayView *day_view); +/* Week number in upper-left corner of the day view widget */ +gboolean e_day_view_get_show_week_number (EDayView *day_view); +void e_day_view_set_show_week_number (EDayView *day_view, gboolean show); + G_END_DECLS #endif /* _E_DAY_VIEW_H_ */ diff --git a/calendar/gui/e-itip-control.c b/calendar/gui/e-itip-control.c index bf8ceec3be..ff6aeb92ba 100644 --- a/calendar/gui/e-itip-control.c +++ b/calendar/gui/e-itip-control.c @@ -2097,7 +2097,7 @@ send_item (EItipControl *itip) comp = get_real_item (itip); if (comp != NULL) { - itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, priv->current_ecal, NULL, NULL, NULL); + itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, priv->current_ecal, NULL, NULL, NULL, TRUE); g_object_unref (comp); dialog = gtk_message_dialog_new ( NULL, 0, @@ -2152,7 +2152,7 @@ send_freebusy (EItipControl *itip) for (l = comp_list; l; l = l->next) { ECalComponent *comp = E_CAL_COMPONENT (l->data); - itip_send_comp (E_CAL_COMPONENT_METHOD_REPLY, comp, priv->current_ecal, NULL, NULL, NULL); + itip_send_comp (E_CAL_COMPONENT_METHOD_REPLY, comp, priv->current_ecal, NULL, NULL, NULL, TRUE); g_object_unref (comp); } @@ -2598,7 +2598,7 @@ ok_clicked_cb (GtkWidget *widget, gpointer data) g_slist_free (list); e_cal_component_rescan (comp); - itip_send_comp (E_CAL_COMPONENT_METHOD_REPLY, comp, priv->current_ecal, priv->top_level, NULL, NULL); + itip_send_comp (E_CAL_COMPONENT_METHOD_REPLY, comp, priv->current_ecal, priv->top_level, NULL, NULL, TRUE); g_object_unref (comp); } diff --git a/calendar/gui/e-week-view.c b/calendar/gui/e-week-view.c index e531a133fa..7683f7a687 100644 --- a/calendar/gui/e-week-view.c +++ b/calendar/gui/e-week-view.c @@ -3432,10 +3432,10 @@ e_week_view_change_event_time (EWeekView *week_view, time_t start_dt, time_t end *date.value = icaltime_from_timet_with_zone (start_dt, is_all_day, e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view))); - e_cal_component_set_dtstart (comp, &date); + cal_comp_set_dtstart_with_oldzone (client, comp, &date); *date.value = icaltime_from_timet_with_zone (end_dt, is_all_day, e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view))); - e_cal_component_set_dtend (comp, &date); + cal_comp_set_dtend_with_oldzone (client, comp, &date); e_cal_component_commit_sequence (comp); diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c index 3ff2944752..40b36aa154 100644 --- a/calendar/gui/gnome-cal.c +++ b/calendar/gui/gnome-cal.c @@ -1328,6 +1328,20 @@ gnome_calendar_get_tag (GnomeCalendar *gcal) return GTK_WIDGET (gcal->priv->date_navigator); } +static time_t +gc_get_default_time (ECalModel *model, gpointer user_data) +{ + GnomeCalendar *gcal = user_data; + time_t res = 0, end; + + g_return_val_if_fail (model != NULL, 0); + g_return_val_if_fail (GNOME_IS_CALENDAR (user_data), 0); + + gnome_calendar_get_current_time_range (gcal, &res, &end); + + return res; +} + static void setup_widgets (GnomeCalendar *gcal) { @@ -1511,6 +1525,8 @@ setup_widgets (GnomeCalendar *gcal) gtk_widget_show (label); gtk_widget_show (vbox); + e_cal_model_set_default_time_func (e_memo_table_get_model (E_MEMO_TABLE (priv->memo)), gc_get_default_time, gcal); + update_memo_view (gcal); } @@ -2138,7 +2154,7 @@ client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal) source = e_cal_get_source (ecal); state = e_cal_get_load_state (ecal); - if (status == E_CALENDAR_STATUS_AUTHENTICATION_FAILED) + if (status == E_CALENDAR_STATUS_AUTHENTICATION_FAILED || status == E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED) auth_cal_forget_password (ecal); switch (status) { @@ -2164,17 +2180,10 @@ client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal) status = E_CALENDAR_STATUS_OK; break; - case E_CALENDAR_STATUS_AUTHENTICATION_FAILED: - { - const gchar *auth_domain = e_source_get_property (source, "auth-domain"); - const gchar *component_name; - - component_name = auth_domain ? auth_domain : "Calendar"; - - /* Warn the user password is wrong */ - e_passwords_forget_password (component_name, e_cal_get_uri(ecal)); - return; - } + case E_CALENDAR_STATUS_AUTHENTICATION_FAILED: + /* try to reopen calendar - it'll ask for a password once again */ + e_cal_open_async (ecal, FALSE); + return; case E_CALENDAR_STATUS_REPOSITORY_OFFLINE: /* check to see if we have dialog already running for this operation */ id = g_strdup ("calendar:unable-to-load-the-calendar"); @@ -2232,6 +2241,9 @@ default_client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar source = e_cal_get_source (ecal); state = e_cal_get_load_state (ecal); + if (status == E_CALENDAR_STATUS_AUTHENTICATION_FAILED || status == E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED) + auth_cal_forget_password (ecal); + switch (status) { case E_CALENDAR_STATUS_OK: break; @@ -2239,13 +2251,18 @@ default_client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar if (state == E_CAL_LOAD_NOT_LOADED) e_cal_open_async (ecal, FALSE); return; - case E_CALENDAR_STATUS_INVALID_SERVER_VERSION : + case E_CALENDAR_STATUS_AUTHENTICATION_FAILED: + /* try to reopen calendar - it'll ask for a password once again */ + e_cal_open_async (ecal, FALSE); + return; + case E_CALENDAR_STATUS_INVALID_SERVER_VERSION: e_error_run (NULL, "calendar:server-version", NULL); - status = E_CALENDAR_STATUS_OK; default: /* Make sure the source doesn't disappear on us */ g_object_ref (source); + g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, gcal); + /* FIXME should we do this to prevent multiple error dialogs? */ priv->clients_list = g_list_remove (priv->clients_list, ecal); g_hash_table_remove (priv->clients, e_source_peek_uid (source)); @@ -2265,7 +2282,6 @@ default_client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, default_client_cal_opened_cb, NULL); - e_cal_model_set_default_client ( e_calendar_view_get_model ( E_CALENDAR_VIEW (priv->views[priv->current_view_type])), diff --git a/calendar/gui/itip-utils.c b/calendar/gui/itip-utils.c index e879a9b440..17a5d97fb5 100644 --- a/calendar/gui/itip-utils.c +++ b/calendar/gui/itip-utils.c @@ -1023,7 +1023,7 @@ comp_minimal (ECalComponent *comp, gboolean attendee) } static ECalComponent * -comp_compliant (ECalComponentItipMethod method, ECalComponent *comp, ECal *client, icalcomponent *zones) +comp_compliant (ECalComponentItipMethod method, ECalComponent *comp, ECal *client, icalcomponent *zones, gboolean strip_alarms) { ECalComponent *clone, *temp_clone; struct icaltimetype itt; @@ -1080,8 +1080,31 @@ comp_compliant (ECalComponentItipMethod method, ECalComponent *comp, ECal *clien e_cal_component_free_recur_list (rrule_list); } - /* We delete incoming alarms anyhow, and this helps with outlook */ - e_cal_component_remove_all_alarms (clone); + /* We delete incoming alarms if requested, even this helps with outlook */ + if (strip_alarms) { + e_cal_component_remove_all_alarms (clone); + } else { + /* Always strip procedure alarms, because of security */ + GList *uids, *l; + + uids = e_cal_component_get_alarm_uids (clone); + + for (l = uids; l; l = l->next) { + ECalComponentAlarm *alarm; + ECalComponentAlarmAction action = E_CAL_COMPONENT_ALARM_UNKNOWN; + + alarm = e_cal_component_get_alarm (clone, (const char *)l->data); + if (alarm) { + e_cal_component_alarm_get_action (alarm, &action); + e_cal_component_alarm_free (alarm); + + if (action == E_CAL_COMPONENT_ALARM_PROCEDURE) + e_cal_component_remove_alarm (clone, (const char *)l->data); + } + } + + cal_obj_uid_list_free (uids); + } /* Strip X-LIC-ERROR stuff */ e_cal_component_strip_errors (clone); @@ -1164,7 +1187,7 @@ append_cal_attachments (EMsgComposer *composer, gboolean itip_send_comp (ECalComponentItipMethod method, ECalComponent *send_comp, - ECal *client, icalcomponent *zones, GSList *attachments_list, GList *users) + ECal *client, icalcomponent *zones, GSList *attachments_list, GList *users, gboolean strip_alarms) { EMsgComposer *composer; EComposerHeaderTable *table; @@ -1197,7 +1220,7 @@ itip_send_comp (ECalComponentItipMethod method, ECalComponent *send_comp, } /* Tidy up the comp */ - comp = comp_compliant (method, send_comp, client, zones); + comp = comp_compliant (method, send_comp, client, zones, strip_alarms); if (comp == NULL) goto cleanup; @@ -1312,7 +1335,7 @@ reply_to_calendar_comp (ECalComponentItipMethod method, gboolean retval = FALSE; /* Tidy up the comp */ - comp = comp_compliant (method, send_comp, client, zones); + comp = comp_compliant (method, send_comp, client, zones, TRUE); if (comp == NULL) goto cleanup; diff --git a/calendar/gui/itip-utils.h b/calendar/gui/itip-utils.h index c41171cfe4..3c84af929f 100644 --- a/calendar/gui/itip-utils.h +++ b/calendar/gui/itip-utils.h @@ -58,7 +58,7 @@ const gchar *itip_strip_mailto (const gchar *address); char *itip_get_comp_attendee (ECalComponent *comp, ECal *client); gboolean itip_send_comp (ECalComponentItipMethod method, ECalComponent *comp, - ECal *client, icalcomponent *zones, GSList *attachments_list, GList *users); + ECal *client, icalcomponent *zones, GSList *attachments_list, GList *users, gboolean strip_alarms); gboolean itip_publish_comp (ECal *client, gchar* uri, gchar* username, gchar* password, ECalComponent **pub_comp); diff --git a/calendar/gui/print.c b/calendar/gui/print.c index dcd9672ec7..f448b4704d 100644 --- a/calendar/gui/print.c +++ b/calendar/gui/print.c @@ -1062,13 +1062,33 @@ print_attendees (GtkPrintContext *context, PangoFontDescription *font, cairo_t * return top; } +static char * +get_summary_with_location (icalcomponent *icalcomp) +{ + const gchar *summary, *location; + char *text; + + g_return_val_if_fail (icalcomp != NULL, NULL); + + summary = icalcomponent_get_summary (icalcomp); + text = summary ? (char*) summary : ""; + + location = icalcomponent_get_location (icalcomp); + if (location && *location) { + text = g_strdup_printf ("%s (%s)", text, location); + } else { + text = g_strdup (text); + } + + return text; +} + static void print_day_long_event (GtkPrintContext *context, PangoFontDescription *font, double left, double right, double top, double bottom, double row_height, EDayViewEvent *event, struct pdinfo *pdi, ECalModel *model) { - const gchar *summary; double x1, x2, y1, y2; double left_triangle_width = -1.0, right_triangle_width = -1.0; char *text; @@ -1134,12 +1154,13 @@ print_day_long_event (GtkPrintContext *context, PangoFontDescription *font, } /* Print the text. */ - summary = icalcomponent_get_summary (event->comp_data->icalcomp); - text = summary ? (char*) summary : ""; + text = get_summary_with_location (event->comp_data->icalcomp); x1 += 4; x2 -= 4; print_text (context, font, text, PANGO_ALIGN_CENTER, x1, x2, y1, y2); + + g_free (text); } @@ -1148,11 +1169,10 @@ print_day_event (GtkPrintContext *context, PangoFontDescription *font, double left, double right, double top, double bottom, EDayViewEvent *event, struct pdinfo *pdi, ECalModel *model) { - const gchar *summary, *location; double x1, x2, y1, y2, col_width, row_height; int start_offset, end_offset, start_row, end_row; char *text, start_buffer[32], end_buffer[32]; - gboolean display_times = FALSE, free_text = FALSE; + gboolean display_times = FALSE; struct tm date_tm; double red, green, blue; @@ -1188,14 +1208,7 @@ print_day_event (GtkPrintContext *context, PangoFontDescription *font, e_cal_model_get_rgb_color_for_component (model, event->comp_data, &red, &green, &blue); print_border_rgb (context, x1, x2, y1, y2, 1.0, red, green, blue); - summary = icalcomponent_get_summary (event->comp_data->icalcomp); - text = summary ? (char*) summary : ""; - - location = icalcomponent_get_location (event->comp_data->icalcomp); - if (location && *location) { - text = g_strdup_printf ("%s (%s)", text, location); - free_text = TRUE; - } + text = get_summary_with_location (event->comp_data->icalcomp); if (display_times) { gchar *t = NULL; @@ -1217,22 +1230,16 @@ print_day_event (GtkPrintContext *context, PangoFontDescription *font, e_time_format_time (&date_tm, pdi->use_24_hour_format, FALSE, end_buffer, sizeof (end_buffer)); - if (free_text) - t = text; - + t = text; text = g_strdup_printf ("%s - %s %s ", start_buffer, end_buffer, text); - free_text = TRUE; - - if (t) - g_free (t); + g_free (t); } bound_text (context, font, text, -1, x1 + 2, y1, x2 - 2, y2, FALSE, NULL, NULL); - if (free_text) - g_free (text); + g_free (text); } @@ -1337,7 +1344,7 @@ print_day_details (GtkPrintContext *context, GnomeCalendar *gcal, time_t whence, /* lay out the short events, within the day. */ e_day_view_layout_day_events (pdi.events[0], DAY_VIEW_ROWS, - DAY_VIEW_MINS_PER_ROW, pdi.cols_per_row); + DAY_VIEW_MINS_PER_ROW, pdi.cols_per_row, -1); /* print the short events. */ if (top > bottom ) @@ -1497,15 +1504,13 @@ print_week_event (GtkPrintContext *context, PangoFontDescription *font, { EWeekViewEventSpan *span; gint span_num; - const gchar *summary; char *text; int num_days, start_x, start_y, start_h, end_x, end_y, end_h; double x1, x2, y1, y2; double red, green, blue; GdkPixbuf *pixbuf = NULL; - summary = icalcomponent_get_summary (event->comp_data->icalcomp); - text = summary ? (char*) summary : ""; + text = get_summary_with_location (event->comp_data->icalcomp); for (span_num = 0; span_num < event->num_spans; span_num++) { span = &g_array_index (spans, EWeekViewEventSpan, @@ -1610,6 +1615,8 @@ print_week_event (GtkPrintContext *context, PangoFontDescription *font, if (pixbuf) g_object_unref (pixbuf); + + g_free (text); } |