Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / devtools / v8plus / lib / python2.4 / site-packages / Pmw / Pmw_1_2 / lib / PmwMenuBar.py
CommitLineData
920dae64
AT
1# Manager widget for menus.
2
3import string
4import types
5import Tkinter
6import Pmw
7
8class 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()