Merge lp:~laudeci/unity-launcher-editor/dev into lp:unity-launcher-editor

Proposed by Laudeci Oliveira
Status: Merged
Merged at revision: 54
Proposed branch: lp:~laudeci/unity-launcher-editor/dev
Merge into: lp:unity-launcher-editor
Diff against target: 1776 lines (+815/-501)
13 files modified
distribute_setup.py (+3/-3)
unitylaunchereditor/appgui.py (+7/-24)
unitylaunchereditor/data/application.glade (+51/-234)
unitylaunchereditor/desktop.py (+1/-1)
unitylaunchereditor/groupsdialog.py (+157/-32)
unitylaunchereditor/locale/unity-launcher-editor.pot (+79/-0)
unitylaunchereditor/mainwindow.py (+135/-187)
unitylaunchereditor/newlauncher.py (+23/-19)
unitylaunchereditor/translation.py (+28/-0)
unitylaunchereditor/utils.py (+1/-1)
unitylaunchereditor/widgets/__init__.py (+1/-0)
unitylaunchereditor/widgets/grouptree.py (+133/-0)
unitylaunchereditor/widgets/launcherview.py (+196/-0)
To merge this branch: bzr merge lp:~laudeci/unity-launcher-editor/dev
Reviewer Review Type Date Requested Status
Laudeci Oliveira Approve
Ursula Junque Pending
Review via email: mp+61009@code.launchpad.net

Description of the change

Modularization and code internationalization

To post a comment you must log in.
Revision history for this message
Laudeci Oliveira (laudeci) :
review: Approve
53. By Ursula Junque

Merging Pretto's branch

54. By Ursula Junque

merging laudeci-dev

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'distribute_setup.py'
2--- distribute_setup.py 2011-05-13 14:49:09 +0000
3+++ distribute_setup.py 2011-05-21 20:12:30 +0000
4@@ -144,7 +144,7 @@
5 except ImportError:
6 return _do_download(version, download_base, to_dir, download_delay)
7 try:
8- pkg_resources.require("distribute>="+version)
9+ pkg_resources.require("distribute>=" + version)
10 return
11 except pkg_resources.VersionConflict:
12 e = sys.exc_info()[1]
13@@ -351,7 +351,7 @@
14 def _under_prefix(location):
15 if 'install' not in sys.argv:
16 return True
17- args = sys.argv[sys.argv.index('install')+1:]
18+ args = sys.argv[sys.argv.index('install') + 1:]
19 for index, arg in enumerate(args):
20 for option in ('--root', '--prefix'):
21 if arg.startswith('%s=' % option):
22@@ -359,7 +359,7 @@
23 return location.startswith(top_dir)
24 elif arg == option:
25 if len(args) > index:
26- top_dir = args[index+1]
27+ top_dir = args[index + 1]
28 return location.startswith(top_dir)
29 if arg == '--user' and USER_SITE is not None:
30 return location.startswith(USER_SITE)
31
32=== modified file 'unitylaunchereditor/appgui.py'
33--- unitylaunchereditor/appgui.py 2011-05-13 18:18:55 +0000
34+++ unitylaunchereditor/appgui.py 2011-05-21 20:12:30 +0000
35@@ -18,9 +18,11 @@
36 def save_unity_list(self, menu_items):
37 try:
38 print str(menu_items)
39- self.gsettings.set_strv('favorites',menu_items)
40- except GError,e:
41- print e
42+ self.gsettings.set_strv('favorites', menu_items)
43+ self.get_unity_list()
44+ return True
45+ except GError, e:
46+ return False
47 #return_code = os.system('unity --reset') #subprocess.call(['unity','--reset'])
48 #if return_code != 0:
49 # print "Settings fail to transition to new unity compiz favorites"
50@@ -28,27 +30,8 @@
51 def get_unity_list(self):
52 """ Create a list of items from unity's Launcher Panel."""
53 unity = self.gsettings.get_value('favorites')
54- store = self.main_window.listview_launcher.get_model()
55- store.clear()
56- print unity
57- for menu_item in unity:
58- desktop_parser = DesktopParser(menu_item)
59- desktop_parser.update_keys()
60- sname = desktop_parser.get('Name')
61- icon = desktop_parser.get('Icon')
62- if sname is None:
63- sname = desktop_parser.get('Name', 'en')
64- if icon is None:
65- pix = None
66- else:
67- pix = get_icon(icon)
68- store.append((pix, '%s' % sname, desktop_parser, menu_item))
69- print sname, menu_item
70
71- self.main_window.listview_launcher.set_model(store)
72- self.main_window.listview_launcher.connect('cursor-changed',
73- self.main_window.listview_launcher_row_change)
74- #make first row active
75- self.main_window.listview_launcher.set_cursor((0,))
76+ self.main_window.load_launcher_from_list(unity)
77+
78
79
80
81=== modified file 'unitylaunchereditor/data/application.glade'
82--- unitylaunchereditor/data/application.glade 2011-05-12 18:36:05 +0000
83+++ unitylaunchereditor/data/application.glade 2011-05-21 20:12:30 +0000
84@@ -159,203 +159,6 @@
85 </packing>
86 </child>
87 </object>
88- <object class="GtkFrame" id="frame4">
89- <property name="visible">True</property>
90- <property name="can_focus">False</property>
91- <property name="border_width">4</property>
92- <property name="label_xalign">0</property>
93- <property name="label_yalign">0</property>
94- <property name="shadow_type">none</property>
95- <child>
96- <object class="GtkAlignment" id="alignment5">
97- <property name="visible">True</property>
98- <property name="can_focus">False</property>
99- <property name="left_padding">12</property>
100- <child>
101- <object class="GtkTable" id="table1">
102- <property name="visible">True</property>
103- <property name="can_focus">False</property>
104- <property name="border_width">5</property>
105- <property name="n_rows">4</property>
106- <property name="n_columns">2</property>
107- <property name="column_spacing">5</property>
108- <property name="row_spacing">5</property>
109- <child>
110- <object class="GtkEventBox" id="eventbox7">
111- <property name="visible">True</property>
112- <property name="can_focus">False</property>
113- <child>
114- <object class="GtkLabel" id="label9">
115- <property name="visible">True</property>
116- <property name="can_focus">False</property>
117- <property name="xalign">0</property>
118- <property name="yalign">0</property>
119- <property name="label" translatable="yes">Target Environment:</property>
120- </object>
121- </child>
122- </object>
123- <packing>
124- <property name="top_attach">3</property>
125- <property name="bottom_attach">4</property>
126- <property name="x_options">GTK_FILL</property>
127- <property name="y_options">GTK_FILL</property>
128- </packing>
129- </child>
130- <child>
131- <object class="GtkComboBox" id="cmbTarget">
132- <property name="visible">True</property>
133- <property name="can_focus">False</property>
134- <property name="model">lstTarget</property>
135- </object>
136- <packing>
137- <property name="left_attach">1</property>
138- <property name="right_attach">2</property>
139- <property name="top_attach">3</property>
140- <property name="bottom_attach">4</property>
141- </packing>
142- </child>
143- <child>
144- <object class="GtkEventBox" id="eventbox6">
145- <property name="visible">True</property>
146- <property name="can_focus">False</property>
147- <child>
148- <object class="GtkLabel" id="label8">
149- <property name="visible">True</property>
150- <property name="can_focus">False</property>
151- <property name="xalign">0</property>
152- <property name="label" translatable="yes">Command:</property>
153- </object>
154- </child>
155- </object>
156- <packing>
157- <property name="top_attach">2</property>
158- <property name="bottom_attach">3</property>
159- <property name="x_options">GTK_FILL</property>
160- <property name="y_options">GTK_FILL</property>
161- </packing>
162- </child>
163- <child>
164- <object class="GtkHBox" id="hbox4">
165- <property name="visible">True</property>
166- <property name="can_focus">False</property>
167- <child>
168- <object class="GtkEntry" id="txtGCommand">
169- <property name="visible">True</property>
170- <property name="can_focus">True</property>
171- <property name="invisible_char">•</property>
172- <property name="invisible_char_set">True</property>
173- <property name="primary_icon_activatable">False</property>
174- <property name="secondary_icon_activatable">False</property>
175- <property name="primary_icon_sensitive">True</property>
176- <property name="secondary_icon_sensitive">True</property>
177- </object>
178- <packing>
179- <property name="expand">True</property>
180- <property name="fill">True</property>
181- <property name="position">0</property>
182- </packing>
183- </child>
184- <child>
185- <object class="GtkButton" id="cmdGRun">
186- <property name="label" translatable="yes">...</property>
187- <property name="visible">True</property>
188- <property name="can_focus">True</property>
189- <property name="receives_default">True</property>
190- <property name="use_action_appearance">False</property>
191- </object>
192- <packing>
193- <property name="expand">False</property>
194- <property name="fill">True</property>
195- <property name="position">1</property>
196- </packing>
197- </child>
198- </object>
199- <packing>
200- <property name="left_attach">1</property>
201- <property name="right_attach">2</property>
202- <property name="top_attach">2</property>
203- <property name="bottom_attach">3</property>
204- </packing>
205- </child>
206- <child>
207- <object class="GtkEventBox" id="eventbox5">
208- <property name="visible">True</property>
209- <property name="can_focus">False</property>
210- <child>
211- <object class="GtkLabel" id="label3">
212- <property name="visible">True</property>
213- <property name="can_focus">False</property>
214- <property name="xalign">0</property>
215- <property name="label" translatable="yes">Command Name:</property>
216- </object>
217- </child>
218- </object>
219- <packing>
220- <property name="top_attach">1</property>
221- <property name="bottom_attach">2</property>
222- <property name="x_options">GTK_FILL</property>
223- <property name="y_options"></property>
224- </packing>
225- </child>
226- <child>
227- <object class="GtkEventBox" id="eventbox8">
228- <property name="visible">True</property>
229- <property name="can_focus">False</property>
230- <child>
231- <object class="GtkLabel" id="label10">
232- <property name="visible">True</property>
233- <property name="can_focus">False</property>
234- <property name="xalign">0</property>
235- <property name="label" translatable="yes">Group Name:</property>
236- </object>
237- </child>
238- </object>
239- <packing>
240- <property name="x_options">GTK_FILL</property>
241- <property name="y_options"></property>
242- </packing>
243- </child>
244- <child>
245- <object class="GtkEntry" id="txtGName">
246- <property name="visible">True</property>
247- <property name="can_focus">True</property>
248- <property name="invisible_char">•</property>
249- <property name="invisible_char_set">True</property>
250- <property name="primary_icon_activatable">False</property>
251- <property name="secondary_icon_activatable">False</property>
252- <property name="primary_icon_sensitive">True</property>
253- <property name="secondary_icon_sensitive">True</property>
254- </object>
255- <packing>
256- <property name="left_attach">1</property>
257- <property name="right_attach">2</property>
258- <property name="top_attach">1</property>
259- <property name="bottom_attach">2</property>
260- <property name="y_options"></property>
261- </packing>
262- </child>
263- <child>
264- <object class="GtkEntry" id="txtGGroup">
265- <property name="visible">True</property>
266- <property name="can_focus">True</property>
267- <property name="invisible_char">•</property>
268- <property name="invisible_char_set">True</property>
269- <property name="primary_icon_activatable">False</property>
270- <property name="secondary_icon_activatable">False</property>
271- <property name="primary_icon_sensitive">True</property>
272- <property name="secondary_icon_sensitive">True</property>
273- </object>
274- <packing>
275- <property name="left_attach">1</property>
276- <property name="right_attach">2</property>
277- <property name="y_options"></property>
278- </packing>
279- </child>
280- </object>
281- </child>
282- </object>
283- </child>
284- </object>
285 <object class="GtkListStore" id="liststore1"/>
286 <object class="GtkListStore" id="lstTarget">
287 <columns>
288@@ -398,19 +201,14 @@
289 </packing>
290 </child>
291 <child>
292- <object class="GtkScrolledWindow" id="scrolledwindow1">
293+ <object class="GtkScrolledWindow" id="list_container">
294 <property name="visible">True</property>
295 <property name="can_focus">True</property>
296 <property name="hscrollbar_policy">never</property>
297 <property name="vscrollbar_policy">automatic</property>
298 <property name="shadow_type">in</property>
299 <child>
300- <object class="GtkTreeView" id="ListViewLauncher">
301- <property name="visible">True</property>
302- <property name="can_focus">True</property>
303- <property name="headers_visible">False</property>
304- <property name="reorderable">True</property>
305- </object>
306+ <placeholder/>
307 </child>
308 </object>
309 <packing>
310@@ -420,35 +218,57 @@
311 </packing>
312 </child>
313 <child>
314- <object class="GtkButton" id="cmdAdd">
315- <property name="label">gtk-add</property>
316+ <object class="GtkHButtonBox" id="hbuttonbox2">
317 <property name="visible">True</property>
318- <property name="can_focus">True</property>
319- <property name="receives_default">True</property>
320- <property name="use_action_appearance">False</property>
321- <property name="use_stock">True</property>
322+ <property name="can_focus">False</property>
323+ <property name="layout_style">end</property>
324+ <child>
325+ <object class="GtkButton" id="cmdAdd">
326+ <property name="visible">True</property>
327+ <property name="can_focus">True</property>
328+ <property name="receives_default">True</property>
329+ <property name="use_action_appearance">False</property>
330+ <child>
331+ <object class="GtkImage" id="image1">
332+ <property name="visible">True</property>
333+ <property name="can_focus">False</property>
334+ <property name="stock">gtk-add</property>
335+ </object>
336+ </child>
337+ </object>
338+ <packing>
339+ <property name="expand">False</property>
340+ <property name="fill">False</property>
341+ <property name="position">0</property>
342+ </packing>
343+ </child>
344+ <child>
345+ <object class="GtkButton" id="cmdRemove">
346+ <property name="visible">True</property>
347+ <property name="can_focus">True</property>
348+ <property name="receives_default">True</property>
349+ <property name="use_action_appearance">False</property>
350+ <child>
351+ <object class="GtkImage" id="image2">
352+ <property name="visible">True</property>
353+ <property name="can_focus">False</property>
354+ <property name="stock">gtk-remove</property>
355+ </object>
356+ </child>
357+ </object>
358+ <packing>
359+ <property name="expand">False</property>
360+ <property name="fill">False</property>
361+ <property name="position">1</property>
362+ </packing>
363+ </child>
364 </object>
365 <packing>
366 <property name="expand">False</property>
367- <property name="fill">False</property>
368+ <property name="fill">True</property>
369 <property name="position">2</property>
370 </packing>
371 </child>
372- <child>
373- <object class="GtkButton" id="cmdRemove">
374- <property name="label">gtk-remove</property>
375- <property name="visible">True</property>
376- <property name="can_focus">True</property>
377- <property name="receives_default">True</property>
378- <property name="use_action_appearance">False</property>
379- <property name="use_stock">True</property>
380- </object>
381- <packing>
382- <property name="expand">False</property>
383- <property name="fill">False</property>
384- <property name="position">3</property>
385- </packing>
386- </child>
387 </object>
388 <packing>
389 <property name="resize">False</property>
390@@ -784,7 +604,9 @@
391 <object class="GtkAlignment" id="alignment3">
392 <property name="visible">True</property>
393 <property name="can_focus">False</property>
394- <property name="left_padding">12</property>
395+ <property name="bottom_padding">9</property>
396+ <property name="left_padding">6</property>
397+ <property name="right_padding">9</property>
398 <child>
399 <object class="GtkVBox" id="vbox4">
400 <property name="visible">True</property>
401@@ -845,18 +667,13 @@
402 </packing>
403 </child>
404 <child>
405- <object class="GtkScrolledWindow" id="scrolledwindow2">
406+ <object class="GtkScrolledWindow" id="group_container">
407 <property name="visible">True</property>
408 <property name="can_focus">True</property>
409 <property name="hscrollbar_policy">automatic</property>
410 <property name="vscrollbar_policy">automatic</property>
411 <child>
412- <object class="GtkTreeView" id="tvwGroups">
413- <property name="visible">True</property>
414- <property name="can_focus">True</property>
415- <property name="model">liststore1</property>
416- <property name="headers_visible">False</property>
417- </object>
418+ <placeholder/>
419 </child>
420 </object>
421 <packing>
422
423=== modified file 'unitylaunchereditor/desktop.py'
424--- unitylaunchereditor/desktop.py 2011-05-13 18:18:55 +0000
425+++ unitylaunchereditor/desktop.py 2011-05-21 20:12:30 +0000
426@@ -54,7 +54,7 @@
427 self.add_section(keyname)
428 self.keys_menu.append(keyname)
429
430- def remove_section(self,keyname):
431+ def remove_sections(self, keyname):
432 self.remove_section(keyname)
433 self.keys_menu.append(keyname)
434
435
436=== modified file 'unitylaunchereditor/groupsdialog.py'
437--- unitylaunchereditor/groupsdialog.py 2011-05-10 02:13:09 +0000
438+++ unitylaunchereditor/groupsdialog.py 2011-05-21 20:12:30 +0000
439@@ -1,3 +1,8 @@
440+# -*- coding: utf-8 -*-
441+#####################################################################
442+# Laudeci Oliveira <laudeci@ubuntu.com>
443+# Ursula Junque <ursinha@ubuntu.com>
444+#
445 # Copyright 2011 unity-launcher-editor-dev.
446 #
447 # This program is free software; you can redistribute it and/or modify
448@@ -14,42 +19,157 @@
449 import gtk
450 from gobject import TYPE_STRING
451 from utils import FileChooser
452-from os.path import exists, expanduser, isfile, join
453-
454+from translation import _
455
456 class GroupsDialog(gtk.Dialog):
457 """XXX: add docs."""
458
459- def __init__(self, title='Add Group...'):
460+ def __init__(self, title=_('Add Group...'), parent=None):
461 super(GroupsDialog, self).__init__(title,
462- None, (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT |
463+ None, (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT |
464 gtk.DIALOG_NO_SEPARATOR),
465 (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
466-
467- glade_file = "application.glade"
468- self.builder = gtk.Builder()
469-
470- glade_path = join("data", glade_file)
471- if not exists(glade_path):
472- raise Exception(
473- "Critical: couldn't find glade file: %s" % glade_path)
474- self.builder.add_from_file(glade_path)
475- self.add_group_panel = self.builder.get_object('frame4')
476-
477+
478+
479+ self.set_resizable(False)
480+
481+ if parent:
482+ self.set_transient_for(parent)
483+
484+ self.add_group_panel = self.create_widgets()
485+ self.vbox.pack_start(self.add_group_panel, True, True, 0)
486+ self.vbox.show_all()
487+
488 self.ok_button = self.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
489 self.ok_button.grab_default()
490 self.ok_button.set_sensitive(False)
491 self.set_alternative_button_order(
492 [gtk.RESPONSE_CANCEL, gtk.RESPONSE_OK])
493+
494+ self.txtName.connect('changed', self.on_change)
495+ self.txtCommand.connect('changed', self.on_change)
496+ self.cmdGRun.connect('clicked', self.open_executable)
497
498- self.txtGroup =self.builder.get_object('txtGGroup')
499- self.txtName = self.builder.get_object('txtGName')
500+ def create_widgets(self):
501+ '''
502+ this will create input widgets for our dialog
503+ without depending on glade for that and
504+ solving the file not found error report.
505+ '''
506+
507+ frame4 = gtk.Frame()
508+ frame4.set_shadow_type(gtk.SHADOW_NONE)
509+
510+ align = gtk.Alignment()
511+ align.set_padding(0, 0, 12, 0)
512+
513+ table = gtk.Table(rows=4, columns=2, homogeneous=False)
514+ table.set_col_spacings(5)
515+ table.set_row_spacings(5)
516+
517+ label8 = gtk.Label(_('Group Name:'))
518+ label8.set_alignment(0, 0.5)
519+ eventbox8 = gtk.EventBox()
520+ eventbox8.add(label8)
521+
522+ table.attach(eventbox8,
523+ left_attach=0,
524+ right_attach=1,
525+ top_attach=0,
526+ bottom_attach=1,
527+ xoptions=gtk.FILL,
528+ yoptions=gtk.FILL,
529+ xpadding=0,
530+ ypadding=0)
531+
532+
533+ label5 = gtk.Label(_('Command Name:'))
534+ label5.set_alignment(0, 0.5)
535+ eventbox5 = gtk.EventBox()
536+ eventbox5.add(label5)
537+ table.attach(eventbox5,
538+ left_attach=0,
539+ right_attach=1,
540+ top_attach=1,
541+ bottom_attach=2,
542+ xoptions=gtk.FILL,
543+ yoptions=gtk.FILL,
544+ xpadding=0,
545+ ypadding=0)
546+
547+
548+ label6 = gtk.Label(_('Command:'))
549+ label6.set_alignment(0, 0.5)
550+ eventbox6 = gtk.EventBox()
551+ eventbox6.add(label6)
552+ table.attach(eventbox6,
553+ left_attach=0,
554+ right_attach=1,
555+ top_attach=2,
556+ bottom_attach=3,
557+ xoptions=gtk.FILL,
558+ yoptions=gtk.FILL,
559+ xpadding=0,
560+ ypadding=0)
561+
562+ label7 = gtk.Label(_('Target Environment:'))
563+ label7.set_alignment(0, 0.5)
564+ eventbox7 = gtk.EventBox()
565+ eventbox7.add(label7)
566+ table.attach(eventbox7,
567+ left_attach=0,
568+ right_attach=1,
569+ top_attach=3,
570+ bottom_attach=4,
571+ xoptions=gtk.FILL,
572+ yoptions=gtk.FILL,
573+ xpadding=0,
574+ ypadding=0)
575+
576+ self.txtGroup = gtk.Entry()
577+ table.attach(self.txtGroup,
578+ left_attach=1,
579+ right_attach=2,
580+ top_attach=0,
581+ bottom_attach=1,
582+ xoptions=gtk.FILL,
583+ yoptions=gtk.FILL,
584+ xpadding=0,
585+ ypadding=0)
586+
587+ self.txtName = gtk.Entry()
588 self.txtName.set_name('Name')
589- self.txtCommand = self.builder.get_object('txtGCommand')
590+ table.attach(self.txtName,
591+ left_attach=1,
592+ right_attach=2,
593+ top_attach=1,
594+ bottom_attach=2,
595+ xoptions=gtk.EXPAND | gtk.FILL,
596+ #yoptions=gtk.None,
597+ xpadding=0,
598+ ypadding=0)
599+
600+ hbox4 = gtk.HBox()
601+ self.txtCommand = gtk.Entry()
602 self.txtCommand.set_name('Exec')
603- self.cmbTargetEnvironment = self.builder.get_object('cmbTarget')
604+ self.cmdGRun = gtk.Button('...')
605+
606+ hbox4.pack_start(self.txtCommand, expand=True, fill=True, padding=0)
607+ hbox4.pack_start(self.cmdGRun, expand=False, fill=True, padding=0)
608+
609+ table.attach(hbox4,
610+ left_attach=1,
611+ right_attach=2,
612+ top_attach=2,
613+ bottom_attach=3,
614+ xoptions=gtk.EXPAND | gtk.FILL,
615+ yoptions=gtk.EXPAND | gtk.FILL,
616+ xpadding=0,
617+ ypadding=0)
618+
619+ self.cmbTargetEnvironment = gtk.ComboBox()
620 self.cmbTargetEnvironment.set_name('TargetEnvironment')
621-
622+
623 self.combo_model = gtk.ListStore(TYPE_STRING)
624 for target_key in ['Unity', 'Message Menu', 'Unity;Message Menu']:
625 self.combo_model.append([target_key])
626@@ -60,14 +180,22 @@
627 self.cmbTargetEnvironment.add_attribute(celltitle, 'text', 0)
628 self.cmbTargetEnvironment.set_model(self.combo_model)
629 self.cmbTargetEnvironment.set_active(0)
630-
631- self.txtName.connect('changed', self.on_change)
632- self.txtCommand.connect('changed', self.on_change)
633- self.builder.get_object('cmdGRun').connect(
634- 'clicked', self.open_executable)
635-
636- self.vbox.pack_start(self.add_group_panel, True, True, 0)
637-
638+
639+ table.attach(self.cmbTargetEnvironment,
640+ left_attach=1,
641+ right_attach=2,
642+ top_attach=3,
643+ bottom_attach=4,
644+ xoptions=gtk.EXPAND | gtk.FILL,
645+ yoptions=gtk.EXPAND | gtk.FILL,
646+ xpadding=0,
647+ ypadding=0)
648+
649+ align.add(table)
650+ frame4.add(align)
651+
652+ return frame4
653+
654 def populate(self, values):
655 try:
656 self.txtGroup.set_text(values['GroupName'])
657@@ -94,6 +222,7 @@
658 'TargetEnvironment': (
659 self.cmbTargetEnvironment.get_active_text()),
660 }
661+ print obj
662 if destroy:
663 self.destroy()
664 if resp == gtk.RESPONSE_OK:
665@@ -114,7 +243,3 @@
666 if response:
667 self.txtCommand.set_text(filename)
668
669-
670-if __name__ == "__main__":
671- dialog = GroupsDialog()
672- result, group = dialog.run()
673
674=== added directory 'unitylaunchereditor/locale'
675=== added directory 'unitylaunchereditor/locale/en'
676=== added file 'unitylaunchereditor/locale/unity-launcher-editor.pot'
677--- unitylaunchereditor/locale/unity-launcher-editor.pot 1970-01-01 00:00:00 +0000
678+++ unitylaunchereditor/locale/unity-launcher-editor.pot 2011-05-21 20:12:30 +0000
679@@ -0,0 +1,79 @@
680+# SOME DESCRIPTIVE TITLE.
681+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
682+# This file is distributed under the same license as the PACKAGE package.
683+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
684+#
685+#, fuzzy
686+msgid ""
687+msgstr ""
688+"Project-Id-Version: PACKAGE VERSION\n"
689+"Report-Msgid-Bugs-To: \n"
690+"POT-Creation-Date: 2011-05-15 00:23-0300\n"
691+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
692+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
693+"Language-Team: LANGUAGE <LL@li.org>\n"
694+"Language: \n"
695+"MIME-Version: 1.0\n"
696+"Content-Type: text/plain; charset=CHARSET\n"
697+"Content-Transfer-Encoding: 8bit\n"
698+
699+#: groupsdialog.py:29
700+msgid "Add Group..."
701+msgstr ""
702+
703+#: groupsdialog.py:41 mainwindow.py:48
704+#, python-format
705+msgid "Critical: couldn't find glade file: %s"
706+msgstr ""
707+
708+#: mainwindow.py:141
709+msgid "Save"
710+msgstr ""
711+
712+#: mainwindow.py:142
713+msgid "Save changes"
714+msgstr ""
715+
716+#: mainwindow.py:143
717+msgid "Do you want to save your changes?"
718+msgstr ""
719+
720+#: mainwindow.py:226 mainwindow.py:276 mainwindow.py:287
721+msgid "Remove"
722+msgstr ""
723+
724+#: mainwindow.py:227
725+msgid "Remove Group"
726+msgstr ""
727+
728+#: mainwindow.py:228
729+msgid "You are about to remove a Quick List Group, are you sure?"
730+msgstr ""
731+
732+#: mainwindow.py:277 mainwindow.py:288
733+msgid "Remove Launcher"
734+msgstr ""
735+
736+#: mainwindow.py:278
737+msgid "You are about to remove a Launcher item, are you sure?"
738+msgstr ""
739+
740+#: mainwindow.py:289
741+msgid "No launcher selected"
742+msgstr ""
743+
744+#: mainwindow.py:298
745+msgid "Add Launcher"
746+msgstr ""
747+
748+#: mainwindow.py:299
749+msgid "Add a new launcher..."
750+msgstr ""
751+
752+#: mainwindow.py:300
753+msgid "Type a launcher name to create a new launcher."
754+msgstr ""
755+
756+#: mainwindow.py:302
757+msgid "Name:"
758+msgstr ""
759
760=== modified file 'unitylaunchereditor/mainwindow.py'
761--- unitylaunchereditor/mainwindow.py 2011-05-13 18:18:55 +0000
762+++ unitylaunchereditor/mainwindow.py 2011-05-21 20:12:30 +0000
763@@ -21,15 +21,12 @@
764 import gobject
765 from pkg_resources import resource_filename
766 from desktop import DesktopParser
767-from os.path import basename, dirname, exists, expanduser, join
768+from os.path import basename, exists, expanduser, join
769 from utils import DialogType, FileChooser, get_icon, MessageBox, nullstring
770 from groupsdialog import GroupsDialog
771-
772-# Constants for column mapping
773-(COLUMN_ICON,
774- COLUMN_NAME,
775- COLUMN_DESKTOP,
776- COLUMN_PATH) = range(4)
777+from widgets.launcherview import LauncherView
778+from widgets.grouptree import GroupTree
779+from translation import _
780
781 #constantes for toolbar buttons
782 (TOOLBUTTON_ADD,
783@@ -40,51 +37,31 @@
784
785 builder = gtk.Builder()
786
787- def __init__(self, controller = None, glade_file="application.glade"):
788+ def __init__(self, controller=None, glade_file="application.glade"):
789 self.controller = controller
790 glade_path = resource_filename(__name__, join("data", glade_file))
791 try:
792 self.builder.add_from_file(glade_path)
793 except gobject.GError:
794 if not exists(glade_path):
795- print "Critical: couldn't find glade file: %s" % glade_path
796+ print _("Critical: couldn't find glade file: %s") % glade_path
797 raise
798 except Exception, exc:
799- print "Something else went wrong: %s" % exc
800+ print ("Something else went wrong: %s") % exc
801 raise
802
803 window_name = "window1"
804 self.window = self.builder.get_object(window_name)
805
806 # launcher Objects
807- self.listview_launcher = self.builder.get_object('ListViewLauncher')
808- self.LauncherModel = gtk.ListStore(Pixbuf, gobject.TYPE_STRING,
809- gobject.TYPE_PYOBJECT, gobject.TYPE_STRING)
810- render_pixbuf = gtk.CellRendererPixbuf()
811- render_text = gtk.CellRendererText()
812- col = gtk.TreeViewColumn()
813- col.pack_start(render_pixbuf, expand=False)
814- col.add_attribute(render_pixbuf, 'pixbuf', COLUMN_ICON)
815- col.pack_start(render_text, expand=True)
816- col.add_attribute(render_text, 'text', COLUMN_NAME)
817- self.listview_launcher.append_column(col)
818- self.listview_launcher.set_model(self.LauncherModel)
819-
820+ self.list_container = self.builder.get_object('list_container')
821+ self.listview_launcher = LauncherView()
822+ self.list_container.add_with_viewport(self.listview_launcher)
823 # groups objects
824- self.tvwGroups = self.builder.get_object('tvwGroups')
825- self.GroupsModel = gtk.TreeStore(gobject.TYPE_STRING,
826- gobject.TYPE_STRING)
827- col = gtk.TreeViewColumn('Quicklist Groups',
828- gtk.CellRendererText(), text=0)
829- self.tvwGroups.append_column(col)
830-
831- cell_renderer = gtk.CellRendererText();
832- #cell_renderer.set_property('editable', True);
833- col = gtk.TreeViewColumn('', cell_renderer, text=1);
834- self.tvwGroups.append_column(col)
835-
836- self.tvwGroups.set_model(self.GroupsModel)
837-
838+ self.group_container = self.builder.get_object('group_container')
839+ self.tvwGroups = GroupTree()
840+ self.group_container.add_with_viewport(self.tvwGroups)
841+
842 # info Widgets
843 self.imgIcon = self.builder.get_object('imgIcon')
844 self.txtName = self.builder.get_object('txtName')
845@@ -127,7 +104,7 @@
846 self.txtCommand.connect('focus-out-event', self.on_txt_focus_out)
847
848 #list group signals
849- self.tvwGroups.connect('cursor-changed', self.tvwgroups_row_change)
850+ self.tvwGroups.connect('selection-changed', self.on_tvwgroups_row_change)
851
852 #group signals
853 self.builder.get_object('btnAdd').connect('clicked', self.add_remove_group, TOOLBUTTON_ADD)
854@@ -141,44 +118,63 @@
855 file_name = basename(str_path)
856 str_path = '%s/.local/share/applications/%s' % (expanduser('~'),
857 file_name)
858-
859- #if not '/home' in str_path:
860- # str_path='%s.local/share/applications/%s' % (expanduser('~'),str_path)
861- # #str_path='%s/Desktop/applications/%s' % (expanduser('~'),str_path)
862- #else:
863- # file_name= basename(str_path)
864- # str_path='%s/Desktop/applications/%s' % (expanduser('~'),file_name)
865 return str_path
866
867+ def load_launcher_from_list(self, unity_items):
868+ self.listview_launcher.clear_list();
869+ for menu_item in unity_items:
870+ self.listview_launcher.add_row(menu_item)
871+
872+ self.listview_launcher.connect('selection-changed', self.listview_launcher_row_change)
873+ #make first row active
874+ self.listview_launcher.set_cursor((0,))
875+
876 def save_launchers(self, widget):
877- dialog = MessageBox( self.window,
878- window_title='Save' ,
879- action_text='Save changes',
880- message='Do you want to save your changes?',
881+ dialog = MessageBox(self.window,
882+ window_title=_('Save'),
883+ action_text=_('Save changes'),
884+ message=_('Do you want to save your changes?'),
885 dlg_type=DialogType.DIALOG_CONFIRMATION,
886 label_text=None
887 )
888 result, text = dialog.run()
889 if result:
890- for n in self.LauncherModel:
891- obj = n[COLUMN_DESKTOP]
892- fli = open(self.normalize_path( n[COLUMN_PATH]),'w')
893+ launchers = []
894+ for row in self.listview_launcher.get_rows():
895+ file_path = self.normalize_path(row["path"])
896+ fli = open(file_path, 'w')
897+
898+ obj = row["obj"]
899 obj.write(fli)
900 fli.close()
901- launchers = []
902- for launcher in self.LauncherModel:
903- launchers.append(self.normalize_path(launcher[COLUMN_PATH]))
904- if self.controller:
905- self.controller.save_unity_list(launchers)
906+ launchers.append(file_path)
907+
908+ if self.controller:
909+ self.controller.save_unity_list(launchers)
910+ MessageBox(self.window,
911+ window_title=_('Information'),
912+ action_text=_('Changes saved'),
913+ message=_('Your changes were successfuly saved.\n\n To apply the changes to your launcher you will need to <b>logout</b> and login again.'),
914+ dlg_type=DialogType.DIALOG_MESSAGE,
915+ label_text=None
916+ ).run()
917+ else:
918+ MessageBox(self.window,
919+ window_title=_('Error'),
920+ action_text=_('Changes not saved'),
921+ message=_("There's a problem with your application, \n controller not found."),
922+ dlg_type=DialogType.DIALOG_MESSAGE,
923+ label_text=None
924+ ).run()
925+
926
927 def chk_toggle(self, widget):
928 # only run when gaving the focus
929 # this will prevent execution when setting the value by code.
930
931 if widget.is_focus():
932+ objDesktop = self.listview_launcher.get_selected_desktop()
933 value = widget.get_active()
934- model, tree_iter = self.get_selected_launcher_row()
935- objDesktop = model[tree_iter][COLUMN_DESKTOP]
936 option = widget.get_name()
937 objDesktop.set(option, value)
938
939@@ -194,39 +190,36 @@
940 value = widget.get_text()
941
942 if ilength > 0:
943- model, tree_iter = self.get_selected_launcher_row()
944- objDesktop = model[tree_iter][COLUMN_DESKTOP]
945+ objDesktop = self.listview_launcher.get_selected_desktop()
946 option = widget.get_name()
947- if option == 'Name':
948- model[tree_iter][COLUMN_NAME] = value
949 objDesktop.set(option, value)
950+ if option == 'Name' or option == 'Comment':
951+ sname = objDesktop.get('Name')
952+ desc = objDesktop.get('Comment')
953+ self.listview_launcher.set_value('<b>%s</b>\n%s' % (sname, desc), self.listview_launcher.COLUMN_NAME)
954
955 def add_remove_group(self, widget, operation):
956- model, tree_iter = self.get_selected_launcher_row()
957- if not model:
958- return
959- objDesktop = model[tree_iter][COLUMN_DESKTOP]
960-
961+
962+ objDesktop = self.listview_launcher.get_selected_desktop()
963+
964 if operation == TOOLBUTTON_ADD:
965 #TODO : update ayatana entry
966- dialog = GroupsDialog()
967+
968+ dialog = GroupsDialog(parent=self.window)
969 result, group = dialog.run()
970 if result:
971- gModel = self.tvwGroups.get_model()
972- root = gModel.append(None, (group['GroupName'], ''))
973+ root = self.tvwGroups.add_root(group['GroupName'])
974
975 shortcut_group_name = "%s Shortcut Group" % group['GroupName']
976-
977- gModel.append(root, ('Name', group['Name']))
978- gModel.append(root, ('Exec', group['Exec']))
979- gModel.append(root, ('TargetEnvironment',
980- group['TargetEnvironment']))
981+ self.tvwGroups.add_root_row(root, 'Name', group['Name'])
982+ self.tvwGroups.add_root_row(root, 'Exec', group['Exec'])
983+ self.tvwGroups.add_root_row(root, 'TargetEnvironment', group['TargetEnvironment'])
984
985 items = objDesktop.get('X-Ayatana-Desktop-Shortcuts')
986 if items is None:
987 items = []
988 else:
989- items =[n for n in items if n != '']
990+ items = [n for n in items if n != '']
991 items.append(group['GroupName'])
992 objDesktop.set('X-Ayatana-Desktop-Shortcuts', items)
993
994@@ -234,106 +227,76 @@
995 objDesktop.set('Name', group['Name'] , None, shortcut_group_name)
996 objDesktop.set('Exec', group['Exec'] , None, shortcut_group_name)
997 objDesktop.set('TargetEnvironment', group['TargetEnvironment'] , None, shortcut_group_name)
998+ self.tvwGroups.expand(root, True)
999
1000
1001
1002 elif operation == TOOLBUTTON_REMOVE:
1003 dialog = MessageBox(self.window,
1004- window_title='Remove' ,
1005- action_text='Remove Group',
1006- message='You are about to remove a Quick List Group, are you sure?',
1007+ window_title=_('Remove') ,
1008+ action_text=_('Remove Group'),
1009+ message=_('You are about to remove a Quick List Group, are you sure?'),
1010 dlg_type=DialogType.DIALOG_CONFIRMATION,
1011 label_text=None
1012 )
1013 result = dialog.run()
1014
1015 if result[0]:
1016- selection = self.tvwGroups.get_selection()
1017- gModel, titer = selection.get_selected()
1018- root_iter = gModel.iter_parent(titer)
1019-
1020- if not root_iter:
1021- root_iter = titer
1022-
1023- shortcut_group_name = "%s Shortcut Group" % gModel.get_value(titer, 0)
1024- gModel.remove(root_iter)
1025+ root_iter = self.tvwGroups.get_selected_root()
1026+ group = self.tvwGroups.get_root_text()
1027+ shortcut_group_name = "%s Shortcut Group" % group
1028+
1029+ self.tvwGroups.remove_root(root_iter)
1030+
1031 items = objDesktop.get('X-Ayatana-Desktop-Shortcuts')
1032- items.remove(shortcut_group_name)
1033+ items.remove(group)
1034+ groups = [x for x in items if x != '']
1035 objDesktop.remove_section(shortcut_group_name)
1036- objDesktop.set('X-Ayatana-Desktop-Shortcuts',items)
1037+ objDesktop.set('X-Ayatana-Desktop-Shortcuts', groups)
1038
1039 elif operation == TOOLBUTTON_EDIT:
1040- selection = self.tvwGroups.get_selection()
1041- gModel, titer = selection.get_selected()
1042-
1043- root_iter = gModel.iter_parent(titer)
1044-
1045- if not root_iter:
1046- root_iter = titer
1047- count = gModel.iter_n_children(root_iter)
1048-
1049- shortcut_group_name = "%s Shortcut Group" % gModel.get_value(root_iter, 0)
1050-
1051- items = {'GroupName': gModel.get_value(root_iter, 0)}
1052-
1053- for n in range(count):
1054- it = gModel.iter_nth_child(root_iter, n)
1055- items[ gModel.get_value(it, 0)]= gModel.get_value(it, 1)
1056- dialog = GroupsDialog()
1057+ root_iter = self.tvwGroups.get_selected_root()
1058+
1059+ root_text = self.tvwGroups.get_root_text()
1060+
1061+ shortcut_group_name = "%s Shortcut Group" % root_text
1062+
1063+ items = self.tvwGroups.get_children_values(root_iter)
1064+
1065+ dialog = GroupsDialog(parent=self.window)
1066 dialog.populate(items)
1067 result, group = dialog.run()
1068-
1069+ print self.builder
1070 if result:
1071- #gModel.set(root_iter,0,group['Name'])
1072- it = gModel.iter_nth_child(root_iter, 0)
1073- gModel.set(it,1,group['Name'])
1074- it = gModel.iter_nth_child(root_iter, 1)
1075- gModel.set(it,1,group['Exec'])
1076- it = gModel.iter_nth_child(root_iter, 2)
1077- gModel.set(it,1,group['TargetEnvironment'])
1078+ self.tvwGroups.set_child_value(root_iter, 0, group['Name'])
1079+ self.tvwGroups.set_child_value(root_iter, 1, group['Exec'])
1080+ self.tvwGroups.set_child_value(root_iter, 2, group['TargetEnvironment'])
1081
1082 objDesktop.set('Name', group['Name'] , None, shortcut_group_name)
1083 objDesktop.set('Exec', group['Exec'] , None, shortcut_group_name)
1084- objDesktop.set('TargetEnvironment', group['TargetEnvironment'] , None,shortcut_group_name)
1085+ objDesktop.set('TargetEnvironment', group['TargetEnvironment'] , None, shortcut_group_name)
1086
1087
1088
1089 def remove_from_launcher(self, widget):
1090 """Signal handler for button to remoce an item from the Launcher List"""
1091
1092- model, tree_iter = self.get_selected_launcher_row()
1093- if tree_iter:
1094+ if self.listview_launcher.is_selected:
1095 dialog = MessageBox(self.window,
1096- window_title='Remove' ,
1097- action_text='Remove Launcher',
1098- message='You are about to remove a Launcher item, are you sure?',
1099+ window_title=_('Remove') ,
1100+ action_text=_('Remove Launcher'),
1101+ message=_('You are about to remove a Launcher item, are you sure?'),
1102 dlg_type=DialogType.DIALOG_CONFIRMATION,
1103 label_text=None
1104 )
1105 result, text = dialog.run()
1106 if result:
1107- #get the current index on the list
1108- indx = model.get_path(tree_iter)[0]
1109- model.remove(tree_iter)
1110- # try to select the previous item in the list
1111- #or the next if the list still having data
1112- icount = len(model)
1113- print indx, icount
1114-
1115- if indx == icount and icount > 0:
1116- print 'indx-1'
1117- self.listview_launcher.set_cursor((indx - 1,))
1118- elif indx < icount and icount > 0:
1119- print 'indx'
1120- self.listview_launcher.set_cursor((indx,))
1121- else:
1122- print 'indx+1'
1123- self.listview_launcher.set_cursor((indx + 1,))
1124+ self.listview_launcher.remove_current_row()
1125
1126 else:
1127- MessageBox(self.window,window_title='Remove' ,
1128- action_text='Remove Launcher',
1129- message='No launcher selected',
1130+ MessageBox(self.window, window_title=_('Remove') ,
1131+ action_text=_('Remove Launcher'),
1132+ message=_('No launcher selected'),
1133 dlg_type=DialogType.DIALOG_CONFIRMATION,
1134 label_text=None
1135 ).run()
1136@@ -342,33 +305,31 @@
1137 """Signal handler for button to add a new item into the Launcher List"""
1138
1139 dialog = MessageBox(self.window,
1140- window_title='Add Launcher' ,
1141- action_text='Add a new launcher...' ,
1142- message='Type a launcher name to create a new launcher.',
1143+ window_title=_('Add Launcher') ,
1144+ action_text=_('Add a new launcher...') ,
1145+ message=_('Type a launcher name to create a new launcher.'),
1146 dlg_type=DialogType.DIALOG_INPUT,
1147- label_text='Name:'
1148+ label_text=_('Name:')
1149 )
1150
1151 result, text = dialog.run()
1152- print result, text
1153+
1154 if result and len(text) > 0:
1155 desktop_parser = DesktopParser()
1156 desktop_parser.set('Name', text)
1157 desktop_parser.set('Terminal', False)
1158- path = join(expanduser('~/.local/share/applications/'),
1159+ desktop_parser.set('Icon', 'wft')
1160+ path_name = join(expanduser('~/.local/share/applications/'),
1161 '%s.desktop' % text)
1162- tree_iter = self.LauncherModel.append((get_icon('wft'), text, desktop_parser,
1163- path))
1164- #selects the inserted row
1165- self.listview_launcher.set_cursor(self.LauncherModel.get_path(tree_iter))
1166+ row_iter = self.listview_launcher.add_row(path_name, True, desktop_parser)
1167+ return row_iter
1168
1169 def open_executable(self, widget):
1170 dialog = FileChooser()
1171 response, filename = dialog.run()
1172 if response:
1173 self.txtCommand.set_text(filename)
1174- model, tree_iter = self.get_selected_launcher_row()
1175- objDesktop = model[tree_iter][COLUMN_DESKTOP]
1176+ objDesktop = self.listview_launcher.get_selected_desktop()
1177 objDesktop.set(self.txtCommand.get_name(), filename)
1178
1179
1180@@ -395,62 +356,49 @@
1181 self.imgIcon.set_from_pixbuf(pixbuf)
1182 # TODO: add code to write changes here
1183 # the best way is to put an apply button?
1184- model, tree_iter = self.get_selected_launcher_row()
1185- objDesktop = model[tree_iter][COLUMN_DESKTOP]
1186- model[tree_iter][COLUMN_ICON] = pixbuf
1187+ objDesktop = self.listview_launcher.get_selected_desktop()
1188 objDesktop.set('Icon', filename)
1189-
1190- def get_selected_launcher_row(self):
1191- selection = self.listview_launcher.get_selection()
1192- return selection.get_selected()
1193+ self.listview_launcher.set_value(pixbuf, self.listview_launcher.COLUMN_ICON)
1194
1195- def listview_launcher_row_change(self, data=None):
1196+ def listview_launcher_row_change(self, widget, model, row_iter, objDesktop):
1197
1198 #disable groups toobar buttons
1199 self.btnEdit.set_sensitive(False)
1200 self.btnRemove.set_sensitive(False)
1201
1202- model, tree_iter = self.get_selected_launcher_row()
1203-
1204- objDesktop = model[tree_iter][COLUMN_DESKTOP]
1205-
1206 # show properties
1207- self.imgIcon.set_from_pixbuf(model[tree_iter][COLUMN_ICON])
1208+ self.imgIcon.set_from_pixbuf(widget.get_selected_icon())
1209
1210 self.txtName.set_text(nullstring(objDesktop.get('Name')))
1211 self.txtComment.get_buffer().set_text(
1212 nullstring(objDesktop.get('Comment')))
1213 self.txtCommand.set_text(nullstring(objDesktop.get('Exec')))
1214- self.chkTerminal.set_active(objDesktop.get('Terminal'))
1215+
1216+ checked = objDesktop.get('Terminal')
1217+ if not checked:
1218+ checked = False
1219+
1220+ self.chkTerminal.set_active(checked)
1221
1222 items = objDesktop.get('X-Ayatana-Desktop-Shortcuts')
1223
1224- gModel = self.tvwGroups.get_model()
1225- gModel.clear()
1226+ self.tvwGroups.clear()
1227
1228 if items:
1229- if isinstance(items,str):
1230- items=[items]
1231+ if isinstance(items, str):
1232+ items = [items]
1233
1234 for group in items:
1235 if group != '':
1236- root = gModel.append(None, (group, ''))
1237+ root = self.tvwGroups.add_root(group)
1238 for key in ('Name', 'Exec', 'TargetEnvironment'):
1239- opt = objDesktop.get(key, "%s Shortcut Group" % group)
1240- if opt:
1241- gModel.append(root, (key, opt))
1242+ value = objDesktop.get(key, "%s Shortcut Group" % group)
1243+ if value:
1244+ self.tvwGroups.add_root_row(root, key, value)
1245+ self.tvwGroups.expand_all()
1246+
1247
1248- def tvwgroups_row_change(self, data=None):
1249- selection = self.tvwGroups.get_selection()
1250- gModel, titer = selection.get_selected()
1251-
1252- if not gModel or not titer:
1253- return
1254-
1255- root_iter = gModel.iter_parent(titer)
1256-
1257- if not root_iter:
1258- root_iter = titer
1259+ def on_tvwgroups_row_change(self, widget, root_iter):
1260 if root_iter:
1261 self.btnEdit.set_sensitive(True)
1262 self.btnRemove.set_sensitive(True)
1263
1264=== modified file 'unitylaunchereditor/newlauncher.py'
1265--- unitylaunchereditor/newlauncher.py 2011-05-12 20:23:39 +0000
1266+++ unitylaunchereditor/newlauncher.py 2011-05-21 20:12:30 +0000
1267@@ -22,26 +22,28 @@
1268 from desktop import DesktopParser
1269 from os.path import exists, expanduser, isdir, isfile, join
1270 from xdg import BaseDirectory
1271+from pkg_resources import resource_filename
1272 from utils import DialogType, FileChooser, get_icon, MessageBox, nullstring
1273 # Constants for column mapping
1274 (COLUMN_ICON,
1275 COLUMN_NAME,
1276 COLUMN_DESKTOP,
1277 COLUMN_PATH,
1278- COLUMN_COMMENT) = range(5)
1279+ COLUMN_COMMENT,
1280+ COLUMN_SORT) = range(6)
1281
1282 class AddLauncherDialog(gtk.Dialog):
1283 """XXX: add docs."""
1284 def __init__(self, title='Add Launcher...'):
1285 super(AddLauncherDialog, self).__init__(title,
1286- None, (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT |
1287+ None, (gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT |
1288 gtk.DIALOG_NO_SEPARATOR),
1289 (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
1290
1291 glade_file = "application.glade"
1292 self.builder = gtk.Builder()
1293-
1294- glade_path = join(expanduser("~/Desktop/unity-launcher-editor/data"), glade_file)
1295+ glade_path = resource_filename(__name__, join("data", glade_file))
1296+ #glade_path = join(expanduser("~/Desktop/unity-launcher-editor/data"), glade_file)
1297 if not exists(glade_path):
1298 raise Exception("Critical: couldn't find glade file: %s" % glade_path)
1299 self.builder.add_from_file(glade_path)
1300@@ -53,12 +55,12 @@
1301 self.set_alternative_button_order(
1302 [gtk.RESPONSE_CANCEL, gtk.RESPONSE_OK])
1303
1304- self.lvwAddLaunchers =self.builder.get_object('lvwAddLaunchers')
1305- self.txtSearch = self.builder.get_object('entry2')
1306- self.txtSearch.connect("icon-press", lambda x,y,z : self.filter.refilter())
1307+ self.lvwAddLaunchers = self.builder.get_object('lvwAddLaunchers')
1308+ self.txtSearch = self.builder.get_object('entry2')
1309+ self.txtSearch.connect("icon-press", lambda x, y, z : self.filter.refilter())
1310
1311 self.listmodel = gtk.ListStore(gtk.gdk.Pixbuf, gobject.TYPE_STRING,
1312- gobject.TYPE_PYOBJECT, gobject.TYPE_STRING, gobject.TYPE_STRING)
1313+ gobject.TYPE_PYOBJECT, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING)
1314
1315 self.filter = self.listmodel.filter_new()
1316 self.filter.set_visible_func(self.match_type)
1317@@ -68,7 +70,6 @@
1318
1319 col = gtk.TreeViewColumn()
1320
1321- col.set_sort_column_id(COLUMN_NAME)
1322 col.pack_start(render_pixbuf, expand=False)
1323 col.add_attribute(render_pixbuf, 'pixbuf', COLUMN_ICON)
1324 col.pack_start(render_text, expand=True)
1325@@ -82,9 +83,9 @@
1326 self.lvwAddLaunchers.append_column(col)
1327 self.lvwAddLaunchers.set_model(self.sorter)
1328 #self.lvwAddLaunchers.set_search_entry(self.txtSearch);
1329- apps_list=[]
1330+ apps_list = []
1331 for n in ['/usr/share/']:#BaseDirectory.xdg_data_dirs:
1332- desktop_dir = '%sapplications' %n
1333+ desktop_dir = '%sapplications' % n
1334
1335 for launcher_location in glob.glob('%s/*.desktop' % desktop_dir):
1336 # blacklist ubiquity as will have two ubiquity in the netbook live session then
1337@@ -92,12 +93,14 @@
1338 apps_list.append(launcher_location) #= self.register_new_app(launcher_location, apps_list)
1339 apps_list.sort()
1340 self.populate(apps_list)
1341+ self.listmodel.set_sort_column_id(COLUMN_SORT,gtk.SORT_ASCENDING)
1342 self.vbox.pack_start(self.add_panel, True, True, 0)
1343+
1344
1345 def match_type(self, model, iter):
1346 value = model.get_value(iter, COLUMN_DESKTOP)
1347
1348- if self.txtSearch.get_text_length()==0:
1349+ if self.txtSearch.get_text_length() == 0:
1350 return True
1351 if self.txtSearch.get_text().lower() in value.get("Name").lower():
1352 return True
1353@@ -105,7 +108,7 @@
1354 return False
1355
1356 def populate(self, values):
1357- var=[]
1358+ var = []
1359 for menu_item in values:
1360 print menu_item
1361 desktop_parser = DesktopParser(menu_item)
1362@@ -116,15 +119,16 @@
1363 if sname is None:
1364 sname = desktop_parser.get('Name', 'en')
1365 if icon is None:
1366- pix = get_icon('image-missing',32)
1367+ pix = get_icon('image-missing', 16)
1368 else:
1369- pix = get_icon(icon,32)
1370- var.append(('%s' % sname,pix,desktop_parser, menu_item, comm))
1371+ pix = get_icon(icon, 16)
1372+ var.append(('%s' % sname, pix, desktop_parser, menu_item, comm,sname.upper()))
1373
1374 #self.listmodel.append((pix, '%s' % sname, desktop_parser, menu_item))
1375- var.sort()
1376- for sname, pix, desktop_parser, menu_item, comm in var:
1377- self.listmodel.append((pix, '%s' % sname, desktop_parser, menu_item, comm))
1378+ #var.sort()
1379+
1380+ for sname, pix, desktop_parser, menu_item, comm, ssort in var:
1381+ self.listmodel.append((pix, '%s' % sname, desktop_parser, menu_item, comm,ssort.upper()))
1382 #self.main_window.listview_launcher.set_model(store)
1383
1384 def get_desktop_dir(self):
1385
1386=== added file 'unitylaunchereditor/translation.py'
1387--- unitylaunchereditor/translation.py 1970-01-01 00:00:00 +0000
1388+++ unitylaunchereditor/translation.py 2011-05-21 20:12:30 +0000
1389@@ -0,0 +1,28 @@
1390+# -*- coding: utf-8 -*-
1391+#####################################################################
1392+# Laudeci Oliveira <laudeci@ubuntu.com>
1393+# Ursula Junque <ursinha@ubuntu.com>
1394+#
1395+# Copyright 2011 unity-launcher-editor-dev.
1396+#
1397+# This program is free software; you can redistribute it and/or modify
1398+# it under the terms of the GNU General Public License as published
1399+# by the Free Software Foundation; version 3 only.
1400+#
1401+# This program is distributed in the hope that it will be useful,
1402+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1403+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1404+# GNU General Public License for more details.
1405+#
1406+#####################################################################
1407+
1408+APP = 'unity-launcher-editor'
1409+DIR = 'locale'
1410+
1411+import locale
1412+import gettext
1413+
1414+locale.setlocale(locale.LC_ALL, '')
1415+gettext.bindtextdomain(APP, DIR)
1416+gettext.textdomain(APP)
1417+_ = gettext.gettext
1418
1419=== modified file 'unitylaunchereditor/utils.py'
1420--- unitylaunchereditor/utils.py 2011-05-13 18:18:55 +0000
1421+++ unitylaunchereditor/utils.py 2011-05-21 20:12:30 +0000
1422@@ -88,7 +88,7 @@
1423 return False, None
1424
1425 class MessageBox(gtk.MessageDialog):
1426- def __init__(self,parent,
1427+ def __init__(self, parent,
1428 window_title,
1429 action_text,
1430 message,
1431
1432=== added directory 'unitylaunchereditor/widgets'
1433=== added file 'unitylaunchereditor/widgets/__init__.py'
1434--- unitylaunchereditor/widgets/__init__.py 1970-01-01 00:00:00 +0000
1435+++ unitylaunchereditor/widgets/__init__.py 2011-05-21 20:12:30 +0000
1436@@ -0,0 +1,1 @@
1437+
1438
1439=== added file 'unitylaunchereditor/widgets/grouptree.py'
1440--- unitylaunchereditor/widgets/grouptree.py 1970-01-01 00:00:00 +0000
1441+++ unitylaunchereditor/widgets/grouptree.py 2011-05-21 20:12:30 +0000
1442@@ -0,0 +1,133 @@
1443+# -*- coding: utf-8 -*-
1444+#####################################################################
1445+# Laudeci Oliveira <laudeci@ubuntu.com>
1446+# Ursula Junque <ursinha@ubuntu.com>
1447+#
1448+# Copyright 2011 unity-launcher-editor-dev.
1449+#
1450+# This program is free software; you can redistribute it and/or modify
1451+# it under the terms of the GNU General Public License as published
1452+# by the Free Software Foundation; version 3 only.
1453+#
1454+# This program is distributed in the hope that it will be useful,
1455+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1456+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1457+# GNU General Public License for more details.
1458+#
1459+#####################################################################
1460+
1461+import gtk
1462+from gtk.gdk import Pixbuf
1463+import gobject
1464+import pango
1465+from re import sub
1466+
1467+class GroupTree(gtk.TreeView):
1468+
1469+ __gsignals__ = {
1470+ "selection-changed" : (gobject.SIGNAL_RUN_LAST,
1471+ gobject.TYPE_NONE,
1472+ (gobject.TYPE_PYOBJECT,)),
1473+
1474+ }
1475+
1476+ def __init__(self):
1477+ super(GroupTree, self).__init__()
1478+ self.set_headers_visible(False)
1479+ self._setup_columns()
1480+ self._setup_model()
1481+
1482+ self.connect('cursor-changed', self._on_row_change)
1483+
1484+
1485+
1486+ def _setup_columns(self):
1487+
1488+ render = gtk.CellRendererText()
1489+
1490+ column = gtk.TreeViewColumn()
1491+ column.pack_start(render, expand=True)
1492+ column.add_attribute(render, 'markup', 0)
1493+ self.append_column(column)
1494+
1495+ cell_renderer = gtk.CellRendererText();
1496+ col = gtk.TreeViewColumn('', cell_renderer, text=1);
1497+ self.append_column(col)
1498+
1499+ def _setup_model(self):
1500+ model = gtk.TreeStore(gobject.TYPE_STRING,
1501+ gobject.TYPE_STRING)
1502+
1503+ old_model = self.get_model()
1504+
1505+ if old_model:
1506+ del old_model
1507+ self.set_model(model)
1508+
1509+ def get_selected_root(self):
1510+ selection = self.get_selection()
1511+ gModel, titer = selection.get_selected()
1512+ root_iter = gModel.iter_parent(titer)
1513+
1514+ if not root_iter:
1515+ root_iter = titer
1516+
1517+ return root_iter
1518+
1519+ def get_children_values(self, root_iter):
1520+ model = self.get_model()
1521+ items = {'GroupName': self.get_root_text()}
1522+ items_count = model.iter_n_children(root_iter)
1523+
1524+ for indx in range(items_count):
1525+ it = model.iter_nth_child(root_iter, indx)
1526+ items[ model.get_value(it, 0)] = model.get_value(it, 1)
1527+ return items
1528+ def expand(self, root_iter, select=False):
1529+ model = self.get_model()
1530+ path = model.get_path(root_iter)
1531+ self.expand_row(path, False)
1532+ if select:
1533+ self.set_cursor(path)
1534+
1535+ def set_child_value(self, root_iter, indx, value):
1536+ model = self.get_model()
1537+
1538+ it = model.iter_nth_child(root_iter, indx)
1539+ model.set(it, 1, value)
1540+
1541+ def get_root_text(self):
1542+ root_iter = self.get_selected_root()
1543+ text = self.get_model().get_value(root_iter, 0)
1544+ text = sub('<.*?>', '', text)
1545+ return text
1546+
1547+ def _on_row_change(self, data=None):
1548+ try:
1549+ root_iter = self.get_selected_root()
1550+ except:
1551+ root_iter = None
1552+
1553+ self.emit("selection-changed", root_iter)
1554+
1555+ def add_root_row(self, root, column, value):
1556+ model = self.get_model()
1557+
1558+ new_row = model.append(root, (column, value))
1559+
1560+ return new_row
1561+
1562+ def add_root(self, group_name):
1563+ model = self.get_model()
1564+
1565+ new_root = model.append(None, ("<b>%s</b>" % group_name, ''))
1566+
1567+ return new_root
1568+
1569+ def clear(self):
1570+ self.get_model().clear()
1571+
1572+ def remove_root(self, root):
1573+ model = self.get_model()
1574+ model.remove(root)
1575+
1576
1577=== added file 'unitylaunchereditor/widgets/launcherview.py'
1578--- unitylaunchereditor/widgets/launcherview.py 1970-01-01 00:00:00 +0000
1579+++ unitylaunchereditor/widgets/launcherview.py 2011-05-21 20:12:30 +0000
1580@@ -0,0 +1,196 @@
1581+# -*- coding: utf-8 -*-
1582+#####################################################################
1583+# Laudeci Oliveira <laudeci@ubuntu.com>
1584+# Ursula Junque <ursinha@ubuntu.com>
1585+#
1586+# Copyright 2011 unity-launcher-editor-dev.
1587+#
1588+# This program is free software; you can redistribute it and/or modify
1589+# it under the terms of the GNU General Public License as published
1590+# by the Free Software Foundation; version 3 only.
1591+#
1592+# This program is distributed in the hope that it will be useful,
1593+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1594+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1595+# GNU General Public License for more details.
1596+#
1597+#####################################################################
1598+
1599+import gtk
1600+from gtk.gdk import Pixbuf
1601+import gobject
1602+import pango
1603+
1604+from desktop import DesktopParser
1605+from utils import get_icon
1606+
1607+class LauncherView(gtk.TreeView):
1608+ __gsignals__ = {
1609+ "selection-changed" : (gobject.SIGNAL_RUN_LAST,
1610+ gobject.TYPE_NONE,
1611+ (gobject.TYPE_PYOBJECT,
1612+ gobject.TYPE_PYOBJECT,
1613+ gobject.TYPE_PYOBJECT),),
1614+
1615+ }
1616+ # Constants for column mapping
1617+ (COLUMN_ICON, COLUMN_NAME, COLUMN_DESKTOP, COLUMN_PATH) = range(4)
1618+
1619+ def __init__(self):
1620+ super(LauncherView, self).__init__()
1621+ self.set_headers_visible(False)
1622+ self.set_reorderable(True)
1623+ #self.set_rules_hint(True)
1624+ self.get_selection().set_mode(gtk.SELECTION_SINGLE)
1625+
1626+ self._setup_columns()
1627+ self._setup_model()
1628+
1629+ # assign the tooltip
1630+ self.set_has_tooltip(True)
1631+ self.connect("query-tooltip", self._ViewTooltip)
1632+ #self.set_events(gtk.gdk.POINTER_MOTION_MASK)
1633+
1634+ self.connect('cursor-changed', self._on_row_change)
1635+
1636+ def _setup_columns(self):
1637+ #this renderer will show application icon
1638+ render_pixbuf = gtk.CellRendererPixbuf()
1639+
1640+ #this will show application text
1641+ #using 2 lines, one for application name and other for description
1642+ #or command
1643+ render_text = gtk.CellRendererText()
1644+ render_text.set_property("ellipsize", pango.ELLIPSIZE_END)
1645+
1646+
1647+ column = gtk.TreeViewColumn()
1648+ column.pack_start(render_pixbuf, expand=False)
1649+ column.add_attribute(render_pixbuf, 'pixbuf', self.COLUMN_ICON)
1650+ column.pack_start(render_text, expand=True)
1651+ column.add_attribute(render_text, 'markup', self.COLUMN_NAME)
1652+ self.append_column(column)
1653+
1654+ def _setup_model(self):
1655+ model = gtk.ListStore(Pixbuf,
1656+ gobject.TYPE_STRING,
1657+ gobject.TYPE_PYOBJECT,
1658+ gobject.TYPE_STRING)
1659+
1660+ old_model = self.get_model()
1661+
1662+ if old_model:
1663+ del old_model
1664+ self.set_model(model)
1665+
1666+ def _ViewTooltip(self, widget, x, y, keyboard_mode, tooltip):
1667+ try:
1668+ (path, col, x, y) = widget.get_path_at_pos(int(x), int(y))
1669+ it = widget.get_model().get_iter(path)
1670+ value = widget.get_model().get_value(it, self.COLUMN_NAME)
1671+ value += "\n%s" % widget.get_model().get_value(it, self.COLUMN_PATH)
1672+ pix = widget.get_model().get_value(it, self.COLUMN_ICON)
1673+ tooltip.set_icon(pix)
1674+ tooltip.set_markup(value)
1675+ except Exception, e:
1676+ tooltip.set_text(str(e))
1677+
1678+
1679+ return True
1680+
1681+ def _on_row_change(self, data=None):
1682+
1683+ selection = self.get_selection()
1684+ model, row_iter = selection.get_selected()
1685+
1686+ objDesktop = model[row_iter][self.COLUMN_DESKTOP]
1687+ self.emit("selection-changed", model, row_iter, objDesktop)
1688+
1689+ def clear_list(self):
1690+ model = self.get_model()
1691+ if model:
1692+ model.clear()
1693+ def get_selected_row(self):
1694+ selection = self.get_selection()
1695+ return selection.get_selected()
1696+
1697+ def get_rows(self):
1698+ desktops = []
1699+ for row_iter in self.get_model():
1700+ desktops.append({
1701+ "icon": row_iter[self.COLUMN_ICON],
1702+ "path": row_iter[self.COLUMN_PATH],
1703+ "obj": row_iter[self.COLUMN_DESKTOP]
1704+ })
1705+
1706+ return desktops
1707+
1708+ def get_selected_desktop(self):
1709+ selection = self.get_selection()
1710+ model, row_iter = selection.get_selected()
1711+
1712+ return model[row_iter][self.COLUMN_DESKTOP]
1713+
1714+ def get_selected_icon(self):
1715+ selection = self.get_selection()
1716+ model, row_iter = selection.get_selected()
1717+
1718+ return model[row_iter][self.COLUMN_ICON]
1719+
1720+ def set_value(self, value, column):
1721+ selection = self.get_selection()
1722+ model, row_iter = selection.get_selected()
1723+
1724+ model[row_iter][column] = value
1725+
1726+ @property
1727+ def is_selected(self):
1728+ selection = self.get_selection()
1729+ model, row_iter = selection.get_selected()
1730+
1731+ return (not row_iter is None)
1732+
1733+ def remove_current_row(self):
1734+ selection = self.get_selection()
1735+ model, row_iter = selection.get_selected()
1736+
1737+ indx = model.get_path(row_iter)[0]
1738+ model.remove(row_iter)
1739+
1740+ icount = len(model)
1741+
1742+ if indx == icount and icount > 0:
1743+ self.set_cursor((indx - 1,))
1744+ elif indx < icount and icount > 0:
1745+ self.set_cursor((indx,))
1746+ else:
1747+ self.set_cursor((indx + 1,))
1748+
1749+ def set_selected_iter(self, row):
1750+ self.set_cursor(self.get_model().get_path(row))
1751+
1752+ def add_row(self, path_name, selected=False, desktop_parser=None):
1753+ if not desktop_parser:
1754+ desktop_parser = DesktopParser(path_name)
1755+ desktop_parser.update_keys()
1756+
1757+ sname = desktop_parser.get('Name')
1758+ icon = desktop_parser.get('Icon')
1759+ desc = desktop_parser.get('Comment')
1760+ if sname is None:
1761+ sname = desktop_parser.get('Name', 'en')
1762+ if icon is None:
1763+ pix = None
1764+ else:
1765+ pix = get_icon(icon)
1766+
1767+ model = self.get_model()
1768+ new_iter = model.append((pix, '<b>%s</b>\n%s' % (sname, desc), desktop_parser, path_name))
1769+
1770+ if selected:
1771+ self.set_cursor(self.get_model().get_path(new_iter))
1772+
1773+ return new_iter
1774+
1775+if __name__ == "__main__":
1776+ x = LauncherView()

Subscribers

People subscribed via source and target branches