0027398: Integrate Qt Browser Widget to Open CASCADE Technology
[occt.git] / tools / DFBrowser / DFBrowser_ThreadItemUsedShapesMap.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 <DFBrowser_ThreadItemUsedShapesMap.hxx>
17
18 #include <DFBrowser_Module.hxx>
19 #include <DFBrowser_Tools.hxx>
20 #include <DFBrowser_TreeModel.hxx>
21
22 #include <DFBrowserPane_TNamingUsedShapes.hxx>
23 #include <DFBrowserPane_Tools.hxx>
24
25 #include <TNaming_DataMapIteratorOfDataMapOfShapePtrRefShape.hxx>
26 #include <TNaming_PtrRefShape.hxx>
27 #include <TNaming_RefShape.hxx>
28 #include <TNaming_UsedShapes.hxx>
29
30 #include <Standard_Type.hxx>
31 #include <TDocStd_Document.hxx>
32
33 // =======================================================================
34 // function : Run
35 // purpose :
36 // =======================================================================
37 void DFBrowser_ThreadItemUsedShapesMap::Run()
38 {
39   if (!myModule)
40     return;
41   DFBrowser_TreeModel* aDFBrowserModel = dynamic_cast<DFBrowser_TreeModel*> (myModule->GetOCAFViewModel());
42   if (!aDFBrowserModel)
43     return;
44
45   Handle(TDocStd_Application) anApplication = aDFBrowserModel->GetTDocStdApplication();
46   if (anApplication.IsNull())
47     return;
48
49   for (Standard_Integer aDocId = 1, aNbDocuments = anApplication->NbDocuments(); aDocId <= aNbDocuments; aDocId++)
50   {
51     Handle(TDocStd_Document) aDocument;
52     anApplication->GetDocument (aDocId, aDocument);
53     if (aDocument.IsNull())
54       continue;
55
56     TDF_Label aLabel = aDocument->Main().Root();
57
58     Handle(TNaming_UsedShapes) anAttribute;
59     if (!aLabel.FindAttribute (TNaming_UsedShapes::GetID(), anAttribute))
60       continue;
61
62     std::list<TCollection_AsciiString> aReferences;
63     findReferences (anAttribute, aReferences);
64     if (!aReferences.empty())
65       myAttributeRefs.Bind (anAttribute, aReferences);
66   }
67 }
68
69 // =======================================================================
70 // function : ApplyValues
71 // purpose :
72 // =======================================================================
73 void DFBrowser_ThreadItemUsedShapesMap::ApplyValues()
74 {
75  if (myAttributeRefs.IsEmpty())
76     return;
77
78   DFBrowserPane_AttributePaneAPI* aPane = myModule->GetAttributePane (STANDARD_TYPE (TNaming_UsedShapes)->Name());
79   if (aPane)
80   {
81     DFBrowserPane_TNamingUsedShapes* aUsedShapesPane = dynamic_cast<DFBrowserPane_TNamingUsedShapes*> (aPane);
82     aUsedShapesPane->SetSortedReferences (myAttributeRefs);
83   }
84   // update
85   DFBrowser_TreeModel* aDFBrowserModel = dynamic_cast<DFBrowser_TreeModel*> (myModule->GetOCAFViewModel());
86   for (NCollection_DataMap<Handle(TDF_Attribute), std::list<TCollection_AsciiString> >::Iterator aRefIt (myAttributeRefs);
87        aRefIt.More(); aRefIt.Next())
88   {
89     TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex
90                                                    (aDFBrowserModel->FindIndexByAttribute (aRefIt.Key()));
91     if (anItemBase)
92       anItemBase->Init();
93   }
94   // clear cache
95   myAttributeRefs.Clear();
96 }
97
98 // =======================================================================
99 // function : ClearSortedReferences
100 // purpose :
101 // =======================================================================
102 void DFBrowser_ThreadItemUsedShapesMap::ClearSortedReferences (DFBrowser_Module* theModule)
103 {
104   DFBrowserPane_AttributePaneAPI* aPane = theModule->GetAttributePane (STANDARD_TYPE (TNaming_UsedShapes)->Name());
105   if (!aPane)
106     return;
107
108   DFBrowserPane_TNamingUsedShapes* aUsedShapesPane = dynamic_cast<DFBrowserPane_TNamingUsedShapes*> (aPane);
109   aUsedShapesPane->ClearSortedReferences();
110
111   // update tree item state
112   DFBrowser_TreeModel* aDFBrowserModel = dynamic_cast<DFBrowser_TreeModel*> (theModule->GetOCAFViewModel());
113   if (!aDFBrowserModel)
114     return;
115   Handle(TDocStd_Application) anApplication = aDFBrowserModel->GetTDocStdApplication();
116   if (anApplication.IsNull())
117     return;
118
119   for (Standard_Integer aDocId = 1, aNbDocuments = anApplication->NbDocuments(); aDocId <= aNbDocuments; aDocId++)
120   {
121     Handle(TDocStd_Document) aDocument;
122     anApplication->GetDocument (aDocId, aDocument);
123     if (aDocument.IsNull())
124       continue;
125     TDF_Label aLabel = aDocument->Main().Root();
126     Handle(TNaming_UsedShapes) anAttribute;
127     if (aLabel.FindAttribute (TNaming_UsedShapes::GetID(), anAttribute))
128     {
129       TreeModel_ItemBasePtr anItemBase = TreeModel_ModelBase::GetItemByIndex(
130                                                               aDFBrowserModel->FindIndexByAttribute (anAttribute));
131       if (anItemBase)
132         anItemBase->Init();
133     }
134   }
135 }
136
137 // =======================================================================
138 // function : isLessThan
139 // purpose :
140 // =======================================================================
141 bool DFBrowser_ThreadItemUsedShapesMap::isLessThan (const QStringList& theLeft, const QStringList& theRight)
142 {
143   int aState = 1; //! where 0 - less, 1 - equal, 2 - larger
144   int aLeftSize = theLeft.size();
145   int aRightSize = theRight.size();
146
147   for (int anItemId = 0; anItemId < aRightSize && anItemId < aLeftSize && aState == 1; anItemId++)
148   {
149     int aRightId = theRight[anItemId].toInt();
150     int aLeftId = theLeft[anItemId].toInt();
151     if (aLeftId == aRightId)
152       continue;
153     else if (aLeftId < aRightId)
154       aState = 0; // less
155     else if (aLeftId > aRightId)
156       aState = 2; // less
157   }
158   if (aState == 1)
159   { // equal in similar parts
160     if (aLeftSize < aRightSize)
161       aState = 0;
162     else if (aLeftSize > aRightSize)
163       aState = 2;
164   }
165   return aState == 0;
166 }
167
168 // =======================================================================
169 // function : addValue
170 // purpose :
171 // =======================================================================
172 void DFBrowser_ThreadItemUsedShapesMap::addValue (const TCollection_AsciiString& theEntry,
173                                                   QList<QPair<TCollection_AsciiString, QStringList > >& theEntries)
174 {
175   QStringList aSplit = QString (theEntry.ToCString()).split (":");
176
177   int aLessIndex = -1;
178   bool isInserted = false;
179   // looking for nearest smaller value from the end of the list
180   for (int anEntryId = theEntries.size() - 1; anEntryId >= 0 && !isInserted; anEntryId--)
181   {
182     if (isLessThan(aSplit, theEntries[anEntryId].second))
183       aLessIndex = anEntryId;
184     else
185     {
186       // if less than was found and now, the entry is greater than current entry
187       if (aLessIndex != -1)
188       {
189         theEntries.insert (aLessIndex, qMakePair (theEntry, aSplit));
190         isInserted = true;
191       }
192       break;
193     }
194   }
195   if (!isInserted)
196   {
197     if (aLessIndex != -1) // less than all, insert at this position
198       theEntries.insert (aLessIndex, qMakePair (theEntry, aSplit));
199     else
200       theEntries.append (qMakePair (theEntry, aSplit));
201   }
202 }
203
204 // =======================================================================
205 // function : findReferences
206 // purpose :
207 // =======================================================================
208 //#define REQUIRE_OCAF_REVIEW:26 : start
209 void DFBrowser_ThreadItemUsedShapesMap::findReferences (Handle(TDF_Attribute) theAttribute,
210                                                         std::list<TCollection_AsciiString>& theReferences)
211 {
212   Handle(TNaming_UsedShapes) anAttribute = Handle(TNaming_UsedShapes)::DownCast (theAttribute);
213
214   QList<QPair<TCollection_AsciiString, QStringList> > anEntries;
215   for (TNaming_DataMapIteratorOfDataMapOfShapePtrRefShape aDataIt(anAttribute->Map()); aDataIt.More(); aDataIt.Next())
216     addValue(DFBrowserPane_Tools::GetEntry (aDataIt.Value()->Label()), anEntries);
217
218   for (QList<QPair<TCollection_AsciiString, QStringList> >::const_iterator anEntryIt = anEntries.begin();
219        anEntryIt != anEntries.end(); anEntryIt++)
220     theReferences.push_back (anEntryIt->first);
221 }
222 //#define REQUIRE_OCAF_REVIEW:26 : end