X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModuleBase%2FModuleBase_WidgetMultiSelector.cpp;h=c74b323b83b6f038769f71032f5418ff79a0c24e;hb=acaa4d04df93d44ed6c093584aa7de2f7f86b5e3;hp=34d5d8a8ee8290af90ff7a3d43e3a52211d43475;hpb=a7f44a41bdf29e7bd978ff3b8c8bd514d1223be7;p=modules%2Fshaper.git diff --git a/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp b/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp index 34d5d8a8e..c74b323b8 100644 --- a/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp +++ b/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp @@ -1,3 +1,5 @@ +// Copyright (C) 2014-20xx CEA/DEN, EDF R&D + /* * ModuleBase_WidgetMultiSelector.cpp * @@ -9,11 +11,11 @@ #include #include #include +#include #include #include #include -#include #include @@ -24,6 +26,9 @@ #include #include #include +#include +#include +#include #include #include @@ -32,48 +37,90 @@ ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParen ModuleBase_IWorkshop* theWorkshop, const Config_WidgetAPI* theData, const std::string& theParentId) - : ModuleBase_ModelWidget(theParent, theData, theParentId), - myWorkshop(theWorkshop), myIsActive(false), myUseSubShapes(false) + : ModuleBase_WidgetValidated(theParent, theData, theParentId), + myWorkshop(theWorkshop), myIsActive(false) { - myMainWidget = new QWidget(theParent); - QGridLayout* aMainLay = new QGridLayout(myMainWidget); + QGridLayout* aMainLay = new QGridLayout(this); ModuleBase_Tools::adjustMargins(aMainLay); - QLabel* aTypeLabel = new QLabel(tr("Type"), myMainWidget); + QLabel* aTypeLabel = new QLabel(tr("Type"), this); aMainLay->addWidget(aTypeLabel, 0, 0); - myTypeCombo = new QComboBox(myMainWidget); + myTypeCombo = new QComboBox(this); // There is no sence to paramerize list of types while we can not parametrize selection mode - QString aTypesStr("Vertices Edges Faces Solids"); + + std::string aPropertyTypes = theData->getProperty("type_choice"); + QString aTypesStr = aPropertyTypes.c_str(); QStringList aShapeTypes = aTypesStr.split(' '); + myTypeCombo->addItems(aShapeTypes); aMainLay->addWidget(myTypeCombo, 0, 1); + // if the xml definition contains one type, the controls to select a type should not be shown + if (aShapeTypes.size() == 1) { + aTypeLabel->setVisible(false); + myTypeCombo->setVisible(false); + } - QLabel* aListLabel = new QLabel(tr("Selected objects:"), myMainWidget); - aMainLay->addWidget(aListLabel, 1, 0, 1, -1); + QLabel* aListLabel = new QLabel(tr("Selected objects:"), this); + aMainLay->addWidget(aListLabel, 1, 0); + // if the xml definition contains one type, an information label should be shown near to the latest + if (aShapeTypes.size() == 1) { + QString aLabelText = QString::fromStdString(theData->widgetLabel()); + QString aLabelIcon = QString::fromStdString(theData->widgetIcon()); + QLabel* aSelectedLabel = new QLabel(aLabelText, this); + if (!aLabelIcon.isEmpty()) + aSelectedLabel->setPixmap(QPixmap(aLabelIcon)); + aMainLay->addWidget(aSelectedLabel, 1, 1); + aMainLay->setColumnStretch(2, 1); + } - myListControl = new QListWidget(myMainWidget); + myListControl = new QListWidget(this); aMainLay->addWidget(myListControl, 2, 0, 2, -1); aMainLay->setRowStretch(2, 1); - aMainLay->addWidget(new QLabel(myMainWidget)); + aMainLay->addWidget(new QLabel(this)); //FIXME(sbh)??? aMainLay->setRowMinimumHeight(3, 20); - myMainWidget->setLayout(aMainLay); - //TODO: Move into the base class - myUseSubShapes = theData->getBooleanAttribute("use_subshapes", false); - //TODO_END + this->setLayout(aMainLay); connect(myTypeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onSelectionTypeChanged())); - activateSelection(true); + myCopyAction = new QAction(QIcon(":pictures/copy.png"), tr("Copy"), this); + myCopyAction->setShortcut(QKeySequence::Copy); + myCopyAction->setEnabled(false); + connect(myCopyAction, SIGNAL(triggered(bool)), SLOT(onCopyItem())); + myListControl->addAction(myCopyAction); + myListControl->setContextMenuPolicy(Qt::ActionsContextMenu); + connect(myListControl, SIGNAL(itemSelectionChanged()), SLOT(onListSelection())); } ModuleBase_WidgetMultiSelector::~ModuleBase_WidgetMultiSelector() { - activateSelection(false); + myIsActive = false; + activateShapeSelection(); +} + +//******************************************************************** +void ModuleBase_WidgetMultiSelector::activateCustom() +{ + ModuleBase_IViewer* aViewer = myWorkshop->viewer(); + connect(myWorkshop, SIGNAL(selectionChanged()), + this, SLOT(onSelectionChanged()), + Qt::UniqueConnection); + + myIsActive = true; + activateShapeSelection(); +} + +//******************************************************************** +void ModuleBase_WidgetMultiSelector::deactivate() +{ + disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged())); + myIsActive = false; + activateShapeSelection(); } //******************************************************************** -bool ModuleBase_WidgetMultiSelector::storeValue() const +bool ModuleBase_WidgetMultiSelector::storeValueCustom() const { + // the value is stored on the selection changed signal processing // A rare case when plugin was not loaded. if(!myFeature) return false; @@ -82,19 +129,12 @@ bool ModuleBase_WidgetMultiSelector::storeValue() const std::dynamic_pointer_cast(aData->attribute(attributeID())); if (aSelectionListAttr) { - aSelectionListAttr->clear(); // Store shapes type - TopAbs_ShapeEnum aCurrentType = - ModuleBase_WidgetShapeSelector::shapeType(myTypeCombo->currentText()); - aSelectionListAttr->setSelectionType((int) aCurrentType); - // Store selection in the attribute - foreach (GeomSelection aSelec, mySelection) { - aSelectionListAttr->append(aSelec.first, aSelec.second); - } - updateObject(myFeature); - return true; - } - return false; + TopAbs_ShapeEnum aCurrentType = + ModuleBase_WidgetShapeSelector::shapeType(myTypeCombo->currentText()); + aSelectionListAttr->setSelectionType(myTypeCombo->currentText().toStdString()); + } + return true; } //******************************************************************** @@ -108,25 +148,102 @@ bool ModuleBase_WidgetMultiSelector::restoreValue() std::dynamic_pointer_cast(aData->attribute(attributeID())); if (aSelectionListAttr) { - mySelection.clear(); // Restore shape type - TopAbs_ShapeEnum aShapeType = (TopAbs_ShapeEnum) aSelectionListAttr->selectionType(); - setCurrentShapeType(aShapeType); - // Restore selection in the list - for (int i = 0; i < aSelectionListAttr->size(); i++) { - AttributeSelectionPtr aSelectAttr = aSelectionListAttr->value(i); - mySelection.append(GeomSelection(aSelectAttr->context(), aSelectAttr->value())); - } - updateSelectionList(); + setCurrentShapeType( + ModuleBase_WidgetShapeSelector::shapeType(aSelectionListAttr->selectionType().c_str())); + updateSelectionList(aSelectionListAttr); return true; } return false; } //******************************************************************** -QWidget* ModuleBase_WidgetMultiSelector::getControl() const +void ModuleBase_WidgetMultiSelector::storeAttributeValue() { - return myMainWidget; + DataPtr aData = myFeature->data(); + AttributeSelectionListPtr aSelectionListAttr = + std::dynamic_pointer_cast(aData->attribute(attributeID())); + if (aSelectionListAttr.get() == NULL) + return; + + mySelectionType = aSelectionListAttr->selectionType(); + mySelection.clear(); + int aSize = aSelectionListAttr->size(); + for (int i = 0; i < aSelectionListAttr->size(); i++) { + AttributeSelectionPtr aSelectAttr = aSelectionListAttr->value(i); + mySelection.append(GeomSelection(aSelectAttr->context(), aSelectAttr->value())); + } +} + +//******************************************************************** +void ModuleBase_WidgetMultiSelector::restoreAttributeValue(bool/* theValid*/) +{ + DataPtr aData = myFeature->data(); + AttributeSelectionListPtr aSelectionListAttr = + std::dynamic_pointer_cast(aData->attribute(attributeID())); + if (aSelectionListAttr.get() == NULL) + return; + aSelectionListAttr->clear(); + + // Store shapes type + aSelectionListAttr->setSelectionType(mySelectionType); + + // Store selection in the attribute + int aSize = mySelection.size(); + foreach (GeomSelection aSelec, mySelection) { + aSelectionListAttr->append(aSelec.first, aSelec.second); + } +} + +//******************************************************************** +bool ModuleBase_WidgetMultiSelector::setSelectionCustom(const ModuleBase_ViewerPrs& thePrs) +{ + ResultPtr aResult; + if (!thePrs.owner().IsNull()) { + ObjectPtr anObject = myWorkshop->selection()->getSelectableObject(thePrs.owner()); + aResult = std::dynamic_pointer_cast(anObject); + } + else { + aResult = std::dynamic_pointer_cast(thePrs.object()); + } + + + if (myFeature) { + // We can not select a result of our feature + const std::list& aResList = myFeature->results(); + std::list::const_iterator aIt; + bool isSkipSelf = false; + for (aIt = aResList.cbegin(); aIt != aResList.cend(); ++aIt) { + if ((*aIt) == aResult) { + isSkipSelf = true; + break; + } + } + if(isSkipSelf) + return false; + } + + // if the result has the similar shap as the parameter shape, just the context is set to the + // selection list attribute. + DataPtr aData = myFeature->data(); + AttributeSelectionListPtr aSelectionListAttr = + std::dynamic_pointer_cast(aData->attribute(attributeID())); + + const TopoDS_Shape& aTDSShape = thePrs.shape(); + // if only result is selected, an empty shape is set to the model + if (aTDSShape.IsNull()) { + aSelectionListAttr->append(aResult, GeomShapePtr()); + } + else { + GeomShapePtr aShape = std::shared_ptr(new GeomAPI_Shape()); + aShape->setImpl(new TopoDS_Shape(aTDSShape)); + // We can not select a result of our feature + if (aShape->isEqual(aResult->shape())) + aSelectionListAttr->append(aResult, GeomShapePtr()); + else + aSelectionListAttr->append(aResult, aShape); + } + return true; } //******************************************************************** @@ -145,82 +262,38 @@ bool ModuleBase_WidgetMultiSelector::eventFilter(QObject* theObj, QEvent* theEve return ModuleBase_ModelWidget::eventFilter(theObj, theEvent); } -//******************************************************************** -void ModuleBase_WidgetMultiSelector::activateSelection(bool toActivate) -{ - myIsActive = toActivate; - if (myIsActive) { - connect(myWorkshop, SIGNAL(selectionChanged()), - this, SLOT(onSelectionChanged()), - Qt::UniqueConnection); - activateShapeSelection(); - } else { - disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged())); - myWorkshop->deactivateSubShapesSelection(); - } -} - //******************************************************************** void ModuleBase_WidgetMultiSelector::onSelectionTypeChanged() { activateShapeSelection(); QObjectPtrList anEmptyList; + // This method will call Selection changed event which will call onSelectionChanged + // To clear mySelection, myListControl and storeValue() + // So, we don't need to call it myWorkshop->setSelected(anEmptyList); - // Clear mySelection, myListControl and storeValue() - onSelectionChanged(); } //******************************************************************** void ModuleBase_WidgetMultiSelector::onSelectionChanged() { - ModuleBase_ISelection* aSelection = myWorkshop->selection(); - NCollection_List aSelectedShapes; //, aFilteredShapes; - std::list aOwnersList; - aSelection->selectedShapes(aSelectedShapes, aOwnersList); + QList aSelected = getSelectedEntitiesOrObjects(myWorkshop->selection()); - mySelection.clear(); - std::list::const_iterator aIt; - NCollection_List::Iterator aShpIt(aSelectedShapes); - GeomShapePtr aShape; - for (aIt = aOwnersList.cbegin(); aIt != aOwnersList.cend(); aShpIt.Next(), aIt++) { - ResultPtr aResult = std::dynamic_pointer_cast(*aIt); - if (myFeature) { - // We can not select a result of our feature - const std::list& aResList = myFeature->results(); - std::list::const_iterator aIt; - bool isSkipSelf = false; - for (aIt = aResList.cbegin(); aIt != aResList.cend(); ++aIt) { - if ((*aIt) == aResult) { - isSkipSelf = true; - break; - } + DataPtr aData = myFeature->data(); + AttributeSelectionListPtr aSelectionListAttr = + std::dynamic_pointer_cast(aData->attribute(attributeID())); + + aSelectionListAttr->clear(); + if (aSelected.size() > 0) { + foreach (ModuleBase_ViewerPrs aPrs, aSelected) { + if (isValidSelection(aPrs)) { + setSelectionCustom(aPrs); } - if(isSkipSelf) - continue; } - aShape = std::shared_ptr(new GeomAPI_Shape()); - aShape->setImpl(new TopoDS_Shape(aShpIt.Value())); - mySelection.append(GeomSelection(aResult, aShape)); } - updateSelectionList(); emit valuesChanged(); -} - -//******************************************************************** -void ModuleBase_WidgetMultiSelector::filterShapes(const NCollection_List& theShapesToFilter, - NCollection_List& theResult) -{ - if(myTypeCombo->count() == 0 || theShapesToFilter.IsEmpty()) - return; - TopAbs_ShapeEnum aReferenceType = - ModuleBase_WidgetShapeSelector::shapeType(myTypeCombo->currentText()); - NCollection_List::Iterator anIter(theShapesToFilter); - for (; anIter.More(); anIter.Next()) { - TopoDS_Shape aShape = anIter.Value(); - if (aShape.IsNull() || aShape.ShapeType() != aReferenceType) - continue; - theResult.Append(aShape); - } + // the updateObject method should be called to flush the updated sigal. The workshop listens it, + // calls validators for the feature and, as a result, updates the Apply button state. + updateObject(myFeature); } //******************************************************************** @@ -232,11 +305,13 @@ void ModuleBase_WidgetMultiSelector::setCurrentShapeType(const TopAbs_ShapeEnum aShapeTypeName = myTypeCombo->itemText(idx); TopAbs_ShapeEnum aRefType = ModuleBase_WidgetShapeSelector::shapeType(aShapeTypeName); if(aRefType == theShapeType && idx != myTypeCombo->currentIndex()) { - activateSelection(false); + myIsActive = false; + activateShapeSelection(); bool isBlocked = myTypeCombo->blockSignals(true); myTypeCombo->setCurrentIndex(idx); + myIsActive = true; myTypeCombo->blockSignals(isBlocked); - activateSelection(true); + activateShapeSelection(); break; } } @@ -244,32 +319,52 @@ void ModuleBase_WidgetMultiSelector::setCurrentShapeType(const TopAbs_ShapeEnum void ModuleBase_WidgetMultiSelector::activateShapeSelection() { - QString aNewType = myTypeCombo->currentText(); - QIntList aList; - aList.append(ModuleBase_WidgetShapeSelector::shapeType(aNewType)); - myWorkshop->activateSubShapesSelection(aList); + ModuleBase_IViewer* aViewer = myWorkshop->viewer(); + + if (myIsActive) { + QString aNewType = myTypeCombo->currentText(); + QIntList aList; + aList.append(ModuleBase_WidgetShapeSelector::shapeType(aNewType)); + myWorkshop->activateSubShapesSelection(aList); + } else { + myWorkshop->deactivateSubShapesSelection(); + } + + activateFilters(myWorkshop, myIsActive); } //******************************************************************** -void ModuleBase_WidgetMultiSelector::updateSelectionList() +void ModuleBase_WidgetMultiSelector::updateSelectionList(AttributeSelectionListPtr theList) { - QString aType; - if (myTypeCombo->currentText().toLower() == "vertices") - aType = "vertex"; - else if (myTypeCombo->currentText().toLower() == "edges") - aType = "edge"; - else if (myTypeCombo->currentText().toLower() == "faces") - aType = "face"; - else if (myTypeCombo->currentText().toLower() == "solids") - aType = "solid"; - myListControl->clear(); - int i = 1; - foreach (GeomSelection aSel, mySelection) { - QString aName(aSel.first->data()->name().c_str()); - aName += ":" + aType + QString("_%1").arg(i); - myListControl->addItem(aName); - i++; + for (int i = 0; i < theList->size(); i++) { + AttributeSelectionPtr aAttr = theList->value(i); + myListControl->addItem(aAttr->namingName().c_str()); } + // We have to call repaint because sometimes the List control is not updated myListControl->repaint(); } + +//******************************************************************** +void ModuleBase_WidgetMultiSelector::onCopyItem() +{ + QList aItems = myListControl->selectedItems(); + QString aRes; + foreach(QListWidgetItem* aItem, aItems) { + if (!aRes.isEmpty()) + aRes += "\n"; + aRes += aItem->text(); + } + if (!aRes.isEmpty()) { + QClipboard *clipboard = QApplication::clipboard(); + clipboard->setText(aRes); + } +} + +//******************************************************************** +void ModuleBase_WidgetMultiSelector::onListSelection() +{ + QList aItems = myListControl->selectedItems(); + myCopyAction->setEnabled(!aItems.isEmpty()); +} +