0029018: Documentation - Provide user guide for Qt browser
[occt.git] / tools / ToolsDraw / ToolsDraw.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/ToolsDraw.hxx>
17 #include <inspector/ToolsDraw.hxx>
18
19 #include <AIS_InteractiveContext.hxx>
20 #include <BRep_Builder.hxx>
21 #include <BRepTools.hxx>
22 #include <DBRep.hxx>
23 #include <DDocStd.hxx>
24 #include <Draw.hxx>
25 #include <Draw_PluginMacro.hxx>
26 #include <NCollection_DataMap.hxx>
27 #include <Standard_Stream.hxx>
28 #include <TDocStd_Application.hxx>
29 #include <inspector/TInspector_Communicator.hxx>
30 #include <TopoDS_Shape.hxx>
31 #include <ViewerTest.hxx>
32 #include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
33
34 #if ! defined(_WIN32)
35 extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
36 #else
37 Standard_EXPORT ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
38 #endif
39
40 static TInspector_Communicator* MyCommunicator;
41
42 // =======================================================================
43 // function : convertToPluginName
44 // purpose  : defines plugin library name by the command argument
45 // =======================================================================
46 Standard_Boolean convertToPluginName (const TCollection_AsciiString& theArgument,
47                                       TCollection_AsciiString& thePluginName)
48 {
49   TCollection_AsciiString anArgument = theArgument;
50   anArgument.LowerCase();
51
52   if (anArgument == "dfbrowser")       { thePluginName = "TKDFBrowser"; return Standard_True; }
53   else if (anArgument == "shapeview")  { thePluginName = "TKShapeView"; return Standard_True; }
54   else if (anArgument == "vinspector") { thePluginName = "TKVInspector"; return Standard_True; }
55
56   return Standard_False;
57 }
58
59 // =======================================================================
60 // function : getArgumentPlugins
61 // purpose  : fills container of plugin names by the next following plugin names
62 // =======================================================================
63 void getArgumentPlugins (Standard_Integer theArgsNb, const char** theArgs, Standard_Integer& theIt,
64                          NCollection_List<TCollection_AsciiString>& thePlugins)
65 {
66   while (theIt != theArgsNb)
67   {
68     TCollection_AsciiString aPluginName;
69     if (convertToPluginName (theArgs[theIt], aPluginName))
70     {
71       if (!thePlugins.Contains (aPluginName))
72         thePlugins.Append (aPluginName);
73     }
74     else
75     {
76       break;
77     }
78     theIt++;
79   }
80   theIt--; // the last not processed parameter is the next argument
81 }
82
83 // =======================================================================
84 // function : tinspector
85 // purpose  : 
86 // =======================================================================
87 static int tinspector (Draw_Interpretor&/* di*/, Standard_Integer theArgsNb, const char** theArgs)
88 {
89   if (theArgsNb < 1)
90   {
91     std::cout << "Error: wrong number of arguments.\n";
92     return 1;
93   }
94
95   // parse command arguments
96   NCollection_List<TCollection_AsciiString> aPlugins;
97   NCollection_DataMap<TCollection_AsciiString, NCollection_List<Handle(Standard_Transient)> > aParameters;
98   NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString > anOpenFileParameters;
99   TCollection_AsciiString aPluginNameToActivate;
100   Standard_Boolean aNeedToUpdateContent = Standard_False,
101                    aNeedToHideInspector = Standard_False,
102                    aNeedToShowInspector = Standard_False;
103
104   NCollection_List<Handle(Standard_Transient)> aDefaultParameters;
105   TCollection_AsciiString aDefaultOpenFileParameter;
106
107   NCollection_List<Handle(Standard_Transient)> anObjectsToSelect;
108   NCollection_List<TCollection_AsciiString> anItemNamesToSelect;
109
110   for (Standard_Integer anIt = 1; anIt < theArgsNb; ++anIt)
111   {
112     TCollection_AsciiString aParam (theArgs[anIt]);
113     aParam.LowerCase();
114
115     if (aParam.IsEqual ("-plugins")) // [-plugins {name1 [name2] ... [name3] | all}]
116     {
117       anIt++;
118       getArgumentPlugins(theArgsNb, theArgs, anIt, aPlugins);
119     }
120     else if (aParam.IsEqual ("-activate")) // [-activate name]
121     {
122       anIt++;
123       if (anIt == theArgsNb)
124       {
125         cout << "Empty argument of '" << aParam << "'.\n";
126         return 1;
127       }
128       TCollection_AsciiString aPluginName;
129       if (convertToPluginName (theArgs[anIt], aPluginName))
130         aPluginNameToActivate = aPluginName;
131     }
132     else if (aParam.IsEqual ("-shape")) // [-shape object [name1] ... [nameN]]
133     {
134       anIt++;
135       if (anIt == theArgsNb)
136       {
137         cout << "Empty argument of '" << aParam << "'.\n";
138         return 1;
139       }
140       TopoDS_Shape aShape = DBRep::Get (theArgs[anIt]);
141       anIt++;
142       if (aShape.IsNull())
143       {
144         cout << "Wrong shape name: " << aParam << ".\n";
145         return 1;
146       }
147       NCollection_List<TCollection_AsciiString> anArgPlugins;
148       getArgumentPlugins(theArgsNb, theArgs, anIt, anArgPlugins);
149       if (anArgPlugins.IsEmpty())
150         aDefaultParameters.Append(aShape.TShape());
151       else
152       {
153         for (NCollection_List<TCollection_AsciiString>::Iterator anArgIt (anArgPlugins);
154           anArgIt.More(); anArgIt.Next())
155         {
156           NCollection_List<Handle(Standard_Transient)> aPluginParameters;
157           aParameters.Find(anArgIt.Value(), aPluginParameters);
158           aPluginParameters.Append(aShape.TShape());
159           aParameters.Bind (anArgIt.Value(), aPluginParameters);
160         }
161       }
162     }
163     else if (aParam.IsEqual ("-open")) // [-open file_name [name1] ... [nameN]]
164     {
165       anIt++;
166       if (anIt == theArgsNb)
167       {
168         cout << "Empty argument of '" << aParam << "'.\n";
169         return 1;
170       }
171       TCollection_AsciiString aFileName (theArgs[anIt]);
172       anIt++;
173
174       NCollection_List<TCollection_AsciiString> anArgPlugins;
175       getArgumentPlugins(theArgsNb, theArgs, anIt, anArgPlugins);
176       if (anArgPlugins.IsEmpty())
177         aDefaultOpenFileParameter = aFileName;
178       else
179       {
180         for (NCollection_List<TCollection_AsciiString>::Iterator anArgIt (anArgPlugins);
181           anArgIt.More(); anArgIt.Next())
182         {
183           NCollection_List<Handle(Standard_Transient)> aPluginParameters;
184           aParameters.Find(anArgIt.Value(), aPluginParameters);
185           anOpenFileParameters.Bind(anArgIt.Value(), aFileName);
186         }
187       }
188     }
189     else if (aParam.IsEqual ("-update")) // [-update]
190     {
191       aNeedToUpdateContent = Standard_True;
192     }
193     else if (aParam.IsEqual ("-select")) // [-select {name|object}]
194     {
195       anIt++;
196       if (anIt == theArgsNb)
197       {
198         cout << "Empty argument of '" << aParam << "'.\n";
199         return 1;
200       }
201       // search shape with given name
202       TopoDS_Shape aShape = DBRep::Get (theArgs[anIt]);
203       if (!aShape.IsNull())
204       {
205         anObjectsToSelect.Append(aShape.TShape());
206       }
207       // search prsentations with given name
208       if (GetMapOfAIS().IsBound2(theArgs[anIt]))
209       {
210         Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast
211           (GetMapOfAIS().Find2 (theArgs[anIt]));
212         if (!anIO.IsNull())
213         anObjectsToSelect.Append(anIO);
214       }
215       // give parameters as a container of names
216       aParam = TCollection_AsciiString (theArgs[anIt]);
217       while (!aParam.StartsWith ("-"))
218       {
219         anItemNamesToSelect.Append (aParam);
220         anIt++;
221         if (anIt >= theArgsNb)
222           break;
223         aParam = theArgs[anIt];
224       }
225       anIt--;
226     }
227     else if (aParam.IsEqual ("-show")) // [-show {0|1} = 1]
228     {
229       anIt++;
230       if (anIt == theArgsNb)
231       {
232         cout << "Empty argument of '" << aParam << "'.\n";
233         return 1;
234       }
235       aNeedToHideInspector = Draw::Atoi (theArgs[anIt]) == 0;
236       aNeedToShowInspector = Draw::Atoi (theArgs[anIt]) > 0;
237     }
238     else
239     {
240       cout << "Wrong argument of command: " << aParam.ToCString() << "\n";
241       return 1;
242     }
243   }
244
245   // start inspector
246   Standard_Boolean isTInspectorCreation = !MyCommunicator;
247   if (!MyCommunicator)
248     MyCommunicator = new TInspector_Communicator();
249
250   Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
251   if (!aContext.IsNull())
252     aDefaultParameters.Append (aContext);
253
254   // Sets OCAF application into DFBrowser
255   const Handle(TDocStd_Application)& anApplication = DDocStd::GetApplication();
256   // Initialize standard document formats at creation - they should
257   // be available even if this DRAW plugin is not loaded by pload command
258   if (!anApplication.IsNull())
259   {
260     NCollection_List<Handle(Standard_Transient)> aDFBrowserParameters;
261     aParameters.Find("TKDFBrowser", aDFBrowserParameters);
262     aDFBrowserParameters.Append(anApplication);
263     aParameters.Bind ("TKDFBrowser", aDFBrowserParameters);
264   }
265
266   // by starting, if the plugns were not defined, register all
267   if (isTInspectorCreation)
268   {
269     if (aPlugins.IsEmpty())
270     {
271       aPlugins.Append("TKDFBrowser");
272       aPlugins.Append("TKShapeView");
273       aPlugins.Append("TKVInspector");
274     }
275     aPluginNameToActivate = !aPluginNameToActivate.IsEmpty() ? aPluginNameToActivate : aPlugins.First();
276   }
277
278   // register plugin from parameters
279   for (NCollection_List<TCollection_AsciiString>::Iterator aPluginNameIt (aPlugins);
280        aPluginNameIt.More(); aPluginNameIt.Next())
281     MyCommunicator->RegisterPlugin (aPluginNameIt.Value());
282
283   // init all registered plugins with the default and parameters values
284   NCollection_List<TCollection_AsciiString> aRegisteredPlugins = MyCommunicator->RegisteredPlugins();
285   for (NCollection_List<TCollection_AsciiString>::Iterator anIterator (aRegisteredPlugins);
286     anIterator.More(); anIterator.Next())
287   {
288     TCollection_AsciiString aPluginName = anIterator.Value();
289     NCollection_List<Handle(Standard_Transient)> aParameterValues;
290     aParameters.Find (aPluginName, aParameterValues);
291
292     for (NCollection_List<Handle(Standard_Transient)>::Iterator aDefIt(aDefaultParameters);
293          aDefIt.More(); aDefIt.Next())
294       aParameterValues.Append (aDefIt.Value());
295     MyCommunicator->Init (aPluginName, aParameterValues, Standard_True);
296   }
297
298   if (!aPluginNameToActivate.IsEmpty())
299     MyCommunicator->Activate (!aPluginNameToActivate.IsEmpty() ? aPluginNameToActivate : aPlugins.First());
300
301   if (!anOpenFileParameters.IsEmpty())
302   {
303     for (NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString >::Iterator anOpenIt
304       (anOpenFileParameters); anOpenIt.More(); anOpenIt.Next())
305       MyCommunicator->OpenFile(anOpenIt.Key(), anOpenIt.Value());
306   }
307   else if (!aDefaultOpenFileParameter.IsEmpty()) // open file in active plugin
308     MyCommunicator->OpenFile("", aDefaultOpenFileParameter);
309
310   if (!anObjectsToSelect.IsEmpty())
311     MyCommunicator->SetSelected(anObjectsToSelect);
312
313   if (!anItemNamesToSelect.IsEmpty())
314     MyCommunicator->SetSelected(anItemNamesToSelect);
315
316   if (aNeedToUpdateContent)
317     MyCommunicator->UpdateContent();
318
319   if (isTInspectorCreation || aNeedToShowInspector)
320     MyCommunicator->SetVisible (true);
321
322   if (aNeedToHideInspector)
323     MyCommunicator->SetVisible (false);
324
325   return 0;
326 }
327
328 // =======================================================================
329 // function : Commands
330 // purpose  : 
331 // =======================================================================
332 void ToolsDraw::Commands(Draw_Interpretor& theCommands)
333 {
334   const char *group = "Tools";
335
336   // display
337   theCommands.Add ("tinspector",
338     "tinspector [-plugins {name1 ... [nameN] | all}]"
339     "\n\t\t:            [-activate name]"
340     "\n\t\t:            [-shape object [name1] ... [nameN]]"
341     "\n\t\t:            [-open file_name [name1] ... [nameN]]"
342     "\n\t\t:            [-update]"
343     "\n\t\t:            [-select {object | name1 ... [nameN]}]"
344     "\n\t\t:            [-show {0|1} = 1]"
345     "\n\t\t: Starts tool of inspection."
346     "\n\t\t: Options:"
347     "\n\t\t:  -plugins enters plugins that should be added in the inspector."
348     "\n\t\t:           Available names are: dfbrowser, vinspector and shapeview."
349     "\n\t\t:           Plugins order will be the same as defined in arguments."
350     "\n\t\t:           'all' adds all available plugins in the order:"
351     "\n\t\t:                 DFBrowser, VInspector and ShapeView."
352     "\n\t\t:           If at the first call this option is not used, 'all' option is applyed;"
353     "\n\t\t:  -activate activates the plugin in the tool view."
354     "\n\t\t:           If at the first call this option is not used, the first plugin is activated;"
355     "\n\t\t:  -shape initializes plugin/s by the shape object. If 'name' is empty, initializes all plugins;"
356     "\n\t\t:  -open gives the file to the plugin/s. If the plugin is active, after open, update content will be done;"
357     "\n\t\t:  -update updates content of the active plugin;"
358     "\n\t\t:  -select sets the parameter that should be selected in an active tool view."
359     "\n\t\t:          Depending on active tool the parameter is:"
360     "\n\t\t:          ShapeView: 'object' is an instance of TopoDS_Shape TShape,"
361     "\n\t\t:          DFBrowser: 'name' is an entry of TDF_Label and name2(optionaly) for TDF_Attribute type name,"
362     "\n\t\t:          VInspector: 'object' is an instance of AIS_InteractiveObject;"
363     "\n\t\t:  -show sets Inspector view visible or hidden. The first call of this command will show it.",
364       __FILE__, tinspector, group);
365 }
366
367 // =======================================================================
368 // function : Factory
369 // purpose  : 
370 // =======================================================================
371 void ToolsDraw::Factory (Draw_Interpretor& theDI)
372 {
373   // definition of Tools Command
374   ToolsDraw::Commands (theDI);
375
376 #ifdef OCCT_DEBUG
377       theDI << "Draw Plugin : OCC Tools commands are loaded\n";
378 #endif
379 }
380
381 // Declare entry point PLUGINFACTORY
382 DPLUGIN (ToolsDraw)