aboutsummaryrefslogtreecommitdiffstats
path: root/calendar
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2010-01-17 02:34:32 +0800
committerMatthew Barnes <mbarnes@redhat.com>2010-01-18 01:11:08 +0800
commit3e7c7808cc65c22bc40a7d1d30ffa0044097a6ff (patch)
treed74cd0017e310c79b796eba3df7bfb8947a673d7 /calendar
parent2cf0c27e2ece428dd2af1945f6fececbe9dbcc15 (diff)
downloadgsoc2013-evolution-3e7c7808cc65c22bc40a7d1d30ffa0044097a6ff.tar.gz
gsoc2013-evolution-3e7c7808cc65c22bc40a7d1d30ffa0044097a6ff.tar.zst
gsoc2013-evolution-3e7c7808cc65c22bc40a7d1d30ffa0044097a6ff.zip
Improve clipboard behavior.
Add "copy-target-list" and "paste-target-list" to the ESelectable interface. These are underutilized for the moment, but will eventually be used to help integrate drag-and-drop support into ESelectable. Add cut and paste support to EWebView, along with a new "editable" property and new clipboard signals "copy-clipboard", "cut-clipboard" and "paste-clipboard". In EFocusTracker, listen for "owner-changed" signals from the default clipboard as another trigger to update actions, particularly the Paste action. (Unfortunately this doesn't work for EWebView since GtkHtml implements its own clipboard.) In EMsgComposer, convert GtkhtmlEditor's clipboard methods to empty stubs, since EFocusTracker will now trigger EWebView's clipboard actions. Also, intercept EWebView::paste-clipboard signals and improve the interaction between the HTML editor and the attachment bar based on use cases in bug #603715.
Diffstat (limited to 'calendar')
-rw-r--r--calendar/gui/e-calendar-view.c90
-rw-r--r--calendar/gui/e-calendar-view.h4
-rw-r--r--calendar/gui/e-memo-table.c78
-rw-r--r--calendar/gui/e-memo-table.h4
-rw-r--r--calendar/gui/e-task-table.c84
-rw-r--r--calendar/gui/e-task-table.h8
6 files changed, 242 insertions, 26 deletions
diff --git a/calendar/gui/e-calendar-view.c b/calendar/gui/e-calendar-view.c
index 57973828a3..fd8650edad 100644
--- a/calendar/gui/e-calendar-view.c
+++ b/calendar/gui/e-calendar-view.c
@@ -74,11 +74,16 @@ struct _ECalendarViewPrivate {
/* The default category */
gchar *default_category;
+
+ GtkTargetList *copy_target_list;
+ GtkTargetList *paste_target_list;
};
enum {
PROP_0,
- PROP_MODEL
+ PROP_COPY_TARGET_LIST,
+ PROP_MODEL,
+ PROP_PASTE_TARGET_LIST
};
/* FIXME Why are we emitting these event signals here? Can't the model just be listened to? */
@@ -268,11 +273,23 @@ calendar_view_get_property (GObject *object,
GParamSpec *pspec)
{
switch (property_id) {
+ case PROP_COPY_TARGET_LIST:
+ g_value_set_boxed (
+ value, e_calendar_view_get_copy_target_list (
+ E_CALENDAR_VIEW (object)));
+ return;
+
case PROP_MODEL:
g_value_set_object (
value, e_calendar_view_get_model (
E_CALENDAR_VIEW (object)));
return;
+
+ case PROP_PASTE_TARGET_LIST:
+ g_value_set_boxed (
+ value, e_calendar_view_get_paste_target_list (
+ E_CALENDAR_VIEW (object)));
+ return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -293,6 +310,16 @@ calendar_view_dispose (GObject *object)
priv->model = NULL;
}
+ if (priv->copy_target_list != NULL) {
+ gtk_target_list_unref (priv->copy_target_list);
+ priv->copy_target_list = NULL;
+ }
+
+ if (priv->paste_target_list != NULL) {
+ gtk_target_list_unref (priv->paste_target_list);
+ priv->paste_target_list = NULL;
+ }
+
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (e_calendar_view_parent_class)->dispose (object);
}
@@ -318,13 +345,15 @@ calendar_view_update_actions (ESelectable *selectable,
{
ECalendarView *view;
GtkAction *action;
+ GtkTargetList *target_list;
GList *list, *iter;
+ gboolean can_paste = FALSE;
gboolean sources_are_editable = TRUE;
- gboolean clipboard_has_calendar;
gboolean recurring = FALSE;
gboolean sensitive;
const gchar *tooltip;
gint n_selected;
+ gint ii;
view = E_CALENDAR_VIEW (selectable);
@@ -353,9 +382,10 @@ calendar_view_update_actions (ESelectable *selectable,
g_list_free (list);
- clipboard_has_calendar = (clipboard_targets != NULL) &&
- e_targets_include_calendar (
- clipboard_targets, n_clipboard_targets);
+ target_list = e_selectable_get_paste_target_list (selectable);
+ for (ii = 0; ii < n_clipboard_targets && !can_paste; ii++)
+ can_paste = gtk_target_list_find (
+ target_list, clipboard_targets[ii], NULL);
action = e_focus_tracker_get_cut_clipboard_action (focus_tracker);
sensitive = (n_selected > 0) && sources_are_editable;
@@ -370,7 +400,7 @@ calendar_view_update_actions (ESelectable *selectable,
gtk_action_set_tooltip (action, tooltip);
action = e_focus_tracker_get_paste_clipboard_action (focus_tracker);
- sensitive = sources_are_editable && clipboard_has_calendar;
+ sensitive = sources_are_editable && can_paste;
tooltip = _("Paste events from the clipboard");
gtk_action_set_sensitive (action, sensitive);
gtk_action_set_tooltip (action, tooltip);
@@ -718,6 +748,12 @@ e_calendar_view_class_init (ECalendarViewClass *class)
class->open_event = e_calendar_view_open_event;
class->paste_text = NULL;
+ /* Inherited from ESelectableInterface */
+ g_object_class_override_property (
+ object_class,
+ PROP_COPY_TARGET_LIST,
+ "copy-target-list");
+
g_object_class_install_property (
object_class,
PROP_MODEL,
@@ -729,6 +765,12 @@ e_calendar_view_class_init (ECalendarViewClass *class)
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
+ /* Inherited from ESelectableInterface */
+ g_object_class_override_property (
+ object_class,
+ PROP_PASTE_TARGET_LIST,
+ "paste-target-list");
+
signals[POPUP_EVENT] = g_signal_new (
"popup-event",
G_TYPE_FROM_CLASS (class),
@@ -820,7 +862,17 @@ e_calendar_view_class_init (ECalendarViewClass *class)
static void
e_calendar_view_init (ECalendarView *calendar_view)
{
+ GtkTargetList *target_list;
+
calendar_view->priv = E_CALENDAR_VIEW_GET_PRIVATE (calendar_view);
+
+ target_list = gtk_target_list_new (NULL, 0);
+ e_target_list_add_calendar_targets (target_list, 0);
+ calendar_view->priv->copy_target_list = target_list;
+
+ target_list = gtk_target_list_new (NULL, 0);
+ e_target_list_add_calendar_targets (target_list, 0);
+ calendar_view->priv->paste_target_list = target_list;
}
static void
@@ -1017,7 +1069,8 @@ const gchar *
e_calendar_view_get_default_category (ECalendarView *cal_view)
{
g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), NULL);
- return (const gchar *) cal_view->priv->default_category;
+
+ return cal_view->priv->default_category;
}
/**
@@ -1029,16 +1082,31 @@ e_calendar_view_get_default_category (ECalendarView *cal_view)
* components from the given calendar view.
*/
void
-e_calendar_view_set_default_category (ECalendarView *cal_view, const gchar *category)
+e_calendar_view_set_default_category (ECalendarView *cal_view,
+ const gchar *category)
{
g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view));
- if (cal_view->priv->default_category)
- g_free (cal_view->priv->default_category);
-
+ g_free (cal_view->priv->default_category);
cal_view->priv->default_category = g_strdup (category);
}
+GtkTargetList *
+e_calendar_view_get_copy_target_list (ECalendarView *cal_view)
+{
+ g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), NULL);
+
+ return cal_view->priv->copy_target_list;
+}
+
+GtkTargetList *
+e_calendar_view_get_paste_target_list (ECalendarView *cal_view)
+{
+ g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), NULL);
+
+ return cal_view->priv->paste_target_list;
+}
+
GList *
e_calendar_view_get_selected_events (ECalendarView *cal_view)
{
diff --git a/calendar/gui/e-calendar-view.h b/calendar/gui/e-calendar-view.h
index d79a6fdc9d..62fcabcc37 100644
--- a/calendar/gui/e-calendar-view.h
+++ b/calendar/gui/e-calendar-view.h
@@ -159,6 +159,10 @@ void e_calendar_view_set_status_message
(ECalendarView *cal_view,
const gchar *message,
gint percent);
+GtkTargetList * e_calendar_view_get_copy_target_list
+ (ECalendarView *cal_view);
+GtkTargetList * e_calendar_view_get_paste_target_list
+ (ECalendarView *cal_view);
GList * e_calendar_view_get_selected_events
(ECalendarView *cal_view);
diff --git a/calendar/gui/e-memo-table.c b/calendar/gui/e-memo-table.c
index 5f2cd26baf..11c74820a6 100644
--- a/calendar/gui/e-memo-table.c
+++ b/calendar/gui/e-memo-table.c
@@ -67,11 +67,16 @@
struct _EMemoTablePrivate {
gpointer shell_view; /* weak pointer */
ECalModel *model;
+
+ GtkTargetList *copy_target_list;
+ GtkTargetList *paste_target_list;
};
enum {
PROP_0,
+ PROP_COPY_TARGET_LIST,
PROP_MODEL,
+ PROP_PASTE_TARGET_LIST,
PROP_SHELL_VIEW
};
@@ -300,12 +305,24 @@ memo_table_get_property (GObject *object,
GParamSpec *pspec)
{
switch (property_id) {
+ case PROP_COPY_TARGET_LIST:
+ g_value_set_boxed (
+ value, e_memo_table_get_copy_target_list (
+ E_MEMO_TABLE (object)));
+ return;
+
case PROP_MODEL:
g_value_set_object (
value, e_memo_table_get_model (
E_MEMO_TABLE (object)));
return;
+ case PROP_PASTE_TARGET_LIST:
+ g_value_set_boxed (
+ value, e_memo_table_get_paste_target_list (
+ E_MEMO_TABLE (object)));
+ return;
+
case PROP_SHELL_VIEW:
g_value_set_object (
value, e_memo_table_get_shell_view (
@@ -334,6 +351,16 @@ memo_table_dispose (GObject *object)
priv->model = NULL;
}
+ if (priv->copy_target_list != NULL) {
+ gtk_target_list_unref (priv->copy_target_list);
+ priv->copy_target_list = NULL;
+ }
+
+ if (priv->paste_target_list != NULL) {
+ gtk_target_list_unref (priv->paste_target_list);
+ priv->paste_target_list = NULL;
+ }
+
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (parent_class)->dispose (object);
}
@@ -689,12 +716,14 @@ memo_table_update_actions (ESelectable *selectable,
{
EMemoTable *memo_table;
GtkAction *action;
+ GtkTargetList *target_list;
GSList *list, *iter;
+ gboolean can_paste = FALSE;
gboolean sources_are_editable = TRUE;
- gboolean clipboard_has_calendar;
gboolean sensitive;
const gchar *tooltip;
gint n_selected;
+ gint ii;
memo_table = E_MEMO_TABLE (selectable);
n_selected = e_table_selected_count (E_TABLE (memo_table));
@@ -709,9 +738,10 @@ memo_table_update_actions (ESelectable *selectable,
}
g_slist_free (list);
- clipboard_has_calendar = (clipboard_targets != NULL) &&
- e_targets_include_calendar (
- clipboard_targets, n_clipboard_targets);
+ target_list = e_selectable_get_paste_target_list (selectable);
+ for (ii = 0; ii < n_clipboard_targets && !can_paste; ii++)
+ can_paste = gtk_target_list_find (
+ target_list, clipboard_targets[ii], NULL);
action = e_focus_tracker_get_cut_clipboard_action (focus_tracker);
sensitive = (n_selected > 0) && sources_are_editable;
@@ -726,7 +756,7 @@ memo_table_update_actions (ESelectable *selectable,
gtk_action_set_tooltip (action, tooltip);
action = e_focus_tracker_get_paste_clipboard_action (focus_tracker);
- sensitive = sources_are_editable && clipboard_has_calendar;
+ sensitive = sources_are_editable && can_paste;
tooltip = _("Paste memos from the clipboard");
gtk_action_set_sensitive (action, sensitive);
gtk_action_set_tooltip (action, tooltip);
@@ -1046,6 +1076,12 @@ memo_table_class_init (EMemoTableClass *class)
table_class->double_click = memo_table_double_click;
table_class->right_click = memo_table_right_click;
+ /* Inherited from ESelectableInterface */
+ g_object_class_override_property (
+ object_class,
+ PROP_COPY_TARGET_LIST,
+ "copy-target-list");
+
g_object_class_install_property (
object_class,
PROP_MODEL,
@@ -1057,6 +1093,12 @@ memo_table_class_init (EMemoTableClass *class)
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
+ /* Inherited from ESelectableInterface */
+ g_object_class_override_property (
+ object_class,
+ PROP_PASTE_TARGET_LIST,
+ "paste-target-list");
+
g_object_class_install_property (
object_class,
PROP_SHELL_VIEW,
@@ -1111,7 +1153,17 @@ memo_table_class_init (EMemoTableClass *class)
static void
memo_table_init (EMemoTable *memo_table)
{
+ GtkTargetList *target_list;
+
memo_table->priv = E_MEMO_TABLE_GET_PRIVATE (memo_table);
+
+ target_list = gtk_target_list_new (NULL, 0);
+ e_target_list_add_calendar_targets (target_list, 0);
+ memo_table->priv->copy_target_list = target_list;
+
+ target_list = gtk_target_list_new (NULL, 0);
+ e_target_list_add_calendar_targets (target_list, 0);
+ memo_table->priv->paste_target_list = target_list;
}
static void
@@ -1249,3 +1301,19 @@ e_memo_table_get_selected (EMemoTable *memo_table)
return closure.objects;
}
+
+GtkTargetList *
+e_memo_table_get_copy_target_list (EMemoTable *memo_table)
+{
+ g_return_val_if_fail (E_IS_MEMO_TABLE (memo_table), NULL);
+
+ return memo_table->priv->copy_target_list;
+}
+
+GtkTargetList *
+e_memo_table_get_paste_target_list (EMemoTable *memo_table)
+{
+ g_return_val_if_fail (E_IS_MEMO_TABLE (memo_table), NULL);
+
+ return memo_table->priv->paste_target_list;
+}
diff --git a/calendar/gui/e-memo-table.h b/calendar/gui/e-memo-table.h
index c891117203..b0e4ba6a6a 100644
--- a/calendar/gui/e-memo-table.h
+++ b/calendar/gui/e-memo-table.h
@@ -103,6 +103,10 @@ void e_memo_table_set_use_24_hour_format
(EMemoTable *memo_table,
gboolean use_24_hour_format);
GSList * e_memo_table_get_selected (EMemoTable *memo_table);
+GtkTargetList * e_memo_table_get_copy_target_list
+ (EMemoTable *memo_table);
+GtkTargetList * e_memo_table_get_paste_target_list
+ (EMemoTable *memo_table);
G_END_DECLS
diff --git a/calendar/gui/e-task-table.c b/calendar/gui/e-task-table.c
index 9f0962dcb8..4a378f2daf 100644
--- a/calendar/gui/e-task-table.c
+++ b/calendar/gui/e-task-table.c
@@ -69,11 +69,16 @@
struct _ETaskTablePrivate {
gpointer shell_view; /* weak pointer */
ECalModel *model;
+
+ GtkTargetList *copy_target_list;
+ GtkTargetList *paste_target_list;
};
enum {
PROP_0,
+ PROP_COPY_TARGET_LIST,
PROP_MODEL,
+ PROP_PASTE_TARGET_LIST,
PROP_SHELL_VIEW
};
@@ -338,12 +343,24 @@ task_table_get_property (GObject *object,
GParamSpec *pspec)
{
switch (property_id) {
+ case PROP_COPY_TARGET_LIST:
+ g_value_set_boxed (
+ value, e_task_table_get_copy_target_list (
+ E_TASK_TABLE (object)));
+ return;
+
case PROP_MODEL:
g_value_set_object (
value, e_task_table_get_model (
E_TASK_TABLE (object)));
return;
+ case PROP_PASTE_TARGET_LIST:
+ g_value_set_boxed (
+ value, e_task_table_get_paste_target_list (
+ E_TASK_TABLE (object)));
+ return;
+
case PROP_SHELL_VIEW:
g_value_set_object (
value, e_task_table_get_shell_view (
@@ -372,6 +389,16 @@ task_table_dispose (GObject *object)
priv->model = NULL;
}
+ if (priv->copy_target_list != NULL) {
+ gtk_target_list_unref (priv->copy_target_list);
+ priv->copy_target_list = NULL;
+ }
+
+ if (priv->paste_target_list != NULL) {
+ gtk_target_list_unref (priv->paste_target_list);
+ priv->paste_target_list = NULL;
+ }
+
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (parent_class)->dispose (object);
}
@@ -870,12 +897,14 @@ task_table_update_actions (ESelectable *selectable,
{
ETaskTable *task_table;
GtkAction *action;
+ GtkTargetList *target_list;
GSList *list, *iter;
+ gboolean can_paste = FALSE;
gboolean sources_are_editable = TRUE;
- gboolean clipboard_has_calendar;
gboolean sensitive;
const gchar *tooltip;
gint n_selected;
+ gint ii;
task_table = E_TASK_TABLE (selectable);
n_selected = e_table_selected_count (E_TABLE (task_table));
@@ -890,9 +919,10 @@ task_table_update_actions (ESelectable *selectable,
}
g_slist_free (list);
- clipboard_has_calendar = (clipboard_targets != NULL) &&
- e_targets_include_calendar (
- clipboard_targets, n_clipboard_targets);
+ target_list = e_selectable_get_paste_target_list (selectable);
+ for (ii = 0; ii < n_clipboard_targets && !can_paste; ii++)
+ can_paste = gtk_target_list_find (
+ target_list, clipboard_targets[ii], NULL);
action = e_focus_tracker_get_cut_clipboard_action (focus_tracker);
sensitive = (n_selected > 0) && sources_are_editable;
@@ -907,7 +937,7 @@ task_table_update_actions (ESelectable *selectable,
gtk_action_set_tooltip (action, tooltip);
action = e_focus_tracker_get_paste_clipboard_action (focus_tracker);
- sensitive = sources_are_editable && clipboard_has_calendar;
+ sensitive = sources_are_editable && can_paste;
tooltip = _("Paste tasks from the clipboard");
gtk_action_set_sensitive (action, sensitive);
gtk_action_set_tooltip (action, tooltip);
@@ -1010,7 +1040,7 @@ clipboard_get_calendar_data (ETaskTable *task_table,
icalcomponent_kind kind;
const gchar *status_message;
- g_return_if_fail (E_IS_CALENDAR_TABLE (task_table));
+ g_return_if_fail (E_IS_TASK_TABLE (task_table));
if (!text || !*text)
return;
@@ -1305,6 +1335,12 @@ task_table_class_init (ETaskTableClass *class)
table_class->double_click = task_table_double_click;
table_class->right_click = task_table_right_click;
+ /* Inherited from ESelectableInterface */
+ g_object_class_override_property (
+ object_class,
+ PROP_COPY_TARGET_LIST,
+ "copy-target-list");
+
g_object_class_install_property (
object_class,
PROP_MODEL,
@@ -1316,6 +1352,12 @@ task_table_class_init (ETaskTableClass *class)
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
+ /* Inherited from ESelectableInterface */
+ g_object_class_override_property (
+ object_class,
+ PROP_PASTE_TARGET_LIST,
+ "paste-target-list");
+
g_object_class_install_property (
object_class,
PROP_SHELL_VIEW,
@@ -1370,7 +1412,17 @@ task_table_class_init (ETaskTableClass *class)
static void
task_table_init (ETaskTable *task_table)
{
+ GtkTargetList *target_list;
+
task_table->priv = E_TASK_TABLE_GET_PRIVATE (task_table);
+
+ target_list = gtk_target_list_new (NULL, 0);
+ e_target_list_add_calendar_targets (target_list, 0);
+ task_table->priv->copy_target_list = target_list;
+
+ target_list = gtk_target_list_new (NULL, 0);
+ e_target_list_add_calendar_targets (target_list, 0);
+ task_table->priv->paste_target_list = target_list;
}
static void
@@ -1451,7 +1503,7 @@ e_task_table_new (EShellView *shell_view,
ECalModel *
e_task_table_get_model (ETaskTable *task_table)
{
- g_return_val_if_fail (E_IS_CALENDAR_TABLE (task_table), NULL);
+ g_return_val_if_fail (E_IS_TASK_TABLE (task_table), NULL);
return task_table->priv->model;
}
@@ -1459,7 +1511,7 @@ e_task_table_get_model (ETaskTable *task_table)
EShellView *
e_task_table_get_shell_view (ETaskTable *task_table)
{
- g_return_val_if_fail (E_IS_CALENDAR_TABLE (task_table), NULL);
+ g_return_val_if_fail (E_IS_TASK_TABLE (task_table), NULL);
return task_table->priv->shell_view;
}
@@ -1506,6 +1558,22 @@ e_task_table_get_selected (ETaskTable *task_table)
return closure.objects;
}
+GtkTargetList *
+e_task_table_get_copy_target_list (ETaskTable *task_table)
+{
+ g_return_val_if_fail (E_IS_TASK_TABLE (task_table), NULL);
+
+ return task_table->priv->copy_target_list;
+}
+
+GtkTargetList *
+e_task_table_get_paste_target_list (ETaskTable *task_table)
+{
+ g_return_val_if_fail (E_IS_TASK_TABLE (task_table), NULL);
+
+ return task_table->priv->paste_target_list;
+}
+
static void
hide_completed_rows (ECalModel *model,
GList *clients_list,
diff --git a/calendar/gui/e-task-table.h b/calendar/gui/e-task-table.h
index b23f128b87..a112e222f8 100644
--- a/calendar/gui/e-task-table.h
+++ b/calendar/gui/e-task-table.h
@@ -45,10 +45,10 @@
#define E_TASK_TABLE_CLASS(cls) \
(G_TYPE_CHECK_CLASS_CAST \
((cls), E_TYPE_TASK_TABLE, ETaskTableClass))
-#define E_IS_CALENDAR_TABLE(obj) \
+#define E_IS_TASK_TABLE(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE \
((obj), E_TYPE_TASK_TABLE))
-#define E_IS_CALENDAR_TABLE_CLASS(cls) \
+#define E_IS_TASK_TABLE_CLASS(cls) \
(G_TYPE_CHECK_CLASS_TYPE \
((cls), E_TYPE_TASK_TABLE))
#define E_TASK_TABLE_GET_CLASS(obj) \
@@ -93,6 +93,10 @@ GtkWidget * e_task_table_new (EShellView *shell_view,
ECalModel * e_task_table_get_model (ETaskTable *task_table);
EShellView * e_task_table_get_shell_view (ETaskTable *task_table);
GSList * e_task_table_get_selected (ETaskTable *task_table);
+GtkTargetList * e_task_table_get_copy_target_list
+ (ETaskTable *task_table);
+GtkTargetList * e_task_table_get_paste_target_list
+ (ETaskTable *task_table);
ECalModelComponent *
e_task_table_get_selected_comp
(ETaskTable *task_table);