1 // Copyright (C) 2014-2015 EDF-R&D
2 // This library is free software; you can redistribute it and/or
3 // modify it under the terms of the GNU Lesser General Public
4 // License as published by the Free Software Foundation; either
5 // version 2.1 of the License, or (at your option) any later version.
7 // This library is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 // Lesser General Public License for more details.
12 // You should have received a copy of the GNU Lesser General Public
13 // License along with this library; if not, write to the Free Software
14 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #include "HYDROGUI_PriorityTableModel.h"
21 #include <HYDROGUI_DataObject.h>
25 @param theParent the parent object
27 HYDROGUI_PriorityTableModel::HYDROGUI_PriorityTableModel( QObject* theParent )
28 : QAbstractTableModel( theParent ),
36 HYDROGUI_PriorityTableModel::~HYDROGUI_PriorityTableModel()
42 Qt::ItemFlags HYDROGUI_PriorityTableModel::flags( const QModelIndex & theIndex ) const
44 return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled;
49 QVariant HYDROGUI_PriorityTableModel::data( const QModelIndex &theIndex, int theRole ) const
53 int aRow = theIndex.row();
54 int aColumn = theIndex.column();
56 if ( !theIndex.isValid() || aRow > myRules.size() ) {
60 if ( theRole == Qt::DisplayRole ) {
61 HYDROData_CustomRule aRule = myRules.at(aRow);
64 aVariant = aRule.Object1->GetName();
65 } else if ( aColumn == 1 ) {
66 aVariant = priorityToString( aRule.Priority );
67 } else if ( aColumn == 2 ) {
68 aVariant = aRule.Object2->GetName();
69 } else if ( aColumn == 3 ) {
70 aVariant = mergeTypeToString( aRule.MergeType );
72 } else if ( theRole == Qt::EditRole ) {
73 HYDROData_CustomRule aRule = myRules.at(aRow);
76 aVariant = aRule.Object1->GetName();
77 } else if ( aColumn == 1 ) {
78 aVariant = aRule.Priority;
79 } else if ( aColumn == 2 ) {
80 aVariant = aRule.Object2->GetName();
81 } else if ( aColumn == 3 ) {
82 aVariant = aRule.MergeType;
84 } else if ( theRole == Qt::UserRole ) {
85 if ( aColumn == 0 || aColumn == 2 ) {
87 HYDROData_CustomRule aRule = myRules.at( aRow );
88 Handle(HYDROData_Entity) aUsedObject = aColumn == 0 ? aRule.Object2 : aRule.Object1;
89 if ( !aUsedObject.IsNull() ) {
90 aNames = getAvailablePairs( aUsedObject );
93 } else if ( aColumn == 1 ) {
94 QMap<QString, QVariant> aMap;
95 aMap.insert( priorityToString( LESS ), LESS );
96 aMap.insert( priorityToString( GREATER ), GREATER );
97 aVariant = QVariant( aMap );
98 } else if ( aColumn == 3 ) {
99 QMap<QString, QVariant> aMap;
100 aMap.insert( mergeTypeToString( HYDROData_Zone::Merge_Object ), HYDROData_Zone::Merge_Object );
101 aMap.insert( mergeTypeToString( HYDROData_Zone::Merge_ZMIN ), HYDROData_Zone::Merge_ZMIN );
102 aMap.insert( mergeTypeToString( HYDROData_Zone::Merge_ZMAX ), HYDROData_Zone::Merge_ZMAX );
103 aVariant = QVariant( aMap );
105 } else if ( theRole == Qt::TextAlignmentRole ) {
106 aVariant = Qt::AlignCenter;
114 bool HYDROGUI_PriorityTableModel::setData( const QModelIndex & theIndex, const QVariant & theValue, int theRole )
116 int aRow = theIndex.row();
117 if ( !theIndex.isValid() || aRow > myRules.size() ) {
123 if ( theRole == Qt::EditRole ) {
124 bool aRuleChanged = false;
125 myPrevRules = myRules;
127 int aColumn = theIndex.column();
129 if ( aColumn == 0 || aColumn == 2 ) {
130 Handle(HYDROData_Entity) anObject;
131 QString anObjName = theValue.toString();
132 foreach ( const Handle(HYDROData_Entity) anObj, myObjects ) {
133 if ( anObj->GetName() == anObjName ) {
138 if ( !anObject.IsNull() ) {
139 HYDROData_CustomRule anEditedRule = myRules[aRow];
141 QString anEntryNew = HYDROGUI_DataObject::dataObjectEntry( anObject );
142 if ( aColumn == 0 ) {
143 QString anEntryOld = HYDROGUI_DataObject::dataObjectEntry( anEditedRule.Object1 );
144 if ( anEntryOld != anEntryNew )
146 anEditedRule.Object1 = anObject;
148 QString anEntryOld = HYDROGUI_DataObject::dataObjectEntry( anEditedRule.Object2 );
149 if ( anEntryOld != anEntryNew )
151 anEditedRule.Object2 = anObject;
154 if ( !isUsed( anEditedRule.Object1, anEditedRule.Object2 ) ) {
155 myRules[aRow] = anEditedRule;
158 aRuleChanged = false;
159 emit showError( tr("ALREADY_EXISTS") );
162 } else if ( aColumn == 1 ) {
163 HYDROData_PriorityType aNewPriority = (HYDROData_PriorityType)theValue.toInt();
164 if ( myRules[aRow].Priority != aNewPriority )
166 myRules[aRow].Priority = aNewPriority;
167 } else if ( aColumn == 3 ) {
168 HYDROData_Zone::MergeType aNewMergeType = (HYDROData_Zone::MergeType)theValue.toInt();
169 if ( myRules[aRow].MergeType != aNewMergeType )
171 myRules[aRow].MergeType = aNewMergeType;
183 int HYDROGUI_PriorityTableModel::rowCount( const QModelIndex &theParent ) const
185 return myRules.count();
190 int HYDROGUI_PriorityTableModel::columnCount( const QModelIndex &theParent ) const
192 return myColumnCount;
197 @param theRules the list of rules
199 void HYDROGUI_PriorityTableModel::setRules( const HYDROData_ListOfRules& theRules )
202 myPrevRules = myRules;
209 @return the list of rules
211 HYDROData_ListOfRules HYDROGUI_PriorityTableModel::getRules() const
218 QVariant HYDROGUI_PriorityTableModel::headerData( int theSection,
219 Qt::Orientation theOrientation,
224 if ( theRole != Qt::DisplayRole ) {
228 if ( theOrientation == Qt::Horizontal ) {
232 aData = tr( "OBJECT1" );
235 aData = tr( "PRIORITY" );
238 aData = tr( "OBJECT2" );
242 if ( getObjectsKind() != KIND_LAND_COVER_MAP )
243 aData = tr( "BATHYMETRY" );
247 } else if ( theOrientation == Qt::Vertical ) {
248 aData = theSection + 1;
255 Set objects which could be used for rules definition.
256 @param theObjects the ordered list of objects
258 void HYDROGUI_PriorityTableModel::setObjects( const QList<Handle(HYDROData_Entity)>& theObjects )
260 myObjects = theObjects;
262 myPrevRules = myRules;
266 // Remove rules which use objects which are no longer available
267 QStringList aNames = getAvailableObjectNames();
268 QMutableListIterator<HYDROData_CustomRule> anIter( myRules );
269 while ( anIter.hasNext() ) {
270 HYDROData_CustomRule aRule = anIter.next();
271 if ( !aNames.contains( aRule.Object1->GetName() ) ||
272 !aNames.contains( aRule.Object2->GetName() ) ) {
282 @return true if a rule has been created successfully
284 bool HYDROGUI_PriorityTableModel::createNewRule()
286 if ( !canCreateNewRule() ) {
290 // Existing pairs of object indexes
291 QStringList aNames = getAvailableObjectNames();
292 QList< QPair<int, int> > aRules;
293 foreach( const HYDROData_CustomRule& aRule, getRules() ) {
294 int anIndex1 = aNames.indexOf( aRule.Object1->GetName() );
295 int anIndex2 = aNames.indexOf( aRule.Object2->GetName() );
296 if ( anIndex1 >= 0 && anIndex2 >= 0 ) {
297 aRules << QPair<int, int>( anIndex1, anIndex2 );
298 aRules << QPair<int, int>( anIndex2, anIndex1 );
303 // 1. the new pair of objects
304 // 2. the priority type corresponding to the objects order
305 Handle(HYDROData_Entity) anObject1, anObject2;
306 HYDROData_PriorityType aPriorityType = GREATER;
308 int aNbObjects = myObjects.count();
309 for ( int anIndex1 = 0; anIndex1 < aNbObjects; anIndex1++ ) {
310 bool isFound = false;
312 for ( int anIndex2 = 0; anIndex2 < aNbObjects; anIndex2++ ) {
313 if ( anIndex1 == anIndex2 ) {
317 if ( !aRules.contains( QPair<int, int>( anIndex1, anIndex2 ) ) ) {
318 anObject1 = myObjects.at( anIndex1 );
319 anObject2 = myObjects.at( anIndex2 );
320 if ( anIndex1 > anIndex2 ) {
321 aPriorityType = LESS;
334 bool isCreated = false;
336 if ( !anObject1.IsNull() && !anObject2.IsNull() ) {
337 HYDROData_CustomRule aNewRule;
338 aNewRule.Object1 = anObject1;
339 aNewRule.Object2 = anObject2;
340 aNewRule.Priority = aPriorityType;
341 aNewRule.MergeType = HYDROData_Zone::Merge_ZMIN;
343 myPrevRules = myRules;
356 Check if a new rule can be created.
357 @return true if a new rule could be created
359 bool HYDROGUI_PriorityTableModel::canCreateNewRule() const
361 int aNbObjects = myObjects.count();
363 return ( myRules.count() < (aNbObjects - 1)*aNbObjects/2 );
368 bool HYDROGUI_PriorityTableModel::removeRows ( int theRow, int theCount, const QModelIndex & theParent )
370 if ( myRules.isEmpty() || theRow < 0 || theRow >= myRules.count() ) {
374 int aLastRow = theRow + theCount - 1;
375 if ( aLastRow > myRules.count() ) {
376 aLastRow = myRules.count() - 1;
379 myPrevRules = myRules;
381 beginRemoveRows( theParent, theRow, aLastRow );
383 // Remove the corresponding rules
384 for ( int i = 1; i <= theCount; i++ ) {
385 myRules.removeAt( theRow );
394 Remove all data from the model.
395 @return true if at least one row is removed
397 bool HYDROGUI_PriorityTableModel::removeAll()
399 return removeRows( 0, rowCount() );
403 Get available pairs for the given object.
404 @param theObject the object
405 @return the list of object names
407 QStringList HYDROGUI_PriorityTableModel::getAvailablePairs( const Handle(HYDROData_Entity)& theObject ) const
411 if ( !theObject.IsNull() ) {
412 aNames = getAvailableObjectNames();
413 aNames.removeAll( theObject->GetName() );
421 @params theRows the list of rows to remove
422 @return true if at least one row is removed
424 bool HYDROGUI_PriorityTableModel::removeRows ( const QList<int> theRows )
426 QList<int> aSortedRows = theRows;
427 qSort( aSortedRows );
429 int aRowToRemove = -1;
431 foreach ( int aRow, aSortedRows ) {
432 aRowToRemove = aRow - aNbRemoved;
433 if ( removeRow( aRowToRemove ) ) {
438 return ( aNbRemoved > 0 );
442 Get priority string representation.
443 @param thePriority the priority
445 QString HYDROGUI_PriorityTableModel::priorityToString( const int thePriority ) const
447 switch( thePriority )
452 return tr( "GREATER" );
459 Get merge type string representation.
460 @param theMergeType the merge type
462 QString HYDROGUI_PriorityTableModel::mergeTypeToString( const int theMergeType ) const
464 switch( theMergeType )
466 case HYDROData_Zone::Merge_Object:
467 return tr( "PRIORITY" );
468 case HYDROData_Zone::Merge_ZMIN:
470 case HYDROData_Zone::Merge_ZMAX:
478 Check if the given pair of objects is already used.
479 @return true if the pair is used
481 bool HYDROGUI_PriorityTableModel::isUsed( const Handle(HYDROData_Entity)& theObj1,
482 const Handle(HYDROData_Entity)& theObj2 ) const
486 foreach ( const HYDROData_CustomRule& aRule, myRules ) {
487 if ( ( aRule.Object1->GetName() == theObj1->GetName() &&
488 aRule.Object2->GetName() == theObj2->GetName() ) ||
489 ( aRule.Object1->GetName() == theObj2->GetName() &&
490 aRule.Object2->GetName() == theObj1->GetName() ) ) {
500 Get available object names.
501 @return the list of object names
503 QStringList HYDROGUI_PriorityTableModel::getAvailableObjectNames() const
507 foreach ( const Handle(HYDROData_Entity) anObj, myObjects ) {
508 if ( !anObj.IsNull() ) {
509 aNames << anObj->GetName();
517 Set number of columns in the table.
518 @param theColumnCount the number of columns
520 void HYDROGUI_PriorityTableModel::setColumnCount( int theColumnCount )
522 myColumnCount = theColumnCount;
526 Undo last change in the list of priority rules.
528 void HYDROGUI_PriorityTableModel::undoLastChange()
531 myRules = myPrevRules;
536 Get type of objects for which rules are defined assuming,
537 that all objects in the list have the same type.
538 @return the type of objects
540 const ObjectKind HYDROGUI_PriorityTableModel::getObjectsKind() const
542 if ( myObjects.isEmpty() )
545 return myObjects.at( 0 )->GetKind();