0029018: Documentation - Provide user guide for Qt browser
[occt.git] / tools / TInspector / TInspector_Window.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/TInspector_Window.hxx>
17 #include <inspector/TInspector_Window.hxx>
18
19 #include <inspector/TInspectorAPI_Communicator.hxx>
20 #include <inspector/TInspector_PluginParameters.hxx>
21
22 #include <QApplication>
23 #include <QDockWidget>
24 #include <QLabel>
25 #include <QMainWindow>
26 #include <QPushButton>
27 #include <QStackedWidget>
28 #include <QVBoxLayout>
29
30 const int TINSPECTOR_DEFAULT_WIDTH = 650;
31 const int TINSPECTOR_DEFAULT_HEIGHT = 500;//350;
32 const int TINSPECTOR_DEFAULT_POSITION_X = 200;
33 const int TINSPECTOR_DEFAULT_POSITION_Y = 60;
34
35 // =======================================================================
36 // function : Constructor
37 // purpose :
38 // =======================================================================
39 TInspector_Window::TInspector_Window()
40 : QObject(), myOpenButton (0)
41 {
42   myMainWindow = new QMainWindow();
43
44   QWidget* aCentralWidget = new QWidget (myMainWindow);
45   myMainWindow->setCentralWidget (aCentralWidget);
46   QVBoxLayout* aCentralLayout = new QVBoxLayout (aCentralWidget);
47   aCentralLayout->setContentsMargins (0, 0, 0, 0);
48   aCentralLayout->setSpacing (0);
49
50   myToolsStack = new QStackedWidget (aCentralWidget);
51   myToolsStack->setFrameShape (QFrame::Box);
52   aCentralLayout->addWidget (myToolsStack);
53
54   myEmptyWidget = new QWidget (aCentralWidget);
55   myToolsStack->addWidget (myEmptyWidget);
56
57   myButtonWidget = new QWidget (aCentralWidget);
58   myButtonLay = new QHBoxLayout (myButtonWidget);
59   myButtonLay->setContentsMargins (0, 0, 0, 0);
60   myButtonLay->setSpacing (0);
61   myButtonLay->insertStretch (0, 1);
62
63   aCentralLayout->addWidget (myButtonWidget);
64   aCentralLayout->addWidget (myToolsStack);
65
66   myMainWindow->resize (TINSPECTOR_DEFAULT_WIDTH, TINSPECTOR_DEFAULT_HEIGHT);
67   myMainWindow->move (TINSPECTOR_DEFAULT_POSITION_X, TINSPECTOR_DEFAULT_POSITION_Y);
68   myMainWindow->setDockOptions (QMainWindow::VerticalTabs);
69
70   myParameters = new TInspector_PluginParameters (this);
71 }
72
73 // =======================================================================
74 // function : RegisterPlugin
75 // purpose :
76 // =======================================================================
77 void TInspector_Window::RegisterPlugin (const TCollection_AsciiString& thePluginName)
78 {
79   TInspector_ToolInfo anInfo;
80   int aToolId;
81   if (FindPlugin (thePluginName, anInfo, aToolId))
82     return;
83
84   myToolNames.append (TInspector_ToolInfo (thePluginName));
85 }
86
87 // =======================================================================
88 // function : RegisteredPlugins
89 // purpose :
90 // =======================================================================
91 NCollection_List<TCollection_AsciiString> TInspector_Window::RegisteredPlugins() const
92 {
93   NCollection_List<TCollection_AsciiString> aPlugins;
94
95   for (int aToolId = 0, aSize = myToolNames.size(); aToolId < aSize; aToolId++)
96     aPlugins.Append (myToolNames[aToolId].myName);
97
98   return aPlugins;
99 }
100
101 // =======================================================================
102 // function : Init
103 // purpose :
104 // =======================================================================
105 void TInspector_Window::Init (const TCollection_AsciiString& thePluginName,
106                               const NCollection_List<Handle(Standard_Transient)>& theParameters,
107                               const Standard_Boolean theAppend)
108 {
109   if (thePluginName.IsEmpty())
110   {
111     // Init all plugins by the given parameters
112     for (int aToolId = 0, aSize = myToolNames.size(); aToolId < aSize; aToolId++)
113       Init (myToolNames[aToolId].myName, theParameters, theAppend);
114
115     // temporary activation of the first tool
116     if (!myToolNames.isEmpty())
117       ActivateTool (myToolNames[0].myName);
118     return;
119   }
120
121   if (theAppend)
122   {
123     NCollection_List<Handle(Standard_Transient)> aParameters;
124     if (myParameters->FindParameters (thePluginName))
125       aParameters = myParameters->Parameters (thePluginName);
126
127     for (NCollection_List<Handle(Standard_Transient)>::Iterator anIterator (theParameters);
128       anIterator.More(); anIterator.Next())
129       aParameters.Append (anIterator.Value());
130
131     myParameters->SetParameters (thePluginName, aParameters, Standard_False);
132   }
133   else
134     myParameters->SetParameters (thePluginName, theParameters, Standard_False);
135
136   TInspector_ToolInfo anInfo;
137   int aToolId;
138   if (!FindPlugin (thePluginName, anInfo, aToolId))
139     return;
140
141   if (anInfo.myButton)
142     return;
143
144   QString aButtonName = anInfo.myName.ToCString();
145   if (aButtonName.indexOf("TK") == 0)
146     aButtonName = aButtonName.mid(2);
147
148   QPushButton* aButton = new QPushButton(aButtonName, myButtonWidget);
149   connect (aButton, SIGNAL (clicked (bool)), this, SLOT (onButtonClicked()));
150   myButtonLay->insertWidget (myButtonLay->count()-1, aButton);
151   anInfo.myButton = aButton;
152   myToolNames[aToolId] = anInfo;
153 }
154
155 // =======================================================================
156 // function : ActivateTool
157 // purpose :
158 // =======================================================================
159 void TInspector_Window::ActivateTool (const TCollection_AsciiString& thePluginName)
160 {
161   int aToolIndex = -1;
162   for (int aToolId = 0, aSize = myToolNames.size(); aToolId < aSize; aToolId++)
163   {
164     if (myToolNames[aToolId].myName != thePluginName)
165       continue;
166     aToolIndex = aToolId;
167     break;
168   }
169
170   if (aToolIndex < 0)
171     return;
172
173   TInspector_ToolInfo anInfo = myToolNames[aToolIndex];
174   if (!anInfo.myWidget)
175   {
176     if (!LoadPlugin (thePluginName, anInfo))
177     {
178       anInfo.myButton->setEnabled (false);
179       return;
180     }
181     myToolsStack->addWidget (anInfo.myWidget);
182     myToolNames[aToolIndex] = anInfo;
183   }
184
185   QWidget* aWidget = anInfo.myWidget;
186   myToolsStack->setCurrentWidget (aWidget);
187   if (myOpenButton)
188     myOpenButton->setObjectName (thePluginName.ToCString());
189
190   anInfo.myCommunicator->UpdateContent();
191   onCommuncatorNameChanged();
192 }
193
194 // =======================================================================
195 // function : SetSelected
196 // purpose :
197 // =======================================================================
198 void TInspector_Window::SetSelected (const NCollection_List<TCollection_AsciiString>& theItemNames)
199 {
200   TInspector_ToolInfo anInfo;
201   if (!ActiveToolInfo (anInfo))
202     return;
203
204   myParameters->SetSelectedNames (anInfo.myName, theItemNames);
205
206   TInspectorAPI_Communicator* aCommunicator = anInfo.myCommunicator;
207   if (aCommunicator)
208   {
209     aCommunicator->UpdateContent();
210   }
211 }
212
213 // =======================================================================
214 // function : SetSelected
215 // purpose :
216 // =======================================================================
217 void TInspector_Window::SetSelected (const NCollection_List<Handle(Standard_Transient)>& theObjects)
218 {
219   TInspector_ToolInfo anInfo;
220   if (!ActiveToolInfo (anInfo))
221     return;
222
223   myParameters->SetSelected (anInfo.myName, theObjects);
224
225   TInspectorAPI_Communicator* aCommunicator = anInfo.myCommunicator;
226   if (aCommunicator)
227   {
228     aCommunicator->UpdateContent();
229   }
230 }
231
232 // =======================================================================
233 // function : SetOpenButton
234 // purpose :
235 // =======================================================================
236 void TInspector_Window::SetOpenButton (QPushButton* theButton)
237 {
238   myOpenButton = theButton;
239   TInspector_ToolInfo anInfo;
240   if (ActiveToolInfo (anInfo))
241     myOpenButton->setObjectName (anInfo.myName.ToCString());
242   myButtonLay->insertWidget (0, theButton);
243 }
244
245 // =======================================================================
246 // function : OpenFile
247 // purpose :
248 // =======================================================================
249 void TInspector_Window::OpenFile (const TCollection_AsciiString& thePluginName,
250                                   const TCollection_AsciiString& theFileName)
251 {
252   if (thePluginName.IsEmpty())
253   {
254     // Apply file name to all plugins
255     for (int aToolId = 0, aSize = myToolNames.size(); aToolId < aSize; aToolId++)
256       OpenFile (myToolNames[aToolId].myName, theFileName);
257     return;
258   }
259
260   myParameters->AddFileName (thePluginName, theFileName);
261
262   TInspector_ToolInfo anInfo;
263   if (!ActiveToolInfo (anInfo) || anInfo.myName != thePluginName)
264     return;
265
266   TInspectorAPI_Communicator* aCommunicator = anInfo.myCommunicator;
267   if (aCommunicator)
268     aCommunicator->UpdateContent();
269 }
270
271 // =======================================================================
272 // function : UpdateContent
273 // purpose :
274 // =======================================================================
275 void TInspector_Window::UpdateContent()
276 {
277   TInspector_ToolInfo anInfo;
278   if (!ActiveToolInfo (anInfo) || !anInfo.myCommunicator)
279     return;
280
281   anInfo.myCommunicator->UpdateContent();
282 }
283
284 // =======================================================================
285 // function : LoadPlugin
286 // purpose :
287 // =======================================================================
288 bool TInspector_Window::LoadPlugin (const TCollection_AsciiString& thePluginName, TInspector_ToolInfo& theInfo)
289 {
290   bool aLoaded = false;
291
292   QApplication::setOverrideCursor (Qt::WaitCursor);
293   TInspectorAPI_Communicator* aCommunicator = TInspectorAPI_Communicator::LoadPluginLibrary (thePluginName);
294
295   if (aCommunicator)
296   {
297     aCommunicator->SetParameters (myParameters);
298     QWidget* aParentWidget = new QWidget (myMainWindow);
299     QVBoxLayout* aLayout = new QVBoxLayout (aParentWidget);
300     aLayout->setContentsMargins (0, 0, 0, 0);
301     aLayout->setSpacing (0);
302     aParentWidget->setLayout (aLayout);
303     aCommunicator->SetParent (aParentWidget);
304     theInfo.myWidget = aParentWidget;
305     theInfo.myCommunicator = aCommunicator;
306 #if QT_VERSION >= 0x050000
307     connect (aParentWidget, SIGNAL (objectNameChanged (const QString&)), this, SLOT (onCommuncatorNameChanged()));
308 #endif
309     aLoaded = true;
310   }
311   QApplication::restoreOverrideCursor();
312   return aLoaded;
313 }
314
315 // =======================================================================
316 // function : onButtonClicked
317 // purpose :
318 // =======================================================================
319 void TInspector_Window::onButtonClicked()
320 {
321   QPushButton* aButton = (QPushButton*)sender();
322   ActivateTool (TCollection_AsciiString ("TK") + aButton->text().toStdString().c_str());
323 }
324
325 // =======================================================================
326 // function : onCommuncatorNameChanged
327 // purpose :
328 // =======================================================================
329 void TInspector_Window::onCommuncatorNameChanged()
330 {
331 #if QT_VERSION >= 0x050000
332   TInspector_ToolInfo anInfo;
333   if (!ActiveToolInfo (anInfo))
334     return;
335   myMainWindow->setWindowTitle (anInfo.myWidget->objectName());
336 #endif
337 }
338
339 // =======================================================================
340 // function : ActiveToolInfo
341 // purpose :
342 // =======================================================================
343 bool TInspector_Window::ActiveToolInfo (TInspector_Window::TInspector_ToolInfo& theToolInfo) const
344 {
345   QWidget* anActiveWidget = myToolsStack->currentWidget();
346   if (anActiveWidget == myEmptyWidget)
347     return false;
348
349   for (int aToolId = 0, aSize = myToolNames.size(); aToolId < aSize; aToolId++)
350   {
351     if (myToolNames[aToolId].myWidget && myToolNames[aToolId].myWidget == anActiveWidget)
352     {
353       theToolInfo = myToolNames[aToolId];
354       return true;
355     }
356   }
357   return false;
358 }
359
360 // =======================================================================
361 // function : FindPlugin
362 // purpose :
363 // =======================================================================
364 bool TInspector_Window::FindPlugin (const TCollection_AsciiString& thePluginName, TInspector_ToolInfo& theToolInfo,
365                                     int& theToolId)
366 {
367   for (int aToolId = 0, aSize = myToolNames.size(); aToolId < aSize; aToolId++)
368   {
369     TInspector_ToolInfo anInfo = myToolNames[aToolId];
370     if (anInfo.myName != thePluginName)
371       continue;
372     theToolInfo = anInfo;
373     theToolId = aToolId;
374     return true;
375   }
376
377   return false;
378 }
379