CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/Fireworks/Core/src/FWSelectionManager.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     Core
00004 // Class  :     FWSelectionManager
00005 //
00006 // Implementation:
00007 //     <Notes on implementation>
00008 //
00009 // Original Author:  Chris Jones
00010 //         Created:  Fri Jan 18 14:40:51 EST 2008
00011 // $Id: FWSelectionManager.cc,v 1.11 2009/11/20 17:53:59 chrjones Exp $
00012 //
00013 
00014 // system include files
00015 #include <boost/bind.hpp>
00016 #include <iostream>
00017 
00018 // user include files
00019 #include "Fireworks/Core/interface/FWSelectionManager.h"
00020 #include "Fireworks/Core/interface/FWModelChangeManager.h"
00021 #include "Fireworks/Core/interface/FWEventItem.h"
00022 
00023 
00024 //
00025 // constants, enums and typedefs
00026 //
00027 
00028 //
00029 // static data member definitions
00030 //
00031 
00032 //
00033 // constructors and destructor
00034 //
00035 FWSelectionManager::FWSelectionManager(FWModelChangeManager* iCM) :
00036    m_changeManager(iCM),
00037    m_wasChanged(false)
00038 {
00039    assert(0!=m_changeManager);
00040    m_changeManager->changeSignalsAreDone_.connect(boost::bind(&FWSelectionManager::finishedAllSelections,this));
00041 }
00042 
00043 // FWSelectionManager::FWSelectionManager(const FWSelectionManager& rhs)
00044 // {
00045 //    // do actual copying here;
00046 // }
00047 
00048 /*FWSelectionManager::~FWSelectionManager()
00049    {
00050    }*/
00051 
00052 //
00053 // assignment operators
00054 //
00055 // const FWSelectionManager& FWSelectionManager::operator=(const FWSelectionManager& rhs)
00056 // {
00057 //   //An exception safe implementation is
00058 //   FWSelectionManager temp(rhs);
00059 //   swap(rhs);
00060 //
00061 //   return *this;
00062 // }
00063 
00064 //
00065 // member functions
00066 //
00067 void
00068 FWSelectionManager::clearSelection()
00069 {
00070    FWChangeSentry sentry(*m_changeManager);
00071    for(std::set<FWModelId>::iterator it = m_selection.begin(), itEnd = m_selection.end();
00072        it != itEnd;
00073        ++it) {
00074       //NOTE: this will cause
00075       it->unselect();
00076    }
00077    clearItemSelection();
00078 }
00079 
00080 void
00081 FWSelectionManager::clearItemSelection()
00082 {
00083    //may need this in the future 
00084    //FWChangeSentry sentry(*m_changeManager);
00085    std::set<FWEventItem*> items;
00086    items.swap(m_itemSelection);
00087    for(std::set<FWEventItem*>::iterator it = items.begin(), itEnd = items.end();
00088        it != itEnd;
00089        ++it) {
00090       //NOTE: this will cause
00091       (*it)->unselectItem();
00092    }
00093 }
00094 
00095 void 
00096 FWSelectionManager::clearModelSelectionLeaveItem()
00097 {
00098    FWChangeSentry sentry(*m_changeManager);
00099    for(std::set<FWModelId>::iterator it = m_selection.begin(), itEnd = m_selection.end();
00100        it != itEnd;
00101        ++it) {
00102       //NOTE: this will cause
00103       it->unselect();
00104    }
00105 }
00106 
00107 void
00108 FWSelectionManager::finishedAllSelections()
00109 {
00110    if(m_wasChanged) {
00111       m_selection=m_newSelection;
00112       selectionChanged_(*this);
00113       m_wasChanged = false;
00114    }
00115 }
00116 
00117 void
00118 FWSelectionManager::select(const FWModelId& iId)
00119 {
00120    bool changed = m_newSelection.insert(iId).second;
00121    m_wasChanged |=changed;
00122    if(changed) {
00123       //if this is new, we need to connect to the 'item' just incase it changes
00124       if(m_itemConnectionCount.size()<= iId.item()->id()) {
00125          m_itemConnectionCount.resize(iId.item()->id()+1);
00126       }
00127       if(1 ==++(m_itemConnectionCount[iId.item()->id()].first) ) {
00128          //want to know early about item change so we can send the 'selectionChanged' message
00129          // as part of the itemChange message from the ChangeManager
00130          // This way if more than one Item has changed, we still only send one 'selectionChanged' message
00131          m_itemConnectionCount[iId.item()->id()].second =
00132             iId.item()->preItemChanged_.connect(boost::bind(&FWSelectionManager::itemChanged,this,_1));
00133       }
00134    }
00135 }
00136 
00137 void
00138 FWSelectionManager::unselect(const FWModelId& iId)
00139 {
00140    bool changed = (0 != m_newSelection.erase(iId));
00141    m_wasChanged |=changed;
00142    if(changed) {
00143       assert(m_itemConnectionCount.size() > iId.item()->id());
00144       //was this the last model selected for this item?
00145       if(0 ==--(m_itemConnectionCount[iId.item()->id()].first)) {
00146          m_itemConnectionCount[iId.item()->id()].second.disconnect();
00147       }
00148    }
00149 }
00150 
00151 void
00152 FWSelectionManager::itemChanged(const FWEventItem* iItem)
00153 {
00154    assert(0!=iItem);
00155    assert(m_itemConnectionCount.size() > iItem->id());
00156    //if this appears in any of our models we need to remove them
00157    FWModelId low(iItem,0);
00158    FWModelId high(iItem,0x7FFFFFFF); //largest signed 32 bit number
00159    bool someoneChanged = false;
00160    {
00161       std::set<FWModelId>::iterator itL=m_newSelection.lower_bound(low),
00162                                     itH=m_newSelection.upper_bound(high);
00163       if(itL!=itH) {
00164          m_wasChanged =true;
00165          someoneChanged=true;
00166          m_newSelection.erase(itL,itH);
00167       }
00168    }
00169    {
00170       std::set<FWModelId>::iterator itL=m_selection.lower_bound(low),
00171                                     itH=m_selection.upper_bound(high);
00172       if(itL!=itH) {
00173          m_wasChanged =true;
00174          someoneChanged = true;
00175          //Don't need to erase here since will happen in 'finishedAllSelection'
00176       }
00177    }
00178    assert(someoneChanged);
00179    m_itemConnectionCount[iItem->id()].second.disconnect();
00180    m_itemConnectionCount[iItem->id()].first = 0;
00181 }
00182 
00183 void 
00184 FWSelectionManager::selectItem(FWEventItem* iItem)
00185 {
00186    m_itemSelection.insert(iItem);
00187    itemSelectionChanged_(*this);
00188 }
00189 void 
00190 FWSelectionManager::unselectItem(FWEventItem* iItem)
00191 {
00192    m_itemSelection.erase(iItem);
00193    itemSelectionChanged_(*this);
00194 }
00195 //
00196 // const member functions
00197 //
00198 const std::set<FWModelId>&
00199 FWSelectionManager::selected() const
00200 {
00201    return m_selection;
00202 }
00203 
00204 const std::set<FWEventItem*>&
00205 FWSelectionManager::selectedItems() const
00206 {
00207    return m_itemSelection;
00208 }
00209 
00210 //
00211 // static member functions
00212 //