From 2c4217fd3d212a67e062062dcbd04c0e84a8110a Mon Sep 17 00:00:00 2001 From: nds Date: Mon, 11 Jan 2016 16:21:31 +0300 Subject: [PATCH] Improve multi-selector control to provide items multi-selection and "Delete" context menu action. --- src/Model/Model_AttributeRefList.cpp | 4 ++ src/Model/Model_AttributeRefList.h | 4 ++ src/Model/Model_AttributeSelectionList.cpp | 4 ++ src/Model/Model_AttributeSelectionList.h | 4 ++ src/ModelAPI/ModelAPI_AttributeRefList.h | 4 ++ .../ModelAPI_AttributeSelectionList.h | 4 ++ .../ModuleBase_WidgetMultiSelector.cpp | 62 ++++++++++++++++++- .../ModuleBase_WidgetMultiSelector.h | 4 ++ 8 files changed, 87 insertions(+), 3 deletions(-) diff --git a/src/Model/Model_AttributeRefList.cpp b/src/Model/Model_AttributeRefList.cpp index 469a4add2..200807984 100644 --- a/src/Model/Model_AttributeRefList.cpp +++ b/src/Model/Model_AttributeRefList.cpp @@ -212,6 +212,10 @@ void Model_AttributeRefList::removeLast() } } +void Model_AttributeRefList::remove(const std::set& theIndices) +{ +} + Model_AttributeRefList::Model_AttributeRefList(TDF_Label& theLabel) { myIsInitialized = theLabel.FindAttribute(TDataStd_ReferenceList::GetID(), myRef) == Standard_True; diff --git a/src/Model/Model_AttributeRefList.h b/src/Model/Model_AttributeRefList.h index e92f5eae3..eaa1d9206 100644 --- a/src/Model/Model_AttributeRefList.h +++ b/src/Model/Model_AttributeRefList.h @@ -56,6 +56,10 @@ class Model_AttributeRefList : public ModelAPI_AttributeRefList /// Removes the last element in the list. MODEL_EXPORT virtual void removeLast(); + /// Removes the elements from the list. + /// \param theIndices a list of indices of elements to be removed + MODEL_EXPORT virtual void remove(const std::set& theIndices); + /// Returns true if attribute was initialized by some value MODEL_EXPORT virtual bool isInitialized(); protected: diff --git a/src/Model/Model_AttributeSelectionList.cpp b/src/Model/Model_AttributeSelectionList.cpp index f762ebaf3..677d14d78 100644 --- a/src/Model/Model_AttributeSelectionList.cpp +++ b/src/Model/Model_AttributeSelectionList.cpp @@ -83,6 +83,10 @@ void Model_AttributeSelectionList::removeLast() } } +void Model_AttributeSelectionList::remove(const std::set& theIndices) +{ +} + int Model_AttributeSelectionList::size() { return mySize->Get(); diff --git a/src/Model/Model_AttributeSelectionList.h b/src/Model/Model_AttributeSelectionList.h index 6721dd8ad..a69635c4b 100644 --- a/src/Model/Model_AttributeSelectionList.h +++ b/src/Model/Model_AttributeSelectionList.h @@ -42,6 +42,10 @@ public: /// Removes the last element in the list MODEL_EXPORT virtual void removeLast(); + /// Removes the elements from the list. + /// \param theIndices a list of indices of elements to be removed + MODEL_EXPORT virtual void remove(const std::set& theIndices); + /// Returns the number ofselection attributes in the list MODEL_EXPORT virtual int size(); diff --git a/src/ModelAPI/ModelAPI_AttributeRefList.h b/src/ModelAPI/ModelAPI_AttributeRefList.h index d51900022..101fc8695 100644 --- a/src/ModelAPI/ModelAPI_AttributeRefList.h +++ b/src/ModelAPI/ModelAPI_AttributeRefList.h @@ -61,6 +61,10 @@ class ModelAPI_AttributeRefList : public ModelAPI_Attribute /// Removes the last element in the list. virtual void removeLast() = 0; + /// Removes the elements from the list. + /// \param theIndices a list of indices of elements to be removed + virtual void remove(const std::set& theIndices) = 0; + MODELAPI_EXPORT virtual ~ModelAPI_AttributeRefList(); protected: /// Objects are created for features automatically diff --git a/src/ModelAPI/ModelAPI_AttributeSelectionList.h b/src/ModelAPI/ModelAPI_AttributeSelectionList.h index 52eec8ca1..0c875c336 100644 --- a/src/ModelAPI/ModelAPI_AttributeSelectionList.h +++ b/src/ModelAPI/ModelAPI_AttributeSelectionList.h @@ -35,6 +35,10 @@ class ModelAPI_AttributeSelectionList : public ModelAPI_Attribute /// Removes the last element in the list virtual void removeLast() = 0; + /// Removes the elements from the list. + /// \param theIndices a list of indices of elements to be removed + virtual void remove(const std::set& theIndices) = 0; + /// Returns the number of selection attributes in the list virtual int size() = 0; diff --git a/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp b/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp index bb4ec7861..73ee5e462 100755 --- a/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp +++ b/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp @@ -37,6 +37,8 @@ #include #include +const int ATTRIBUTE_SELECTION_INDEX_ROLE = Qt::UserRole + 1; + /** * Customization of a List Widget to make it to be placed on full width of container */ @@ -129,6 +131,7 @@ ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParen QString anObjName = QString::fromStdString(attributeID()); myListControl->setObjectName(anObjName); myListControl->setToolTip(aToolTip); + myListControl->setSelectionMode(QAbstractItemView::ExtendedSelection); aMainLay->addWidget(myListControl, 2, 0, 1, -1); aMainLay->setRowStretch(2, 1); @@ -142,6 +145,13 @@ ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParen myCopyAction->setEnabled(false); connect(myCopyAction, SIGNAL(triggered(bool)), SLOT(onCopyItem())); myListControl->addAction(myCopyAction); + + myDeleteAction = new QAction(QIcon(":pictures/delete.png"), tr("Delete"), this); + myDeleteAction->setShortcut(QKeySequence::Delete); + myDeleteAction->setEnabled(false); + connect(myDeleteAction, SIGNAL(triggered(bool)), SLOT(onDeleteItem())); + myListControl->addAction(myDeleteAction); + myListControl->setContextMenuPolicy(Qt::ActionsContextMenu); connect(myListControl, SIGNAL(itemSelectionChanged()), SLOT(onListSelection())); } @@ -426,15 +436,21 @@ void ModuleBase_WidgetMultiSelector::updateSelectionList() if (aSelectionListAttr.get()) { for (int i = 0; i < aSelectionListAttr->size(); i++) { AttributeSelectionPtr aAttr = aSelectionListAttr->value(i); - myListControl->addItem(aAttr->namingName().c_str()); + QListWidgetItem* anItem = new QListWidgetItem(aAttr->namingName().c_str(), myListControl); + anItem->setData(ATTRIBUTE_SELECTION_INDEX_ROLE, i); + myListControl->addItem(anItem); } } else { AttributeRefListPtr aRefListAttr = myFeature->data()->reflist(attributeID()); for (int i = 0; i < aRefListAttr->size(); i++) { ObjectPtr anObject = aRefListAttr->object(i); - if (anObject.get()) - myListControl->addItem(anObject->data()->name().c_str()); + if (anObject.get()) { + QListWidgetItem* anItem = new QListWidgetItem(anObject->data()->name().c_str(), + myListControl); + anItem->setData(ATTRIBUTE_SELECTION_INDEX_ROLE, i); + myListControl->addItem(anItem); + } } } // We have to call repaint because sometimes the List control is not updated @@ -474,9 +490,49 @@ void ModuleBase_WidgetMultiSelector::onCopyItem() } } +//******************************************************************** +void ModuleBase_WidgetMultiSelector::onDeleteItem() +{ + // find attribute indices to delete + QList aItems = myListControl->selectedItems(); + std::set anAttributeIds; + foreach(QListWidgetItem* anItem, aItems) { + int anIndex = anItem->data(ATTRIBUTE_SELECTION_INDEX_ROLE).toInt(); + if (anAttributeIds.find(anIndex) == anAttributeIds.end()) + anAttributeIds.insert(anIndex); + } + // refill attribute by the items which indices are not in the list of ids + bool aDone = false; + AttributeSelectionListPtr aSelectionListAttr = myFeature->data()->selectionList(attributeID()); + if (aSelectionListAttr.get()) { + aDone = !anAttributeIds.empty(); + //aSelectionListAttr->remove(anAttributeIds); + std::set::const_iterator anIt = anAttributeIds.begin(), aLast = anAttributeIds.end(); + for (; anIt != aLast; anIt++) + aSelectionListAttr->removeLast(); + } + else { + AttributeRefListPtr aRefListAttr = myFeature->data()->reflist(attributeID()); + if (aRefListAttr.get()) { + aDone = !anAttributeIds.empty(); + //aRefListAttr->remove(anAttributeIds); + std::set::const_iterator anIt = anAttributeIds.begin(), aLast = anAttributeIds.end(); + for (; anIt != aLast; anIt++) + aRefListAttr->removeLast(); + } + } + if (aDone) { + restoreValue(); + myWorkshop->setSelected(getAttributeSelection()); + } +} + //******************************************************************** void ModuleBase_WidgetMultiSelector::onListSelection() { QList aItems = myListControl->selectedItems(); myCopyAction->setEnabled(!aItems.isEmpty()); + myDeleteAction->setEnabled(!aItems.isEmpty()); + + //myWorkshop->setSelected(>setSelected(getAttributeSelection()); } diff --git a/src/ModuleBase/ModuleBase_WidgetMultiSelector.h b/src/ModuleBase/ModuleBase_WidgetMultiSelector.h index d8df98aa3..9165161fc 100755 --- a/src/ModuleBase/ModuleBase_WidgetMultiSelector.h +++ b/src/ModuleBase/ModuleBase_WidgetMultiSelector.h @@ -85,6 +85,9 @@ protected slots: /// Slot for copy command in a list pop-up menu void onCopyItem(); + /// Slot for delete command in a list pop-up menu + void onDeleteItem(); + /// Slot is called on selection of list of selected items void onListSelection(); @@ -153,6 +156,7 @@ protected: /// An action for pop-up menu in a list control QAction* myCopyAction; + QAction* myDeleteAction; /// backup parameters of the model attribute. The class processes three types of attribute: /// Reference, RefAttr and Selection. Depending on the attribute type, only the attribute parameter -- 2.39.2