From 2a3580e43deb40eca14ed7ff16ad5cac6a7a5e2b Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 21 Jun 2013 16:22:15 +0200 Subject: Calendar views inline text edit with Ctrl+C/V/X does not work The shortcuts Ctrl+C/V/X are used for whole calendar items copy/paste/cut, not for text when editing event details inline, either in a day/week view or in a list view. By tracking the is-editing property of respective cell editor and using it when enabling/disabling clipboard actions makes the respective text operations work as expected. --- e-util/e-table-click-to-add.c | 46 ++++++++++++++++++++++++++++++- e-util/e-table-click-to-add.h | 1 + e-util/e-table-group-container.c | 29 +++++++++++++++++++- e-util/e-table-group-container.h | 2 ++ e-util/e-table-group-leaf.c | 35 +++++++++++++++++++++++- e-util/e-table-group-leaf.h | 2 ++ e-util/e-table-group.c | 59 ++++++++++++++++++++++++++++++++++++++++ e-util/e-table-group.h | 2 ++ e-util/e-table-item.c | 32 ++++++++++++++++++++++ e-util/e-table-item.h | 2 ++ e-util/e-table.c | 57 +++++++++++++++++++++++++++++++++++++- e-util/e-table.h | 1 + e-util/e-tree.c | 36 ++++++++++++++++++++++++ e-util/e-tree.h | 2 ++ 14 files changed, 302 insertions(+), 4 deletions(-) (limited to 'e-util') diff --git a/e-util/e-table-click-to-add.c b/e-util/e-table-click-to-add.c index 6de00f913b..f44b4a2235 100644 --- a/e-util/e-table-click-to-add.c +++ b/e-util/e-table-click-to-add.c @@ -59,7 +59,8 @@ enum { PROP_MODEL, PROP_MESSAGE, PROP_WIDTH, - PROP_HEIGHT + PROP_HEIGHT, + PROP_IS_EDITING }; static void @@ -310,6 +311,9 @@ etcta_get_property (GObject *object, case PROP_HEIGHT: g_value_set_double (value, etcta->height); break; + case PROP_IS_EDITING: + g_value_set_boolean (value, e_table_click_to_add_is_editing (etcta)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -366,6 +370,16 @@ set_initial_selection (ETableClickToAdd *etcta) 0); } +static void +table_click_to_add_row_is_editing_changed_cb (ETableItem *item, + GParamSpec *param, + ETableClickToAdd *etcta) +{ + g_return_if_fail (E_IS_TABLE_CLICK_TO_ADD (etcta)); + + g_object_notify (G_OBJECT (etcta), "is-editing"); +} + static void finish_editing (ETableClickToAdd *etcta) { @@ -400,7 +414,13 @@ finish_editing (ETableClickToAdd *etcta) etcta->row, "key_press", G_CALLBACK (item_key_press), etcta); + g_signal_connect ( + etcta->row, "notify::is-editing", + G_CALLBACK (table_click_to_add_row_is_editing_changed_cb), etcta); + set_initial_selection (etcta); + + g_object_notify (G_OBJECT (etcta), "is-editing"); } } @@ -451,9 +471,15 @@ etcta_event (GnomeCanvasItem *item, etcta->row, "key_press", G_CALLBACK (item_key_press), etcta); + g_signal_connect ( + etcta->row, "notify::is-editing", + G_CALLBACK (table_click_to_add_row_is_editing_changed_cb), etcta); + e_canvas_item_grab_focus (GNOME_CANVAS_ITEM (etcta->row), TRUE); set_initial_selection (etcta); + + g_object_notify (G_OBJECT (etcta), "is-editing"); } break; @@ -587,6 +613,16 @@ etcta_class_init (ETableClickToAddClass *class) G_PARAM_READABLE | G_PARAM_LAX_VALIDATION)); + g_object_class_install_property ( + object_class, + PROP_IS_EDITING, + g_param_spec_boolean ( + "is-editing", + "Whether is in an editing mode", + "Whether is in an editing mode", + FALSE, + G_PARAM_READABLE)); + etcta_signals[CURSOR_CHANGE] = g_signal_new ( "cursor_change", G_OBJECT_CLASS_TYPE (object_class), @@ -664,3 +700,11 @@ e_table_click_to_add_commit (ETableClickToAdd *etcta) create_rect_and_text (etcta); e_canvas_item_move_absolute (etcta->text, 3, 3); } + +gboolean +e_table_click_to_add_is_editing (ETableClickToAdd *etcta) +{ + g_return_val_if_fail (E_IS_TABLE_CLICK_TO_ADD (etcta), FALSE); + + return etcta->row && e_table_item_is_editing (E_TABLE_ITEM (etcta->row)); +} diff --git a/e-util/e-table-click-to-add.h b/e-util/e-table-click-to-add.h index cd1519b82e..7c0c400f35 100644 --- a/e-util/e-table-click-to-add.h +++ b/e-util/e-table-click-to-add.h @@ -93,6 +93,7 @@ struct _ETableClickToAddClass { GType e_table_click_to_add_get_type (void) G_GNUC_CONST; void e_table_click_to_add_commit (ETableClickToAdd *etcta); +gboolean e_table_click_to_add_is_editing (ETableClickToAdd *etcta); G_END_DECLS diff --git a/e-util/e-table-group-container.c b/e-util/e-table-group-container.c index 5741cd1093..f338c50b11 100644 --- a/e-util/e-table-group-container.c +++ b/e-util/e-table-group-container.c @@ -59,7 +59,8 @@ enum { PROP_CURSOR_MODE, PROP_SELECTION_MODEL, PROP_LENGTH_THRESHOLD, - PROP_UNIFORM_ROW_HEIGHT + PROP_UNIFORM_ROW_HEIGHT, + PROP_IS_EDITING }; static EPrintable * @@ -991,6 +992,9 @@ etgc_get_property (GObject *object, case PROP_UNIFORM_ROW_HEIGHT: g_value_set_boolean (value, etgc->uniform_row_height); break; + case PROP_IS_EDITING: + g_value_set_boolean (value, e_table_group_container_is_editing (etgc)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -1147,6 +1151,11 @@ etgc_class_init (ETableGroupContainerClass *class) "Minimum Width", 0.0, G_MAXDOUBLE, 0.0, G_PARAM_READWRITE)); + + g_object_class_override_property ( + object_class, + PROP_IS_EDITING, + "is-editing"); } static void @@ -1665,3 +1674,21 @@ etgc_get_printable (ETableGroup *etg) return printable; } + +gboolean +e_table_group_container_is_editing (ETableGroupContainer *etgc) +{ + GList *list; + + g_return_val_if_fail (E_IS_TABLE_GROUP_CONTAINER (etgc), FALSE); + + for (list = etgc->children; list; list = g_list_next (list)) { + ETableGroupContainerChildNode *child_node = (ETableGroupContainerChildNode *) list->data; + + if (e_table_group_is_editing (child_node->child)) { + return TRUE; + } + } + + return FALSE; +} diff --git a/e-util/e-table-group-container.h b/e-util/e-table-group-container.h index 2f1457d279..f06dc746aa 100644 --- a/e-util/e-table-group-container.h +++ b/e-util/e-table-group-container.h @@ -133,6 +133,8 @@ void e_table_group_container_construct ETableSortInfo *sort_info, gint n); +gboolean e_table_group_container_is_editing (ETableGroupContainer *etgc); + G_END_DECLS #endif /* _E_TABLE_GROUP_CONTAINER_H_ */ diff --git a/e-util/e-table-group-leaf.c b/e-util/e-table-group-leaf.c index 8d1a91da69..3f50d00f64 100644 --- a/e-util/e-table-group-leaf.c +++ b/e-util/e-table-group-leaf.c @@ -54,9 +54,20 @@ enum { PROP_CURSOR_MODE, PROP_LENGTH_THRESHOLD, PROP_SELECTION_MODEL, - PROP_UNIFORM_ROW_HEIGHT + PROP_UNIFORM_ROW_HEIGHT, + PROP_IS_EDITING }; +static void +etgl_item_is_editing_changed_cb (ETableItem *item, + GParamSpec *param, + ETableGroupLeaf *etgl) +{ + g_return_if_fail (E_IS_TABLE_GROUP_LEAF (etgl)); + + g_object_notify (G_OBJECT (etgl), "is-editing"); +} + static void etgl_dispose (GObject *object) { @@ -97,6 +108,9 @@ etgl_dispose (GObject *object) etgl->item, etgl->etgl_start_drag_id); + g_signal_handlers_disconnect_by_func (etgl->item, + etgl_item_is_editing_changed_cb, etgl); + etgl->etgl_cursor_change_id = 0; etgl->etgl_cursor_activated_id = 0; etgl->etgl_double_click_id = 0; @@ -331,6 +345,9 @@ etgl_realize (GnomeCanvasItem *item) etgl->item, "start_drag", G_CALLBACK (etgl_start_drag), etgl); + g_signal_connect (etgl->item, "notify::is-editing", + G_CALLBACK (etgl_item_is_editing_changed_cb), etgl); + e_canvas_item_request_reflow (item); } @@ -627,6 +644,10 @@ etgl_get_property (GObject *object, break; case PROP_UNIFORM_ROW_HEIGHT: g_value_set_boolean (value, etgl->uniform_row_height); + break; + case PROP_IS_EDITING: + g_value_set_boolean (value, e_table_group_leaf_is_editing (etgl)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -781,6 +802,11 @@ etgl_class_init (ETableGroupLeafClass *class) "Uniform row height", FALSE, G_PARAM_READWRITE)); + + g_object_class_override_property ( + object_class, + PROP_IS_EDITING, + "is-editing"); } static void @@ -814,3 +840,10 @@ etgl_init (ETableGroupLeaf *etgl) e_canvas_item_set_reflow_callback (GNOME_CANVAS_ITEM (etgl), etgl_reflow); } +gboolean +e_table_group_leaf_is_editing (ETableGroupLeaf *etgl) +{ + g_return_val_if_fail (E_IS_TABLE_GROUP_LEAF (etgl), FALSE); + + return etgl->item && e_table_item_is_editing (etgl->item); +} diff --git a/e-util/e-table-group-leaf.h b/e-util/e-table-group-leaf.h index 93aa2bf2da..60f0b7fb90 100644 --- a/e-util/e-table-group-leaf.h +++ b/e-util/e-table-group-leaf.h @@ -104,6 +104,8 @@ ETableGroup * e_table_group_leaf_new (GnomeCanvasGroup *parent, ETableModel *model, ETableSortInfo *sort_info); +gboolean e_table_group_leaf_is_editing (ETableGroupLeaf *etgl); + G_END_DECLS #endif /* _E_TABLE_GROUP_LEAF_H_ */ diff --git a/e-util/e-table-group.c b/e-util/e-table-group.c index b5671d90f8..80f89af5e8 100644 --- a/e-util/e-table-group.c +++ b/e-util/e-table-group.c @@ -49,6 +49,11 @@ enum { LAST_SIGNAL }; +enum { + PROP_0, + PROP_IS_EDITING +}; + static guint etg_signals[LAST_SIGNAL] = { 0, }; static gboolean etg_get_focus (ETableGroup *table_group); @@ -77,6 +82,24 @@ etg_dispose (GObject *object) G_OBJECT_CLASS (etg_parent_class)->dispose (object); } +static void +etg_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + ETableGroup *etg = E_TABLE_GROUP (object); + + switch (property_id) { + case PROP_IS_EDITING: + g_value_set_boolean (value, e_table_group_is_editing (etg)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + /** * e_table_group_new * @parent: The %GnomeCanvasGroup to create a child of. @@ -639,6 +662,7 @@ etg_class_init (ETableGroupClass *class) GObjectClass *object_class = G_OBJECT_CLASS (class); object_class->dispose = etg_dispose; + object_class->get_property = etg_get_property; item_class->event = etg_event; @@ -664,6 +688,16 @@ etg_class_init (ETableGroupClass *class) class->get_mouse_over = NULL; class->get_cell_geometry = NULL; + g_object_class_install_property ( + object_class, + PROP_IS_EDITING, + g_param_spec_boolean ( + "is-editing", + "Whether is in an editing mode", + "Whether is in an editing mode", + FALSE, + G_PARAM_READABLE)); + etg_signals[CURSOR_CHANGE] = g_signal_new ( "cursor_change", G_OBJECT_CLASS_TYPE (object_class), @@ -750,3 +784,28 @@ etg_init (ETableGroup *table_group) { /* nothing to do */ } + +gboolean +e_table_group_is_editing (ETableGroup *table_group) +{ + static gboolean in = FALSE; + gboolean is_editing = FALSE; + + g_return_val_if_fail (E_IS_TABLE_GROUP (table_group), FALSE); + + /* this should be called from the main thread only, + and each descendant overrides the property, + thus might cause no call recursion */ + if (in) { + g_warn_if_reached (); + return FALSE; + } + + in = TRUE; + + g_object_get (G_OBJECT (table_group), "is-editing", &is_editing, NULL); + + in = FALSE; + + return is_editing; +} diff --git a/e-util/e-table-group.h b/e-util/e-table-group.h index 985450074b..a1f0acbfba 100644 --- a/e-util/e-table-group.h +++ b/e-util/e-table-group.h @@ -237,6 +237,8 @@ void e_table_group_apply_to_leafs (ETableGroup *table_group, ETableGroupLeafFn fn, gpointer closure); +gboolean e_table_group_is_editing (ETableGroup *table_group); + G_END_DECLS #endif /* _E_TABLE_GROUP_H_ */ diff --git a/e-util/e-table-item.c b/e-util/e-table-item.c index de749ead68..ad6c0890f4 100644 --- a/e-util/e-table-item.c +++ b/e-util/e-table-item.c @@ -99,6 +99,7 @@ enum { PROP_LENGTH_THRESHOLD, PROP_CURSOR_ROW, PROP_UNIFORM_ROW_HEIGHT, + PROP_IS_EDITING, PROP_MINIMUM_WIDTH, PROP_WIDTH, @@ -1697,6 +1698,9 @@ eti_get_property (GObject *object, case PROP_UNIFORM_ROW_HEIGHT: g_value_set_boolean (value, eti->uniform_row_height); break; + case PROP_IS_EDITING: + g_value_set_boolean (value, e_table_item_is_editing (eti)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -3273,6 +3277,16 @@ eti_class_init (ETableItemClass *class) FALSE, G_PARAM_READWRITE)); + g_object_class_install_property ( + object_class, + PROP_IS_EDITING, + g_param_spec_boolean ( + "is-editing", + "Whether is in an editing mode", + "Whether is in an editing mode", + FALSE, + G_PARAM_READABLE)); + eti_signals[CURSOR_CHANGE] = g_signal_new ( "cursor_change", G_OBJECT_CLASS_TYPE (object_class), @@ -3582,6 +3596,8 @@ e_table_item_enter_edit (ETableItem *eti, eti->editing_row = row; eti->edit_ctx = e_cell_enter_edit (eti->cell_views[col], view_to_model_col (eti, col), col, row); + + g_object_notify (G_OBJECT (eti), "is-editing"); } /** @@ -3616,6 +3632,8 @@ e_table_item_leave_edit (ETableItem *eti) eti->cell_views[col], view_to_model_col (eti, col), col, row, edit_ctx); + + g_object_notify (G_OBJECT (eti), "is-editing"); } /** @@ -4039,3 +4057,17 @@ e_table_item_get_printable (ETableItem *item) return printable; } + +/** + * e_table_item_is_editing: + * @eti: an %ETableItem + * + * Returns: Whether the table item is currently editing cell content. + **/ +gboolean +e_table_item_is_editing (ETableItem *eti) +{ + g_return_val_if_fail (E_IS_TABLE_ITEM (eti), FALSE); + + return eti_editing (eti); +} diff --git a/e-util/e-table-item.h b/e-util/e-table-item.h index 656c46b0a7..01e6a227dd 100644 --- a/e-util/e-table-item.h +++ b/e-util/e-table-item.h @@ -256,6 +256,8 @@ gint e_table_item_row_diff (ETableItem *eti, gint start_row, gint end_row); +gboolean e_table_item_is_editing (ETableItem *eti); + G_END_DECLS #endif /* _E_TABLE_ITEM_H_ */ diff --git a/e-util/e-table.c b/e-util/e-table.c index 6d7ebbbcf3..b380419390 100644 --- a/e-util/e-table.c +++ b/e-util/e-table.c @@ -105,7 +105,8 @@ enum { PROP_HADJUSTMENT, PROP_VADJUSTMENT, PROP_HSCROLL_POLICY, - PROP_VSCROLL_POLICY + PROP_VSCROLL_POLICY, + PROP_IS_EDITING }; enum { @@ -1066,6 +1067,16 @@ et_table_rows_deleted (ETableModel *table_model, } } +static void +group_is_editing_changed_cb (ETableClickToAdd *etcta, + GParamSpec *param, + ETable *table) +{ + g_return_if_fail (E_IS_TABLE (table)); + + g_object_notify (G_OBJECT (table), "is-editing"); +} + static void et_build_groups (ETable *et) { @@ -1123,6 +1134,9 @@ et_build_groups (ETable *et) g_signal_connect ( et->group, "start_drag", G_CALLBACK (group_start_drag), et); + g_signal_connect ( + et->group, "notify::is-editing", + G_CALLBACK (group_is_editing_changed_cb), et); if (!(et->is_grouped) && was_grouped) et_disconnect_model (et); @@ -1352,6 +1366,16 @@ canvas_vbox_event (ECanvasVbox *vbox, return TRUE; } +static void +click_to_add_is_editing_changed_cb (ETableClickToAdd *etcta, + GParamSpec *param, + ETable *table) +{ + g_return_if_fail (E_IS_TABLE (table)); + + g_object_notify (G_OBJECT (table), "is-editing"); +} + static gboolean click_to_add_event (ETableClickToAdd *etcta, GdkEventKey *key, @@ -1492,6 +1516,9 @@ e_table_setup_table (ETable *e_table, g_signal_connect ( e_table->click_to_add, "cursor_change", G_CALLBACK (click_to_add_cursor_change), e_table); + g_signal_connect ( + e_table->click_to_add, "notify::is-editing", + G_CALLBACK (click_to_add_is_editing_changed_cb), e_table); } } @@ -2268,6 +2295,9 @@ et_get_property (GObject *object, else g_value_set_enum (value, 0); break; + case PROP_IS_EDITING: + g_value_set_boolean (value, e_table_is_editing (etable)); + break; default: break; } @@ -2339,10 +2369,16 @@ et_set_property (GObject *object, E_CANVAS_VBOX (etable->canvas_vbox), etable->click_to_add); + g_signal_connect ( + etable->click_to_add, "event", + G_CALLBACK (click_to_add_event), etable); g_signal_connect ( etable->click_to_add, "cursor_change", G_CALLBACK (click_to_add_cursor_change), etable); + g_signal_connect ( + etable->click_to_add, "notify::is-editing", + G_CALLBACK (click_to_add_is_editing_changed_cb), etable); } else { g_object_run_dispose (G_OBJECT (etable->click_to_add)); etable->click_to_add = NULL; @@ -3576,6 +3612,16 @@ e_table_class_init (ETableClass *class) E_TYPE_TABLE_MODEL, G_PARAM_READABLE)); + g_object_class_install_property ( + object_class, + PROP_IS_EDITING, + g_param_spec_boolean ( + "is-editing", + "Whether is in an editing mode", + "Whether is in an editing mode", + FALSE, + G_PARAM_READABLE)); + gtk_widget_class_install_style_property ( widget_class, g_param_spec_int ( @@ -3624,3 +3670,12 @@ e_table_thaw_state_change (ETable *table) e_table_state_change (table); } } + +gboolean +e_table_is_editing (ETable *table) +{ + g_return_val_if_fail (E_IS_TABLE (table), FALSE); + + return (table->click_to_add && e_table_click_to_add_is_editing (E_TABLE_CLICK_TO_ADD (table->click_to_add))) || + (table->group && e_table_group_is_editing (table->group)); +} diff --git a/e-util/e-table.h b/e-util/e-table.h index f3b36d0a5e..4ae15cd6e1 100644 --- a/e-util/e-table.h +++ b/e-util/e-table.h @@ -396,6 +396,7 @@ void e_table_commit_click_to_add (ETable *table); void e_table_freeze_state_change (ETable *table); void e_table_thaw_state_change (ETable *table); +gboolean e_table_is_editing (ETable *table); G_END_DECLS diff --git a/e-util/e-tree.c b/e-util/e-tree.c index 5a6b52452e..56b807f2d6 100644 --- a/e-util/e-tree.c +++ b/e-util/e-tree.c @@ -97,6 +97,7 @@ enum { PROP_DRAW_FOCUS, PROP_ETTA, PROP_UNIFORM_ROW_HEIGHT, + PROP_IS_EDITING, PROP_ALWAYS_SEARCH, PROP_HADJUSTMENT, PROP_VADJUSTMENT, @@ -259,6 +260,16 @@ static void context_destroyed (gpointer data, GObject *ctx); G_DEFINE_TYPE_WITH_CODE (ETree, e_tree, GTK_TYPE_TABLE, G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL)) +static void +tree_item_is_editing_changed_cb (ETableItem *item, + GParamSpec *param, + ETree *tree) +{ + g_return_if_fail (E_IS_TREE (tree)); + + g_object_notify (G_OBJECT (tree), "is-editing"); +} + static void et_disconnect_from_etta (ETree *et) { @@ -1137,6 +1148,9 @@ et_build_item (ETree *et) g_signal_connect ( et->priv->item, "start_drag", G_CALLBACK (item_start_drag), et); + g_signal_connect ( + et->priv->item, "notify::is-editing", + G_CALLBACK (tree_item_is_editing_changed_cb), et); } static void @@ -1997,6 +2011,10 @@ et_get_property (GObject *object, g_value_set_boolean (value, etree->priv->uniform_row_height); break; + case PROP_IS_EDITING: + g_value_set_boolean (value, e_tree_is_editing (etree)); + break; + case PROP_ALWAYS_SEARCH: g_value_set_boolean (value, etree->priv->always_search); break; @@ -3760,6 +3778,16 @@ e_tree_class_init (ETreeClass *class) FALSE, G_PARAM_READWRITE)); + g_object_class_install_property ( + object_class, + PROP_IS_EDITING, + g_param_spec_boolean ( + "is-editing", + "Whether is in an editing mode", + "Whether is in an editing mode", + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property ( object_class, PROP_ALWAYS_SEARCH, @@ -3902,3 +3930,11 @@ e_tree_thaw_state_change (ETree *tree) e_tree_state_change (tree); } } + +gboolean +e_tree_is_editing (ETree *tree) +{ + g_return_val_if_fail (E_IS_TREE (tree), FALSE); + + return tree->priv->item && e_table_item_is_editing (E_TABLE_ITEM (tree->priv->item)); +} diff --git a/e-util/e-tree.h b/e-util/e-tree.h index 0fbdd67d17..8ccf083ffe 100644 --- a/e-util/e-tree.h +++ b/e-util/e-tree.h @@ -361,6 +361,8 @@ void e_tree_set_info_message (ETree *tree, void e_tree_freeze_state_change (ETree *table); void e_tree_thaw_state_change (ETree *table); +gboolean e_tree_is_editing (ETree *tree); + G_END_DECLS #endif /* _E_TREE_H_ */ -- cgit v1.2.3