Code

Add ubuntu palette, closes 1510556.
[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 <sigc++/sigc++.h>
22 #include "libnr/nr-rect.h"
23 #include "libnr/nr-convex-hull.h"
24 #include "forward.h"
25 #include "gc-managed.h"
26 #include "gc-finalized.h"
27 #include "gc-anchored.h"
28 #include "gc-soft-ptr.h"
29 #include "util/list.h"
31 class SPItem;
33 namespace Inkscape {
34 namespace XML {
35 class Node;
36 }
37 }
39 namespace Inkscape {
41 /**
42  * @brief The set of selected SPObjects for a given desktop.
43  *
44  * This class represents the set of selected SPItems for a given
45  * SPDesktop.
46  *
47  * An SPObject and its parent cannot be simultaneously selected;
48  * selecting an SPObjects has the side-effect of unselecting any of
49  * its children which might have been selected.
50  *
51  * This is a per-desktop object that keeps the list of selected objects
52  * at the given desktop. Both SPItem and SPRepr lists can be retrieved
53  * from the selection. Many actions operate on the selection, so it is
54  * widely used throughout the code.
55  * It also implements its own asynchronous notification signals that 
56  * UI elements can listen to.
57  */
58 class Selection : public Inkscape::GC::Managed<>,
59                   public Inkscape::GC::Finalized,
60                   public Inkscape::GC::Anchored
61 {
62 public:
63     /**
64      * Constructs an selection object, bound to a particular
65      * SPDesktop
66      *
67      * @param desktop the desktop in question
68      */
69     Selection(SPDesktop *desktop);
70     ~Selection();
72     /**
73      * @brief Returns the desktop the seoection is bound to
74      *
75      * @return the desktop the selection is bound to
76      */
77     SPDesktop *desktop() { return _desktop; }
79     /**
80      * @brief Returns active layer for selection (currentLayer or its parent)
81      *
82      * @return layer item the selection is bound to
83      */
84     SPObject *activeContext();
86     /**
87      * @brief Add an SPObject to the set of selected objects
88      *
89      * @param obj the SPObject to add
90      */
91     void add(SPObject *obj, bool persist_selection_context = false);
93     /**
94      * @brief Add an XML node's SPObject to the set of selected objects
95      *
96      * @param the xml node of the item to add
97      */
98     void add(XML::Node *repr) { add(_objectForXMLNode(repr)); }
100     /**
101      * @brief Set the selection to a single specific object
102      *
103      * @param obj the object to select
104      */
105     void set(SPObject *obj, bool persist_selection_context = false);
107     /**
108      * @brief Set the selection to an XML node's SPObject
109      *
110      * @param repr the xml node of the item to select
111      */
112     void set(XML::Node *repr) { set(_objectForXMLNode(repr)); }
114     /**
115      * @brief Removes an item from the set of selected objects
116      *
117      * It is ok to call this method for an unselected item.
118      *
119      * @param item the item to unselect
120      */
121     void remove(SPObject *obj);
123     /**
124      * @brief Removes an item if selected, adds otherwise
125      *
126      * @param item the item to unselect
127      */
128     void toggle(SPObject *obj);
130     /**
131      * @brief Removes an item from the set of selected objects
132      *
133      * It is ok to call this method for an unselected item.
134      *
135      * @param repr the xml node of the item to remove
136      */
137     void remove(XML::Node *repr) { remove(_objectForXMLNode(repr)); }
139     /**
140      * @brief Selects exactly the specified objects
141      *
142      * @param objs the objects to select
143      */
144     void setList(GSList const *objs);
146     /**
147      * @brief Adds the specified objects to selection, without deselecting first
148      *
149      * @param objs the objects to select
150      */
151     void addList(GSList const *objs);
153     /**
154      * @brief Clears the selection and selects the specified objects
155      *
156      * @param repr a list of xml nodes for the items to select
157      */
158     void setReprList(GSList const *reprs);
160     /** \brief  Add items from an STL iterator range to the selection
161      *  \param  from the begin iterator
162      *  \param  to   the end iterator
163      */
164     template <typename InputIterator>
165     void add(InputIterator from, InputIterator to) {
166         _invalidateCachedLists();
167         while ( from != to ) {
168             _add(*from);
169             ++from;
170         }
171         _emitChanged();
172     }
174     /**
175      * @brief Unselects all selected objects.
176      */
177     void clear();
179     /**
180      * @brief Returns true if no items are selected
181      */
182     bool isEmpty() const { return _objs == NULL; }
184     /**
185      * @brief Returns true if the given object is selected
186      */
187     bool includes(SPObject *obj) const;
189     /**
190      * @brief Returns true if the given item is selected
191      */
192     bool includes(XML::Node *repr) const {
193         return includes(_objectForXMLNode(repr));
194     }
196     /**
197      * @brief Returns a single selected object
198      *
199      * @return NULL unless exactly one object is selected
200      */
201     SPObject *single();
203     /**
204      * @brief Returns a single selected item
205      *
206      * @return NULL unless exactly one object is selected
207      */
208     SPItem *singleItem();
210     /**
211      * @brief Returns a single selected object's xml node
212      *
213      * @return NULL unless exactly one object is selected
214      */
215     XML::Node *singleRepr();
217     /** @brief Returns the list of selected objects */
218     GSList const *list();
219     /** @brief Returns the list of selected SPItems */
220     GSList const *itemList();
221     /** @brief Returns a list of the xml nodes of all selected objects */
222     /// \todo only returns reprs of SPItems currently; need a separate
223     ///      method for that
224     GSList const *reprList();
226     /** @brief Returns the number of layers in which there are selected objects */
227     guint numberOfLayers();
229     /** @brief Returns the number of parents to which the selected objects belong */
230     guint numberOfParents();
232     /** @brief Returns the bounding rectangle of the selection */
233     NRRect *bounds(NRRect *dest) const;
234     /** @brief Returns the bounding rectangle of the selection */
235     ::NR::Rect bounds() const;
237     /**
238      * @brief Returns the bounding rectangle of the selection
239      *
240      * \todo how is this different from bounds()?
241      */ 
242     NRRect *boundsInDocument(NRRect *dest) const;
244     /**
245      * @brief Returns the bounding rectangle of the selection
246      *
247      * \todo how is this different from bounds()?
248      */
249     ::NR::Rect boundsInDocument() const;
251     /**
252      * @brief Returns the rotation/skew center of the selection
253      */
254     ::NR::Point center() const;
256     /**
257      * @brief Gets the selection's snap points.
258      * @return Selection's snap points
259      */
260     std::vector<NR::Point> getSnapPoints() const;
262     /**
263      * @brief Gets the snap points of a selection that form a convex hull.
264      * @return Selection's convex hull points
265      */
266     std::vector<NR::Point> getSnapPointsConvexHull() const;
268     /**
269      * @return A vector containing the top-left and bottom-right
270      * corners of each selected object's bounding box.
271      */
272     std::vector<NR::Point> getBBoxPoints() const;
274     /**
275      * @return A vector containing the 2 (top-left and bottom-right)
276      * corners of the selection bounding box.
277      */
278     std::vector<NR::Point> getBBoxPointsOuter() const;
280     /**
281      * @brief Connects a slot to be notified of selection changes
282      *
283      * This method connects the given slot such that it will
284      * be called upon any change in the set of selected objects.
285      *
286      * @param slot the slot to connect
287      *
288      * @return the resulting connection
289      */
290     sigc::connection connectChanged(sigc::slot<void, Selection *> const &slot) {
291         return _changed_signal.connect(slot);
292     }
294     /**
295      * @brief Connects a slot to be notified of selected 
296      *        object modifications 
297      *
298      * This method connects the given slot such that it will
299      * receive notifications whenever any selected item is
300      * modified.
301      *
302      * @param slot the slot to connect
303      *
304      * @return the resulting connection
305      *
306      */
307     sigc::connection connectModified(sigc::slot<void, Selection *, guint> const &slot)
308     {
309         return _modified_signal.connect(slot);
310     }
312 private:
313     /** @brief no copy */
314     Selection(Selection const &);
315     /** @brief no assign */
316     void operator=(Selection const &);
318     /** @brief Issues modification notification signals */
319     static gboolean _emit_modified(Selection *selection);
320     /** @brief Schedules an item modification signal to be sent */
321     static void _schedule_modified(SPObject *obj, guint flags, Selection *selection);
322     /** @brief Releases a selected object that is being removed */
323     static void _release(SPObject *obj, Selection *selection);
324     /** @brief Releases an active layer object that is being removed */
325     static void _releaseSelectionContext(SPObject *obj, Selection *selection);
327     /** @brief Issues modified selection signal */
328     void _emitModified(guint flags);
329     /** @brief Issues changed selection signal */
330     void _emitChanged(bool persist_selection_context = false);
332     void _invalidateCachedLists();
334     /** @brief unselect all descendants of the given item */
335     void _removeObjectDescendants(SPObject *obj);
336     /** @brief unselect all ancestors of the given item */
337     void _removeObjectAncestors(SPObject *obj);
338     /** @brief clears the selection (without issuing a notification) */
339     void _clear();
340     /** @brief adds an object (without issuing a notification) */
341     void _add(SPObject *obj);
342     /** @brief removes an object (without issuing a notification) */
343     void _remove(SPObject *obj);
344     /** @brief returns the SPObject corresponding to an xml node (if any) */
345     SPObject *_objectForXMLNode(XML::Node *repr) const;
346     /** @brief Releases an active layer object that is being removed */
347     void _releaseContext(SPObject *obj);
349     mutable GSList *_objs;
350     mutable GSList *_reprs;
351     mutable GSList *_items;
353     GC::soft_ptr<SPDesktop> _desktop;
354     SPObject* _selection_context;
355     gulong _context_release_handler_id;
356     guint _flags;
357     guint _idle;
359     sigc::signal<void, Selection *> _changed_signal;
360     sigc::signal<void, Selection *, guint> _modified_signal;
361 };
365 #endif
366 /*
367   Local Variables:
368   mode:c++
369   c-file-style:"stroustrup"
370   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
371   indent-tabs-mode:nil
372   fill-column:99
373   End:
374 */
375 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :