Viewing file: SoftwarePropertiesGtk.py (32.28 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
# GTK+ based frontend to software-properties # # Copyright (c) 2004-2007 Canonical Ltd. # 2004-2005 Michiel Sikkes # # Author: Michiel Sikkes <michiel@eyesopened.nl> # Michael Vogt <mvo@debian.org> # Sebastian Heinlein <glatzor@ubuntu.com> # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # USA
import apt import apt_pkg import tempfile from gettext import gettext as _ import os import re from xml.sax.saxutils import escape
import gtk import gtk.glade import gobject
from SimpleGladeApp import SimpleGladeApp from aptsources.sourceslist import SourceEntry from DialogAdd import DialogAdd from DialogMirror import DialogMirror from DialogEdit import DialogEdit from DialogCacheOutdated import DialogCacheOutdated from DialogAddSourcesList import DialogAddSourcesList from CdromProgress import CdromProgress
import softwareproperties import softwareproperties.distro from softwareproperties.SoftwareProperties import SoftwareProperties import softwareproperties.SoftwareProperties
(LIST_MARKUP, LIST_ENABLED, LIST_ENTRY_OBJ) = range(3)
( COLUMN_ACTIVE, COLUMN_DESC ) = range(2)
RESPONSE_REPLACE = 1 RESPONSE_ADD = 2
# columns of the source_store ( STORE_ACTIVE, STORE_DESCRIPTION, STORE_SOURCE, STORE_SEPARATOR, STORE_VISIBLE ) = range(5)
class SoftwarePropertiesGtk(SoftwareProperties,SimpleGladeApp): def __init__(self, datadir=None, options=None, file=None, parent=None): """ Provide a GTK based graphical user interface to configure the used software repositories, corresponding authentication keys and update automation """ SoftwareProperties.__init__(self, options=options, datadir=datadir) gtk.window_set_default_icon_name("software-properties")
SimpleGladeApp.__init__(self, datadir+"glade/main.glade", None, domain="software-properties")
if parent: self.window_main.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG) self.window_main.show() self.window_main.set_transient_for(parent)
# If externally called, reparent to external application. self.options = options if options and options.toplevel != None: self.window_main.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG) self.window_main.show() toplevel = gtk.gdk.window_foreign_new(int(options.toplevel)) if (toplevel): self.window_main.window.set_transient_for(toplevel)
# Show what we have early self.window_main.show()
# used to store the handlers of callbacks self.handlers = []
# Put some life into the user interface: self.init_popcon() self.init_auto_update() self.show_auto_update_level() # Setup the key list self.init_keys() self.show_keys() # Setup the ISV sources list self.init_isv_sources() self.show_isv_sources() self.show_cdrom_sources() # Setup and show the distro elements self.init_distro() self.show_distro()
# Show the import/replace sources.list dialog if a file different # to the default sources.list was specified # NOTE: If the file path points to the default sources.list the user # perhaps assumed that s-p would act like a normal editor. # We have got some bug reports from users calling # "sudo software-properties-gtk /etc/apt/sources.list" from the # command line. if file != None and \ os.path.abspath(file) != "%s%s" % (apt_pkg.Config.FindDir("Dir::Etc"), apt_pkg.Config.Find("Dir::Etc::sourcelist")): self.open_file(file)
def init_popcon(self): """ If popcon is enabled show the statistics tab and an explanation corresponding to the used distro """ is_helpful = self.get_popcon_participation() if is_helpful != None: self.label_popcon_desc.set_label(softwareproperties.distro.get_popcon_description(self.distro)) self.vbox_popcon.show() self.checkbutton_popcon.set_active(is_helpful)
def init_auto_update(self): """ Set up the widgets that allow to configure the update automation """ # this maps the key (combo-box-index) to the auto-update-interval value # where (-1) means, no key self.combobox_interval_mapping = { 0 : 1, 1 : 2, 2 : 7, 3 : 14 } self.combobox_update_interval.set_active(0)
#update_days = apt_pkg.Config.FindI(softwareproperties.CONF_MAP["autoupdate"])
self.combobox_update_interval.append_text(_("Daily")) self.combobox_update_interval.append_text(_("Every two days")) self.combobox_update_interval.append_text(_("Weekly")) self.combobox_update_interval.append_text(_("Every two weeks"))
model_check_interval = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_INT) update_days = self.get_update_interval()
# If a custom period is defined add a corresponding entry if not update_days in self.combobox_interval_mapping.values(): if update_days > 0: self.combobox_update_interval.append_text(_("Every %s days") % update_days) self.combobox_interval_mapping[4] = update_days for key in self.combobox_interval_mapping: if self.combobox_interval_mapping[key] == update_days: self.combobox_update_interval.set_active(key) break
if update_days >= 1: self.checkbutton_auto_update.set_active(True) self.combobox_update_interval.set_sensitive(True) self.vbox_auto_updates.set_sensitive(True) else: self.checkbutton_auto_update.set_active(False) self.combobox_update_interval.set_sensitive(False) self.vbox_auto_updates.set_sensitive(False)
self.handlers.append( (self.checkbutton_auto_update, self.checkbutton_auto_update.connect("toggled", self.on_auto_update_toggled))) self.handlers.append( (self.combobox_update_interval, self.combobox_update_interval.connect("changed", self.on_combobox_update_interval_changed))) self.handlers.append( (self.radiobutton_updates_download, self.radiobutton_updates_download.connect("toggled", self.set_update_automation_level, softwareproperties.UPDATE_DOWNLOAD))) self.handlers.append( (self.radiobutton_updates_inst_sec, self.radiobutton_updates_inst_sec.connect("toggled", self.set_update_automation_level, softwareproperties.UPDATE_INST_SEC))) self.handlers.append( (self.radiobutton_updates_notify, self.radiobutton_updates_notify.connect("toggled", self.set_update_automation_level, softwareproperties.UPDATE_NOTIFY)))
def show_auto_update_level(self): """Represent the level of update automation in the user interface""" level = self.get_update_automation_level() self.block_handlers() if level == None: self.radiobutton_updates_inst_sec.set_inconsistent(True) self.radiobutton_updates_download.set_inconsistent(True) self.radiobutton_updates_notify.set_inconsistent(True) else: self.radiobutton_updates_inst_sec.set_inconsistent(False) self.radiobutton_updates_download.set_inconsistent(False) self.radiobutton_updates_notify.set_inconsistent(False) if level == softwareproperties.UPDATE_MANUAL or \ level == softwareproperties.UPDATE_NOTIFY: self.radiobutton_updates_notify.set_active(True) elif level == softwareproperties.UPDATE_DOWNLOAD: self.radiobutton_updates_download.set_active(True) elif level == softwareproperties.UPDATE_INST_SEC: self.radiobutton_updates_inst_sec.set_active(True) # Unblock the toggle handlers self.unblock_handlers()
def init_distro(self): """Setup the user interface elements to represent the distro"""
# TRANS: %s stands for the distribution name e.g. Debian or Ubuntu self.label_updates.set_label("<b>%s</b>" % (_("%s updates") %\ self.distro.id)) # TRANS: %s stands for the distribution name e.g. Debian or Ubuntu self.label_dist_name.set_label(_("%s Software") % self.distro.id)
self.handlers.append((self.checkbutton_source_code, self.checkbutton_source_code.connect("toggled", self.on_checkbutton_source_code_toggled)))
# Setup the checkbuttons for the components for checkbutton in self.vbox_dist_comps.get_children(): self.vbox_dist_comps.remove(checkbutton) for comp in self.distro.source_template.components: # TRANSLATORS: Label for the components in the Internet section # first %s is the description of the component # second %s is the code name of the comp, eg main, universe label = _("%s (%s)") % (comp.get_description(), comp.name) checkbox = gtk.CheckButton(label)
checkbox.comp = comp # setup the callback and show the checkbutton self.handlers.append((checkbox, checkbox.connect("toggled", self.on_component_toggled, comp.name))) self.vbox_dist_comps.add(checkbox) checkbox.show()
# Setup the checkbuttons for the child repos / updates for checkbutton in self.vbox_updates.get_children(): self.vbox_updates.remove(checkbutton) if len(self.distro.source_template.children) < 1: self.frame_children.hide() for template in self.distro.source_template.children: checkbox = gtk.CheckButton(label="%s (%s)" % (template.description, template.name)) checkbox.template = template self.handlers.append((checkbox, checkbox.connect("toggled", self.on_checkbutton_child_toggled, template))) self.vbox_updates.add(checkbox) checkbox.show()
# setup the server chooser cell = gtk.CellRendererText() self.combobox_server.pack_start(cell, True) self.combobox_server.add_attribute(cell, 'text', 0) self.handlers.append((self.combobox_server, self.combobox_server.connect("changed", self.on_combobox_server_changed))) server_store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_BOOLEAN) self.combobox_server.set_model(server_store) self.combobox_server.set_row_separator_func(self.is_row_separator, 2)
def block_handlers(self): for (widget, handler) in self.handlers: widget.handler_block(handler) def unblock_handlers(self): for (widget, handler) in self.handlers: widget.handler_unblock(handler)
def show_distro(self): """Fill the distro user interface with life""" self.block_handlers() # Enable or disable the child source checkbuttons for checkbox in self.vbox_updates.get_children(): (active, inconsistent) = self.get_comp_child_state(checkbox.template) checkbox.set_active(active) checkbox.set_inconsistent(inconsistent)
# Enable or disable the component checkbuttons for checkbox in self.vbox_dist_comps.get_children(): # check if the comp is enabled (active, inconsistent) = self.get_comp_download_state(checkbox.comp) checkbox.set_inconsistent(inconsistent) checkbox.set_active(active)
# If no components are enabled there will be no need for updates # and source code if len(self.distro.enabled_comps) < 1: self.vbox_updates.set_sensitive(False) self.checkbutton_source_code.set_sensitive(False) else: self.vbox_updates.set_sensitive(True) self.checkbutton_source_code.set_sensitive(True)
# Check for source code sources source_code_state = self.get_source_code_state() if source_code_state == None: self.checkbutton_source_code.set_inconsistent(True) elif source_code_state == True: self.checkbutton_source_code.set_active(True) self.checkbutton_source_code.set_inconsistent(False) else: self.checkbutton_source_code.set_active(False) self.checkbutton_source_code.set_inconsistent(False)
# Will show a short explanation if no CDROMs are used if len(self.get_cdrom_sources()) == 0: self.scrolledwindow_cd.hide() self.scrolledwindow_no_cd.show() else: self.scrolledwindow_cd.show() self.scrolledwindow_no_cd.hide()
# provide a list of mirrors server_store = self.combobox_server.get_model() server_store.clear() seen_server_new = [] for (name, uri, active) in self.distro.get_server_list(): server_store.append([name, uri, False]) if [name, uri] in self.seen_server: self.seen_server.remove([name, uri]) elif uri != None: seen_server_new.append([name, uri]) if active == True: self.active_server = len(server_store) - 1 self.combobox_server.set_active(self.active_server) for [name, uri] in self.seen_server: server_store.append([name, uri, False]) self.seen_server = seen_server_new # add a separator and the option to choose another mirror from the list server_store.append(["sep", None, True]) server_store.append([_("Other..."), None, False])
# make the interface respond to user interput again self.unblock_handlers()
# Output a lot of debug stuff if self.options.debug == True or self.options.massive_debug == True: print "ENABLED COMPS: %s" % self.distro.enabled_comps print "INTERNET COMPS: %s" % self.distro.download_comps print "MAIN SOURCES" for source in self.distro.main_sources: self.print_source_entry(source) print "CHILD SOURCES" for source in self.distro.child_sources: self.print_source_entry(source) print "CDROM SOURCES" for source in self.distro.cdrom_sources: self.print_source_entry(source) print "SOURCE CODE SOURCES" for source in self.distro.source_code_sources: self.print_source_entry(source) print "DISABLED SOURCES" for source in self.distro.disabled_sources: self.print_source_entry(source) print "ISV" for source in self.sourceslist_visible: self.print_source_entry(source)
def set_update_automation_level(self, widget, state): '''Call the backend to set the update automation level to the given value''' if widget.get_active() == True: self.vbox_auto_updates.foreach(lambda b: b.set_inconsistent(False)) SoftwareProperties.set_update_automation_level(self, state) self.set_modified_config()
def is_row_separator(self, model, iter, column=0): ''' Check if a given row is a separator ''' return model.get_value(iter, column)
def on_combobox_server_changed(self, combobox): """ Replace the servers used by the main and update sources with the selected one """ if combobox.get_active() == self.active_server: return server_store = combobox.get_model() iter = combobox.get_active_iter() uri = server_store.get_value(iter, 1) name = server_store.get_value(iter, 0) if name == _("Other..."): dialog = DialogMirror(self.window_main, self.datadir, self.distro, self.custom_mirrors) res = dialog.run() if res != None: self.distro.change_server(res) self.set_modified_sourceslist() else: combobox.set_active(self.active_server) elif uri != None and len(self.distro.used_servers) > 0: self.active_server = combobox.get_active() self.distro.change_server(uri) self.distro.default_server = uri self.set_modified_sourceslist() else: self.distro.default_server = uri
def on_component_toggled(self, checkbutton, comp): """ Sync the components of all main sources (excluding cdroms), child sources and source code sources """ if checkbutton.get_active() == True: self.enable_component(comp) else: self.disable_component(comp) self.set_modified_sourceslist()
def on_checkbutton_child_toggled(self, checkbutton, template): """ Enable or disable a child repo of the distribution main repository """ if checkbutton.get_active() == False: self.disable_child_source(template) else: self.enable_child_source(template) def on_checkbutton_source_code_toggled(self, checkbutton): """ Disable or enable the source code for all sources """ if checkbutton.get_active() == True: self.enable_source_code_sources() else: self.disable_source_code_sources()
def on_checkbutton_popcon_toggled(self, widget): """ The user clicked on the popcon paritipcation button """ self.set_popcon_pariticipation(widget.get_active())
def open_file(self, file): """Show a confirmation for adding the channels of the specified file""" dialog = DialogAddSourcesList(self.window_main, self.sourceslist, self.render_source, self.get_comparable, self.datadir, file) (res, new_sources) = dialog.run() if res == RESPONSE_REPLACE: self.sourceslist.list = [] if res in (RESPONSE_ADD, RESPONSE_REPLACE): for source in new_sources: self.sourceslist.add(source.type, source.uri, source.dist, source.comps, source.comment) self.set_modified_sourceslist()
def on_sources_drag_data_received(self, widget, context, x, y, selection, target_type, timestamp): """Extract the dropped file pathes and open the first file, only""" uri = selection.data.strip() uri_splitted = uri.split() if len(uri_splitted)>0: self.open_file(uri_splitted[0])
def hide(self): self.window_main.hide() def init_isv_sources(self): """ Read all valid sources into our ListStore """ # STORE_ACTIVE - is the source enabled or disabled # STORE_DESCRIPTION - description of the source entry # STORE_SOURCE - the source entry object # STORE_SEPARATOR - if the entry is a separator # STORE_VISIBLE - if the entry is shown or hidden self.cdrom_store = gtk.ListStore(gobject.TYPE_BOOLEAN, gobject.TYPE_STRING, gobject.TYPE_PYOBJECT, gobject.TYPE_BOOLEAN, gobject.TYPE_BOOLEAN) self.treeview_cdroms.set_model(self.cdrom_store) self.source_store = gtk.ListStore(gobject.TYPE_BOOLEAN, gobject.TYPE_STRING, gobject.TYPE_PYOBJECT, gobject.TYPE_BOOLEAN, gobject.TYPE_BOOLEAN) self.treeview_sources.set_model(self.source_store) self.treeview_sources.set_row_separator_func(self.is_separator, STORE_SEPARATOR)
cell_desc = gtk.CellRendererText() cell_desc.set_property("xpad", 2) cell_desc.set_property("ypad", 2) col_desc = gtk.TreeViewColumn(_("Software Sources"), cell_desc, markup=COLUMN_DESC) col_desc.set_max_width(1000)
cell_toggle = gtk.CellRendererToggle() cell_toggle.set_property("xpad", 2) cell_toggle.set_property("ypad", 2) self.handlers.append([cell_toggle, cell_toggle.connect('toggled', self.on_isv_source_toggled, self.cdrom_store)]) col_active = gtk.TreeViewColumn(_("Active"), cell_toggle, active=COLUMN_ACTIVE)
self.treeview_cdroms.append_column(col_active) self.treeview_cdroms.append_column(col_desc)
cell_desc = gtk.CellRendererText() cell_desc.set_property("xpad", 2) cell_desc.set_property("ypad", 2) col_desc = gtk.TreeViewColumn(_("Software Sources"), cell_desc, markup=COLUMN_DESC) col_desc.set_max_width(1000)
cell_toggle = gtk.CellRendererToggle() cell_toggle.set_property("xpad", 2) cell_toggle.set_property("ypad", 2) self.handlers.append([cell_toggle, cell_toggle.connect('toggled', self.on_isv_source_toggled, self.source_store)]) col_active = gtk.TreeViewColumn(_("Active"), cell_toggle, active=COLUMN_ACTIVE)
self.treeview_sources.append_column(col_active) self.treeview_sources.append_column(col_desc) # drag and drop support for sources.list self.treeview_sources.drag_dest_set(gtk.DEST_DEFAULT_ALL, \ [('text/uri-list',0, 0)], \ gtk.gdk.ACTION_COPY) self.treeview_sources.connect("drag_data_received",\ self.on_sources_drag_data_received)
def on_isv_source_activate(self, treeview, path, column): """Open the edit dialog if a channel was double clicked""" self.on_edit_clicked(treeview)
def on_treeview_sources_cursor_changed(self, treeview): """Enable the buttons remove and edit if a channel is selected""" sel = self.treeview_sources.get_selection() (model, iter) = sel.get_selected() if iter: self.button_edit.set_sensitive(True) self.button_remove.set_sensitive(True) else: self.button_edit.set_sensitive(False) self.button_remove.set_sensitive(False) def on_isv_source_toggled(self, cell_toggle, path, store): """Enable or disable the selected channel""" #FIXME cdroms need to disable the comps in the childs and sources iter = store.get_iter((int(path),)) source_entry = store.get_value(iter, STORE_SOURCE) self.toggle_source_use(source_entry)
def init_keys(self): """Setup the user interface parts needed for the key handling""" self.keys_store = gtk.ListStore(str) self.treeview2.set_model(self.keys_store) tr = gtk.CellRendererText() keys_col = gtk.TreeViewColumn("Key", tr, text=0) self.treeview2.append_column(keys_col)
#FIXME revert automation settings too def on_button_revert_clicked(self, button): """Restore the source list from the startup of the dialog""" SoftwareProperties.revert(self) self.set_modified_sourceslist() self.show_auto_update_level() self.button_revert.set_sensitive(False) self.modified_sourceslist = False
def set_modified_config(self): """The config was changed and now needs to be saved and reloaded""" SoftwareProperties.set_modified_config(self) self.button_revert.set_sensitive(True)
def set_modified_sourceslist(self): """The sources list was changed and now needs to be saved and reloaded""" SoftwareProperties.set_modified_sourceslist(self) self.show_distro() self.show_isv_sources() self.show_cdrom_sources() self.button_revert.set_sensitive(True)
def show_isv_sources(self): """ Show the repositories of independent software vendors in the third-party software tree view """ self.source_store.clear()
for source in self.get_isv_sources(): contents = self.render_source(source) self.source_store.append([not source.disabled, contents, source, False, True])
(path_x, path_y) = self.treeview_sources.get_cursor() if len(self.source_store) < 1 or path_x <0: self.button_remove.set_sensitive(False) self.button_edit.set_sensitive(False)
def show_cdrom_sources(self): """ Show CD-ROM/DVD based repositories of the currently used distro in the CDROM based sources list """ self.cdrom_store.clear() for source in self.get_cdrom_sources(): contents = self.render_source(source) self.cdrom_store.append([not source.disabled, contents, source, False, True]) def is_separator(self, model, iter, column): """ Return true if the selected row is a separator """ return model.get_value(iter, column) def show_keys(self): self.keys_store.clear() for key in self.apt_key.list(): self.keys_store.append([key])
def on_combobox_update_interval_changed(self, widget): """Set the update automation interval to the chosen one""" i = self.combobox_update_interval.get_active() if i != -1: value = self.combobox_interval_mapping[i] self.set_update_interval(value)
def on_auto_update_toggled(self, widget): """Enable or disable automatic updates and modify the user interface accordingly""" if self.checkbutton_auto_update.get_active(): self.combobox_update_interval.set_sensitive(True) self.vbox_auto_updates.set_sensitive(True) # if no frequency was specified use daily i = self.combobox_update_interval.get_active() if i == -1: i = 0 self.combobox_update_interval.set_active(i) value = self.combobox_interval_mapping[i] # A little hack to re-set the former selected update automation level self.vbox_auto_updates.foreach(lambda b: b.toggled()) else: self.combobox_update_interval.set_sensitive(False) self.vbox_auto_updates.set_sensitive(False) SoftwareProperties.set_update_automation_level(self, None) value = 0 self.set_update_interval(str(value))
def on_add_clicked(self, widget): """Show a dialog that allows to enter the apt line of a to be used repo""" dialog = DialogAdd(self.window_main, self.sourceslist, self.datadir, self.distro) line = dialog.run() if line != None: self.add_source_from_line(line) self.set_modified_sourceslist() def on_edit_clicked(self, widget): """Show a dialog to edit an ISV source""" sel = self.treeview_sources.get_selection() (model, iter) = sel.get_selected() if not iter: return source_entry = model.get_value(iter, LIST_ENTRY_OBJ) dialog = DialogEdit(self.window_main, self.sourceslist, source_entry, self.datadir) if dialog.run() == gtk.RESPONSE_OK: self.set_modified_sourceslist()
# FIXME:outstanding from merge def on_isv_source_activated(self, treeview, path, column): """Open the edit dialog if a channel was double clicked""" # check if the channel can be edited if self.button_edit.get_property("sensitive") == True: self.on_edit_clicked(treeview)
# FIXME:outstanding from merge def on_treeview_sources_cursor_changed(self, treeview): """set the sensitiveness of the edit and remove button corresponding to the selected channel""" sel = self.treeview_sources.get_selection() (model, iter) = sel.get_selected() if not iter: # No channel is selected, so disable edit and remove self.button_edit.set_sensitive(False) self.button_remove.set_sensitive(False) return # allow to remove the selected channel self.button_remove.set_sensitive(True) # disable editing of cdrom sources source_entry = model.get_value(iter, LIST_ENTRY_OBJ) if source_entry.uri.startswith("cdrom:"): self.button_edit.set_sensitive(False) else: self.button_edit.set_sensitive(True)
def on_remove_clicked(self, widget): """Remove the selected source""" model = self.treeview_sources.get_model() (path, column) = self.treeview_sources.get_cursor() iter = model.get_iter(path) if iter: self.remove_source(model.get_value(iter, LIST_ENTRY_OBJ)) self.set_modified_sourceslist()
def add_key_clicked(self, widget): """Provide a file chooser that allows to add the gnupg of a trusted software vendor""" chooser = gtk.FileChooserDialog(title=_("Import key"), parent=self.window_main, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK,gtk.RESPONSE_ACCEPT)) res = chooser.run() chooser.hide() if res == gtk.RESPONSE_ACCEPT: if not self.add_key(chooser.get_filename()): error(self.window_main, _("Error importing selected file"), _("The selected file may not be a GPG key file " \ "or it might be corrupt.")) self.show_keys()
def remove_key_clicked(self, widget): """Remove a trusted software vendor key""" selection = self.treeview2.get_selection() (model,a_iter) = selection.get_selected() if a_iter == None: return key = model.get_value(a_iter,0) if not self.remove_key(key[:8]): error(self.main, _("Error removing the key"), _("The key you selected could not be removed. " "Please report this as a bug.")) self.show_keys()
def on_restore_clicked(self, widget): """Restore the original keys""" self.apt_key.update() self.show_keys()
def on_delete_event(self, widget, args): """Close the window if requested""" self.on_close_button(widget)
def on_close_button(self, widget): """Show a dialog that a reload of the channel information is required only if there is no parent defined""" if self.modified_sourceslist == True and \ self.options.toplevel == None: d = DialogCacheOutdated(self.window_main, self.datadir) res = d.run() self.quit()
def on_button_add_cdrom_clicked(self, widget): '''Show a dialog that allows to add a repository located on a CDROM or DVD''' # testing #apt_pkg.Config.Set("APT::CDROM::Rename","true")
saved_entry = apt_pkg.Config.Find("Dir::Etc::sourcelist") tmp = tempfile.NamedTemporaryFile() apt_pkg.Config.Set("Dir::Etc::sourcelist",tmp.name) progress = CdromProgress(self.datadir,self.window_main) cdrom = apt_pkg.GetCdrom() # if nothing was found just return try: res = cdrom.Add(progress) except SystemError, msg: #print "aiiiieeee, exception from cdrom.Add() [%s]" % msg progress.close() dialog = gtk.MessageDialog(parent=self.window_main, flags=gtk.DIALOG_MODAL, type=gtk.MESSAGE_ERROR, buttons=gtk.BUTTONS_OK, message_format=None) dialog.set_markup(_("<big><b>Error scanning the CD</b></big>\n\n%s")%msg) res = dialog.run() dialog.destroy() return apt_pkg.Config.Set("Dir::Etc::sourcelist",saved_entry) if res == False: progress.close() return # read tmp file with source name (read only last line) line = "" for x in open(tmp.name): line = x if line != "": full_path = "%s%s" % (apt_pkg.Config.FindDir("Dir::Etc"),saved_entry) self.sourceslist.list.append(SourceEntry(line,full_path)) self.set_modified_sourceslist()
|