From bae3f70c4e95c5bff78d7994d04b1cc4dddbc407 Mon Sep 17 00:00:00 2001 From: mzn Date: Wed, 22 Oct 2014 12:00:55 +0000 Subject: [PATCH] Add duplicates check. --- src/HYDROGUI/HYDROGUI_CalculationDlg.cxx | 4 + src/HYDROGUI/HYDROGUI_CalculationOp.cxx | 19 +- src/HYDROGUI/HYDROGUI_PriorityTableModel.cxx | 176 +++++++++++++++---- src/HYDROGUI/HYDROGUI_PriorityTableModel.h | 22 ++- src/HYDROGUI/HYDROGUI_PriorityWidget.cxx | 85 +++++++-- src/HYDROGUI/HYDROGUI_PriorityWidget.h | 9 +- src/HYDROGUI/resources/HYDROGUI_msg_en.ts | 8 + 7 files changed, 261 insertions(+), 62 deletions(-) diff --git a/src/HYDROGUI/HYDROGUI_CalculationDlg.cxx b/src/HYDROGUI/HYDROGUI_CalculationDlg.cxx index 3406908a..08b27e22 100644 --- a/src/HYDROGUI/HYDROGUI_CalculationDlg.cxx +++ b/src/HYDROGUI/HYDROGUI_CalculationDlg.cxx @@ -91,6 +91,10 @@ void HYDROGUI_CalculationDlg::reset() // Activate the automatic mode setMode( HYDROData_CalculationCase::AUTOMATIC ); + + // Reset the priority widget state + QList anObjects; + myPriorityWidget->setObjects( anObjects ); } QWizardPage* HYDROGUI_CalculationDlg::createObjectsPage() { diff --git a/src/HYDROGUI/HYDROGUI_CalculationOp.cxx b/src/HYDROGUI/HYDROGUI_CalculationOp.cxx index 4cb4e9c8..79a96110 100644 --- a/src/HYDROGUI/HYDROGUI_CalculationOp.cxx +++ b/src/HYDROGUI/HYDROGUI_CalculationOp.cxx @@ -632,9 +632,10 @@ void HYDROGUI_CalculationOp::onNext( const int theIndex ) // automatic names generation for regions and zones myEditedObject->SetName( aNewCaseName ); - // Set objects in the specified order + // Set parameters for automatic mode int aMode = aPanel->getMode(); if ( aMode == HYDROData_CalculationCase::AUTOMATIC ) { + // Set objects in the specified order myEditedObject->RemoveGeometryObjects(); foreach ( const QString& aName, aPanel->getAllGeomObjects() ) { Handle(HYDROData_Object) anObject = Handle(HYDROData_Object)::DownCast( @@ -645,16 +646,16 @@ void HYDROGUI_CalculationOp::onNext( const int theIndex ) myEditedObject->AddGeometryObject( anObject ); } - } - aPanel->setMoveZonesEnabled( aMode == HYDROData_CalculationCase::MANUAL ); - // Set priority rules - myEditedObject->ClearRules(); - foreach ( const HYDROData_CustomRule& aRule, aPanel->getRules() ) { - myEditedObject->AddRule( aRule.Object1, aRule.Priority, - aRule.Object2, aRule.MergeType ); + // Set priority rules + myEditedObject->ClearRules(); + foreach ( const HYDROData_CustomRule& aRule, aPanel->getRules() ) { + myEditedObject->AddRule( aRule.Object1, aRule.Priority, + aRule.Object2, aRule.MergeType ); + } } - + aPanel->setMoveZonesEnabled( aMode == HYDROData_CalculationCase::MANUAL ); + if ( myEditedObject->IsMustBeUpdated() ) { myShowZones = true; diff --git a/src/HYDROGUI/HYDROGUI_PriorityTableModel.cxx b/src/HYDROGUI/HYDROGUI_PriorityTableModel.cxx index c0e1dacb..de7a41c8 100644 --- a/src/HYDROGUI/HYDROGUI_PriorityTableModel.cxx +++ b/src/HYDROGUI/HYDROGUI_PriorityTableModel.cxx @@ -85,7 +85,13 @@ QVariant HYDROGUI_PriorityTableModel::data( const QModelIndex &theIndex, int the } } else if ( theRole == Qt::UserRole ) { if ( aColumn == 0 || aColumn == 2 ) { - aVariant = getAvailableObjects(); + QStringList aNames; + HYDROData_CustomRule aRule = myRules.at( aRow ); + Handle(HYDROData_Object) aUsedObject = aColumn == 0 ? aRule.Object2 : aRule.Object1; + if ( !aUsedObject.IsNull() ) { + aNames = getAvailablePairs( aUsedObject ); + } + aVariant = aNames; } else if ( aColumn == 1 ) { QMap aMap; aMap.insert( priorityToString( LESS ), LESS ); @@ -129,13 +135,20 @@ bool HYDROGUI_PriorityTableModel::setData( const QModelIndex & theIndex, const Q } } if ( !anObject.IsNull() ) { + HYDROData_CustomRule anEditedRule = myRules[aRow]; + if ( aColumn == 0 ) { - myRules[aRow].Object1 = anObject; + anEditedRule.Object1 = anObject; } else { - myRules[aRow].Object2 = anObject; + anEditedRule.Object2 = anObject; + } + + if ( !isUsed( anEditedRule.Object1, anEditedRule.Object2 ) ) { + myRules[aRow] = anEditedRule; + aRes = true; + } else { + emit showError( tr("ALREADY_EXISTS") ); } - - aRes = true; } } else if ( aColumn == 1 ) { myRules[aRow].Priority = (HYDROData_PriorityType)theValue.toInt(); @@ -167,9 +180,9 @@ int HYDROGUI_PriorityTableModel::columnCount( const QModelIndex &theParent ) con */ void HYDROGUI_PriorityTableModel::setRules( const HYDROData_ListOfRules& theRules ) { + beginResetModel(); myRules = theRules; - - reset(); + endResetModel(); } /** @@ -224,6 +237,9 @@ void HYDROGUI_PriorityTableModel::setObjects( const QList anIter( myRules ); while ( anIter.hasNext() ) { HYDROData_CustomRule aRule = anIter.next(); @@ -233,56 +249,131 @@ void HYDROGUI_PriorityTableModel::setObjects( const QList> aRules; + foreach( const HYDROData_CustomRule& aRule, getRules() ) { + int anIndex1 = myObjects.indexOf( aRule.Object1 ); + int anIndex2 = myObjects.indexOf( aRule.Object2 ); + if ( anIndex1 >= 0 && anIndex2 >= 0 ) { + aRules << QPair( anIndex1, anIndex2 ); + aRules << QPair( anIndex2, anIndex1 ); + } + } + + // Try to find new pair of objects + Handle(HYDROData_Object) anObject1, anObject2; + + int aNbObjects = myObjects.count(); + for ( int anIndex1 = 0; anIndex1 < aNbObjects; anIndex1++ ) { + bool isFound = false; + + for ( int anIndex2 = 0; anIndex2 < aNbObjects; anIndex2++ ) { + if ( anIndex1 == anIndex2 ) { + continue; + } + + if ( !aRules.contains( QPair( anIndex1, anIndex2 ) ) ) { + anObject1 = myObjects.at( anIndex1 ); + anObject2 = myObjects.at( anIndex2 ); + isFound = true; + break; + } + } + + if ( isFound ) { + break; + } + } + + // Create a new rule + bool isCreated = false; + + if ( !anObject1.IsNull() && !anObject2.IsNull() ) { + HYDROData_CustomRule aNewRule; + aNewRule.Object1 = anObject1; + aNewRule.Object2 = anObject2; + aNewRule.Priority = LESS; + aNewRule.MergeType = HYDROData_Zone::Merge_ZMIN; + + beginResetModel(); + myRules << aNewRule; + endResetModel(); + + isCreated = true; } - HYDROData_CustomRule aNewRule; - aNewRule.Object1 = myObjects.at(0); - aNewRule.Object2 = myObjects.at(1); - aNewRule.Priority = LESS; - aNewRule.MergeType = HYDROData_Zone::Merge_ZMIN; + return isCreated; +} - myRules << aNewRule; +/** + Check if a new rule can be created. + @return true if a new rule could be created + */ +bool HYDROGUI_PriorityTableModel::canCreateNewRule() const +{ + int aNbObjects = myObjects.count(); - reset(); + return ( myRules.count() < (aNbObjects - 1)*aNbObjects/2 ); } /** */ bool HYDROGUI_PriorityTableModel::removeRows ( int theRow, int theCount, const QModelIndex & theParent ) { - bool aRes = false; + if ( myRules.isEmpty() || theRow < 0 || theRow >= myRules.count() ) { + return false; + } - if ( theRow + theCount <= myRules.count() ) { - for ( int i = 1; i <= theCount; i++ ) { - myRules.removeAt( theRow ); - } - aRes = true; - reset(); + int aLastRow = theRow + theCount - 1; + if ( aLastRow > myRules.count() ) { + aLastRow = myRules.count() - 1; + } + + beginRemoveRows( theParent, theRow, aLastRow ); + + // Remove the corresponding rules + for ( int i = 1; i <= theCount; i++ ) { + myRules.removeAt( theRow ); } + endRemoveRows(); + return true; } /** - Get available objects. + Remove all data from the model. + @return true if at least one row is removed + */ +bool HYDROGUI_PriorityTableModel::removeAll() +{ + return removeRows( 0, rowCount() ); +} + +/** + Get available pairs for the given object. + @param theObject the object @return the list of object names */ -QStringList HYDROGUI_PriorityTableModel::getAvailableObjects() const +QStringList HYDROGUI_PriorityTableModel::getAvailablePairs( const Handle(HYDROData_Object)& theObject ) const { QStringList aNames; foreach ( const Handle(HYDROData_Object) anObj, myObjects ) { - if ( !anObj.IsNull() ) { + if ( !anObj.IsNull() && anObj->GetName() != theObject->GetName() ) { aNames << anObj->GetName(); } } @@ -293,8 +384,9 @@ QStringList HYDROGUI_PriorityTableModel::getAvailableObjects() const /** Remove the rows. @params theRows the list of rows to remove + @return true if at least one row is removed */ -void HYDROGUI_PriorityTableModel::removeRows ( const QList theRows ) +bool HYDROGUI_PriorityTableModel::removeRows ( const QList theRows ) { QList aSortedRows = theRows; qSort( aSortedRows ); @@ -307,6 +399,8 @@ void HYDROGUI_PriorityTableModel::removeRows ( const QList theRows ) aNbRemoved++; } } + + return ( aNbRemoved > 0 ); } /** @@ -344,3 +438,25 @@ QString HYDROGUI_PriorityTableModel::mergeTypeToString( const int theMergeType ) return QString(); }; } + +/** + Check if the given pair of objects is already used. + @return true if the pair is used + */ +bool HYDROGUI_PriorityTableModel::isUsed( const Handle(HYDROData_Object)& theObj1, + const Handle(HYDROData_Object)& theObj2 ) const +{ + bool isUsed = false; + + foreach ( const HYDROData_CustomRule& aRule, myRules ) { + if ( ( aRule.Object1->GetName() == theObj1->GetName() && + aRule.Object2->GetName() == theObj2->GetName() ) || + ( aRule.Object1->GetName() == theObj2->GetName() && + aRule.Object2->GetName() == theObj1->GetName() ) ) { + isUsed = true; + break; + } + } + + return isUsed; +} \ No newline at end of file diff --git a/src/HYDROGUI/HYDROGUI_PriorityTableModel.h b/src/HYDROGUI/HYDROGUI_PriorityTableModel.h index bd113ac4..666d72c5 100644 --- a/src/HYDROGUI/HYDROGUI_PriorityTableModel.h +++ b/src/HYDROGUI/HYDROGUI_PriorityTableModel.h @@ -57,23 +57,31 @@ public: Qt::Orientation theOrientation, int theRole = Qt::DisplayRole ) const; - virtual bool removeRows ( int theRow, int theCount, const QModelIndex & theParent = QModelIndex() ); + virtual bool removeRows( int theRow, int theCount, const QModelIndex & theParent = QModelIndex() ); + + bool removeRows( const QList theRows ); + bool removeAll(); - void removeRows ( const QList theRows ); + void setObjects( const QList& theObjects ); void setRules( const HYDROData_ListOfRules& theObjects ); HYDROData_ListOfRules getRules() const; - void setObjects( const QList& theObjects ); - - void createNewRule(); - + bool createNewRule(); + bool canCreateNewRule() const; + protected: - QStringList getAvailableObjects() const; + bool isUsed( const Handle(HYDROData_Object)& theObj1, + const Handle(HYDROData_Object)& theObj2 ) const; + + QStringList getAvailablePairs( const Handle(HYDROData_Object)& theObject ) const; QString priorityToString( const int thePriority ) const; QString mergeTypeToString( const int theMergeType ) const; +signals: + void showError( const QString& theMsg ); + private: friend class test_HYDROGUI_PriorityTableModel; diff --git a/src/HYDROGUI/HYDROGUI_PriorityWidget.cxx b/src/HYDROGUI/HYDROGUI_PriorityWidget.cxx index 719503bb..f842733b 100644 --- a/src/HYDROGUI/HYDROGUI_PriorityWidget.cxx +++ b/src/HYDROGUI/HYDROGUI_PriorityWidget.cxx @@ -26,6 +26,8 @@ #include "HYDROData_PriorityQueue.h" +#include + #include #include #include @@ -113,7 +115,11 @@ void HYDROGUI_PriorityWidget::Delegate::setModelData( if ( aComboBox ) { int aColumn = theIndex.column(); if ( aColumn == 0 || aColumn == 2 ) { - theModel->setData( theIndex, aComboBox->currentText() ); + QString aCurrentText = theIndex.data( Qt::EditRole ).toString(); + QString aNewText = aComboBox->currentText(); + if ( aNewText != aCurrentText ) { + theModel->setData( theIndex, aNewText ); + } } else { theModel->setData( theIndex, aComboBox->itemData( aComboBox->currentIndex() ) ); } @@ -138,15 +144,17 @@ HYDROGUI_PriorityWidget::HYDROGUI_PriorityWidget( QWidget* theParent ) myAdd->setText( tr( "ADD" ) ); myRemove = new QToolButton; myRemove->setText( tr( "REMOVE" ) ); - myRemove->setEnabled( false ); - + myClear = new QToolButton; + myClear->setText( tr( "CLEAR_ALL" ) ); + // Table view myTable = new QTableView( this ); myTable->setItemDelegate( new Delegate( this ) ); myTable->setEditTriggers( QAbstractItemView::DoubleClicked | QAbstractItemView::SelectedClicked ); // Set the custom model - myTable->setModel( new HYDROGUI_PriorityTableModel() ); + HYDROGUI_PriorityTableModel* aModel = new HYDROGUI_PriorityTableModel(); + myTable->setModel( aModel ); // Layout // buttons @@ -154,16 +162,24 @@ HYDROGUI_PriorityWidget::HYDROGUI_PriorityWidget( QWidget* theParent ) aButtonsLayout->addWidget( myAdd ); aButtonsLayout->addWidget( myRemove ); aButtonsLayout->addStretch( 1 ); + aButtonsLayout->addWidget( myClear ); // main aMainLayout->addLayout( aButtonsLayout ); aMainLayout->addWidget( myTable ); + // Update controls + updateControls(); + // Connections connect( myAdd, SIGNAL( clicked() ), this, SLOT( onAddRule() ) ); connect( myRemove, SIGNAL( clicked() ), this, SLOT( onRemoveRule() ) ); + connect( myClear, SIGNAL( clicked() ), this, SLOT( onClearRules() ) ); + connect ( myTable->selectionModel(), SIGNAL( selectionChanged( QItemSelection, QItemSelection ) ), this, SLOT( onSelectionChanged() ) ); + + connect( aModel, SIGNAL( showError( const QString& ) ), this, SLOT( onShowError( const QString& ) ) ); } /** @@ -174,21 +190,21 @@ HYDROGUI_PriorityWidget::~HYDROGUI_PriorityWidget() } /** - Adds the new rule. + Add the new default constructed rule. */ void HYDROGUI_PriorityWidget::onAddRule() { HYDROGUI_PriorityTableModel* aModel = dynamic_cast( myTable->model() ); - if( aModel ) { - aModel->createNewRule(); + if ( aModel ) { + if (aModel->createNewRule()) { + updateControls(); + } } - myTable->resizeColumnsToContents(); - onSelectionChanged(); } /** - Removes the selected rule. + Remove the selected rule. */ void HYDROGUI_PriorityWidget::onRemoveRule() { @@ -202,10 +218,23 @@ void HYDROGUI_PriorityWidget::onRemoveRule() foreach ( const QModelIndex& anIndex, aSelectedIndexes ) { aRows << anIndex.row(); } - aModel->removeRows( aRows ); + + if ( aModel->removeRows( aRows ) ) { + updateControls(); + } + } +} + +/** + Clear all rules. + */ +void HYDROGUI_PriorityWidget::onClearRules() +{ + HYDROGUI_PriorityTableModel* aModel = + dynamic_cast( myTable->model() ); + if ( aModel && aModel->removeAll() ) { + updateControls(); } - myTable->resizeColumnsToContents(); - onSelectionChanged(); } /** @@ -217,6 +246,7 @@ void HYDROGUI_PriorityWidget::setObjects( const QList& dynamic_cast( myTable->model() ); if( aModel ) { aModel->setObjects( theObjects ); + updateControls(); } } @@ -241,14 +271,14 @@ HYDROData_ListOfRules HYDROGUI_PriorityWidget::getRules() const Set rules. @param theRules the list of rules */ -void HYDROGUI_PriorityWidget::setRules( const HYDROData_ListOfRules& theRules ) const +void HYDROGUI_PriorityWidget::setRules( const HYDROData_ListOfRules& theRules ) { HYDROGUI_PriorityTableModel* aModel = dynamic_cast( myTable->model() ); if( aModel ) { aModel->setRules( theRules ); + updateControls(); } - myTable->resizeColumnsToContents(); } /** @@ -258,4 +288,29 @@ void HYDROGUI_PriorityWidget::onSelectionChanged() { QModelIndexList aSelectedIndexes = myTable->selectionModel()->selectedRows(); myRemove->setEnabled( aSelectedIndexes.count() > 0 ); +} + +/** + Update GUI controls state. + */ +void HYDROGUI_PriorityWidget::updateControls() +{ + HYDROGUI_PriorityTableModel* aModel = + dynamic_cast( myTable->model() ); + if( aModel ) { + myAdd->setEnabled( aModel->canCreateNewRule() ); + bool isTableNotEmpty = aModel->rowCount() > 0; + myClear->setEnabled( isTableNotEmpty ); + if ( isTableNotEmpty ) { + myTable->resizeColumnsToContents(); + } + } + onSelectionChanged(); +} + +/** + Show error message. + */ +void HYDROGUI_PriorityWidget::onShowError( const QString& theMsg ) { + SUIT_MessageBox::critical( this, tr( "ERROR" ), theMsg ); } \ No newline at end of file diff --git a/src/HYDROGUI/HYDROGUI_PriorityWidget.h b/src/HYDROGUI/HYDROGUI_PriorityWidget.h index ff4ea338..39b45a3b 100644 --- a/src/HYDROGUI/HYDROGUI_PriorityWidget.h +++ b/src/HYDROGUI/HYDROGUI_PriorityWidget.h @@ -53,18 +53,25 @@ public: void setObjects( const QList& theObjects ); HYDROData_ListOfRules getRules() const; - void setRules( const HYDROData_ListOfRules& theRules ) const; + void setRules( const HYDROData_ListOfRules& theRules ); + +protected: + void updateControls(); protected slots: void onAddRule(); void onRemoveRule(); + void onClearRules(); void onSelectionChanged(); + void onShowError( const QString& theMsg ); + private: QTableView* myTable; ///< the table view QToolButton* myAdd; ///< the add rule button QToolButton* myRemove; ///< the remove rule button + QToolButton* myClear; ///< the clear all rules button }; #endif diff --git a/src/HYDROGUI/resources/HYDROGUI_msg_en.ts b/src/HYDROGUI/resources/HYDROGUI_msg_en.ts index 48a3a1fb..ee829ba2 100644 --- a/src/HYDROGUI/resources/HYDROGUI_msg_en.ts +++ b/src/HYDROGUI/resources/HYDROGUI_msg_en.ts @@ -2171,6 +2171,10 @@ Polyline should consist from one not closed curve. REMOVE Remove + + CLEAR_ALL + Clear all + @@ -2207,6 +2211,10 @@ Polyline should consist from one not closed curve. BATHYMETRY Bathymetry + + ALREADY_EXISTS + The selected objects combination already exists. + -- 2.39.2