aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/gui/e-calendar-table.c
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2009-12-08 00:31:17 +0800
committerMatthew Barnes <mbarnes@redhat.com>2009-12-26 04:42:17 +0800
commitabc0e4c694fb3d9624e890384880def730769fa0 (patch)
tree8d411f90f4edb0859ffe0b260c85e02e7d273088 /calendar/gui/e-calendar-table.c
parent83dc7625983470bff4ce8b9070fbc23c3370c472 (diff)
downloadgsoc2013-evolution-abc0e4c694fb3d9624e890384880def730769fa0.tar
gsoc2013-evolution-abc0e4c694fb3d9624e890384880def730769fa0.tar.gz
gsoc2013-evolution-abc0e4c694fb3d9624e890384880def730769fa0.tar.bz2
gsoc2013-evolution-abc0e4c694fb3d9624e890384880def730769fa0.tar.lz
gsoc2013-evolution-abc0e4c694fb3d9624e890384880def730769fa0.tar.xz
gsoc2013-evolution-abc0e4c694fb3d9624e890384880def730769fa0.tar.zst
gsoc2013-evolution-abc0e4c694fb3d9624e890384880def730769fa0.zip
Introduce ESelectable and EFocusTracker.
EFocusTracker tracks the input focus within a window and helps keep the sensitivity of "selectable" actions in the main menu up-to-date. Selectable actions include Cut, Copy, Paste, Select All and Delete. EFocusTracker has built-in support for widgets that implement the GtkEditable interface such as GtkEntry and GtkTextView. It also supports custom widgets that implement the ESelectable interface, which is a subset of GtkEditable and can apply to anything that displays selectable content (esp. tree views and ETables). This commit integrates EFocusTracker with EShellWindow, CompEditor, EMsgComposer, and ESignatureManager. It also bumps the GtkHTML requirement to 2.29.5 to utilize the new GtkhtmlEditor:html constructor property.
Diffstat (limited to 'calendar/gui/e-calendar-table.c')
-rw-r--r--calendar/gui/e-calendar-table.c540
1 files changed, 310 insertions, 230 deletions
diff --git a/calendar/gui/e-calendar-table.c b/calendar/gui/e-calendar-table.c
index a1495fb005..9ac534e333 100644
--- a/calendar/gui/e-calendar-table.c
+++ b/calendar/gui/e-calendar-table.c
@@ -37,6 +37,7 @@
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <misc/e-gui-utils.h>
+#include <misc/e-selectable.h>
#include <table/e-cell-checkbox.h>
#include <table/e-cell-toggle.h>
#include <table/e-cell-text.h>
@@ -248,6 +249,32 @@ calendar_table_model_cal_view_done_cb (ECalendarTable *cal_table,
calendar_table_emit_status_message (cal_table, NULL, -1.0);
}
+/* Deletes all of the selected components in the table */
+static void
+delete_selected_components (ECalendarTable *cal_table)
+{
+ GSList *objs, *l;
+ const gchar *status_message;
+
+ objs = e_calendar_table_get_selected (cal_table);
+
+ status_message = _("Deleting selected objects");
+ calendar_table_emit_status_message (cal_table, status_message, -1.0);
+
+ for (l = objs; l; l = l->next) {
+ ECalModelComponent *comp_data = (ECalModelComponent *) l->data;
+ GError *error = NULL;
+
+ e_cal_remove_object (comp_data->client,
+ icalcomponent_get_uid (comp_data->icalcomp), &error);
+ delete_error_dialog (error, E_CAL_COMPONENT_TODO);
+ g_clear_error (&error);
+ }
+
+ calendar_table_emit_status_message (cal_table, NULL, -1.0);
+
+ g_slist_free (objs);
+}
static void
calendar_table_set_model (ECalendarTable *cal_table,
ECalModel *model)
@@ -846,6 +873,270 @@ calendar_table_right_click (ETable *table,
}
static void
+calendar_table_update_actions (ESelectable *selectable,
+ EFocusTracker *focus_tracker,
+ GdkAtom *clipboard_targets,
+ gint n_clipboard_targets)
+{
+ ECalendarTable *cal_table;
+ GtkAction *action;
+ GSList *list, *iter;
+ gboolean sources_are_editable = TRUE;
+ gboolean clipboard_has_calendar;
+ gboolean sensitive;
+ const gchar *tooltip;
+ gint n_selected;
+
+ cal_table = E_CALENDAR_TABLE (selectable);
+ n_selected = e_table_selected_count (E_TABLE (cal_table));
+
+ list = e_calendar_table_get_selected (cal_table);
+ for (iter = list; iter != NULL; iter = iter->next) {
+ ECalModelComponent *comp_data = iter->data;
+ gboolean read_only;
+
+ e_cal_is_read_only (comp_data->client, &read_only, NULL);
+ sources_are_editable &= !read_only;
+ }
+ g_slist_free (list);
+
+ clipboard_has_calendar = (clipboard_targets != NULL) &&
+ e_targets_include_calendar (
+ clipboard_targets, n_clipboard_targets);
+
+ action = e_focus_tracker_get_cut_clipboard_action (focus_tracker);
+ sensitive = (n_selected > 0) && sources_are_editable;
+ tooltip = _("Cut selected tasks to the clipboard");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+
+ action = e_focus_tracker_get_copy_clipboard_action (focus_tracker);
+ sensitive = (n_selected > 0);
+ tooltip = _("Copy selected tasks to the clipboard");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+
+ action = e_focus_tracker_get_paste_clipboard_action (focus_tracker);
+ sensitive = sources_are_editable && clipboard_has_calendar;
+ tooltip = _("Paste tasks from the clipboard");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+
+ action = e_focus_tracker_get_select_all_action (focus_tracker);
+ sensitive = TRUE;
+ tooltip = _("Select all visible tasks");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+}
+
+static void
+calendar_table_cut_clipboard (ESelectable *selectable)
+{
+ ECalendarTable *cal_table;
+
+ cal_table = E_CALENDAR_TABLE (selectable);
+
+ e_selectable_copy_clipboard (selectable);
+ delete_selected_components (cal_table);
+}
+
+/* Helper for calendar_table_copy_clipboard() */
+static void
+copy_row_cb (gint model_row, gpointer data)
+{
+ ECalendarTable *cal_table;
+ ECalModelComponent *comp_data;
+ ECalModel *model;
+ gchar *comp_str;
+ icalcomponent *child;
+
+ cal_table = E_CALENDAR_TABLE (data);
+
+ g_return_if_fail (cal_table->tmp_vcal != NULL);
+
+ model = e_calendar_table_get_model (cal_table);
+ comp_data = e_cal_model_get_component_at (model, model_row);
+ if (!comp_data)
+ return;
+
+ /* Add timezones to the VCALENDAR component. */
+ e_cal_util_add_timezones_from_component (
+ cal_table->tmp_vcal, comp_data->icalcomp);
+
+ /* Add the new component to the VCALENDAR component. */
+ comp_str = icalcomponent_as_ical_string_r (comp_data->icalcomp);
+ child = icalparser_parse_string (comp_str);
+ if (child) {
+ icalcomponent_add_component (
+ cal_table->tmp_vcal,
+ icalcomponent_new_clone (child));
+ icalcomponent_free (child);
+ }
+ g_free (comp_str);
+}
+
+static void
+calendar_table_copy_clipboard (ESelectable *selectable)
+{
+ ECalendarTable *cal_table;
+ GtkClipboard *clipboard;
+ gchar *comp_str;
+
+ cal_table = E_CALENDAR_TABLE (selectable);
+
+ /* Create a temporary VCALENDAR object. */
+ cal_table->tmp_vcal = e_cal_util_new_top_level ();
+
+ e_table_selected_row_foreach (
+ E_TABLE (cal_table), copy_row_cb, cal_table);
+ comp_str = icalcomponent_as_ical_string_r (cal_table->tmp_vcal);
+
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+ e_clipboard_set_calendar (clipboard, comp_str, -1);
+ gtk_clipboard_store (clipboard);
+
+ g_free (comp_str);
+
+ icalcomponent_free (cal_table->tmp_vcal);
+ cal_table->tmp_vcal = NULL;
+}
+
+/* Helper for calenable_table_paste_clipboard() */
+static void
+clipboard_get_calendar_data (ECalendarTable *cal_table,
+ const gchar *text)
+{
+ icalcomponent *icalcomp;
+ gchar *uid;
+ ECalComponent *comp;
+ ECalModel *model;
+ ECal *client;
+ icalcomponent_kind kind;
+ const gchar *status_message;
+
+ g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
+
+ if (!text || !*text)
+ return;
+
+ icalcomp = icalparser_parse_string (text);
+ if (!icalcomp)
+ return;
+
+ /* check the type of the component */
+ kind = icalcomponent_isa (icalcomp);
+ if (kind != ICAL_VCALENDAR_COMPONENT &&
+ kind != ICAL_VEVENT_COMPONENT &&
+ kind != ICAL_VTODO_COMPONENT &&
+ kind != ICAL_VJOURNAL_COMPONENT) {
+ return;
+ }
+
+ model = e_calendar_table_get_model (cal_table);
+ client = e_cal_model_get_default_client (model);
+
+ status_message = _("Updating objects");
+ calendar_table_emit_status_message (cal_table, status_message, -1.0);
+
+ if (kind == ICAL_VCALENDAR_COMPONENT) {
+ icalcomponent_kind child_kind;
+ icalcomponent *subcomp;
+ icalcomponent *vcal_comp;
+
+ vcal_comp = icalcomp;
+ subcomp = icalcomponent_get_first_component (
+ vcal_comp, ICAL_ANY_COMPONENT);
+ while (subcomp) {
+ child_kind = icalcomponent_isa (subcomp);
+ if (child_kind == ICAL_VEVENT_COMPONENT ||
+ child_kind == ICAL_VTODO_COMPONENT ||
+ child_kind == ICAL_VJOURNAL_COMPONENT) {
+ ECalComponent *tmp_comp;
+
+ uid = e_cal_component_gen_uid ();
+ tmp_comp = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (
+ tmp_comp,
+ icalcomponent_new_clone (subcomp));
+ e_cal_component_set_uid (tmp_comp, uid);
+ free (uid);
+
+ /* FIXME should we convert start/due/complete
+ * times? Also, need error handling. */
+ e_cal_create_object (
+ client, e_cal_component_get_icalcomponent (tmp_comp),
+ NULL, NULL);
+
+ g_object_unref (tmp_comp);
+ }
+ subcomp = icalcomponent_get_next_component (
+ vcal_comp, ICAL_ANY_COMPONENT);
+ }
+ } else {
+ comp = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (comp, icalcomp);
+ uid = e_cal_component_gen_uid ();
+ e_cal_component_set_uid (comp, (const gchar *) uid);
+ free (uid);
+
+ e_cal_create_object (
+ client, e_cal_component_get_icalcomponent (comp),
+ NULL, NULL);
+
+ g_object_unref (comp);
+ }
+
+ calendar_table_emit_status_message (cal_table, NULL, -1.0);
+}
+
+static void
+calendar_table_paste_clipboard (ESelectable *selectable)
+{
+ ECalendarTable *cal_table;
+ GtkClipboard *clipboard;
+ GnomeCanvasItem *item;
+ GnomeCanvas *table_canvas;
+
+ cal_table = E_CALENDAR_TABLE (selectable);
+
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+
+ table_canvas = E_TABLE (cal_table)->table_canvas;
+ item = table_canvas->focused_item;
+
+ /* XXX Should ECellText implement GtkEditable? */
+
+ /* Paste text into a cell being edited. */
+ if (gtk_clipboard_wait_is_text_available (clipboard) &&
+ GTK_WIDGET_HAS_FOCUS (table_canvas) &&
+ E_IS_TABLE_ITEM (item) &&
+ E_TABLE_ITEM (item)->editing_col >= 0 &&
+ E_TABLE_ITEM (item)->editing_row >= 0) {
+
+ ETableItem *etable_item = E_TABLE_ITEM (item);
+
+ e_cell_text_paste_clipboard (
+ etable_item->cell_views[etable_item->editing_col],
+ etable_item->editing_col,
+ etable_item->editing_row);
+
+ /* Paste iCalendar data into the table. */
+ } else if (e_clipboard_wait_is_calendar_available (clipboard)) {
+ gchar *calendar_source;
+
+ calendar_source = e_clipboard_wait_for_calendar (clipboard);
+ clipboard_get_calendar_data (cal_table, calendar_source);
+ g_free (calendar_source);
+ }
+}
+
+static void
+calendar_table_select_all (ESelectable *selectable)
+{
+ e_table_select_all (E_TABLE (selectable));
+}
+
+static void
calendar_table_class_init (ECalendarTableClass *class)
{
GObjectClass *object_class;
@@ -937,6 +1228,16 @@ calendar_table_init (ECalendarTable *cal_table)
cal_table->priv = E_CALENDAR_TABLE_GET_PRIVATE (cal_table);
}
+static void
+calendar_table_selectable_init (ESelectableInterface *interface)
+{
+ interface->update_actions = calendar_table_update_actions;
+ interface->cut_clipboard = calendar_table_cut_clipboard;
+ interface->copy_clipboard = calendar_table_copy_clipboard;
+ interface->paste_clipboard = calendar_table_paste_clipboard;
+ interface->select_all = calendar_table_select_all;
+}
+
GType
e_calendar_table_get_type (void)
{
@@ -956,8 +1257,17 @@ e_calendar_table_get_type (void)
NULL /* value_table */
};
+ static const GInterfaceInfo selectable_info = {
+ (GInterfaceInitFunc) calendar_table_selectable_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL /* interface_data */
+ };
+
type = g_type_register_static (
E_TABLE_TYPE, "ECalendarTable", &type_info, 0);
+
+ g_type_add_interface_static (
+ type, E_TYPE_SELECTABLE, &selectable_info);
}
return type;
@@ -1061,32 +1371,6 @@ add_uid_cb (gint model_row, gpointer data)
closure->objects = g_slist_prepend (closure->objects, comp_data);
}
-/* Deletes all of the selected components in the table */
-static void
-delete_selected_components (ECalendarTable *cal_table)
-{
- GSList *objs, *l;
- const gchar *status_message;
-
- objs = e_calendar_table_get_selected (cal_table);
-
- status_message = _("Deleting selected objects");
- calendar_table_emit_status_message (cal_table, status_message, -1.0);
-
- for (l = objs; l; l = l->next) {
- ECalModelComponent *comp_data = (ECalModelComponent *) l->data;
- GError *error = NULL;
-
- e_cal_remove_object (comp_data->client,
- icalcomponent_get_uid (comp_data->icalcomp), &error);
- delete_error_dialog (error, E_CAL_COMPONENT_TODO);
- g_clear_error (&error);
- }
-
- calendar_table_emit_status_message (cal_table, NULL, -1.0);
-
- g_slist_free (objs);
-}
static void
add_retract_data (ECalComponent *comp, const gchar *retract_comment)
{
@@ -1223,210 +1507,6 @@ e_calendar_table_get_selected (ECalendarTable *cal_table)
return closure.objects;
}
-/**
- * e_calendar_table_cut_clipboard:
- * @cal_table: A calendar table.
- *
- * Cuts selected tasks in the given calendar table
- */
-void
-e_calendar_table_cut_clipboard (ECalendarTable *cal_table)
-{
- g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
-
- e_calendar_table_copy_clipboard (cal_table);
- delete_selected_components (cal_table);
-}
-
-/* callback for e_table_selected_row_foreach */
-static void
-copy_row_cb (gint model_row, gpointer data)
-{
- ECalendarTable *cal_table;
- ECalModelComponent *comp_data;
- ECalModel *model;
- gchar *comp_str;
- icalcomponent *child;
-
- cal_table = E_CALENDAR_TABLE (data);
-
- g_return_if_fail (cal_table->tmp_vcal != NULL);
-
- model = e_calendar_table_get_model (cal_table);
- comp_data = e_cal_model_get_component_at (model, model_row);
- if (!comp_data)
- return;
-
- /* add timezones to the VCALENDAR component */
- e_cal_util_add_timezones_from_component (cal_table->tmp_vcal, comp_data->icalcomp);
-
- /* add the new component to the VCALENDAR component */
- comp_str = icalcomponent_as_ical_string_r (comp_data->icalcomp);
- child = icalparser_parse_string (comp_str);
- if (child) {
- icalcomponent_add_component (cal_table->tmp_vcal,
- icalcomponent_new_clone (child));
- icalcomponent_free (child);
- }
- g_free (comp_str);
-}
-
-/**
- * e_calendar_table_copy_clipboard:
- * @cal_table: A calendar table.
- *
- * Copies selected tasks into the clipboard
- */
-void
-e_calendar_table_copy_clipboard (ECalendarTable *cal_table)
-{
- GtkClipboard *clipboard;
- gchar *comp_str;
-
- g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
-
- /* create temporary VCALENDAR object */
- cal_table->tmp_vcal = e_cal_util_new_top_level ();
-
- e_table_selected_row_foreach (
- E_TABLE (cal_table), copy_row_cb, cal_table);
- comp_str = icalcomponent_as_ical_string_r (cal_table->tmp_vcal);
-
- clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
- e_clipboard_set_calendar (clipboard, comp_str, -1);
- gtk_clipboard_store (clipboard);
-
- /* free memory */
- icalcomponent_free (cal_table->tmp_vcal);
- g_free (comp_str);
- cal_table->tmp_vcal = NULL;
-}
-
-static void
-clipboard_get_calendar_data (ECalendarTable *cal_table, const gchar *text)
-{
- icalcomponent *icalcomp;
- gchar *uid;
- ECalComponent *comp;
- ECalModel *model;
- ECal *client;
- icalcomponent_kind kind;
- const gchar *status_message;
-
- g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
-
- if (!text || !*text)
- return;
-
- icalcomp = icalparser_parse_string (text);
- if (!icalcomp)
- return;
-
- /* check the type of the component */
- kind = icalcomponent_isa (icalcomp);
- if (kind != ICAL_VCALENDAR_COMPONENT &&
- kind != ICAL_VEVENT_COMPONENT &&
- kind != ICAL_VTODO_COMPONENT &&
- kind != ICAL_VJOURNAL_COMPONENT) {
- return;
- }
-
- model = e_calendar_table_get_model (cal_table);
- client = e_cal_model_get_default_client (model);
-
- status_message = _("Updating objects");
- calendar_table_emit_status_message (cal_table, status_message, -1.0);
-
- if (kind == ICAL_VCALENDAR_COMPONENT) {
- icalcomponent_kind child_kind;
- icalcomponent *subcomp;
- icalcomponent *vcal_comp;
-
- vcal_comp = icalcomp;
- subcomp = icalcomponent_get_first_component (
- vcal_comp, ICAL_ANY_COMPONENT);
- while (subcomp) {
- child_kind = icalcomponent_isa (subcomp);
- if (child_kind == ICAL_VEVENT_COMPONENT ||
- child_kind == ICAL_VTODO_COMPONENT ||
- child_kind == ICAL_VJOURNAL_COMPONENT) {
- ECalComponent *tmp_comp;
-
- uid = e_cal_component_gen_uid ();
- tmp_comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (
- tmp_comp, icalcomponent_new_clone (subcomp));
- e_cal_component_set_uid (tmp_comp, uid);
- free (uid);
-
- /* FIXME should we convert start/due/complete times? */
- /* FIXME Error handling */
- e_cal_create_object (client, e_cal_component_get_icalcomponent (tmp_comp), NULL, NULL);
-
- g_object_unref (tmp_comp);
- }
- subcomp = icalcomponent_get_next_component (
- vcal_comp, ICAL_ANY_COMPONENT);
- }
- } else {
- comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (comp, icalcomp);
- uid = e_cal_component_gen_uid ();
- e_cal_component_set_uid (comp, (const gchar *) uid);
- free (uid);
-
- e_cal_create_object (client, e_cal_component_get_icalcomponent (comp), NULL, NULL);
-
- g_object_unref (comp);
- }
-
- calendar_table_emit_status_message (cal_table, NULL, -1.0);
-}
-
-/**
- * e_calendar_table_paste_clipboard:
- * @cal_table: A calendar table.
- *
- * Pastes tasks currently in the clipboard into the given calendar table
- */
-void
-e_calendar_table_paste_clipboard (ECalendarTable *cal_table)
-{
- GtkClipboard *clipboard;
- GnomeCanvasItem *item;
- GnomeCanvas *table_canvas;
-
- g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
-
- clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
-
- table_canvas = E_TABLE (cal_table)->table_canvas;
- item = table_canvas->focused_item;
-
- /* Paste text into a cell being edited. */
- if (gtk_clipboard_wait_is_text_available (clipboard) &&
- GTK_WIDGET_HAS_FOCUS (table_canvas) &&
- E_IS_TABLE_ITEM (item) &&
- E_TABLE_ITEM (item)->editing_col >= 0 &&
- E_TABLE_ITEM (item)->editing_row >= 0) {
-
- ETableItem *etable_item = E_TABLE_ITEM (item);
-
- e_cell_text_paste_clipboard (
- etable_item->cell_views[etable_item->editing_col],
- etable_item->editing_col,
- etable_item->editing_row);
-
- /* Paste iCalendar data into the table. */
- } else if (e_clipboard_wait_is_calendar_available (clipboard)) {
- gchar *calendar_source;
-
- calendar_source = e_clipboard_wait_for_calendar (clipboard);
- clipboard_get_calendar_data (cal_table, calendar_source);
- g_free (calendar_source);
- }
-}
-
static void
hide_completed_rows (ECalModel *model, GList *clients_list, gchar *hide_sexp, GPtrArray *comp_objects)
{