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 applist.sort()
246
247 menu = gtk.Menu()
248 for app in applist:
249 item = imageitem_from_name(app['Icon'], app['Name'], 24)
250 if item:
251 item.connect("activate", callback, "exec:" + app['Exec'])
252 item.show()
253 menu.append(item)
254
255 return menu
256
257
258 """
259 # TEST:
260
261 # menu-callback
262 def menu_handler(item, id):
263 # now check id
264 if id[:5]=="exec:":
265 print "EXECUTE: " + id[5:]
266
267 def button_press(widget, event):
268 widget.menu.popup(None, None, None, event.button,
269 event.time)
270 return False
271
272 def destroy(widget, event):
273 gtk.main_quit()
274
275
276
277 # ApplicationMenu test
278
279 appmenu = ApplicationMenu('/usr/share/applications')
280
281 win = gtk.Window()
282 win.resize(200, 200)
283 win.connect("delete_event", destroy)
284 but = gtk.Button("Press!")
285 but.menu = gtk.Menu()
286 lst = ["Development", "Office", "Game", "Utility"]
287 for i in xrange(len(lst)):
288 item = gtk.MenuItem(lst[i])
289 submenu = appmenu.get_menu_for_category(lst[i], menu_handler)
290 if submenu:
291 item.set_submenu(submenu)
292 item.show()
293 but.menu.append(item)
294 but.menu.show()
295 but.connect("button_press_event", button_press)
296 win.add(but)
297 but.show()
298 win.show()
299 gtk.main()
300 """
301
302
303 if __name__ == "__main__":
304
305 import screenlets.utils
306
307
309 print "ID: "+str(id)
310
311 if id[:5]=="exec:":
312 print "EXECUTE: " + id[5:]
313
318
321
322
323 p = screenlets.utils.find_first_screenlet_path('Control')
324 print p
325 menu = create_menu_from_file(p + "/menu.xml", xml_menu_handler)
326 if menu:
327 win = gtk.Window()
328 win.resize(200, 200)
329 win.connect("delete_event", destroy)
330 but = gtk.Button("Press!")
331 but.menu = menu
332 but.connect("button_press_event", button_press)
333 win.add(but)
334 but.show()
335 win.show()
336 gtk.main()
337 else:
338 print _("Error while creating menu.")
339