1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 import glob, gtk
16 import xml.dom.minidom
17 from xml.dom.minidom import Node
18 import os
19 import gettext
20
21 gettext.textdomain('screenlets')
22 gettext.bindtextdomain('screenlets', '/usr/share/locale')
23
25 return gettext.gettext(s)
26
27
28
29
31 """Creates a nw gtk.ImageMenuItem from a given icon-/filename."""
32 item = gtk.ImageMenuItem(label)
33 image = gtk.Image()
34 if filename and filename[0]=='/':
35
36 try:
37 image.set_from_file(filename)
38 pb = image.get_pixbuf()
39
40 if pb.get_width() > icon_size :
41 pb2 = pb.scale_simple(
42 icon_size, icon_size,
43 gtk.gdk.INTERP_HYPER)
44 image.set_from_pixbuf(pb2)
45 else:
46 image.set_from_pixbuf(pb)
47 except:
48 print _("Error while creating image from file: %s") % filename
49 return None
50 else:
51 image.set_from_icon_name(filename, 3)
52 if image:
53 item.set_image(image)
54 return item
55
57 """Read ".desktop"-file into a dict
58 NOTE: Should use utils.IniReader ..."""
59 list = {}
60 f=None
61 try:
62 f = open (filename, "r")
63 except:
64 print _("Error: file %s not found.") % filename
65 if f:
66 lines = f.readlines()
67 for line in lines:
68 if line[0] != "#" and line !="\n" and line[0] != "[":
69 ll = line.split('=', 1)
70 if len(ll) > 1:
71 list[ll[0]] = ll[1].replace("\n", "")
72 return list
73
76 """Create MenuItems from a directory.
77 TODO: use regular expressions"""
78
79 lst = glob.glob(dirname + "/" + filter)
80
81 lst.sort()
82 dlen = len(dirname) + 1
83
84 for filename in lst:
85
86 fname = filename[dlen:]
87
88 if skip.count(fname)<1:
89
90
91 l = len(search)
92 if l>0 and l == len(replace):
93 for i in xrange(l):
94 fname = fname.replace(search[i], replace[i])
95
96 id = id_prefix + fname + id_suffix
97
98
99 item = gtk.MenuItem(fname)
100 item.connect("activate", callback, id)
101 item.show()
102 menu.append(item)
103
105 """Create a gtk.Menu by an XML-Node"""
106 menu = gtk.Menu()
107 for node in node.childNodes:
108
109 type = node.nodeType
110 if type == Node.ELEMENT_NODE:
111 label = node.getAttribute("label")
112 id = node.getAttribute("id")
113 item = None
114 is_check = False
115
116 if node.nodeName == "item":
117 item = gtk.MenuItem(label)
118
119 elif node.nodeName == "checkitem":
120 item = gtk.CheckMenuItem(label)
121 is_check = True
122 if node.hasAttribute("checked"):
123 item.set_active(True)
124
125 elif node.nodeName == "imageitem":
126 icon = node.getAttribute("icon")
127 item = imageitem_from_name(icon, label, icon_size)
128
129 elif node.nodeName == "separator":
130 item = gtk.SeparatorMenuItem()
131
132 elif node.nodeName == "appdir":
133
134 path = node.getAttribute("path")
135 appmenu = ApplicationMenu(path)
136 cats = node.getAttribute("cats").split(",")
137 for cat in cats:
138 item = gtk.MenuItem(cat)
139
140 submenu = appmenu.get_menu_for_category(cat, callback)
141 item.set_submenu(submenu)
142 item.show()
143 menu.append(item)
144 item = None
145
146 elif node.nodeName == "scandir":
147
148 dir = node.getAttribute("directory")
149
150 dir = dir.replace('$HOME', os.environ['HOME'])
151
152 idprfx = node.getAttribute("id_prefix")
153 idsufx = node.getAttribute("id_suffix")
154 srch = node.getAttribute("search").split(',')
155 repl = node.getAttribute("replace").split(',')
156 skp = node.getAttribute("skip").split(',')
157
158 flt = node.getAttribute("filter")
159 if flt=='':
160 flt='*'
161
162
163 fill_menu_from_directory(dir, menu, callback, filter=flt,
164 id_prefix=idprfx, id_suffix=idsufx, search=srch,
165 replace=repl, skip=skp)
166
167 if item:
168 if node.hasChildNodes():
169
170 submenu = create_menu_from_xml(node,
171 callback, icon_size)
172 item.set_submenu(submenu)
173 item.show()
174 if id:
175 item.connect("activate", callback, id)
176 menu.append(item)
177 return menu
178
180 """Creates a menu from an XML-file and returns None if something went wrong"""
181 doc = None
182 try:
183 doc = xml.dom.minidom.parse(filename)
184 except Exception, e:
185 print _("XML-Error: %s") % str(e)
186 return None
187 return create_menu_from_xml(doc.firstChild, callback)
188
189
190
192 """A utility-class to simplify the creation of gtk.Menus from directories with
193 desktop-files. Reads all files in one or multiple directories into its internal list
194 and offers an easy way to create entire categories as complete gtk.Menu
195 with gtk.ImageMenuItems. """
196
197
198 __path = ""
199
200 __applications = []
201
202
207
208
209
211 dirlst = glob.glob(path + '/*')
212
213 namelen = len(path)
214 for file in dirlst:
215 if file[-8:]=='.desktop':
216 fname = file[namelen:]
217
218 df = read_desktop_file(file)
219 name = ""
220 icon = ""
221 cmd = ""
222 try:
223 name = df['Name']
224 icon = df['Icon']
225 cmd = df['Exec']
226 cats = df['Categories'].split(';')
227
228
229 self.__applications.append(df)
230 except Exception, ex:
231 print _("Exception: %s") % str(ex)
232 print _("An error occured with desktop-file: %s") % file
233
234
236
237 applist = []
238 for app in self.__applications:
239 try:
240 if (';'+app['Categories']).count(';'+cat_name+';') > 0:
241 applist.append(app)
242 except:
243 pass
244
245
246 for app in applist:
247 if applist.count(app) > 1:
248 applist.remove(app)
249
250 applist.sort()
251
252 menu = gtk.Menu()
253 for app in applist:
254 item = imageitem_from_name(app['Icon'], app['Name'], 24)
255 if item:
256 item.connect("activate", callback, "exec:" + app['Exec'])
257 item.show()
258 menu.append(item)
259
260 return menu
261
262
263 """
264 # TEST:
265
266 # menu-callback
267 def menu_handler(item, id):
268 # now check id
269 if id[:5]=="exec:":
270 print "EXECUTE: " + id[5:]
271
272 def button_press(widget, event):
273 widget.menu.popup(None, None, None, event.button,
274 event.time)
275 return False
276
277 def destroy(widget, event):
278 gtk.main_quit()
279
280
281
282 # ApplicationMenu test
283
284 appmenu = ApplicationMenu('/usr/share/applications')
285
286 win = gtk.Window()
287 win.resize(200, 200)
288 win.connect("delete_event", destroy)
289 but = gtk.Button("Press!")
290 but.menu = gtk.Menu()
291 lst = ["Development", "Office", "Game", "Utility"]
292 for i in xrange(len(lst)):
293 item = gtk.MenuItem(lst[i])
294 submenu = appmenu.get_menu_for_category(lst[i], menu_handler)
295 if submenu:
296 item.set_submenu(submenu)
297 item.show()
298 but.menu.append(item)
299 but.menu.show()
300 but.connect("button_press_event", button_press)
301 win.add(but)
302 but.show()
303 win.show()
304 gtk.main()
305 """
306
307
308 if __name__ == "__main__":
309
310 import screenlets.utils
311
312
314 print "ID: "+str(id)
315
316 if id[:5]=="exec:":
317 print "EXECUTE: " + id[5:]
318
323
326
327
328 p = screenlets.utils.find_first_screenlet_path('Control')
329 print p
330 menu = create_menu_from_file(p + "/menu.xml", xml_menu_handler)
331 if menu:
332 win = gtk.Window()
333 win.resize(200, 200)
334 win.connect("delete_event", destroy)
335 but = gtk.Button("Press!")
336 but.menu = menu
337 but.connect("button_press_event", button_press)
338 win.add(but)
339 but.show()
340 win.show()
341 gtk.main()
342 else:
343 print _("Error while creating menu.")
344