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_ListModel.h"
21 #include "HYDROGUI_DataObject.h"
23 #include <SUIT_Session.h>
24 #include <SUIT_ResourceMgr.h>
28 const QString OBJ_LIST_MIME_TYPE = "application/hydro.objects.list";
33 @param theParent the parent object
35 HYDROGUI_ListModel::HYDROGUI_ListModel( QObject* theParent )
36 : QAbstractListModel( theParent ), myIsDecorationEnabled( true )
38 // Get resource manager
39 SUIT_ResourceMgr* aResMgr = 0;
40 SUIT_Session* aSession = SUIT_Session::session();
42 aResMgr = SUIT_Session::session()->resourceMgr();
45 // Define eye icon and empty icon
46 myEmpty = QPixmap( 16, 16 );
47 myEmpty.fill( Qt::transparent );
49 myEye = aResMgr->loadPixmap( "HYDRO", tr( "EYE_ICO" ) );
51 myEye = QPixmap( 16, 16 );
52 myEye.fill( Qt::black );
59 HYDROGUI_ListModel::~HYDROGUI_ListModel()
63 void HYDROGUI_ListModel::setBackgroundColor(int theInd, QColor theColor)
65 myColoredRow[theInd] = theColor;
68 void HYDROGUI_ListModel::clearAllBackgroundColors()
73 QColor HYDROGUI_ListModel::getBackgroundColor(int theInd) const
75 if (myColoredRow.count( theInd ))
76 return myColoredRow[theInd];
83 QVariant HYDROGUI_ListModel::data( const QModelIndex &theIndex, int theRole ) const
87 int aRow = theIndex.row();
88 int aColumn = theIndex.column();
94 if( aColumn==0 && aRow >=0 && aRow < myObjects.count() )
95 return myObjects.at( aRow ).first->GetName();
100 case Qt::BackgroundRole:
102 if( aColumn==0 && aRow >=0 && aRow < myObjects.count() && myColoredRow.contains(aRow))
104 QBrush aBackgr(myColoredRow[aRow]);
111 case Qt::DecorationRole:
113 if( myIsDecorationEnabled &&
114 aColumn==0 && aRow >=0 && aRow < myObjects.count() ) {
115 bool isVisible = isObjectVisible( aRow );
125 case HYDROGUI_VisibleRole:
127 bool isVisible = isObjectVisible( aRow );
128 return QVariant( isVisible ).toString();
131 case HYDROGUI_EntryRole:
133 if( aColumn==0 && aRow >=0 && aRow < myObjects.count() ) {
134 aVariant = HYDROGUI_DataObject::dataObjectEntry( myObjects.at( aRow ).first );
145 int HYDROGUI_ListModel::rowCount( const QModelIndex &theParent ) const
147 return myObjects.count();
152 @param theObjects the list of pairs (object; object visibility)
154 void HYDROGUI_ListModel::setObjects( const Object2VisibleList& theObjects )
157 myObjects = theObjects;
163 @return the list of objects ordered according to the model
165 HYDROGUI_ListModel::ObjectList HYDROGUI_ListModel::getObjects() const
167 ObjectList anObjects;
169 foreach( const Object2Visible& anItem, myObjects ) {
170 anObjects << anItem.first;
177 Add the object to the end of the list.
178 @param theObjects the pair (object; visibility)
180 void HYDROGUI_ListModel::addObject( const Object2Visible& theObject )
183 myObjects << theObject;
188 Remove the object from the list.
189 @param theObjectName the name of the object to remove
191 void HYDROGUI_ListModel::removeObjectByName( const QString& theObjectName )
193 Object2Visible anItem;
194 foreach( anItem, myObjects ) {
195 if ( anItem.first->GetName() == theObjectName ) {
201 myObjects.removeAll(anItem);
207 Check if the object is visible.
208 @param theIndex the object index
209 @return true if the object is visible, false - otherwise
211 bool HYDROGUI_ListModel::isObjectVisible( int theIndex ) const
213 bool isVisible = false;
215 if ( theIndex >= 0 && theIndex < myObjects.count() ) {
216 isVisible = myObjects.at( theIndex ).second;
224 QVariant HYDROGUI_ListModel::headerData( int theSection,
225 Qt::Orientation theOrientation,
228 if( theOrientation==Qt::Horizontal && theRole==Qt::DisplayRole )
233 return tr( "VISIBLE" );
235 return tr( "OBJECT_NAME" );
243 Qt::ItemFlags HYDROGUI_ListModel::flags( const QModelIndex& theIndex ) const
245 Qt::ItemFlags aDefaultFlags = QAbstractListModel::flags( theIndex );
246 if( theIndex.isValid() )
247 return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | aDefaultFlags;
249 return Qt::ItemIsDropEnabled | aDefaultFlags;
254 QMimeData* HYDROGUI_ListModel::mimeData( const QModelIndexList& theIndexes ) const
256 QMimeData* aMimeData = new QMimeData();
257 QByteArray anEncodedData;
258 QDataStream aStream( &anEncodedData, QIODevice::WriteOnly );
260 QList<int> anIdsList = getIds( theIndexes, true );
261 foreach( int anId, anIdsList )
264 aMimeData->setData( OBJ_LIST_MIME_TYPE, anEncodedData );
270 QStringList HYDROGUI_ListModel::mimeTypes() const
273 aTypes << OBJ_LIST_MIME_TYPE;
279 bool HYDROGUI_ListModel::dropMimeData( const QMimeData* theData, Qt::DropAction theAction,
280 int theRow, int theColumn, const QModelIndex& theParent )
282 if( theAction == Qt::IgnoreAction)
285 if( !theData->hasFormat( OBJ_LIST_MIME_TYPE ))
291 // TODO: to disable drop between items use: int aDropItemId = theParent.row();
292 int aDropItemId = theParent.isValid() ? theParent.row() : theRow;
294 QByteArray anEncodedData = theData->data( OBJ_LIST_MIME_TYPE );
295 QDataStream aStream( &anEncodedData, QIODevice::ReadOnly );
296 QList<int> anIdsList;
297 while( !aStream.atEnd() )
304 move( anIdsList, DragAndDrop, false, aDropItemId ); //TODO set visibility?
310 Qt::DropActions HYDROGUI_ListModel::supportedDropActions() const
312 return Qt::MoveAction | Qt::CopyAction;
317 Qt::DropActions HYDROGUI_ListModel::supportedDragActions() const
319 // Set the supported drag actions for the items in the model
320 return Qt::MoveAction | Qt::CopyAction;
324 Get list of ids by the list model indexes.
325 @param theIsToSort defines if the list of ids should be sorted in ascending order
326 @return the list of ids
328 QList<int> HYDROGUI_ListModel::getIds( const QModelIndexList& theIndexes,
329 bool theIsToSort ) const
332 foreach( const QModelIndex& anIndex, theIndexes ) {
333 anIds << anIndex.row();
345 @param theItem the item id to move
346 @param theType the move operation type
347 @param theIsVisibleOnly indicates if do move relating to the visible objects only
348 @param theDropItem the drop item id ( used for drag and drop obly )
349 @return true in case of success
351 bool HYDROGUI_ListModel::move( const int theItem, const OpType theType,
352 bool theIsVisibleOnly, const int theDropItem )
355 if ( theItem < 0 || theItem >= myObjects.count() ) {
359 int aDestinationIndex = -1;
360 bool isInsertBefore = false;
364 isInsertBefore = true;
366 aDestinationIndex = theItem - 1;
367 if ( theIsVisibleOnly ) {
368 while ( aDestinationIndex >= 0 && !isObjectVisible( aDestinationIndex ) ) {
375 if ( theItem < myObjects.count() - 1 ) {
376 aDestinationIndex = theItem + 1;
377 if ( theIsVisibleOnly ) {
378 while ( aDestinationIndex < myObjects.count() && !isObjectVisible( aDestinationIndex ) ) {
385 isInsertBefore = true;
387 aDestinationIndex = 0;
391 if ( theItem < myObjects.count() - 1 ) {
392 aDestinationIndex = myObjects.count() - 1;
396 if ( theItem > theDropItem ) {
397 isInsertBefore = true;
398 aDestinationIndex = theDropItem;
400 aDestinationIndex = theDropItem - 1;
405 if ( aDestinationIndex >= 0 && aDestinationIndex < myObjects.count() ) {
406 int aDestinationRow = isInsertBefore ? aDestinationIndex : aDestinationIndex + 1;
407 if ( beginMoveRows( QModelIndex(), theItem, theItem, QModelIndex(), aDestinationRow ) ) {
408 myPrevObjects = myObjects;
409 myObjects.move( theItem, aDestinationIndex );
420 @param theItems the list of item ids to move
421 @param theType the move operation type
422 @param theIsVisibleOnly indicates if do move relating to the visible objects only
423 @param theDropItem the drop item id ( used for drag and drop obly )
424 @return true in case of success
426 bool HYDROGUI_ListModel::move( const QList<int>& theItems, const OpType theType,
427 bool theIsVisibleOnly, const int theDropItem )
431 QListIterator<int> anIt( theItems );
439 while ( anIt.hasPrevious() ) {
440 int anId = anIt.previous();
441 if ( theType == Top ) {
445 if ( !move( anId, theType, theIsVisibleOnly, theDropItem ) ) {
454 while ( anIt.hasNext() ) {
455 int anId = anIt.next();
456 if ( theType == Bottom ) {
460 if ( !move( anId, theType, theIsVisibleOnly, theDropItem ) ) {
468 aRes = isDragAndDropAllowed( theItems, theDropItem );
471 int aDropItem = theDropItem;
472 while ( anIt.hasNext() ) {
473 int anId = anIt.next();
474 aDropItem = theDropItem + aDropShift;
475 if ( anId > aDropItem ) {
480 if ( ( aDropItem - anId ) != 1 ) {
484 move( anId, theType, theIsVisibleOnly, aDropItem );
496 Check if drag and drop operation allowed.
497 @param theItems the list of dragged item ids
498 @param theDropItem the drop item id
499 @return true if drag and drop allowed
501 bool HYDROGUI_ListModel::isDragAndDropAllowed( const QList<int>& theItems,
502 const int theDropItem ) const
504 bool isAllowed = false;
506 if ( theDropItem >= 0 &&
507 // TODO: to disable drop between items use: theDropItem < myObjects.count()
508 theDropItem <= myObjects.count() &&
509 !theItems.empty() && theItems.count() < myObjects.count() &&
510 !theItems.contains( theDropItem )) {
518 Enable/disable decoration (eye icon).
519 @param theIsToEnable if true - the decoration will be enabled
521 void HYDROGUI_ListModel::setDecorationEnabled( const bool theIsToEnable )
523 myIsDecorationEnabled = theIsToEnable;
526 void HYDROGUI_ListModel::undoLastMove()
529 myObjects = myPrevObjects;