OpenWalnut  1.2.5
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends
WItemSelector.h
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 
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends