// Copyright (C) 2014-2022 CEA/DEN, EDF R&D, OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // // internal includes #include "RepairGUI_InspectObjectDlg.h" // GEOM includes #include #include #include #include // GUI includes #include #include #include #include #include #include #include #include #include #include #include // OCCT includes #include #include #include #include #include #include #include // Qt includes #include #include #include #include #include #include #include #include #include #include #include // Shape type definitions (values are equal to corresponding types of TopAbs_ShapeEnum). #define TYPE_FACE 4 #define TYPE_EDGE 6 #define TYPE_VERTEX 7 // Comparison type definitions #define COMPARE_GT 0 #define COMPARE_GE 1 #define COMPARE_LT 2 #define COMPARE_LE 3 // Default tolerance values #define DEFAULT_TOLERANCE_VALUE 1.e-07 //================================================================================= // class : RepairGUI_InspectObjectDlg::TreeWidgetItem // purpose : class for "Inspect Object" tree item creation //================================================================================= class RepairGUI_InspectObjectDlg::TreeWidgetItem : public QTreeWidgetItem { public: TreeWidgetItem(QTreeWidget*, const QStringList&, const TopoDS_Shape&, const Handle(SALOME_InteractiveObject)&, double = DEFAULT_TOLERANCE_VALUE, int = Type); TreeWidgetItem(QTreeWidgetItem*, const QStringList&, const TopoDS_Shape&, const QString&, double = DEFAULT_TOLERANCE_VALUE, int = Type); ~TreeWidgetItem(); bool isVisible(); void setVisible( bool, QIcon& ); TopoDS_Shape getShape() const; Handle(SALOME_InteractiveObject) getIO() const; double getTolerance() const; void setTolerance(double theTolerance); private: bool myIsVisible; TopoDS_Shape myShape; Handle(SALOME_InteractiveObject) myIO; double myTolerance; }; RepairGUI_InspectObjectDlg::TreeWidgetItem::TreeWidgetItem (QTreeWidget *view, const QStringList &strings, const TopoDS_Shape &shape, const Handle(SALOME_InteractiveObject) &io, double theTolerance, int type) : QTreeWidgetItem( view, strings, type ), myIsVisible( false ), myShape( shape ), myIO( io ), myTolerance (theTolerance) { } RepairGUI_InspectObjectDlg::TreeWidgetItem::TreeWidgetItem (QTreeWidgetItem *parent, const QStringList &strings, const TopoDS_Shape &shape, const QString &entry, double theTolerance, int type) : QTreeWidgetItem( parent, strings, type ), myIsVisible( false ), myShape( shape ), myTolerance (theTolerance) { myIO = new SALOME_InteractiveObject( entry.toUtf8(), "GEOM", "TEMP_IO" ); setFlags( flags() | Qt::ItemIsEditable ); } RepairGUI_InspectObjectDlg::TreeWidgetItem::~TreeWidgetItem() { } bool RepairGUI_InspectObjectDlg::TreeWidgetItem::isVisible() { return myIsVisible; } void RepairGUI_InspectObjectDlg::TreeWidgetItem::setVisible( bool isVisible, QIcon& icon ) { myIsVisible = isVisible; setIcon( 1, icon ); } TopoDS_Shape RepairGUI_InspectObjectDlg::TreeWidgetItem::getShape() const { return myShape; } Handle(SALOME_InteractiveObject) RepairGUI_InspectObjectDlg::TreeWidgetItem::getIO() const { return myIO; } double RepairGUI_InspectObjectDlg::TreeWidgetItem::getTolerance() const { return myTolerance; } void RepairGUI_InspectObjectDlg::TreeWidgetItem::setTolerance(double theTolerance) { myTolerance = theTolerance; } //================================================================================= // class : RepairGUI_InspectObjectDlg::Delegate // purpose : class for "Inspect Object" tree item editing //================================================================================= class RepairGUI_InspectObjectDlg::Delegate : public QItemDelegate { public: Delegate( QObject* = 0 ); ~Delegate(); void setEditorData( QWidget*, const QModelIndex& ) const; void setModelData( QWidget*, QAbstractItemModel*, const QModelIndex& ) const; QWidget* createEditor( QWidget*, const QStyleOptionViewItem&, const QModelIndex& ) const; }; RepairGUI_InspectObjectDlg::Delegate::Delegate( QObject* parent ) : QItemDelegate( parent ) { } RepairGUI_InspectObjectDlg::Delegate::~Delegate() { } void RepairGUI_InspectObjectDlg::Delegate::setEditorData( QWidget* editor, const QModelIndex& index ) const { QItemDelegate::setEditorData( editor, index ); editor->setProperty( "___name___", editor->property( "text" ) ); } void RepairGUI_InspectObjectDlg::Delegate::setModelData( QWidget* editor, QAbstractItemModel* model, const QModelIndex& index ) const { QString aNewName = editor->property( "text" ).toString(); if ( aNewName.trimmed().isEmpty() ) editor->setProperty( "text", editor->property( "___name___" ) ); QItemDelegate::setModelData( editor, model, index ); } QWidget* RepairGUI_InspectObjectDlg::Delegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const { return index.column() == 1 ? 0 : QItemDelegate::createEditor( parent, option, index ); } //================================================================================= // class : RepairGUI_InspectObjectDlg() // purpose : Constructs a RepairGUI_InspectObjectDlg which is a child of 'parent'. //================================================================================= RepairGUI_InspectObjectDlg::RepairGUI_InspectObjectDlg(GeometryGUI *theGeomGUI, SUIT_Desktop* parent ) : QDialog (parent), GEOMBase_Helper (parent), myGeomGUI (theGeomGUI), myTreeObjects (0), myFilteredTreeObjects (0), myCurrentTreeObjects (0), myEditMainShape (0), myTolFilterGrp (0), myShapeTypeBtnGrp (0), myComparisonCompo (0), myTolEdit (0), myMinTolValLabel (0), myMaxTolValLabel (0), myTreesLayout (0), myMaxTol (-1.), myMinTol (-1.), myIsSelectAll (false), myTransparency (0.0) { SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); QIcon iconSelect( resMgr->loadPixmap( "GEOM", tr( "ICON_SELECT" ) ) ); myVisible = QIcon( resMgr->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_VISIBLE" ) ) ); myInvisible = QIcon( resMgr->loadPixmap( "SUIT", tr( "ICON_DATAOBJ_INVISIBLE" ) ) ); QPixmap anImageVtx(resMgr->loadPixmap("GEOM", tr("ICON_OBJBROWSER_VERTEX"))); QPixmap anImageEdge(resMgr->loadPixmap("GEOM", tr("ICON_OBJBROWSER_EDGE"))); QPixmap anImageFace(resMgr->loadPixmap("GEOM", tr("ICON_OBJBROWSER_FACE"))); setWindowTitle( tr( "GEOM_INSPECT_OBJECT_TITLE" ) ); setAttribute( Qt::WA_DeleteOnClose ); myViewWindow = myGeomGUI->getApp()->desktop()->activeWindow(); QGridLayout* topLayout = new QGridLayout( this ); topLayout->setMargin( 11 ); topLayout->setSpacing( 6 ); /********************** Inspected Object **********************/ QHBoxLayout* mainShapeLayout = new QHBoxLayout(this); QLabel* label = new QLabel( tr( "GEOM_INSPECT_OBJECT_MAIN_SHAPE" ), this ); QPushButton* selBtn = new QPushButton(this); selBtn->setIcon( iconSelect ); myEditMainShape = new QLineEdit(this); myEditMainShape->setReadOnly(true); mainShapeLayout->addWidget( label ); mainShapeLayout->addWidget( selBtn ); mainShapeLayout->addWidget( myEditMainShape ); /********************** Tolerance filter **********************/ myTolFilterGrp = new QGroupBox (tr("GEOM_INSPECT_TOLERANCE_FILTER"), this); myShapeTypeBtnGrp = new QButtonGroup(myTolFilterGrp); // Filter on shape type QRadioButton *aVtx = new QRadioButton(tr("GEOM_VERTEX"), myTolFilterGrp); QRadioButton *anEdge = new QRadioButton(tr("GEOM_EDGE"), myTolFilterGrp); QRadioButton *aFace = new QRadioButton(tr("GEOM_FACE"), myTolFilterGrp); aVtx->setIcon(anImageVtx); anEdge->setIcon(anImageEdge); aFace->setIcon(anImageFace); myShapeTypeBtnGrp->addButton(aVtx, TYPE_VERTEX); myShapeTypeBtnGrp->addButton(anEdge, TYPE_EDGE); myShapeTypeBtnGrp->addButton(aFace, TYPE_FACE); // Filter on sub-shape tolerance QLabel *aTolLabel = new QLabel(tr("GEOM_TOLERANCE"), myTolFilterGrp); QLabel *aMinTolLabel = new QLabel(tr("GEOM_MIN"), myTolFilterGrp); QLabel *aMaxTolLabel = new QLabel(tr("GEOM_MAX"), myTolFilterGrp); QGridLayout *aFilterLayout = new QGridLayout(myTolFilterGrp); myMinTolValLabel = new QLabel(myTolFilterGrp); myMaxTolValLabel = new QLabel(myTolFilterGrp); myMinTolResetBtn = new QPushButton(tr("GEOM_INSPECT_RESET_MIN"), myTolFilterGrp); myMaxTolResetBtn = new QPushButton(tr("GEOM_INSPECT_RESET_MAX"), myTolFilterGrp); myComparisonCompo = new QComboBox(myTolFilterGrp); myTolEdit = new SalomeApp_DoubleSpinBox(myTolFilterGrp); myTolEdit->setMinimumWidth(120); aFilterLayout->addWidget(aVtx, 0, 0); aFilterLayout->addWidget(anEdge, 0, 1); aFilterLayout->addWidget(aFace, 0, 2); aFilterLayout->addWidget(aMaxTolLabel, 1, 0, Qt::AlignRight); aFilterLayout->addWidget(aTolLabel, 2, 0); aFilterLayout->addWidget(aMinTolLabel, 3, 0, Qt::AlignRight); aFilterLayout->addWidget(myMaxTolValLabel, 1, 1); aFilterLayout->addWidget(myComparisonCompo, 2, 1); aFilterLayout->addWidget(myMinTolValLabel, 3, 1); aFilterLayout->addWidget(myMaxTolResetBtn, 1, 2); aFilterLayout->addWidget(myTolEdit, 2, 2); aFilterLayout->addWidget(myMinTolResetBtn, 3, 2); aFilterLayout->setRowMinimumHeight(0, 30); myTolFilterGrp->setCheckable(true); /********************** Sub-objects trees **********************/ createTreeWidget(myTreeObjects); createTreeWidget(myFilteredTreeObjects); myTreesLayout = new QStackedLayout(this); myTreesLayout->addWidget(myTreeObjects); myTreesLayout->addWidget(myFilteredTreeObjects); /********************** Buttons **********************/ QVBoxLayout* buttonsLayout1 = new QVBoxLayout(this); QPushButton* buttonShow = new QPushButton( tr( "GEOM_INSPECT_OBJECT_SHOW" ), this ); QPushButton* buttonShowOnly = new QPushButton( tr( "GEOM_INSPECT_OBJECT_SHOW_ONLY" ), this ); QPushButton* buttonHide = new QPushButton( tr( "GEOM_INSPECT_OBJECT_HIDE" ), this ); QPushButton* buttonPublish = new QPushButton( tr( "GEOM_INSPECT_OBJECT_PUBLISH" ), this ); QPushButton* aShowAllBtn = new QPushButton(tr("SHOW_ALL_BTN"), this); QPushButton* aHideAllBtn = new QPushButton(tr("HIDE_ALL_BTN"), this); buttonsLayout1->addWidget( buttonShow ); buttonsLayout1->addWidget( buttonShowOnly ); buttonsLayout1->addWidget( buttonHide ); buttonsLayout1->addWidget( aShowAllBtn ); buttonsLayout1->addWidget( aHideAllBtn ); buttonsLayout1->addWidget( buttonPublish ); buttonsLayout1->addStretch(); QHBoxLayout* buttonsLayout2 = new QHBoxLayout(this); QPushButton* buttonClose = new QPushButton( tr( "GEOM_BUT_CLOSE" ), this ); QPushButton* buttonHelp = new QPushButton( tr( "GEOM_BUT_HELP" ), this ); buttonsLayout2->addWidget( buttonClose ); buttonsLayout2->addStretch(); buttonsLayout2->addWidget( buttonHelp ); topLayout->addLayout( mainShapeLayout, 0, 0 ); topLayout->addWidget( myTolFilterGrp, 1, 0); topLayout->addLayout( myTreesLayout, 2, 0 ); topLayout->addLayout( buttonsLayout1, 0, 1, 3, 1 ); topLayout->addLayout( buttonsLayout2, 3, 0, 1, 2 ); connect( selBtn, SIGNAL( clicked() ), this, SLOT( onEditMainShape() ) ); connect( buttonShow, SIGNAL( clicked() ), this, SLOT( clickOnShow() ) ); connect( buttonShowOnly, SIGNAL( clicked() ), this, SLOT( clickOnShowOnly() ) ); connect( buttonHide, SIGNAL( clicked() ), this, SLOT( clickOnHide() ) ); connect( buttonPublish, SIGNAL( clicked() ), this, SLOT( clickOnPublish() ) ); connect( buttonClose, SIGNAL( clicked() ), this, SLOT( reject() ) ); connect( buttonHelp, SIGNAL( clicked() ), this, SLOT( clickOnHelp() ) ); connect( aShowAllBtn, SIGNAL( clicked() ), this, SLOT( clickOnShowAll() ) ); connect( aHideAllBtn, SIGNAL( clicked() ), this, SLOT( clickOnHideAll() ) ); init(); } RepairGUI_InspectObjectDlg::~RepairGUI_InspectObjectDlg() { if ( myViewWindow ) onEditMainShape(); // restore initial parameters for viewer getDisplayer()->UnsetColor(); getDisplayer()->UnsetWidth(); // no need to delete child widgets, Qt does it all for us } //================================================================================= // function : createTreeWidget() // purpose : //================================================================================= void RepairGUI_InspectObjectDlg::createTreeWidget(QTreeWidget *&theTreeObjects) { theTreeObjects = new QTreeWidget(this); theTreeObjects->setColumnCount(2); QStringList columnNames; columnNames.append(tr("GEOM_INSPECT_OBJECT_NAME")); columnNames.append(""); theTreeObjects->setHeaderLabels(columnNames); QTreeWidgetItem* headerItem = new QTreeWidgetItem(columnNames); headerItem->setIcon(1, myInvisible); theTreeObjects->setHeaderItem(headerItem); theTreeObjects->header()->moveSection(1, 0); theTreeObjects->header()->setSectionsClickable(true); theTreeObjects->header()->setSectionsMovable(false); theTreeObjects->header()->setSectionResizeMode( 1, QHeaderView::ResizeToContents); theTreeObjects->setSelectionMode(QAbstractItemView::ExtendedSelection); theTreeObjects->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed); // set custom item delegate theTreeObjects->setItemDelegate(new Delegate(theTreeObjects)); } //================================================================================= // function : init() // purpose : initialize dialog data //================================================================================= void RepairGUI_InspectObjectDlg::init() { myTolFilterGrp->setChecked(false); myComparisonCompo->addItem(">", GEOMUtils::CC_GT); myComparisonCompo->addItem(">=", GEOMUtils::CC_GE); myComparisonCompo->addItem("<", GEOMUtils::CC_LT); myComparisonCompo->addItem("<=", GEOMUtils::CC_LE); initSpinBox(myTolEdit, 0., 100., DEFAULT_TOLERANCE_VALUE, "len_tol_precision"); myTolEdit->setValue(DEFAULT_TOLERANCE_VALUE); // Signals and slots connections initTreeWidget(myTreeObjects); initTreeWidget(myFilteredTreeObjects); myCurrentTreeObjects = myTreeObjects; myMaxTolResetBtn->setEnabled(false); myMinTolResetBtn->setEnabled(false); connect(myMinTolResetBtn, SIGNAL(clicked()), this, SLOT(clickOnResetToMin())); connect(myMaxTolResetBtn, SIGNAL(clicked()), this, SLOT(clickOnResetToMax())); connect(myShapeTypeBtnGrp, SIGNAL(buttonClicked(int)), this, SLOT(onInitFilteredData())); connect(myGeomGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog())); connect(myGeomGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(reject())); connect( myGeomGUI->getApp()->selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( onViewSelectionChanged() ) ); connect( myGeomGUI->getApp()->desktop(), SIGNAL( windowActivated( SUIT_ViewWindow* ) ), this, SLOT( onWindowActivated( SUIT_ViewWindow* ) ) ); // Connect signals and slots for filter group box elements. connect(myTolFilterGrp, SIGNAL(toggled(bool)), this, SLOT(onFilterToggled(bool))); connect(myComparisonCompo, SIGNAL(currentIndexChanged(int)), this, SLOT(onFilterData())); connect(myTolEdit, SIGNAL(valueChanged(double)), this, SLOT(onFilterData())); if ( myViewWindow ) connect( myViewWindow->getViewManager(), SIGNAL( deleteView( SUIT_ViewWindow* ) ), this, SLOT( onCloseView( SUIT_ViewWindow* ) ), Qt::UniqueConnection ); // Initialize the dialog with current selection. onViewSelectionChanged(); } //================================================================================= // function : initSpinBox() // purpose : //================================================================================= void RepairGUI_InspectObjectDlg::initSpinBox(SalomeApp_DoubleSpinBox* spinBox, double min, double max, double step, const char* quantity) { // Obtain precision from preferences SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); int aPrecision = resMgr->integerValue( "Geometry", quantity, 6 ); spinBox->setPrecision( aPrecision ); spinBox->setDecimals( qAbs( aPrecision ) ); // it's necessary to set decimals before the range setting, // by default Qt rounds boundaries to 2 decimals at setRange spinBox->setRange( min, max ); spinBox->setSingleStep( step ); // Add a hint for the user saying how to tune precision QString userPropName = QObject::tr( QString( "GEOM_PREF_%1" ).arg( quantity ).toLatin1().constData() ); spinBox->setProperty( "validity_tune_hint", QVariant( QObject::tr( "GEOM_PRECISION_HINT" ).arg( userPropName ) ) ); } //================================================================================= // function : initTreeWidget() // purpose : //================================================================================= void RepairGUI_InspectObjectDlg::initTreeWidget(QTreeWidget *theTreeObjects) { connect(theTreeObjects, SIGNAL(itemClicked (QTreeWidgetItem *, int)), this, SLOT(onItemClicked(QTreeWidgetItem *, int))); connect(theTreeObjects, SIGNAL(itemChanged (QTreeWidgetItem *, int)), this, SLOT(onItemChanged(QTreeWidgetItem *, int))); connect(theTreeObjects, SIGNAL(itemExpanded (QTreeWidgetItem *)), this, SLOT(onItemExpanded(QTreeWidgetItem *))); connect(theTreeObjects, SIGNAL(itemSelectionChanged()), this, SLOT(onItemSelectionChanged())); connect(theTreeObjects->header(), SIGNAL(sectionClicked(int)), this, SLOT(onHeaderClicked(int))); } //================================================================================= // function : enterEvent() // purpose : //================================================================================= void RepairGUI_InspectObjectDlg::enterEvent (QEvent*) { if (!myTolFilterGrp->isEnabled()) ActivateThisDialog(); } //================================================================================= // function : checkVisibleIcon() // purpose : set visible or invisible icon in the header of tree //================================================================================= void RepairGUI_InspectObjectDlg::checkVisibleIcon() { bool isInvisible = false; QTreeWidgetItemIterator it( myCurrentTreeObjects ); while ( *it ) { TreeWidgetItem* anItem = dynamic_cast(*it); if ( !anItem->isHidden() && !anItem->isVisible() ) { isInvisible = true; break; } ++it; } if ( isInvisible ) { myCurrentTreeObjects->headerItem()->setIcon( 1, myInvisible ); myIsSelectAll = false; } else { myCurrentTreeObjects->headerItem()->setIcon( 1, myVisible ); myIsSelectAll = true; } } //================================================================================= // function : addSubObjects() // purpose : add sub-objects to parent object in the tree //================================================================================= void RepairGUI_InspectObjectDlg::addSubObjects (TreeWidgetItem *theParentItem, const TopTools_IndexedMapOfShape &theIndices) { TreeWidgetItem* aMainItem = dynamic_cast( myTreeObjects->topLevelItem(0) ); TopoDS_Iterator it( theParentItem->getShape() ); for ( ; it.More(); it.Next() ) { TopoDS_Shape aSubShape = it.Value(); int anIndex = theIndices.FindIndex(aSubShape); QString anEntry = QString( "TEMP_" ) + aMainItem->getIO()->getEntry() + QString("_%1").arg( anIndex ); TreeWidgetItem* anItem = new TreeWidgetItem( theParentItem, QStringList(), aSubShape, anEntry); anItem->setVisible( false, myInvisible ); addSubObjects(anItem, theIndices); } } //================================================================================= // function : onInitFilteredData() // purpose : add sub-objects to parent object in the filtered tree //================================================================================= void RepairGUI_InspectObjectDlg::onInitFilteredData() { TreeWidgetItem *aMainItem = dynamic_cast(myFilteredTreeObjects->topLevelItem(0)); if (!aMainItem) { return; } // Remove the children. SALOME_ListIO aListOfIO; QTreeWidgetItemIterator it(aMainItem); while (*it) { TreeWidgetItem* anItem = dynamic_cast(*it); if (aMainItem != anItem && (anItem->flags() & Qt::ItemIsSelectable) && anItem->isVisible() && !anItem->isHidden()) { aListOfIO.Append(anItem->getIO()); } ++it; } myFilteredTreeObjects->clearSelection(); myFilteredTreeObjects->headerItem()->setIcon(1, myInvisible); getDisplayer()->Erase(aListOfIO); getDisplayer()->UpdateViewer(); // Delete child items. QList aListItems = aMainItem->takeChildren(); foreach (QTreeWidgetItem *anItem, aListItems) { delete anItem; } // Initialize the tree with a new list. TopoDS_Shape aShape = aMainItem->getShape(); TopAbs_ShapeEnum aShapeType = aShape.ShapeType(); myShapeTypeBtnGrp->button(TYPE_FACE)->setVisible(aShapeType < TYPE_FACE); myShapeTypeBtnGrp->button(TYPE_EDGE)->setVisible(aShapeType < TYPE_EDGE); myShapeTypeBtnGrp->button(TYPE_VERTEX)->setVisible(aShapeType < TYPE_VERTEX); int anId = myShapeTypeBtnGrp->checkedId(); myMaxTol = -RealLast(); myMinTol = RealLast(); if (anId != -1 && myShapeTypeBtnGrp->checkedButton()->isVisible()) { // Get sub-shapes TopTools_MapOfShape aMapFence; TopExp_Explorer anExp(aShape, (TopAbs_ShapeEnum)anId); TopTools_IndexedMapOfShape anIndices; TopExp::MapShapes(aShape, anIndices); for (; anExp.More(); anExp.Next()) { const TopoDS_Shape &aSubShape = anExp.Current(); if (aMapFence.Add(aSubShape)) { // Compute tolerance Standard_Real aTolerance = -1.; switch (aSubShape.ShapeType()) { case TYPE_FACE: aTolerance = BRep_Tool::Tolerance(TopoDS::Face(aSubShape)); break; case TYPE_EDGE: aTolerance = BRep_Tool::Tolerance(TopoDS::Edge(aSubShape)); break; case TYPE_VERTEX: aTolerance = BRep_Tool::Tolerance(TopoDS::Vertex(aSubShape)); break; default: break; } if (aTolerance < 0.) { continue; } if (aTolerance > myMaxTol) { myMaxTol = aTolerance; } if (aTolerance < myMinTol) { myMinTol = aTolerance; } int anIndex = anIndices.FindIndex(aSubShape); QString anEntry = QString( "TEMP_" ) + aMainItem->getIO()->getEntry() + QString::number(anIndex); TreeWidgetItem* anItem = new TreeWidgetItem(aMainItem, QStringList(), aSubShape, anEntry, aTolerance); anItem->setVisible( false, myInvisible ); } } } // Compose names of sub-items if the main item is expanded. if (aMainItem->isExpanded()) { onItemExpanded(aMainItem); } myMaxTolResetBtn->setEnabled(myMaxTol >= myMinTol); myMinTolResetBtn->setEnabled(myMaxTol >= myMinTol); if (myMaxTol < myMinTol) { myMinTol = DEFAULT_TOLERANCE_VALUE; myMaxTol = DEFAULT_TOLERANCE_VALUE; myMinTolValLabel->setText(QString::number(DEFAULT_TOLERANCE_VALUE)); myMaxTolValLabel->setText(QString::number(DEFAULT_TOLERANCE_VALUE)); myTolEdit->setValue(DEFAULT_TOLERANCE_VALUE); } else { myMinTolValLabel->setText(QString::number(myMinTol)); myMaxTolValLabel->setText(QString::number(myMaxTol)); if (GEOMUtils::CompareToleranceValues(myMinTol, myTolEdit->value()) == 1) { clickOnResetToMin(); } else if (GEOMUtils::CompareToleranceValues (myMaxTol, myTolEdit->value()) == -1) { clickOnResetToMax(); } else { onFilterData(); } } } //================================================================================= // function : onFilterData() // purpose : filter objects in the filtered tree //================================================================================= void RepairGUI_InspectObjectDlg::onFilterData() { TreeWidgetItem *aMainItem = dynamic_cast(myFilteredTreeObjects->topLevelItem(0)); if (!aMainItem) { return; } SALOME_ListIO aListOfIOToHide; QTreeWidgetItemIterator anIt(aMainItem); const int aCompValue = myComparisonCompo->itemData(myComparisonCompo->currentIndex()).toInt(); const double aTolValue = myTolEdit->value(); while (*anIt) { TreeWidgetItem* anItem = dynamic_cast(*anIt); if (aMainItem != anItem) { const bool isToFilter = !GEOMUtils::IsFitCondition ((GEOMUtils::ComparisonCondition) aCompValue, anItem->getTolerance(), aTolValue); if (isToFilter && !anItem->isHidden()) { if (anItem->isVisible()) { aListOfIOToHide.Append(anItem->getIO()); } anItem->setVisible(false, myInvisible); } anItem->setHidden(isToFilter); } ++anIt; } if (!aListOfIOToHide.IsEmpty()) { getDisplayer()->Erase(aListOfIOToHide); getDisplayer()->UpdateViewer(); } checkVisibleIcon(); } //================================================================================= // function : displayItem() // purpose : display sub-object of inspected object according its tree item //================================================================================= void RepairGUI_InspectObjectDlg::displayItem( TreeWidgetItem* theItem ) { GEOM_Displayer* aDisplayer = getDisplayer(); if ( theItem == myCurrentTreeObjects->topLevelItem(0) ) { aDisplayer->UnsetColor(); aDisplayer->UnsetWidth(); } else if ( aDisplayer->GetColor() != Quantity_NOC_VIOLET && aDisplayer->GetWidth() != 2.0 ) { aDisplayer->SetColor( Quantity_NOC_VIOLET ); aDisplayer->SetWidth( 2.0 ); } SALOME_Prs* aPrs = aDisplayer->buildSubshapePresentation( theItem->getShape(), theItem->getIO()->getEntry(), GEOM_Displayer::GetActiveView() ); if ( aPrs ) displayPreview( aPrs, true, false ); } //================================================================================= // function : setItemDisplayStatus() // purpose : set visible or invisible status for the same items in the tree //================================================================================= void RepairGUI_InspectObjectDlg::setItemDisplayStatus( TreeWidgetItem* theItem, bool theIsVisible ) { QTreeWidgetItemIterator it( myCurrentTreeObjects ); while (*it) { TreeWidgetItem* anItem = dynamic_cast(*it); if ( anItem->getShape().IsSame( theItem->getShape() ) ) anItem->setVisible( theIsVisible, theIsVisible ? myVisible : myInvisible ); ++it; } } //================================================================================= // function : setMainObjectTransparency() // purpose : set transparency for the inspected object //================================================================================= void RepairGUI_InspectObjectDlg::setMainObjectTransparency( double theTransparency ) { SUIT_ViewManager* aViewMan = myViewWindow->getViewManager(); SALOME_View* aView = dynamic_cast( aViewMan->getViewModel() ); SalomeApp_Study* aStudy = dynamic_cast( myGeomGUI->getApp()->activeStudy() ); TreeWidgetItem* aMainItem = dynamic_cast( myCurrentTreeObjects->topLevelItem(0) ); if (!aMainItem) { return; } aStudy->setObjectProperty( myViewWindow->getViewManager()->getGlobalId(), QString( aMainItem->getIO()->getEntry() ), GEOM::propertyName( GEOM::Transparency ), theTransparency ); if ( aView->isVisible( aMainItem->getIO() ) ) getDisplayer()->Redisplay( aMainItem->getIO(), true, aView ); } //================================================================================= // function : restoreParam() // purpose : restore initial parameters of the dialog and the viewer //================================================================================= void RepairGUI_InspectObjectDlg::restoreParam() { SUIT_ViewManager* aViewMan = myViewWindow->getViewManager(); SALOME_View* aView = dynamic_cast( aViewMan->getViewModel() ); GEOM_Displayer* aDisplayer = getDisplayer(); // restore initial parameters for viewer aDisplayer->UnsetColor(); aDisplayer->UnsetWidth(); // restore transparency of main object setMainObjectTransparency( myTransparency ); // erase sub-shapes TreeWidgetItem* aMainItem = dynamic_cast( myCurrentTreeObjects->topLevelItem(0) ); QTreeWidgetItemIterator it( myCurrentTreeObjects ); while (*it) { if ( *it != aMainItem ) { TreeWidgetItem* anItem = dynamic_cast(*it); aDisplayer->Erase( anItem->getIO(), false, false, aView ); anItem->setVisible( false, myInvisible ); } ++it; } } //================================================================================= // function : onEditMainShape() // purpose : called when selection button was clicked //================================================================================= void RepairGUI_InspectObjectDlg::onEditMainShape() { if ( myEditMainShape->text().isEmpty() || !myViewWindow ) return; restoreParam(); // restore initial parameters for dialog box myEditMainShape->setEnabled( true ); myEditMainShape->setText(""); myEditMainShape->setFocus(); myTreeObjects->clear(); myFilteredTreeObjects->clear(); } //================================================================================= // function : onItemClicked() // purpose : called when tree item was clicked //================================================================================= void RepairGUI_InspectObjectDlg::onItemClicked( QTreeWidgetItem* theItem, int theColumn ) { if ( theColumn!= 1 || !( theItem->flags() & Qt::ItemIsSelectable ) || !myViewWindow ) return; GEOM_Displayer* aDisplayer = getDisplayer(); TreeWidgetItem* anItem = dynamic_cast( theItem ); if ( anItem->isVisible() ) { aDisplayer->Erase( anItem->getIO(), false, true ); setItemDisplayStatus( anItem, false ); } else { displayItem( anItem ); setItemDisplayStatus( anItem, true ); } aDisplayer->UpdateViewer(); checkVisibleIcon(); } //================================================================================= // function : onItemChanged() // purpose : called when tree item was changed //================================================================================= void RepairGUI_InspectObjectDlg::onItemChanged( QTreeWidgetItem* theItem, int theColumn ) { if ( theColumn!= 0 || !( theItem->flags() & Qt::ItemIsEditable ) ) return; // rename the same items in the tree QTreeWidgetItemIterator it( myCurrentTreeObjects ); while ( *it ) { TreeWidgetItem* anItem = dynamic_cast(*it); if ( anItem->getShape().IsSame( dynamic_cast( theItem )->getShape() ) ) anItem->setText( 0, theItem->text(0) ); ++it; } } //================================================================================= // function : onItemExpanded() // purpose : called when tree item was expanded //================================================================================= void RepairGUI_InspectObjectDlg::onItemExpanded( QTreeWidgetItem* theItem ) { TreeWidgetItem* aMainItem = dynamic_cast( myCurrentTreeObjects->topLevelItem(0) ); GEOM::GEOM_Object_var aMainObject = GEOMBase::ConvertIOinGEOMObject( aMainItem->getIO() ); for ( int i = 0; i < theItem->childCount(); i++ ) { TreeWidgetItem* aSubItem = dynamic_cast( theItem->child(i) ); int anIndex = GEOMBase::GetIndex( aSubItem->getShape(), aMainItem->getShape() ); if ( aSubItem->text(0).isEmpty() ) { char* aName = aMainObject->GetSubShapeName( anIndex ); if ( !QString( aName ).isEmpty() ) aSubItem->setText( 0, QString( aName ) ); else aSubItem->setText( 0, QString("%1_%2").arg( GEOMBase::TypeName( aSubItem->getShape().ShapeType(), true ) ).arg( anIndex ) ); } } } //================================================================================= // function : onItemSelectionChanged() // purpose : called when tree item was selected //================================================================================= void RepairGUI_InspectObjectDlg::onItemSelectionChanged() { if ( !myViewWindow ) return; QList listItem = myCurrentTreeObjects->selectedItems(); SALOME_ListIO aSelected; for ( int i = 0; i < listItem.size(); i++ ) { TreeWidgetItem* anItem = dynamic_cast( listItem.at(i) ); aSelected.Append( anItem->getIO() ); } myGeomGUI->getApp()->selectionMgr()->setSelectedObjects( aSelected ); } //================================================================================= // function : onHeaderClicked() // purpose : called when header item of tree was clicked //================================================================================= void RepairGUI_InspectObjectDlg::onHeaderClicked( int theColumn ) { if ( theColumn != 1 || !myViewWindow ) return; GEOM_Displayer* aDisplayer = getDisplayer(); if ( myIsSelectAll ) { myIsSelectAll = false; myCurrentTreeObjects->headerItem()->setIcon( 1, myInvisible ); SALOME_ListIO aListOfIO; QTreeWidgetItemIterator it( myCurrentTreeObjects ); while ( *it ) { TreeWidgetItem* anItem = dynamic_cast(*it); if ( !anItem->isHidden() && ( anItem->flags() & Qt::ItemIsSelectable ) && anItem->isVisible() ) { aListOfIO.Append( anItem->getIO() ); anItem->setVisible( false, myInvisible ); } ++it; } aDisplayer->Erase( aListOfIO ); } else { myIsSelectAll = true; myCurrentTreeObjects->headerItem()->setIcon( 1, myVisible ); QTreeWidgetItemIterator it( myCurrentTreeObjects ); while ( *it ) { TreeWidgetItem* anItem = dynamic_cast(*it); if ( !anItem->isHidden() && ( anItem->flags() & Qt::ItemIsSelectable ) && !anItem->isVisible() ) { displayItem( anItem ); anItem->setVisible( true, myVisible ); } ++it; } } aDisplayer->UpdateViewer(); } //================================================================================= // function : onViewSelectionChanged() // purpose : called when selection of object browser was changed //================================================================================= void RepairGUI_InspectObjectDlg::onViewSelectionChanged() { if (!myEditMainShape->isEnabled()) return; //get shape from selection SALOME_ListIO selected; myGeomGUI->getApp()->selectionMgr()->selectedObjects(selected); if ( selected.Extent() != 1 ) return; if ( !myViewWindow ) { SUIT_ViewManager* occVm = myGeomGUI->getApp()->getViewManager( OCCViewer_Viewer::Type(), true ); myViewWindow = occVm->getActiveView(); connect( occVm, SIGNAL( deleteView( SUIT_ViewWindow* ) ), this, SLOT( onCloseView( SUIT_ViewWindow* ) ), Qt::UniqueConnection ); } TopoDS_Shape aShape = GEOMBase::GetTopoFromSelection( selected ); if ( aShape.IsNull() ) return; Handle(SALOME_InteractiveObject) anIO = selected.First(); GEOM::GEOM_Object_var anObject = GEOMBase::ConvertIOinGEOMObject( anIO ); QString aName = anObject->GetName(); CORBA::String_var anEntry = anObject->GetStudyEntry(); myEditMainShape->setText( aName ); myEditMainShape->setEnabled( false ); // remember initial transparency value SalomeApp_Study* aStudy = dynamic_cast( myGeomGUI->getApp()->activeStudy() ); QVariant v = aStudy->getObjectProperty( myViewWindow->getViewManager()->getGlobalId(), QString( anEntry.in() ), GEOM::propertyName( GEOM::Transparency ), myTransparency ); if ( v.canConvert( QVariant::Double ) ) myTransparency = v.toDouble(); TreeWidgetItem* anItem = new TreeWidgetItem (myTreeObjects, QStringList() << aName, aShape, anIO); TreeWidgetItem* anItemFiltered = new TreeWidgetItem (myFilteredTreeObjects, QStringList() << aName, aShape, anIO); if ( getDisplayer()->IsDisplayed( anEntry.in() ) ) { anItem->setVisible( true, myVisible ); anItemFiltered->setVisible( true, myVisible ); } else { anItem->setVisible( false, myInvisible ); anItemFiltered->setVisible( false, myInvisible ); } setMainObjectTransparency( 0.5 ); // add sub-objects in the tree TopTools_IndexedMapOfShape anIndices; TopExp::MapShapes(aShape, anIndices); addSubObjects(anItem, anIndices); onInitFilteredData(); updateViewer(false); // check icon for tree header checkVisibleIcon(); } //================================================================================= // function : onWindowActivated() // purpose : called when other window was activated //================================================================================= void RepairGUI_InspectObjectDlg::onWindowActivated( SUIT_ViewWindow* theViewWindow ) { if ( myViewWindow ) restoreParam(); connect( theViewWindow->getViewManager(), SIGNAL( deleteView( SUIT_ViewWindow* ) ), this, SLOT( onCloseView( SUIT_ViewWindow* ) ), Qt::UniqueConnection ); if ( theViewWindow->getViewManager()->getType() != OCCViewer_Viewer::Type() && theViewWindow->getViewManager()->getType() != SVTK_Viewer::Type() ) { myViewWindow = 0; return; } myViewWindow = theViewWindow; if ( myCurrentTreeObjects->topLevelItemCount() > 0 ) { setMainObjectTransparency( 0.5 ); TreeWidgetItem* aMainItem = dynamic_cast( myCurrentTreeObjects->topLevelItem(0) ); if ( getDisplayer()->IsDisplayed( aMainItem->getIO()->getEntry() ) ) aMainItem->setVisible( true, myVisible ); else aMainItem->setVisible( false, myInvisible ); } checkVisibleIcon(); } //================================================================================= // function : onCloseView() // purpose : called when last view was closed //================================================================================= void RepairGUI_InspectObjectDlg::onCloseView( SUIT_ViewWindow* ) { if ( myGeomGUI->getApp()->desktop()->windows().size() == 0 ) { restoreParam(); myViewWindow = 0; } } //================================================================================= // function : clickOnShow() // purpose : called when "Show selected" button was clicked //================================================================================= void RepairGUI_InspectObjectDlg::clickOnShow() { if ( !myViewWindow ) return; QList listItem = myCurrentTreeObjects->selectedItems(); for ( int i = 0; i < listItem.size(); i++ ) { TreeWidgetItem* anItem = dynamic_cast( listItem.at(i) ); if ( !anItem->isVisible() ) { displayItem( anItem ); setItemDisplayStatus( anItem, true ); } } getDisplayer()->UpdateViewer(); checkVisibleIcon(); } //================================================================================= // function : clickOnShowOnly() // purpose : called when "Show only selected" button was clicked //================================================================================= void RepairGUI_InspectObjectDlg::clickOnShowOnly() { if ( !myViewWindow ) return; SALOME_ListIO aListOfIO; QTreeWidgetItemIterator it( myCurrentTreeObjects ); while ( *it ) { TreeWidgetItem* anItem = dynamic_cast(*it); if ( !anItem->isHidden() && ( anItem->flags() & Qt::ItemIsSelectable ) && anItem->isVisible() ) { aListOfIO.Append( anItem->getIO() ); anItem->setVisible( false, myInvisible ); } ++it; } getDisplayer()->Erase( aListOfIO ); clickOnShow(); } //================================================================================= // function : clickOnHide() // purpose : called when "Hide selected" button was clicked //================================================================================= void RepairGUI_InspectObjectDlg::clickOnHide() { if ( !myViewWindow ) return; QList listItem = myCurrentTreeObjects->selectedItems(); for ( int i = 0; i < listItem.size(); i++ ) { TreeWidgetItem* anItem = dynamic_cast( listItem.at(i) ); if ( anItem->isVisible() ) { getDisplayer()->Erase( anItem->getIO(), false, false ); setItemDisplayStatus( anItem, false ); } } getDisplayer()->UpdateViewer(); checkVisibleIcon(); } //================================================================================= // function : clickOnPublish() // purpose : called when "Publish selected" button was clicked //================================================================================= void RepairGUI_InspectObjectDlg::clickOnPublish() { // find main object TreeWidgetItem* aMainItem = dynamic_cast( myCurrentTreeObjects->topLevelItem(0) ); if (!aMainItem) { return; } GEOM::GEOM_Object_var aMainObject = GEOMBase::ConvertIOinGEOMObject( aMainItem->getIO() ); // find unique indices of selected objects QList selectedItems = myCurrentTreeObjects->selectedItems(); QMap< int, QString > anIndices; GEOM::ListOfLong_var anArray = new GEOM::ListOfLong; anArray->length( selectedItems.size() ); int j = 0; for ( int i = 0; i < selectedItems.size(); i++ ) { TreeWidgetItem* anItem = dynamic_cast( selectedItems.at(i) ); int anIndex = GEOMBase::GetIndex( anItem->getShape(), aMainItem->getShape() ); if ( anIndices.find( anIndex ) == anIndices.end() && anItem != aMainItem ) { anIndices[ anIndex ] = anItem->text(0); anArray[j++] = anIndex; } } anArray->length(j); // get selected sub-shapes GEOM::GEOM_IShapesOperations_var anOper = getGeomEngine()->GetIShapesOperations(); GEOM::ListOfGO_var aList = anOper->MakeSubShapes( aMainObject, anArray ); // publish sub-shapes for ( int i = 0; i < (int)aList->length(); i++ ) GeometryGUI::GetGeomGen()->AddInStudy( aList[i], anIndices.values().at(i).toStdString().c_str(), aMainObject ); updateObjBrowser(); } //================================================================================= // function : clickOnHelp() // purpose : called when Help button was clicked to open a help page //================================================================================= void RepairGUI_InspectObjectDlg::clickOnHelp() { myGeomGUI->getApp()->onHelpContextModule( "GEOM", "inspect_object_operation_page.html" ); } //================================================================================= // function : clickOnResetToMin() // purpose : called when Reset button was clicked to reset tolerance filter to minimal value. //================================================================================= void RepairGUI_InspectObjectDlg::clickOnResetToMin() { if (myMinTol >= myTolEdit->minimum() && myMinTol <= myTolEdit->maximum()) { myTolEdit->setValue(myMinTol); } } //================================================================================= // function : clickOnResetToMax() // purpose : called when Reset button was clicked to reset tolerance filter to maximal value. //================================================================================= void RepairGUI_InspectObjectDlg::clickOnResetToMax() { if (myMaxTol >= myTolEdit->minimum() && myMaxTol <= myTolEdit->maximum()) { myTolEdit->setValue(myMaxTol); } } //================================================================================= // function : clickOnShowAll() // purpose : called when Help button was clicked to show all shapes //================================================================================= void RepairGUI_InspectObjectDlg::clickOnShowAll() { myIsSelectAll = false; onHeaderClicked(1); } //================================================================================= // function : clickOnHideAll() // purpose : called when Help button was clicked to hide all shapes //================================================================================= void RepairGUI_InspectObjectDlg::clickOnHideAll() { myIsSelectAll = true; onHeaderClicked(1); } //================================================================================= // function : DeactivateActiveDialog() // purpose : //================================================================================= void RepairGUI_InspectObjectDlg::DeactivateActiveDialog() { setEnabled(false); disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0); myGeomGUI->SetActiveDialogBox(0); globalSelection(); erasePreview(); } //================================================================================= // function : ActivateThisDialog() // purpose : //================================================================================= void RepairGUI_InspectObjectDlg::ActivateThisDialog() { /* Emit a signal to deactivate the active dialog */ myGeomGUI->EmitSignalDeactivateDialog(); setEnabled(true); myGeomGUI->SetActiveDialogBox( (QDialog*)this ); connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), this, SLOT(onViewSelectionChanged())); updateViewer(false); } //================================================================================= // function : onFilterToggled() // purpose : //================================================================================= void RepairGUI_InspectObjectDlg::onFilterToggled(bool isOn) { if (isOn) { myCurrentTreeObjects = myFilteredTreeObjects; myTreesLayout->setCurrentIndex(1); } else { myCurrentTreeObjects = myTreeObjects; myTreesLayout->setCurrentIndex(0); } updateViewer(true); } //================================================================================= // function : updateViewer() // purpose : //================================================================================= void RepairGUI_InspectObjectDlg::updateViewer(const bool theIsHideOtherTree) { GEOM_Displayer *aDisplayer = getDisplayer(); if (theIsHideOtherTree) { QTreeWidget *aTreeToHide = myCurrentTreeObjects == myTreeObjects ? myFilteredTreeObjects: myTreeObjects; // Hide the objects of disappeared tree, do not switch off flags. SALOME_ListIO aListOfIO; QTreeWidgetItemIterator it(aTreeToHide); while (*it) { TreeWidgetItem* anItem = dynamic_cast(*it); if ((anItem->flags() & Qt::ItemIsSelectable) && anItem->isVisible() && !anItem->isHidden()) { aListOfIO.Append(anItem->getIO()); } ++it; } aDisplayer->Erase(aListOfIO); } // Show the objects that are marked as shown in the appeared tree. QTreeWidgetItemIterator it2(myCurrentTreeObjects); while (*it2) { TreeWidgetItem* anItem = dynamic_cast(*it2); if ((anItem->flags() & Qt::ItemIsSelectable) && anItem->isVisible() && !anItem->isHidden()) { displayItem(anItem); } ++it2; } aDisplayer->UpdateViewer(); }