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 <HYDROData_LandCover.h>
22 #include <HYDROGUI_DataObject.h>
26 @param theParent the parent object
28 HYDROGUI_PriorityTableModel::HYDROGUI_PriorityTableModel( QObject* theParent )
29 : QAbstractTableModel( theParent ),
37 HYDROGUI_PriorityTableModel::~HYDROGUI_PriorityTableModel()
43 Qt::ItemFlags HYDROGUI_PriorityTableModel::flags( const QModelIndex & theIndex ) const
45 return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled;
50 QVariant HYDROGUI_PriorityTableModel::data( const QModelIndex &theIndex, int theRole ) const
54 int aRow = theIndex.row();
55 int aColumn = theIndex.column();
57 if ( !theIndex.isValid() || aRow > myRules.size() ) {
61 if ( theRole == Qt::DisplayRole ) {
62 HYDROData_CustomRule aRule = myRules.at(aRow);
65 aVariant = aRule.Object1->GetName();
66 } else if ( aColumn == 1 ) {
67 aVariant = priorityToString( aRule.Priority );
68 } else if ( aColumn == 2 ) {
69 aVariant = aRule.Object2->GetName();
70 } else if ( aColumn == 3 ) {
71 aVariant = mergeTypeToString( aRule.MergeType );
73 } else if ( theRole == Qt::EditRole ) {
74 HYDROData_CustomRule aRule = myRules.at(aRow);
77 aVariant = aRule.Object1->GetName();
78 } else if ( aColumn == 1 ) {
79 aVariant = aRule.Priority;
80 } else if ( aColumn == 2 ) {
81 aVariant = aRule.Object2->GetName();
82 } else if ( aColumn == 3 ) {
83 aVariant = aRule.MergeType;
85 } else if ( theRole == Qt::UserRole ) {
86 if ( aColumn == 0 || aColumn == 2 ) {
88 HYDROData_CustomRule aRule = myRules.at( aRow );
89 Handle(HYDROData_Entity) aUsedObject = aColumn == 0 ? aRule.Object2 : aRule.Object1;
90 if ( !aUsedObject.IsNull() ) {
91 aNames = getAvailablePairs( aUsedObject );
94 } else if ( aColumn == 1 ) {
95 QMap<QString, QVariant> aMap;
96 aMap.insert( priorityToString( LESS ), LESS );
97 aMap.insert( priorityToString( GREATER ), GREATER );
98 aVariant = QVariant( aMap );
99 } else if ( aColumn == 3 ) {
100 QMap<QString, QVariant> aMap;
101 aMap.insert( mergeTypeToString( HYDROData_Zone::Merge_Object ), HYDROData_Zone::Merge_Object );
102 aMap.insert( mergeTypeToString( HYDROData_Zone::Merge_ZMIN ), HYDROData_Zone::Merge_ZMIN );
103 aMap.insert( mergeTypeToString( HYDROData_Zone::Merge_ZMAX ), HYDROData_Zone::Merge_ZMAX );
104 aVariant = QVariant( aMap );
106 } else if ( theRole == Qt::TextAlignmentRole ) {
107 aVariant = Qt::AlignCenter;
115 bool HYDROGUI_PriorityTableModel::setData( const QModelIndex & theIndex, const QVariant & theValue, int theRole )
117 int aRow = theIndex.row();
118 if ( !theIndex.isValid() || aRow > myRules.size() ) {
124 if ( theRole == Qt::EditRole ) {
125 bool aRuleChanged = false;
126 myPrevRules = myRules;
128 int aColumn = theIndex.column();
130 if ( aColumn == 0 || aColumn == 2 ) {
131 Handle(HYDROData_Entity) anObject;
132 QString anObjName = theValue.toString();
133 foreach ( const Handle(HYDROData_Entity) anObj, myObjects ) {
134 if ( anObj->GetName() == anObjName ) {
139 if ( !anObject.IsNull() ) {
140 HYDROData_CustomRule anEditedRule = myRules[aRow];
142 QString anEntryNew = HYDROGUI_DataObject::dataObjectEntry( anObject );
143 if ( aColumn == 0 ) {
144 QString anEntryOld = HYDROGUI_DataObject::dataObjectEntry( anEditedRule.Object1 );
145 if ( anEntryOld != anEntryNew )
147 anEditedRule.Object1 = anObject;
149 QString anEntryOld = HYDROGUI_DataObject::dataObjectEntry( anEditedRule.Object2 );
150 if ( anEntryOld != anEntryNew )
152 anEditedRule.Object2 = anObject;
155 if ( !isUsed( anEditedRule.Object1, anEditedRule.Object2 ) ) {
156 myRules[aRow] = anEditedRule;
159 aRuleChanged = false;
160 emit showError( tr("ALREADY_EXISTS") );
163 } else if ( aColumn == 1 ) {
164 HYDROData_PriorityType aNewPriority = (HYDROData_PriorityType)theValue.toInt();
165 if ( myRules[aRow].Priority != aNewPriority )
167 myRules[aRow].Priority = aNewPriority;
168 } else if ( aColumn == 3 ) {
169 HYDROData_Zone::MergeType aNewMergeType = (HYDROData_Zone::MergeType)theValue.toInt();
170 if ( myRules[aRow].MergeType != aNewMergeType )
172 myRules[aRow].MergeType = aNewMergeType;
184 int HYDROGUI_PriorityTableModel::rowCount( const QModelIndex &theParent ) const
186 return myRules.count();
191 int HYDROGUI_PriorityTableModel::columnCount( const QModelIndex &theParent ) const
193 return myColumnCount;
198 @param theRules the list of rules
200 void HYDROGUI_PriorityTableModel::setRules( const HYDROData_ListOfRules& theRules )
203 myPrevRules = myRules;
210 @return the list of rules
212 HYDROData_ListOfRules HYDROGUI_PriorityTableModel::getRules() const
219 QVariant HYDROGUI_PriorityTableModel::headerData( int theSection,
220 Qt::Orientation theOrientation,
225 if ( theRole != Qt::DisplayRole ) {
229 if ( theOrientation == Qt::Horizontal ) {
233 aData = tr( "OBJECT1" );
236 aData = tr( "PRIORITY" );
239 aData = tr( "OBJECT2" );
243 if ( getObjectsKind() != KIND_LAND_COVER )
244 aData = tr( "BATHYMETRY" );
248 } else if ( theOrientation == Qt::Vertical ) {
249 aData = theSection + 1;
256 Set objects which could be used for rules definition.
257 @param theObjects the ordered list of objects
259 void HYDROGUI_PriorityTableModel::setObjects( const QList<Handle(HYDROData_Entity)>& theObjects )
261 myObjects = theObjects;
263 myPrevRules = myRules;
267 // Remove rules which use objects which are no longer available
268 QStringList aNames = getAvailableObjectNames();
269 QMutableListIterator<HYDROData_CustomRule> anIter( myRules );
270 while ( anIter.hasNext() ) {
271 HYDROData_CustomRule aRule = anIter.next();
272 if ( !aNames.contains( aRule.Object1->GetName() ) ||
273 !aNames.contains( aRule.Object2->GetName() ) ) {
283 @return true if a rule has been created successfully
285 bool HYDROGUI_PriorityTableModel::createNewRule()
287 if ( !canCreateNewRule() ) {
291 // Existing pairs of object indexes
292 QStringList aNames = getAvailableObjectNames();
293 QList< QPair<int, int> > aRules;
294 foreach( const HYDROData_CustomRule& aRule, getRules() ) {
295 int anIndex1 = aNames.indexOf( aRule.Object1->GetName() );
296 int anIndex2 = aNames.indexOf( aRule.Object2->GetName() );
297 if ( anIndex1 >= 0 && anIndex2 >= 0 ) {
298 aRules << QPair<int, int>( anIndex1, anIndex2 );
299 aRules << QPair<int, int>( anIndex2, anIndex1 );
304 // 1. the new pair of objects
305 // 2. the priority type corresponding to the objects order
306 Handle(HYDROData_Entity) anObject1, anObject2;
307 HYDROData_PriorityType aPriorityType = GREATER;
309 int aNbObjects = myObjects.count();
310 for ( int anIndex1 = 0; anIndex1 < aNbObjects; anIndex1++ ) {
311 bool isFound = false;
313 for ( int anIndex2 = 0; anIndex2 < aNbObjects; anIndex2++ ) {
314 if ( anIndex1 == anIndex2 ) {
318 if ( !aRules.contains( QPair<int, int>( anIndex1, anIndex2 ) ) ) {
319 anObject1 = myObjects.at( anIndex1 );
320 anObject2 = myObjects.at( anIndex2 );
321 if ( anIndex1 > anIndex2 ) {
322 aPriorityType = LESS;
335 bool isCreated = false;
337 if ( !anObject1.IsNull() && !anObject2.IsNull() ) {
338 HYDROData_CustomRule aNewRule;
339 aNewRule.Object1 = anObject1;
340 aNewRule.Object2 = anObject2;
341 aNewRule.Priority = aPriorityType;
342 aNewRule.MergeType = HYDROData_Zone::Merge_ZMIN;
344 myPrevRules = myRules;
357 Check if a new rule can be created.
358 @return true if a new rule could be created
360 bool HYDROGUI_PriorityTableModel::canCreateNewRule() const
362 int aNbObjects = myObjects.count();
364 return ( myRules.count() < (aNbObjects - 1)*aNbObjects/2 );
369 bool HYDROGUI_PriorityTableModel::removeRows ( int theRow, int theCount, const QModelIndex & theParent )
371 if ( myRules.isEmpty() || theRow < 0 || theRow >= myRules.count() ) {
375 int aLastRow = theRow + theCount - 1;
376 if ( aLastRow > myRules.count() ) {
377 aLastRow = myRules.count() - 1;
380 myPrevRules = myRules;
382 beginRemoveRows( theParent, theRow, aLastRow );
384 // Remove the corresponding rules
385 for ( int i = 1; i <= theCount; i++ ) {
386 myRules.removeAt( theRow );
395 Remove all data from the model.
396 @return true if at least one row is removed
398 bool HYDROGUI_PriorityTableModel::removeAll()
400 return removeRows( 0, rowCount() );
404 Get available pairs for the given object.
405 @param theObject the object
406 @return the list of object names
408 QStringList HYDROGUI_PriorityTableModel::getAvailablePairs( const Handle(HYDROData_Entity)& theObject ) const
412 if ( !theObject.IsNull() ) {
413 aNames = getAvailableObjectNames();
414 aNames.removeAll( theObject->GetName() );
422 @params theRows the list of rows to remove
423 @return true if at least one row is removed
425 bool HYDROGUI_PriorityTableModel::removeRows ( const QList<int> theRows )
427 QList<int> aSortedRows = theRows;
428 qSort( aSortedRows );
430 int aRowToRemove = -1;
432 foreach ( int aRow, aSortedRows ) {
433 aRowToRemove = aRow - aNbRemoved;
434 if ( removeRow( aRowToRemove ) ) {
439 return ( aNbRemoved > 0 );
443 Get priority string representation.
444 @param thePriority the priority
446 QString HYDROGUI_PriorityTableModel::priorityToString( const int thePriority ) const
448 switch( thePriority )
453 return tr( "GREATER" );
460 Get merge type string representation.
461 @param theMergeType the merge type
463 QString HYDROGUI_PriorityTableModel::mergeTypeToString( const int theMergeType ) const
465 switch( theMergeType )
467 case HYDROData_Zone::Merge_Object:
468 return tr( "PRIORITY" );
469 case HYDROData_Zone::Merge_ZMIN:
471 case HYDROData_Zone::Merge_ZMAX:
479 Check if the given pair of objects is already used.
480 @return true if the pair is used
482 bool HYDROGUI_PriorityTableModel::isUsed( const Handle(HYDROData_Entity)& theObj1,
483 const Handle(HYDROData_Entity)& theObj2 ) const
487 foreach ( const HYDROData_CustomRule& aRule, myRules ) {
488 if ( ( aRule.Object1->GetName() == theObj1->GetName() &&
489 aRule.Object2->GetName() == theObj2->GetName() ) ||
490 ( aRule.Object1->GetName() == theObj2->GetName() &&
491 aRule.Object2->GetName() == theObj1->GetName() ) ) {
501 Get available object names.
502 @return the list of object names
504 QStringList HYDROGUI_PriorityTableModel::getAvailableObjectNames() const
508 foreach ( const Handle(HYDROData_Entity) anObj, myObjects ) {
509 if ( !anObj.IsNull() ) {
510 aNames << anObj->GetName();
518 Set number of columns in the table.
519 @param theColumnCount the number of columns
521 void HYDROGUI_PriorityTableModel::setColumnCount( int theColumnCount )
523 myColumnCount = theColumnCount;
527 Undo last change in the list of priority rules.
529 void HYDROGUI_PriorityTableModel::undoLastChange()
532 myRules = myPrevRules;
538 Get type of objects for which rules are defined assuming,
539 that all objects in the list have the same type.
540 @return the type of objects
542 const ObjectKind HYDROGUI_PriorityTableModel::getObjectsKind() const
544 if ( myObjects.isEmpty() )
547 return myObjects.at( 0 )->GetKind();