0029674: Improvements in Inspector tool
[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_Tools.hxx>
20 #include <inspector/TreeModel_VisibilityState.hxx>
21
22 #include <Standard_WarningsDisable.hxx>
23 #include <QIcon>
24 #include <Standard_WarningsRestore.hxx>
25
26 // =======================================================================
27 // function : Constructor
28 // purpose :
29 // =======================================================================
30 TreeModel_ModelBase::TreeModel_ModelBase (QObject* theParent)
31 : QAbstractItemModel (theParent), m_pRootItem (0), m_pUseVisibilityColumn (false),
32   myVisibilityState (0)
33 {
34 }
35
36 // =======================================================================
37 // function :  GetItemByIndex
38 // purpose :
39 // =======================================================================
40 TreeModel_ItemBasePtr TreeModel_ModelBase::GetItemByIndex (const QModelIndex& theIndex)
41 {
42   TreeModel_ItemBase* anItem = (TreeModel_ItemBase*)theIndex.internalPointer();
43   return TreeModel_ItemBasePtr (anItem);
44 }
45
46 // =======================================================================
47 // function :  reset
48 // purpose :
49 // =======================================================================
50 void TreeModel_ModelBase::Reset()
51 {
52   for (int aColId = 0, aNbColumns = columnCount(); aColId < aNbColumns; aColId++)
53   {
54     TreeModel_ItemBasePtr aRootItem = RootItem (aColId);
55     if (aRootItem)
56       aRootItem->Reset();
57   }
58 }
59
60 // =======================================================================
61 // function :  index
62 // purpose :
63 // =======================================================================
64 QModelIndex TreeModel_ModelBase::index (int theRow, int theColumn, const QModelIndex& theParent) const
65 {
66   if (!hasIndex (theRow, theColumn, theParent))
67     return QModelIndex();
68
69   // to create index on the root item
70   if (!theParent.isValid())
71     return createIndex (theRow, theColumn, getIndexValue (RootItem (theColumn)));
72
73   TreeModel_ItemBasePtr aParentItem;
74   if (!theParent.isValid())
75     aParentItem = RootItem (theColumn);
76   else
77     aParentItem = GetItemByIndex (theParent);
78
79   TreeModel_ItemBasePtr aChildItem = aParentItem->Child (theRow, theColumn);
80   return aChildItem ? createIndex (theRow, theColumn, getIndexValue (aChildItem)) : QModelIndex();
81 }
82
83 // =======================================================================
84 // function :  data
85 // purpose :
86 // =======================================================================
87 QVariant TreeModel_ModelBase::data (const QModelIndex& theIndex, int theRole) const
88 {
89   if (!theIndex.isValid())
90     return QVariant ("undefined");
91
92   if (IsUseVisibilityColumn() && theIndex.column() == TreeModel_ColumnType_Visibility)
93   {
94     if (theRole != Qt::DecorationRole)
95       return QVariant();
96
97     TreeModel_ItemBasePtr anItem = GetItemByIndex (theIndex);
98     if (!anItem->data (theIndex, theRole).isNull()) // value is already in cache
99       return anItem->data (theIndex, theRole);
100
101     if (!anItem->IsInitialized())
102       anItem->Init();
103
104     if (!myVisibilityState || !myVisibilityState->CanBeVisible (theIndex))
105       return QVariant();
106
107     QVariant aValue = QIcon (myVisibilityState->IsVisible (theIndex) ? ":/icons/item_visible.png"
108                                                                      : ":/icons/item_invisible.png");
109     anItem->SetCustomData (aValue, theRole);
110     return aValue;
111   }
112
113   TreeModel_ItemBasePtr anItem = GetItemByIndex (theIndex);
114   return anItem->data (theIndex, theRole);
115 }
116
117 // =======================================================================
118 // function :  parent
119 // purpose :
120 // =======================================================================
121 QModelIndex TreeModel_ModelBase::parent (const QModelIndex& theIndex) const
122 {
123   if (!theIndex.isValid())
124     return QModelIndex();
125
126   TreeModel_ItemBasePtr aChildItem = GetItemByIndex (theIndex);
127   TreeModel_ItemBasePtr aParentItem = aChildItem ? aChildItem->Parent() : TreeModel_ItemBasePtr();
128
129   if (!aParentItem)
130     return QModelIndex();
131
132   return createIndex (aParentItem->Row(), aParentItem->Column(), getIndexValue (aParentItem));
133 }
134
135 // =======================================================================
136 // function :  flags
137 // purpose :
138 // =======================================================================
139 Qt::ItemFlags TreeModel_ModelBase::flags (const QModelIndex& theIndex) const
140 {
141   if (!theIndex.isValid())
142     return 0;
143   return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
144 }
145
146 // =======================================================================
147 // function : headerData
148 // purpose :
149 // =======================================================================
150 QVariant TreeModel_ModelBase::headerData (int theSection, Qt::Orientation theOrientation, int theRole) const
151 {
152   if (theOrientation != Qt::Horizontal || theRole != Qt::DisplayRole)
153     return QVariant();
154
155   if (IsUseVisibilityColumn() && theSection == TreeModel_ColumnType_Visibility)
156     return QVariant();
157
158   return GetHeaderItem (theSection).GetName();
159 }
160
161 // =======================================================================
162 // function :  rowCount
163 // purpose :
164 // =======================================================================
165 int TreeModel_ModelBase::rowCount (const QModelIndex& theParent) const
166 {
167   // to create index on the root item
168   if (!theParent.isValid())
169     return 1;
170
171   TreeModel_ItemBasePtr aParentItem;
172   if (!theParent.isValid())
173     aParentItem = RootItem (0);
174   else
175     aParentItem = GetItemByIndex (theParent);
176
177   return aParentItem ? aParentItem->rowCount() : 0;
178 }
179
180 // =======================================================================
181 // function : EmitLayoutChanged
182 // purpose :
183 // =======================================================================
184 void TreeModel_ModelBase::EmitLayoutChanged()
185 {
186   emit layoutChanged();
187 }
188
189 // =======================================================================
190 // function : EmitLayoutChanged
191 // purpose :
192 // =======================================================================
193 void TreeModel_ModelBase::EmitDataChanged (const QModelIndex& theTopLeft, const QModelIndex& theBottomRight,
194                                            const QVector<int>& theRoles,
195                                            const bool isResetItem)
196 {
197   TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (theTopLeft);
198   if (anItemBase && isResetItem)
199     anItemBase->Reset();
200
201 #if QT_VERSION < 0x050000
202   (void)theRoles;
203   emit dataChanged (theTopLeft, theBottomRight);
204 #else
205   emit dataChanged (theTopLeft, theBottomRight, theRoles);
206 #endif
207 }
208
209 // =======================================================================
210 // function : SingleSelected
211 // purpose :
212 // =======================================================================
213 QModelIndex TreeModel_ModelBase::SingleSelected (const QModelIndexList& theIndices, const int theCellId,
214                                                  const Qt::Orientation theOrientation)
215 {
216   QModelIndexList aFirstColumnSelectedIndices;
217   for (QModelIndexList::const_iterator anIndicesIt = theIndices.begin(); anIndicesIt != theIndices.end(); anIndicesIt++)
218   {
219     QModelIndex anIndex = *anIndicesIt;
220     if ((theOrientation == Qt::Horizontal && anIndex.column() == theCellId) ||
221         (theOrientation == Qt::Vertical && anIndex.row() == theCellId))
222       aFirstColumnSelectedIndices.append (anIndex);
223   }
224   return aFirstColumnSelectedIndices.size() == 1 ? aFirstColumnSelectedIndices.first() : QModelIndex();
225 }
226
227 // =======================================================================
228 // function :  getIndexValue
229 // purpose :
230 // =======================================================================
231 void* TreeModel_ModelBase::getIndexValue (const TreeModel_ItemBasePtr& theItem)
232 {
233   return theItem.data();
234 }