Merge lp:~pitti/computer-janitor/pygi into lp:computer-janitor

Proposed by Martin Pitt on 2011-01-19
Status: Merged
Approved by: Barry Warsaw on 2011-02-16
Approved revision: 257
Merged at revision: 254
Proposed branch: lp:~pitti/computer-janitor/pygi
Merge into: lp:computer-janitor
Diff against target: 365 lines (+74/-51) 7 files modified
To merge this branch: bzr merge lp:~pitti/computer-janitor/pygi
Reviewer Review Type Date Requested Status
Barry Warsaw 2011-01-19 Approve on 2011-02-16
Martin Pitt Resubmit on 2011-02-16
Review via email: mp+46779@code.launchpad.net

Description of the Change

This branch ports from pygtk to pygi. With GTK3 it works perfectly, with GTK2 we have to disable the "select all/none" right-click popup menu, but I think we can live with that (see changelog and code comment for details).

Note that I had to fix some stuff in pygobject for this, so I bumped the dependency to a not-yet-released version. I'll upload a new git snapshot of pygobject to natty soon, but for now if you want to play with this, do

  git clone git://git.gnome.org/pygobject
  ./autogen.sh && make
  export PYTHONPATH=`pwd`:$PYTHONPATH

and then run "./run_from_checkout.sh" in the computer-janitor branch.

I think it should work with the current gtk2 that we have in Natty (I tested it), but I also did a lot of fixes there recently for porting other software. So please let me know if you get crashes or malfunctions.

To post a comment you must log in.
Martin Pitt (pitti) wrote :

Note that I just uploaded a recent git snapshot of pygobject into natty, which now works with this branch. We also have the hot and fresh gtk 2.24.0 release with lots of annotation fixes, so this branch works fine on current natty now.

Barry Warsaw (barry) wrote :

Thanks Martin! I'll give it another try tomorrow.

lp:~pitti/computer-janitor/pygi updated on 2011-02-16
257. By Martin Pitt on 2011-02-16

merge with trunk

Martin Pitt (pitti) wrote :

I merged my branch with trunk for yesterday's upload, and ported the new bits.

review: Resubmit
Barry Warsaw (barry) wrote :

Thanks Martin, this looks really good. I'm going to go ahead and merge it, with a few minor changes (which I'll make after the merge):

* Bump version number to 2.1
* Update copyright years
* Tweak a few Python style things
* Use logging instead of stderr for the popup message

On the latter, what do you think about adding an Edit menu that has the following items:

Select all
Select all packages
Select all other
---
Unselect all
Unselect all packages
Unselect all other

That would at least provide the missing functionality elsewhere, and we could even keep that when using gtk3.

review: Approve
Martin Pitt (pitti) wrote :

Thanks Barry! An Edit menu sounds fine to me, and it's also more obvious than the right click menu. But in the next Ubuntu release we'll have GTK 3, and thus can have the menu back.

Preview Diff

1=== modified file 'computerjanitorapp/gtk/dialogs.py'
2--- computerjanitorapp/gtk/dialogs.py 2011-02-15 22:24:27 +0000
3+++ computerjanitorapp/gtk/dialogs.py 2011-02-16 13:45:44 +0000
4@@ -23,7 +23,7 @@
5 ]
6
7
8-import gtk
9+from gi.repository import Gtk
10
11 from operator import mod as interpolate
12
13@@ -71,15 +71,15 @@
14 if ok_button is None:
15 # The user de-selected all cruft from the ui, so there's actually
16 # nothing to clean up.
17- dialog = gtk.MessageDialog(
18+ dialog = Gtk.MessageDialog(
19 parent=self._ui.widgets['window'],
20- type=gtk.MESSAGE_WARNING,
21- buttons=gtk.BUTTONS_NONE,
22+ type=Gtk.MessageType.WARNING,
23+ buttons=Gtk.ButtonsType.NONE,
24 message_format=_('There is nothing to clean up'),
25 )
26 dialog.set_title(_('Clean up'))
27 dialog.format_secondary_markup(message)
28- dialog.add_button(_('Ok'), gtk.RESPONSE_YES)
29+ dialog.add_button(_('Ok'), Gtk.ResponseType.YES)
30 dialog.show_all()
31 dialog.run()
32 dialog.hide()
33@@ -88,20 +88,20 @@
34 # but that would require a richer interface to the dbus service,
35 # and probably to the cruft plugin architecture underneath that.
36 message = _('Are you sure you want to clean your system?')
37- dialog = gtk.MessageDialog(
38+ dialog = Gtk.MessageDialog(
39 parent=self._ui.widgets['window'],
40- type=gtk.MESSAGE_WARNING,
41- buttons=gtk.BUTTONS_NONE,
42+ type=Gtk.MessageType.WARNING,
43+ buttons=Gtk.ButtonsType.NONE,
44 message_format=message)
45 dialog.set_title(_('Clean up'))
46 dialog.format_secondary_markup(message)
47- dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CLOSE)
48- dialog.add_button(ok_button, gtk.RESPONSE_YES)
49+ dialog.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CLOSE)
50+ dialog.add_button(ok_button, Gtk.ResponseType.YES)
51 # Show the dialog and get the user's response.
52 dialog.show_all()
53 response = dialog.run()
54 dialog.hide()
55- return response == gtk.RESPONSE_YES
56+ return response == Gtk.ResponseType.YES
57
58
59 class CleanupProblem(DialogBase):
60@@ -116,10 +116,10 @@
61 message = _('System clean up could not complete. '
62 'Be sure no other package manager such as Synaptic or '
63 'Update Manager is running.')
64- dialog = gtk.MessageDialog(
65+ dialog = Gtk.MessageDialog(
66 parent=self._ui.widgets['window'],
67- type=gtk.MESSAGE_ERROR,
68- buttons=gtk.BUTTONS_OK,
69+ type=Gtk.MessageType.ERROR,
70+ buttons=Gtk.ButtonsType.OK,
71 message_format=message)
72 dialog.set_title(_('System clean up failure'))
73 dialog.show_all()
74
75=== modified file 'computerjanitorapp/gtk/store.py'
76--- computerjanitorapp/gtk/store.py 2010-03-22 18:17:11 +0000
77+++ computerjanitorapp/gtk/store.py 2011-02-16 13:45:44 +0000
78@@ -24,7 +24,7 @@
79 ]
80
81
82-import gtk
83+from gi.repository import Gtk
84 import gobject
85
86
87@@ -49,7 +49,7 @@
88
89
90 class Store:
91- """The higher level wrapper around the gtk.ListStore."""
92+ """The higher level wrapper around the Gtk.ListStore."""
93
94 def __init__(self, janitord):
95 """Create the Store.
96@@ -63,7 +63,7 @@
97 # of cruft. See ListStoreColumns for details.
98 #
99 # XXX 2010-03-04 barry: pygtk does not like 'unicode'.
100- self.store = gtk.ListStore(str, str, str, bool, bool, bool, bool, bool)
101+ self.store = Gtk.ListStore(str, str, str, bool, bool, bool, bool, bool)
102
103 def find_cruft(self):
104 """Find cruft and populate the backing store.
105@@ -139,7 +139,7 @@
106
107 # Filter functions for use with TreeView column display.
108
109-def unused(store, iter):
110+def unused(store, iter, data):
111 """True if the cruft is not being ignored and is package cruft.
112
113 :param store: The ListStore instance.
114@@ -150,7 +150,7 @@
115 return show and is_package_cruft
116
117
118-def optimize(store, iter):
119+def optimize(store, iter, data):
120 """True if the cruft is not package cruft.
121
122 :param store: The ListStore instance.
123
124=== modified file 'computerjanitorapp/gtk/ui.py'
125--- computerjanitorapp/gtk/ui.py 2010-08-23 13:56:29 +0000
126+++ computerjanitorapp/gtk/ui.py 2011-02-16 13:45:44 +0000
127@@ -23,11 +23,12 @@
128
129
130 import os
131-import gtk
132+from gi.repository import Gtk
133+Gtk.require_version('2.0')
134 import sys
135 import dbus
136 import glib
137-import pango
138+from gi.repository import Pango
139 import gobject
140
141 from operator import mod
142@@ -86,7 +87,7 @@
143
144 def run(self):
145 """Set up the widgets and run the main loop."""
146- builder = gtk.Builder()
147+ builder = Gtk.Builder()
148 builder.set_translation_domain('computerjanitor')
149 # Load the glade ui file, which can be overridden from the environment
150 # for testing purposes.
151@@ -109,7 +110,7 @@
152 root.set_default_size(ROOT_WIDTH, ROOT_HEIGHT)
153 # Map the root window and go!
154 root.show()
155- gtk.main()
156+ Gtk.main()
157
158 def find_and_bind_widgets(self, builder):
159 """Bind widgets and callbacks."""
160@@ -117,8 +118,8 @@
161 # keeping track of them as mapped to their name.
162 self.widgets = {}
163 for ui_object in builder.get_objects():
164- if issubclass(type(ui_object), gtk.Buildable):
165- widget_name = gtk.Buildable.get_name(ui_object)
166+ if issubclass(type(ui_object), Gtk.Buildable):
167+ widget_name = Gtk.Buildable.get_name(ui_object)
168 self.widgets[widget_name] = ui_object
169 # Search through the attributes of this instance looking for
170 # callbacks for this widget. We use the naming convention
171@@ -143,29 +144,29 @@
172 # Each TreeView contains two columns. The leftmost one is a toggle
173 # that when select tells c-j to act on that cruft. Deselecting the
174 # toggle ignores the package for next time.
175- toggle_cr = gtk.CellRendererToggle()
176+ toggle_cr = Gtk.CellRendererToggle()
177 toggle_cr.connect('toggled', self._toggled, treeview)
178 toggle_cr.set_property('yalign', 0)
179- toggle_col = gtk.TreeViewColumn()
180- toggle_col.pack_start(toggle_cr)
181+ toggle_col = Gtk.TreeViewColumn()
182+ toggle_col.pack_start(toggle_cr, True)
183 toggle_col.add_attribute(toggle_cr, 'active', ListStoreColumns.active)
184 treeview.append_column(toggle_col)
185 # The rightmost column contains the details of the cruft. It will
186 # always contain the cruft name and can be expanded to display cruft
187 # details. Tell the column to get its toggle's active state from the
188 # model.
189- name_cr = gtk.CellRendererText()
190+ name_cr = Gtk.CellRendererText()
191 name_cr.set_property('yalign', 0)
192- name_cr.set_property('wrap-mode', pango.WRAP_WORD)
193- name_col = gtk.TreeViewColumn()
194- name_col.pack_start(name_cr)
195+ name_cr.set_property('wrap-mode', Pango.WrapMode.WORD)
196+ name_col = Gtk.TreeViewColumn()
197+ name_col.pack_start(name_cr, True)
198 name_col.add_attribute(name_cr, 'markup', ListStoreColumns.text)
199 treeview.append_column(name_col)
200 self.cruft_name_columns.add(name_col)
201 # The individual crufts may or may not be visible in this TreeView.
202 # It's the filter function that controls this, so set that now.
203- filter_store = self.store.filter_new()
204- filter_store.set_visible_func(filter_func)
205+ filter_store = self.store.filter_new(None)
206+ filter_store.set_visible_func(filter_func, None)
207 treeview.set_model(filter_store)
208 # Each TreeView has a popup menu for select or deselecting all visible
209 # cruft.
210@@ -176,12 +177,12 @@
211
212 :param treeview: The `TreeView` to attach the menu to.
213 """
214- select_all = gtk.MenuItem(label='Select all')
215+ select_all = Gtk.MenuItem(label='Select all')
216 select_all.connect('activate', self.popup_menu_select_all, treeview)
217- unselect_all = gtk.MenuItem(label='Unselect all')
218+ unselect_all = Gtk.MenuItem(label='Unselect all')
219 unselect_all.connect('activate',
220 self.popup_menu_unselect_all, treeview)
221- menu = gtk.Menu()
222+ menu = Gtk.Menu()
223 menu.append(select_all)
224 menu.append(unselect_all)
225 menu.show_all()
226@@ -389,7 +390,7 @@
227 # Don't quit while we're working.
228 if self.working:
229 return True
230- gtk.main_quit()
231+ Gtk.main_quit()
232
233 on_window_delete_event = on_quit_menuitem_activate
234
235@@ -402,7 +403,7 @@
236 """
237 # Original comment: This is slightly tricky and probably a source of
238 # bugs. Oh well.
239- if event.button == 1:
240+ if event.button.button == 1:
241 # Left button event. Select the row being clicked on. If the
242 # click is on the cruft name, show or hide its long description.
243 # If the click the click is elsewhere do not handle it. This
244@@ -423,7 +424,7 @@
245 # We are not handling this event so that the toggle button
246 # handling can occur.
247 return False
248- elif event.button == 3:
249+ elif event.button.button == 3:
250 # Right button event. Pop up the select/deselect all menu.
251 treeview.grab_focus()
252 x = int(event.x)
253@@ -434,7 +435,14 @@
254 path, column, cell_x, cell_y = pathinfo
255 treeview.set_cursor(path, column, False)
256 menu = self.popup_menus[treeview]
257- menu.popup(None, None, None, event.button, time)
258+ try:
259+ menu.popup_for_device(None, None, None, None, None,
260+ event.button.button, time)
261+ except AttributeError:
262+ # popup_for_device() is introspection safe, but only exists in
263+ # GTK3. popup() isn't introspectable, so in GTK 2 we need to
264+ # disable the popup menu functionality
265+ print >> sys.stderr, 'popup menu not supported when using GTK2'
266 return True
267 else:
268 # No other events are handled by us.
269@@ -454,7 +462,7 @@
270 # Get the rightmost of the two columns in the TreeView, i.e. the one
271 # containing the text.
272 column = treeview.get_column(1)
273- name_cr = column.get_cell_renderers()[0]
274+ name_cr = column.get_cells()[0]
275 # Wrap to the entire width of the column.
276 width = column.get_width()
277 name_cr.set_property('wrap-width', width)
278
279=== modified file 'data/ComputerJanitor.ui'
280--- data/ComputerJanitor.ui 2010-09-20 12:31:47 +0000
281+++ data/ComputerJanitor.ui 2011-02-16 13:45:44 +0000
282@@ -266,7 +266,6 @@
283 <property name="border_width">5</property>
284 <property name="type_hint">normal</property>
285 <property name="transient_for">window</property>
286- <property name="has_separator">False</property>
287 <property name="program_name">Computer Janitor</property>
288 <property name="version">x.y</property>
289 <property name="copyright" translatable="yes">Copyright 2008, 2009, 2010 Canonical Ltd.
290@@ -305,7 +304,6 @@
291 <property name="destroy_with_parent">True</property>
292 <property name="type_hint">normal</property>
293 <property name="transient_for">window</property>
294- <property name="has_separator">False</property>
295 <child internal-child="vbox">
296 <object class="GtkVBox" id="dialog-vbox2">
297 <property name="visible">True</property>
298
299=== modified file 'debian/changelog'
300--- debian/changelog 2011-02-15 23:20:27 +0000
301+++ debian/changelog 2011-02-16 13:45:44 +0000
302@@ -1,3 +1,21 @@
303+computer-janitor (2.0.6-0ubuntu1) UNRELEASED; urgency=low
304+
305+ * data/ComputerJanitor.ui: Drop obsolete has_separator properties.
306+ * run_from_checkout.sh: Drop setting of $PYTHONPATH. Current directory is
307+ there by default anyway, and this breaks setting it from the environment.
308+ * computerjanitorapp/gtk/*: Port from pygtk2 to pygi. Works fully with GTK3
309+ now, with GTK2 we need to disable the right-click popup menu
310+ (popup_for_device() is introspection safe, but only exists in GTK3.
311+ popup() isn't introspectable).
312+ * computerjanitorapp/gtk/ui.py: Force GTK2 for now, as we do not yet have a
313+ GTK3 theme in Natty, and don't carry the GTK3 stack in the default
314+ install.
315+ * debian/control: Update dependencies for the pygtk → pygi switch.
316+ * debian/control: Drop obsolete system-cleaner conflicts and gksu
317+ dependency.
318+
319+ -- Martin Pitt <martin.pitt@ubuntu.com> Sat, 15 Jan 2011 11:31:02 -0600
320+
321 computer-janitor (2.0.5-0ubuntu1) natty; urgency=low
322
323 * python-dbus cannot type-convert a set, so use a tuple for the package
324
325=== modified file 'debian/control'
326--- debian/control 2011-01-12 19:16:56 +0000
327+++ debian/control 2011-02-16 13:45:44 +0000
328@@ -18,8 +18,6 @@
329 python-argparse (>= 1.1),
330 dbus,
331 update-manager-core (>= 1:0.98.1)
332-Conflicts: system-cleaner
333-Replaces: system-cleaner
334 XB-Python-Version: ${python:Versions}
335 Description: Clean up a system so it's more like a freshly installed one
336 Over time, a computer system tends to get cluttered. For example,
337@@ -35,10 +33,12 @@
338
339 Package: computer-janitor-gtk
340 Architecture: all
341-Depends: ${python:Depends}, computer-janitor (=${source:Version}),
342- python-gtk2 (>= 2.16), ${misc:Depends}, gksu
343-Conflicts: system-cleaner-gtk
344-Replaces: system-cleaner-gtk
345+Depends: ${python:Depends},
346+ computer-janitor (=${source:Version}),
347+ python-gobject (>= 2.27.0+git20110116),
348+ gir1.2-gtk-2.0 (>= 2.23.90-0ubuntu3),
349+ gir1.2-pango-2.0,
350+ ${misc:Depends}
351 XB-Python-Version: ${python:Versions}
352 Description: Clean up a system so it's more like a freshly installed one
353 Over time, a computer system tends to get cluttered. For example,
354
355=== modified file 'run_from_checkout.sh'
356--- run_from_checkout.sh 2009-11-10 20:09:40 +0000
357+++ run_from_checkout.sh 2011-02-16 13:45:44 +0000
358@@ -3,7 +3,6 @@
359 # wrapper to make it easy to run c-j from a bzr checkout
360 #
361
362-export PYTHONPATH=.
363 export COMPUTER_JANITOR_PLUGINS=./plugins
364 export COMPUTER_JANITOR_GLADE=./data/ComputerJanitor.ui
365 export COMPUTER_JANITOR_DEBUG=yes

Subscribers

People subscribed via source and target branches