[evolution] Add 'Status' column to Memos and Calendar's List View



commit d307dec20868a17c6be0e51396ad436be4eb9ffe
Author: Milan Crha <mcrha redhat com>
Date:   Thu Jun 13 14:48:45 2019 +0200

    Add 'Status' column to Memos and Calendar's List View
    
    This is related to https://gitlab.gnome.org/GNOME/evolution/issues/478,
    where support for the STATUS property had been added for those components.

 src/calendar/gui/comp-util.c                    | 122 +++++++++++++++++++++
 src/calendar/gui/comp-util.h                    |  11 ++
 src/calendar/gui/e-cal-component-preview.c      |  20 +---
 src/calendar/gui/e-cal-list-view.c              |  24 +++++
 src/calendar/gui/e-cal-list-view.etspec         |   1 +
 src/calendar/gui/e-cal-model-calendar.c         |  15 +++
 src/calendar/gui/e-cal-model-calendar.h         |   1 +
 src/calendar/gui/e-cal-model-memos.c            |  50 ++++++++-
 src/calendar/gui/e-cal-model-memos.h            |   3 +-
 src/calendar/gui/e-cal-model-tasks.c            |  90 ++--------------
 src/calendar/gui/e-cal-model.c                  | 135 ++++++++++++++++++++++++
 src/calendar/gui/e-cal-model.h                  |   8 ++
 src/calendar/gui/e-comp-editor-property-parts.c |  29 ++---
 src/calendar/gui/e-memo-table.c                 |  26 +++++
 src/calendar/gui/e-memo-table.etspec            |   1 +
 src/calendar/gui/e-task-table.c                 |  88 +--------------
 src/calendar/gui/print.c                        |  18 +---
 17 files changed, 422 insertions(+), 220 deletions(-)
---
diff --git a/src/calendar/gui/comp-util.c b/src/calendar/gui/comp-util.c
index 00cc7cd089..552a23d37a 100644
--- a/src/calendar/gui/comp-util.c
+++ b/src/calendar/gui/comp-util.c
@@ -1601,3 +1601,125 @@ cal_comp_util_get_attendee_comments (ICalComponent *icomp)
 
        return NULL;
 }
+
+static struct _status_values {
+       ICalComponentKind kind;
+       ICalPropertyStatus status;
+       const gchar *text;
+} status_values[] = {
+       { I_CAL_VEVENT_COMPONENT,   I_CAL_STATUS_NONE,        NC_("iCalendarStatus", "None") },
+       { I_CAL_VEVENT_COMPONENT,   I_CAL_STATUS_TENTATIVE,   NC_("iCalendarStatus", "Tentative") },
+       { I_CAL_VEVENT_COMPONENT,   I_CAL_STATUS_CONFIRMED,   NC_("iCalendarStatus", "Confirmed") },
+       { I_CAL_VJOURNAL_COMPONENT, I_CAL_STATUS_NONE,        NC_("iCalendarStatus", "None") },
+       { I_CAL_VJOURNAL_COMPONENT, I_CAL_STATUS_DRAFT,       NC_("iCalendarStatus", "Draft") },
+       { I_CAL_VJOURNAL_COMPONENT, I_CAL_STATUS_FINAL,       NC_("iCalendarStatus", "Final") },
+       { I_CAL_VTODO_COMPONENT,    I_CAL_STATUS_NONE,        NC_("iCalendarStatus", "Not Started") },
+       { I_CAL_VTODO_COMPONENT,    I_CAL_STATUS_NEEDSACTION, NC_("iCalendarStatus", "Needs Action") },
+       { I_CAL_VTODO_COMPONENT,    I_CAL_STATUS_INPROCESS,   NC_("iCalendarStatus", "In Progress") },
+       { I_CAL_VTODO_COMPONENT,    I_CAL_STATUS_COMPLETED,   NC_("iCalendarStatus", "Completed") },
+       { I_CAL_ANY_COMPONENT,      I_CAL_STATUS_CANCELLED,   NC_("iCalendarStatus", "Cancelled") }
+};
+
+/**
+ * cal_comp_util_status_to_localized_string:
+ * @kind: an #ICalComponentKind of a component the @status belongs to
+ * @status: an #ICalPropertyStatus
+ *
+ * Returns localized text, suitable for user-visible strings,
+ * corresponding to the @status value. The @kind is used to
+ * distinguish how to localize certain values.
+ *
+ * To transform the returned string back to the enum value
+ * use cal_comp_util_localized_string_to_status().
+ *
+ * Returns: (nullable): the @status as a localized string, or %NULL,
+ *    when such @status could not be found for the given @kind
+ *
+ * Since: 3.34
+ **/
+const gchar *
+cal_comp_util_status_to_localized_string (ICalComponentKind kind,
+                                         ICalPropertyStatus status)
+{
+       gint ii;
+
+       for (ii = 0; ii < G_N_ELEMENTS (status_values); ii++) {
+               if ((status_values[ii].kind == kind ||
+                    status_values[ii].kind == I_CAL_ANY_COMPONENT ||
+                    kind == I_CAL_ANY_COMPONENT) &&
+                    status_values[ii].status == status)
+                       return g_dpgettext2 (GETTEXT_PACKAGE, "iCalendarStatus", status_values[ii].text);
+       }
+
+       return NULL;
+}
+
+/**
+ * cal_comp_util_localized_string_to_status:
+ * @kind: an #ICalComponentKind of a component the status belongs to
+ * @localized_string: (nullable): localized text for the status, or %NULL
+ * @cmp_func: (scope call) (closure user_data) (nullable): optional compare function, can be %NULL
+ * @user_data: user data for the @cmp_func
+ *
+ * Converts @localized_string returned from cal_comp_util_status_to_localized_string()
+ * back to an #ICalPropertyStatus enum. Returns %I_CAL_STATUS_NONE, when
+ * the @localized_string cannot be found for the given @kind.
+ *
+ * Returns: an #ICalPropertyStatus corresponding to given @kind and @localized_string,
+ *    or %I_CAL_STATUS_NONE, when the value cannot be found.
+ *
+ * Since: 3.34
+ **/
+ICalPropertyStatus
+cal_comp_util_localized_string_to_status (ICalComponentKind kind,
+                                         const gchar *localized_string,
+                                         GCompareDataFunc cmp_func,
+                                         gpointer user_data)
+{
+       gint ii;
+
+       if (!localized_string || !*localized_string)
+               return I_CAL_STATUS_NONE;
+
+       if (!cmp_func) {
+               cmp_func = (GCompareDataFunc) e_util_utf8_strcasecmp;
+               user_data = NULL;
+       }
+
+       for (ii = 0; ii < G_N_ELEMENTS (status_values); ii++) {
+               if ((status_values[ii].kind == kind ||
+                    status_values[ii].kind == I_CAL_ANY_COMPONENT ||
+                    kind == I_CAL_ANY_COMPONENT) &&
+                    cmp_func (localized_string, g_dpgettext2 (GETTEXT_PACKAGE, "iCalendarStatus", 
status_values[ii].text), user_data) == 0)
+                       return status_values[ii].status;
+       }
+
+       return I_CAL_STATUS_NONE;
+}
+
+/**
+ * cal_comp_util_get_status_list_for_kind:
+ * @kind: an #ICalComponentKind
+ *
+ * Returns: (element-type utf8) (transfer container): a #GList of localized strings
+ *    corresponding to #ICalPropertyStatus usable for the @kind. The caller owns
+ *    the returned #GList, but not the items of it. In other words, free the returned
+ *    #GList with g_list_free(), when no longer needed.
+ *
+ * Since: 3.34
+ **/
+GList *
+cal_comp_util_get_status_list_for_kind (ICalComponentKind kind)
+{
+       GList *items = NULL;
+       gint ii;
+
+       for (ii = 0; ii < G_N_ELEMENTS (status_values); ii++) {
+               if ((status_values[ii].kind == kind ||
+                    status_values[ii].kind == I_CAL_ANY_COMPONENT ||
+                    kind == I_CAL_ANY_COMPONENT))
+                       items = g_list_prepend (items, (gpointer) g_dpgettext2 (GETTEXT_PACKAGE, 
"iCalendarStatus", status_values[ii].text));
+       }
+
+       return g_list_reverse (items);
+}
diff --git a/src/calendar/gui/comp-util.h b/src/calendar/gui/comp-util.h
index b6ae7dc617..c1ee0a7e04 100644
--- a/src/calendar/gui/comp-util.h
+++ b/src/calendar/gui/comp-util.h
@@ -154,4 +154,15 @@ gchar *            cal_comp_util_dup_parameter_xvalue
                                                 const gchar *name);
 gchar *                cal_comp_util_get_attendee_comments
                                                (ICalComponent *icomp);
+const gchar *  cal_comp_util_status_to_localized_string
+                                               (ICalComponentKind kind,
+                                                ICalPropertyStatus status);
+ICalPropertyStatus
+               cal_comp_util_localized_string_to_status
+                                               (ICalComponentKind kind,
+                                                const gchar *localized_string,
+                                                GCompareDataFunc cmp_func,
+                                                gpointer user_data);
+GList *                cal_comp_util_get_status_list_for_kind /* const gchar * */
+                                               (ICalComponentKind kind);
 #endif
diff --git a/src/calendar/gui/e-cal-component-preview.c b/src/calendar/gui/e-cal-component-preview.c
index f760b9df42..e667131732 100644
--- a/src/calendar/gui/e-cal-component-preview.c
+++ b/src/calendar/gui/e-cal-component-preview.c
@@ -31,6 +31,7 @@
 #include "shell/e-shell-utils.h"
 
 #include "calendar-config.h"
+#include "comp-util.h"
 #include "itip-utils.h"
 
 #include "e-cal-component-preview.h"
@@ -331,23 +332,10 @@ cal_component_preview_write_html (ECalComponentPreview *preview,
        prop = i_cal_component_get_first_property (icomp, I_CAL_STATUS_PROPERTY);
        if (prop) {
                status = e_cal_component_get_status (comp);
-               switch (status) {
-               case I_CAL_STATUS_INPROCESS :
-                       tmp = _("In Progress");
-                       break;
-               case I_CAL_STATUS_COMPLETED :
-                       tmp = _("Completed");
-                       break;
-               case I_CAL_STATUS_CANCELLED :
-                       tmp = _("Cancelled");
-                       break;
-               case I_CAL_STATUS_NONE :
-               default :
-                       tmp = _("Not Started");
-                       break;
-               }
+               tmp = cal_comp_util_status_to_localized_string (i_cal_component_isa (icomp), status);
 
-               cal_component_preview_add_table_line (buffer, _("Status:"), tmp);
+               if (tmp)
+                       cal_component_preview_add_table_line (buffer, _("Status:"), tmp);
 
                g_object_unref (prop);
        }
diff --git a/src/calendar/gui/e-cal-list-view.c b/src/calendar/gui/e-cal-list-view.c
index a01841aa20..2bb9490d4f 100644
--- a/src/calendar/gui/e-cal-list-view.c
+++ b/src/calendar/gui/e-cal-list-view.c
@@ -256,11 +256,35 @@ setup_e_table (ECalListView *cal_list_view)
        e_table_extras_add_cell (extras, "classification", popup_cell);
        g_object_unref (popup_cell);
 
+       /* Status field. */
+       cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT);
+       g_object_set (
+               cell,
+               "bg_color_column", E_CAL_MODEL_FIELD_COLOR,
+               "strikeout_column", E_CAL_MODEL_FIELD_CANCELLED,
+               NULL);
+
+       popup_cell = e_cell_combo_new ();
+       e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell);
+       g_object_unref (cell);
+
+       strings = cal_comp_util_get_status_list_for_kind (e_cal_model_get_component_kind (model));
+       e_cell_combo_set_popdown_strings (
+               E_CELL_COMBO (popup_cell),
+               strings);
+       g_list_free (strings);
+
+       e_table_extras_add_cell (extras, "calstatus", popup_cell);
+       g_object_unref (popup_cell);
+
        /* Sorting */
 
        e_table_extras_add_compare (
                extras, "date-compare",
                e_cell_date_edit_compare_cb);
+       e_table_extras_add_compare (
+               extras, "status-compare",
+               e_cal_model_util_status_compare_cb);
 
        /* set proper format component for a default 'date' cell renderer */
        cell = e_table_extras_get_cell (extras, "date");
diff --git a/src/calendar/gui/e-cal-list-view.etspec b/src/calendar/gui/e-cal-list-view.etspec
index 0b772c0d45..78655f267c 100644
--- a/src/calendar/gui/e-cal-list-view.etspec
+++ b/src/calendar/gui/e-cal-list-view.etspec
@@ -8,6 +8,7 @@
   <ETableColumn model_col="10" _title="Created" expansion="2.0" minimum_width="10" resizable="true" 
cell="dateedit" compare="date-compare" priority="-2"/>
   <ETableColumn model_col="11" _title="Last modified" expansion="2.0" minimum_width="10" resizable="true" 
cell="dateedit" compare="date-compare" priority="-2"/>
   <ETableColumn model_col="12" _title="Source" expansion="1.0" minimum_width="10" resizable="true" 
cell="string" compare="collate" priority="-2"/>
+  <ETableColumn model_col="17" _title="Status" expansion="1.0" minimum_width="10" resizable="true" 
cell="calstatus" compare="status-compare" priority="-1"/>
 
   <ETableState>
     <column source="2"/>
diff --git a/src/calendar/gui/e-cal-model-calendar.c b/src/calendar/gui/e-cal-model-calendar.c
index 74e6b5f106..99d82b441d 100644
--- a/src/calendar/gui/e-cal-model-calendar.c
+++ b/src/calendar/gui/e-cal-model-calendar.c
@@ -251,6 +251,7 @@ cal_model_calendar_store_values_from_model (ECalModel *model,
        e_cal_model_util_set_value (values, source_model, E_CAL_MODEL_CALENDAR_FIELD_DTEND, row);
        e_cal_model_util_set_value (values, source_model, E_CAL_MODEL_CALENDAR_FIELD_LOCATION, row);
        e_cal_model_util_set_value (values, source_model, E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY, row);
+       e_cal_model_util_set_value (values, source_model, E_CAL_MODEL_CALENDAR_FIELD_STATUS, row);
 }
 
 static void
@@ -265,6 +266,7 @@ cal_model_calendar_fill_component_from_values (ECalModel *model,
        set_dtend (model, comp_data, e_cal_model_util_get_value (values, E_CAL_MODEL_CALENDAR_FIELD_DTEND));
        set_location (comp_data, e_cal_model_util_get_value (values, E_CAL_MODEL_CALENDAR_FIELD_LOCATION));
        set_transparency (comp_data, e_cal_model_util_get_value (values, 
E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY));
+       e_cal_model_util_set_status (comp_data, e_cal_model_util_get_value (values, 
E_CAL_MODEL_CALENDAR_FIELD_STATUS));
 }
 
 static gint
@@ -300,6 +302,8 @@ cal_model_calendar_value_at (ETableModel *etm,
                return get_location (comp_data);
        case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
                return get_transparency (comp_data);
+       case E_CAL_MODEL_CALENDAR_FIELD_STATUS:
+               return e_cal_model_util_get_status (comp_data);
        }
 
        return (gpointer) "";
@@ -352,6 +356,9 @@ cal_model_calendar_set_value_at (ETableModel *etm,
        case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
                set_transparency (comp_data, value);
                break;
+       case E_CAL_MODEL_CALENDAR_FIELD_STATUS:
+               e_cal_model_util_set_status (comp_data, value);
+               break;
        }
 
        e_cal_model_modify_component (E_CAL_MODEL (model), comp_data, mod);
@@ -380,6 +387,7 @@ cal_model_calendar_is_cell_editable (ETableModel *etm,
        case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
        case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
        case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
+       case E_CAL_MODEL_CALENDAR_FIELD_STATUS:
                return TRUE;
        }
 
@@ -402,6 +410,8 @@ cal_model_calendar_duplicate_value (ETableModel *etm,
        case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
        case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
                return g_strdup (value);
+       case E_CAL_MODEL_CALENDAR_FIELD_STATUS:
+               return (gpointer) value;
        }
 
        return NULL;
@@ -426,6 +436,7 @@ cal_model_calendar_free_value (ETableModel *etm,
                break;
        case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
        case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
+       case E_CAL_MODEL_CALENDAR_FIELD_STATUS:
                break;
        }
 }
@@ -445,6 +456,8 @@ cal_model_calendar_initialize_value (ETableModel *etm,
        case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
        case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
                return g_strdup ("");
+       case E_CAL_MODEL_CALENDAR_FIELD_STATUS:
+               return (gpointer) "";
        }
 
        return NULL;
@@ -465,6 +478,7 @@ cal_model_calendar_value_is_empty (ETableModel *etm,
                return value ? FALSE : TRUE;
        case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
        case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
+       case E_CAL_MODEL_CALENDAR_FIELD_STATUS:
                return string_is_empty (value);
        }
 
@@ -486,6 +500,7 @@ cal_model_calendar_value_to_string (ETableModel *etm,
                return e_cal_model_date_value_to_string (E_CAL_MODEL (etm), value);
        case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
        case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
+       case E_CAL_MODEL_CALENDAR_FIELD_STATUS:
                return g_strdup (value);
        }
 
diff --git a/src/calendar/gui/e-cal-model-calendar.h b/src/calendar/gui/e-cal-model-calendar.h
index c5d6833b9d..5b22385180 100644
--- a/src/calendar/gui/e-cal-model-calendar.h
+++ b/src/calendar/gui/e-cal-model-calendar.h
@@ -58,6 +58,7 @@ typedef enum {
        E_CAL_MODEL_CALENDAR_FIELD_DTEND = E_CAL_MODEL_FIELD_LAST,
        E_CAL_MODEL_CALENDAR_FIELD_LOCATION,
        E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY,
+       E_CAL_MODEL_CALENDAR_FIELD_STATUS,
        E_CAL_MODEL_CALENDAR_FIELD_LAST
 } ECalModelCalendarField;
 
diff --git a/src/calendar/gui/e-cal-model-memos.c b/src/calendar/gui/e-cal-model-memos.c
index 058b3fb636..30b89f17dc 100644
--- a/src/calendar/gui/e-cal-model-memos.c
+++ b/src/calendar/gui/e-cal-model-memos.c
@@ -56,7 +56,7 @@ cal_model_memos_store_values_from_model (ECalModel *model,
        g_return_if_fail (E_IS_TABLE_MODEL (source_model));
        g_return_if_fail (values != NULL);
 
-       /* nothing is stored from UI currently */
+       e_cal_model_util_set_value (values, source_model, E_CAL_MODEL_MEMOS_FIELD_STATUS, row);
 }
 
 static void
@@ -79,6 +79,8 @@ cal_model_memos_fill_component_from_values (ECalModel *model,
        }
 
        g_clear_object (&dtstart);
+
+       e_cal_model_util_set_status (comp_data, e_cal_model_util_get_value (values, 
E_CAL_MODEL_MEMOS_FIELD_STATUS));
 }
 
 static gint
@@ -107,6 +109,11 @@ cal_model_memos_value_at (ETableModel *etm,
        if (!comp_data)
                return (gpointer) "";
 
+       switch (col) {
+       case E_CAL_MODEL_MEMOS_FIELD_STATUS:
+               return e_cal_model_util_get_status (comp_data);
+       }
+
        return (gpointer) "";
 }
 
@@ -134,6 +141,12 @@ cal_model_memos_set_value_at (ETableModel *etm,
                return;
        }
 
+       switch (col) {
+       case E_CAL_MODEL_MEMOS_FIELD_STATUS:
+               e_cal_model_util_set_status (comp_data, value);
+               break;
+       }
+
        e_cal_model_modify_component (E_CAL_MODEL (model), comp_data, E_CAL_OBJ_MOD_ALL);
 }
 
@@ -143,7 +156,6 @@ cal_model_memos_is_cell_editable (ETableModel *etm,
                                   gint row)
 {
        ECalModelMemos *model = (ECalModelMemos *) etm;
-       gboolean retval = FALSE;
 
        g_return_val_if_fail (E_IS_CAL_MODEL_MEMOS (model), FALSE);
        g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_MEMOS_FIELD_LAST, FALSE);
@@ -153,9 +165,14 @@ cal_model_memos_is_cell_editable (ETableModel *etm,
                return FALSE;
 
        if (col < E_CAL_MODEL_FIELD_LAST)
-               retval = table_model_parent_interface->is_cell_editable (etm, col, row);
+               return table_model_parent_interface->is_cell_editable (etm, col, row);
 
-       return retval;
+       switch (col) {
+       case E_CAL_MODEL_MEMOS_FIELD_STATUS:
+               return TRUE;
+       }
+
+       return FALSE;
 }
 
 static gpointer
@@ -168,6 +185,11 @@ cal_model_memos_duplicate_value (ETableModel *etm,
        if (col < E_CAL_MODEL_FIELD_LAST)
                return table_model_parent_interface->duplicate_value (etm, col, value);
 
+       switch (col) {
+       case E_CAL_MODEL_MEMOS_FIELD_STATUS:
+               return (gpointer) value;
+       }
+
        return NULL;
 }
 
@@ -182,6 +204,11 @@ cal_model_memos_free_value (ETableModel *etm,
                table_model_parent_interface->free_value (etm, col, value);
                return;
        }
+
+       switch (col) {
+       case E_CAL_MODEL_MEMOS_FIELD_STATUS:
+               break;
+       }
 }
 
 static gpointer
@@ -193,6 +220,11 @@ cal_model_memos_initialize_value (ETableModel *etm,
        if (col < E_CAL_MODEL_FIELD_LAST)
                return table_model_parent_interface->initialize_value (etm, col);
 
+       switch (col) {
+       case E_CAL_MODEL_MEMOS_FIELD_STATUS:
+               return (gpointer) "";
+       }
+
        return NULL;
 }
 
@@ -206,6 +238,11 @@ cal_model_memos_value_is_empty (ETableModel *etm,
        if (col < E_CAL_MODEL_FIELD_LAST)
                return table_model_parent_interface->value_is_empty (etm, col, value);
 
+       switch (col) {
+       case E_CAL_MODEL_MEMOS_FIELD_STATUS:
+               return string_is_empty (value);
+       }
+
        return TRUE;
 }
 
@@ -219,6 +256,11 @@ cal_model_memos_value_to_string (ETableModel *etm,
        if (col < E_CAL_MODEL_FIELD_LAST)
                return table_model_parent_interface->value_to_string (etm, col, value);
 
+       switch (col) {
+       case E_CAL_MODEL_MEMOS_FIELD_STATUS:
+               return g_strdup (value);
+       }
+
        return g_strdup ("");
 }
 
diff --git a/src/calendar/gui/e-cal-model-memos.h b/src/calendar/gui/e-cal-model-memos.h
index b5bf0a5453..ac3ad582d6 100644
--- a/src/calendar/gui/e-cal-model-memos.h
+++ b/src/calendar/gui/e-cal-model-memos.h
@@ -56,7 +56,8 @@ typedef struct _ECalModelMemosPrivate ECalModelMemosPrivate;
 typedef enum {
        /* If you add new items here or reorder them, you have to update the
         * .etspec files for the tables using this model */
-       E_CAL_MODEL_MEMOS_FIELD_LAST = E_CAL_MODEL_FIELD_LAST
+       E_CAL_MODEL_MEMOS_FIELD_STATUS = E_CAL_MODEL_FIELD_LAST,
+       E_CAL_MODEL_MEMOS_FIELD_LAST
 
 } ECalModelMemoField;
 
diff --git a/src/calendar/gui/e-cal-model-tasks.c b/src/calendar/gui/e-cal-model-tasks.c
index 6e86ea0190..c95916d835 100644
--- a/src/calendar/gui/e-cal-model-tasks.c
+++ b/src/calendar/gui/e-cal-model-tasks.c
@@ -267,38 +267,6 @@ is_status_canceled (ECalModelComponent *comp_data)
        return res;
 }
 
-static gpointer
-get_status (ECalModelComponent *comp_data)
-{
-       ICalProperty *prop;
-
-       prop = i_cal_component_get_first_property (comp_data->icalcomp, I_CAL_STATUS_PROPERTY);
-       if (prop) {
-               ICalPropertyStatus status;
-
-               status = i_cal_property_get_status (prop);
-
-               g_object_unref (prop);
-
-               switch (status) {
-               case I_CAL_STATUS_NONE:
-                       return (gpointer) "";
-               case I_CAL_STATUS_NEEDSACTION:
-                       return (gpointer) _("Not Started");
-               case I_CAL_STATUS_INPROCESS:
-                       return (gpointer) _("In Progress");
-               case I_CAL_STATUS_COMPLETED:
-                       return (gpointer) _("Completed");
-               case I_CAL_STATUS_CANCELLED:
-                       return (gpointer) _("Cancelled");
-               default:
-                       return (gpointer) "";
-               }
-       }
-
-       return (gpointer) "";
-}
-
 static gpointer
 get_url (ECalModelComponent *comp_data)
 {
@@ -565,64 +533,20 @@ set_status (ECalModelComponent *comp_data,
             const gchar *value)
 {
        ICalPropertyStatus status;
-       ICalProperty *prop;
 
-       prop = i_cal_component_get_first_property (comp_data->icalcomp, I_CAL_STATUS_PROPERTY);
+       status = e_cal_model_util_set_status (comp_data, value);
 
-       /* an empty string is the same as 'None' */
-       if (!value[0]) {
-               g_clear_object (&prop);
+       if (status == I_CAL_STATUS_NONE)
                return;
-       }
 
-       /* Translators: "None" for task's status */
-       if (!e_util_utf8_strcasecmp (value, C_("cal-task-status", "None"))) {
-               g_clear_object (&prop);
-               return;
-       } else if (!e_util_utf8_strcasecmp (value, _("Not Started")))
-               status = I_CAL_STATUS_NEEDSACTION;
-       else if (!e_util_utf8_strcasecmp (value, _("In Progress")))
-               status = I_CAL_STATUS_INPROCESS;
-       else if (!e_util_utf8_strcasecmp (value, _("Completed")))
-               status = I_CAL_STATUS_COMPLETED;
-       else if (!e_util_utf8_strcasecmp (value, _("Cancelled")))
-               status = I_CAL_STATUS_CANCELLED;
-       else {
-               g_clear_object (&prop);
-               g_warning ("Invalid status: %s\n", value);
-               return;
-       }
-
-       if (prop) {
-               i_cal_property_set_status (prop, status);
-               g_object_unref (prop);
-       } else {
-               prop = i_cal_property_new_status (status);
-               i_cal_component_take_property (comp_data->icalcomp, prop);
-       }
-
-       switch (status) {
-       case I_CAL_STATUS_NEEDSACTION:
+       if (status == I_CAL_STATUS_NEEDSACTION)
                ensure_task_not_complete (comp_data, TRUE);
-               break;
-
-       case I_CAL_STATUS_INPROCESS:
+       else if (status == I_CAL_STATUS_INPROCESS)
                ensure_task_partially_complete (comp_data);
-               break;
-
-       case I_CAL_STATUS_CANCELLED:
+       else if (status == I_CAL_STATUS_CANCELLED)
                ensure_task_not_complete (comp_data, FALSE);
-               break;
-
-       case I_CAL_STATUS_COMPLETED:
+       else if (status == I_CAL_STATUS_COMPLETED)
                ensure_task_complete (comp_data, -1);
-               break;
-
-       /* to make compiler happy */
-       /* coverity[dead_error_begin] */
-       default:
-               break;
-       }
 }
 
 static void
@@ -955,7 +879,7 @@ cal_model_tasks_value_at (ETableModel *etm,
        case E_CAL_MODEL_TASKS_FIELD_PRIORITY :
                return get_priority (comp_data);
        case E_CAL_MODEL_TASKS_FIELD_STATUS :
-               return get_status (comp_data);
+               return e_cal_model_util_get_status (comp_data);
        case E_CAL_MODEL_TASKS_FIELD_URL :
                return get_url (comp_data);
        case E_CAL_MODEL_TASKS_FIELD_LOCATION:
diff --git a/src/calendar/gui/e-cal-model.c b/src/calendar/gui/e-cal-model.c
index db252daec1..560c271c44 100644
--- a/src/calendar/gui/e-cal-model.c
+++ b/src/calendar/gui/e-cal-model.c
@@ -4189,3 +4189,138 @@ e_cal_model_emit_object_created (ECalModel *model,
 
        g_signal_emit (model, signals[OBJECT_CREATED], 0, where);
 }
+
+gpointer
+e_cal_model_util_get_status (ECalModelComponent *comp_data)
+{
+       ICalProperty *prop;
+       const gchar *res = "";
+
+       g_return_val_if_fail (comp_data != NULL, (gpointer) "");
+
+       prop = i_cal_component_get_first_property (comp_data->icalcomp, I_CAL_STATUS_PROPERTY);
+       if (prop) {
+               ICalPropertyStatus status;
+
+               status = i_cal_property_get_status (prop);
+
+               g_object_unref (prop);
+
+               res = cal_comp_util_status_to_localized_string (i_cal_component_isa (comp_data->icalcomp), 
status);
+               if (!res)
+                       res = "";
+       }
+
+       return (gpointer) res;
+}
+
+ICalPropertyStatus
+e_cal_model_util_set_status (ECalModelComponent *comp_data,
+                            gconstpointer value)
+{
+       ICalProperty *prop;
+       ICalPropertyStatus status;
+       const gchar *str_value = value;
+
+       g_return_val_if_fail (comp_data != NULL, I_CAL_STATUS_NONE);
+
+       prop = i_cal_component_get_first_property (comp_data->icalcomp, I_CAL_STATUS_PROPERTY);
+
+       if (!str_value || !*str_value) {
+               if (prop) {
+                       i_cal_component_remove_property (comp_data->icalcomp, prop);
+                       g_object_unref (prop);
+               }
+
+               return I_CAL_STATUS_NONE;
+       }
+
+       status = cal_comp_util_localized_string_to_status (i_cal_component_isa (comp_data->icalcomp), 
str_value, NULL, NULL);
+
+       if (status == I_CAL_STATUS_NONE) {
+               if (prop) {
+                       i_cal_component_remove_property (comp_data->icalcomp, prop);
+                       g_object_unref (prop);
+               }
+       } else if (prop) {
+               i_cal_property_set_status (prop, status);
+               g_object_unref (prop);
+       } else {
+               prop = i_cal_property_new_status (status);
+               i_cal_component_take_property (comp_data->icalcomp, prop);
+       }
+
+       return status;
+}
+
+static const gchar *
+get_cmp_cache_str (gpointer cmp_cache,
+                  const gchar *str)
+{
+       const gchar *value;
+
+       if (!cmp_cache || !str)
+               return str;
+
+       value = e_table_sorting_utils_lookup_cmp_cache (cmp_cache, str);
+       if (!value) {
+               gchar *ckey;
+
+               ckey = g_utf8_collate_key (str, -1);
+               e_table_sorting_utils_add_to_cmp_cache (cmp_cache, (gchar *) str, ckey);
+               value = ckey;
+       }
+
+       return value;
+}
+
+static gint
+cmp_cache_strings (gconstpointer str_a,
+                  gconstpointer str_b,
+                  gpointer cmp_cache)
+{
+       if (!cmp_cache)
+               return g_utf8_collate (str_a, str_b);
+
+       str_b = get_cmp_cache_str (cmp_cache, str_b);
+
+       g_return_val_if_fail (str_a != NULL, 0);
+       g_return_val_if_fail (str_b != NULL, 0);
+
+       return g_strcmp0 (str_a, str_b);
+}
+
+gint
+e_cal_model_util_status_compare_cb (gconstpointer a,
+                                   gconstpointer b,
+                                   gpointer cmp_cache)
+{
+       const gchar *string_a = a;
+       const gchar *string_b = b;
+       gint status_a = -2;
+       gint status_b = -2;
+
+       if (!string_a || !*string_a) {
+               status_a = -1;
+       } else {
+               const gchar *cache_str = get_cmp_cache_str (cmp_cache, string_a);
+
+               status_a = cal_comp_util_localized_string_to_status (I_CAL_ANY_COMPONENT, cache_str, 
cmp_cache_strings, cmp_cache);
+
+               if (status_a == I_CAL_STATUS_NONE)
+                       status_a = -1;
+       }
+
+       if (string_b == NULL || *string_b == '\0')
+               status_b = -1;
+       else {
+               const gchar *cache_str = get_cmp_cache_str (cmp_cache, string_b);
+
+               status_b = cal_comp_util_localized_string_to_status (I_CAL_ANY_COMPONENT, cache_str, 
cmp_cache_strings, cmp_cache);
+
+               if (status_b == I_CAL_STATUS_NONE)
+                       status_b = -1;
+       }
+
+       return status_a - status_b;
+}
diff --git a/src/calendar/gui/e-cal-model.h b/src/calendar/gui/e-cal-model.h
index 77ef0d5884..69f2f66554 100644
--- a/src/calendar/gui/e-cal-model.h
+++ b/src/calendar/gui/e-cal-model.h
@@ -405,6 +405,14 @@ void               e_cal_model_util_set_value      (GHashTable *values,
                                                 gint row);
 gpointer       e_cal_model_util_get_value      (GHashTable *values,
                                                 gint column);
+gpointer       e_cal_model_util_get_status     (ECalModelComponent *comp_data);
+ICalPropertyStatus
+               e_cal_model_util_set_status     (ECalModelComponent *comp_data,
+                                                gconstpointer value);
+gint           e_cal_model_util_status_compare_cb
+                                               (gconstpointer a,
+                                                gconstpointer b,
+                                                gpointer cmp_cache);
 
 G_END_DECLS
 
diff --git a/src/calendar/gui/e-comp-editor-property-parts.c b/src/calendar/gui/e-comp-editor-property-parts.c
index 296a6e7efd..fc35f35bc9 100644
--- a/src/calendar/gui/e-comp-editor-property-parts.c
+++ b/src/calendar/gui/e-comp-editor-property-parts.c
@@ -24,6 +24,7 @@
 #include <e-util/e-util.h>
 
 #include "calendar-config.h"
+#include "comp-util.h"
 #include "e-timezone-entry.h"
 
 #include "e-comp-editor-property-part.h"
@@ -1202,23 +1203,23 @@ ECompEditorPropertyPart *
 e_comp_editor_property_part_status_new (ICalComponentKind kind)
 {
        ECompEditorPropertyPartPickerMap map_vevent[] = {
-               { I_CAL_STATUS_NONE,      NC_("ECompEditor", "None"),      TRUE,  NULL },
-               { I_CAL_STATUS_TENTATIVE, NC_("ECompEditor", "Tentative"), FALSE, NULL },
-               { I_CAL_STATUS_CONFIRMED, NC_("ECompEditor", "Confirmed"), FALSE, NULL },
-               { I_CAL_STATUS_CANCELLED, NC_("ECompEditor", "Cancelled"), FALSE, NULL }
+               { I_CAL_STATUS_NONE,      NULL, TRUE,  NULL },
+               { I_CAL_STATUS_TENTATIVE, NULL, FALSE, NULL },
+               { I_CAL_STATUS_CONFIRMED, NULL, FALSE, NULL },
+               { I_CAL_STATUS_CANCELLED, NULL, FALSE, NULL }
        };
        ECompEditorPropertyPartPickerMap map_vjournal[] = {
-               { I_CAL_STATUS_NONE,      NC_("ECompEditor", "None"),      TRUE,  NULL },
-               { I_CAL_STATUS_DRAFT,     NC_("ECompEditor", "Draft"),     FALSE, NULL },
-               { I_CAL_STATUS_FINAL,     NC_("ECompEditor", "Final"),     FALSE, NULL },
-               { I_CAL_STATUS_CANCELLED, NC_("ECompEditor", "Cancelled"), FALSE, NULL }
+               { I_CAL_STATUS_NONE,      NULL, TRUE,  NULL },
+               { I_CAL_STATUS_DRAFT,     NULL, FALSE, NULL },
+               { I_CAL_STATUS_FINAL,     NULL, FALSE, NULL },
+               { I_CAL_STATUS_CANCELLED, NULL, FALSE, NULL }
        };
        ECompEditorPropertyPartPickerMap map_vtodo[] = {
-               { I_CAL_STATUS_NONE,        NC_("ECompEditor", "Not Started"),  TRUE,  NULL },
-               { I_CAL_STATUS_NEEDSACTION, NC_("ECompEditor", "Needs Action"), FALSE, NULL },
-               { I_CAL_STATUS_INPROCESS,   NC_("ECompEditor", "In Progress"),  FALSE, NULL },
-               { I_CAL_STATUS_COMPLETED,   NC_("ECompEditor", "Completed"),    FALSE, NULL },
-               { I_CAL_STATUS_CANCELLED,   NC_("ECompEditor", "Cancelled"),    FALSE, NULL }
+               { I_CAL_STATUS_NONE,        NULL, TRUE,  NULL },
+               { I_CAL_STATUS_NEEDSACTION, NULL, FALSE, NULL },
+               { I_CAL_STATUS_INPROCESS,   NULL, FALSE, NULL },
+               { I_CAL_STATUS_COMPLETED,   NULL, FALSE, NULL },
+               { I_CAL_STATUS_CANCELLED,   NULL, FALSE, NULL }
        };
        ECompEditorPropertyPartPickerMap *map;
        gint ii, n_elems;
@@ -1242,7 +1243,7 @@ e_comp_editor_property_part_status_new (ICalComponentKind kind)
        }
 
        for (ii = 0; ii < n_elems; ii++) {
-               map[ii].description = g_dpgettext2 (GETTEXT_PACKAGE, "ECompEditor", map[ii].description);
+               map[ii].description = cal_comp_util_status_to_localized_string (kind, map[ii].value);
        }
 
        return e_comp_editor_property_part_picker_with_map_new (map, n_elems,
diff --git a/src/calendar/gui/e-memo-table.c b/src/calendar/gui/e-memo-table.c
index 2355978aa8..ddb866c1b6 100644
--- a/src/calendar/gui/e-memo-table.c
+++ b/src/calendar/gui/e-memo-table.c
@@ -34,6 +34,7 @@
 #include <glib/gi18n.h>
 #include <glib/gstdio.h>
 
+#include "comp-util.h"
 #include "e-cal-dialogs.h"
 #include "e-cal-model-memos.h"
 #include "e-cal-ops.h"
@@ -270,6 +271,7 @@ memo_table_constructed (GObject *object)
        ETableSpecification *specification;
        AtkObject *a11y;
        gchar *etspecfile;
+       GList *strings;
        GError *local_error = NULL;
 
        memo_table = E_MEMO_TABLE (object);
@@ -328,9 +330,33 @@ memo_table_constructed (GObject *object)
                E_CELL_DATE_EDIT (popup_cell),
                memo_table_get_current_time, memo_table, NULL);
 
+       /* Status field. */
+       cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT);
+       g_object_set (
+               cell,
+               "bg_color_column", E_CAL_MODEL_FIELD_COLOR,
+               "strikeout_column", E_CAL_MODEL_FIELD_CANCELLED,
+               NULL);
+
+       popup_cell = e_cell_combo_new ();
+       e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell);
+       g_object_unref (cell);
+
+       strings = cal_comp_util_get_status_list_for_kind (e_cal_model_get_component_kind (model));
+       e_cell_combo_set_popdown_strings (
+               E_CELL_COMBO (popup_cell),
+               strings);
+       g_list_free (strings);
+
+       e_table_extras_add_cell (extras, "calstatus", popup_cell);
+       g_object_unref (popup_cell);
+
        /* Sorting */
        e_table_extras_add_compare (
                extras, "date-compare", e_cell_date_edit_compare_cb);
+       e_table_extras_add_compare (
+               extras, "status-compare",
+               e_cal_model_util_status_compare_cb);
 
        /* Create pixmaps */
 
diff --git a/src/calendar/gui/e-memo-table.etspec b/src/calendar/gui/e-memo-table.etspec
index 267311a8b2..810830e9cb 100644
--- a/src/calendar/gui/e-memo-table.etspec
+++ b/src/calendar/gui/e-memo-table.etspec
@@ -6,6 +6,7 @@
   <ETableColumn model_col="10" _title="Created" expansion="2.0" minimum_width="10" resizable="true" 
cell="dateedit" compare="date-compare" priority="-2"/>
   <ETableColumn model_col="11" _title="Last modified" expansion="2.0" minimum_width="10" resizable="true" 
cell="dateedit" compare="date-compare" priority="-2"/>
   <ETableColumn model_col="12" _title="Source" expansion="1.0" minimum_width="10" resizable="true" 
cell="string" compare="collate" priority="-2"/>
+  <ETableColumn model_col="14" _title="Status" expansion="1.0" minimum_width="10" resizable="true" 
cell="calstatus" compare="status-compare" priority="-1"/>
 
   <ETableState>
     <column source="1"/>
diff --git a/src/calendar/gui/e-task-table.c b/src/calendar/gui/e-task-table.c
index 167bf52a34..4f08347bf0 100644
--- a/src/calendar/gui/e-task-table.c
+++ b/src/calendar/gui/e-task-table.c
@@ -152,86 +152,6 @@ task_table_priority_compare_cb (gconstpointer a,
        return (priority1 < priority2) ? -1 : (priority1 > priority2);
 }
 
-static const gchar *
-get_cache_str (gpointer cmp_cache,
-               const gchar *str)
-{
-       const gchar *value;
-
-       if (!cmp_cache || !str)
-               return str;
-
-       value = e_table_sorting_utils_lookup_cmp_cache (cmp_cache, str);
-       if (!value) {
-               gchar *ckey;
-
-               ckey = g_utf8_collate_key (str, -1);
-               e_table_sorting_utils_add_to_cmp_cache (cmp_cache, (gchar *) str, ckey);
-               value = ckey;
-       }
-
-       return value;
-}
-
-static gboolean
-same_cache_string (gpointer cmp_cache,
-                   const gchar *str_a,
-                   const gchar *str_b)
-{
-       if (!cmp_cache)
-               return g_utf8_collate (str_a, str_b) == 0;
-
-       str_b = get_cache_str (cmp_cache, str_b);
-
-       g_return_val_if_fail (str_a != NULL, FALSE);
-       g_return_val_if_fail (str_b != NULL, FALSE);
-
-       return strcmp (str_a, str_b) == 0;
-}
-
-static gint
-task_table_status_compare_cb (gconstpointer a,
-                              gconstpointer b,
-                              gpointer cmp_cache)
-{
-       const gchar *string_a = a;
-       const gchar *string_b = b;
-       gint status_a = -2;
-       gint status_b = -2;
-
-       if (string_a == NULL || *string_a == '\0')
-               status_a = -1;
-       else {
-               const gchar *cache_str = get_cache_str (cmp_cache, string_a);
-
-               if (same_cache_string (cmp_cache, cache_str, _("Not Started")))
-                       status_a = 0;
-               else if (same_cache_string (cmp_cache, cache_str, _("In Progress")))
-                       status_a = 1;
-               else if (same_cache_string (cmp_cache, cache_str, _("Completed")))
-                       status_a = 2;
-               else if (same_cache_string (cmp_cache, cache_str, _("Cancelled")))
-                       status_a = 3;
-       }
-
-       if (string_b == NULL || *string_b == '\0')
-               status_b = -1;
-       else {
-               const gchar *cache_str = get_cache_str (cmp_cache, string_b);
-
-               if (same_cache_string (cmp_cache, cache_str, _("Not Started")))
-                       status_b = 0;
-               else if (same_cache_string (cmp_cache, cache_str, _("In Progress")))
-                       status_b = 1;
-               else if (same_cache_string (cmp_cache, cache_str, _("Completed")))
-                       status_b = 2;
-               else if (same_cache_string (cmp_cache, cache_str, _("Cancelled")))
-                       status_b = 3;
-       }
-
-       return (status_a < status_b) ? -1 : (status_a > status_b);
-}
-
 /* Deletes all of the selected components in the table */
 static void
 delete_selected_components (ETaskTable *task_table)
@@ -630,11 +550,7 @@ task_table_constructed (GObject *object)
        e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell);
        g_object_unref (cell);
 
-       strings = NULL;
-       strings = g_list_append (strings, (gchar *) _("Not Started"));
-       strings = g_list_append (strings, (gchar *) _("In Progress"));
-       strings = g_list_append (strings, (gchar *) _("Completed"));
-       strings = g_list_append (strings, (gchar *) _("Cancelled"));
+       strings = cal_comp_util_get_status_list_for_kind (e_cal_model_get_component_kind (model));
        e_cell_combo_set_popdown_strings (
                E_CELL_COMBO (popup_cell),
                strings);
@@ -654,7 +570,7 @@ task_table_constructed (GObject *object)
                task_table_priority_compare_cb);
        e_table_extras_add_compare (
                extras, "status-compare",
-               task_table_status_compare_cb);
+               e_cal_model_util_status_compare_cb);
 
        /* Create pixmaps */
 
diff --git a/src/calendar/gui/print.c b/src/calendar/gui/print.c
index ada2b17a74..8d14117c2b 100644
--- a/src/calendar/gui/print.c
+++ b/src/calendar/gui/print.c
@@ -36,6 +36,7 @@
 #include <gtk/gtk.h>
 #include <glib/gi18n.h>
 
+#include "comp-util.h"
 #include "e-cal-model.h"
 #include "e-day-view.h"
 #include "e-day-view-layout.h"
@@ -3606,22 +3607,7 @@ print_comp_draw_real (GtkPrintOperation *operation,
                /* Status */
                status = e_cal_component_get_status (comp);
                if (status != I_CAL_STATUS_NONE) {
-                       switch (status) {
-                       case I_CAL_STATUS_NEEDSACTION:
-                               status_string = _("Not Started");
-                               break;
-                       case I_CAL_STATUS_INPROCESS:
-                               status_string = _("In Progress");
-                               break;
-                       case I_CAL_STATUS_COMPLETED:
-                               status_string = _("Completed");
-                               break;
-                       case I_CAL_STATUS_CANCELLED:
-                               status_string = _("Cancelled");
-                               break;
-                       default:
-                               break;
-                       }
+                       status_string = cal_comp_util_status_to_localized_string (I_CAL_VTODO_COMPONENT, 
status);
 
                        if (status_string) {
                                gchar *status_text = g_strdup_printf (


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]