70857bc046c8f010b358c1de83628e2ba8014c22
[occt.git] / tools / DFBrowser / DFBrowser_TreeModel.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/DFBrowser_TreeModel.hxx>
17
18 #include <inspector/DFBrowser_Item.hxx>
19 #include <inspector/DFBrowser_ItemApplication.hxx>
20 #include <inspector/DFBrowser_ItemDocument.hxx>
21 #include <inspector/DFBrowser_Module.hxx>
22 #include <inspector/DFBrowser_Window.hxx>
23 #include <inspector/DFBrowserPane_Tools.hxx>
24 #include <NCollection_List.hxx>
25
26 #include <TDocStd_Application.hxx>
27 #include <TDocStd_Document.hxx>
28 #include <TNaming_Builder.hxx>
29 #include <TNaming_NamedShape.hxx>
30
31 #include <Standard_WarningsDisable.hxx>
32 #include <QAbstractItemModel>
33 #include <Standard_WarningsRestore.hxx>
34
35 const int COLUMN_NAME_WIDTH = 300;
36
37 // =======================================================================
38 // function : Constructor
39 // purpose :
40 // =======================================================================
41 DFBrowser_TreeModel::DFBrowser_TreeModel (QObject* theParent)
42 : TreeModel_ModelBase (theParent)
43 {
44 }
45
46 // =======================================================================
47 // function : InitColumns
48 // purpose :
49 // =======================================================================
50 void DFBrowser_TreeModel::InitColumns()
51 {
52   setHeaderItem (0, TreeModel_HeaderSection ("Name"));
53 }
54
55 // =======================================================================
56 // function : SetModule
57 // purpose :
58 // =======================================================================
59 void DFBrowser_TreeModel::SetModule (DFBrowser_Module* theModule)
60 {
61   DFBrowser_ItemApplicationPtr aRootItem = itemDynamicCast<DFBrowser_ItemApplication> (RootItem (0));
62   aRootItem->SetModule (theModule);
63 }
64
65 // =======================================================================
66 // function : createRootItem
67 // purpose :
68 // =======================================================================
69 TreeModel_ItemBasePtr DFBrowser_TreeModel::createRootItem (const int)
70 {
71   return DFBrowser_ItemApplication::CreateItem (TreeModel_ItemBasePtr());
72 }
73
74 // =======================================================================
75 // function : Init
76 // purpose :
77 // =======================================================================
78 void DFBrowser_TreeModel::Init (const Handle(TDocStd_Application)& theApplication)
79 {
80   DFBrowser_ItemApplicationPtr aRootItem = itemDynamicCast<DFBrowser_ItemApplication> (RootItem (0));
81   Reset();
82   aRootItem->SetApplication (theApplication);
83   EmitLayoutChanged();
84 }
85
86 // =======================================================================
87 // function : GetTDocStdApplication
88 // purpose :
89 // =======================================================================
90 Handle(TDocStd_Application) DFBrowser_TreeModel::GetTDocStdApplication() const
91 {
92   DFBrowser_ItemApplicationPtr aRootItem = itemDynamicCast<DFBrowser_ItemApplication> (RootItem (0));
93   return aRootItem->GetApplication();
94 }
95
96 // =======================================================================
97 // function : FindIndex
98 // purpose :
99 // =======================================================================
100 QModelIndex DFBrowser_TreeModel::FindIndex (const TDF_Label& theLabel) const
101 {
102   TDF_Label aRoot = theLabel.Root();
103
104   NCollection_List<TDF_Label> aLabels;
105   aLabels.Prepend (theLabel);
106   TDF_Label aFather = theLabel.Father();
107   if (!aFather.IsNull())
108   {
109     while (aFather != aRoot)
110     {
111       aLabels.Prepend (aFather);
112       aFather = aFather.Father();
113     }
114   }
115   bool aDocumentItemFound = false;
116   QModelIndex aParentIndex = index (0, 0);
117   TreeModel_ItemBasePtr aParentItem = TreeModel_ModelBase::GetItemByIndex (aParentIndex); // application item
118   // find document, where label of document item is equal to Root label
119   for (int aChildId = 0, aCount = aParentItem->rowCount(); aChildId < aCount; aChildId++)
120   {
121     QModelIndex anIndex = index (aChildId, 0, aParentIndex);
122     TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
123     DFBrowser_ItemDocumentPtr anItem = itemDynamicCast<DFBrowser_ItemDocument> (anItemBase);
124     if (anItem->GetLabel() == aRoot)
125     {
126       aParentItem = anItem;
127       aParentIndex = anIndex;
128       aDocumentItemFound = true;
129       break;
130     }
131   }
132   if (!aDocumentItemFound) // document is not found
133     return QModelIndex();
134
135   for (NCollection_List<TDF_Label>::const_iterator aLabelIt = aLabels.begin(); aLabelIt != aLabels.end()
136        && aParentIndex.isValid(); aLabelIt++)
137   {
138     const TDF_Label aLabel = *aLabelIt;
139     for (int aParentChildId = 0, aCount = aParentItem->rowCount(); aParentChildId < aCount; aParentChildId++)
140     {
141       QModelIndex anIndex = index (aParentChildId, 0, aParentIndex);
142       DFBrowser_ItemPtr anItem = itemDynamicCast<DFBrowser_Item> (TreeModel_ModelBase::GetItemByIndex (anIndex));
143       if (anItem->HasAttribute())
144         continue;
145
146       if (anItem->HasLabel() && anItem->GetLabel().IsEqual (aLabel))
147       {
148         aParentItem = anItem;
149         aParentIndex = anIndex;
150         break;
151       }
152     }
153   }
154   return aParentIndex;
155 }
156
157 // =======================================================================
158 // function : FindIndexByPath
159 // purpose :
160 // =======================================================================
161 QModelIndex DFBrowser_TreeModel::FindIndexByPath (const QStringList& theLabelEntries, const QString& theValue) const
162 {
163   QModelIndex aFoundIndex;
164
165   QModelIndex aRootIndex = index (0, 0);
166   TreeModel_ItemBasePtr aRootItem = TreeModel_ModelBase::GetItemByIndex (aRootIndex); // application item
167   // find document, where label of document item is equal to Root label
168   for (int aDocItemId = 0, aNbDocItems = aRootItem->rowCount(); aDocItemId < aNbDocItems && !aFoundIndex.isValid(); aDocItemId++)
169   {
170     QModelIndex aParentIndex = index (aDocItemId, 0, aRootIndex);
171     if (!aParentIndex.isValid()) // OCAF document for this document item is not found
172       continue;
173     if (theLabelEntries.size() == 0)
174     {
175       aFoundIndex = aParentIndex;
176       break;
177     }
178     TreeModel_ItemBasePtr aParentItem = TreeModel_ModelBase::GetItemByIndex (aParentIndex);
179     for (int aPathId = 1, aPathCount = theLabelEntries.size(); aPathId < aPathCount + 1; aPathId++)
180     {
181       QString anEntry;
182       if (aPathId < aPathCount)
183         anEntry = theLabelEntries[aPathId];
184       else
185         anEntry = theValue;
186
187       bool aFoundEntry = false;
188       for (int aChildId = 0, aNbChildren = aParentItem->rowCount(); aChildId < aNbChildren; aChildId++)
189       {
190         QModelIndex anIndex = index (aChildId, 0, aParentIndex);
191         TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
192         DFBrowser_ItemPtr anItem = itemDynamicCast<DFBrowser_Item> (anItemBase);
193
194         if (aPathId == aPathCount && anItem->HasAttribute())
195         {
196           // processing attribute in theValue
197           DFBrowser_ItemApplicationPtr aRootAppItem = itemDynamicCast<DFBrowser_ItemApplication>(RootItem (0));
198           QString anAttributeInfo = DFBrowser_Module::GetAttributeInfo (anItem->GetAttribute(), aRootAppItem->GetModule(),
199                                                                         Qt::DisplayRole, 0).toString();
200           if (anAttributeInfo == anEntry)
201           {
202             aParentItem = anItem;
203             aParentIndex = anIndex;
204             aFoundEntry = true;
205             break;
206           }
207         }
208         else if (anItem->HasLabel() &&
209                  anEntry == QString (DFBrowserPane_Tools::GetEntry (anItem->GetLabel()).ToCString()))
210         {
211           aParentItem = anItem;
212           aParentIndex = anIndex;
213           aFoundEntry = true;
214           break;
215         }
216
217       }
218       if (!aFoundEntry) // an entry is not found on some level tree, find it in other documents
219         break;
220       else
221         aFoundIndex = aParentIndex;
222     }
223   }
224   return aFoundIndex;
225 }
226
227 // =======================================================================
228 // function : FindIndexByAttribute
229 // purpose :
230 // =======================================================================
231 QModelIndex DFBrowser_TreeModel::FindIndexByAttribute (Handle(TDF_Attribute) theAttribute) const
232 {
233   QModelIndex aFoundIndex;
234   const TDF_Label aLabel = theAttribute->Label();
235
236   QModelIndex aParentIndex = FindIndex (aLabel);
237   if (!aParentIndex.isValid())
238     return aFoundIndex;
239
240   TreeModel_ItemBasePtr aParentItem = TreeModel_ModelBase::GetItemByIndex (aParentIndex);
241   for (int aChildId = 0, aCount = aParentItem->rowCount(); aChildId < aCount; aChildId++)
242   {
243     QModelIndex anIndex = index (aChildId, 0, aParentIndex);
244     TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex (anIndex);
245     DFBrowser_ItemPtr anItem = itemDynamicCast<DFBrowser_Item> (anItemBase);
246     if (anItem->GetAttribute() == theAttribute)
247     {
248       aFoundIndex = anIndex;
249       break;
250     }
251   }
252   return aFoundIndex;
253 }
254
255 // =======================================================================
256 // function : ConvertToIndices
257 // purpose :
258 // =======================================================================
259 void DFBrowser_TreeModel::ConvertToIndices (const NCollection_List<TDF_Label>& theReferences,
260                                             QModelIndexList& theIndices)
261 {
262   for (NCollection_List<TDF_Label>::Iterator aLabelItr (theReferences); aLabelItr.More(); aLabelItr.Next())
263     theIndices.append (FindIndex (aLabelItr.Value()));
264 }
265
266 // =======================================================================
267 // function : ConvertToIndices
268 // purpose :
269 // =======================================================================
270 void DFBrowser_TreeModel::ConvertToIndices (const NCollection_List<Handle(TDF_Attribute)>& theReferences,
271                                             QModelIndexList& theIndices)
272 {
273   for (NCollection_List<Handle(TDF_Attribute)>::Iterator anAttrItr (theReferences); anAttrItr.More(); anAttrItr.Next())
274     theIndices.append(FindIndexByAttribute (anAttrItr.Value()));
275 }
276
277 // =======================================================================
278 // function : data
279 // purpose :
280 // =======================================================================
281 QVariant DFBrowser_TreeModel::data (const QModelIndex& theIndex, int theRole) const
282 {
283   if (theRole == Qt::BackgroundRole && myHighlightedIndices.contains (theIndex))
284     return DFBrowserPane_Tools::LightHighlightColor();
285   return TreeModel_ModelBase::data (theIndex, theRole);
286 }