Merge lp:~dylanmccall/update-manager/dialogs-refactor into lp:update-manager

Proposed by Dylan McCall
Status: Merged
Merged at revision: 2631
Proposed branch: lp:~dylanmccall/update-manager/dialogs-refactor
Merge into: lp:update-manager
Diff against target: 3504 lines (+976/-1517)
14 files modified
UpdateManager/Dialogs.py (+94/-52)
UpdateManager/InstallProgress.py (+0/-100)
UpdateManager/SimpleGtkbuilderApp.py (+0/-63)
UpdateManager/UpdateManager.py (+78/-47)
UpdateManager/UpdateProgress.py (+0/-81)
UpdateManager/UpdatesAvailable.py (+94/-123)
UpdateManager/backend/InstallBackendAptdaemon.py (+63/-66)
UpdateManager/backend/InstallBackendSynaptic.py (+34/-28)
UpdateManager/backend/__init__.py (+66/-28)
data/gtkbuilder/Dialog.ui (+49/-50)
data/gtkbuilder/UpdateManager.ui (+276/-444)
debian/update-manager.install (+0/-3)
po/POTFILES.in (+0/-2)
po/update-manager.pot (+222/-430)
To merge this branch: bzr merge lp:~dylanmccall/update-manager/dialogs-refactor
Reviewer Review Type Date Requested Status
Dimitri John Ledkov Approve
Review via email: mp+164673@code.launchpad.net

Description of the change

With this branch, I am proposing some refactoring of update-manager's various screens so they all use the same base class, "Dialog", which is typically a Gtk widget that can be added as a child of the application's main window.

Previously, the design of the application meant we used Dialog sometimes, but not always, with the UpdatesAvailable screen being a particularly noteworthy omission. To deal with all these different screens, whenever UpdateManager wanted to show a new screen it would call that screen's start method, and then the screen itself would effectively take control of the main window. This meant adding new widgets, hiding the main window, making it resizable, and the like; which also meant code duplication, several calls to Gtk.main, and a strong smell of feature envy :) With my design, I'm trying to adopt a more conventional layout, using the Dialog class throughout, as a GTK widget wherever possible. (The settings dialog and InstallBackendSynaptic keep us from being all internal Gtk widgets all the time, but we're really close).

There is now a little less code (diffstat: 11 files changed, 747 insertions(+), 1074 deletions(-)), and it should be much easier to make a single change and have it apply logically across the application. In addition, because the main window has a better handle on its children, this paves the way for us to implement pretty transitions between screens, for example using the new-fangled GtkRevealer widget. Originally this would have meant changing every screen to deal with a new container in the main window. With this change, we can do it all in UpdateManager.py.

To post a comment you must log in.
2634. By Dylan McCall

Put back the "backend" module. It wasn't necessary to move it in this branch.

2635. By Dylan McCall

Removed unnecessary layout changes in InstallBackendAptdaemon. Progress dialog should not wiggle when it first appears, now.

2636. By Dylan McCall

Fix packaging and pot files.
Put back the 6px margin above header label in each dialog.

2637. By Dylan McCall

Progress dialog is resizable while downloading packages, too.

Revision history for this message
Dimitri John Ledkov (xnox) wrote :

Looks good to me. Installed and running this version of update-manager. Will report any bugs / regression. So far everything looks good.

review: Approve
Revision history for this message
Sebastien Bacher (seb128) wrote :

Those changes seem to have a created https://bugs.launchpad.net/ubuntu/+source/update-manager/+bug/1200775 (apturl stopped working on "AttributeError: 'InstallBackendAptdaemon' object has no attribute 'connect'")

Revision history for this message
Sebastien Bacher (seb128) wrote :

That merge is also creating https://errors.ubuntu.com/problem/3ca9b88401b3789ff4d00462be7b20206f60e181

_action_done() is calling "self.window_main.start_error(False, error_string, error_desc)", or window_main is a GtkDialog not an UpdateManager object anymore, so it doesn't have that function

Dylan, do you think you could look at that?

Revision history for this message
Sebastien Bacher (seb128) wrote :

I've opened https://bugs.launchpad.net/ubuntu/+source/update-manager/+bug/1258112 about the most recently described issue

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'UpdateManager/Dialogs.py'
--- UpdateManager/Dialogs.py 2013-01-09 21:04:35 +0000
+++ UpdateManager/Dialogs.py 2013-05-21 05:43:25 +0000
@@ -24,6 +24,7 @@
2424
25from gi.repository import Gtk25from gi.repository import Gtk
26from gi.repository import Gdk26from gi.repository import Gdk
27from gi.repository import GLib
27from gi.repository import GObject28from gi.repository import GObject
28GObject.threads_init()29GObject.threads_init()
2930
@@ -31,39 +32,79 @@
31warnings.filterwarnings(32warnings.filterwarnings(
32 "ignore", "Accessed deprecated property", DeprecationWarning)33 "ignore", "Accessed deprecated property", DeprecationWarning)
3334
35import logging
34import dbus36import dbus
35import os37import os
36import subprocess38import subprocess
37import sys39import sys
38from .SimpleGtkbuilderApp import SimpleGtkbuilderApp
3940
40from gettext import gettext as _41from gettext import gettext as _
4142
4243
43class Dialog(SimpleGtkbuilderApp):44class Dialog(object):
44 def __init__(self, window_main):45 def __init__(self, window_main):
45 self.window_main = window_main46 self.window_main = window_main
46 self.focus_button = None47
47 SimpleGtkbuilderApp.__init__(48 def start(self):
48 self,49 pass
49 self.window_main.datadir + "/gtkbuilder/Dialog.ui",50
50 "update-manager")51 def close(self):
5152 return self.stop()
52 def main(self):53
53 self.window_main.push(self.pane_dialog, self)54 def stop(self):
54 if self.focus_button:55 pass
55 self.focus_button.grab_focus()56
5657 def run(self, parent=None):
57 def run(self, parent=None):58 pass
58 if self.focus_button:59
59 self.focus_button.grab_focus()60
61class BuilderDialog(Dialog, Gtk.Alignment):
62 def __init__(self, window_main, ui_path, root_widget):
63 Dialog.__init__(self, window_main)
64 Gtk.Alignment.__init__(self)
65
66 builder = self._load_ui(ui_path, root_widget)
67 self.add(builder.get_object(root_widget))
68 self.show()
69
70 def _load_ui(self, path, root_widget, domain="update-manager"):
71 builder = Gtk.Builder()
72 builder.set_translation_domain(domain)
73 builder.add_objects_from_file(path, [root_widget])
74 builder.connect_signals(self)
75
76 for o in builder.get_objects():
77 if issubclass(type(o), Gtk.Buildable):
78 name = Gtk.Buildable.get_name(o)
79 setattr(self, name, o)
80 else:
81 logging.debug("WARNING: can not get name for '%s'" % o)
82
83 return builder
84
85 def run(self, parent=None):
86 # FIXME: THIS WILL CRASH!
60 if parent:87 if parent:
61 self.window_dialog.set_transient_for(parent)88 self.window_dialog.set_transient_for(parent)
62 self.window_dialog.set_modal(True)89 self.window_dialog.set_modal(True)
63 self.window_dialog.run()90 self.window_dialog.run()
6491
65 def close(self):92
66 sys.exit(0) # By default, exit the app93class InternalDialog(BuilderDialog):
94 def __init__(self, window_main, content_widget=None):
95 ui_path = os.path.join(window_main.datadir, "gtkbuilder/Dialog.ui")
96 BuilderDialog.__init__(self, window_main, ui_path, "pane_dialog")
97
98 self.focus_button = None
99 self.set_content_widget(content_widget)
100 self.connect("realize", self._on_realize)
101
102 def _on_realize(self, user_data):
103 if self.focus_button:
104 self.focus_button.set_can_default(True)
105 self.focus_button.set_can_focus(True)
106 self.focus_button.grab_default()
107 self.focus_button.grab_focus()
67108
68 def add_button(self, label, callback, secondary=False):109 def add_button(self, label, callback, secondary=False):
69 # from_stock tries stock first and falls back to mnemonic110 # from_stock tries stock first and falls back to mnemonic
@@ -83,48 +124,50 @@
83 return None124 return None
84125
85 def on_settings_button_clicked(self):126 def on_settings_button_clicked(self):
86 cmd = ["/usr/bin/software-properties-gtk",127 self.window_main.show_settings()
87 "--open-tab", "2",
88 # FIXME: once get_xid() is available via introspections, add
89 # this back
90 #"--toplevel", "%s" % self.window_main.get_window().get_xid()
91 ]
92 subprocess.Popen(cmd)
93128
94 def set_header(self, label):129 def set_header(self, label):
95 self.label_header.set_label(label)130 if label:
131 self.label_header.set_markup(
132 "<span size='larger' weight='bold'>%s</span>" % label)
133 self.label_header.set_visible(bool(label))
96134
97 def set_desc(self, label):135 def set_desc(self, label):
98 self.label_desc.set_label(label)136 if label:
137 self.label_desc.set_markup(label)
99 self.label_desc.set_visible(bool(label))138 self.label_desc.set_visible(bool(label))
100139
140 def set_content_widget(self, content_widget):
141 if content_widget:
142 self.main_container.add(content_widget)
143 self.main_container.set_visible(bool(content_widget))
101144
102class StoppedUpdatesDialog(Dialog):145class StoppedUpdatesDialog(InternalDialog):
103 def __init__(self, window_main):146 def __init__(self, window_main):
104 Dialog.__init__(self, window_main)147 InternalDialog.__init__(self, window_main)
105 self.set_header(_("You stopped the check for updates."))148 self.set_header(_("You stopped the check for updates."))
106 self.add_settings_button()149 self.add_settings_button()
107 self.add_button(_("_Check Again"), self.check)150 self.add_button(_("_Check Again"), self.check)
108 self.focus_button = self.add_button(Gtk.STOCK_OK, self.close)151 self.focus_button = self.add_button(Gtk.STOCK_OK, self.window_main.close)
109152
110 def check(self):153 def check(self):
111 self.window_main.start_update()154 self.window_main.start_update()
112155
113156
114class NoUpdatesDialog(Dialog):157class NoUpdatesDialog(InternalDialog):
115 def __init__(self, window_main, error_occurred=False):158 def __init__(self, window_main, error_occurred=False):
116 Dialog.__init__(self, window_main)159 InternalDialog.__init__(self, window_main)
117 if error_occurred:160 if error_occurred:
118 self.set_header(_("No software updates are available."))161 self.set_header(_("No software updates are available."))
119 else:162 else:
120 self.set_header(_("The software on this computer is up to date."))163 self.set_header(_("The software on this computer is up to date."))
121 self.add_settings_button()164 self.add_settings_button()
122 self.focus_button = self.add_button(Gtk.STOCK_OK, self.close)165 self.focus_button = self.add_button(Gtk.STOCK_OK, self.window_main.close)
123166
124167
125class DistUpgradeDialog(Dialog):168class DistUpgradeDialog(InternalDialog):
126 def __init__(self, window_main, meta_release):169 def __init__(self, window_main, meta_release):
127 Dialog.__init__(self, window_main)170 InternalDialog.__init__(self, window_main)
128 self.meta_release = meta_release171 self.meta_release = meta_release
129 self.set_header(_("The software on this computer is up to date."))172 self.set_header(_("The software on this computer is up to date."))
130 # Translators: these are Ubuntu version names like "Ubuntu 12.04"173 # Translators: these are Ubuntu version names like "Ubuntu 12.04"
@@ -134,7 +177,7 @@
134 meta_release.current_dist_version))177 meta_release.current_dist_version))
135 self.add_settings_button()178 self.add_settings_button()
136 self.add_button(_("Upgrade…"), self.upgrade)179 self.add_button(_("Upgrade…"), self.upgrade)
137 self.focus_button = self.add_button(Gtk.STOCK_OK, self.close)180 self.focus_button = self.add_button(Gtk.STOCK_OK, self.window_main.close)
138181
139 def upgrade(self):182 def upgrade(self):
140 # Pass on several arguments183 # Pass on several arguments
@@ -169,9 +212,9 @@
169 DistUpgradeDialog.run(self, parent)212 DistUpgradeDialog.run(self, parent)
170213
171214
172class PartialUpgradeDialog(Dialog):215class PartialUpgradeDialog(InternalDialog):
173 def __init__(self, window_main):216 def __init__(self, window_main):
174 Dialog.__init__(self, window_main)217 InternalDialog.__init__(self, window_main)
175 self.set_header(_("Not all updates can be installed"))218 self.set_header(_("Not all updates can be installed"))
176 self.set_desc(_(219 self.set_desc(_(
177 """Run a partial upgrade, to install as many updates as possible.220 """Run a partial upgrade, to install as many updates as possible.
@@ -191,24 +234,24 @@
191 "/usr/lib/ubuntu-release-upgrader/do-partial-upgrade "234 "/usr/lib/ubuntu-release-upgrader/do-partial-upgrade "
192 "--frontend=DistUpgradeViewGtk3")235 "--frontend=DistUpgradeViewGtk3")
193236
194 def main(self):237 def start(self):
195 Dialog.main(self)238 Dialog.start(self)
196 # Block progress until user has answered this question239 # Block progress until user has answered this question
197 Gtk.main()240 Gtk.main()
198241
199242
200class ErrorDialog(Dialog):243class ErrorDialog(InternalDialog):
201 def __init__(self, window_main, header, desc=None):244 def __init__(self, window_main, header, desc=None):
202 Dialog.__init__(self, window_main)245 InternalDialog.__init__(self, window_main)
203 self.set_header(header)246 self.set_header(header)
204 if desc:247 if desc:
205 self.set_desc(desc)248 self.set_desc(desc)
206 self.label_desc.set_selectable(True)249 self.label_desc.set_selectable(True)
207 self.add_settings_button()250 self.add_settings_button()
208 self.focus_button = self.add_button(Gtk.STOCK_OK, self.close)251 self.focus_button = self.add_button(Gtk.STOCK_OK, self.window_main.close)
209252
210 def main(self):253 def start(self):
211 Dialog.main(self)254 Dialog.start(self)
212 # The label likes to start selecting everything (b/c it got focus255 # The label likes to start selecting everything (b/c it got focus
213 # before we switched to our default button).256 # before we switched to our default button).
214 self.label_desc.select_region(0, 0)257 self.label_desc.select_region(0, 0)
@@ -229,17 +272,16 @@
229 self.window_main.start_available(error_occurred=True)272 self.window_main.start_available(error_occurred=True)
230273
231274
232class NeedRestartDialog(Dialog):275class NeedRestartDialog(InternalDialog):
233 def __init__(self, window_main):276 def __init__(self, window_main):
234 Dialog.__init__(self, window_main)277 InternalDialog.__init__(self, window_main)
235 self.set_header(278 self.set_header(
236 _("The computer needs to restart to finish installing updates."))279 _("The computer needs to restart to finish installing updates."))
237 self.focus_button = self.add_button(_("_Restart"), self.restart)280 self.focus_button = self.add_button(_("_Restart"), self.restart)
238281
239 def main(self):282 def start(self):
240 Dialog.main(self)283 Dialog.start(self)
241 # Turn off close button284 # Turn off close button
242 self.window_main.realize()
243 self.window_main.get_window().set_functions(Gdk.WMFunction.MOVE |285 self.window_main.get_window().set_functions(Gdk.WMFunction.MOVE |
244 Gdk.WMFunction.MINIMIZE)286 Gdk.WMFunction.MINIMIZE)
245287
246288
=== removed file 'UpdateManager/InstallProgress.py'
--- UpdateManager/InstallProgress.py 2012-12-13 20:39:37 +0000
+++ UpdateManager/InstallProgress.py 1970-01-01 00:00:00 +0000
@@ -1,100 +0,0 @@
1# InstallProgress.py
2# -*- Mode: Python; indent-tabs-mode: nil; tab-width: 4; coding: utf-8 -*-
3#
4# Copyright (c) 2004-2012 Canonical
5# 2004 Michiel Sikkes
6# 2005 Martin Willemoes Hansen
7# 2010 Mohamed Amine IL Idrissi
8#
9# Author: Michiel Sikkes <michiel@eyesopened.nl>
10# Michael Vogt <mvo@debian.org>
11# Martin Willemoes Hansen <mwh@sysrq.dk>
12# Mohamed Amine IL Idrissi <ilidrissiamine@gmail.com>
13# Alex Launi <alex.launi@canonical.com>
14# Michael Terry <michael.terry@canonical.com>
15#
16# This program is free software; you can redistribute it and/or
17# modify it under the terms of the GNU General Public License as
18# published by the Free Software Foundation; either version 2 of the
19# License, or (at your option) any later version.
20#
21# This program is distributed in the hope that it will be useful,
22# but WITHOUT ANY WARRANTY; without even the implied warranty of
23# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24# GNU General Public License for more details.
25#
26# You should have received a copy of the GNU General Public License
27# along with this program; if not, write to the Free Software
28# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
29# USA
30
31from __future__ import absolute_import, print_function
32
33import warnings
34warnings.filterwarnings("ignore", "Accessed deprecated property",
35 DeprecationWarning)
36
37import os
38import sys
39
40from .backend import get_backend
41
42from .Core.utils import (inhibit_sleep,
43 allow_sleep)
44
45
46class InstallProgress(object):
47
48 def __init__(self, app):
49 self.window_main = app
50 self.datadir = app.datadir
51 self.options = app.options
52
53 # Used for inhibiting power management
54 self.sleep_cookie = None
55 self.sleep_dev = None
56
57 # get the install backend
58 self.install_backend = get_backend(self.datadir, self.window_main)
59 self.install_backend.connect("action-done", self._on_backend_done)
60
61 def invoke_manager(self):
62 # don't display apt-listchanges, we already showed the changelog
63 os.environ["APT_LISTCHANGES_FRONTEND"] = "none"
64
65 # Do not suspend during the update process
66 (self.sleep_dev, self.sleep_cookie) = inhibit_sleep()
67
68 # If the progress dialog should be closed automatically afterwards
69 #settings = Gio.Settings("com.ubuntu.update-manager")
70 #close_on_done = settings.get_boolean("autoclose-install-window")
71 # FIXME: confirm with mpt whether this should still be a setting
72 close_on_done = False
73
74 # Get the packages which should be installed and update
75 pkgs_install = []
76 pkgs_upgrade = []
77 for pkg in self.window_main.cache:
78 if pkg.marked_install:
79 pkgs_install.append(pkg.name)
80 elif pkg.marked_upgrade:
81 pkgs_upgrade.append(pkg.name)
82 self.install_backend.commit(pkgs_install, pkgs_upgrade, close_on_done)
83
84 def _on_backend_done(self, backend, action, authorized, success,
85 error_string, error_desc):
86 # Allow suspend after synaptic is finished
87 if self.sleep_cookie:
88 allow_sleep(self.sleep_dev, self.sleep_cookie)
89 self.sleep_cookie = self.sleep_dev = None
90
91 # Either launch main dialog and continue or quit altogether
92 if success:
93 self.window_main.start_available()
94 elif error_string:
95 self.window_main.start_error(False, error_string, error_desc)
96 else:
97 sys.exit(0)
98
99 def main(self):
100 self.invoke_manager()
1010
=== removed file 'UpdateManager/SimpleGtkbuilderApp.py'
--- UpdateManager/SimpleGtkbuilderApp.py 2012-11-19 16:33:28 +0000
+++ UpdateManager/SimpleGtkbuilderApp.py 1970-01-01 00:00:00 +0000
@@ -1,63 +0,0 @@
1# -*- Mode: Python; indent-tabs-mode: nil; tab-width: 4; coding: utf-8 -*-
2
3"""
4 SimpleGladeApp.py
5 Module that provides an object oriented abstraction to pygtk and libglade.
6 Copyright (C) 2004 Sandino Flores Moreno
7"""
8
9# This library is free software; you can redistribute it and/or
10# modify it under the terms of the GNU Lesser General Public
11# License as published by the Free Software Foundation; either
12# version 2.1 of the License, or (at your option) any later version.
13#
14# This library is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17# Lesser General Public License for more details.
18#
19# You should have received a copy of the GNU Lesser General Public
20# License along with this library; if not, write to the Free Software
21# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22# USA
23
24import logging
25
26from gi.repository import Gtk
27
28
29# based on SimpleGladeApp
30class SimpleGtkbuilderApp:
31
32 def __init__(self, path, domain):
33 self.builder = Gtk.Builder()
34 self.builder.set_translation_domain(domain)
35 self.builder.add_from_file(path)
36 self.builder.connect_signals(self)
37 for o in self.builder.get_objects():
38 if issubclass(type(o), Gtk.Buildable):
39 name = Gtk.Buildable.get_name(o)
40 setattr(self, name, o)
41 else:
42 logging.debug("WARNING: can not get name for '%s'" % o)
43
44 def run(self):
45 """
46 Starts the main loop of processing events checking for Control-C.
47
48 The default implementation checks wheter a Control-C is pressed,
49 then calls on_keyboard_interrupt().
50
51 Use this method for starting programs.
52 """
53 try:
54 Gtk.main()
55 except KeyboardInterrupt:
56 self.on_keyboard_interrupt()
57
58 def on_keyboard_interrupt(self):
59 """
60 This method is called by the default implementation of run()
61 after a program is finished by pressing Control-C.
62 """
63 pass
640
=== modified file 'UpdateManager/UpdateManager.py'
--- UpdateManager/UpdateManager.py 2013-03-01 18:21:56 +0000
+++ UpdateManager/UpdateManager.py 2013-05-21 05:43:25 +0000
@@ -23,7 +23,7 @@
23from __future__ import absolute_import, print_function23from __future__ import absolute_import, print_function
2424
25from gi.repository import Gtk25from gi.repository import Gtk
26from gi.repository import Gdk26from gi.repository import Gdk, GdkX11
27from gi.repository import Gio27from gi.repository import Gio
28from gi.repository import GLib28from gi.repository import GLib
2929
@@ -33,7 +33,9 @@
3333
34import apt_pkg34import apt_pkg
35import os35import os
36import subprocess
36import sys37import sys
38import time
37from gettext import gettext as _39from gettext import gettext as _
3840
39import dbus41import dbus
@@ -50,22 +52,22 @@
50 PartialUpgradeDialog,52 PartialUpgradeDialog,
51 UnsupportedDialog,53 UnsupportedDialog,
52 UpdateErrorDialog)54 UpdateErrorDialog)
53from .InstallProgress import InstallProgress
54from .MetaReleaseGObject import MetaRelease55from .MetaReleaseGObject import MetaRelease
55from .UpdateProgress import UpdateProgress
56from .UpdatesAvailable import UpdatesAvailable56from .UpdatesAvailable import UpdatesAvailable
57from .Core.AlertWatcher import AlertWatcher57from .Core.AlertWatcher import AlertWatcher
58from .Core.MyCache import MyCache58from .Core.MyCache import MyCache
59from .Core.roam import NetworkManagerHelper59from .Core.roam import NetworkManagerHelper
60from .Core.UpdateList import UpdateList60from .Core.UpdateList import UpdateList
61from .backend import (InstallBackend,
62 get_backend)
6163
62# file that signals if we need to reboot64# file that signals if we need to reboot
63REBOOT_REQUIRED_FILE = "/var/run/reboot-required"65REBOOT_REQUIRED_FILE = "/var/run/reboot-required"
6466
6567
66class UpdateManager(Gtk.Window):68class UpdateManager(Gtk.Window):
67 """ This class is the main window and work flow controller. Panes will add69 """ This class is the main window and work flow controller. The main
68 themselves to the main window and it will morph between them."""70 window will show panes, and it will morph between them. """
6971
70 def __init__(self, datadir, options):72 def __init__(self, datadir, options):
71 Gtk.Window.__init__(self)73 Gtk.Window.__init__(self)
@@ -82,16 +84,14 @@
82 # Basic GTK+ parameters84 # Basic GTK+ parameters
83 self.set_title(_("Software Updater"))85 self.set_title(_("Software Updater"))
84 self.set_icon_name("system-software-update")86 self.set_icon_name("system-software-update")
85 self.set_resizable(False)
86 self.set_position(Gtk.WindowPosition.CENTER)87 self.set_position(Gtk.WindowPosition.CENTER)
8788
88 # Keep window at a constant size89 # Keep window at a constant size
89 ctx = self.get_style_context()90 ctx = self.get_style_context()
90 ctx.connect("changed", lambda ctx: self.resize_to_standard_width())91 ctx.connect("changed", lambda ctx: self.resize_to_standard_width())
91 self.resize_to_standard_width()
9292
93 # Signals93 # Signals
94 self.connect("delete-event", self.close)94 self.connect("delete-event", self._on_close)
9595
96 self._setup_dbus()96 self._setup_dbus()
9797
@@ -110,6 +110,17 @@
110 self.options and self.options.devel_release,110 self.options and self.options.devel_release,
111 self.options and self.options.use_proposed)111 self.options and self.options.use_proposed)
112112
113 def begin_user_resizable(self, stored_width=0, stored_height=0):
114 self.set_resizable(True)
115 if stored_width > 0 and stored_height > 0:
116 # There is a race here. If we immediately resize, it often doesn't
117 # take. Using idle_add helps, but we *still* occasionally don't
118 # restore the size correctly. Help needed to track this down!
119 GLib.idle_add(lambda: self.resize(stored_width, stored_height))
120
121 def end_user_resizable(self):
122 self.set_resizable(False)
123
113 def resize_to_standard_width(self):124 def resize_to_standard_width(self):
114 if self.get_resizable():125 if self.get_resizable():
115 return # only size to a specific em if we are a static size126 return # only size to a specific em if we are a static size
@@ -130,56 +141,77 @@
130 self.disconnect(self.initial_focus_id)141 self.disconnect(self.initial_focus_id)
131 return False142 return False
132143
133 def push(self, pane, controller):144 def _start_pane(self, pane):
134 child = self.get_child()145 if self.controller is not None:
135 if child is not None:146 self.controller.stop()
136 if self.controller and hasattr(self.controller, "save_state"):147 if isinstance(self.controller, Gtk.Widget):
137 self.controller.save_state()148 self.controller.destroy()
138 child.destroy()149
150 self.controller = pane
151 self._look_ready()
152 self.end_user_resizable()
139153
140 if pane is None:154 if pane is None:
141 self.controller = None
142 return155 return
143156
144 pane.reparent(self)157 if isinstance(pane, Gtk.Widget):
145 self.controller = controller158 self.add(pane)
146159 pane.start()
147 # Reset state160 self.show_all()
148 self.set_resizable(False)161 else:
149 self.resize_to_standard_width()162 pane.start()
150 self.set_sensitive(True)163 self.hide()
151 if self.get_window() is not None:164
152 self.get_window().set_cursor(None)165 def _on_close(self, widget, data=None):
153 self.get_window().set_functions(Gdk.WMFunction.ALL)166 self.close()
154167
155 if self.controller and hasattr(self.controller, "restore_state"):168 def close(self):
156 self.controller.restore_state()
157
158 pane.show()
159 self.show()
160
161 def close(self, widget, data=None):
162 if not self.get_sensitive():169 if not self.get_sensitive():
163 return True170 return True
164171
165 if self.controller and hasattr(self.controller, "close"):172 controller_close = self.controller.close()
166 # let controller handle it as they will173 if controller_close:
167 if self.controller.close():174 return controller_close
168 return
169
170 self.exit()175 self.exit()
171176
172 def exit(self):177 def exit(self):
173 """ exit the application, save the state """178 """ exit the application, save the state """
174 self.push(None, None)179 self._start_pane(None)
175 sys.exit(0)180 sys.exit(0)
176181
182 def show_settings(self):
183 try:
184 apt_pkg.pkgsystem_unlock()
185 except SystemError:
186 pass
187 cmd = ["/usr/bin/software-properties-gtk",
188 "--open-tab", "2",
189 "--toplevel", "%s" % self.get_window().get_xid()
190 ]
191 self._look_busy()
192 try:
193 p = subprocess.Popen(cmd)
194 except OSError:
195 pass
196 else:
197 while p.poll() is None:
198 while Gtk.events_pending():
199 Gtk.main_iteration()
200 time.sleep(0.05)
201 finally:
202 self.start_available()
203
177 def start_update(self):204 def start_update(self):
178 if self.options.no_update:205 if self.options.no_update:
179 self.start_available()206 self.start_available()
180 return207 return
181208
182 self._start_pane(UpdateProgress(self))209 update_backend = get_backend(self, InstallBackend.ACTION_UPDATE)
210 self._start_pane(update_backend)
211
212 def start_install(self):
213 install_backend = get_backend(self, InstallBackend.ACTION_INSTALL)
214 self._start_pane(install_backend)
183215
184 def start_available(self, cancelled_update=False, error_occurred=False):216 def start_available(self, cancelled_update=False, error_occurred=False):
185 self._look_busy()217 self._look_busy()
@@ -214,24 +246,23 @@
214 "a previous check.")246 "a previous check.")
215 return UpdatesAvailable(self, header, desc)247 return UpdatesAvailable(self, header, desc)
216248
217 def start_install(self):
218 self._start_pane(InstallProgress(self))
219
220 def start_error(self, is_update_error, header, desc):249 def start_error(self, is_update_error, header, desc):
221 if is_update_error:250 if is_update_error:
222 self._start_pane(UpdateErrorDialog(self, header, desc))251 self._start_pane(UpdateErrorDialog(self, header, desc))
223 else:252 else:
224 self._start_pane(ErrorDialog(self, header, desc))253 self._start_pane(ErrorDialog(self, header, desc))
225254
226 def _start_pane(self, pane):
227 self._look_busy()
228 pane.main()
229
230 def _look_busy(self):255 def _look_busy(self):
231 self.set_sensitive(False)256 self.set_sensitive(False)
232 if self.get_window() is not None:257 if self.get_window() is not None:
233 self.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.WATCH))258 self.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.WATCH))
234259
260 def _look_ready(self):
261 self.set_sensitive(True)
262 if self.get_window() is not None:
263 self.get_window().set_cursor(None)
264 self.get_window().set_functions(Gdk.WMFunction.ALL)
265
235 def _check_meta_release(self):266 def _check_meta_release(self):
236 if self.meta_release is None:267 if self.meta_release is None:
237 return None268 return None
238269
=== removed file 'UpdateManager/UpdateProgress.py'
--- UpdateManager/UpdateProgress.py 2012-12-13 20:39:37 +0000
+++ UpdateManager/UpdateProgress.py 1970-01-01 00:00:00 +0000
@@ -1,81 +0,0 @@
1# UpdateProgress.py
2# -*- Mode: Python; indent-tabs-mode: nil; tab-width: 4; coding: utf-8 -*-
3#
4# Copyright (c) 2004-2012 Canonical
5# 2004 Michiel Sikkes
6# 2005 Martin Willemoes Hansen
7# 2010 Mohamed Amine IL Idrissi
8#
9# Author: Michiel Sikkes <michiel@eyesopened.nl>
10# Michael Vogt <mvo@debian.org>
11# Martin Willemoes Hansen <mwh@sysrq.dk>
12# Mohamed Amine IL Idrissi <ilidrissiamine@gmail.com>
13# Alex Launi <alex.launi@canonical.com>
14# Michael Terry <michael.terry@canonical.com>
15#
16# This program is free software; you can redistribute it and/or
17# modify it under the terms of the GNU General Public License as
18# published by the Free Software Foundation; either version 2 of the
19# License, or (at your option) any later version.
20#
21# This program is distributed in the hope that it will be useful,
22# but WITHOUT ANY WARRANTY; without even the implied warranty of
23# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24# GNU General Public License for more details.
25#
26# You should have received a copy of the GNU General Public License
27# along with this program; if not, write to the Free Software
28# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
29# USA
30
31from __future__ import absolute_import, print_function
32
33import warnings
34warnings.filterwarnings("ignore", "Accessed deprecated property",
35 DeprecationWarning)
36
37import os
38
39from .backend import get_backend
40
41from .Core.utils import inhibit_sleep, allow_sleep
42
43
44class UpdateProgress(object):
45
46 def __init__(self, app):
47 self.window_main = app
48 self.datadir = app.datadir
49 self.options = app.options
50
51 # Used for inhibiting power management
52 self.sleep_cookie = None
53 self.sleep_dev = None
54
55 # get the install backend
56 self.install_backend = get_backend(self.datadir, self.window_main)
57 self.install_backend.connect("action-done", self._on_backend_done)
58
59 def invoke_manager(self):
60 # don't display apt-listchanges
61 os.environ["APT_LISTCHANGES_FRONTEND"] = "none"
62
63 # Do not suspend during the update process
64 (self.sleep_dev, self.sleep_cookie) = inhibit_sleep()
65
66 self.install_backend.update()
67
68 def _on_backend_done(self, backend, action, authorized, success,
69 error_string, error_desc):
70 # Allow suspend after synaptic is finished
71 if self.sleep_cookie:
72 allow_sleep(self.sleep_dev, self.sleep_cookie)
73 self.sleep_cookie = self.sleep_dev = None
74
75 if error_string:
76 self.window_main.start_error(True, error_string, error_desc)
77 else:
78 self.window_main.start_available(not success)
79
80 def main(self):
81 self.invoke_manager()
820
=== modified file 'UpdateManager/UpdatesAvailable.py'
--- UpdateManager/UpdatesAvailable.py 2013-03-05 18:02:34 +0000
+++ UpdateManager/UpdatesAvailable.py 2013-05-21 05:43:25 +0000
@@ -48,22 +48,20 @@
48import os48import os
49import re49import re
50import logging50import logging
51import subprocess
52import time51import time
53import threading52import threading
5453
55from gettext import gettext as _54from gettext import gettext as _
56from gettext import ngettext55from gettext import ngettext
5756
58
59from .Core.utils import humanize_size57from .Core.utils import humanize_size
60from .Core.AlertWatcher import AlertWatcher58from .Core.AlertWatcher import AlertWatcher
61from .Core.UpdateList import UpdateSystemGroup59from .Core.UpdateList import UpdateSystemGroup
60from .Dialogs import InternalDialog
6261
63from DistUpgrade.DistUpgradeCache import NotEnoughFreeSpaceError62from DistUpgrade.DistUpgradeCache import NotEnoughFreeSpaceError
6463
65from .ChangelogViewer import ChangelogViewer64from .ChangelogViewer import ChangelogViewer
66from .SimpleGtkbuilderApp import SimpleGtkbuilderApp
67from .UnitySupport import UnitySupport65from .UnitySupport import UnitySupport
6866
6967
@@ -205,40 +203,52 @@
205 return cell_start203 return cell_start
206204
207205
208class UpdatesAvailable(SimpleGtkbuilderApp):206class UpdatesAvailable(InternalDialog):
209 APP_INSTALL_ICONS_PATH = "/usr/share/app-install/icons"207 APP_INSTALL_ICONS_PATH = "/usr/share/app-install/icons"
210208
211 def __init__(self, app, header=None, desc=None):209 def __init__(self, window_main, header=None, desc=None):
212 self.window_main = app210 InternalDialog.__init__(self, window_main)
213 self.datadir = app.datadir211
214 self.options = app.options212 self.window_main = window_main
215 self.cache = app.cache213 self.datadir = window_main.datadir
216 self.list = app.update_list214 self.cache = window_main.cache
217 SimpleGtkbuilderApp.__init__(215
218 self,216 self.custom_header = header
219 self.datadir + "/gtkbuilder/UpdateManager.ui",217 self.custom_desc = desc
220 "update-manager")218
219 content_ui_path = os.path.join(self.datadir, "gtkbuilder/UpdateManager.ui")
220 self._load_ui(content_ui_path, "pane_updates_available")
221 self.set_content_widget(self.pane_updates_available)
222
223 self.dl_size = 0
224 self.connected = True
221225
222 # Used for inhibiting power management226 # Used for inhibiting power management
223 self.sleep_cookie = None227 self.sleep_cookie = None
224 self.sleep_dev = None228 self.sleep_dev = None
225229
226 # workaround for LP: #945536
227 self.clearing_store = False
228
229 self.custom_header = header
230 self.custom_desc = desc
231
232 self.button_close.grab_focus()
233 self.dl_size = 0
234 self.connected = True
235
236 self.settings = Gio.Settings("com.ubuntu.update-manager")230 self.settings = Gio.Settings("com.ubuntu.update-manager")
237231
238 # Special icon theme for looking up app-install-data icons232 # Special icon theme for looking up app-install-data icons
239 self.app_icons = Gtk.IconTheme()233 self.app_icons = Gtk.IconTheme()
240 self.app_icons.append_search_path(self.APP_INSTALL_ICONS_PATH)234 self.app_icons.append_search_path(self.APP_INSTALL_ICONS_PATH)
241235
236 # Create Unity launcher quicklist
237 # FIXME: instead of passing parent we really should just send signals
238 self.unity = UnitySupport(parent=self)
239
240 # setup the help viewer and disable the help button if there
241 # is no viewer available
242 #self.help_viewer = HelpViewer("update-manager")
243 #if self.help_viewer.check() == False:
244 # self.button_help.set_sensitive(False)
245
246 self.add_settings_button()
247 self.button_close = self.add_button(Gtk.STOCK_CANCEL, self.window_main.close)
248 self.button_install = self.add_button(_("Install Now"),
249 self.on_button_install_clicked)
250 self.focus_button = self.button_install
251
242 # create text view252 # create text view
243 self.textview_changes = ChangelogViewer()253 self.textview_changes = ChangelogViewer()
244 self.textview_changes.show()254 self.textview_changes.show()
@@ -246,27 +256,9 @@
246 changes_buffer = self.textview_changes.get_buffer()256 changes_buffer = self.textview_changes.get_buffer()
247 changes_buffer.create_tag("versiontag", weight=Pango.Weight.BOLD)257 changes_buffer.create_tag("versiontag", weight=Pango.Weight.BOLD)
248258
249 # expander
250 self.expander_details.set_expanded(
251 self.settings.get_boolean("show-details"))
252 self.expander_details.connect("activate", self.pre_activate_details)
253 self.expander_details.connect("notify::expanded",
254 self.activate_details)
255 self.expander_desc.connect("notify::expanded", self.activate_desc)
256
257 # useful exit stuff
258 self.button_close.connect("clicked", lambda w: self.window_main.exit())
259
260 # If auto-updates are on, change cancel label
261 self.notifier_settings = Gio.Settings("com.ubuntu.update-notifier")
262 self.notifier_settings.connect(
263 "changed::auto-launch",
264 lambda s, p: self.update_close_button())
265 self.update_close_button()
266
267 # the treeview (move into it's own code!)259 # the treeview (move into it's own code!)
268 self.store = Gtk.TreeStore(str, GObject.TYPE_PYOBJECT, str, bool)260 self.store = Gtk.TreeStore(str, GObject.TYPE_PYOBJECT, str, bool)
269 self.treeview_update.set_model(self.store)261 self.treeview_update.set_model(None)
270262
271 restart_icon_renderer = Gtk.CellRendererPixbuf()263 restart_icon_renderer = Gtk.CellRendererPixbuf()
272 restart_icon_renderer.set_property("xpad", 4)264 restart_icon_renderer.set_property("xpad", 4)
@@ -280,9 +272,9 @@
280 restart_column.set_cell_data_func(restart_icon_renderer,272 restart_column.set_cell_data_func(restart_icon_renderer,
281 self.restart_icon_renderer_data_func)273 self.restart_icon_renderer_data_func)
282274
283 pkg_area = CellAreaPackage(bool(self.list.security_groups))275 self.pkg_cell_area = CellAreaPackage(False)
284 pkg_column = Gtk.TreeViewColumn.new_with_area(pkg_area)276 pkg_column = Gtk.TreeViewColumn.new_with_area(self.pkg_cell_area)
285 pkg_area.column = pkg_column277 self.pkg_cell_area.column = pkg_column
286 pkg_column.set_title(_("Install"))278 pkg_column.set_title(_("Install"))
287 pkg_column.set_property("spacing", 4)279 pkg_column.set_property("spacing", 4)
288 pkg_column.set_expand(True)280 pkg_column.set_expand(True)
@@ -331,24 +323,26 @@
331 self.treeview_update.connect("button-press-event",323 self.treeview_update.connect("button-press-event",
332 self.on_treeview_button_press)324 self.on_treeview_button_press)
333325
334 # setup the help viewer and disable the help button if there
335 # is no viewer available
336 #self.help_viewer = HelpViewer("update-manager")
337 #if self.help_viewer.check() == False:
338 # self.button_help.set_sensitive(False)
339
340 if not os.path.exists("/usr/bin/software-properties-gtk"):
341 self.button_settings.set_sensitive(False)
342
343 # init show version326 # init show version
344 self.show_versions = self.settings.get_boolean("show-versions")327 self.show_versions = self.settings.get_boolean("show-versions")
345 # init summary_before_name328 # init summary_before_name
346 self.summary_before_name = self.settings.get_boolean(329 self.summary_before_name = self.settings.get_boolean(
347 "summary-before-name")330 "summary-before-name")
348331
349 # Create Unity launcher quicklist332 # expander
350 # FIXME: instead of passing parent we really should just send signals333 self.expander_details.set_expanded(
351 self.unity = UnitySupport(parent=self)334 self.settings.get_boolean("show-details"))
335 self.expander_details.connect("activate", self.pre_activate_details)
336 self.expander_details.connect("notify::expanded",
337 self.activate_details)
338 self.expander_desc.connect("notify::expanded", self.activate_desc)
339
340 # If auto-updates are on, change cancel label
341 self.notifier_settings = Gio.Settings("com.ubuntu.update-notifier")
342 self.notifier_settings.connect(
343 "changed::auto-launch",
344 lambda s, p: self.update_close_button())
345 self.update_close_button()
352346
353 # Alert watcher347 # Alert watcher
354 self.alert_watcher = AlertWatcher()348 self.alert_watcher = AlertWatcher()
@@ -357,6 +351,16 @@
357 self.alert_watcher.connect("network-3g-alert",351 self.alert_watcher.connect("network-3g-alert",
358 self._on_network_3g_alert)352 self._on_network_3g_alert)
359353
354 def stop(self):
355 InternalDialog.stop(self)
356 self._save_state()
357
358 def start(self):
359 InternalDialog.start(self)
360 self.set_update_list(self.window_main.update_list)
361 self.alert_watcher.check_alert_state()
362 self._restore_state()
363
360 def is_auto_update(self):364 def is_auto_update(self):
361 update_days = apt_pkg.config.find_i(365 update_days = apt_pkg.config.find_i(
362 "APT::Periodic::Update-Package-Lists")366 "APT::Periodic::Update-Package-Lists")
@@ -378,22 +382,25 @@
378 self.on_button_install_clicked(None)382 self.on_button_install_clicked(None)
379383
380 def restart_icon_renderer_data_func(self, cell_layout, renderer, model,384 def restart_icon_renderer_data_func(self, cell_layout, renderer, model,
381 iter, data):385 iter, user_data):
382 def pkg_requires_restart(pkg):386 def pkg_requires_restart(pkg):
383 restart_condition = pkg.candidate.record.get('XB-Restart-Required')387 if pkg is None or pkg.candidate is None:
388 return False
389 restart_condition = pkg.candidate.record.get(
390 'XB-Restart-Required')
384 return restart_condition == 'system'391 return restart_condition == 'system'
385392
386 data = model.get_value(iter, LIST_UPDATE_DATA)393 data = model.get_value(iter, LIST_UPDATE_DATA)
387 path = model.get_path(iter)394 path = model.get_path(iter)
388395
389 requires_restart = False396 requires_restart = False
390 if data.item:397 if data.item and data.item.pkg:
391 requires_restart = pkg_requires_restart(data.item.pkg)398 requires_restart = pkg_requires_restart(data.item.pkg)
392 elif data.group:399 elif data.group:
393 if not self.treeview_update.row_expanded(path):400 if not self.treeview_update.row_expanded(path):
394 # A package in the group requires restart401 # A package in the group requires restart
395 for group_item in data.group.items:402 for group_item in data.group.items:
396 if pkg_requires_restart(group_item.pkg):403 if group_item.pkg and pkg_requires_restart(group_item.pkg):
397 requires_restart = True404 requires_restart = True
398 break405 break
399406
@@ -408,8 +415,8 @@
408 gicon = None415 gicon = None
409 renderer.set_property("gicon", gicon)416 renderer.set_property("gicon", gicon)
410417
411 def pkg_toggle_renderer_data_func(self, cell_layout, renderer, model, iter,418 def pkg_toggle_renderer_data_func(self, cell_layout, renderer, model,
412 data):419 iter, user_data):
413 data = model.get_value(iter, LIST_UPDATE_DATA)420 data = model.get_value(iter, LIST_UPDATE_DATA)
414421
415 activatable = False422 activatable = False
@@ -439,8 +446,8 @@
439 renderer.set_property("activatable", activatable)446 renderer.set_property("activatable", activatable)
440 renderer.set_property("inconsistent", inconsistent)447 renderer.set_property("inconsistent", inconsistent)
441448
442 def pkg_icon_renderer_data_func(self, cell_layout, renderer, model, iter,449 def pkg_icon_renderer_data_func(self, cell_layout, renderer, model,
443 data):450 iter, user_data):
444 data = model.get_value(iter, LIST_UPDATE_DATA)451 data = model.get_value(iter, LIST_UPDATE_DATA)
445452
446 gicon = None453 gicon = None
@@ -466,8 +473,8 @@
466 else:473 else:
467 return icon # Assume it's in one of the user's themes474 return icon # Assume it's in one of the user's themes
468475
469 def pkg_label_renderer_data_func(self, cell_layout, renderer, model, iter,476 def pkg_label_renderer_data_func(self, cell_layout, renderer, model,
470 data):477 iter, user_data):
471 data = model.get_value(iter, LIST_UPDATE_DATA)478 data = model.get_value(iter, LIST_UPDATE_DATA)
472 name = GLib.markup_escape_text(model.get_value(iter, LIST_NAME))479 name = GLib.markup_escape_text(model.get_value(iter, LIST_NAME))
473480
@@ -742,6 +749,9 @@
742749
743 if self.custom_header is not None:750 if self.custom_header is not None:
744 text_header = self.custom_header751 text_header = self.custom_header
752 if self.custom_desc is not None:
753 text_desc = self.custom_desc
754
745 # show different text on first run (UX team suggestion)755 # show different text on first run (UX team suggestion)
746 elif self.settings.get_boolean("first-run"):756 elif self.settings.get_boolean("first-run"):
747 flavor = self.window_main.meta_release.flavor_name757 flavor = self.window_main.meta_release.flavor_name
@@ -754,19 +764,10 @@
754 text_header = _("Updated software is available for this "764 text_header = _("Updated software is available for this "
755 "computer. Do you want to install it now?")765 "computer. Do you want to install it now?")
756766
757 if self.custom_desc is not None:
758 text_desc = self.custom_desc
759
760 self.notebook_details.set_sensitive(True)767 self.notebook_details.set_sensitive(True)
761 self.treeview_update.set_sensitive(True)768 self.treeview_update.set_sensitive(True)
762 self.button_install.grab_default()769 self.set_header(text_header)
763 self.label_header.set_label(text_header)770 self.set_desc(text_desc)
764
765 if text_desc is not None:
766 self.label_desc.set_label(text_desc)
767 self.label_desc.show()
768 else:
769 self.label_desc.hide()
770771
771 return True772 return True
772773
@@ -774,47 +775,20 @@
774 def pre_activate_details(self, expander):775 def pre_activate_details(self, expander):
775 expanded = self.expander_details.get_expanded()776 expanded = self.expander_details.get_expanded()
776 if expanded:777 if expanded:
777 self.save_state()778 self._save_state()
778779
779 def activate_details(self, expander, data):780 def activate_details(self, expander, data):
780 expanded = self.expander_details.get_expanded()781 expanded = self.expander_details.get_expanded()
781 self.settings.set_boolean("show-details", expanded)782 self.settings.set_boolean("show-details", expanded)
782 if expanded:783 if expanded:
783 self.on_treeview_update_cursor_changed(self.treeview_update)784 self.on_treeview_update_cursor_changed(self.treeview_update)
784 self.restore_state()785 self._restore_state()
785786
786 def activate_desc(self, expander, data):787 def activate_desc(self, expander, data):
787 expanded = self.expander_desc.get_expanded()788 expanded = self.expander_desc.get_expanded()
788 self.expander_desc.set_vexpand(expanded)789 self.expander_desc.set_vexpand(expanded)
789790
790 #def on_button_help_clicked(self, widget):791 def on_button_install_clicked(self):
791 # self.help_viewer.run()
792
793 def on_button_settings_clicked(self, widget):
794 #print("on_button_settings_clicked")
795 try:
796 apt_pkg.pkgsystem_unlock()
797 except SystemError:
798 pass
799 cmd = ["/usr/bin/software-properties-gtk",
800 "--open-tab", "2",
801 # FIXME: once get_xid() is available via introspections, add
802 # this back
803 #"--toplevel", "%s" % self.window_main.get_window().get_xid()
804 ]
805 self.window_main.set_sensitive(False)
806 p = subprocess.Popen(cmd)
807 while p.poll() is None:
808 while Gtk.events_pending():
809 Gtk.main_iteration()
810 time.sleep(0.05)
811 apt_pkg.init_config()
812 self.window_main.refresh_cache()
813 self.fillstore()
814 self.update_close_button()
815 self.window_main.set_sensitive(True)
816
817 def on_button_install_clicked(self, widget):
818 self.unity.set_install_menuitem_visible(False)792 self.unity.set_install_menuitem_visible(False)
819 #print("on_button_install_clicked")793 #print("on_button_install_clicked")
820 err_sum = _("Not enough free disk space")794 err_sum = _("Not enough free disk space")
@@ -930,24 +904,22 @@
930 del actiongroup904 del actiongroup
931 self.setBusy(False)905 self.setBusy(False)
932906
933 def save_state(self):907 def _save_state(self):
934 """ save the state (window-size for now) """908 """ save the state (window-size for now) """
935 if self.expander_details.get_expanded():909 if self.expander_details.get_expanded():
936 (w, h) = self.window_main.get_size()910 (w, h) = self.window_main.get_size()
937 self.settings.set_int("window-width", w)911 self.settings.set_int("window-width", w)
938 self.settings.set_int("window-height", h)912 self.settings.set_int("window-height", h)
939913
940 def restore_state(self):914 def _restore_state(self):
941 """ restore the state (window-size for now) """915 """ restore the state (window-size for now) """
942 w = self.settings.get_int("window-width")916 w = self.settings.get_int("window-width")
943 h = self.settings.get_int("window-height")917 h = self.settings.get_int("window-height")
944 expanded = self.expander_details.get_expanded()918 expanded = self.expander_details.get_expanded()
945 self.window_main.set_resizable(expanded)919 if expanded:
946 if w > 0 and h > 0 and expanded:920 self.window_main.begin_user_resizable(w, h)
947 # There is a race here. If we immediately resize, it often doesn't921 else:
948 # take. Using idle_add helps, but we *still* occasionally don't922 self.window_main.end_user_resizable()
949 # restore the size correctly. Help needed to track this down!
950 GLib.idle_add(lambda: self.window_main.resize(w, h))
951 return False923 return False
952924
953 def _add_header(self, name, groups):925 def _add_header(self, name, groups):
@@ -996,7 +968,9 @@
996 ]968 ]
997 self.store.append(group_iter, item_row)969 self.store.append(group_iter, item_row)
998970
999 def fillstore(self):971 def set_update_list(self, update_list):
972 self.list = update_list
973
1000 # use the watch cursor974 # use the watch cursor
1001 self.setBusy(True)975 self.setBusy(True)
1002 # disconnect the view first976 # disconnect the view first
@@ -1017,14 +991,11 @@
1017 self._add_groups(self.list.update_groups)991 self._add_groups(self.list.update_groups)
1018992
1019 self.treeview_update.set_model(self.store)993 self.treeview_update.set_model(self.store)
994 self.pkg_cell_area.indent_toplevel = bool(self.list.security_groups)
995 self.update_close_button()
1020 self.update_count()996 self.update_count()
1021 self.setBusy(False)997 self.setBusy(False)
1022 while Gtk.events_pending():998 while Gtk.events_pending():
1023 Gtk.main_iteration()999 Gtk.main_iteration()
1024 self.updates_changed()1000 self.updates_changed()
1025 return False1001 return False
1026
1027 def main(self):
1028 self.window_main.push(self.pane_updates_available, self)
1029 self.fillstore()
1030 self.alert_watcher.check_alert_state()
10311002
=== modified file 'UpdateManager/backend/InstallBackendAptdaemon.py'
--- UpdateManager/backend/InstallBackendAptdaemon.py 2013-02-06 21:12:16 +0000
+++ UpdateManager/backend/InstallBackendAptdaemon.py 2013-05-21 05:43:25 +0000
@@ -24,20 +24,25 @@
2424
25from UpdateManager.backend import InstallBackend25from UpdateManager.backend import InstallBackend
26from UpdateManager.UnitySupport import UnitySupport26from UpdateManager.UnitySupport import UnitySupport
27from UpdateManager.Dialogs import BuilderDialog
2728
28from gettext import gettext as _29from gettext import gettext as _
2930
30import apt31import apt
31import dbus32import dbus
32import sys33import os
3334
3435
35class InstallBackendAptdaemon(InstallBackend):36class InstallBackendAptdaemon(InstallBackend, BuilderDialog):
36
37 """Makes use of aptdaemon to refresh the cache and to install updates."""37 """Makes use of aptdaemon to refresh the cache and to install updates."""
3838
39 def __init__(self, datadir, window_main):39 def __init__(self, window_main, action):
40 InstallBackend.__init__(self, datadir, window_main)40 InstallBackend.__init__(self, window_main, action)
41 ui_path = os.path.join(window_main.datadir,
42 "gtkbuilder/UpdateProgress.ui")
43 BuilderDialog.__init__(self, window_main, ui_path,
44 "pane_update_progress")
45
41 self.client = client.AptClient()46 self.client = client.AptClient()
42 self.unity = UnitySupport()47 self.unity = UnitySupport()
43 self._expanded_size = None48 self._expanded_size = None
@@ -59,17 +64,20 @@
59 pass64 pass
60 try:65 try:
61 trans = yield self.client.update_cache(defer=True)66 trans = yield self.client.update_cache(defer=True)
62 yield self._run_in_dialog(trans, self.UPDATE,67 yield self._show_transaction(trans, self.ACTION_UPDATE,
63 _("Checking for updates…"),68 _("Checking for updates…"), False)
64 False, False)
65 except errors.NotAuthorizedError:69 except errors.NotAuthorizedError:
66 self.emit("action-done", self.UPDATE, False, False, None, None)70 self._action_done(self.ACTION_UPDATE,
71 authorized=False, success=False,
72 error_string=None, error_desc=None)
67 except:73 except:
68 self.emit("action-done", self.UPDATE, True, False, None, None)74 self._action_done(self.ACTION_UPDATE,
75 authorized=True, success=False,
76 error_string=None, error_desc=None)
69 raise77 raise
7078
71 @inline_callbacks79 @inline_callbacks
72 def commit(self, pkgs_install, pkgs_upgrade, close_on_done):80 def commit(self, pkgs_install, pkgs_upgrade):
73 """Commit a list of package adds and removes"""81 """Commit a list of package adds and removes"""
74 try:82 try:
75 apt.apt_pkg.pkgsystem_unlock()83 apt.apt_pkg.pkgsystem_unlock()
@@ -81,18 +89,23 @@
81 pkgs_install, reinstall, remove, purge, pkgs_upgrade,89 pkgs_install, reinstall, remove, purge, pkgs_upgrade,
82 downgrade, defer=True)90 downgrade, defer=True)
83 trans.connect("progress-changed", self._on_progress_changed)91 trans.connect("progress-changed", self._on_progress_changed)
84 yield self._run_in_dialog(trans, self.INSTALL,92 yield self._show_transaction(trans, self.ACTION_INSTALL,
85 _("Installing updates…"),93 _("Installing updates…"), True)
86 True, close_on_done)
87 except errors.NotAuthorizedError as e:94 except errors.NotAuthorizedError as e:
88 self.emit("action-done", self.INSTALL, False, False, None, None)95 self._action_done(self.ACTION_INSTALL,
96 authorized=False, success=False,
97 error_string=None, error_desc=None)
89 except dbus.DBusException as e:98 except dbus.DBusException as e:
90 #print(e, e.get_dbus_name())99 #print(e, e.get_dbus_name())
91 if e.get_dbus_name() != "org.freedesktop.DBus.Error.NoReply":100 if e.get_dbus_name() != "org.freedesktop.DBus.Error.NoReply":
92 raise101 raise
93 self.emit("action-done", self.INSTALL, False, False, None, None)102 self._action_done(self.ACTION_INSTALL,
103 authorized=False, success=False,
104 error_string=None, error_desc=None)
94 except Exception as e:105 except Exception as e:
95 self.emit("action-done", self.INSTALL, True, False, None, None)106 self._action_done(self.ACTION_INSTALL,
107 authorized=True, success=False,
108 error_string=None, error_desc=None)
96 raise109 raise
97110
98 def _on_progress_changed(self, trans, progress):111 def _on_progress_changed(self, trans, progress):
@@ -111,28 +124,18 @@
111 self._resize_to_show_details(expander)124 self._resize_to_show_details(expander)
112125
113 @inline_callbacks126 @inline_callbacks
114 def _run_in_dialog(self, trans, action, header, show_details,127 def _show_transaction(self, trans, action, header, show_details):
115 close_on_done):128 self.label_header.set_label(header)
116 builder = Gtk.Builder()
117 builder.set_translation_domain("update-manager")
118 builder.add_from_file(self.datadir + "/gtkbuilder/UpdateProgress.ui")
119
120 label_header = builder.get_object("label_header")
121 label_header.set_label(header)
122129
123 progressbar = AptProgressBar(trans)130 progressbar = AptProgressBar(trans)
124 progressbar.show()131 progressbar.show()
125 progressbar_slot = builder.get_object("progressbar_slot")132 self.progressbar_slot.add(progressbar)
126 progressbar_slot.add(progressbar)
127133
128 self.button_cancel = AptCancelButton(trans)134 self.button_cancel = AptCancelButton(trans)
129 if action == self.UPDATE:135 if action == self.ACTION_UPDATE:
130 self.button_cancel.set_label(Gtk.STOCK_STOP)136 self.button_cancel.set_label(Gtk.STOCK_STOP)
131 self.button_cancel.show()137 self.button_cancel.show()
132 button_cancel_slot = builder.get_object("button_cancel_slot")138 self.button_cancel_slot.add(self.button_cancel)
133 button_cancel_slot.add(self.button_cancel)
134
135 label_details = builder.get_object("label_details")
136139
137 if show_details:140 if show_details:
138 expander = AptDetailsExpander(trans)141 expander = AptDetailsExpander(trans)
@@ -140,39 +143,30 @@
140 expander.set_hexpand(True)143 expander.set_hexpand(True)
141 expander.show_all()144 expander.show_all()
142 expander.connect("notify::expanded", self._on_expanded)145 expander.connect("notify::expanded", self._on_expanded)
143 expander_slot = builder.get_object("expander_slot")146 self.expander_slot.add(expander)
144 expander_slot.add(expander)147 self.expander_slot.show()
145 expander_slot.show()
146 else:148 else:
147 expander = None149 expander = None
148150
149 trans.connect("status-details-changed", self._on_details_changed,151 trans.connect("status-details-changed", self._on_details_changed,
150 label_details)152 self.label_details)
151 trans.connect("status-changed", self._on_status_changed, label_details,153 trans.connect("status-changed", self._on_status_changed, self.label_details,
152 expander)154 expander)
153 trans.connect("finished", self._on_finished, action, close_on_done)155 trans.connect("finished", self._on_finished, action)
154 trans.connect("medium-required", self._on_medium_required)156 trans.connect("medium-required", self._on_medium_required)
155 trans.connect("config-file-conflict", self._on_config_file_conflict)157 trans.connect("config-file-conflict", self._on_config_file_conflict)
156158
157 yield trans.set_debconf_frontend("gnome")159 yield trans.set_debconf_frontend("gnome")
158 yield trans.run()160 yield trans.run()
159161
160 self.window_main.push(builder.get_object("pane_update_progress"),
161 self)
162
163 self.window_main.get_window().set_functions(Gdk.WMFunction.MOVE |
164 Gdk.WMFunction.RESIZE |
165 Gdk.WMFunction.MINIMIZE)
166
167 def _on_expanded(self, expander, param):162 def _on_expanded(self, expander, param):
168 # Make the dialog resizable if the expander is expanded163 # Make the dialog resizable if the expander is expanded
169 # try to restore a previous size164 # try to restore a previous size
170 if not expander.get_expanded():165 if not expander.get_expanded():
171 self._expanded_size = (expander.terminal.get_visible(),166 self._expanded_size = (expander.terminal.get_visible(),
172 self.window_main.get_size())167 self.window_main.get_size())
173 self.window_main.set_resizable(False)168 self.window_main.end_user_resizable()
174 elif self._expanded_size:169 elif self._expanded_size:
175 self.window_main.set_resizable(True)
176 term_visible, (stored_width, stored_height) = self._expanded_size170 term_visible, (stored_width, stored_height) = self._expanded_size
177 # Check if the stored size was for the download details or171 # Check if the stored size was for the download details or
178 # the terminal widget172 # the terminal widget
@@ -181,9 +175,8 @@
181 # get a new size for the terminal widget175 # get a new size for the terminal widget
182 self._resize_to_show_details(expander)176 self._resize_to_show_details(expander)
183 else:177 else:
184 self.window_main.resize(stored_width, stored_height)178 self.window_main.begin_user_resizable(stored_width, stored_height)
185 else:179 else:
186 self.window_main.set_resizable(True)
187 self._resize_to_show_details(expander)180 self._resize_to_show_details(expander)
188181
189 def _resize_to_show_details(self, expander):182 def _resize_to_show_details(self, expander):
@@ -195,16 +188,19 @@
195 If the expander is expanded afterwards the window won't change its188 If the expander is expanded afterwards the window won't change its
196 size anymore. So we have to do this manually. See LP#840942189 size anymore. So we have to do this manually. See LP#840942
197 """190 """
198 win_width, win_height = self.window_main.get_size()191 if expander.get_expanded():
199 exp_width = expander.get_allocation().width192 win_width, win_height = self.window_main.get_size()
200 exp_height = expander.get_allocation().height193 exp_width = expander.get_allocation().width
201 if expander.terminal.get_visible():194 exp_height = expander.get_allocation().height
202 terminal_width = expander.terminal.get_char_width() * 80195 if expander.terminal.get_visible():
203 terminal_height = expander.terminal.get_char_height() * 24196 terminal_width = expander.terminal.get_char_width() * 80
204 self.window_main.resize(terminal_width - exp_width + win_width,197 terminal_height = expander.terminal.get_char_height() * 24
205 terminal_height - exp_height + win_height)198 new_width = terminal_width - exp_width + win_width
206 else:199 new_height = terminal_height - exp_height + win_height
207 self.window_main.resize(win_width + 100, win_height + 200)200 else:
201 new_width = win_width + 100
202 new_height = win_height + 200
203 self.window_main.begin_user_resizable(new_width, new_height)
208204
209 def _on_medium_required(self, transaction, medium, drive):205 def _on_medium_required(self, transaction, medium, drive):
210 dialog = AptMediumRequiredDialog(medium, drive, self.window_main)206 dialog = AptMediumRequiredDialog(medium, drive, self.window_main)
@@ -224,18 +220,19 @@
224 else:220 else:
225 transaction.resolve_config_file_conflict(old, "keep")221 transaction.resolve_config_file_conflict(old, "keep")
226222
227 def _on_finished(self, trans, status, action, close_on_done):223 def _on_finished(self, trans, status, action):
228 error_string = None224 error_string = None
229 error_desc = None225 error_desc = None
230 if status == EXIT_FAILED:226 if status == EXIT_FAILED:
231 error_string = get_error_string_from_enum(trans.error.code)227 error_string = get_error_string_from_enum(trans.error.code)
232 error_desc = get_error_description_from_enum(trans.error.code)228 error_desc = get_error_description_from_enum(trans.error.code)
233 elif status == EXIT_SUCCESS and close_on_done:
234 sys.exit(0)
235 # tell unity to hide the progress again229 # tell unity to hide the progress again
236 self.unity.set_progress(-1)230 self.unity.set_progress(-1)
237 self.emit("action-done", action, True, status == EXIT_SUCCESS,231 is_success = (status == EXIT_SUCCESS)
238 error_string, error_desc)232 self._action_done(action,
233 authorized=True, success=is_success,
234 error_string=error_string, error_desc=error_desc)
235
239236
240if __name__ == "__main__":237if __name__ == "__main__":
241 b = InstallBackendAptdaemon(None)238 b = InstallBackendAptdaemon(None)
242239
=== modified file 'UpdateManager/backend/InstallBackendSynaptic.py'
--- UpdateManager/backend/InstallBackendSynaptic.py 2012-12-13 20:39:37 +0000
+++ UpdateManager/backend/InstallBackendSynaptic.py 2013-05-21 05:43:25 +0000
@@ -8,13 +8,43 @@
8from gettext import gettext as _8from gettext import gettext as _
99
10from gi.repository import GObject10from gi.repository import GObject
11# Extra GdkX11 import for pygobject bug #673396
12# https://bugzilla.gnome.org/show_bug.cgi?id=673396
13from gi.repository import GdkX11
1114
12from UpdateManager.backend import InstallBackend15from UpdateManager.backend import InstallBackend
16from UpdateManager.Dialogs import Dialog
1317
1418
15class InstallBackendSynaptic(InstallBackend):19class InstallBackendSynaptic(InstallBackend):
16 """ Install backend based on synaptic """20 """ Install backend based on synaptic """
1721
22 def update(self):
23 opt = ["--update-at-startup"]
24 tempf = None
25 self._run_synaptic(self.ACTION_UPDATE, opt, tempf)
26
27 def commit(self, pkgs_install, pkgs_upgrade, close_on_done=False):
28 # close when update was successful (its ok to use a Synaptic::
29 # option here, it will not get auto-saved, because synaptic does
30 # not save options in non-interactive mode)
31 opt = []
32 if close_on_done:
33 opt.append("-o")
34 opt.append("Synaptic::closeZvt=true")
35 # custom progress strings
36 opt.append("--progress-str")
37 opt.append("%s" % _("Please wait, this can take some time."))
38 opt.append("--finish-str")
39 opt.append("%s" % _("Update is complete"))
40 tempf = tempfile.NamedTemporaryFile(mode="w+")
41 for pkg_name in pkgs_install + pkgs_upgrade:
42 tempf.write("%s\tinstall\n" % pkg_name)
43 opt.append("--set-selections-file")
44 opt.append("%s" % tempf.name)
45 tempf.flush()
46 self._run_synaptic(self.ACTION_INSTALL, opt, tempf)
47
18 def _run_synaptic(self, action, opt, tempf):48 def _run_synaptic(self, action, opt, tempf):
19 """Execute synaptic."""49 """Execute synaptic."""
20 try:50 try:
@@ -42,31 +72,7 @@
42 action, tempf = data72 action, tempf = data
43 if tempf:73 if tempf:
44 tempf.close()74 tempf.close()
45 self.emit("action-done", action, True, os.WEXITSTATUS(condition) == 0,75 self._action_done(action,
46 None, None)76 authorized=True,
4777 success=os.WEXITSTATUS(condition) == 0,
48 def update(self):78 error_string=None, error_desc=None)
49 opt = ["--update-at-startup"]
50 tempf = None
51 self._run_synaptic(self.UPDATE, opt, tempf)
52
53 def commit(self, pkgs_install, pkgs_upgrade, close_on_done):
54 # close when update was successful (its ok to use a Synaptic::
55 # option here, it will not get auto-saved, because synaptic does
56 # not save options in non-interactive mode)
57 opt = []
58 if close_on_done:
59 opt.append("-o")
60 opt.append("Synaptic::closeZvt=true")
61 # custom progress strings
62 opt.append("--progress-str")
63 opt.append("%s" % _("Please wait, this can take some time."))
64 opt.append("--finish-str")
65 opt.append("%s" % _("Update is complete"))
66 tempf = tempfile.NamedTemporaryFile(mode="w+")
67 for pkg_name in pkgs_install + pkgs_upgrade:
68 tempf.write("%s\tinstall\n" % pkg_name)
69 opt.append("--set-selections-file")
70 opt.append("%s" % tempf.name)
71 tempf.flush()
72 self._run_synaptic(self.INSTALL, opt, tempf)
7379
=== modified file 'UpdateManager/backend/__init__.py'
--- UpdateManager/backend/__init__.py 2012-12-13 20:39:37 +0000
+++ UpdateManager/backend/__init__.py 2013-05-21 05:43:25 +0000
@@ -7,41 +7,79 @@
7from __future__ import absolute_import7from __future__ import absolute_import
88
9import os9import os
10import sys
1011
11from gi.repository import GObject12from gi.repository import GObject
1213from UpdateManager.Core.utils import (inhibit_sleep,
1314 allow_sleep)
14class InstallBackend(GObject.GObject):15from UpdateManager.Dialogs import Dialog
15 """The abstract backend that can install/remove packages"""16
1617
17 __gsignals__ = {"action-done": (GObject.SignalFlags.RUN_FIRST,18class InstallBackend(Dialog):
18 None,19 ACTION_UPDATE = 0
19 (GObject.TYPE_INT, # action id20 ACTION_INSTALL = 1
20 GObject.TYPE_BOOLEAN, # authorized21
21 GObject.TYPE_BOOLEAN, # success22 def __init__(self, window_main, action):
22 GObject.TYPE_STRING, # error string23 Dialog.__init__(self, window_main)
23 GObject.TYPE_STRING) # error desc24 self.action = action
24 ),25 self.sleep_cookie = None
25 }26 self.sleep_dev = None
2627
27 (INSTALL, UPDATE) = range(2)28 def start(self):
2829 os.environ["APT_LISTCHANGES_FRONTEND"] = "none"
29 def __init__(self, datadir, window_main):30
30 """init backend31 # Do not suspend during the update process
31 takes a gtk main window as parameter32 (self.sleep_dev, self.sleep_cookie) = inhibit_sleep()
32 """33
33 GObject.GObject.__init__(self)34 if self.action == self.ACTION_INSTALL:
34 self.datadir = datadir35 # Get the packages which should be installed and update
35 self.window_main = window_main36 pkgs_install = []
3637 pkgs_upgrade = []
37 def commit(self, pkgs_install, pkgs_upgrade, close_on_done):38 for pkg in self.window_main.cache:
38 """Commit the cache changes """39 if pkg.marked_install:
39 raise NotImplemented40 pkgs_install.append(pkg.name)
41 elif pkg.marked_upgrade:
42 pkgs_upgrade.append(pkg.name)
43 self.commit(pkgs_install, pkgs_upgrade)
44 else:
45 self.update()
4046
41 def update(self):47 def update(self):
42 """Run a update to refresh the package list"""48 """Run a update to refresh the package list"""
43 raise NotImplemented49 raise NotImplemented
4450
51 def commit(self, pkgs_install, pkgs_upgrade):
52 """Commit the cache changes """
53 raise NotImplemented
54
55 def _action_done(self, action, authorized, success, error_string,
56 error_desc):
57 # Allow suspend after update is finished
58 if self.sleep_cookie:
59 allow_sleep(self.sleep_dev, self.sleep_cookie)
60 self.sleep_cookie = self.sleep_dev = None
61
62 # If the progress dialog should be closed automatically afterwards
63 #settings = Gio.Settings("com.ubuntu.update-manager")
64 #close_after_install = settings.get_boolean(
65 # "autoclose-install-window")
66 # FIXME: confirm with mpt whether this should still be a setting
67 close_after_install = False
68
69 if action == self.ACTION_INSTALL:
70 if success:
71 self.window_main.start_available()
72 elif error_string:
73 self.window_main.start_error(False, error_string, error_desc)
74 else:
75 self.window_main.exit()
76 else:
77 if error_string:
78 self.window_main.start_error(True, error_string, error_desc)
79 else:
80 is_cancelled_update = not success
81 self.window_main.start_available(is_cancelled_update)
82
4583
46def get_backend(*args, **kwargs):84def get_backend(*args, **kwargs):
47 """Select and return a package manager backend."""85 """Select and return a package manager backend."""
4886
=== modified file 'data/gtkbuilder/Dialog.ui'
--- data/gtkbuilder/Dialog.ui 2013-01-25 16:41:01 +0000
+++ data/gtkbuilder/Dialog.ui 2013-05-21 05:43:25 +0000
@@ -1,36 +1,23 @@
1<?xml version="1.0" encoding="UTF-8"?>1<?xml version="1.0" encoding="UTF-8"?>
2<interface>2<interface>
3 <!-- interface-requires gtk+ 3.0 -->3 <!-- interface-requires gtk+ 3.0 -->
4 <object class="GtkDialog" id="window_dialog">4 <object class="GtkWindow" id="window_dialog">
5 <property name="can_focus">False</property>5 <property name="can_focus">False</property>
6 <property name="type_hint">dialog</property>6 <child>
7 <child internal-child="vbox">7 <object class="GtkBox" id="pane_dialog">
8 <object class="GtkBox" id="dialog-vbox1">8 <property name="visible">True</property>
9 <property name="can_focus">False</property>9 <property name="can_focus">False</property>
10 <property name="hexpand">True</property>
11 <property name="vexpand">True</property>
12 <property name="border_width">12</property>
10 <property name="orientation">vertical</property>13 <property name="orientation">vertical</property>
11 <child internal-child="action_area">
12 <object class="GtkButtonBox" id="dialog-action_area1">
13 <property name="can_focus">False</property>
14 <property name="layout_style">end</property>
15 <child>
16 <placeholder/>
17 </child>
18 </object>
19 <packing>
20 <property name="expand">False</property>
21 <property name="fill">True</property>
22 <property name="pack_type">end</property>
23 <property name="position">0</property>
24 </packing>
25 </child>
26 <child>14 <child>
27 <object class="GtkGrid" id="pane_dialog">15 <object class="GtkGrid" id="header_grid">
28 <property name="visible">True</property>16 <property name="visible">True</property>
29 <property name="can_focus">False</property>17 <property name="can_focus">False</property>
18 <property name="margin_bottom">12</property>
30 <property name="hexpand">True</property>19 <property name="hexpand">True</property>
31 <property name="vexpand">True</property>20 <property name="row_spacing">2</property>
32 <property name="border_width">12</property>
33 <property name="row_spacing">12</property>
34 <property name="column_spacing">12</property>21 <property name="column_spacing">12</property>
35 <child>22 <child>
36 <object class="GtkImage" id="image_logo">23 <object class="GtkImage" id="image_logo">
@@ -44,23 +31,21 @@
44 <property name="left_attach">0</property>31 <property name="left_attach">0</property>
45 <property name="top_attach">0</property>32 <property name="top_attach">0</property>
46 <property name="width">1</property>33 <property name="width">1</property>
47 <property name="height">1</property>34 <property name="height">2</property>
48 </packing>35 </packing>
49 </child>36 </child>
50 <child>37 <child>
51 <object class="GtkLabel" id="label_header">38 <object class="GtkLabel" id="label_header">
52 <property name="visible">True</property>
53 <property name="can_focus">False</property>39 <property name="can_focus">False</property>
40 <property name="no_show_all">True</property>
54 <property name="margin_top">6</property>41 <property name="margin_top">6</property>
55 <property name="hexpand">True</property>42 <property name="hexpand">True</property>
56 <property name="xalign">0</property>43 <property name="xalign">0</property>
57 <property name="yalign">0</property>44 <property name="yalign">0</property>
58 <property name="wrap">True</property>45 <property name="wrap">True</property>
59 <property name="width_chars">20</property>
60 <property name="max_width_chars">20</property>46 <property name="max_width_chars">20</property>
61 <attributes>47 <attributes>
62 <attribute name="weight" value="bold"/>48 <attribute name="weight" value="bold"/>
63 <attribute name="scale" value="1.25"/>
64 </attributes>49 </attributes>
65 </object>50 </object>
66 <packing>51 <packing>
@@ -75,7 +60,6 @@
75 <property name="can_focus">False</property>60 <property name="can_focus">False</property>
76 <property name="no_show_all">True</property>61 <property name="no_show_all">True</property>
77 <property name="hexpand">True</property>62 <property name="hexpand">True</property>
78 <property name="vexpand">True</property>
79 <property name="xalign">0</property>63 <property name="xalign">0</property>
80 <property name="yalign">0</property>64 <property name="yalign">0</property>
81 <property name="wrap">True</property>65 <property name="wrap">True</property>
@@ -88,37 +72,52 @@
88 <property name="height">1</property>72 <property name="height">1</property>
89 </packing>73 </packing>
90 </child>74 </child>
91 <child>75 </object>
92 <object class="GtkButtonBox" id="buttonbox">76 <packing>
93 <property name="visible">True</property>77 <property name="expand">False</property>
94 <property name="can_focus">False</property>78 <property name="fill">True</property>
95 <property name="valign">end</property>79 <property name="position">0</property>
96 <property name="hexpand">True</property>80 </packing>
97 <property name="vexpand">True</property>81 </child>
98 <property name="spacing">6</property>82 <child>
99 <property name="homogeneous">True</property>83 <object class="GtkBox" id="main_container">
100 <property name="layout_style">end</property>84 <property name="can_focus">False</property>
101 <child>85 <property name="no_show_all">True</property>
102 <placeholder/>86 <property name="margin_bottom">12</property>
103 </child>87 <property name="hexpand">True</property>
104 </object>88 <property name="vexpand">True</property>
105 <packing>89 <property name="orientation">vertical</property>
106 <property name="left_attach">0</property>
107 <property name="top_attach">2</property>
108 <property name="width">2</property>
109 <property name="height">1</property>
110 </packing>
111 </child>
112 <child>90 <child>
113 <placeholder/>91 <placeholder/>
114 </child>92 </child>
115 </object>93 </object>
116 <packing>94 <packing>
117 <property name="expand">False</property>95 <property name="expand">True</property>
118 <property name="fill">True</property>96 <property name="fill">True</property>
97 <property name="padding">4</property>
119 <property name="position">1</property>98 <property name="position">1</property>
120 </packing>99 </packing>
121 </child>100 </child>
101 <child>
102 <object class="GtkButtonBox" id="buttonbox">
103 <property name="visible">True</property>
104 <property name="can_focus">False</property>
105 <property name="valign">end</property>
106 <property name="hexpand">True</property>
107 <property name="spacing">6</property>
108 <property name="homogeneous">True</property>
109 <property name="layout_style">end</property>
110 <child>
111 <placeholder/>
112 </child>
113 </object>
114 <packing>
115 <property name="expand">False</property>
116 <property name="fill">True</property>
117 <property name="pack_type">end</property>
118 <property name="position">2</property>
119 </packing>
120 </child>
122 </object>121 </object>
123 </child>122 </child>
124 </object>123 </object>
125124
=== modified file 'data/gtkbuilder/UpdateManager.ui'
--- data/gtkbuilder/UpdateManager.ui 2012-12-18 02:30:27 +0000
+++ data/gtkbuilder/UpdateManager.ui 2013-05-21 05:43:25 +0000
@@ -1,533 +1,365 @@
1<?xml version="1.0" encoding="UTF-8"?>1<?xml version="1.0" encoding="UTF-8"?>
2<interface>2<interface>
3 <!-- interface-requires gtk+ 3.0 -->3 <!-- interface-requires gtk+ 3.0 -->
4 <object class="GtkImage" id="image-apply">4 <object class="GtkVBox" id="pane_updates_available">
5 <property name="visible">True</property>5 <property name="visible">True</property>
6 <property name="can_focus">False</property>6 <property name="can_focus">False</property>
7 <property name="stock">gtk-apply</property>7 <property name="spacing">12</property>
8 </object>
9 <object class="GtkWindow" id="window_updates_available">
10 <property name="can_focus">False</property>
11 <child>8 <child>
12 <object class="GtkVBox" id="pane_updates_available">9 <object class="GtkExpander" id="expander_details">
13 <property name="visible">True</property>10 <property name="visible">True</property>
14 <property name="can_focus">False</property>11 <property name="can_focus">True</property>
15 <property name="border_width">6</property>
16 <property name="spacing">6</property>12 <property name="spacing">6</property>
13 <property name="resize_toplevel">True</property>
17 <child>14 <child>
18 <object class="GtkVBox" id="vbox_updates">15 <object class="GtkVBox" id="vbox4">
19 <property name="visible">True</property>16 <property name="visible">True</property>
20 <property name="can_focus">False</property>17 <property name="can_focus">False</property>
21 <property name="border_width">6</property>18 <property name="spacing">6</property>
22 <property name="spacing">12</property>
23 <child>19 <child>
24 <object class="GtkHBox" id="hbox3">20 <object class="GtkScrolledWindow" id="scrolledwindow_update">
25 <property name="visible">True</property>21 <property name="visible">True</property>
26 <property name="can_focus">False</property>22 <property name="can_focus">True</property>
27 <property name="spacing">12</property>23 <property name="shadow_type">in</property>
28 <child>24 <property name="min_content_height">100</property>
29 <object class="GtkImage" id="image_logo">25 <child>
30 <property name="visible">True</property>26 <object class="GtkTreeView" id="treeview_update">
31 <property name="can_focus">False</property>27 <property name="visible">True</property>
32 <property name="yalign">0</property>28 <property name="can_focus">True</property>
33 <property name="pixel_size">48</property>29 <property name="headers_visible">False</property>
34 <property name="icon_name">system-software-update</property>30 <property name="headers_clickable">False</property>
35 </object>31 <property name="rules_hint">True</property>
36 <packing>32 <child internal-child="accessible">
37 <property name="expand">False</property>33 <object class="AtkObject" id="treeview_update-atkobject">
38 <property name="fill">False</property>34 <property name="AtkObject::accessible-name" translatable="yes">updates</property>
39 <property name="position">0</property>35 </object>
40 </packing>36 </child>
41 </child>37 <signal name="cursor-changed" handler="on_treeview_update_cursor_changed" swapped="no"/>
42 <child>38 <signal name="row-activated" handler="on_treeview_update_row_activated" swapped="no"/>
43 <object class="GtkGrid" id="grid1">39 </object>
44 <property name="visible">True</property>
45 <property name="can_focus">False</property>
46 <property name="margin_bottom">6</property>
47 <property name="row_spacing">6</property>
48 <property name="column_spacing">12</property>
49 <child>
50 <object class="GtkLabel" id="label_header">
51 <property name="visible">True</property>
52 <property name="can_focus">False</property>
53 <property name="hexpand">True</property>
54 <property name="xalign">0</property>
55 <property name="wrap">True</property>
56 <property name="max_width_chars">20</property>
57 <attributes>
58 <attribute name="weight" value="bold"/>
59 <attribute name="scale" value="1.25"/>
60 </attributes>
61 </object>
62 <packing>
63 <property name="left_attach">0</property>
64 <property name="top_attach">0</property>
65 <property name="width">1</property>
66 <property name="height">1</property>
67 </packing>
68 </child>
69 <child>
70 <object class="GtkLabel" id="label_desc">
71 <property name="can_focus">False</property>
72 <property name="no_show_all">True</property>
73 <property name="hexpand">True</property>
74 <property name="xalign">0</property>
75 <property name="wrap">True</property>
76 <property name="max_width_chars">20</property>
77 </object>
78 <packing>
79 <property name="left_attach">0</property>
80 <property name="top_attach">1</property>
81 <property name="width">1</property>
82 <property name="height">1</property>
83 </packing>
84 </child>
85 </object>
86 <packing>
87 <property name="expand">False</property>
88 <property name="fill">True</property>
89 <property name="position">1</property>
90 </packing>
91 </child>40 </child>
92 </object>41 </object>
93 <packing>42 <packing>
94 <property name="expand">False</property>43 <property name="expand">True</property>
95 <property name="fill">True</property>44 <property name="fill">True</property>
96 <property name="position">0</property>45 <property name="position">0</property>
97 </packing>46 </packing>
98 </child>47 </child>
99 <child>48 <child>
100 <object class="GtkExpander" id="expander_details">49 <object class="GtkExpander" id="expander_desc">
101 <property name="visible">True</property>50 <property name="visible">True</property>
102 <property name="can_focus">True</property>51 <property name="can_focus">True</property>
103 <property name="spacing">6</property>
104 <property name="resize_toplevel">True</property>
105 <child>52 <child>
106 <object class="GtkVBox" id="vbox4">53 <object class="GtkNotebook" id="notebook_details">
107 <property name="visible">True</property>54 <property name="visible">True</property>
108 <property name="can_focus">False</property>55 <property name="can_focus">True</property>
109 <property name="spacing">6</property>56 <property name="show_border">False</property>
110 <child>57 <child>
111 <object class="GtkScrolledWindow" id="scrolledwindow_update">58 <object class="GtkVBox" id="vbox5">
59 <property name="visible">True</property>
60 <property name="can_focus">False</property>
61 <property name="border_width">6</property>
62 <property name="spacing">6</property>
63 <child>
64 <object class="GtkScrolledWindow" id="scrolledwindow_changes">
65 <property name="visible">True</property>
66 <property name="can_focus">True</property>
67 <property name="shadow_type">in</property>
68 <child>
69 <placeholder/>
70 </child>
71 </object>
72 <packing>
73 <property name="expand">True</property>
74 <property name="fill">True</property>
75 <property name="position">0</property>
76 </packing>
77 </child>
78 </object>
79 </child>
80 <child type="tab">
81 <object class="GtkLabel" id="label8">
82 <property name="visible">True</property>
83 <property name="can_focus">False</property>
84 <property name="label" translatable="yes">Changes</property>
85 </object>
86 <packing>
87 <property name="tab_fill">False</property>
88 </packing>
89 </child>
90 <child>
91 <object class="GtkScrolledWindow" id="scrolledwindow3">
112 <property name="visible">True</property>92 <property name="visible">True</property>
113 <property name="can_focus">True</property>93 <property name="can_focus">True</property>
94 <property name="border_width">6</property>
114 <property name="shadow_type">in</property>95 <property name="shadow_type">in</property>
115 <property name="min_content_height">100</property>
116 <child>96 <child>
117 <object class="GtkTreeView" id="treeview_update">97 <object class="GtkTextView" id="textview_descr">
118 <property name="visible">True</property>98 <property name="visible">True</property>
119 <property name="can_focus">True</property>99 <property name="can_focus">True</property>
120 <property name="headers_visible">False</property>100 <property name="pixels_above_lines">6</property>
121 <property name="headers_clickable">False</property>101 <property name="editable">False</property>
122 <property name="rules_hint">True</property>102 <property name="wrap_mode">word</property>
103 <property name="left_margin">6</property>
104 <property name="right_margin">6</property>
105 <property name="cursor_visible">False</property>
106 <property name="accepts_tab">False</property>
123 <child internal-child="accessible">107 <child internal-child="accessible">
124 <object class="AtkObject" id="treeview_update-atkobject">108 <object class="AtkObject" id="textview_descr-atkobject">
125 <property name="AtkObject::accessible-name" translatable="yes">updates</property>109 <property name="AtkObject::accessible-name" translatable="yes">Description</property>
126 </object>110 </object>
127 </child>111 </child>
128 <signal name="cursor-changed" handler="on_treeview_update_cursor_changed" swapped="no"/>
129 <signal name="row-activated" handler="on_treeview_update_row_activated" swapped="no"/>
130 <child internal-child="selection">
131 <object class="GtkTreeSelection" id="treeview-selection"/>
132 </child>
133 </object>112 </object>
134 </child>113 </child>
135 </object>114 </object>
136 <packing>115 <packing>
137 <property name="expand">True</property>116 <property name="position">1</property>
138 <property name="fill">True</property>
139 <property name="position">0</property>
140 </packing>117 </packing>
141 </child>118 </child>
142 <child>119 <child type="tab">
143 <object class="GtkExpander" id="expander_desc">120 <object class="GtkLabel" id="label9">
144 <property name="visible">True</property>121 <property name="visible">True</property>
145 <property name="can_focus">True</property>122 <property name="can_focus">False</property>
146 <child>123 <property name="label" translatable="yes">Description</property>
147 <object class="GtkNotebook" id="notebook_details">124 <child internal-child="accessible">
148 <property name="visible">True</property>125 <object class="AtkObject" id="label9-atkobject">
149 <property name="can_focus">True</property>126 <property name="AtkObject::accessible-name" translatable="yes">Description</property>
150 <property name="show_border">False</property>
151 <child>
152 <object class="GtkVBox" id="vbox5">
153 <property name="visible">True</property>
154 <property name="can_focus">False</property>
155 <property name="border_width">6</property>
156 <property name="spacing">6</property>
157 <child>
158 <object class="GtkScrolledWindow" id="scrolledwindow_changes">
159 <property name="visible">True</property>
160 <property name="can_focus">True</property>
161 <property name="shadow_type">in</property>
162 <child>
163 <placeholder/>
164 </child>
165 </object>
166 <packing>
167 <property name="expand">True</property>
168 <property name="fill">True</property>
169 <property name="position">0</property>
170 </packing>
171 </child>
172 </object>
173 </child>
174 <child type="tab">
175 <object class="GtkLabel" id="label8">
176 <property name="visible">True</property>
177 <property name="can_focus">False</property>
178 <property name="label" translatable="yes">Changes</property>
179 </object>
180 <packing>
181 <property name="tab_fill">False</property>
182 </packing>
183 </child>
184 <child>
185 <object class="GtkScrolledWindow" id="scrolledwindow3">
186 <property name="visible">True</property>
187 <property name="can_focus">True</property>
188 <property name="border_width">6</property>
189 <property name="shadow_type">in</property>
190 <child>
191 <object class="GtkTextView" id="textview_descr">
192 <property name="visible">True</property>
193 <property name="can_focus">True</property>
194 <property name="pixels_above_lines">6</property>
195 <property name="editable">False</property>
196 <property name="wrap_mode">word</property>
197 <property name="left_margin">6</property>
198 <property name="right_margin">6</property>
199 <property name="cursor_visible">False</property>
200 <property name="accepts_tab">False</property>
201 <child internal-child="accessible">
202 <object class="AtkObject" id="textview_descr-atkobject">
203 <property name="AtkObject::accessible-name" translatable="yes">Description</property>
204 </object>
205 </child>
206 </object>
207 </child>
208 </object>
209 <packing>
210 <property name="position">1</property>
211 </packing>
212 </child>
213 <child type="tab">
214 <object class="GtkLabel" id="label9">
215 <property name="visible">True</property>
216 <property name="can_focus">False</property>
217 <property name="label" translatable="yes">Description</property>
218 <child internal-child="accessible">
219 <object class="AtkObject" id="label9-atkobject">
220 <property name="AtkObject::accessible-name" translatable="yes">Description</property>
221 </object>
222 </child>
223 </object>
224 <packing>
225 <property name="position">1</property>
226 <property name="tab_fill">False</property>
227 </packing>
228 </child>
229 </object>
230 </child>
231 <child type="label">
232 <object class="GtkLabel" id="label13">
233 <property name="visible">True</property>
234 <property name="can_focus">False</property>
235 <property name="label" translatable="yes">Technical description</property>
236 </object>127 </object>
237 </child>128 </child>
238 </object>129 </object>
239 <packing>130 <packing>
240 <property name="expand">False</property>
241 <property name="fill">True</property>
242 <property name="position">1</property>131 <property name="position">1</property>
132 <property name="tab_fill">False</property>
243 </packing>133 </packing>
244 </child>134 </child>
245 </object>135 </object>
246 </child>136 </child>
247 <child type="label">137 <child type="label">
248 <object class="GtkLabel" id="label12">138 <object class="GtkLabel" id="label13">
249 <property name="visible">True</property>139 <property name="visible">True</property>
250 <property name="can_focus">False</property>140 <property name="can_focus">False</property>
251 <property name="label" translatable="yes">Details of updates</property>141 <property name="label" translatable="yes">Technical description</property>
252 <property name="use_markup">True</property>
253 </object>142 </object>
254 </child>143 </child>
255 </object>144 </object>
256 <packing>145 <packing>
257 <property name="expand">True</property>146 <property name="expand">False</property>
258 <property name="fill">True</property>147 <property name="fill">True</property>
259 <property name="position">2</property>148 <property name="position">1</property>
260 </packing>149 </packing>
261 </child>150 </child>
262 <child>151 </object>
263 <object class="GtkVBox" id="vbox_alerts">152 </child>
264 <property name="can_focus">False</property>153 <child type="label">
265 <property name="spacing">3</property>154 <object class="GtkLabel" id="label12">
266 <child>155 <property name="visible">True</property>
267 <object class="GtkHBox" id="hbox_downsize">156 <property name="can_focus">False</property>
268 <property name="can_focus">False</property>157 <property name="label" translatable="yes">Details of updates</property>
269 <property name="spacing">12</property>158 <property name="use_markup">True</property>
270 <child>159 </object>
271 <object class="GtkImage" id="image_downsize">160 </child>
272 <property name="visible">True</property>161 </object>
273 <property name="can_focus">False</property>162 <packing>
274 <property name="icon_name">aptdaemon-download</property>163 <property name="expand">True</property>
275 </object>164 <property name="fill">True</property>
276 <packing>165 <property name="position">2</property>
277 <property name="expand">False</property>166 </packing>
278 <property name="fill">True</property>167 </child>
279 <property name="position">0</property>168 <child>
280 </packing>169 <object class="GtkVBox" id="vbox_alerts">
281 </child>170 <property name="can_focus">False</property>
282 <child>171 <property name="spacing">3</property>
283 <object class="GtkLabel" id="label_downsize">172 <child>
284 <property name="visible">True</property>173 <object class="GtkHBox" id="hbox_downsize">
285 <property name="can_focus">False</property>174 <property name="can_focus">False</property>
286 <property name="xalign">0</property>175 <property name="spacing">12</property>
287 <property name="label">176 <child>
177 <object class="GtkImage" id="image_downsize">
178 <property name="visible">True</property>
179 <property name="can_focus">False</property>
180 <property name="icon_name">aptdaemon-download</property>
181 </object>
182 <packing>
183 <property name="expand">False</property>
184 <property name="fill">True</property>
185 <property name="position">0</property>
186 </packing>
187 </child>
188 <child>
189 <object class="GtkLabel" id="label_downsize">
190 <property name="visible">True</property>
191 <property name="can_focus">False</property>
192 <property name="xalign">0</property>
193 <property name="label">
288</property>194</property>
289 <property name="wrap">True</property>195 <property name="wrap">True</property>
290 </object>
291 <packing>
292 <property name="expand">True</property>
293 <property name="fill">True</property>
294 <property name="position">1</property>
295 </packing>
296 </child>
297 </object>
298 <packing>
299 <property name="expand">False</property>
300 <property name="fill">False</property>
301 <property name="position">0</property>
302 </packing>
303 </child>
304 <child>
305 <object class="GtkHBox" id="hbox_roaming">
306 <property name="can_focus">False</property>
307 <property name="spacing">12</property>
308 <child>
309 <object class="GtkImage" id="image_roaming">
310 <property name="visible">True</property>
311 <property name="can_focus">False</property>
312 <property name="icon_name">dialog-warning</property>
313 </object>
314 <packing>
315 <property name="expand">False</property>
316 <property name="fill">True</property>
317 <property name="position">0</property>
318 </packing>
319 </child>
320 <child>
321 <object class="GtkLabel" id="label_roaming">
322 <property name="visible">True</property>
323 <property name="can_focus">False</property>
324 <property name="xalign">0</property>
325 <property name="label" translatable="yes">You are connected via roaming and may be charged for the data consumed by this update.</property>
326 <property name="wrap">True</property>
327 </object>
328 <packing>
329 <property name="expand">True</property>
330 <property name="fill">True</property>
331 <property name="position">1</property>
332 </packing>
333 </child>
334 </object>
335 <packing>
336 <property name="expand">False</property>
337 <property name="fill">False</property>
338 <property name="position">1</property>
339 </packing>
340 </child>
341 <child>
342 <object class="GtkHBox" id="hbox_on_3g">
343 <property name="can_focus">False</property>
344 <property name="spacing">12</property>
345 <child>
346 <object class="GtkImage" id="image_on_3g">
347 <property name="visible">True</property>
348 <property name="can_focus">False</property>
349 <property name="icon_name">modem</property>
350 </object>
351 <packing>
352 <property name="expand">False</property>
353 <property name="fill">True</property>
354 <property name="position">0</property>
355 </packing>
356 </child>
357 <child>
358 <object class="GtkLabel" id="label_on_3g">
359 <property name="visible">True</property>
360 <property name="can_focus">False</property>
361 <property name="xalign">0</property>
362 <property name="label" translatable="yes">You may want to wait until you’re not using a mobile broadband connection.</property>
363 <property name="wrap">True</property>
364 </object>
365 <packing>
366 <property name="expand">True</property>
367 <property name="fill">True</property>
368 <property name="position">1</property>
369 </packing>
370 </child>
371 </object>
372 <packing>
373 <property name="expand">False</property>
374 <property name="fill">False</property>
375 <property name="position">2</property>
376 </packing>
377 </child>
378 <child>
379 <object class="GtkHBox" id="hbox_battery">
380 <property name="can_focus">False</property>
381 <property name="spacing">12</property>
382 <child>
383 <object class="GtkImage" id="image_battery">
384 <property name="visible">True</property>
385 <property name="can_focus">False</property>
386 <property name="icon_name">battery</property>
387 </object>
388 <packing>
389 <property name="expand">False</property>
390 <property name="fill">True</property>
391 <property name="position">0</property>
392 </packing>
393 </child>
394 <child>
395 <object class="GtkLabel" id="label_battery">
396 <property name="visible">True</property>
397 <property name="can_focus">False</property>
398 <property name="xalign">0</property>
399 <property name="label" translatable="yes">It’s safer to connect the computer to AC power before updating.</property>
400 <property name="wrap">True</property>
401 </object>
402 <packing>
403 <property name="expand">True</property>
404 <property name="fill">True</property>
405 <property name="position">1</property>
406 </packing>
407 </child>
408 </object>
409 <packing>
410 <property name="expand">False</property>
411 <property name="fill">False</property>
412 <property name="position">3</property>
413 </packing>
414 </child>
415 <child>
416 <object class="GtkHBox" id="hbox_offline">
417 <property name="can_focus">False</property>
418 <property name="spacing">12</property>
419 <child>
420 <object class="GtkImage" id="image_offline">
421 <property name="visible">True</property>
422 <property name="can_focus">False</property>
423 <property name="icon_name">network-offline</property>
424 </object>
425 <packing>
426 <property name="expand">False</property>
427 <property name="fill">True</property>
428 <property name="position">0</property>
429 </packing>
430 </child>
431 <child>
432 <object class="GtkLabel" id="label_offline">
433 <property name="visible">True</property>
434 <property name="can_focus">False</property>
435 <property name="xalign">0</property>
436 <property name="wrap">True</property>
437 </object>
438 <packing>
439 <property name="expand">True</property>
440 <property name="fill">True</property>
441 <property name="position">1</property>
442 </packing>
443 </child>
444 </object>
445 <packing>
446 <property name="expand">False</property>
447 <property name="fill">False</property>
448 <property name="position">4</property>
449 </packing>
450 </child>
451 </object>196 </object>
452 <packing>197 <packing>
453 <property name="expand">False</property>198 <property name="expand">True</property>
454 <property name="fill">True</property>199 <property name="fill">True</property>
455 <property name="position">3</property>200 <property name="position">1</property>
456 </packing>201 </packing>
457 </child>202 </child>
458 </object>203 </object>
459 <packing>204 <packing>
460 <property name="expand">True</property>205 <property name="expand">False</property>
461 <property name="fill">True</property>206 <property name="fill">False</property>
462 <property name="position">0</property>207 <property name="position">0</property>
463 </packing>208 </packing>
464 </child>209 </child>
465 <child>210 <child>
466 <object class="GtkHButtonBox" id="hbuttonbox6">211 <object class="GtkHBox" id="hbox_roaming">
467 <property name="visible">True</property>
468 <property name="can_focus">False</property>212 <property name="can_focus">False</property>
469 <property name="border_width">5</property>213 <property name="spacing">12</property>
470 <property name="spacing">6</property>
471 <property name="layout_style">end</property>
472 <child>214 <child>
473 <object class="GtkButton" id="button_settings">215 <object class="GtkImage" id="image_roaming">
474 <property name="label" translatable="yes">_Settings...</property>
475 <property name="visible">True</property>216 <property name="visible">True</property>
476 <property name="can_focus">True</property>217 <property name="can_focus">False</property>
477 <property name="receives_default">True</property>218 <property name="icon_name">dialog-warning</property>
478 <property name="use_underline">True</property>
479 <signal name="clicked" handler="on_button_settings_clicked" swapped="no"/>
480 </object>219 </object>
481 <packing>220 <packing>
482 <property name="expand">False</property>221 <property name="expand">False</property>
483 <property name="fill">False</property>222 <property name="fill">True</property>
484 <property name="position">0</property>223 <property name="position">0</property>
485 <property name="secondary">True</property>224 </packing>
486 </packing>225 </child>
487 </child>226 <child>
488 <child>227 <object class="GtkLabel" id="label_roaming">
489 <object class="GtkButton" id="button_close">228 <property name="visible">True</property>
490 <property name="label">gtk-cancel</property>229 <property name="can_focus">False</property>
491 <property name="visible">True</property>230 <property name="xalign">0</property>
492 <property name="can_focus">True</property>231 <property name="label" translatable="yes">You are connected via roaming and may be charged for the data consumed by this update.</property>
493 <property name="can_default">True</property>232 <property name="wrap">True</property>
494 <property name="receives_default">True</property>233 </object>
495 <property name="use_stock">True</property>234 <packing>
496 <accelerator key="W" signal="clicked" modifiers="GDK_CONTROL_MASK"/>235 <property name="expand">True</property>
497 <accelerator key="Q" signal="clicked" modifiers="GDK_CONTROL_MASK"/>
498 </object>
499 <packing>
500 <property name="expand">False</property>
501 <property name="fill">False</property>
502 <property name="position">2</property>
503 </packing>
504 </child>
505 <child>
506 <object class="GtkButton" id="button_install">
507 <property name="label" translatable="yes">_Install Now</property>
508 <property name="visible">True</property>
509 <property name="can_focus">True</property>
510 <property name="can_default">True</property>
511 <property name="has_default">True</property>
512 <property name="receives_default">True</property>
513 <property name="image">image-apply</property>
514 <property name="use_underline">True</property>
515 <signal name="clicked" handler="on_button_install_clicked" swapped="no"/>
516 </object>
517 <packing>
518 <property name="expand">False</property>
519 <property name="fill">True</property>236 <property name="fill">True</property>
520 <property name="position">3</property>237 <property name="position">1</property>
521 </packing>238 </packing>
522 </child>239 </child>
523 </object>240 </object>
524 <packing>241 <packing>
525 <property name="expand">False</property>242 <property name="expand">False</property>
526 <property name="fill">True</property>243 <property name="fill">False</property>
527 <property name="position">1</property>244 <property name="position">1</property>
528 </packing>245 </packing>
529 </child>246 </child>
247 <child>
248 <object class="GtkHBox" id="hbox_on_3g">
249 <property name="can_focus">False</property>
250 <property name="spacing">12</property>
251 <child>
252 <object class="GtkImage" id="image_on_3g">
253 <property name="visible">True</property>
254 <property name="can_focus">False</property>
255 <property name="icon_name">modem</property>
256 </object>
257 <packing>
258 <property name="expand">False</property>
259 <property name="fill">True</property>
260 <property name="position">0</property>
261 </packing>
262 </child>
263 <child>
264 <object class="GtkLabel" id="label_on_3g">
265 <property name="visible">True</property>
266 <property name="can_focus">False</property>
267 <property name="xalign">0</property>
268 <property name="label" translatable="yes">You may want to wait until you’re not using a mobile broadband connection.</property>
269 <property name="wrap">True</property>
270 </object>
271 <packing>
272 <property name="expand">True</property>
273 <property name="fill">True</property>
274 <property name="position">1</property>
275 </packing>
276 </child>
277 </object>
278 <packing>
279 <property name="expand">False</property>
280 <property name="fill">False</property>
281 <property name="position">2</property>
282 </packing>
283 </child>
284 <child>
285 <object class="GtkHBox" id="hbox_battery">
286 <property name="can_focus">False</property>
287 <property name="spacing">12</property>
288 <child>
289 <object class="GtkImage" id="image_battery">
290 <property name="visible">True</property>
291 <property name="can_focus">False</property>
292 <property name="icon_name">battery</property>
293 </object>
294 <packing>
295 <property name="expand">False</property>
296 <property name="fill">True</property>
297 <property name="position">0</property>
298 </packing>
299 </child>
300 <child>
301 <object class="GtkLabel" id="label_battery">
302 <property name="visible">True</property>
303 <property name="can_focus">False</property>
304 <property name="xalign">0</property>
305 <property name="label" translatable="yes">It’s safer to connect the computer to AC power before updating.</property>
306 <property name="wrap">True</property>
307 </object>
308 <packing>
309 <property name="expand">True</property>
310 <property name="fill">True</property>
311 <property name="position">1</property>
312 </packing>
313 </child>
314 </object>
315 <packing>
316 <property name="expand">False</property>
317 <property name="fill">False</property>
318 <property name="position">3</property>
319 </packing>
320 </child>
321 <child>
322 <object class="GtkHBox" id="hbox_offline">
323 <property name="can_focus">False</property>
324 <property name="spacing">12</property>
325 <child>
326 <object class="GtkImage" id="image_offline">
327 <property name="visible">True</property>
328 <property name="can_focus">False</property>
329 <property name="icon_name">network-offline</property>
330 </object>
331 <packing>
332 <property name="expand">False</property>
333 <property name="fill">True</property>
334 <property name="position">0</property>
335 </packing>
336 </child>
337 <child>
338 <object class="GtkLabel" id="label_offline">
339 <property name="visible">True</property>
340 <property name="can_focus">False</property>
341 <property name="xalign">0</property>
342 <property name="wrap">True</property>
343 </object>
344 <packing>
345 <property name="expand">True</property>
346 <property name="fill">True</property>
347 <property name="position">1</property>
348 </packing>
349 </child>
350 </object>
351 <packing>
352 <property name="expand">False</property>
353 <property name="fill">False</property>
354 <property name="position">4</property>
355 </packing>
356 </child>
530 </object>357 </object>
358 <packing>
359 <property name="expand">False</property>
360 <property name="fill">True</property>
361 <property name="position">3</property>
362 </packing>
531 </child>363 </child>
532 </object>364 </object>
533</interface>365</interface>
534366
=== modified file 'debian/update-manager.install'
--- debian/update-manager.install 2012-11-19 16:33:28 +0000
+++ debian/update-manager.install 2013-05-21 05:43:25 +0000
@@ -8,10 +8,7 @@
8debian/tmp/usr/share/applications/update-manager.desktop8debian/tmp/usr/share/applications/update-manager.desktop
9debian/tmp/usr/lib/python3*/dist-packages/UpdateManager/ChangelogViewer.py9debian/tmp/usr/lib/python3*/dist-packages/UpdateManager/ChangelogViewer.py
10debian/tmp/usr/lib/python3*/dist-packages/UpdateManager/Dialogs.py10debian/tmp/usr/lib/python3*/dist-packages/UpdateManager/Dialogs.py
11debian/tmp/usr/lib/python3*/dist-packages/UpdateManager/InstallProgress.py
12debian/tmp/usr/lib/python3*/dist-packages/UpdateManager/MetaReleaseGObject.py11debian/tmp/usr/lib/python3*/dist-packages/UpdateManager/MetaReleaseGObject.py
13debian/tmp/usr/lib/python3*/dist-packages/UpdateManager/UpdateManager.py12debian/tmp/usr/lib/python3*/dist-packages/UpdateManager/UpdateManager.py
14debian/tmp/usr/lib/python3*/dist-packages/UpdateManager/UpdateProgress.py
15debian/tmp/usr/lib/python3*/dist-packages/UpdateManager/UpdatesAvailable.py13debian/tmp/usr/lib/python3*/dist-packages/UpdateManager/UpdatesAvailable.py
16debian/tmp/usr/lib/python3*/dist-packages/UpdateManager/SimpleGtkbuilderApp.py
17debian/tmp/usr/lib/python3*/dist-packages/UpdateManager/HelpViewer.py14debian/tmp/usr/lib/python3*/dist-packages/UpdateManager/HelpViewer.py
1815
=== modified file 'po/POTFILES.in'
--- po/POTFILES.in 2012-09-25 07:36:24 +0000
+++ po/POTFILES.in 2013-05-21 05:43:25 +0000
@@ -4,9 +4,7 @@
4UpdateManager/ChangelogViewer.py4UpdateManager/ChangelogViewer.py
5UpdateManager/MetaReleaseGObject.py5UpdateManager/MetaReleaseGObject.py
6UpdateManager/Dialogs.py6UpdateManager/Dialogs.py
7UpdateManager/InstallProgress.py
8UpdateManager/UpdateManager.py7UpdateManager/UpdateManager.py
9UpdateManager/UpdateProgress.py
10UpdateManager/UpdatesAvailable.py8UpdateManager/UpdatesAvailable.py
11UpdateManager/UnitySupport.py9UpdateManager/UnitySupport.py
12UpdateManagerText/UpdateManagerText.py10UpdateManagerText/UpdateManagerText.py
1311
=== modified file 'po/update-manager.pot'
--- po/update-manager.pot 2012-06-25 16:25:51 +0000
+++ po/update-manager.pot 2013-05-21 05:43:25 +0000
@@ -8,7 +8,7 @@
8msgstr ""8msgstr ""
9"Project-Id-Version: PACKAGE VERSION\n"9"Project-Id-Version: PACKAGE VERSION\n"
10"Report-Msgid-Bugs-To: \n"10"Report-Msgid-Bugs-To: \n"
11"POT-Creation-Date: 2012-06-25 12:22-0400\n"11"POT-Creation-Date: 2013-05-20 10:14-0700\n"
12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"12"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"13"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14"Language-Team: LANGUAGE <LL@li.org>\n"14"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -18,176 +18,235 @@
18"Content-Transfer-Encoding: 8bit\n"18"Content-Transfer-Encoding: 8bit\n"
19"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"19"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
2020
21#: ../UpdateManager/backend/InstallBackendSynaptic.py:6421#: ../UpdateManager/backend/InstallBackendAptdaemon.py:68
22msgid "Checking for updates…"
23msgstr ""
24
25#: ../UpdateManager/backend/InstallBackendAptdaemon.py:93
26msgid "Installing updates…"
27msgstr ""
28
29#: ../UpdateManager/backend/InstallBackendSynaptic.py:37
22msgid "Please wait, this can take some time."30msgid "Please wait, this can take some time."
23msgstr ""31msgstr ""
2432
25#: ../UpdateManager/backend/InstallBackendSynaptic.py:6633#: ../UpdateManager/backend/InstallBackendSynaptic.py:39
26msgid "Update is complete"34msgid "Update is complete"
27msgstr ""35msgstr ""
2836
29#: ../UpdateManager/DistUpgradeFetcher.py:11437#: ../UpdateManager/ChangelogViewer.py:79
30#: ../UpdateManager/DistUpgradeFetcherKDE.py:109
31msgid "Could not find the release notes"
32msgstr ""
33
34#: ../UpdateManager/DistUpgradeFetcher.py:115
35#: ../UpdateManager/DistUpgradeFetcherKDE.py:110
36msgid "The server may be overloaded. "
37msgstr ""
38
39#: ../UpdateManager/DistUpgradeFetcher.py:125
40#: ../UpdateManager/DistUpgradeFetcherKDE.py:114
41msgid "Could not download the release notes"
42msgstr ""
43
44#: ../UpdateManager/DistUpgradeFetcher.py:126
45#: ../UpdateManager/DistUpgradeFetcherKDE.py:115
46msgid "Please check your internet connection."
47msgstr ""
48
49#: ../UpdateManager/DistUpgradeFetcherKDE.py:68
50#: ../UpdateManager/DistUpgradeFetcherKDE.py:91
51msgid "Upgrade"
52msgstr ""
53
54#: ../UpdateManager/DistUpgradeFetcherKDE.py:95
55#: ../data/gtkbuilder/UpdateManager.ui.h:15
56msgid "Release Notes"
57msgstr ""
58
59#: ../UpdateManager/DistUpgradeFetcherKDE.py:134
60#: ../UpdateManager/DistUpgradeFetcherKDE.py:148
61#: ../UpdateManager/DistUpgradeFetcherKDE.py:150
62msgid "Downloading additional package files..."
63msgstr ""
64
65#: ../UpdateManager/DistUpgradeFetcherKDE.py:148
66#, python-format
67msgid "File %s of %s at %sB/s"
68msgstr ""
69
70#: ../UpdateManager/DistUpgradeFetcherKDE.py:150
71#, python-format
72msgid "File %s of %s"
73msgstr ""
74
75#: ../UpdateManager/DistUpgradeFetcherKDE.py:155
76#, python-format
77msgid "Please insert '%s' into the drive '%s'"
78msgstr ""
79
80#. change = QMessageBox.question(None, _("Media Change"), msg, QMessageBox.Ok, QMessageBox.Cancel)
81#: ../UpdateManager/DistUpgradeFetcherKDE.py:157
82msgid "Media Change"
83msgstr ""
84
85#: ../UpdateManager/ChangelogViewer.py:75
86msgid "Open Link in Browser"38msgid "Open Link in Browser"
87msgstr ""39msgstr ""
8840
89#: ../UpdateManager/ChangelogViewer.py:7841#: ../UpdateManager/ChangelogViewer.py:83
90msgid "Copy Link to Clipboard"42msgid "Copy Link to Clipboard"
91msgstr ""43msgstr ""
9244
93#: ../UpdateManager/GtkProgress.py:16245#: ../UpdateManager/Dialogs.py:120
94#, python-format46msgid "Settings…"
95msgid "Downloading file %(current)li of %(total)li with %(speed)s/s"47msgstr ""
96msgstr ""48
9749#: ../UpdateManager/Dialogs.py:148 ../UpdateManager/UpdateManager.py:244
98#: ../UpdateManager/GtkProgress.py:16750msgid "You stopped the check for updates."
99#, python-format51msgstr ""
100msgid "Downloading file %(current)li of %(total)li"52
101msgstr ""53#: ../UpdateManager/Dialogs.py:150
10254msgid "_Check Again"
103#: ../UpdateManager/UpdateManager.py:10055msgstr ""
104msgid "Your Ubuntu release is not supported anymore."56
105msgstr ""57#: ../UpdateManager/Dialogs.py:161
10658msgid "No software updates are available."
107#: ../UpdateManager/UpdateManager.py:10159msgstr ""
108msgid ""60
109"You will not get any further security fixes or critical updates. Please "61#: ../UpdateManager/Dialogs.py:163 ../UpdateManager/Dialogs.py:172
110"upgrade to a later version of Ubuntu."62msgid "The software on this computer is up to date."
111msgstr ""63msgstr ""
11264
113#: ../UpdateManager/UpdateManager.py:10965#. Translators: these are Ubuntu version names like "Ubuntu 12.04"
114msgid "Upgrade information"66#: ../UpdateManager/Dialogs.py:174
115msgstr ""67#, python-format
11668msgid "However, %s %s is now available (you have %s)."
117#: ../UpdateManager/UpdateManager.py:20469msgstr ""
118#: ../UpdateManagerText/UpdateManagerText.py:3570
71#: ../UpdateManager/Dialogs.py:179
72msgid "Upgrade…"
73msgstr ""
74
75#. Translators: this is an Ubuntu version name like "Ubuntu 12.04"
76#: ../UpdateManager/Dialogs.py:201
77#, python-format
78msgid "Software updates are no longer provided for %s %s."
79msgstr ""
80
81#. Translators: this is an Ubuntu version name like "Ubuntu 12.04"
82#: ../UpdateManager/Dialogs.py:205
83#, python-format
84msgid "To stay secure, you should upgrade to %s %s."
85msgstr ""
86
87#: ../UpdateManager/Dialogs.py:218
88msgid "Not all updates can be installed"
89msgstr ""
90
91#: ../UpdateManager/Dialogs.py:220
92msgid ""
93"Run a partial upgrade, to install as many updates as possible.\n"
94"\n"
95" This can be caused by:\n"
96" * A previous upgrade which didn't complete\n"
97" * Problems with some of the installed software\n"
98" * Unofficial software packages not provided by Ubuntu\n"
99" * Normal changes of a pre-release version of Ubuntu"
100msgstr ""
101
102#: ../UpdateManager/Dialogs.py:228
103msgid "_Partial Upgrade"
104msgstr ""
105
106#: ../UpdateManager/Dialogs.py:229
107msgid "_Continue"
108msgstr ""
109
110#: ../UpdateManager/Dialogs.py:265
111msgid "_Try Again"
112msgstr ""
113
114#: ../UpdateManager/Dialogs.py:279
115msgid "The computer needs to restart to finish installing updates."
116msgstr ""
117
118#: ../UpdateManager/Dialogs.py:280
119msgid "_Restart"
120msgstr ""
121
122#. Basic GTK+ parameters
123#: ../UpdateManager/UpdateManager.py:85 ../data/update-manager.desktop.in.h:1
124msgid "Software Updater"
125msgstr ""
126
127#: ../UpdateManager/UpdateManager.py:242
128msgid "Some software couldn’t be checked for updates."
129msgstr ""
130
131#: ../UpdateManager/UpdateManager.py:245
132msgid "Updated software is available from a previous check."
133msgstr ""
134
135#. we assert a clean cache
136#: ../UpdateManager/UpdateManager.py:323
137msgid "Software index is broken"
138msgstr ""
139
140#: ../UpdateManager/UpdateManager.py:324
141msgid ""
142"It is impossible to install or remove any software. Please use the package "
143"manager \"Synaptic\" or run \"sudo apt-get install -f\" in a terminal to fix "
144"this issue at first."
145msgstr ""
146
147#: ../UpdateManager/UpdateManager.py:330
148msgid "Could not initialize the package information"
149msgstr ""
150
151#: ../UpdateManager/UpdateManager.py:331
152msgid ""
153"An unresolvable problem occurred while initializing the package "
154"information.\n"
155"\n"
156"Please report this bug against the 'update-manager' package and include the "
157"following error message:\n"
158msgstr ""
159
160#: ../UpdateManager/UpdateManager.py:348
161msgid "Could not calculate the upgrade"
162msgstr ""
163
164#: ../UpdateManager/UpdateManager.py:349
165msgid ""
166"An unresolvable problem occurred while calculating the upgrade.\n"
167"\n"
168"Please report this bug against the 'update-manager' package and include the "
169"following error message:\n"
170msgstr ""
171
172#: ../UpdateManager/UpdatesAvailable.py:248
173msgid "Install Now"
174msgstr ""
175
176#: ../UpdateManager/UpdatesAvailable.py:278
177#: ../UpdateManagerText/UpdateManagerText.py:36
119msgid "Install"178msgid "Install"
120msgstr ""179msgstr ""
121180
122#: ../UpdateManager/UpdateManager.py:206181#: ../UpdateManager/UpdatesAvailable.py:312
123msgid "Name"182msgid "Download"
183msgstr ""
184
185#: ../UpdateManager/UpdatesAvailable.py:372
186msgid "_Remind Me Later"
124msgstr ""187msgstr ""
125188
126#. upload_archive = version_match.group(2).strip()189#. upload_archive = version_match.group(2).strip()
127#: ../UpdateManager/UpdateManager.py:359190#: ../UpdateManager/UpdatesAvailable.py:506
128#, python-format191#, python-format
129msgid "Version %s: \n"192msgid "Version %s: \n"
130msgstr ""193msgstr ""
131194
132#: ../UpdateManager/UpdateManager.py:417195#: ../UpdateManager/UpdatesAvailable.py:569
133msgid ""196msgid ""
134"No network connection detected, you can not download changelog information."197"No network connection detected, you can not download changelog information."
135msgstr ""198msgstr ""
136199
137#: ../UpdateManager/UpdateManager.py:427200#: ../UpdateManager/UpdatesAvailable.py:579
138msgid "Downloading list of changes..."201msgid "Downloading list of changes..."
139msgstr ""202msgstr ""
140203
141#: ../UpdateManager/UpdateManager.py:471204#: ../UpdateManager/UpdatesAvailable.py:623
142msgid "_Deselect All"205msgid "_Deselect All"
143msgstr ""206msgstr ""
144207
145#: ../UpdateManager/UpdateManager.py:477208#: ../UpdateManager/UpdatesAvailable.py:629
146msgid "Select _All"209msgid "Select _All"
147msgstr ""210msgstr ""
148211
149#: ../UpdateManager/UpdateManager.py:536212#: ../UpdateManager/UpdatesAvailable.py:704
150#, python-format213#, python-format
151msgid "%s will be downloaded."214msgid "%s will be downloaded."
152msgstr ""215msgstr ""
153216
154#: ../UpdateManager/UpdateManager.py:548217#: ../UpdateManager/UpdatesAvailable.py:718
155msgid "The update has already been downloaded."218msgid "The update has already been downloaded."
156msgid_plural "The updates have already been downloaded."219msgid_plural "The updates have already been downloaded."
157msgstr[0] ""220msgstr[0] ""
158msgstr[1] ""221msgstr[1] ""
159222
160#: ../UpdateManager/UpdateManager.py:553223#: ../UpdateManager/UpdatesAvailable.py:724
161msgid "There are no updates to install."224msgid "There are no updates to install."
162msgstr ""225msgstr ""
163226
164#: ../UpdateManager/UpdateManager.py:562227#: ../UpdateManager/UpdatesAvailable.py:733
165msgid "Unknown download size."228msgid "Unknown download size."
166msgstr ""229msgstr ""
167230
168#: ../UpdateManager/UpdateManager.py:577231#: ../UpdateManager/UpdatesAvailable.py:759
169msgid "The software on this computer is up to date."
170msgstr ""
171
172#: ../UpdateManager/UpdateManager.py:591
173#, python-format232#, python-format
174msgid ""233msgid ""
175"Updated software has been issued since %s was released. Do you want to "234"Updated software has been issued since %s %s was released. Do you want to "
176"install it now?"235"install it now?"
177msgstr ""236msgstr ""
178237
179#: ../UpdateManager/UpdateManager.py:594238#: ../UpdateManager/UpdatesAvailable.py:764
180msgid ""239msgid ""
181"Updated software is available for this computer. Do you want to install it "240"Updated software is available for this computer. Do you want to install it "
182"now?"241"now?"
183msgstr ""242msgstr ""
184243
185#. print("on_button_install_clicked")244#. print("on_button_install_clicked")
186#: ../UpdateManager/UpdateManager.py:645245#: ../UpdateManager/UpdatesAvailable.py:794
187msgid "Not enough free disk space"246msgid "Not enough free disk space"
188msgstr ""247msgstr ""
189248
190#: ../UpdateManager/UpdateManager.py:646249#: ../UpdateManager/UpdatesAvailable.py:795
191#, python-format250#, python-format
192msgid ""251msgid ""
193"The upgrade needs a total of %s free space on disk '%s'. Please free at "252"The upgrade needs a total of %s free space on disk '%s'. Please free at "
@@ -195,125 +254,46 @@
195"temporary packages of former installations using 'sudo apt-get clean'."254"temporary packages of former installations using 'sudo apt-get clean'."
196msgstr ""255msgstr ""
197256
198#: ../UpdateManager/UpdateManager.py:671257#: ../UpdateManager/UpdatesAvailable.py:821
199msgid ""
200"The computer needs to restart to finish installing updates. Please save your "
201"work before continuing."
202msgstr ""
203
204#: ../UpdateManager/UpdateManager.py:728
205msgid "Reading package information"
206msgstr ""
207
208#: ../UpdateManager/UpdateManager.py:743
209msgid "Connecting..."258msgid "Connecting..."
210msgstr ""259msgstr ""
211260
212#: ../UpdateManager/UpdateManager.py:758261#: ../UpdateManager/UpdatesAvailable.py:837
213msgid "You may not be able to check for updates or download new updates."262msgid "You may not be able to check for updates or download new updates."
214msgstr ""263msgstr ""
215264
216#: ../UpdateManager/UpdateManager.py:880265#: ../UpdateManager/UpdatesAvailable.py:986
217msgid "Could not initialize the package information"266msgid "Security updates"
218msgstr ""267msgstr ""
219268
220#: ../UpdateManager/UpdateManager.py:881269#: ../UpdateManager/UpdatesAvailable.py:989
221msgid ""270msgid "Other updates"
222"An unresolvable problem occurred while initializing the package "271msgstr ""
223"information.\n"272
224"\n"273#: ../UpdateManager/UnitySupport.py:67
225"Please report this bug against the 'update-manager' package and include the "
226"following error message:\n"
227msgstr ""
228
229#: ../UpdateManager/UpdateManager.py:905
230msgid "Could not calculate the upgrade"
231msgstr ""
232
233#: ../UpdateManager/UpdateManager.py:906
234msgid ""
235"An unresolvable problem occurred while calculating the upgrade.\n"
236"\n"
237"Please report this bug against the 'update-manager' package and include the "
238"following error message:"
239msgstr ""
240
241#: ../UpdateManager/UpdateManager.py:930
242msgid " (New install)"
243msgstr ""
244
245#. TRANSLATORS: the b stands for Bytes
246#: ../UpdateManager/UpdateManager.py:937
247#, python-format
248msgid "(Size: %s)"
249msgstr ""
250
251#: ../UpdateManager/UpdateManager.py:941
252#, python-format
253msgid "From version %(old_version)s to %(new_version)s"
254msgstr ""
255
256#: ../UpdateManager/UpdateManager.py:945
257#, python-format
258msgid "Version %s"
259msgstr ""
260
261#: ../UpdateManager/UpdateManager.py:978
262msgid "Release upgrade not possible right now"
263msgstr ""
264
265#: ../UpdateManager/UpdateManager.py:979
266#, python-format
267msgid ""
268"The release upgrade can not be performed currently, please try again later. "
269"The server reported: '%s'"
270msgstr ""
271
272#: ../UpdateManager/UpdateManager.py:981
273msgid "Downloading the release upgrade tool"
274msgstr ""
275
276#: ../UpdateManager/UpdateManager.py:988
277#, python-format
278msgid "<b>New Ubuntu release '%s' is available</b>"
279msgstr ""
280
281#. we assert a clean cache
282#: ../UpdateManager/UpdateManager.py:1027
283msgid "Software index is broken"
284msgstr ""
285
286#: ../UpdateManager/UpdateManager.py:1028
287msgid ""
288"It is impossible to install or remove any software. Please use the package "
289"manager \"Synaptic\" or run \"sudo apt-get install -f\" in a terminal to fix "
290"this issue at first."
291msgstr ""
292
293#: ../UpdateManager/UnitySupport.py:57
294msgid "Install All Available Updates"274msgid "Install All Available Updates"
295msgstr ""275msgstr ""
296276
297#: ../UpdateManagerText/UpdateManagerText.py:34277#: ../UpdateManagerText/UpdateManagerText.py:35
298msgid "Cancel"278msgid "Cancel"
299msgstr ""279msgstr ""
300280
301#: ../UpdateManagerText/UpdateManagerText.py:37281#: ../UpdateManagerText/UpdateManagerText.py:38
302msgid "Changelog"282msgid "Changelog"
303msgstr ""283msgstr ""
304284
305#: ../UpdateManagerText/UpdateManagerText.py:40285#: ../UpdateManagerText/UpdateManagerText.py:41
306msgid "Updates"286msgid "Updates"
307msgstr ""287msgstr ""
308288
309#: ../UpdateManagerText/UpdateManagerText.py:53289#: ../UpdateManagerText/UpdateManagerText.py:54
310msgid "Building Updates List"290msgid "Building Updates List"
311msgstr ""291msgstr ""
312292
313#: ../UpdateManagerText/UpdateManagerText.py:56293#: ../UpdateManagerText/UpdateManagerText.py:57
314msgid ""294msgid ""
315"\n"295"\n"
316"A normal upgrade can not be calculated, please run: \n"296"A normal upgrade can not be calculated, please run:\n"
317" sudo apt-get dist-upgrade\n"297" sudo apt-get dist-upgrade\n"
318"\n"298"\n"
319"\n"299"\n"
@@ -324,35 +304,30 @@
324" * Normal changes of a pre-release version of Ubuntu"304" * Normal changes of a pre-release version of Ubuntu"
325msgstr ""305msgstr ""
326306
327#: ../UpdateManagerText/UpdateManagerText.py:125307#: ../UpdateManagerText/UpdateManagerText.py:127
328msgid "Downloading changelog"308msgid "Downloading changelog"
329msgstr ""309msgstr ""
330310
331#: ../UpdateManager/Core/MyCache.py:147311#: ../UpdateManager/Core/MyCache.py:333
332#, python-format
333msgid "Other updates (%s)"
334msgstr ""
335
336#: ../UpdateManager/Core/MyCache.py:325
337msgid "This update does not come from a source that supports changelogs."312msgid "This update does not come from a source that supports changelogs."
338msgstr ""313msgstr ""
339314
340#: ../UpdateManager/Core/MyCache.py:331 ../UpdateManager/Core/MyCache.py:359315#: ../UpdateManager/Core/MyCache.py:339 ../UpdateManager/Core/MyCache.py:376
341msgid ""316msgid ""
342"Failed to download the list of changes. \n"317"Failed to download the list of changes. \n"
343"Please check your Internet connection."318"Please check your Internet connection."
344msgstr ""319msgstr ""
345320
346#: ../UpdateManager/Core/MyCache.py:338321#: ../UpdateManager/Core/MyCache.py:346
347#, python-format322#, python-format
348msgid ""323msgid ""
349"Changes for the versions:\n"324"Changes for %s versions:\n"
350"Installed version: %s\n"325"Installed version: %s\n"
351"Available version: %s\n"326"Available version: %s\n"
352"\n"327"\n"
353msgstr ""328msgstr ""
354329
355#: ../UpdateManager/Core/MyCache.py:348330#: ../UpdateManager/Core/MyCache.py:362
356#, python-format331#, python-format
357msgid ""332msgid ""
358"The changelog does not contain any relevant changes.\n"333"The changelog does not contain any relevant changes.\n"
@@ -361,7 +336,7 @@
361"until the changes become available or try again later."336"until the changes become available or try again later."
362msgstr ""337msgstr ""
363338
364#: ../UpdateManager/Core/MyCache.py:353339#: ../UpdateManager/Core/MyCache.py:369
365#, python-format340#, python-format
366msgid ""341msgid ""
367"The list of changes is not available yet.\n"342"The list of changes is not available yet.\n"
@@ -370,124 +345,15 @@
370"until the changes become available or try again later."345"until the changes become available or try again later."
371msgstr ""346msgstr ""
372347
373#: ../UpdateManager/Core/UpdateList.py:51348#. Translators: the %s is a distro name, like 'Ubuntu' and 'base' as in
374msgid "Failed to detect distribution"349#. the core components and packages.
375msgstr ""350#: ../UpdateManager/Core/UpdateList.py:167
376351#, python-format
377#: ../UpdateManager/Core/UpdateList.py:52352msgid "%s base"
378#, python-format
379msgid "A error '%s' occurred while checking what system you are using."
380msgstr ""
381
382#: ../UpdateManager/Core/UpdateList.py:63
383msgid "Important security updates"
384msgstr ""
385
386#: ../UpdateManager/Core/UpdateList.py:64
387msgid "Recommended updates"
388msgstr ""
389
390#: ../UpdateManager/Core/UpdateList.py:65
391msgid "Proposed updates"
392msgstr ""
393
394#: ../UpdateManager/Core/UpdateList.py:66
395msgid "Backports"
396msgstr ""
397
398#: ../UpdateManager/Core/UpdateList.py:67
399msgid "Distribution updates"
400msgstr ""
401
402#: ../UpdateManager/Core/UpdateList.py:72
403msgid "Other updates"
404msgstr ""
405
406#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:72
407#, python-format
408msgid "authenticate '%(file)s' against '%(signature)s' "
409msgstr ""
410
411#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:131
412#, python-format
413msgid "extracting '%s'"
414msgstr ""
415
416#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:151
417#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:152
418msgid "Could not run the upgrade tool"
419msgstr ""
420
421#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:152
422msgid ""
423"This is most likely a bug in the upgrade tool. Please report it as a bug "
424"using the command 'ubuntu-bug update-manager'."
425msgstr ""
426
427#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:227
428msgid "Upgrade tool signature"
429msgstr ""
430
431#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:234
432msgid "Upgrade tool"
433msgstr ""
434
435#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:268
436msgid "Failed to fetch"
437msgstr ""
438
439#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:269
440msgid "Fetching the upgrade failed. There may be a network problem. "
441msgstr ""
442
443#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:273
444msgid "Authentication failed"
445msgstr ""
446
447#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:274
448msgid ""
449"Authenticating the upgrade failed. There may be a problem with the network "
450"or with the server. "
451msgstr ""
452
453#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:279
454msgid "Failed to extract"
455msgstr ""
456
457#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:280
458msgid ""
459"Extracting the upgrade failed. There may be a problem with the network or "
460"with the server. "
461msgstr ""
462
463#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:285
464msgid "Verification failed"
465msgstr ""
466
467#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:286
468msgid ""
469"Verifying the upgrade failed. There may be a problem with the network or "
470"with the server. "
471msgstr ""
472
473#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:300
474#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:306
475msgid "Can not run the upgrade"
476msgstr ""
477
478#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:301
479msgid ""
480"This usually is caused by a system where /tmp is mounted noexec. Please "
481"remount without noexec and run the upgrade again."
482msgstr ""
483
484#: ../UpdateManager/Core/DistUpgradeFetcherCore.py:307
485#, python-format
486msgid "The error message is '%s'."
487msgstr ""353msgstr ""
488354
489#. TRANSLATORS: download size of small updates, e.g. "250 kB"355#. TRANSLATORS: download size of small updates, e.g. "250 kB"
490#: ../UpdateManager/Core/utils.py:433356#: ../UpdateManager/Core/utils.py:485
491#, python-format357#, python-format
492msgid "%(size).0f kB"358msgid "%(size).0f kB"
493msgid_plural "%(size).0f kB"359msgid_plural "%(size).0f kB"
@@ -495,112 +361,46 @@
495msgstr[1] ""361msgstr[1] ""
496362
497#. TRANSLATORS: download size of updates, e.g. "2.3 MB"363#. TRANSLATORS: download size of updates, e.g. "2.3 MB"
498#: ../UpdateManager/Core/utils.py:436364#: ../UpdateManager/Core/utils.py:489
499#, python-format365#, python-format
500msgid "%.1f MB"366msgid "%.1f MB"
501msgstr ""367msgstr ""
502368
503#: ../data/gtkbuilder/UpdateManager.ui.h:1369#: ../data/gtkbuilder/UpdateManager.ui.h:1
504msgid "<big><b>Starting Software Updater</b></big>"370msgid "updates"
505msgstr ""371msgstr ""
506372
507#: ../data/gtkbuilder/UpdateManager.ui.h:2373#: ../data/gtkbuilder/UpdateManager.ui.h:2
508msgid ""374msgid "Changes"
509"Software updates correct errors, eliminate security vulnerabilities and "
510"provide new features."
511msgstr ""375msgstr ""
512376
513#: ../data/gtkbuilder/UpdateManager.ui.h:3377#: ../data/gtkbuilder/UpdateManager.ui.h:3
514msgid "_Partial Upgrade"378msgid "Description"
515msgstr ""379msgstr ""
516380
517#: ../data/gtkbuilder/UpdateManager.ui.h:4381#: ../data/gtkbuilder/UpdateManager.ui.h:4
518msgid "<big><b>Not all updates can be installed</b></big>"382msgid "Technical description"
519msgstr ""383msgstr ""
520384
521#: ../data/gtkbuilder/UpdateManager.ui.h:5385#: ../data/gtkbuilder/UpdateManager.ui.h:5
522msgid ""
523"Run a partial upgrade, to install as many updates as possible. \n"
524"\n"
525"This can be caused by:\n"
526" * A previous upgrade which didn't complete\n"
527" * Problems with some of the installed software\n"
528" * Unofficial software packages not provided by Ubuntu\n"
529" * Normal changes of a pre-release version of Ubuntu"
530msgstr ""
531
532#: ../data/gtkbuilder/UpdateManager.ui.h:12
533msgid "Co_ntinue"
534msgstr ""
535
536#: ../data/gtkbuilder/UpdateManager.ui.h:13
537msgid "<big><b>Running on battery</b></big>"
538msgstr ""
539
540#: ../data/gtkbuilder/UpdateManager.ui.h:14
541msgid "Your system is running on battery. Are you sure you want to continue?"
542msgstr ""
543
544#: ../data/gtkbuilder/UpdateManager.ui.h:16
545msgid "_Upgrade"
546msgstr ""
547
548#: ../data/gtkbuilder/UpdateManager.ui.h:17
549msgid "Show progress of individual files"
550msgstr ""
551
552#: ../data/gtkbuilder/UpdateManager.ui.h:18
553#: ../data/update-manager.desktop.in.h:1
554msgid "Software Updater"
555msgstr ""
556
557#: ../data/gtkbuilder/UpdateManager.ui.h:19
558msgid "U_pgrade"
559msgstr ""
560
561#: ../data/gtkbuilder/UpdateManager.ui.h:20
562msgid "_Restart Now"
563msgstr ""
564
565#: ../data/gtkbuilder/UpdateManager.ui.h:21
566msgid "updates"
567msgstr ""
568
569#: ../data/gtkbuilder/UpdateManager.ui.h:22
570msgid "Changes"
571msgstr ""
572
573#: ../data/gtkbuilder/UpdateManager.ui.h:23
574msgid "Description"
575msgstr ""
576
577#: ../data/gtkbuilder/UpdateManager.ui.h:24
578msgid "Details of updates"386msgid "Details of updates"
579msgstr ""387msgstr ""
580388
581#: ../data/gtkbuilder/UpdateManager.ui.h:25389#: ../data/gtkbuilder/UpdateManager.ui.h:6
582msgid ""390msgid ""
583"You are connected via roaming and may be charged for the data consumed by "391"You are connected via roaming and may be charged for the data consumed by "
584"this update."392"this update."
585msgstr ""393msgstr ""
586394
587#: ../data/gtkbuilder/UpdateManager.ui.h:26395#: ../data/gtkbuilder/UpdateManager.ui.h:7
588msgid ""396msgid ""
589"You may want to wait until you’re not using a mobile broadband connection."397"You may want to wait until you’re not using a mobile broadband connection."
590msgstr ""398msgstr ""
591399
592#: ../data/gtkbuilder/UpdateManager.ui.h:27400#: ../data/gtkbuilder/UpdateManager.ui.h:8
593msgid "It’s safer to connect the computer to AC power before updating."401msgid "It’s safer to connect the computer to AC power before updating."
594msgstr ""402msgstr ""
595403
596#: ../data/gtkbuilder/UpdateManager.ui.h:28
597msgid "_Settings..."
598msgstr ""
599
600#: ../data/gtkbuilder/UpdateManager.ui.h:29
601msgid "_Install Now"
602msgstr ""
603
604#: ../data/update-manager.desktop.in.h:2404#: ../data/update-manager.desktop.in.h:2
605msgid "Software Updates"405msgid "Software Updates"
606msgstr ""406msgstr ""
@@ -609,46 +409,38 @@
609msgid "Show and install available updates"409msgid "Show and install available updates"
610msgstr ""410msgstr ""
611411
612#: ../update-manager:71 ../update-manager-text:55412#: ../update-manager:70 ../update-manager-text:55
613msgid "Show version and exit"413msgid "Show version and exit"
614msgstr ""414msgstr ""
615415
616#: ../update-manager:74416#: ../update-manager:73
617msgid "Directory that contains the data files"417msgid "Directory that contains the data files"
618msgstr ""418msgstr ""
619419
620#: ../update-manager:77420#: ../update-manager:76
621msgid "Check if a new Ubuntu release is available"421msgid "Check if a new Ubuntu release is available"
622msgstr ""422msgstr ""
623423
624#: ../update-manager:80424#: ../update-manager:79
625msgid "Check if upgrading to the latest devel release is possible"425msgid "Check if upgrading to the latest devel release is possible"
626msgstr ""426msgstr ""
627427
628#: ../update-manager:84428#: ../update-manager:83
629msgid "Upgrade using the latest proposed version of the release upgrader"429msgid "Upgrade using the latest proposed version of the release upgrader"
630msgstr ""430msgstr ""
631431
632#: ../update-manager:91432#: ../update-manager:90
633msgid "Do not focus on map when starting"433msgid "Do not focus on map when starting"
634msgstr ""434msgstr ""
635435
636#: ../update-manager:94436#: ../update-manager:93
637msgid "Try to run a dist-upgrade"437msgid "Do not check for updates when starting"
638msgstr ""438msgstr ""
639439
640#: ../update-manager:97440#: ../update-manager:97
641msgid "Do not check for updates when starting"
642msgstr ""
643
644#: ../update-manager:101
645msgid "Test upgrade with a sandbox aufs overlay"441msgid "Test upgrade with a sandbox aufs overlay"
646msgstr ""442msgstr ""
647443
648#: ../update-manager:121
649msgid "Running partial upgrade"
650msgstr ""
651
652#: ../update-manager-text:59444#: ../update-manager-text:59
653msgid "Show description of the package instead of the changelog"445msgid "Show description of the package instead of the changelog"
654msgstr ""446msgstr ""
@@ -713,7 +505,7 @@
713505
714#. Why do we use %s here instead of $strings or {} format placeholders?506#. Why do we use %s here instead of $strings or {} format placeholders?
715#. It's because we don't want to break existing translations.507#. It's because we don't want to break existing translations.
716#: ../janitor/plugincore/exceptions.py:42508#: ../janitor/plugincore/exceptions.py:43
717#, python-format509#, python-format
718msgid "Unimplemented method: %s"510msgid "Unimplemented method: %s"
719msgstr ""511msgstr ""
@@ -722,45 +514,45 @@
722msgid "A file on disk"514msgid "A file on disk"
723msgstr ""515msgstr ""
724516
725#: ../janitor/plugincore/core/missing_package_cruft.py:39517#: ../janitor/plugincore/core/missing_package_cruft.py:40
726msgid "Install missing package."518msgid "Install missing package."
727msgstr ""519msgstr ""
728520
729#. 2012-06-08 BAW: i18n string; don't use {} or PEP 292.521#. 2012-06-08 BAW: i18n string; don't use {} or PEP 292.
730#: ../janitor/plugincore/core/missing_package_cruft.py:49522#: ../janitor/plugincore/core/missing_package_cruft.py:50
731#, python-format523#, python-format
732msgid "Package %s should be installed."524msgid "Package %s should be installed."
733msgstr ""525msgstr ""
734526
735#: ../janitor/plugincore/core/package_cruft.py:49527#: ../janitor/plugincore/core/package_cruft.py:50
736msgid ".deb package"528msgid ".deb package"
737msgstr ""529msgstr ""
738530
739#: ../janitor/plugincore/plugins/langpack_manual_plugin.py:46531#: ../janitor/plugincore/plugins/langpack_manual_plugin.py:47
740#, python-format532#, python-format
741msgid "%s needs to be marked as manually installed."533msgid "%s needs to be marked as manually installed."
742msgstr ""534msgstr ""
743535
744#: ../janitor/plugincore/plugins/kdelibs4to5_plugin.py:49536#: ../janitor/plugincore/plugins/kdelibs4to5_plugin.py:50
745msgid ""537msgid ""
746"When upgrading, if kdelibs4-dev is installed, kdelibs5-dev needs to be "538"When upgrading, if kdelibs4-dev is installed, kdelibs5-dev needs to be "
747"installed. See bugs.launchpad.net, bug #279621 for details."539"installed. See bugs.launchpad.net, bug #279621 for details."
748msgstr ""540msgstr ""
749541
750#: ../janitor/plugincore/plugins/dpkg_status_plugin.py:44542#: ../janitor/plugincore/plugins/dpkg_status_plugin.py:45
751#, python-format543#, python-format
752msgid "%i obsolete entries in the status file"544msgid "%i obsolete entries in the status file"
753msgstr ""545msgstr ""
754546
755#: ../janitor/plugincore/plugins/dpkg_status_plugin.py:47547#: ../janitor/plugincore/plugins/dpkg_status_plugin.py:48
756msgid "Obsolete entries in dpkg status"548msgid "Obsolete entries in dpkg status"
757msgstr ""549msgstr ""
758550
759#. pragma: no cover551#. pragma: no cover
760#: ../janitor/plugincore/plugins/dpkg_status_plugin.py:50552#: ../janitor/plugincore/plugins/dpkg_status_plugin.py:51
761msgid "Obsolete dpkg status entries"553msgid "Obsolete dpkg status entries"
762msgstr ""554msgstr ""
763555
764#: ../janitor/plugincore/plugins/remove_lilo_plugin.py:42556#: ../janitor/plugincore/plugins/remove_lilo_plugin.py:43
765msgid "Remove lilo since grub is also installed.(See bug #314004 for details.)"557msgid "Remove lilo since grub is also installed.(See bug #314004 for details.)"
766msgstr ""558msgstr ""

Subscribers

People subscribed via source and target branches

to status/vote changes: