aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/gui/e-memo-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-memo-table.c
parent83dc7625983470bff4ce8b9070fbc23c3370c472 (diff)
downloadgsoc2013-evolution-abc0e4c694fb3d9624e890384880def730769fa0.tar.gz
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-memo-table.c')
-rw-r--r--calendar/gui/e-memo-table.c544
1 files changed, 312 insertions, 232 deletions
diff --git a/calendar/gui/e-memo-table.c b/calendar/gui/e-memo-table.c
index 977715898e..4df17c5487 100644
--- a/calendar/gui/e-memo-table.c
+++ b/calendar/gui/e-memo-table.c
@@ -36,7 +36,8 @@
#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include <e-util/e-binding.h>
-#include <widgets/misc/e-gui-utils.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>
@@ -181,6 +182,33 @@ memo_table_model_cal_view_done_cb (EMemoTable *memo_table,
memo_table_emit_status_message (memo_table, NULL, -1.0);
}
+/* Deletes all of the selected components in the table */
+static void
+delete_selected_components (EMemoTable *memo_table)
+{
+ GSList *objs, *l;
+ const gchar *status_message;
+
+ objs = e_memo_table_get_selected (memo_table);
+
+ status_message = _("Deleting selected objects");
+ memo_table_emit_status_message (memo_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_JOURNAL);
+ g_clear_error (&error);
+ }
+
+ memo_table_emit_status_message (memo_table, NULL, -1.0);
+
+ g_slist_free (objs);
+}
+
static void
memo_table_set_model (EMemoTable *memo_table,
ECalModel *model)
@@ -629,6 +657,270 @@ memo_table_right_click (ETable *table,
}
static void
+memo_table_update_actions (ESelectable *selectable,
+ EFocusTracker *focus_tracker,
+ GdkAtom *clipboard_targets,
+ gint n_clipboard_targets)
+{
+ EMemoTable *memo_table;
+ GtkAction *action;
+ GSList *list, *iter;
+ gboolean sources_are_editable = TRUE;
+ gboolean clipboard_has_calendar;
+ gboolean sensitive;
+ const gchar *tooltip;
+ gint n_selected;
+
+ memo_table = E_MEMO_TABLE (selectable);
+ n_selected = e_table_selected_count (E_TABLE (memo_table));
+
+ list = e_memo_table_get_selected (memo_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 memos 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 memos 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 memos 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 memos");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+}
+
+static void
+memo_table_cut_clipboard (ESelectable *selectable)
+{
+ EMemoTable *memo_table;
+
+ memo_table = E_MEMO_TABLE (selectable);
+
+ e_selectable_copy_clipboard (selectable);
+ delete_selected_components (memo_table);
+}
+
+/* Helper for memo_table_copy_clipboard() */
+static void
+copy_row_cb (gint model_row, gpointer data)
+{
+ EMemoTable *memo_table;
+ ECalModelComponent *comp_data;
+ ECalModel *model;
+ gchar *comp_str;
+ icalcomponent *child;
+
+ memo_table = E_MEMO_TABLE (data);
+
+ g_return_if_fail (memo_table->tmp_vcal != NULL);
+
+ model = e_memo_table_get_model (memo_table);
+ comp_data = e_cal_model_get_component_at (model, model_row);
+ if (comp_data == NULL)
+ return;
+
+ /* Add timezones to the VCALENDAR component. */
+ e_cal_util_add_timezones_from_component (
+ memo_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 (
+ memo_table->tmp_vcal,
+ icalcomponent_new_clone (child));
+ icalcomponent_free (child);
+ }
+ g_free (comp_str);
+}
+
+static void
+memo_table_copy_clipboard (ESelectable *selectable)
+{
+ EMemoTable *memo_table;
+ GtkClipboard *clipboard;
+ gchar *comp_str;
+
+ memo_table = E_MEMO_TABLE (selectable);
+
+ /* Create a temporary VCALENDAR object. */
+ memo_table->tmp_vcal = e_cal_util_new_top_level ();
+
+ e_table_selected_row_foreach (
+ E_TABLE (memo_table), copy_row_cb, memo_table);
+ comp_str = icalcomponent_as_ical_string_r (memo_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 (memo_table->tmp_vcal);
+ memo_table->tmp_vcal = NULL;
+}
+
+/* Helper for memo_table_paste_clipboard() */
+static void
+clipboard_get_calendar_data (EMemoTable *memo_table,
+ const gchar *text)
+{
+ icalcomponent *icalcomp;
+ gchar *uid;
+ ECalComponent *comp;
+ ECal *client;
+ ECalModel *model;
+ icalcomponent_kind kind;
+ const gchar *status_message;
+
+ g_return_if_fail (E_IS_MEMO_TABLE (memo_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_memo_table_get_model (memo_table);
+ client = e_cal_model_get_default_client (model);
+
+ status_message = _("Updating objects");
+ memo_table_emit_status_message (memo_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);
+ }
+
+ memo_table_emit_status_message (memo_table, NULL, -1.0);
+}
+
+static void
+memo_table_paste_clipboard (ESelectable *selectable)
+{
+ EMemoTable *memo_table;
+ GtkClipboard *clipboard;
+ GnomeCanvasItem *item;
+ GnomeCanvas *table_canvas;
+
+ memo_table = E_MEMO_TABLE (selectable);
+
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+
+ table_canvas = E_TABLE (memo_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 (memo_table, calendar_source);
+ g_free (calendar_source);
+ }
+}
+
+static void
+memo_table_select_all (ESelectable *selectable)
+{
+ e_table_select_all (E_TABLE (selectable));
+}
+
+static void
memo_table_class_init (EMemoTableClass *class)
{
GObjectClass *object_class;
@@ -720,6 +1012,16 @@ memo_table_init (EMemoTable *memo_table)
memo_table->priv = E_MEMO_TABLE_GET_PRIVATE (memo_table);
}
+static void
+memo_table_selectable_init (ESelectableInterface *interface)
+{
+ interface->update_actions = memo_table_update_actions;
+ interface->cut_clipboard = memo_table_cut_clipboard;
+ interface->copy_clipboard = memo_table_copy_clipboard;
+ interface->paste_clipboard = memo_table_paste_clipboard;
+ interface->select_all = memo_table_select_all;
+}
+
GType
e_memo_table_get_type (void)
{
@@ -739,8 +1041,17 @@ e_memo_table_get_type (void)
NULL /* value_table */
};
+ static const GInterfaceInfo selectable_info = {
+ (GInterfaceInitFunc) memo_table_selectable_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL /* interface_data */
+ };
+
type = g_type_register_static (
E_TABLE_TYPE, "EMemoTable", &type_info, 0);
+
+ g_type_add_interface_static (
+ type, E_TYPE_SELECTABLE, &selectable_info);
}
return type;
@@ -847,33 +1158,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 (EMemoTable *memo_table)
-{
- GSList *objs, *l;
- const gchar *status_message;
-
- objs = e_memo_table_get_selected (memo_table);
-
- status_message = _("Deleting selected objects");
- memo_table_emit_status_message (memo_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_JOURNAL);
- g_clear_error (&error);
- }
-
- memo_table_emit_status_message (memo_table, NULL, -1.0);
-
- g_slist_free (objs);
-}
-
/**
* e_memo_table_delete_selected:
* @memo_table: A memo table.
@@ -938,210 +1222,6 @@ e_memo_table_get_selected (EMemoTable *memo_table)
return closure.objects;
}
-/**
- * e_memo_table_cut_clipboard:
- * @memo_table: A calendar table.
- *
- * Cuts selected tasks in the given calendar table
- */
-void
-e_memo_table_cut_clipboard (EMemoTable *memo_table)
-{
- g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
-
- e_memo_table_copy_clipboard (memo_table);
- delete_selected_components (memo_table);
-}
-
-/* callback for e_table_selected_row_foreach */
-static void
-copy_row_cb (gint model_row, gpointer data)
-{
- EMemoTable *memo_table;
- ECalModelComponent *comp_data;
- ECalModel *model;
- gchar *comp_str;
- icalcomponent *child;
-
- memo_table = E_MEMO_TABLE (data);
-
- g_return_if_fail (memo_table->tmp_vcal != NULL);
-
- model = e_memo_table_get_model (memo_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 (memo_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 (memo_table->tmp_vcal,
- icalcomponent_new_clone (child));
- icalcomponent_free (child);
- }
- g_free (comp_str);
-}
-
-/**
- * e_memo_table_copy_clipboard:
- * @memo_table: A calendar table.
- *
- * Copies selected tasks into the clipboard
- */
-void
-e_memo_table_copy_clipboard (EMemoTable *memo_table)
-{
- GtkClipboard *clipboard;
- gchar *comp_str;
-
- g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
-
- /* create temporary VCALENDAR object */
- memo_table->tmp_vcal = e_cal_util_new_top_level ();
-
- e_table_selected_row_foreach (
- E_TABLE (memo_table), copy_row_cb, memo_table);
- comp_str = icalcomponent_as_ical_string_r (memo_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 (memo_table->tmp_vcal);
- g_free (comp_str);
- memo_table->tmp_vcal = NULL;
-}
-
-static void
-clipboard_get_calendar_data (EMemoTable *memo_table, const gchar *text)
-{
- icalcomponent *icalcomp;
- gchar *uid;
- ECalComponent *comp;
- ECal *client;
- ECalModel *model;
- icalcomponent_kind kind;
- const gchar *status_message;
-
- g_return_if_fail (E_IS_MEMO_TABLE (memo_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_memo_table_get_model (memo_table);
- client = e_cal_model_get_default_client (model);
-
- status_message = _("Updating objects");
- memo_table_emit_status_message (memo_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);
- }
-
- memo_table_emit_status_message (memo_table, NULL, -1.0);
-}
-
-/**
- * e_memo_table_paste_clipboard:
- * @memo_table: A calendar table.
- *
- * Pastes tasks currently in the clipboard into the given calendar table
- */
-void
-e_memo_table_paste_clipboard (EMemoTable *memo_table)
-{
- GtkClipboard *clipboard;
- GnomeCanvasItem *item;
- GnomeCanvas *table_canvas;
-
- g_return_if_fail (E_IS_MEMO_TABLE (memo_table));
-
- clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
-
- table_canvas = E_TABLE (memo_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 (memo_table, calendar_source);
- g_free (calendar_source);
- }
-}
-
/* Returns the current time, for the ECellDateEdit items.
FIXME: Should probably use the timezone of the item rather than the
current timezone, though that may be difficult to get from here. */