Salome HOME
Move z levels sources.
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_ZLevelsModel.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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.
10 //
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.
15 //
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
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "HYDROGUI_ZLevelsModel.h"
24 #include <QMimeData>
25
26 const QString OBJ_LIST_MIME_TYPE = "application/hydro.objects.list";
27
28 HYDROGUI_ZLevelsModel::HYDROGUI_ZLevelsModel( QObject* theParent )
29  : QAbstractListModel( theParent )
30 {
31   myEmpty = QPixmap( 16, 16 );
32   myEmpty.fill( Qt::white );
33   myEye = QPixmap( "eye.png" );//TODO: loading from resources
34   setSupportedDragActions( Qt::MoveAction | Qt::CopyAction );
35 }
36
37 HYDROGUI_ZLevelsModel::~HYDROGUI_ZLevelsModel()
38 {
39 }
40
41 QVariant HYDROGUI_ZLevelsModel::data( const QModelIndex &theIndex, int theRole ) const
42 {
43   QVariant aVariant;
44
45   int aRow = theIndex.row();
46   int aColumn = theIndex.column();
47
48   switch( theRole )
49   {
50   case Qt::DisplayRole:
51     {
52       if( aColumn==0 && aRow >=0 && aRow < myObjects.count() )
53         return myObjects.at( aRow ).first;
54       else
55         return QVariant();
56     }
57     break;
58
59   case Qt::DecorationRole:
60     {
61       if( aColumn==0 && aRow >=0 && aRow < myObjects.count() )
62       {
63         bool isVisible = IsObjectVisible( aRow );
64         if( isVisible )
65           return myEye;
66         else
67           return myEmpty;
68       }
69       return QVariant();
70     }
71     break;
72
73   case HYDROGUI_VisibleRole:
74     {
75       bool isVisible = IsObjectVisible( aRow );
76       return QVariant( isVisible ).toString();
77     }
78     break;
79   }
80
81   return aVariant;
82 }
83
84 int HYDROGUI_ZLevelsModel::rowCount( const QModelIndex &theParent ) const
85 {
86   return myObjects.count();
87 }
88
89 void HYDROGUI_ZLevelsModel::setObjects( const QList<QPair<QString, bool>>& theObjects )
90 {
91   myObjects = theObjects;
92
93   reset();
94 }
95
96 bool HYDROGUI_ZLevelsModel::IsObjectVisible( int theIndex ) const
97 {
98   bool isVisible = false;
99
100   if ( theIndex >= 0 && theIndex < myObjects.count() ) {
101     isVisible = myObjects.at( theIndex ).second;
102   }
103
104   return isVisible;
105 }
106
107 QVariant HYDROGUI_ZLevelsModel::headerData( int theSection,
108                                             Qt::Orientation theOrientation,
109                                             int theRole ) const
110 {
111   if( theOrientation==Qt::Horizontal && theRole==Qt::DisplayRole )
112   {
113     switch( theSection )
114     {
115     case 0:
116       return tr( "VISIBLE" );
117     case 1:
118       return tr( "OBJECT_NAME" );
119     };
120   }
121   return QVariant();
122 }
123
124 Qt::ItemFlags HYDROGUI_ZLevelsModel::flags( const QModelIndex& theIndex ) const
125 {
126   Qt::ItemFlags aDefaultFlags = QAbstractListModel::flags( theIndex );
127   if( theIndex.isValid() )
128     return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | aDefaultFlags;
129   else
130     return Qt::ItemIsDropEnabled | aDefaultFlags;
131 }
132
133 QMimeData* HYDROGUI_ZLevelsModel::mimeData( const QModelIndexList& theIndices ) const
134 {
135   QMimeData* aMimeData = new QMimeData();
136   QByteArray anEncodedData;
137   QDataStream aStream( &anEncodedData, QIODevice::WriteOnly );
138
139   QList<int> anIdsList = getIds( theIndices );
140   foreach( int anId, anIdsList )
141     aStream << anId;
142
143   aMimeData->setData( OBJ_LIST_MIME_TYPE, anEncodedData );
144   return aMimeData;
145 }
146
147 QStringList HYDROGUI_ZLevelsModel::mimeTypes() const
148 {
149   QStringList aTypes;
150   aTypes << OBJ_LIST_MIME_TYPE;
151   return aTypes;
152 }
153
154 bool HYDROGUI_ZLevelsModel::dropMimeData( const QMimeData* theData, Qt::DropAction theAction,
155                                           int theRow, int theColumn, const QModelIndex& theParent )
156 {
157   if( theAction == Qt::IgnoreAction)
158     return true;
159
160   if( !theData->hasFormat( OBJ_LIST_MIME_TYPE ))
161     return false;
162
163   if( theColumn > 0 )
164     return false;
165
166   int aDropItemId = theParent.row();
167
168   QByteArray anEncodedData = theData->data( OBJ_LIST_MIME_TYPE );
169   QDataStream aStream( &anEncodedData, QIODevice::ReadOnly );
170   QList<int> anIdsList;
171   while( !aStream.atEnd() )
172   {
173     int anId;
174     aStream >> anId;
175     anIdsList << anId;
176   }
177   move( anIdsList, DragAndDrop, aDropItemId );
178   return true;
179 }
180
181 Qt::DropActions HYDROGUI_ZLevelsModel::supportedDropActions() const
182 {
183   return Qt::MoveAction | Qt::CopyAction;
184 }
185
186 QList<int> HYDROGUI_ZLevelsModel::getIds( const QModelIndexList& theIndexes, bool theIsToSort ) const
187 {
188   QList<int> anIds;
189   foreach( const QModelIndex& anIndex, theIndexes ) {
190     anIds << anIndex.row();
191   }
192
193   if ( theIsToSort ) {
194     qSort( anIds );
195   }
196
197   return anIds;
198 }
199
200 bool HYDROGUI_ZLevelsModel::move( const int theItem, const OpType theType,
201                                   bool theIsVisibleOnly, const int theDropItem )
202 {
203   bool aRes = false;
204   if ( theItem < 0 || theItem >= myObjects.count() ) {
205     return aRes;
206   }
207
208   int aDestinationIndex = -1;
209
210   switch ( theType ) {
211     case Up:
212       if ( theItem > 0 ) {
213         aDestinationIndex = theItem - 1;
214         if ( theIsVisibleOnly ) {
215           while ( aDestinationIndex >= 0 && !IsObjectVisible( aDestinationIndex ) ) {
216             aDestinationIndex--;
217           }
218         }
219       }
220       break;
221     case Down:
222       if ( theItem < myObjects.count() - 1 ) {
223         aDestinationIndex = theItem + 1;
224         if ( theIsVisibleOnly ) {
225           while ( aDestinationIndex < myObjects.count() && !IsObjectVisible( aDestinationIndex ) ) {
226             aDestinationIndex++;
227           }
228         }
229       }
230       break;
231     case Top:
232       if ( theItem > 0 ) {
233         aDestinationIndex = 0;
234       }
235       break;
236     case Bottom:
237       if ( theItem < myObjects.count() - 1 ) {
238         aDestinationIndex = myObjects.count() - 1;
239       }
240       break;
241   }
242
243   if ( aDestinationIndex >= 0 && aDestinationIndex < myObjects.count() ) {
244     int aDestinationRow = (theType == Up || theType == Top) ? aDestinationIndex : aDestinationIndex + 1;
245     if ( beginMoveRows( QModelIndex(), theItem, theItem, QModelIndex(), aDestinationRow ) ) {
246       myObjects.move( theItem, aDestinationIndex );
247       endMoveRows();
248       aRes = true;
249     }
250   }
251         
252   return aRes;
253 }
254
255 bool HYDROGUI_ZLevelsModel::move( const QList<int>& theItems, const OpType theType, 
256                                   bool theIsVisibleOnly, const int theDropItem )
257 {
258   bool aRes = true;
259
260   bool isReverse = theType == Top || theType == Down;
261   QListIterator<int> anIt( theItems );
262   int aShift = 0;
263   if ( isReverse ) {
264     anIt.toBack();
265     while ( anIt.hasPrevious() ) {
266       int anId = anIt.previous();
267       if ( theType == Top ) {
268         anId += aShift;
269         aShift++;
270       }
271       if ( !move( anId, theType, theIsVisibleOnly, theDropItem ) ) {
272         aRes = false;
273         break;
274       }
275     }
276   } else {
277     while ( anIt.hasNext() ) {
278       int anId = anIt.next();
279       if ( theType == Bottom ) {
280         anId -= aShift;
281         aShift++;
282       }
283       if ( !move( anId, theType, theIsVisibleOnly, theDropItem ) ) {
284         aRes = false;
285         break;
286       }
287     }
288   }
289
290   // reset(); //TODO dataChanged?
291
292   return aRes;
293 }
294