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