#3296 caf::SelectionManager: Refactoring to avoid sending multiple selection changes

Must be considered if using the CmdSelectionGangeExec
This commit is contained in:
Jacob Støren 2018-08-31 15:13:58 +02:00
parent 9a94fc2cde
commit e26a57011d
10 changed files with 196 additions and 60 deletions

View File

@ -107,6 +107,7 @@ bool RicPointTangentManipulator::eventFilter(QObject *obj, QEvent* inputEvent)
if(m_partManager->isManipulatorActive())
{
emit notifySelected();
emit notifyRedraw();
return true;
@ -307,7 +308,6 @@ void RicPointTangentManipulatorPartMgr::tryToActivateManipulator(const cvf::HitI
m_tangentOnStartManipulation = m_tangent;
m_originOnStartManipulation = m_origin;
m_currentHandleIndex = i;
caf::SelectionManager::instance()->clear(caf::SelectionManager::FIRST_LEVEL);
}
}
@ -639,9 +639,9 @@ PdmUiSelectionVisualizer3d::~PdmUiSelectionVisualizer3d()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiSelectionVisualizer3d::onSelectionManagerSelectionChanged(int selectionLevel)
void PdmUiSelectionVisualizer3d::onSelectionManagerSelectionChanged( const std::set<int>& changedSelectionLevels )
{
if (selectionLevel != 0) return;
if (!changedSelectionLevels.count(0)) return;
for (auto editor: m_active3DEditors)
{
@ -805,6 +805,10 @@ void RicWellTarget3dEditor::configureAndUpdateUi(const QString& uiConfigName)
SIGNAL( notifyUpdate(const cvf::Vec3d& , const cvf::Vec3d& ) ),
this,
SLOT( slotUpdated(const cvf::Vec3d& , const cvf::Vec3d& ) ) );
QObject::connect(m_manipulator,
SIGNAL( notifySelected() ),
this,
SLOT( slotSelectedIn3D() ) );
m_cvfModel = new cvf::ModelBasicList;
m_ownerViewer->addStaticModelOnce(m_cvfModel.p());
}
@ -873,3 +877,14 @@ void RicWellTarget3dEditor::slotUpdated(const cvf::Vec3d& origin, const cvf::Vec
std::cout << "RicWellTarget3dEditor::slotUpdated() end" << std::endl;
}
void RicWellTarget3dEditor::slotSelectedIn3D()
{
RimWellPathTarget* target = dynamic_cast<RimWellPathTarget*>(this->pdmObject());
if ( !target)
{
return;
}
caf::SelectionManager::instance()->setSelectedItemAtLevel(target, caf::SelectionManager::FIRST_LEVEL);
}

View File

@ -59,6 +59,7 @@ public:
void appendPartsToModel(cvf::ModelBasicList* model);
signals:
void notifySelected();
void notifyRedraw();
void notifyUpdate(const cvf::Vec3d& origin, const cvf::Vec3d& tangent);
@ -229,7 +230,7 @@ public:
PdmUiSelectionVisualizer3d(caf::Viewer* ownerViewer);
~PdmUiSelectionVisualizer3d();
protected:
virtual void onSelectionManagerSelectionChanged(int selectionLevel) override;
virtual void onSelectionManagerSelectionChanged( const std::set<int>& changedSelectionLevels ) override;
std::vector< QPointer<PdmUi3dObjectEditorHandle> > m_active3DEditors;
@ -284,6 +285,7 @@ protected:
private slots:
void slotUpdated(const cvf::Vec3d& origin, const cvf::Vec3d& tangent);
void slotSelectedIn3D();
private:
QPointer<RicPointTangentManipulator> m_manipulator;
cvf::ref<cvf::ModelBasicList> m_cvfModel;

View File

@ -58,7 +58,7 @@ QString CmdSelectionChangeExec::name()
//--------------------------------------------------------------------------------------------------
void CmdSelectionChangeExec::redo()
{
SelectionManager::instance()->setSelectionFromReferences(m_commandData->m_newSelection.v(), m_commandData->m_selectionLevel.v());
SelectionManager::instance()->setSelectionAtLevelFromReferences(m_commandData->m_newSelection.v(), m_commandData->m_selectionLevel.v());
}
//--------------------------------------------------------------------------------------------------
@ -66,7 +66,7 @@ void CmdSelectionChangeExec::redo()
//--------------------------------------------------------------------------------------------------
void CmdSelectionChangeExec::undo()
{
SelectionManager::instance()->setSelectionFromReferences(m_commandData->m_previousSelection.v(), m_commandData->m_selectionLevel.v());
SelectionManager::instance()->setSelectionAtLevelFromReferences(m_commandData->m_previousSelection.v(), m_commandData->m_selectionLevel.v());
}
//--------------------------------------------------------------------------------------------------

View File

@ -63,6 +63,7 @@ CmdSelectionChangeExec* CmdSelectionHelper::createSelectionCommand(const std::ve
{
CmdSelectionChangeExec* selectionChangeExec = new CmdSelectionChangeExec(SelectionManager::instance()->notificationCenter());
selectionChangeExec->commandData()->m_selectionLevel.v() = selectionLevel;
SelectionManager::instance()->selectionAsReferences(selectionChangeExec->commandData()->m_previousSelection.v(), selectionLevel);
for (size_t i = 0; i < selection.size(); i++)

View File

@ -35,6 +35,8 @@
//##################################################################################################
#pragma once
#include <set>
namespace caf
{
class SelectionChangedReceiver
@ -46,7 +48,7 @@ public:
protected:
friend class SelectionManager;
/// Called whenever caf::SelectionManager's selection changes
virtual void onSelectionManagerSelectionChanged(int selectionLevel) = 0;
virtual void onSelectionManagerSelectionChanged( const std::set<int>& changedSelectionLevels ) = 0;
};
}

View File

@ -87,37 +87,131 @@ void SelectionManager::selectedItems(std::vector<PdmUiItem*>& items, int selecti
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void SelectionManager::setSelectedItems(const std::vector<PdmUiItem*>& items, int selectionLevel /*= 0*/)
void SelectionManager::setSelectedItems(const std::vector<PdmUiItem*>& items)
{
std::vector< std::pair<PdmPointer<PdmObjectHandle>, PdmUiItem*> >& selection = m_selectionPrLevel[selectionLevel];
std::vector< std::pair<PdmPointer<PdmObjectHandle>, PdmUiItem*> > newSelection;
std::map <int, std::vector< std::pair<PdmPointer<PdmObjectHandle>, PdmUiItem*> > > newCompleteSelectionMap;
for (size_t i = 0; i < items.size(); i++)
std::vector< std::pair<PdmPointer<PdmObjectHandle>, PdmUiItem*> > & newSelection = newCompleteSelectionMap[0];
extractInternalSelectionItems(items, &newSelection);
std::set<int> changedLevels = findChangedLevels(newCompleteSelectionMap);
if ( !changedLevels.empty() )
{
m_selectionPrLevel = newCompleteSelectionMap;
notifySelectionChanged(changedLevels);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void SelectionManager::extractInternalSelectionItems(const std::vector<PdmUiItem *> &items,
std::vector<std::pair<PdmPointer<PdmObjectHandle>, PdmUiItem *>> *newSelection)
{
for ( size_t i = 0; i < items.size(); i++ )
{
PdmUiFieldHandle* fieldHandle = dynamic_cast<PdmUiFieldHandle*>(items[i]);
if (fieldHandle)
if ( fieldHandle )
{
PdmObjectHandle* obj = fieldHandle->fieldHandle()->ownerObject();
newSelection.push_back(std::make_pair(obj, fieldHandle));
newSelection->push_back(std::make_pair(obj, fieldHandle));
}
else
{
PdmUiObjectHandle* obj = dynamic_cast<PdmUiObjectHandle*>(items[i]);
if (obj)
if ( obj )
{
newSelection.push_back(std::make_pair(obj->objectHandle(), obj));
newSelection->push_back(std::make_pair(obj->objectHandle(), obj));
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void SelectionManager::setSelectedItemsAtLevel(const std::vector<PdmUiItem*>& items, int selectionLevel)
{
std::vector< std::pair<PdmPointer<PdmObjectHandle>, PdmUiItem*> >& selection = m_selectionPrLevel[selectionLevel];
std::vector< std::pair<PdmPointer<PdmObjectHandle>, PdmUiItem*> > newSelection;
extractInternalSelectionItems(items, &newSelection);
if (newSelection != selection)
{
selection = newSelection;
notifySelectionChanged(selectionLevel);
notifySelectionChanged({selectionLevel});
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void SelectionManager::setSelection(const std::vector< SelectionItem > completeSelection)
{
std::map <int, std::vector< std::pair<PdmPointer<PdmObjectHandle>, PdmUiItem*> > > newCompleteSelectionMap;
std::map<int, std::vector<PdmUiItem*> > newSelectionPrLevel;
for (const SelectionItem& item: completeSelection)
{
newSelectionPrLevel[item.selectionLevel].push_back(item.item);
}
for (auto& levelItemsPair: newSelectionPrLevel)
{
std::vector< std::pair<PdmPointer<PdmObjectHandle>, PdmUiItem*> > & newSelectionLevel = newCompleteSelectionMap[levelItemsPair.first];
extractInternalSelectionItems(levelItemsPair.second, &newSelectionLevel);
}
std::set<int> changedLevels = findChangedLevels(newCompleteSelectionMap);
if ( !changedLevels.empty())
{
m_selectionPrLevel = newCompleteSelectionMap;
notifySelectionChanged(changedLevels);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<int> SelectionManager::findChangedLevels(const std::map<int, std::vector<std::pair<PdmPointer<PdmObjectHandle>, PdmUiItem *>>> & newCompleteSelectionMap ) const
{
std::set<int> changedLevels;
// Compare the existing levels with the corresponding levels in the new selection
for ( auto& levelSelectionPair : m_selectionPrLevel )
{
auto it = newCompleteSelectionMap.find(levelSelectionPair.first);
if ( it != newCompleteSelectionMap.end() )
{
if ( levelSelectionPair.second != it->second ) changedLevels.insert(levelSelectionPair.first);
}
else
{
if ( !levelSelectionPair.second.empty() ) changedLevels.insert(levelSelectionPair.first);
}
}
// Add each of the levels in the new selection that are not present in the existing selection
for ( auto& levelSelectionPair : newCompleteSelectionMap )
{
auto it = m_selectionPrLevel.find(levelSelectionPair.first);
if ( it == m_selectionPrLevel.end() )
{
changedLevels.insert(levelSelectionPair.first);
}
}
return changedLevels;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -142,12 +236,23 @@ PdmUiItem* SelectionManager::selectedItem(int selectionLevel /*= 0*/)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void SelectionManager::setSelectedItem(PdmUiItem* item, int selectionLevel /*= 0*/)
void SelectionManager::setSelectedItem(PdmUiItem* item)
{
std::vector<PdmUiItem*> singleSelection;
singleSelection.push_back(item);
setSelectedItems(singleSelection, selectionLevel);
setSelectedItems(singleSelection);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void SelectionManager::setSelectedItemAtLevel(PdmUiItem* item, int selectionLevel)
{
std::vector<PdmUiItem*> singleSelection;
singleSelection.push_back(item);
setSelectedItemsAtLevel(singleSelection, selectionLevel);
}
//--------------------------------------------------------------------------------------------------
@ -187,7 +292,7 @@ void SelectionManager::selectionAsReferences(std::vector<QString>& referenceList
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void SelectionManager::setSelectionFromReferences(const std::vector<QString>& referenceList, int selectionLevel /*= 0*/)
void SelectionManager::setSelectionAtLevelFromReferences(const std::vector<QString>& referenceList, int selectionLevel /*= 0*/)
{
std::vector<PdmUiItem*> uiItems;
@ -206,7 +311,7 @@ void SelectionManager::setSelectionFromReferences(const std::vector<QString>& re
}
}
setSelectedItems(uiItems, selectionLevel);
setSelectedItemsAtLevel(uiItems, selectionLevel);
}
//--------------------------------------------------------------------------------------------------
@ -254,9 +359,9 @@ void SelectionManager::clearAll()
m_selectionPrLevel.clear();
for (int level: changedSelectionLevels)
if ( changedSelectionLevels.size() )
{
notifySelectionChanged(level);
notifySelectionChanged(changedSelectionLevels);
}
}
@ -274,18 +379,18 @@ void SelectionManager::clear(int selectionLevel)
{
m_selectionPrLevel[selectionLevel].clear();
notifySelectionChanged(selectionLevel);
notifySelectionChanged({selectionLevel});
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void SelectionManager::notifySelectionChanged( int selectionLevel)
void SelectionManager::notifySelectionChanged( const std::set<int>& changedSelectionLevels )
{
for (auto receiver: m_selectionReceivers)
{
receiver->onSelectionManagerSelectionChanged(selectionLevel);
receiver->onSelectionManagerSelectionChanged(changedSelectionLevels);
}
}
@ -324,10 +429,7 @@ void SelectionManager::removeObjectFromAllSelections(PdmObjectHandle* pdmObject)
}
}
for (int level: changedSelectionLevels)
{
notifySelectionChanged(level);
}
notifySelectionChanged(changedSelectionLevels);
}
void SelectionManager::setPdmRootObject(PdmObjectHandle* root)

View File

@ -69,23 +69,21 @@ public:
public:
static SelectionManager* instance();
// OBSOLETE ! Remove when time to refactor the command system
NotificationCenter* notificationCenter();
void setActiveChildArrayFieldHandle(PdmChildArrayFieldHandle* childArray);
PdmChildArrayFieldHandle* activeChildArrayFieldHandle();
void setPdmRootObject(PdmObjectHandle* root);
PdmObjectHandle* pdmRootObject() { return m_rootObject; }
PdmUiItem* selectedItem(int selectionLevel = 0);
void setSelectedItem(PdmUiItem* item, int selectionLevel = 0);
void selectedItems(std::vector<PdmUiItem*>& items, int selectionLevel = 0);
void setSelectedItems(const std::vector<PdmUiItem*>& items, int selectionLevel = 0);
void setSelectedItem(PdmUiItem* item);
void setSelectedItemAtLevel(PdmUiItem* item, int selectionLevel);
void setSelectedItems(const std::vector<PdmUiItem*>& items);
void setSelectedItemsAtLevel(const std::vector<PdmUiItem*>& items, int selectionLevel = 0);
struct SelectionItem { PdmUiItem* item; int selectionLevel; };
void setSelection(const std::vector< SelectionItem > completeSelection);
void selectionAsReferences(std::vector<QString>& referenceList, int selectionLevel = 0) const;
void setSelectionFromReferences(const std::vector<QString>& referenceList, int selectionLevel = 0);
void setSelectionAtLevelFromReferences(const std::vector<QString>& referenceList, int selectionLevel);
bool isSelected(PdmUiItem* item, int selectionLevel) const;
@ -150,10 +148,24 @@ public:
return nullptr;
}
// OBSOLETE ! Remove when time to refactor the command system
NotificationCenter* notificationCenter();
void setActiveChildArrayFieldHandle(PdmChildArrayFieldHandle* childArray);
PdmChildArrayFieldHandle* activeChildArrayFieldHandle();
void setPdmRootObject(PdmObjectHandle* root);
PdmObjectHandle* pdmRootObject() { return m_rootObject; }
// End OBSOLETE
private:
SelectionManager();
void notifySelectionChanged( int selectionLevel);
static void extractInternalSelectionItems(const std::vector<PdmUiItem *> &items,
std::vector<std::pair<PdmPointer<PdmObjectHandle>, PdmUiItem *>> *internalSelectionItems);
void notifySelectionChanged( const std::set<int>& changedSelectionLevels );
std::set<int> findChangedLevels(const std::map<int, std::vector<std::pair<PdmPointer<PdmObjectHandle>, PdmUiItem *>>> &newCompleteSelectionMap) const;
friend class SelectionChangedReceiver;
void registerSelectionChangedReceiver ( SelectionChangedReceiver* receiver) { m_selectionReceivers.insert(receiver);}

View File

@ -282,11 +282,11 @@ void PdmUiTableViewEditor::setRowSelectionLevel(int selectionLevel)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiTableViewEditor::onSelectionManagerSelectionChanged(int selectionLevel)
void PdmUiTableViewEditor::onSelectionManagerSelectionChanged( const std::set<int>& changedSelectionLevels )
{
if (m_isBlockingSelectionManagerChanged) return;
if (isSelectionRoleDefined() && (m_rowSelectionLevel == selectionLevel))
if (isSelectionRoleDefined() && (changedSelectionLevels.count(m_rowSelectionLevel) ))
{
std::vector<PdmUiItem*> items;
SelectionManager::instance()->selectedItems(items, m_rowSelectionLevel);
@ -355,21 +355,24 @@ void PdmUiTableViewEditor::updateSelectionManagerFromTableSelection()
}
}
std::vector<PdmUiItem*> items { selectedRowObjects.begin(), selectedRowObjects.end() };
std::vector<SelectionManager::SelectionItem> newCompleteSelection;
for (auto item : selectedRowObjects)
{
newCompleteSelection.push_back({ item, m_rowSelectionLevel });
}
if ( childArrayFieldHandle() && childArrayFieldHandle()->ownerObject() )
{
newCompleteSelection.push_back({ childArrayFieldHandle()->ownerObject()->uiCapability() ,
m_tableSelectionLevel });
}
m_isBlockingSelectionManagerChanged = true;
{
SelectionManager::instance()->clearAll();
if (childArrayFieldHandle() && childArrayFieldHandle()->ownerObject())
{
SelectionManager::instance()->setSelectedItem(childArrayFieldHandle()->ownerObject()->uiCapability(),
m_tableSelectionLevel);
}
SelectionManager::instance()->setSelectedItems(items, m_rowSelectionLevel);
}
SelectionManager::instance()->setSelection(newCompleteSelection);
m_isBlockingSelectionManagerChanged = false;
}
}

View File

@ -128,7 +128,7 @@ protected:
QWidget* createLabelWidget(QWidget * parent) override;
virtual void configureAndUpdateUi(const QString& uiConfigName) override;
virtual void onSelectionManagerSelectionChanged(int selectionLevel) override;
virtual void onSelectionManagerSelectionChanged( const std::set<int>& changedSelectionLevels ) override;
private:
void selectedUiItems(const QModelIndexList& modelIndexList, std::vector<PdmUiItem*>& objects);

View File

@ -384,7 +384,6 @@ void PdmUiTreeViewEditor::updateSelectionManager()
std::vector<PdmUiItem*> items;
this->selectedUiItems(items);
SelectionManager::instance()->clearAll();
SelectionManager::instance()->setSelectedItems(items);
}
}