1 |
bh |
187 |
# Copyright (C) 2001, 2002 by Intevation GmbH |
2 |
|
|
# Author: |
3 |
|
|
# Bernhard Herzog <[email protected]> |
4 |
|
|
# |
5 |
|
|
# This program is free software under the GPL (>=v2) |
6 |
|
|
# Read the file COPYING coming with Thuban for details. |
7 |
|
|
|
8 |
|
|
"""Menu management""" |
9 |
|
|
|
10 |
|
|
__version__ = "$Revision$" |
11 |
|
|
|
12 |
jan |
374 |
from Thuban import _ |
13 |
bh |
187 |
|
14 |
|
|
class Menu: |
15 |
|
|
|
16 |
|
|
"""Represent a menu or submenu. |
17 |
|
|
|
18 |
|
|
A menu has a name and a title. The name can be used to identify |
19 |
|
|
menus internally while the title is intended for use in the GUI. |
20 |
|
|
|
21 |
|
|
Menu items can be added with the Insert* methods. |
22 |
|
|
""" |
23 |
|
|
|
24 |
|
|
def __init__(self, name, title, items = None): |
25 |
|
|
"""Initialize the menu. |
26 |
|
|
|
27 |
|
|
Parameters: |
28 |
|
|
name -- the name of the menu |
29 |
|
|
title -- the (possibly localized) title of the menu |
30 |
|
|
items -- (optional) a list of menu items. |
31 |
|
|
|
32 |
|
|
The items list may contains strings with command names, None to |
33 |
|
|
indicate separators or Menu instances for submenus. |
34 |
|
|
""" |
35 |
|
|
self.name = name |
36 |
|
|
self.title = title |
37 |
|
|
if items is None: |
38 |
|
|
self.items = [] |
39 |
|
|
else: |
40 |
|
|
self.items = items |
41 |
|
|
|
42 |
|
|
def item_index(self, item): |
43 |
|
|
"""Return the index of item in the menu. |
44 |
|
|
|
45 |
jan |
1061 |
item -- may be the name of a non-menu entry or the |
46 |
|
|
name of a menu or a menu itself. |
47 |
bh |
236 |
|
48 |
bh |
187 |
Return None it item is not found. |
49 |
|
|
""" |
50 |
bh |
236 |
for i in range(len(self.items)): |
51 |
|
|
temp = self.items[i] |
52 |
|
|
if temp == item: |
53 |
|
|
# this case takes care of item being the name of an |
54 |
|
|
# entry or a menu. |
55 |
|
|
return i |
56 |
|
|
elif isinstance(temp, Menu) and temp.name == item: |
57 |
|
|
# item is the name of a menu |
58 |
|
|
return i |
59 |
|
|
# Didn't find the item so return None |
60 |
|
|
return None |
61 |
bh |
187 |
|
62 |
|
|
def find_menu(self, name): |
63 |
|
|
"""Return the submenu named name or None if no such item exists""" |
64 |
|
|
for item in self.items: |
65 |
|
|
if isinstance(item, Menu) and item.name == name: |
66 |
|
|
return item |
67 |
|
|
return None |
68 |
|
|
|
69 |
|
|
def InsertItem(self, item, menu = (), after = None): |
70 |
|
|
"""Insert a menu item. |
71 |
|
|
|
72 |
|
|
Parameters: |
73 |
bh |
236 |
|
74 |
bh |
187 |
item -- the menu item to insert must be either a string with |
75 |
|
|
the command's name or a Menu instance. |
76 |
bh |
236 |
|
77 |
bh |
187 |
menu -- (optional) the submenu to insert into. It should be a |
78 |
|
|
sequence of menu names. |
79 |
bh |
236 |
|
80 |
bh |
187 |
after -- (optional) insert the new item after this one. after |
81 |
|
|
should be the name of a command. |
82 |
|
|
""" |
83 |
|
|
# if menu is given, get the first submenu |
84 |
|
|
if menu: |
85 |
|
|
submenu_index = self.find_menu(menu[0]) |
86 |
|
|
if submenu_index is not None: |
87 |
|
|
submenu_index.InsertItem(item, menu = menu[1:], after = after) |
88 |
|
|
else: |
89 |
|
|
# the submenu doesn't exist yet. Raise an error. |
90 |
jan |
374 |
raise KeyError(_("Submenu %s doesn't exist") % menu[0]) |
91 |
bh |
187 |
else: |
92 |
|
|
if after is not None: |
93 |
|
|
idx = self.item_index(after) |
94 |
|
|
else: |
95 |
|
|
idx = None |
96 |
|
|
|
97 |
|
|
if idx is not None: |
98 |
bh |
236 |
self.items.insert(idx + 1, item) |
99 |
bh |
187 |
else: |
100 |
|
|
self.items.append(item) |
101 |
|
|
|
102 |
jan |
1047 |
def InsertSeparator(self, after = None): |
103 |
|
|
"""Insert a separator |
104 |
bh |
187 |
|
105 |
jan |
1047 |
after -- (optional) insert the separator after this one. after |
106 |
|
|
should be the name of a command. |
107 |
|
|
""" |
108 |
|
|
self.InsertItem(None, after = after) |
109 |
|
|
|
110 |
bh |
187 |
def InsertMenu(self, name, title, menu = (), after = None): |
111 |
|
|
"""Insert and return a new menu. |
112 |
|
|
|
113 |
|
|
Parameters: |
114 |
|
|
|
115 |
|
|
name -- the (internal) name of the menu |
116 |
|
|
|
117 |
|
|
title -- the (possibly localized) title |
118 |
bh |
236 |
|
119 |
bh |
187 |
menu -- (optional) the submenu to insert into. It should be a |
120 |
|
|
sequence of menu names. |
121 |
bh |
236 |
|
122 |
bh |
187 |
after -- (optional) insert the new item after this one. after |
123 |
|
|
should be the name of a command. |
124 |
|
|
""" |
125 |
|
|
newmenu = Menu(name, title) |
126 |
|
|
self.InsertItem(newmenu, menu = menu, after = after) |
127 |
|
|
return newmenu |
128 |
bh |
214 |
|
129 |
jan |
2202 |
def FindOrInsertMenu(self, name, title, menu = (), after = None): |
130 |
|
|
""" |
131 |
|
|
Find the menu with the specified name. If found, return it. |
132 |
|
|
Else insert the menu as specified and return it. |
133 |
|
|
|
134 |
|
|
Parameters: See InsertMenu(). |
135 |
|
|
""" |
136 |
|
|
|
137 |
|
|
m = self.find_menu(name) |
138 |
|
|
if m is None: |
139 |
|
|
m = self.InsertMenu(name, title, menu, after) |
140 |
|
|
return m |
141 |
|
|
|
142 |
|
|
|
143 |
bh |
214 |
def SetItems(self, items): |
144 |
|
|
"""Replace the contents of the menu by items.""" |
145 |
|
|
self.items = items |
146 |
jan |
1061 |
|
147 |
|
|
def RemoveItem(self, item): |
148 |
|
|
"""Remove an item from the menu. |
149 |
|
|
|
150 |
|
|
item -- the (internal) name of the item. |
151 |
|
|
""" |
152 |
|
|
i = self.item_index(item) |
153 |
|
|
if i is not None: |
154 |
|
|
self.items.pop(i) |