class MainMenuBar(Pmw
.MegaArchetype
):
def __init__(self
, parent
= None, **kw
):
# Define the megawidget options.
('hull_tearoff', 0, None),
self
.defineoptions(kw
, optiondefs
, dynamicGroups
= ('Menu',))
# Initialise the base class (after defining the options).
Pmw
.MegaArchetype
.__init
__(self
, parent
, Tkinter
.Menu
)
self
._menuInfo
[None] = (None, [])
# Map from a menu name to a tuple of information about the menu.
# The first item in the tuple is the name of the parent menu (for
# toplevel menus this is None). The second item in the tuple is
# a list of status help messages for each item in the menu.
# The key for the information for the main menubar is None.
self
._menu
= self
.interior()
self
._menu
.bind('<Leave>', self
._resetHelpmessage
)
self
._menu
.bind('<Motion>',
lambda event
=None, self
=self
: self
._menuHelp
(event
, None))
# Check keywords and initialise options.
def deletemenuitems(self
, menuName
, start
, end
= None):
self
.component(menuName
).delete(start
, end
)
del self
._menuInfo
[menuName
][1][start
]
self
._menuInfo
[menuName
][1][start
:end
+1] = []
def deletemenu(self
, menuName
):
"""Delete should be called for cascaded menus before main menus.
parentName
= self
._menuInfo
[menuName
][0]
del self
._menuInfo
[menuName
]
parentMenu
= self
.component(parentName
)
menu
= self
.component(menuName
)
for item
in range(parentMenu
.index('end') + 1):
if parentMenu
.type(item
) == 'cascade':
itemMenu
= str(parentMenu
.entrycget(item
, 'menu'))
del self
._menuInfo
[parentName
][1][item
]
self
.destroycomponent(menuName
)
for index
in range(len(self
._menuInfo
[None][1])):
self
.entryconfigure(index
, state
= 'disabled')
for index
in range(len(self
._menuInfo
[None][1])):
self
.entryconfigure(index
, state
= 'normal')
def addmenu(self
, menuName
, balloonHelp
, statusHelp
= None,
traverseSpec
= None, **kw
):
self
._addmenu
(None, menuName
, balloonHelp
, statusHelp
,
def addcascademenu(self
, parentMenuName
, menuName
, statusHelp
='',
traverseSpec
= None, **kw
):
self
._addmenu
(parentMenuName
, menuName
, None, statusHelp
,
def _addmenu(self
, parentMenuName
, menuName
, balloonHelp
, statusHelp
,
if (menuName
) in self
.components():
raise ValueError, 'menu "%s" already exists' % menuName
if kw
.has_key('tearoff'):
menukw
['tearoff'] = kw
['tearoff']
menukw
['name'] = kw
['name']
if not kw
.has_key('label'):
self
._addHotkeyToOptions
(parentMenuName
, kw
, traverseSpec
)
if parentMenuName
is None:
balloon
= self
['balloon']
# Bug in Tk: balloon help not implemented
# if balloon is not None:
# balloon.mainmenubind(parentMenu, balloonHelp, statusHelp)
parentMenu
= self
.component(parentMenuName
)
apply(parentMenu
.add_cascade
, (), kw
)
menu
= apply(self
.createcomponent
, (menuName
,
Tkinter
.Menu
, (parentMenu
,)), menukw
)
parentMenu
.entryconfigure('end', menu
= menu
)
self
._menuInfo
[parentMenuName
][1].append(statusHelp
)
self
._menuInfo
[menuName
] = (parentMenuName
, [])
menu
.bind('<Leave>', self
._resetHelpmessage
)
lambda event
=None, self
=self
, menuName
=menuName
:
self
._menuHelp
(event
, menuName
))
def addmenuitem(self
, menuName
, itemType
, statusHelp
= '',
traverseSpec
= None, **kw
):
menu
= self
.component(menuName
)
if itemType
!= 'separator':
self
._addHotkeyToOptions
(menuName
, kw
, traverseSpec
)
if itemType
== 'command':
command
= menu
.add_command
elif itemType
== 'separator':
command
= menu
.add_separator
elif itemType
== 'checkbutton':
command
= menu
.add_checkbutton
elif itemType
== 'radiobutton':
command
= menu
.add_radiobutton
elif itemType
== 'cascade':
command
= menu
.add_cascade
raise ValueError, 'unknown menuitem type "%s"' % itemType
self
._menuInfo
[menuName
][1].append(statusHelp
)
def _addHotkeyToOptions(self
, menuName
, kw
, traverseSpec
):
if (not self
['hotkeys'] or kw
.has_key('underline') or
not kw
.has_key('label')):
if type(traverseSpec
) == types
.IntType
:
kw
['underline'] = traverseSpec
menu
= self
.component(menuName
)
for item
in range(end
+ 1):
if menu
.type(item
) not in ('separator', 'tearoff'):
string
.atoi(str(menu
.entrycget(item
, 'underline')))
label
= str(menu
.entrycget(item
, 'label'))
if underline
< len(label
):
hotkey
= string
.lower(label
[underline
])
if hotkey
not in hotkeyList
:
hotkeyList
.append(hotkey
)
if type(traverseSpec
) == types
.StringType
:
lowerLetter
= string
.lower(traverseSpec
)
if traverseSpec
in name
and lowerLetter
not in hotkeyList
:
kw
['underline'] = string
.index(name
, traverseSpec
)
targets
= string
.digits
+ string
.letters
lowerName
= string
.lower(name
)
for letter_index
in range(len(name
)):
letter
= lowerName
[letter_index
]
if letter
in targets
and letter
not in hotkeyList
:
kw
['underline'] = letter_index
def _menuHelp(self
, event
, menuName
):
index
= menu
.index('@%d'% event
.x
)
menu
= self
.component(menuName
)
index
= menu
.index('@%d'% event
.y
)
balloon
= self
['balloon']
if str(menu
.cget('tearoff')) == '1':
help = self
._menuInfo
[menuName
][1][index
]
def _resetHelpmessage(self
, event
=None):
balloon
= self
['balloon']
Pmw
.forwardmethods(MainMenuBar
, Tkinter
.Menu
, '_hull')