1 // Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "HYDROGUI_ListModel.h"
25 #include "HYDROGUI_DataObject.h"
27 #include <SUIT_Session.h>
28 #include <SUIT_ResourceMgr.h>
32 const QString OBJ_LIST_MIME_TYPE = "application/hydro.objects.list";
37 @param theParent the parent object
39 HYDROGUI_ListModel::HYDROGUI_ListModel( QObject* theParent )
40 : QAbstractListModel( theParent ), myIsDecorationEnabled( true )
42 // Get resource manager
43 SUIT_ResourceMgr* aResMgr = 0;
44 SUIT_Session* aSession = SUIT_Session::session();
46 aResMgr = SUIT_Session::session()->resourceMgr();
49 // Define eye icon and empty icon
50 myEmpty = QPixmap( 16, 16 );
51 myEmpty.fill( Qt::transparent );
53 myEye = aResMgr->loadPixmap( "HYDRO", tr( "EYE_ICO" ) );
55 myEye = QPixmap( 16, 16 );
56 myEye.fill( Qt::black );
59 // Set the supported drag actions for the items in the model
60 setSupportedDragActions( Qt::MoveAction | Qt::CopyAction );
66 HYDROGUI_ListModel::~HYDROGUI_ListModel()
72 QVariant HYDROGUI_ListModel::data( const QModelIndex &theIndex, int theRole ) const
76 int aRow = theIndex.row();
77 int aColumn = theIndex.column();
83 if( aColumn==0 && aRow >=0 && aRow < myObjects.count() )
84 return myObjects.at( aRow ).first->GetName();
90 case Qt::DecorationRole:
92 if( myIsDecorationEnabled &&
93 aColumn==0 && aRow >=0 && aRow < myObjects.count() ) {
94 bool isVisible = isObjectVisible( aRow );
104 case HYDROGUI_VisibleRole:
106 bool isVisible = isObjectVisible( aRow );
107 return QVariant( isVisible ).toString();
110 case HYDROGUI_EntryRole:
112 if( aColumn==0 && aRow >=0 && aRow < myObjects.count() ) {
113 aVariant = HYDROGUI_DataObject::dataObjectEntry( myObjects.at( aRow ).first );
124 int HYDROGUI_ListModel::rowCount( const QModelIndex &theParent ) const
126 return myObjects.count();
131 @param theObjects the list of pairs (object; object visibility)
133 void HYDROGUI_ListModel::setObjects( const Object2VisibleList& theObjects )
135 myObjects = theObjects;
142 @return the list of objects ordered according to the model
144 HYDROGUI_ListModel::ObjectList HYDROGUI_ListModel::getObjects() const
146 ObjectList anObjects;
148 foreach( const Object2Visible& anItem, myObjects ) {
149 anObjects << anItem.first;
156 Add the object to the end of the list.
157 @param theObjects the pair (object; visibility)
159 void HYDROGUI_ListModel::addObject( const Object2Visible& theObject )
161 myObjects << theObject;
167 Remove the object from the list.
168 @param theObjectName the name of the object to remove
170 void HYDROGUI_ListModel::removeObjectByName( const QString& theObjectName )
172 Object2Visible anItem;
173 foreach( anItem, myObjects ) {
174 if ( anItem.first->GetName() == theObjectName ) {
179 myObjects.removeAll(anItem);
186 Check if the object is visible.
187 @param theIndex the object index
188 @return true if the object is visible, false - otherwise
190 bool HYDROGUI_ListModel::isObjectVisible( int theIndex ) const
192 bool isVisible = false;
194 if ( theIndex >= 0 && theIndex < myObjects.count() ) {
195 isVisible = myObjects.at( theIndex ).second;
203 QVariant HYDROGUI_ListModel::headerData( int theSection,
204 Qt::Orientation theOrientation,
207 if( theOrientation==Qt::Horizontal && theRole==Qt::DisplayRole )
212 return tr( "VISIBLE" );
214 return tr( "OBJECT_NAME" );
222 Qt::ItemFlags HYDROGUI_ListModel::flags( const QModelIndex& theIndex ) const
224 Qt::ItemFlags aDefaultFlags = QAbstractListModel::flags( theIndex );
225 if( theIndex.isValid() )
226 return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | aDefaultFlags;
228 return Qt::ItemIsDropEnabled | aDefaultFlags;
233 QMimeData* HYDROGUI_ListModel::mimeData( const QModelIndexList& theIndexes ) const
235 QMimeData* aMimeData = new QMimeData();
236 QByteArray anEncodedData;
237 QDataStream aStream( &anEncodedData, QIODevice::WriteOnly );
239 QList<int> anIdsList = getIds( theIndexes, true );
240 foreach( int anId, anIdsList )
243 aMimeData->setData( OBJ_LIST_MIME_TYPE, anEncodedData );
249 QStringList HYDROGUI_ListModel::mimeTypes() const
252 aTypes << OBJ_LIST_MIME_TYPE;
258 bool HYDROGUI_ListModel::dropMimeData( const QMimeData* theData, Qt::DropAction theAction,
259 int theRow, int theColumn, const QModelIndex& theParent )
261 if( theAction == Qt::IgnoreAction)
264 if( !theData->hasFormat( OBJ_LIST_MIME_TYPE ))
270 // TODO: to disable drop between items use: int aDropItemId = theParent.row();
271 int aDropItemId = theParent.isValid() ? theParent.row() : theRow;
273 QByteArray anEncodedData = theData->data( OBJ_LIST_MIME_TYPE );
274 QDataStream aStream( &anEncodedData, QIODevice::ReadOnly );
275 QList<int> anIdsList;
276 while( !aStream.atEnd() )
283 move( anIdsList, DragAndDrop, false, aDropItemId ); //TODO set visibility?
289 Qt::DropActions HYDROGUI_ListModel::supportedDropActions() const
291 return Qt::MoveAction | Qt::CopyAction;
295 Get list of ids by the list model indexes.
296 @param theIsToSort defines if the list of ids should be sorted in ascending order
297 @return the list of ids
299 QList<int> HYDROGUI_ListModel::getIds( const QModelIndexList& theIndexes,
300 bool theIsToSort ) const
303 foreach( const QModelIndex& anIndex, theIndexes ) {
304 anIds << anIndex.row();
316 @param theItem the item id to move
317 @param theType the move operation type
318 @param theIsVisibleOnly indicates if do move relating to the visible objects only
319 @param theDropItem the drop item id ( used for drag and drop obly )
320 @return true in case of success
322 bool HYDROGUI_ListModel::move( const int theItem, const OpType theType,
323 bool theIsVisibleOnly, const int theDropItem )
326 if ( theItem < 0 || theItem >= myObjects.count() ) {
330 int aDestinationIndex = -1;
331 bool isInsertBefore = false;
335 isInsertBefore = true;
337 aDestinationIndex = theItem - 1;
338 if ( theIsVisibleOnly ) {
339 while ( aDestinationIndex >= 0 && !isObjectVisible( aDestinationIndex ) ) {
346 if ( theItem < myObjects.count() - 1 ) {
347 aDestinationIndex = theItem + 1;
348 if ( theIsVisibleOnly ) {
349 while ( aDestinationIndex < myObjects.count() && !isObjectVisible( aDestinationIndex ) ) {
356 isInsertBefore = true;
358 aDestinationIndex = 0;
362 if ( theItem < myObjects.count() - 1 ) {
363 aDestinationIndex = myObjects.count() - 1;
367 if ( theItem > theDropItem ) {
368 isInsertBefore = true;
369 aDestinationIndex = theDropItem;
371 aDestinationIndex = theDropItem - 1;
376 if ( aDestinationIndex >= 0 && aDestinationIndex < myObjects.count() ) {
377 int aDestinationRow = isInsertBefore ? aDestinationIndex : aDestinationIndex + 1;
378 if ( beginMoveRows( QModelIndex(), theItem, theItem, QModelIndex(), aDestinationRow ) ) {
379 myObjects.move( theItem, aDestinationIndex );
390 @param theItems the list of item ids to move
391 @param theType the move operation type
392 @param theIsVisibleOnly indicates if do move relating to the visible objects only
393 @param theDropItem the drop item id ( used for drag and drop obly )
394 @return true in case of success
396 bool HYDROGUI_ListModel::move( const QList<int>& theItems, const OpType theType,
397 bool theIsVisibleOnly, const int theDropItem )
401 QListIterator<int> anIt( theItems );
409 while ( anIt.hasPrevious() ) {
410 int anId = anIt.previous();
411 if ( theType == Top ) {
415 if ( !move( anId, theType, theIsVisibleOnly, theDropItem ) ) {
424 while ( anIt.hasNext() ) {
425 int anId = anIt.next();
426 if ( theType == Bottom ) {
430 if ( !move( anId, theType, theIsVisibleOnly, theDropItem ) ) {
438 aRes = isDragAndDropAllowed( theItems, theDropItem );
441 int aDropItem = theDropItem;
442 while ( anIt.hasNext() ) {
443 int anId = anIt.next();
444 aDropItem = theDropItem + aDropShift;
445 if ( anId > aDropItem ) {
450 if ( ( aDropItem - anId ) != 1 ) {
454 move( anId, theType, theIsVisibleOnly, aDropItem );
466 Check if drag and drop operation allowed.
467 @param theItems the list of dragged item ids
468 @param theDropItem the drop item id
469 @return true if drag and drop allowed
471 bool HYDROGUI_ListModel::isDragAndDropAllowed( const QList<int>& theItems,
472 const int theDropItem ) const
474 bool isAllowed = false;
476 if ( theDropItem >= 0 &&
477 // TODO: to disable drop between items use: theDropItem < myObjects.count()
478 theDropItem <= myObjects.count() &&
479 !theItems.empty() && theItems.count() < myObjects.count() &&
480 !theItems.contains( theDropItem )) {
488 Enable/disable decoration (eye icon).
489 @param theIsToEnable if true - the decoration will be enabled
491 void HYDROGUI_ListModel::setDecorationEnabled( const bool theIsToEnable )
493 myIsDecorationEnabled = theIsToEnable;