Salome HOME
Add duplicates check.
authormzn <mzn@opencascade.com>
Wed, 22 Oct 2014 12:00:55 +0000 (12:00 +0000)
committermzn <mzn@opencascade.com>
Wed, 22 Oct 2014 12:00:55 +0000 (12:00 +0000)
src/HYDROGUI/HYDROGUI_CalculationDlg.cxx
src/HYDROGUI/HYDROGUI_CalculationOp.cxx
src/HYDROGUI/HYDROGUI_PriorityTableModel.cxx
src/HYDROGUI/HYDROGUI_PriorityTableModel.h
src/HYDROGUI/HYDROGUI_PriorityWidget.cxx
src/HYDROGUI/HYDROGUI_PriorityWidget.h
src/HYDROGUI/resources/HYDROGUI_msg_en.ts

index 3406908ad58f3b31b4ba6728315076c980fec032..08b27e22ff9c04b21168a49dee6af61c75d44f59 100644 (file)
@@ -91,6 +91,10 @@ void HYDROGUI_CalculationDlg::reset()
 
   // Activate the automatic mode
   setMode( HYDROData_CalculationCase::AUTOMATIC );
+
+  // Reset the priority widget state
+  QList<Handle(HYDROData_Object)> anObjects;
+  myPriorityWidget->setObjects( anObjects );
 }
 
 QWizardPage* HYDROGUI_CalculationDlg::createObjectsPage() {
index 4cb4e9c85299ce62e45aed1d1376b312114b151a..79a9611092b81d4b3a1fe2d5c9ebce17470ffc74 100644 (file)
@@ -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;
index c0e1dacbfd2ea5b4edd6256e413c944c9371b5b5..de7a41c87e397a91ceea8f6662f2a4948fb44f4c 100644 (file)
@@ -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<QString, QVariant> 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<Handle(HYDROData_Objec
 {
   myObjects = theObjects;
 
+  beginResetModel();
+
+  // Remove rules which use objects which are no longer available
   QMutableListIterator<HYDROData_CustomRule> anIter( myRules );
   while ( anIter.hasNext() ) {
     HYDROData_CustomRule aRule = anIter.next();
@@ -233,56 +249,131 @@ void HYDROGUI_PriorityTableModel::setObjects( const QList<Handle(HYDROData_Objec
     }
   }
 
-  reset();
+  endResetModel();
 }
 
 /**
- Create new rule. 
+ Create new rule.
+ @return true if a rule has been created successfully
  */
-void HYDROGUI_PriorityTableModel::createNewRule() 
+bool HYDROGUI_PriorityTableModel::createNewRule() 
 {
-  if ( myObjects.count() < 2 ) {
-    return;
+  if ( !canCreateNewRule() ) {
+    return false;
+  }
+
+  // Existing pairs of object indexes
+  QList<QPair<int, int>> 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<int, int>( anIndex1, anIndex2 );
+      aRules << QPair<int, int>( 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<int, int>( 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<int> theRows )
+bool HYDROGUI_PriorityTableModel::removeRows ( const QList<int> theRows )
 {
   QList<int> aSortedRows = theRows;
   qSort( aSortedRows );
@@ -307,6 +399,8 @@ void HYDROGUI_PriorityTableModel::removeRows ( const QList<int> 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
index bd113ac47616b680b30ce43581cb9d88d1de8c73..666d72c58dc2736b8afa6d3332031ba6dcf5cd5b 100644 (file)
@@ -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<int> theRows );
+  bool removeAll();
 
-  void removeRows ( const QList<int> theRows );
+  void setObjects( const QList<Handle(HYDROData_Object)>& theObjects );
 
   void setRules( const HYDROData_ListOfRules& theObjects );
   HYDROData_ListOfRules getRules() const;
 
-  void setObjects( const QList<Handle(HYDROData_Object)>& 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;
 
index 719503bb7d33627155db387c7c6fc05926ccfde2..f842733bad178838730b735016613710340e9610 100644 (file)
@@ -26,6 +26,8 @@
 
 #include "HYDROData_PriorityQueue.h"
 
+#include <SUIT_MessageBox.h>
+
 #include <QComboBox>
 #include <QLayout>
 #include <QStyledItemDelegate>
@@ -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<HYDROGUI_PriorityTableModel*>( 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<HYDROGUI_PriorityTableModel*>( myTable->model() );
+  if ( aModel && aModel->removeAll() ) {
+    updateControls();
   }
-  myTable->resizeColumnsToContents();
-  onSelectionChanged();
 }
 
 /**
@@ -217,6 +246,7 @@ void HYDROGUI_PriorityWidget::setObjects( const QList<Handle(HYDROData_Object)>&
     dynamic_cast<HYDROGUI_PriorityTableModel*>( 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<HYDROGUI_PriorityTableModel*>( 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<HYDROGUI_PriorityTableModel*>( 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
index ff4ea3381d5d035bce19633098e6ff78d3b33978..39b45a3b2112beb67fc5b42b06fbd9eb29df1780 100644 (file)
@@ -53,18 +53,25 @@ public:
   void setObjects( const QList<Handle(HYDROData_Object)>& 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
index 48a3a1fbc1aca95d3bda59482e2ef9cba2f2d842..ee829ba2f1877689602145c2bb7c52d2878bfeff 100644 (file)
@@ -2171,6 +2171,10 @@ Polyline should consist from one not closed curve.</translation>
       <source>REMOVE</source>
       <translation>Remove</translation>
     </message>
+    <message>
+      <source>CLEAR_ALL</source>
+      <translation>Clear all</translation>
+    </message>
   </context>
   
   <context>
@@ -2207,6 +2211,10 @@ Polyline should consist from one not closed curve.</translation>
       <source>BATHYMETRY</source>
       <translation>Bathymetry</translation>
     </message>
+    <message>
+      <source>ALREADY_EXISTS</source>
+      <translation>The selected objects combination already exists.</translation>
+    </message>
   </context>
 
 </TS>