OpenWalnut  1.2.5
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
WItemSelector.h
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #ifndef WITEMSELECTOR_H
26 #define WITEMSELECTOR_H
27 
28 #include <istream>
29 #include <ostream>
30 #include <vector>
31 #include <string>
32 
33 #include <boost/shared_ptr.hpp>
34 #include <boost/signals2/signal.hpp>
35 
36 #include "WItemSelection.h"
37 #include "WItemSelectionItem.h"
38 #include "WExportCommon.h"
39 
40 /**
41  * This class represents a subset of a WItemSelection. It is a class for managing selections. The class is kept very restrictive. The selection
42  * can't be edited after the instantiation of the class to keep the interface clean, easily usable and consistent among multiple threads. So
43  * please DO NOT extend it to provide methods for changing it!
44  *
45  * This class can be seen as some kind of special "iterator" providing access to the underlying set without allowing it to be modified. The class
46  * provides methods to access the whole set and the subset represented by itself. The restrictive interface ensures thread-safety and enforces
47  * that each new selection is done by a new instance of this class, which is needed by the WPropertyVariable to work properly.
48  *
49  * \note the protected constructor avoids instance creation of classes not the WItemSelection. This is restrictive but needed. Nobody can create
50  * instances of it, changing the underlying WItemSelection and using it as selector for another ItemSelection instance.
51  */
52 class OWCOMMON_EXPORT WItemSelector // NOLINT
53 {
54 friend class WItemSelection;
55 public:
56 
57  /**
58  * The type used for storing index lists. It is a list of integer correlating with the elements in the managed WItemSelection class.
59  */
60  typedef std::vector< size_t > IndexList;
61 
62  /**
63  * Copy constructor. Creates a new copy of the selector and ensure proper signal subscriptions to the underlying selection.
64  *
65  * \param other the selector to copy
66  */
67  WItemSelector( const WItemSelector& other );
68 
69  /**
70  * Copy assignment. Creates a new copy of the selector and ensure proper signal subscriptions to the underlying selection.
71  *
72  * \param other the selector to copy
73  *
74  * \return this.
75  */
76  WItemSelector& operator=( const WItemSelector & other );
77 
78  /**
79  * Destructor.
80  */
81  virtual ~WItemSelector();
82 
83  /**
84  * Creates a new valid instance with the specified items selected. This is especially useful to simply create a new selection if only the old
85  * selection is known.
86  *
87  * \note Please be aware that, in the moment this method returns, another thread can make all selectors invalid again causing the returned
88  * one to be invalid too. To avoid this, use the newSelector method only if the old has locked the selection using \ref lock and \ref unlock.
89  *
90  * \param selected the selected items (their index in WItemSelection).
91  *
92  * \return the new selector instance
93  */
94  WItemSelector newSelector( IndexList selected ) const;
95 
96  /**
97  * Creates a new valid instance with the specified items selected. This can be useful to add a certain index. The new selector has the
98  * selection from this AND the specified one. If you want to create a selector containing only one selected item, use the method that uses
99  * the IndexList.
100  *
101  * \note Please be aware that, in the moment this method returns, another thread can make all selectors invalid again causing the returned
102  * one to be invalid too. To avoid this, use the newSelector method only if the old has locked the selection using \ref lock and \ref unlock.
103  *
104  * \param selected the selected item (the index in WItemSelection).
105  *
106  * \return the new selector instance
107  */
108  WItemSelector newSelector( size_t selected ) const;
109 
110  /**
111  * Creates a new valid instance with the specified items selected. This is especially useful to simply create a new selection if only the
112  * string representing it is known. This somehow correlates to the << operator.
113  *
114  * \note Please be aware that, in the moment this method returns, another thread can make all selectors invalid again causing the returned
115  * one to be invalid too. To avoid this, use the newSelector method only if the old has locked the selection using \ref lock and \ref unlock.
116  *
117  * \param asString the selected items
118  *
119  * \return the new selector instance
120  */
121  WItemSelector newSelector( const std::string asString ) const;
122 
123  /**
124  * Creates a new selector, but basing on this instance as old one. The new selector tries to keep the old selection but makes the internal
125  * selection list valid with the current underlying selection.
126  *
127  * \note Please be aware that, in the moment this method returns, another thread can make all selectors invalid again causing the returned
128  * one to be invalid too. To avoid this, use the newSelector method only if the old has locked the selection using \ref lock and \ref unlock.
129  *
130  * \return the new (valid) selector.
131  */
132  WItemSelector newSelector() const;
133 
134  /**
135  * Compares two selector. They are assumed to be equal if the selected items are equal and if the underlying WItemSelection is the same.
136  *
137  * \param other the selector
138  *
139  * \return true if equal
140  */
141  bool operator==( const WItemSelector& other ) const;
142 
143  /**
144  * Write a selection in string representation to the given output stream.
145  *
146  * \param out the output stream where to put the information
147  *
148  * \return the output stream extended by the information of this selector
149  */
150  std::ostream& operator<<( std::ostream& out ) const;
151 
152  /**
153  * Gives the count of elements in the set of selectable items. This is \ref size + number of unselected items.
154  *
155  * \return the number of all items in the item set.
156  */
157  virtual size_t sizeAll() const;
158 
159  /**
160  * The number of selected items.
161  *
162  * \return the number of selected items.
163  */
164  virtual size_t size() const;
165 
166  /**
167  * True if the selection is empty.
168  *
169  * \return true if nothing is selected.
170  */
171  virtual bool empty() const;
172 
173  /**
174  * Gets the item with the given index from the WItemSelection. This index does not equal the index of the same item for \ref at. This method
175  * is useful to go through the list of ALL items (not only the selected).
176  *
177  * \param index the index
178  *
179  * \return the item
180  */
181  virtual const boost::shared_ptr< WItemSelectionItem > atAll( size_t index ) const;
182 
183  /**
184  * Gets the selected item with the given index. This is not the same index as the element has in the corresponding WItemSelection!
185  * This method is especially useful to iterate the through the selected items.
186  *
187  * \param index the index
188  *
189  * \return the item
190  */
191  virtual const boost::shared_ptr< WItemSelectionItem > at( size_t index ) const;
192 
193  /**
194  * Helps to get the index of an selected item in the WItemSelection. This is somehow similar to \ref at, but does not return the item but the
195  * index to it.
196  *
197  * \param index the index in the selection (not the item index in WItemSelection)
198  *
199  * \return the index in WItemSelection.
200  */
201  virtual size_t getItemIndexOfSelected( size_t index ) const;
202 
203  /**
204  * Checks whether the selection is valid anymore. If a selector is not valid anymore, you should ask the one providing the selectors (most
205  * probably a WPropSelection) for a new one.
206  *
207  * \return true if valid.
208  */
209  virtual bool isValid() const;
210 
211  /**
212  * Read locks the underlying selection. This ensure, that the selection stays fixed as long as this selector is locked. This also ensures
213  * that no invalidation can be issued as long as this selector has the lock. BUT it is possible that an invalidation occurs while this
214  * selector waits. So please always check for validity of the selector ater locking.
215  */
216  void lock();
217 
218  /**
219  * Unlocks the selection again. Always call this after a lock.
220  */
221  void unlock();
222 
223  /**
224  * Allow cast from selector to unsigned int.
225  *
226  * \return the index of the first selected item in the selection.
227  */
228  operator unsigned int() const;
229 
230  /**
231  * Casts the selector to a list of indices currently selected. It contains the list of index in the corresponding WItemSelection. This is
232  * especially useful if the whole index list is needed without nasty iterations.
233  *
234  * \return the list of index.
235  */
236  IndexList getIndexList() const;
237 
238 protected:
239 
240  /**
241  * Constructor creates an selector for the specified selection of items. Noting is selected after construction.
242  *
243  * \param selection the selection handled by this instance
244  * \param selected the set of selected items
245  */
246  WItemSelector( boost::shared_ptr< WItemSelection > selection, IndexList selected );
247 
248  /**
249  * The selection handled by this selector.
250  */
251  boost::shared_ptr< WItemSelection > m_selection;
252 
253  /**
254  * The list of items currently selected.
255  */
257 
258  /**
259  * Stores the connection made using WItemSelection::subscribeInvalidateSignal.
260  */
261  boost::signals2::connection m_invalidateSignalConnection;
262 
263 private:
264 
265  /**
266  * Creates a new selector instance using the specified index list. Handles all needed signal subscription stuff.
267  *
268  * \param selected the index list of selected items
269  *
270  * \return new selector
271  */
272  WItemSelector createSelector( const IndexList& selected ) const;
273 
274  /**
275  * Handles the case of invalidation.
276  */
277  void invalidate();
278 
279  /**
280  * If true the selector is valid.
281  */
282  bool m_valid;
283 
284  /**
285  * This locks prevents the selection to be modified during selector iteration.
286  */
288 };
289 
290 /**
291  * Write a selection in string representation to the given output stream.
292  *
293  * \param out the output stream where to put the information
294  * \param other the instance to write out
295  *
296  * \return the output stream extended by the information of this selector
297  */
298 std::ostream& operator<<( std::ostream& out, const WItemSelector& other );
299 
300 #endif // WITEMSELECTOR_H
301