Code

Use subdirectories with icon sizes.
[inkscape.git] / src / selection.h
1 #ifndef SEEN_INKSCAPE_SELECTION_H
2 #define SEEN_INKSCAPE_SELECTION_H
4 /** \file
5  * Inkscape::Selection: per-desktop selection container
6  *
7  * Authors:
8  *   Lauris Kaplinski <lauris@kaplinski.com>
9  *   MenTaLguY <mental@rydia.net>
10  *   bulia byak <buliabyak@users.sf.net>
11  *
12  * Copyright (C) 2004-2005 MenTaLguY
13  * Copyright (C) 1999-2002 Lauris Kaplinski
14  * Copyright (C) 2001-2002 Ximian, Inc.
15  *
16  * Released under GNU GPL, read the file 'COPYING' for more information
17  */
19 #include <vector>
20 #include <map>
21 #include <list>
22 #include <sigc++/sigc++.h>
24 //#include "libnr/nr-rect.h"
25 #include "libnr/nr-convex-hull.h"
26 #include "forward.h"
27 #include "gc-managed.h"
28 #include "gc-finalized.h"
29 #include "gc-anchored.h"
30 #include "gc-soft-ptr.h"
31 #include "util/list.h"
32 #include "sp-item.h"
33 #include "snapped-point.h"
35 class SPItem;
36 class SPBox3D;
37 class Persp3D;
39 namespace Inkscape {
40 namespace XML {
41 class Node;
42 }
43 }
45 namespace Inkscape {
47 /**
48  * @brief The set of selected SPObjects for a given desktop.
49  *
50  * This class represents the set of selected SPItems for a given
51  * SPDesktop.
52  *
53  * An SPObject and its parent cannot be simultaneously selected;
54  * selecting an SPObjects has the side-effect of unselecting any of
55  * its children which might have been selected.
56  *
57  * This is a per-desktop object that keeps the list of selected objects
58  * at the given desktop. Both SPItem and SPRepr lists can be retrieved
59  * from the selection. Many actions operate on the selection, so it is
60  * widely used throughout the code.
61  * It also implements its own asynchronous notification signals that
62  * UI elements can listen to.
63  */
64 class Selection : public Inkscape::GC::Managed<>,
65                   public Inkscape::GC::Finalized,
66                   public Inkscape::GC::Anchored
67 {
68 public:
69     /**
70      * Constructs an selection object, bound to a particular
71      * SPDesktop
72      *
73      * @param desktop the desktop in question
74      */
75     Selection(SPDesktop *desktop);
76     ~Selection();
78     /**
79      * @brief Returns the desktop the selection is bound to
80      *
81      * @return the desktop the selection is bound to
82      */
83     SPDesktop *desktop() { return _desktop; }
85     /**
86      * @brief Returns active layer for selection (currentLayer or its parent)
87      *
88      * @return layer item the selection is bound to
89      */
90     SPObject *activeContext();
92     /**
93      * @brief Add an SPObject to the set of selected objects
94      *
95      * @param obj the SPObject to add
96      */
97     void add(SPObject *obj, bool persist_selection_context = false);
99     /**
100      * @brief Add an XML node's SPObject to the set of selected objects
101      *
102      * @param the xml node of the item to add
103      */
104     void add(XML::Node *repr) { add(_objectForXMLNode(repr)); }
106     /**
107      * @brief Set the selection to a single specific object
108      *
109      * @param obj the object to select
110      */
111     void set(SPObject *obj, bool persist_selection_context = false);
113     /**
114      * @brief Set the selection to an XML node's SPObject
115      *
116      * @param repr the xml node of the item to select
117      */
118     void set(XML::Node *repr) { set(_objectForXMLNode(repr)); }
120     /**
121      * @brief Removes an item from the set of selected objects
122      *
123      * It is ok to call this method for an unselected item.
124      *
125      * @param item the item to unselect
126      */
127     void remove(SPObject *obj);
129     /**
130      * @brief Removes an item if selected, adds otherwise
131      *
132      * @param item the item to unselect
133      */
134     void toggle(SPObject *obj);
136     /**
137      * @brief Removes an item from the set of selected objects
138      *
139      * It is ok to call this method for an unselected item.
140      *
141      * @param repr the xml node of the item to remove
142      */
143     void remove(XML::Node *repr) { remove(_objectForXMLNode(repr)); }
145     /**
146      * @brief Selects exactly the specified objects
147      *
148      * @param objs the objects to select
149      */
150     void setList(GSList const *objs);
152     /**
153      * @brief Adds the specified objects to selection, without deselecting first
154      *
155      * @param objs the objects to select
156      */
157     void addList(GSList const *objs);
159     /**
160      * @brief Clears the selection and selects the specified objects
161      *
162      * @param repr a list of xml nodes for the items to select
163      */
164     void setReprList(GSList const *reprs);
166     /** \brief  Add items from an STL iterator range to the selection
167      *  \param  from the begin iterator
168      *  \param  to   the end iterator
169      */
170     template <typename InputIterator>
171     void add(InputIterator from, InputIterator to) {
172         _invalidateCachedLists();
173         while ( from != to ) {
174             _add(*from);
175             ++from;
176         }
177         _emitChanged();
178     }
180     /**
181      * @brief Unselects all selected objects.
182      */
183     void clear();
185     /**
186      * @brief Returns true if no items are selected
187      */
188     bool isEmpty() const { return _objs == NULL; }
190     /**
191      * @brief Returns true if the given object is selected
192      */
193     bool includes(SPObject *obj) const;
195     /**
196      * @brief Returns true if the given item is selected
197      */
198     bool includes(XML::Node *repr) const {
199         return includes(_objectForXMLNode(repr));
200     }
202     /**
203      * @brief Returns a single selected object
204      *
205      * @return NULL unless exactly one object is selected
206      */
207     SPObject *single();
209     /**
210      * @brief Returns a single selected item
211      *
212      * @return NULL unless exactly one object is selected
213      */
214     SPItem *singleItem();
216     /**
217      * @brief Returns a single selected object's xml node
218      *
219      * @return NULL unless exactly one object is selected
220      */
221     XML::Node *singleRepr();
223     /** @brief Returns the list of selected objects */
224     GSList const *list();
225     /** @brief Returns the list of selected SPItems */
226     GSList const *itemList();
227     /** @brief Returns a list of the xml nodes of all selected objects */
228     /// \todo only returns reprs of SPItems currently; need a separate
229     ///      method for that
230     GSList const *reprList();
232     /** @brief Returns a list of all perspectives which have a 3D box in the current selection
233        (these may also be nested in groups) */
234     std::list<Persp3D *> const perspList();
236     /** @brief Returns a list of all 3D boxes in the current selection which are associated to @c
237        persp. If @c pers is @c NULL, return all selected boxes.
238     */
239     std::list<SPBox3D *> const box3DList(Persp3D *persp = NULL);
241     /** @brief Returns the number of layers in which there are selected objects */
242     guint numberOfLayers();
244     /** @brief Returns the number of parents to which the selected objects belong */
245     guint numberOfParents();
247     /** @brief Returns the bounding rectangle of the selection */
248     NRRect *bounds(NRRect *dest, SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) const;
249     /** @brief Returns the bounding rectangle of the selection */
250     Geom::OptRect bounds(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) const;
252     /**
253      * @brief Returns the bounding rectangle of the selection
254      *
255      * Gives the coordinates in internal format, does not match onscreen guides.
256      * (0,0 is the upper left corner, not the lower left corner)
257      */
258     NRRect *boundsInDocument(NRRect *dest, SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) const;
260     /**
261      * @brief Returns the bounding rectangle of the selection
262      *
263      * Gives the coordinates in internal format, does not match onscreen guides.
264      * (0,0 is the upper left corner, not the lower left corner)
265      */
266     Geom::OptRect boundsInDocument(SPItem::BBoxType type = SPItem::APPROXIMATE_BBOX) const;
268     /**
269      * @brief Returns the rotation/skew center of the selection
270      */
271     boost::optional<Geom::Point> center() const;
273     /**
274      * @brief Gets the selection's snap points.
275      * @return Selection's snap points
276      */
277     std::vector<Inkscape::SnapCandidatePoint> getSnapPoints(SnapPreferences const *snapprefs) const;
279     /**
280      * @brief Gets the snap points of a selection that form a convex hull.
281      * @return Selection's convex hull points
282      */
283     std::vector<Inkscape::SnapCandidatePoint> getSnapPointsConvexHull(SnapPreferences const *snapprefs) const;
285     /**
286      * @brief Connects a slot to be notified of selection changes
287      *
288      * This method connects the given slot such that it will
289      * be called upon any change in the set of selected objects.
290      *
291      * @param slot the slot to connect
292      *
293      * @return the resulting connection
294      */
295     sigc::connection connectChanged(sigc::slot<void, Selection *> const &slot) {
296         return _changed_signal.connect(slot);
297     }
299     /**
300      * @brief Connects a slot to be notified of selected
301      *        object modifications
302      *
303      * This method connects the given slot such that it will
304      * receive notifications whenever any selected item is
305      * modified.
306      *
307      * @param slot the slot to connect
308      *
309      * @return the resulting connection
310      *
311      */
312     sigc::connection connectModified(sigc::slot<void, Selection *, guint> const &slot)
313     {
314         return _modified_signal.connect(slot);
315     }
317 private:
318     /** @brief no copy */
319     Selection(Selection const &);
320     /** @brief no assign */
321     void operator=(Selection const &);
323     /** @brief Issues modification notification signals */
324     static gboolean _emit_modified(Selection *selection);
325     /** @brief Schedules an item modification signal to be sent */
326     void _schedule_modified(SPObject *obj, guint flags);
328     /** @brief Issues modified selection signal */
329     void _emitModified(guint flags);
330     /** @brief Issues changed selection signal */
331     void _emitChanged(bool persist_selection_context = false);
333     void _invalidateCachedLists();
335     /** @brief unselect all descendants of the given item */
336     void _removeObjectDescendants(SPObject *obj);
337     /** @brief unselect all ancestors of the given item */
338     void _removeObjectAncestors(SPObject *obj);
339     /** @brief clears the selection (without issuing a notification) */
340     void _clear();
341     /** @brief adds an object (without issuing a notification) */
342     void _add(SPObject *obj);
343     /** @brief removes an object (without issuing a notification) */
344     void _remove(SPObject *obj);
345     /** @brief returns the SPObject corresponding to an xml node (if any) */
346     SPObject *_objectForXMLNode(XML::Node *repr) const;
347     /** @brief Releases an active layer object that is being removed */
348     void _releaseContext(SPObject *obj);
350     mutable GSList *_objs;
351     mutable GSList *_reprs;
352     mutable GSList *_items;
354     void add_box_perspective(SPBox3D *box);
355     void add_3D_boxes_recursively(SPObject *obj);
356     void remove_box_perspective(SPBox3D *box);
357     void remove_3D_boxes_recursively(SPObject *obj);
359     std::list<SPBox3D *> _3dboxes;
361     GC::soft_ptr<SPDesktop> _desktop;
362     SPObject* _selection_context;
363     guint _flags;
364     guint _idle;
366     std::map<SPObject *, sigc::connection> _modified_connections;
367     std::map<SPObject *, sigc::connection> _release_connections;
368     sigc::connection _context_release_connection;
370     sigc::signal<void, Selection *> _changed_signal;
371     sigc::signal<void, Selection *, guint> _modified_signal;
372 };
376 #endif
377 /*
378   Local Variables:
379   mode:c++
380   c-file-style:"stroustrup"
381   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
382   indent-tabs-mode:nil
383   fill-column:99
384   End:
385 */
386 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :