0032429: Coding - Warnings during compilation on macosx arm64 with option BUILD_Inspe...
[occt.git] / tools / TreeModel / TreeModel_ModelBase.cxx
1 // Created on: 2017-06-16
2 // Created by: Natalia ERMOLAEVA
3 // Copyright (c) 2017 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement. 
15
16 #include <inspector/TreeModel_ModelBase.hxx>
17
18 #include <inspector/TreeModel_ItemBase.hxx>
19 #include <inspector/TreeModel_ItemProperties.hxx>
20 #include <inspector/TreeModel_Tools.hxx>
21 #include <inspector/TreeModel_VisibilityState.hxx>
22
23 #include <Standard_Transient.hxx>
24
25 #include <Standard_WarningsDisable.hxx>
26 #include <QIcon>
27 #include <Standard_WarningsRestore.hxx>
28
29 const int COLUMN_NAME_WIDTH = 260;
30 const int COLUMN_SIZE_WIDTH = 30;
31
32 // =======================================================================
33 // function : Constructor
34 // purpose :
35 // =======================================================================
36 TreeModel_ModelBase::TreeModel_ModelBase (QObject* theParent)
37 : QAbstractItemModel (theParent), m_pUseVisibilityColumn (false),
38   myVisibilityState (0)
39 {
40   myVisibleIcon = QIcon (":/icons/item_visible.png");
41   myInvisibleIcon = QIcon (":/icons/item_invisible.png");
42 }
43
44 // =======================================================================
45 // function :  InitColumns
46 // purpose :
47 // =======================================================================
48 void TreeModel_ModelBase::InitColumns()
49 {
50   setHeaderItem (TreeModel_ColumnType_Name,       TreeModel_HeaderSection ("Name", COLUMN_NAME_WIDTH));
51   setHeaderItem (TreeModel_ColumnType_Visibility, TreeModel_HeaderSection ("Visibility", TreeModel_ModelBase::ColumnVisibilityWidth()));
52   setHeaderItem (TreeModel_ColumnType_Row,        TreeModel_HeaderSection ("Row", COLUMN_SIZE_WIDTH));
53 }
54
55 // =======================================================================
56 // function :  GetItemByIndex
57 // purpose :
58 // =======================================================================
59 TreeModel_ItemBasePtr TreeModel_ModelBase::GetItemByIndex (const QModelIndex& theIndex)
60 {
61   TreeModel_ItemBase* anItem = (TreeModel_ItemBase*)theIndex.internalPointer();
62   return TreeModel_ItemBasePtr (anItem);
63 }
64
65 // =======================================================================
66 // function :  reset
67 // purpose :
68 // =======================================================================
69 void TreeModel_ModelBase::Reset()
70 {
71   for (int aColId = 0, aNbColumns = columnCount(); aColId < aNbColumns; aColId++)
72   {
73     TreeModel_ItemBasePtr aRootItem = RootItem (aColId);
74     if (aRootItem)
75       aRootItem->Reset();
76   }
77 }
78
79 // =======================================================================
80 // function :  index
81 // purpose :
82 // =======================================================================
83 QModelIndex TreeModel_ModelBase::index (int theRow, int theColumn, const QModelIndex& theParent) const
84 {
85   if (!hasIndex (theRow, theColumn, theParent))
86     return QModelIndex();
87
88   // to create index on the root item
89   if (!theParent.isValid())
90     return createIndex (theRow, theColumn, getIndexValue (RootItem (theColumn)));
91
92   TreeModel_ItemBasePtr aParentItem;
93   if (!theParent.isValid())
94     aParentItem = RootItem (theColumn);
95   else
96     aParentItem = GetItemByIndex (theParent);
97
98   TreeModel_ItemBasePtr aChildItem = aParentItem->Child (theRow, theColumn);
99   return aChildItem ? createIndex (theRow, theColumn, getIndexValue (aChildItem)) : QModelIndex();
100 }
101
102 // =======================================================================
103 // function :  data
104 // purpose :
105 // =======================================================================
106 QVariant TreeModel_ModelBase::data (const QModelIndex& theIndex, int theRole) const
107 {
108   if (!theIndex.isValid())
109     return QVariant ("undefined");
110
111   if (IsUseVisibilityColumn() && theIndex.column() == TreeModel_ColumnType_Visibility)
112   {
113     if (theRole != Qt::DecorationRole)
114       return QVariant();
115
116     TreeModel_ItemBasePtr anItem = GetItemByIndex (theIndex);
117     if (!anItem->data (theIndex, theRole).isNull()) // value is already in cache
118       return anItem->data (theIndex, theRole);
119
120     if (!anItem->IsInitialized())
121       anItem->Init();
122
123     if (!myVisibilityState || !myVisibilityState->CanBeVisible (theIndex))
124       return QVariant();
125
126     QVariant aValue = myVisibilityState->IsVisible (theIndex) ? myVisibleIcon : myInvisibleIcon;
127     anItem->SetCustomData (aValue, theRole);
128     return aValue;
129   }
130
131   TreeModel_ItemBasePtr anItem = GetItemByIndex (theIndex);
132   QVariant anItemData = anItem->data (theIndex, theRole);
133
134   if (anItemData.isNull() && theRole == Qt::BackgroundRole && myHighlightedIndices.contains (theIndex))
135     anItemData = TreeModel_Tools::LightHighlightColor();
136
137   return anItemData;
138 }
139
140 // =======================================================================
141 // function :  parent
142 // purpose :
143 // =======================================================================
144 QModelIndex TreeModel_ModelBase::parent (const QModelIndex& theIndex) const
145 {
146   if (!theIndex.isValid())
147     return QModelIndex();
148
149   TreeModel_ItemBasePtr aChildItem = GetItemByIndex (theIndex);
150   TreeModel_ItemBasePtr aParentItem = aChildItem ? aChildItem->Parent() : TreeModel_ItemBasePtr();
151
152   if (!aParentItem)
153     return QModelIndex();
154
155   return createIndex (aParentItem->Row(), aParentItem->Column(), getIndexValue (aParentItem));
156 }
157
158 // =======================================================================
159 // function :  flags
160 // purpose :
161 // =======================================================================
162 Qt::ItemFlags TreeModel_ModelBase::flags (const QModelIndex& theIndex) const
163 {
164   if (!theIndex.isValid())
165   {
166     return Qt::ItemFlags();
167   }
168   return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
169 }
170
171 // =======================================================================
172 // function : headerData
173 // purpose :
174 // =======================================================================
175 QVariant TreeModel_ModelBase::headerData (int theSection, Qt::Orientation theOrientation, int theRole) const
176 {
177   if (theOrientation != Qt::Horizontal || theRole != Qt::DisplayRole)
178     return QVariant();
179
180   if (IsUseVisibilityColumn() && theSection == TreeModel_ColumnType_Visibility)
181     return QVariant();
182
183   return myHeaderValues[theSection].GetName();
184 }
185
186 // =======================================================================
187 // function :  rowCount
188 // purpose :
189 // =======================================================================
190 int TreeModel_ModelBase::rowCount (const QModelIndex& theParent) const
191 {
192   // to create index on the root item
193   if (!theParent.isValid())
194     return 1;
195
196   TreeModel_ItemBasePtr aParentItem;
197   if (!theParent.isValid())
198     aParentItem = RootItem (0);
199   else
200     aParentItem = GetItemByIndex (theParent);
201
202   if (!aParentItem)
203     return 0;
204
205   return aParentItem ? aParentItem->rowCount() : 0;
206 }
207
208 // =======================================================================
209 // function : EmitLayoutChanged
210 // purpose :
211 // =======================================================================
212 void TreeModel_ModelBase::EmitLayoutChanged()
213 {
214   emit layoutChanged();
215 }
216
217 // =======================================================================
218 // function : EmitLayoutChanged
219 // purpose :
220 // =======================================================================
221 void TreeModel_ModelBase::EmitDataChanged (const QModelIndex& theTopLeft, const QModelIndex& theBottomRight,
222                                            const QVector<int>& theRoles,
223                                            const bool isResetItem)
224 {
225   TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (theTopLeft);
226   if (anItemBase && isResetItem)
227     anItemBase->Reset();
228
229 #if QT_VERSION < 0x050000
230   (void)theRoles;
231   emit dataChanged (theTopLeft, theBottomRight);
232 #else
233   emit dataChanged (theTopLeft, theBottomRight, theRoles);
234 #endif
235 }
236
237 // =======================================================================
238 // function : Selected
239 // purpose :
240 // =======================================================================
241 QModelIndexList TreeModel_ModelBase::Selected (const QModelIndexList& theIndices, const int theCellId,
242                                                const Qt::Orientation theOrientation)
243 {
244   QModelIndexList aSelected;
245   for (QModelIndexList::const_iterator anIndicesIt = theIndices.begin(); anIndicesIt != theIndices.end(); anIndicesIt++)
246   {
247     QModelIndex anIndex = *anIndicesIt;
248     if ((theOrientation == Qt::Horizontal && anIndex.column() == theCellId) ||
249         (theOrientation == Qt::Vertical && anIndex.row() == theCellId))
250       aSelected.append (anIndex);
251   }
252   return aSelected;
253 }
254
255 // =======================================================================
256 // function : SingleSelected
257 // purpose :
258 // =======================================================================
259 QModelIndex TreeModel_ModelBase::SingleSelected (const QModelIndexList& theIndices, const int theCellId,
260                                                  const Qt::Orientation theOrientation)
261 {
262   QModelIndexList aSelected = Selected (theIndices, theCellId, theOrientation);
263   return aSelected.size() == 1 ? aSelected.first() : QModelIndex();
264 }
265
266 // =======================================================================
267 // function :  SelectedItems
268 // purpose :
269 // =======================================================================
270 QList<TreeModel_ItemBasePtr> TreeModel_ModelBase::SelectedItems (const QModelIndexList& theIndices)
271 {
272   QList<TreeModel_ItemBasePtr> anItems;
273
274   for (QModelIndexList::const_iterator anIndicesIt = theIndices.begin(); anIndicesIt != theIndices.end(); anIndicesIt++)
275   {
276     TreeModel_ItemBasePtr anItem = TreeModel_ModelBase::GetItemByIndex (*anIndicesIt);
277     if (!anItem || anItems.contains (anItem))
278       continue;
279     anItems.append (anItem);
280   }
281   return anItems;
282 }
283
284 // =======================================================================
285 // function : SubItemsPresentations
286 // purpose :
287 // =======================================================================
288 void TreeModel_ModelBase::SubItemsPresentations (const QModelIndexList& theIndices,
289                                                  NCollection_List<Handle(Standard_Transient)>& thePresentations)
290 {
291   QList<TreeModel_ItemBasePtr> anItems;
292
293   for (QModelIndexList::const_iterator anIndicesIt = theIndices.begin(); anIndicesIt != theIndices.end(); anIndicesIt++)
294   {
295     TreeModel_ItemBasePtr anItem = TreeModel_ModelBase::GetItemByIndex (*anIndicesIt);
296     if (!anItem || anItems.contains (anItem))
297       continue;
298     subItemsPresentations (anItem, thePresentations);
299   }
300 }
301
302 // =======================================================================
303 // function : subItemPresentations
304 // purpose :
305 // =======================================================================
306 void TreeModel_ModelBase::subItemsPresentations (const TreeModel_ItemBasePtr& theItem,
307                                                  NCollection_List<Handle(Standard_Transient)>& thePresentations)
308 {
309   theItem->Presentations (thePresentations);
310
311   QList<TreeModel_ItemBasePtr> anItems;
312   for (int aRowId = 0; aRowId < theItem->rowCount(); aRowId++)
313   {
314     subItemsPresentations (theItem->Child (aRowId, theItem->Column()), thePresentations);
315   }
316 }
317
318 // =======================================================================
319 // function : createRoot
320 // purpose :
321 // =======================================================================
322 void TreeModel_ModelBase::createRoot (const int theColumnId)
323 {
324   myRootItems.insert (theColumnId, createRootItem (theColumnId));
325 }
326
327 // =======================================================================
328 // function : setHeaderItem
329 // purpose :
330 // =======================================================================
331 void TreeModel_ModelBase::setHeaderItem (const int theColumnId, const TreeModel_HeaderSection& theSection)
332 {
333   if (theSection.IsEmpty())
334   {
335     // remove section
336     myHeaderValues.remove (theColumnId);
337     myRootItems.remove (theColumnId);
338   }
339
340   myHeaderValues[theColumnId] = theSection;
341   createRoot (theColumnId);
342 }
343
344 // =======================================================================
345 // function :  getIndexValue
346 // purpose :
347 // =======================================================================
348 void* TreeModel_ModelBase::getIndexValue (const TreeModel_ItemBasePtr& theItem)
349 {
350   return theItem.data();
351 }