]> SALOME platform Git repositories - modules/gui.git/blob - src/GuiHelpers/StandardApp_Module.cxx
Salome HOME
abc7ce984c91d14f1d62fbc4bada80d2028cfe61
[modules/gui.git] / src / GuiHelpers / StandardApp_Module.cxx
1 // Copyright (C) 2011-2012  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Guillaume Boulant (EDF)
20
21 #include "StandardApp_Module.hxx"
22
23 #include <SUIT_Desktop.h>
24 #include <SUIT_Study.h>
25 #include <SalomeApp_Application.h>
26 #include <SALOME_LifeCycleCORBA.hxx>
27 #include "QtxPopupMgr.h"
28
29 #include CORBA_CLIENT_HEADER(SALOMEDS)
30 #include CORBA_CLIENT_HEADER(SALOMEDS_Attributes)
31
32 // QT Includes
33 #include <QIcon>
34 #include <QAction>
35
36 #include <Basics_Utils.hxx>
37 #include "QtHelper.hxx"
38
39 // Constructor
40 StandardApp_Module::StandardApp_Module() :
41   SalomeApp_Module( "" )
42 {
43   // Note that it's no use to specify here the moduleName because it's
44   // automatically determined by the name of the GUI library
45   // (lib<moduleName>.so) just before initialize step. If you want
46   // nevertheless to setup the module name you should specified this
47   // name in the initialize function below using the CAM_module
48   // function setModuleName(QString&). You are warn then that the
49   // loading of resource files may be incorect and should be manually
50   // managed. In conclusion, if you don't need a special
51   // configuration, please conform to the standard convention: if
52   // <moduleName> is the name of the module as declared in the GUI
53   // configuration file (SalomeApp.xml), then you just have to provide
54   // a library whose name is lib<moduleName>.so and which contains a
55   // factory "extern C" function 'CAM_Module* createModule()'
56 }
57
58 int StandardApp_Module::ACTIONID_DEFAULT_INIT_VALUE = 910;
59 int StandardApp_Module::ACTIONID_UNDEFINED = -1;
60
61 // Module's initialization
62 void StandardApp_Module::initialize( CAM_Application* app )
63 {
64   //
65   // ----------------------------------------------------------------
66   // Standard initialization
67   // ----------------------------------------------------------------
68   //
69   SalomeApp_Module::initialize( app );
70   _resourceMgr = app->resourceMgr();
71   // Please note that the moduleName() function is inherited from
72   // CAM_module classe, and that its value is determined automatically
73   // from the name specified in the SalomeApp.xml associated to this
74   // module and which corresponds to the name of the GUI library
75   // (lib<moduleName>.so). For XSALOME, see
76   // share/salome/resources/xsalome/SalomeApp.xml in the install
77   // directory.
78   _defaultMenuId = this->createMenu( QCHARSTAR(moduleName()), -1, -1, 30 );
79   _defaultToolbarId = this->createTool ( QCHARSTAR(moduleName()) );
80   _actionId_internalCount = StandardApp_Module::ACTIONID_DEFAULT_INIT_VALUE;
81
82   //
83   // ----------------------------------------------------------------
84   // The following initializes the GUI widget and associated actions
85   // ----------------------------------------------------------------
86   // These functions may be redefined in specialized version of this class
87   this->createModuleWidgets();
88   this->createModuleActions();
89 }
90
91 QIcon StandardApp_Module::createIcon(const QString& iconName) {
92   // The icon file is supposed to be available througth the resource
93   // manager, i.e. in the folder containing the XSALOME resources (see
94   // specification in the module file SalomeApp.xml).
95   QPixmap aPixmap = _resourceMgr->loadPixmap( QCHARSTAR(moduleName()), iconName );
96   return QIcon( aPixmap );
97 }
98
99 int StandardApp_Module::newActionId() {
100   _actionId_internalCount++;
101   return _actionId_internalCount;
102 }
103
104 /*!
105  * This function creates an action and connects it to a button in the
106  * toolbar and to an item in the menu associated to this module.  This
107  * function applies a common and standard procedure with a maximum of
108  * default values. If no identifier is specified, then a static
109  * internal counter is used to associate an identifier to the created
110  * action. In any case, the action identifier is returned.
111  *
112  * Note that the action (object of type QAction) can be retrieved
113  * using the method "QAction * action(int identifier)" of the super
114  * class.
115  */
116 int StandardApp_Module::createStandardAction(const QString& label,
117                                              QObject * slotobject,
118                                              const char* slotmember,
119                                              const QString& iconName,
120                                              const QString& tooltip,
121                                              const int identifier)
122 {
123
124   // If the tooltip is not defined, we choose instead the label text.
125   QString effToolTip(tooltip);
126   if ( effToolTip.isEmpty() )
127     effToolTip = label;
128
129   QIcon actionIcon = this->createIcon(iconName);
130
131   // If the identifier is not specified, then we use an internal
132   // counter.
133   int effIdentifier = identifier;
134   if ( effIdentifier == StandardApp_Module::ACTIONID_UNDEFINED ) {
135     effIdentifier=newActionId();
136   }
137
138   // Creating the action
139   QAction * action= this->createAction( effIdentifier, label, actionIcon,
140                                         label, effToolTip, 0, getApp()->desktop(),
141                                         false, slotobject, slotmember);
142
143   return effIdentifier;
144 }
145
146 /**
147  * Integrate the action in the default toolbar
148  */
149 void StandardApp_Module::addActionInToolbar(int actionId) {
150   this->createTool( actionId, _defaultToolbarId );
151 }
152
153 /**
154  * Integrate the action in the default menu
155  */
156 void StandardApp_Module::addActionInMenubar(int actionId) {
157   this->action( actionId )->setIconVisibleInMenu(true);
158   this->createMenu( actionId, _defaultMenuId, 10 );
159 }
160
161 /**
162  * Add the specified action as an item in the popup menu, with the
163  * specified visible rule. The default is "visible for object browser".
164  */
165 void StandardApp_Module::addActionInPopupMenu(int actionId,const QString& rule) {
166   // _GBO_ for a fine customization of the rule (for example with a
167   // test on the type of the selected object), see the LIGTH module:
168   // implement "LightApp_Selection*    createSelection() const;"
169   int parentId = -1;
170   QtxPopupMgr* mgr = this->popupMgr();
171   this->action( actionId )->setIconVisibleInMenu(true);
172   mgr->insert ( this->action( actionId ), parentId, 0 );
173   mgr->setRule( this->action( actionId ), rule, QtxPopupMgr::VisibleRule );
174 }
175
176 /*!
177  * This function can be used to create additionnal widget for this
178  * module GUI (e.g. docked widget). It can be redefined in a
179  * specialized version of this class.
180  */
181 void StandardApp_Module::createModuleWidgets() {
182   // Nothing to do in this default gui
183 }
184
185 /*!
186  * This function can be used to defined the list of actions for this
187  * module GUI.  It can be redefined in a specialized version of this
188  * class.
189  * Depending on wether you use the method "createStandardAction" or
190  * not, the actions will be automatically plugged in the toolbar and
191  * the menu associated to the module.
192  */
193 void StandardApp_Module::createModuleActions() {
194   int actionId = this->createStandardAction("Test", this, SLOT(OnTest()),
195                                             "f1.png", "Run the default test function");
196   this->addActionInToolbar(actionId);
197 }
198
199 // Get compatible dockable windows.
200 void StandardApp_Module::windows( QMap<int, int>& theMap ) const
201 {
202   theMap.clear();
203   theMap.insert( SalomeApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
204   theMap.insert( SalomeApp_Application::WT_PyConsole,     Qt::BottomDockWidgetArea );
205 }
206
207 // Module's engine IOR
208 QString StandardApp_Module::engineIOR() const
209 {
210   CORBA::String_var anIOR = getApp()->orb()->object_to_string(getEngine());
211   return QString( anIOR.in() );
212 }
213
214 /*!
215  * This specifies the filename for the icon to be used for the study
216  * component associated to the module. Note that this icon could be
217  * different than the module icon which is defined by the
218  * SalomeApp.xml file dedicated to this module (see the shared
219  * resources folder dedicated to the module) and which is used for the
220  * toolbar of the SALOME application.
221  */
222 QString StandardApp_Module::studyIconName()
223 {
224   // By default, we return the module icone name
225   return iconName(); // inherited from CAM_Module
226 }
227
228 /*!
229  * This can be used to switch the layout of main application
230  * dockwidgets to one of the predefined configuration (see enum
231  * DockLayoutType). When a layout is set, the previous layout is
232  * memorized and can be restored using the unsetDockLayout function (1
233  * step undo). It is typically to be used in the functions
234  * activateModule to setup the layout and deactivateModule to unset
235  * the layout, i.e. restore to the previous state.
236  */
237 void StandardApp_Module::setDockLayout(DockLayoutType layoutType) {
238   SUIT_Desktop* desk = getApp()->desktop();
239   _areaAtBottomLeftCorner = desk->corner(Qt::BottomLeftCorner);
240   _areaAtBottomRightCorner = desk->corner(Qt::BottomRightCorner);
241
242   if ( layoutType == DOCKLAYOUT_LEFT_VLARGE ) {
243     desk->setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
244     desk->setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);
245   } else {
246     desk->setCorner(Qt::BottomLeftCorner, Qt::BottomDockWidgetArea);
247     desk->setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);
248   }
249 }
250
251 /*!
252  * This function restores the layout state that was previously in
253  * place before the last setDockLayout call.
254  */
255 void StandardApp_Module::unsetDockLayout() {
256   SUIT_Desktop* desk = getApp()->desktop();
257   desk->setCorner(Qt::BottomLeftCorner, _areaAtBottomLeftCorner);
258   desk->setCorner(Qt::BottomRightCorner, _areaAtBottomRightCorner);
259 }
260
261 // Module's activation
262 bool StandardApp_Module::activateModule( SUIT_Study* theStudy )
263 {
264   bool bOk = SalomeApp_Module::activateModule( theStudy );
265
266   setMenuShown( true );
267   setToolShown( true );
268
269   if ( this->createStudyComponentAtActivation() ) {
270     this->createStudyComponent(theStudy);
271   }
272
273   return bOk;
274 }
275
276 /*!
277  * This function should be implemented in a specialized class and must
278  * return true if you want to automatically create a study component
279  * for this module at activation step (when you first load the module
280  * for a given study). The default function return true.
281  */
282 bool StandardApp_Module::createStudyComponentAtActivation() {
283   return true;
284 }
285
286 /*!
287  * This creates a root entry in the active study for this module, i.e
288  * a SComponent with the name of the module and the icon specified for
289  * the module. This component is associated to the engine (return by
290  * getEngine()) if the engine is a SALOMEDS::Driver.
291  */
292 void StandardApp_Module::createStudyComponent(SUIT_Study* theStudy) {
293
294   SALOME_NamingService *aNamingService = SalomeApp_Application::namingService();
295   CORBA::Object_var aSMObject = aNamingService->Resolve("/myStudyManager");
296   SALOMEDS::StudyManager_var aStudyManager = SALOMEDS::StudyManager::_narrow(aSMObject);
297   SALOMEDS::Study_var aDSStudy = aStudyManager->GetStudyByID(theStudy->id());
298
299   SALOMEDS::SComponent_var aFather = aDSStudy->FindComponent(QCHARSTAR(moduleName()));
300   if (aFather->_is_nil())
301     {
302       SALOMEDS::StudyBuilder_var aStudyBuilder = aDSStudy->NewBuilder();
303       aFather = aStudyBuilder->NewComponent(QCHARSTAR(moduleName()));
304       SALOMEDS::GenericAttribute_var anAttr = aStudyBuilder->FindOrCreateAttribute(aFather, "AttributeName");
305       SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
306       aName->SetValue(QCHARSTAR(moduleName()));
307       aName->Destroy();
308       anAttr = aStudyBuilder->FindOrCreateAttribute(aFather, "AttributePixMap");
309       SALOMEDS::AttributePixMap_var aPixMap = SALOMEDS::AttributePixMap::_narrow(anAttr);
310       aPixMap->SetPixMap(QCHARSTAR(studyIconName()));
311
312       // WARN: The engine should be associated to the SComponent IF
313       // AND ONLY IF it is a SALOMEDS::Driver. Otherwise, there is no
314       // need to do that, and it could even lead to exception
315       // raising (eh, you work on SALOME isn't it?)
316       SALOMEDS::Driver_var driver = SALOMEDS::Driver::_narrow(this->getEngine());
317       if ( ! driver->_is_nil() ) {
318         STDLOG("Associate the SComponent to the engine");
319         aStudyBuilder->DefineComponentInstance(aFather, this->getEngine());
320       }
321     }
322
323 }
324
325 // Module's deactivation
326 bool StandardApp_Module::deactivateModule( SUIT_Study* theStudy )
327 {
328   setMenuShown( false );
329   setToolShown( false );
330
331   return SalomeApp_Module::deactivateModule( theStudy );
332 }
333
334 void StandardApp_Module::OnTest()
335 {
336   // Just for test
337   STDLOG("OnTest: engine IOR = "<<QCHARSTAR(engineIOR()));
338 }
339