Salome HOME
d352ddf85b90e0506f8f264e0bc04d51637608ea
[samples/pyhello.git] / src / PYHELLOGUI / PYHELLOGUI.py
1 # Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
2 #
3 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 #
6 # This library is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU Lesser General Public
8 # License as published by the Free Software Foundation; either
9 # version 2.1 of the License, or (at your option) any later version.
10 #
11 # This library is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 # Lesser General Public License for more details.
15 #
16 # You should have received a copy of the GNU Lesser General Public
17 # License along with this library; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 #
20 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 #
22
23 # ---
24 # File   : PYHELLOGUI.py
25 # Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
26 # ---
27 #
28 import traceback
29 import os
30 from qtsalome import *
31
32 from PYHELLO_utils import *
33
34 import salome
35
36 ################################################
37 # GUI context class
38 # Used to store actions, menus, toolbars, etc...
39 ################################################
40
41 class GUIcontext:
42     # menus/toolbars/actions IDs
43     PYHELLO_MENU_ID  = 90
44     HELLO_ID         = 941
45     CREATE_OBJECT_ID = 942
46     OPTIONS_ID       = 943
47     OPTION_1_ID      = 944
48     OPTION_2_ID      = 945
49     OPTION_3_ID      = 946
50     PASSWORD_ID      = 947
51     PYHELLO_TB_ID    = 90
52     DELETE_ALL_ID    = 951
53     SHOW_ME_ID       = 952
54     DELETE_ME_ID     = 953
55     RENAME_ME_ID     = 954
56     # default object name
57     DEFAULT_NAME     = "Object"
58     # default password
59     DEFAULT_PASSWD   = "Passwd"
60
61     # constructor
62     def __init__( self ):
63         # create top-level menu
64         mid = sgPyQt.createMenu( "PyHello", -1, GUIcontext.PYHELLO_MENU_ID, sgPyQt.defaultMenuGroup() )
65         # create toolbar
66         tid = sgPyQt.createTool( "PyHello" )
67         # create actions and fill menu and toolbar with actions
68         a = sgPyQt.createAction( GUIcontext.HELLO_ID, "Hello", "Hello", "Show hello dialog box", "ExecPYHELLO.png" )
69         sgPyQt.createMenu( a, mid )
70         sgPyQt.createTool( a, tid )
71         a = sgPyQt.createSeparator()
72         sgPyQt.createMenu( a, mid )
73         a = sgPyQt.createAction( GUIcontext.CREATE_OBJECT_ID, "Create object", "Create object", "Create object" )
74         sgPyQt.createMenu( a, mid )
75         a = sgPyQt.createSeparator()
76         sgPyQt.createMenu( a, mid )
77         try:
78             ag = sgPyQt.createActionGroup( GUIcontext.OPTIONS_ID )
79             ag.setText( "Creation mode" )
80             ag.setUsesDropDown(True)
81             a = sgPyQt.createAction( GUIcontext.OPTION_1_ID, "Default name", "Default name", "Use default name for the objects" )
82             a.setCheckable( True )
83             ag.add( a )
84             a = sgPyQt.createAction( GUIcontext.OPTION_2_ID, "Generate name", "Generate name", "Generate name for the objects" )
85             a.setCheckable( True )
86             ag.add( a )
87             a = sgPyQt.createAction( GUIcontext.OPTION_3_ID, "Ask name", "Ask name", "Request object name from the user" )
88             a.setCheckable( True )
89             ag.add( a )
90             sgPyQt.createMenu( ag, mid )
91             sgPyQt.createTool( ag, tid )
92             default_mode = sgPyQt.integerSetting( "PYHELLO", "creation_mode", 0 )
93             sgPyQt.action( GUIcontext.OPTION_1_ID + default_mode ).setChecked( True )
94         except:
95             pass
96         a = sgPyQt.createSeparator()
97         a = sgPyQt.createAction( GUIcontext.PASSWORD_ID, "Display password", "Display password", "Display password" )
98         sgPyQt.createMenu( a, mid )
99         
100         # the following action are used in context popup
101         a = sgPyQt.createAction( GUIcontext.DELETE_ALL_ID, "Delete all", "Delete all", "Delete all objects" )
102         a = sgPyQt.createAction( GUIcontext.SHOW_ME_ID,    "Show",       "Show",       "Show object name" )
103         a = sgPyQt.createAction( GUIcontext.DELETE_ME_ID,  "Delete",     "Delete",     "Remove object" )
104         a = sgPyQt.createAction( GUIcontext.RENAME_ME_ID,  "Rename",     "Rename",     "Rename object" )
105         pass
106     pass
107
108 ################################################
109 # Global variables
110 ################################################
111
112 # object counter
113 __objectid__ = 0
114
115 ################################################
116        
117 # Get SALOME PyQt interface
118 import SalomePyQt
119 sgPyQt = SalomePyQt.SalomePyQt()
120
121 # Get SALOME Swig interface
122 import libSALOME_Swig
123 sg = libSALOME_Swig.SALOMEGUI_Swig()
124
125 ################################################
126
127 ################################################
128 # Internal methods
129 ################################################
130
131 ###
132 # returns True if object has children
133 ###
134 def _hasChildren( sobj ):
135     if sobj:
136         iter  = salome.myStudy.NewChildIterator( sobj )
137         while iter.More():
138             name = iter.Value().GetName()
139             if name:
140                 return True
141             iter.Next()
142             pass
143         pass
144     return False
145
146 ###
147 # increment object counter in the map
148 ###
149 def _incObjToMap( m, id ):
150     if id not in m: m[id] = 0
151     m[id] += 1
152     pass
153
154 ###
155 # analyse selection
156 ###
157 def _getSelection():
158     selcount = sg.SelectedCount()
159     seltypes = {}
160     for i in range( selcount ):
161         _incObjToMap( seltypes, getObjectID( sg.getSelected( i ) ) )
162         pass
163     return selcount, seltypes
164
165 ################################################
166 # Callback functions
167 ################################################
168
169 # called when module is initialized
170 # perform initialization actions
171 def initialize():
172     if verbose() : print "PYHELLOGUI.initialize()"
173     # set default preferences values
174     if not sgPyQt.hasSetting( "PYHELLO", "def_obj_name"):
175         sgPyQt.addSetting( "PYHELLO", "def_obj_name", GUIcontext.DEFAULT_NAME )
176     if not sgPyQt.hasSetting( "PYHELLO", "creation_mode"):
177         sgPyQt.addSetting( "PYHELLO", "creation_mode", 0 )
178     if not sgPyQt.hasSetting( "PYHELLO", "Password"):
179         sgPyQt.addSetting( "PYHELLO", "Password", GUIcontext.DEFAULT_PASSWD )
180     pass
181
182 # called when module is initialized
183 # return map of popup windows to be used by the module
184 def windows():
185     if verbose() : print "PYHELLOGUI.windows()"
186     wm = {}
187     wm[SalomePyQt.WT_ObjectBrowser] = Qt.LeftDockWidgetArea
188     wm[SalomePyQt.WT_PyConsole]     = Qt.BottomDockWidgetArea
189     return wm
190
191 # called when module is initialized
192 # return list of 2d/3d views to be used ny the module
193 def views():
194     if verbose() : print "PYHELLOGUI.views()"
195     return []
196
197 # called when module is initialized
198 # export module's preferences
199 def createPreferences():
200     if verbose() : print "PYHELLOGUI.createPreferences()"
201     gid = sgPyQt.addPreference( "General" )
202     gid = sgPyQt.addPreference( "Object creation", gid )
203     pid = sgPyQt.addPreference( "Default name",  gid, SalomePyQt.PT_String,   "PYHELLO", "def_obj_name" )
204     pid = sgPyQt.addPreference( "Default creation mode", gid, SalomePyQt.PT_Selector, "PYHELLO", "creation_mode" )
205     strings = QStringList()
206     strings.append( "Default name" )
207     strings.append( "Generate name" )
208     strings.append( "Ask name" )
209     indexes = []
210     indexes.append( QVariant(0) )
211     indexes.append( QVariant(1) )
212     indexes.append( QVariant(2) )
213     sgPyQt.setPreferenceProperty( pid, "strings", QVariant( strings ) )
214     sgPyQt.setPreferenceProperty( pid, "indexes", QVariant( indexes ) )
215     pid = sgPyQt.addPreference( "Password",  gid, SalomePyQt.PT_String,   "PYHELLO", "Password" )
216     sgPyQt.setPreferenceProperty( pid, "echo", QVariant( 2 ) )
217     pass
218
219 # called when module is activated
220 # returns True if activating is successfull and False otherwise
221 def activate():
222     if verbose() : print "PYHELLOGUI.activate()"
223     GUIcontext()
224     return True
225
226 # called when module is deactivated
227 def deactivate():
228     if verbose() : print "PYHELLOGUI.deactivate()"
229     pass
230
231 # called when popup menu is invoked
232 # popup menu and menu context are passed as parameters
233 def createPopupMenu( popup, context ):
234     if verbose() : print "PYHELLOGUI.createPopupMenu(): context = %s" % context
235     selcount, selected = _getSelection()
236     if verbose() : print selcount, selected
237     if selcount == 1:
238         # one object is selected
239         if moduleID() in selected:
240             # menu for component
241             popup.addAction( sgPyQt.action( GUIcontext.DELETE_ALL_ID ) )
242         elif objectID() in selected:
243             # menu for object
244             popup.addAction( sgPyQt.action( GUIcontext.SHOW_ME_ID ) )
245             popup.addAction( sgPyQt.action( GUIcontext.RENAME_ME_ID ) )
246             popup.addSeparator()
247             popup.addAction( sgPyQt.action( GUIcontext.DELETE_ME_ID ) )
248             pass
249         pass
250     elif selcount > 1:
251         # several objects are selected
252         if len( selected ) == 1:
253             if moduleID() in selected:
254                 # menu for component
255                 popup.addAction( sgPyQt.action( GUIcontext.DELETE_ALL_ID ) )
256             elif objectID() in selected:
257                 # menu for list of objects
258                 popup.addAction( sgPyQt.action( GUIcontext.DELETE_ME_ID ) )
259                 pass
260             pass
261         pass
262     pass
263
264 # called when GUI action is activated
265 # action ID is passed as parameter
266 def OnGUIEvent( commandID ):
267     if verbose() : print "PYHELLOGUI.OnGUIEvent(): command = %d" % commandID
268     if dict_command.has_key( commandID ):
269         try:
270             dict_command[commandID]()
271         except:
272             traceback.print_exc()
273     else:
274         if verbose() : print "The command is not implemented: %d" % commandID
275     pass
276
277 # called when module's preferences are changed
278 # preference's resources section and setting name are passed as parameters
279 def preferenceChanged( section, setting ):
280     if verbose() : print "PYHELLOGUI.preferenceChanged(): %s / %s" % ( section, setting )
281     pass
282
283 # called when active view is changed
284 # view ID is passed as parameter
285 def activeViewChanged( viewID ):
286     if verbose() : print "PYHELLOGUI.activeViewChanged(): %d" % viewID
287     pass
288
289 # called when active view is cloned
290 # cloned view ID is passed as parameter
291 def viewCloned( viewID ):
292     if verbose() : print "PYHELLOGUI.viewCloned(): %d" % viewID
293     pass
294
295 # called when active view is viewClosed
296 # view ID is passed as parameter
297 def viewClosed( viewID ):
298     if verbose() : print "PYHELLOGUI.viewClosed(): %d" % viewID
299     pass
300
301 # called when study is opened
302 # returns engine IOR
303 def engineIOR():
304     if verbose() : print "PYHELLOGUI.engineIOR()"
305     return getEngineIOR()
306
307 # called to check if object can be dragged
308 # returns True if drag operation is allowed for this object
309 def isDraggable(what):
310     if verbose() : print "PYHELLOGUI.isDraggable()"
311     # return True if object is draggable
312     return False
313
314 # called to check if object allows dropping on it
315 # returns True if drop operation is allowed for this object
316 def isDropAccepted(where):
317     if verbose() : print "PYHELLOGUI.isDropAccepted()"
318     # return True if object accept drops
319     return False
320
321 # called when drag and drop operation is finished
322 # performs corresponding data re-arrangement if allowed
323 def dropObjects(what, where, row, action):
324     if verbose() :
325         print "PYHELLOGUI.dropObjects()"
326         # 'what' is a list of entries of objects being dropped
327         for i in what: print "- dropped:", i
328         # 'where' is a parent object's entry
329         print "- dropping on:", where
330         # 'row' is an position in the parent's children list;
331         # -1 if appending to the end of children list is performed
332         print "- dropping position:", row
333         # 'action' is a dropping action being performed:
334         # - 0x01 (Qt::CopyAction) for copy
335         # - 0x02 (Qt::MoveAction) for move
336         print "- drop action:", action
337         pass
338     pass
339
340 ################################################
341 # GUI actions implementation
342 ################################################
343
344 ###
345 # 'HELLO' dialog box
346 ###
347 class MyDialog( QDialog ):
348     # constructor
349     def __init__( self, parent = None, modal = 0):
350         QDialog.__init__( self, parent )
351         self.setObjectName( "MyDialog" )
352         self.setModal( modal )
353         self.setWindowTitle( "HELLO!" )
354         vb = QVBoxLayout( self )
355         vb.setContentsMargins( 8, 8, 8, 8 )
356
357         hb0 = QHBoxLayout( self )
358         label = QLabel( "Prenom: ", self )
359         hb0.addWidget( label )
360         self.entry = QLineEdit( self )
361         self.entry.setMinimumWidth( 200 )
362         hb0.addWidget( self.entry )
363         vb.addLayout( hb0 )
364         
365         hb1 = QHBoxLayout( self )
366         bOk = QPushButton( "&OK", self )
367         bOk.setIcon( sgPyQt.loadIcon( 'PYHELLO', 'ICO_HANDSHAKE' ) )
368         bOk.clicked.connect(self.accept)
369         hb1.addWidget( bOk )
370         
371         hb1.addStretch( 10 )
372         
373         bCancel = QPushButton( "&Cancel", self )
374         bCancel.setIcon( sgPyQt.loadIcon( 'PYHELLO', 'ICO_STOP' ) )
375         bCancel.clicked.connect(self.close)
376         hb1.addWidget( bCancel )
377         vb.addLayout( hb1 )
378         pass
379     
380     # OK button slot
381     def accept( self ):
382         name = str( self.entry.text() )
383         if name != "":
384             banner = getEngine().makeBanner( name )
385             QMessageBox.information( self, 'Info', banner )
386             self.close()
387         else:
388             QMessageBox.warning( self, 'Error!', 'Please, enter the name!' )
389         pass
390
391 ###
392 # Show 'HELLO' dialog box
393 ###
394 def ShowHELLO():
395     # create dialog box
396     d = MyDialog( sgPyQt.getDesktop(), 1 )
397     # show dialog box
398     d.exec_()
399     pass
400
401 ###
402 # Create new object
403 ###
404 def CreateObject():
405     global __objectid__
406     default_name = str( sgPyQt.stringSetting( "PYHELLO", "def_obj_name", GUIcontext.DEFAULT_NAME ) ).strip()
407     try:
408         if sgPyQt.action( GUIcontext.OPTION_3_ID ).isChecked():
409             # request object name from the user
410             name, ok = QInputDialog.getText( sgPyQt.getDesktop(),
411                                              "Create Object",
412                                              "Enter object name:",
413                                              QLineEdit.Normal,
414                                              default_name )
415             if not ok: return
416             name = str( name ).strip()
417         elif sgPyQt.action( GUIcontext.OPTION_2_ID ).isChecked():
418             # generate object name
419             __objectid__  = __objectid__ + 1
420             name = "%s %d" % ( default_name, __objectid__ )
421         else:
422             name = default_name
423             pass
424         pass
425     except:
426         # generate object name
427         __objectid__  = __objectid__ + 1
428         name = "%s %d" % ( default_name, __objectid__ )
429         pass
430     if not name: return
431     getEngine().createObject( name )
432     sg.updateObjBrowser()
433     pass
434
435 ###
436 # Delete all objects
437 ###
438 def DeleteAll():
439     father = salome.myStudy.FindComponent( moduleName() )
440     if father:
441         iter = salome.myStudy.NewChildIterator( father )
442         builder = salome.myStudy.NewBuilder()
443         while iter.More():
444             sobj = iter.Value()
445             iter.Next()
446             builder.RemoveObjectWithChildren( sobj )
447             pass
448         sg.updateObjBrowser()
449         pass
450     pass
451
452 ###
453 # Show object's name
454 ###
455 def ShowMe():
456     entry = sg.getSelected( 0 )
457     if entry != '':
458         sobj = salome.myStudy.FindObjectID( entry )
459         if ( sobj ):
460             test, attr = sobj.FindAttribute( "AttributeName" )
461             if test:
462                 QMessageBox.information( sgPyQt.getDesktop(), 'Info', "My name is '%s'" % attr.Value() )
463                 pass
464             pass
465         pass
466     pass
467
468 ###
469 # Delete selected object(s)
470 ###
471 def Delete():
472     builder = salome.myStudy.NewBuilder()
473     if sg.SelectedCount() <= 0: return
474     for i in range( sg.SelectedCount() ):
475         entry = sg.getSelected( i )
476         if entry != '':
477             sobj = salome.myStudy.FindObjectID( entry )
478             if ( sobj ):
479                 builder.RemoveObject( sobj )
480                 pass
481             pass
482         pass
483     sg.updateObjBrowser()
484     pass
485
486 ###
487 # Rename selected object
488 ###
489 def Rename():
490     builder = salome.myStudy.NewBuilder()
491     entry = sg.getSelected( 0 )
492     if entry != '':
493         sobj = salome.myStudy.FindObjectID( entry )
494         if ( sobj ):
495             name, ok = QInputDialog.getText( sgPyQt.getDesktop(),
496                                              "Object name",
497                                              "Enter object name:",
498                                              QLineEdit.Normal,
499                                              sobj.GetName() )
500             name = str( name ).strip()
501             if not ok or not name: return
502             attr = builder.FindOrCreateAttribute( sobj, "AttributeName" )
503             attr.SetValue( name )
504             sg.updateObjBrowser()
505             pass
506         pass
507     pass
508
509 ###
510 # Display password stored in the preferences
511 ###
512 def Password():
513   passwd = str( sgPyQt.stringSetting( "PYHELLO", "Password", GUIcontext.DEFAULT_PASSWD ) ).strip()
514   QMessageBox.information(sgPyQt.getDesktop(),
515                           "Password",
516                           passwd)
517
518 ###
519 # Commands dictionary
520 ###
521 dict_command = {
522     GUIcontext.HELLO_ID         : ShowHELLO,
523     GUIcontext.CREATE_OBJECT_ID : CreateObject,
524     GUIcontext.DELETE_ALL_ID    : DeleteAll,
525     GUIcontext.SHOW_ME_ID       : ShowMe,
526     GUIcontext.DELETE_ME_ID     : Delete,
527     GUIcontext.RENAME_ME_ID     : Rename,
528     GUIcontext.PASSWORD_ID      : Password,
529     }