[evolution] I#399 - Allow Selection From Multiple User-Defined Reminder Times
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution] I#399 - Allow Selection From Multiple User-Defined Reminder Times
- Date: Tue, 11 Jun 2019 16:18:14 +0000 (UTC)
commit fbe4b92b595fa5bfbc2827c86793ac37313e11fc
Author: Milan Crha <mcrha redhat com>
Date: Tue Jun 11 18:18:27 2019 +0200
I#399 - Allow Selection From Multiple User-Defined Reminder Times
Closes https://gitlab.gnome.org/GNOME/evolution/issues/399
data/org.gnome.evolution.calendar.gschema.xml.in | 4 +
src/calendar/gui/e-alarm-list.c | 45 +-
src/calendar/gui/e-comp-editor-page-reminders.c | 700 +++++++++++++++++------
3 files changed, 523 insertions(+), 226 deletions(-)
---
diff --git a/data/org.gnome.evolution.calendar.gschema.xml.in
b/data/org.gnome.evolution.calendar.gschema.xml.in
index 4813b6e14a..3fe4a630ec 100644
--- a/data/org.gnome.evolution.calendar.gschema.xml.in
+++ b/data/org.gnome.evolution.calendar.gschema.xml.in
@@ -457,6 +457,10 @@
<default>false</default>
<_summary>Allow direct edit of event Summary when clicking on it in the Day, Work Week, Week or Month
view.</_summary>
</key>
+ <key name="custom-reminders-minutes" type="ai">
+ <default>[]</default>
+ <_summary>User-defined reminder times, in minutes</_summary>
+ </key>
<!-- The following keys are deprecated. -->
diff --git a/src/calendar/gui/e-alarm-list.c b/src/calendar/gui/e-alarm-list.c
index 3b0d47c988..2509d9782c 100644
--- a/src/calendar/gui/e-alarm-list.c
+++ b/src/calendar/gui/e-alarm-list.c
@@ -357,48 +357,17 @@ e_alarm_list_get_path (GtkTreeModel *tree_model,
static gchar *
get_alarm_duration_string (ICalDuration *duration)
{
- GString *string = g_string_new (NULL);
- gboolean have_something;
- guint value;
+ gint seconds = 0;
- have_something = FALSE;
+ seconds = i_cal_duration_as_int (duration);
- value = i_cal_duration_get_days (duration);
- if (value >= 1) {
- /* Translator: Entire string is like "Pop up an alert %d days before start" */
- g_string_printf (string, ngettext ("%d day", "%d days", value), value);
- have_something = TRUE;
- }
-
- value = i_cal_duration_get_weeks (duration);
- if (value >= 1) {
- /* Translator: Entire string is like "Pop up an alert %d weeks before start" */
- g_string_printf (string, ngettext ("%d week","%d weeks", value), value);
- have_something = TRUE;
- }
-
- value = i_cal_duration_get_hours (duration);
- if (value >= 1) {
- /* Translator: Entire string is like "Pop up an alert %d hours before start" */
- g_string_printf (string, ngettext ("%d hour", "%d hours", value), value);
- have_something = TRUE;
- }
-
- value = i_cal_duration_get_minutes (duration);
- if (value >= 1) {
- /* Translator: Entire string is like "Pop up an alert %d minutes before start" */
- g_string_printf (string, ngettext ("%d minute", "%d minutes", value), value);
- have_something = TRUE;
- }
+ if (!seconds)
+ return NULL;
- value = i_cal_duration_get_seconds (duration);
- if (value >= 1) {
- /* Translator: Entire string is like "Pop up an alert %d seconds before start" */
- g_string_printf (string, ngettext ("%d second", "%d seconds", value), value);
- have_something = TRUE;
- }
+ if (seconds < 0)
+ seconds *= -1;
- return g_string_free (string, !have_something);
+ return e_cal_util_seconds_to_string (seconds);
}
static gchar *
diff --git a/src/calendar/gui/e-comp-editor-page-reminders.c b/src/calendar/gui/e-comp-editor-page-reminders.c
index 1708886cc4..f2f1076b63 100644
--- a/src/calendar/gui/e-comp-editor-page-reminders.c
+++ b/src/calendar/gui/e-comp-editor-page-reminders.c
@@ -39,33 +39,10 @@
#define SECTION_NAME _("Send To")
#define X_EVOLUTION_NEEDS_DESCRIPTION "X-EVOLUTION-NEEDS-DESCRIPTION"
-enum {
- ALARM_NONE,
- ALARM_15_MINUTES,
- ALARM_1_HOUR,
- ALARM_1_DAY,
- ALARM_USER_TIME,
- ALARM_CUSTOM
-};
-
-static const gint alarm_map_with_user_time[] = {
- ALARM_NONE,
- ALARM_15_MINUTES,
- ALARM_1_HOUR,
- ALARM_1_DAY,
- ALARM_USER_TIME,
- ALARM_CUSTOM,
- -1
-};
-
-static const gint alarm_map_without_user_time[] = {
- ALARM_NONE,
- ALARM_15_MINUTES,
- ALARM_1_HOUR,
- ALARM_1_DAY,
- ALARM_CUSTOM,
- -1
-};
+#define N_PREDEFINED_ALARMS 3
+#define N_MAX_PREDEFINED_USER_ALARMS 10
+/* The 3 = 1 for the default alarm + 1 for None + 1 for Custom */
+#define N_MAX_PREDEFINED_ALARMS ((N_PREDEFINED_ALARMS) + (N_MAX_PREDEFINED_USER_ALARMS) + 3)
/* "relative" types */
enum {
@@ -130,6 +107,7 @@ static const gint duration_units_map[] = {
struct _ECompEditorPageRemindersPrivate {
GtkWidget *alarms_combo;
+ GtkWidget *remove_custom_times_button;
GtkWidget *alarms_scrolled_window;
GtkWidget *alarms_tree_view;
GtkWidget *alarms_button_box;
@@ -161,11 +139,15 @@ struct _ECompEditorPageRemindersPrivate {
GtkWidget *custom_email_message_check;
GtkWidget *custom_email_message_text_view;
+ GtkWidget *add_custom_time_popover;
+ GtkWidget *add_custom_time_days_spin;
+ GtkWidget *add_custom_time_hours_spin;
+ GtkWidget *add_custom_time_minutes_spin;
+ GtkWidget *add_custom_time_add_button;
+
EAlarmList *alarm_list;
- EDurationType alarm_units;
- gint alarm_interval;
- /* either with-user-time or without it */
- const gint *alarm_map;
+ /* Interval in minutes. */
+ gint predefined_alarms[N_MAX_PREDEFINED_ALARMS];
/* Addressbook name selector, created on demand */
ENameSelector *name_selector;
@@ -173,6 +155,29 @@ struct _ECompEditorPageRemindersPrivate {
G_DEFINE_TYPE (ECompEditorPageReminders, e_comp_editor_page_reminders, E_TYPE_COMP_EDITOR_PAGE)
+static gint
+ecep_reminders_get_alarm_index (GtkComboBox *combo_box)
+{
+ GtkTreeModel *model;
+ gint alarm_index;
+
+ g_return_val_if_fail (GTK_IS_COMBO_BOX (combo_box), -1);
+
+ alarm_index = gtk_combo_box_get_active (combo_box);
+ if (alarm_index == -1)
+ return alarm_index;
+
+ model = gtk_combo_box_get_model (combo_box);
+ if (!model)
+ return -1;
+
+ /* The Custom alarm is always the last item */
+ if (alarm_index == gtk_tree_model_iter_n_children (model, NULL) - 1)
+ alarm_index = -2;
+
+ return alarm_index;
+}
+
static void
ecep_reminders_sanitize_option_widgets (ECompEditorPageReminders *page_reminders)
{
@@ -184,8 +189,7 @@ ecep_reminders_sanitize_option_widgets (ECompEditorPageReminders *page_reminders
any_selected = gtk_tree_selection_count_selected_rows (gtk_tree_view_get_selection (
GTK_TREE_VIEW (page_reminders->priv->alarms_tree_view))) > 0;
- is_custom = e_dialog_combo_box_get (page_reminders->priv->alarms_combo,
- page_reminders->priv->alarm_map) == ALARM_CUSTOM;
+ is_custom = ecep_reminders_get_alarm_index (GTK_COMBO_BOX (page_reminders->priv->alarms_combo)) == -2;
gtk_widget_set_sensitive (page_reminders->priv->alarms_tree_view, is_custom);
gtk_widget_set_sensitive (page_reminders->priv->alarms_add_button, is_custom);
@@ -360,6 +364,7 @@ ecep_reminders_selected_to_widgets (ECompEditorPageReminders *page_reminders)
ICalDuration *duration;
GtkTreeSelection *selection;
GtkTreeIter iter;
+ gint duration_minutes = 0;
g_return_if_fail (E_IS_COMP_EDITOR_PAGE_REMINDERS (page_reminders));
@@ -400,18 +405,22 @@ ecep_reminders_selected_to_widgets (ECompEditorPageReminders *page_reminders)
else
e_dialog_combo_box_set (page_reminders->priv->relative_time_combo, AFTER, relative_map);
- if (duration && i_cal_duration_get_days (duration)) {
+ if (duration) {
+ duration_minutes = i_cal_duration_as_int (duration) / 60;
+
+ if (duration_minutes < 0)
+ duration_minutes *= -1;
+ }
+
+ if (duration_minutes && !(duration_minutes % (24 * 60))) {
e_dialog_combo_box_set (page_reminders->priv->unit_combo, DAYS, value_map);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON (page_reminders->priv->time_spin),
- i_cal_duration_get_days (duration));
- } else if (duration && i_cal_duration_get_hours (duration)) {
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (page_reminders->priv->time_spin),
duration_minutes / (24 * 60));
+ } else if (duration_minutes && !(duration_minutes % 60)) {
e_dialog_combo_box_set (page_reminders->priv->unit_combo, HOURS, value_map);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON (page_reminders->priv->time_spin),
- i_cal_duration_get_hours (duration));
- } else if (duration && i_cal_duration_get_minutes (duration)) {
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (page_reminders->priv->time_spin),
duration_minutes / 60);
+ } else if (duration_minutes) {
e_dialog_combo_box_set (page_reminders->priv->unit_combo, MINUTES, value_map);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON (page_reminders->priv->time_spin),
- i_cal_duration_get_minutes (duration));
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (page_reminders->priv->time_spin),
duration_minutes);
} else {
e_dialog_combo_box_set (page_reminders->priv->unit_combo, MINUTES, value_map);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (page_reminders->priv->time_spin), 0);
@@ -803,13 +812,32 @@ ecep_reminders_alarms_selection_changed_cb (GtkTreeSelection *selection,
ecep_reminders_selected_to_widgets (page_reminders);
}
+static gint
+ecep_reminders_interval_to_int (gint days,
+ gint hours,
+ gint minutes)
+{
+ return (days * 24 * 60) + (hours * 60) + minutes;
+}
+
+static void
+ecep_reminders_int_to_interval (gint value,
+ gint *out_days,
+ gint *out_hours,
+ gint *out_minutes)
+{
+ *out_days = value / (24 * 60);
+ *out_hours = (value / 60) % 24;
+ *out_minutes = value % 60;
+}
+
static void
ecep_reminders_alarms_combo_changed_cb (GtkComboBox *combo_box,
ECompEditorPageReminders *page_reminders)
{
ECalComponentAlarm *alarm;
ICalDuration *duration;
- gint alarm_type;
+ gint alarm_index;
g_return_if_fail (E_IS_COMP_EDITOR_PAGE_REMINDERS (page_reminders));
@@ -818,13 +846,13 @@ ecep_reminders_alarms_combo_changed_cb (GtkComboBox *combo_box,
if (!e_comp_editor_page_get_updating (E_COMP_EDITOR_PAGE (page_reminders)))
e_comp_editor_page_emit_changed (E_COMP_EDITOR_PAGE (page_reminders));
- alarm_type = e_dialog_combo_box_get (page_reminders->priv->alarms_combo,
page_reminders->priv->alarm_map);
- if (alarm_type == ALARM_NONE) {
+ alarm_index = ecep_reminders_get_alarm_index (GTK_COMBO_BOX (page_reminders->priv->alarms_combo));
+ if (alarm_index == -1 || alarm_index == 0) {
e_alarm_list_clear (page_reminders->priv->alarm_list);
return;
}
- if (alarm_type == ALARM_CUSTOM) {
+ if (alarm_index == -2) {
GtkTreeSelection *selection;
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW
(page_reminders->priv->alarms_tree_view));
@@ -849,37 +877,23 @@ ecep_reminders_alarms_combo_changed_cb (GtkComboBox *combo_box,
i_cal_duration_set_is_neg (duration, TRUE);
- switch (alarm_type) {
- case ALARM_15_MINUTES:
- i_cal_duration_set_minutes (duration, 15);
- break;
+ if (alarm_index >= 1 && alarm_index < N_MAX_PREDEFINED_ALARMS) {
+ gint ii;
- case ALARM_1_HOUR:
- i_cal_duration_set_hours (duration, 1);
- break;
+ for (ii = 0; ii < alarm_index - 1 && page_reminders->priv->predefined_alarms[ii] != -1; ii++)
{
+ }
- case ALARM_1_DAY:
- i_cal_duration_set_days (duration, 1);
- break;
+ g_warn_if_fail (ii == alarm_index - 1);
- case ALARM_USER_TIME:
- switch (page_reminders->priv->alarm_units) {
- case E_DURATION_DAYS:
- i_cal_duration_set_days (duration, page_reminders->priv->alarm_interval);
- break;
+ if (ii == alarm_index - 1) {
+ gint days = 0, hours = 0, minutes = 0;
- case E_DURATION_HOURS:
- i_cal_duration_set_hours (duration, page_reminders->priv->alarm_interval);
- break;
+ ecep_reminders_int_to_interval (page_reminders->priv->predefined_alarms[alarm_index -
1], &days, &hours, &minutes);
- case E_DURATION_MINUTES:
- i_cal_duration_set_minutes (duration, page_reminders->priv->alarm_interval);
- break;
+ i_cal_duration_set_days (duration, days);
+ i_cal_duration_set_hours (duration, hours);
+ i_cal_duration_set_minutes (duration, minutes);
}
- break;
-
- default:
- break;
}
e_cal_component_alarm_take_trigger (alarm,
@@ -1094,11 +1108,10 @@ ecep_reminders_send_to_clicked_cb (GtkWidget *button,
}
static gboolean
-ecep_reminders_is_custom_alarm (ECalComponentAlarm *ca,
+ecep_reminders_is_custom_alarm (ECompEditorPageReminders *page_reminders,
+ ECalComponentAlarm *ca,
const gchar *old_summary,
- EDurationType user_units,
- gint user_interval,
- gint *alarm_type)
+ gint *alarm_index)
{
ECalComponentAlarmTrigger *trigger;
ECalComponentAlarmRepeat *repeat;
@@ -1106,6 +1119,7 @@ ecep_reminders_is_custom_alarm (ECalComponentAlarm *ca,
ECalComponentText *desc;
ICalDuration *duration;
GSList *attachments;
+ gint ii, value;
action = e_cal_component_alarm_get_action (ca);
if (action != E_CAL_COMPONENT_ALARM_DISPLAY)
@@ -1134,70 +1148,23 @@ ecep_reminders_is_custom_alarm (ECalComponentAlarm *ca,
return TRUE;
duration = e_cal_component_alarm_trigger_get_duration (trigger);
- if (!duration || i_cal_duration_is_neg (duration) != 1)
- return TRUE;
-
- if (i_cal_duration_get_weeks (duration) != 0)
+ if (!duration || (!i_cal_duration_is_neg (duration) && i_cal_duration_as_int (duration) != 0))
return TRUE;
if (i_cal_duration_get_seconds (duration) != 0)
return TRUE;
- if (i_cal_duration_get_days (duration) == 1 &&
- i_cal_duration_get_hours (duration) == 0 &&
- i_cal_duration_get_minutes (duration) == 0) {
- if (alarm_type)
- *alarm_type = ALARM_1_DAY;
- return FALSE;
- }
-
- if (i_cal_duration_get_days (duration) == 0 &&
- i_cal_duration_get_hours (duration) == 1 &&
- i_cal_duration_get_minutes (duration) == 0) {
- if (alarm_type)
- *alarm_type = ALARM_1_HOUR;
- return FALSE;
- }
-
- if (i_cal_duration_get_days (duration) == 0 &&
- i_cal_duration_get_hours (duration) == 0 &&
- i_cal_duration_get_minutes (duration) == 15) {
- if (alarm_type)
- *alarm_type = ALARM_15_MINUTES;
- return FALSE;
- }
+ value = i_cal_duration_as_int (duration) / 60;
- if (user_interval != -1) {
- switch (user_units) {
- case E_DURATION_DAYS:
- if (i_cal_duration_get_days (duration) == user_interval &&
- i_cal_duration_get_hours (duration) == 0 &&
- i_cal_duration_get_minutes (duration) == 0) {
- if (alarm_type)
- *alarm_type = ALARM_USER_TIME;
- return FALSE;
- }
- break;
+ if (value < 0)
+ value *= -1;
- case E_DURATION_HOURS:
- if (i_cal_duration_get_days (duration) == 0 &&
- i_cal_duration_get_hours (duration) == user_interval &&
- i_cal_duration_get_minutes (duration) == 0) {
- if (alarm_type)
- *alarm_type = ALARM_USER_TIME;
- return FALSE;
- }
- break;
+ for (ii = 0; ii < N_MAX_PREDEFINED_ALARMS && page_reminders->priv->predefined_alarms[ii] != -1; ii++)
{
+ if (value == page_reminders->priv->predefined_alarms[ii]) {
+ if (alarm_index)
+ *alarm_index = ii + 1;
- case E_DURATION_MINUTES:
- if (i_cal_duration_get_days (duration) == 0 &&
- i_cal_duration_get_hours (duration) == 0 &&
- i_cal_duration_get_minutes (duration) == user_interval) {
- if (alarm_type)
- *alarm_type = ALARM_USER_TIME;
- return FALSE;
- }
- break;
+ return FALSE;
}
}
@@ -1205,12 +1172,11 @@ ecep_reminders_is_custom_alarm (ECalComponentAlarm *ca,
}
static gboolean
-ecep_reminders_is_custom_alarm_uid_list (ECalComponent *comp,
+ecep_reminders_is_custom_alarm_uid_list (ECompEditorPageReminders *page_reminders,
+ ECalComponent *comp,
GSList *alarm_uids,
const gchar *old_summary,
- EDurationType user_units,
- gint user_interval,
- gint *alarm_type)
+ gint *alarm_index)
{
ECalComponentAlarm *ca;
gboolean result;
@@ -1222,7 +1188,7 @@ ecep_reminders_is_custom_alarm_uid_list (ECalComponent *comp,
return TRUE;
ca = e_cal_component_get_alarm (comp, alarm_uids->data);
- result = ecep_reminders_is_custom_alarm (ca, old_summary, user_units, user_interval, alarm_type);
+ result = ecep_reminders_is_custom_alarm (page_reminders, ca, old_summary, alarm_index);
e_cal_component_alarm_free (ca);
return result;
@@ -1406,7 +1372,7 @@ ecep_reminders_fill_widgets (ECompEditorPage *page,
valarm = i_cal_component_get_first_component (component, I_CAL_VALARM_COMPONENT);
if (!valarm) {
- e_dialog_combo_box_set (page_reminders->priv->alarms_combo, ALARM_NONE,
page_reminders->priv->alarm_map);
+ gtk_combo_box_set_active (GTK_COMBO_BOX (page_reminders->priv->alarms_combo), 0);
return;
}
@@ -1415,15 +1381,21 @@ ecep_reminders_fill_widgets (ECompEditorPage *page,
comp = e_cal_component_new_from_icalcomponent (i_cal_component_clone (component));
if (comp && e_cal_component_has_alarms (comp)) {
GSList *alarms, *link;
- gint alarm_type = ALARM_NONE;
+ gint alarm_index = 0;
alarms = e_cal_component_get_alarm_uids (comp);
- if (ecep_reminders_is_custom_alarm_uid_list (comp, alarms, i_cal_component_get_summary
(component),
- page_reminders->priv->alarm_units, page_reminders->priv->alarm_interval, &alarm_type))
- alarm_type = ALARM_CUSTOM;
+ if (ecep_reminders_is_custom_alarm_uid_list (page_reminders, comp, alarms,
i_cal_component_get_summary (component), &alarm_index)) {
+ GtkTreeModel *model;
- e_dialog_combo_box_set (page_reminders->priv->alarms_combo, alarm_type,
page_reminders->priv->alarm_map);
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (page_reminders->priv->alarms_combo));
+ alarm_index = gtk_tree_model_iter_n_children (model, NULL) - 1;
+ }
+
+ if (alarm_index < 0)
+ alarm_index = 0;
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (page_reminders->priv->alarms_combo), alarm_index);
e_alarm_list_clear (page_reminders->priv->alarm_list);
@@ -1438,7 +1410,7 @@ ecep_reminders_fill_widgets (ECompEditorPage *page,
g_slist_free_full (alarms, g_free);
- if (e_dialog_combo_box_get (page_reminders->priv->alarms_combo,
page_reminders->priv->alarm_map) == ALARM_CUSTOM) {
+ if (ecep_reminders_get_alarm_index (GTK_COMBO_BOX (page_reminders->priv->alarms_combo)) ==
-2) {
GtkTreeSelection *selection;
GtkTreeIter iter;
@@ -1447,7 +1419,7 @@ ecep_reminders_fill_widgets (ECompEditorPage *page,
gtk_tree_selection_select_iter (selection, &iter);
}
} else {
- e_dialog_combo_box_set (page_reminders->priv->alarms_combo, ALARM_NONE,
page_reminders->priv->alarm_map);
+ gtk_combo_box_set_active (GTK_COMBO_BOX (page_reminders->priv->alarms_combo), 0);
}
g_clear_object (&comp);
@@ -1642,6 +1614,353 @@ ecep_reminders_setup_ui (ECompEditorPageReminders *page_reminders)
}
}
+static gboolean
+ecep_reminders_add_predefined_alarm (ECompEditorPageReminders *page_reminders,
+ gint value_minutes)
+{
+ gint ii;
+
+ g_return_val_if_fail (E_IS_COMP_EDITOR_PAGE_REMINDERS (page_reminders), FALSE);
+ g_return_val_if_fail (value_minutes >= 0, FALSE);
+
+ for (ii = 0; ii < N_MAX_PREDEFINED_ALARMS && page_reminders->priv->predefined_alarms[ii] != -1; ii++)
{
+ if (value_minutes == page_reminders->priv->predefined_alarms[ii])
+ return FALSE;
+ }
+
+ if (ii < N_MAX_PREDEFINED_ALARMS) {
+ page_reminders->priv->predefined_alarms[ii] = value_minutes;
+
+ if (ii + 1 < N_MAX_PREDEFINED_ALARMS)
+ page_reminders->priv->predefined_alarms[ii + 1] = -1;
+ }
+
+ return ii < N_MAX_PREDEFINED_ALARMS;
+}
+
+static gint
+ecep_reminders_compare_predefined_alarm (gconstpointer data1,
+ gconstpointer data2,
+ gpointer user_data)
+{
+ gint value1 = * (gint *) data1;
+ gint value2 = * (gint *) data2;
+
+ return value1 - value2;
+}
+
+static void
+ecep_reminders_sort_predefined_alarms (ECompEditorPageReminders *page_reminders)
+{
+ gint nelems;
+
+ g_return_if_fail (E_IS_COMP_EDITOR_PAGE_REMINDERS (page_reminders));
+
+ for (nelems = N_PREDEFINED_ALARMS; nelems < N_MAX_PREDEFINED_ALARMS &&
page_reminders->priv->predefined_alarms[nelems] != -1; nelems++) {
+ /* Just count those filled */
+ }
+
+ nelems -= N_PREDEFINED_ALARMS;
+
+ if (nelems > 1) {
+ g_qsort_with_data (&(page_reminders->priv->predefined_alarms[N_PREDEFINED_ALARMS]), nelems,
+ sizeof (gint), ecep_reminders_compare_predefined_alarm, NULL);
+ }
+}
+
+static gboolean
+ecep_reminders_fill_alarms_combo (ECompEditorPageReminders *page_reminders,
+ gint select_minutes)
+{
+ GtkComboBoxText *text_combo;
+ gint ii, select_index = 0;
+ gboolean did_select = FALSE;
+
+ g_return_val_if_fail (E_IS_COMP_EDITOR_PAGE_REMINDERS (page_reminders), FALSE);
+ g_return_val_if_fail (GTK_IS_COMBO_BOX_TEXT (page_reminders->priv->alarms_combo), FALSE);
+
+ text_combo = GTK_COMBO_BOX_TEXT (page_reminders->priv->alarms_combo);
+
+ g_signal_handlers_block_by_func (text_combo, ecep_reminders_alarms_combo_changed_cb, page_reminders);
+
+ if (select_minutes < 0)
+ select_index = gtk_combo_box_get_active (GTK_COMBO_BOX (text_combo));
+
+ gtk_combo_box_text_remove_all (text_combo);
+
+ /* Translators: "None" for "No reminder set" */
+ gtk_combo_box_text_append_text (text_combo, C_("cal-reminders", "None"));
+
+ for (ii = 0; ii < N_MAX_PREDEFINED_ALARMS && page_reminders->priv->predefined_alarms[ii] != -1; ii++)
{
+ gchar *text, *merged;
+
+ if (page_reminders->priv->predefined_alarms[ii]) {
+ text = e_cal_util_seconds_to_string (page_reminders->priv->predefined_alarms[ii] *
60);
+ /* Translators: This constructs predefined reminder's description, for example "15
minutes before",
+ "1 hour before", "1 day before", but, if user has set, also more complicated
strings like
+ "2 days 13 hours 1 minute before". */
+ merged = g_strdup_printf (C_("cal-reminders", "%s before"), text);
+ gtk_combo_box_text_append_text (text_combo, merged);
+ g_free (merged);
+ g_free (text);
+ } else {
+ gtk_combo_box_text_append_text (text_combo, C_("cal-reminders", "at the start"));
+ }
+
+ if (select_minutes >= 0 && select_minutes == page_reminders->priv->predefined_alarms[ii])
+ select_index = ii + 1;
+ }
+
+ /* Translators: "Custom" for "Custom reminder set" */
+ gtk_combo_box_text_append_text (text_combo, C_("cal-reminders", "Custom"));
+
+ g_signal_handlers_unblock_by_func (text_combo, ecep_reminders_alarms_combo_changed_cb,
page_reminders);
+
+ if (select_index >= 0 && select_index <= ii) {
+ gtk_combo_box_set_active (GTK_COMBO_BOX (text_combo), select_index);
+ did_select = select_minutes >= 0;
+ } else {
+ gtk_combo_box_set_active (GTK_COMBO_BOX (text_combo), 0);
+ }
+
+ return did_select;
+}
+
+static void
+ecep_reminders_add_default_alarm_time (ECompEditorPageReminders *page_reminders)
+{
+ EDurationType alarm_units;
+ gint alarm_interval, minutes;
+
+ g_return_if_fail (E_IS_COMP_EDITOR_PAGE_REMINDERS (page_reminders));
+
+ alarm_interval = calendar_config_get_default_reminder_interval ();
+ alarm_units = calendar_config_get_default_reminder_units ();
+
+ minutes = ecep_reminders_interval_to_int (
+ alarm_units == E_DURATION_DAYS ? alarm_interval : 0,
+ alarm_units == E_DURATION_HOURS ? alarm_interval : 0,
+ alarm_units == E_DURATION_MINUTES ? alarm_interval : 0);
+
+ ecep_reminders_add_predefined_alarm (page_reminders, minutes);
+}
+
+static void
+ecep_reminders_add_custom_time_add_button_clicked_cb (GtkButton *button,
+ gpointer user_data)
+{
+ ECompEditorPageReminders *page_reminders = user_data;
+ gboolean found = FALSE;
+ gint new_minutes, ii;
+
+ g_return_if_fail (E_IS_COMP_EDITOR_PAGE_REMINDERS (page_reminders));
+
+ new_minutes = ecep_reminders_interval_to_int (
+ gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON
(page_reminders->priv->add_custom_time_days_spin)),
+ gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON
(page_reminders->priv->add_custom_time_hours_spin)),
+ gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON
(page_reminders->priv->add_custom_time_minutes_spin)));
+ g_return_if_fail (new_minutes >= 0);
+
+ gtk_widget_hide (page_reminders->priv->add_custom_time_popover);
+
+ for (ii = 0; ii < N_MAX_PREDEFINED_ALARMS && page_reminders->priv->predefined_alarms[ii] != -1; ii++)
{
+ if (new_minutes == page_reminders->priv->predefined_alarms[ii]) {
+ found = TRUE;
+ gtk_combo_box_set_active (GTK_COMBO_BOX (page_reminders->priv->alarms_combo), ii + 1);
+ break;
+ }
+ }
+
+ if (!found) {
+ GSettings *settings;
+ GVariant *variant;
+ gboolean any_user_alarm_added = FALSE;
+ gint32 array[N_MAX_PREDEFINED_USER_ALARMS + 1] = { 0 }, narray = 0, ii;
+
+ settings = e_util_ref_settings ("org.gnome.evolution.calendar");
+ variant = g_settings_get_value (settings, "custom-reminders-minutes");
+ if (variant) {
+ const gint32 *stored;
+ gsize nstored = 0;
+
+ stored = g_variant_get_fixed_array (variant, &nstored, sizeof (gint32));
+ if (stored && nstored > 0) {
+ /* Skip the oldest, when too many stored */
+ for (ii = nstored >= N_MAX_PREDEFINED_USER_ALARMS ? 1 : 0; ii <
N_MAX_PREDEFINED_USER_ALARMS && ii < nstored; ii++) {
+ array[narray] = stored[ii];
+ narray++;
+ }
+ }
+
+ g_variant_unref (variant);
+ }
+
+ /* Add the new at the end of the array */
+ array[narray] = new_minutes;
+ narray++;
+
+ variant = g_variant_new_fixed_array (G_VARIANT_TYPE_INT32, array, narray, sizeof (gint32));
+ g_settings_set_value (settings, "custom-reminders-minutes", variant);
+
+ g_object_unref (settings);
+
+ page_reminders->priv->predefined_alarms[N_PREDEFINED_ALARMS] = -1;
+
+ ecep_reminders_add_default_alarm_time (page_reminders);
+
+ for (ii = 0; ii < narray; ii++) {
+ if (ecep_reminders_add_predefined_alarm (page_reminders, array[ii]))
+ any_user_alarm_added = TRUE;
+ }
+
+ ecep_reminders_sort_predefined_alarms (page_reminders);
+
+ if (!ecep_reminders_fill_alarms_combo (page_reminders, new_minutes))
+ gtk_combo_box_set_active (GTK_COMBO_BOX (page_reminders->priv->alarms_combo), 0);
+
+ gtk_widget_set_sensitive (page_reminders->priv->remove_custom_times_button,
any_user_alarm_added);
+ }
+}
+
+static void
+ecep_reminders_add_custom_time_clicked_cb (GtkWidget *button,
+ gpointer user_data)
+{
+ ECompEditorPageReminders *page_reminders = user_data;
+
+ g_return_if_fail (E_IS_COMP_EDITOR_PAGE_REMINDERS (page_reminders));
+
+ if (!page_reminders->priv->add_custom_time_popover) {
+ GtkWidget *widget;
+ GtkBox *vbox, *box;
+
+ page_reminders->priv->add_custom_time_days_spin = gtk_spin_button_new_with_range (0.0, 366.0,
1.0);
+ page_reminders->priv->add_custom_time_hours_spin = gtk_spin_button_new_with_range (0.0, 23.0,
1.0);
+ page_reminders->priv->add_custom_time_minutes_spin = gtk_spin_button_new_with_range (0.0,
59.0, 1.0);
+
+ g_object_set (G_OBJECT (page_reminders->priv->add_custom_time_days_spin),
+ "digits", 0,
+ "numeric", TRUE,
+ "snap-to-ticks", TRUE,
+ NULL);
+
+ g_object_set (G_OBJECT (page_reminders->priv->add_custom_time_hours_spin),
+ "digits", 0,
+ "numeric", TRUE,
+ "snap-to-ticks", TRUE,
+ NULL);
+
+ g_object_set (G_OBJECT (page_reminders->priv->add_custom_time_minutes_spin),
+ "digits", 0,
+ "numeric", TRUE,
+ "snap-to-ticks", TRUE,
+ NULL);
+
+ vbox = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 2));
+
+ widget = gtk_label_new (_("Set a custom predefined time to"));
+ gtk_box_pack_start (vbox, widget, FALSE, FALSE, 0);
+
+ box = GTK_BOX (gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2));
+ g_object_set (G_OBJECT (box),
+ "halign", GTK_ALIGN_START,
+ "hexpand", FALSE,
+ "valign", GTK_ALIGN_CENTER,
+ "vexpand", FALSE,
+ NULL);
+
+ gtk_box_pack_start (box, page_reminders->priv->add_custom_time_days_spin, FALSE, FALSE, 4);
+ /* Translators: this is part of: "Set a custom predefined time to [nnn] days [nnn] hours
[nnn] minutes", where the text in "[]" means a separate widget */
+ widget = gtk_label_new_with_mnemonic (C_("cal-reminders", "da_ys"));
+ gtk_label_set_mnemonic_widget (GTK_LABEL (widget),
page_reminders->priv->add_custom_time_days_spin);
+ gtk_box_pack_start (box, widget, FALSE, FALSE, 4);
+
+ gtk_box_pack_start (vbox, GTK_WIDGET (box), FALSE, FALSE, 0);
+
+ box = GTK_BOX (gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2));
+ g_object_set (G_OBJECT (box),
+ "halign", GTK_ALIGN_START,
+ "hexpand", FALSE,
+ "valign", GTK_ALIGN_CENTER,
+ "vexpand", FALSE,
+ NULL);
+
+ gtk_box_pack_start (box, page_reminders->priv->add_custom_time_hours_spin, FALSE, FALSE, 4);
+ /* Translators: this is part of: "Set a custom predefined time to [nnn] days [nnn] hours
[nnn] minutes", where the text in "[]" means a separate widget */
+ widget = gtk_label_new_with_mnemonic (C_("cal-reminders", "_hours"));
+ gtk_label_set_mnemonic_widget (GTK_LABEL (widget),
page_reminders->priv->add_custom_time_hours_spin);
+ gtk_box_pack_start (box, widget, FALSE, FALSE, 4);
+
+ gtk_box_pack_start (vbox, GTK_WIDGET (box), FALSE, FALSE, 0);
+
+ box = GTK_BOX (gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2));
+ g_object_set (G_OBJECT (box),
+ "halign", GTK_ALIGN_START,
+ "hexpand", FALSE,
+ "valign", GTK_ALIGN_CENTER,
+ "vexpand", FALSE,
+ NULL);
+
+ gtk_box_pack_start (box, page_reminders->priv->add_custom_time_minutes_spin, FALSE, FALSE, 4);
+ /* Translators: this is part of: "Set a custom predefined time to [nnn] days [nnn] hours
[nnn] minutes", where the text in "[]" means a separate widget */
+ widget = gtk_label_new_with_mnemonic (C_("cal-reminders", "_minutes"));
+ gtk_label_set_mnemonic_widget (GTK_LABEL (widget),
page_reminders->priv->add_custom_time_minutes_spin);
+ gtk_box_pack_start (box, widget, FALSE, FALSE, 4);
+
+ gtk_box_pack_start (vbox, GTK_WIDGET (box), FALSE, FALSE, 0);
+
+ page_reminders->priv->add_custom_time_add_button = gtk_button_new_with_mnemonic (_("_Add
time"));
+ g_object_set (G_OBJECT (page_reminders->priv->add_custom_time_add_button),
+ "halign", GTK_ALIGN_CENTER,
+ NULL);
+
+ gtk_box_pack_start (vbox, page_reminders->priv->add_custom_time_add_button, FALSE, FALSE, 0);
+
+ gtk_widget_show_all (GTK_WIDGET (vbox));
+
+ page_reminders->priv->add_custom_time_popover = gtk_popover_new (GTK_WIDGET (page_reminders));
+ gtk_popover_set_position (GTK_POPOVER (page_reminders->priv->add_custom_time_popover),
GTK_POS_BOTTOM);
+ gtk_container_add (GTK_CONTAINER (page_reminders->priv->add_custom_time_popover), GTK_WIDGET
(vbox));
+ gtk_container_set_border_width (GTK_CONTAINER
(page_reminders->priv->add_custom_time_popover), 6);
+
+ g_signal_connect (page_reminders->priv->add_custom_time_add_button, "clicked",
+ G_CALLBACK (ecep_reminders_add_custom_time_add_button_clicked_cb), page_reminders);
+ }
+
+ gtk_widget_hide (page_reminders->priv->add_custom_time_popover);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (page_reminders->priv->add_custom_time_days_spin), 0.0);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (page_reminders->priv->add_custom_time_hours_spin), 0.0);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (page_reminders->priv->add_custom_time_minutes_spin), 0.0);
+ gtk_popover_set_relative_to (GTK_POPOVER (page_reminders->priv->add_custom_time_popover), button);
+ gtk_widget_show (page_reminders->priv->add_custom_time_popover);
+
+ gtk_widget_grab_focus (page_reminders->priv->add_custom_time_days_spin);
+}
+
+static void
+ecep_reminders_remove_custom_times_clicked_cb (GtkButton *button,
+ gpointer user_data)
+{
+ ECompEditorPageReminders *page_reminders = user_data;
+ GSettings *settings;
+
+ g_return_if_fail (E_IS_COMP_EDITOR_PAGE_REMINDERS (page_reminders));
+
+ settings = e_util_ref_settings ("org.gnome.evolution.calendar");
+ g_settings_reset (settings, "custom-reminders-minutes");
+ g_object_unref (settings);
+
+ page_reminders->priv->predefined_alarms[N_PREDEFINED_ALARMS] = -1;
+
+ ecep_reminders_add_default_alarm_time (page_reminders);
+
+ ecep_reminders_fill_alarms_combo (page_reminders, -1);
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (page_reminders->priv->alarms_combo), 0);
+
+ gtk_widget_set_sensitive (page_reminders->priv->remove_custom_times_button, FALSE);
+}
+
static void
ecep_reminders_constructed (GObject *object)
{
@@ -1655,7 +1974,10 @@ ecep_reminders_constructed (GObject *object)
GtkGrid *grid;
ECompEditor *comp_editor;
EFocusTracker *focus_tracker;
- gchar *combo_label, *config_dir;
+ gint ii;
+ gchar *config_dir;
+ GSettings *settings;
+ GVariant *variant;
G_OBJECT_CLASS (e_comp_editor_page_reminders_parent_class)->constructed (object);
@@ -1716,58 +2038,60 @@ ecep_reminders_constructed (GObject *object)
gtk_label_set_mnemonic_widget (GTK_LABEL (label), page_reminders->priv->alarms_combo);
- /* Add the user defined time if necessary */
- page_reminders->priv->alarm_interval = calendar_config_get_default_reminder_interval ();
- page_reminders->priv->alarm_units = calendar_config_get_default_reminder_units ();
+ widget = e_dialog_button_new_with_icon ("list-add", NULL);
+ gtk_widget_set_tooltip_text (widget, _("Add custom predefined time"));
+ gtk_widget_show (widget);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
- combo_label = NULL;
+ g_signal_connect (widget, "clicked",
+ G_CALLBACK (ecep_reminders_add_custom_time_clicked_cb), page_reminders);
- switch (page_reminders->priv->alarm_units) {
- case E_DURATION_DAYS:
- if (page_reminders->priv->alarm_interval != 1) {
- combo_label = g_strdup_printf (ngettext ("%d day before", "%d days before",
- page_reminders->priv->alarm_interval), page_reminders->priv->alarm_interval);
- }
- break;
+ widget = e_dialog_button_new_with_icon ("edit-clear", NULL);
+ gtk_widget_set_tooltip_text (widget, _("Remove custom predefined times"));
+ gtk_widget_show (widget);
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ page_reminders->priv->remove_custom_times_button = widget;
+ gtk_widget_set_sensitive (page_reminders->priv->remove_custom_times_button, FALSE);
- case E_DURATION_HOURS:
- if (page_reminders->priv->alarm_interval != 1) {
- combo_label = g_strdup_printf (ngettext ("%d hour before", "%d hours before",
- page_reminders->priv->alarm_interval), page_reminders->priv->alarm_interval);
- }
- break;
+ g_signal_connect (widget, "clicked",
+ G_CALLBACK (ecep_reminders_remove_custom_times_clicked_cb), page_reminders);
+
+ page_reminders->priv->predefined_alarms[0] = ecep_reminders_interval_to_int (0, 0, 15);
+ page_reminders->priv->predefined_alarms[1] = ecep_reminders_interval_to_int (0, 1, 0);
+ page_reminders->priv->predefined_alarms[2] = ecep_reminders_interval_to_int (1, 0, 0);
+ page_reminders->priv->predefined_alarms[3] = -1;
+
+ ecep_reminders_add_default_alarm_time (page_reminders);
+
+ settings = e_util_ref_settings ("org.gnome.evolution.calendar");
+ variant = g_settings_get_value (settings, "custom-reminders-minutes");
+
+ if (variant) {
+ const gint32 *stored;
+ gsize nstored = 0;
+
+ stored = g_variant_get_fixed_array (variant, &nstored, sizeof (gint32));
+ if (stored && nstored > 0) {
+ if (nstored > N_MAX_PREDEFINED_USER_ALARMS)
+ nstored = N_MAX_PREDEFINED_USER_ALARMS;
- case E_DURATION_MINUTES:
- if (page_reminders->priv->alarm_interval != 15) {
- combo_label = g_strdup_printf (ngettext ("%d minute before", "%d minutes before",
- page_reminders->priv->alarm_interval), page_reminders->priv->alarm_interval);
+ for (ii = 0; ii < nstored; ii++) {
+ if (stored[ii] >= 0 &&
+ ecep_reminders_add_predefined_alarm (page_reminders, stored[ii])) {
+ gtk_widget_set_sensitive
(page_reminders->priv->remove_custom_times_button, TRUE);
+ }
+ }
}
- break;
- }
- text_combo = GTK_COMBO_BOX_TEXT (widget);
- /* Translators: "None" for "No reminder set" */
- gtk_combo_box_text_append_text (text_combo, C_("cal-reminders", "None"));
- /* Translators: Predefined reminder's description */
- gtk_combo_box_text_append_text (text_combo, C_("cal-reminders", "15 minutes before"));
- /* Translators: Predefined reminder's description */
- gtk_combo_box_text_append_text (text_combo, C_("cal-reminders", "1 hour before"));
- /* Translators: Predefined reminder's description */
- gtk_combo_box_text_append_text (text_combo, C_("cal-reminders", "1 day before"));
-
- if (combo_label) {
- gtk_combo_box_text_append_text (text_combo, combo_label);
- g_free (combo_label);
-
- page_reminders->priv->alarm_map = alarm_map_with_user_time;
- } else {
- page_reminders->priv->alarm_map = alarm_map_without_user_time;
+ g_variant_unref (variant);
}
- /* Translators: "Custom" for "Custom reminder set" */
- gtk_combo_box_text_append_text (text_combo, C_("cal-reminders", "Custom"));
+ g_object_unref (settings);
- gtk_combo_box_set_active (GTK_COMBO_BOX (text_combo), 0);
+ ecep_reminders_sort_predefined_alarms (page_reminders);
+ ecep_reminders_fill_alarms_combo (page_reminders, -1);
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (page_reminders->priv->alarms_combo), 0);
g_signal_connect (page_reminders->priv->alarms_combo, "changed",
G_CALLBACK (ecep_reminders_alarms_combo_changed_cb), page_reminders);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]