00001 //--------------------------------------------------------------------------- 00002 // 00003 // Project: OpenWalnut ( http://www.openwalnut.org ) 00004 // 00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS 00006 // For more information see http://www.openwalnut.org/copying 00007 // 00008 // This file is part of OpenWalnut. 00009 // 00010 // OpenWalnut is free software: you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as published by 00012 // the Free Software Foundation, either version 3 of the License, or 00013 // (at your option) any later version. 00014 // 00015 // OpenWalnut is distributed in the hope that it will be useful, 00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 // GNU Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public License 00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>. 00022 // 00023 //--------------------------------------------------------------------------- 00024 00025 #ifndef WITEMSELECTOR_H 00026 #define WITEMSELECTOR_H 00027 00028 #include <istream> 00029 #include <ostream> 00030 #include <vector> 00031 #include <string> 00032 00033 #include <boost/shared_ptr.hpp> 00034 #include <boost/signals2/signal.hpp> 00035 00036 #include "WItemSelection.h" 00037 #include "WItemSelectionItem.h" 00038 #include "WExportCommon.h" 00039 00040 /** 00041 * This class represents a subset of a WItemSelection. It is a class for managing selections. The class is kept very restrictive. The selection 00042 * can't be edited after the instantiation of the class to keep the interface clean, easily usable and consistent among multiple threads. So 00043 * please DO NOT extend it to provide methods for changing it! 00044 * 00045 * 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 00046 * provides methods to access the whole set and the subset represented by itself. The restrictive interface ensures thread-safety and enforces 00047 * that each new selection is done by a new instance of this class, which is needed by the WPropertyVariable to work properly. 00048 * 00049 * \note the protected constructor avoids instance creation of classes not the WItemSelection. This is restrictive but needed. Nobody can create 00050 * instances of it, changing the underlying WItemSelection and using it as selector for another ItemSelection instance. 00051 */ 00052 class OWCOMMON_EXPORT WItemSelector // NOLINT 00053 { 00054 friend class WItemSelection; 00055 public: 00056 00057 /** 00058 * The type used for storing index lists. It is a list of integer correlating with the elements in the managed WItemSelection class. 00059 */ 00060 typedef std::vector< size_t > IndexList; 00061 00062 /** 00063 * Copy constructor. Creates a new copy of the selector and ensure proper signal subscriptions to the underlying selection. 00064 * 00065 * \param other the selector to copy 00066 */ 00067 WItemSelector( const WItemSelector& other ); 00068 00069 /** 00070 * Copy assignment. Creates a new copy of the selector and ensure proper signal subscriptions to the underlying selection. 00071 * 00072 * \param other the selector to copy 00073 * 00074 * \return this. 00075 */ 00076 WItemSelector& operator=( const WItemSelector & other ); 00077 00078 /** 00079 * Destructor. 00080 */ 00081 virtual ~WItemSelector(); 00082 00083 /** 00084 * Creates a new valid instance with the specified items selected. This is especially useful to simply create a new selection if only the old 00085 * selection is known. 00086 * 00087 * \note Please be aware that, in the moment this method returns, another thread can make all selectors invalid again causing the returned 00088 * 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. 00089 * 00090 * \param selected the selected items (their index in WItemSelection). 00091 * 00092 * \return the new selector instance 00093 */ 00094 WItemSelector newSelector( IndexList selected ) const; 00095 00096 /** 00097 * Creates a new valid instance with the specified items selected. This can be useful to add a certain index. The new selector has the 00098 * selection from this AND the specified one. If you want to create a selector containing only one selected item, use the method that uses 00099 * the IndexList. 00100 * 00101 * \note Please be aware that, in the moment this method returns, another thread can make all selectors invalid again causing the returned 00102 * 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. 00103 * 00104 * \param selected the selected item (the index in WItemSelection). 00105 * 00106 * \return the new selector instance 00107 */ 00108 WItemSelector newSelector( size_t selected ) const; 00109 00110 /** 00111 * Creates a new valid instance with the specified items selected. This is especially useful to simply create a new selection if only the 00112 * string representing it is known. This somehow correlates to the << operator. 00113 * 00114 * \note Please be aware that, in the moment this method returns, another thread can make all selectors invalid again causing the returned 00115 * 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. 00116 * 00117 * \param asString the selected items 00118 * 00119 * \return the new selector instance 00120 */ 00121 WItemSelector newSelector( const std::string asString ) const; 00122 00123 /** 00124 * 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 00125 * selection list valid with the current underlying selection. 00126 * 00127 * \note Please be aware that, in the moment this method returns, another thread can make all selectors invalid again causing the returned 00128 * 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. 00129 * 00130 * \return the new (valid) selector. 00131 */ 00132 WItemSelector newSelector() const; 00133 00134 /** 00135 * Compares two selector. They are assumed to be equal if the selected items are equal and if the underlying WItemSelection is the same. 00136 * 00137 * \param other the selector 00138 * 00139 * \return true if equal 00140 */ 00141 bool operator==( const WItemSelector& other ) const; 00142 00143 /** 00144 * Write a selection in string representation to the given output stream. 00145 * 00146 * \param out the output stream where to put the information 00147 * 00148 * \return the output stream extended by the information of this selector 00149 */ 00150 std::ostream& operator<<( std::ostream& out ) const; 00151 00152 /** 00153 * Gives the count of elements in the set of selectable items. This is \ref size + number of unselected items. 00154 * 00155 * \return the number of all items in the item set. 00156 */ 00157 virtual size_t sizeAll() const; 00158 00159 /** 00160 * The number of selected items. 00161 * 00162 * \return the number of selected items. 00163 */ 00164 virtual size_t size() const; 00165 00166 /** 00167 * True if the selection is empty. 00168 * 00169 * \return true if nothing is selected. 00170 */ 00171 virtual bool empty() const; 00172 00173 /** 00174 * 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 00175 * is useful to go through the list of ALL items (not only the selected). 00176 * 00177 * \param index the index 00178 * 00179 * \return the item 00180 */ 00181 virtual const boost::shared_ptr< WItemSelectionItem > atAll( size_t index ) const; 00182 00183 /** 00184 * Gets the selected item with the given index. This is not the same index as the element has in the corresponding WItemSelection! 00185 * This method is especially useful to iterate the through the selected items. 00186 * 00187 * \param index the index 00188 * 00189 * \return the item 00190 */ 00191 virtual const boost::shared_ptr< WItemSelectionItem > at( size_t index ) const; 00192 00193 /** 00194 * 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 00195 * index to it. 00196 * 00197 * \param index the index in the selection (not the item index in WItemSelection) 00198 * 00199 * \return the index in WItemSelection. 00200 */ 00201 virtual size_t getItemIndexOfSelected( size_t index ) const; 00202 00203 /** 00204 * Checks whether the selection is valid anymore. If a selector is not valid anymore, you should ask the one providing the selectors (most 00205 * probably a WPropSelection) for a new one. 00206 * 00207 * \return true if valid. 00208 */ 00209 virtual bool isValid() const; 00210 00211 /** 00212 * Read locks the underlying selection. This ensure, that the selection stays fixed as long as this selector is locked. This also ensures 00213 * that no invalidation can be issued as long as this selector has the lock. BUT it is possible that an invalidation occurs while this 00214 * selector waits. So please always check for validity of the selector ater locking. 00215 */ 00216 void lock(); 00217 00218 /** 00219 * Unlocks the selection again. Always call this after a lock. 00220 */ 00221 void unlock(); 00222 00223 /** 00224 * Allow cast from selector to unsigned int. 00225 * 00226 * \return the index of the first selected item in the selection. 00227 */ 00228 operator unsigned int() const; 00229 00230 /** 00231 * Casts the selector to a list of indices currently selected. It contains the list of index in the corresponding WItemSelection. This is 00232 * especially useful if the whole index list is needed without nasty iterations. 00233 * 00234 * \return the list of index. 00235 */ 00236 IndexList getIndexList() const; 00237 00238 protected: 00239 00240 /** 00241 * Constructor creates an selector for the specified selection of items. Noting is selected after construction. 00242 * 00243 * \param selection the selection handled by this instance 00244 * \param selected the set of selected items 00245 */ 00246 WItemSelector( boost::shared_ptr< WItemSelection > selection, IndexList selected ); 00247 00248 /** 00249 * The selection handled by this selector. 00250 */ 00251 boost::shared_ptr< WItemSelection > m_selection; 00252 00253 /** 00254 * The list of items currently selected. 00255 */ 00256 IndexList m_selected; 00257 00258 /** 00259 * Stores the connection made using WItemSelection::subscribeInvalidateSignal. 00260 */ 00261 boost::signals2::connection m_invalidateSignalConnection; 00262 00263 private: 00264 00265 /** 00266 * Creates a new selector instance using the specified index list. Handles all needed signal subscription stuff. 00267 * 00268 * \param selected the index list of selected items 00269 * 00270 * \return new selector 00271 */ 00272 WItemSelector createSelector( const IndexList& selected ) const; 00273 00274 /** 00275 * Handles the case of invalidation. 00276 */ 00277 void invalidate(); 00278 00279 /** 00280 * If true the selector is valid. 00281 */ 00282 bool m_valid; 00283 00284 /** 00285 * This locks prevents the selection to be modified during selector iteration. 00286 */ 00287 WItemSelection::ReadTicket m_lock; 00288 }; 00289 00290 /** 00291 * Write a selection in string representation to the given output stream. 00292 * 00293 * \param out the output stream where to put the information 00294 * \param other the instance to write out 00295 * 00296 * \return the output stream extended by the information of this selector 00297 */ 00298 std::ostream& operator<<( std::ostream& out, const WItemSelector& other ); 00299 00300 #endif // WITEMSELECTOR_H 00301