]> SALOME platform Git repositories - tools/eficas.git/blob - Pmw/Pmw_1_2/lib/PmwMenuBar.py
Salome HOME
Modif V6_4_°
[tools/eficas.git] / Pmw / Pmw_1_2 / lib / PmwMenuBar.py
1 # Manager widget for menus.
2
3 import string
4 import types
5 import Tkinter
6 import Pmw
7
8 class MenuBar(Pmw.MegaWidget):
9
10     def __init__(self, parent = None, **kw):
11
12         # Define the megawidget options.
13         INITOPT = Pmw.INITOPT
14         optiondefs = (
15             ('balloon',      None,       None),
16             ('hotkeys',      1,          INITOPT),
17             ('padx',         0,          INITOPT),
18         )
19         self.defineoptions(kw, optiondefs, dynamicGroups = ('Menu', 'Button'))
20
21         # Initialise the base class (after defining the options).
22         Pmw.MegaWidget.__init__(self, parent)
23
24         self._menuInfo = {}
25         # Map from a menu name to a tuple of information about the menu.
26         # The first item in the tuple is the name of the parent menu (for
27         # toplevel menus this is None). The second item in the tuple is
28         # a list of status help messages for each item in the menu.
29         # The third item in the tuple is the id of the binding used
30         # to detect mouse motion to display status help.
31         # Information for the toplevel menubuttons is not stored here.
32
33         self._mydeletecommand = self.component('hull').tk.deletecommand
34         # Cache this method for use later.
35
36         # Check keywords and initialise options.
37         self.initialiseoptions()
38
39     def deletemenuitems(self, menuName, start, end = None):
40         self.component(menuName + '-menu').delete(start, end)
41         if end is None:
42             del self._menuInfo[menuName][1][start]
43         else:
44             self._menuInfo[menuName][1][start:end+1] = []
45
46     def deletemenu(self, menuName):
47         """Delete should be called for cascaded menus before main menus.
48         """
49
50         # Clean up binding for this menu.
51         parentName = self._menuInfo[menuName][0]
52         bindId = self._menuInfo[menuName][2]
53         _bindtag = 'PmwMenuBar' + str(self) + menuName
54         self.unbind_class(_bindtag, '<Motion>')
55         self._mydeletecommand(bindId) # unbind_class does not clean up
56         del self._menuInfo[menuName]
57
58         if parentName is None:
59             self.destroycomponent(menuName + '-button')
60         else:
61             parentMenu = self.component(parentName + '-menu')
62
63             menu = self.component(menuName + '-menu')
64             menuId = str(menu)
65             for item in range(parentMenu.index('end') + 1):
66                 if parentMenu.type(item) == 'cascade':
67                     itemMenu = str(parentMenu.entrycget(item, 'menu'))
68                     if itemMenu == menuId:
69                         parentMenu.delete(item)
70                         del self._menuInfo[parentName][1][item]
71                         break
72
73         self.destroycomponent(menuName + '-menu')
74
75     def disableall(self):
76         for menuName in self._menuInfo.keys():
77             if self._menuInfo[menuName][0] is None:
78                 menubutton = self.component(menuName + '-button')
79                 menubutton.configure(state = 'disabled')
80
81     def enableall(self):
82         for menuName in self._menuInfo.keys():
83             if self._menuInfo[menuName][0] is None:
84                 menubutton = self.component(menuName + '-button')
85                 menubutton.configure(state = 'normal')
86
87     def addmenu(self, menuName, balloonHelp, statusHelp = None,
88             side = 'left', traverseSpec = None, **kw):
89
90         self._addmenu(None, menuName, balloonHelp, statusHelp,
91             traverseSpec, side, 'text', kw)
92
93     def addcascademenu(self, parentMenuName, menuName, statusHelp = '',
94             traverseSpec = None, **kw):
95
96         self._addmenu(parentMenuName, menuName, None, statusHelp,
97             traverseSpec, None, 'label', kw)
98
99     def _addmenu(self, parentMenuName, menuName, balloonHelp, statusHelp,
100             traverseSpec, side, textKey, kw):
101
102         if (menuName + '-menu') in self.components():
103             raise ValueError, 'menu "%s" already exists' % menuName
104
105         menukw = {}
106         if kw.has_key('tearoff'):
107             menukw['tearoff'] = kw['tearoff']
108             del kw['tearoff']
109         else:
110             menukw['tearoff'] = 0
111
112         if not kw.has_key(textKey):
113             kw[textKey] = menuName
114
115         self._addHotkeyToOptions(parentMenuName, kw, textKey, traverseSpec)
116
117         if parentMenuName is None:
118             button = apply(self.createcomponent, (menuName + '-button',
119                     (), 'Button',
120                     Tkinter.Menubutton, (self.interior(),)), kw)
121             button.pack(side=side, padx = self['padx'])
122             balloon = self['balloon']
123             if balloon is not None:
124                 balloon.bind(button, balloonHelp, statusHelp)
125             parentMenu = button
126         else:
127             parentMenu = self.component(parentMenuName + '-menu')
128             apply(parentMenu.add_cascade, (), kw)
129             self._menuInfo[parentMenuName][1].append(statusHelp)
130
131         menu = apply(self.createcomponent, (menuName + '-menu',
132                 (), 'Menu',
133                 Tkinter.Menu, (parentMenu,)), menukw)
134         if parentMenuName is None:
135             button.configure(menu = menu)
136         else:
137             parentMenu.entryconfigure('end', menu = menu)
138
139         # Need to put this binding after the class bindings so that
140         # menu.index() does not lag behind.
141         _bindtag = 'PmwMenuBar' + str(self) + menuName
142         bindId = self.bind_class(_bindtag, '<Motion>',
143             lambda event=None, self=self, menuName=menuName:
144                     self._menuHelp(menuName))
145         menu.bindtags(menu.bindtags() + (_bindtag,))
146         menu.bind('<Leave>', self._resetHelpmessage)
147
148         self._menuInfo[menuName] = (parentMenuName, [], bindId)
149
150     def addmenuitem(self, menuName, itemType, statusHelp = '',
151             traverseSpec = None, **kw):
152
153         menu = self.component(menuName + '-menu')
154         if itemType != 'separator':
155             self._addHotkeyToOptions(menuName, kw, 'label', traverseSpec)
156
157         if itemType == 'command':
158             command = menu.add_command
159         elif itemType == 'separator':
160             command = menu.add_separator
161         elif itemType == 'checkbutton':
162             command = menu.add_checkbutton
163         elif itemType == 'radiobutton':
164             command = menu.add_radiobutton
165         elif itemType == 'cascade':
166             command = menu.add_cascade
167         else:
168             raise ValueError, 'unknown menuitem type "%s"' % itemType
169
170         self._menuInfo[menuName][1].append(statusHelp)
171         apply(command, (), kw)
172
173     def _addHotkeyToOptions(self, menuName, kw, textKey, traverseSpec):
174
175         if (not self['hotkeys'] or kw.has_key('underline') or
176                 not kw.has_key(textKey)):
177             return
178
179         if type(traverseSpec) == types.IntType:
180             kw['underline'] = traverseSpec
181             return
182
183         hotkeyList = []
184         if menuName is None:
185             for menuName in self._menuInfo.keys():
186                 if self._menuInfo[menuName][0] is None:
187                     menubutton = self.component(menuName + '-button')
188                     underline = string.atoi(str(menubutton.cget('underline')))
189                     if underline != -1:
190                         label = str(menubutton.cget(textKey))
191                         if underline < len(label):
192                             hotkey = string.lower(label[underline])
193                             if hotkey not in hotkeyList:
194                                 hotkeyList.append(hotkey)
195         else:
196             menu = self.component(menuName + '-menu')
197             end = menu.index('end')
198             if end is not None:
199                 for item in range(end + 1):
200                     if menu.type(item) not in ('separator', 'tearoff'):
201                         underline = string.atoi(
202                             str(menu.entrycget(item, 'underline')))
203                         if underline != -1:
204                             label = str(menu.entrycget(item, textKey))
205                             if underline < len(label):
206                                 hotkey = string.lower(label[underline])
207                                 if hotkey not in hotkeyList:
208                                     hotkeyList.append(hotkey)
209
210         name = kw[textKey]
211
212         if type(traverseSpec) == types.StringType:
213             lowerLetter = string.lower(traverseSpec)
214             if traverseSpec in name and lowerLetter not in hotkeyList:
215                 kw['underline'] = string.index(name, traverseSpec)
216         else:
217             targets = string.digits + string.letters
218             lowerName = string.lower(name)
219             for letter_index in range(len(name)):
220                 letter = lowerName[letter_index]
221                 if letter in targets and letter not in hotkeyList:
222                     kw['underline'] = letter_index
223                     break
224
225     def _menuHelp(self, menuName):
226         menu = self.component(menuName + '-menu')
227         index = menu.index('active')
228
229         balloon = self['balloon']
230         if balloon is not None:
231             if index is None:
232                 balloon.showstatus('')
233             else:
234                 if str(menu.cget('tearoff')) == '1':
235                     index = index - 1
236                 if index >= 0:
237                     help = self._menuInfo[menuName][1][index]
238                     balloon.showstatus(help)
239
240     def _resetHelpmessage(self, event=None):
241         balloon = self['balloon']
242         if balloon is not None:
243             balloon.clearstatus()