[evolution] I#95 - Calendar: Show all calendar events in the List View
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution] I#95 - Calendar: Show all calendar events in the List View
- Date: Fri, 13 Nov 2020 08:55:02 +0000 (UTC)
commit 41f5e390b5a914a469899fd7ca21254ba86016fe
Author: Milan Crha <mcrha redhat com>
Date: Fri Nov 13 09:53:45 2020 +0100
I#95 - Calendar: Show all calendar events in the List View
Closes https://gitlab.gnome.org/GNOME/evolution/-/issues/95
src/calendar/gui/e-cal-data-model.c | 33 +++++
src/calendar/gui/e-cal-data-model.h | 2 +
src/calendar/gui/e-cal-list-view.c | 118 +++++----------
src/calendar/gui/e-cal-list-view.h | 3 -
src/calendar/gui/e-cal-model.c | 41 +++---
src/calendar/gui/e-calendar-view.c | 116 ++++++++-------
src/calendar/gui/e-calendar-view.h | 1 +
src/modules/calendar/e-cal-base-shell-sidebar.c | 47 ++++--
src/modules/calendar/e-cal-base-shell-sidebar.h | 8 ++
src/modules/calendar/e-cal-shell-content.c | 184 +++++++++++++++++++++++-
src/modules/calendar/e-cal-shell-content.h | 2 +
src/modules/calendar/e-cal-shell-view-private.c | 22 +++
src/modules/calendar/e-cal-shell-view.c | 16 ++-
13 files changed, 423 insertions(+), 170 deletions(-)
---
diff --git a/src/calendar/gui/e-cal-data-model.c b/src/calendar/gui/e-cal-data-model.c
index 325f3b2e01..1bc43627e4 100644
--- a/src/calendar/gui/e-cal-data-model.c
+++ b/src/calendar/gui/e-cal-data-model.c
@@ -2557,6 +2557,39 @@ e_cal_data_model_remove_client (ECalDataModel *data_model,
UNLOCK_PROPS ();
}
+static gboolean
+cal_data_model_remove_client_cb (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ ECalDataModel *data_model = user_data;
+
+ cal_data_model_remove_client_view (data_model, value);
+
+ return TRUE;
+}
+
+/**
+ * e_cal_data_model_remove_all_clients:
+ * @data_model: an #ECalDataModel
+ *
+ * Removes all clients from the @data_model.
+ *
+ * Since: 3.40
+ **/
+void
+e_cal_data_model_remove_all_clients (ECalDataModel *data_model)
+{
+ g_return_if_fail (E_IS_CAL_DATA_MODEL (data_model));
+
+ LOCK_PROPS ();
+
+ g_hash_table_foreach_remove (data_model->priv->clients,
+ cal_data_model_remove_client_cb, data_model);
+
+ UNLOCK_PROPS ();
+}
+
/**
* e_cal_data_model_ref_client:
* @data_model: an #EDataModel instance
diff --git a/src/calendar/gui/e-cal-data-model.h b/src/calendar/gui/e-cal-data-model.h
index 15ce5e708a..ea317e5303 100644
--- a/src/calendar/gui/e-cal-data-model.h
+++ b/src/calendar/gui/e-cal-data-model.h
@@ -117,6 +117,8 @@ void e_cal_data_model_add_client (ECalDataModel *data_model,
ECalClient *client);
void e_cal_data_model_remove_client (ECalDataModel *data_model,
const gchar *uid);
+void e_cal_data_model_remove_all_clients
+ (ECalDataModel *data_model);
ECalClient * e_cal_data_model_ref_client (ECalDataModel *data_model,
const gchar *uid);
GList * e_cal_data_model_get_clients (ECalDataModel *data_model);
diff --git a/src/calendar/gui/e-cal-list-view.c b/src/calendar/gui/e-cal-list-view.c
index 22430f4b9c..3536376ecd 100644
--- a/src/calendar/gui/e-cal-list-view.c
+++ b/src/calendar/gui/e-cal-list-view.c
@@ -55,7 +55,8 @@ enum {
/* The icons to represent the event. */
static const gchar *icon_names[] = {
"x-office-calendar",
- "stock_people"
+ "stock_people",
+ "view-refresh"
};
static void e_cal_list_view_dispose (GObject *object);
@@ -96,6 +97,34 @@ e_cal_list_view_get_property (GObject *object,
}
}
+static gchar *
+e_cal_list_view_get_description_text (ECalendarView *cal_view)
+{
+ ECalModel *model;
+ GString *string;
+ const gchar *format;
+ gint n_rows;
+ gint n_selected;
+
+ g_return_val_if_fail (E_IS_CAL_LIST_VIEW (cal_view), NULL);
+
+ model = e_calendar_view_get_model (cal_view);
+ n_rows = e_table_model_row_count (E_TABLE_MODEL (model));
+ n_selected = e_table_selected_count (e_cal_list_view_get_table (E_CAL_LIST_VIEW (cal_view)));
+ string = g_string_sized_new (64);
+
+ format = ngettext ("%d appointment", "%d appointments", n_rows);
+ g_string_append_printf (string, format, n_rows);
+
+ if (n_selected > 0) {
+ format = _("%d selected");
+ g_string_append_len (string, ", ", 2);
+ g_string_append_printf (string, format, n_selected);
+ }
+
+ return g_string_free (string, FALSE);
+}
+
static void
e_cal_list_view_class_init (ECalListViewClass *class)
{
@@ -118,6 +147,7 @@ e_cal_list_view_class_init (ECalListViewClass *class)
view_class->get_selected_events = e_cal_list_view_get_selected_events;
view_class->get_selected_time_range = e_cal_list_view_get_selected_time_range;
view_class->get_visible_time_range = e_cal_list_view_get_visible_time_range;
+ view_class->get_description_text = e_cal_list_view_get_description_text;
g_object_class_override_property (
object_class,
@@ -313,7 +343,7 @@ setup_e_table (ECalListView *cal_list_view)
gtk_scrolled_window_set_policy (
GTK_SCROLLED_WINDOW (widget),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_grid_attach (GTK_GRID (container), widget, 0, 0, 2, 2);
+ gtk_grid_attach (GTK_GRID (container), widget, 0, 1, 2, 2);
g_object_set (G_OBJECT (widget),
"hexpand", TRUE,
"vexpand", TRUE,
@@ -611,74 +641,12 @@ e_cal_list_view_get_selected_events (ECalendarView *cal_view)
return event_list;
}
-/* It also frees 'itt' */
-static void
-adjust_range (ICalTime *itt,
- time_t *earliest,
- time_t *latest,
- gboolean *set)
-{
- time_t t;
-
- if (!itt || !i_cal_time_is_valid_time (itt)) {
- g_clear_object (&itt);
- return;
- }
-
- t = i_cal_time_as_timet (itt);
-
- *earliest = MIN (*earliest, t);
- *latest = MAX (*latest, t);
- *set = TRUE;
-
- g_clear_object (&itt);
-}
-
-/* NOTE: Time use for this function increases linearly with number of events.
- * This is not ideal, since it's used in a couple of places. We could probably
- * be smarter about it, and use do it less frequently... */
static gboolean
e_cal_list_view_get_visible_time_range (ECalendarView *cal_view,
time_t *start_time,
time_t *end_time)
{
- time_t earliest = G_MAXINT, latest = 0;
- gboolean set = FALSE;
- gint n_rows, i;
-
- n_rows = e_table_model_row_count (E_TABLE_MODEL (e_calendar_view_get_model (cal_view)));
-
- for (i = 0; i < n_rows; i++) {
- ECalModelComponent *comp;
- ICalComponent *icomp;
-
- comp = e_cal_model_get_component_at (e_calendar_view_get_model (cal_view), i);
- if (!comp)
- continue;
-
- icomp = comp->icalcomp;
- if (!icomp)
- continue;
-
- adjust_range (i_cal_component_get_dtstart (icomp), &earliest, &latest, &set);
- adjust_range (i_cal_component_get_dtend (icomp), &earliest, &latest, &set);
- }
-
- if (set) {
- *start_time = earliest;
- *end_time = latest;
- return TRUE;
- }
-
- if (!n_rows) {
- ECalModel *model = e_calendar_view_get_model (cal_view);
-
- /* Use time range set in the model when nothing shown in the list view */
- e_cal_model_get_time_range (model, start_time, end_time);
-
- return TRUE;
- }
-
+ /* No time range */
return FALSE;
}
@@ -690,26 +658,6 @@ e_cal_list_view_get_table (ECalListView *cal_list_view)
return cal_list_view->priv->table;
}
-gboolean
-e_cal_list_view_get_range_shown (ECalListView *cal_list_view,
- GDate *start_date,
- gint *days_shown)
-{
- time_t first, last;
- GDate end_date;
-
- g_return_val_if_fail (E_IS_CAL_LIST_VIEW (cal_list_view), FALSE);
-
- if (!e_cal_list_view_get_visible_time_range (E_CALENDAR_VIEW (cal_list_view), &first, &last))
- return FALSE;
-
- time_to_gdate_with_zone (start_date, first, e_calendar_view_get_timezone (E_CALENDAR_VIEW
(cal_list_view)));
- time_to_gdate_with_zone (&end_date, last, e_calendar_view_get_timezone (E_CALENDAR_VIEW
(cal_list_view)));
-
- *days_shown = g_date_days_between (start_date, &end_date);
- return TRUE;
-}
-
gboolean
e_cal_list_view_is_editing (ECalListView *eclv)
{
diff --git a/src/calendar/gui/e-cal-list-view.h b/src/calendar/gui/e-cal-list-view.h
index 985955d4a0..272efa3d5b 100644
--- a/src/calendar/gui/e-cal-list-view.h
+++ b/src/calendar/gui/e-cal-list-view.h
@@ -72,9 +72,6 @@ struct _ECalListViewClass {
GType e_cal_list_view_get_type (void);
ECalendarView * e_cal_list_view_new (ECalModel *cal_model);
ETable * e_cal_list_view_get_table (ECalListView *cal_list_view);
-gboolean e_cal_list_view_get_range_shown (ECalListView *cal_list_view,
- GDate *start_date,
- gint *days_shown);
gboolean e_cal_list_view_is_editing (ECalListView *eclv);
G_END_DECLS
diff --git a/src/calendar/gui/e-cal-model.c b/src/calendar/gui/e-cal-model.c
index 2a622e3ce4..860683c8e7 100644
--- a/src/calendar/gui/e-cal-model.c
+++ b/src/calendar/gui/e-cal-model.c
@@ -1573,8 +1573,13 @@ cal_model_value_at (ETableModel *etm,
retval = 0;
- if (i_cal_component_isa (comp_data->icalcomp) == I_CAL_VEVENT_COMPONENT ||
- i_cal_component_isa (comp_data->icalcomp) == I_CAL_VJOURNAL_COMPONENT) {
+ if (i_cal_component_isa (comp_data->icalcomp) == I_CAL_VEVENT_COMPONENT) {
+ if (e_cal_util_component_has_attendee (comp_data->icalcomp))
+ retval = 1;
+ if (e_cal_util_component_has_recurrences (comp_data->icalcomp) ||
+ e_cal_util_component_is_instance (comp_data->icalcomp))
+ retval = 2;
+ } else if (i_cal_component_isa (comp_data->icalcomp) == I_CAL_VJOURNAL_COMPONENT) {
if (e_cal_util_component_has_attendee (comp_data->icalcomp))
retval = 1;
} else {
@@ -3630,27 +3635,29 @@ e_cal_model_remove_all_objects (ECalModel *model)
{
ECalModelComponent *comp_data;
ETableModel *table_model;
- GSList *link;
- gint index;
+ GSList *comps = NULL;
+ guint ii;
table_model = E_TABLE_MODEL (model);
- for (index = model->priv->objects->len - 1; index >= 0; index--) {
- e_table_model_pre_change (table_model);
- comp_data = g_ptr_array_remove_index (model->priv->objects, index);
- if (!comp_data) {
- e_table_model_no_change (table_model);
- continue;
- }
+ for (ii = 0; ii < model->priv->objects->len; ii++) {
+ comp_data = g_ptr_array_index (model->priv->objects, ii);
- link = g_slist_append (NULL, comp_data);
- g_signal_emit (model, signals[COMPS_DELETED], 0, link);
+ if (comp_data)
+ comps = g_slist_prepend (comps, comp_data);
+ }
- g_slist_free (link);
- g_object_unref (comp_data);
+ ii = model->priv->objects->len;
- e_table_model_row_deleted (table_model, index);
- }
+ e_table_model_pre_change (table_model);
+ e_table_model_rows_deleted (table_model, 0, ii);
+
+ g_ptr_array_set_size (model->priv->objects, 0);
+
+ if (comps)
+ g_signal_emit (model, signals[COMPS_DELETED], 0, comps);
+
+ g_slist_free_full (comps, g_object_unref);
}
void
diff --git a/src/calendar/gui/e-calendar-view.c b/src/calendar/gui/e-calendar-view.c
index 7d9e6e9e34..d0826fd195 100644
--- a/src/calendar/gui/e-calendar-view.c
+++ b/src/calendar/gui/e-calendar-view.c
@@ -1110,6 +1110,66 @@ calendar_view_delete_selection (ESelectable *selectable)
g_list_free (selected);
}
+static gchar *
+calendar_view_get_description_text (ECalendarView *cal_view)
+{
+ time_t start_time, end_time;
+ struct tm start_tm, end_tm;
+ ICalTime *tt;
+ ICalTimezone *zone;
+ gchar start_buffer[512] = { 0 };
+ gchar end_buffer[512] = { 0 };
+
+ g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), NULL);
+
+
+ if (!e_calendar_view_get_visible_time_range (cal_view, &start_time, &end_time))
+ return NULL;
+
+ zone = e_cal_model_get_timezone (cal_view->priv->model);
+
+ tt = i_cal_time_new_from_timet_with_zone (start_time, FALSE, zone);
+ start_tm = e_cal_util_icaltime_to_tm (tt);
+ g_clear_object (&tt);
+
+ /* Subtract one from end_time so we don't get an extra day. */
+ tt = i_cal_time_new_from_timet_with_zone (end_time - 1, FALSE, zone);
+ end_tm = e_cal_util_icaltime_to_tm (tt);
+ g_clear_object (&tt);
+
+ if (E_IS_MONTH_VIEW (cal_view) || E_IS_CAL_LIST_VIEW (cal_view)) {
+ if (start_tm.tm_year == end_tm.tm_year) {
+ if (start_tm.tm_mon == end_tm.tm_mon) {
+ e_utf8_strftime (start_buffer, sizeof (start_buffer), "%d", &start_tm);
+ e_utf8_strftime (end_buffer, sizeof (end_buffer), _("%d %b %Y"), &end_tm);
+ } else {
+ e_utf8_strftime (start_buffer, sizeof (start_buffer), _("%d %b"), &start_tm);
+ e_utf8_strftime (end_buffer, sizeof (end_buffer), _("%d %b %Y"), &end_tm);
+ }
+ } else {
+ e_utf8_strftime (start_buffer, sizeof (start_buffer), _("%d %b %Y"), &start_tm);
+ e_utf8_strftime (end_buffer, sizeof (end_buffer), _("%d %b %Y"), &end_tm);
+ }
+ } else {
+ if (start_tm.tm_year == end_tm.tm_year &&
+ start_tm.tm_mon == end_tm.tm_mon &&
+ start_tm.tm_mday == end_tm.tm_mday) {
+ e_utf8_strftime (start_buffer, sizeof (start_buffer), _("%A %d %b %Y"), &start_tm);
+ } else if (start_tm.tm_year == end_tm.tm_year) {
+ e_utf8_strftime (start_buffer, sizeof (start_buffer), _("%a %d %b"), &start_tm);
+ e_utf8_strftime (end_buffer, sizeof (end_buffer), _("%a %d %b %Y"), &end_tm);
+ } else {
+ e_utf8_strftime (start_buffer, sizeof (start_buffer), _("%a %d %b %Y"), &start_tm);
+ e_utf8_strftime (end_buffer, sizeof (end_buffer), _("%a %d %b %Y"), &end_tm);
+ }
+ }
+
+ if (*start_buffer && *end_buffer)
+ return g_strdup_printf ("%s - %s", start_buffer, end_buffer);
+
+ return g_strdup_printf ("%s%s", start_buffer, end_buffer);
+}
+
static void
e_calendar_view_class_init (ECalendarViewClass *class)
{
@@ -1138,6 +1198,7 @@ e_calendar_view_class_init (ECalendarViewClass *class)
class->update_query = NULL;
class->open_event = e_calendar_view_open_event;
class->paste_text = NULL;
+ class->get_description_text = calendar_view_get_description_text;
/* Inherited from ESelectableInterface */
g_object_class_override_property (
@@ -2324,60 +2385,17 @@ e_calendar_view_is_editing (ECalendarView *cal_view)
gchar *
e_calendar_view_get_description_text (ECalendarView *cal_view)
{
- time_t start_time, end_time;
- struct tm start_tm, end_tm;
- ICalTime *tt;
- ICalTimezone *zone;
- gchar start_buffer[512] = { 0 };
- gchar end_buffer[512] = { 0 };
+ ECalendarViewClass *klass;
g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), NULL);
- if (!e_calendar_view_get_visible_time_range (cal_view, &start_time, &end_time))
- return NULL;
-
- zone = e_cal_model_get_timezone (cal_view->priv->model);
-
- tt = i_cal_time_new_from_timet_with_zone (start_time, FALSE, zone);
- start_tm = e_cal_util_icaltime_to_tm (tt);
- g_clear_object (&tt);
-
- /* Subtract one from end_time so we don't get an extra day. */
- tt = i_cal_time_new_from_timet_with_zone (end_time - 1, FALSE, zone);
- end_tm = e_cal_util_icaltime_to_tm (tt);
- g_clear_object (&tt);
-
- if (E_IS_MONTH_VIEW (cal_view) || E_IS_CAL_LIST_VIEW (cal_view)) {
- if (start_tm.tm_year == end_tm.tm_year) {
- if (start_tm.tm_mon == end_tm.tm_mon) {
- e_utf8_strftime (start_buffer, sizeof (start_buffer), "%d", &start_tm);
- e_utf8_strftime (end_buffer, sizeof (end_buffer), _("%d %b %Y"), &end_tm);
- } else {
- e_utf8_strftime (start_buffer, sizeof (start_buffer), _("%d %b"), &start_tm);
- e_utf8_strftime (end_buffer, sizeof (end_buffer), _("%d %b %Y"), &end_tm);
- }
- } else {
- e_utf8_strftime (start_buffer, sizeof (start_buffer), _("%d %b %Y"), &start_tm);
- e_utf8_strftime (end_buffer, sizeof (end_buffer), _("%d %b %Y"), &end_tm);
- }
- } else {
- if (start_tm.tm_year == end_tm.tm_year &&
- start_tm.tm_mon == end_tm.tm_mon &&
- start_tm.tm_mday == end_tm.tm_mday) {
- e_utf8_strftime (start_buffer, sizeof (start_buffer), _("%A %d %b %Y"), &start_tm);
- } else if (start_tm.tm_year == end_tm.tm_year) {
- e_utf8_strftime (start_buffer, sizeof (start_buffer), _("%a %d %b"), &start_tm);
- e_utf8_strftime (end_buffer, sizeof (end_buffer), _("%a %d %b %Y"), &end_tm);
- } else {
- e_utf8_strftime (start_buffer, sizeof (start_buffer), _("%a %d %b %Y"), &start_tm);
- e_utf8_strftime (end_buffer, sizeof (end_buffer), _("%a %d %b %Y"), &end_tm);
- }
- }
+ klass = E_CALENDAR_VIEW_GET_CLASS (cal_view);
+ g_return_val_if_fail (klass != NULL, NULL);
- if (*start_buffer && *end_buffer)
- return g_strdup_printf ("%s - %s", start_buffer, end_buffer);
+ if (klass->get_description_text)
+ return klass->get_description_text (cal_view);
- return g_strdup_printf ("%s%s", start_buffer, end_buffer);
+ return NULL;
}
void
diff --git a/src/calendar/gui/e-calendar-view.h b/src/calendar/gui/e-calendar-view.h
index 8ed9ffd0db..03c56401ab 100644
--- a/src/calendar/gui/e-calendar-view.h
+++ b/src/calendar/gui/e-calendar-view.h
@@ -183,6 +183,7 @@ struct _ECalendarViewClass {
void (*update_query) (ECalendarView *cal_view);
void (*open_event) (ECalendarView *cal_view);
void (*paste_text) (ECalendarView *cal_view);
+ gchar * (*get_description_text) (ECalendarView *cal_view);
};
GType e_calendar_view_get_type (void);
diff --git a/src/modules/calendar/e-cal-base-shell-sidebar.c b/src/modules/calendar/e-cal-base-shell-sidebar.c
index 5644d7aa39..0ddc5112d4 100644
--- a/src/modules/calendar/e-cal-base-shell-sidebar.c
+++ b/src/modules/calendar/e-cal-base-shell-sidebar.c
@@ -302,6 +302,8 @@ typedef struct _OpenClientData {
ESource *source;
EClient *client;
gboolean was_cancelled;
+ ECalBaseShellSidebarOpenFunc cb;
+ gpointer cb_user_data;
} OpenClientData;
static void
@@ -310,12 +312,19 @@ open_client_data_free (gpointer pdata)
OpenClientData *data = pdata;
if (data) {
- /* To free the cancellable in the 'value' pair, which is useless now */
- g_hash_table_insert (data->sidebar->priv->selected_uids,
- g_strdup (e_source_get_uid (data->source)),
- NULL);
+ if (data->cb || !data->client) {
+ g_hash_table_remove (data->sidebar->priv->selected_uids, e_source_get_uid
(data->source));
+ } else {
+ /* To free the cancellable in the 'value' pair, which is useless now */
+ g_hash_table_insert (data->sidebar->priv->selected_uids,
+ g_strdup (e_source_get_uid (data->source)),
+ NULL);
+ }
- if (data->client) {
+ if (data->cb) {
+ if (data->client)
+ data->cb (data->sidebar, data->client, data->cb_user_data);
+ } else if (data->client) {
g_signal_emit (data->sidebar, signals[CLIENT_OPENED], 0, data->client);
} else if (!data->was_cancelled) {
ESourceSelector *selector = e_cal_base_shell_sidebar_get_selector (data->sidebar);
@@ -351,7 +360,9 @@ e_cal_base_shell_sidebar_open_client_thread (EAlertSinkThreadJobData *job_data,
static void
e_cal_base_shell_sidebar_ensure_source_opened (ECalBaseShellSidebar *sidebar,
- ESource *source)
+ ESource *source,
+ ECalBaseShellSidebarOpenFunc cb,
+ gpointer cb_user_data)
{
OpenClientData *data;
EShellView *shell_view;
@@ -362,8 +373,8 @@ e_cal_base_shell_sidebar_ensure_source_opened (ECalBaseShellSidebar *sidebar,
g_return_if_fail (E_IS_CAL_BASE_SHELL_SIDEBAR (sidebar));
g_return_if_fail (E_IS_SOURCE (source));
- /* Skip it when it's already opening or opened */
- if (g_hash_table_contains (sidebar->priv->selected_uids, e_source_get_uid (source)))
+ /* Skip it when it's already opening or opened and the callback is not set */
+ if (!cb && g_hash_table_contains (sidebar->priv->selected_uids, e_source_get_uid (source)))
return;
shell_view = e_shell_sidebar_get_shell_view (E_SHELL_SIDEBAR (sidebar));
@@ -398,6 +409,8 @@ e_cal_base_shell_sidebar_ensure_source_opened (ECalBaseShellSidebar *sidebar,
data->extension_name = extension_name; /* no need to copy, it's a static string */
data->sidebar = g_object_ref (sidebar);
data->source = g_object_ref (source);
+ data->cb = cb;
+ data->cb_user_data = cb_user_data;
activity = e_shell_view_submit_thread_job (
shell_view, description, alert_ident, alert_arg_0,
@@ -440,7 +453,7 @@ e_cal_base_shell_sidebar_source_selected (ESourceSelector *selector,
g_return_if_fail (E_IS_CAL_BASE_SHELL_SIDEBAR (sidebar));
if (!g_hash_table_contains (sidebar->priv->selected_uids, e_source_get_uid (source))) {
- e_cal_base_shell_sidebar_ensure_source_opened (sidebar, source);
+ e_cal_base_shell_sidebar_ensure_source_opened (sidebar, source, NULL, NULL);
}
}
@@ -961,8 +974,22 @@ e_cal_base_shell_sidebar_ensure_sources_open (ECalBaseShellSidebar *cal_base_she
for (link = selected; link; link = g_list_next (link)) {
ESource *source = link->data;
- e_cal_base_shell_sidebar_ensure_source_opened (cal_base_shell_sidebar, source);
+ e_cal_base_shell_sidebar_ensure_source_opened (cal_base_shell_sidebar, source, NULL, NULL);
}
g_list_free_full (selected, g_object_unref);
}
+
+/* Opens the client with given uid. Calls the cb only if it succeeded */
+void
+e_cal_base_shell_sidebar_open_source (ECalBaseShellSidebar *cal_base_shell_sidebar,
+ ESource *source,
+ ECalBaseShellSidebarOpenFunc cb,
+ gpointer cb_user_data)
+{
+ g_return_if_fail (E_IS_CAL_BASE_SHELL_SIDEBAR (cal_base_shell_sidebar));
+ g_return_if_fail (E_IS_SOURCE (source));
+ g_return_if_fail (cb != NULL);
+
+ e_cal_base_shell_sidebar_ensure_source_opened (cal_base_shell_sidebar, source, cb, cb_user_data);
+}
diff --git a/src/modules/calendar/e-cal-base-shell-sidebar.h b/src/modules/calendar/e-cal-base-shell-sidebar.h
index ee86ad2b38..7012f1f54d 100644
--- a/src/modules/calendar/e-cal-base-shell-sidebar.h
+++ b/src/modules/calendar/e-cal-base-shell-sidebar.h
@@ -49,6 +49,10 @@ typedef struct _ECalBaseShellSidebar ECalBaseShellSidebar;
typedef struct _ECalBaseShellSidebarClass ECalBaseShellSidebarClass;
typedef struct _ECalBaseShellSidebarPrivate ECalBaseShellSidebarPrivate;
+typedef void (* ECalBaseShellSidebarOpenFunc) (ECalBaseShellSidebar *cal_base_shell_sidebar,
+ EClient *client,
+ gpointer user_data);
+
enum {
E_CAL_BASE_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE = 1 << 0,
E_CAL_BASE_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_WRITABLE = 1 << 1,
@@ -87,6 +91,10 @@ ESourceSelector *
e_cal_base_shell_sidebar_get_selector (ECalBaseShellSidebar *cal_base_shell_sidebar);
void e_cal_base_shell_sidebar_ensure_sources_open
(ECalBaseShellSidebar *cal_base_shell_sidebar);
+void e_cal_base_shell_sidebar_open_source (ECalBaseShellSidebar *cal_base_shell_sidebar,
+ ESource *source,
+ ECalBaseShellSidebarOpenFunc cb,
+ gpointer cb_user_data);
G_END_DECLS
diff --git a/src/modules/calendar/e-cal-shell-content.c b/src/modules/calendar/e-cal-shell-content.c
index 4a986d46df..7588f1b8af 100644
--- a/src/modules/calendar/e-cal-shell-content.c
+++ b/src/modules/calendar/e-cal-shell-content.c
@@ -56,6 +56,9 @@ struct _ECalShellContentPrivate {
ECalModel *memo_model;
ECalDataModel *memo_data_model;
+ ECalModel *list_view_model;
+ ECalDataModel *list_view_data_model;
+
ETagCalendar *tag_calendar;
gulong datepicker_selection_changed_id;
gulong datepicker_range_moved_id;
@@ -1268,6 +1271,87 @@ cal_shell_content_move_view_range_cb (ECalendarView *cal_view,
e_cal_shell_content_move_view_range (cal_shell_content, move_type, (time_t) exact_date);
}
+static void
+cal_shell_content_clear_all_in_list_view (ECalShellContent *cal_shell_content)
+{
+ ECalDataModelSubscriber *subscriber;
+
+ subscriber = E_CAL_DATA_MODEL_SUBSCRIBER (cal_shell_content->priv->list_view_model);
+
+ e_cal_data_model_unsubscribe (cal_shell_content->priv->list_view_data_model, subscriber);
+ e_cal_model_remove_all_objects (cal_shell_content->priv->list_view_model);
+ e_cal_data_model_remove_all_clients (cal_shell_content->priv->list_view_data_model);
+ e_cal_data_model_subscribe (cal_shell_content->priv->list_view_data_model, subscriber, 0, 0);
+}
+
+static void
+cal_shell_content_client_opened_cb (ECalBaseShellSidebar *cal_base_shell_sidebar,
+ EClient *client,
+ gpointer user_data)
+{
+ ECalShellContent *cal_shell_content = user_data;
+ ESourceSelector *source_selector;
+ ESource *source;
+
+ g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content));
+
+ if (cal_shell_content->priv->current_view != E_CAL_VIEW_KIND_LIST || !E_IS_CAL_CLIENT (client))
+ return;
+
+ source_selector = e_cal_base_shell_sidebar_get_selector (cal_base_shell_sidebar);
+ source = e_source_selector_ref_primary_selection (source_selector);
+
+ /* It can happen that the previously opening calendar finished its open
+ after the current calendar, in which case this would replace the data,
+ thus ensure the opened calendar is the correct calendar. */
+ if (source == e_client_get_source (client)) {
+ cal_shell_content_clear_all_in_list_view (cal_shell_content);
+ e_cal_data_model_add_client (cal_shell_content->priv->list_view_data_model, E_CAL_CLIENT
(client));
+ }
+
+ g_clear_object (&source);
+}
+
+static void
+cal_shell_content_update_list_view (ECalShellContent *cal_shell_content)
+{
+ ECalBaseShellSidebar *cal_base_shell_sidebar;
+ ESourceSelector *source_selector;
+ ECalClient *client;
+ ESource *source;
+
+ cal_base_shell_sidebar = E_CAL_BASE_SHELL_SIDEBAR (e_shell_view_get_shell_sidebar (
+ e_shell_content_get_shell_view (E_SHELL_CONTENT (cal_shell_content))));
+
+ source_selector = e_cal_base_shell_sidebar_get_selector (cal_base_shell_sidebar);
+
+ source = e_source_selector_ref_primary_selection (source_selector);
+ if (!source)
+ return;
+
+ e_cal_model_set_default_source_uid (cal_shell_content->priv->list_view_model, e_source_get_uid
(source));
+
+ client = e_cal_data_model_ref_client (cal_shell_content->priv->list_view_data_model, e_source_get_uid
(source));
+
+ if (!client)
+ e_cal_base_shell_sidebar_open_source (cal_base_shell_sidebar, source,
cal_shell_content_client_opened_cb, cal_shell_content);
+
+ g_clear_object (&client);
+ g_clear_object (&source);
+}
+
+static void
+cal_shell_content_primary_selection_changed_cb (ESourceSelector *selector,
+ gpointer user_data)
+{
+ ECalShellContent *cal_shell_content = user_data;
+
+ g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content));
+
+ if (cal_shell_content->priv->current_view == E_CAL_VIEW_KIND_LIST)
+ cal_shell_content_update_list_view (cal_shell_content);
+}
+
static void
cal_shell_content_foreign_client_opened_cb (ECalBaseShellSidebar *cal_base_shell_sidebar,
ECalClient *client,
@@ -1388,6 +1472,10 @@ cal_shell_content_view_created (ECalBaseShellContent *cal_base_shell_content)
/* Show everything known by default in the task and memo pads */
e_cal_model_set_time_range (cal_shell_content->priv->memo_model, 0, 0);
e_cal_model_set_time_range (cal_shell_content->priv->task_model, 0, 0);
+ e_cal_model_set_time_range (cal_shell_content->priv->list_view_model, 0, 0);
+
+ g_signal_connect (e_cal_base_shell_sidebar_get_selector (E_CAL_BASE_SHELL_SIDEBAR (shell_sidebar)),
"primary-selection-changed",
+ G_CALLBACK (cal_shell_content_primary_selection_changed_cb), cal_shell_content);
cal_shell_content->priv->datepicker_selection_changed_id =
g_signal_connect (e_calendar_get_item (calendar), "selection-changed",
@@ -1516,7 +1604,7 @@ e_cal_shell_content_create_calendar_views (ECalShellContent *cal_shell_content)
G_CALLBACK (month_view_adjustment_changed_cb), cal_shell_content);
/* List View */
- calendar_view = e_cal_list_view_new (model);
+ calendar_view = e_cal_list_view_new (cal_shell_content->priv->list_view_model);
cal_shell_content->priv->views[E_CAL_VIEW_KIND_LIST] = calendar_view;
g_object_ref_sink (calendar_view);
@@ -1618,6 +1706,12 @@ cal_shell_content_dispose (GObject *object)
E_CAL_DATA_MODEL_SUBSCRIBER (cal_shell_content->priv->memo_model));
}
+ if (cal_shell_content->priv->list_view_data_model) {
+ e_cal_data_model_set_disposing (cal_shell_content->priv->list_view_data_model, TRUE);
+ e_cal_data_model_unsubscribe (cal_shell_content->priv->list_view_data_model,
+ E_CAL_DATA_MODEL_SUBSCRIBER (cal_shell_content->priv->list_view_model));
+ }
+
if (cal_shell_content->priv->tag_calendar) {
ECalDataModel *data_model;
@@ -1640,6 +1734,8 @@ cal_shell_content_dispose (GObject *object)
g_clear_object (&cal_shell_content->priv->memo_table);
g_clear_object (&cal_shell_content->priv->memo_model);
g_clear_object (&cal_shell_content->priv->memo_data_model);
+ g_clear_object (&cal_shell_content->priv->list_view_model);
+ g_clear_object (&cal_shell_content->priv->list_view_data_model);
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (e_cal_shell_content_parent_class)->dispose (object);
@@ -1678,6 +1774,11 @@ cal_shell_content_constructed (GObject *object)
cal_shell_content->priv->task_model =
e_cal_model_tasks_new (cal_shell_content->priv->task_data_model, e_shell_get_registry
(shell), shell);
+ cal_shell_content->priv->list_view_data_model =
+ e_cal_base_shell_content_create_new_data_model (E_CAL_BASE_SHELL_CONTENT (cal_shell_content));
+ cal_shell_content->priv->list_view_model =
+ e_cal_model_calendar_new (cal_shell_content->priv->list_view_data_model, e_shell_get_registry
(shell), shell);
+
e_binding_bind_property (
cal_shell_content->priv->memo_model, "timezone",
cal_shell_content->priv->memo_data_model, "timezone",
@@ -1688,6 +1789,11 @@ cal_shell_content_constructed (GObject *object)
cal_shell_content->priv->task_data_model, "timezone",
G_BINDING_SYNC_CREATE);
+ e_binding_bind_property (
+ cal_shell_content->priv->list_view_model, "timezone",
+ cal_shell_content->priv->list_view_data_model, "timezone",
+ G_BINDING_SYNC_CREATE);
+
/* Build content widgets. */
container = GTK_WIDGET (object);
@@ -2027,10 +2133,58 @@ cal_shell_content_resubscribe (ECalendarView *cal_view,
}
}
+/* Only helper function */
+static void
+cal_shell_content_switch_list_view (ECalShellContent *cal_shell_content,
+ ECalViewKind from_view_kind,
+ ECalViewKind to_view_kind)
+{
+ EShellView *shell_view;
+ EShellSidebar *shell_sidebar;
+ ECalBaseShellSidebar *cal_base_shell_sidebar;
+ ECalendar *date_navigator;
+ ESourceSelector *source_selector;
+ ECalModel *model;
+ gchar *cal_filter;
+
+ g_return_if_fail (from_view_kind != to_view_kind);
+
+ if (to_view_kind != E_CAL_VIEW_KIND_LIST &&
+ from_view_kind != E_CAL_VIEW_KIND_LIST)
+ return;
+
+ shell_view = e_shell_content_get_shell_view (E_SHELL_CONTENT (cal_shell_content));
+ shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+ cal_base_shell_sidebar = E_CAL_BASE_SHELL_SIDEBAR (shell_sidebar);
+ date_navigator = e_cal_base_shell_sidebar_get_date_navigator (cal_base_shell_sidebar);
+ source_selector = e_cal_base_shell_sidebar_get_selector (cal_base_shell_sidebar);
+
+ gtk_widget_set_visible (GTK_WIDGET (date_navigator), to_view_kind != E_CAL_VIEW_KIND_LIST);
+ e_source_selector_set_show_toggles (source_selector, to_view_kind != E_CAL_VIEW_KIND_LIST);
+
+ model = e_calendar_view_get_model (cal_shell_content->priv->views[from_view_kind]);
+ cal_filter = e_cal_data_model_dup_filter (e_cal_model_get_data_model (model));
+ if (cal_filter) {
+ model = e_calendar_view_get_model (cal_shell_content->priv->views[to_view_kind]);
+ e_cal_data_model_set_filter (e_cal_model_get_data_model (model), cal_filter);
+ g_free (cal_filter);
+ }
+
+ /* The list view is activated */
+ if (to_view_kind == E_CAL_VIEW_KIND_LIST) {
+ cal_shell_content_update_list_view (cal_shell_content);
+ /* The list view is deactivated */
+ } else if (from_view_kind == E_CAL_VIEW_KIND_LIST) {
+ cal_shell_content_clear_all_in_list_view (cal_shell_content);
+ e_cal_base_shell_sidebar_ensure_sources_open (cal_base_shell_sidebar);
+ }
+}
+
void
e_cal_shell_content_set_current_view_id (ECalShellContent *cal_shell_content,
ECalViewKind view_kind)
{
+ EShellView *shell_view;
time_t start_time = -1, end_time = -1;
gint ii;
@@ -2069,6 +2223,9 @@ e_cal_shell_content_set_current_view_id (ECalShellContent *cal_shell_content,
cal_view->in_focus = in_focus;
+ if (ii == E_CAL_VIEW_KIND_LIST)
+ continue;
+
if (focus_changed && in_focus) {
/* Currently focused view changed. Any events within the common time
range are not shown in the newly focused view, thus make sure it'll
@@ -2098,11 +2255,17 @@ e_cal_shell_content_set_current_view_id (ECalShellContent *cal_shell_content,
}
}
+ cal_shell_content_switch_list_view (cal_shell_content, cal_shell_content->priv->current_view,
view_kind);
+
cal_shell_content->priv->current_view = view_kind;
g_object_notify (G_OBJECT (cal_shell_content), "current-view-id");
gtk_widget_queue_draw (GTK_WIDGET
(cal_shell_content->priv->views[cal_shell_content->priv->current_view]));
+
+ shell_view = e_shell_content_get_shell_view (E_SHELL_CONTENT (cal_shell_content));
+ e_shell_view_update_actions (shell_view);
+ e_cal_shell_view_update_sidebar (E_CAL_SHELL_VIEW (shell_view));
}
ECalViewKind
@@ -2382,8 +2545,15 @@ e_cal_shell_content_update_filters (ECalShellContent *cal_shell_content,
if (!cal_filter)
return;
- data_model = e_cal_base_shell_content_get_data_model (E_CAL_BASE_SHELL_CONTENT (cal_shell_content));
- model = e_cal_base_shell_content_get_model (E_CAL_BASE_SHELL_CONTENT (cal_shell_content));
+ if (e_cal_shell_content_get_current_view_id (cal_shell_content) == E_CAL_VIEW_KIND_LIST) {
+ data_model = cal_shell_content->priv->list_view_data_model;
+ model = cal_shell_content->priv->list_view_model;
+ start_range = 0;
+ end_range = 0;
+ } else {
+ data_model = e_cal_base_shell_content_get_data_model (E_CAL_BASE_SHELL_CONTENT
(cal_shell_content));
+ model = e_cal_base_shell_content_get_model (E_CAL_BASE_SHELL_CONTENT (cal_shell_content));
+ }
cal_shell_content_update_model_filter (data_model, model, cal_filter, start_range, end_range);
e_cal_shell_content_update_tasks_filter (cal_shell_content, cal_filter);
@@ -2434,3 +2604,11 @@ e_cal_shell_content_update_filters (ECalShellContent *cal_shell_content,
}
}
}
+
+ECalDataModel *
+e_cal_shell_content_get_list_view_data_model (ECalShellContent *cal_shell_content)
+{
+ g_return_val_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content), NULL);
+
+ return cal_shell_content->priv->list_view_data_model;
+}
diff --git a/src/modules/calendar/e-cal-shell-content.h b/src/modules/calendar/e-cal-shell-content.h
index 21a9d2e403..11240d4614 100644
--- a/src/modules/calendar/e-cal-shell-content.h
+++ b/src/modules/calendar/e-cal-shell-content.h
@@ -106,6 +106,8 @@ void e_cal_shell_content_update_filters (ECalShellContent
*cal_shell_content,
time_t end_range);
void e_cal_shell_content_update_tasks_filter (ECalShellContent *cal_shell_content,
const gchar *cal_filter);
+ECalDataModel * e_cal_shell_content_get_list_view_data_model
+ (ECalShellContent *cal_shell_content);
G_END_DECLS
diff --git a/src/modules/calendar/e-cal-shell-view-private.c b/src/modules/calendar/e-cal-shell-view-private.c
index f0cc8b705e..e098b32252 100644
--- a/src/modules/calendar/e-cal-shell-view-private.c
+++ b/src/modules/calendar/e-cal-shell-view-private.c
@@ -428,6 +428,28 @@ e_cal_shell_view_private_constructed (ECalShellView *cal_shell_view)
G_CALLBACK (e_shell_view_update_actions),
cal_shell_view);
priv->views[ii].selection_changed_handler_id = handler_id;
+
+ if (ii == E_CAL_VIEW_KIND_LIST) {
+ ECalModel *model;
+
+ model = e_calendar_view_get_model (calendar_view);
+
+ g_signal_connect_object (calendar_view, "selection-changed",
+ G_CALLBACK (e_cal_shell_view_update_sidebar), cal_shell_view,
+ G_CONNECT_SWAPPED);
+
+ g_signal_connect_object (model, "model-changed",
+ G_CALLBACK (e_cal_shell_view_update_sidebar), cal_shell_view,
+ G_CONNECT_SWAPPED);
+
+ g_signal_connect_object (model, "model-rows-inserted",
+ G_CALLBACK (e_cal_shell_view_update_sidebar), cal_shell_view,
+ G_CONNECT_SWAPPED);
+
+ g_signal_connect_object (model, "model-rows-deleted",
+ G_CALLBACK (e_cal_shell_view_update_sidebar), cal_shell_view,
+ G_CONNECT_SWAPPED);
+ }
}
/* Keep our own reference to this so we can
diff --git a/src/modules/calendar/e-cal-shell-view.c b/src/modules/calendar/e-cal-shell-view.c
index c8f441cd40..b6876fc512 100644
--- a/src/modules/calendar/e-cal-shell-view.c
+++ b/src/modules/calendar/e-cal-shell-view.c
@@ -259,6 +259,7 @@ cal_shell_view_update_actions (EShellView *shell_view)
GtkAction *action;
gchar *data_filter;
gboolean is_searching;
+ gboolean is_list_view;
gboolean sensitive;
guint32 state;
@@ -303,7 +304,11 @@ cal_shell_view_update_actions (EShellView *shell_view)
cal_view = e_cal_shell_content_get_current_calendar_view (cal_shell_content);
memo_table = e_cal_shell_content_get_memo_table (cal_shell_content);
task_table = e_cal_shell_content_get_task_table (cal_shell_content);
- data_model = e_cal_base_shell_content_get_data_model (E_CAL_BASE_SHELL_CONTENT (cal_shell_content));
+ is_list_view = E_IS_CAL_LIST_VIEW (cal_view);
+ if (is_list_view)
+ data_model = e_cal_shell_content_get_list_view_data_model (cal_shell_content);
+ else
+ data_model = e_cal_base_shell_content_get_data_model (E_CAL_BASE_SHELL_CONTENT
(cal_shell_content));
data_filter = e_cal_data_model_dup_filter (data_model);
is_searching = data_filter && *data_filter &&
g_strcmp0 (data_filter, "#t") != 0 &&
@@ -397,10 +402,10 @@ cal_shell_view_update_actions (EShellView *shell_view)
gtk_action_set_sensitive (action, sensitive);
action = ACTION (CALENDAR_SEARCH_PREV);
- gtk_action_set_sensitive (action, is_searching);
+ gtk_action_set_sensitive (action, is_searching && !is_list_view);
action = ACTION (CALENDAR_SEARCH_NEXT);
- gtk_action_set_sensitive (action, is_searching);
+ gtk_action_set_sensitive (action, is_searching && !is_list_view);
action = ACTION (CALENDAR_SEARCH_STOP);
sensitive = is_searching && priv->searching_activity != NULL;
@@ -489,6 +494,11 @@ cal_shell_view_update_actions (EShellView *shell_view)
action = ACTION (EVENT_MEETING_NEW);
gtk_action_set_visible (action, has_mail_identity);
+ gtk_action_set_sensitive (ACTION (CALENDAR_GO_BACK), !is_list_view);
+ gtk_action_set_sensitive (ACTION (CALENDAR_GO_FORWARD), !is_list_view);
+ gtk_action_set_sensitive (ACTION (CALENDAR_GO_TODAY), !is_list_view);
+ gtk_action_set_sensitive (ACTION (CALENDAR_JUMP_TO), !is_list_view);
+
if ((cal_view && e_calendar_view_is_editing (cal_view)) ||
e_table_is_editing (E_TABLE (memo_table)) ||
e_table_is_editing (E_TABLE (task_table))) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]