From: knutux Date: Fri, 31 Mar 2006 11:50:44 +0000 (+0000) Subject: patch #1450307 - option for select all to work in layer with it's sub-layers: X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=de85b07c6395bae59577144d3fb48a8f60975edb;p=inkscape.git patch #1450307 - option for select all to work in layer with it's sub-layers: * Replaced check-box in preferences with 3 radio buttons (in all document in current layer only, in current layer with sub-layers) * Altered "Select all" functionality to include objects in sub-layers (if preference is on) * Altered TAB functionality to include sub-layers (had to introduce "context layer" concept in Selection class - without it TAB'ing would end in deepest child, but it needs to return to parent on subsequent TAB key press) --- diff --git a/ChangeLog b/ChangeLog index 88edb807b..e8bd87cfd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2006-03-29 Andrius R. + + * src/layer-fns.h, src/dialogs/layer-properties.cpp, + src/dialogs/layer-properties.h, src/layer-fns.cpp: + + patch #1450307 - option for select all to work in layer with it's sub-layers + 2006-03-29 Andrius R. * po/lt.po: Translated and added new language - Lithuanian. diff --git a/src/enums.h b/src/enums.h index fb8a30c50..4d3c75c20 100644 --- a/src/enums.h +++ b/src/enums.h @@ -73,5 +73,13 @@ enum { SP_CLONE_ORPHANS_ASKME }; +/* "inlayer" preference values */ + +enum PrefsSelectionContext { + PREFS_SELECTION_ALL = 0, + PREFS_SELECTION_LAYER = 1, + PREFS_SELECTION_LAYER_RECURSIVE = 2, +}; + #endif diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 4da9b33b8..d4bc26c5d 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -330,7 +330,7 @@ void sp_edit_select_all_full (bool force_all_layers, bool invert) g_return_if_fail(SP_IS_GROUP(dt->currentLayer())); - bool inlayer = prefs_get_int_attribute ("options.kbselection", "inlayer", 1); + PrefsSelectionContext inlayer = (PrefsSelectionContext)prefs_get_int_attribute ("options.kbselection", "inlayer", PREFS_SELECTION_LAYER); bool onlyvisible = prefs_get_int_attribute ("options.kbselection", "onlyvisible", 1); bool onlysensitive = prefs_get_int_attribute ("options.kbselection", "onlysensitive", 1); @@ -341,8 +341,11 @@ void sp_edit_select_all_full (bool force_all_layers, bool invert) exclude = selection->itemList(); } - if (inlayer && !force_all_layers) { + if (force_all_layers) + inlayer = PREFS_SELECTION_ALL; + switch (inlayer) { + case PREFS_SELECTION_LAYER: { if ( (onlysensitive && SP_ITEM(dt->currentLayer())->isLocked()) || (onlyvisible && dt->itemIsHidden(SP_ITEM(dt->currentLayer()))) ) return; @@ -364,9 +367,16 @@ void sp_edit_select_all_full (bool force_all_layers, bool invert) } g_slist_free (all_items); - - } else { + break; + } + case PREFS_SELECTION_LAYER_RECURSIVE: { + items = get_all_items (NULL, dt->currentLayer(), dt, onlyvisible, onlysensitive, exclude); + break; + } + default: { items = get_all_items (NULL, dt->currentRoot(), dt, onlyvisible, onlysensitive, exclude); + break; + } } selection->setList (items); @@ -1656,11 +1666,11 @@ namespace { template SPItem *next_item(SPDesktop *desktop, GSList *path, SPObject *root, - bool only_in_viewport, bool inlayer, bool onlyvisible, bool onlysensitive); + bool only_in_viewport, PrefsSelectionContext inlayer, bool onlyvisible, bool onlysensitive); template SPItem *next_item_from_list(SPDesktop *desktop, GSList const *items, SPObject *root, - bool only_in_viewport, bool inlayer, bool onlyvisible, bool onlysensitive); + bool only_in_viewport, PrefsSelectionContext inlayer, bool onlyvisible, bool onlysensitive); struct Forward { typedef SPObject *Iterator; @@ -1711,13 +1721,13 @@ sp_selection_item_next(void) g_return_if_fail(desktop != NULL); Inkscape::Selection *selection = SP_DT_SELECTION(desktop); - bool inlayer = prefs_get_int_attribute ("options.kbselection", "inlayer", 1); + PrefsSelectionContext inlayer = (PrefsSelectionContext)prefs_get_int_attribute ("options.kbselection", "inlayer", PREFS_SELECTION_LAYER); bool onlyvisible = prefs_get_int_attribute ("options.kbselection", "onlyvisible", 1); bool onlysensitive = prefs_get_int_attribute ("options.kbselection", "onlysensitive", 1); SPObject *root; - if (inlayer) { - root = desktop->currentLayer(); + if (PREFS_SELECTION_ALL != inlayer) { + root = selection->activeContext(); } else { root = desktop->currentRoot(); } @@ -1725,7 +1735,7 @@ sp_selection_item_next(void) SPItem *item=next_item_from_list(desktop, selection->itemList(), root, SP_CYCLING == SP_CYCLE_VISIBLE, inlayer, onlyvisible, onlysensitive); if (item) { - selection->set(item); + selection->set(item, PREFS_SELECTION_LAYER_RECURSIVE == inlayer); if ( SP_CYCLING == SP_CYCLE_FOCUS ) { scroll_to_show_item(desktop, item); } @@ -1741,13 +1751,13 @@ sp_selection_item_prev(void) g_return_if_fail(desktop != NULL); Inkscape::Selection *selection = SP_DT_SELECTION(desktop); - bool inlayer = prefs_get_int_attribute ("options.kbselection", "inlayer", 1); + PrefsSelectionContext inlayer = (PrefsSelectionContext)prefs_get_int_attribute ("options.kbselection", "inlayer", PREFS_SELECTION_LAYER); bool onlyvisible = prefs_get_int_attribute ("options.kbselection", "onlyvisible", 1); bool onlysensitive = prefs_get_int_attribute ("options.kbselection", "onlysensitive", 1); SPObject *root; - if (inlayer) { - root = desktop->currentLayer(); + if (PREFS_SELECTION_ALL != inlayer) { + root = selection->activeContext(); } else { root = desktop->currentRoot(); } @@ -1755,7 +1765,7 @@ sp_selection_item_prev(void) SPItem *item=next_item_from_list(desktop, selection->itemList(), root, SP_CYCLING == SP_CYCLE_VISIBLE, inlayer, onlyvisible, onlysensitive); if (item) { - selection->set(item); + selection->set(item, PREFS_SELECTION_LAYER_RECURSIVE == inlayer); if ( SP_CYCLING == SP_CYCLE_FOCUS ) { scroll_to_show_item(desktop, item); } @@ -1766,7 +1776,7 @@ namespace { template SPItem *next_item_from_list(SPDesktop *desktop, GSList const *items, - SPObject *root, bool only_in_viewport, bool inlayer, bool onlyvisible, bool onlysensitive) + SPObject *root, bool only_in_viewport, PrefsSelectionContext inlayer, bool onlyvisible, bool onlysensitive) { SPObject *current=root; while (items) { @@ -1800,7 +1810,7 @@ SPItem *next_item_from_list(SPDesktop *desktop, GSList const *items, template SPItem *next_item(SPDesktop *desktop, GSList *path, SPObject *root, - bool only_in_viewport, bool inlayer, bool onlyvisible, bool onlysensitive) + bool only_in_viewport, PrefsSelectionContext inlayer, bool onlyvisible, bool onlysensitive) { typename D::Iterator children; typename D::Iterator iter; @@ -1821,7 +1831,7 @@ SPItem *next_item(SPDesktop *desktop, GSList *path, SPObject *root, while ( iter && !found ) { SPObject *object=D::object(iter); if (desktop->isLayer(object)) { - if (!inlayer) { // recurse into sublayers + if (PREFS_SELECTION_LAYER != inlayer) { // recurse into sublayers found = next_item(desktop, NULL, object, only_in_viewport, inlayer, onlyvisible, onlysensitive); } } else if ( SP_IS_ITEM(object) && diff --git a/src/selection.cpp b/src/selection.cpp index 473a7202e..0b17eefe9 100644 --- a/src/selection.cpp +++ b/src/selection.cpp @@ -5,7 +5,9 @@ * Lauris Kaplinski * MenTaLguY * bulia byak + * Andrius R. * + * Copyright (C) 2006 Andrius R. * Copyright (C) 2004-2005 MenTaLguY * Copyright (C) 1999-2002 Lauris Kaplinski * Copyright (C) 2001-2002 Ximian, Inc. @@ -36,6 +38,8 @@ Selection::Selection(SPDesktop *desktop) : _reprs(NULL), _items(NULL), _desktop(desktop), + _selection_context(NULL), + _context_release_handler_id(0), _flags(0), _idle(0) { @@ -89,11 +93,40 @@ void Selection::_emitModified(guint flags) { _modified_signal.emit(this, flags); } -void Selection::_emitChanged() { +void Selection::_emitChanged(bool persist_selection_context/* = false */) { + if (persist_selection_context) { + if (NULL == _selection_context) { + _selection_context = desktop()->currentLayer(); + sp_object_ref(_selection_context, NULL); + g_signal_connect(G_OBJECT(_selection_context), "release", + G_CALLBACK(&Selection::_releaseSelectionContext), this); + } + } else { + _releaseContext(_selection_context); + } + inkscape_selection_changed(this); _changed_signal.emit(this); } +void +Selection::_releaseSelectionContext(SPObject *obj, Selection *selection) +{ + selection->_releaseContext(obj); +} + +void +Selection::_releaseContext(SPObject *obj) +{ + if (NULL == _selection_context || _selection_context != obj) + return; + + g_signal_handler_disconnect(G_OBJECT(_selection_context), _context_release_handler_id); + sp_object_unref(_selection_context, NULL); + _context_release_handler_id = 0; + _selection_context = NULL; +} + void Selection::_invalidateCachedLists() { g_slist_free(_items); _items = NULL; @@ -111,6 +144,12 @@ void Selection::_clear() { } } +SPObject *Selection::activeContext() { + if (NULL != _selection_context) + return _selection_context; + return desktop()->currentLayer(); + } + bool Selection::includes(SPObject *obj) const { if (obj == NULL) return FALSE; @@ -120,7 +159,7 @@ bool Selection::includes(SPObject *obj) const { return ( g_slist_find(_objs, obj) != NULL ); } -void Selection::add(SPObject *obj) { +void Selection::add(SPObject *obj, bool persist_selection_context/* = false */) { g_return_if_fail(obj != NULL); g_return_if_fail(SP_IS_OBJECT(obj)); @@ -130,7 +169,7 @@ void Selection::add(SPObject *obj) { _invalidateCachedLists(); _add(obj); - _emitChanged(); + _emitChanged(persist_selection_context); } void Selection::_add(SPObject *obj) { @@ -152,9 +191,9 @@ void Selection::_add(SPObject *obj) { */ } -void Selection::set(SPObject *object) { +void Selection::set(SPObject *object, bool persist_selection_context) { _clear(); - add(object); + add(object, persist_selection_context); } void Selection::toggle(SPObject *obj) { diff --git a/src/selection.h b/src/selection.h index 6d403c426..c78a1fdbb 100644 --- a/src/selection.h +++ b/src/selection.h @@ -76,12 +76,19 @@ public: */ SPDesktop *desktop() { return _desktop; } + /** + * @brief Returns active layer for selection (currentLayer or its parent) + * + * @return layer item the selection is bound to + */ + SPObject *activeContext(); + /** * @brief Add an SPObject to the set of selected objects * * @param obj the SPObject to add */ - void add(SPObject *obj); + void add(SPObject *obj, bool persist_selection_context = false); /** * @brief Add an XML node's SPObject to the set of selected objects @@ -95,7 +102,7 @@ public: * * @param obj the object to select */ - void set(SPObject *obj); + void set(SPObject *obj, bool persist_selection_context = false); /** * @brief Set the selection to an XML node's SPObject @@ -308,11 +315,13 @@ private: static void _schedule_modified(SPObject *obj, guint flags, Selection *selection); /** @brief Releases a selected object that is being removed */ static void _release(SPObject *obj, Selection *selection); + /** @brief Releases an active layer object that is being removed */ + static void _releaseSelectionContext(SPObject *obj, Selection *selection); /** @brief Issues modified selection signal */ void _emitModified(guint flags); /** @brief Issues changed selection signal */ - void _emitChanged(); + void _emitChanged(bool persist_selection_context = false); void _invalidateCachedLists(); @@ -328,12 +337,16 @@ private: void _remove(SPObject *obj); /** @brief returns the SPObject corresponding to an xml node (if any) */ SPObject *_objectForXMLNode(XML::Node *repr) const; + /** @brief Releases an active layer object that is being removed */ + void _releaseContext(SPObject *obj); mutable GSList *_objs; mutable GSList *_reprs; mutable GSList *_items; GC::soft_ptr _desktop; + SPObject* _selection_context; + gulong _context_release_handler_id; guint _flags; guint _idle; diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index b90ed8d98..a1e87b854 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -468,13 +468,19 @@ void InkscapePreferences::initPageTransforms() void InkscapePreferences::initPageSelecting() { - _sel_current.init ( _("Select only within current layer"), "options.kbselection", "inlayer", true); + _sel_all.init ( _("Select in all layers"), "options.kbselection", "inlayer", PREFS_SELECTION_ALL, false, 0); + _sel_current.init ( _("Select only within current layer"), "options.kbselection", "inlayer", PREFS_SELECTION_LAYER, true, &_sel_all); + _sel_recursive.init ( _("Select in current layer and sublayers"), "options.kbselection", "inlayer", PREFS_SELECTION_LAYER_RECURSIVE, false, &_sel_all); _sel_hidden.init ( _("Ignore hidden objects"), "options.kbselection", "onlyvisible", true); _sel_locked.init ( _("Ignore locked objects"), "options.kbselection", "onlysensitive", true); _page_select.add_group_header( _("Ctrl+A, Tab, Shift+Tab:")); + _page_select.add_line( true, "", _sel_all, "", + _("Make keyboard selection commands work on objects in all layers")); _page_select.add_line( true, "", _sel_current, "", - _("Uncheck this to make keyboard selection commands work on objects in all layers")); + _("Make keyboard selection commands work on objects in current layer only")); + _page_select.add_line( true, "", _sel_recursive, "", + _("Make keyboard selection commands work on objects in current layer and all its sublayers")); _page_select.add_line( true, "", _sel_hidden, "", _("Uncheck this to be able to select objects that are hidden (either by themselves or by being in a hidden group or layer)")); _page_select.add_line( true, "", _sel_locked, "", diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h index af3dfa44b..3702c88f3 100644 --- a/src/ui/dialog/inkscape-preferences.h +++ b/src/ui/dialog/inkscape-preferences.h @@ -120,7 +120,10 @@ protected: PrefCheckButton _trans_scale_stroke, _trans_scale_corner, _trans_gradient,_trans_pattern; PrefRadioButton _trans_optimized, _trans_preserved; - PrefCheckButton _sel_current, _sel_hidden, _sel_locked; + PrefRadioButton _sel_all; + PrefRadioButton _sel_current; + PrefRadioButton _sel_recursive; + PrefCheckButton _sel_hidden, _sel_locked; PrefSpinButton _misc_export, _misc_recent, _misc_simpl; PrefCheckButton _misc_imp_bitmap, _misc_comment, _misc_scripts;