-// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
-//
-// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
+// Copyright (C) 2014-2015 EDF-R&D
// 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.
+// 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
#include "HYDROGUI_PriorityTableModel.h"
+#include <HYDROGUI_DataObject.h>
/**
Constructor.
@param theParent the parent object
*/
HYDROGUI_PriorityTableModel::HYDROGUI_PriorityTableModel( QObject* theParent )
- : QAbstractTableModel( theParent )
+ : QAbstractTableModel( theParent ),
+ myColumnCount( 4 )
{
}
}
} else if ( theRole == Qt::UserRole ) {
if ( aColumn == 0 || aColumn == 2 ) {
- aVariant = getAvailableObjects();
+ QStringList aNames;
+ HYDROData_CustomRule aRule = myRules.at( aRow );
+ Handle(HYDROData_Entity) 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 );
}
bool aRes = false;
-
+
if ( theRole == Qt::EditRole ) {
+ bool aRuleChanged = false;
+ myPrevRules = myRules;
+
int aColumn = theIndex.column();
if ( aColumn == 0 || aColumn == 2 ) {
- Handle(HYDROData_Object) anObject;
+ Handle(HYDROData_Entity) anObject;
QString anObjName = theValue.toString();
- foreach ( const Handle(HYDROData_Object) anObj, myObjects ) {
+ foreach ( const Handle(HYDROData_Entity) anObj, myObjects ) {
if ( anObj->GetName() == anObjName ) {
anObject = anObj;
break;
}
}
if ( !anObject.IsNull() ) {
+ HYDROData_CustomRule anEditedRule = myRules[aRow];
+
+ QString anEntryNew = HYDROGUI_DataObject::dataObjectEntry( anObject );
if ( aColumn == 0 ) {
- myRules[aRow].Object1 = anObject;
+ QString anEntryOld = HYDROGUI_DataObject::dataObjectEntry( anEditedRule.Object1 );
+ if ( anEntryOld != anEntryNew )
+ aRuleChanged = true;
+ anEditedRule.Object1 = anObject;
} else {
- myRules[aRow].Object2 = anObject;
+ QString anEntryOld = HYDROGUI_DataObject::dataObjectEntry( anEditedRule.Object2 );
+ if ( anEntryOld != anEntryNew )
+ aRuleChanged = true;
+ anEditedRule.Object2 = anObject;
+ }
+
+ if ( !isUsed( anEditedRule.Object1, anEditedRule.Object2 ) ) {
+ myRules[aRow] = anEditedRule;
+ aRes = true;
+ } else {
+ aRuleChanged = false;
+ emit showError( tr("ALREADY_EXISTS") );
}
-
- aRes = true;
}
} else if ( aColumn == 1 ) {
- myRules[aRow].Priority = (HYDROData_PriorityType)theValue.toInt();
+ HYDROData_PriorityType aNewPriority = (HYDROData_PriorityType)theValue.toInt();
+ if ( myRules[aRow].Priority != aNewPriority )
+ aRuleChanged = true;
+ myRules[aRow].Priority = aNewPriority;
} else if ( aColumn == 3 ) {
- myRules[aRow].MergeType = (HYDROData_Zone::MergeAltitudesType)theValue.toInt();;
+ HYDROData_Zone::MergeType aNewMergeType = (HYDROData_Zone::MergeType)theValue.toInt();
+ if ( myRules[aRow].MergeType != aNewMergeType )
+ aRuleChanged = true;
+ myRules[aRow].MergeType = aNewMergeType;
}
+
+ if ( aRuleChanged )
+ emit ruleChanged();
}
return aRes;
*/
int HYDROGUI_PriorityTableModel::columnCount( const QModelIndex &theParent ) const
{
- return 4;
+ return myColumnCount;
}
/**
*/
void HYDROGUI_PriorityTableModel::setRules( const HYDROData_ListOfRules& theRules )
{
+ beginResetModel();
+ myPrevRules = myRules;
myRules = theRules;
-
- reset();
+ endResetModel();
}
/**
aData = tr( "OBJECT2" );
break;
case 3:
- aData = tr( "BATHYMETRY" );
+ {
+ if ( getObjectsKind() != KIND_LAND_COVER_MAP )
+ aData = tr( "BATHYMETRY" );
+ }
break;
};
} else if ( theOrientation == Qt::Vertical ) {
}
/**
- Set objects which could be used for rules.
- @param theObjects the list of objects
+ Set objects which could be used for rules definition.
+ @param theObjects the ordered list of objects
*/
-void HYDROGUI_PriorityTableModel::setObjects( const QList<Handle(HYDROData_Object)>& theObjects )
+void HYDROGUI_PriorityTableModel::setObjects( const QList<Handle(HYDROData_Entity)>& theObjects )
{
myObjects = theObjects;
+
+ myPrevRules = myRules;
+ beginResetModel();
+
+ // Remove rules which use objects which are no longer available
+ QStringList aNames = getAvailableObjectNames();
QMutableListIterator<HYDROData_CustomRule> anIter( myRules );
while ( anIter.hasNext() ) {
HYDROData_CustomRule aRule = anIter.next();
- if ( !myObjects.contains( aRule.Object1 ) ||
- !myObjects.contains( aRule.Object2 ) ) {
+ if ( !aNames.contains( aRule.Object1->GetName() ) ||
+ !aNames.contains( aRule.Object2->GetName() ) ) {
anIter.remove();
}
}
- 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
+ QStringList aNames = getAvailableObjectNames();
+ QList< QPair<int, int> > aRules;
+ foreach( const HYDROData_CustomRule& aRule, getRules() ) {
+ int anIndex1 = aNames.indexOf( aRule.Object1->GetName() );
+ int anIndex2 = aNames.indexOf( aRule.Object2->GetName() );
+ if ( anIndex1 >= 0 && anIndex2 >= 0 ) {
+ aRules << QPair<int, int>( anIndex1, anIndex2 );
+ aRules << QPair<int, int>( anIndex2, anIndex1 );
+ }
+ }
+
+ // Try to find:
+ // 1. the new pair of objects
+ // 2. the priority type corresponding to the objects order
+ Handle(HYDROData_Entity) anObject1, anObject2;
+ HYDROData_PriorityType aPriorityType = GREATER;
+
+ 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 );
+ if ( anIndex1 > anIndex2 ) {
+ aPriorityType = LESS;
+ }
+ isFound = true;
+ break;
+ }
+ }
+
+ if ( isFound ) {
+ break;
+ }
}
- HYDROData_CustomRule aNewRule;
- aNewRule.Object1 = myObjects.at(0);
- aNewRule.Object2 = myObjects.at(1);
- aNewRule.Priority = LESS;
- aNewRule.MergeType = HYDROData_Zone::Merge_ZMIN;
+ // Create a new rule
+ bool isCreated = false;
+
+ if ( !anObject1.IsNull() && !anObject2.IsNull() ) {
+ HYDROData_CustomRule aNewRule;
+ aNewRule.Object1 = anObject1;
+ aNewRule.Object2 = anObject2;
+ aNewRule.Priority = aPriorityType;
+ aNewRule.MergeType = HYDROData_Zone::Merge_ZMIN;
+
+ myPrevRules = myRules;
+
+ beginResetModel();
+ myRules << aNewRule;
+ endResetModel();
- myRules << aNewRule;
+ isCreated = true;
+ }
- reset();
+ return isCreated;
+}
+
+/**
+ 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();
+
+ 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;
}
+ myPrevRules = myRules;
+
+ 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_Entity)& theObject ) const
{
QStringList aNames;
- foreach ( const Handle(HYDROData_Object) anObj, myObjects ) {
- if ( !anObj.IsNull() ) {
- aNames << anObj->GetName();
- }
+ if ( !theObject.IsNull() ) {
+ aNames = getAvailableObjectNames();
+ aNames.removeAll( theObject->GetName() );
}
return aNames;
/**
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 );
aNbRemoved++;
}
}
+
+ return ( aNbRemoved > 0 );
}
/**
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_Entity)& theObj1,
+ const Handle(HYDROData_Entity)& 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;
+}
+
+/**
+ Get available object names.
+ @return the list of object names
+ */
+QStringList HYDROGUI_PriorityTableModel::getAvailableObjectNames() const
+{
+ QStringList aNames;
+
+ foreach ( const Handle(HYDROData_Entity) anObj, myObjects ) {
+ if ( !anObj.IsNull() ) {
+ aNames << anObj->GetName();
+ }
+ }
+
+ return aNames;
+}
+
+/**
+ Set number of columns in the table.
+ @param theColumnCount the number of columns
+ */
+void HYDROGUI_PriorityTableModel::setColumnCount( int theColumnCount )
+{
+ myColumnCount = theColumnCount;
+}
+
+/**
+ Undo last change in the list of priority rules.
+ */
+void HYDROGUI_PriorityTableModel::undoLastChange()
+{
+ beginResetModel();
+ myRules = myPrevRules;
+ endResetModel();
+}
+
+/**
+ Get type of objects for which rules are defined assuming,
+ that all objects in the list have the same type.
+ @return the type of objects
+ */
+const ObjectKind HYDROGUI_PriorityTableModel::getObjectsKind() const
+{
+ if ( myObjects.isEmpty() )
+ return KIND_UNKNOWN;
+
+ return myObjects.at( 0 )->GetKind();
+}