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